Repository: facebookincubator/Polygames Branch: main Commit: eb5390e57cc3 Files: 2575 Total size: 19.2 MB Directory structure: gitextract_jldjsds9/ ├── .circleci/ │ └── config.yml ├── .clang-format ├── .github/ │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── build.sh ├── littlegolem/ │ └── play_littlegolem.py ├── nix/ │ ├── Dockerfile │ ├── Dockerfile-centos7-nix │ ├── README.md │ ├── get-nvidia.sh │ ├── shell-cpu.nix │ └── shell-cuda.nix ├── pypolygames/ │ ├── __init__.py │ ├── __main__.py │ ├── convert.py │ ├── draw_model.py │ ├── env_creation_helpers.py │ ├── evaluation.py │ ├── human.py │ ├── model_zoo/ │ │ ├── __init__.py │ │ ├── amazons_model.py │ │ ├── connect4_benchmark_model.py │ │ ├── deep_conv_conv_logit_model.py │ │ ├── deep_conv_fc_logit_model.py │ │ ├── generic_model.py │ │ ├── loss.py │ │ ├── nano_conv_logit_model.py │ │ ├── nano_fc_logit_model.py │ │ ├── res_conv_conv_logit_model.py │ │ ├── res_conv_conv_logit_pool_model.py │ │ ├── res_conv_conv_logit_pool_model_v2.py │ │ ├── res_conv_fc_logit_model.py │ │ ├── u_conv_conv_logit_model.py │ │ ├── u_conv_fc_logit_model.py │ │ └── utils.py │ ├── params.py │ ├── tests/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── data/ │ │ │ ├── BlockGo.txt │ │ │ ├── Breakthrough.txt │ │ │ ├── ChineseCheckers.txt │ │ │ ├── DiceShogi.txt │ │ │ ├── Einstein.txt │ │ │ ├── GameOfTheAmazons.txt │ │ │ ├── Havannah5.txt │ │ │ ├── Havannah8.txt │ │ │ ├── Hex11.txt │ │ │ ├── Hex13.txt │ │ │ ├── KyotoShogi.txt │ │ │ ├── Minishogi.txt │ │ │ ├── Othello10.txt │ │ │ ├── Othello16.txt │ │ │ ├── OthelloOpt10.txt │ │ │ ├── OthelloOpt16.txt │ │ │ ├── Surakarta.txt │ │ │ └── Tristannogo.txt │ │ ├── test_interactions.py │ │ ├── test_mcts.py │ │ ├── test_params.py │ │ └── test_zoo.py │ ├── training.py │ ├── utils/ │ │ ├── __init__.py │ │ ├── assert_utils.py │ │ ├── checkpoint.py │ │ ├── command_history.py │ │ ├── helpers.py │ │ ├── listings.py │ │ ├── logger.py │ │ ├── multi_counter.py │ │ ├── plotter.py │ │ ├── restrack.py │ │ ├── result.py │ │ └── test_listings.py │ └── weight_init.py ├── singularity/ │ ├── README.md │ ├── environment.yml │ └── polygames.def ├── src/ │ ├── CMakeLists.txt │ ├── common/ │ │ ├── async.h │ │ ├── thread_id.cc │ │ ├── thread_id.h │ │ ├── threads.cc │ │ └── threads.h │ ├── core/ │ │ ├── actor.h │ │ ├── actor_player.h │ │ ├── forward_player.h │ │ ├── game.cc │ │ ├── game.h │ │ ├── human_player.h │ │ ├── model_manager.cc │ │ ├── model_manager.h │ │ ├── player.h │ │ ├── pybind.cc │ │ ├── replay_buffer.cc │ │ ├── replay_buffer.h │ │ ├── state.cc │ │ ├── state.h │ │ ├── test_state.cc │ │ └── utils.h │ ├── distributed/ │ │ ├── distributed.cc │ │ ├── distributed.h │ │ ├── ib.cc │ │ ├── network.cc │ │ ├── network.h │ │ ├── rdma.h │ │ ├── rdma_nop.cc │ │ └── rpc.h │ ├── games/ │ │ ├── amazons.cc │ │ ├── amazons.h │ │ ├── block_go.h │ │ ├── breakthrough.cc │ │ ├── breakthrough.h │ │ ├── breakthrough_state.h │ │ ├── chess.cc │ │ ├── chess.h │ │ ├── chinesecheckers.cc │ │ ├── chinesecheckers.h │ │ ├── chinesecheckers_defines.h │ │ ├── commons/ │ │ │ ├── chessboard.h │ │ │ ├── hash.h │ │ │ └── player.h │ │ ├── connect6.h │ │ ├── connect6_state.h │ │ ├── connectfour.h │ │ ├── diceshogi.h │ │ ├── diceshogi_state.h │ │ ├── einstein.h │ │ ├── game_action.h │ │ ├── game_base.cc │ │ ├── game_base.h │ │ ├── game_player.h │ │ ├── game_state.h │ │ ├── gomoku_swap2.cc │ │ ├── gomoku_swap2.h │ │ ├── havannah.h │ │ ├── havannah_state.h │ │ ├── hex.h │ │ ├── hex_state.h │ │ ├── kyotoshogi.h │ │ ├── kyotoshogi_state.h │ │ ├── ludii/ │ │ │ ├── README.md │ │ │ ├── jni_utils.cc │ │ │ ├── jni_utils.h │ │ │ ├── ludii_game_wrapper.cc │ │ │ ├── ludii_game_wrapper.h │ │ │ ├── ludii_state_wrapper.cc │ │ │ └── ludii_state_wrapper.h │ │ ├── mastermind_state.cc │ │ ├── mastermind_state.h │ │ ├── minesweeper.cc │ │ ├── minesweeper_common.h │ │ ├── minesweeper_csp_vkms/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ConnectedComponent.h │ │ │ ├── CspStrategy.h │ │ │ ├── SolutionSet.h │ │ │ ├── SolutionSetSampler.h │ │ │ └── csp_vkms.cc │ │ ├── minesweeper_state.h │ │ ├── minishogi.h │ │ ├── mnkgame.h │ │ ├── nogo_action.cc │ │ ├── nogo_action.h │ │ ├── nogo_bitboard.h │ │ ├── nogo_game.cc │ │ ├── nogo_game.h │ │ ├── nogo_position.h │ │ ├── nogo_state.cc │ │ ├── nogo_state.h │ │ ├── nogo_zestate.h │ │ ├── othello.h │ │ ├── othello_opt.cc │ │ ├── othello_opt.h │ │ ├── outeropengomoku_new.h │ │ ├── shogi.h │ │ ├── surakarta.h │ │ ├── surakarta_state.h │ │ ├── tristan_nogo.cc │ │ ├── tristan_nogo.h │ │ ├── tristannogo_state.h │ │ ├── weakschur/ │ │ │ ├── SchurMatrix.cpp │ │ │ ├── SchurMatrix.hpp │ │ │ ├── SchurVector.cpp │ │ │ ├── SchurVector.hpp │ │ │ ├── WeakSchur.cpp │ │ │ ├── WeakSchur.hpp │ │ │ └── weakschur_state.h │ │ ├── yinsh.cc │ │ └── yinsh.h │ ├── mcts/ │ │ ├── CMakeLists.txt │ │ ├── actor.h │ │ ├── mcts.cc │ │ ├── mcts.h │ │ ├── node.cc │ │ ├── node.h │ │ ├── player.h │ │ ├── pybind.cc │ │ ├── storage.cc │ │ ├── storage.h │ │ ├── test.cc │ │ ├── types.h │ │ └── utils.h │ ├── third_party/ │ │ ├── asio/ │ │ │ ├── associated_allocator.hpp │ │ │ ├── associated_executor.hpp │ │ │ ├── async_result.hpp │ │ │ ├── awaitable.hpp │ │ │ ├── basic_datagram_socket.hpp │ │ │ ├── basic_deadline_timer.hpp │ │ │ ├── basic_io_object.hpp │ │ │ ├── basic_raw_socket.hpp │ │ │ ├── basic_seq_packet_socket.hpp │ │ │ ├── basic_serial_port.hpp │ │ │ ├── basic_signal_set.hpp │ │ │ ├── basic_socket.hpp │ │ │ ├── basic_socket_acceptor.hpp │ │ │ ├── basic_socket_iostream.hpp │ │ │ ├── basic_socket_streambuf.hpp │ │ │ ├── basic_stream_socket.hpp │ │ │ ├── basic_streambuf.hpp │ │ │ ├── basic_streambuf_fwd.hpp │ │ │ ├── basic_waitable_timer.hpp │ │ │ ├── bind_executor.hpp │ │ │ ├── buffer.hpp │ │ │ ├── buffered_read_stream.hpp │ │ │ ├── buffered_read_stream_fwd.hpp │ │ │ ├── buffered_stream.hpp │ │ │ ├── buffered_stream_fwd.hpp │ │ │ ├── buffered_write_stream.hpp │ │ │ ├── buffered_write_stream_fwd.hpp │ │ │ ├── buffers_iterator.hpp │ │ │ ├── co_spawn.hpp │ │ │ ├── completion_condition.hpp │ │ │ ├── compose.hpp │ │ │ ├── connect.hpp │ │ │ ├── coroutine.hpp │ │ │ ├── deadline_timer.hpp │ │ │ ├── defer.hpp │ │ │ ├── detached.hpp │ │ │ ├── detail/ │ │ │ │ ├── array.hpp │ │ │ │ ├── array_fwd.hpp │ │ │ │ ├── assert.hpp │ │ │ │ ├── atomic_count.hpp │ │ │ │ ├── base_from_completion_cond.hpp │ │ │ │ ├── bind_handler.hpp │ │ │ │ ├── buffer_resize_guard.hpp │ │ │ │ ├── buffer_sequence_adapter.hpp │ │ │ │ ├── buffered_stream_storage.hpp │ │ │ │ ├── call_stack.hpp │ │ │ │ ├── chrono.hpp │ │ │ │ ├── chrono_time_traits.hpp │ │ │ │ ├── completion_handler.hpp │ │ │ │ ├── concurrency_hint.hpp │ │ │ │ ├── conditionally_enabled_event.hpp │ │ │ │ ├── conditionally_enabled_mutex.hpp │ │ │ │ ├── config.hpp │ │ │ │ ├── consuming_buffers.hpp │ │ │ │ ├── cstddef.hpp │ │ │ │ ├── cstdint.hpp │ │ │ │ ├── date_time_fwd.hpp │ │ │ │ ├── deadline_timer_service.hpp │ │ │ │ ├── dependent_type.hpp │ │ │ │ ├── descriptor_ops.hpp │ │ │ │ ├── descriptor_read_op.hpp │ │ │ │ ├── descriptor_write_op.hpp │ │ │ │ ├── dev_poll_reactor.hpp │ │ │ │ ├── epoll_reactor.hpp │ │ │ │ ├── event.hpp │ │ │ │ ├── eventfd_select_interrupter.hpp │ │ │ │ ├── executor_function.hpp │ │ │ │ ├── executor_op.hpp │ │ │ │ ├── fd_set_adapter.hpp │ │ │ │ ├── fenced_block.hpp │ │ │ │ ├── functional.hpp │ │ │ │ ├── future.hpp │ │ │ │ ├── gcc_arm_fenced_block.hpp │ │ │ │ ├── gcc_hppa_fenced_block.hpp │ │ │ │ ├── gcc_sync_fenced_block.hpp │ │ │ │ ├── gcc_x86_fenced_block.hpp │ │ │ │ ├── global.hpp │ │ │ │ ├── handler_alloc_helpers.hpp │ │ │ │ ├── handler_cont_helpers.hpp │ │ │ │ ├── handler_invoke_helpers.hpp │ │ │ │ ├── handler_tracking.hpp │ │ │ │ ├── handler_type_requirements.hpp │ │ │ │ ├── handler_work.hpp │ │ │ │ ├── hash_map.hpp │ │ │ │ ├── impl/ │ │ │ │ │ ├── buffer_sequence_adapter.ipp │ │ │ │ │ ├── descriptor_ops.ipp │ │ │ │ │ ├── dev_poll_reactor.hpp │ │ │ │ │ ├── dev_poll_reactor.ipp │ │ │ │ │ ├── epoll_reactor.hpp │ │ │ │ │ ├── epoll_reactor.ipp │ │ │ │ │ ├── eventfd_select_interrupter.ipp │ │ │ │ │ ├── handler_tracking.ipp │ │ │ │ │ ├── kqueue_reactor.hpp │ │ │ │ │ ├── kqueue_reactor.ipp │ │ │ │ │ ├── null_event.ipp │ │ │ │ │ ├── pipe_select_interrupter.ipp │ │ │ │ │ ├── posix_event.ipp │ │ │ │ │ ├── posix_mutex.ipp │ │ │ │ │ ├── posix_thread.ipp │ │ │ │ │ ├── posix_tss_ptr.ipp │ │ │ │ │ ├── reactive_descriptor_service.ipp │ │ │ │ │ ├── reactive_serial_port_service.ipp │ │ │ │ │ ├── reactive_socket_service_base.ipp │ │ │ │ │ ├── resolver_service_base.ipp │ │ │ │ │ ├── scheduler.ipp │ │ │ │ │ ├── select_reactor.hpp │ │ │ │ │ ├── select_reactor.ipp │ │ │ │ │ ├── service_registry.hpp │ │ │ │ │ ├── service_registry.ipp │ │ │ │ │ ├── signal_set_service.ipp │ │ │ │ │ ├── socket_ops.ipp │ │ │ │ │ ├── socket_select_interrupter.ipp │ │ │ │ │ ├── strand_executor_service.hpp │ │ │ │ │ ├── strand_executor_service.ipp │ │ │ │ │ ├── strand_service.hpp │ │ │ │ │ ├── strand_service.ipp │ │ │ │ │ ├── throw_error.ipp │ │ │ │ │ ├── timer_queue_ptime.ipp │ │ │ │ │ ├── timer_queue_set.ipp │ │ │ │ │ ├── win_event.ipp │ │ │ │ │ ├── win_iocp_handle_service.ipp │ │ │ │ │ ├── win_iocp_io_context.hpp │ │ │ │ │ ├── win_iocp_io_context.ipp │ │ │ │ │ ├── win_iocp_serial_port_service.ipp │ │ │ │ │ ├── win_iocp_socket_service_base.ipp │ │ │ │ │ ├── win_mutex.ipp │ │ │ │ │ ├── win_object_handle_service.ipp │ │ │ │ │ ├── win_static_mutex.ipp │ │ │ │ │ ├── win_thread.ipp │ │ │ │ │ ├── win_tss_ptr.ipp │ │ │ │ │ ├── winrt_ssocket_service_base.ipp │ │ │ │ │ ├── winrt_timer_scheduler.hpp │ │ │ │ │ ├── winrt_timer_scheduler.ipp │ │ │ │ │ └── winsock_init.ipp │ │ │ │ ├── io_control.hpp │ │ │ │ ├── io_object_executor.hpp │ │ │ │ ├── io_object_impl.hpp │ │ │ │ ├── is_buffer_sequence.hpp │ │ │ │ ├── is_executor.hpp │ │ │ │ ├── keyword_tss_ptr.hpp │ │ │ │ ├── kqueue_reactor.hpp │ │ │ │ ├── limits.hpp │ │ │ │ ├── local_free_on_block_exit.hpp │ │ │ │ ├── macos_fenced_block.hpp │ │ │ │ ├── memory.hpp │ │ │ │ ├── mutex.hpp │ │ │ │ ├── non_const_lvalue.hpp │ │ │ │ ├── noncopyable.hpp │ │ │ │ ├── null_event.hpp │ │ │ │ ├── null_fenced_block.hpp │ │ │ │ ├── null_global.hpp │ │ │ │ ├── null_mutex.hpp │ │ │ │ ├── null_reactor.hpp │ │ │ │ ├── null_signal_blocker.hpp │ │ │ │ ├── null_socket_service.hpp │ │ │ │ ├── null_static_mutex.hpp │ │ │ │ ├── null_thread.hpp │ │ │ │ ├── null_tss_ptr.hpp │ │ │ │ ├── object_pool.hpp │ │ │ │ ├── old_win_sdk_compat.hpp │ │ │ │ ├── op_queue.hpp │ │ │ │ ├── operation.hpp │ │ │ │ ├── pipe_select_interrupter.hpp │ │ │ │ ├── pop_options.hpp │ │ │ │ ├── posix_event.hpp │ │ │ │ ├── posix_fd_set_adapter.hpp │ │ │ │ ├── posix_global.hpp │ │ │ │ ├── posix_mutex.hpp │ │ │ │ ├── posix_signal_blocker.hpp │ │ │ │ ├── posix_static_mutex.hpp │ │ │ │ ├── posix_thread.hpp │ │ │ │ ├── posix_tss_ptr.hpp │ │ │ │ ├── push_options.hpp │ │ │ │ ├── reactive_descriptor_service.hpp │ │ │ │ ├── reactive_null_buffers_op.hpp │ │ │ │ ├── reactive_serial_port_service.hpp │ │ │ │ ├── reactive_socket_accept_op.hpp │ │ │ │ ├── reactive_socket_connect_op.hpp │ │ │ │ ├── reactive_socket_recv_op.hpp │ │ │ │ ├── reactive_socket_recvfrom_op.hpp │ │ │ │ ├── reactive_socket_recvmsg_op.hpp │ │ │ │ ├── reactive_socket_send_op.hpp │ │ │ │ ├── reactive_socket_sendto_op.hpp │ │ │ │ ├── reactive_socket_service.hpp │ │ │ │ ├── reactive_socket_service_base.hpp │ │ │ │ ├── reactive_wait_op.hpp │ │ │ │ ├── reactor.hpp │ │ │ │ ├── reactor_fwd.hpp │ │ │ │ ├── reactor_op.hpp │ │ │ │ ├── reactor_op_queue.hpp │ │ │ │ ├── recycling_allocator.hpp │ │ │ │ ├── regex_fwd.hpp │ │ │ │ ├── resolve_endpoint_op.hpp │ │ │ │ ├── resolve_op.hpp │ │ │ │ ├── resolve_query_op.hpp │ │ │ │ ├── resolver_service.hpp │ │ │ │ ├── resolver_service_base.hpp │ │ │ │ ├── scheduler.hpp │ │ │ │ ├── scheduler_operation.hpp │ │ │ │ ├── scheduler_thread_info.hpp │ │ │ │ ├── scoped_lock.hpp │ │ │ │ ├── scoped_ptr.hpp │ │ │ │ ├── select_interrupter.hpp │ │ │ │ ├── select_reactor.hpp │ │ │ │ ├── service_registry.hpp │ │ │ │ ├── signal_blocker.hpp │ │ │ │ ├── signal_handler.hpp │ │ │ │ ├── signal_init.hpp │ │ │ │ ├── signal_op.hpp │ │ │ │ ├── signal_set_service.hpp │ │ │ │ ├── socket_holder.hpp │ │ │ │ ├── socket_ops.hpp │ │ │ │ ├── socket_option.hpp │ │ │ │ ├── socket_select_interrupter.hpp │ │ │ │ ├── socket_types.hpp │ │ │ │ ├── solaris_fenced_block.hpp │ │ │ │ ├── static_mutex.hpp │ │ │ │ ├── std_event.hpp │ │ │ │ ├── std_fenced_block.hpp │ │ │ │ ├── std_global.hpp │ │ │ │ ├── std_mutex.hpp │ │ │ │ ├── std_static_mutex.hpp │ │ │ │ ├── std_thread.hpp │ │ │ │ ├── strand_executor_service.hpp │ │ │ │ ├── strand_service.hpp │ │ │ │ ├── string_view.hpp │ │ │ │ ├── thread.hpp │ │ │ │ ├── thread_context.hpp │ │ │ │ ├── thread_group.hpp │ │ │ │ ├── thread_info_base.hpp │ │ │ │ ├── throw_error.hpp │ │ │ │ ├── throw_exception.hpp │ │ │ │ ├── timer_queue.hpp │ │ │ │ ├── timer_queue_base.hpp │ │ │ │ ├── timer_queue_ptime.hpp │ │ │ │ ├── timer_queue_set.hpp │ │ │ │ ├── timer_scheduler.hpp │ │ │ │ ├── timer_scheduler_fwd.hpp │ │ │ │ ├── tss_ptr.hpp │ │ │ │ ├── type_traits.hpp │ │ │ │ ├── variadic_templates.hpp │ │ │ │ ├── wait_handler.hpp │ │ │ │ ├── wait_op.hpp │ │ │ │ ├── win_event.hpp │ │ │ │ ├── win_fd_set_adapter.hpp │ │ │ │ ├── win_fenced_block.hpp │ │ │ │ ├── win_global.hpp │ │ │ │ ├── win_iocp_handle_read_op.hpp │ │ │ │ ├── win_iocp_handle_service.hpp │ │ │ │ ├── win_iocp_handle_write_op.hpp │ │ │ │ ├── win_iocp_io_context.hpp │ │ │ │ ├── win_iocp_null_buffers_op.hpp │ │ │ │ ├── win_iocp_operation.hpp │ │ │ │ ├── win_iocp_overlapped_op.hpp │ │ │ │ ├── win_iocp_overlapped_ptr.hpp │ │ │ │ ├── win_iocp_serial_port_service.hpp │ │ │ │ ├── win_iocp_socket_accept_op.hpp │ │ │ │ ├── win_iocp_socket_connect_op.hpp │ │ │ │ ├── win_iocp_socket_recv_op.hpp │ │ │ │ ├── win_iocp_socket_recvfrom_op.hpp │ │ │ │ ├── win_iocp_socket_recvmsg_op.hpp │ │ │ │ ├── win_iocp_socket_send_op.hpp │ │ │ │ ├── win_iocp_socket_service.hpp │ │ │ │ ├── win_iocp_socket_service_base.hpp │ │ │ │ ├── win_iocp_thread_info.hpp │ │ │ │ ├── win_iocp_wait_op.hpp │ │ │ │ ├── win_mutex.hpp │ │ │ │ ├── win_object_handle_service.hpp │ │ │ │ ├── win_static_mutex.hpp │ │ │ │ ├── win_thread.hpp │ │ │ │ ├── win_tss_ptr.hpp │ │ │ │ ├── winapp_thread.hpp │ │ │ │ ├── wince_thread.hpp │ │ │ │ ├── winrt_async_manager.hpp │ │ │ │ ├── winrt_async_op.hpp │ │ │ │ ├── winrt_resolve_op.hpp │ │ │ │ ├── winrt_resolver_service.hpp │ │ │ │ ├── winrt_socket_connect_op.hpp │ │ │ │ ├── winrt_socket_recv_op.hpp │ │ │ │ ├── winrt_socket_send_op.hpp │ │ │ │ ├── winrt_ssocket_service.hpp │ │ │ │ ├── winrt_ssocket_service_base.hpp │ │ │ │ ├── winrt_timer_scheduler.hpp │ │ │ │ ├── winrt_utils.hpp │ │ │ │ ├── winsock_init.hpp │ │ │ │ ├── work_dispatcher.hpp │ │ │ │ └── wrapped_handler.hpp │ │ │ ├── dispatch.hpp │ │ │ ├── error.hpp │ │ │ ├── error_code.hpp │ │ │ ├── execution_context.hpp │ │ │ ├── executor.hpp │ │ │ ├── executor_work_guard.hpp │ │ │ ├── generic/ │ │ │ │ ├── basic_endpoint.hpp │ │ │ │ ├── datagram_protocol.hpp │ │ │ │ ├── detail/ │ │ │ │ │ ├── endpoint.hpp │ │ │ │ │ └── impl/ │ │ │ │ │ └── endpoint.ipp │ │ │ │ ├── raw_protocol.hpp │ │ │ │ ├── seq_packet_protocol.hpp │ │ │ │ └── stream_protocol.hpp │ │ │ ├── handler_alloc_hook.hpp │ │ │ ├── handler_continuation_hook.hpp │ │ │ ├── handler_invoke_hook.hpp │ │ │ ├── high_resolution_timer.hpp │ │ │ ├── impl/ │ │ │ │ ├── awaitable.hpp │ │ │ │ ├── buffered_read_stream.hpp │ │ │ │ ├── buffered_write_stream.hpp │ │ │ │ ├── co_spawn.hpp │ │ │ │ ├── compose.hpp │ │ │ │ ├── connect.hpp │ │ │ │ ├── defer.hpp │ │ │ │ ├── detached.hpp │ │ │ │ ├── dispatch.hpp │ │ │ │ ├── error.ipp │ │ │ │ ├── error_code.ipp │ │ │ │ ├── execution_context.hpp │ │ │ │ ├── execution_context.ipp │ │ │ │ ├── executor.hpp │ │ │ │ ├── executor.ipp │ │ │ │ ├── handler_alloc_hook.ipp │ │ │ │ ├── io_context.hpp │ │ │ │ ├── io_context.ipp │ │ │ │ ├── post.hpp │ │ │ │ ├── read.hpp │ │ │ │ ├── read_at.hpp │ │ │ │ ├── read_until.hpp │ │ │ │ ├── redirect_error.hpp │ │ │ │ ├── serial_port_base.hpp │ │ │ │ ├── serial_port_base.ipp │ │ │ │ ├── spawn.hpp │ │ │ │ ├── src.cpp │ │ │ │ ├── src.hpp │ │ │ │ ├── system_context.hpp │ │ │ │ ├── system_context.ipp │ │ │ │ ├── system_executor.hpp │ │ │ │ ├── thread_pool.hpp │ │ │ │ ├── thread_pool.ipp │ │ │ │ ├── use_awaitable.hpp │ │ │ │ ├── use_future.hpp │ │ │ │ ├── write.hpp │ │ │ │ └── write_at.hpp │ │ │ ├── io_context.hpp │ │ │ ├── io_context_strand.hpp │ │ │ ├── io_service.hpp │ │ │ ├── io_service_strand.hpp │ │ │ ├── ip/ │ │ │ │ ├── address.hpp │ │ │ │ ├── address_v4.hpp │ │ │ │ ├── address_v4_iterator.hpp │ │ │ │ ├── address_v4_range.hpp │ │ │ │ ├── address_v6.hpp │ │ │ │ ├── address_v6_iterator.hpp │ │ │ │ ├── address_v6_range.hpp │ │ │ │ ├── bad_address_cast.hpp │ │ │ │ ├── basic_endpoint.hpp │ │ │ │ ├── basic_resolver.hpp │ │ │ │ ├── basic_resolver_entry.hpp │ │ │ │ ├── basic_resolver_iterator.hpp │ │ │ │ ├── basic_resolver_query.hpp │ │ │ │ ├── basic_resolver_results.hpp │ │ │ │ ├── detail/ │ │ │ │ │ ├── endpoint.hpp │ │ │ │ │ ├── impl/ │ │ │ │ │ │ └── endpoint.ipp │ │ │ │ │ └── socket_option.hpp │ │ │ │ ├── host_name.hpp │ │ │ │ ├── icmp.hpp │ │ │ │ ├── impl/ │ │ │ │ │ ├── address.hpp │ │ │ │ │ ├── address.ipp │ │ │ │ │ ├── address_v4.hpp │ │ │ │ │ ├── address_v4.ipp │ │ │ │ │ ├── address_v6.hpp │ │ │ │ │ ├── address_v6.ipp │ │ │ │ │ ├── basic_endpoint.hpp │ │ │ │ │ ├── host_name.ipp │ │ │ │ │ ├── network_v4.hpp │ │ │ │ │ ├── network_v4.ipp │ │ │ │ │ ├── network_v6.hpp │ │ │ │ │ └── network_v6.ipp │ │ │ │ ├── multicast.hpp │ │ │ │ ├── network_v4.hpp │ │ │ │ ├── network_v6.hpp │ │ │ │ ├── resolver_base.hpp │ │ │ │ ├── resolver_query_base.hpp │ │ │ │ ├── tcp.hpp │ │ │ │ ├── udp.hpp │ │ │ │ ├── unicast.hpp │ │ │ │ └── v6_only.hpp │ │ │ ├── is_executor.hpp │ │ │ ├── is_read_buffered.hpp │ │ │ ├── is_write_buffered.hpp │ │ │ ├── local/ │ │ │ │ ├── basic_endpoint.hpp │ │ │ │ ├── connect_pair.hpp │ │ │ │ ├── datagram_protocol.hpp │ │ │ │ ├── detail/ │ │ │ │ │ ├── endpoint.hpp │ │ │ │ │ └── impl/ │ │ │ │ │ └── endpoint.ipp │ │ │ │ └── stream_protocol.hpp │ │ │ ├── packaged_task.hpp │ │ │ ├── placeholders.hpp │ │ │ ├── posix/ │ │ │ │ ├── basic_descriptor.hpp │ │ │ │ ├── basic_stream_descriptor.hpp │ │ │ │ ├── descriptor.hpp │ │ │ │ ├── descriptor_base.hpp │ │ │ │ └── stream_descriptor.hpp │ │ │ ├── post.hpp │ │ │ ├── read.hpp │ │ │ ├── read_at.hpp │ │ │ ├── read_until.hpp │ │ │ ├── redirect_error.hpp │ │ │ ├── serial_port.hpp │ │ │ ├── serial_port_base.hpp │ │ │ ├── signal_set.hpp │ │ │ ├── socket_base.hpp │ │ │ ├── spawn.hpp │ │ │ ├── ssl/ │ │ │ │ ├── context.hpp │ │ │ │ ├── context_base.hpp │ │ │ │ ├── detail/ │ │ │ │ │ ├── buffered_handshake_op.hpp │ │ │ │ │ ├── engine.hpp │ │ │ │ │ ├── handshake_op.hpp │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── engine.ipp │ │ │ │ │ │ └── openssl_init.ipp │ │ │ │ │ ├── io.hpp │ │ │ │ │ ├── openssl_init.hpp │ │ │ │ │ ├── openssl_types.hpp │ │ │ │ │ ├── password_callback.hpp │ │ │ │ │ ├── read_op.hpp │ │ │ │ │ ├── shutdown_op.hpp │ │ │ │ │ ├── stream_core.hpp │ │ │ │ │ ├── verify_callback.hpp │ │ │ │ │ └── write_op.hpp │ │ │ │ ├── error.hpp │ │ │ │ ├── impl/ │ │ │ │ │ ├── context.hpp │ │ │ │ │ ├── context.ipp │ │ │ │ │ ├── error.ipp │ │ │ │ │ ├── rfc2818_verification.ipp │ │ │ │ │ └── src.hpp │ │ │ │ ├── rfc2818_verification.hpp │ │ │ │ ├── stream.hpp │ │ │ │ ├── stream_base.hpp │ │ │ │ ├── verify_context.hpp │ │ │ │ └── verify_mode.hpp │ │ │ ├── ssl.hpp │ │ │ ├── steady_timer.hpp │ │ │ ├── strand.hpp │ │ │ ├── streambuf.hpp │ │ │ ├── system_context.hpp │ │ │ ├── system_error.hpp │ │ │ ├── system_executor.hpp │ │ │ ├── system_timer.hpp │ │ │ ├── this_coro.hpp │ │ │ ├── thread.hpp │ │ │ ├── thread_pool.hpp │ │ │ ├── time_traits.hpp │ │ │ ├── ts/ │ │ │ │ ├── buffer.hpp │ │ │ │ ├── executor.hpp │ │ │ │ ├── internet.hpp │ │ │ │ ├── io_context.hpp │ │ │ │ ├── net.hpp │ │ │ │ ├── netfwd.hpp │ │ │ │ ├── socket.hpp │ │ │ │ └── timer.hpp │ │ │ ├── unyield.hpp │ │ │ ├── use_awaitable.hpp │ │ │ ├── use_future.hpp │ │ │ ├── uses_executor.hpp │ │ │ ├── version.hpp │ │ │ ├── wait_traits.hpp │ │ │ ├── windows/ │ │ │ │ ├── basic_object_handle.hpp │ │ │ │ ├── basic_overlapped_handle.hpp │ │ │ │ ├── basic_random_access_handle.hpp │ │ │ │ ├── basic_stream_handle.hpp │ │ │ │ ├── object_handle.hpp │ │ │ │ ├── overlapped_handle.hpp │ │ │ │ ├── overlapped_ptr.hpp │ │ │ │ ├── random_access_handle.hpp │ │ │ │ └── stream_handle.hpp │ │ │ ├── write.hpp │ │ │ ├── write_at.hpp │ │ │ └── yield.hpp │ │ ├── asio.hpp │ │ ├── concurrentqueue/ │ │ │ ├── LICENSE.md │ │ │ ├── README.md │ │ │ ├── benchmarks/ │ │ │ │ ├── benchmarks.cpp │ │ │ │ ├── boost/ │ │ │ │ │ ├── LICENSE_1_0.txt │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── array.hpp │ │ │ │ │ ├── assert.hpp │ │ │ │ │ ├── atomic/ │ │ │ │ │ │ ├── atomic.hpp │ │ │ │ │ │ ├── atomic_flag.hpp │ │ │ │ │ │ ├── capabilities.hpp │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ ├── atomic_flag.hpp │ │ │ │ │ │ │ ├── atomic_template.hpp │ │ │ │ │ │ │ ├── bitwise_cast.hpp │ │ │ │ │ │ │ ├── caps_gcc_alpha.hpp │ │ │ │ │ │ │ ├── caps_gcc_arm.hpp │ │ │ │ │ │ │ ├── caps_gcc_atomic.hpp │ │ │ │ │ │ │ ├── caps_gcc_ppc.hpp │ │ │ │ │ │ │ ├── caps_gcc_sparc.hpp │ │ │ │ │ │ │ ├── caps_gcc_sync.hpp │ │ │ │ │ │ │ ├── caps_gcc_x86.hpp │ │ │ │ │ │ │ ├── caps_linux_arm.hpp │ │ │ │ │ │ │ ├── caps_msvc_arm.hpp │ │ │ │ │ │ │ ├── caps_msvc_x86.hpp │ │ │ │ │ │ │ ├── caps_windows.hpp │ │ │ │ │ │ │ ├── config.hpp │ │ │ │ │ │ │ ├── int_sizes.hpp │ │ │ │ │ │ │ ├── interlocked.hpp │ │ │ │ │ │ │ ├── link.hpp │ │ │ │ │ │ │ ├── lockpool.hpp │ │ │ │ │ │ │ ├── operations.hpp │ │ │ │ │ │ │ ├── operations_fwd.hpp │ │ │ │ │ │ │ ├── operations_lockfree.hpp │ │ │ │ │ │ │ ├── ops_cas_based.hpp │ │ │ │ │ │ │ ├── ops_emulated.hpp │ │ │ │ │ │ │ ├── ops_extending_cas_based.hpp │ │ │ │ │ │ │ ├── ops_gcc_alpha.hpp │ │ │ │ │ │ │ ├── ops_gcc_arm.hpp │ │ │ │ │ │ │ ├── ops_gcc_atomic.hpp │ │ │ │ │ │ │ ├── ops_gcc_ppc.hpp │ │ │ │ │ │ │ ├── ops_gcc_sparc.hpp │ │ │ │ │ │ │ ├── ops_gcc_sync.hpp │ │ │ │ │ │ │ ├── ops_gcc_x86.hpp │ │ │ │ │ │ │ ├── ops_gcc_x86_dcas.hpp │ │ │ │ │ │ │ ├── ops_linux_arm.hpp │ │ │ │ │ │ │ ├── ops_msvc_arm.hpp │ │ │ │ │ │ │ ├── ops_msvc_common.hpp │ │ │ │ │ │ │ ├── ops_msvc_x86.hpp │ │ │ │ │ │ │ ├── ops_windows.hpp │ │ │ │ │ │ │ ├── pause.hpp │ │ │ │ │ │ │ ├── platform.hpp │ │ │ │ │ │ │ └── storage_type.hpp │ │ │ │ │ │ └── fences.hpp │ │ │ │ │ ├── atomic.hpp │ │ │ │ │ ├── config/ │ │ │ │ │ │ ├── abi/ │ │ │ │ │ │ │ ├── borland_prefix.hpp │ │ │ │ │ │ │ ├── borland_suffix.hpp │ │ │ │ │ │ │ ├── msvc_prefix.hpp │ │ │ │ │ │ │ └── msvc_suffix.hpp │ │ │ │ │ │ ├── abi_prefix.hpp │ │ │ │ │ │ ├── abi_suffix.hpp │ │ │ │ │ │ ├── auto_link.hpp │ │ │ │ │ │ ├── compiler/ │ │ │ │ │ │ │ ├── borland.hpp │ │ │ │ │ │ │ ├── clang.hpp │ │ │ │ │ │ │ ├── codegear.hpp │ │ │ │ │ │ │ ├── comeau.hpp │ │ │ │ │ │ │ ├── common_edg.hpp │ │ │ │ │ │ │ ├── compaq_cxx.hpp │ │ │ │ │ │ │ ├── cray.hpp │ │ │ │ │ │ │ ├── digitalmars.hpp │ │ │ │ │ │ │ ├── gcc.hpp │ │ │ │ │ │ │ ├── gcc_xml.hpp │ │ │ │ │ │ │ ├── greenhills.hpp │ │ │ │ │ │ │ ├── hp_acc.hpp │ │ │ │ │ │ │ ├── intel.hpp │ │ │ │ │ │ │ ├── kai.hpp │ │ │ │ │ │ │ ├── metrowerks.hpp │ │ │ │ │ │ │ ├── mpw.hpp │ │ │ │ │ │ │ ├── nvcc.hpp │ │ │ │ │ │ │ ├── pathscale.hpp │ │ │ │ │ │ │ ├── pgi.hpp │ │ │ │ │ │ │ ├── sgi_mipspro.hpp │ │ │ │ │ │ │ ├── sunpro_cc.hpp │ │ │ │ │ │ │ ├── vacpp.hpp │ │ │ │ │ │ │ ├── visualc.hpp │ │ │ │ │ │ │ └── xlcpp.hpp │ │ │ │ │ │ ├── no_tr1/ │ │ │ │ │ │ │ ├── cmath.hpp │ │ │ │ │ │ │ ├── complex.hpp │ │ │ │ │ │ │ ├── functional.hpp │ │ │ │ │ │ │ ├── memory.hpp │ │ │ │ │ │ │ └── utility.hpp │ │ │ │ │ │ ├── platform/ │ │ │ │ │ │ │ ├── aix.hpp │ │ │ │ │ │ │ ├── amigaos.hpp │ │ │ │ │ │ │ ├── beos.hpp │ │ │ │ │ │ │ ├── bsd.hpp │ │ │ │ │ │ │ ├── cloudabi.hpp │ │ │ │ │ │ │ ├── cray.hpp │ │ │ │ │ │ │ ├── cygwin.hpp │ │ │ │ │ │ │ ├── haiku.hpp │ │ │ │ │ │ │ ├── hpux.hpp │ │ │ │ │ │ │ ├── irix.hpp │ │ │ │ │ │ │ ├── linux.hpp │ │ │ │ │ │ │ ├── macos.hpp │ │ │ │ │ │ │ ├── qnxnto.hpp │ │ │ │ │ │ │ ├── solaris.hpp │ │ │ │ │ │ │ ├── symbian.hpp │ │ │ │ │ │ │ ├── vms.hpp │ │ │ │ │ │ │ ├── vxworks.hpp │ │ │ │ │ │ │ └── win32.hpp │ │ │ │ │ │ ├── posix_features.hpp │ │ │ │ │ │ ├── requires_threads.hpp │ │ │ │ │ │ ├── select_compiler_config.hpp │ │ │ │ │ │ ├── select_platform_config.hpp │ │ │ │ │ │ ├── select_stdlib_config.hpp │ │ │ │ │ │ ├── stdlib/ │ │ │ │ │ │ │ ├── dinkumware.hpp │ │ │ │ │ │ │ ├── libcomo.hpp │ │ │ │ │ │ │ ├── libcpp.hpp │ │ │ │ │ │ │ ├── libstdcpp3.hpp │ │ │ │ │ │ │ ├── modena.hpp │ │ │ │ │ │ │ ├── msl.hpp │ │ │ │ │ │ │ ├── roguewave.hpp │ │ │ │ │ │ │ ├── sgi.hpp │ │ │ │ │ │ │ ├── stlport.hpp │ │ │ │ │ │ │ └── vacpp.hpp │ │ │ │ │ │ ├── suffix.hpp │ │ │ │ │ │ ├── user.hpp │ │ │ │ │ │ └── warning_disable.hpp │ │ │ │ │ ├── config.hpp │ │ │ │ │ ├── core/ │ │ │ │ │ │ ├── enable_if.hpp │ │ │ │ │ │ ├── noncopyable.hpp │ │ │ │ │ │ └── swap.hpp │ │ │ │ │ ├── cstdint.hpp │ │ │ │ │ ├── current_function.hpp │ │ │ │ │ ├── detail/ │ │ │ │ │ │ ├── is_xxx.hpp │ │ │ │ │ │ ├── iterator.hpp │ │ │ │ │ │ └── workaround.hpp │ │ │ │ │ ├── exception/ │ │ │ │ │ │ └── exception.hpp │ │ │ │ │ ├── functional/ │ │ │ │ │ │ ├── hash/ │ │ │ │ │ │ │ └── hash_fwd.hpp │ │ │ │ │ │ └── hash_fwd.hpp │ │ │ │ │ ├── limits.hpp │ │ │ │ │ ├── lockfree/ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ ├── atomic.hpp │ │ │ │ │ │ │ ├── copy_payload.hpp │ │ │ │ │ │ │ ├── freelist.hpp │ │ │ │ │ │ │ ├── parameter.hpp │ │ │ │ │ │ │ ├── prefix.hpp │ │ │ │ │ │ │ ├── tagged_ptr.hpp │ │ │ │ │ │ │ ├── tagged_ptr_dcas.hpp │ │ │ │ │ │ │ └── tagged_ptr_ptrcompression.hpp │ │ │ │ │ │ ├── policies.hpp │ │ │ │ │ │ └── queue.hpp │ │ │ │ │ ├── memory_order.hpp │ │ │ │ │ ├── mpl/ │ │ │ │ │ │ ├── O1_size.hpp │ │ │ │ │ │ ├── O1_size_fwd.hpp │ │ │ │ │ │ ├── always.hpp │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ ├── arg_fwd.hpp │ │ │ │ │ │ ├── assert.hpp │ │ │ │ │ │ ├── at_fwd.hpp │ │ │ │ │ │ ├── aux_/ │ │ │ │ │ │ │ ├── O1_size_impl.hpp │ │ │ │ │ │ │ ├── adl_barrier.hpp │ │ │ │ │ │ │ ├── arg_typedef.hpp │ │ │ │ │ │ │ ├── arity.hpp │ │ │ │ │ │ │ ├── arity_spec.hpp │ │ │ │ │ │ │ ├── begin_end_impl.hpp │ │ │ │ │ │ │ ├── clear_impl.hpp │ │ │ │ │ │ │ ├── common_name_wknd.hpp │ │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ │ ├── adl.hpp │ │ │ │ │ │ │ │ ├── arrays.hpp │ │ │ │ │ │ │ │ ├── bcc.hpp │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ ├── compiler.hpp │ │ │ │ │ │ │ │ ├── ctps.hpp │ │ │ │ │ │ │ │ ├── dmc_ambiguous_ctps.hpp │ │ │ │ │ │ │ │ ├── dtp.hpp │ │ │ │ │ │ │ │ ├── eti.hpp │ │ │ │ │ │ │ │ ├── forwarding.hpp │ │ │ │ │ │ │ │ ├── gcc.hpp │ │ │ │ │ │ │ │ ├── gpu.hpp │ │ │ │ │ │ │ │ ├── has_apply.hpp │ │ │ │ │ │ │ │ ├── has_xxx.hpp │ │ │ │ │ │ │ │ ├── integral.hpp │ │ │ │ │ │ │ │ ├── intel.hpp │ │ │ │ │ │ │ │ ├── lambda.hpp │ │ │ │ │ │ │ │ ├── msvc.hpp │ │ │ │ │ │ │ │ ├── msvc_typename.hpp │ │ │ │ │ │ │ │ ├── nttp.hpp │ │ │ │ │ │ │ │ ├── operators.hpp │ │ │ │ │ │ │ │ ├── overload_resolution.hpp │ │ │ │ │ │ │ │ ├── pp_counter.hpp │ │ │ │ │ │ │ │ ├── preprocessor.hpp │ │ │ │ │ │ │ │ ├── static_constant.hpp │ │ │ │ │ │ │ │ ├── ttp.hpp │ │ │ │ │ │ │ │ ├── use_preprocessed.hpp │ │ │ │ │ │ │ │ └── workaround.hpp │ │ │ │ │ │ │ ├── count_args.hpp │ │ │ │ │ │ │ ├── find_if_pred.hpp │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ ├── fold_impl_body.hpp │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ ├── has_apply.hpp │ │ │ │ │ │ │ ├── has_begin.hpp │ │ │ │ │ │ │ ├── has_key_impl.hpp │ │ │ │ │ │ │ ├── has_rebind.hpp │ │ │ │ │ │ │ ├── has_size.hpp │ │ │ │ │ │ │ ├── has_tag.hpp │ │ │ │ │ │ │ ├── has_type.hpp │ │ │ │ │ │ │ ├── include_preprocessed.hpp │ │ │ │ │ │ │ ├── insert_impl.hpp │ │ │ │ │ │ │ ├── integral_wrapper.hpp │ │ │ │ │ │ │ ├── is_msvc_eti_arg.hpp │ │ │ │ │ │ │ ├── iter_apply.hpp │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ ├── lambda_arity_param.hpp │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ ├── lambda_spec.hpp │ │ │ │ │ │ │ ├── lambda_support.hpp │ │ │ │ │ │ │ ├── logical_op.hpp │ │ │ │ │ │ │ ├── msvc_dtw.hpp │ │ │ │ │ │ │ ├── msvc_eti_base.hpp │ │ │ │ │ │ │ ├── msvc_is_class.hpp │ │ │ │ │ │ │ ├── msvc_never_true.hpp │ │ │ │ │ │ │ ├── msvc_type.hpp │ │ │ │ │ │ │ ├── na.hpp │ │ │ │ │ │ │ ├── na_assert.hpp │ │ │ │ │ │ │ ├── na_fwd.hpp │ │ │ │ │ │ │ ├── na_spec.hpp │ │ │ │ │ │ │ ├── nested_type_wknd.hpp │ │ │ │ │ │ │ ├── nttp_decl.hpp │ │ │ │ │ │ │ ├── overload_names.hpp │ │ │ │ │ │ │ ├── preprocessed/ │ │ │ │ │ │ │ │ ├── bcc/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── bcc551/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── bcc_pre590/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── dmc/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── gcc/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── msvc60/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── msvc70/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── mwcw/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── no_ctps/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ ├── no_ttp/ │ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ │ └── plain/ │ │ │ │ │ │ │ │ ├── advance_backward.hpp │ │ │ │ │ │ │ │ ├── advance_forward.hpp │ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ │ ├── apply.hpp │ │ │ │ │ │ │ │ ├── apply_fwd.hpp │ │ │ │ │ │ │ │ ├── apply_wrap.hpp │ │ │ │ │ │ │ │ ├── arg.hpp │ │ │ │ │ │ │ │ ├── basic_bind.hpp │ │ │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ │ ├── bitor.hpp │ │ │ │ │ │ │ │ ├── bitxor.hpp │ │ │ │ │ │ │ │ ├── deque.hpp │ │ │ │ │ │ │ │ ├── divides.hpp │ │ │ │ │ │ │ │ ├── equal_to.hpp │ │ │ │ │ │ │ │ ├── fold_impl.hpp │ │ │ │ │ │ │ │ ├── full_lambda.hpp │ │ │ │ │ │ │ │ ├── greater.hpp │ │ │ │ │ │ │ │ ├── greater_equal.hpp │ │ │ │ │ │ │ │ ├── inherit.hpp │ │ │ │ │ │ │ │ ├── iter_fold_if_impl.hpp │ │ │ │ │ │ │ │ ├── iter_fold_impl.hpp │ │ │ │ │ │ │ │ ├── lambda_no_ctps.hpp │ │ │ │ │ │ │ │ ├── less.hpp │ │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ │ ├── list_c.hpp │ │ │ │ │ │ │ │ ├── map.hpp │ │ │ │ │ │ │ │ ├── minus.hpp │ │ │ │ │ │ │ │ ├── modulus.hpp │ │ │ │ │ │ │ │ ├── not_equal_to.hpp │ │ │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ │ │ ├── plus.hpp │ │ │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ │ ├── reverse_iter_fold_impl.hpp │ │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ │ ├── set_c.hpp │ │ │ │ │ │ │ │ ├── shift_left.hpp │ │ │ │ │ │ │ │ ├── shift_right.hpp │ │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ │ ├── times.hpp │ │ │ │ │ │ │ │ ├── unpack_args.hpp │ │ │ │ │ │ │ │ ├── vector.hpp │ │ │ │ │ │ │ │ └── vector_c.hpp │ │ │ │ │ │ │ ├── preprocessor/ │ │ │ │ │ │ │ │ ├── add.hpp │ │ │ │ │ │ │ │ ├── def_params_tail.hpp │ │ │ │ │ │ │ │ ├── default_params.hpp │ │ │ │ │ │ │ │ ├── enum.hpp │ │ │ │ │ │ │ │ ├── ext_params.hpp │ │ │ │ │ │ │ │ ├── filter_params.hpp │ │ │ │ │ │ │ │ ├── params.hpp │ │ │ │ │ │ │ │ ├── partial_spec_params.hpp │ │ │ │ │ │ │ │ ├── range.hpp │ │ │ │ │ │ │ │ ├── repeat.hpp │ │ │ │ │ │ │ │ ├── sub.hpp │ │ │ │ │ │ │ │ └── tuple.hpp │ │ │ │ │ │ │ ├── ptr_to_ref.hpp │ │ │ │ │ │ │ ├── push_front_impl.hpp │ │ │ │ │ │ │ ├── reverse_fold_impl.hpp │ │ │ │ │ │ │ ├── reverse_fold_impl_body.hpp │ │ │ │ │ │ │ ├── sequence_wrapper.hpp │ │ │ │ │ │ │ ├── static_cast.hpp │ │ │ │ │ │ │ ├── template_arity.hpp │ │ │ │ │ │ │ ├── template_arity_fwd.hpp │ │ │ │ │ │ │ ├── traits_lambda_spec.hpp │ │ │ │ │ │ │ ├── type_wrapper.hpp │ │ │ │ │ │ │ ├── value_wknd.hpp │ │ │ │ │ │ │ └── yes_no.hpp │ │ │ │ │ │ ├── base.hpp │ │ │ │ │ │ ├── begin.hpp │ │ │ │ │ │ ├── begin_end.hpp │ │ │ │ │ │ ├── begin_end_fwd.hpp │ │ │ │ │ │ ├── bind.hpp │ │ │ │ │ │ ├── bind_fwd.hpp │ │ │ │ │ │ ├── bool.hpp │ │ │ │ │ │ ├── bool_fwd.hpp │ │ │ │ │ │ ├── clear.hpp │ │ │ │ │ │ ├── clear_fwd.hpp │ │ │ │ │ │ ├── deref.hpp │ │ │ │ │ │ ├── empty_fwd.hpp │ │ │ │ │ │ ├── end.hpp │ │ │ │ │ │ ├── erase_fwd.hpp │ │ │ │ │ │ ├── erase_key_fwd.hpp │ │ │ │ │ │ ├── eval_if.hpp │ │ │ │ │ │ ├── find.hpp │ │ │ │ │ │ ├── find_if.hpp │ │ │ │ │ │ ├── fold.hpp │ │ │ │ │ │ ├── front_fwd.hpp │ │ │ │ │ │ ├── has_key.hpp │ │ │ │ │ │ ├── has_key_fwd.hpp │ │ │ │ │ │ ├── has_xxx.hpp │ │ │ │ │ │ ├── identity.hpp │ │ │ │ │ │ ├── if.hpp │ │ │ │ │ │ ├── insert.hpp │ │ │ │ │ │ ├── insert_fwd.hpp │ │ │ │ │ │ ├── insert_range_fwd.hpp │ │ │ │ │ │ ├── int.hpp │ │ │ │ │ │ ├── int_fwd.hpp │ │ │ │ │ │ ├── integral_c.hpp │ │ │ │ │ │ ├── integral_c_fwd.hpp │ │ │ │ │ │ ├── integral_c_tag.hpp │ │ │ │ │ │ ├── is_placeholder.hpp │ │ │ │ │ │ ├── iter_fold_if.hpp │ │ │ │ │ │ ├── iterator_range.hpp │ │ │ │ │ │ ├── iterator_tags.hpp │ │ │ │ │ │ ├── key_type_fwd.hpp │ │ │ │ │ │ ├── lambda.hpp │ │ │ │ │ │ ├── lambda_fwd.hpp │ │ │ │ │ │ ├── limits/ │ │ │ │ │ │ │ ├── arity.hpp │ │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ │ └── unrolling.hpp │ │ │ │ │ │ ├── list/ │ │ │ │ │ │ │ ├── aux_/ │ │ │ │ │ │ │ │ ├── O1_size.hpp │ │ │ │ │ │ │ │ ├── begin_end.hpp │ │ │ │ │ │ │ │ ├── clear.hpp │ │ │ │ │ │ │ │ ├── empty.hpp │ │ │ │ │ │ │ │ ├── front.hpp │ │ │ │ │ │ │ │ ├── include_preprocessed.hpp │ │ │ │ │ │ │ │ ├── item.hpp │ │ │ │ │ │ │ │ ├── iterator.hpp │ │ │ │ │ │ │ │ ├── numbered.hpp │ │ │ │ │ │ │ │ ├── numbered_c.hpp │ │ │ │ │ │ │ │ ├── pop_front.hpp │ │ │ │ │ │ │ │ ├── preprocessed/ │ │ │ │ │ │ │ │ │ └── plain/ │ │ │ │ │ │ │ │ │ ├── list10.hpp │ │ │ │ │ │ │ │ │ ├── list10_c.hpp │ │ │ │ │ │ │ │ │ ├── list20.hpp │ │ │ │ │ │ │ │ │ ├── list20_c.hpp │ │ │ │ │ │ │ │ │ ├── list30.hpp │ │ │ │ │ │ │ │ │ ├── list30_c.hpp │ │ │ │ │ │ │ │ │ ├── list40.hpp │ │ │ │ │ │ │ │ │ ├── list40_c.hpp │ │ │ │ │ │ │ │ │ ├── list50.hpp │ │ │ │ │ │ │ │ │ └── list50_c.hpp │ │ │ │ │ │ │ │ ├── push_back.hpp │ │ │ │ │ │ │ │ ├── push_front.hpp │ │ │ │ │ │ │ │ ├── size.hpp │ │ │ │ │ │ │ │ └── tag.hpp │ │ │ │ │ │ │ ├── list0.hpp │ │ │ │ │ │ │ ├── list0_c.hpp │ │ │ │ │ │ │ ├── list10.hpp │ │ │ │ │ │ │ ├── list10_c.hpp │ │ │ │ │ │ │ ├── list20.hpp │ │ │ │ │ │ │ ├── list20_c.hpp │ │ │ │ │ │ │ ├── list30.hpp │ │ │ │ │ │ │ ├── list30_c.hpp │ │ │ │ │ │ │ ├── list40.hpp │ │ │ │ │ │ │ ├── list40_c.hpp │ │ │ │ │ │ │ ├── list50.hpp │ │ │ │ │ │ │ └── list50_c.hpp │ │ │ │ │ │ ├── list.hpp │ │ │ │ │ │ ├── logical.hpp │ │ │ │ │ │ ├── long.hpp │ │ │ │ │ │ ├── long_fwd.hpp │ │ │ │ │ │ ├── next.hpp │ │ │ │ │ │ ├── next_prior.hpp │ │ │ │ │ │ ├── not.hpp │ │ │ │ │ │ ├── or.hpp │ │ │ │ │ │ ├── pair.hpp │ │ │ │ │ │ ├── placeholders.hpp │ │ │ │ │ │ ├── pop_front_fwd.hpp │ │ │ │ │ │ ├── prior.hpp │ │ │ │ │ │ ├── protect.hpp │ │ │ │ │ │ ├── push_back_fwd.hpp │ │ │ │ │ │ ├── push_front.hpp │ │ │ │ │ │ ├── push_front_fwd.hpp │ │ │ │ │ │ ├── quote.hpp │ │ │ │ │ │ ├── reverse_fold.hpp │ │ │ │ │ │ ├── same_as.hpp │ │ │ │ │ │ ├── sequence_tag.hpp │ │ │ │ │ │ ├── sequence_tag_fwd.hpp │ │ │ │ │ │ ├── set/ │ │ │ │ │ │ │ ├── aux_/ │ │ │ │ │ │ │ │ ├── at_impl.hpp │ │ │ │ │ │ │ │ ├── begin_end_impl.hpp │ │ │ │ │ │ │ │ ├── clear_impl.hpp │ │ │ │ │ │ │ │ ├── empty_impl.hpp │ │ │ │ │ │ │ │ ├── erase_impl.hpp │ │ │ │ │ │ │ │ ├── erase_key_impl.hpp │ │ │ │ │ │ │ │ ├── has_key_impl.hpp │ │ │ │ │ │ │ │ ├── insert_impl.hpp │ │ │ │ │ │ │ │ ├── insert_range_impl.hpp │ │ │ │ │ │ │ │ ├── item.hpp │ │ │ │ │ │ │ │ ├── iterator.hpp │ │ │ │ │ │ │ │ ├── key_type_impl.hpp │ │ │ │ │ │ │ │ ├── set0.hpp │ │ │ │ │ │ │ │ ├── size_impl.hpp │ │ │ │ │ │ │ │ ├── tag.hpp │ │ │ │ │ │ │ │ └── value_type_impl.hpp │ │ │ │ │ │ │ └── set0.hpp │ │ │ │ │ │ ├── size_fwd.hpp │ │ │ │ │ │ ├── size_t.hpp │ │ │ │ │ │ ├── size_t_fwd.hpp │ │ │ │ │ │ ├── value_type_fwd.hpp │ │ │ │ │ │ ├── void.hpp │ │ │ │ │ │ └── void_fwd.hpp │ │ │ │ │ ├── noncopyable.hpp │ │ │ │ │ ├── parameter/ │ │ │ │ │ │ ├── aux_/ │ │ │ │ │ │ │ ├── arg_list.hpp │ │ │ │ │ │ │ ├── cast.hpp │ │ │ │ │ │ │ ├── default.hpp │ │ │ │ │ │ │ ├── is_maybe.hpp │ │ │ │ │ │ │ ├── overloads.hpp │ │ │ │ │ │ │ ├── parameter_requirements.hpp │ │ │ │ │ │ │ ├── parenthesized_type.hpp │ │ │ │ │ │ │ ├── preprocessor/ │ │ │ │ │ │ │ │ ├── flatten.hpp │ │ │ │ │ │ │ │ └── for_each.hpp │ │ │ │ │ │ │ ├── result_of0.hpp │ │ │ │ │ │ │ ├── set.hpp │ │ │ │ │ │ │ ├── tag.hpp │ │ │ │ │ │ │ ├── tagged_argument.hpp │ │ │ │ │ │ │ ├── template_keyword.hpp │ │ │ │ │ │ │ ├── unwrap_cv_reference.hpp │ │ │ │ │ │ │ ├── void.hpp │ │ │ │ │ │ │ └── yesno.hpp │ │ │ │ │ │ ├── binding.hpp │ │ │ │ │ │ ├── config.hpp │ │ │ │ │ │ ├── keyword.hpp │ │ │ │ │ │ ├── macros.hpp │ │ │ │ │ │ ├── match.hpp │ │ │ │ │ │ ├── name.hpp │ │ │ │ │ │ ├── parameters.hpp │ │ │ │ │ │ ├── preprocessor.hpp │ │ │ │ │ │ └── value_type.hpp │ │ │ │ │ ├── parameter.hpp │ │ │ │ │ ├── preprocessor/ │ │ │ │ │ │ ├── arithmetic/ │ │ │ │ │ │ │ ├── add.hpp │ │ │ │ │ │ │ ├── dec.hpp │ │ │ │ │ │ │ ├── inc.hpp │ │ │ │ │ │ │ └── sub.hpp │ │ │ │ │ │ ├── array/ │ │ │ │ │ │ │ ├── data.hpp │ │ │ │ │ │ │ ├── elem.hpp │ │ │ │ │ │ │ └── size.hpp │ │ │ │ │ │ ├── cat.hpp │ │ │ │ │ │ ├── comma_if.hpp │ │ │ │ │ │ ├── comparison/ │ │ │ │ │ │ │ ├── equal.hpp │ │ │ │ │ │ │ ├── less_equal.hpp │ │ │ │ │ │ │ └── not_equal.hpp │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ └── config.hpp │ │ │ │ │ │ ├── control/ │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ ├── dmc/ │ │ │ │ │ │ │ │ │ └── while.hpp │ │ │ │ │ │ │ │ ├── edg/ │ │ │ │ │ │ │ │ │ └── while.hpp │ │ │ │ │ │ │ │ ├── msvc/ │ │ │ │ │ │ │ │ │ └── while.hpp │ │ │ │ │ │ │ │ └── while.hpp │ │ │ │ │ │ │ ├── expr_if.hpp │ │ │ │ │ │ │ ├── expr_iif.hpp │ │ │ │ │ │ │ ├── if.hpp │ │ │ │ │ │ │ ├── iif.hpp │ │ │ │ │ │ │ └── while.hpp │ │ │ │ │ │ ├── debug/ │ │ │ │ │ │ │ └── error.hpp │ │ │ │ │ │ ├── dec.hpp │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ ├── auto_rec.hpp │ │ │ │ │ │ │ ├── check.hpp │ │ │ │ │ │ │ ├── dmc/ │ │ │ │ │ │ │ │ └── auto_rec.hpp │ │ │ │ │ │ │ ├── is_binary.hpp │ │ │ │ │ │ │ ├── is_nullary.hpp │ │ │ │ │ │ │ └── split.hpp │ │ │ │ │ │ ├── empty.hpp │ │ │ │ │ │ ├── enum.hpp │ │ │ │ │ │ ├── enum_params.hpp │ │ │ │ │ │ ├── enum_params_with_a_default.hpp │ │ │ │ │ │ ├── enum_shifted_params.hpp │ │ │ │ │ │ ├── expr_if.hpp │ │ │ │ │ │ ├── facilities/ │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ └── is_empty.hpp │ │ │ │ │ │ │ ├── empty.hpp │ │ │ │ │ │ │ ├── expand.hpp │ │ │ │ │ │ │ ├── identity.hpp │ │ │ │ │ │ │ ├── intercept.hpp │ │ │ │ │ │ │ ├── is_1.hpp │ │ │ │ │ │ │ ├── is_empty.hpp │ │ │ │ │ │ │ ├── is_empty_variadic.hpp │ │ │ │ │ │ │ └── overload.hpp │ │ │ │ │ │ ├── for.hpp │ │ │ │ │ │ ├── identity.hpp │ │ │ │ │ │ ├── inc.hpp │ │ │ │ │ │ ├── iterate.hpp │ │ │ │ │ │ ├── iteration/ │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ ├── bounds/ │ │ │ │ │ │ │ │ │ ├── lower1.hpp │ │ │ │ │ │ │ │ │ ├── lower2.hpp │ │ │ │ │ │ │ │ │ ├── lower3.hpp │ │ │ │ │ │ │ │ │ ├── lower4.hpp │ │ │ │ │ │ │ │ │ ├── lower5.hpp │ │ │ │ │ │ │ │ │ ├── upper1.hpp │ │ │ │ │ │ │ │ │ ├── upper2.hpp │ │ │ │ │ │ │ │ │ ├── upper3.hpp │ │ │ │ │ │ │ │ │ ├── upper4.hpp │ │ │ │ │ │ │ │ │ └── upper5.hpp │ │ │ │ │ │ │ │ ├── finish.hpp │ │ │ │ │ │ │ │ ├── iter/ │ │ │ │ │ │ │ │ │ ├── forward1.hpp │ │ │ │ │ │ │ │ │ ├── forward2.hpp │ │ │ │ │ │ │ │ │ ├── forward3.hpp │ │ │ │ │ │ │ │ │ ├── forward4.hpp │ │ │ │ │ │ │ │ │ ├── forward5.hpp │ │ │ │ │ │ │ │ │ ├── reverse1.hpp │ │ │ │ │ │ │ │ │ ├── reverse2.hpp │ │ │ │ │ │ │ │ │ ├── reverse3.hpp │ │ │ │ │ │ │ │ │ ├── reverse4.hpp │ │ │ │ │ │ │ │ │ └── reverse5.hpp │ │ │ │ │ │ │ │ ├── local.hpp │ │ │ │ │ │ │ │ ├── rlocal.hpp │ │ │ │ │ │ │ │ ├── self.hpp │ │ │ │ │ │ │ │ └── start.hpp │ │ │ │ │ │ │ ├── iterate.hpp │ │ │ │ │ │ │ ├── local.hpp │ │ │ │ │ │ │ └── self.hpp │ │ │ │ │ │ ├── list/ │ │ │ │ │ │ │ ├── adt.hpp │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ ├── dmc/ │ │ │ │ │ │ │ │ │ └── fold_left.hpp │ │ │ │ │ │ │ │ ├── edg/ │ │ │ │ │ │ │ │ │ ├── fold_left.hpp │ │ │ │ │ │ │ │ │ └── fold_right.hpp │ │ │ │ │ │ │ │ ├── fold_left.hpp │ │ │ │ │ │ │ │ └── fold_right.hpp │ │ │ │ │ │ │ ├── fold_left.hpp │ │ │ │ │ │ │ ├── fold_right.hpp │ │ │ │ │ │ │ ├── for_each_i.hpp │ │ │ │ │ │ │ └── reverse.hpp │ │ │ │ │ │ ├── logical/ │ │ │ │ │ │ │ ├── and.hpp │ │ │ │ │ │ │ ├── bitand.hpp │ │ │ │ │ │ │ ├── bool.hpp │ │ │ │ │ │ │ ├── compl.hpp │ │ │ │ │ │ │ └── not.hpp │ │ │ │ │ │ ├── punctuation/ │ │ │ │ │ │ │ ├── comma.hpp │ │ │ │ │ │ │ ├── comma_if.hpp │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ └── is_begin_parens.hpp │ │ │ │ │ │ │ └── is_begin_parens.hpp │ │ │ │ │ │ ├── repeat.hpp │ │ │ │ │ │ ├── repetition/ │ │ │ │ │ │ │ ├── deduce_r.hpp │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ ├── dmc/ │ │ │ │ │ │ │ │ │ └── for.hpp │ │ │ │ │ │ │ │ ├── edg/ │ │ │ │ │ │ │ │ │ └── for.hpp │ │ │ │ │ │ │ │ ├── for.hpp │ │ │ │ │ │ │ │ └── msvc/ │ │ │ │ │ │ │ │ └── for.hpp │ │ │ │ │ │ │ ├── enum.hpp │ │ │ │ │ │ │ ├── enum_binary_params.hpp │ │ │ │ │ │ │ ├── enum_params.hpp │ │ │ │ │ │ │ ├── enum_params_with_a_default.hpp │ │ │ │ │ │ │ ├── enum_shifted.hpp │ │ │ │ │ │ │ ├── enum_shifted_params.hpp │ │ │ │ │ │ │ ├── enum_trailing.hpp │ │ │ │ │ │ │ ├── enum_trailing_params.hpp │ │ │ │ │ │ │ ├── for.hpp │ │ │ │ │ │ │ ├── repeat.hpp │ │ │ │ │ │ │ └── repeat_from_to.hpp │ │ │ │ │ │ ├── selection/ │ │ │ │ │ │ │ └── max.hpp │ │ │ │ │ │ ├── seq/ │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ ├── is_empty.hpp │ │ │ │ │ │ │ │ └── split.hpp │ │ │ │ │ │ │ ├── elem.hpp │ │ │ │ │ │ │ ├── enum.hpp │ │ │ │ │ │ │ ├── first_n.hpp │ │ │ │ │ │ │ ├── fold_left.hpp │ │ │ │ │ │ │ ├── for_each.hpp │ │ │ │ │ │ │ ├── for_each_i.hpp │ │ │ │ │ │ │ ├── for_each_product.hpp │ │ │ │ │ │ │ ├── push_back.hpp │ │ │ │ │ │ │ ├── rest_n.hpp │ │ │ │ │ │ │ ├── seq.hpp │ │ │ │ │ │ │ ├── size.hpp │ │ │ │ │ │ │ └── subseq.hpp │ │ │ │ │ │ ├── slot/ │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ ├── counter.hpp │ │ │ │ │ │ │ │ ├── def.hpp │ │ │ │ │ │ │ │ ├── shared.hpp │ │ │ │ │ │ │ │ ├── slot1.hpp │ │ │ │ │ │ │ │ ├── slot2.hpp │ │ │ │ │ │ │ │ ├── slot3.hpp │ │ │ │ │ │ │ │ ├── slot4.hpp │ │ │ │ │ │ │ │ └── slot5.hpp │ │ │ │ │ │ │ └── slot.hpp │ │ │ │ │ │ ├── stringize.hpp │ │ │ │ │ │ ├── tuple/ │ │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ │ └── is_single_return.hpp │ │ │ │ │ │ │ ├── eat.hpp │ │ │ │ │ │ │ ├── elem.hpp │ │ │ │ │ │ │ ├── rem.hpp │ │ │ │ │ │ │ ├── size.hpp │ │ │ │ │ │ │ └── to_list.hpp │ │ │ │ │ │ └── variadic/ │ │ │ │ │ │ ├── elem.hpp │ │ │ │ │ │ └── size.hpp │ │ │ │ │ ├── static_assert.hpp │ │ │ │ │ ├── swap.hpp │ │ │ │ │ ├── throw_exception.hpp │ │ │ │ │ ├── type_traits/ │ │ │ │ │ │ ├── add_const.hpp │ │ │ │ │ │ ├── add_lvalue_reference.hpp │ │ │ │ │ │ ├── add_reference.hpp │ │ │ │ │ │ ├── add_rvalue_reference.hpp │ │ │ │ │ │ ├── add_volatile.hpp │ │ │ │ │ │ ├── conditional.hpp │ │ │ │ │ │ ├── declval.hpp │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ ├── config.hpp │ │ │ │ │ │ │ ├── is_function_ptr_helper.hpp │ │ │ │ │ │ │ ├── is_function_ptr_tester.hpp │ │ │ │ │ │ │ ├── is_mem_fun_pointer_impl.hpp │ │ │ │ │ │ │ ├── is_mem_fun_pointer_tester.hpp │ │ │ │ │ │ │ └── yes_no_type.hpp │ │ │ │ │ │ ├── has_trivial_assign.hpp │ │ │ │ │ │ ├── has_trivial_destructor.hpp │ │ │ │ │ │ ├── integral_constant.hpp │ │ │ │ │ │ ├── intrinsics.hpp │ │ │ │ │ │ ├── is_abstract.hpp │ │ │ │ │ │ ├── is_arithmetic.hpp │ │ │ │ │ │ ├── is_array.hpp │ │ │ │ │ │ ├── is_assignable.hpp │ │ │ │ │ │ ├── is_base_and_derived.hpp │ │ │ │ │ │ ├── is_class.hpp │ │ │ │ │ │ ├── is_const.hpp │ │ │ │ │ │ ├── is_convertible.hpp │ │ │ │ │ │ ├── is_destructible.hpp │ │ │ │ │ │ ├── is_enum.hpp │ │ │ │ │ │ ├── is_floating_point.hpp │ │ │ │ │ │ ├── is_function.hpp │ │ │ │ │ │ ├── is_integral.hpp │ │ │ │ │ │ ├── is_lvalue_reference.hpp │ │ │ │ │ │ ├── is_member_function_pointer.hpp │ │ │ │ │ │ ├── is_member_pointer.hpp │ │ │ │ │ │ ├── is_pod.hpp │ │ │ │ │ │ ├── is_pointer.hpp │ │ │ │ │ │ ├── is_polymorphic.hpp │ │ │ │ │ │ ├── is_reference.hpp │ │ │ │ │ │ ├── is_rvalue_reference.hpp │ │ │ │ │ │ ├── is_same.hpp │ │ │ │ │ │ ├── is_scalar.hpp │ │ │ │ │ │ ├── is_signed.hpp │ │ │ │ │ │ ├── is_union.hpp │ │ │ │ │ │ ├── is_unsigned.hpp │ │ │ │ │ │ ├── is_void.hpp │ │ │ │ │ │ ├── is_volatile.hpp │ │ │ │ │ │ ├── make_signed.hpp │ │ │ │ │ │ ├── remove_const.hpp │ │ │ │ │ │ ├── remove_cv.hpp │ │ │ │ │ │ └── remove_reference.hpp │ │ │ │ │ ├── utility/ │ │ │ │ │ │ ├── declval.hpp │ │ │ │ │ │ ├── detail/ │ │ │ │ │ │ │ └── result_of_iterate.hpp │ │ │ │ │ │ ├── enable_if.hpp │ │ │ │ │ │ └── result_of.hpp │ │ │ │ │ └── version.hpp │ │ │ │ ├── boostqueue.h │ │ │ │ ├── cpuid.cpp │ │ │ │ ├── cpuid.h │ │ │ │ ├── extract_graph_data.py │ │ │ │ ├── lockbasedqueue.h │ │ │ │ ├── simplelockfree.h │ │ │ │ ├── stdqueue.h │ │ │ │ ├── tbb/ │ │ │ │ │ ├── COPYING │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── aggregator.h │ │ │ │ │ ├── aligned_space.h │ │ │ │ │ ├── arena.cpp │ │ │ │ │ ├── arena.h │ │ │ │ │ ├── atomic.h │ │ │ │ │ ├── blocked_range.h │ │ │ │ │ ├── blocked_range2d.h │ │ │ │ │ ├── blocked_range3d.h │ │ │ │ │ ├── cache_aligned_allocator.cpp │ │ │ │ │ ├── cache_aligned_allocator.h │ │ │ │ │ ├── cilk-tbb-interop.h │ │ │ │ │ ├── combinable.h │ │ │ │ │ ├── compat/ │ │ │ │ │ │ ├── condition_variable │ │ │ │ │ │ ├── ppl.h │ │ │ │ │ │ ├── thread │ │ │ │ │ │ └── tuple │ │ │ │ │ ├── concurrent_hash_map.cpp │ │ │ │ │ ├── concurrent_hash_map.h │ │ │ │ │ ├── concurrent_lru_cache.h │ │ │ │ │ ├── concurrent_monitor.cpp │ │ │ │ │ ├── concurrent_monitor.h │ │ │ │ │ ├── concurrent_priority_queue.h │ │ │ │ │ ├── concurrent_queue.cpp │ │ │ │ │ ├── concurrent_queue.h │ │ │ │ │ ├── concurrent_unordered_map.h │ │ │ │ │ ├── concurrent_unordered_set.h │ │ │ │ │ ├── concurrent_vector.cpp │ │ │ │ │ ├── concurrent_vector.h │ │ │ │ │ ├── condition_variable.cpp │ │ │ │ │ ├── critical_section.cpp │ │ │ │ │ ├── critical_section.h │ │ │ │ │ ├── custom_scheduler.h │ │ │ │ │ ├── dynamic_link.cpp │ │ │ │ │ ├── dynamic_link.h │ │ │ │ │ ├── enumerable_thread_specific.h │ │ │ │ │ ├── flow_graph.h │ │ │ │ │ ├── governor.cpp │ │ │ │ │ ├── governor.h │ │ │ │ │ ├── ia32-masm/ │ │ │ │ │ │ ├── atomic_support.asm │ │ │ │ │ │ ├── itsx.asm │ │ │ │ │ │ └── lock_byte.asm │ │ │ │ │ ├── ia64-gas/ │ │ │ │ │ │ ├── atomic_support.s │ │ │ │ │ │ ├── ia64_misc.s │ │ │ │ │ │ ├── lock_byte.s │ │ │ │ │ │ ├── log2.s │ │ │ │ │ │ └── pause.s │ │ │ │ │ ├── ibm_aix51/ │ │ │ │ │ │ └── atomic_support.c │ │ │ │ │ ├── intel64-masm/ │ │ │ │ │ │ ├── atomic_support.asm │ │ │ │ │ │ ├── intel64_misc.asm │ │ │ │ │ │ └── itsx.asm │ │ │ │ │ ├── internal/ │ │ │ │ │ │ ├── _aggregator_impl.h │ │ │ │ │ │ ├── _concurrent_queue_impl.h │ │ │ │ │ │ ├── _concurrent_unordered_impl.h │ │ │ │ │ │ ├── _flow_graph_impl.h │ │ │ │ │ │ ├── _flow_graph_indexer_impl.h │ │ │ │ │ │ ├── _flow_graph_item_buffer_impl.h │ │ │ │ │ │ ├── _flow_graph_join_impl.h │ │ │ │ │ │ ├── _flow_graph_node_impl.h │ │ │ │ │ │ ├── _flow_graph_tagged_buffer_impl.h │ │ │ │ │ │ ├── _flow_graph_trace_impl.h │ │ │ │ │ │ ├── _flow_graph_types_impl.h │ │ │ │ │ │ ├── _mutex_padding.h │ │ │ │ │ │ ├── _range_iterator.h │ │ │ │ │ │ ├── _tbb_strings.h │ │ │ │ │ │ ├── _tbb_windef.h │ │ │ │ │ │ ├── _x86_eliding_mutex_impl.h │ │ │ │ │ │ └── _x86_rtm_rw_mutex_impl.h │ │ │ │ │ ├── intrusive_list.h │ │ │ │ │ ├── itt_notify.cpp │ │ │ │ │ ├── itt_notify.h │ │ │ │ │ ├── lin32-tbb-export.def │ │ │ │ │ ├── lin32-tbb-export.lst │ │ │ │ │ ├── lin64-tbb-export.def │ │ │ │ │ ├── lin64-tbb-export.lst │ │ │ │ │ ├── lin64ipf-tbb-export.def │ │ │ │ │ ├── lin64ipf-tbb-export.lst │ │ │ │ │ ├── mac32-tbb-export.def │ │ │ │ │ ├── mac32-tbb-export.lst │ │ │ │ │ ├── mac64-tbb-export.def │ │ │ │ │ ├── mac64-tbb-export.lst │ │ │ │ │ ├── machine/ │ │ │ │ │ │ ├── gcc_armv7.h │ │ │ │ │ │ ├── gcc_generic.h │ │ │ │ │ │ ├── gcc_ia32_common.h │ │ │ │ │ │ ├── gcc_itsx.h │ │ │ │ │ │ ├── ibm_aix51.h │ │ │ │ │ │ ├── icc_generic.h │ │ │ │ │ │ ├── linux_common.h │ │ │ │ │ │ ├── linux_ia32.h │ │ │ │ │ │ ├── linux_ia64.h │ │ │ │ │ │ ├── linux_intel64.h │ │ │ │ │ │ ├── mac_ppc.h │ │ │ │ │ │ ├── macos_common.h │ │ │ │ │ │ ├── mic_common.h │ │ │ │ │ │ ├── msvc_armv7.h │ │ │ │ │ │ ├── msvc_ia32_common.h │ │ │ │ │ │ ├── sunos_sparc.h │ │ │ │ │ │ ├── windows_api.h │ │ │ │ │ │ ├── windows_ia32.h │ │ │ │ │ │ ├── windows_intel64.h │ │ │ │ │ │ └── xbox360_ppc.h │ │ │ │ │ ├── mailbox.h │ │ │ │ │ ├── market.cpp │ │ │ │ │ ├── market.h │ │ │ │ │ ├── memory_pool.h │ │ │ │ │ ├── mutex.cpp │ │ │ │ │ ├── mutex.h │ │ │ │ │ ├── null_mutex.h │ │ │ │ │ ├── null_rw_mutex.h │ │ │ │ │ ├── observer_proxy.cpp │ │ │ │ │ ├── observer_proxy.h │ │ │ │ │ ├── parallel_do.h │ │ │ │ │ ├── parallel_for.h │ │ │ │ │ ├── parallel_for_each.h │ │ │ │ │ ├── parallel_invoke.h │ │ │ │ │ ├── parallel_reduce.h │ │ │ │ │ ├── parallel_scan.h │ │ │ │ │ ├── parallel_sort.h │ │ │ │ │ ├── parallel_while.h │ │ │ │ │ ├── partitioner.h │ │ │ │ │ ├── pipeline.cpp │ │ │ │ │ ├── pipeline.h │ │ │ │ │ ├── private_server.cpp │ │ │ │ │ ├── queuing_mutex.cpp │ │ │ │ │ ├── queuing_mutex.h │ │ │ │ │ ├── queuing_rw_mutex.cpp │ │ │ │ │ ├── queuing_rw_mutex.h │ │ │ │ │ ├── reader_writer_lock.cpp │ │ │ │ │ ├── reader_writer_lock.h │ │ │ │ │ ├── recursive_mutex.cpp │ │ │ │ │ ├── recursive_mutex.h │ │ │ │ │ ├── runtime_loader.h │ │ │ │ │ ├── scalable_allocator.h │ │ │ │ │ ├── scheduler.cpp │ │ │ │ │ ├── scheduler.h │ │ │ │ │ ├── scheduler_common.h │ │ │ │ │ ├── scheduler_utility.h │ │ │ │ │ ├── semaphore.cpp │ │ │ │ │ ├── semaphore.h │ │ │ │ │ ├── spin_mutex.cpp │ │ │ │ │ ├── spin_mutex.h │ │ │ │ │ ├── spin_rw_mutex.cpp │ │ │ │ │ ├── spin_rw_mutex.h │ │ │ │ │ ├── task.cpp │ │ │ │ │ ├── task.h │ │ │ │ │ ├── task_arena.h │ │ │ │ │ ├── task_group.h │ │ │ │ │ ├── task_group_context.cpp │ │ │ │ │ ├── task_scheduler_init.h │ │ │ │ │ ├── task_scheduler_observer.h │ │ │ │ │ ├── task_stream.h │ │ │ │ │ ├── tbb.h │ │ │ │ │ ├── tbb_allocator.h │ │ │ │ │ ├── tbb_assert_impl.h │ │ │ │ │ ├── tbb_config.h │ │ │ │ │ ├── tbb_exception.h │ │ │ │ │ ├── tbb_machine.h │ │ │ │ │ ├── tbb_main.cpp │ │ │ │ │ ├── tbb_main.h │ │ │ │ │ ├── tbb_misc.cpp │ │ │ │ │ ├── tbb_misc.h │ │ │ │ │ ├── tbb_misc_ex.cpp │ │ │ │ │ ├── tbb_profiling.h │ │ │ │ │ ├── tbb_resource.rc │ │ │ │ │ ├── tbb_statistics.cpp │ │ │ │ │ ├── tbb_statistics.h │ │ │ │ │ ├── tbb_stddef.h │ │ │ │ │ ├── tbb_thread.cpp │ │ │ │ │ ├── tbb_thread.h │ │ │ │ │ ├── tbb_version.h │ │ │ │ │ ├── tbbmalloc_proxy.h │ │ │ │ │ ├── tick_count.h │ │ │ │ │ ├── tls.h │ │ │ │ │ ├── tools_api/ │ │ │ │ │ │ ├── disable_warnings.h │ │ │ │ │ │ ├── internal/ │ │ │ │ │ │ │ └── ittnotify.h │ │ │ │ │ │ ├── ittnotify.h │ │ │ │ │ │ ├── ittnotify_config.h │ │ │ │ │ │ ├── ittnotify_static.c │ │ │ │ │ │ ├── ittnotify_static.h │ │ │ │ │ │ ├── ittnotify_types.h │ │ │ │ │ │ ├── legacy/ │ │ │ │ │ │ │ └── ittnotify.h │ │ │ │ │ │ └── prototype/ │ │ │ │ │ │ └── ittnotify.h │ │ │ │ │ ├── version_string.ver │ │ │ │ │ ├── win32-tbb-export.def │ │ │ │ │ ├── win32-tbb-export.lst │ │ │ │ │ ├── win64-gcc-tbb-export.def │ │ │ │ │ ├── win64-gcc-tbb-export.lst │ │ │ │ │ ├── win64-tbb-export.def │ │ │ │ │ ├── win64-tbb-export.lst │ │ │ │ │ ├── winrt-tbb-export.lst │ │ │ │ │ ├── x86_rtm_rw_mutex.cpp │ │ │ │ │ └── xbox360-tbb-export.def │ │ │ │ ├── tbbqueue.h │ │ │ │ └── wrappers.h │ │ │ ├── blockingconcurrentqueue.h │ │ │ ├── concurrentqueue.h │ │ │ ├── internal/ │ │ │ │ └── concurrentqueue_internal_debug.h │ │ │ ├── samples.md │ │ │ └── tests/ │ │ │ ├── CDSChecker/ │ │ │ │ ├── README.txt │ │ │ │ ├── corealgo.h │ │ │ │ ├── enqueue_dequeue_many.cpp │ │ │ │ └── enqueue_dequeue_one.cpp │ │ │ ├── common/ │ │ │ │ ├── simplethread.cpp │ │ │ │ ├── simplethread.h │ │ │ │ ├── systemtime.cpp │ │ │ │ └── systemtime.h │ │ │ ├── corealgos.h │ │ │ ├── fuzztests/ │ │ │ │ └── fuzztests.cpp │ │ │ ├── relacy/ │ │ │ │ ├── freelist.cpp │ │ │ │ ├── integrated.cpp │ │ │ │ ├── relacy/ │ │ │ │ │ ├── CHANGES │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── VERSION │ │ │ │ │ ├── example/ │ │ │ │ │ │ ├── cli_ws_deque/ │ │ │ │ │ │ │ ├── cli_ws_deque.cpp │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── cli_ws_deque.sln │ │ │ │ │ │ │ │ └── cli_ws_deque.vcproj │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── condvar/ │ │ │ │ │ │ │ ├── condvar.cpp │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── condvar.sln │ │ │ │ │ │ │ │ └── condvar.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── condvar.sln │ │ │ │ │ │ │ │ └── condvar.vcproj │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── eao_blocking/ │ │ │ │ │ │ │ └── eao_blocking.cpp │ │ │ │ │ │ ├── eventcount/ │ │ │ │ │ │ │ ├── eventcount.cpp │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── eventcount.sln │ │ │ │ │ │ │ │ └── eventcount.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── eventcount.sln │ │ │ │ │ │ │ │ └── eventcount.vcproj │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── examples/ │ │ │ │ │ │ │ ├── amp_condvar.hpp │ │ │ │ │ │ │ ├── examples.cpp │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── examples.sln │ │ │ │ │ │ │ │ └── examples.vcproj │ │ │ │ │ │ │ ├── spsc_overwrite_queue.hpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── java_ws_deque/ │ │ │ │ │ │ │ ├── java_ws_deque.cpp │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── java_ws_deque.sln │ │ │ │ │ │ │ │ └── java_ws_deque.vcproj │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── mpmc/ │ │ │ │ │ │ │ ├── mpmc.cpp │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── mpmc.sln │ │ │ │ │ │ │ │ └── mpmc.vcproj │ │ │ │ │ │ │ ├── pcx.h │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── mutex_business_logic/ │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── mutex_business_logic.sln │ │ │ │ │ │ │ │ └── mutex_business_logic.vcproj │ │ │ │ │ │ │ ├── mutex_business_logic.cpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── peterson/ │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── peterson.sln │ │ │ │ │ │ │ │ └── peterson.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── peterson.sln │ │ │ │ │ │ │ │ └── peterson.vcproj │ │ │ │ │ │ │ ├── peterson.cpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── proxy_collector/ │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── proxy_collector.sln │ │ │ │ │ │ │ │ └── proxy_collector.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── proxy_collector.sln │ │ │ │ │ │ │ │ └── proxy_collector.vcproj │ │ │ │ │ │ │ ├── proxy_collector.cpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── ref_counting/ │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── ref_counting.sln │ │ │ │ │ │ │ │ └── ref_counting.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── ref_counting.sln │ │ │ │ │ │ │ │ └── ref_counting.vcproj │ │ │ │ │ │ │ ├── ref_counting.cpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── smr/ │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── smr.sln │ │ │ │ │ │ │ │ └── smr.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── smr.sln │ │ │ │ │ │ │ │ └── smr.vcproj │ │ │ │ │ │ │ ├── smr.cpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── spsc_queue/ │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── spsc_queue.sln │ │ │ │ │ │ │ │ └── spsc_queue.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── spsc_queue.sln │ │ │ │ │ │ │ │ └── spsc_queue.vcproj │ │ │ │ │ │ │ ├── spsc_queue.cpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── stack/ │ │ │ │ │ │ │ ├── DESCRIPTION.TXT │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── stack.sln │ │ │ │ │ │ │ │ └── stack.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── stack.sln │ │ │ │ │ │ │ │ └── stack.vcproj │ │ │ │ │ │ │ ├── stack.cpp │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── tbb_eventcount/ │ │ │ │ │ │ │ ├── eventcount.cpp │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── eventcount.sln │ │ │ │ │ │ │ │ └── eventcount.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── eventcount.sln │ │ │ │ │ │ │ │ └── eventcount.vcproj │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ │ ├── ws_deque/ │ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ │ ├── ws_deque.sln │ │ │ │ │ │ │ │ └── ws_deque.vcproj │ │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ │ ├── ws_deque.sln │ │ │ │ │ │ │ │ └── ws_deque.vcproj │ │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ │ ├── stdafx.h │ │ │ │ │ │ │ └── ws_deque.cpp │ │ │ │ │ │ └── ws_deque2/ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ ├── ws_deque.sln │ │ │ │ │ │ │ └── ws_deque.vcproj │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ ├── stdafx.h │ │ │ │ │ │ └── ws_deque.cpp │ │ │ │ │ ├── relacy/ │ │ │ │ │ │ ├── atomic.hpp │ │ │ │ │ │ ├── atomic_events.hpp │ │ │ │ │ │ ├── atomic_fence.hpp │ │ │ │ │ │ ├── backoff.hpp │ │ │ │ │ │ ├── base.hpp │ │ │ │ │ │ ├── cli.hpp │ │ │ │ │ │ ├── cli_interlocked.hpp │ │ │ │ │ │ ├── cli_var.hpp │ │ │ │ │ │ ├── cli_volatile.hpp │ │ │ │ │ │ ├── context.hpp │ │ │ │ │ │ ├── context_addr_hash.hpp │ │ │ │ │ │ ├── context_base.hpp │ │ │ │ │ │ ├── context_base_impl.hpp │ │ │ │ │ │ ├── context_bound_scheduler.hpp │ │ │ │ │ │ ├── defs.hpp │ │ │ │ │ │ ├── dyn_thread.hpp │ │ │ │ │ │ ├── dyn_thread_ctx.hpp │ │ │ │ │ │ ├── foreach.hpp │ │ │ │ │ │ ├── full_search_scheduler.hpp │ │ │ │ │ │ ├── history.hpp │ │ │ │ │ │ ├── java.hpp │ │ │ │ │ │ ├── java_atomic.hpp │ │ │ │ │ │ ├── java_var.hpp │ │ │ │ │ │ ├── java_volatile.hpp │ │ │ │ │ │ ├── memory.hpp │ │ │ │ │ │ ├── memory_order.hpp │ │ │ │ │ │ ├── pch.hpp │ │ │ │ │ │ ├── platform.hpp │ │ │ │ │ │ ├── pthread.h │ │ │ │ │ │ ├── random.hpp │ │ │ │ │ │ ├── random_scheduler.hpp │ │ │ │ │ │ ├── relacy.hpp │ │ │ │ │ │ ├── relacy_cli.hpp │ │ │ │ │ │ ├── relacy_java.hpp │ │ │ │ │ │ ├── relacy_std.hpp │ │ │ │ │ │ ├── rmw.hpp │ │ │ │ │ │ ├── scheduler.hpp │ │ │ │ │ │ ├── signature.hpp │ │ │ │ │ │ ├── slab_allocator.hpp │ │ │ │ │ │ ├── stdlib/ │ │ │ │ │ │ │ ├── condition_variable.hpp │ │ │ │ │ │ │ ├── event.hpp │ │ │ │ │ │ │ ├── mutex.hpp │ │ │ │ │ │ │ ├── pthread.hpp │ │ │ │ │ │ │ ├── semaphore.hpp │ │ │ │ │ │ │ └── windows.hpp │ │ │ │ │ │ ├── sync_var.hpp │ │ │ │ │ │ ├── test_params.hpp │ │ │ │ │ │ ├── test_result.hpp │ │ │ │ │ │ ├── test_suite.hpp │ │ │ │ │ │ ├── thread.hpp │ │ │ │ │ │ ├── thread_base.hpp │ │ │ │ │ │ ├── thread_local.hpp │ │ │ │ │ │ ├── thread_local_ctx.hpp │ │ │ │ │ │ ├── var.hpp │ │ │ │ │ │ ├── volatile.hpp │ │ │ │ │ │ ├── waitset.hpp │ │ │ │ │ │ └── windows.h │ │ │ │ │ └── test/ │ │ │ │ │ ├── addr_hash.hpp │ │ │ │ │ ├── advanced.txt │ │ │ │ │ ├── compare_swap.hpp │ │ │ │ │ ├── condvar.hpp │ │ │ │ │ ├── data_race.hpp │ │ │ │ │ ├── detection.txt │ │ │ │ │ ├── dyn_thread.hpp │ │ │ │ │ ├── event.hpp │ │ │ │ │ ├── features.txt │ │ │ │ │ ├── fence.hpp │ │ │ │ │ ├── foo.cpp │ │ │ │ │ ├── futex.hpp │ │ │ │ │ ├── g++/ │ │ │ │ │ │ ├── build_all_cygwin_debug.bat │ │ │ │ │ │ ├── build_all_debug.bat │ │ │ │ │ │ ├── build_all_release.sh │ │ │ │ │ │ ├── build_cygwin_release.cmd │ │ │ │ │ │ ├── build_debug.cmd │ │ │ │ │ │ ├── build_release.cmd │ │ │ │ │ │ └── test.cpp │ │ │ │ │ ├── jtest/ │ │ │ │ │ │ ├── jtest.cpp │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ ├── jtest.sln │ │ │ │ │ │ │ └── jtest.vcproj │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ ├── jtest.sln │ │ │ │ │ │ │ └── jtest.vcproj │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ ├── main.cpp │ │ │ │ │ ├── memory.hpp │ │ │ │ │ ├── memory_order.hpp │ │ │ │ │ ├── msvc71/ │ │ │ │ │ │ ├── test.sln │ │ │ │ │ │ └── test.vcproj │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ ├── rrd.sln │ │ │ │ │ │ ├── rrd.vcproj │ │ │ │ │ │ ├── test.sln │ │ │ │ │ │ └── test.vcproj │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ ├── rrd.sln │ │ │ │ │ │ ├── rrd.vcproj │ │ │ │ │ │ ├── test.sln │ │ │ │ │ │ └── test.vcproj │ │ │ │ │ ├── mutex.hpp │ │ │ │ │ ├── ntest/ │ │ │ │ │ │ ├── msvc8/ │ │ │ │ │ │ │ ├── ntest.sln │ │ │ │ │ │ │ └── ntest.vcproj │ │ │ │ │ │ ├── msvc9/ │ │ │ │ │ │ │ ├── ntest.sln │ │ │ │ │ │ │ └── ntest.vcproj │ │ │ │ │ │ ├── ntest.cpp │ │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ │ └── stdafx.h │ │ │ │ │ ├── pthread.hpp │ │ │ │ │ ├── scheduler.hpp │ │ │ │ │ ├── semaphore.hpp │ │ │ │ │ ├── stdafx.cpp │ │ │ │ │ ├── stdafx.h │ │ │ │ │ ├── thread_local.hpp │ │ │ │ │ ├── todo.txt │ │ │ │ │ ├── trash/ │ │ │ │ │ │ ├── original.hpp │ │ │ │ │ │ └── rtl.hpp │ │ │ │ │ ├── tutorial.txt │ │ │ │ │ ├── wfmo.hpp │ │ │ │ │ └── windows.hpp │ │ │ │ ├── relacy_shims.h │ │ │ │ └── spmchash.cpp │ │ │ └── unittests/ │ │ │ ├── mallocmacro.cpp │ │ │ ├── minitest.h │ │ │ └── unittests.cpp │ │ ├── fmt/ │ │ │ ├── .clang-format │ │ │ ├── .github/ │ │ │ │ └── pull_request_template.md │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── CMakeLists.txt │ │ │ ├── CONTRIBUTING.md │ │ │ ├── ChangeLog.rst │ │ │ ├── LICENSE.rst │ │ │ ├── README.rst │ │ │ ├── include/ │ │ │ │ └── fmt/ │ │ │ │ ├── chrono.h │ │ │ │ ├── color.h │ │ │ │ ├── core.h │ │ │ │ ├── format-inl.h │ │ │ │ ├── format.h │ │ │ │ ├── locale.h │ │ │ │ ├── ostream.h │ │ │ │ ├── posix.h │ │ │ │ ├── prepare.h │ │ │ │ ├── printf.h │ │ │ │ ├── ranges.h │ │ │ │ └── safe-duration-cast.h │ │ │ ├── src/ │ │ │ │ ├── format.cc │ │ │ │ └── posix.cc │ │ │ └── support/ │ │ │ └── cmake/ │ │ │ ├── FindSetEnv.cmake │ │ │ ├── cxx14.cmake │ │ │ ├── fmt-config.cmake.in │ │ │ └── fmt.pc.in │ │ ├── pybind11/ │ │ │ ├── .appveyor.yml │ │ │ ├── .readthedocs.yml │ │ │ ├── .travis.yml │ │ │ ├── CMakeLists.txt │ │ │ ├── CONTRIBUTING.md │ │ │ ├── ISSUE_TEMPLATE.md │ │ │ ├── LICENSE │ │ │ ├── MANIFEST.in │ │ │ ├── README.md │ │ │ ├── docs/ │ │ │ │ ├── Doxyfile │ │ │ │ ├── _static/ │ │ │ │ │ └── theme_overrides.css │ │ │ │ ├── advanced/ │ │ │ │ │ ├── cast/ │ │ │ │ │ │ ├── chrono.rst │ │ │ │ │ │ ├── custom.rst │ │ │ │ │ │ ├── eigen.rst │ │ │ │ │ │ ├── functional.rst │ │ │ │ │ │ ├── index.rst │ │ │ │ │ │ ├── overview.rst │ │ │ │ │ │ ├── stl.rst │ │ │ │ │ │ └── strings.rst │ │ │ │ │ ├── classes.rst │ │ │ │ │ ├── embedding.rst │ │ │ │ │ ├── exceptions.rst │ │ │ │ │ ├── functions.rst │ │ │ │ │ ├── misc.rst │ │ │ │ │ ├── pycpp/ │ │ │ │ │ │ ├── index.rst │ │ │ │ │ │ ├── numpy.rst │ │ │ │ │ │ ├── object.rst │ │ │ │ │ │ └── utilities.rst │ │ │ │ │ └── smart_ptrs.rst │ │ │ │ ├── basics.rst │ │ │ │ ├── benchmark.py │ │ │ │ ├── benchmark.rst │ │ │ │ ├── changelog.rst │ │ │ │ ├── classes.rst │ │ │ │ ├── compiling.rst │ │ │ │ ├── conf.py │ │ │ │ ├── faq.rst │ │ │ │ ├── index.rst │ │ │ │ ├── intro.rst │ │ │ │ ├── limitations.rst │ │ │ │ ├── reference.rst │ │ │ │ ├── release.rst │ │ │ │ ├── requirements.txt │ │ │ │ └── upgrade.rst │ │ │ ├── include/ │ │ │ │ └── pybind11/ │ │ │ │ ├── attr.h │ │ │ │ ├── buffer_info.h │ │ │ │ ├── cast.h │ │ │ │ ├── chrono.h │ │ │ │ ├── common.h │ │ │ │ ├── complex.h │ │ │ │ ├── detail/ │ │ │ │ │ ├── class.h │ │ │ │ │ ├── common.h │ │ │ │ │ ├── descr.h │ │ │ │ │ ├── init.h │ │ │ │ │ ├── internals.h │ │ │ │ │ └── typeid.h │ │ │ │ ├── eigen.h │ │ │ │ ├── embed.h │ │ │ │ ├── eval.h │ │ │ │ ├── functional.h │ │ │ │ ├── iostream.h │ │ │ │ ├── numpy.h │ │ │ │ ├── operators.h │ │ │ │ ├── options.h │ │ │ │ ├── pybind11.h │ │ │ │ ├── pytypes.h │ │ │ │ ├── stl.h │ │ │ │ └── stl_bind.h │ │ │ ├── pybind11/ │ │ │ │ ├── __init__.py │ │ │ │ ├── __main__.py │ │ │ │ └── _version.py │ │ │ ├── setup.cfg │ │ │ ├── setup.py │ │ │ ├── tests/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── conftest.py │ │ │ │ ├── constructor_stats.h │ │ │ │ ├── local_bindings.h │ │ │ │ ├── object.h │ │ │ │ ├── pybind11_cross_module_tests.cpp │ │ │ │ ├── pybind11_tests.cpp │ │ │ │ ├── pybind11_tests.h │ │ │ │ ├── pytest.ini │ │ │ │ ├── test_buffers.cpp │ │ │ │ ├── test_buffers.py │ │ │ │ ├── test_builtin_casters.cpp │ │ │ │ ├── test_builtin_casters.py │ │ │ │ ├── test_call_policies.cpp │ │ │ │ ├── test_call_policies.py │ │ │ │ ├── test_callbacks.cpp │ │ │ │ ├── test_callbacks.py │ │ │ │ ├── test_chrono.cpp │ │ │ │ ├── test_chrono.py │ │ │ │ ├── test_class.cpp │ │ │ │ ├── test_class.py │ │ │ │ ├── test_cmake_build/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── embed.cpp │ │ │ │ │ ├── installed_embed/ │ │ │ │ │ │ └── CMakeLists.txt │ │ │ │ │ ├── installed_function/ │ │ │ │ │ │ └── CMakeLists.txt │ │ │ │ │ ├── installed_target/ │ │ │ │ │ │ └── CMakeLists.txt │ │ │ │ │ ├── main.cpp │ │ │ │ │ ├── subdirectory_embed/ │ │ │ │ │ │ └── CMakeLists.txt │ │ │ │ │ ├── subdirectory_function/ │ │ │ │ │ │ └── CMakeLists.txt │ │ │ │ │ ├── subdirectory_target/ │ │ │ │ │ │ └── CMakeLists.txt │ │ │ │ │ └── test.py │ │ │ │ ├── test_constants_and_functions.cpp │ │ │ │ ├── test_constants_and_functions.py │ │ │ │ ├── test_copy_move.cpp │ │ │ │ ├── test_copy_move.py │ │ │ │ ├── test_docstring_options.cpp │ │ │ │ ├── test_docstring_options.py │ │ │ │ ├── test_eigen.cpp │ │ │ │ ├── test_eigen.py │ │ │ │ ├── test_embed/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── catch.cpp │ │ │ │ │ ├── external_module.cpp │ │ │ │ │ ├── test_interpreter.cpp │ │ │ │ │ └── test_interpreter.py │ │ │ │ ├── test_enum.cpp │ │ │ │ ├── test_enum.py │ │ │ │ ├── test_eval.cpp │ │ │ │ ├── test_eval.py │ │ │ │ ├── test_eval_call.py │ │ │ │ ├── test_exceptions.cpp │ │ │ │ ├── test_exceptions.py │ │ │ │ ├── test_factory_constructors.cpp │ │ │ │ ├── test_factory_constructors.py │ │ │ │ ├── test_gil_scoped.cpp │ │ │ │ ├── test_gil_scoped.py │ │ │ │ ├── test_iostream.cpp │ │ │ │ ├── test_iostream.py │ │ │ │ ├── test_kwargs_and_defaults.cpp │ │ │ │ ├── test_kwargs_and_defaults.py │ │ │ │ ├── test_local_bindings.cpp │ │ │ │ ├── test_local_bindings.py │ │ │ │ ├── test_methods_and_attributes.cpp │ │ │ │ ├── test_methods_and_attributes.py │ │ │ │ ├── test_modules.cpp │ │ │ │ ├── test_modules.py │ │ │ │ ├── test_multiple_inheritance.cpp │ │ │ │ ├── test_multiple_inheritance.py │ │ │ │ ├── test_numpy_array.cpp │ │ │ │ ├── test_numpy_array.py │ │ │ │ ├── test_numpy_dtypes.cpp │ │ │ │ ├── test_numpy_dtypes.py │ │ │ │ ├── test_numpy_vectorize.cpp │ │ │ │ ├── test_numpy_vectorize.py │ │ │ │ ├── test_opaque_types.cpp │ │ │ │ ├── test_opaque_types.py │ │ │ │ ├── test_operator_overloading.cpp │ │ │ │ ├── test_operator_overloading.py │ │ │ │ ├── test_pickling.cpp │ │ │ │ ├── test_pickling.py │ │ │ │ ├── test_pytypes.cpp │ │ │ │ ├── test_pytypes.py │ │ │ │ ├── test_sequences_and_iterators.cpp │ │ │ │ ├── test_sequences_and_iterators.py │ │ │ │ ├── test_smart_ptr.cpp │ │ │ │ ├── test_smart_ptr.py │ │ │ │ ├── test_stl.cpp │ │ │ │ ├── test_stl.py │ │ │ │ ├── test_stl_binders.cpp │ │ │ │ ├── test_stl_binders.py │ │ │ │ ├── test_tagbased_polymorphic.cpp │ │ │ │ ├── test_tagbased_polymorphic.py │ │ │ │ ├── test_virtual_functions.cpp │ │ │ │ └── test_virtual_functions.py │ │ │ └── tools/ │ │ │ ├── FindCatch.cmake │ │ │ ├── FindEigen3.cmake │ │ │ ├── FindPythonLibsNew.cmake │ │ │ ├── check-style.sh │ │ │ ├── libsize.py │ │ │ ├── mkdoc.py │ │ │ ├── pybind11Config.cmake.in │ │ │ └── pybind11Tools.cmake │ │ └── zstd/ │ │ └── lib/ │ │ ├── README.md │ │ ├── common/ │ │ │ ├── bitstream.h │ │ │ ├── compiler.h │ │ │ ├── cpu.h │ │ │ ├── debug.c │ │ │ ├── debug.h │ │ │ ├── entropy_common.c │ │ │ ├── error_private.c │ │ │ ├── error_private.h │ │ │ ├── fse.h │ │ │ ├── fse_decompress.c │ │ │ ├── huf.h │ │ │ ├── mem.h │ │ │ ├── pool.c │ │ │ ├── pool.h │ │ │ ├── threading.c │ │ │ ├── threading.h │ │ │ ├── xxhash.c │ │ │ ├── xxhash.h │ │ │ ├── zstd_common.c │ │ │ ├── zstd_errors.h │ │ │ └── zstd_internal.h │ │ ├── compress/ │ │ │ ├── fse_compress.c │ │ │ ├── hist.c │ │ │ ├── hist.h │ │ │ ├── huf_compress.c │ │ │ ├── zstd_compress.c │ │ │ ├── zstd_compress_internal.h │ │ │ ├── zstd_compress_literals.c │ │ │ ├── zstd_compress_literals.h │ │ │ ├── zstd_compress_sequences.c │ │ │ ├── zstd_compress_sequences.h │ │ │ ├── zstd_compress_superblock.c │ │ │ ├── zstd_compress_superblock.h │ │ │ ├── zstd_cwksp.h │ │ │ ├── zstd_double_fast.c │ │ │ ├── zstd_double_fast.h │ │ │ ├── zstd_fast.c │ │ │ ├── zstd_fast.h │ │ │ ├── zstd_lazy.c │ │ │ ├── zstd_lazy.h │ │ │ ├── zstd_ldm.c │ │ │ ├── zstd_ldm.h │ │ │ ├── zstd_opt.c │ │ │ ├── zstd_opt.h │ │ │ ├── zstdmt_compress.c │ │ │ └── zstdmt_compress.h │ │ ├── decompress/ │ │ │ ├── huf_decompress.c │ │ │ ├── zstd_ddict.c │ │ │ ├── zstd_ddict.h │ │ │ ├── zstd_decompress.c │ │ │ ├── zstd_decompress_block.c │ │ │ ├── zstd_decompress_block.h │ │ │ └── zstd_decompress_internal.h │ │ ├── deprecated/ │ │ │ ├── zbuff.h │ │ │ ├── zbuff_common.c │ │ │ ├── zbuff_compress.c │ │ │ └── zbuff_decompress.c │ │ ├── dictBuilder/ │ │ │ ├── cover.c │ │ │ ├── cover.h │ │ │ ├── divsufsort.c │ │ │ ├── divsufsort.h │ │ │ ├── fastcover.c │ │ │ ├── zdict.c │ │ │ └── zdict.h │ │ ├── dll/ │ │ │ └── example/ │ │ │ ├── README.md │ │ │ ├── build_package.bat │ │ │ ├── fullbench-dll.sln │ │ │ └── fullbench-dll.vcxproj │ │ ├── legacy/ │ │ │ ├── zstd_legacy.h │ │ │ ├── zstd_v01.c │ │ │ ├── zstd_v01.h │ │ │ ├── zstd_v02.c │ │ │ ├── zstd_v02.h │ │ │ ├── zstd_v03.c │ │ │ ├── zstd_v03.h │ │ │ ├── zstd_v04.c │ │ │ ├── zstd_v04.h │ │ │ ├── zstd_v05.c │ │ │ ├── zstd_v05.h │ │ │ ├── zstd_v06.c │ │ │ ├── zstd_v06.h │ │ │ ├── zstd_v07.c │ │ │ └── zstd_v07.h │ │ ├── libzstd.pc.in │ │ └── zstd.h │ └── tube/ │ ├── CMakeLists.txt │ ├── README.md │ ├── pytube/ │ │ ├── __init__.py │ │ ├── data_channel_manager.py │ │ ├── test_dc_manager.py │ │ └── utils.py │ └── src_cpp/ │ ├── context.h │ ├── data_block.h │ ├── data_channel.cc │ ├── data_channel.h │ ├── dispatcher.h │ ├── env_thread.h │ ├── episodic_trajectory.h │ ├── fixed_len_trajectory.h │ ├── indefinite_trajectory.h │ ├── pybind.cc │ ├── test/ │ │ ├── test_data_channel.cc │ │ └── test_producer.h │ └── utils.h └── tests/ ├── CMakeLists.txt ├── README.md ├── connectfour-tests.cc ├── havannah-state-tests.cc ├── havannah-tests.cc ├── hex-state-tests.cc ├── hex-tests.cc ├── ludii-game-tests.cc ├── python/ │ └── test_replay_buffer.py ├── tests.cc └── utils.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .circleci/config.yml ================================================ # Python CircleCI 2.0 configuration file # # Check https://circleci.com/docs/2.0/language-python/ for more details # version: 2 jobs: build: branches: ignore: - dennis-tests docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` #- image: circleci/python:3.6.1 #- image: singularityware/singularity:3.1-slim # would be faster but interacts badly with cuda docker image loading - image : nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04 # machine: true working_directory: ~/repo # resource_class: xlarge # not activated for the project steps: - checkout #- run: #- name: Install singularity #- command: | #- #chmod u+x ~/repo/.circleci/*.sh #- #/bin/bash ~/repo/.circleci/install_singularity.sh #- sudo wget -O- http://neuro.debian.net/lists/xenial.us-ca.full | sudo tee /etc/apt/sources.list.d/neurodebian.sources.list && \ #- sudo apt-key adv --recv-keys --keyserver hkp://pool.sks-keyservers.net:80 0xA5D32F012649A5A9 && \ #- sudo apt-get update #- sudo apt-get install -y singularity-container - restore_cache: keys: - tag3-conda-{{ checksum "singularity/environment.yml" }}-pytorch - tag3-conda-{{ checksum "singularity/environment.yml" }} - tag1-conda - run: name: Install miniconda and clone pytorch command: | apt-get update apt-get install -y \ build-essential \ libzmq3-dev \ cmake \ wget \ vim \ git \ ca-certificates \ libjpeg-dev \ openjdk-8-jdk \ libgtest-dev \ libpng-dev rm -rf /var/lib/apt/lists/ # build gtest (for polygames-tests) cd /usr/src/googletest/googletest mkdir build cd build cmake .. make cp libgtest* /usr/lib/ cd .. rm -rf build # conda CHECKPATH=/opt/conda if [ -d "$CHECKPATH" ]; then echo "$CHECKPATH already exists" else wget -O ~/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash ~/miniconda.sh -b -p /opt/conda rm ~/miniconda.sh git clone --recursive https://github.com/pytorch/pytorch --branch=v1.1.0 ~/pytorch fi - save_cache: paths: - /opt/conda - ~/pytorch key: tag1-conda - run: name: Install conda environment command: | CHECKPATH=/opt/conda/envs/pypg . /opt/conda/etc/profile.d/conda.sh if [ -d "$CHECKPATH" ]; then echo "$CHECKPATH already exists" # conda env update -f singularity/environment.yml --name pypg else conda env create -f singularity/environment.yml --name pypg conda activate pypg pip install mypy>=0.630 pytest>=4.3.0 pytest-cov>=2.6.1 # only required for testing fi - save_cache: paths: - /opt/conda - ~/pytorch key: tag3-conda-{{ checksum "singularity/environment.yml" }} - run: name: Install pytorch command: | CHECKPATH=~/pytorch/done if [ -f "$CHECKPATH" ]; then echo "pytorch already exists" else . /opt/conda/etc/profile.d/conda.sh conda activate pypg which pip pip install -U pip cd ~/pytorch export CMAKE_PREFIX_PATH=${CONDA_PREFIX:-"$(dirname $(which conda))/../"} # export MAX_JOBS=$(cat /proc/cpuinfo | grep -c processor) # if (( $MAX_JOBS < 4 )); # then MAX_JOBS=4; # fi; export MAX_JOBS=4 # calibrate for circleci resources... echo "Using $MAX_JOBS jobs for pytorch compilation" # # set cuda arch list so that the built binary can be run on both pascal and volta MAX_JOBS=$MAX_JOBS TORCH_CUDA_ARCH_LIST='6.0;7.0' pip install . -v touch $CHECKPATH fi - save_cache: paths: - /opt/conda - ~/pytorch key: tag3-conda-{{ checksum "singularity/environment.yml" }}-pytorch - run: name: Build polygames command: | . /opt/conda/etc/profile.d/conda.sh conda activate pypg mkdir build cd build cmake .. make -j 2 - run: name: Build polygames-tests command: | . /opt/conda/etc/profile.d/conda.sh conda activate pypg mkdir ludii wget -P ludii https://ludii.games/downloads/Ludii.jar mkdir tests/build cd tests/build cmake .. make -j 2 - run: name: Test games command: | ./build/test_state - run: name: Test polygames-tests (unit tests) command: | ./tests/build/polygames-tests - run: name: Test Mcts command: | ./build/torchRL/mcts/test_mcts 1 100 ./build/torchRL/mcts/test_mcts 4 50 - run: name: Test python command: | . /opt/conda/etc/profile.d/conda.sh conda activate pypg pytest pypolygames --durations=10 --verbose - run: name: Run training command: | . /opt/conda/etc/profile.d/conda.sh conda activate pypg python -m pypolygames traineval --act_batchsize=2 \ --batchsize=2 --replay_capacity=16 --replay_warmup=2 \ --num_epoch=1 --num_game=12 --model_name=NanoFCLogitModel \ --epoch_len=1 --device=cpu --game_name=TicTacToe --sync_period=1 --device_eval=cpu \ --num_actor_eval=2 --num_rollouts_opponent=50 --num_game_eval=4 ================================================ FILE: .clang-format ================================================ AccessModifierOffset: -1 AllowShortFunctionsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false BinPackParameters: false BreakConstructorInitializersBeforeComma: true PenaltyBreakBeforeFirstCallParameter: 0 PenaltyReturnTypeOnItsOwnLine: 200 PointerBindsToType: true SpacesBeforeTrailingComments: 2 ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing to Polygames We want to make contributing to this project as easy and transparent as possible. ## Pull Requests We actively welcome your pull requests. 1. Fork the repo and create your branch from `master`. 2. If you've added code that should be tested, add tests. 3. If you've changed APIs, update the documentation. 4. Ensure the test suite passes. 5. Make sure your code lints. 6. If you haven't already, complete the Contributor License Agreement ("CLA"). ## Our Development Process Any pull request will trigger continuous integration. Its configuration is available [here](../.circleci/config.yml). In particular it defines tests that you should try to run locally as well: - testing mcts and state C++ code ```  ./build/test_state ./build/torchRL/mcts/test_mcts 1 100 ./build/torchRL/mcts/test_mcts 4 50 ``` - testing the python tools: ``` pytest pypolygames --durations=10 --verbose ``` - trying a short training: ``` python -m pypolygames traineval --act_batchsize=2 \ --batchsize=2 --replay_capacity=16 --replay_warmup=2 \ --num_epoch=1 --num_game=12 --model_name=NanoFCLogitModel \ --epoch_len=1 --device=cpu --game_name=TicTacToe --sync_period=1 --device_eval=cpu \ --num_actor_eval=2 --num_rollouts_opponent=50 --num_game_eval=4 ``` ## Contributor License Agreement ("CLA") In order to accept your pull request, we need you to submit a CLA. You only need to do this once to work on any of Facebook's open source projects. Complete your CLA here: ## Issues We use GitHub issues to track public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue. ## Coding Style The root contains a ```.clang-format``` file that define the coding style of this repo, run the following command before submitting PR or push ``` clang-format -i path_to_your_cc_files clang-format -i path_to_your_h_files ``` ## License By contributing to `Polygames`, you agree that your contributions will be licensed under the LICENSE file in the root directory of this source tree. ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ ## Steps to reproduce 1. _____ 2. _____ 3. _____ ## Observed Results * What happened? This could be a description, log output, etc. ## Expected Results * What did you expect to happen? ## Relevant Code ``` // TODO(you): code here to reproduce the problem ``` ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## Types of changes - [ ] Docs change / refactoring / dependency upgrade - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) ## Motivation and Context / Related issue ## How Has This Been Tested (if it applies) ## Checklist - [ ] The documentation is up-to-date with the changes I made. - [ ] I have read the **CONTRIBUTING** document and completed the CLA (see **CONTRIBUTING**). - [ ] All tests passed, and additional code has been covered with new tests. ================================================ FILE: .gitignore ================================================ # Created by https://www.gitignore.io/api/vim,c++,cmake,linux,macos,python,intellij,sublimetext # Edit at https://www.gitignore.io/?templates=vim,c++,cmake,linux,macos,python,intellij,sublimetext ### C++ ### # Prerequisites *.d # Compiled Object files *.slo *.lo *.o *.obj # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll # Fortran module files *.mod *.smod # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app ### CMake ### CMakeLists.txt.user CMakeCache.txt CMakeFiles CMakeScripts Testing Makefile cmake_install.cmake install_manifest.txt compile_commands.json CTestTestfile.cmake _deps ### CMake Patch ### # External projects *-prefix/ ### Intellij ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml .idea/**/usage.statistics.xml .idea/**/dictionaries .idea/**/shelf # Generated files .idea/**/contentModel.xml # Sensitive or high-churn files .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/dbnavigator.xml # Gradle .idea/**/gradle.xml .idea/**/libraries # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using # auto-import. # .idea/modules.xml # .idea/*.iml # .idea/modules # CMake cmake-build-*/ # Mongo Explorer plugin .idea/**/mongoSettings.xml # File-based project format *.iws # IntelliJ out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Cursive Clojure plugin .idea/replstate.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties # Editor-based Rest Client .idea/httpRequests # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser # JetBrains templates **___jb_tmp___ ### Intellij Patch ### # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 # *.iml # modules.xml # .idea/misc.xml # *.ipr # Sonarlint plugin .idea/sonarlint ### Linux ### *~ # temporary files which can be created if a process still has a handle open of a deleted file .fuse_hidden* # KDE directory preferences .directory # Linux trash folder which might appear on any partition or disk .Trash-* # .nfs files are created when an open file is removed but is still being accessed .nfs* ### macOS ### # General .DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don’t work, or not # install all needed dependencies. #Pipfile.lock # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ ### SublimeText ### # Cache files for Sublime Text *.tmlanguage.cache *.tmPreferences.cache *.stTheme.cache # Workspace files are user-specific *.sublime-workspace # Project files should be checked into the repository, unless a significant # proportion of contributors will probably not be using Sublime Text # *.sublime-project # SFTP configuration file sftp-config.json # Package control specific files Package Control.last-run Package Control.ca-list Package Control.ca-bundle Package Control.system-ca-bundle Package Control.cache/ Package Control.ca-certs/ Package Control.merged-ca-bundle Package Control.user-ca-bundle oscrypto-ca-bundle.crt bh_unicode_properties.cache # Sublime-github package stores a github token in this file # https://packagecontrol.io/packages/sublime-github GitHub.sublime-settings ### Vim ### # Swap [._]*.s[a-v][a-z] [._]*.sw[a-p] [._]s[a-rt-v][a-z] [._]ss[a-gi-z] [._]sw[a-p] # Session Session.vim # Temporary .netrwhist # Auto-generated tag files tags # Persistent undo [._]*.un~ # End of https://www.gitignore.io/api/vim,c++,cmake,linux,macos,python,intellij,sublimetext *.simg cmake-build-debug/ # Visual Studio Code .vscode/ # Eclipse projects /.cproject /.project .settings/ # Experiment directory exps/ # For some people testing run.sh # Ludii's JAR file ludii/Ludii.jar ================================================ FILE: CMakeLists.txt ================================================ CMAKE_MINIMUM_REQUIRED(VERSION 3.3) project(polygames) # if(NOT CMAKE_BUILD_TYPE) # set(CMAKE_BUILD_TYPE RelWithDebInfo) # endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsized-deallocation -O3 -ffast-math") set(CMAKE_POSITION_INDEPENDENT_CODE ON) OPTION(PYTORCH12 "Is PyTorch >= 1.2" OFF) OPTION(PYTORCH15 "Is PyTorch >= 1.5" OFF) IF(PYTORCH15) ADD_DEFINITIONS(-DPYTORCH15 -DPYTORCH12) ELSEIF(PYTORCH12) ADD_DEFINITIONS(-DPYTORCH12) ENDIF() execute_process( COMMAND python -c "import torch; import os; print(os.path.dirname(torch.__file__), end='')" OUTPUT_VARIABLE TorchPath ) set(CMAKE_PREFIX_PATH ${TorchPath}) find_package(Torch REQUIRED) find_package(Boost COMPONENTS system) if( Boost_FOUND ) include_directories( ${Boost_INCLUDE_DIRS}) endif() option(WITH_LUDII "Include LUDII support" ON) if(WITH_LUDII) find_package(JNI) if (JNI_FOUND) include_directories( ${JNI_INCLUDE_DIRS}) else() message(STATUS "Java not found, LUDII support will not be included") add_definitions(-DNO_JAVA) endif() else() add_definitions(-DNO_JAVA) endif() message(STATUS "Adding PyTorch compilation flags: ${TORCH_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}") add_subdirectory(src) # add Minesweeper benchmarks add_subdirectory(src/games/minesweeper_csp_vkms) # tests add_executable(test_state src/core/test_state.cc src/core/state.cc) target_link_libraries(test_state PUBLIC _tube _mcts _games ${JNI_LIBRARIES}) enable_testing() add_test(NAME test_replay_buffer COMMAND ${PYTHON_EXECUTABLE} -m test_replay_buffer WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/python) set_tests_properties(test_replay_buffer PROPERTIES ENVIRONMENT "PYTHONPATH=${PROJECT_SOURCE_DIR}:$ENV{PYTHONPATH}") ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) Facebook, Inc. and its affiliates. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ [![CircleCI](https://circleci.com/gh/facebookincubator/Polygames.svg?style=svg)](https://circleci.com/gh/facebookincubator/Polygames) # Polygames This README is a work in progress, please feel very free to post issues - we are happy to help. Save up computational power: you can find checkpoints here: http://dl.fbaipublicfiles.com/polygames/checkpoints/list.txt (feel free to open an issue for discussing which checkpoint you should use for which game/problem!). For Nix users: see [this doc](./nix/README.md). ## Requirement: ``` C++17 compatible compiler miniconda3 ``` ## Compilation Guide: ### First install conda and pytorch Create a fresh conda environment with python3.7, install pytorch and dependencies. ``` # create a fresh conda environment with python3 # you will need to have miniconda3 set up conda create --name [your env name] python=3.7 pip conda activate [your env name] # Or source activate [your env name], depending on conda version. conda install numpy pyyaml mkl mkl-include setuptools cmake cffi typing conda install pytorch cudatoolkit=10.1 -c pytorch conda install -c conda-forge tensorboardx conda install -c conda-forge openjdk # optional conda install -c conda-forge graphviz # optional pip install visdom pip install torchviz # optional ``` ### Clone the repo and build ``` git clone --recursive https://github.com/facebookincubator/polygames cd polygames mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=relwithdebinfo -DPYTORCH15=ON make -j ``` Ludii support can be disabled by appending `-DWITH_LUDII=OFF` to the cmake command (required if you don't have jdk) ## Content The repo contains mostly the following folders: - the `pypolygames` python package, which serves as an entry point for the application - the `src` folder, containing all C++ source code and third party libraries - the `src/games` folder, containing the games coded in C++ ## How to use the application The application is launched from the `pypolygames` python package, in either of the following modes:ar - `pypolygames train` (training mode): a game and a model (as well as several other options, see below) are chosen and the model is iteratively trained with MCTS - `pypolygames eval` (evaluation mode): the model confronts either a pure MCTS or another neural network powered MCTS. The evaluation of a training can be done either offline (from checkpoints periodically saved) or in real time; in that case, the evaluation considers only the most recent checkpoint in order to follow closely the training, skipping some checkpoints in case the eval computation takes longer than the time becween consecutive checkpoints. It is displayed through visdom. - `pypolygames traineval` (training + evaluation mode): it mixes the two previous modes and allow to launch one command instead of two. With the `real_time` option the modes can be launched in parallel instead of sequentially. - `pypolygames human` (human mode): a human player plays against the machine When a training is launched, it creates a `game_GAMENAME_model_MODELNAME_feat_FEATURIZATION_GMT_YYYYMMDDHHMMSS` within the `save_dir` where it will log relevant files: - `model.pt` - `train.log` - `stat.tb` - `checkpoints_EPOCH.pt` for for checkpoints saved each `saving_period` epoch (e.g., if `saving_period == 10`, `checkpoints_0.pt`, `checkpoints_10.pt`, `checkpoints_20.pt`, `checkpoints_30.pt`) This directory will be the `checkpoint_save_dir` directory used by evaluation to retrieve the checkpoints to perform eval computation. ### Parameters The list of parameters for each mode is available with ``` python -m pypolygames {train,eval,traineval,human} --help ``` #### Threads In train (resp. eval) mode, `num_game * num_actor` (resp. `num_game * num_actor_eval * num_actor_opponent`) is the total number of threads. The more `num_actor` (and `num_actor_eval`, `num_actor_opponent`), the larger the MCTS is for a given player. In human mode, since `num_game` is set to one, for leveraging the computing power available on the platform, a rule-of-thumb is to set `num_actor` to 5 times the number of CPUs available (it is platform-dependent though, and performance tests should be done). ### Model zoo All models can be found in `pypolygames/model_zoo`. They come with a set of sensible parameters that can be customized as well as default games. Usually models come in pair: `MODELNAMEFCLogitModel` and `MODELNAMEConvLogitModel`: - `FCLogit` models use a fully-connected layer for logit inference and are compatible with all games - `ConvLogit` models use a convolutional layer for logit inference and are only compatible with games whose action space if of same dimensions than their input space (an exception will be raised in case of an attempt to use an incompatible game) So far the models being implemented are the folling: - `GenericModel`: generic model compatible with all games, default when no `model_name` is specified - `NanoFCLogitModel`: a simple model with a logit-inference fully-connected layer - `NanoConvLogitModel`: a simple model with a logit-inference convolutional layer - `ResConvFCLogitModel`: resnets with a logit-inference fully-connected layer - `ResConvConvLogitModel`: resnets with a logit-inference convolutional layer - `UConvFCLogitModel`: unets (direct paths between first and last layers) with a logit-inference fully-connected layer - `UConvConvLogitModel`: unets (direct paths between first and last layers) with a logit-inference convolutional layer - `AmazonsModel`: only for the Amazons game Depending on the actual model chosen, some parameters might not have any use. ### Featurization ``` --out_features=True: the input to the NN includes a channel with 1 on the frontier. --turn_features=True: the input to the NN includes a channel with the player index broadcasted. --geometric_features=True: the input to the NN includes 4 geometric channels representing the position on the board. --random_features=4: the input to the NN includes 4 random features. --one_feature=True: the input to the NN includes a channel with 1 everywhere. --history=3: the representation from the last 3 steps is added in the featurization. ``` ### Examples Run the following command before running the code ``` export OMP_NUM_THREADS=1 ``` #### Examples for the training mode - Launch the game `Connect4` with the `GenericModel` ``` python -m pypolygames train --game_name="Connect4" ``` - Launch a game with a specific model and specific parameters ``` python -m pypolygames train --game_name="Connect4" --out_features=True \ --model_name="UConvFCLogitModel" \ --nnsize=16 \ --nnks=3 \ --pooling ``` - Save checkpoints every 20 epochs in a specific folder ``` python -m pypolygames train --game_name="Connect4" --model_name="UConvFCLogitModel" \ --saving_period=20 \ --save_dir="/checkpoints" ``` - Run training on GPU for a max time ``` python -m pypolygames train --game_name="Connect4" --model_name="UConvFCLogitModel" \ --device="cuda:0" \ --max_time=3600 ``` - Resume training from a given epoch ``` python -m pypolygames train \ --save_dir="/checkpoints/game_Connect4_model_GenericModel_feat..._GMT_20190717103728" \ --init_epoch=42 ``` - Initiate from a pretrained model ``` python -m pypolygames train --init_checkpoint="path/to/pretrained_model.pt" \ --lr=0.001 ``` Note that any checkpoint can serve as a pretrained model - Train on multiple GPUs ``` python -m pypolygames train --init_checkpoint "path/to/pretrained_model.pt" \ --device cuda:0 cuda:1 cuda:2 cuda:3 cuda:4 ``` In this case `cuda:0` will be used for training the model while `cuda:1`, `cuda:2` and `cuda:3` will be used for generating games. If there is only one device specified, it will be used for both purposes. Notes: - By default, the number of threads used for processing and batch sizes for inference are set automatically. These can be overriden with `num_thread` and `per_thread_batchsize` respectively. - `num_game` specifies the number of "master" threads scheduling games, and the total number of games being run in parallel will be `num_game * per_thread_batchsize`. Since `per_thread_batchsize` is automatically determined by default, this could be a large number in some instances. #### Examples for the evaluation mode - Run offline evaluation ``` python -m pypolygames eval \ --checkpoint_dir="/checkpoints/game_Connect4_model_GenericModel_feat..._GMT_20190717103728" ``` - Plot evaluation on `http://localhost:10000` as the same time as training happens (training needs to be run from another process) ``` python -m pypolygames eval \ --checkpoint_dir="/checkpoints/game_Connect4_model_GenericModel_feat..._GMT_20190717103728" \ --real_time \ --plot_enabled \ --plot_port=10000 ``` - Run evaluation on cpu with 100 games per evaluation, the pure-MCTS opponent playing 1000 rollouts while the model plays 400 rollouts ``` python -m pypolygames eval \ --checkpoint_dir="/checkpoints/game_Connect4_model_GenericModel_feat..._GMT_20190717103728" \ --device_eval="cpu" \ --num_game_eval=100 \ --num_rollouts_eval=400 \ --num_actor_eval=8 \ --num_rollouts_opponent=1000 \ --num_actor_opponent=8 ``` - A specific checkpoint plays against another neural-network-powered MCTS ``` python -m pypolygames eval \ --checkpoint="/checkpoints/checkpoint_600.zip" \ --num_rollouts_eval=400 \ --num_actor_eval=8 \ --checkpoint_opponent="/checkpoints/checkpoint_200.zip" \ --num_rollouts_opponent=1000 \ --num_actor_opponent=8 ``` - Four GPUs are used for evaluating the model, all for inference ``` python -m pypolygames eval \ --checkpoint="/checkpoints/checkpoint_600.zip" \ --device_eval cuda:0 cuda:1 cuda:2 cuda:3 \ --num_rollouts_eval=400 \ --num_actor_eval=8 \ --num_rollouts_opponent=1000 \ --num_actor_opponent=8 ``` Notes: - `num_actor_eval`, `num_rollouts_eval`, `num_actor_opponent` and `num_rollouts_opponent` are independent from the values used during training; in particular for proper benchmarking `num_actor_eval` and `num_rollouts_eval` should be set to the values used in human mode - `num_game_eval * num_actor_eval` (resp. `num_game_eval * num_actor_opponent`) is the number of threads used by the model to be evaluated (resp. the opponent) - there is no `per_thread_batchsize` in this mode - the higher `num_actor_eval` (resp. `num_actor_opponent`), the larger MCTS for a move in a given game will be, up to a limit where overheads between threads lead to decreasing returns. Empiracally this limit seems to be around 8. This limit may be game/model/platform dependent and should be tuned for a given instance. - against a pure MCTS opponent, `num_rollouts_opponent` should be set significantly higher than `num_rollouts_eval` #### Examples for the training+evaluation mode - Run first training then evaluation on the last checkpoint ``` python -m pypolygames traineval --game_name="Connect4" \ --save_dir="/checkpoints" \ --num_epoch=1000 ``` - Plot evaluation on `http://localhost:10000` as the same time as training happens ``` python -m pypolygames traineval --game_name="Connect4" \ --save_dir="/checkpoints" \ --real_time \ --plot_enabled \ --plot_port=10000 ``` #### Examples for the human mode - Play to Connect4 against a pure MCTS as the second player with 8 threads ``` python -m pypolygames human --game_name="Connect4" \ --pure_mcts \ --num_actor 8 ``` - Play to Connect4 against a pretrained model as the second player ``` python -m pypolygames human \ --init_checkpoint="/checkpoints/checkpoint_600.zip" \ --human_first ``` - Play with a timer, each side having 1800s in total, and the model playing each move with 0.07 of the remaining time ``` python -m pypolygames human \ --init_checkpoint="/checkpoints/checkpoint_600.zip" \ --total_time=1800 \ --time_ratio=0.07 ``` - The model uses four GPUs, all for inference ``` python -m pypolygames human \ --init_checkpoint "/checkpoints/checkpoint_600.zip" \ --device cuda:0 cuda:1 cuda:2 cuda:3 ``` - The model uses four GPUs, all for inference, and uses the text protocol (actions are represented by x y z, each on one line): ``` python -m pypolygames tp \ --init_checkpoint "/checkpoints/checkpoint_600.zip" \ --device cuda:0 cuda:1 cuda:2 cuda:3 ``` Notes: - in human mode, the model being fixed, the goal is to maximize performance given the platform running the model - the most effective way to improve model performance is to increase the MCTS size - as for training and evaluation, but given that there is only one game played, `num_actor` is the total number of threads - the higher `num_actor`, the larger the MCTS, up to a limit where overheads between threads lead to decreasing returns. Empiracally this limit seems to be around 8. This limit may be game/model/platform dependent and should be tuned for a given instance. - in a time-limited game `num_rollouts` should not be specified as it is maximized within each `time_ratio` * remaining time period ### Examples for converting models Saved checkpoints of models also store details about the game for which they were trained, and can only be used directly for the game in which they were trained. This is why `eval` runs do not require the `--game_name` to be specified; this is inferred from the model. The `pypolygames convert` command can be used to convert models to different games. - Fully automated convert between games: ``` python -m pypolygames convert \ --init_checkpoint "/checkpoints/checkpoint_600.pt.gz" \ --game_name="LudiiGomoku.lud" \ --out="/checkpoints/converted/XToGomoku.pt.gz" ``` This takes the previously-trained model stored in `"/checkpoints/checkpoint_600.pt.gz"`, modifies it such that it can be used to play the Ludii implementation of Gomoku, and stores this modified version of the model in the new file `"/checkpoints/converted/XToGomoku.pt.gz"`. This works best when using neural network architectures that are compatible with arbitrary board shapes (such as `ResConvConvLogitPoolModel`), and source and target games that have identical numbers of channels for state and move tensors, as well as identical semantics for those channels. For instance, the Ludii implementation of Yavalath has the same number of channels with identical semantics (in the same order) as Gomoku. Therefore, if the source model in `"/checkpoints/checkpoint_600.pt.gz"` was trained using `--model_name=ResConvConvLogitPoolModel` and `--game_name="LudiiYavalath.lud"`, this conversion can be performed directly without having to delete any parameters or add any new parameters. - Fully automated convert between game options: ``` python -m pypolygames convert \ --init_checkpoint "/checkpoints/checkpoint_600.pt.gz" \ --game_options="Board Size/19x19" \ --out="/checkpoints/converted/Gomoku/15x15_to_19x19.pt.gz" ``` This example will convert the source checkpoint `"/checkpoints/checkpoint_600.pt.gz"` into a model that can be used in a game loaded with the additional `--game_options="Board Size/19x19"` argument. For example, `--game_name=LudiiGomoku.lud` is by default played on a 15x15 board, but can be played on a larger 19x19 board with the `--game_options="Board Size/19x19"` argument. Note that the convert command only takes game options into account if some form of `--game_options` is explicitly provided among the command line arguments. This means that, if a model was first trained for `--game_options=Board Size/19x19`, and the goal is to convert it into one for the default board size of 15x15, it is still necessary to provide either `--game_options` (without any values after it) or `--game_options=Board Size/15x15` to the convert script. This tells it that the goal is indeed to revert to default options, rather than just leaving whichever options were baked into the source model. ### Examples for generating figures of models If the optional `graphviz` and `torchviz` dependencies are installed, we can use `torchviz` to automatically generate figures of our models. This can be done using `draw_model` script: ``` python -m pypolygames draw_model \ --game_name="Hex5pie" \ --model_name="ResConvConvLogitPoolModelV2" \ --out="/private/home/$USER/ImageName" ``` This command will generate an image of the `ResConvConvLogitPoolModelV2` architecture when playing `Hex5pie`, and save it to `/private/home/$USER/ImageName.png` (note that the `.png` extension will be automatically appended). Any arguments that can be used to modify the game, or any aspect of the Neural Network architecture, can be used in this command. ### Running games through Ludii See [detailed documentation on the Ludii integration here](./src/games/ludii/). ## Contributing We welcome contributions! Please check basic instructions [here](.github/CONTRIBUTING.md) ## Initial contributors Contributors to the early version of Polygames (before open source release) include: Tristan Cazenave, Univ. Dauphine; Yen-Chi Chen, National Taiwan Normal University; Guan-Wei Chen, National Dong Hwa University; Shi-Yu Chen, National Dong Hwa University; Xian-Dong Chiu, National Dong Hwa University; Julien Dehos, Univ. Littoral Cote d’Opale; Maria Elsa, National Dong Hwa University; Qucheng Gong, Facebook AI Research; Hengyuan Hu, Facebook AI Research; Vasil Khalidov, Facebook AI Research; Chen-Ling Li, National Dong Hwa University; Hsin-I Lin, National Dong Hwa University; Yu-Jin Lin, National Dong Hwa University; Xavier Martinet, Facebook AI Research; Vegard Mella, Facebook AI Research; Jeremy Rapin, Facebook AI Research; Baptiste Roziere, Facebook AI Research; Gabriel Synnaeve, Facebook AI Research; Fabien Teytaud, Univ. Littoral Cote d’Opale; Olivier Teytaud, Facebook AI Research; Shi-Cheng Ye, National Dong Hwa University; Yi-Jun Ye, National Dong Hwa University; Shi-Jim Yen, National Dong Hwa University; Sergey Zagoruyko, Facebook AI Research ## License `polygames` is released under the MIT license. See [LICENSE](LICENSE) for additional details about it. Third-party libraries are also included under their own license. ================================================ FILE: build.sh ================================================ #!/bin/sh # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. export OMP_NUM_THREADS=1 mkdir -p build cd build cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=1 make -j $(($(nproc) + 1)) cd .. ================================================ FILE: littlegolem/play_littlegolem.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import requests from time import sleep from bs4 import BeautifulSoup import argparse import os def lg_connect(thelogin, thepassword): ''' Send login request and get session/login cookies. ''' myresponse = requests.post("https://www.littlegolem.net/jsp/login/index.jsp", data = {'login': thelogin, 'password': thepassword}) if myresponse.status_code != requests.codes.ok: raise ConnectionError("failed to request littlegolem (lg_connect)") if not 'login2' in myresponse.cookies: raise ConnectionError("failed to connect as '{}' (lg_connect)".format(thelogin)) return myresponse.cookies def lg_clean_str(thestr): ''' Remove \t, \n, \r and # in a string. ''' return thestr.translate({ord(c): None for c in '\t\n\r#'}) def lg_get_onmove_games(thecookies): ''' Get the list of games "on move". Return a list [(game id, game name)]. ''' myresponse = requests.get("http://www.littlegolem.net/jsp/game/", cookies = thecookies) if myresponse.status_code != requests.codes.ok: raise ConnectionError("failed to request littlegolem (lg_get_onmove_games)") myhtml = BeautifulSoup(myresponse.text, "html.parser") mydivs = myhtml.select("div.portlet.box.blue-madison") if not mydivs: return [] mytrs = mydivs[0].select("tbody")[0].select("tr") return [ (lg_clean_str(mytds[0].a.text), mytds[4].text) for mytds in (mytr.select("td") for mytr in mytrs) ] def lg_get_hsgf(thegid): ''' Get the description of a game, in the hsgf format. ''' myurl = "http://www.littlegolem.net/servlet/sgf/{}/game{}.hsgf".format(thegid, thegid) myresponse = requests.get(myurl) if myresponse.status_code != requests.codes.ok: raise ConnectionError("failed to request littlegolem (lg_get_hsgf)") #import pdb;pdb.set_trace() return myresponse.text def lg_play(thecookies, thegid, themove): myurl = "http://www.littlegolem.net/jsp/game/game.jsp?sendgame={}&sendmove={}".format(thegid, themove) myresponse = requests.post(myurl, cookies = thecookies) if myresponse.status_code != requests.codes.ok: raise ConnectionError("failed to request littlegolem (lg_play)") def einstein_convert_txt_to_polygames(myhsgf, gid): #requests.get("http://www.littlegolem.net/jsp/game/game.jsp?gid=2127403").text myurl = "http://www.littlegolem.net/jsp/game/game.jsp?gid={}".format(gid) myresponse = requests.get(myurl) if myresponse.status_code != requests.codes.ok: raise ConnectionError("failed to request littlegolem (einstein html)") myhtml = BeautifulSoup(myresponse.text, "html.parser") imgs = myhtml.select("img") assert(len(imgs) == 32) # 2 is dice img # 3-27 is number img num_myhsgf = len(myhsgf.split("/")) turn = num_myhsgf % 2 dice = int(imgs[2]['src'][28]) assert(dice >= 1 and dice <= 6) state_str = "" for i in range(25): current = None num_img = imgs[i + 3]['src'] color = None num = None if len(num_img) < 27: color = num_img[18] else: color = num_img[27] num = num_img[29] if color == 'b': current = chr(ord("A") + int(num) - 1) elif color == 'r': current = chr(ord("a") + int(num) - 1) elif color == '0': current = "0" else: print("parse image error, unexpected color") assert(False) state_str += current s = "" s += str(dice) + "\n" #input dice value s += "m\n" # we switch to manual mode s += "singlemovemode\n" # make one move, print it, exit s += "set_" + state_str + str(turn) + "\n" # set state string if turn == 0: # By default we assume that we play first. s += "swap\n" # Please note that this has nothing to do with the pie rule. s += "c\n" # Resume; this is the genmove. s += str(dice) + "\n" #input dice value (unused) #s += "exit\n" # Safety exit return s, state_str, dice, turn #[Event "Tournament null"] #[Site "www.littlegolem.net"] #[White "luffy_bot"] #[Black "gzero_bot"] #[Result "0-1"] #1. h2-g3 e7-e6 2. a2-b3 g7-f6 3. b3-c4 f6-e5 4. f2-e3 b7-c6 5. g3-f4 f7-f6 6. g2-f3 h7-g6 7. e1-f2 a7-b6 8. h1-g2 b6-c5 9. d2-c3 h8-g7 10. c2-d3 e8-f7 11. b2-b3 c7-d6 12. b3-b4 a8-b7 13. d3-d4 c5xd4 14. c3xd4 g6-g5 15. f2-g3 g7-g6 16. b4-a5 c6-c5 17. d4xc5 d6xc5 18. d1-d2 d7-c6 19. f3-e4 g6-f5 20. e2-f3 f7-g6 21. a1-b2 d8-c7 22. b2-c3 g6-h5 23. e4xf5 e6xf5 24. d2-d3 h5-h4 25. g3xh4 e5xf4 26. resign 0-1 def breakthrough_convert_txt_to_polygames(txt): turn = 0 last_action = None s = "m\n" # we switch to manual mode s += "singlemovemode\n" # make one move, print it, exit elements = txt.split(".") swapped = False print(txt) for e in elements: if e[0] != " ": continue if e[2:] == "resign])": s += "exit\n" # We stop everything. continue if len(e) < 6 or (e[3] != "-" and e[3] != "x"): continue es = e.split() e0 = es[0] e1 = es[1] #print(e0) #print(e1) y = ord(e0[0]) - ord('a') z = 8 - int(e0[1]) x = ord(e0[3]) - ord('a') - y + 1 last_action = str(x) + str(y) + str(z) s += last_action + "\n" turn = 1 - turn if e1 == "*": continue else: y = ord(e1[0]) - ord('a') z = 8 - int(e1[1]) x = ord(e1[3]) - ord('a') - y + 1 last_action = str(x) + str(y) + str(z) s += last_action + "\n" turn = 1 - turn if turn == 0: # By default we assume that we play first. s += "swap\n" # Please note that this has nothing to do with the pie rule. s += "c\n" # Resume; this is the genmove. s += "exit\n" # Safety exit #print("turn is" + str(turn)) return s, swapped, turn def hex_convert_hsgf_to_polygames(hsgf): turn = 0 last_action = None s = "m\n" # we switch to manual mode s += "singlemovemode\n" # make one move, print it, exit elements = hsgf.split(";") swapped = False print(hsgf) for e in elements: if e[2:] == "resign])": s += "exit\n" # We stop everything. continue if len(e) < 5: continue if e[2:6] == "swap": # swap is implemented differently in littlegolem and polygames. # we convert by flipping all remaining moves along the long diagonal. swapped = True s += last_action + "\n" turn = 1 - turn continue if (e[0] == "W" or e[0] == "B") and e[1] == "[" and e[4] == "]": x = ord(e[2]) - ord('a') y = ord(e[3]) - ord('a') if swapped: x, y = y, x last_action = chr(ord('a') + x) + str(1 + y) s += last_action + "\n" # Swap is implemented as replaying the last action in Hex. turn = 1 - turn if turn == 0: # By default we assume that we play first. s += "swap\n" # Please note that this has nothing to do with the pie rule. s += "c\n" # Resume; this is the genmove. s += "exit\n" # Safety exit return s, swapped, last_action #(;FF[4]EV[null]PB[leela_bot]PW[gzero_bot]SZ[13]RE[B]GC[ game #2103276] #SO[http://www.littlegolem.com];W[ma];B[swap];W[jd];B[ej];W[ji];B[if]; #W[ck];B[ed];W[di];B[he];W[hf];B[ie];W[dd];B[ec];W[cc];B[cj];W[ef];B[dl]; #W[ke];B[jg];W[cl];B[dj];W[le];B[kd];W[je];B[lf];W[ig];B[jf];W[hg];B[db]; #W[ff];B[hb];W[cb];B[resign]) def havannah_convert_hsgf_to_polygames(hsgf, boardsize): turn = 0 last_action = None s = "m\n" # we switch to manual mode s += "singlemovemode\n" # make one move, print it, exit elements = hsgf.split(";") swapped = False print(hsgf) for e in elements: if e[2:] == "resign])": s += "exit\n" # We stop everything. continue if len(e) < 5: continue if e[2:6] == "swap": # swap is implemented differently in littlegolem and polygames. # we convert by flipping all remaining moves along the long diagonal. swapped = True s += last_action + "\n" turn = 1 - turn continue if (e[0] == "W" or e[0] == "B") and e[1] == "[" and (e[4] == "]" or e[5] == "]"): # in littlegolem x, y = y, x in polygames x = int(e[3]) if (e[4] != "]"): x = int(e[3:5]) y = ord(e[2]) - ord('A') v = 1 if (y >= boardsize): v = y - boardsize + 2 last_action = str((x * -1)+(boardsize*2-v)) + "," + str(y) s += last_action + "\n" # Swap is implemented as replaying the last action in Hex. turn = 1 - turn if turn == 0: # By default we assume that we play first. s += "swap\n" # Please note that this has nothing to do with the pie rule. s += "c\n" # Resume; this is the genmove. s += "exit\n" # Safety exit return s, swapped, last_action if __name__ == "__main__": parser = argparse.ArgumentParser(description='Play polygames on littlegolem.') parser.add_argument('--username', type=str, help='Username for login') parser.add_argument('--password', type=str, help='Password for login') parser.add_argument('--hex11_model', type=str, help='Model to use for playing hex11pie') parser.add_argument('--hex13_model', type=str, help='Model to use for playing hex13pie') parser.add_argument('--havannah8_model', type=str, help='Model to use for playing havannah8pie') parser.add_argument('--breakthrough_model', type=str, help='Model to use for playing breakthrough') parser.add_argument('--havannah10_model', type=str, help='Model to use for playing havannah10pie') parser.add_argument('--einstein_model', type=str, help='Model to use for playing einstein') args = parser.parse_args() try: mylogin = args.username mypassword = args.password mycookies = lg_connect(mylogin, mypassword) mygames = lg_get_onmove_games(mycookies) except ConnectionError as e: print("error:", e) exit(1) if not mygames: print("no turn to play") else: played = [] not_played = [] for mygame in mygames: try: (mygid, mygname) = mygame print("playing game #{} ({})...".format(mygid, mygname)) myhsgf = lg_get_hsgf(mygid) #if "river" not in myhsgf: # uncomment this if you want to play only against someone with "river" in the name # # (e.g. rookDriver, a.k.a the other Teytaud) # print("I do not play ", myhsgf) # not_played.append(mygname) # continue print("I play ", myhsgf) resign_score = -0.99 model_path = None swapped = False last_action = None turn = None state_str = None dice = None if mygname == "Hex Size 11" and args.hex11_model: polygames_commands, swapped, last_action = hex_convert_hsgf_to_polygames(myhsgf) model_path = args.hex11_model elif mygname == "Hex Size 13" and args.hex13_model: polygames_commands, swapped, last_action = hex_convert_hsgf_to_polygames(myhsgf) model_path = args.hex13_model elif mygname == "Havannah Size 8" and args.havannah8_model: polygames_commands, swapped, last_action = havannah_convert_hsgf_to_polygames(myhsgf, 8) model_path = args.havannah8_model elif mygname == "Breakthrough Size 8" and args.breakthrough_model: polygames_commands, swapped, turn = breakthrough_convert_txt_to_polygames(myhsgf) model_path = args.breakthrough_model elif mygname == "Havannah Size 10" and args.havannah10_model: polygames_commands, swapped, last_action = havannah_convert_hsgf_to_polygames(myhsgf, 10) model_path = args.havannah10_model elif mygname[:7] == "havannah"[:7] and "ize 8" in mygname and args.havannah8_model: polygames_commands, swapped, last_action = havannah_convert_hsgf_to_polygames(myhsgf, 8) model_path = args.havannah8_model elif mygname[:7] == "havannah"[:7] and "ize 10" in mygname and args.havannah10_model: polygames_commands, swapped, last_action = havannah_convert_hsgf_to_polygames(myhsgf, 10) model_path = args.havannah10_model elif mygname[:8] == "EinStein würfelt nicht! 3-points match"[:8] and args.einstein_model: #pass in gid to handle specially for Einstein. e.g. parse board and dice value from html polygames_commands, state_str, dice, turn = einstein_convert_txt_to_polygames(myhsgf, mygid) model_path = args.einstein_model else: not_played.append(mygname) continue played.append(mygname) # 60 seconds per move. Human first. 8 threads. # Singularity command line below might be old fashioned ? # command = "singularity exec --nv --overlay overlay.img /checkpoint/polygames/polygames_190927.simg python -m pypolygames human --init_checkpoint " + model_path command = "python -m pypolygames human --init_checkpoint " + model_path command += " --total_time 60000 --time_ratio 0.01 --human_first --num_actor 8" import subprocess command = "echo -e \"" + polygames_commands.translate({ord(c): '\\n' for c in '\n'}) + "\" | " + command print(command) mcts_value = None move = None if mygname[:8] == "EinStein würfelt nicht! 3-points match"[:8]: # Unfortunately EinStein game needs special handling # Somehow if I put -e here it gets passed to the program, need to investigate command = "echo" + command[7:] #print(command) result = subprocess.check_output(command, shell=True) mcts_value = result.splitlines()[-2].decode() move = result.splitlines()[-4].decode() print(move) move_tokens = move.split() origin = move_tokens[-3] origin_num = int(origin[1]) target = move_tokens[-1] origin_idx = -1 for i in range(5): for j in range(5): idx = i * 5 + j if ord(state_str[idx]) - ord('a') == origin_num - 1 and origin[0] == 'x': origin_idx = idx break if ord(state_str[idx]) - ord('A') == origin_num - 1 and origin[0] == 'o': origin_idx = idx break #print(origin_idx) char0 = chr(4 - origin_idx % 5 + ord('a')) char1 = chr(4 - origin_idx // 5 + ord('a')) char2 = chr(ord('E') - ord(target[0]) + ord('a')) char3 = chr(5 - int(target[1]) + ord('a')) move = char0 + char1 + char2 + char3 else: result = subprocess.check_output(command, shell=True) # Maybe "cwd = '..' " ? not if we assume # run from the root of polygames #print(result) (mcts_value, move) = [i.decode() for i in result.splitlines()[-2:]] mcts_value = mcts_value.split(":")[-1] print("MCTS value: " + mcts_value) print("Making move: " + move) print("in game " + mygname) mymove = None if mygname == "Hex Size 11" or mygname == "Hex Size 13": print("playing hex") x = ord(move[0]) - ord('a') y = int(move[1:]) - 1 if swapped: x, y = y, x # in littlegolem, swap is implemented by mirror move and not switching colors mymove = chr(ord('a') + int(x)) + chr(ord('a') + int(y)) if last_action != None and last_action.lower() == move.lower(): mymove = "swap" elif (mygname[:10] == "Havannah Size 8"[:10] or mygname[:4] == "havannah.in"[:4]) and "Size 8" in mygname: print("playing havannah 8") boardsize = 8 # ONLY FOR SIZE 8 listmove = move.split(',') x = int(listmove[0]) y = int(listmove[1]) mymove = chr(ord('a') + y + boardsize - 1) + chr(ord('a') + x + boardsize - 1) # ,11 if last_action != None and last_action.lower() == move.lower(): mymove = "swap" elif (mygname[:4] == "havannah.in"[:4] or mygname[:10] == "Havannah Size 10"[:10]) and "Size 10" in mygname: print("playing havannah 10") boardsize = 10 # ONLY FOR SIZE 10 listmove = move.split(',') x = int(listmove[0]) y = int(listmove[1]) mymove = chr(ord('a') + y + boardsize - 5) + chr(ord('a') + x + boardsize - 5) # ,11 if last_action != None and last_action.lower() == move.lower(): mymove = "swap" elif mygname == "Breakthrough Size 8": boardsize = 8 listmove = move.split(',') x = int(listmove[0]) y = int(listmove[1]) z = boardsize - int(listmove[2]) - 1 z1 = z + 1 if turn == 0 else z - 1 mymove = str(y) + str(z) + str(y + x - 1) + str(z1) elif mygname[:8] == "EinStein würfelt nicht! 3-points match"[:8]: mymove = move else: print("implement mymove for " + mygname) exit(1) mymove = mymove.lower() # No resign in Einstein, due to the complications on LittleGolem. # Anyway, in a multigame (i.e. the best of k games), resigning is complicated and can not save up much time. if float(mcts_value) < resign_score and "nStein w" not in mygname: print("Resigning!") mymove = "resign" print("Sending move " + mymove) lg_play(mycookies, mygid, mymove) except ConnectionError as e: print("error:", e) exit(1) if len(played): print("Made a move in ", played) if len(not_played): print("Did not make a move in ", not_played) # requests: https://2.python-requests.org/en/master/ # beautifulsoup4: https://www.crummy.com/software/BeautifulSoup/bs4/doc/ ================================================ FILE: nix/Dockerfile ================================================ # This Dockerfile configures a Debian system with Nix, builds Polygames and # runs some tests. To build this docker image, run: # `docker build -t polygames .` ############################################################################### # Initialize the docker image. You can ignore this when installing on a real # system. ############################################################################### FROM debian:buster ENV DEBIAN_FRONTEND noninteractive RUN apt-get update -y RUN apt-get install -y git curl sudo xz-utils RUN useradd -ms /bin/bash -G sudo myuser RUN echo "myuser ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers USER myuser ENV USER="myuser" ENV HOME="/home/myuser" ############################################################################### # Install Nix. ############################################################################### RUN curl https://nixos.org/releases/nix/latest/install | sh # For docker only: ENV PATH="$HOME/.nix-profile/bin/:$PATH" # On a real system, yau have to run these two lines instead: #RUN echo "source $HOME/.nix-profile/etc/profile.d/nix.sh" >> $HOME/.bashrc #RUN source $HOME/.bashrc ############################################################################### # Activate the cachix repo. ############################################################################### RUN nix-env -iA nixpkgs.cachix RUN cachix use polygames ############################################################################### # Get Polygames. ############################################################################### WORKDIR $HOME RUN git clone https://github.com/facebookincubator/polygames.git WORKDIR $HOME/Polygames # On a real system with CUDA devices, you have to run `./nix/get-nvidia.sh` # here. ############################################################################### # Build Polygames. ############################################################################### RUN mkdir $HOME/Polygames/build WORKDIR $HOME/Polygames/build RUN nix-shell ../nix/shell-cpu.nix --run "cmake -DPYTORCH12=ON .. ; make -j4" ############################################################################### # Run unit-tests. ############################################################################### RUN mkdir $HOME/Polygames/tests/build WORKDIR $HOME/Polygames/tests/build RUN nix-shell ../../nix/shell-cpu.nix --run "cmake .. ; make -j4 ; ./polygames-tests" ############################################################################### # Run tests. ############################################################################### WORKDIR $HOME/Polygames/ RUN nix-shell nix/shell-cpu.nix --run "pytest pypolygames --durations=10 --verbose" ================================================ FILE: nix/Dockerfile-centos7-nix ================================================ # docker build -t polygames-centos7-nix -f Dockerfile-centos7-nix . # docker run --rm -it polygames-centos7-nix # nix-shell nix/shell-cpu.nix --run "python -m pypolygames train --game_name Hex11 --device=cpu" FROM centos:centos7 RUN yum update -y RUN yum install -y git curl sudo xz-utils cacert RUN useradd -ms /bin/bash -G wheel myuser RUN echo "myuser ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers USER myuser ENV USER="myuser" ENV HOME="/home/myuser" RUN curl https://nixos.org/releases/nix/latest/install | sh RUN echo "source $HOME/.nix-profile/etc/profile.d/nix.sh" >> $HOME/.bashrc RUN source $HOME/.bashrc ENV PATH="$HOME/.nix-profile/bin/:$PATH#" ENV NIX_SSL_CERT_FILE="/etc/ssl/certs/ca-bundle.crt" RUN nix-env -iA nixpkgs.cachix RUN cachix use polygames WORKDIR $HOME RUN git clone https://github.com/juliendehos/Polygames.git --branch=nix RUN mkdir $HOME/Polygames/build WORKDIR $HOME/Polygames/build RUN nix-shell ../nix/shell-cpu.nix --run "cmake -DPYTORCH12=ON .. ; make -j4" WORKDIR $HOME/Polygames/ ================================================ FILE: nix/README.md ================================================ # Polygames for Nix users [Nix](https://nixos.org/) is a package manager that can be installed on any Linux distribution (you just need root permissions to create the `/nix` directory). Alternatively, NixOS is a Linux distribution based on Nix. Polygames is quite easy to use with Nix and NixOS, as explained below. See also the [Dockerfile](./Dockerfile). ## Get Polygames - Clone the repo: ``` git clone https://github.com/facebookincubator/polygames.git cd Polygames ``` ## Configure your system (NixOS) - With NixOS, if you want to run Polygames on CPU, you have nothing to configure. - If you want to run Polygames on CUDA devices, check that the Nvidia driver is enable in `/etc/nixos/configuration.nix` (don't forget to rebuild and reboot the system, if necessary): ``` services.xserver.videoDrivers = [ "nvidia" ]; nixpkgs.config.allowUnfree = true; ``` ## Configure your system (Nix + Linux) - Install Nix: ``` curl https://nixos.org/releases/nix/latest/install | sh echo "source $HOME/.nix-profile/etc/profile.d/nix.sh" >> $HOME/.bashrc source $HOME/.bashrc ``` - If you want to run Polygames on CUDA devices: - Install the Nvidia driver using your Linux distribution. - Check that `nvidia-smi` is also installed. - Get the Nvidia driver version and write the `nvidia.json` config file: ``` ./nix/get-nvidia.sh ``` ## Build & run Polygames - Activate the binary cache (optional if you like compiling for hours): ``` nix-env -iA nixpkgs.cachix cachix use polygames ``` > Warning: this cache provides pre-built binaries for CPU and for Nvidia > 418.74 only but you can [build your own binary > cache](README.md#build-you-own-binary-cache). - Open a nix-shell: - CPU: ``` nix-shell nix/shell-cpu.nix ``` - CUDA: ``` nix-shell nix/shell-cuda.nix ``` - Build Polygames: ``` mkdir build cd build cmake -DPYTORCH12=ON .. make -j4 cd .. ``` - Run Polygames: - CPU: ``` python -m pypolygames train --game_name="Connect4" --device=cpu ``` - CUDA: ``` python -m pypolygames train --game_name="Connect4" --device=cuda:0 ``` ## Build you own binary cache When you open a nix-shell for the first time, Nix/NixOS fetches and builds all the required dependencies. [This cachix repo](https://polygames.cachix.org/) provides some pre-built dependencies that should greatly speed-up the installation. However, if your Nvidia driver version is not in the cache, you have to build CUDA/Pytorch/etc. You can upload the built binaries to reuse them on other machines: - Create a (free) account on [cachix](https://cachix.org/). - Create a repo on cachix. - Push your binaries to this repo: ``` find /nix/store -maxdepth 1 -name "*pytorch*" -exec cachix push {} \; ``` - Use your repo when you install/configure Polygames on a new machine: ``` cachix use ``` ================================================ FILE: nix/get-nvidia.sh ================================================ #!/bin/sh nvidiaVersion=$(nvidia-smi --query-gpu=driver_version --format=csv | tail -n 1) echo "detected: ${nvidiaVersion}" nvidiaUrl="http://download.nvidia.com/XFree86/Linux-x86_64/${nvidiaVersion}/NVIDIA-Linux-x86_64-${nvidiaVersion}.run" nvidiaSha256=$(nix-prefetch-url ${nvidiaUrl}) OUTNAME="nvidia.json" echo "{" > ${OUTNAME} echo " \"nvidiaVersion\" : \"${nvidiaVersion}\"," >> ${OUTNAME} echo " \"nvidiaSha256\" : \"${nvidiaSha256}\"" >> ${OUTNAME} echo "}" >> ${OUTNAME} echo "${OUTNAME} written" ================================================ FILE: nix/shell-cpu.nix ================================================ let rev = "dfa8e8b9bc4a18bab8f2c55897b6054d31e2c71b"; channel = fetchTarball "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; config = { allowUnfree = true; }; pkgs = import channel { inherit config; }; python = pkgs.python3; pytorch = pkgs.python3Packages.pytorchWithoutCuda; pybind11 = pkgs.pybind11; tensorboardX = pkgs.python3Packages.buildPythonPackage rec { pname = "tensorboardX"; version = "1.8"; src = fetchTarball "https://github.com/lanpa/tensorboardX/archive/v1.8.tar.gz"; propagatedBuildInputs = with pkgs.python3Packages; [ six protobuf numpy ]; doCheck = false; }; in pkgs.mkShell { name = "Polygames-cpu"; src = ./.; buildInputs = [ pkgs.cmake pkgs.czmq pkgs.gtest pkgs.python3Packages.pytest pkgs.openjdk pytorch tensorboardX ]; shellHook = '' export CFLAGS="-I${pybind11}/include -I${pytorch}/${python.sitePackages}/torch/include -I${pytorch}/${python.sitePackages}/torch/include/torch/csrc/api/include" export CXXFLAGS=$CFLAGS export LDFLAGS="-L${pytorch}/${python.sitePackages}/torch/lib -L$out/${python.sitePackages}" export PYTHONPATH="$PYTHONPATH:build:build/torchRL/mcts:build/torchRL/tube" export OMP_NUM_THREADS=1 ''; } ================================================ FILE: nix/shell-cuda.nix ================================================ let jsonPath = ../nvidia.json; hasJson = builtins.pathExists jsonPath; json = builtins.fromJSON (builtins.readFile jsonPath); overlay = self: super: { linuxPackages = super.linuxPackages // { nvidia_x11 = (super.linuxPackages.nvidia_x11.override { }).overrideAttrs(oldAttrs: rec { version = json.nvidiaVersion; name = "nvidia-${version}"; src = super.fetchurl { url = "http://download.nvidia.com/XFree86/Linux-x86_64/${version}/NVIDIA-Linux-x86_64-${version}.run"; sha256 = json.nvidiaSha256; }; useGLVND = true; }); }; }; rev = "dfa8e8b9bc4a18bab8f2c55897b6054d31e2c71b"; channel = fetchTarball "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; config = { allowUnfree = true; cudaSupport = true; packageOverrides = pkgs: { cudatoolkit = pkgs.cudatoolkit_10; cudnn = pkgs.cudnn_cudatoolkit_10; }; }; pkgs = import channel { overlays = if hasJson then [overlay] else []; inherit config; }; python = pkgs.python3; pytorch = pkgs.python3Packages.pytorchWithCuda; pybind11 = pkgs.pybind11; tensorboardX = pkgs.python3Packages.buildPythonPackage rec { pname = "tensorboardX"; version = "1.8"; src = fetchTarball "https://github.com/lanpa/tensorboardX/archive/v1.8.tar.gz"; propagatedBuildInputs = with pkgs.python3Packages; [ six protobuf numpy ]; doCheck = false; }; in pkgs.mkShell { name = "Polygames-cuda"; src = ./.; buildInputs = [ pkgs.boost pkgs.cmake pkgs.cudatoolkit pkgs.cudnn pkgs.czmq pkgs.gtest pkgs.linuxPackages.nvidia_x11 pkgs.python3Packages.pytest pkgs.openjdk pytorch tensorboardX ]; shellHook = '' export CFLAGS="-I${pybind11}/include -I${pytorch}/${python.sitePackages}/torch/include -I${pytorch}/${python.sitePackages}/torch/include/torch/csrc/api/include" export CXXFLAGS=$CFLAGS export LDFLAGS="-L${pytorch}/${python.sitePackages}/torch/lib -L$out/${python.sitePackages} -L${pkgs.cudatoolkit}/lib" export LD_LIBRARY_PATH="${pkgs.linuxPackages.nvidia_x11}/lib" export PYTHONPATH="$PYTHONPATH:build:build/torchRL/mcts:build/torchRL/tube" export OMP_NUM_THREADS=1 ''; } ================================================ FILE: pypolygames/__init__.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import os import sys # disable CUDA cache as it can throw errors when doing distributed # training and the cache folder is on NFS os.environ['CUDA_CACHE_DISABLE'] = '1' root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) game = os.path.join(root, "build/src") if game not in sys.path: sys.path.append(game) tube = os.path.join(root, "build/src", "tube") if tube not in sys.path: sys.path.append(tube) pytube = os.path.join(root, "src", "tube") if pytube not in sys.path: sys.path.append(pytube) mcts = os.path.join(root, "build/src", "mcts") if mcts not in sys.path: sys.path.append(mcts) ================================================ FILE: pypolygames/__main__.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import os from pathlib import Path import sys import warnings import time from dataclasses import astuple import argparse from multiprocessing import Process from typing import Union, List from .params import ( GameParams, ModelParams, OptimParams, SimulationParams, ExecutionParams, EvalParams, ) from .utils import CommandHistory from .training import run_training from .evaluation import run_evaluation from .human import run_human_played_game from .human import run_tp_played_game from .convert import convert_checkpoint from .draw_model import draw_model DOC = """The python package `pypolygames` can be used in either of the following modes: - `pypolygames train` (training mode): a game and a model (as well as several other options, see below) are chosen and the model is iteratively trained with MCTS - `pypolygames eval` (evaluation mode): the model confronts either a pure MCTS or another neural network powered MCTS. The evaluation of a training can be done either offline (from checkpoints periodically saved) or in real time; in that case, the evaluation considers only the most recent checkpoint in order to follow closely the training, skipping some checkpoints in case the eval computation takes longer than the time becween consecutive checkpoints. It is displayed through visdom. - `pypolygames traineval` (training + evaluation mode): it mixes the two previous modes and allow to launch one command instead of two. With the `real_time` option the modes can be launched in parallel instead of sequentially. - `pypolygames human` (human mode): a human player plays against the machine Trainings log the following relevant files in the `checkpoint_dir`: - `model.pt` - `train.log` - `stat.tb` - `checkpoints_.pt` for for checkpoints saved each `saving_period` epoch (e.g., if `saving_period == 10`, `checkpoints_0.pt`, `checkpoints_9.pt`, `checkpoints_19.pt`, `checkpoints_29.pt`) By default, the checkpoint_dir is exps/dev/game__model__feat__GMT_ This directory will be the `checkpoint_dir` directory used by evaluation to retrieve the checkpoints to perform eval computation.""" def _check_arg_consistency(args: argparse.Namespace) -> None: # Most of the consistency is done in the `__post_init__` methods in the params class if ( args.command_history.last_command_contains("pure_mcts") and getattr(args, "game_name", None) is None ): raise ValueError( "In '--pure_mcts' the game must be specified with '--game_name'" ) if args.command_history.last_command_contains("human"): if ( getattr(args, "pure_mcts", None) is False and getattr(args, "init_checkpoint", None) is None ): raise ValueError( "The human player need to play either a '--pure_mcts' " "or a '--init_checkpoint' neural network powered MCTS" ) if args.command_history.last_command_contains("device_opponent"): if getattr(args, "checkpoint_opponent", None) is None: raise ValueError( "If the opponent is a pure MCTS player " "('--checkpoint_opponent' not set), " "all its computation will happen on CPU, " "'--device_opponent' should not be set" ) if args.command_history.last_command_contains( "per_thread_batchsize" ) and args.command_history.last_command_contains("act_batchsize"): raise ValueError( "When '--per_thread_batchsize' is set, '--act_batchsize' is not used" ) if getattr(args, "total_time", 0) is not None and getattr(args, "total_time", 0) > 0: if args.command_history.last_command_contains("num_rollouts"): raise ValueError( "When a '--total_time' is set, " "the '--num_rollouts' will adapt automatically and should not be set" ) def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( description=DOC, formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False, ) parser.set_defaults(func=run_training_and_evaluation_from_args_warning) subparsers = parser.add_subparsers( help="Modes to be chosen from: `python -m pypolygames MODE`" ) # TRAINING parser_train = subparsers.add_parser("train") parser_train.set_defaults(func=run_training_from_args) # EVALUATION parser_eval = subparsers.add_parser("eval") parser_eval.set_defaults(func=run_evaluation_from_args) # TRAINING + EVALUATION parser_traineval = subparsers.add_parser("traineval") parser_traineval.set_defaults(func=run_training_and_evaluation_from_args) # HUMAN-PLAYED GAME parser_human = subparsers.add_parser("human") parser_human.set_defaults(func=run_human_played_game_from_args) # TEXT-PROTOCOLE GAME parser_tp = subparsers.add_parser("tp") parser_tp.set_defaults(func=run_tp_played_game_from_args) # CONVERT CHECKPOINT COMMAND parser_convert = subparsers.add_parser("convert") parser_convert.set_defaults(func=convert_checkpoint_from_args) parser_convert.add_argument('--out', type=str, required=True, help='File name to save the converted checkpoint to') parser_convert.add_argument('--skip', type=str, nargs="*", help='List of attributes to not copy, leaving them initialized') parser_convert.add_argument( '--auto_tune_nnsize', action="store_true", help='Tune nnsize automatically such that number of filters in hidden layers remains unchanged.' ) parser_convert.add_argument( '--zero_shot', type=bool, default=False, help='Convert for zero-shot evaluation without training; this will initialise any skipped or new params to 0.' ) parser_convert.add_argument( '--move_source_channels', type=int, nargs="*", help=('For fully convolutional architectures, for every channel in the destination game\'s move tensors, ' 'specify the channel from the original tensor that we should transfer weights from.') ) parser_convert.add_argument( '--state_source_channels', type=int, nargs="*", help=('For fully convolutional architectures, for every channel in the destination game\'s state tensors, ' 'specify the channel from the original tensor that we should transfer weights from.') ) # DRAW MODEL COMMAND parser_draw_model = subparsers.add_parser("draw_model") parser_draw_model.set_defaults(func=draw_model_from_args) parser_draw_model.add_argument('--out', type=str, required=True, help='File name (without extension) to save figure to.') # Game params train_game_params_group = parser_train.add_argument_group( "Game parameters", "Not to be specified in case of loading a checkpoint or a pretrained model", ) traineval_game_params_group = parser_traineval.add_argument_group( "Game parameters", "Not to be specified in case of loading a checkpoint or a pretrained model", ) game_params_group = parser.add_argument_group( "Game parameters", "Not to be specified in case of loading a checkpoint or a pretrained model", ) human_game_params_group = parser_human.add_argument_group( "Game parameters", "Mandatory for pure MTCS, " "but not to be specified in case of loading a pretrained model", ) for arg_name, arg_field in GameParams.arg_fields(): train_game_params_group.add_argument(arg_field.name, **arg_field.opts) traineval_game_params_group.add_argument(arg_field.name, **arg_field.opts) game_params_group.add_argument( arg_field.name, **{**arg_field.opts, **dict(help=argparse.SUPPRESS)} ) human_game_params_group.add_argument(arg_field.name, **arg_field.opts) parser_convert.add_argument(arg_field.name, **arg_field.opts) parser_draw_model.add_argument(arg_field.name, **arg_field.opts) # Model params train_model_params_group = parser_train.add_argument_group( "Model parameters", "Not to be specified in case of loading a checkpoint or a pretrained model", ) traineval_model_params_group = parser_traineval.add_argument_group( "Model parameters", "Not to be specified in case of loading a checkpoint or a pretrained model", ) model_params_group = parser.add_argument_group("Model parameters") human_model_params_group = parser_human.add_argument_group( "Model parameters", "The machine model can be either a '--pure_mcts' or " "a '--init_checkpoint' neural network powered MCTS", ) for arg_name, arg_field in ModelParams.arg_fields(): if arg_name != "pure_mcts": train_model_params_group.add_argument(arg_field.name, **arg_field.opts) traineval_model_params_group.add_argument(arg_field.name, **arg_field.opts) model_params_group.add_argument( arg_field.name, **{**arg_field.opts, **dict(help=argparse.SUPPRESS)} ) if arg_name in {"pure_mcts", "init_checkpoint"}: human_model_params_group.add_argument(arg_field.name, **arg_field.opts) if arg_name != "pure_mcts": parser_convert.add_argument(arg_field.name, **arg_field.opts) parser_draw_model.add_argument(arg_field.name, **arg_field.opts) # Optimizer params train_optim_params_group = parser_train.add_argument_group("Optimizer parameters") traineval_optim_params_group = parser_traineval.add_argument_group( "Optimizer parameters" ) optim_params_group = parser.add_argument_group("Optimizer parameters") for _, arg_field in OptimParams.arg_fields(): train_optim_params_group.add_argument(arg_field.name, **arg_field.opts) traineval_optim_params_group.add_argument(arg_field.name, **arg_field.opts) optim_params_group.add_argument( arg_field.name, **{**arg_field.opts, **dict(help=argparse.SUPPRESS)} ) # Simulation params train_simulation_params_group = parser_train.add_argument_group( "Simulation parameters" ) traineval_simulation_params_group = parser_traineval.add_argument_group( "Simulation parameters" ) simulation_params_group = parser.add_argument_group("Simulation parameters") human_simulation_params_group = parser_human.add_argument_group( "Simulation parameters" ) for arg_name, arg_field in SimulationParams.arg_fields(): if arg_name not in { "human_first", "time_ratio", "total_time", }: # , "num_actor"}: train_simulation_params_group.add_argument(arg_field.name, **arg_field.opts) traineval_simulation_params_group.add_argument( arg_field.name, **arg_field.opts ) simulation_params_group.add_argument( arg_field.name, **{**arg_field.opts, **dict(help=argparse.SUPPRESS)} ) #if arg_name in {"num_actor", "num_rollouts"}: if True: human_simulation_params_group.add_argument(arg_field.name, **arg_field.opts) # Execution params train_execution_params_group = parser_train.add_argument_group( "Execution parameters" ) traineval_execution_params_group = parser_traineval.add_argument_group( "Execution parameters" ) human_execution_params_group = parser_human.add_argument_group( "Execution parameters" ) execution_params_group = parser.add_argument_group("Execution parameters") for arg_name, arg_field in ExecutionParams.arg_fields(): if arg_name not in {"human_first", "time_ratio", "total_time"}: train_execution_params_group.add_argument(arg_field.name, **arg_field.opts) traineval_execution_params_group.add_argument( arg_field.name, **arg_field.opts ) execution_params_group.add_argument( arg_field.name, **{**arg_field.opts, **dict(help=argparse.SUPPRESS)} ) if arg_name in {"human_first", "time_ratio", "total_time", "device", "seed"}: human_execution_params_group.add_argument(arg_field.name, **arg_field.opts) # Evaluation params eval_eval_params_group = parser_eval.add_argument_group("Evaluation parameters") traineval_eval_params_group = parser_traineval.add_argument_group( "Evaluation parameters" ) eval_params_group = parser.add_argument_group("Evaluation parameters") for arg_name, arg_field in EvalParams.arg_fields(): eval_eval_params_group.add_argument(arg_field.name, **arg_field.opts) if arg_name not in {"checkpoint_dir", "checkpoint"}: traineval_eval_params_group.add_argument(arg_field.name, **arg_field.opts) eval_params_group.add_argument( arg_field.name, **{**arg_field.opts, **dict(help=argparse.SUPPRESS)} ) args = parser.parse_args() args.command_history = CommandHistory() # check arg consistency _check_arg_consistency(args) return args def _get_game_features(game_params: GameParams) -> str: return "_".join(str(x) for x in astuple(game_params)) def _get_timestamp() -> str: return time.strftime("%Y%m%d%H%M%S", time.gmtime()) def update_and_create_checkpoint_dir( game_params: GameParams, model_params: ModelParams, execution_params: ExecutionParams, ) -> None: # create a dedicated folder if none is provided if execution_params.checkpoint_dir is None: game_name = game_params.game_name model_name = model_params.model_name game_features = _get_game_features(game_params) timestamp = _get_timestamp() subfolder = f"game_{game_name}_model_{model_name}_feat_{game_features}_GMT_{timestamp}" execution_params.checkpoint_dir = Path("exps").absolute() / "dev" / subfolder execution_params.checkpoint_dir.mkdir(exist_ok=True, parents=True) def instanciate_params_from_args( Dataclass, args: argparse.Namespace ) -> Union[ GameParams, ModelParams, OptimParams, SimulationParams, ExecutionParams, EvalParams ]: return Dataclass( **{param: getattr(args, param, None) for param, _ in Dataclass.arg_fields()} ) def run_training_from_args(args: argparse.Namespace): command_history = args.command_history game_params = instanciate_params_from_args(GameParams, args) model_params = instanciate_params_from_args(ModelParams, args) optim_params = instanciate_params_from_args(OptimParams, args) simulation_params = instanciate_params_from_args(SimulationParams, args) execution_params = instanciate_params_from_args(ExecutionParams, args) update_and_create_checkpoint_dir( game_params=game_params, model_params=model_params, execution_params=execution_params, ) run_training( command_history=command_history, game_params=game_params, model_params=model_params, optim_params=optim_params, simulation_params=simulation_params, execution_params=execution_params, ) def run_evaluation_from_args(args: argparse.Namespace): eval_params = instanciate_params_from_args(EvalParams, args) execution_params = instanciate_params_from_args(ExecutionParams, args) run_evaluation(eval_params=eval_params, execution_params=execution_params) def run_training_and_evaluation_from_args(args: argparse.Namespace): command_history = args.command_history game_params = instanciate_params_from_args(GameParams, args) model_params = instanciate_params_from_args(ModelParams, args) optim_params = instanciate_params_from_args(OptimParams, args) simulation_params = instanciate_params_from_args(SimulationParams, args) execution_params = instanciate_params_from_args(ExecutionParams, args) # create the save dir update_and_create_checkpoint_dir( game_params=game_params, model_params=model_params, execution_params=execution_params, ) args.checkpoint_dir = execution_params.checkpoint_dir eval_params = instanciate_params_from_args(EvalParams, args) if args.real_time: eval_process = Process(target=run_evaluation, args=(eval_params,)) eval_process.start() run_training( command_history=command_history, game_params=game_params, model_params=model_params, optim_params=optim_params, simulation_params=simulation_params, execution_params=execution_params, ) eval_process.join() else: run_training( command_history=command_history, game_params=game_params, model_params=model_params, optim_params=optim_params, simulation_params=simulation_params, execution_params=execution_params, ) run_evaluation(eval_params=eval_params, only_last=True) def run_human_played_game_from_args(args: argparse.Namespace): game_params = instanciate_params_from_args(GameParams, args) model_params = instanciate_params_from_args(ModelParams, args) simulation_params = instanciate_params_from_args(SimulationParams, args) simulation_params.num_game = 1 execution_params = instanciate_params_from_args(ExecutionParams, args) run_human_played_game( game_params=game_params, model_params=model_params, simulation_params=simulation_params, execution_params=execution_params, ) def run_tp_played_game_from_args(args: argparse.Namespace): game_params = instanciate_params_from_args(GameParams, args) model_params = instanciate_params_from_args(ModelParams, args) simulation_params = instanciate_params_from_args(SimulationParams, args) simulation_params.num_game = 1 execution_params = instanciate_params_from_args(ExecutionParams, args) run_tp_played_game( game_params=game_params, model_params=model_params, simulation_params=simulation_params, execution_params=execution_params, ) def convert_checkpoint_from_args(args: argparse.Namespace): command_history = args.command_history game_params = instanciate_params_from_args(GameParams, args) model_params = instanciate_params_from_args(ModelParams, args) convert_checkpoint( command_history=command_history, game_params=game_params, model_params=model_params, out=args.out, skip=args.skip, auto_tune_nnsize=args.auto_tune_nnsize, zero_shot=args.zero_shot, move_source_channels=args.move_source_channels, state_source_channels=args.state_source_channels, ) def draw_model_from_args(args: argparse.Namespace): game_params = instanciate_params_from_args(GameParams, args) model_params = instanciate_params_from_args(ModelParams, args) draw_model( game_params=game_params, model_params=model_params, out=args.out, ) def run_training_and_evaluation_from_args_warning(args: argparse.Namespace): # pypolygames called directly if len(sys.argv) == 1: print(DOC) # otherwise default to traineval else: warnings.warn( "'pypolygames' called with arguments runs as 'pypolygames traineval'", DeprecationWarning, ) run_training_and_evaluation_from_args(args) if __name__ == "__main__": args = parse_args() args.func(args) ================================================ FILE: pypolygames/convert.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import time from typing import Iterator, Tuple, Callable, Optional, List, Dict from pathlib import Path import copy import torch import polygames from . import utils from .model_zoo import utils as zutils from .params import GameParams, ModelParams, SimulationParams, ExecutionParams from .env_creation_helpers import ( sanitize_game_params, create_model, create_game, create_player, ) def convert_checkpoint( command_history: utils.CommandHistory, game_params: GameParams, model_params: ModelParams, out: str, skip: List[str], auto_tune_nnsize: bool, zero_shot: bool, move_source_channels: List[int], state_source_channels: List[int], ): checkpoint = utils.load_checkpoint( checkpoint_path=model_params.init_checkpoint) old_model_params = checkpoint["model_params"] old_game_params = checkpoint["game_params"] sanitize_game_params(old_game_params) # backwards compatibility for models without game_options model_state_dict = checkpoint["model_state_dict"] print(old_model_params.model_name) print(getattr(old_model_params, "model_name")) new_model_params = copy.deepcopy(old_model_params) new_game_params = copy.deepcopy(old_game_params) for k, v in vars(model_params).items(): if not command_history.last_command_contains(k) or k == "init_checkpoint": continue ov = getattr(new_model_params, k) if v != ov: print("Changing %s from %s to %s" % (k, ov, v)) setattr(new_model_params, k, v) for k, v in vars(game_params).items(): if not command_history.last_command_contains(k): continue ov = getattr(new_game_params, k) if v != ov: print("Changing %s from %s to %s" % (k, ov, v)) setattr(new_game_params, k, v) fix_global_pooling = old_model_params.model_name == "ResConvConvLogitPoolModelV2" and new_model_params.model_name == "ResConvConvLogitPoolModelV2" and new_model_params.global_pooling > 0 if fix_global_pooling: print("Note: attempting to patch global pooling weights to match the new model") if zero_shot: print("Note: converting model for zero-shot evaluation only! Added/reinitialized params will be all 0 and untrainable!") if auto_tune_nnsize or move_source_channels is not None or state_source_channels is not None: # We'll need to load the game info old_game_info = zutils.get_game_info(old_game_params) new_game_info = zutils.get_game_info(new_game_params) if auto_tune_nnsize: # We want to automatically tune nnsize, such that the number # of filters in hidden layers does not change from source to # target model c_old, _, _ = old_game_info["feature_size"][:3] c_new, _, _ = new_game_info["feature_size"][:3] new_nnsize = float((getattr(old_model_params, 'nnsize') * c_old) / c_new) print("Auto-tuning nnsize to:", new_nnsize) setattr(new_model_params, 'nnsize', new_nnsize) if move_source_channels is not None: c_action_new, _, _ = new_game_info["action_size"][:3] if c_action_new != len(move_source_channels): print("ERROR: if --move_source_channels is specified, it must have exactly c_action_new entries!") print("c_action_new = ", c_action_new) print("len(move_source_channels) = ", len(move_source_channels)) if state_source_channels is not None: c_state_new, _, _ = new_game_info["feature_size"][:3] if c_state_new != len(state_source_channels): print("ERROR: if --state_source_channels is specified, it must have exactly c_state_new entries!") print("c_state_new = ", c_state_new) print("len(state_source_channels) = ", len(state_source_channels)) m = create_model(game_params=new_game_params, model_params=new_model_params) s = m.state_dict() params_added = 0 params_removed = 0 params_reinitialized = 0 taken = [] for k, src in model_state_dict.items(): if not k in s: moved = False for k2, dst in s.items(): if not k2 in model_state_dict and src.shape == dst.shape and not k2 in taken: print("%s shape %s moved to %s" % (k, src.shape, k2)) taken.append(k2) dst.copy_(src) moved = True break if not moved: print("%s shape %s removed" % (k, src.shape)) params_removed += src.numel() for k, dst in s.items(): if k in taken: continue if zero_shot: dst = dst.fill_(0) if skip is not None and k in skip: print("%s shape %s skipped" % (k, dst.shape)) params_reinitialized += dst.numel() continue if not k in model_state_dict: params_added += dst.numel() continue src = model_state_dict[k] if move_source_channels is not None and "pi_logit." in k: # Use manually specified channels to transfer from for # last Conv2D operation that produces pi logits if "weight" in k: for i in range(len(move_source_channels)): if move_source_channels[i] >= 0: dst_view = dst src_view = src for j in range(dst_view.dim()): if j == 0: # Don't narrow this dim, need original indexing continue if src_view.shape[j] > dst_view.shape[j]: src_view = src_view.narrow(j, 0, dst_view.shape[j]) if dst_view.shape[j] > src_view.shape[j]: dst_view = dst_view.narrow(j, 0, src_view.shape[j]) dst_view[i] = src_view[move_source_channels[i]] elif "bias" in k: for i in range(len(move_source_channels)): if move_source_channels[i] >= 0: dst[i] = src[move_source_channels[i]] continue if state_source_channels is not None and "mono.0." in k: # Use manually specified channels to transfer from for # first Conv2D operation on state tensor if "weight" in k: for i in range(len(state_source_channels)): if state_source_channels[i] >= 0: dst_view = dst src_view = src for j in range(dst_view.dim()): if j == 1: # Don't narrow this dim, need original indexing continue if src_view.shape[j] > dst_view.shape[j]: src_view = src_view.narrow(j, 0, dst_view.shape[j]) if dst_view.shape[j] > src_view.shape[j]: dst_view = dst_view.narrow(j, 0, src_view.shape[j]) dst_view[:, i] = src_view[:, state_source_channels[i]] elif "bias" in k: for i in range(len(state_source_channels)): if state_source_channels[i] >= 0: dst[i] = src[state_source_channels[i]] continue delta = dst.numel() - src.numel() if delta > 0: params_added += delta else: params_removed -= delta if dst.shape != src.shape: print("%s shape %s -> %s" % (k, src.shape, dst.shape)) if fix_global_pooling and "resnets" in k and "0.0" in k and "weight" in k: if src.dim() == 4 and dst.dim() == 4: src_c = src.shape[0] dst_c = dst.shape[0] src_s = int(src_c * old_model_params.global_pooling) dst_s = int(dst_c * new_model_params.global_pooling) src_d = src_c + src_s dst_d = dst_c + src_s print("Moving global pooling weights from %d:%d to %d:%d" % (src_c, src_d, dst_c, dst_d)) min_c = min(src_c, dst_c) dst[:min_c, dst_c:dst_d, :, :] = src[:min_c, src_c:src_d, :, :] #dst.narrow(0, 0, src_c).narrow(1, dst_c, src_s).copy_(src.narrow(1, src_c, src_s)) print("Moving global pooling weights from %d:%d to %d:%d" % (src_c+src_s, src_d+src_s, dst_c+dst_s, dst_d+dst_s)) #dst.narrow(0, 0, src_c).narrow(1, dst_c+dst_s, src_s).copy_(src.narrow(1, src_c+src_s, src_s)) dst[:min_c, dst_c+dst_s:dst_d+dst_s, :, :] = src[:min_c, src_c+src_s:src_d+src_s, :, :] src = src[:, :src_c, :, :] dst = dst[:, :dst_c, :, :] #src = src.narrow(1, 0, src_c) #dst = dst.narrow(1, 0, dst_c) while dst.dim() < src.dim(): dst = dst.unsqueeze(0) while src.dim() < dst.dim(): src = src.unsqueeze(0) for i in range(dst.dim()): if src.shape[i] > dst.shape[i]: src = src.narrow(i, 0, dst.shape[i]) if dst.shape[i] > src.shape[i]: dst = dst.narrow(i, 0, src.shape[i]) dst.copy_(src) print("Parameters added: %d" % params_added) print("Parameters removed: %d" % params_removed) print("Parameters reinitialized: %d" % params_reinitialized) checkpoint["model_state_dict"] = s checkpoint["model_params"] = new_model_params checkpoint["game_params"] = new_game_params Path(out).parent.mkdir(parents=True, exist_ok=True) import gzip with gzip.open(out, "wb") as f: torch.save(checkpoint, f) ================================================ FILE: pypolygames/draw_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import time from typing import Iterator, Tuple, Callable, Optional, List, Dict import copy import torch import polygames from .model_zoo.utils import get_game_info from .params import GameParams, ModelParams from .env_creation_helpers import ( create_model, ) def draw_model( game_params: GameParams, model_params: ModelParams, out: str, ): import torchviz m = create_model(game_params=game_params, model_params=model_params) info = get_game_info(game_params) m.eval() # necessary for batch norm as it expects more than 1 ex in training feature_size = info["feature_size"][:3] action_size = info["action_size"][:3] input_data = torch.zeros([1] + feature_size, device=torch.device("cpu")) model_out = m(input_data) dot = torchviz.make_dot((model_out["v"], model_out["pi_logit"]), params=dict(list(m.named_parameters()))) dot.format = 'png' dot.render(out) ================================================ FILE: pypolygames/env_creation_helpers.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from typing import Optional, Iterator, List import torch # must be loaded before tube import tube import mcts import polygames from . import model_zoo from .params import GameParams, ModelParams from .weight_init import WEIGHT_INIT def sanitize_game_params(game_params: GameParams) -> None: # eval and human modes do not support `per_thread_batchsize` != 0 # while in training, the option could have been set to > 0 # ideally this should be a simulation parameter, but it would change # the C++ 'polygames.Game' signature # EDIT: now it a simulation parameter, but for retro-compatibility # we keep that function game_params.per_thread_batchsize = 0 # Many old models don't have the game_options attribute if not hasattr(game_params, 'game_options'): game_params.game_options = list() def create_game( game_params: GameParams, num_episode: int, seed: int, eval_mode: bool, per_thread_batchsize: int = 0, rewind: int = 0, predict_end_state: bool = False, predict_n_states: int = 0, ) -> polygames.Game: # Many old models don't have the game_options attribute if hasattr(game_params, 'game_options'): game_options = game_params.game_options if game_options is None: game_options = list() else: game_options = list() return polygames.Game( game_params.game_name, game_options, num_episode, seed, eval_mode, game_params.out_features, game_params.turn_features, game_params.turn_features_mc, game_params.geometric_features, game_params.history, game_params.random_features, game_params.one_feature, per_thread_batchsize, rewind, predict_end_state, predict_n_states, ) # cannot use named parameters :( def create_model( game_params: GameParams, model_params: ModelParams, resume_training: bool = False, model_state_dict: Optional[dict] = None, ) -> torch.jit.ScriptModule: if model_params.model_name is not None: if model_params.model_name in model_zoo.MODELS: model = model_zoo.MODELS[model_params.model_name]( game_params=game_params, model_params=model_params ) else: raise RuntimeError( f'The model "{model_params.model_name}" has not been implemented ' f'in the "model_zoo" package' ) else: print("creating a generic model") model = model_zoo.GenericModel( game_params=game_params, model_params=model_params ) if resume_training: if model_state_dict is not None: print("load state dict!") model.load_state_dict(model_state_dict) else: model.apply(WEIGHT_INIT[model_params.init_method]) nb_params = sum(p.numel() for p in model.parameters() if p.requires_grad) print(f"total #trainable params = {nb_params}") return model def _set_mcts_option( num_rollouts: int, seed: int, human_mode: bool = False, time_ratio: float = 0.7, total_time: float = 0, sample_before_step_idx: int = 0, randomized_rollouts: bool = False, sampling_mcts: bool = False, ) -> mcts.MctsOption: # TODO: put hardcoded value in conf file mcts_option = mcts.MctsOption() mcts_option.puct = 1.1 mcts_option.sample_before_step_idx = sample_before_step_idx mcts_option.num_rollout_per_thread = num_rollouts mcts_option.seed = seed mcts_option.virtual_loss = 1 mcts_option.total_time = total_time mcts_option.time_ratio = time_ratio mcts_option.randomized_rollouts = randomized_rollouts mcts_option.sampling_mcts = sampling_mcts return mcts_option def _create_pure_mcts_player( game: polygames.Game, mcts_option: mcts.MctsOption, num_actor: int ) -> mcts.MctsPlayer: """a player that uses only mcts + random rollout, no neural net""" player = mcts.MctsPlayer(mcts_option) for _ in range(num_actor): actor = polygames.Actor( None, game.get_feat_size(), game.get_action_size(), [], 0, False, False, False, None ) player.set_actor(actor) return player def _create_neural_mcts_player( game: polygames.Game, mcts_option: mcts.MctsOption, num_actor: int, actor_channel: tube.DataChannel, model_manager: Optional[polygames.ModelManager] = None, rnn_state_shape: List[int] = [], rnn_seqlen: int = 0, logit_value: bool = False, ) -> mcts.MctsPlayer: player = mcts.MctsPlayer(mcts_option) for _ in range(num_actor): num_actor += 1 actor = polygames.Actor( actor_channel, game.get_feat_size(), game.get_action_size(), rnn_state_shape, rnn_seqlen, logit_value, True, True, model_manager, ) player.set_actor(actor) return player def _create_forward_player( game: polygames.Game, actor_channel: tube.DataChannel, model_manager: Optional[polygames.ModelManager] = None, rnn_state_shape: List[int] = [], rnn_seqlen: int = 0, logit_value: bool = False, ) -> mcts.MctsPlayer: player = polygames.ForwardPlayer() actor = polygames.Actor( actor_channel, game.get_feat_size(), game.get_action_size(), rnn_state_shape, rnn_seqlen, logit_value, True, True, model_manager, ) player.set_actor(actor) return player def create_player( seed_generator: Iterator[int], game: polygames.Game, player: str, num_actor: int, num_rollouts: int, pure_mcts: bool, actor_channel: Optional[tube.DataChannel], model_manager: Optional[polygames.ModelManager] = None, human_mode: bool = False, time_ratio: float = 0.07, total_time: float = 0, sample_before_step_idx: int = 0, randomized_rollouts: bool = False, sampling_mcts: bool = False, rnn_state_shape: List[int] = [], rnn_seqlen: int = 0, logit_value: bool = False, ): if player == "mcts": mcts_option = _set_mcts_option( num_rollouts=num_rollouts, seed=next(seed_generator), human_mode=human_mode, time_ratio=time_ratio, total_time=total_time, sample_before_step_idx=sample_before_step_idx, randomized_rollouts=randomized_rollouts, sampling_mcts=sampling_mcts, ) if pure_mcts: return _create_pure_mcts_player( game=game, mcts_option=mcts_option, num_actor=num_actor ) else: return _create_neural_mcts_player( game=game, mcts_option=mcts_option, num_actor=num_actor, actor_channel=actor_channel, model_manager=model_manager, rnn_state_shape=rnn_state_shape, rnn_seqlen=rnn_seqlen, logit_value=logit_value ) elif player == "forward": return _create_forward_player( game=game, actor_channel=actor_channel, model_manager=model_manager, rnn_state_shape=rnn_state_shape, rnn_seqlen=rnn_seqlen, logit_value=logit_value ) else: raise RuntimeError("Unknown player " + player) ================================================ FILE: pypolygames/evaluation.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import os import sys import time from concurrent.futures import ThreadPoolExecutor from typing import Iterator, Tuple, List, Callable, Optional, Dict import torch import tube from pytube.data_channel_manager import DataChannelManager from .params import GameParams, EvalParams, ExecutionParams from . import utils from .env_creation_helpers import ( sanitize_game_params, create_model, create_game, create_player, ) ####################################################################################### # PLOTTER CREATION ####################################################################################### def create_plotter(eval_params: EvalParams) -> utils.Plotter: checkpoint_dir = eval_params.checkpoint_dir if checkpoint_dir[-1] == "/": checkpoint_dir = checkpoint_dir[:-1] plot_env = os.path.basename(checkpoint_dir) return utils.Plotter( plot_enabled=eval_params.plot_enabled, env=plot_env, server=eval_params.plot_server, port=eval_params.plot_port, ) ####################################################################################### # CHECKPOINT ITERATOR CREATION ####################################################################################### def create_checkpoint_iter(eval_params: EvalParams, only_last: bool = False): if eval_params.checkpoint_dir is not None: return utils.gen_checkpoints( checkpoint_dir=eval_params.checkpoint_dir, real_time=eval_params.real_time and not only_last, only_last=only_last, ) else: return [utils.load_checkpoint(eval_params.checkpoint)] ####################################################################################### # OPPONENT MODEL AND DEVICE CREATION ####################################################################################### def create_models_and_devices_opponent( eval_params: EvalParams ) -> Tuple[List[torch.jit.ScriptModule], List[torch.device], GameParams]: devices_opponent = [ torch.device(device_opponent) for device_opponent in eval_params.device_opponent ] checkpoint_opponent = utils.load_checkpoint(eval_params.checkpoint_opponent) model_state_dict_opponent = checkpoint_opponent["model_state_dict"] game_params_opponent = checkpoint_opponent["game_params"] sanitize_game_params(game_params_opponent) model_params_opponent = checkpoint_opponent["model_params"] models_opponent = [] for device_opponent in devices_opponent: model_opponent = create_model( game_params=game_params_opponent, model_params=model_params_opponent, resume_training=False, ).to(device_opponent) remove = [] for k, v in model_state_dict_opponent.items(): if "training" in k: remove.append(k) for k in remove: model_state_dict_opponent.pop(k) model_opponent.load_state_dict(model_state_dict_opponent) model_opponent.eval() models_opponent.append(model_opponent) return models_opponent, devices_opponent, game_params_opponent ####################################################################################### # EVALUATION ENVIRONMENT CREATION ####################################################################################### def create_evaluation_environment( seed_generator: Iterator[int], game_params: GameParams, eval_params: EvalParams, current_batch_size: int = None, pure_mcts_eval: bool = False, pure_mcts_opponent: bool = True, num_evaluated_games: int = 0 ) -> Tuple[ tube.Context, Optional[tube.DataChannel], Optional[tube.DataChannel], Callable[[], List[int]], ]: num_game = eval_params.num_game_eval num_actor_eval = eval_params.num_actor_eval num_rollouts_eval = eval_params.num_rollouts_eval num_actor_opponent = eval_params.num_actor_opponent num_rollouts_opponent = eval_params.num_rollouts_opponent first_hand = [] second_hand = [] games = [] context = tube.Context() actor_channel_eval = ( None if pure_mcts_eval else tube.DataChannel("act_eval", num_game * num_actor_eval, 1) ) actor_channel_opponent = ( None if pure_mcts_opponent else tube.DataChannel("act_opponent", num_game * num_actor_opponent, 1) ) for game_no in range(current_batch_size if current_batch_size else num_game): game = create_game( game_params, num_episode=1, seed=next(seed_generator), eval_mode=True ) player = create_player( seed_generator=seed_generator, game=game, player="mcts", num_actor=num_actor_eval, num_rollouts=num_rollouts_eval, pure_mcts=pure_mcts_eval, actor_channel=actor_channel_eval, model_manager=None, human_mode=False, sample_before_step_idx=8, randomized_rollouts=False, sampling_mcts=False, ) if game.is_one_player_game(): game.add_eval_player(player) first_hand.append(game) else: opponent = create_player( seed_generator=seed_generator, game=game, player="mcts", num_actor=num_actor_opponent, num_rollouts=num_rollouts_opponent, pure_mcts=pure_mcts_opponent, actor_channel=actor_channel_opponent, model_manager=None, human_mode=False, sample_before_step_idx=8, randomized_rollouts=False, sampling_mcts=False, ) game_id = num_evaluated_games + game_no if player_moves_first(game_id, num_game): game.add_eval_player(player) game.add_eval_player(opponent) first_hand.append(game) else: game.add_eval_player(opponent) game.add_eval_player(player) second_hand.append(game) context.push_env_thread(game) games.append(game) def get_eval_reward(): nonlocal first_hand, second_hand reward = [] for hand in first_hand: reward.append(hand.get_result()[0]) for hand in second_hand: reward.append(hand.get_result()[1]) return reward return context, actor_channel_eval, actor_channel_opponent, get_eval_reward def player_moves_first(game_id, num_games_eval): return game_id < num_games_eval // 2 ####################################################################################### # EVALUATION ####################################################################################### def _forward_pass_on_device( device: torch.device, model: torch.jit.ScriptModule, batch_s: torch.Tensor ) -> Dict[str, torch.Tensor]: batch_s = utils.to_device(batch_s, device) with torch.no_grad(): reply = model(batch_s) return reply def _play_game_neural_mcts_against_pure_mcts_opponent( context: tube.Context, actor_channel_eval: tube.DataChannel, devices_eval: List[torch.device], models_eval: List[torch.jit.ScriptModule], ) -> None: nb_devices_eval = len(devices_eval) context.start() dcm = DataChannelManager([actor_channel_eval]) while not context.terminated(): batch = dcm.get_input(max_timeout_s=1) if len(batch) == 0: continue assert len(batch) == 1 # only one channel # split in as many part as there are devices batches_eval_s = torch.chunk( batch[actor_channel_eval.name]["s"], nb_devices_eval, dim=0 ) futures = [] reply_eval = {"v": None, "pi_logit": None} # multithread with ThreadPoolExecutor(max_workers=nb_devices_eval) as executor: for device, model, batch_s in zip( devices_eval, models_eval, batches_eval_s ): futures.append( executor.submit(_forward_pass_on_device, device, model, batch_s) ) results = [future.result() for future in futures] reply_eval["v"] = torch.cat([result["v"] for result in results], dim=0) reply_eval["pi_logit"] = torch.cat([result["pi_logit"] for result in results], dim=0) dcm.set_reply(actor_channel_eval.name, reply_eval) dcm.terminate() def _play_game_neural_mcts_against_neural_mcts_opponent( context: tube.Context, actor_channel_eval: tube.DataChannel, actor_channel_opponent: tube.DataChannel, devices_eval: List[torch.device], models_eval: List[torch.jit.ScriptModule], devices_opponent: List[torch.device], models_opponent: List[torch.jit.ScriptModule], ) -> None: nb_devices_eval = len(devices_eval) nb_devices_opponent = len(devices_opponent) context.start() dcm = DataChannelManager([actor_channel_eval, actor_channel_opponent]) while not context.terminated(): batch = dcm.get_input(max_timeout_s=1) if len(batch) == 0: continue assert len(batch) <= 2 # up to two channels if actor_channel_eval.name in batch: # split in as many part as there are devices batches_eval_s = torch.chunk( batch[actor_channel_eval.name]["s"], nb_devices_eval, dim=0 ) futures = [] reply_eval = {"v": None, "pi_logit": None} # multithread with ThreadPoolExecutor(max_workers=nb_devices_eval) as executor: for device, model, batch_s in zip( devices_eval, models_eval, batches_eval_s ): futures.append( executor.submit(_forward_pass_on_device, device, model, batch_s) ) results = [future.result() for future in futures] reply_eval["v"] = torch.cat([result["v"] for result in results], dim=0) reply_eval["pi_logit"] = torch.cat( [result["pi_logit"] for result in results], dim=0 ) dcm.set_reply(actor_channel_eval.name, reply_eval) if actor_channel_opponent.name in batch: # split in as many part as there are devices batches_opponent_s = torch.chunk( batch[actor_channel_opponent.name]["s"], nb_devices_opponent, dim=0 ) futures = [] reply_opponent = {"v": None, "pi_logit": None} # multithread with ThreadPoolExecutor(max_workers=nb_devices_opponent) as executor: for device, model, batch_s in zip( devices_opponent, models_opponent, batches_opponent_s ): futures.append( executor.submit(_forward_pass_on_device, device, model, batch_s) ) results = [future.result() for future in futures] reply_opponent["v"] = torch.cat( [result["v"] for result in results], dim=0 ) reply_opponent["pi_logit"] = torch.cat( [result["pi_logit"] for result in results], dim=0 ) dcm.set_reply(actor_channel_opponent.name, reply_opponent) dcm.terminate() def evaluate_on_checkpoint( game_params: GameParams, eval_params: EvalParams, context: tube.Context, actor_channel_eval: Optional[tube.DataChannel], actor_channel_opponent: Optional[tube.DataChannel], get_eval_reward: Callable[[], List[int]], devices_eval: Optional[List[torch.device]], models_eval: Optional[List[torch.jit.ScriptModule]], pure_mcts_eval: bool, devices_opponent: Optional[List[torch.device]], models_opponent: Optional[List[torch.jit.ScriptModule]], pure_mcts_opponent: bool, ) -> utils.Result: if eval_params.eval_verbosity: print(f"Playing {eval_params.num_game_eval} games of {game_params.game_name}:") print( f"- {'pure MCTS' if pure_mcts_eval else type(models_eval[0]).__name__} " f"player uses " f"{eval_params.num_rollouts_eval} rollouts per actor " f"with {eval_params.num_actor_eval} " f"actor{'s' if eval_params.num_actor_eval > 1 else ''}" ) print( f"- {'pure MCTS' if pure_mcts_opponent else type(models_opponent[0]).__name__} " f"opponent uses " f"{eval_params.num_rollouts_opponent} rollouts per actor " f"with {eval_params.num_actor_opponent} " f"actor{'s' if eval_params.num_actor_opponent > 1 else ''}" ) if pure_mcts_eval: pass # not implemented else: if pure_mcts_opponent: _play_game_neural_mcts_against_pure_mcts_opponent( context=context, actor_channel_eval=actor_channel_eval, devices_eval=devices_eval, models_eval=models_eval, ) else: _play_game_neural_mcts_against_neural_mcts_opponent( context=context, actor_channel_eval=actor_channel_eval, actor_channel_opponent=actor_channel_opponent, devices_eval=devices_eval, models_eval=models_eval, devices_opponent=devices_opponent, models_opponent=models_opponent, ) result = utils.Result(get_eval_reward()) if eval_params.eval_verbosity >= 2: print("@@@eval: %s" % result.log()) return result ####################################################################################### # OVERALL EVALUATION WORKFLOW ####################################################################################### def run_evaluation(eval_params: EvalParams, execution_params: ExecutionParams, only_last: bool = False) -> None: start_time = time.time() logger_dir = eval_params.checkpoint_dir if eval_params.checkpoint_dir is None: logger_dir = os.path.dirname(eval_params.checkpoint) logger_path = os.path.join(logger_dir, "eval.log") sys.stdout = utils.Logger(logger_path) print("#" * 70) print("#" + "EVALUATION".center(68) + "#") print("#" * 70) # evaluation is done on a NN-powered MCTS pure_mcts_eval = False print("setting-up pseudo-random generator...") seed_generator = utils.generate_random_seeds(seed=eval_params.seed_eval) if eval_params.plot_enabled: print("creating plotter...") plotter = create_plotter(eval_params=eval_params) print("finding checkpoints...") checkpoint_iter = create_checkpoint_iter( eval_params=eval_params, only_last=only_last ) models_opponent = [] pure_mcts_opponent = True devices_opponent = None game_params_opponent = None if eval_params.checkpoint_opponent is not None: print("creating opponent model(s) and device(s)...") pure_mcts_opponent = False ( models_opponent, devices_opponent, game_params_opponent, ) = create_models_and_devices_opponent(eval_params=eval_params) results = [] first_checkpoint = False game_params = None for checkpoint in checkpoint_iter: epoch = checkpoint.get("epoch", 0) # 0 when checkpoint_dir is None model_state_dict_eval = checkpoint["model_state_dict"] model_params_eval = checkpoint["model_params"] if game_params is None: game_params = checkpoint["game_params"] sanitize_game_params(game_params) # check that game_params are consistent between the model_eval and # the model_opponent if game_params_opponent is not None and game_params != game_params_opponent: raise ValueError( "The game parameters between the model to be tested" "and the opponent model are different" ) # check that game_params are consistent from one epoch to the other checkpoint_game_params = checkpoint["game_params"] sanitize_game_params(checkpoint_game_params) if game_params != checkpoint_game_params: raise ValueError(f"The game parameters have changed at checkpoint #{epoch}") if not first_checkpoint: print("creating model(s) and device(s)...") devices_eval = [ torch.device(device_eval) for device_eval in eval_params.device_eval ] models_eval = [] for device_eval in devices_eval: models_eval.append( create_model( game_params=game_params, model_params=model_params_eval, resume_training=False, ).to(device_eval) ) first_checkpoint = True print("updating model(s)...") for model_eval in models_eval: model_eval.load_state_dict(model_state_dict_eval) model_eval.eval() num_evaluated_games = 0 rewards = [] eval_batch_size = eval_params.num_parallel_games_eval if eval_params.num_parallel_games_eval else eval_params.num_game_eval print("evaluating {} games with batches of size {}".format(eval_params.num_game_eval, eval_batch_size)) while num_evaluated_games < eval_params.num_game_eval: if eval_params.eval_verbosity: print("creating evaluation environment...") current_batch_size = min(eval_batch_size, eval_params.num_game_eval - num_evaluated_games) ( context, actor_channel_eval, actor_channel_opponent, get_eval_reward, ) = create_evaluation_environment( seed_generator=seed_generator, game_params=game_params, eval_params=eval_params, current_batch_size=current_batch_size, pure_mcts_eval=pure_mcts_eval, pure_mcts_opponent=pure_mcts_opponent, num_evaluated_games=num_evaluated_games, ) if eval_params.eval_verbosity: print("evaluating...") partial_result = evaluate_on_checkpoint( game_params=game_params, eval_params=eval_params, context=context, actor_channel_eval=actor_channel_eval, actor_channel_opponent=actor_channel_opponent, get_eval_reward=get_eval_reward, devices_eval=devices_eval, models_eval=models_eval, pure_mcts_eval=pure_mcts_eval, devices_opponent=devices_opponent, models_opponent=models_opponent, pure_mcts_opponent=pure_mcts_opponent, ) num_evaluated_games += current_batch_size rewards += partial_result.reward elapsed_time = time.time() - start_time print(f"Evaluated on {num_evaluated_games} games in : {elapsed_time} s") result = utils.Result(rewards) print("@@@eval: %s" % result.log()) results.append((epoch, result)) if eval_params.plot_enabled: print("plotting...") plotter.plot_results(results) plotter.save() elapsed_time = time.time() - start_time print(f"total time: {elapsed_time} s") ================================================ FILE: pypolygames/human.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import time from concurrent.futures import ThreadPoolExecutor from typing import Iterator, Tuple, Callable, Optional, List, Dict import torch import tube import polygames from pytube.data_channel_manager import DataChannelManager from . import utils from .params import GameParams, ModelParams, SimulationParams, ExecutionParams from .env_creation_helpers import ( sanitize_game_params, create_model, create_game, create_player, ) ####################################################################################### # HUMAN-PLAYED ENVIRONMENT CREATION ####################################################################################### def create_human_environment( seed_generator: Iterator[int], game_params: GameParams, simulation_params: SimulationParams, execution_params: ExecutionParams, pure_mcts: bool, model ) -> Tuple[tube.Context, Optional[tube.DataChannel], Callable[[], int]]: human_first = execution_params.human_first time_ratio = execution_params.time_ratio total_time = execution_params.total_time context = tube.Context() actor_channel = ( None if pure_mcts else tube.DataChannel("act", simulation_params.num_actor, 1) ) rnn_state_shape = [] if model is not None and hasattr(model, "rnn_cells") and model.rnn_cells > 0: rnn_state_shape = [model.rnn_cells, model.rnn_channels] rnn_state_size = 0 if len(rnn_state_shape) >= 2: rnn_state_size = rnn_state_shape[0] * rnn_state_shape[1] logit_value = getattr(model, "logit_value", False) game = create_game( game_params, num_episode=1, seed=next(seed_generator), eval_mode=True, per_thread_batchsize=0, rewind=simulation_params.rewind, predict_end_state=game_params.predict_end_state, predict_n_states=game_params.predict_n_states, ) player = create_player( seed_generator=seed_generator, game=game, player="mcts", num_actor=simulation_params.num_actor, num_rollouts=simulation_params.num_rollouts, pure_mcts=pure_mcts, actor_channel=actor_channel, model_manager=None, human_mode=True, total_time=total_time, time_ratio=time_ratio, sample_before_step_idx=80, randomized_rollouts=False, sampling_mcts=False, rnn_state_shape=rnn_state_shape, rnn_seqlen=execution_params.rnn_seqlen, logit_value=logit_value, ) human_player = polygames.HumanPlayer() if game.is_one_player_game(): game.add_human_player(human_player) else: if human_first: game.add_human_player(human_player) game.add_eval_player(player) else: game.add_eval_player(player) game.add_human_player(human_player) context.push_env_thread(game) def get_result_for_human_player(): nonlocal game, human_first return game.get_result()[not human_first] return context, actor_channel, get_result_for_human_player def create_tp_environment( seed_generator: Iterator[int], game_params: GameParams, simulation_params: SimulationParams, execution_params: ExecutionParams, pure_mcts: bool, ) -> Tuple[tube.Context, Optional[tube.DataChannel], Callable[[], int]]: human_first = execution_params.human_first time_ratio = execution_params.time_ratio total_time = execution_params.total_time context = tube.Context() actor_channel = ( None if pure_mcts else tube.DataChannel("act", simulation_params.num_actor, 1) ) game = create_game( game_params, num_episode=1, seed=next(seed_generator), eval_mode=True, per_thread_batchsize=0, ) player = create_player( seed_generator=seed_generator, game=game, num_actor=simulation_params.num_actor, num_rollouts=simulation_params.num_rollouts, pure_mcts=pure_mcts, actor_channel=actor_channel, model_manager=None, human_mode=True, total_time=total_time, time_ratio=time_ratio, ) tp_player = polygames.TPPlayer() if game.is_one_player_game(): game.add_tp_player(tp_player) else: if human_first: game.add_tp_player(tp_player) game.add_eval_player(player) else: game.add_eval_player(player) game.add_tp_player(tp_player) context.push_env_thread(game) def get_result_for_tp_player(): nonlocal game, human_first return game.get_result()[not human_first] return context, actor_channel, get_result_for_tp_player ####################################################################################### # HUMAN-PLAYED GAME ####################################################################################### def _forward_pass_on_device( device: torch.device, model: torch.jit.ScriptModule, batch_s: torch.Tensor, batch_rnn_state: torch.Tensor = None ) -> Dict[str, torch.Tensor]: batch_s = utils.to_device(batch_s, device) if batch_rnn_state is not None: batch_rnn_state = utils.to_device(batch_rnn_state, device) with torch.no_grad(): reply = model(batch_s, batch_rnn_state) else: with torch.no_grad(): reply = model(batch_s) return reply def _play_game_against_mcts(context: tube.Context) -> None: context.start() while not context.terminated(): time.sleep(1) def _play_game_against_neural_mcts( devices: List[torch.device], models: List[torch.jit.ScriptModule], context: tube.Context, actor_channel: tube.DataChannel, ) -> None: nb_devices = len(devices) context.start() dcm = DataChannelManager([actor_channel]) # multithread with ThreadPoolExecutor(max_workers=nb_devices) as executor: while not context.terminated(): batch = dcm.get_input(max_timeout_s=1) if len(batch) == 0: continue assert len(batch) == 1 # split in as many part as there are devices batches_s = torch.chunk( batch[actor_channel.name]["s"], nb_devices, dim=0 ) has_rnn = "rnn_state" in batch[actor_channel.name] if has_rnn: batches_rnn_state = torch.chunk( batch[actor_channel.name]["rnn_state"], nb_devices, dim=0 ) futures = [] reply_eval = {"v": None, "pi_logit": None} if has_rnn: for device, model, batch_s, batch_rnn_state in zip( devices, models, batches_s, batches_rnn_state ): futures.append( executor.submit(_forward_pass_on_device, device, model, batch_s, batch_rnn_state) ) results = [future.result() for future in futures] reply_eval["v"] = torch.cat([result["v"] for result in results], dim=0) reply_eval["pi_logit"] = torch.cat([result["pi_logit"] for result in results], dim=0) reply_eval["rnn_state_out"] = torch.cat([result["rnn_state"] for result in results], dim=0) else: for device, model, batch_s in zip( devices, models, batches_s ): futures.append( executor.submit(_forward_pass_on_device, device, model, batch_s) ) results = [future.result() for future in futures] reply_eval["v"] = torch.cat([result["v"] for result in results], dim=0) reply_eval["pi_logit"] = torch.cat([result["pi_logit"] for result in results], dim=0) dcm.set_reply(actor_channel.name, reply_eval) dcm.terminate() def play_game( pure_mcts: bool, devices: Optional[List[torch.device]], models: Optional[List[torch.jit.ScriptModule]], context: tube.Context, actor_channel: Optional[tube.DataChannel], get_result_for_human_player: Callable[[], int], ) -> int: if pure_mcts: _play_game_against_mcts(context) else: _play_game_against_neural_mcts( devices=devices, models=models, context=context, actor_channel=actor_channel ) print("game over") return get_result_for_human_player() def play_tp_game( #FIXME TODO not sure this helps pure_mcts: bool, devices: Optional[List[torch.device]], models: Optional[List[torch.jit.ScriptModule]], context: tube.Context, actor_channel: Optional[tube.DataChannel], get_result_for_human_player: Callable[[], int], ) -> int: if pure_mcts: _play_game_against_mcts(context) else: _play_game_against_neural_mcts( devices=devices, models=models, context=context, actor_channel=actor_channel ) print("#game over") return get_result_for_human_player() ####################################################################################### # OVERALL HUMAN-PLAYED GAME WORKFLOW ####################################################################################### def run_human_played_game( game_params: GameParams, model_params: ModelParams, simulation_params: SimulationParams, execution_params: ExecutionParams, ): print("#" * 70) print("#" + "HUMAN-PLAYED GAME".center(68) + "#") print("#" * 70) print("setting-up pseudo-random generator...") seed_generator = utils.generate_random_seeds(seed=execution_params.seed) devices, models = None, None if not model_params.pure_mcts: print("loading pretrained model from checkpoint...") checkpoint = utils.load_checkpoint(checkpoint_path=model_params.init_checkpoint) game_params = checkpoint["game_params"] sanitize_game_params(game_params) model_params = checkpoint["model_params"] model_state_dict = checkpoint["model_state_dict"] del checkpoint print("creating model(s) and device(s)...") models = [] devices = [torch.device(device) for device in execution_params.devices] for device in devices: model = create_model(game_params=game_params, model_params=model_params).to( device ) print("updating model...") model.load_state_dict(model_state_dict) model.eval() models.append(model) print("creating human-played environment") context, actor_channel, get_result_for_human_player = create_human_environment( seed_generator=seed_generator, game_params=game_params, simulation_params=simulation_params, execution_params=execution_params, pure_mcts=model_params.pure_mcts, model=model ) print("playing against a human player...") human_score = play_game( pure_mcts=model_params.pure_mcts, devices=devices, models=models, context=context, actor_channel=actor_channel, get_result_for_human_player=get_result_for_human_player, ) print(f"result for the human human_player: {human_score}") def run_tp_played_game( game_params: GameParams, model_params: ModelParams, simulation_params: SimulationParams, execution_params: ExecutionParams, ): print("#" * 70) print("#" + "HUMAN-PLAYED GAME".center(68) + "#") print("#" * 70) print("#setting-up pseudo-random generator...") seed_generator = utils.generate_random_seeds(seed=execution_params.seed) devices, models = None, None if not model_params.pure_mcts: print("#loading pretrained model from checkpoint...") checkpoint = utils.load_checkpoint(checkpoint_path=model_params.init_checkpoint) game_params = checkpoint["game_params"] sanitize_game_params(game_params) model_params = checkpoint["model_params"] model_state_dict = checkpoint["model_state_dict"] del checkpoint print("#creating model(s) and device(s)...") models = [] devices = [torch.device(device) for device in execution_params.device] for device in devices: model = create_model(game_params=game_params, model_params=model_params).to( device ) print("#updating model...") model.load_state_dict(model_state_dict) model.eval() models.append(model) print("#creating human-played environment") context, actor_channel, get_result_for_human_player = create_tp_environment( seed_generator=seed_generator, game_params=game_params, simulation_params=simulation_params, execution_params=execution_params, pure_mcts=model_params.pure_mcts, ) print("#playing against a tp player...") human_score = play_tp_game( pure_mcts=model_params.pure_mcts, devices=devices, models=models, context=context, actor_channel=actor_channel, get_result_for_human_player=get_result_for_human_player, ) print(f"#result for the TP_player: {human_score}") ================================================ FILE: pypolygames/model_zoo/__init__.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from .generic_model import GenericModel from .amazons_model import AmazonsModel from .nano_fc_logit_model import NanoFCLogitModel from .nano_conv_logit_model import NanoConvLogitModel from .deep_conv_fc_logit_model import DeepConvFCLogitModel from .deep_conv_conv_logit_model import DeepConvConvLogitModel from .res_conv_fc_logit_model import ResConvFCLogitModel from .res_conv_conv_logit_model import ResConvConvLogitModel from .res_conv_conv_logit_pool_model import ResConvConvLogitPoolModel from .res_conv_conv_logit_pool_model_v2 import ResConvConvLogitPoolModelV2 from .u_conv_fc_logit_model import UConvFCLogitModel from .u_conv_conv_logit_model import UConvConvLogitModel from .connect4_benchmark_model import Connect4BenchModel from .utils import MODELS # directory where models are registered ================================================ FILE: pypolygames/model_zoo/amazons_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class AmazonsModel(torch.jit.ScriptModule): __constants__ = ["c_prime", "h_prime", "w_prime"] DEFAULT_FCSIZE = 1024 DEFAULT_NNSIZE = 4 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 default_game_name = "GameOfTheAmazons" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] # fc size if model_params.fcsize is None: model_params.fcsize = self.DEFAULT_FCSIZE fcsize = model_params.fcsize # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) self.model_params = model_params self.net1 = nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation ) self.net2 = nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, ) self.net3 = nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, ) self.net4 = nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, ) self.v1 = nn.Linear(int(nnsize * c) * h * w, fcsize) self.v2 = nn.Linear(fcsize, fcsize) self.v3 = nn.Linear(fcsize, 1) self.pi1 = nn.Linear(int(nnsize * c) * h * w, fcsize) self.pi2 = nn.Linear(fcsize, fcsize) self.pi3 = nn.Linear(fcsize, c_prime + h_prime + w_prime) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime bs = x.shape[0] h1 = nn.functional.relu(self.net1(x)) h2 = nn.functional.relu(self.net2(h1)) + h1 h3 = nn.functional.relu(self.net3(h2)) + h2 h4 = nn.functional.relu(self.net4(h3)) + h3 v = nn.functional.relu(self.v1(h4.flatten(1))) v = nn.functional.relu(self.v2(v)) v = torch.tanh(self.v3(v)) pi_logit = nn.functional.relu(self.pi1(h4.flatten(1))) pi_logit = nn.functional.relu(self.pi2(pi_logit)) pi_logit = nn.functional.relu(self.pi3(pi_logit)) if return_logit: v1 = pi_logit[:, :c_prime].reshape(-1, c_prime, 1, 1) v2 = pi_logit[:, c_prime : c_prime + h_prime].reshape(-1, 1, h_prime, 1) v3 = pi_logit[:, c_prime + h_prime :].reshape(-1, 1, 1, w_prime) # This representation is not sparse, that's a temporary hack # for testing the idea of a cartesian product. pi_logit = v1 + v2 + v3 return v, pi_logit # TODO(oteytaud): remove duplicate reshaping. v1 = nn.functional.softmax(pi_logit[:, :c_prime].reshape(-1, c_prime, 1, 1), 1) v2 = nn.functional.softmax( pi_logit[:, c_prime : c_prime + h_prime].reshape(-1, 1, h_prime, 1), 2 ) v3 = nn.functional.softmax( pi_logit[:, c_prime + h_prime :].reshape(-1, 1, 1, w_prime), 3 ) pi = v1 * v2 * v3 # pi = nn.functional.softmax(pi.view(pi.shape[0], -1), 1).reshape(pi.shape) # This representation is not sparse, that's a temporary hack # for testing the idea of a cartesian product. return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply def loss( self, model, x: torch.Tensor, v: torch.Tensor, pi: torch.Tensor, pi_mask: torch.Tensor, stat: utils.MultiCounter ) -> float: # print(x.size()) # print(x[0]) # print(v) # print(pi.size()) batchsize = pi.shape[0] # pi = pi.view(batchsize, -1) pred_v, pred_logit = self._forward(x, True) utils.assert_eq(v.size(), pred_v.size()) utils.assert_eq(pred_logit.size(), pi.size()) utils.assert_eq(pred_logit.dim(), 4) pred_logit = pred_logit * pi_mask.view(pred_logit.shape) # pred_logit = pred_logit.view(batchsize, -1) v_err = 0.5 * (v - pred_v).pow(2).squeeze(1) s = pred_logit.shape bs = x.shape[0] pred_log_pi = nn.functional.log_softmax(pred_logit.flatten(1), 1).reshape(s) # pred_log_pi = nn.functional.log_softmax(pred_logit, 1) pi_err = -(pred_log_pi * pi).reshape(bs, -1).sum(1) # why would these quantities be equal ? utils.assert_eq(v_err.size(), pi_err.size()) err = v_err + pi_err stat["v_err"].feed(v_err.detach().mean().item()) stat["pi_err"].feed(pi_err.detach().mean().item()) return err.mean() ================================================ FILE: pypolygames/model_zoo/connect4_benchmark_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn from . import utils as zutils from ..params import GameParams, ModelParams # import utils @zutils.register_model class Connect4BenchModel(torch.jit.ScriptModule): def __init__(self, game_params: GameParams, model_params: ModelParams): # def __init__(self): super().__init__() self.fc1 = nn.Linear(6 * 7 * 2, 200) self.fc2 = nn.Linear(200, 200) self.fc3 = nn.Linear(200, 200) self.fc_pi = nn.Linear(200, 7) self.fc_val = nn.Linear(200, 1) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): x = x[:, :2, :, :] # print(x.size()) x = x.view(-1, 84) h = nn.functional.relu(self.fc1(x)) h = nn.functional.relu(self.fc2(h)) h = nn.functional.relu(self.fc3(h)) v = self.fc_val(h) pi_logit = self.fc_pi(h) if return_logit: return v, pi_logit pi = nn.functional.softmax(pi_logit, 1) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, 7, 1, 1) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/deep_conv_conv_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class DeepConvConvLogitModel(torch.jit.ScriptModule): __constants__ = ["c_prime", "h_prime", "w_prime", "mono", "conv_nets"] DEFAULT_NB_NETS = 13 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Hex13" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] if h_prime != h or w_prime != w: raise RuntimeError( f'The game "{self.game_name}" is not eligible to a conv-computed logit ' f'model such as "{self.__class__.__name__}" - try with ' f'"{self.__class__.__name__.replace("ConvLogit", "FCLogit")}" instead' ) # nb identical hidden layers (first layer excepted) if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] conv_nets = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_nets) ] if pooling: for i in range(nb_nets): conv_nets[i] = nn.Sequential( conv_nets[i], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) for i in range(nb_nets): conv_nets[i] = nn.Sequential( conv_nets[i], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) self.mono = nn.Sequential(*mono) self.conv_nets = nn.ModuleList(conv_nets) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Conv2d( int(nnsize * c), c_prime, nnks, stride=stride, padding=padding, dilation=dilation ) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): bs = x.shape[0] h = F.relu(self.mono(x)) for conv_net in self.conv_nets: h = F.relu(conv_net(h)) v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h).flatten(1) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit.flatten(1), 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/deep_conv_fc_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class DeepConvFCLogitModel(torch.jit.ScriptModule): __constants__ = ["c_prime", "h_prime", "w_prime", "mono", "conv_nets"] DEFAULT_NB_NETS = 13 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Connect4" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] # nb identical hidden layers (first layer excepted) if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] conv_nets = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_nets) ] if pooling: for i in range(nb_nets): conv_nets[i] = nn.Sequential( conv_nets[i], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) for i in range(nb_nets): conv_nets[i] = nn.Sequential( conv_nets[i], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) self.mono = nn.Sequential(*mono) self.conv_nets = nn.ModuleList(conv_nets) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Linear(int(nnsize * c) * h * w, c_prime * h_prime * w_prime) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): bs = x.shape[0] h = F.relu(self.mono(x)) for conv_net in self.conv_nets: h = F.relu(conv_net(h)) v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h.flatten(1)) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit.flatten(1), 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/generic_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class GenericModel(torch.jit.ScriptModule): __constants__ = [ "c_prime", "h_prime", "w_prime", "net1", "net2", "net3", "net4", "v1", "v2", "pi1", "pi2", ] DEFAULT_FCSIZE = 1024 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Connect4" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] # fc size if model_params.fcsize is None: model_params.fcsize = self.DEFAULT_FCSIZE fcsize = model_params.fcsize # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params net1 = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] net2 = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] net3 = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] net4 = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] v1 = [nn.Linear(int(nnsize * c) * h * w, fcsize)] v2 = [nn.Linear(fcsize, fcsize)] pi1 = [nn.Linear(int(nnsize * c) * h * w, fcsize)] pi2 = [nn.Linear(fcsize, fcsize)] if bn or bn_affine: net1.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) net2.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) net3.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) net4.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) v1.append( nn.BatchNorm1d(fcsize, track_running_stats=True, affine=bn_affine) ) v2.append( nn.BatchNorm1d(fcsize, track_running_stats=True, affine=bn_affine) ) pi1.append( nn.BatchNorm1d(fcsize, track_running_stats=True, affine=bn_affine) ) pi2.append( nn.BatchNorm1d(fcsize, track_running_stats=True, affine=bn_affine) ) self.net1 = nn.Sequential(*net1) self.net2 = nn.Sequential(*net2) self.net3 = nn.Sequential(*net3) self.net4 = nn.Sequential(*net4) self.v1 = nn.Sequential(*v1) self.v2 = nn.Sequential(*v2) self.pi1 = nn.Sequential(*pi1) self.pi2 = nn.Sequential(*pi2) self.v3 = nn.Linear(fcsize, 1) self.pi3 = nn.Linear(fcsize, c_prime * h_prime * w_prime) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): h1 = F.relu(self.net1(x)) h2 = F.relu(self.net2(h1)) + h1 h3 = F.relu(self.net3(h2)) + h2 h4 = F.relu(self.net4(h3)) + h3 v1 = F.relu(self.v1(h4.flatten(1))) v2 = F.relu(self.v2(v1)) v = torch.tanh(self.v3(v2)) pi_logit1 = F.relu(self.pi1(h4.flatten(1))) pi_logit2 = F.relu(self.pi2(pi_logit1)) pi_logit = self.pi3(pi_logit2) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit.flatten(1), 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/loss.py ================================================ import torch from torch import nn import torch.nn.functional as F from typing import Tuple def mcts_loss( self, model, batch, ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: predicts = getattr(self, "predicts", 0) x = batch["s"] v = batch["v"] pi = batch["pi"] pi_mask = batch["pi_mask"] predict_pi = batch["predict_pi"] if predicts > 0 else None predict_pi_mask = batch["predict_pi_mask"] if predicts > 0 else None pi = pi.flatten(1) if predicts > 0: pred_v, pred_logit, pred_predict_logit = model._forward(x, return_logit=True) else: pred_v, pred_logit, *_ = model._forward(x, return_logit=True) pi_mask = pi_mask.view(pred_logit.shape); pred_logit = pred_logit * pi_mask - 400 * (1 - pi_mask) if predicts > 0: predict_pi_err = (F.mse_loss(pred_predict_logit, predict_pi, reduction="none") * predict_pi_mask).flatten(2).sum(2).flatten(1).mean(1) v_err = F.mse_loss(pred_v, v, reduction="none").squeeze(1) pred_log_pi = nn.functional.log_softmax(pred_logit.flatten(1), dim=1).view_as(pred_logit) * pi_mask pi_err = -(pred_log_pi * pi).sum(1) err = v_err * 1.5 + pi_err + (predict_pi_err * 0.1 if predicts > 0 else 0) return err.mean(), v_err.detach().mean(), pi_err.detach().mean(), (predict_pi_err.detach().mean() if predicts > 0 else None) ================================================ FILE: pypolygames/model_zoo/nano_conv_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class NanoConvLogitModel(torch.jit.ScriptModule): __constants__ = ["c_prime", "h_prime", "w_prime", "net"] DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Hex13" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] if h_prime != h or w_prime != w: raise RuntimeError( f'The game "{self.game_name}" is not eligible to a conv-computed logit ' f'model such as "{self.__class__.__name__}" - try with ' f'"{self.__class__.__name__.replace("ConvLogit", "FCLogit")}" instead' ) # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params net = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] if bn or bn_affine: net.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) self.net = nn.Sequential(*net) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Conv2d( int(nnsize * c), c_prime, nnks, stride=stride, padding=padding, dilation=dilation ) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): h = F.relu(self.net(x)) v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h).flatten(1) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit.flatten(1), 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/nano_fc_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class NanoFCLogitModel(torch.jit.ScriptModule): __constants__ = ["c_prime", "h_prime", "w_prime", "net"] DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Connect4" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params net = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] if bn or bn_affine: net.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) self.net = nn.Sequential(*net) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Linear(int(nnsize * c) * h * w, c_prime * h_prime * w_prime) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): h = F.relu(self.net(x)) v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h.flatten(1)) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit.flatten(1), 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/res_conv_conv_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class ResConvConvLogitModel(torch.jit.ScriptModule): __constants__ = [ "c_prime", "h_prime", "w_prime", "nb_layers_per_net", "mono", "resnets", ] DEFAULT_NB_NETS = 5 DEFAULT_NB_LAYERS_PER_NET = 3 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Hex13" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] if h_prime != h or w_prime != w: raise RuntimeError( f'The game "{self.game_name}" is not eligible to a conv-computed logit ' f'model such as "{self.__class__.__name__}" - try with ' f'"{self.__class__.__name__.replace("ConvLogit", "FCLogit")}" instead' ) # nb resnets if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets # nb layers per resnet if model_params.nb_layers_per_net is None: model_params.nb_layers_per_net = self.DEFAULT_NB_LAYERS_PER_NET nb_layers_per_net = model_params.nb_layers_per_net self.nb_layers_per_net = nb_layers_per_net # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] resnet_list = [] for i in range(nb_nets): nets = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) if pooling: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) resnet_list.append(nets) if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine), ) for i in range(nb_nets): for j in range(nb_layers_per_net): resnet_list[i][j] = nn.Sequential( resnet_list[i][j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) for i in range(nb_nets): resnet_list[i] = nn.ModuleList(resnet_list[i]) self.mono = nn.Sequential(*mono) self.resnets = nn.ModuleList(resnet_list) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Conv2d( int(nnsize * c), c_prime, nnks, stride=stride, padding=padding, dilation=dilation ) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): previous_block = self.mono(x) # linear transformation only for resnet in self.resnets: sublayer_no = 0 h = F.relu(previous_block) # initial activation for net in resnet: if sublayer_no < self.nb_layers_per_net - 1: h = F.relu(net(h)) else: h = net(h) + previous_block # linear transformation only previous_block = h sublayer_no = sublayer_no + 1 h = F.relu(previous_block) # final activation v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h).flatten(1) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit, 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/res_conv_conv_logit_pool_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class ResConvConvLogitPoolModel(torch.jit.ScriptModule): __constants__ = [ "c_prime", "h_prime", "w_prime", "nb_layers_per_net", "mono", "resnets", ] DEFAULT_NB_NETS = 5 DEFAULT_NB_LAYERS_PER_NET = 3 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Hex13" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] if h_prime != h or w_prime != w: raise RuntimeError( f'The game "{self.game_name}" is not eligible to a conv-computed logit ' f'model such as "{self.__class__.__name__}" - try with ' f'"{self.__class__.__name__.replace("ConvLogit", "FCLogit")}" instead' ) # nb resnets if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets # nb layers per resnet if model_params.nb_layers_per_net is None: model_params.nb_layers_per_net = self.DEFAULT_NB_LAYERS_PER_NET nb_layers_per_net = model_params.nb_layers_per_net self.nb_layers_per_net = nb_layers_per_net # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params batchnorm_momentum = model_params.batchnorm_momentum mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] resnet_list = [] for i in range(nb_nets): nets = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine, momentum=batchnorm_momentum ), ) if pooling: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) resnet_list.append(nets) if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine, momentum=batchnorm_momentum), ) for i in range(nb_nets): for j in range(nb_layers_per_net): resnet_list[i][j] = nn.Sequential( resnet_list[i][j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) for i in range(nb_nets): resnet_list[i] = nn.ModuleList(resnet_list[i]) self.mono = nn.Sequential(*mono) self.resnets = nn.ModuleList(resnet_list) self.v = nn.Linear(2 * int(nnsize * c), 1) self.pi_logit = nn.Conv2d( int(nnsize * c), c_prime, nnks, stride=stride, padding=padding, dilation=dilation ) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): previous_block = self.mono(x) # linear transformation only for resnet in self.resnets: sublayer_no = 0 h = F.relu(previous_block) # initial activation for net in resnet: if sublayer_no < self.nb_layers_per_net - 1: h = F.relu(net(h)) else: h = net(h) + previous_block # linear transformation only previous_block = h sublayer_no = sublayer_no + 1 h = F.relu(previous_block) # final activation pool = torch.cat((F.adaptive_max_pool2d(h, 1), F.adaptive_avg_pool2d(h, 1)), 1) v = torch.tanh(self.v(pool.flatten(1))) pi_logit = self.pi_logit(h).flatten(1) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit, 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, x.size(2), x.size(3)) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/res_conv_conv_logit_pool_model_v2.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from typing import Tuple from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class ResConvConvLogitPoolModelV2(torch.jit.ScriptModule): __constants__ = [ "c_prime", "h_prime", "w_prime", "nb_layers_per_net", "mono", "resnets", "global_pooling", ] DEFAULT_NB_NETS = 5 DEFAULT_NB_LAYERS_PER_NET = 3 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Hex13" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] r_c, r_h, r_w = info["raw_feature_size"] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] if h_prime != h or w_prime != w: raise RuntimeError( f'The game "{self.game_name}" is not eligible to a conv-computed logit ' f'model such as "{self.__class__.__name__}" - try with ' f'"{self.__class__.__name__.replace("ConvLogit", "FCLogit")}" instead' ) # nb resnets if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets # nb layers per resnet if model_params.nb_layers_per_net is None: model_params.nb_layers_per_net = self.DEFAULT_NB_LAYERS_PER_NET nb_layers_per_net = model_params.nb_layers_per_net self.nb_layers_per_net = nb_layers_per_net # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params self.global_pooling = model_params.global_pooling if model_params.activation_function == "relu": self.af = F.relu elif model_params.activation_function == "gelu": self.af = F.gelu elif model_params.activation_function == "celu": self.af = F.celu else: raise RuntimeError("Unknown activation function") batchnorm_momentum = model_params.batchnorm_momentum self.predict_end_state = game_params.predict_end_state self.predict_n_states = game_params.predict_n_states self.predicts = self.predict_n_states + (2 if self.predict_end_state else 0) print("global pooling ", self.global_pooling) print("af ", model_params.activation_function) mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] resnet_list = [] for i in range(nb_nets): nets = [ nn.Conv2d( int(nnsize * c) + int(nnsize * c * (self.global_pooling if _ == 0 else 0)) * 2, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine, momentum=batchnorm_momentum ), ) if pooling: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) resnet_list.append(nets) if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine, momentum=batchnorm_momentum), ) for i in range(nb_nets): resnet_list[i] = nn.ModuleList(resnet_list[i]) self.mono = nn.Sequential(*mono) self.resnets = nn.ModuleList(resnet_list) self.v = nn.Linear(2 * int(nnsize * c), 2 * int(nnsize * c)) self.v2 = nn.Linear(2 * int(nnsize * c), 1) self.pi_logit = nn.Conv2d( int(nnsize * c), c_prime, nnks, stride=stride, padding=padding, dilation=dilation ) if self.predicts > 0: self.predict_pi_logit = nn.Conv2d( int(nnsize * c), r_c * self.predicts, nnks, stride=stride, padding=padding, dilation=dilation ) else: self.predict_pi_logit = None @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): af = self.af global_pooling = self.global_pooling previous_block = self.mono(x) # linear transformation only for resnet in self.resnets: sublayer_no = 0 h = previous_block if global_pooling > 0: hpart = h.narrow(1, 0, int(h.size(1) * global_pooling)) h = torch.cat((h, F.adaptive_max_pool2d(hpart, 1).expand_as(hpart), F.adaptive_avg_pool2d(hpart, 1).expand_as(hpart)), 1) h = af(h) # initial activation for net in resnet: if sublayer_no < self.nb_layers_per_net - 1: h = af(net(h)) else: h = net(h) + previous_block # linear transformation only previous_block = h sublayer_no = sublayer_no + 1 h = af(previous_block) # final activation pool = torch.cat((F.adaptive_max_pool2d(h, 1), F.adaptive_avg_pool2d(h, 1)), 1) pi_logit = self.pi_logit(h).flatten(1) v = af(self.v(pool.flatten(1))) v = torch.tanh(self.v2(v)) if return_logit: if self.predict_pi_logit is not None: predict_pi_logit = self.predict_pi_logit(h) return v, pi_logit, predict_pi_logit else: return v, pi_logit, torch.empty(0) s = pi_logit.shape pi = F.softmax(pi_logit.float(), 1).reshape(s) return v, pi, torch.empty(0) @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit, _ = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, x.size(2), x.size(3)) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/res_conv_fc_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class ResConvFCLogitModel(torch.jit.ScriptModule): __constants__ = [ "c_prime", "h_prime", "w_prime", "nb_layers_per_net", "mono", "resnets", ] DEFAULT_NB_NETS = 5 DEFAULT_NB_LAYERS_PER_NET = 3 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Connect4" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] # nb resnets if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets # nb layers per resnet if model_params.nb_layers_per_net is None: model_params.nb_layers_per_net = self.DEFAULT_NB_LAYERS_PER_NET nb_layers_per_net = model_params.nb_layers_per_net self.nb_layers_per_net = nb_layers_per_net # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] resnet_list = [] for i in range(nb_nets): nets = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) if pooling: for j in range(nb_layers_per_net): nets[j] = nn.Sequential( nets[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) resnet_list.append(nets) if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine), ) for i in range(nb_nets): for j in range(nb_layers_per_net): resnet_list[i][j] = nn.Sequential( resnet_list[i][j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) for i in range(nb_nets): resnet_list[i] = nn.ModuleList(resnet_list[i]) self.mono = nn.Sequential(*mono) self.resnets = nn.ModuleList(resnet_list) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Linear(int(nnsize * c) * h * w, c_prime * h_prime * w_prime) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): previous_block = self.mono(x) # linear transformation only for resnet in self.resnets: sublayer_no = 0 h = F.relu(previous_block) # initial activation for net in resnet: if sublayer_no < self.nb_layers_per_net - 1: h = F.relu(net(h)) else: h = net(h) + previous_block # linear transformation only previous_block = h sublayer_no = sublayer_no + 1 h = F.relu(previous_block) # final activation v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h.flatten(1)) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit, 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/u_conv_conv_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class UConvConvLogitModel(torch.jit.ScriptModule): __constants__ = [ "c_prime", "h_prime", "w_prime", "nb_layers_per_net", "mono", "nb_unets_div_by_2", "unets", ] DEFAULT_NB_NETS = 5 DEFAULT_NB_LAYERS_PER_NET = 3 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Hex13" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] if h_prime != h or w_prime != w: raise RuntimeError( f'The game "{self.game_name}" is not eligible to a conv-computed logit ' f'model such as "{self.__class__.__name__}" - try with ' f'"{self.__class__.__name__.replace("ConvLogit", "FCLogit")}" instead' ) # nb unets if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets if nb_nets % 2 == 0: raise RuntimeError( f'The model "{self.__class__.__name__}" accepts only odd numbers ' f'for "nb_nets" while it was set to {nb_nets}' ) self.nb_unets_div_by_2 = nb_unets_div_by_2 = nb_nets // 2 # nb layers per unet if model_params.nb_layers_per_net is None: model_params.nb_layers_per_net = self.DEFAULT_NB_LAYERS_PER_NET nb_layers_per_net = model_params.nb_layers_per_net self.nb_layers_per_net = nb_layers_per_net # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) self.mono = nn.Sequential(*mono) unet_list = [None] * (2 * nb_unets_div_by_2 + 1) for i in range(nb_unets_div_by_2): nets1 = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] nets2 = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): nets1[j] = nn.Sequential( nets1[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) nets2[j] = nn.Sequential( nets2[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) if pooling: for j in range(nb_layers_per_net): nets1[j] = nn.Sequential( nets1[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) nets2[j] = nn.Sequential( nets2[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) unet_list[i] = nn.ModuleList(nets1) unet_list[-i - 1] = nn.ModuleList(nets2) middle_nets = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): middle_nets[j] = nn.Sequential( middle_nets[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) if pooling: for j in range(nb_layers_per_net): middle_nets[j] = nn.Sequential( middle_nets[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) unet_list[nb_unets_div_by_2] = nn.ModuleList(middle_nets) self.unets = nn.ModuleList(unet_list) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Conv2d( int(nnsize * c), c_prime, nnks, stride=stride, padding=padding, dilation=dilation ) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): h = self.mono(x) # linear transformation only saved_h = [ h ] * self.nb_unets_div_by_2 # saves output of last linear transformation layer_no = 0 for unet in self.unets: sublayer_no = 0 for net in unet: h = F.relu(h) # activation on previous block h = net(h) if sublayer_no == self.nb_layers_per_net - 1: if layer_no < self.nb_unets_div_by_2: saved_h[layer_no] = h elif layer_no > self.nb_unets_div_by_2: h = h + saved_h[layer_no - self.nb_unets_div_by_2 - 1] sublayer_no = sublayer_no + 1 layer_no = layer_no + 1 h = F.relu(h) # final activation v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h).flatten(1) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit.flatten(1), 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/u_conv_fc_logit_model.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import torch from torch import nn import torch.nn.functional as F from . import utils as zutils from ..params import GameParams, ModelParams from .. import utils @zutils.register_model class UConvFCLogitModel(torch.jit.ScriptModule): __constants__ = [ "c_prime", "h_prime", "w_prime", "nb_layers_per_net", "mono", "nb_unets_div_by_2", "unets", ] DEFAULT_NB_NETS = 5 DEFAULT_NB_LAYERS_PER_NET = 3 DEFAULT_NNSIZE = 2 DEFAULT_NNKS = 3 DEFAULT_STRIDE = 1 DEFAULT_DILATION = 1 DEFAULT_POOLING = False DEFAULT_BN = False # DEFAULT_BN_AFFINE = False default_game_name = "Connect4" def __init__(self, game_params: GameParams, model_params: ModelParams): torch.jit.ScriptModule.__init__(self) if game_params.game_name is None: game_params.game_name = self.__class__.default_game_name self.game_name = game_params.game_name self.game_params = game_params info = zutils.get_game_info(game_params) c, h, w = self.c, self.h, self.w = info["feature_size"][:3] c_prime, h_prime, w_prime = self.c_prime, self.h_prime, self.w_prime = info[ "action_size" ][:3] # nb unets if model_params.nb_nets is None: model_params.nb_nets = self.DEFAULT_NB_NETS nb_nets = model_params.nb_nets if nb_nets % 2 == 0: raise RuntimeError( f'The model "{self.__class__.__name__}" accepts only odd numbers ' f'for "nb_nets" while it was set to {nb_nets}' ) self.nb_unets_div_by_2 = nb_unets_div_by_2 = nb_nets // 2 # nb layers per unet if model_params.nb_layers_per_net is None: model_params.nb_layers_per_net = self.DEFAULT_NB_LAYERS_PER_NET nb_layers_per_net = model_params.nb_layers_per_net self.nb_layers_per_net = nb_layers_per_net # nn size if model_params.nnsize is None: model_params.nnsize = self.DEFAULT_NNSIZE nnsize = model_params.nnsize # kernel size if model_params.nnks is None: model_params.nnks = self.DEFAULT_NNKS nnks = model_params.nnks # stride stride = self.DEFAULT_STRIDE # dilation dilation = self.DEFAULT_DILATION # padding padding = zutils.get_consistent_padding_from_nnks(nnks=nnks, dilation=dilation) # pooling if model_params.pooling is None: model_params.pooling = self.DEFAULT_POOLING pooling = model_params.pooling # batch norm if model_params.bn is None: model_params.bn = self.DEFAULT_BN bn = model_params.bn # # batch norm affine # if model_params.bn_affine is None: # model_params.bn_affine = self.DEFAULT_BN_AFFINE # bn_affine = model_params.bn_affine bn_affine = bn self.model_params = model_params mono = [ nn.Conv2d( c, int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) ] if bn or bn_affine: mono.append( nn.BatchNorm2d(int(nnsize * c), track_running_stats=True, affine=bn_affine) ) self.mono = nn.Sequential(*mono) unet_list = [None] * (2 * nb_unets_div_by_2 + 1) for i in range(nb_unets_div_by_2): nets1 = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] nets2 = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): nets1[j] = nn.Sequential( nets1[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) nets2[j] = nn.Sequential( nets2[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) if pooling: for j in range(nb_layers_per_net): nets1[j] = nn.Sequential( nets1[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) nets2[j] = nn.Sequential( nets2[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) unet_list[i] = nn.ModuleList(nets1) unet_list[-i - 1] = nn.ModuleList(nets2) middle_nets = [ nn.Conv2d( int(nnsize * c), int(nnsize * c), nnks, stride=stride, padding=padding, dilation=dilation, bias=not bn_affine, ) for _ in range(nb_layers_per_net) ] if bn or bn_affine: for j in range(nb_layers_per_net): middle_nets[j] = nn.Sequential( middle_nets[j], nn.BatchNorm2d( int(nnsize * c), track_running_stats=True, affine=bn_affine ), ) if pooling: for j in range(nb_layers_per_net): middle_nets[j] = nn.Sequential( middle_nets[j], nn.MaxPool2d( kernel_size=nnks, padding=padding, stride=stride, dilation=dilation, ), ) unet_list[nb_unets_div_by_2] = nn.ModuleList(middle_nets) self.unets = nn.ModuleList(unet_list) self.v = nn.Linear(int(nnsize * c) * h * w, 1) self.pi_logit = nn.Linear(int(nnsize * c) * h * w, c_prime * h_prime * w_prime) @torch.jit.script_method def _forward(self, x: torch.Tensor, return_logit: bool): h = self.mono(x) # linear transformation only saved_h = [ h ] * self.nb_unets_div_by_2 # saves output of last linear transformation layer_no = 0 for unet in self.unets: sublayer_no = 0 for net in unet: h = F.relu(h) # activation on previous block h = net(h) if sublayer_no == self.nb_layers_per_net - 1: if layer_no < self.nb_unets_div_by_2: saved_h[layer_no] = h elif layer_no > self.nb_unets_div_by_2: h = h + saved_h[layer_no - self.nb_unets_div_by_2 - 1] sublayer_no = sublayer_no + 1 layer_no = layer_no + 1 h = F.relu(h) # final activation v = torch.tanh(self.v(h.flatten(1))) pi_logit = self.pi_logit(h.flatten(1)) if return_logit: return v, pi_logit s = pi_logit.shape pi = F.softmax(pi_logit.flatten(1), 1).reshape(s) return v, pi @torch.jit.script_method def forward(self, x: torch.Tensor): v, pi_logit = self._forward(x, True) pi_logit = pi_logit.view(-1, self.c_prime, self.h_prime, self.w_prime) reply = {"v": v, "pi_logit": pi_logit} return reply ================================================ FILE: pypolygames/model_zoo/utils.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from typing import Dict from .. import params from .. import env_creation_helpers import torch MODELS: Dict[str, torch.jit.ScriptModule] = {} def register_model(cls): MODELS[cls.__name__] = cls return cls def get_game_info(game_params: params) -> Dict[str, list]: game = env_creation_helpers.create_game( game_params=game_params, num_episode=-1, seed=0, eval_mode=False, per_thread_batchsize=0, ) info = {"feature_size": game.get_feat_size(), "action_size": game.get_action_size()} info["raw_feature_size"] = game.get_raw_feat_size() return info def get_consistent_padding_from_nnks(nnks: int, dilation: int = 1) -> int: # the params are such than the output layer of a Conv2d is the same # size as the input layer assuming the stride is one padding = dilation * (nnks - 1) / 2 if padding != int(padding): raise ValueError( "The values of nnks, padding and dilation must be integers " "such as 2 * padding == dilation * (nnks - 1) - " f"nnks={nnks} dilation={dilation} padding={padding} - " "for default values for dilation and padding, nnks should be even" ) return int(padding) ================================================ FILE: pypolygames/params.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from collections import OrderedDict from dataclasses import dataclass, field import os from pathlib import Path from typing import Iterator, Tuple, Union, List, Optional, Dict, Any from .weight_init import WEIGHT_INIT def boolarg(x): if str(x).lower() in ["true", "yes", "on", "1", "y"]: return True if str(x).lower() in ["false", "no", "off", "0", "n"]: return False raise RuntimeError("Unknown bool value " + str(x)) @dataclass class ArgFields: name: Optional[str] = None opts: Optional[Dict[str, Any]] = None @dataclass class GameParams: game_name: Optional[str] = None game_options: List[str] = None out_features: bool = False turn_features: bool = False turn_features_mc: bool = False geometric_features: bool = False random_features: int = 0 one_feature: bool = False history: int = 0 predict_end_state: bool = False predict_n_states: int = 0 player: str = "mcts" def __setattr__(self, attr, value): if value is None: value = getattr(self, attr) super().__setattr__(attr, value) def __eq__(self, other_game_params): return all( getattr(self, field) == getattr(other_game_params, field) for field in { "game_name", "game_options", "out_features", "turn_features", "turn_features_mc", "geometric_features", "one_feature", "history", "predict_end_state", "predict_n_states", "player", } ) @classmethod def arg_fields(cls) -> Iterator[Tuple[str, ArgFields]]: params = OrderedDict( game_name=ArgFields( opts=dict( type=str, help="Game name - if left unspecified it will default to the game " "that the model selected with '--model_name' refers to as default", ) ), game_options=ArgFields( opts=dict( type=str, nargs="*", default=None, help="Optional list of extra options to customise the game.", ) ), out_features=ArgFields( opts=dict( action="store_false" if cls.out_features else "store_true", help="If set, the input to the NN includes a channel " "with 1 on the frontier", ) ), turn_features=ArgFields( opts=dict( action="store_false" if cls.turn_features else "store_true", help="If set, the input to the NN includes a channel " "with the player index broadcasted", ) ), turn_features_mc=ArgFields( opts=dict( action="store_false" if cls.turn_features_mc else "store_true", help="If set, the input to the NN includes one channel " "for each player (color), with the one corresponding to the" " current player set to 1 and the others set to 0", ) ), geometric_features=ArgFields( opts=dict( action="store_false" if cls.geometric_features else "store_true", help="If set, the input to the NN includes " "4 geometric channels representing the position on the board", ) ), random_features=ArgFields( opts=dict(type=int, help="Number of random features the input includes") ), one_feature=ArgFields( opts=dict( action="store_false" if cls.one_feature else "store_true", help="If set, the input to the NN includes " "a channel with 1 everywhere", ) ), history=ArgFields( opts=dict( type=int, help="Number of last steps whose representation is " "added in the featurization", ) ), predict_end_state=ArgFields( opts=dict( type=boolarg, help="Side learning: predict end state", ) ), predict_n_states=ArgFields( opts=dict( type=int, help="Side learning: predict N next game states", ) ), player=ArgFields( opts=dict( type=str, help="Type of player to use. One of: mcts, forward", ) ) ) for param, arg_field in params.items(): if arg_field.name is None: arg_field.name = f"--{param}" if arg_field.opts is None: arg_field.opts = {} if "help" not in arg_field.opts: arg_field.opts["help"] = "" arg_field.opts["help"] += f" (DEFAULT: {getattr(cls(), param)})" yield param, arg_field @dataclass class ModelParams: """Model parameters - all set to 'None' as they have sensible default specified in their definitions""" init_checkpoint: Path = None pure_mcts: bool = False model_name: str = None nb_nets: int = None nb_layers_per_net: int = None nnsize: float = None fcsize: int = None nnks: int = None pooling: bool = False bn: bool = False # bn_affine: bool = False init_method: str = next(iter(WEIGHT_INIT)) activation_function: str = "relu" global_pooling: float = 0 batchnorm_momentum: float = 0.01 rnn_interval: float = 0 def __setattr__(self, attr, value): if value is None: value = getattr(self, attr) super().__setattr__(attr, value) def __post_init__(self): if self.init_checkpoint is not None: if self.pure_mcts: raise ValueError( "The MCTS can be either assisted with a " "'--init_checkpoint' neural network or be a '--pure_mcts'" ) self.init_checkpoint = self.init_checkpoint.absolute() # if self.bn and self.bn_affine: # raise ValueError( # "At most one of the options '--bn' and '--bn_affine' can be selected" # ) @classmethod def arg_fields(cls) -> Iterator[Tuple[str, ArgFields]]: params = OrderedDict( init_checkpoint=ArgFields( opts=dict( type=Path, help="Path to pretrained model (a checkpoint), in case of a " "simulation or for fine-tuning - if specified the game parameters " "and model parameters should be left unspecified as the pretrained " "model contains them", ) ), pure_mcts=ArgFields( opts=dict( action="store_false" if cls.pure_mcts else "store_true", help="If set, the inference will be done with MCTS only " "- no Neural Network", ) ), model_name=ArgFields( opts=dict( type=str, help="Model name - if left unspecified " "it will default to a generic model", ) ), nb_nets=ArgFields( opts=dict(type=int, help="Number of subnets, when applicable") ), nb_layers_per_net=ArgFields( opts=dict(type=int, help="Number of layer per subnets, when applicable") ), nnsize=ArgFields( opts=dict( type=float, help="Number of units per hidden layer, when applicable" ) ), fcsize=ArgFields( opts=dict( type=int, help="Size of final full-connected layers, when applicable", ) ), nnks=ArgFields( opts=dict( type=int, help="Kernel size for convolutional layers, when applicable " "- dilation and stride are set to one, " "so it must be an even number", ) ), pooling=ArgFields( opts=dict( action="store_false" if cls.pooling else "store_true", help="If set, adds pooling layers following convolutional layers, " "when applicable", ) ), bn=ArgFields( opts=dict( action="store_false" if cls.bn else "store_true", # help="If set, adds batch normalisation with " # "no learnable affine parameters", help="If set, adds batch normalisation with " "learnable affine parameters", ) ), # bn_affine=ArgFields( # opts=dict( # action="store_false" if cls.bn_affine else "store_true", # help="If set, adds batch normalisation with " # "learnable affine parameters", # ) # ), init_method=ArgFields( opts=dict( type=str, help="Weight initialisation method", choices=list(WEIGHT_INIT), ) ), activation_function=ArgFields( opts=dict( type=str, help="Activation function to use", ) ), global_pooling=ArgFields( opts=dict( type=float, help="Global pooling - this will, for the models that support it, " "add global pooling over some channels after convolutional layers. " "The parameter is the proportion of the channels that should be pooled. " "Eg. 0.1 will specify that we should pool 10% of the channels" ) ), batchnorm_momentum=ArgFields( opts=dict( type=float, help="Batch normalization momentum", ) ), rnn_interval=ArgFields( opts=dict( type=float, help="RNN layer every this many CNN layers", ) ), ) for param, arg_field in params.items(): if arg_field.name is None: arg_field.name = f"--{param}" if arg_field.opts is None: arg_field.opts = {} if "help" not in arg_field.opts: arg_field.opts["help"] = "" arg_field.opts["help"] += f" (DEFAULT: {getattr(cls(), param)})" yield param, arg_field @dataclass class OptimParams: num_epoch: int = 10_000_000 # basically infinity epoch_len: int = 1000 batchsize: int = 128 lr: float = 1e-3 eps: float = 1.5e-4 grad_clip: float = 0.25 reset_optimizer_state: bool = False def __setattr__(self, attr, value): if value is None: value = getattr(self, attr) super().__setattr__(attr, value) @classmethod def arg_fields(cls) -> Iterator[Tuple[str, ArgFields]]: params = OrderedDict( num_epoch=ArgFields(opts=dict(type=int, help=f"Number of epochs")), epoch_len=ArgFields( opts=dict(type=int, help=f"Number of train batches per epoch") ), batchsize=ArgFields( opts=dict( type=int, help="Number of training examples in a mini-batch (train batch)" "- also the batchsize in GPU (when enabled) for training", ) ), lr=ArgFields(opts=dict(type=float, default=cls.lr, help=f"Learning rate")), eps=ArgFields( opts=dict( type=float, help="Term added to the denominator to improve " "numerical stability ", ) ), grad_clip=ArgFields( opts=dict(type=float, help=f"Max norm of the gradients") ), reset_optimizer_state=ArgFields( opts=dict( action="store_false" if cls.reset_optimizer_state else "store_true", help="If set, any internal state of optimizer from checkpoint will be reset" ) ), ) for param, arg_field in params.items(): if arg_field.name is None: arg_field.name = f"--{param}" if arg_field.opts is None: arg_field.opts = {} if "help" not in arg_field.opts: arg_field.opts["help"] = "" arg_field.opts["help"] += f" (DEFAULT: {getattr(cls(), param)})" yield param, arg_field @dataclass class SimulationParams: num_game: int = 2 num_threads: int = 0 num_actor: int = 1 # should be 1 at training time num_rollouts: int = 1600 replay_capacity: int = 1_000_000 replay_warmup: int = 10_000 sync_period: int = 100 act_batchsize: int = 1 per_thread_batchsize: int = 0 bsfinder_max_bs: int = 10240 bsfinder_max_ms: float = 100 rewind: int = 0 randomized_rollouts: bool = False sampling_mcts: bool = False sample_before_step_idx: int = 30 train_channel_timeout_ms: int = 1000 train_channel_num_slots: int = 10000 def __setattr__(self, attr, value): if value is None: value = getattr(self, attr) super().__setattr__(attr, value) def __post_init__(self) -> None: if self.per_thread_batchsize == 0 and self.act_batchsize > self.num_game: raise ValueError("'act_batchsize' cannot be larger than 'num_games'") @classmethod def arg_fields(cls) -> Iterator[Tuple[str, ArgFields]]: params = OrderedDict( num_game=ArgFields( opts=dict(type=int, help=f"Number of game-running threads") ), num_threads=ArgFields( opts=dict(type=int, help=f"Number of async threads") ), num_actor=ArgFields( opts=dict( type=int, help=f"Number of actors per non-human player, " "one actor being one thread doing MCTS " "- the more num_actor, the larger the MCTS", ) ), num_rollouts=ArgFields( opts=dict(type=int, help="Number of rollouts per actor/thread") ), replay_capacity=ArgFields( opts=dict( type=int, help="Nb of act_batches the replay buffer can contain" ) ), replay_warmup=ArgFields( opts=dict( type=int, help="Nb of act_batches the replay buffer needs to buffer " "before the training can start", ) ), sync_period=ArgFields( opts=dict( type=int, help="Number of epochs between two consecutive sync " "between the model and the assembler", ) ), act_batchsize=ArgFields( opts=dict( type=int, help="When '--per_thread_batchsize' is not set, " "number or requests batched together for inference", ) ), per_thread_batchsize=ArgFields( opts=dict( type=int, help="When non-zero, " "number of games per game-running thread, " "batched together for inference (see '--act_batchsize'). " "This parameter will be automatically tuned if it is <= 0", ) ), bsfinder_max_bs=ArgFields( opts=dict( type=int, help="The maximum batch size for the automatic batch size " "finder to use", ) ), bsfinder_max_ms=ArgFields( opts=dict( type=float, help="The maximum time in milliseconds for a batch size " "found by the automatic batch size finder to use", ) ), rewind=ArgFields( opts=dict( type=int, help="Use rewind feature for training; number of times to rewind", ) ), randomized_rollouts=ArgFields( opts=dict( type=boolarg, help="Enable randomized rollouts", ) ), sampling_mcts=ArgFields( opts=dict( type=boolarg, help="Use sampling MCTS", ) ), sample_before_step_idx=ArgFields( opts=dict( type=int, help="Before this many steps in the game, sample over moves instead " " of always selecting the best move", ) ), train_channel_timeout_ms=ArgFields( opts=dict( type=int, help="Timeout (in milliseconds) to wait for actors to produce " "trajectories", ) ), train_channel_num_slots=ArgFields( opts=dict( type=int, help="Number of slots in train channel used to send trajectories", ) ), ) for param, arg_field in params.items(): if arg_field.name is None: arg_field.name = f"--{param}" if arg_field.opts is None: arg_field.opts = {} if "help" not in arg_field.opts: arg_field.opts["help"] = "" arg_field.opts["help"] += f" (DEFAULT: {getattr(cls(), param)})" yield param, arg_field @dataclass class ExecutionParams: checkpoint_dir: Path = None save_dir: str = None # keep for deprecation warning save_uncompressed: bool = True do_not_save_replay_buffer: bool = False saving_period: int = 100 max_time: Optional[int] = None human_first: bool = False time_ratio: float = 0.035 total_time: float = 0 devices: List[str] = field(default_factory=lambda: ["cuda:0"]) seed: int = 1 listen: str = "" connect: str = "" opponent_model_path: Path = None tournament_mode: bool = False rnn_seqlen: int = 0 def __setattr__(self, attr, value): if value is None: try: value = getattr(self, attr) except AttributeError: value = getattr(type(self)(), attr) super().__setattr__(attr, value) def __post_init__(self) -> None: if self.checkpoint_dir is not None: self.checkpoint_dir = self.checkpoint_dir.resolve().absolute() if self.save_dir is not None: raise RuntimeError("""--save_dir is deprecated, use --checkpoint_dir instead, with slightly different behavior: - no subfolder creation. - resumes from latest checkpoint if available in the directory.""") @classmethod def arg_fields(cls) -> Iterator[Tuple[str, ArgFields]]: params = OrderedDict( checkpoint_dir=ArgFields( opts=dict( type=Path, help="Directory for saving checkpoints. " "If the directory is not empty, the latest checkpoint will be resumed", ) ), save_dir=ArgFields( opts=dict( type=Path, help="Deprecated, use checkpoint_dir with slightly different behavior instead" ) ), save_uncompressed=ArgFields( opts=dict( action="store_false" if cls.save_uncompressed else "store_true", help="If set, saved checkpoints will be saved uncompressed", ) ), do_not_save_replay_buffer=ArgFields( opts=dict( action="store_false" if cls.do_not_save_replay_buffer else "store_true", help="If set, the replay buffer will be not saved " "in the checkpoint", ) ), saving_period=ArgFields( opts=dict( type=int, help="Number of epochs between two consecutive checkpoints", ) ), max_time=ArgFields( opts=dict(type=int, help="Maximum time allowed for a run (in seconds)") ), human_first=ArgFields( opts=dict( action="store_false" if cls.human_first else "store_true", help="If set in a two-player game, " "the human player plays first", ) ), time_ratio=ArgFields( opts=dict( type=float, help="Part of the remaining time for the next move" ) ), total_time=ArgFields( opts=dict( type=float, help="Total time in seconds for the entire game for one player", ) ), devices=ArgFields( opts=dict( type=str, nargs="*", help="List of torch devices where the computation for the model" "will happen " '(e.g., "cpu", "cuda:0") ' "- in training mode, only one device is allowed", ) ), seed=ArgFields( opts=dict(type=int, help="Seed for pseudo-random number generator") ), listen=ArgFields( opts=dict( type=str, help="Listen for distributed training, eg. tcp://0.0.0.0:5611", ) ), connect=ArgFields( opts=dict( type=str, help="Connect to hostname for distributed training, eg. tcp://127.0.0.1:5611", ) ), opponent_model_path=ArgFields( opts=dict( type=Path, help="Load this model as the opponent - will not request model updates", ) ), tournament_mode=ArgFields( opts=dict( type=boolarg, help="Use tournament mode", ) ), rnn_seqlen=ArgFields( opts=dict( type=int, help="RNN sequence length used for training", ) ), ) for param, arg_field in params.items(): if arg_field.name is None: arg_field.name = f"--{param}" if arg_field.opts is None: arg_field.opts = {} if "help" not in arg_field.opts: arg_field.opts["help"] = "" arg_field.opts["help"] += f" (DEFAULT: {getattr(cls(), param)})" yield param, arg_field @dataclass class EvalParams: real_time: bool = False checkpoint_dir: Path = None checkpoint: Path = None device_eval: List[str] = field(default_factory=lambda: ["cuda:0"]) num_game_eval: int = 100 num_parallel_games_eval: int = None num_actor_eval: int = 1 num_rollouts_eval: int = 400 checkpoint_opponent: Path = None device_opponent: List[str] = field(default_factory=lambda: ["cuda:0"]) num_actor_opponent: int = 1 num_rollouts_opponent: int = 2000 seed_eval: int = 2 plot_enabled: bool = False plot_server: str = "http://localhost" plot_port: int = 8097 eval_verbosity: int = 1 def __setattr__(self, attr, value): if value is None: try: value = getattr(self, attr) except AttributeError: # TODO: this part may be buggy (infinite recursion), is it needed? # cannot create with both None for checkpoint_dir and checkpoint defaults = self.__class__(checkpoint_dir=Path("blublu")) if attr != "checkpoint_dir": value = getattr(defaults, attr) super().__setattr__(attr, value) def __post_init__(self) -> None: if self.real_time and self.checkpoint is not None: raise ValueError( "In '--real_time' the evaluation follow the training " "so '--checkpoint' should not be set" ) if self.checkpoint_dir is None and self.checkpoint is None: raise ValueError( "Either a '--checkpoint_dir' or a path to a '--checkpoint' " "must be specified" ) if self.checkpoint_dir is not None and self.checkpoint is not None: raise ValueError( "Either a '--checkpoint_dir' or a path to a '--checkpoint' " "must be specified, but not both" ) if self.checkpoint is not None and self.plot_enabled: raise ValueError( "Plotting is not available if the evaluation is performed " "only on one checkpoint" ) if self.checkpoint_dir is not None: self.checkpoint_dir = self.checkpoint_dir.absolute() if self.checkpoint is not None: self.checkpoint = self.checkpoint.absolute() @classmethod def arg_fields(cls) -> Iterator[Tuple[str, ArgFields]]: params = OrderedDict( real_time=ArgFields( opts=dict( action="store_false" if cls.real_time else "store_true", help="In 'real_time' the evaluation follows the training " "as it goes, " "taking the last available checkpoints and " "skipping some previous checkpoints " "if they are taking too much time to compute", ) ), checkpoint_dir=ArgFields( opts=dict( type=Path, help="Directory storing the checkpoints " "- if set, '--checkpoint' should not be set", ) ), checkpoint=ArgFields( opts=dict( type=Path, help="Path to the individual checkpoint to be evaluated " "- if set, '--checkpoint_dir' should not be set", ) ), device_eval=ArgFields( opts=dict( type=str, nargs="*", help="List of torch devices where the computation for the model" "to be tested will happen " '(e.g., "cpu", "cuda:0")', ) ), num_game_eval=ArgFields( opts=dict( type=int, help="Number of games played against a pure MCTS opponent" ) ), num_parallel_games_eval=ArgFields( opts=dict( type=int, help="Number of evaluation games to be played in parallel. " "If set to None, all games are played in parallel" ) ), num_actor_eval=ArgFields( opts=dict( type=int, help="Number of actors per player for the model to be tested, " "one actor being one thread doing MCTS " "- the more num_actor_eval, the larger the MCTS " "- when the model plays against another model as opponent, " "it needs to be set to a number > 1", ) ), num_rollouts_eval=ArgFields( opts=dict( type=int, help="Number of rollouts per actor/thread for " "the model to be tested", ) ), checkpoint_opponent=ArgFields( opts=dict( type=Path, help="Path to the checkpoint the opponent will use as model" " - if not set, the opponent will be a pure MCTS", ) ), device_opponent=ArgFields( opts=dict( type=str, nargs="*", help="List of torch devices where the computation for the opponent" "will happen " '(e.g., "cpu", "cuda:0")', ) ), num_actor_opponent=ArgFields( opts=dict( type=int, help="Number of MCTS actor threads for the opponent", ) ), num_rollouts_opponent=ArgFields( opts=dict( type=int, help="Number of rollouts per actor/thread for the opponent", ) ), seed_eval=ArgFields( opts=dict(type=int, help="Seed for pseudo-random number generator") ), plot_enabled=ArgFields( opts=dict( action="store_false" if cls.plot_enabled else "store_true", help="If set, visdom plots the evaluation as it is computed", ) ), plot_server=ArgFields(opts=dict(type=str, help="Visdom server url")), plot_port=ArgFields(opts=dict(type=int, help="Visdom server port")), eval_verbosity=ArgFields(opts=dict(type=int, help="Verbosity during the evaluation")), ) defaults = cls(checkpoint_dir=Path("blublu")) # cannot create with both None for checkpoint_dir and checkpoint defaults.checkpoint_dir = None # revert for param, arg_field in params.items(): if arg_field.name is None: arg_field.name = f"--{param}" if arg_field.opts is None: arg_field.opts = {} if "help" not in arg_field.opts: arg_field.opts["help"] = "" arg_field.opts[ "help" ] += f" (DEFAULT: {getattr(defaults, param)})" yield param, arg_field GenericParams = Union[ GameParams, ModelParams, OptimParams, SimulationParams, ExecutionParams ] ================================================ FILE: pypolygames/tests/README.md ================================================ ## how to use test_interactions.py - remove old ground-truth file: `rm pypolygames/tests/data/Hex11.txt` - run tests to generate a new ground-truth file: `pytest pypolygames --durations=10 --verbose -x` - manually check that the generated file is correct: `cat pypolygames/tests/data/Hex11.txt` - check that all tests pass: `pytest pypolygames --durations=10 --verbose` ================================================ FILE: pypolygames/tests/__init__.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. ================================================ FILE: pypolygames/tests/data/BlockGo.txt ================================================ actions: ['0', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 35, 8, 9 Current board: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |x| | | | | | | | | | | |x| | | | | | | | | | | |x|x| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Legal Actions: Action 0: 0, 3, 3 Action 1: 4, 3, 3 Action 2: 8, 3, 3 Action 3: 8, 2, 3 Action 4: 8, 3, 2 Action 5: 8, 2, 2 Action 6: 12, 3, 3 Action 7: 12, 2, 3 Action 8: 12, 1, 3 Action 9: 12, 0, 3 Action 10: 13, 3, 3 Action 11: 13, 3, 2 Action 12: 13, 3, 1 Action 13: 13, 3, 0 Action 14: 16, 3, 3 Action 15: 16, 2, 3 Action 16: 16, 2, 2 Action 17: 16, 1, 2 Action 18: 17, 3, 3 Action 19: 17, 3, 2 Action 20: 17, 4, 2 Action 21: 17, 4, 1 Action 22: 20, 3, 3 Action 23: 20, 2, 3 Action 24: 20, 2, 4 Action 25: 20, 1, 4 Action 26: 21, 3, 3 Action 27: 21, 3, 2 Action 28: 21, 2, 2 Action 29: 21, 2, 1 Action 30: 24, 3, 3 Action 31: 24, 2, 3 Action 32: 24, 1, 3 Action 33: 24, 2, 2 Action 34: 25, 3, 3 Action 35: 25, 3, 2 Action 36: 25, 3, 1 Action 37: 25, 4, 2 Action 38: 26, 3, 3 Action 39: 26, 4, 3 Action 40: 26, 5, 3 Action 41: 26, 4, 4 Action 42: 27, 3, 3 Action 43: 27, 3, 4 Action 44: 27, 3, 5 Action 45: 27, 2, 4 Action 46: 28, 3, 3 Action 47: 28, 2, 3 Action 48: 28, 1, 3 Action 49: 28, 1, 2 Action 50: 29, 3, 3 Action 51: 29, 3, 2 Action 52: 29, 3, 1 Action 53: 29, 4, 1 Action 54: 30, 3, 3 Action 55: 30, 4, 3 Action 56: 30, 5, 3 Action 57: 30, 5, 4 Action 58: 31, 3, 3 Action 59: 31, 3, 4 Action 60: 31, 3, 5 Action 61: 31, 2, 5 Action 62: 32, 3, 3 Action 63: 32, 2, 3 Action 64: 32, 1, 3 Action 65: 32, 3, 2 Action 66: 33, 3, 3 Action 67: 33, 3, 2 Action 68: 33, 3, 1 Action 69: 33, 4, 3 Action 70: 34, 3, 3 Action 71: 34, 4, 3 Action 72: 34, 5, 3 Action 73: 34, 3, 4 Action 74: 35, 3, 3 Action 75: 35, 3, 4 Action 76: 35, 3, 5 Action 77: 35, 2, 3 Action 78: 0, 9, 3 Action 79: 4, 9, 3 Action 80: 8, 9, 3 Action 81: 8, 8, 3 Action 82: 8, 9, 2 Action 83: 8, 8, 2 Action 84: 12, 9, 3 Action 85: 12, 8, 3 Action 86: 12, 7, 3 Action 87: 12, 6, 3 Action 88: 13, 9, 3 Action 89: 13, 9, 2 Action 90: 13, 9, 1 Action 91: 13, 9, 0 Action 92: 16, 9, 3 Action 93: 16, 8, 3 Action 94: 16, 8, 2 Action 95: 16, 7, 2 Action 96: 17, 9, 3 Action 97: 17, 9, 2 Action 98: 17, 10, 2 Action 99: 17, 10, 1 Action 100: 20, 9, 3 Action 101: 20, 8, 3 Action 102: 20, 8, 4 Action 103: 20, 7, 4 Action 104: 21, 9, 3 Action 105: 21, 9, 2 Action 106: 21, 8, 2 Action 107: 21, 8, 1 Action 108: 24, 9, 3 Action 109: 24, 8, 3 Action 110: 24, 7, 3 Action 111: 24, 8, 2 Action 112: 25, 9, 3 Action 113: 25, 9, 2 Action 114: 25, 9, 1 Action 115: 25, 10, 2 Action 116: 26, 9, 3 Action 117: 26, 10, 3 Action 118: 26, 11, 3 Action 119: 26, 10, 4 Action 120: 27, 9, 3 Action 121: 27, 9, 4 Action 122: 27, 9, 5 Action 123: 27, 8, 4 Action 124: 28, 9, 3 Action 125: 28, 8, 3 Action 126: 28, 7, 3 Action 127: 28, 7, 2 Action 128: 29, 9, 3 Action 129: 29, 9, 2 Action 130: 29, 9, 1 Action 131: 29, 10, 1 Action 132: 30, 9, 3 Action 133: 30, 10, 3 Action 134: 30, 11, 3 Action 135: 30, 11, 4 Action 136: 31, 9, 3 Action 137: 31, 9, 4 Action 138: 31, 9, 5 Action 139: 31, 8, 5 Action 140: 32, 9, 3 Action 141: 32, 8, 3 Action 142: 32, 7, 3 Action 143: 32, 9, 2 Action 144: 33, 9, 3 Action 145: 33, 9, 2 Action 146: 33, 9, 1 Action 147: 33, 10, 3 Action 148: 34, 9, 3 Action 149: 34, 10, 3 Action 150: 34, 11, 3 Action 151: 34, 9, 4 Action 152: 35, 9, 3 Action 153: 35, 9, 4 Action 154: 35, 9, 5 Action 155: 35, 8, 3 Action 156: 0, 3, 9 Action 157: 4, 3, 9 Action 158: 8, 3, 9 Action 159: 8, 2, 9 Action 160: 8, 3, 8 Action 161: 8, 2, 8 Action 162: 12, 3, 9 Action 163: 12, 2, 9 Action 164: 12, 1, 9 Action 165: 12, 0, 9 Action 166: 13, 3, 9 Action 167: 13, 3, 8 Action 168: 13, 3, 7 Action 169: 13, 3, 6 Action 170: 16, 3, 9 Action 171: 16, 2, 9 Action 172: 16, 2, 8 Action 173: 16, 1, 8 Action 174: 17, 3, 9 Action 175: 17, 3, 8 Action 176: 17, 4, 8 Action 177: 17, 4, 7 Action 178: 20, 3, 9 Action 179: 20, 2, 9 Action 180: 20, 2, 10 Action 181: 20, 1, 10 Action 182: 21, 3, 9 Action 183: 21, 3, 8 Action 184: 21, 2, 8 Action 185: 21, 2, 7 Action 186: 24, 3, 9 Action 187: 24, 2, 9 Action 188: 24, 1, 9 Action 189: 24, 2, 8 Action 190: 25, 3, 9 Action 191: 25, 3, 8 Action 192: 25, 3, 7 Action 193: 25, 4, 8 Action 194: 26, 3, 9 Action 195: 26, 4, 9 Action 196: 26, 5, 9 Action 197: 26, 4, 10 Action 198: 27, 3, 9 Action 199: 27, 3, 10 Action 200: 27, 3, 11 Action 201: 27, 2, 10 Action 202: 28, 3, 9 Action 203: 28, 2, 9 Action 204: 28, 1, 9 Action 205: 28, 1, 8 Action 206: 29, 3, 9 Action 207: 29, 3, 8 Action 208: 29, 3, 7 Action 209: 29, 4, 7 Action 210: 30, 3, 9 Action 211: 30, 4, 9 Action 212: 30, 5, 9 Action 213: 30, 5, 10 Action 214: 31, 3, 9 Action 215: 31, 3, 10 Action 216: 31, 3, 11 Action 217: 31, 2, 11 Action 218: 32, 3, 9 Action 219: 32, 2, 9 Action 220: 32, 1, 9 Action 221: 32, 3, 8 Action 222: 33, 3, 9 Action 223: 33, 3, 8 Action 224: 33, 3, 7 Action 225: 33, 4, 9 Action 226: 34, 3, 9 Action 227: 34, 4, 9 Action 228: 34, 5, 9 Action 229: 34, 3, 10 Action 230: 35, 3, 9 Action 231: 35, 3, 10 Action 232: 35, 3, 11 Action 233: 35, 2, 9 Input action: applying action... Last Action: 31, 2, 11 Current board: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |o| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |x| | | | | | | | | | | |x| | | | | |x|x| | | | |x|x| | | | |x| | | | | | | | | | | |x| | | | | | | | | | | | | | | | | | | | | | Legal Actions: Action 0: 4, 9, 3 Action 1: 8, 9, 3 Action 2: 8, 8, 3 Action 3: 8, 9, 2 Action 4: 8, 8, 2 Action 5: 12, 9, 3 Action 6: 12, 8, 3 Action 7: 12, 7, 3 Action 8: 12, 6, 3 Action 9: 13, 9, 3 Action 10: 13, 9, 2 Action 11: 13, 9, 1 Action 12: 13, 9, 0 Action 13: 16, 9, 3 Action 14: 16, 8, 3 Action 15: 16, 8, 2 Action 16: 16, 7, 2 Action 17: 17, 9, 3 Action 18: 17, 9, 2 Action 19: 17, 10, 2 Action 20: 17, 10, 1 Action 21: 20, 9, 3 Action 22: 20, 8, 3 Action 23: 20, 8, 4 Action 24: 20, 7, 4 Action 25: 21, 9, 3 Action 26: 21, 9, 2 Action 27: 21, 8, 2 Action 28: 21, 8, 1 Action 29: 24, 9, 3 Action 30: 24, 8, 3 Action 31: 24, 7, 3 Action 32: 24, 8, 2 Action 33: 25, 9, 3 Action 34: 25, 9, 2 Action 35: 25, 9, 1 Action 36: 25, 10, 2 Action 37: 26, 9, 3 Action 38: 26, 10, 3 Action 39: 26, 11, 3 Action 40: 26, 10, 4 Action 41: 27, 9, 3 Action 42: 27, 9, 4 Action 43: 27, 9, 5 Action 44: 27, 8, 4 Action 45: 28, 9, 3 Action 46: 28, 8, 3 Action 47: 28, 7, 3 Action 48: 28, 7, 2 Action 49: 29, 9, 3 Action 50: 29, 9, 2 Action 51: 29, 9, 1 Action 52: 29, 10, 1 Action 53: 30, 9, 3 Action 54: 30, 10, 3 Action 55: 30, 11, 3 Action 56: 30, 11, 4 Action 57: 31, 9, 3 Action 58: 31, 9, 4 Action 59: 31, 9, 5 Action 60: 31, 8, 5 Action 61: 32, 9, 3 Action 62: 32, 8, 3 Action 63: 32, 7, 3 Action 64: 32, 9, 2 Action 65: 33, 9, 3 Action 66: 33, 9, 2 Action 67: 33, 9, 1 Action 68: 33, 10, 3 Action 69: 34, 9, 3 Action 70: 34, 10, 3 Action 71: 34, 11, 3 Action 72: 34, 9, 4 Action 73: 35, 9, 3 Action 74: 35, 9, 4 Action 75: 35, 9, 5 Action 76: 35, 8, 3 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Breakthrough.txt ================================================ actions: ['1', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 1, 7, 6 Current board: x|x|x|x|x|x|x|x x|x|x|x|x|x|x|x | | | | | | | | | | | | | | | | | | | | | | | | | | | |o o|o|o|o|o|o|o| o|o|o|o|o|o|o|o Legal Actions: Action 0: 2, 0, 1 Action 1: 1, 0, 1 Action 2: 2, 1, 1 Action 3: 0, 1, 1 Action 4: 1, 1, 1 Action 5: 2, 2, 1 Action 6: 0, 2, 1 Action 7: 1, 2, 1 Action 8: 2, 3, 1 Action 9: 0, 3, 1 Action 10: 1, 3, 1 Action 11: 2, 4, 1 Action 12: 0, 4, 1 Action 13: 1, 4, 1 Action 14: 2, 5, 1 Action 15: 0, 5, 1 Action 16: 1, 5, 1 Action 17: 2, 6, 1 Action 18: 0, 6, 1 Action 19: 1, 6, 1 Action 20: 0, 7, 1 Action 21: 1, 7, 1 Input action: applying action... Last Action: 1, 7, 7 Current board: x|x|x|x|x|x|x|x |x|x|x|x|x|x|x x| | | | | | | | | | | | | | | | | | | | | | | | | | | |o o|o|o|o|o|o|o|o o|o|o|o|o|o|o| Legal Actions: Action 0: 1, 0, 0 Action 1: 2, 0, 2 Action 2: 1, 0, 2 Action 3: 0, 1, 0 Action 4: 2, 1, 1 Action 5: 1, 1, 1 Action 6: 2, 2, 1 Action 7: 0, 2, 1 Action 8: 1, 2, 1 Action 9: 2, 3, 1 Action 10: 0, 3, 1 Action 11: 1, 3, 1 Action 12: 2, 4, 1 Action 13: 0, 4, 1 Action 14: 1, 4, 1 Action 15: 2, 5, 1 Action 16: 0, 5, 1 Action 17: 1, 5, 1 Action 18: 2, 6, 1 Action 19: 0, 6, 1 Action 20: 1, 6, 1 Action 21: 0, 7, 1 Action 22: 1, 7, 1 Input action: Input action: ================================================ FILE: pypolygames/tests/data/ChineseCheckers.txt ================================================ actions: ['C4', 'G35', 'A10', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: move from A10 to G05 hands: 1 Current Board: Empty=' ' White=' ● ' Black=' ○ ' A ● / \ ● - ● / \ / \ ● - ● - ● / \ / \ / \ ● - ● - ● - F / \ / \ / \ / \ B - - - - - - - - ● - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ - ○ E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Chesses which can move: A / \ - / \ / \ - - / \ / \ / \ - - - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C07 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C08-C04 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C09-C05- / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C10-C06- - E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Please choose chess and move to where: (Use "a01", "B5","C10", etc. to correspond to the correct format in chess board) Chess you choose is: > A / \ - / \ / \ - - / \ / \ / \ - - - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - -G35 / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - -G50- - / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - - - / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - - - - E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Where you wanna go: > applying action... Last Action: move from G05 to G11 hands: 3 Current Board: Empty=' ' White=' ● ' Black=' ○ ' A ● / \ ● - ● / \ / \ ● - ● - ● / \ / \ / \ ● - ● - ● - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - ● - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ - ○ E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Chesses which can move: A / \ - / \ / \ - - / \ / \ / \ - - - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - -G35 / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C07 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C08- / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C09-C05-C02 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C10-C06- -C01 E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Please choose chess and move to where: (Use "a01", "B5","C10", etc. to correspond to the correct format in chess board) Chess you choose is: > Error! No any legal move. This is invalid Input! Please try again. Current Board: Empty=' ' White=' ● ' Black=' ○ ' A ● / \ ● - ● / \ / \ ● - ● - ● / \ / \ / \ ● - ● - ● - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - ● - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ - ○ E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Chesses which can move: A / \ - / \ / \ - - / \ / \ / \ - - - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - -G35 / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C07 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C08- / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C09-C05-C02 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C10-C06- -C01 E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Chess you choose is: > This is invalid Input! Please try again. Current Board: Empty=' ' White=' ● ' Black=' ○ ' A ● / \ ● - ● / \ / \ ● - ● - ● / \ / \ / \ ● - ● - ● - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - ● - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - - ○ - ○ - ○ - ○ E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Chesses which can move: A / \ - / \ / \ - - / \ / \ / \ - - - F / \ / \ / \ / \ B - - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - - - \ / \ / \ / \ / \ / \ / \ / \ / \ / - - - - - - - -G35 / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C07 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C08- / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C09-C05-C02 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ - - - - - - - - -C10-C06- -C01 E \ / \ / \ / \ / C - - - \ / \ / \ / - - \ / \ / - \ / D Chess you choose is: > ================================================ FILE: pypolygames/tests/data/DiceShogi.txt ================================================ actions: ['1', '1', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: b-D3 Current board: A| B| C| D| E 5 r| | s| g| k 4 | | | | p 3 | | | b| 2 P| | | | 1 K| G| S| B| R Legal Actions: Action 0: B-E2 Action 1: R-E2 Action 2: R-E3 Action 3: R-E4 Input format : action index e.g. 0 Input action: applying action... Random outcome ? Last Action: r-A2 Current board: A| B| C| D| E 5 | | s| g| k 4 | | | | p 3 | | | b| 2 r| | | | R 1 K| G| S| B| Legal Actions: Action 0: S-D2 Action 1: R-D2 Input format : action index e.g. 0 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Einstein.txt ================================================ actions: ['0', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 0, 0, 2 Current board: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Legal Actions: Action 0: 0, 2, 4 Input action: applying action... Random outcome ? ================================================ FILE: pypolygames/tests/data/GameOfTheAmazons.txt ================================================ actions: ['A7', 'B6', 'C6', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: moved chess from J04 to J01 and put arrow at J06 Current board: Empty=' ' WhiteChess='○' BlackChess='●' WhiteArrow='□' BlackArrow='■' A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ │ │ │ ● │ │ │ ● │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ ● │ │ │ │ │ │ │ │ │ ● │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ │ │ │ │ │ □ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ │ │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ ○ │ │ │ │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ ○ │ │ │ ○ │ │ │ ○ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J Position of chesses which are possible to move: `A07`, `D10`, `G10`, `J07` Input three positions to play: (uses format , e.g. `A1`, `b2`, `C03`...) Input the position of the chess which wants to move on: > Input the position of selected chess after moved: Allowed positions: ('?' means an allowed position) A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ ? │ │ │ ● │ │ │ ● │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ ? │ │ ? │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ ? │ ? │ │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ ● │ ? │ ? │ ? │ ? │ ? │ ? │ ? │ ? │ ● │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ ? │ ? │ │ │ │ │ │ │ │ □ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ ? │ │ ? │ │ │ │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ ○ │ │ │ ? │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ ? │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ ? │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ ○ │ │ │ ○ │ │ │ ○ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J > Input the position of the arrow that wants to put: Allowed positions: ('?' means an allowed position) A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ │ ? │ │ ● │ │ ? │ ● │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ ? │ │ │ ? │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ ? │ │ ? │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ ? │ ? │ ? │ │ │ │ │ │ │ ● │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ ? │ │ ? │ ? │ ? │ ? │ ? │ ? │ ? │ □ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ ? │ ? │ ? │ │ │ │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ ○ │ ? │ │ ? │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ ? │ │ │ ? │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ ? │ │ │ │ ? │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ ? │ │ ○ │ │ │ ○ │ │ │ ○ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J > applying action... Last Action: moved chess from J01 to J05 and put arrow at J01 Current board: Empty=' ' WhiteChess='○' BlackChess='●' WhiteArrow='□' BlackArrow='■' A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ │ │ │ ● │ │ │ ● │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ │ │ ● │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ ● │ ■ │ │ │ │ │ │ │ □ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ │ │ │ │ │ ○ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ ○ │ │ │ │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ ○ │ │ │ ○ │ │ │ □ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J Position of chesses which are possible to move: `B06`, `D10`, `G10`, `J07` Input three positions to play: (uses format , e.g. `A1`, `b2`, `C03`...) Input the position of the chess which wants to move on: > invalid input, try again. Input the position of the chess which wants to move on: > ================================================ FILE: pypolygames/tests/data/Havannah5.txt ================================================ actions: ['0,4', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 8,4 Current board: Havannah 0 1 2 3 4 5 6 7 8 -------------------- 0 \ . \ . \ . \ . \ . \ ------------------------ 1 \ . \ . \ . \ . \ . \ . \ ---------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ -------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 5 \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ ---------------------------- 7 \ . \ . \ . \ . \ . \ . \ ------------------------ 8 \ . \ . \ . \ . \ X \ -------------------- 0 1 2 3 4 5 6 7 8 Legal Actions: 0,4 0,5 0,6 0,7 0,8 1,3 1,4 1,5 1,6 1,7 1,8 2,2 2,3 2,4 2,5 2,6 2,7 2,8 3,1 3,2 3,3 3,4 3,5 3,6 3,7 3,8 4,0 4,1 4,2 4,3 4,4 4,5 4,6 4,7 4,8 5,0 5,1 5,2 5,3 5,4 5,5 5,6 5,7 6,0 6,1 6,2 6,3 6,4 6,5 6,6 7,0 7,1 7,2 7,3 7,4 7,5 8,0 8,1 8,2 8,3 Input action: applying action... Last Action: 8,3 Current board: Havannah 0 1 2 3 4 5 6 7 8 -------------------- 0 \ O \ . \ . \ . \ . \ ------------------------ 1 \ . \ . \ . \ . \ . \ . \ ---------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ -------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 5 \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ ---------------------------- 7 \ . \ . \ . \ . \ . \ . \ ------------------------ 8 \ . \ . \ . \ X \ X \ -------------------- 0 1 2 3 4 5 6 7 8 Legal Actions: 0,5 0,6 0,7 0,8 1,3 1,4 1,5 1,6 1,7 1,8 2,2 2,3 2,4 2,5 2,6 2,7 2,8 3,1 3,2 3,3 3,4 3,5 3,6 3,7 3,8 4,0 4,1 4,2 4,3 4,4 4,5 4,6 4,7 4,8 5,0 5,1 5,2 5,3 5,4 5,5 5,6 5,7 6,0 6,1 6,2 6,3 6,4 6,5 6,6 7,0 7,1 7,2 7,3 7,4 7,5 8,0 8,1 8,2 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Havannah8.txt ================================================ actions: ['0,7', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 14,7 Current board: Havannah 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 -------------------------------- 0 \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 1 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------ 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------------------- 5 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------------------ 7 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------------------ 8 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------------------- 9 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------------------- 10 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------ 11 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------- 12 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------- 13 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 14 \ . \ . \ . \ . \ . \ . \ . \ X \ -------------------------------- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Legal Actions: 0,7 0,8 0,9 0,10 0,11 0,12 0,13 0,14 1,6 1,7 1,8 1,9 1,10 1,11 1,12 1,13 1,14 2,5 2,6 2,7 2,8 2,9 2,10 2,11 2,12 2,13 2,14 3,4 3,5 3,6 3,7 3,8 3,9 3,10 3,11 3,12 3,13 3,14 4,3 4,4 4,5 4,6 4,7 4,8 4,9 4,10 4,11 4,12 4,13 4,14 5,2 5,3 5,4 5,5 5,6 5,7 5,8 5,9 5,10 5,11 5,12 5,13 5,14 6,1 6,2 6,3 6,4 6,5 6,6 6,7 6,8 6,9 6,10 6,11 6,12 6,13 6,14 7,0 7,1 7,2 7,3 7,4 7,5 7,6 7,7 7,8 7,9 7,10 7,11 7,12 7,13 7,14 8,0 8,1 8,2 8,3 8,4 8,5 8,6 8,7 8,8 8,9 8,10 8,11 8,12 8,13 9,0 9,1 9,2 9,3 9,4 9,5 9,6 9,7 9,8 9,9 9,10 9,11 9,12 10,0 10,1 10,2 10,3 10,4 10,5 10,6 10,7 10,8 10,9 10,10 10,11 11,0 11,1 11,2 11,3 11,4 11,5 11,6 11,7 11,8 11,9 11,10 12,0 12,1 12,2 12,3 12,4 12,5 12,6 12,7 12,8 12,9 13,0 13,1 13,2 13,3 13,4 13,5 13,6 13,7 13,8 14,0 14,1 14,2 14,3 14,4 14,5 14,6 Input action: applying action... Last Action: 14,6 Current board: Havannah 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 -------------------------------- 0 \ O \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 1 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------ 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------------------- 5 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------------------ 7 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------------------ 8 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------------------- 9 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------------------- 10 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------------------ 11 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ -------------------------------------------- 12 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ---------------------------------------- 13 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ------------------------------------ 14 \ . \ . \ . \ . \ . \ . \ X \ X \ -------------------------------- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Legal Actions: 0,8 0,9 0,10 0,11 0,12 0,13 0,14 1,6 1,7 1,8 1,9 1,10 1,11 1,12 1,13 1,14 2,5 2,6 2,7 2,8 2,9 2,10 2,11 2,12 2,13 2,14 3,4 3,5 3,6 3,7 3,8 3,9 3,10 3,11 3,12 3,13 3,14 4,3 4,4 4,5 4,6 4,7 4,8 4,9 4,10 4,11 4,12 4,13 4,14 5,2 5,3 5,4 5,5 5,6 5,7 5,8 5,9 5,10 5,11 5,12 5,13 5,14 6,1 6,2 6,3 6,4 6,5 6,6 6,7 6,8 6,9 6,10 6,11 6,12 6,13 6,14 7,0 7,1 7,2 7,3 7,4 7,5 7,6 7,7 7,8 7,9 7,10 7,11 7,12 7,13 7,14 8,0 8,1 8,2 8,3 8,4 8,5 8,6 8,7 8,8 8,9 8,10 8,11 8,12 8,13 9,0 9,1 9,2 9,3 9,4 9,5 9,6 9,7 9,8 9,9 9,10 9,11 9,12 10,0 10,1 10,2 10,3 10,4 10,5 10,6 10,7 10,8 10,9 10,10 10,11 11,0 11,1 11,2 11,3 11,4 11,5 11,6 11,7 11,8 11,9 11,10 12,0 12,1 12,2 12,3 12,4 12,5 12,6 12,7 12,8 12,9 13,0 13,1 13,2 13,3 13,4 13,5 13,6 13,7 13,8 14,0 14,1 14,2 14,3 14,4 14,5 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Hex11.txt ================================================ actions: ['a1', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: k11 Current board: Hex a b c d e f g h i j k --------------------------------------------- 1 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 5 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 7 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 8 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 9 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 10 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 11 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ B \ -------------------------------------------- a b c d e f g h i j k Legal Actions: a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 h11 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j11 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 Input action: applying action... Last Action: k10 Current board: Hex a b c d e f g h i j k --------------------------------------------- 1 \ W \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 5 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 7 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 8 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 9 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ --------------------------------------------- 10 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ B \ --------------------------------------------- 11 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ B \ -------------------------------------------- a b c d e f g h i j k Legal Actions: a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 h11 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j11 k1 k2 k3 k4 k5 k6 k7 k8 k9 Input action: failed to parse action Input action: ================================================ FILE: pypolygames/tests/data/Hex13.txt ================================================ actions: ['a1', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: m13 Current board: Hex a b c d e f g h i j k l m ----------------------------------------------------- 1 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 5 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 7 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 8 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 9 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 10 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 11 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 12 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 13 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ B \ ---------------------------------------------------- a b c d e f g h i j k l m Legal Actions: a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 e12 e13 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 g12 g13 h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 h11 h12 h13 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j11 j12 j13 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 l1 l2 l3 l4 l5 l6 l7 l8 l9 l10 l11 l12 l13 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 Input action: applying action... Last Action: m12 Current board: Hex a b c d e f g h i j k l m ----------------------------------------------------- 1 \ W \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 2 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 3 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 4 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 5 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 6 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 7 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 8 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 9 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 10 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 11 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ ----------------------------------------------------- 12 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ B \ ----------------------------------------------------- 13 \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ . \ B \ ---------------------------------------------------- a b c d e f g h i j k l m Legal Actions: a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 e12 e13 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 g12 g13 h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 h11 h12 h13 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j11 j12 j13 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 l1 l2 l3 l4 l5 l6 l7 l8 l9 l10 l11 l12 l13 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 Input action: failed to parse action Input action: ================================================ FILE: pypolygames/tests/data/KyotoShogi.txt ================================================ actions: ['0', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: p -> r-A4 Current board: A| B| C| D| E 5 | g| k| s| t 4 r| | | | 3 | | | | 2 | | | | 1 T| S| K| G| P Legal Actions: Action 0: T -> L-B2 Action 1: T -> L-A2 Action 2: S -> B-C2 Action 3: S -> B-B2 Action 4: S -> B-A2 Action 5: K -> K-D2 Action 6: K -> K-C2 Action 7: K -> K-B2 Action 8: G -> KN-E2 Action 9: G -> KN-D2 Action 10: G -> KN-C2 Action 11: P -> R-E2 Input format : action index e.g. 0 Input action: applying action... Last Action: r -> p-A1 Current board: A| B| C| D| E 5 | g| k| s| t 4 | | | | 3 | | | | 2 | L| | | 1 p| S| K| G| P Legal Actions: Action 0: L -> T-B3 Action 1: L -> T-B4 Action 2: L -> T-B5 Action 3: S -> B-C2 Action 4: S -> B-A2 Action 5: K -> K-D2 Action 6: K -> K-C2 Action 7: G -> KN-E2 Action 8: G -> KN-D2 Action 9: G -> KN-C2 Action 10: P -> R-E2 Input format : action index e.g. 0 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Minishogi.txt ================================================ actions: ['0', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: p-E3 Current board: A| B| C| D| E 5 r| b| s| g| k 4 | | | | 3 | | | | p 2 P| | | | 1 K| G| S| B| R Legal Actions: Action 0: K-B2 Action 1: G-C2 Action 2: G-B2 Action 3: S-D2 Action 4: S-C2 Action 5: S-B2 Action 6: B-E2 Action 7: B-C2 Action 8: B-B3 Action 9: B-A4 Action 10: R-E2 Action 11: R-E3 Action 12: P-A3 Input format : action index e.g. 0 Input action: applying action... Last Action: p-E2 Current board: A| B| C| D| E 5 r| b| s| g| k 4 | | | | 3 | | | | 2 P| K| | | p 1 | G| S| B| R Legal Actions: Action 0: K-C2 Action 1: K-C3 Action 2: K-B3 Action 3: K-A3 Action 4: K-A1 Action 5: G-C2 Action 6: G-A1 Action 7: S-D2 Action 8: S-C2 Action 9: B-E2 Action 10: B-C2 Action 11: B-B3 Action 12: B-A4 Action 13: R-E2 Action 14: P-A3 Input format : action index e.g. 0 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Othello10.txt ================================================ actions: ['G6', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: put chess at F04 Current board: Empty=' ' Black='●' White='○' A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ │ │ │ │ │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ ○ │ ● │ │ │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ ● │ ● │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ │ │ ● │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J Allowed positions: ('?' means an allowed position) A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ │ │ │ │ │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ ○ │ ● │ ? │ │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ ● │ ● │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ │ ? │ ● │ ? │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J Input a position to play: (uses format , e.g. `A1`, `b2`, `C03`...) > applying action... Last Action: put chess at H07 Current board: Empty=' ' Black='●' White='○' A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ │ │ │ │ │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ ● │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ ○ │ ○ │ ● │ │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ ● │ ● │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ │ │ ● │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J Allowed positions: ('?' means an allowed position) A B C D E F G H I J ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 10 │ │ │ │ │ │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ ● │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ ○ │ ○ │ ● │ ? │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ ● │ ● │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ ? │ ? │ ● │ ? │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ ? │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J Input a position to play: (uses format , e.g. `A1`, `b2`, `C03`...) > invalid input, try again. > ================================================ FILE: pypolygames/tests/data/Othello16.txt ================================================ actions: ['J9', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: put chess at I07 Current board: Empty=' ' Black='●' White='○' A B C D E F G H I J K L M N O P ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 16 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 16 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 15 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 15 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 14 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 14 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 13 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 13 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 12 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 12 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 11 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 11 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 10 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ ○ │ ● │ │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ ● │ ● │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ │ ● │ │ │ │ │ │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J K L M N O P Allowed positions: ('?' means an allowed position) A B C D E F G H I J K L M N O P ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 16 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 16 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 15 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 15 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 14 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 14 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 13 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 13 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 12 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 12 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 11 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 11 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 10 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ ○ │ ● │ ? │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ ● │ ● │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ ? │ ● │ ? │ │ │ │ │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J K L M N O P Input a position to play: (uses format , e.g. `A1`, `b2`, `C03`...) > applying action... Last Action: put chess at K10 Current board: Empty=' ' Black='●' White='○' A B C D E F G H I J K L M N O P ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 16 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 16 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 15 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 15 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 14 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 14 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 13 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 13 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 12 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 12 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 11 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 11 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 10 │ │ │ │ │ │ │ │ │ │ │ ● │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ ○ │ ○ │ ● │ │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ ● │ ● │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ │ │ ● │ │ │ │ │ │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J K L M N O P Allowed positions: ('?' means an allowed position) A B C D E F G H I J K L M N O P ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ 16 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 16 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 15 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 15 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 14 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 14 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 13 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 13 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 12 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 12 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 11 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 11 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 10 │ │ │ │ │ │ │ │ │ │ │ ● │ │ │ │ │ │ 10 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 09 │ │ │ │ │ │ │ │ ○ │ ○ │ ● │ ? │ │ │ │ │ │ 09 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 08 │ │ │ │ │ │ │ │ ● │ ● │ │ │ │ │ │ │ │ 08 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 07 │ │ │ │ │ │ │ ? │ ? │ ● │ ? │ │ │ │ │ │ │ 07 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 06 │ │ │ │ │ │ │ │ │ ? │ │ │ │ │ │ │ │ 06 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 05 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 05 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 04 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 04 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 03 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 03 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 02 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 02 ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ 01 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 01 └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ A B C D E F G H I J K L M N O P Input a position to play: (uses format , e.g. `A1`, `b2`, `C03`...) > invalid input, try again. > ================================================ FILE: pypolygames/tests/data/OthelloOpt10.txt ================================================ actions: ['0', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 0, 5, 6 Current board: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |o|x| | | | | | | |x|x| | | | | | | | |x| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Legal Actions: Action 0: 0, 6, 4 Action 1: 0, 4, 6 Action 2: 0, 6, 6 Input action: applying action... Last Action: 0, 7, 3 Current board: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |x| | | | | |o|o|x| | | | | | |x|x| | | | | | | | |x| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Legal Actions: Action 0: 0, 7, 4 Action 1: 0, 3, 6 Action 2: 0, 4, 6 Action 3: 0, 6, 6 Action 4: 0, 5, 7 Input action: Input action: ================================================ FILE: pypolygames/tests/data/OthelloOpt16.txt ================================================ actions: ['0', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 0, 8, 9 Current board: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |o|x| | | | | | | | | | | | | |x|x| | | | | | | | | | | | | | |x| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Legal Actions: Action 0: 0, 9, 7 Action 1: 0, 7, 9 Action 2: 0, 9, 9 Input action: applying action... Last Action: 0, 10, 6 Current board: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |x| | | | | | | | | | | |o|o|x| | | | | | | | | | | | |x|x| | | | | | | | | | | | | | |x| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Legal Actions: Action 0: 0, 10, 7 Action 1: 0, 6, 9 Action 2: 0, 7, 9 Action 3: 0, 9, 9 Action 4: 0, 8, 10 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Surakarta.txt ================================================ actions: ['A5-B4', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: F2-E3 Current board: A|B|C|D|E|F 6 x|x|x|x|x|x 5 x|x|x|x|x|x 4 | | | | | 3 | | | |o| 2 o|o|o|o|o| 1 o|o|o|o|o|o Legal Actions: Action 0: A5-B4 Action 1: A5-A4 Action 2: B5-C4 Action 3: B5-B4 Action 4: B5-A4 Action 5: C5-D4 Action 6: C5-C4 Action 7: C5-B4 Action 8: D5-E4 Action 9: D5-D4 Action 10: D5-C4 Action 11: E5-F4 Action 12: E5-E4 Action 13: E5-D4 Action 14: F5-F4 Action 15: F5-E4 Input format : - e.g. A1-A2 Input action: applying action... Last Action: F1-F2 Current board: A|B|C|D|E|F 6 x|x|x|x|x|x 5 |x|x|x|x|x 4 |x| | | | 3 | | | |o| 2 o|o|o|o|o|o 1 o|o|o|o|o| Legal Actions: Action 0: A6-A5 Action 1: B4-C4 Action 2: B4-C3 Action 3: B4-B3 Action 4: B4-A3 Action 5: B4-A4 Action 6: B4-A5 Action 7: B5-C4 Action 8: B5-A4 Action 9: B5-A5 Action 10: B6-A5 Action 11: C5-D4 Action 12: C5-C4 Action 13: D5-E4 Action 14: D5-D4 Action 15: D5-C4 Action 16: E5-F4 Action 17: E5-E4 Action 18: E5-D4 Action 19: F5-F4 Action 20: F5-E4 Input format : - e.g. A1-A2 Input action: Input action: ================================================ FILE: pypolygames/tests/data/Tristannogo.txt ================================================ actions: ['0', 'blublu'] ###################################################################### # HUMAN-PLAYED GAME # ###################################################################### setting-up pseudo-random generator... creating human-played environment playing against a human player... Last Action: 0, 8, 8 Current board: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 Legal Actions: Action 0: 0, 0, 0 Action 1: 0, 1, 0 Action 2: 0, 2, 0 Action 3: 0, 3, 0 Action 4: 0, 4, 0 Action 5: 0, 5, 0 Action 6: 0, 6, 0 Action 7: 0, 7, 0 Action 8: 0, 8, 0 Action 9: 0, 0, 1 Action 10: 0, 1, 1 Action 11: 0, 2, 1 Action 12: 0, 3, 1 Action 13: 0, 4, 1 Action 14: 0, 5, 1 Action 15: 0, 6, 1 Action 16: 0, 7, 1 Action 17: 0, 8, 1 Action 18: 0, 0, 2 Action 19: 0, 1, 2 Action 20: 0, 2, 2 Action 21: 0, 3, 2 Action 22: 0, 4, 2 Action 23: 0, 5, 2 Action 24: 0, 6, 2 Action 25: 0, 7, 2 Action 26: 0, 8, 2 Action 27: 0, 0, 3 Action 28: 0, 1, 3 Action 29: 0, 2, 3 Action 30: 0, 3, 3 Action 31: 0, 4, 3 Action 32: 0, 5, 3 Action 33: 0, 6, 3 Action 34: 0, 7, 3 Action 35: 0, 8, 3 Action 36: 0, 0, 4 Action 37: 0, 1, 4 Action 38: 0, 2, 4 Action 39: 0, 3, 4 Action 40: 0, 4, 4 Action 41: 0, 5, 4 Action 42: 0, 6, 4 Action 43: 0, 7, 4 Action 44: 0, 8, 4 Action 45: 0, 0, 5 Action 46: 0, 1, 5 Action 47: 0, 2, 5 Action 48: 0, 3, 5 Action 49: 0, 4, 5 Action 50: 0, 5, 5 Action 51: 0, 6, 5 Action 52: 0, 7, 5 Action 53: 0, 8, 5 Action 54: 0, 0, 6 Action 55: 0, 1, 6 Action 56: 0, 2, 6 Action 57: 0, 3, 6 Action 58: 0, 4, 6 Action 59: 0, 5, 6 Action 60: 0, 6, 6 Action 61: 0, 7, 6 Action 62: 0, 8, 6 Action 63: 0, 0, 7 Action 64: 0, 1, 7 Action 65: 0, 2, 7 Action 66: 0, 3, 7 Action 67: 0, 4, 7 Action 68: 0, 5, 7 Action 69: 0, 6, 7 Action 70: 0, 7, 7 Action 71: 0, 8, 7 Action 72: 0, 0, 8 Action 73: 0, 1, 8 Action 74: 0, 2, 8 Action 75: 0, 3, 8 Action 76: 0, 4, 8 Action 77: 0, 5, 8 Action 78: 0, 6, 8 Action 79: 0, 7, 8 Input action: applying action... Last Action: 0, 7, 8 Current board: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 Legal Actions: Action 0: 0, 1, 0 Action 1: 0, 2, 0 Action 2: 0, 3, 0 Action 3: 0, 4, 0 Action 4: 0, 5, 0 Action 5: 0, 6, 0 Action 6: 0, 7, 0 Action 7: 0, 8, 0 Action 8: 0, 0, 1 Action 9: 0, 1, 1 Action 10: 0, 2, 1 Action 11: 0, 3, 1 Action 12: 0, 4, 1 Action 13: 0, 5, 1 Action 14: 0, 6, 1 Action 15: 0, 7, 1 Action 16: 0, 8, 1 Action 17: 0, 0, 2 Action 18: 0, 1, 2 Action 19: 0, 2, 2 Action 20: 0, 3, 2 Action 21: 0, 4, 2 Action 22: 0, 5, 2 Action 23: 0, 6, 2 Action 24: 0, 7, 2 Action 25: 0, 8, 2 Action 26: 0, 0, 3 Action 27: 0, 1, 3 Action 28: 0, 2, 3 Action 29: 0, 3, 3 Action 30: 0, 4, 3 Action 31: 0, 5, 3 Action 32: 0, 6, 3 Action 33: 0, 7, 3 Action 34: 0, 8, 3 Action 35: 0, 0, 4 Action 36: 0, 1, 4 Action 37: 0, 2, 4 Action 38: 0, 3, 4 Action 39: 0, 4, 4 Action 40: 0, 5, 4 Action 41: 0, 6, 4 Action 42: 0, 7, 4 Action 43: 0, 8, 4 Action 44: 0, 0, 5 Action 45: 0, 1, 5 Action 46: 0, 2, 5 Action 47: 0, 3, 5 Action 48: 0, 4, 5 Action 49: 0, 5, 5 Action 50: 0, 6, 5 Action 51: 0, 7, 5 Action 52: 0, 8, 5 Action 53: 0, 0, 6 Action 54: 0, 1, 6 Action 55: 0, 2, 6 Action 56: 0, 3, 6 Action 57: 0, 4, 6 Action 58: 0, 5, 6 Action 59: 0, 6, 6 Action 60: 0, 7, 6 Action 61: 0, 8, 6 Action 62: 0, 0, 7 Action 63: 0, 1, 7 Action 64: 0, 2, 7 Action 65: 0, 3, 7 Action 66: 0, 4, 7 Action 67: 0, 5, 7 Action 68: 0, 6, 7 Action 69: 0, 7, 7 Action 70: 0, 8, 7 Action 71: 0, 0, 8 Action 72: 0, 1, 8 Action 73: 0, 2, 8 Action 74: 0, 3, 8 Action 75: 0, 4, 8 Action 76: 0, 5, 8 Action 77: 0, 6, 8 Input action: Input action: ================================================ FILE: pypolygames/tests/test_interactions.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import time import difflib import tempfile import subprocess from pathlib import Path from pprint import pprint from unittest import SkipTest import pytest from ..utils import listings class FileStream: """Simplifies stdout reading """ def __init__(self) -> None: self.tempdir = tempfile.TemporaryDirectory() path = Path(self.tempdir.name) / "std_in_out.txt" self.writer = path.open("w") self.reader = path.open("r") def __del__(self) -> None: self.writer.close() self.reader.close() # Specify any specific set of actions for your game GAME_ACTIONS = {"Breakthrough": ["1", "blublu"], "GameOfTheAmazons": ["A7", "B6", "C6", "blublu"], "Othello10": ["G6", "blublu"], "Othello16": ["J9", "blublu"], "Havannah5": ["0,4", "blublu"], "Havannah8": ["0,7", "blublu"], "Hex11": ["a1", "blublu"], "Hex13": ["a1", "blublu"], "Surakarta": ["A5-B4", "blublu"], "DiceShogi": ["1", "1", "blublu"], "ChineseCheckers": ["C4", "G35", "A10", "blublu"], } @pytest.mark.parametrize( "game_name", [game_name for game_name in listings.games(olympiads=True)] ) def test_game_interactions(game_name: str): raise SkipTest if game_name in ["Einstein", "DiceShogi"]: # Feel free to add name here in order to deactivate a test raise SkipTest(f"Skipping {game_name} for lack of reproducibility") actions = GAME_ACTIONS.get(game_name, ["0", "blublu"]) # let's play fsout = FileStream() command = ['timeout', '--signal=SIGTERM', '20', 'python', '-um', 'pypolygames', 'human', "--pure_mcts", f'--game_name={game_name}', '--num_rollouts=2', '--seed=12'] input_requests = ["Input", "Random outcome", "Chess you choose is:", "Where you wanna go:"] # this may need to be made more robust text = "" popen = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=fsout.writer) try: # wait for the process to initialize for _ in range(120): # wait for input request if any(x in text for x in input_requests): break text = fsout.reader.read() if text: print(text) # for debugging time.sleep(.1) for action in actions: print(f"*** PLAYING: {action} ***") popen.stdin.write((action + "\n").encode()) popen.stdin.flush() text = "" for _ in range(20): # wait for input request if any(x in text for x in input_requests): break text = fsout.reader.read() if text: print(text) time.sleep(.1) except Exception as e: popen.terminate() # make sure the process is killed, whatever happens raise e popen.terminate() fsout.reader.seek(0) all_text = f"actions: {actions}\n" + fsout.reader.read() # # compare the outputs to records filepath = Path(__file__).parent / "data" / f"{game_name}.txt" filepath.parent.mkdir(exist_ok=True) if not filepath.exists(): filepath.write_text(all_text) raise AssertionError("Logs were written, rerun once again to test reproducibility") expected = filepath.read_text() if all_text != expected: print("\n\n\nHERE IS THE DIFF:\n\n\n") pprint(list(difflib.Differ().compare(all_text.splitlines(), expected.splitlines()))) raise ValueError(f"String differ. If the new string is better, delete {filepath}\n" "and rerun twice (pytest pypolygames/tests/test_interactions)\n" "Alternatively, feel free to add failing games to the list of skipped\n" "tests at the top of this function, and notify jrapin or teytaud\n" "(we'll reactivate it for you later on, since it can be cumbersome).") ================================================ FILE: pypolygames/tests/test_mcts.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import time import random from unittest import SkipTest from pathlib import Path import pytest from .. import params from .. import evaluation from .. import utils @pytest.mark.parametrize( "game_name", [game_name for game_name in utils.listings.games()] ) def test_mcts(game_name) -> None: # # Important informations in the following block about which games are skipped because they are: # - too slow (more than 1min) # - crashing (segfault or crash with no more information) # - too_bad: not better with larger rollouts (these games are played but not evaluated) # also, for some games, we must add some tolerance (they dont win at 100%) # crashing = [] is_one_player_game = any(x in game_name for x in ["asterm", "ineswee", "WeakSchur"]) too_slow = [ "GameOfTheAmazons", "Connect6", "KyotoShogi", "Hex19", "Hex19pie", "Minishogi", "DiceShogi", "ChineseCheckers", ] too_bad = ["Havannah5", "Havannah5pie", "Surakarta", "DiceShogi", "Connect6"] if game_name in crashing + too_slow: # + one_player_games: raise SkipTest(f"Skipping {game_name}") if "inesweeper" in game_name and "4_4_4" not in game_name: raise SkipTest(f"Skipping {game_name}") if "astermind" in game_name and "4_4_6" not in game_name: raise SkipTest(f"Skipping {game_name}") if "WeakSchur" in game_name: raise SkipTest(f"Skipping {game_name} (currently aborts when finished, which kills the CI)") # for allowing some tolerance to winning all games with larger rollouts, add here: tolerance = { "TicTacToe": 4, "FreeStyleGomoku": 4, "OuterOpenGomoku": 3, "Havannah5pieExt": 2, "Havannah8": 5, "Havannah8pie": 5, "Hex13": 2, "Hex13pie": 2, "Einstein": 3, "Othello10": 2, "OthelloOpt10": 2, "YINSH": 3, "Minishogi": 1, "GomokuSwap2": 3, "BlockGo": 2, }.get(game_name, 1) # game_params = params.GameParams(game_name=game_name) case = random.randint(0, 2) rollouts = (2, 40) if ( not case ): # In case 0, 0 wins, else 1 (this makes sure results dependent on rollouts) rollouts = tuple(reversed(rollouts)) eval_params = params.EvalParams( num_game_eval=10, device_eval="cpu", checkpoint_dir=Path("mock/path"), # this should not be *required* here! no network num_rollouts_eval=rollouts[0], num_rollouts_opponent=rollouts[1], ) # device eval is actually not used def seed_generator(): i = 0 while True: yield i i += 1 context, _, _, get_eval_reward = evaluation.create_evaluation_environment( seed_generator=seed_generator(), game_params=game_params, eval_params=eval_params, pure_mcts_eval=True, ) context.start() while not context.terminated(): time.sleep(0.01) # check that the one with most rollouts wins! score = sum(v > 0 for v in get_eval_reward()) expected = 0 if case else eval_params.num_game_eval msg = f"Wrong score for random case {case}, expected {expected} with tol {tolerance} but got {score}." if is_one_player_game or game_name in too_bad: raise SkipTest(f"Skipping evaluation of {game_name} (not very good, or one player)") assert abs(score - expected) <= tolerance, msg ================================================ FILE: pypolygames/tests/test_params.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import pytest from pathlib import Path from dataclasses import asdict from .. import params @pytest.mark.parametrize( "cls", [ params.GameParams, params.ModelParams, params.OptimParams, params.SimulationParams, params.EvalParams, params.ExecutionParams, ], ) def test_dataclass(cls): argfields = dict(cls.arg_fields()) for key, field in argfields.items(): if key != field.name.strip("-"): raise AssertionError( f"ArgField key ('{key}') and " f"name ('{field.name.strip('-')}') must match!" ) if "default" in field.opts: assert field.opts["default"] == getattr( cls, key ), f"Field default do not match class one for {key}" field_keys = set(argfields) cls_attrs = set( asdict(cls() if cls != params.EvalParams else cls(checkpoint_dir=Path("blublu"))) ) additional = field_keys - cls_attrs missing = cls_attrs - field_keys errors = [] if additional: errors.append( f"Found additional fields {additional} in " f"{cls.__name__}.arg_fields() compared to its attributes." ) if missing: errors.append( f"Found missing fields {missing} in " f"{cls.__name__}.arg_fields() compared to its attributes." ) if errors: raise AssertionError("\n".join(errors)) ================================================ FILE: pypolygames/tests/test_zoo.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from unittest import SkipTest import pytest import torch from .. import model_zoo from ..model_zoo.utils import get_game_info from .. import params from .. import utils @pytest.mark.parametrize("model_name", [n for n in model_zoo.MODELS]) def test_models(model_name) -> None: if model_name in ["Connect4BenchModel", "ResConvConvLogitPoolModelV2"]: raise SkipTest(f"Skipping {model_name}") game_params = params.GameParams( game_name="Tristannogo" if "GameOfTheAmazons" not in model_name else "GameOfTheAmazons" ) model_params = params.ModelParams(model_name=model_name) info = get_game_info(game_params) model = model_zoo.MODELS[model_name](game_params, model_params) model.eval() # necessary for batch norm as it expects more than 1 ex in training feature_size = info["feature_size"][:3] action_size = info["action_size"][:3] input_data = torch.zeros([1] + feature_size, device=torch.device("cpu")) outputs = model.forward(input_data) assert list(outputs["v"].shape) == [1, 1] assert list(outputs["pi"].shape) == [1] + action_size # loss multi_counter = utils.MultiCounter(root=None) pi_mask = torch.ones(outputs["pi"].shape) model.loss( model, input_data, outputs["v"], outputs["pi"], pi_mask, multi_counter ) # make sure it computes something ================================================ FILE: pypolygames/training.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import os import sys import time import datetime from pathlib import Path from dataclasses import asdict from typing import Iterator, Tuple, Callable, List, Optional, Dict from concurrent.futures import ThreadPoolExecutor import torch from torch import nn import tube import polygames from .params import ( GameParams, ModelParams, OptimParams, SimulationParams, ExecutionParams, ) from . import utils from .env_creation_helpers import create_model, create_game, create_player from .model_zoo import utils as zutils from .model_zoo import loss as model_loss ####################################################################################### # OPTIMIZER CREATION ####################################################################################### def create_optimizer( model: torch.jit.ScriptModule, optim_params: OptimParams, optim_state_dict: Optional[dict] = None, ) -> torch.optim.Optimizer: optim = torch.optim.Adam( model.parameters(), lr=optim_params.lr, eps=optim_params.eps ) if optim_state_dict is not None and not optim_params.reset_optimizer_state: try: optim.load_state_dict(optim_state_dict) except ValueError: print("Optimizer state not compatible... skipping.") return optim ####################################################################################### # TRAINING ENVIRONMENT CREATION ####################################################################################### def create_training_environment( seed_generator: Iterator[int], model_path: Path, device: str, game_params: GameParams, simulation_params: SimulationParams, execution_params: ExecutionParams, model ) -> Tuple[tube.Context, polygames.ModelManager, Callable[[], List[int]], bool]: games = [] context = tube.Context() print("Game generation device: {}".format(device)) listen_ep = execution_params.listen connect_ep = execution_params.connect opponent_model_path = execution_params.opponent_model_path is_server = listen_ep != "" is_client = connect_ep != "" print("is_server is ", is_server) print("is_client is ", is_client) model_manager = polygames.ModelManager( simulation_params.act_batchsize, str(device), simulation_params.replay_capacity, next(seed_generator), str(model_path), simulation_params.train_channel_timeout_ms, simulation_params.train_channel_num_slots, ) model_manager.set_find_batch_size_max_bs(simulation_params.bsfinder_max_bs) model_manager.set_find_batch_size_max_ms(simulation_params.bsfinder_max_ms) if is_server: model_manager.start_server(listen_ep) if is_client: model_manager.start_client(connect_ep) if is_client and is_server: raise RuntimeError("Client and server parameters have both been specified") rnn_state_shape = getattr(model, "rnn_state_shape", []) logit_value = getattr(model, "logit_value", False) print("rnn_state_shape is ", rnn_state_shape) if simulation_params.num_threads != 0: polygames.init_threads(simulation_params.num_threads) opgame = None op_rnn_state_shape = None op_rnn_seqlen = None op_logit_value = None if not is_server: if opponent_model_path: print("loading opponent model") checkpoint = utils.load_checkpoint(checkpoint_path=opponent_model_path) opmodel = create_model( game_params=checkpoint["game_params"], model_params=checkpoint["model_params"], resume_training=True, model_state_dict=checkpoint["model_state_dict"], ) opponent_model_path = execution_params.checkpoint_dir / "model_opponent.pt" opmodel.save(str(opponent_model_path)) opgame = create_game( checkpoint["game_params"], num_episode=-1, seed=next(seed_generator), eval_mode=False, ) op_rnn_state_shape = getattr(opmodel, "rnn_state_shape", []) op_rnn_seqlen = 0 if hasattr(checkpoint["execution_params"], "rnn_seqlen"): op_rnn_seqlen = checkpoint["execution_params"].rnn_seqlen op_logit_value = getattr(opmodel, "logit_value", False) model_manager_opponent = polygames.ModelManager( simulation_params.act_batchsize, str(device), simulation_params.replay_capacity, next(seed_generator), str(opponent_model_path) if opponent_model_path else str(model_path), simulation_params.train_channel_timeout_ms, simulation_params.train_channel_num_slots, ) model_manager_opponent.set_find_batch_size_max_bs(simulation_params.bsfinder_max_bs) model_manager_opponent.set_find_batch_size_max_ms(simulation_params.bsfinder_max_ms) print("tournament_mode is " + str(execution_params.tournament_mode)) if execution_params.tournament_mode: model_manager_opponent.set_is_tournament_opponent(True) if opponent_model_path: model_manager_opponent.set_dont_request_model_updates(True) if is_client: model_manager_opponent.start_client(connect_ep) if not is_server: train_channel = model_manager.get_train_channel() actor_channel = model_manager.get_act_channel() op_actor_channel = actor_channel if model_manager_opponent is not None: op_actor_channel = model_manager_opponent.get_act_channel() for i in range(simulation_params.num_game): game = create_game( game_params, num_episode=-1, seed=next(seed_generator), eval_mode=False, per_thread_batchsize=simulation_params.per_thread_batchsize, rewind=simulation_params.rewind, predict_end_state=game_params.predict_end_state, predict_n_states=game_params.predict_n_states, ) player_1 = create_player( seed_generator=seed_generator, game=game, player=game_params.player, num_actor=simulation_params.num_actor, num_rollouts=simulation_params.num_rollouts, pure_mcts=False, actor_channel=actor_channel, model_manager=model_manager, human_mode=False, sample_before_step_idx=simulation_params.sample_before_step_idx, randomized_rollouts=simulation_params.randomized_rollouts, sampling_mcts=simulation_params.sampling_mcts, rnn_state_shape=rnn_state_shape, rnn_seqlen=execution_params.rnn_seqlen, logit_value=logit_value ) player_1.set_name("dev") if game.is_one_player_game(): game.add_player(player_1, train_channel) else: player_2 = create_player( seed_generator=seed_generator, game=opgame if opgame is not None else game, player=game_params.player, num_actor=simulation_params.num_actor, num_rollouts=simulation_params.num_rollouts, pure_mcts=False, actor_channel=op_actor_channel, model_manager=model_manager_opponent, human_mode=False, sample_before_step_idx=simulation_params.sample_before_step_idx, randomized_rollouts=simulation_params.randomized_rollouts, sampling_mcts=simulation_params.sampling_mcts, rnn_state_shape=op_rnn_state_shape if op_rnn_state_shape is not None else rnn_state_shape, rnn_seqlen=op_rnn_seqlen if op_rnn_seqlen is not None else execution_params.rnn_seqlen, logit_value=op_logit_value if op_logit_value is not None else logit_value ) player_2.set_name("opponent") if next(seed_generator) % 2 == 0: game.add_player(player_1, train_channel, game, player_1) game.add_player(player_2, train_channel, opgame if opgame is not None else game, player_1) else: game.add_player(player_2, train_channel, opgame if opgame is not None else game, player_1) game.add_player(player_1, train_channel, game, player_1) context.push_env_thread(game) games.append(game) def get_train_reward() -> Callable[[], List[int]]: nonlocal games nonlocal opgame reward = [] for game in games: reward.append(game.get_result()[0]) if opgame is not None: reward.append(opgame.get_result()[0]) return reward return context, model_manager, get_train_reward, is_client ####################################################################################### # REPLAY BUFFER WARMING-UP ####################################################################################### def warm_up_replay_buffer( model_manager: polygames.ModelManager, replay_warmup: int ) -> None: model_manager.start() prev_buffer_size = -1 t = t_init = time.time() t0 = -1 size0 = 0 while model_manager.buffer_size() < replay_warmup: buffer_size = model_manager.buffer_size() if buffer_size != prev_buffer_size: # avoid flooding stdout if buffer_size > 10000 and t0 == -1: size0 = buffer_size t0 = time.time() prev_buffer_size = max(prev_buffer_size, 0) frame_rate = (buffer_size - prev_buffer_size) / (time.time() - t) frame_rate = int(frame_rate) prev_buffer_size = buffer_size t = time.time() duration = t - t_init print( f"warming-up replay buffer: {(buffer_size * 100) // replay_warmup}% " f"({buffer_size}/{replay_warmup}) in {duration:.2f}s " f"- speed: {frame_rate} frames/s", ) time.sleep(2) print( f"replay buffer warmed up: 100% " f"({model_manager.buffer_size()}/{replay_warmup})" " " ) print( "avg speed: %.2f frames/s" % ((model_manager.buffer_size() - size0) / (time.time() - t0)) ) ####################################################################################### # TRAINING ####################################################################################### class ModelWrapperForDDP(nn.Module): def __init__(self, module): super().__init__() self.module = module def forward(self, x: torch.Tensor, rnn_state: torch.Tensor=None, rnn_state_mask: torch.Tensor=None): if rnn_state is None: return self.module._forward(x, return_logit=True) else: return self.module._forward(x, rnn_state, rnn_state_mask, return_logit=True) class DDPWrapperForModel(nn.Module): def __init__(self, module): super().__init__() self.module = module def _forward(self, x: torch.Tensor, rnn_state: torch.Tensor=None, rnn_state_mask: torch.Tensor=None, return_logit: bool=False): if not return_logit: raise RuntimeError("DDPWrapperForModel: return_logit is false") if rnn_state is None: return self.module.forward(x) else: return self.module.forward(x, rnn_state, rnn_state_mask) _pre_num_add = None _pre_num_sample = None _running_add_rate = 0 _running_sample_rate = 0 _last_train_time = 0 def _train_epoch( model: torch.jit.ScriptModule, device: torch.device, ddpmodel: ModelWrapperForDDP, batchsizes, optim: torch.optim.Optimizer, model_manager: polygames.ModelManager, stat: utils.MultiCounter, epoch: int, optim_params: OptimParams, sync_period: int, ) -> None: global _pre_num_add global _pre_num_sample global _running_add_rate global _running_sample_rate global _last_train_time global _remote_replay_buffer_inited if _pre_num_add is None: pre_num_add = model_manager.buffer_num_add() pre_num_sample = model_manager.buffer_num_sample() else: pre_num_add = _pre_num_add pre_num_sample = _pre_num_sample sync_s = 0. num_sync = 0 train_start_time = time.time() if pre_num_sample > 0: print("sample/add ratio ", float(pre_num_sample) / pre_num_add) if _last_train_time == 0: _last_train_time = time.time(); batchsize = optim_params.batchsize lossmodel = DDPWrapperForModel(ddpmodel) if ddpmodel is not None else model lossmodel.train() world_size = 0 rank = 0 if ddpmodel is not None: print("DDP is active") world_size = torch.distributed.get_world_size() rank = torch.distributed.get_rank() print("World size %d, rank %d. Waiting for all processes" % (world_size, rank)) torch.distributed.barrier() print("Synchronizing model") for p in ddpmodel.parameters(): torch.distributed.broadcast(p.data, 0) for p in ddpmodel.buffers(): torch.distributed.broadcast(p.data, 0) print("Synchronized, start training") has_predict = False cpubatch = {} for k, v in batchsizes.items(): sizes = v.copy() sizes.insert(0, batchsize) cpubatch[k] = torch.empty(sizes) if k == "predict_pi": has_predict = True for eid in range(optim_params.epoch_len): while _running_add_rate * 1.25 < _running_sample_rate: print("add rate insufficient, waiting") time.sleep(5) t = time.time() time_elapsed = t - _last_train_time _last_train_time = t alpha = pow(0.99, time_elapsed) post_num_add = model_manager.buffer_num_add() post_num_sample = model_manager.buffer_num_sample() delta_add = post_num_add - pre_num_add delta_sample = post_num_sample - pre_num_sample _running_add_rate = _running_add_rate * alpha + (delta_add / time_elapsed) * (1 - alpha) _running_sample_rate = _running_sample_rate * alpha + (delta_sample / time_elapsed) * (1 - alpha) pre_num_add = post_num_add pre_num_sample = post_num_sample print("running add rate: %.2f / s" % (_running_add_rate)) print("running sample rate: %.2f / s" % (_running_sample_rate)) print("current add rate: %.2f / s" % (delta_add / time_elapsed)) print("current sample rate: %.2f / s" % (delta_sample / time_elapsed)) if world_size > 0: batchlist = None if rank == 0: batchlist = {} for k in cpubatch.keys(): batchlist[k] = [] for i in range(world_size): for k,v in model_manager.sample(batchsize).items(): batchlist[k].append(v) for k, v in cpubatch.items(): torch.distributed.scatter(v, batchlist[k] if rank == 0 else None) batch = utils.to_device(cpubatch, device) else: batch = model_manager.sample(batchsize) batch = utils.to_device(batch, device) for k, v in batch.items(): batch[k] = v.detach() loss, v_err, pi_err, predict_err = model_loss.mcts_loss(model, lossmodel, batch) loss.backward() grad_norm = nn.utils.clip_grad_norm_(lossmodel.parameters(), optim_params.grad_clip) optim.step() optim.zero_grad() stat["v_err"].feed(v_err.item()) stat["pi_err"].feed(pi_err.item()) if has_predict: stat["predict_err"].feed(predict_err.item()) stat["loss"].feed(loss.item()) stat["grad_norm"].feed(grad_norm) if (epoch * optim_params.epoch_len + eid + 1) % sync_period == 0: sync_t0 = time.time() model_manager.update_model(model.state_dict()) sync_s += time.time() - sync_t0 num_sync += 1 t = time.time() time_elapsed = t - _last_train_time _last_train_time = t alpha = pow(0.99, time_elapsed) post_num_add = model_manager.buffer_num_add() post_num_sample = model_manager.buffer_num_sample() delta_add = post_num_add - pre_num_add delta_sample = post_num_sample - pre_num_sample _running_add_rate = _running_add_rate * alpha + (delta_add / time_elapsed) * (1 - alpha) _running_sample_rate = _running_sample_rate * alpha + (delta_sample / time_elapsed) * (1 - alpha) pre_num_add = post_num_add pre_num_sample = post_num_sample total_time_elapsed = time.time() - train_start_time print("running add rate: %.2f / s" % (_running_add_rate)) print("running sample rate: %.2f / s" % (_running_sample_rate)) print("current add rate: %.2f / s" % (delta_add / time_elapsed)) print("current sample rate: %.2f / s" % (delta_sample / time_elapsed)) print(f"syncing duration: {sync_s:2f}s for {num_sync} syncs ({int(100 * sync_s / total_time_elapsed)}% of train time)") _pre_num_add = pre_num_add _pre_num_sample = pre_num_sample stat.summary(epoch) stat.reset() def train_model( command_history: utils.CommandHistory, start_time: float, model: torch.jit.ScriptModule, device: torch.device, ddpmodel, optim: torch.optim.Optimizer, context: tube.Context, model_manager: polygames.ModelManager, get_train_reward: Callable[[], List[int]], game_params: GameParams, model_params: ModelParams, optim_params: OptimParams, simulation_params: SimulationParams, execution_params: ExecutionParams, epoch: int = 0, ) -> None: info = zutils.get_game_info(game_params) c, h, w = info["feature_size"][:3] rc, rh, rw = info["raw_feature_size"][:3] c_prime, h_prime, w_prime = info[ "action_size" ][:3] predicts = (2 if game_params.predict_end_state else 0) + game_params.predict_n_states batchsizes = { "s": [c, h, w], "v": [3 if getattr(model, "logit_value", False) else 1], "pred_v": [1], "pi": [c_prime, h_prime, w_prime], "pi_mask": [c_prime, h_prime, w_prime] } if game_params.player == "forward": batchsizes["action_pi"] = [c_prime, h_prime, w_prime] if predicts > 0: batchsizes["predict_pi"] = [rc * predicts, rh, rw] batchsizes["predict_pi_mask"] = [rc * predicts, rh, rw] if getattr(model, "rnn_state_shape", None) is not None: batchsizes["rnn_state_mask"] = [1] if execution_params.rnn_seqlen > 0: for k, v in batchsizes.items(): batchsizes[k] = [execution_params.rnn_seqlen, *v] if getattr(model, "rnn_state_shape", None) is not None: batchsizes["rnn_initial_state"] = model.rnn_state_shape rank = 0 if ddpmodel: rank = torch.distributed.get_rank() executor = ThreadPoolExecutor(max_workers=1) savefuture = None stat = utils.MultiCounter(execution_params.checkpoint_dir) max_time = execution_params.max_time init_epoch = epoch while max_time is None or time.time() < start_time + max_time: if epoch - init_epoch >= optim_params.num_epoch: break epoch += 1 if rank == 0 and epoch % execution_params.saving_period == 0: model_manager.add_tournament_model("e%d" % (epoch), model.state_dict()) savestart = time.time() if savefuture is not None: savefuture.result() savefuture = utils.save_checkpoint( command_history=command_history, epoch=epoch, model=model, optim=optim, game_params=game_params, model_params=model_params, optim_params=optim_params, simulation_params=simulation_params, execution_params=execution_params, executor=executor ) print("checkpoint saved in %gs" % (time.time() - savestart)) _train_epoch( model=model, device=device, ddpmodel=ddpmodel, batchsizes=batchsizes, optim=optim, model_manager=model_manager, stat=stat, epoch=epoch, optim_params=optim_params, sync_period=simulation_params.sync_period, ) # resource usage stats print("Resource usage:") print(utils.get_res_usage_str()) print("Context stats:") print(context.get_stats_str()) # train result print( ">>>train: epoch: %d, %s" % (epoch, utils.Result(get_train_reward()).log()), flush=True, ) if savefuture is not None: savefuture.result() # checkpoint last state utils.save_checkpoint( command_history=command_history, epoch=epoch, model=model, optim=optim, game_params=game_params, model_params=model_params, optim_params=optim_params, simulation_params=simulation_params, execution_params=execution_params, ) def client_loop( model_manager: polygames.ModelManager, start_time: float, context: tube.Context, execution_params: ExecutionParams, ) -> None: model_manager.start() max_time = execution_params.max_time while max_time is None or time.time() < start_time + max_time: time.sleep(60) print("Resource usage:") print(utils.get_res_usage_str()) print("Context stats:") print(context.get_stats_str()) ####################################################################################### # OVERALL TRAINING WORKFLOW ####################################################################################### def run_training( command_history: utils.CommandHistory, game_params: GameParams, model_params: ModelParams, optim_params: OptimParams, simulation_params: SimulationParams, execution_params: ExecutionParams, ) -> None: start_time = time.time() logger_path = os.path.join(execution_params.checkpoint_dir, "train.log") sys.stdout = utils.Logger(logger_path) print("#" * 70) print("#" + "TRAINING".center(68) + "#") print("#" * 70) if execution_params.rnn_seqlen > 0: optim_params.batchsize //= execution_params.rnn_seqlen simulation_params.replay_capacity //= execution_params.rnn_seqlen simulation_params.replay_warmup //= execution_params.rnn_seqlen simulation_params.train_channel_num_slots //= execution_params.rnn_seqlen print("setting-up pseudo-random generator...") seed_generator = utils.generate_random_seeds(seed=execution_params.seed) # checkpoint, resume from where it stops epoch = 0 ckpts = list(utils.gen_checkpoints(checkpoint_dir=execution_params.checkpoint_dir, only_last=True, real_time=False)) checkpoint = {} if ckpts: checkpoint = ckpts[0] former_command_history = checkpoint["command_history"] command_history.build_history(former_command_history) optim_params = command_history.update_params_from_checkpoint( checkpoint_params=checkpoint["optim_params"], resume_params=optim_params ) simulation_params = command_history.update_params_from_checkpoint( checkpoint_params=checkpoint["simulation_params"], resume_params=simulation_params, ) execution_params = command_history.update_params_from_checkpoint( checkpoint_params=checkpoint["execution_params"], resume_params=execution_params, ) if command_history.last_command_contains("init_checkpoint"): if ckpts: raise RuntimeError("Cannot restart from init_checkpoint, already restarting from non-empty checkpoint_dir") # pretrained model, consider new training from epoch zero print("loading pretrained model from checkpoint...") checkpoint = utils.load_checkpoint(checkpoint_path=model_params.init_checkpoint) if checkpoint: # game_params and model_params cannot change on a checkpoint # either write the same, or don't specify them ignored = {"init_checkpoint", "game_name"} # this one can change current_params = dict(game_params=game_params, model_params=model_params) # for params_name, params in current_params.items(): # for attr, val in asdict(params).items(): # if command_history.last_command_contains(attr) and attr not in ignored: # ckpt_val = getattr(checkpoint[params_name], attr) # assert val == ckpt_val, f"When resuming, got '{val}' for {attr} but cannot override from past run with '{ckpt_val}'." specified_game_name = game_params.game_name game_params = checkpoint["game_params"] if specified_game_name is not None: game_params.game_name = specified_game_name model_params = checkpoint["model_params"] for params_name, params in current_params.items(): for attr, val in asdict(params).items(): if command_history.last_command_contains(attr) and attr not in ignored: ckpt_val = getattr(checkpoint[params_name], attr) if val != ckpt_val: print(f"Note: overrriding {attr} from {ckpt_val} to {val}") setattr(checkpoint[params_name], attr, val) epoch = checkpoint["epoch"] print("reconstructing the model...") else: print("creating and saving the model...") if len(execution_params.devices) != 1: raise RuntimeError("Only one device is supported for training") device = execution_params.devices[0] model = create_model( game_params=game_params, model_params=model_params, resume_training=bool(checkpoint), model_state_dict=checkpoint["model_state_dict"] if checkpoint else None, ).to(device) model_path = execution_params.checkpoint_dir / "model.pt" model.save(str(model_path)) ddpmodel = None if os.environ.get("RANK") is not None: torch.distributed.init_process_group(backend="gloo", timeout=datetime.timedelta(0, 864000)) ddpmodel = nn.parallel.DistributedDataParallel(ModelWrapperForDDP(model), broadcast_buffers=False, find_unused_parameters=False) print("creating optimizer...") optim = create_optimizer( model=ddpmodel if ddpmodel is not None else model, optim_params=optim_params, optim_state_dict=checkpoint.get("optim_state_dict", None), ) print("creating training environment...") context, model_manager, get_train_reward, is_client = create_training_environment( seed_generator=seed_generator, model_path=model_path, device=device, game_params=game_params, simulation_params=simulation_params, execution_params=execution_params, model=model ) if not is_client: model_manager.update_model(model.state_dict()) model_manager.add_tournament_model("init", model.state_dict()) context.start() if is_client: client_loop( model_manager=model_manager, start_time=start_time, context=context, execution_params=execution_params ) else: if ddpmodel is None or torch.distributed.get_rank() == 0: print("warming-up replay buffer...") warm_up_replay_buffer( model_manager=model_manager, replay_warmup=simulation_params.replay_warmup ) print("training model...") train_model( command_history=command_history, start_time=start_time, model=model, device=device, ddpmodel=ddpmodel, optim=optim, context=context, model_manager=model_manager, get_train_reward=get_train_reward, game_params=game_params, model_params=model_params, optim_params=optim_params, simulation_params=simulation_params, execution_params=execution_params, epoch=epoch ) elapsed_time = time.time() - start_time print(f"total time: {elapsed_time} s") ================================================ FILE: pypolygames/utils/__init__.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from .checkpoint import Checkpoint, save_checkpoint, load_checkpoint, gen_checkpoints from .command_history import CommandHistory from .logger import Logger from .plotter import Plotter from .multi_counter import MultiCounter from .helpers import * from .assert_utils import assert_eq from .result import Result from .restrack import get_res_usage_str from . import listings ================================================ FILE: pypolygames/utils/assert_utils.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. """Utils for assertions""" def assert_eq(real, expected): assert real == expected, '%s (true) vs %s (expected)' % (real, expected) def assert_neq(real, expected): assert real != expected, '%s (true) vs %s (expected)' % (real, expected) def assert_lt(real, expected): assert real < expected, '%s (true) vs %s (expected)' % (real, expected) def assert_lteq(real, expected): assert real <= expected, '%s (true) vs %s (expected)' % (real, expected) def assert_tensor_eq(t1, t2, eps=1e-6): if t1.size() != t2.size(): print('Warning: size mismatch', t1.size(), 'vs', t2.size()) return False t1 = t1.cpu().numpy() t2 = t2.cpu().numpy() diff = abs(t1 - t2) eq = (diff < eps).all() if not eq: import pdb pdb.set_trace() assert(eq) def assert_zero_grads(params): for p in params: if p.grad is not None: assert(p.grad.sum().item() == 0) ================================================ FILE: pypolygames/utils/checkpoint.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import glob import time import gzip import zipfile import re import copy from pathlib import Path from typing import Iterator, Dict, Union, Any from concurrent.futures import ThreadPoolExecutor import torch from .command_history import CommandHistory from ..params import ( GameParams, ModelParams, OptimParams, SimulationParams, ExecutionParams, ) Checkpoint = Dict[ str, Union[ int, bytes, Dict[str, Any], GameParams, ModelParams, OptimParams, SimulationParams, ExecutionParams, ], ] def save_checkpoint( command_history: CommandHistory, epoch: int, model: torch.jit.ScriptModule, optim: torch.optim.Optimizer, game_params: GameParams, model_params: ModelParams, optim_params: OptimParams, simulation_params: SimulationParams, execution_params: ExecutionParams, executor: ThreadPoolExecutor = None, ) -> None: checkpoint_dir = execution_params.checkpoint_dir save_uncompressed = execution_params.save_uncompressed checkpoint_name = f"checkpoint_{epoch}" checkpoint = { "command_history": command_history, "epoch": epoch, "model_state_dict": {k : v.cpu().clone() if isinstance(v, torch.Tensor) else copy.deepcopy(v) for k, v in model.state_dict().items()}, "optim_state_dict": {k : v.cpu().clone() if isinstance(v, torch.Tensor) else copy.deepcopy(v) for k, v in optim.state_dict().items()}, "game_params": game_params, "model_params": model_params, "optim_params": optim_params, "simulation_params": simulation_params, "execution_params": execution_params, } def saveit(): nonlocal save_uncompressed nonlocal checkpoint nonlocal checkpoint_dir if save_uncompressed: torch.save(checkpoint, checkpoint_dir / f"{checkpoint_name}.pt") else: # with zipfile.ZipFile(Path(checkpoint_dir) / f"{checkpoint_name}.zip", "w", allowZip64=True) as z: # with z.open(f"{checkpoint_name}.pt", "w", force_zip64=True) as f: # torch.save(checkpoint, f) with gzip.open(checkpoint_dir / f"{checkpoint_name}.pt.gz", "wb") as f: torch.save(checkpoint, f) if executor is not None: return executor.submit(saveit) else: saveit() def load_checkpoint(checkpoint_path: Path) -> Checkpoint: ext = checkpoint_path.suffix if ext == ".pt": checkpoint = torch.load(str(checkpoint_path), map_location=torch.device('cpu')) elif ext == ".gz": with gzip.open(checkpoint_path, "rb") as f: checkpoint = torch.load(f, map_location=torch.device('cpu')) elif ext == ".zip": with zipfile.ZipFile(checkpoint_path, "r", allowZip64=True) as z: checkpoint_unzipped_name = z.namelist()[0] with z.open(checkpoint_unzipped_name, "r") as f: checkpoint = torch.load(f) else: raise ValueError( "The checkpoint file extension must be either " "'.pt', '.gz', '.pt.gz' or '.zip'" ) return checkpoint EXT_PATTERN = re.compile(r"(\.pt|\.gz|\.pt\.gz|\.zip)$") def gen_checkpoints( checkpoint_dir: Path, real_time: bool, only_last: bool = False ) -> Iterator[Checkpoint]: checkpoint_basepath = str(checkpoint_dir / "checkpoint_") epoch_list = set() checkpoint_ext_detected = False first_time = True # infinite loop, could be made elegant with inotify while first_time or real_time: if not first_time: time.sleep(2) first_time = False checkpoint_path_list_no_ext = [ re.sub(EXT_PATTERN, "", checkpoint_path) for checkpoint_path in glob.glob(f"{checkpoint_basepath}*") ] new_epoch_list = { int(checkpoint_path_no_ext[len(checkpoint_basepath):]) for checkpoint_path_no_ext in checkpoint_path_list_no_ext } if not checkpoint_ext_detected and new_epoch_list: checkpoint_ext = re.search( EXT_PATTERN, next(iter(glob.glob(f"{checkpoint_basepath}*"))) ).group(0) checkpoint_ext_detected = True added_epoch_list = sorted(new_epoch_list - epoch_list) # if the evaluation runs in real time, only consider the latest checkpoint if real_time or only_last: added_epoch_list = added_epoch_list[-1:] epoch_list = new_epoch_list for epoch in added_epoch_list: print(f"loading checkpoint #{epoch}...") checkpoint_path = f"{checkpoint_basepath}{epoch}{checkpoint_ext}" yield load_checkpoint(checkpoint_path=Path(checkpoint_path)) ================================================ FILE: pypolygames/utils/command_history.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import sys import itertools from dataclasses import fields from typing import Optional, List from ..params import GenericParams class CommandHistory: def __init__(self): # remove '=' command = [ x for x in itertools.chain.from_iterable( map(lambda x: x.split("="), sys.argv) ) ] self._commands = [command] def build_history(self, former_command_history: "CommandHistory"): self._commands = former_command_history._commands + self._commands def former_commands_contain(self, option: str) -> bool: if option[:2] != "--": option = f"--{option}" for command in self._commands[:-1]: if option in command: return True return False def last_command_contains(self, option: str) -> bool: if option[:2] != "--": option = f"--{option}" if self._commands: if option in self._commands[-1]: return True return False def last_command_contains_params( self, DataclassParams: GenericParams, exclude: Optional[List[str]] = None ) -> bool: if exclude is None: exclude = [] exclude = [ f"--{option}" if option[:2] != "--" else option for option in exclude ] if self._commands: for _, arg_field in DataclassParams.arg_fields(): if arg_field.name not in exclude and self.last_command_contains( arg_field.name ): return True return False def update_params_from_checkpoint( self, checkpoint_params: GenericParams, resume_params: GenericParams ) -> GenericParams: Dataclass = type(checkpoint_params) params = {} for field in fields(Dataclass): formerly_set = self.former_commands_contain(field.name) newly_set = self.last_command_contains(field.name) if not formerly_set: if not newly_set: params.update({field.name: getattr(resume_params, field.name)}) else: params.update({field.name: getattr(resume_params, field.name)}) else: if not newly_set: params.update({field.name: getattr(checkpoint_params, field.name)}) else: params.update({field.name: getattr(resume_params, field.name)}) return Dataclass(**params) ================================================ FILE: pypolygames/utils/helpers.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from typing import Iterator import torch import random import numpy as np def generate_random_seeds(seed: int) -> Iterator[int]: # set-up all seeds random.seed(seed) np.random.seed(seed + 1) torch.manual_seed(seed + 2) torch.cuda.manual_seed(seed + 3) # generate random seeds generator = random.Random(seed) while True: yield generator.randint(0, 2 ** 31 - 1) def to_device(batch, device): if isinstance(batch, torch.Tensor): return batch.to(device).detach() elif isinstance(batch, dict): return {key: to_device(batch[key], device) for key in batch} else: assert False, "unsupported type: %s" % type(batch) ================================================ FILE: pypolygames/utils/listings.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import re import typing as tp from pathlib import Path def games(olympiads: bool = False) -> tp.List[str]: """List games using pattern in core/game.h Parameters ---------- olympiads: bool only list olympiad games """ if olympiads: pies = {"Hex11pie", "Hex13pie", "Hex19pie", "Havannah5pie", "Havannah8pie"} & set( games() ) # to ready yet return [ "BlockGo", "Einstein", "Othello8", "Othello10", "Othello16", "Minishogi", "DiceShogi", "Surakarta", "Breakthrough", "Tristannogo", "GameOfTheAmazons", ] + list(pies) filepath = Path(__file__).parents[2] / "core" / "game.h" assert filepath.exists() pattern = r".*if\s*?\(\s*?isGameNameMatched\s*?\(\s*?\{\s*?\"(?P\w+)\"[^}]*\}\s*?\)\s*?\)\s*?\{.*" iterator = re.finditer(pattern, filepath.read_text()) return list( x.group("name") for x in iterator if not x.group().strip().startswith("//") ) ================================================ FILE: pypolygames/utils/logger.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import os import sys class Logger: def __init__(self, path, mode='w'): assert mode in {'w', 'a'}, 'unknown mode for logger %s' % mode self.terminal = sys.stdout if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) if mode == 'w' or not os.path.exists(path): self.log = open(path, "w") else: self.log = open(path, "a") def write(self, message): self.terminal.write(message) self.log.write(message) self.log.flush() def flush(self): # for python 3 compatibility. pass ================================================ FILE: pypolygames/utils/multi_counter.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import os from pathlib import Path from collections import defaultdict, Counter from datetime import datetime from tensorboardX import SummaryWriter class ValueStats: def __init__(self, name=None): self.name = name self.reset() def feed(self, v): self.summation += v if v > self.max_value: self.max_value = v self.max_idx = self.counter if v < self.min_value: self.min_value = v self.min_idx = self.counter self.counter += 1 def mean(self): return self.summation / self.counter def summary(self, info=None): info = "" if info is None else info name = "" if self.name is None else self.name if self.counter > 0: # try: return "%s%s[%4d]: avg: %8.4f, min: %8.4f[%4d], max: %8.4f[%4d]" % ( info, name, self.counter, self.summation / self.counter, self.min_value, self.min_idx, self.max_value, self.max_idx, ) # except BaseException: # return "%s%s[Err]:" % (info, name) else: return "%s%s[0]" % (info, name) def reset(self): self.counter = 0 self.summation = 0.0 self.max_value = -1e38 self.min_value = 1e38 self.max_idx = None self.min_idx = None class MultiCounter: def __init__(self, root: Path, verbose=False): # TODO: rethink counters self.last_time = None self.verbose = verbose self.counts = Counter() self.stats = defaultdict(lambda: ValueStats()) self.total_count = 0 self.max_key_len = 0 if root is not None: self.tb_writer = SummaryWriter(str(root / "stat.tb")) else: self.tb_writer = None def __getitem__(self, key): if len(key) > self.max_key_len: self.max_key_len = len(key) if self.last_time is None: self.last_time = datetime.now() return self.stats[key] def start_timer(self): self.last_time = datetime.now() def inc(self, key): if self.verbose: print("[MultiCounter]: %s" % key) self.counts[key] += 1 self.total_count += 1 if self.last_time is None: self.last_time = datetime.now() def reset(self): for k in self.stats.keys(): self.stats[k].reset() self.counts = Counter() self.total_count = 0 self.last_time = datetime.now() def summary(self, global_counter): assert self.last_time is not None time_elapsed = (datetime.now() - self.last_time).total_seconds() print("[%d] Time spent = %.2f s" % (global_counter, time_elapsed)) for key, count in self.counts.items(): print("%s: %d/%d" % (key, count, self.total_count)) for k in sorted(self.stats.keys()): v = self.stats[k] info = str(global_counter) + ":" + k print(v.summary(info=info.ljust(self.max_key_len + 4))) if self.tb_writer is not None: self.tb_writer.add_scalar(k, v.mean(), global_counter) ================================================ FILE: pypolygames/utils/plotter.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from typing import List, Tuple import numpy as np from .result import Result class Plotter: def __init__(self, plot_enabled: bool, env: str, server: str, port: int): self.plot_enabled = plot_enabled self.env = env if plot_enabled: import visdom self.vis = visdom.Visdom(env=env, server=server, port=port) def plot_results(self, results: List[Tuple[int, Result]]): if self.plot_enabled: epochs, results = list(map(np.array, list(zip(*results)))) nb_wins, nb_ties, nb_losses = list( map( np.array, zip( *[ ( result.result["win"], result.result["tie"], result.result["loss"], ) for result in results ] ), ) ) nb_totals = np.array(list(map(sum, zip(nb_wins, nb_ties, nb_losses)))) win_percents, tie_percents, loss_percents = list( map( np.array, zip( *[ (100 * w / total, 100 * t / total, 100 * l / total) for w, t, l, total in zip( nb_wins, nb_ties, nb_losses, nb_totals ) ] ), ) ) # lines self.vis.line( win="eval win-tie-loss", X=epochs, Y=np.array([nb_wins, nb_ties, nb_losses]).T, opts={ "title": "eval win-tie-loss", "xlabel": "#epochs", "ylabel": "#games", "xtickmin": 0, "ytickmin": 0, "ytickmax": 100, "legend": ["wins", "ties", "losses"], }, ) # stacked area self.vis.line( win="eval stacked percentages", X=epochs, Y=np.array( [ win_percents, list(map(sum, zip(win_percents, tie_percents))), [100] * len(epochs), ] ).T, opts={ "title": "eval stacked percentages", "xlabel": "#epochs", "ylabel": "%", "xtickmin": 0, "ytickmin": 0, "ytickmax": 100, "fillarea": True, "legend": ["wins", "ties", "losses"], }, ) def save(self): if self.plot_enabled: self.vis.save([self.env]) ================================================ FILE: pypolygames/utils/restrack.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import resource import os import subprocess def get_gpu_usage_nvidia(): try: nvidia_exe = 'nvidia-smi' nvquery = "index,utilization.gpu,memory.total,memory.used" nvformat = "csv,noheader,nounits" stdout = subprocess.check_output([ nvidia_exe, f"--query-gpu={nvquery}", f"--format={nvformat}"]) except subprocess.CalledProcessError as e: return f"GPU: ({nvidia_exe} error code {e.returncode})" except FileNotFoundError as e: return "GPU: (unknown)" gpustrs_raw = stdout.decode("utf-8").strip().split(os.linesep) gpustrs = [] for gpustr_raw in gpustrs_raw: tokens = gpustr_raw.split(',') gpuid = tokens[0].strip() gpuutil = tokens[1].strip() memtotal = float(tokens[2].strip()) memused = float(tokens[3].strip()) gpustr = f"GPU{gpuid}: {gpuutil}%, {memused} MB / {memtotal} MB" gpustrs.append(gpustr) gpustr = os.linesep.join(gpustrs) return gpustr def get_res_usage_psutil_str(): import psutil p = psutil.Process() ru = p.as_dict(attrs=[ 'cpu_num', 'cpu_percent', 'cpu_times', 'num_threads', 'memory_info', 'memory_percent', 'nice', 'ionice']) cpu_num = ru['cpu_num'] cpu_nthr = ru['num_threads'] cpu_tusr = ru['cpu_times'].user cpu_tsys = ru['cpu_times'].system nice = ru['nice'] ionice = ru['ionice'] cpustr = f"CPU: {cpu_nthr} threads, Tusr={cpu_tusr}, " \ f"Tsys={cpu_tsys}" # f"Tsys={cpu_tsys}, nice={nice}, ionice={ionice}" mem_rss = ru['memory_info'].rss / 1024 / 1024 mem_vms = ru['memory_info'].vms / 1024 / 1024 mem_pcent = ru['memory_percent'] memstr = f"Mem: RSS {mem_rss:8.2f} MB," \ f" VMS {mem_vms:8.2f} MB, {mem_pcent:5.2f}%" gpustr = get_gpu_usage_nvidia() resstr = os.linesep.join([cpustr, gpustr, memstr]) return resstr def get_res_usage_no_psutil_str(): ru = resource.getrusage(resource.RUSAGE_SELF) cpustr = f"CPU User={ru.ru_utime} System={ru.ru_stime}" gpustr = get_gpu_usage_nvidia() memstr = f"Mem maxrss={ru.ru_maxrss}" comment = "(install psutil for detailed data)" resstr = f"{cpustr}, {gpustr}, {memstr}, {comment}" return resstr def get_res_usage_str(): try: import psutil return get_res_usage_psutil_str() except (ImportError, ModuleNotFoundError) as e: return get_res_usage_no_psutil_str() ================================================ FILE: pypolygames/utils/result.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # helper class for result stats def parse_reward(reward): result = {"win": 0, "loss": 0, "tie": 0, "avg": 0.} for r in reward: if r == -1: result["loss"] += 1 elif r == 1: result["win"] += 1 else: result["tie"] += 1 result["total"] = len(reward) result["avg"] = (sum(reward) / max(len(reward), 1) + 1.) / 2. return result class Result: def __init__(self, reward): self.reward = reward self.result = parse_reward(reward) def log(self): total = max(self.result["total"], 1) s = "win: %.2f, tie: %.2f, loss: %.2f, avg: %.2f" % ( 100 * self.result["win"] / total, 100 * self.result["tie"] / total, 100 * self.result["loss"] / total, 100 * self.result["avg"], ) return s ================================================ FILE: pypolygames/utils/test_listings.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from collections import Counter from . import listings def test_lists() -> None: includes = {"Connect4", "TicTacToe", "Othello8", "Othello16", "GameOfTheAmazons", "Hex5", "Hex11", "Hex13", "Connect6", "Havannah5", "Havannah8", "Breakthrough", "Tristannogo", "Minishogi", "Surakarta", "DiceShogi"} listed_items = listings.games() duplicated = {x: y for x, y in Counter(listed_items).items() if y > 1} assert duplicated == {} missing = includes - set(listed_items) assert not missing, f"Could not find {missing} (screening through core/game.h or model_zoo/init or main), was it renamed?" ================================================ FILE: pypolygames/weight_init.py ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from collections import OrderedDict import torch def _init_weight_from_method(init_method): def wrapped_init_method(net): if getattr(net, "weight", None) is not None: # with batch norm affine some weight have dim == 1 if net.weight.dim() > 1: return init_method(net) return wrapped_init_method WEIGHT_INIT = OrderedDict( xavier_uniform=_init_weight_from_method( lambda net: torch.nn.init.xavier_uniform_(net.weight, gain=1.0) ), xavier_normal=_init_weight_from_method( lambda net: torch.nn.init.xavier_normal_(net.weight, gain=1.0) ), kaiming_uniform=_init_weight_from_method( lambda net: torch.nn.init.kaiming_uniform_( net.weight, a=0, mode="fan_in", nonlinearity="relu" ) ), kaiming_normal=_init_weight_from_method( lambda net: torch.nn.init.kaiming_normal_( net.weight, a=0, mode="fan_in", nonlinearity="relu" ) ), ) ================================================ FILE: singularity/README.md ================================================ # Polygames singularity image Build an image with the following command (from polygames root directory): ```bash singularity build singularity/polygames.simg singularity/polygames.def ``` This can take up to 45min. Once the image is built, you can run it with: ```bash singularity shell --nv /checkpoint/polygames/polygames.simg ``` The `--nv` parameters gives access to the GPUs. Do not worry about the warnings: `awk: warning: escape sequence`. In the image, you can compile polygames with (please remove build if it already exists): ```bash cd polygames mkdir build cd build cmake .. make ``` The image can be used to run any command: ```bash singularity run --nv singularity/polygames.simg python -m pypolygames ``` ================================================ FILE: singularity/environment.yml ================================================ name: polygames channels: - pytorch - conda-forge - defaults dependencies: - ca-certificates=2019.6.16=hecc5488_0 - certifi=2019.6.16=py37_0 - libprotobuf=3.8.0=h8b12597_0 - openssl=1.1.1b=h14c3975_1 - protobuf=3.8.0=py37he1b5a44_0 - six=1.12.0=py37_1000 - tensorboardx=1.7=py_0 - blas=1.0=mkl - bzip2=1.0.6=h14c3975_5 - cffi=1.12.3=py37h2e261b9_0 - cmake=3.14.0=h52cb24c_0 - expat=2.2.6=he6710b0_0 - intel-openmp=2019.4=243 - krb5=1.16.1=h173b8e3_7 - libcurl=7.64.1=h20c2e04_0 - libedit=3.1.20181209=hc058e9b_0 - libffi=3.2.1=hd88cf55_4 - libgcc-ng=9.1.0=hdf63c60_0 - libgfortran-ng=7.3.0=hdf63c60_0 - libssh2=1.8.2=h1ba5d50_0 - libstdcxx-ng=9.1.0=hdf63c60_0 - mkl=2019.4=243 - mkl-include=2019.4=243 - mkl_fft=1.0.12=py37ha843d7b_0 - mkl_random=1.0.2=py37hd81dba3_0 - ncurses=6.1=he6710b0_1 - numpy=1.16.4=py37h7e9f1db_0 - numpy-base=1.16.4=py37hde5b4d6_0 - pip=19.1.1=py37_0 - pycparser=2.19=py37_0 - python=3.7.3=h0371630_0 - pyyaml=5.1=py37h7b6447c_0 - readline=7.0=h7b6447c_5 - rhash=1.3.8=h1ba5d50_0 - setuptools=41.0.1=py37_0 - sqlite=3.28.0=h7b6447c_0 - tk=8.6.8=hbc83047_0 - typing=3.6.4=py37_0 - wheel=0.33.4=py37_0 - xz=5.2.4=h14c3975_4 - yaml=0.1.7=had09818_2 - zlib=1.2.11=h7b6447c_3 - magma-cuda100=2.5.0=1 ================================================ FILE: singularity/polygames.def ================================================ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. Bootstrap: docker From: nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04 # chosen among: https://hub.docker.com/r/nvidia/cuda/ %runscript # init file loads conda environment #exec bash --init-file /opt/sing_bash_init_file exec $@ %files singularity/environment.yml environment.yml %environment SHELL=/bin/bash PATH="/opt/conda/bin:$PATH" export OMP_NUM_THREADS=1 # export CUDNN paths to avoid finding the external one export CUDNN_LIB_DIR=/usr/lib/x86_64-linux-gnu/libcudnn.so export CUDNN_INCLUDE_DIR=/usr/include export CUDNN_ROOT_DIR="" . /opt/conda/etc/profile.d/conda.sh conda activate pypg %labels AUTHOR Facebook AI Research %post # inspired from https://github.com/pytorch/pytorch/blob/master/docker/pytorch/Dockerfile # install depencies apt-get update apt-get install -y \ build-essential \ libzmq3-dev \ cmake \ wget \ vim \ git \ ca-certificates \ libjpeg-dev \ libpng-dev rm -rf /var/lib/apt/lists/ mkdir /checkpoint # for future bindings mkdir /public # for future bindings mkdir /scratch # for future bindings # install miniconda and the pypg environment wget -O ~/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash ~/miniconda.sh -b -p /opt/conda rm ~/miniconda.sh . /opt/conda/etc/profile.d/conda.sh conda init bash zsh echo '. /opt/conda/etc/profile.d/conda.sh; conda activate pypg' > /opt/sing_bash_init_file conda env create -f environment.yml --name pypg # conda create -n pypg pip conda activate pypg pip install pytest pytest-cov mypy ipython psutil nevergrad pyzmq # convenient to have # # the environment contains all this # conda create --name pypg python=3.7 pip -y # conda activate pypg # pip install tube # conda install numpy ninja pyyaml mkl mkl-include setuptools cmake cffi typing -y # conda install -c pytorch magma-cuda100 -y # conda install -c conda-forge tensorboardx -y # # it was exported with `conda env export > environment.yml` # download and install pytorch from source (in circleci: 2 cpus) export MAX_JOBS=$(cat /proc/cpuinfo | grep -c processor) if (( $MAX_JOBS < 4 )); then MAX_JOBS=4; fi; echo "Using $MAX_JOBS jobs for pytorch compilation" git clone --recursive https://github.com/pytorch/pytorch --branch=v1.1.0 ~/pytorch cd ~/pytorch export CMAKE_PREFIX_PATH=${CONDA_PREFIX:-"$(dirname $(which conda))/../"} # # set cuda arch list so that the built binary can be run on both pascal and volta MAX_JOBS=$MAX_JOBS TORCH_CUDA_ARCH_LIST='6.0;7.0' pip install . -v ================================================ FILE: src/CMakeLists.txt ================================================ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(third_party) include_directories(third_party/fmt/include) add_subdirectory(third_party/fmt) # add_subdirectory(torchRL) add_subdirectory(third_party/pybind11) add_subdirectory(tube) add_subdirectory(mcts) file(GLOB _zstd_SOURCES third_party/zstd/lib/common/*.c third_party/zstd/lib/compress/*.c third_party/zstd/lib/decompress/*.c) add_library(_zstd OBJECT ${_zstd_SOURCES}) target_include_directories(_zstd BEFORE PUBLIC third_party/zstd/lib third_party/zstd/lib/common) find_path(IBV_INCLUDE_DIR infiniband/verbs.h) find_library(IBV_LIBRARY ibverbs) add_library(libpolygames SHARED "") add_library(_distributed OBJECT distributed/network.cc distributed/distributed.cc ) target_include_directories(_distributed SYSTEM PUBLIC ${TORCH_INCLUDE_DIRS}) if (IBV_INCLUDE_DIR AND IBV_LIBRARY) message(STATUS "Found ibverbs: ${IBV_INCLUDE_DIR}/infiniband/verbs.h ${IBV_LIBRARY}") target_sources(_distributed PRIVATE distributed/ib.cc) target_include_directories(_distributed SYSTEM PUBLIC ${IBV_INCLUDE_DIR}) target_link_libraries(libpolygames PUBLIC ${IBV_LIBRARY}) else() message(STATUS "ibverbs NOT found, InfiniBand support will be disabled!") target_sources(_distributed PRIVATE distributed/rdma_nop.cc) endif() add_library(_common OBJECT common/thread_id.cc common/threads.cc ) set(_games_SOURCES games/gomoku_swap2.cc games/othello_opt.cc games/mastermind_state.cc games/amazons.cc games/breakthrough.cc games/chess.cc games/chinesecheckers.cc games/tristan_nogo.cc games/yinsh.cc games/minesweeper.cc games/weakschur/SchurMatrix.cpp games/weakschur/SchurVector.cpp games/weakschur/WeakSchur.cpp) if (JNI_FOUND) list(APPEND _games_SOURCES games/ludii/jni_utils.cc games/ludii/ludii_game_wrapper.cc games/ludii/ludii_state_wrapper.cc) endif() add_library(_games ${_games_SOURCES}) target_include_directories(_games PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/torchRL) target_include_directories(_games SYSTEM PUBLIC ${TORCH_INCLUDE_DIRS}) target_include_directories(_games PUBLIC ${PYTHON_INCLUDE_DIRS}) target_sources(libpolygames PRIVATE core/game.cc core/state.cc core/replay_buffer.cc core/model_manager.cc $ $ $ ) target_include_directories(libpolygames PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/torchRL) target_link_libraries(libpolygames PUBLIC _tube _mcts _games) set_target_properties(libpolygames PROPERTIES PREFIX "") if (JNI_FOUND) target_include_directories(_games PUBLIC ${JNI_INCLUDE_DIRS}) target_link_libraries(libpolygames PUBLIC ${JNI_LIBRARIES}) endif() pybind11_add_module(polygames core/pybind.cc ) target_link_libraries(polygames PUBLIC libpolygames) ================================================ FILE: src/common/async.h ================================================ #pragma once #include #include #include #include #include #include #include #include #ifdef _POSIX_C_SOURCE #include #endif namespace async { #ifdef _POSIX_C_SOURCE class Semaphore { sem_t sem; public: Semaphore() { sem_init(&sem, 0, 0); } ~Semaphore() { sem_destroy(&sem); } void post() { sem_post(&sem); } void wait() { sem_wait(&sem); } }; #else class Semaphore { int count_ = 0; std::mutex mut_; std::condition_variable cv_; public: void post() { std::unique_lock l(mut_); if (++count_ >= 1) { cv_.notify_one(); } } void wait() { std::unique_lock l(mut_); while (count_ == 0) { cv_.wait(l); } --count_; } }; #endif struct Function { Function* next = nullptr; int priority = 0; void* storage; size_t allocated = 0; void (*dtor)(void*); void (*call)(void*); Function() = default; Function(const Function&) = delete; Function& operator=(const Function&) = delete; Function(Function&& n) { storage = n.storage; allocated = n.allocated; dtor = n.dtor; call = n.call; n.storage = nullptr; } Function& operator=(Function&& n) { std::swap(storage, n.storage); std::swap(allocated, n.allocated); std::swap(dtor, n.dtor); std::swap(call, n.call); return *this; } template Function(F&& f) { storage = std::malloc(sizeof(F)); if (!storage) { throw std::bad_alloc(); } allocated = sizeof(F); try { new (storage) F(std::forward(f)); } catch (...) { std::free(storage); throw; } dtor = [](void* ptr) noexcept { ((F*)ptr)->~F(); }; call = [](void* ptr) noexcept { (*(F*)ptr)(); }; } template Function& operator=(F&& f) { if (allocated < sizeof(F)) { void* newStorage = std::malloc(sizeof(F)); if (!newStorage) { throw std::bad_alloc(); } if (storage) { dtor(storage); std::free(storage); } storage = newStorage; allocated = sizeof(F); } else { if (storage) { dtor(storage); } } try { new (storage) F(std::forward(f)); } catch (...) { std::free(storage); throw; } dtor = [](void* ptr) { ((F*)ptr)->~F(); }; call = [](void* ptr) { (*(F*)ptr)(); }; return *this; } ~Function() { if (storage) { dtor(storage); std::free(storage); } } void operator()() { call(storage); } }; template struct HandleT { Function* func = nullptr; Thread* thread = nullptr; HandleT() = default; HandleT(Function* func, Thread* thread) : func(func) , thread(thread) { } HandleT(HandleT&& n) { func = std::exchange(n.func, nullptr); thread = std::exchange(n.thread, nullptr); } HandleT(const HandleT&) = delete; HandleT& operator=(HandleT&& n) { std::swap(func, n.func); std::swap(thread, n.thread); return *this; } HandleT& operator=(const HandleT&) = delete; ~HandleT() { if (func) { Function* ftmp = thread->freelist; do { func->next = ftmp; } while (!thread->freelist.compare_exchange_weak(ftmp, func)); } } void setPriority(int value) { func->priority = value; } explicit operator bool() const { return func; } }; using Handle = HandleT; struct Thread { std::thread thread; std::atomic queue = nullptr; std::atomic freelist = nullptr; Function* internalqueue = nullptr; bool dead = false; Semaphore sem; Thread() = default; void threadEntry() { while (true) { Function* f = queue; while (!f) { if (dead) { return; } sem.wait(); f = queue; } while (!queue.compare_exchange_weak(f, f->next)) ; if (internalqueue || queue) { do { while (f) { Function** insert = &internalqueue; Function* next = internalqueue; while (next && next->priority <= f->priority) { insert = &next->next; next = next->next; } f->next = next; *insert = f; f = queue; while (f && !queue.compare_exchange_weak(f, f->next)) ; } f = internalqueue; internalqueue = f->next; (*f)(); f = queue; while (f && !queue.compare_exchange_weak(f, f->next)) ; } while (f || internalqueue); } else { (*f)(); } } } void enqueue(Function* func) { Function* qtmp = queue; do { func->next = qtmp; } while (!queue.compare_exchange_weak(qtmp, func)); sem.post(); } template Handle getHandle(F&& f) { Function* func = freelist; while (func && !freelist.compare_exchange_weak(func, func->next)) ; if (!func) { func = new Function(); } Handle h(func, this); *func = std::forward(f); return h; } }; struct Threads { std::atomic_size_t nextThread = 0; std::deque threads; size_t size() const { return threads.size(); } Thread& getThread() { return threads[nextThread++ % threads.size()]; } void enqueue(const Handle& h) { h.thread->enqueue(h.func); } Threads() = default; Threads(int nThreads) { start(nThreads); } void start(int nThreads) { for (int i = 0; i != nThreads; ++i) { threads.emplace_back(); Thread* t = &threads.back(); threads.back().thread = std::thread([t]() { t->threadEntry(); }); } } ~Threads() { for (auto& v : threads) { v.dead = true; v.sem.post(); } for (auto& v : threads) { v.thread.join(); } } }; struct Task { Semaphore sem; std::atomic_int liveCount{0}; Threads* threads = nullptr; Task() = default; Task(Threads& threads) : threads(&threads) { } ~Task() { wait(); } Task& operator=(const Task& n) { if (liveCount || n.liveCount) { throw std::runtime_error("attempt to copy active Task object"); } threads = n.threads; return *this; } template Handle getHandle(Thread& thread, F&& f) { return thread.getHandle([f = std::forward(f), this]() mutable { f(); if (--liveCount == 0) { sem.post(); } }); } void enqueue(const Handle& h) { ++liveCount; threads->enqueue(h); } void wait() { while (liveCount.load(std::memory_order_relaxed) != 0) { sem.wait(); } } }; } // namespace async ================================================ FILE: src/common/thread_id.cc ================================================ #include namespace { std::atomic_int threadIdCounter{0}; thread_local int threadId = ++threadIdCounter; } // namespace namespace common { int getThreadId() { return threadId; } } // namespace common ================================================ FILE: src/common/thread_id.h ================================================ namespace common { int getThreadId(); } ================================================ FILE: src/common/threads.cc ================================================ #include "threads.h" namespace threads { async::Threads threads; std::once_flag flag; void init(int nThreads) { std::call_once( flag, [](int nThreads) { if (nThreads <= 0) { nThreads = std::thread::hardware_concurrency(); if (nThreads <= 0) { throw std::runtime_error("Could not automatically determine the " "number of hardware threads :("); } printf("Starting %d threads (automatically configured)\n", nThreads); } else { printf("Starting %d threads\n", nThreads); } threads.start(nThreads); async::Task task(threads); std::vector handles; for (int i = 0; i != nThreads; ++i) { auto& thread = threads.getThread(); auto h = task.getHandle(thread, [i]() { setCurrentThreadName("async " + std::to_string(i)); }); task.enqueue(h); handles.push_back(std::move(h)); } task.wait(); }, nThreads); } void setCurrentThreadName(const std::string& name) { #ifdef __APPLE__ pthread_setname_np(name.c_str()); #elif __linux__ pthread_setname_np(pthread_self(), name.c_str()); #endif } } // namespace threads ================================================ FILE: src/common/threads.h ================================================ #include "async.h" #include namespace threads { extern async::Threads threads; void init(int nThreads); void setCurrentThreadName(const std::string& name); } // namespace threads ================================================ FILE: src/core/actor.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "model_manager.h" #include "tube/src_cpp/data_block.h" #include "tube/src_cpp/dispatcher.h" #include "state.h" #include "utils.h" //#define DEBUG_ACTOR namespace core { class PiVal { public: PiVal() { reset(); } void reset() { playerId = -999; value = 0.0f; logitPolicy.reset(); rnnState.reset(); } int playerId; float value; torch::Tensor logitPolicy; torch::Tensor rnnState; }; class Actor { public: Actor(std::shared_ptr dc, const std::vector& featSize, const std::vector& actionSize, const std::vector& rnnStateSize, int rnnSeqlen, bool logitValue, bool useValue, bool usePolicy, std::shared_ptr modelManager) : dispatcher_(std::move(dc)) , useValue_(useValue) , usePolicy_(usePolicy) , policySize_(actionSize) , uniformPolicy_(1.0 / product(actionSize)) , rnnStateSize_(rnnStateSize) , rnnSeqlen_(rnnSeqlen) , logitValue_(logitValue) , modelManager_(modelManager) { if (!useValue && !usePolicy_) { return; } feat_ = std::make_shared("s", featSize, torch::kFloat32); pi_ = std::make_shared( "pi_logit", actionSize, torch::kFloat32); value_ = std::make_shared( "v", std::initializer_list{logitValue ? 3 : 1}, torch::kFloat32); if (!rnnStateSize.empty()) { rnnState_ = std::make_shared( "rnn_state", rnnStateSize, torch::kFloat32); rnnStateOut_ = std::make_shared( "rnn_state_out", rnnStateSize, torch::kFloat32); } if (rnnStateSize.empty()) { dispatcher_.addDataBlocks({feat_}, {pi_, value_}); } else { dispatcher_.addDataBlocks( {feat_, rnnState_}, {pi_, value_, rnnStateOut_}); } } PiVal& evaluate(const core::State& s, PiVal& pival) { const auto state = dynamic_cast(&s); assert(state != nullptr); // termination should be handled by mcts assert(!state->terminated()); bool resultsAreValid = false; if (useValue_ || usePolicy_) { getFeatureInTensor(*state, feat_->data); int errcode = dispatcher_.dispatch(); switch (errcode) { case tube::Dispatcher::DISPATCH_ERR_DC_TERM: #ifdef DEBUG_ACTOR std::cout << "actor " << this << ": attempt to dispatch through" << " a terminated data channel " << std::endl; #endif break; case tube::Dispatcher::DISPATCH_ERR_NO_SLOT: #ifdef DEBUG_ACTOR std::cout << "actor " << this << ": no slots available to dispatch" << std::endl; #endif break; case tube::Dispatcher::DISPATCH_NOERR: resultsAreValid = true; } } float val; torch::Tensor policy; if (useValue_ && resultsAreValid) { if (logitValue_) { float* begin = value_->data.data_ptr(); float* end = begin + 3; softmax_(begin, end); } val = logitValue_ ? value_->data[0].item() - value_->data[1].item() : value_->data.item(); } else { val = state->getRandomRolloutReward(state->getCurrentPlayer()); } if (usePolicy_ && resultsAreValid) { policy = pi_->data; } else { policy = torch::zeros(policySize_, torch::kFloat32); policy.fill_(uniformPolicy_); } pival.logitPolicy = policy.clone(); pival.playerId = state->getCurrentPlayer(); pival.value = val; if (rnnStateOut_) { pival.rnnState = rnnStateOut_->data.clone(); } return pival; } void terminate() { dispatcher_.terminate(); } void batchResize(size_t n) { if (!modelManager_) { return; } if (!batchFeat_.defined() || batchFeat_[0].sizes() != feat_->data.sizes() || batchFeat_.size(0) < n) { auto allocBatch = [&](auto&& sizes) { std::vector s1(sizes.begin(), sizes.end()); s1.insert(s1.begin(), n); if (modelManager_ && modelManager_->isCuda()) { return torch::empty( s1, at::TensorOptions().pinned_memory(true).requires_grad(false)); } else { return torch::empty(s1, at::TensorOptions().requires_grad(false)); } }; batchFeat_ = allocBatch(feat_->data.sizes()); batchPi_ = allocBatch(pi_->data.sizes()); batchValue_ = allocBatch(value_->data.sizes()); valueAcc_ = batchValue_.accessor(); piAcc_ = batchPi_.accessor(); featAcc_ = batchFeat_.accessor(); } if (rnnState_) { rnnStateStack_.resize(n); } } void batchPrepare(size_t index, const core::State& s, torch::Tensor rnnState) { if (!modelManager_) { if (rnnState.defined()) { rnnState_->data.copy_(rnnState); } return; } getFeatureInTensor(*dynamic_cast(&s), featAcc_[index].data()); if (!useValue_) { batchValue_[index][0] = s.getRandomRolloutReward(s.getCurrentPlayer()); } if (rnnState.defined()) { if (rnnState.device() != device()) { rnnState = rnnState.to(device()); } rnnStateStack_.at(index) = rnnState; } } void batchEvaluate(size_t n) { if (!modelManager_) { return; } if (useValue_ || usePolicy_) { if (rnnState_) { modelManager_->batchAct( batchFeat_.narrow(0, 0, n), batchValue_.narrow(0, 0, n), batchPi_.narrow(0, 0, n), torch::stack(rnnStateStack_), &batchRnnStateOut_); } else { modelManager_->batchAct(batchFeat_.narrow(0, 0, n), batchValue_.narrow(0, 0, n), batchPi_.narrow(0, 0, n)); } } } void batchResult(size_t index, const core::State& s, PiVal& pival) { if (!modelManager_) { evaluate(s, pival); return; } if (logitValue_) { float* begin = &valueAcc_[index][0]; float* end = begin + 3; softmax_(begin, end); } float val = logitValue_ ? valueAcc_[index][0] - valueAcc_[index][1] : valueAcc_[index][0]; pival.logitPolicy = batchPi_[index].clone(); pival.playerId = s.getCurrentPlayer(); pival.value = val; if (rnnState_) { pival.rnnState = batchRnnStateOut_[index]; } } void recordMove(const core::State* state) { auto id = modelManager_->getTournamentModelId(); ++modelTrackers_[state][id]; } std::string getModelId() const { return modelManager_ ? std::string(modelManager_->getTournamentModelId()) : "dev"; } void result(const core::State* state, float reward) { if (modelManager_) { auto i = modelTrackers_.find(state); if (i != modelTrackers_.end()) { auto m = std::move(i->second); float sum = 0.0f; for (auto& v : m) { sum += v.second; } for (auto& v : m) { v.second /= sum; } modelManager_->result(reward, std::move(m)); modelTrackers_.erase(i); } } } void forget(const core::State* state) { if (modelManager_) { auto i = modelTrackers_.find(state); if (i != modelTrackers_.end()) { modelTrackers_.erase(i); } } } bool isTournamentOpponent() const { return modelManager_ ? modelManager_->isTournamentOpponent() : false; } bool wantsTournamentResult() const { return modelManager_ ? modelManager_->wantsTournamentResult() : false; } std::vector rnnStateSize() const { return rnnStateSize_; } int rnnSeqlen() const { return rnnSeqlen_; } int vOutputs() const { return logitValue_ ? 3 : 1; } int findBatchSize(const core::State& state) const { if (modelManager_) { if (rnnState_) { return modelManager_->findBatchSize( getFeatureInTensor(*dynamic_cast(&state)), torch::zeros(rnnStateSize_)); } else { return modelManager_->findBatchSize( getFeatureInTensor(*dynamic_cast(&state))); } } return 0; } bool isCuda() const { return modelManager_ ? modelManager_->isCuda() : false; } torch::Device device() const { return modelManager_ ? modelManager_->device() : torch::Device(torch::kCPU); } private: tube::Dispatcher dispatcher_; std::shared_ptr feat_; std::shared_ptr pi_; std::shared_ptr value_; std::shared_ptr rnnState_; std::shared_ptr rnnStateOut_; const bool useValue_; const bool usePolicy_; const std::vector policySize_; const float uniformPolicy_; torch::Tensor batchFeat_; torch::Tensor batchPi_; torch::Tensor batchValue_; torch::Tensor batchRnnStateOut_; torch::TensorAccessor valueAcc_{nullptr, nullptr, nullptr}; torch::TensorAccessor piAcc_{nullptr, nullptr, nullptr}; torch::TensorAccessor featAcc_{nullptr, nullptr, nullptr}; std::vector rnnStateStack_; torch::Tensor rnnStateStackResult_; std::unordered_map> modelTrackers_; const std::vector rnnStateSize_; int rnnSeqlen_ = 0; bool logitValue_ = false; std::shared_ptr modelManager_; }; } // namespace core ================================================ FILE: src/core/actor_player.h ================================================ #pragma once #include "actor.h" #include "player.h" namespace core { class ActorPlayer : public Player { public: ActorPlayer() : Player(false) { } void setActor(std::shared_ptr actor) { actor_ = std::move(actor); } void recordMove(const core::State* state) { actor_->recordMove(state); } void result(const core::State* state, float reward) { actor_->result(state, reward); } void forget(const core::State* state) { actor_->forget(state); } bool isTournamentOpponent() const { return actor_->isTournamentOpponent(); } bool wantsTournamentResult() const { return actor_->wantsTournamentResult(); } std::string getModelId() const { return actor_->getModelId(); } float calculateValue(const core::State& state) { PiVal result; actor_->evaluate(state, result); return result.value; } std::vector nextRnnState( const std::vector& state, const std::vector& rnnState) { PiVal result; actor_->batchResize(state.size()); for (size_t i = 0; i != state.size(); ++i) { actor_->batchPrepare(i, *state[i], rnnState[i]); } actor_->batchEvaluate(state.size()); std::vector r; for (size_t i = 0; i != state.size(); ++i) { actor_->batchResult(i, *state[i], result); r.push_back(result.rnnState); } return r; } std::vector rnnStateSize() const { return actor_->rnnStateSize(); } int rnnSeqlen() const { return actor_->rnnSeqlen(); } int vOutputs() const { return actor_->vOutputs(); } int findBatchSize(const core::State& state) const { return actor_->findBatchSize(state); } virtual void terminate() override { if (actor_) { actor_->terminate(); } } protected: std::shared_ptr actor_; }; } // namespace core ================================================ FILE: src/core/forward_player.h ================================================ #pragma once #include "actor_player.h" namespace core { class ForwardPlayer : public ActorPlayer { public: void batchResize(size_t n) { actor_->batchResize(n); } void batchPrepare(size_t index, const State& s, torch::Tensor rnnState) { actor_->batchPrepare(index, s, rnnState); } void batchEvaluate(size_t n) { actor_->batchEvaluate(n); } void batchResult(size_t index, const State& s, PiVal& pival) { actor_->batchResult(index, s, pival); } }; } // namespace core ================================================ FILE: src/core/game.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "game.h" #include "common/thread_id.h" #include "common/threads.h" #include "forward_player.h" #include "utils.h" #include namespace core { struct BatchExecutor { struct MoveHistory { int turn = 0; uint64_t move = 0; float value = 0.0f; torch::Tensor shortFeat; bool featurized = false; }; struct Sequence { std::vector feat; std::vector v; std::vector pi; std::vector piMask; std::vector actionPi; std::vector predV; torch::Tensor rnnInitialState; std::vector rnnStateMask; std::vector predictPi; std::vector predictPiMask; }; struct GameState { std::unique_ptr state; std::vector> playerState; std::vector players; std::vector playersReverseMap; std::vector> feat; std::vector> pi; std::vector> piMask; std::vector> rnnStates; std::vector> actionPi; std::vector> predV; std::vector> reward; size_t stepindex; std::chrono::steady_clock::time_point start; std::vector resignCounter; int drawCounter = 0; bool canResign = false; int resigned = -1; bool drawn = false; std::chrono::steady_clock::time_point prevMoveTime = std::chrono::steady_clock::now(); std::vector playerOrder; std::vector history; bool justRewound = false; bool justRewoundToNegativeValue = false; int rewindCount = 0; std::vector rnnState; std::vector rnnState2; std::vector allowRandomMoves; bool validTournamentGame = false; std::vector startMoves; int randMoveCount = 0; }; Game* game = nullptr; std::vector players_; std::unique_ptr basestate; std::minstd_rand rng{std::random_device{}()}; std::vector seqs; std::list states; std::list freeGameList; int64_t startedGameCount = 0; int64_t completedGameCount = 0; float runningAverageGameSteps = 0.0f; ActorPlayer* devPlayer = nullptr; std::vector actorPlayers; std::vector mctsPlayers; std::vector forwardPlayers; std::vector result_; std::vector> actStates; std::vector> actPlayerStates; std::vector> actGameStates; std::vector playerActStates; bool alignPlayers = true; std::vector> statePlayerSize; std::vector remapPlayerIdx; async::Task task; std::vector actRnnState; const mcts::MctsOption* mctsOption = nullptr; std::vector mctsResult; mutable std::mutex recordMoveMutex; int randint(int n) { return std::uniform_int_distribution(0, n - 1)(rng); } std::unique_ptr cloneState(const std::unique_ptr& state) const { return state->clone(); } void doRandomMoves(GameState& gst, int n) { auto o = cloneState(gst.state); std::vector moves; for (; n > 0; --n) { if (gst.state->terminated()) { break; } size_t n = randint(gst.state->GetLegalActions().size()); moves.push_back(n); gst.state->forward(n); } if (gst.state->terminated()) { gst.state = std::move(o); } else { for (auto m : moves) { for (auto& x : gst.playerState) { if (x) { x->forward(m); } } } // fmt::printf("Did %d random moves: '%s'\n", gst.state->getStepIdx(), // gst.state->history()); } gst.startMoves = std::move(moves); }; std::list::iterator addGame(std::list::iterator at) { if (!freeGameList.empty()) { GameState gst = std::move(freeGameList.front()); freeGameList.pop_front(); return states.insert(at, std::move(gst)); } ++startedGameCount; GameState gst; for (size_t i = 0; i != players_.size(); ++i) { gst.players.push_back(i); } std::shuffle(gst.players.begin(), gst.players.end(), rng); gst.playersReverseMap.resize(players_.size()); for (size_t i = 0; i != players_.size(); ++i) { gst.playersReverseMap[gst.players[i]] = i; } gst.state = cloneState(basestate); unsigned long seed = rng(); gst.state->newGame(seed); gst.playerState.resize(players_.size()); for (size_t i = 0; i != players_.size(); ++i) { std::unique_ptr s = nullptr; int index = gst.players[i]; if (&*game->playerGame_[index] != game) { s = cloneState(game->playerGame_[index]->state_); s->newGame(seed); } gst.playerState[i] = std::move(s); } gst.feat.resize(players_.size()); gst.pi.resize(players_.size()); gst.piMask.resize(players_.size()); gst.reward.resize(players_.size()); gst.rnnState.resize(players_.size()); gst.rnnState2.resize(players_.size()); gst.rnnStates.resize(players_.size()); gst.actionPi.resize(players_.size()); gst.predV.resize(players_.size()); gst.stepindex = 0; gst.start = std::chrono::steady_clock::now(); gst.resignCounter.resize(players_.size()); gst.canResign = !game->evalMode && players_.size() == 2 && randint(3) != 0; gst.validTournamentGame = true; gst.allowRandomMoves.resize(players_.size()); for (auto& v : gst.allowRandomMoves) { v = randint(4) == 0; } if (randint(250) == 0) { switch (randint(2)) { case 0: doRandomMoves(gst, randint(std::max((int)runningAverageGameSteps, 1))); break; case 1: doRandomMoves( gst, randint(std::max((int)runningAverageGameSteps / 10, 1))); break; case 2: doRandomMoves( gst, randint(std::max((int)runningAverageGameSteps / 5, 1))); break; } gst.validTournamentGame = false; } return states.insert(at, std::move(gst)); } bool rewind(GameState* s, int player, bool rewindToNegativeValue) const { if (s->history.size() <= 2) { // fmt::printf("refusing to rewind with history size %d\n", // s->history.size()); return false; } float flip = rewindToNegativeValue ? -1 : 1; size_t index = 0; for (index = s->history.size(); index;) { --index; auto& h = s->history[index]; if (h.turn == player && h.value * flip > 0) { break; } } if (index <= 2) { // fmt::printf("refusing to rewind to index %d\n", index); return false; } if (!s->rnnStates.empty() || !s->rnnState.empty() || !s->rnnState2.empty()) { bool rnn = false; for (auto& v : actorPlayers) { if (v->rnnSeqlen()) { rnn = true; } } if (rnn) { fmt::printf("Cannot currently rewind with rnn states, sorry :(\n"); return false; } } fmt::printf("rewinding from %d to index %d\n", s->history.size(), index); s->justRewound = true; s->justRewoundToNegativeValue = rewindToNegativeValue; auto& gst = *s; gst.state = cloneState(basestate); for (size_t i = 0; i != gst.playerState.size(); ++i) { auto& x = gst.playerState[i]; if (x) { int player = gst.players.at(i); x = cloneState(game->playerGame_.at(player)->state_); } } for (auto m : gst.startMoves) { gst.state->forward(m); for (auto& x : gst.playerState) { if (x) { x->forward(m); } } } for (auto& v : gst.feat) { v.clear(); } for (auto& v : gst.pi) { v.clear(); } for (auto& v : gst.piMask) { v.clear(); } for (auto& v : gst.reward) { v.clear(); } for (auto& v : gst.actionPi) { v.clear(); } for (auto& v : gst.predV) { v.clear(); } for (auto& v : gst.resignCounter) { v = 0; } gst.drawCounter = 0; gst.resigned = -1; gst.drawn = false; gst.history.resize(index); for (auto& v : gst.history) { v.featurized = false; gst.state->forward(v.move); for (auto& x : gst.playerState) { if (x) { x->forward(v.move); } } } return true; } using stateCallback = void (BatchExecutor::*)(GameState*, int currentPlayerIndex, size_t index) const; void actPrepareRnn(GameState* gameState, int currentPlayerIndex, size_t index) const { size_t slot = gameState->playersReverseMap.at(currentPlayerIndex); if (!gameState->rnnState.at(slot).defined()) { auto shape = actorPlayers.at(currentPlayerIndex)->rnnStateSize(); gameState->rnnState[slot] = torch::zeros(shape); } const_cast(actRnnState[index]) = std::move(gameState->rnnState[slot]); gameState->rnnState[slot].reset(); if (&*game->playerGame_.at(currentPlayerIndex) == game) { gameState->rnnStates.at(slot).push_back(actRnnState[index].cpu()); } } void actPrepareForward(GameState* gameState, int currentPlayerIndex, size_t index) const { auto* player = forwardPlayers.at(currentPlayerIndex); if (actRnnState.empty()) { player->batchPrepare(index, *gameState->state, {}); } else { player->batchPrepare(index, *gameState->state, actRnnState.at(index)); } } void actResult(GameState* gameState, int currentPlayerIndex, size_t index) const { State* state = &*gameState->state; size_t slot = gameState->playersReverseMap.at(currentPlayerIndex); if (gameState->rnnState.at(slot).defined()) { throw std::runtime_error("rnnState is not empty error"); } mcts::MctsPlayer* mctsPlayer = mctsPlayers[currentPlayerIndex]; ForwardPlayer* forwardPlayer = forwardPlayers[currentPlayerIndex]; PiVal pival; int bestAction = -1; float value = 0.0f; thread_local std::mt19937_64 tlrng(std::random_device{}()); if (forwardPlayer) { forwardPlayer->batchResult(index, *state, pival); gameState->rnnState[slot] = std::move(pival.rnnState); thread_local std::vector x; getLegalPi(*state, pival.logitPolicy, x); softmax_(x); bestAction = std::discrete_distribution(x.begin(), x.end())(tlrng); int oa = state->overrideAction(); if (oa != -1) { bestAction = oa; } value = pival.value; } else if (mctsPlayer) { gameState->rnnState[slot] = std::move(mctsResult.at(index).rnnState); bestAction = mctsResult.at(index).bestAction; value = mctsResult.at(index).rootValue; } else { throw std::runtime_error("unknown player"); } if (gameState->canResign) { if (value < -0.95f) { if (++gameState->resignCounter.at(slot) >= 7) { gameState->resigned = int(slot); } } else { gameState->resignCounter.at(slot) = 0; } int opponent = (gameState->playersReverseMap.at(currentPlayerIndex) + 1) % 2; if (value > 0.95f) { ++gameState->resignCounter.at(opponent); } else { gameState->resignCounter.at(opponent) = 0; } // Automatic draw disabled for now; this is not the best way to handle // this // TODO: enable this only for models with logit value outputs, since they // have // a logit specific for draw - this would work best with MCTS // modification that allows backpropagating the draw probability // if (gameState->stepindex >= 40 && value > // -0.05 && value < 0.05) { // ++gameState->drawCounter; // if (gameState->drawCounter >= 7) { // gameState->drawn = true; // } // } else { // gameState->drawCounter = 0; // } } bool saveForTraining = true; // TODO: improve this randomizedRollouts check, 1.5 is a magic number that // needs to be synchronized with mcts.cc if (mctsOption && mctsOption->randomizedRollouts && mctsResult.at(index).rollouts < mctsOption->numRolloutPerThread * 1.5f) { saveForTraining = false; } if (saveForTraining) { torch::Tensor feat = getFeatureInTensor(*state); gameState->feat.at(slot).push_back(feat); if (forwardPlayer) { auto actionPolicy = torch::zeros_like(pival.logitPolicy); auto action = state->GetLegalActions().at(bestAction); actionPolicy[action.GetX()][action.GetY()][action.GetZ()] = 1; gameState->actionPi.at(slot).push_back(actionPolicy); gameState->pi.at(slot).push_back(pival.logitPolicy); gameState->piMask.at(slot).push_back(getPolicyMaskInTensor(*state)); } else { auto [policy, policyMask] = getPolicyInTensor(*state, mctsResult.at(index).mctsPolicy); gameState->pi.at(slot).push_back(policy); gameState->piMask.at(slot).push_back(policyMask); } torch::Tensor predV = torch::zeros({1}, torch::kFloat32); predV[0] = value; gameState->predV.at(slot).push_back(predV); gameState->reward[slot].push_back(state->getReward(slot)); } gameState->history.emplace_back(); auto& h = gameState->history.back(); h.turn = slot; h.move = bestAction; h.value = value; h.featurized = saveForTraining; h.shortFeat = getRawFeatureInTensor(*state); if (gameState->rewindCount == 0) { std::lock_guard l(recordMoveMutex); actorPlayers[currentPlayerIndex]->recordMove(state); } state->forward(bestAction); auto now = std::chrono::steady_clock::now(); double elapsed = std::chrono::duration_cast< std::chrono::duration>>( now - gameState->prevMoveTime) .count(); gameState->prevMoveTime = now; // fmt::printf("Thread %d: move took %gs\n", common::getThreadId(), // elapsed); { std::unique_lock lkStats(game->mutexStats_); auto& stats_s = game->stats_["Move Duration (seconds)"]; std::get<0>(stats_s) += 1; std::get<1>(stats_s) += elapsed; std::get<2>(stats_s) += elapsed * elapsed; } if (gameState->justRewound) { float flip = gameState->justRewoundToNegativeValue ? -1.0f : 1.0f; if (h.value * flip < 0.0f) { // fmt::printf("rewound turned negative, rewinding more!\n"); rewind(gameState, slot, gameState->justRewoundToNegativeValue); } else { gameState->justRewound = false; } } // fmt::printf("game in progress: %s\n", state->history()); } std::vector stateCallbacks; std::vector taskHandles; void prepareStateCallbacks() { stateCallbacks.clear(); taskHandles.clear(); size_t offset = 0; for (size_t pi = 0; pi != statePlayerSize.size(); ++pi) { size_t currentPlayerIndex = statePlayerSize[pi].first; size_t currentPlayerStates = statePlayerSize[pi].second; for (size_t i = 0; i != currentPlayerStates; ++i) { GameState* gameState = actGameStates.at(currentPlayerIndex).at(i); auto f = [this, gameState, currentPlayerIndex, index = offset + i]() { for (auto& cb : stateCallbacks) { (this->*cb)(gameState, currentPlayerIndex, index); } }; auto& thread = threads::threads.getThread(); taskHandles.push_back(task.getHandle(thread, std::move(f))); taskHandles.back().setPriority(common::getThreadId()); } offset += currentPlayerStates; } } void pushStateCallback(stateCallback cb) { stateCallbacks.push_back(cb); } void runStateCallbacks() { if (stateCallbacks.empty()) { return; } for (auto& v : taskHandles) { task.enqueue(v); } task.wait(); } void actForPlayer(size_t playerIndex) { // Merge all identical players so they get batched together auto& states = actStates[playerIndex]; if (!states.empty()) { statePlayerSize.clear(); statePlayerSize.emplace_back(playerIndex, states.size()); for (size_t i = 0; i != players_.size(); ++i) { if (i != playerIndex && remapPlayerIdx[i] == playerIndex) { auto& nstates = actStates[i]; if (!nstates.empty()) { states.insert(states.end(), nstates.begin(), nstates.end()); statePlayerSize.emplace_back(i, nstates.size()); nstates.clear(); } } } playerActStates.resize(states.size()); size_t offset = 0; for (size_t pi = 0; pi != statePlayerSize.size(); ++pi) { size_t currentPlayerIndex = statePlayerSize[pi].first; size_t currentPlayerStates = statePlayerSize[pi].second; for (size_t i = 0; i != currentPlayerStates; ++i) { GameState* gameState = actGameStates.at(currentPlayerIndex).at(i); int slot = gameState->playersReverseMap.at(currentPlayerIndex); if (gameState->playerState.at(slot)) { playerActStates.at(offset + i) = &*gameState->playerState[slot]; } else { playerActStates.at(offset + i) = states.at(offset + i); } } offset += currentPlayerStates; } prepareStateCallbacks(); if (actorPlayers.at(playerIndex)->rnnSeqlen()) { actRnnState.resize(states.size()); pushStateCallback(&BatchExecutor::actPrepareRnn); } else { actRnnState.clear(); } mctsResult.clear(); if (forwardPlayers.at(playerIndex)) { forwardPlayers[playerIndex]->batchResize(states.size()); pushStateCallback(&BatchExecutor::actPrepareForward); runStateCallbacks(); forwardPlayers[playerIndex]->batchEvaluate(states.size()); } else { runStateCallbacks(); mctsResult = mctsPlayers.at(playerIndex)->actMcts(playerActStates, actRnnState); } stateCallbacks.clear(); // allowRandomMoves support // TODO: move into a state callback if (mctsPlayers.at(playerIndex)) { offset = 0; for (size_t pi = 0; pi != statePlayerSize.size(); ++pi) { size_t currentPlayerIndex = statePlayerSize[pi].first; size_t currentPlayerStates = statePlayerSize[pi].second; for (size_t i = 0; i != currentPlayerStates; ++i) { State* state = (State*)states.at(offset + i); GameState* gameState = actGameStates.at(currentPlayerIndex).at(i); size_t slot = gameState->playersReverseMap.at(currentPlayerIndex); if (gameState->allowRandomMoves.at(slot)) { float x = 4.0f / std::pow(state->getStepIdx() + 10, 2.0f); if (std::uniform_real_distribution(0, 1.0f)(rng) < x) { mctsResult.at(offset + i).bestAction = randint(state->GetLegalActions().size()); // fmt::printf("at state '%s' - performing random move %s\n", // state->history(), // state->actionDescription(state->GetLegalActions().at(mctsResult.at(offset // + i).bestAction))); gameState->validTournamentGame = false; } } } offset += currentPlayerStates; } } // Support for running the opponent player in a different game // implementation. This is rarely needed or used, but can be useful to // train against a model that was trained on a different game // implementation but with the same action space // TODO: move into a state callback if (&*game->playerGame_.at(playerIndex) != game) { if (devPlayer->rnnSeqlen()) { actRnnState.clear(); offset = 0; for (size_t pi = 0; pi != statePlayerSize.size(); ++pi) { size_t currentPlayerIndex = statePlayerSize[pi].first; size_t currentPlayerStates = statePlayerSize[pi].second; for (size_t i = 0; i != currentPlayerStates; ++i) { GameState* gameState = actGameStates.at(currentPlayerIndex).at(i); size_t slot = gameState->playersReverseMap.at(currentPlayerIndex); if (!gameState->rnnState2.at(slot).defined()) { gameState->rnnState2[slot] = torch::zeros(devPlayer->rnnStateSize()); } actRnnState.push_back(std::move(gameState->rnnState2[slot])); gameState->rnnStates.at(slot).push_back(actRnnState.back().cpu()); } offset += currentPlayerStates; } std::vector nextRnnState = devPlayer->nextRnnState(states, actRnnState); offset = 0; for (size_t pi = 0; pi != statePlayerSize.size(); ++pi) { size_t currentPlayerIndex = statePlayerSize[pi].first; size_t currentPlayerStates = statePlayerSize[pi].second; for (size_t i = 0; i != currentPlayerStates; ++i) { GameState* gameState = actGameStates.at(currentPlayerIndex).at(i); size_t slot = gameState->playersReverseMap.at(currentPlayerIndex); gameState->rnnState2[slot] = std::move(nextRnnState.at(offset + i)); } offset += currentPlayerStates; } } offset = 0; for (size_t pi = 0; pi != statePlayerSize.size(); ++pi) { size_t currentPlayerStates = statePlayerSize[pi].second; for (size_t i = 0; i != currentPlayerStates; ++i) { State* state = (State*)playerActStates.at(offset + i); auto& res = mctsResult.at(offset + i); state->forward(res.bestAction); } offset += currentPlayerStates; } } else { offset = 0; for (size_t pi = 0; pi != statePlayerSize.size(); ++pi) { size_t currentPlayerIndex = statePlayerSize[pi].first; size_t currentPlayerStates = statePlayerSize[pi].second; for (size_t i = 0; i != currentPlayerStates; ++i) { GameState* gameState = actGameStates.at(currentPlayerIndex).at(i); auto& res = mctsResult.at(offset + i); for (auto& x : gameState->playerState) { if (x) { x->forward(res.bestAction); } } } offset += currentPlayerStates; } } mctsOption = mctsPlayers[playerIndex] ? &mctsPlayers[playerIndex]->option() : nullptr; if (mctsPlayers.at(playerIndex)) { double rps = mctsPlayers.at(playerIndex)->rolloutsPerSecond(); std::unique_lock lkStats(game->mutexStats_); auto& stats_s = game->stats_["Rollouts per second"]; std::get<0>(stats_s) += 1; std::get<1>(stats_s) += rps; std::get<2>(stats_s) += rps * rps; } pushStateCallback(&BatchExecutor::actResult); runStateCallbacks(); states.clear(); } } void run() { task = async::Task(threads::threads); for (auto& v : game->players_) { players_.push_back(&*v); } result_.resize(players_.size()); actStates.resize(players_.size()); actPlayerStates.resize(players_.size()); actGameStates.resize(players_.size()); remapPlayerIdx.resize(players_.size()); basestate = std::move(game->state_); seqs.resize(players_.size()); size_t ngames = size_t(std::max(game->perThreadBatchSize, 1)); if (game->perThreadBatchSize < 1) { int bs = 102400; int n = 0; for (auto& v : players_) { auto actorPlayer = dynamic_cast(v); if (actorPlayer) { int v = actorPlayer->findBatchSize(*basestate); if (v > 0) { bs = std::min(bs, v); ++n; } } } if (n) { fmt::printf("Using batch size of %d\n", bs); ngames = bs; } } while (states.size() < ngames && (game->numEpisode < 0 || startedGameCount < game->numEpisode)) { addGame(states.end()); } devPlayer = nullptr; for (auto& v : players_) { auto actorPlayer = dynamic_cast(v); if (!actorPlayer) { throw std::runtime_error( "Cannot use perThreadBatchSize without ActorPlayer"); } if (actorPlayer->getName() == "dev") { devPlayer = actorPlayer; } actorPlayers.push_back(std::move(actorPlayer)); mctsPlayers.push_back(dynamic_cast(v)); forwardPlayers.push_back(dynamic_cast(v)); } if (!devPlayer) { throw std::runtime_error("dev player not found"); } // If two players are the same (pointer comparison), then they can act // together. for (size_t i = 0; i != players_.size(); ++i) { remapPlayerIdx[i] = i; for (size_t i2 = 0; i2 != i; ++i2) { if (i != i2 && players_[i] == players_[i2]) { remapPlayerIdx[i] = i2; } } } while (!states.empty() && !game->terminate_) { for (auto& v : actStates) { v.clear(); } for (auto& v : actPlayerStates) { v.clear(); } for (auto& v : actGameStates) { v.clear(); } for (auto i = states.begin(); i != states.end();) { auto* state = &*i->state; bool completed = state->terminated() || i->resigned != -1 || i->drawn; if (completed) { const auto end = std::chrono::steady_clock::now(); const auto elapsed = std::chrono::duration_cast(end - i->start) .count(); const size_t stepindex = i->stepindex; if (i->rewindCount == 0) { std::unique_lock lkStats(game->mutexStats_); auto& stats_steps = game->stats_["Game Duration (steps)"]; std::get<0>(stats_steps) += 1; std::get<1>(stats_steps) += stepindex; std::get<2>(stats_steps) += stepindex * stepindex; auto& stats_s = game->stats_["Game Duration (seconds)"]; std::get<0>(stats_s) += 1; std::get<1>(stats_s) += elapsed; std::get<2>(stats_s) += elapsed * elapsed; } if (i->drawn) { for (size_t idx = 0; idx != players_.size(); ++idx) { result_.at(i->players.at(idx)) = 0; } } if (i->resigned != -1) { for (size_t idx = 0; idx != players_.size(); ++idx) { result_.at(i->players.at(idx)) = int(idx) == i->resigned ? -1 : 1; } // fmt::printf("player %d (%s) resigned : %s\n", i->resigned, // players_.at(i->players.at(i->resigned))->getName(), // state->history()); } else { for (size_t idx = 0; idx != players_.size(); ++idx) { result_.at(i->players.at(idx)) = state->getReward(idx); } // fmt::printf("game ended normally: %s\n", // state->history().c_str()); if (randint(256) == 0) { fmt::printf( "game ended normally: %s\n", state->history().c_str()); } } runningAverageGameSteps = runningAverageGameSteps * 0.99f + state->getStepIdx() * 0.01f; } bool doRewind = false; int rewindPlayer = 0; bool rewindToNegativeValue = false; bool isForward = dynamic_cast(devPlayer) != nullptr; int seqlen = devPlayer->rnnSeqlen(); if ((isForward && seqlen > 0) || completed) { for (size_t slot = 0; slot != players_.size(); ++slot) { size_t dstp = i->players.at(slot); if (completed) { #ifdef OPENBW_UI fmt::printf("Result for %s: %g\n", players_[dstp]->getName(), result_[dstp]); #endif } else { if ((int)i->pi[slot].size() < seqlen * 16 + 1 || i->history.empty() || i->history.back().turn != (int)slot) { continue; } result_[dstp] = i->history.back().value; i->pi[slot].pop_back(); i->piMask[slot].pop_back(); i->actionPi[slot].pop_back(); i->predV[slot].pop_back(); i->feat[slot].pop_back(); i->rnnStates[slot].pop_back(); i->reward[slot].pop_back(); } auto addseq = [&](const std::vector& src, std::vector& dst, tube::EpisodicTrajectory& traj) { for (auto& x : src) { dst.push_back(x); if ((int)dst.size() > seqlen) { throw std::runtime_error("addseq bad seqlen"); } if ((int)dst.size() == seqlen) { traj.pushBack(torch::stack(dst)); dst.clear(); } } }; std::vector dReward; dReward.resize(i->feat[slot].size()); if (isForward) { float gae = 0.0f; float gamma = 0.997; float gaeLambda = 0.95; float reward = result_[slot]; // reward = 0; for (size_t n = dReward.size(); n;) { --n; float predv = i->predV[slot].at(n).item(); float npredv = 0.0f; if (n == dReward.size() - 1) { npredv = result_[dstp]; // npredv = 0; } else { npredv = i->predV[slot].at(n + 1).item(); } float delta = reward + gamma * npredv - predv; gae = delta + gamma * gaeLambda * gae; dReward.at(n) = gae + predv; reward = i->reward[slot].at(n); } } else { float reward = result_[dstp]; for (size_t n = dReward.size(); n;) { --n; dReward.at(n) = reward; // reward *= 0.99; // reward += i->reward[slot].at(n); } } std::vector rewards; for (size_t j = 0; j != i->feat[slot].size(); ++j) { if (devPlayer->vOutputs() == 3) { torch::Tensor reward = torch::zeros({3}, torch::kFloat32); reward[0] = result_[dstp] > 0; reward[1] = result_[dstp] < 0; reward[2] = result_[dstp] == 0; rewards.push_back(std::move(reward)); } else { torch::Tensor reward = torch::zeros({1}, torch::kFloat32); reward[0] = dReward.at(j); rewards.push_back(std::move(reward)); } } std::vector piReward; piReward.resize(i->pi[slot].size()); auto& seq = seqs[dstp]; if (actorPlayers[dstp]->getModelId() == "dev" && i->feat[slot].size() > 0) { if (seqlen) { for (size_t n = 0; n != i->feat[slot].size(); ++n) { if ((seq.feat.size() + n) % seqlen == seqlen - 1) { game->rnnInitialState_[dstp].pushBack( i->rnnStates[slot].at(n)); } } addseq(i->feat[slot], seq.feat, game->feature_[dstp]); addseq(i->pi[slot], seq.pi, game->pi_[dstp]); addseq(i->piMask[slot], seq.piMask, game->piMask_[dstp]); if (isForward) { addseq( i->actionPi[slot], seq.actionPi, game->actionPi_[dstp]); } addseq(i->predV[slot], seq.predV, game->predV_[dstp]); std::vector rnnStateMask; rnnStateMask.resize(i->feat[slot].size()); for (auto& v : rnnStateMask) { v = torch::ones({1}); } rnnStateMask.at(0).zero_(); addseq( rnnStateMask, seq.rnnStateMask, game->rnnStateMask_[dstp]); } else { for (auto& v : i->feat[slot]) { game->feature_[dstp].pushBack(v); } for (auto& v : i->pi[slot]) { game->pi_[dstp].pushBack(v); } for (auto& v : i->piMask[slot]) { game->piMask_[dstp].pushBack(v); } for (auto& v : i->actionPi[slot]) { game->actionPi_[dstp].pushBack(v); } for (auto& v : i->predV[slot]) { game->predV_[dstp].pushBack(v); } } if (game->predictEndState || game->predictNStates) { int n = (game->predictEndState ? 2 : 0) + game->predictNStates; auto size = state->GetRawFeatureSize(); size.insert(size.begin(), n); auto finalsize = size; finalsize[1] *= finalsize[0]; finalsize.erase(finalsize.begin()); for (size_t m = 0; m != i->history.size(); ++m) { if (!i->history[m].featurized || i->history[m].turn != (int)slot) { continue; } auto tensor = torch::zeros(size); auto mask = torch::zeros(size); size_t offset = 0; if (game->predictEndState) { if (state->terminated()) { tensor[0].copy_(i->history.back().shortFeat); mask[0].fill_(1.0f); } else { tensor[1].copy_(i->history.back().shortFeat); mask[1].fill_(1.0f); } offset += 2; } for (int j = 0; j != game->predictNStates; ++j, ++offset) { size_t index = m + 1 + j; if (index < i->history.size()) { tensor[offset].copy_(i->history[m].shortFeat); mask[offset].fill_(1.0f); } } tensor = tensor.view(finalsize); mask = mask.view(finalsize); if (seqlen) { addseq({tensor}, seq.predictPi, game->predictPi_[dstp]); addseq( {mask}, seq.predictPiMask, game->predictPiMask_[dstp]); } else { game->predictPi_[dstp].pushBack(tensor); game->predictPiMask_[dstp].pushBack(mask); } } } // fmt::printf("result[%d] (%s) is %g\n", p, // players_[p]->getName(), result_[p]); if (seqlen) { addseq(rewards, seq.v, game->v_[dstp]); } else { for (auto& reward : rewards) { game->v_[dstp].pushBack(std::move(reward)); } } } i->pi[slot].clear(); i->piMask[slot].clear(); i->actionPi[slot].clear(); i->predV[slot].clear(); i->feat[slot].clear(); i->rnnStates[slot].clear(); i->reward[slot].clear(); for (auto& v : i->history) { if (v.turn == (int)slot) { v.featurized = false; } } if (completed) { if (actorPlayers[dstp]->getModelId() == "dev") { if (result_[dstp] != 0) { doRewind = true; rewindPlayer = slot; rewindToNegativeValue = result_[dstp] > 0; } } if (i->rewindCount == 0 && i->validTournamentGame) { actorPlayers[dstp]->result(state, result_[dstp]); } else { actorPlayers[dstp]->forget(state); } } } game->sendTrajectory(); if (doRewind) { for (size_t slot = 0; slot != players_.size(); ++slot) { size_t dstp = i->players.at(slot); if (actorPlayers[dstp]->wantsTournamentResult()) { doRewind = false; break; } } } } if (completed) { ++completedGameCount; if (doRewind && i->rewindCount < game->maxRewinds && rewind(&*i, rewindPlayer, rewindToNegativeValue)) { ++i->rewindCount; } else { i = states.erase(i); if (game->numEpisode < 0 || startedGameCount < game->numEpisode) { i = addGame(i); } } } else { i->stepindex++; int slot = state->getCurrentPlayer(); auto playerIdx = i->players.at(slot); actStates.at(playerIdx).push_back(state); actPlayerStates.at(playerIdx).push_back(&*i->playerState[slot]); actGameStates.at(playerIdx).push_back(&*i); ++i; } } if (alignPlayers) { size_t bestPlayerIdx = 0; size_t bestPlayerIdxSize = 0; for (size_t playerIdx = 0; playerIdx != actStates.size(); ++playerIdx) { auto& states = actStates[playerIdx]; if (states.size() > bestPlayerIdxSize) { bestPlayerIdxSize = states.size(); bestPlayerIdx = playerIdx; } } actForPlayer(bestPlayerIdx); } else { for (size_t playerIdx = 0; playerIdx != actStates.size(); ++playerIdx) { actForPlayer(playerIdx); } } } } }; void Game::mainLoop() { threads::setCurrentThreadName("game thread " + std::to_string(common::getThreadId())); threads::init(0); if (players_.size() != (isOnePlayerGame() ? 1 : 2)) { std::cout << "Error: wrong number of players: " << players_.size() << std::endl; assert(false); } if (!evalMode) { reset(); for (auto& v : playerGame_) { if (&*v != this && v->state_) { v->state_->reset(); } } BatchExecutor batchExecutor; batchExecutor.game = this; batchExecutor.run(); } else { // Warm up JIT/model. This can take several seconds, so do it before we // start time counting. for (auto& v : players_) { auto mctsPlayer = std::dynamic_pointer_cast(v); if (mctsPlayer && mctsPlayer->option().totalTime) { std::cout << "Warming up model.\n"; auto opt = mctsPlayer->option(); mctsPlayer->option().totalTime = 0; mctsPlayer->option().numRolloutPerThread = 20; mctsPlayer->option().randomizedRollouts = false; mctsPlayer->reset(); mctsPlayer->actMcts(*state_); mctsPlayer->actMcts(*state_); mctsPlayer->actMcts(*state_); mctsPlayer->actMcts(*state_); mctsPlayer->option() = opt; mctsPlayer->reset(); } } int64_t gameCount = 0; #ifdef DEBUG_GAME std::thread::id thread_id = std::this_thread::get_id(); #endif while ((numEpisode < 0 || gameCount < numEpisode) && !terminate_) { if (terminate_) { #ifdef DEBUG_GAME std::cout << "Thread " << thread_id << ": terminating, " << "game " << this << ", " << gameCount << " / " << numEpisode << " games played" << std::endl; #endif break; } #ifdef DEBUG_GAME std::cout << "Thread " << thread_id << ", game " << this << ": not terminating - run another iteration. " << std::endl; #endif bool aHuman = std::any_of(players_.begin(), players_.end(), [](const std::shared_ptr& player) { return player->isHuman(); }); if (aHuman && state_->stochasticReset()) { std::string line; std::cout << "Random outcome ?" << std::endl; std::cin >> line; state_->forcedDice = std::stoul(line, nullptr, 0); } reset(); int stepindex = 0; auto start = std::chrono::steady_clock::now(); while (!state_->terminated()) { stepindex += 1; #ifdef DEBUG_GAME std::cout << "Thread " << thread_id << ", game " << this << ": step " << stepindex << std::endl; #endif step(); if (isInSingleMoveMode_) { std::cout << lastMctsValue_ << "\n"; state_->printLastAction(); std::exit(0); } if (printMoves_) { std::cout << "MCTS value: " << lastMctsValue_ << "\n"; std::cout << "Made move: " << state_->lastMoveString() << std::endl; } } auto end = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast(end - start).count(); { std::unique_lock lkStats(mutexStats_); auto& stats_steps = stats_["Game Duration (steps)"]; std::get<0>(stats_steps) += 1; std::get<1>(stats_steps) += stepindex; std::get<2>(stats_steps) += stepindex * stepindex; auto& stats_s = stats_["Game Duration (seconds)"]; std::get<0>(stats_s) += 1; std::get<1>(stats_s) += elapsed; std::get<2>(stats_s) += elapsed * elapsed; } #ifdef DEBUG_GAME std::cout << "Thread " << thread_id << ", game " << this << ": game " << gameCount << " / " << numEpisode << " ended; " << stepindex << " steps, " << (static_cast(stepindex) / elapsed) << " steps per second" << std::endl; #endif if (!lastAction_.empty() && aHuman) { std::cout << "\n#Last Action: " << lastAction_ << "\n\n"; state_->printCurrentBoard(); } if (std::any_of(players_.begin(), players_.end(), [](const std::shared_ptr& player) { return player->isTP(); })) { state_->errPrintCurrentBoard(); } result_[0] = state_->getReward(0); if (players_.size() > 1) { result_[1] = state_->getReward(1); } ++gameCount; } #ifdef DEBUG_GAME std::cout << "Thread " << thread_id << ", game " << this << ": exiting main loop" << std::endl; #endif } } std::optional Game::parseSpecialAction(const std::string& str) { if (str == "-1" || str == "undo" || str == "u") { std::cout << "Undoing the last move\n"; state_->undoLastMoveForPlayer(state_->getCurrentPlayer()); return -1; } else if (str == "exit") { std::exit(0); } else if (str == "m" || str == "manual") { bool resume = false; auto playerString = [&](int index) { std::string str; auto& player = players_.at(index); if (std::dynamic_pointer_cast(player)) { str += "MctsPlayer"; } else if (std::dynamic_pointer_cast(player)) { str += "HumanPlayer"; } else { str += typeid(player).name(); } return str; }; auto specialAction = [&](const std::string& str) -> std::optional { if (str == "singlemovemode" || str == "sm") { isInSingleMoveMode_ = true; return -1; } else if (str.substr(0, 3) == "set") { state_->setStateFromStr(str.substr(4)); return -1; } else if (str == "r" || str == "reset") { state_->reset(); for (auto& v : players_) { v->reset(); } return -1; } else if (str == "u" || str == "undo") { state_->undoLastMove(); return -1; } else if (str == "c" || str == "continue") { resume = true; return -1; } else if (str == "swap") { std::next_permutation(players_.begin(), players_.end()); for (size_t i = 0; i != players_.size(); ++i) { std::cout << "Player " << i << " is now " << playerString(i) << "\n"; } return -1; } else if (str == "printmoves") { printMoves_ = true; return -1; } else if (str == "printvalue") { auto mctsPlayer = std::dynamic_pointer_cast( players_.at(state_->getCurrentPlayer())); if (!mctsPlayer) { for (auto& v : players_) { mctsPlayer = std::dynamic_pointer_cast(v); if (mctsPlayer) { break; } } } if (mctsPlayer) { std::cout << "NN Value: " << mctsPlayer->calculateValue(*state_) << "\n"; } else { std::cout << "NN Value: 0\n"; } } return std::nullopt; }; std::cout << "\nEntering moves manually. Enter 'r' or 'reset' to reset the " "board, 'u' or 'undo' to undo the last move, 'c' or 'continue' to " "continue play, or 'swap' to swap the turn order of the players\n\n"; while (!state_->terminated()) { int index = -1; while (index == -1) { std::cout << "Enter a move for player " << state_->getCurrentPlayer() << " (" << playerString(state_->getCurrentPlayer()) << ")\n"; index = state_->humanInputAction(specialAction); if (resume) { return -1; } } if (!lastAction_.empty()) { std::cout << "\nLast Action: " << lastAction_ << "\n\n"; } std::cout << " applying action... " << std::endl; auto action = state_->GetLegalActions().at(index); lastAction_ = state_->actionDescription(action); if (!state_->isStochastic()) { state_->forward(action.GetIndex()); } else { // auto backup_state = state_->clone(); std::string line; std::cout << "Random outcome ?" << std::endl; std::cin >> line; state_->forcedDice = std::stoul(line, nullptr, 0); state_->forward(action.GetIndex()); } } return -1; } return std::nullopt; } /* virtual */ tube::EnvThread::Stats Game::get_stats() { std::unique_lock lkStats(mutexStats_); return stats_; } void Game::step() { auto playerIdx = state_->getCurrentPlayer(); auto& player = players_.at(playerIdx); // std::cout << "board" << std::endl; // state_->printCurrentBoard(); if (player->isTP()) { // auto TPplayer = std::dynamic_pointer_cast(player); assert(!state_->isStochastic()); auto index = state_->TPInputAction(); auto action = state_->GetLegalActions().at(index); lastAction_ = state_->actionDescription(action); state_->forward(index); } else if (player->isHuman()) { if (!hasPrintedHumanHelp_) { std::cout << "\nEnter a move for the human player. Enter 'u' or 'undo' " "to undo your previous move, 'm' or 'manual' to enter moves " "manually for all players.\n\n"; hasPrintedHumanHelp_ = true; } auto humanPlayer = std::dynamic_pointer_cast(player); if (!lastAction_.empty()) { std::cout << "\nLast Action: " << lastAction_ << "\n\n"; } std::cout << "History: " << state_->history() << "\n"; int index = state_->humanInputAction( std::bind(&Game::parseSpecialAction, this, std::placeholders::_1)); if (index == -1) { return step(); } std::cout << " applying action... " << std::endl; auto action = state_->GetLegalActions().at(index); lastAction_ = state_->actionDescription(action); if (!state_->isStochastic()) { state_->forward(action.GetIndex()); } else { // auto backup_state = state_->clone(); std::string line; std::cout << "Random outcome ?" << std::endl; std::cin >> line; state_->forcedDice = std::stoul(line, nullptr, 0); state_->forward(action.GetIndex()); } } else { auto mctsPlayer = std::dynamic_pointer_cast(player); auto rnnShape = mctsPlayer->rnnStateSize(); if (!rnnShape.empty()) { if (rnnState_.size() <= (size_t)playerIdx) { rnnState_.resize(playerIdx + 1); } if (!rnnState_.at(playerIdx).defined()) { rnnState_[playerIdx] = torch::zeros(rnnShape); } } mcts::MctsResult result; if (!rnnShape.empty()) { result = mctsPlayer->actMcts(*state_, rnnState_.at(playerIdx)); rnnState_.at(playerIdx) = std::move(result.rnnState); } else { result = mctsPlayer->actMcts(*state_); } lastMctsValue_ = result.rootValue; // store feature for training if (!evalMode) { torch::Tensor feat = getFeatureInTensor(*state_); auto [policy, policyMask] = getPolicyInTensor(*state_, result.mctsPolicy); feature_[playerIdx].pushBack(std::move(feat)); pi_[playerIdx].pushBack(std::move(policy)); piMask_[playerIdx].pushBack(std::move(policyMask)); } // std::cout << ">>>>actual act" << std::endl; _Action action = state_->GetLegalActions().at(result.bestAction); lastAction_ = state_->actionDescription(action); bool noHuman = std::none_of(players_.begin(), players_.end(), [](const std::shared_ptr& player) { return player->isHuman(); }); if (!state_->isStochastic()) { if (!noHuman) { std::cout << "Performing action " << state_->actionDescription( state_->GetLegalActions().at(result.bestAction)) << "\n"; } } else if (!noHuman) { std::string line; std::cout << "Performing action " << state_->actionDescription( state_->GetLegalActions().at(result.bestAction)) << "\n"; std::cout << "Random outcome ?" << std::endl; std::cin >> line; state_->forcedDice = std::stoul(line, nullptr, 0); } state_->forward(result.bestAction); } } void Game::sendTrajectory() { for (int i = 0; i < (int)players_.size(); ++i) { assert(v_[i].len() == pi_[i].len() && pi_[i].len() == feature_[i].len()); assert(pi_[i].len() == piMask_[i].len()); int errcode; while (prepareForSend(i)) { // ignore error codes from the dispatcher errcode = dispatchers_[i].dispatchNoReply(); switch (errcode) { case tube::Dispatcher::DISPATCH_ERR_DC_TERM: #ifdef DEBUG_GAME std::cout << "game " << this << ", sendTrajectory: " << "attempt to dispatch through" << " a terminated data channel " << std::endl; #endif break; case tube::Dispatcher::DISPATCH_ERR_NO_SLOT: #ifdef DEBUG_GAME std::cout << "game " << this << ": sendTrajectory: " << "no slots available to dispatch" << std::endl; #endif break; case tube::Dispatcher::DISPATCH_NOERR: break; } } assert(v_[i].len() == 0); assert(pi_[i].len() == 0); assert(piMask_[i].len() == 0); assert(feature_[i].len() == 0); } } bool Game::prepareForSend(int playerId) { int len = feature_[playerId].len(); #define check(n) \ if (!n.empty() && n[playerId].len() != len) \ throw std::runtime_error("len mismatch in " #n) check(pi_); check(piMask_); check(actionPi_); check(v_); check(predV_); check(rnnInitialState_); check(rnnStateMask_); #undef check if (feature_[playerId].prepareForSend()) { bool b = pi_[playerId].prepareForSend(); b &= piMask_[playerId].prepareForSend(); if (!actionPi_.empty()) { b &= actionPi_[playerId].prepareForSend(); } b &= v_[playerId].prepareForSend(); b &= predV_[playerId].prepareForSend(); if (predictEndState + predictNStates) { b &= predictPi_[playerId].prepareForSend(); b &= predictPiMask_[playerId].prepareForSend(); } if (!rnnInitialState_.empty()) { b &= rnnInitialState_[playerId].prepareForSend(); b &= rnnStateMask_[playerId].prepareForSend(); } if (!b) { throw std::runtime_error("prepareForSend mismatch 1"); } return true; } bool b = pi_[playerId].prepareForSend(); b |= piMask_[playerId].prepareForSend(); b |= v_[playerId].prepareForSend(); b |= predV_[playerId].prepareForSend(); if (!actionPi_.empty()) { b |= actionPi_[playerId].prepareForSend(); } if (predictEndState + predictNStates) { b |= predictPi_[playerId].prepareForSend(); b |= predictPiMask_[playerId].prepareForSend(); } if (!rnnInitialState_.empty()) { b |= rnnInitialState_[playerId].prepareForSend(); b |= rnnStateMask_[playerId].prepareForSend(); } if (b) { throw std::runtime_error("prepareForSend mismatch 2"); } return false; } } // namespace core ================================================ FILE: src/core/game.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "forward_player.h" #include "mcts/mcts.h" #include "tube/src_cpp/data_channel.h" #include "tube/src_cpp/dispatcher.h" #include "tube/src_cpp/env_thread.h" #ifndef NO_JAVA #include "../games/ludii/jni_utils.h" #include "../games/ludii/ludii_state_wrapper.h" #endif #include "../games/amazons.h" #include "../games/breakthrough_state.h" #include "../games/chess.h" #include "../games/chinesecheckers.h" #include "../games/connect6_state.h" #include "../games/connectfour.h" #include "../games/diceshogi.h" #include "../games/einstein.h" #include "../games/havannah_state.h" #include "../games/hex_state.h" #include "../games/kyotoshogi_state.h" #include "../games/mastermind_state.h" #include "../games/minesweeper_state.h" #include "../games/minishogi.h" #include "../games/mnkgame.h" // #include "../games/nogo_zestate.h" #include "../games/block_go.h" #include "../games/gomoku_swap2.h" #include "../games/othello.h" #include "../games/othello_opt.h" #include "../games/outeropengomoku_new.h" #include "../games/surakarta_state.h" #include "../games/tristannogo_state.h" #include "../games/weakschur/weakschur_state.h" #include "../games/yinsh.h" #include "human_player.h" #include "utils.h" #include #include #include #include //#define DEBUG_GAME namespace core { // Class for 2player fully observable game. class Game : public tube::EnvThread { friend struct BatchExecutor; public: Game(std::string gameName, std::vector gameOptions, int numEpisode, int seed, bool evalMode, bool outFeatures, bool turnFeaturesSingleChannel, bool turnFeaturesMultiChannel, bool geometricFeatures, int history, int randomFeatures, bool oneFeature, int perThreadBatchSize, int maxRewinds, bool predictEndState, int predictNStates) : numEpisode(numEpisode) , evalMode(evalMode) , perThreadBatchSize(perThreadBatchSize) , maxRewinds(maxRewinds) , predictEndState(predictEndState) , predictNStates(predictNStates) , result_(2, 0) { gameName_ = gameName; if (isGameNameMatched({"Connect6"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Connect6v2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Connect4"})) { state_ = newState(seed); /* combinations with numcolors 2,6,8 and slots 4,5,6,10 are interesting. For time horizon it is more difficult to guess. I’d go with 0.5*slots, 1.0 slots, 1.5 slots, 2 slots and then check numbers (just send us results in csv if easy to share and we can suggest additional settings). If those experiments are too long, you should start with colors=6, slots=4 and horizon \in {3,4,5}. With horizon=5 you should get a winning proba of 1. This could be a reasonable check. And we can check (by evaluating the decision tree - maybe we can find a student to look into this) if the strategy is identical to knuth’s. */ // Mastermind___ } else if (isGameNameMatched({"Mastermind_4_5_6"})) { // should be winning proba 1 state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_4_6_6"})) { // should be winning proba 1 state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_4_7_6"})) { // should be winning proba 1 state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_4_3_6"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_4_4_6"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_10_5_2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_10_6_2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_10_7_2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_10_8_2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_10_9_2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_10_10_2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind_10_15_2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Mastermind"})) { state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_4_4_4"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_3_1_1"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_5_2_3"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_5_5_10"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_10_1_5"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_7_3_10"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_5_5_15"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_8_8_10"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_9_9_10"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_16_16_40"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched( {"Minesweeper_30_16_99"})) { // width, height, mines state_ = newState>(seed); } else if (isGameNameMatched({"TicTacToe", "NoughtsAndCrosses", "XsAndOs", "MNKGame_3_3_3"})) { state_ = newState>(seed); } else if (isGameNameMatched( {"FreeStyleGomoku", "GomokuFreeStyle", "MNKGame_15_15_5"})) { state_ = newState>(seed); } else if (isGameNameMatched( {"Othello4", "Reversi4", "Othello04", "Reversi04"})) { state_ = newState>(seed); } else if (isGameNameMatched( {"Othello6", "Reversi6", "Othello06", "Reversi06"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Othello8", "Reversi8", "Othello08", "Reversi08", "Othello", "Reversi"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Othello10", "Reversi10"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Othello12", "Reversi12"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Othello14", "Reversi14"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Othello16", "Reversi16"})) { state_ = newState>(seed); } else if (isGameNameMatched({"OthelloOpt8", "OthelloOpt", "ReversiOpt8", "ReversiOpt"})) { state_ = newState>(seed); } else if (isGameNameMatched({"OthelloOpt10", "ReversiOpt10"})) { state_ = newState>(seed); } else if (isGameNameMatched({"OthelloOpt16", "ReversiOpt16"})) { state_ = newState>(seed); } else if (isGameNameMatched({"GameOfTheAmazons", "Amazons"})) { state_ = newState(seed); } else if (isGameNameMatched({"ChineseCheckers"})) { state_ = newState(seed); } else if (isGameNameMatched({"Hex5pie"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Hex11pie"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Hex13pie"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Hex19pie"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Hex5"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Hex11"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Hex13"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Hex19"})) { state_ = newState>(seed); } else if (isGameNameMatched( {"Havannah5pieExt"})) { // ext = borders, corners state_ = newState>(seed); } else if (isGameNameMatched({"Havannah10pieExt"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Havannah8pieExt"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Havannah5pie"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Havannah8pie"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Havannah10pie"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Havannah5"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Havannah8"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Havannah10"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Breakthrough"})) { state_ = newState>(seed); } else if (isGameNameMatched({"BreakthroughV2"})) { state_ = newState>(seed); } else if (gameName.rfind("Ludii", 0) == 0) { #ifdef NO_JAVA throw std::runtime_error( "Java/JNI support has not been built in, but is required for Ludii"); #else std::string ludii_name = gameName.substr(5); Ludii::JNIUtils::InitJVM(""); // Use default /ludii/Ludii.jar path JNIEnv* jni_env = Ludii::JNIUtils::GetEnv(); if (jni_env) { if (gameOptions.size() > 0) { Ludii::LudiiGameWrapper game_wrapper(ludii_name, gameOptions); for (const std::string option : gameOptions) { std::cout << "Using Game Option: " << option << std::endl; } state_ = newState(seed, std::move(game_wrapper)); } else { Ludii::LudiiGameWrapper game_wrapper(ludii_name); state_ = newState(seed, std::move(game_wrapper)); } } else { // Probably means we couldn't find the Ludii.jar file throw std::runtime_error( "Failed to create Ludii game due to missing JNI Env!"); } #endif } else if (isGameNameMatched({"Tristannogo"})) { state_ = newState(seed); } else if (isGameNameMatched({"OuterOpenGomoku", "OOGomoku"})) { state_ = newState(seed); } else if (isGameNameMatched({"Minishogi"})) { state_ = newState>(seed); } else if (isGameNameMatched({"MinishogiV2"})) { state_ = newState>(seed); } else if (isGameNameMatched({"Surakarta"})) { state_ = newState(seed); } else if (isGameNameMatched({"DiceShogi"})) { state_ = newState(seed); } else if (isGameNameMatched({"BlockGo"})) { state_ = newState(seed); } else if (isGameNameMatched({"YINSH"})) { state_ = newState(seed); } else if (isGameNameMatched({"GomokuSwap2", "Swap2Gomoku", "Gomoku"})) { state_ = newState(seed); } else if (isGameNameMatched({"KyotoShogi"})) { state_ = newState(seed); } else if (isGameNameMatched({"Einstein"})) { state_ = newState(seed); } else if (isGameNameMatched({"WeakSchur_3_20"})) { // subsets, maxNumber state_ = newState>(seed); } else if (isGameNameMatched({"WeakSchur_4_66"})) { // subsets, maxNumber state_ = newState>(seed); // } else if (isGameNameMatched(gameName, {"Nogo"})) { // state_ = newState(); } else if (isGameNameMatched( {"WeakSchur_5_197", "WalkerSchur"})) { // subsets, maxNumber // is Walker // right ? (1952! he said 197...) state_ = newState>(seed); } else if (isGameNameMatched({"WeakSchur_3_70", "ImpossibleSchur"})) { state_ = newState>(seed); } else if (isGameNameMatched( {"WeakSchur_6_583", "FabienSchur"})) { // subsets, maxNumber // beating F. // Teytaud et al state_ = newState>(seed); } else if (isGameNameMatched({"WeakSchur_7_1737", "Arpad7Schur"})) { // beating A. Rimmel et al state_ = newState>(seed); } else if (isGameNameMatched({"WeakSchur_8_5197", "Arpad8Schur"})) { // beating A. Rimmel et al state_ = newState>(seed); } else if (isGameNameMatched({"WeakSchur_9_15315", "Arpad9Schur"})) { // beating A. Rimmel et al state_ = newState>(seed); } else if (isGameNameMatched({"Chess"})) { state_ = newState(seed); } else { throw std::runtime_error("Unknown game name '" + gameName + "'"); } setFeatures(outFeatures, turnFeaturesSingleChannel, turnFeaturesMultiChannel, geometricFeatures, history, randomFeatures, oneFeature); state_->Initialize(); } template std::unique_ptr newState(A&&... args) { auto r = std::make_unique(std::forward(args)...); r->template initializeAs(); return r; } virtual bool isOnePlayerGame() const { return state_->isOnePlayerGame(); } void setFeatures(bool outFeatures, bool turnFeaturesSingleChannel, bool turnFeaturesMultiChannel, bool geometricFeatures, int history, int randomFeatures, bool oneFeature) { featopts.emplace_back(); FeatureOptions& opt = featopts.back(); opt.outFeatures = outFeatures; opt.turnFeaturesSingleChannel = turnFeaturesSingleChannel; opt.turnFeaturesMultiChannel = turnFeaturesMultiChannel; opt.geometricFeatures = geometricFeatures; opt.history = history; opt.randomFeatures = randomFeatures; opt.oneFeature = oneFeature; state_->setFeatures(&opt); } void addHumanPlayer(std::shared_ptr player) { players_.push_back(std::move(player)); } void addTPPlayer(std::shared_ptr player) { players_.push_back(std::move(player)); } void addEvalPlayer(std::shared_ptr player) { assert(evalMode); players_.push_back(std::move(player)); } void addPlayer(std::shared_ptr player, std::shared_ptr dc, std::shared_ptr game, std::shared_ptr devplayer) { assert(dc != nullptr && !evalMode); players_.push_back(player); playerGame_.push_back(game); if (devplayer) { player = devplayer; } int seqlen = player->rnnSeqlen(); auto addseq = [&](std::vector a) { if (seqlen) { a.insert(a.begin(), seqlen); } return a; }; auto feat = tube::EpisodicTrajectory( "s", addseq(state_->GetFeatureSize()), torch::kFloat32); auto rnnInitialState = tube::EpisodicTrajectory( "rnn_initial_state", player->rnnStateSize(), torch::kFloat32); auto rnnStateMask = tube::EpisodicTrajectory( "rnn_state_mask", addseq({1}), torch::kFloat32); auto pi = tube::EpisodicTrajectory( "pi", addseq(state_->GetActionSize()), torch::kFloat32); auto piMask = tube::EpisodicTrajectory( "pi_mask", addseq(state_->GetActionSize()), torch::kFloat32); auto actionPi = tube::EpisodicTrajectory( "action_pi", addseq(state_->GetActionSize()), torch::kFloat32); auto v = tube::EpisodicTrajectory( "v", addseq({player->vOutputs()}), torch::kFloat32); auto predV = tube::EpisodicTrajectory( "pred_v", addseq({player->vOutputs()}), torch::kFloat32); int predicts = (predictEndState ? 2 : 0) + predictNStates; auto predictSize = state_->GetRawFeatureSize(); predictSize[0] *= predicts; auto predictPi = tube::EpisodicTrajectory( "predict_pi", addseq(predictSize), torch::kFloat32); auto predictPiMask = tube::EpisodicTrajectory( "predict_pi_mask", addseq(predictSize), torch::kFloat32); tube::Dispatcher dispatcher(std::move(dc)); std::vector> send; send = {feat.buffer, pi.buffer, piMask.buffer, v.buffer, predV.buffer}; if (predictEndState + predictNStates) { send.push_back(predictPi.buffer); send.push_back(predictPiMask.buffer); predictPi_.push_back(predictPi); predictPiMask_.push_back(predictPiMask); } if (seqlen) { send.push_back(rnnInitialState.buffer); rnnInitialState_.push_back(rnnInitialState); send.push_back(rnnStateMask.buffer); rnnStateMask_.push_back(rnnStateMask); } if (dynamic_cast(&*player) != nullptr) { send.push_back(actionPi.buffer); actionPi_.push_back(actionPi); } dispatcher.addDataBlocks(send, {}); feature_.push_back(feat); pi_.push_back(pi); piMask_.push_back(piMask); v_.push_back(v); predV_.push_back(predV); dispatchers_.push_back(dispatcher); } const std::vector& getRawFeatSize() { return state_->GetRawFeatureSize(); } const std::vector& getFeatSize() { return state_->GetFeatureSize(); } const std::vector& getActionSize() { return state_->GetActionSize(); } virtual void mainLoop() override; std::vector getResult() { return result_; } virtual void terminate() override { #ifdef DEBUG_GAME std::cout << "game " << this << ", setting terminating flag" << std::endl; #endif EnvThread::terminate(); // std::unique_lock lk(terminateMutex_); #ifdef DEBUG_GAME std::cout << "game " << this << ", terminating dispatchers" << std::endl; #endif for (auto& v : dispatchers_) { v.terminate(); } #ifdef DEBUG_GAME std::cout << "game " << this << ", terminating players" << std::endl; #endif for (auto& v : players_) { v->terminate(); } } virtual EnvThread::Stats get_stats() override; const int numEpisode; const bool evalMode; const int perThreadBatchSize; const int maxRewinds; const bool predictEndState; const int predictNStates; private: bool isGameNameMatched(const std::vector&& allowedNames) { auto strToLower = [&](const std::string& str) { std::string s = std::string(str); std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); }); return s; }; std::string nameLower = strToLower(gameName_); for (auto& allowedName : allowedNames) { if (nameLower == strToLower(allowedName)) return true; } return false; } void reset() { state_->reset(); } std::optional parseSpecialAction(const std::string& str); void step(); void sendTrajectory(); bool prepareForSend(int playerId); std::unique_ptr state_; std::vector> players_; std::vector> playerGame_; std::vector feature_; std::vector rnnStateMask_; std::vector rnnInitialState_; std::vector pi_; std::vector piMask_; std::vector actionPi_; std::vector v_; std::vector predV_; std::vector predictPi_; std::vector predictPiMask_; std::vector dispatchers_; std::list featopts; std::vector result_; std::mutex mutexStats_; EnvThread::Stats stats_; std::string lastAction_; bool hasPrintedHumanHelp_ = false; bool isInSingleMoveMode_ = false; float lastMctsValue_ = 0.0f; bool printMoves_ = false; std::string gameName_; std::vector rnnState_; }; } // namespace core ================================================ FILE: src/core/human_player.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "player.h" #include "state.h" namespace core { class HumanPlayer : public Player { public: HumanPlayer() : Player(true){ }; _Action act(State& state) { int index = state.humanInputAction(); assert(false); auto& legalActions = state.GetLegalActions(); assert(index < (int)legalActions.size()); std::cout << " applying action... " << std::endl; return legalActions[index]; // std::cerr << " applied action... " << std::endl; } }; class TPPlayer : public Player { public: TPPlayer() : Player(true) { isTP_ = true; }; _Action act(State& state) { assert(!state.isStochastic()); // TPPlayer is not implemented for // stochastic games. Could be done though. assert(false); int index = state.TPInputAction(); auto& legalActions = state.GetLegalActions(); assert(index < (int)legalActions.size()); std::cerr << " applying action... " << std::endl; return legalActions[index]; // std::cerr << " applied action... " << std::endl; } }; } // namespace core ================================================ FILE: src/core/model_manager.cc ================================================ #include "model_manager.h" #include "common/async.h" #include "common/thread_id.h" #include "distributed/distributed.h" #include "distributed/rpc.h" #include "replay_buffer.h" #include "tube/src_cpp/data_channel.h" #include #include #include #include #include namespace core { std::unordered_map convertIValueToMap( const c10::IValue& value) { std::unordered_map map; auto dict = value.toGenericDict(); #ifdef PYTORCH12 for (auto& name2tensor : dict) { auto name = name2tensor.key().toString(); torch::Tensor tensor = name2tensor.value().toTensor(); #else auto ivalMap = dict->elements(); for (auto& name2tensor : ivalMap) { auto name = name2tensor.first.toString(); torch::Tensor tensor = name2tensor.second.toTensor(); #endif tensor = tensor.detach(); map.insert({name->string(), tensor}); } return map; } // A mutex where threads are strictly ordered by their priority when waiting to // acquire the mutex. // Threads must call PriorityMutex::setThreadPriority to set their priority. // Lower priority values will acquire the mutex first. class PriorityMutex { struct TLData { TLData* next = nullptr; int priority = 0; std::condition_variable cv; bool waiting = false; }; static inline thread_local std::unique_ptr tldata; std::mutex mut; TLData* queue = nullptr; TLData* owner = nullptr; static TLData& getTLData() { if (!tldata) { tldata = std::make_unique(); } return *tldata; } public: static void setThreadPriority(int priority) { getTLData().priority = priority; } void lock() { std::unique_lock l(mut); auto& tld = getTLData(); if (!owner) { owner = &tld; return; } else { if (!queue) { queue = &tld; } else { TLData** insert = &queue; TLData* next = queue; while (next && next->priority <= tld.priority) { insert = &next->next; next = next->next; } tld.next = next; *insert = &tld; } } tld.waiting = true; while (tld.waiting) { tld.cv.wait(l); } } void unlock() { std::unique_lock l(mut); if (queue) { auto* next = queue; next->waiting = false; queue = next->next; owner = next; next->next = nullptr; l.unlock(); next->cv.notify_all(); } else { owner = nullptr; } } }; namespace { template struct StreamBuffer : std::streambuf { T& buf; StreamBuffer(T& buf) : buf(buf) { } virtual std::streamsize xsputn(const char_type* s, std::streamsize count) override { if (buf.capacity() < buf.size() + count) { buf.reserve(std::max(buf.size() * 2, buf.size() + count + 16)); } size_t prevSize = buf.size(); buf.resize(buf.size() + count); char* dst = buf.data() + prevSize; memcpy(dst, s, count); return count; } void write(const std::string& str) { size_t len = str.size(); xsputn((char*)&len, sizeof(len)); xsputn(str.data(), str.size()); } }; template struct StreamReadBuffer : std::streambuf { T& buf; size_t readPos = 0; StreamReadBuffer(T& buf) : buf(buf) { } virtual std::streamsize xsgetn(char_type* s, std::streamsize count) override { count = std::min((size_t)count, buf.size() - readPos); memcpy(s, buf.data() + readPos, count); readPos += count; return count; } std::string_view read() { size_t len = 0; size_t n = xsgetn((char*)&len, sizeof(len)); if (n != sizeof(len)) { return {}; } if (buf.size() - readPos < len) { return {}; } std::string_view r{buf.data() + readPos, len}; readPos += len; return r; } }; std::mutex deviceMutexMutex; std::unordered_map deviceMutex; PriorityMutex* getDeviceMutex(std::string device) { std::lock_guard l(deviceMutexMutex); return &deviceMutex[device]; } } // namespace using TorchJitModel = torch::jit::script::Module; class ModelManagerImpl { public: ModelManagerImpl(int actBatchsize, const std::string& device, int replayCapacity, int seed, const std::string& jitModel, int trainChannelTimeoutMs, int trainChannelNumSlots) : jitModel_(jitModel) , device_(device) , replayBuffer_(replayCapacity, seed) { trainChannel_ = std::make_shared( "train", trainChannelNumSlots, trainChannelTimeoutMs); actChannel_ = std::make_shared("act", actBatchsize, -1); #ifdef PYTORCH12 model_ = std::make_shared(torch::jit::load(jitModel_, device)); #else model_ = torch::jit::load(jitModel_, device); #endif model_->eval(); dtype_ = at::ScalarType::Float; model_->to(dtype_); modelMutex_ = getDeviceMutex(device); } ~ModelManagerImpl() { terminate_ = true; actChannel_->terminate(); trainChannel_->terminate(); for (auto& v : threads_) { v.join(); } if (modelUpdateThread.joinable()) { modelUpdateThread.join(); } } void startServer(std::string serverListenEndpoint) { server_.emplace(); server_->setOnTrainData( [this](std::unordered_map batch) { replayBuffer_.add(std::move(batch)); }); server_->start(serverListenEndpoint); fmt::printf("Listening on %s\n", serverListenEndpoint); } void startClient(std::string serverConnectHostname) { auto firstUpdate = std::make_shared>(); auto firstUpdateFuture = firstUpdate->get_future(); client_.emplace(); client_->setOnUpdateModel( [this, firstUpdate]( std::string_view id, std::unordered_map dict) mutable { if (firstUpdate) { firstUpdate->set_value(true); firstUpdate.reset(); } if (!dontRequestModelUpdates_) { fmt::printf("onUpdateModel '%s'\n", id); updateModel(dict); } }); client_->connect(serverConnectHostname); fmt::printf("Connected to %s\n", serverConnectHostname); modelUpdateThread = std::thread([this]() { while (!terminate_ && !trainChannel_->terminated()) { if (!dontRequestModelUpdates_) { client_->requestModel(isTournamentOpponent_); } for (int i = 0; i != 2 && !terminate_ && !trainChannel_->terminated(); ++i) { std::this_thread::sleep_for(std::chrono::seconds(2)); } } }); if (!dontRequestModelUpdates_) { fmt::printf("Waiting for model\n"); firstUpdateFuture.wait(); fmt::printf("Received model\n"); } else { fmt::printf("Not requesting model updates\n"); } } std::unique_ptr replayBufferRpc; std::shared_ptr replayBufferRpcServer; std::shared_ptr replayBufferRpcClient; void startReplayBufferServer(std::string endpoint) { if (endpoint.substr(0, 6) == "tcp://") { endpoint.erase(0, 6); } if (!replayBufferRpc) { replayBufferRpc = std::make_unique(); replayBufferRpc->asyncRun(8); } replayBufferRpcServer = replayBufferRpc->listen(""); replayBufferRpcServer->define("sample", &ModelManagerImpl::sample, this); replayBufferRpcServer->listen(endpoint); } void startReplayBufferClient(std::string endpoint) { if (endpoint.substr(0, 6) == "tcp://") { endpoint.erase(0, 6); } if (!replayBufferRpc) { replayBufferRpc = std::make_unique(); replayBufferRpc->asyncRun(8); } replayBufferRpcClient = replayBufferRpc->connect(endpoint); } SampleResult remoteSample(int sampleSize) { return {replayBufferRpcClient ->async>( "sample", sampleSize)}; } std::shared_ptr getTrainChannel() { return trainChannel_; } std::shared_ptr getActChannel() { return actChannel_; } std::unordered_map cloneStateDict( const std::unordered_map& stateDict) { torch::NoGradGuard ng; std::unordered_map r; for (auto& [name, tensor] : stateDict) { r[name] = tensor.detach().to( torch::TensorOptions().device(torch::kCPU).dtype(dtype_), false, true); } return r; } void addTournamentModel( std::string id, const std::unordered_map& stateDict) { if (server_) { fmt::printf(" -- ADD MODEL %s --\n", id); server_->updateModel(id, cloneStateDict(stateDict)); } } #ifdef PYTORCH15 void loadModelStateDict( TorchJitModel& model, const std::unordered_map& stateDict) { std::unordered_map dst; for (const auto& v : model.named_parameters()) { dst[v.name] = v.value; } for (const auto& v : model.named_buffers()) { dst[v.name] = v.value; } for (auto& [k, v] : stateDict) { auto i = dst.find(k); if (i == dst.end()) { throw std::runtime_error( fmt::sprintf("key '%s' not found in destination state dict", k)); } else if (i->second.sizes() != v.sizes()) { throw std::runtime_error( fmt::sprintf("state dict key '%s' shape mismatch", k)); } } for (auto& [k, v] : dst) { auto i = stateDict.find(k); if (i == stateDict.end()) { throw std::runtime_error( fmt::sprintf("key '%s' not found in source state dict", k)); } } fmt::printf("loadModelStateDict: state dicts OK\n"); for (auto& v : stateDict) { auto i = dst.find(v.first); if (i != dst.end()) { dst.at(v.first).copy_(v.second).detach(); } else { fmt::printf( "copyModelStateDict: Unknown state dict entry '%s'\n", v.first); std::abort(); } } model.eval(); } #else void loadModelStateDict( TorchJitModel& model, const std::unordered_map& stateDict) { for (auto& [name, tensor] : stateDict) { const char* ptr = name.c_str(); std::string memberNameString; const char* memberNamePtr = ptr; auto* currentModule = &model; decltype(currentModule->find_module(memberNameString)) subModule; while (*ptr) { if (*ptr == '.') { memberNameString.assign(memberNamePtr, ptr - memberNamePtr); subModule = currentModule->find_module(memberNameString); if (!subModule) { fmt::printf( "copyModelStateDict: Unknown state dict entry '%s' -- could " "not find module '%s'\n", name, memberNameString); std::abort(); } currentModule = &*subModule; ++ptr; memberNamePtr = ptr; } else { ++ptr; } } memberNameString.assign(memberNamePtr, ptr - memberNamePtr); if (auto p = currentModule->find_parameter(memberNameString); p) { p->value().toTensor().copy_(tensor); } else if (auto b = currentModule->find_buffer(memberNameString); b) { b->value().toTensor().copy_(tensor); } else { fmt::printf( "copyModelStateDict: Unknown state dict entry '%s' -- could not " "find parameter/buffer '%s'\n", name, memberNameString); std::abort(); } } model.eval(); } #endif void updateModel( const std::unordered_map& stateDict) { torch::NoGradGuard ng; fmt::printf(" -- UPDATE MODEL --\n"); if (server_) { server_->updateModel("dev", cloneStateDict(stateDict)); } PriorityMutex::setThreadPriority(-9); std::lock_guard lk(*modelMutex_); loadModelStateDict(*model_, stateDict); } int bufferSize() const { return replayBuffer_.size(); } bool bufferFull() const { return replayBuffer_.full(); } std::unordered_map sample(int sampleSize) { return replayBuffer_.sample(sampleSize); } void start() { threads_.emplace_back(&ModelManagerImpl::trainThread, this); threads_.emplace_back(&ModelManagerImpl::actThread, this); } void trainThread() { torch::NoGradGuard ng; if (client_) { std::atomic qdone{false}; int qwaiters = 0; std::mutex qmut; std::condition_variable qcv; std::deque> queue; std::vector qthreads; for (int i = 0; i != 4; ++i) { qthreads.emplace_back([&]() { while (true) { std::unique_lock l(qmut); ++qwaiters; while (queue.empty()) { if (qdone) { --qwaiters; return; } qcv.wait(l); } --qwaiters; auto batch = std::move(queue.front()); queue.pop_front(); l.unlock(); client_->sendTrainData(batch); } }); } while (true) { auto batch = trainChannel_->getInput(); if (terminate_ || trainChannel_->terminated()) { break; } trainChannel_->setReply({}); std::lock_guard l(qmut); if (queue.size() < 128) { queue.push_back(batch); } else { fmt::printf("Warning: train data queue is full, discarding data\n"); } if (qwaiters) { qcv.notify_one(); } } std::lock_guard l(qmut); qdone = true; qcv.notify_all(); } else { while (true) { auto batch = trainChannel_->getInput(); if (terminate_ || trainChannel_->terminated()) { break; } replayBuffer_.add(batch); trainChannel_->setReply({}); } } } void actThread() { torch::NoGradGuard ng; while (true) { auto batch = actChannel_->getInput(); if (terminate_ || actChannel_->terminated()) { break; } // TODO[hengyuan]: temp hard code auto s = batch["s"].to(device_); std::vector input; input.push_back(s); PriorityMutex::setThreadPriority(-1); std::unique_lock lk(*modelMutex_); auto output = model_->forward(input); lk.unlock(); auto reply = convertIValueToMap(output); actChannel_->setReply(reply); } } void testAct() { torch::NoGradGuard ng; std::vector inputs; auto x = torch::ones({1, 6 * 7 * 2}, torch::kFloat32); inputs.push_back(x); auto y = model_->forward(inputs); auto reply = convertIValueToMap(y); for (auto& name2tensor : reply) { std::cout << name2tensor.first << ": " << std::endl; std::cout << name2tensor.second << std::endl; } } void batchAct(torch::Tensor input, torch::Tensor v, torch::Tensor pi, torch::Tensor rnnState = {}, torch::Tensor* rnnStateOut = nullptr) { torch::NoGradGuard ng; bool isCuda = device_.is_cuda(); PriorityMutex::setThreadPriority(common::getThreadId()); std::optional g; if (isCuda) { g.emplace(c10::cuda::getStreamFromPool(false, device_.index())); } std::vector inp; inp.push_back(input.to(device_, dtype_, true)); if (rnnState.defined()) { inp.push_back(rnnState.to(device_, dtype_, true)); } std::unique_lock lk(*modelMutex_); auto output = model_->forward(inp); if (isCuda) { g->current_stream().synchronize(); } lk.unlock(); auto reply = convertIValueToMap(output); v.copy_(reply["v"], true); pi.copy_(reply["pi_logit"], true); if (rnnStateOut) { *rnnStateOut = reply["rnn_state"]; } if (isCuda) { g->current_stream().synchronize(); } } struct Timer { std::chrono::steady_clock::time_point start; Timer() { reset(); } void reset() { start = std::chrono::steady_clock::now(); } float elapsedAt(std::chrono::steady_clock::time_point now) { return std::chrono::duration_cast< std::chrono::duration>>(now - start) .count(); } float elapsed() { return elapsedAt(std::chrono::steady_clock::now()); } float elapsedReset() { auto now = std::chrono::steady_clock::now(); float r = elapsedAt(now); start = now; return r; } }; int findBatchSize(torch::Tensor input, torch::Tensor rnnState = {}) { if (hasFoundBatchSize_) { return foundBatchSize_; } torch::NoGradGuard ng; bool isCuda = device_.is_cuda(); PriorityMutex::setThreadPriority(common::getThreadId()); std::optional g; if (isCuda) { g.emplace(c10::cuda::getStreamFromPool(false, device_.index())); } else { return 1; } std::vector inp; torch::Tensor gpuinput = input.to(device_, dtype_, true); torch::Tensor gpurnnState; if (rnnState.defined()) { gpurnnState = rnnState.to(device_, dtype_, true); } auto prep = [&](int bs) { inp.clear(); std::vector batch; for (int i = 0; i != bs; ++i) { batch.push_back(gpuinput); } inp.push_back(torch::stack(batch).to(device_, dtype_, true)); if (rnnState.defined()) { batch.clear(); for (int i = 0; i != bs; ++i) { batch.push_back(gpurnnState); } inp.push_back(torch::stack(batch).to(device_, dtype_, true)); } g->current_stream().synchronize(); }; std::unique_lock lk(*modelMutex_); if (hasFoundBatchSize_) { return foundBatchSize_; } auto call = [&]() { model_->forward(inp); if (isCuda) { g->current_stream().synchronize(); } }; fmt::printf("Finding batch size\n"); prep(1); // warm up for (int i = 0; i != 10; ++i) { call(); } Timer t; for (int i = 0; i != 10; ++i) { call(); } float call1 = t.elapsed() / 10.0f * 1000.0f; fmt::printf("Base latency: %gms\n", call1); float maxms = findBatchSizeMaxMs_; int maxbs = findBatchSizeMaxBs_; struct I { float latency = 0.0f; float throughput = 0.0f; int n = 0; float score() { return latency / n / 400 - std::log(throughput / n); } }; std::map li; int best = 0; float bestScore = std::numeric_limits::infinity(); auto eval = [&](int i) { prep(i); int badcount = 0; float latency = 0.0f; float throughput = 0.0f; int n = 2; for (int j = 0; j != n; ++j) { call(); } for (int j = 0; j != n; ++j) { t.reset(); call(); float ms = t.elapsed() * 1000; latency += ms; throughput += i / ms; if (ms > maxms || i > maxbs) { ++badcount; } } auto& x = li[i]; x.latency += latency; x.throughput += throughput; x.n += n; float score = x.score(); if (badcount < n && score < bestScore) { bestScore = score; best = i; } return badcount < n; }; for (int i = 1;; i += (i + 1) / 2) { if (!eval(i)) { break; } } std::minstd_rand rng(std::random_device{}()); auto expandNear = [&](int k) { int r = 0; auto i = li.find(k); if (i != li.end()) { auto search = [&](auto begin, auto end) { int b = begin->first; int e; if (end == li.end()) { e = std::prev(end)->first; } else { e = end->first; } b = std::max(b, i->first - 3); e = std::max(b, i->first + 6); for (int i = b; i != e; ++i) { if (li.find(i) != li.end()) { continue; } ++r; if (!eval(i)) { break; } } }; search(i, std::next(i)); if (i != li.begin()) { search(std::prev(i), i); } } return r; }; for (int j = 0; j != 4; ++j) { int expands = 12; for (int k = 0; k != 12; ++k) { float sum = 0.0f; std::vector> list; float minweight = std::numeric_limits::infinity(); for (auto& [k, v] : li) { minweight = std::min(minweight, v.score()); } for (auto i = li.begin();;) { auto next = std::next(i); if (next == li.end()) { break; } int from = i->first + 1; int to = next->first; if (to - from > 0) { float weight = std::min(i->second.score(), next->second.score()) - minweight; weight = 1.0f / std::min(std::exp(weight * 4), 1e9f); weight *= to - from; list.emplace_back(weight, from, to); sum += weight; } i = next; } if (list.size() > 0 && sum > 0.0f) { float val = std::uniform_real_distribution(0.0f, sum)(rng); for (auto& [weight, from, to] : list) { val -= weight; if (val <= 0) { int k = std::uniform_int_distribution(from, to - 1)(rng); eval(k); if (expands > 0) { expands -= expandNear(k); } break; } } } } if (best) { expandNear(best); } std::vector> sorted; for (auto& [k, v] : li) { sorted.emplace_back(v.score(), k); } std::sort(sorted.begin(), sorted.end()); for (size_t i = 0; i != sorted.size() && i < 10; ++i) { int k = std::get<1>(sorted[i]); if (li[k].n < 8) { eval(k); } } } foundBatchSize_ = best; hasFoundBatchSize_ = true; for (auto& [k, v] : li) { fmt::printf( "Batch size %d, evals %d latency %fms throughput %g score %g\n", k, v.n, v.latency / v.n, v.throughput / v.n, v.score()); } fmt::printf("Found best batch size of %d with evals %d latency %fms " "throughput %g score %g\n", best, li[best].n, li[best].latency / li[best].n, li[best].throughput / li[best].n, li[best].score()); return best; } bool isCuda() const { return device_.is_cuda(); } torch::Device device() const { return device_; } int64_t bufferNumSample() const { return replayBuffer_.numSample(); } int64_t bufferNumAdd() const { return replayBuffer_.numAdd(); } void setIsTournamentOpponent(bool mode) { isTournamentOpponent_ = mode; } bool isTournamentOpponent() const { return isTournamentOpponent_; } void setDontRequestModelUpdates(bool v) { dontRequestModelUpdates_ = v; } bool wantsTournamentResult() { return client_ ? client_->wantsTournamentResult() : false; } std::string_view getTournamentModelId() { if (client_) { return client_->getModelId(); } else { return "dev"; } } void result(float reward, std::unordered_map models) { if (client_ && isTournamentOpponent_ && !dontRequestModelUpdates_) { client_->sendResult(reward, std::move(models)); } } void setFindBatchSizeMaxMs(float ms) { findBatchSizeMaxMs_ = ms; } void setFindBatchSizeMaxBs(int n) { findBatchSizeMaxBs_ = n; } private: const std::string jitModel_; torch::Device device_; torch::ScalarType dtype_; PriorityMutex* modelMutex_; std::shared_ptr model_; std::shared_ptr actChannel_; std::shared_ptr trainChannel_; std::vector threads_; std::atomic_bool terminate_{false}; ReplayBuffer replayBuffer_; std::atomic_size_t nextActIndex_{0}; std::optional server_; std::optional client_; std::thread modelUpdateThread; bool isTournamentOpponent_ = false; bool dontRequestModelUpdates_ = false; std::atomic hasFoundBatchSize_ = false; std::atomic foundBatchSize_ = 0; std::atomic findBatchSizeMaxMs_ = 100.0f; std::atomic findBatchSizeMaxBs_ = 10240; }; ModelManager::ModelManager() { } ModelManager::ModelManager(int actBatchsize, const std::string& device, int replayCapacity, int seed, const std::string& jitModel, int trainChannelTimeoutMs, int trainChannelNumSlots) { impl = std::make_unique( actBatchsize, device, replayCapacity, seed, jitModel, trainChannelTimeoutMs, trainChannelNumSlots); } ModelManager::~ModelManager() { } std::shared_ptr ModelManager::getTrainChannel() { return impl->getTrainChannel(); } std::shared_ptr ModelManager::getActChannel() { return impl->getActChannel(); } void ModelManager::updateModel( const std::unordered_map& stateDict) { return impl->updateModel(stateDict); } int ModelManager::bufferSize() const { return impl->bufferSize(); } bool ModelManager::bufferFull() const { return impl->bufferFull(); } std::unordered_map ModelManager::sample( int sampleSize) { return impl->sample(sampleSize); } void ModelManager::start() { return impl->start(); } void ModelManager::testAct() { return impl->testAct(); } void ModelManager::setIsTournamentOpponent(bool mode) { return impl->setIsTournamentOpponent(mode); } void ModelManager::addTournamentModel( std::string id, const std::unordered_map& stateDict) { return impl->addTournamentModel(std::move(id), stateDict); } void ModelManager::setDontRequestModelUpdates(bool v) { return impl->setDontRequestModelUpdates(v); } void ModelManager::startServer(std::string serverListenEndpoint) { return impl->startServer(serverListenEndpoint); } void ModelManager::startClient(std::string serverConnectHostname) { return impl->startClient(serverConnectHostname); } void ModelManager::startReplayBufferServer(std::string endpoint) { return impl->startReplayBufferServer(endpoint); } void ModelManager::startReplayBufferClient(std::string endpoint) { return impl->startReplayBufferClient(endpoint); } SampleResult ModelManager::remoteSample(int sampleSize) { return impl->remoteSample(sampleSize); } bool ModelManager::isCuda() const { return impl->isCuda(); } torch::Device ModelManager::device() const { return impl->device(); } void ModelManager::batchAct(at::Tensor input, at::Tensor v, at::Tensor pi, at::Tensor rnnState, at::Tensor* rnnStateOut) { return impl->batchAct(std::move(input), std::move(v), std::move(pi), std::move(rnnState), rnnStateOut); } std::string_view ModelManager::getTournamentModelId() { return impl->getTournamentModelId(); } void ModelManager::result(float reward, std::unordered_map models) { return impl->result(reward, std::move(models)); } int ModelManager::findBatchSize(at::Tensor input, at::Tensor rnnState) { return impl->findBatchSize(input, rnnState); } int64_t ModelManager::bufferNumSample() const { return impl->bufferNumSample(); } int64_t ModelManager::bufferNumAdd() const { return impl->bufferNumAdd(); } bool ModelManager::isTournamentOpponent() const { return impl->isTournamentOpponent(); } bool ModelManager::wantsTournamentResult() { return impl->wantsTournamentResult(); } void ModelManager::setFindBatchSizeMaxMs(float ms) { impl->setFindBatchSizeMaxMs(ms); } void ModelManager::setFindBatchSizeMaxBs(int n) { impl->setFindBatchSizeMaxBs(n); } } // namespace core ================================================ FILE: src/core/model_manager.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include namespace core { struct SampleResult { std::future> fut; std::unordered_map get() { return fut.get(); } }; class ModelManagerImpl; class ModelManager { std::unique_ptr impl; public: ModelManager(); ModelManager(int actBatchsize, const std::string& device, int replayCapacity, int seed, const std::string& jitModel, int trainChannelTimeoutMs, int trainChannelNumSlots); ~ModelManager(); std::shared_ptr getTrainChannel(); std::shared_ptr getActChannel(); void updateModel( const std::unordered_map& stateDict); int bufferSize() const; bool bufferFull() const; std::unordered_map sample(int sampleSize); void start(); void testAct(); void setIsTournamentOpponent(bool mode); void addTournamentModel( std::string id, const std::unordered_map& stateDict); void setDontRequestModelUpdates(bool v); void startServer(std::string serverListenEndpoint); void startClient(std::string serverConnectHostname); void startReplayBufferServer(std::string endpoint); void startReplayBufferClient(std::string endpoint); SampleResult remoteSample(int sampleSize); bool isCuda() const; torch::Device device() const; void batchAct(torch::Tensor input, torch::Tensor v, torch::Tensor pi, torch::Tensor rnnState = {}, torch::Tensor* rnnStateOut = nullptr); std::string_view getTournamentModelId(); void result(float reward, std::unordered_map models); int findBatchSize(torch::Tensor input, torch::Tensor rnnState = {}); int64_t bufferNumSample() const; int64_t bufferNumAdd() const; bool isTournamentOpponent() const; bool wantsTournamentResult(); void setFindBatchSizeMaxMs(float ms); void setFindBatchSizeMaxBs(int n); }; } // namespace core ================================================ FILE: src/core/player.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include namespace core { class State; class Player { public: Player(bool isHuman) : isHuman_(isHuman) { isTP_ = false; } bool isHuman() const { return isHuman_; } bool isTP() const { return isTP_; } virtual void setName(std::string name) { name_ = std::move(name); } const std::string& getName() { return name_; } virtual void terminate() { } virtual void reset() { } private: std::string name_ = "unnamed"; bool isHuman_; protected: bool isTP_; }; } // namespace core ================================================ FILE: src/core/pybind.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include "actor.h" #include "common/threads.h" #include "forward_player.h" #include "game.h" #include "model_manager.h" namespace py = pybind11; using namespace core; PYBIND11_MODULE(polygames, m) { m.def("init_threads", &threads::init); py::class_>(m, "Game") .def(py::init, int, int, bool, bool, bool, bool, bool, int, int, bool, int, int, bool, int>()) .def("add_player", &Game::addPlayer, py::keep_alive<1, 2>()) .def("add_eval_player", &Game::addEvalPlayer) .def("add_human_player", &Game::addHumanPlayer) .def("add_tp_player", &Game::addTPPlayer) .def("get_raw_feat_size", &Game::getRawFeatSize) .def("get_feat_size", &Game::getFeatSize) .def("is_one_player_game", &Game::isOnePlayerGame) .def("set_features", &Game::setFeatures) .def("get_action_size", &Game::getActionSize) .def("get_result", &Game::getResult); py::class_>(m, "Actor") .def(py::init, const std::vector&, // featSize const std::vector&, // actionSize const std::vector&, // rnnStateSize int, // rnnSeqlen bool, // logitValue bool, // useValue bool, // usePolicy std::shared_ptr>()); py::class_>(m, "HumanPlayer") .def(py::init<>(), py::call_guard()); py::class_>(m, "TPPlayer") .def(py::init<>(), py::call_guard()); py::class_>(m, "ActorPlayer") .def(py::init<>(), py::call_guard()) .def("set_actor", &ForwardPlayer::setActor, py::keep_alive<1, 2>()) .def("set_name", &ForwardPlayer::setName); py::class_>( m, "ForwardPlayer") .def(py::init<>(), py::call_guard()); py::class_>(m, "ModelManager") .def(py::init()) .def("get_train_channel", &ModelManager::getTrainChannel) .def("get_act_channel", &ModelManager::getActChannel) .def("update_model", &ModelManager::updateModel) .def("buffer_size", &ModelManager::bufferSize) .def("buffer_full", &ModelManager::bufferFull) .def("buffer_num_sample", &ModelManager::bufferNumSample) .def("buffer_num_add", &ModelManager::bufferNumAdd) .def("sample", &ModelManager::sample) .def("start", &ModelManager::start) .def("test_act", &ModelManager::testAct) .def("set_is_tournament_opponent", &ModelManager::setIsTournamentOpponent) .def("add_tournament_model", &ModelManager::addTournamentModel) .def("set_dont_request_model_updates", &ModelManager::setDontRequestModelUpdates) .def("start_server", &ModelManager::startServer) .def("start_client", &ModelManager::startClient) .def("start_replay_buffer_server", &ModelManager::startReplayBufferServer) .def("start_replay_buffer_client", &ModelManager::startReplayBufferClient) .def("remote_sample", &ModelManager::remoteSample) .def("set_find_batch_size_max_ms", &ModelManager::setFindBatchSizeMaxMs) .def("set_find_batch_size_max_bs", &ModelManager::setFindBatchSizeMaxBs); py::class_(m, "SampleResult").def("get", &SampleResult::get); } ================================================ FILE: src/core/replay_buffer.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include "replay_buffer.h" #define ZSTD_STATIC_LINKING_ONLY #include "zstd/lib/zstd.h" namespace { struct cctx { ZSTD_CCtx* ctx; cctx() { ctx = ZSTD_createCCtx(); if (!ctx) { throw std::runtime_error("Failed to allocate zstd context"); } } ~cctx() { ZSTD_freeCCtx(ctx); } }; struct dctx { ZSTD_DCtx* ctx; dctx() { ctx = ZSTD_createDCtx(); if (!ctx) { throw std::runtime_error("Failed to allocate zstd context"); } } ~dctx() { ZSTD_freeDCtx(ctx); } }; } // namespace namespace core { ReplayBuffer::ReplayBuffer(int capacity, int seed) : capacity(capacity) , buffer(capacity) { rng_.seed(seed); } ReplayBuffer::~ReplayBuffer() { if (!sampleThreads.empty()) { std::unique_lock l(mut); sampleThreadDie = true; cv.notify_all(); l.unlock(); for (auto& v : sampleThreads) { v.join(); } } } void ReplayBuffer::add(std::unordered_map input) { if (input.empty()) { return; } if (!hasKeys) { std::lock_guard l(keyMutex); if (keys.empty()) { for (auto& v : input) { torch::ArrayRef x = v.second.sizes(); x = torch::ArrayRef(x.begin() + 1, x.end()); keys.push_back({v.first, std::vector(x.begin(), x.end()), v.second.dtype()}); } hasKeys = true; for (auto& vx : input) { printf(" key '%s' shape %s\n", vx.first.c_str(), ss(vx.second.sizes()).c_str()); } } } std::vector tmpbuf; auto n = input.begin()->second.size(0); cctx ctx; for (int i = 0; i != n; ++i) { if (input.size() != keys.size()) { throw std::runtime_error("replay buffer keys mismatch"); } BufferEntry* newEntry = new BufferEntry[input.size()]; size_t index = 0; for (const auto& [key, shape, dtype] : keys) { auto t = input.at(key)[i]; if (!t.is_contiguous()) { throw std::runtime_error("replay buffer input is not contiguous"); } void* data = t.data_ptr(); size_t datasize = dtype.itemsize() * t.numel(); tmpbuf.resize(sizeof(size_t) + ZSTD_compressBound(datasize)); auto n = ZSTD_compressCCtx( ctx.ctx, tmpbuf.data(), tmpbuf.size(), data, datasize, 0); if (ZSTD_isError(n)) { throw std::runtime_error("replay buffer compress failed"); } auto& e = newEntry[index++]; e.datasize = datasize; e.data.assign(tmpbuf.begin(), tmpbuf.begin() + n); } auto slot = numAdd_++ % capacity; auto* prev = buffer[slot].exchange(newEntry); if (prev) { delete[] prev; } } } std::unordered_map ReplayBuffer::sampleImpl( int sampleSize) { if (!hasKeys) { return {}; } int siz = size(); std::unordered_map r; std::vector pointers; for (auto& [k, shape, dtype] : keys) { std::vector sizes; sizes.assign(shape.begin(), shape.end()); sizes.insert(sizes.begin(), sampleSize); auto tensor = torch::empty(sizes, dtype); pointers.push_back((char*)tensor.data_ptr()); r[k] = tensor; } dctx ctx; size_t nCopies = 0; auto copy = [&](size_t srcIndex) { auto src = buffer[srcIndex].exchange(nullptr); if (!src) { return 0; } if (nCopies >= (size_t)sampleSize) { throw std::runtime_error( "replay buffer internal error: copied too many samples"); } ++nCopies; for (size_t i = 0; i != keys.size(); ++i) { size_t datasize = src[i].datasize; auto n = ZSTD_decompressDCtx(ctx.ctx, pointers[i], datasize, src[i].data.data(), src[i].data.size()); if (ZSTD_isError(n)) { throw std::runtime_error("replay buffer decompress failed"); } pointers[i] += datasize; } BufferEntry* nullref = nullptr; if (!buffer[srcIndex].compare_exchange_strong(nullref, src)) { delete[] src; } return 1; }; int64_t seq = std::min(numAdd_ - prevSampleNumAdd_, (int64_t)sampleSize); int64_t i = 0; // for (;i != seq;) { // i += copy((prevSampleNumAdd_ + i) % siz); // } prevSampleNumAdd_ += seq; std::vector indices; while (i != sampleSize) { indices.clear(); std::unique_lock l(sampleMutex); for (size_t ii = i; ii != (size_t)sampleSize;) { if (sampleOrderIndex >= sampleOrder.size()) { size_t p = sampleOrder.size(); if (p != (size_t)capacity) { sampleOrder.resize(siz); for (size_t i = p; i != sampleOrder.size(); ++i) { sampleOrder[i] = i; } } std::shuffle(sampleOrder.begin(), sampleOrder.end(), rng_); sampleOrderIndex = 0; } indices.push_back(sampleOrder.at(sampleOrderIndex++)); ++ii; } l.unlock(); for (size_t index : indices) { i += copy(index); } } numSample_ += sampleSize; return r; } std::unordered_map ReplayBuffer::sample( int sampleSize) { // return sampleImpl(sampleSize); // TODO // This code currently prefetches 8 samples for efficent sampling when // training on 8 gpus. This should be made configurable or training // should be made efficient without requiring prefetch std::unique_lock l(mut); if (sampleThreads.empty()) { for (int i = 0; i != 8; ++i) { sampleThreads.emplace_back([this]() { std::unique_lock l(mut); while (true) { while (results.size() >= 8 || resultsSampleSize == 0) { cv.wait(l); if (sampleThreadDie) { return; } } l.unlock(); auto tmp = sampleImpl(resultsSampleSize); l.lock(); results.push_back(std::move(tmp)); cv2.notify_all(); } }); } } resultsSampleSize = sampleSize; while (results.empty()) { cv.notify_all(); cv2.wait(l); } auto r = std::move(results.front()); results.pop_front(); cv.notify_all(); return r; } } // namespace core ================================================ FILE: src/core/replay_buffer.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include namespace core { class ReplayBuffer { public: ReplayBuffer(int capacity, int seed); ~ReplayBuffer(); /* * add to the circular array the elements of input * updates input if size is greater than capacity * initializes if the buffer is empty */ void add(std::unordered_map input); template static std::string ss(T&& sizes) { std::string r = "["; for (int64_t v : sizes) { if (r != "[") r += ", "; r += std::to_string(v); } return r + "]"; } /* * sample sampleSize elements from the replayBuffer */ std::unordered_map sampleImpl(int sampleSize); std::mutex mut; std::condition_variable cv; std::condition_variable cv2; std::deque> results; int resultsSampleSize = 0; bool sampleThreadDie = false; std::vector sampleThreads; std::unordered_map sample(int sampleSize); int size() const { return (int)std::min((int64_t)numAdd_, (int64_t)capacity); } bool full() const { return size() == capacity; } int64_t numAdd() const { return numAdd_; } int64_t numSample() const { return numSample_; } const int capacity; private: struct Key { std::string name; std::vector shape; caffe2::TypeMeta dtype; }; struct BufferEntry { size_t datasize; std::vector data; }; std::vector> buffer; size_t sampleOrderIndex = 0; std::vector sampleOrder; std::vector keys; std::mutex keyMutex; std::atomic hasKeys = false; std::mutex sampleMutex; int64_t prevSampleNumAdd_ = 0; std::atomic_int64_t numAdd_ = 0; std::atomic_int64_t numSample_ = 0; std::mt19937 rng_; }; } // namespace core ================================================ FILE: src/core/state.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "state.h" namespace core { std::ostream& operator<<(std::ostream& os, const _Action& action) { os << action.GetX() << ", " << action.GetY() << ", " << action.GetZ(); return os; } void State::fillFullFeatures() { if (!_featopts) { return; } size_t offset = 0; auto expand = [&](size_t n) { size_t newOffset = offset + n; if (newOffset > _fullFeatures.size()) { throw std::runtime_error("internal error: _fullFeatures is too small"); } return _fullFeatures.data() + std::exchange(offset, newOffset); }; const size_t planeSize = _featSize[1] * _featSize[2]; auto add_constant_plane = [&](float value) { auto* at = expand(planeSize); std::fill(at, at + planeSize, value); }; if (_fullFeatures.empty()) { _outFeatSize = _featSize; _outFeatSize[0] *= (1 + _featopts->history); _outFeatSize[0] += (_featopts->outFeatures ? 1 : 0) + (_featopts->turnFeaturesSingleChannel ? 1 : 0) + (_featopts->turnFeaturesMultiChannel ? getNumPlayerColors() : 0) + (_featopts->geometricFeatures ? 4 : 0) + (_featopts->oneFeature ? 1 : 0) + _featopts->randomFeatures; _fullFeatures.resize(_outFeatSize[0] * _outFeatSize[1] * _outFeatSize[2]); if (_featopts->history > 0) { expand(_features.size() * (_featopts->history + 1)); } else { expand(_features.size()); } if (_featopts->randomFeatures > 0) { float* dst = expand(_featopts->randomFeatures * _featSize[1] * _featSize[2]); for (int k = 1; k <= _featopts->randomFeatures; k++) { for (int i = 1; i <= _featSize[1]; i++) { for (int j = 1; j <= _featSize[2]; j++) { float x = k * 0.754421f + i * 0.147731f + j * 0.242551f; x += 0.145531f * (i * k) + 0.741431f * (i * j) + 0.134134f * (j * k); x += 0.423423f * (i * j * k); *dst++ = x - std::floor(x); } } } } if (_featopts->geometricFeatures) { float* dst = expand(4 * _featSize[1] * _featSize[2]); for (int k = 0; k < 4; k++) { for (int i = 0; i < _featSize[1]; i++) { for (int j = 0; j < _featSize[2]; j++) { if (k == 0) { *dst++ = float(i) / float(_featSize[1] - 1); } else if (k == 1) { *dst++ = float(j) / float(_featSize[2] - 1); } else if (k == 2) { float x = float(i) / float(_featSize[1] - 1) - 0.5f; float y = float(j) / float(_featSize[2] - 1) - 0.5f; *dst++ = x * x + y * y; } else if (k == 3) { float x1 = float(i) / float(_featSize[1] - 1); float x2 = 1.f - float(i) / float(_featSize[1] - 1); x2 = x2 < x1 ? x2 : x1; float x3 = float(j) / float(_featSize[2] - 1); x2 = x2 < x3 ? x2 : x3; float x4 = 1.f - float(j) / float(_featSize[2] - 1); x2 = x2 < x4 ? x2 : x4; *dst++ = x2; } } } } } if (_featopts->oneFeature) { add_constant_plane(1); } if (_featopts->turnFeaturesSingleChannel) { _turnFeaturesSingleChannelOffset = offset; expand(planeSize); } if (_featopts->turnFeaturesMultiChannel) { _turnFeaturesMultiChannelOffset = offset; expand(planeSize * getNumPlayerColors()); } if (_featopts->outFeatures) { float* dst = expand(_featSize[1] * _featSize[2]); for (int i = 0; i < _featSize[1]; i++) { for (int j = 0; j < _featSize[2]; j++) { if ((i == 0) || (i == _featSize[1] - 1) || (j == 0) || (j == _featSize[2] - 1)) { *dst++ = (1.); // 1 for the frontier } else { *dst++ = (0.); // 0 for the rest } } } } _previousFeatures.resize(_features.size() * (_featopts->history + 1)); for (int i = 0; i != _featopts->history + 1; ++i) { std::memcpy(_previousFeatures.data() + _features.size() * i, _features.data(), sizeof(float) * _features.size()); } } if (_featopts->history > 0) { offset = 0; // we check the expected size of features. unsigned int expected_size = (_featopts->history + 1) * _featSize[0] * _featSize[1] * _featSize[2]; if (_previousFeatures.size() != expected_size) { throw std::runtime_error( "internal error: previousFeatures is of incorrect size!"); } std::memcpy(_previousFeatures.data() + _previousFeaturesOffset, _features.data(), sizeof(float) * _features.size()); _previousFeaturesOffset += _features.size(); if (_previousFeaturesOffset == expected_size) { _previousFeaturesOffset = 0; } // we add the previous features in the full features. auto* dst = expand(expected_size); std::memcpy(dst, _previousFeatures.data() + _previousFeaturesOffset, sizeof(float) * (expected_size - _previousFeaturesOffset)); std::memcpy(dst + expected_size - _previousFeaturesOffset, _previousFeatures.data(), sizeof(float) * _previousFeaturesOffset); } else { offset = 0; std::memcpy(expand(_features.size()), _features.data(), sizeof(float) * _features.size()); } if (_featopts->turnFeaturesSingleChannel) { offset = _turnFeaturesSingleChannelOffset; add_constant_plane(getCurrentPlayerColor()); } if (_featopts->turnFeaturesMultiChannel) { offset = _turnFeaturesMultiChannelOffset; int n = getNumPlayerColors(); int myColor = getCurrentPlayerColor(); for (int i = 0; i != n; ++i) { add_constant_plane(i == myColor ? 1.0f : 0.0f); } } } } // namespace core ================================================ FILE: src/core/state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "common/thread_id.h" #include "mcts/types.h" #include #include #include #include #include #include #include #include #include #include #include namespace core { /***** Action and State are abstract classes. Derived classes correspond to various problems. A difference with the AZ setting is that several actions can correspond to the same logit from the neural net. This is useful for complex action spaces in which the list of possible actions is tricky: the MCTS then takes care of differentiating the possible actions. In most of our games, we are still in bijection, but in the case of draughts this makes a difference. ******/ // TODO[doc]: ideally Action should just be private class known // only to State. the Actor and State represent actions using // the mcts::Action (i.e. int64_t) class _Action { public: // Get the location of the move in the neural network output. // Several moves might fall in the same location, no pb. _Action() { } _Action(mcts::Action index, int x, int y, int z) : _i(index) { _loc[0] = x; _loc[1] = y; _loc[2] = z; } int GetX() const { return _loc[0]; } int GetY() const { return _loc[1]; } int GetZ() const { return _loc[2]; } uint64_t GetHash() const { return _hash; } void SetIndex(int i) { _i = i; } int GetIndex() const { return _i; } protected: uint64_t _hash = 0; // Warning! Two actions might have the same position _loc. position // of the action in {0,...,GetXActionSize()-1} * // {0,...,GetYActionSize()-1} * {0,...,GetZActionSize()-1} std::array _loc; // index of the action in the list of legal actions in the // corresponding state. // _i makes sense since an action is never applied to two distinct // states. We could have a pointer to the state this action is // associated to. mcts::Action _i = -1; }; std::ostream& operator<<(std::ostream& os, const _Action& action); enum class GameStatus { player0Turn = 0, player1Turn, tie, player0Win, player1Win }; struct FeatureOptions { // Data specifying the way we generate generic features. bool outFeatures = false; // do we add a feature for borders bool turnFeaturesSingleChannel = false; // do we add a feature for turn (deprecated, use // turnFeaturesMultiChannel instead) bool turnFeaturesMultiChannel = false; // do we add a feature for turn/player(color) (one channel for // each player, 0 for other players, 1 for current player) bool geometricFeatures = false; // do we add geometric features int history = 0; // do we add a feature for history and how long (0 = none) int randomFeatures = 0; // how many random features (could be 0) bool oneFeature = false; // do we want a plane of 1s }; class State { public: void setSeed(int seed) { _rng.seed(seed); } State(int seed) { _rng.seed(seed); _stochasticReset = false; _hash = 0; _featSize.resize(3); _actionSize.resize(3); _stochastic = false; forcedDice = -1; } virtual ~State() { } template void initializeAs() { _typeId = &typeid(T); _copyImpl = [](State* dst, const State* src) { *(T*)dst = *(T*)src; }; } virtual void newGame(unsigned long seed) { } // -----overriding core::State's virtual functions----- static auto threadrng() { static thread_local std::minstd_rand rng(std::random_device{}()); return rng(); } std::unique_ptr clone() const { auto state = clone_(); state->_rng.seed(threadrng()); return state; } int getCurrentPlayer() const { if ((_status == GameStatus::player0Turn) || (_status == GameStatus::player0Win)) { return 0; } else if ((_status == GameStatus::player1Turn) || (_status == GameStatus::player1Win)) { return 1; } else { // assert(false); do not assert this! there might be ties :-) return 0; // the current player does not matter if we have ties. } } std::string lastMoveString() { std::string str; auto sc = clone(); auto* s = (State*)&*sc; auto moves = _moves; auto rngs = _moveRngs; s->reset(); for (size_t i = 0; i != moves.size(); ++i) { if (i == moves.size() - 1) { str = s->actionDescription(s->GetLegalActions().at(moves.at(i))); } std::tie(s->_rng, s->forcedDice) = rngs.at(i); s->forward(moves.at(i)); } return str; } std::string history() const { std::string str; auto sc = clone(); auto* s = (State*)&*sc; auto moves = _moves; auto rngs = _moveRngs; s->reset(); for (size_t i = 0; i != moves.size(); ++i) { if (!str.empty()) { str += " "; } str += s->actionDescription(s->GetLegalActions().at(moves.at(i))); std::tie(s->_rng, s->forcedDice) = rngs.at(i); s->forward(moves.at(i)); } return str; } virtual int getCurrentPlayerColor() const { return getCurrentPlayer(); } virtual int getNumPlayerColors() const { throw std::runtime_error( "getNumPlayerColors is not implemented for this game"); return 0; } int getStepIdx() const { return _moves.size(); } const std::vector& getMoves() const { return _moves; } virtual float getReward(int player) const { assert(player == 0 || player == 1); if (_status == GameStatus::player0Win) { return player == 0 ? 1.0 : -1.0; } else if (_status == GameStatus::player1Win) { return player == 1 ? 1.0 : -1.0; } else { return 0.0; } } virtual int overrideAction() const { return -1; } bool terminated() const { return (_status == GameStatus::tie || _status == GameStatus::player0Win || _status == GameStatus::player1Win); }; virtual float getRandomRolloutReward(int player) const { const int numSimulation = 10; float sumReward = 0.0; for (int i = 0; i < numSimulation; ++i) { auto clonedState = clone(); auto s = dynamic_cast(clonedState.get()); while (!s->terminated()) { s->DoRandomAction(); } sumReward += s->getReward(player); } return sumReward / numSimulation; } void forward(const mcts::Action& action) { assert(action != mcts::InvalidAction); ApplyAction(GetLegalActions().at(action)); _moves.push_back(action); _moveRngs.emplace_back(_rng, forcedDice); } // -----interface for games to implement----- virtual void Initialize() = 0; virtual std::unique_ptr clone_() const = 0; virtual void ApplyAction(const _Action& action) = 0; virtual void DoGoodAction() { DoRandomAction(); } virtual void printCurrentBoard() const { std::cout << stateDescription() << std::endl; } virtual void errPrintCurrentBoard() const { std::cerr << stateDescription() << std::endl; } const std::vector<_Action>& GetLegalActions() const { return _legalActions; } virtual std::string stateDescription() const { std::string str; auto& feats = GetFeatures(); auto& sizes = GetFeatureSize(); if (sizes[0] == 2) { bool allOnesOrZero = true; for (auto& v : feats) { if (v != 0 && v != 1) { allOnesOrZero = false; break; } } if (allOnesOrZero) { size_t index = 0; size_t offset = sizes[1] * sizes[2]; for (int64_t y = 0; y != sizes[1]; ++y) { for (int64_t z = 0; z != sizes[2]; ++z) { if (z) { str += '|'; } char c = ' '; if (feats[index] && feats[offset + index]) { c = '!'; } else if (feats[index]) { c = 'x'; } else if (feats[offset + index]) { c = 'o'; } str += c; ++index; } str += '\n'; } return str; } } size_t index = 0; for (int64_t x = 0; x != sizes[0]; ++x) { str += "Channel " + std::to_string(x) + ":\n"; for (int64_t y = 0; y != sizes[1]; ++y) { for (int64_t z = 0; z != sizes[2]; ++z) { if (z) { str += ' '; } str += feats[index] == int(feats[index]) ? std::to_string(int(feats[index])) : std::to_string(feats[index]); ++index; } str += '\n'; } if (x != sizes[0] - 1) { str += '\n'; } } return str; } virtual std::string actionDescription(const _Action& action) const { std::stringstream ss; ss << action.GetIndex(); return ss.str(); } virtual std::string actionsDescription() const { std::string str; for (auto& v : _legalActions) { str += actionDescription(v) + " "; } return str; } virtual int parseAction(const std::string& str) const { for (size_t i = 0; i != _legalActions.size(); ++i) { if (str == actionDescription(_legalActions[i])) { return i; } } return -1; } int TPInputAction( std::function(std::string)> specialAction = [](std::string) { return std::nullopt; }) { /*std::cout << "Current board:" << std::endl << stateDescription() << std::endl; std::cout << "Legal Actions:" << std::endl << actionsDescription() << std::endl;*/ // Second, receive human feedback. std::string line1; std::string line2; std::string line3; auto& legalActions = GetLegalActions(); int index = -1; int index1 = -1; int index2 = -1; int index3 = -1; std::cout << "# Last action" << std::endl; std::cerr << stateDescription() << std::endl; printLastActionXYZ(); while (index < 0 || index >= (int)legalActions.size()) { std::cout << "#Input action as x y z: "; std::cin >> line1; std::cin >> line2; std::cin >> line3; index1 = parseAction(line1); index2 = parseAction(line2); index3 = parseAction(line3); for (size_t i = 0; i < legalActions.size(); i++) { if ((GetLegalActions().at(i).GetX() == index1) && (GetLegalActions().at(i).GetY() == index2) && (GetLegalActions().at(i).GetZ() == index3)) { index = i; break; } if (i == legalActions.size()) { std::cout << "# bad answer!" << std::endl; } } if (index == -1) { if (auto r = specialAction(line1); r) { return *r; } } } return index; } virtual int humanInputAction( std::function(std::string)> specialAction = [](std::string) { return std::nullopt; }) { std::cout << "Current board:" << std::endl << stateDescription() << std::endl; std::cout << "Legal Actions:" << std::endl << actionsDescription() << std::endl; // Second, receive human feedback. std::string line; auto& legalActions = GetLegalActions(); int index = -1; while (index < 0 || index >= (int)legalActions.size()) { std::cout << "Input action: "; std::cin.clear(); std::cin >> line; if (!std::cin.good()) { std::exit(1); } index = parseAction(line); if (index == -1) { if (auto r = specialAction(line); r) { return *r; } } } return index; } void undoLastMove() { if (_moves.empty()) { return; } auto moves = _moves; auto rngs = _moveRngs; reset(); for (size_t i = 0; i != moves.size() - 1; ++i) { std::tie(_rng, forcedDice) = rngs.at(i); forward(moves.at(i)); } } virtual void setStateFromStr(const std::string& /*str*/) { } void printLastAction() { if (_moves.empty()) { std::cout << "no moves" << std::endl; return; } auto moves = _moves; auto rngs = _moveRngs; reset(); for (size_t i = 0; i != moves.size(); ++i) { std::tie(_rng, forcedDice) = rngs.at(i); if (i == moves.size() - 1) { std::cout << actionDescription(GetLegalActions().at(moves.at(i))) << std::endl; } forward(moves.at(i)); } } void printLastActionXYZ() { if (_moves.empty()) { std::cout << 0 << std::endl; std::cout << 0 << std::endl; std::cout << 0 << std::endl; return; } auto moves = _moves; auto rngs = _moveRngs; reset(); for (size_t i = 0; i != moves.size(); ++i) { std::tie(_rng, forcedDice) = rngs.at(i); if (i == moves.size() - 1) { std::cout << GetLegalActions().at(moves.at(i)).GetX() << std::endl; std::cout << GetLegalActions().at(moves.at(i)).GetY() << std::endl; std::cout << GetLegalActions().at(moves.at(i)).GetZ() << std::endl; } forward(moves.at(i)); } } void undoLastMoveForPlayer(int player) { auto moves = _moves; auto rngs = _moveRngs; reset(); size_t resetToIndex = moves.size(); // Find the last move that was ours for (size_t i = 0; i != moves.size(); ++i) { std::tie(_rng, forcedDice) = rngs.at(i); auto prevPlayer = getCurrentPlayer(); forward(moves[i]); if (prevPlayer == player) { resetToIndex = i; } } // Reset to it reset(); for (size_t i = 0; i != resetToIndex; ++i) { std::tie(_rng, forcedDice) = rngs.at(i); forward(moves.at(i)); } if (getCurrentPlayer() != player) { throw std::runtime_error("Undo error: expected player " + std::to_string(player) + ", got " + std::to_string(getCurrentPlayer())); } } // -----other non-virtual functions----- void fillFullFeatures(); void DoRandomAction() { assert(!_legalActions.empty()); std::uniform_int_distribution distr(0, _legalActions.size() - 1); size_t i = distr(_rng); _Action a = _legalActions[i]; ApplyAction(a); } void doIndexedAction(int j) { int i = j % _legalActions.size(); _Action a = _legalActions[i]; ApplyAction(a); } bool checkMove(const mcts::Action& c) const { return c < (int)_legalActions.size(); } uint64_t getHash() const { return _hash; } const std::vector& GetRawFeatures() const { return _features; } const std::vector& GetRawFeatureSize() const { return _featSize; } // Returns GetXSize x GetYSize x GetZSize float input for the NN. const std::vector& GetFeatures() const { return _fullFeatures.empty() ? _features : _fullFeatures; } const std::vector& GetFeatureSize() const { return _outFeatSize.empty() ? _featSize : _outFeatSize; } int GetFeatureLength() const { auto featureSize = GetFeatureSize(); return featureSize[0] * featureSize[1] * featureSize[2]; } const std::vector& GetActionSize() const { return _actionSize; } void reset() { _moves.clear(); _moveRngs.clear(); _previousFeatures.clear(); _previousFeaturesOffset = 0; _turnFeaturesSingleChannelOffset = 0; _turnFeaturesMultiChannelOffset = 0; _outFeatSize.clear(); _fullFeatures.clear(); _features.clear(); _legalActions.clear(); Initialize(); } void setFeatures(const FeatureOptions* opts) { _featopts = opts; } bool stochasticReset() const { return _stochasticReset; } virtual bool isStochastic() const { return _stochastic; } void copy(const State& src) { _copyImpl(this, &src); } const std::type_info& typeId() const { return *_typeId; } virtual bool isOnePlayerGame() const { return false; } int forcedDice; protected: void clearActions() { _legalActions.clear(); } // Note: x is the channel, y & z are the spartial coordinates void addAction(int x, int y, int z) { _legalActions.emplace_back(_legalActions.size(), x, y, z); } bool _stochastic; bool _stochasticReset; const std::type_info* _typeId = nullptr; void (*_copyImpl)(State* dst, const State* src) = nullptr; std::minstd_rand _rng; GameStatus _status; uint64_t _hash; std::vector _features; // neural network input std::vector<_Action> _legalActions; std::vector _featSize; // size of the neural network input std::vector _actionSize; // size of the neural network output std::vector _moves; std::vector> _moveRngs; const FeatureOptions* _featopts = nullptr; // Below the std::vector involved in the generic added features. // size of the neural network input if using _outFeature or _history > 0: std::vector _outFeatSize; std::vector _fullFeatures; // neural network input, completed std::vector _previousFeatures; // history of features size_t _previousFeaturesOffset = 0; size_t _turnFeaturesSingleChannelOffset = 0; size_t _turnFeaturesMultiChannelOffset = 0; }; } // namespace core using core::_Action; using core::GameStatus; ================================================ FILE: src/core/test_state.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "game.h" #include "state.h" #include float goodEval(core::State& s) { float numWins = 0; int gameCount = 0; while (gameCount < 100) { s.reset(); while (!s.terminated()) { s.DoGoodAction(); } numWins += 0.5 * (1 + s.getReward(0)); ++gameCount; } float winRate = numWins / float(gameCount); std::cout << "good win rate = " << winRate << std::endl; if ((winRate <= 0.01) || (winRate >= 0.99)) { throw std::runtime_error( "this game has a random win rate beyond acceptable."); } return true; } float randEval(core::State& s) { float numWins = 0; int gameCount = 0; while (gameCount < 100) { s.reset(); while (!s.terminated()) { s.DoRandomAction(); } numWins += 0.5 * (1 + s.getReward(0)); ++gameCount; } float winRate = numWins / float(gameCount); std::cout << "win rate = " << winRate << std::endl; if ((winRate <= 0.01) || (winRate >= 0.99)) { throw std::runtime_error( "this game has a random win rate beyond acceptable."); } return true; } int doSimpleTest(core::State& s) { // goodEval(s); // Test that everything is fine. // win_frequency = 0 or 1 in purely random play is weird. randEval(s); // Now testing if the game looks stochastic. bool isStochastic = false; // We will check this for various lengths of simulations, i is the length. // if isStochastic switches to true (i.e. a non-determinism is already // detected), // then we stop the loop. bool theoreticallyStochastic = s.isStochastic(); for (int umax = 8; ((umax < 70) && (!isStochastic)); umax += 1) { s.Initialize(); s.setSeed(5678); if (s.isStochastic()) { theoreticallyStochastic = true; } for (int u = 0; u < umax; u++) { if (!s.terminated()) s.doIndexedAction(int(umax * 7.123 + u * 1.35)); if (s.isStochastic()) { theoreticallyStochastic = true; } // s.stateDescription(); // std::cout << "old:" << u << ":" << s.GetFeatures() << std::endl; } // std::cerr << s.stateDescription() << std::endl; auto oldFeatures = s.GetFeatures(); // we play another game of length u. s.Initialize(); s.setSeed(1234); for (int u = 0; u < umax; u++) { if (!s.terminated()) s.doIndexedAction(int(umax * 7.123 + u * 1.35)); // std::cout << "=====" << std::endl << s.stateDescription() << std::endl; // std::cout << "new:" << u << ":" << s.GetFeatures() << std::endl; } // std::cerr << s.stateDescription() << std::endl; if ((int)s.GetFeatures().size() != s.GetFeatureLength()) { throw std::runtime_error("wrong feature length"); } for (int j = 0; ((!isStochastic) && (j < s.GetFeatureLength())); j++) { if (s.GetFeatures()[j] != oldFeatures[j]) { std::cout << "#horizon" << umax << "+feature" << j << "/" << s.GetFeatureLength() << "--" << s.GetFeatures()[j] << " vs " << oldFeatures[j] << std::endl; isStochastic = true; } } // if (isStochastic && (!theoreticallyStochastic)) { // std::cout << "original:" << oldFeatures << std::endl; // std::cout << "current: " << s.GetFeatures() << std::endl; // } } if (isStochastic != theoreticallyStochastic) { std::cout << s.stateDescription() << std::endl; std::cout << " Theoretically: " << theoreticallyStochastic << std::endl; std::cout << " Practically: " << isStochastic << std::endl; throw std::runtime_error("stochasticity violated"); } // s.Initialize(); return s.GetFeatureSize()[0]; } void doTest(core::State& s) { doSimpleTest(s); std::cout << "testing: fillFullFeatures at the end of ApplyAction and of " "Initialize." << std::endl; core::FeatureOptions opt; opt.randomFeatures = 3; s.setFeatures(&opt); doSimpleTest(s); } // TODO: there should be better way (using gtest?) than writing a main // this is just for demo purpose // After compilation, run test_state from build folder to run the test int main() { int seed = 999; { std::cout << "testing: tristannogo" << std::endl; auto state = StateForTristannogo(seed); doTest(state); std::cout << "test pass: tristannogo" << std::endl; } { std::cout << "testing: BlockGo" << std::endl; auto state = StateForBlockGo(seed); doTest(state); std::cout << "test pass: BlockGo" << std::endl; } { #ifdef NO_JAVA std::cout << "skipping: Ludii Tic-Tac-Toe" << std::endl; #else std::cout << "testing: Ludii Tic-Tac-Toe" << std::endl; Ludii::JNIUtils::InitJVM(""); // Use default /ludii/Ludii.jar path JNIEnv* jni_env = Ludii::JNIUtils::GetEnv(); if (jni_env) { Ludii::LudiiGameWrapper game_wrapper("Tic-Tac-Toe.lud"); auto state = std::make_unique( seed, std::move(game_wrapper)); doTest(*state); Ludii::JNIUtils::CloseJVM(); std::cout << "test pass: Ludii Tic-Tac-Toe" << std::endl; } else { std::cout << "skipping: Ludii Tic-Tac-Toe" << std::endl; } #endif } { std::cout << "testing: connect four" << std::endl; auto state = StateForConnectFour(seed); doTest(state); std::cout << "test pass: connect four" << std::endl; } { std::cout << "testing: breakthrough" << std::endl; auto state = StateForBreakthrough(seed); doTest(state); std::cout << "test pass: breakthrough" << std::endl; } { std::cout << "testing: Connect6" << std::endl; auto state = Connect6::StateForConnect6(seed); doTest(state); std::cout << "test pass: Connect6" << std::endl; } { std::cout << "testing: Tic-tac-toe" << std::endl; auto state = MNKGame::State<3, 3, 3>(seed); doTest(state); std::cout << "test pass: Tic-tac-toe" << std::endl; } { std::cout << "testing: Free-style gomoku" << std::endl; auto state = MNKGame::State<15, 15, 5>(seed); doTest(state); std::cout << "test pass: Free-style gomoku" << std::endl; } { std::cout << "testing: Othello" << std::endl; auto state8 = Othello::State<8>(seed); doTest(state8); std::cout << "test pass: 8×8 Othello" << std::endl; auto state10 = Othello::State<10>(seed); doTest(state10); std::cout << "test pass: 10×10 Othello" << std::endl; auto state16 = Othello::State<16>(seed); doTest(state16); std::cout << "test pass: 16×16 Othello" << std::endl; } { std::cout << "testing: Game of the Amazons" << std::endl; auto state = Amazons::State(seed); doTest(state); std::cout << "test pass: Game of the Amazons" << std::endl; } { std::cout << "testing: Chinese Checkers" << std::endl; auto state = ChineseCheckers::State(seed); doTest(state); std::cout << "test pass: Chinese Checkers" << std::endl; } { std::cout << "testing: Gomoku swap2" << std::endl; auto state = GomokuSwap2::State(seed); doTest(state); std::cout << "test pass: Gomoku swap2" << std::endl; } { std::cout << "testing: hex5pie" << std::endl; auto state = Hex::State<5, true>(seed); doTest(state); std::cout << "test pass: hex5pie" << std::endl; } { std::cout << "testing: hex11pie" << std::endl; auto state = Hex::State<11, true>(seed); doTest(state); std::cout << "test pass: hex11pie" << std::endl; } { std::cout << "testing: hex13pie" << std::endl; auto state = Hex::State<13, true>(seed); doTest(state); std::cout << "test pass: hex13pie" << std::endl; } { std::cout << "testing: hex19pie" << std::endl; auto state = Hex::State<19, true>(seed); doTest(state); std::cout << "test pass: hex19pie" << std::endl; } { std::cout << "testing: hex5" << std::endl; auto state = Hex::State<5, false>(seed); doTest(state); std::cout << "test pass: hex5" << std::endl; } { std::cout << "testing: hex11" << std::endl; auto state = Hex::State<11, false>(seed); doTest(state); std::cout << "test pass: hex11" << std::endl; } { std::cout << "testing: hex13" << std::endl; auto state = Hex::State<13, false>(seed); doTest(state); std::cout << "test pass: hex13" << std::endl; } { std::cout << "testing: hex19" << std::endl; auto state = Hex::State<19, false>(seed); doTest(state); std::cout << "test pass: hex19" << std::endl; } { std::cout << "testing: havannah5pieExt" << std::endl; auto state = Havannah::State<5, true, true>(seed); doTest(state); std::cout << "test pass: havannah5pieExt" << std::endl; } { std::cout << "testing: havannah8pieExt" << std::endl; auto state = Havannah::State<8, true, true>(seed); doTest(state); std::cout << "test pass: havannah8pieExt" << std::endl; } { std::cout << "testing: havannah5pie" << std::endl; auto state = Havannah::State<5, true, false>(seed); doTest(state); std::cout << "test pass: havannah5pie" << std::endl; } { std::cout << "testing: havannah8pie" << std::endl; auto state = Havannah::State<8, true, false>(seed); doTest(state); std::cout << "test pass: havannah8pie" << std::endl; } { std::cout << "testing: havannah5" << std::endl; auto state = Havannah::State<5, false, false>(seed); doTest(state); std::cout << "test pass: havannah5" << std::endl; } { std::cout << "testing: havannah8" << std::endl; auto state = Havannah::State<8, false, false>(seed); doTest(state); std::cout << "test pass: havannah8" << std::endl; } { std::cout << "testing: Outer Open Gomoku" << std::endl; auto state = StateForOOGomoku(seed); doTest(state); std::cout << "test pass: Outer Open Gomoku" << std::endl; } { std::cout << "testing: Mastermind" << std::endl; auto state = Mastermind::State<10, 7, 2>(seed); doTest(state); std::cout << "test pass: Mastermind" << std::endl; } { std::cout << "testing: Minesweeper beginner" << std::endl; auto state = Minesweeper::State<8, 8, 10>(seed); doTest(state); std::cout << "test pass: Minesweeper beginner" << std::endl; } /* win rates for intermediate and expert are too low when taking random actions { std::cout << "testing: Minesweeper intermediate" << std::endl; auto state = Minesweeper::State<15, 13, 40>(seed); doTest(state); std::cout << "test pass: Minesweeper intermediate" << std::endl; } { std::cout << "testing: Minesweeper expert" << std::endl; auto state = Minesweeper::State<30, 16, 99>(seed); doTest(state); std::cout << "test pass: Minesweeper expert" << std::endl; } */ { std::cout << "testing: Outer Open Gomoku" << std::endl; auto state = StateForOOGomoku(seed); doTest(state); std::cout << "test pass: Outer Open Gomoku" << std::endl; } { std::cout << "testing: Surakarta" << std::endl; auto state = StateForSurakarta(seed); doTest(state); std::cout << "test pass: Surakarta" << std::endl; } { std::cout << "testing: Einstein" << std::endl; auto state = StateForEinstein(seed); doTest(state); std::cout << "test pass: Einstein" << std::endl; } { std::cout << "testing: Minishogi" << std::endl; auto state = StateForMinishogi(seed); doTest(state); std::cout << "test pass: Minishogi" << std::endl; } { std::cout << "testing: Diceshogi" << std::endl; auto state = StateForDiceshogi(seed); doTest(state); std::cout << "test pass: Diceshogi" << std::endl; } { std::cout << "testing: YINSH" << std::endl; auto state = StateForYinsh(seed); doTest(state); std::cout << "test pass: YINSH" << std::endl; } { std::cout << "testing: Kyotoshogi" << std::endl; auto state = StateForKyotoshogi(seed); doTest(state); std::cout << "test pass: Kyotoshogi" << std::endl; } { std::cout << "testing: chess" << std::endl; auto state = chess::State(seed); doTest(state); std::cout << "test pass: chess" << std::endl; } } ================================================ FILE: src/core/utils.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include "state.h" namespace core { inline void getFeatureInTensor(const State& state, float* dest) { auto& feat = state.GetFeatures(); memcpy(dest, feat.data(), sizeof(float) * feat.size()); } inline void getFeatureInTensor(const State& state, torch::Tensor dest) { assert(dest.dtype() == torch::kFloat32); auto& feat = state.GetFeatures(); torch::Tensor temp = torch::from_blob( (void*)feat.data(), state.GetFeatureSize(), dest.dtype()); if (feat.size() != temp.numel()) { throw std::runtime_error("getFeatureInTensor size mismatch"); } dest.copy_(temp); } inline torch::Tensor getFeatureInTensor(const State& state) { torch::Tensor t = torch::zeros(state.GetFeatureSize(), torch::kFloat32); getFeatureInTensor(state, t); return t; } inline void getRawFeatureInTensor(const State& state, torch::Tensor dest) { assert(dest.dtype() == torch::kFloat32); auto& feat = state.GetRawFeatures(); torch::Tensor temp = torch::from_blob( (void*)feat.data(), state.GetRawFeatureSize(), dest.dtype()); if (feat.size() != temp.numel()) { throw std::runtime_error("getRawFeatureInTensor size mismatch"); } dest.copy_(temp); } inline torch::Tensor getRawFeatureInTensor(const State& state) { torch::Tensor t = torch::zeros(state.GetRawFeatureSize(), torch::kFloat32); getRawFeatureInTensor(state, t); return t; } inline void getPolicyMaskInTensor( const State& state, torch::TensorAccessor maskaccessor) { for (const auto& action : state.GetLegalActions()) { maskaccessor[action.GetX()][action.GetY()][action.GetZ()] = 1; } } inline void getPolicyMaskInTensor(const State& state, torch::Tensor& mask) { assert(state.GetActionSize().size() == 3); auto maskaccessor = mask.accessor(); getPolicyMaskInTensor(state, maskaccessor); } inline torch::Tensor getPolicyMaskInTensor(const State& state) { torch::Tensor mask = torch::zeros(state.GetActionSize(), torch::kFloat32); getPolicyMaskInTensor(state, mask); return mask; } inline void getPolicyInTensor(const State& state, const std::vector& pi, torch::Tensor& dest, torch::Tensor& mask) { assert(dest.dtype() == torch::kFloat32); assert(state.GetActionSize().size() == 3); auto accessor = dest.accessor(); auto maskaccessor = mask.accessor(); const auto& legalAction = state.GetLegalActions(); for (mcts::Action actionIdx = 0; actionIdx != pi.size(); ++actionIdx) { if (actionIdx >= (int)legalAction.size() || actionIdx < 0) { std::cout << "Wrong action in getPolicyTargetInTensor, " << "action idx: " << actionIdx << ", num legal: " << legalAction.size() << std::endl; std::terminate(); assert(false); } const auto& action = legalAction[actionIdx]; float piVal = pi[actionIdx]; int x = action.GetX(); int y = action.GetY(); int z = action.GetZ(); accessor[x][y][z] += piVal; maskaccessor[x][y][z] = 1; } } inline std::pair getPolicyInTensor( const State& state, const std::vector& pi) { torch::Tensor t = torch::zeros(state.GetActionSize(), torch::kFloat32); torch::Tensor mask = torch::zeros(state.GetActionSize(), torch::kFloat32); getPolicyInTensor(state, pi, t, mask); return std::make_pair(t, mask); } inline void normalize(std::vector& a2pi) { float sumProb = 0.0f; for (auto& p : a2pi) { sumProb += p; } if (sumProb > 1.0f + 1e-3f) { throw std::runtime_error("sumProb is " + std::to_string(sumProb)); } if (sumProb != 0.0f) { for (auto& p : a2pi) { p /= sumProb; } } } inline void getLegalPi(const State& state, torch::TensorAccessor accessor, std::vector& out) { const auto& legalActions = state.GetLegalActions(); out.resize(legalActions.size()); for (size_t i = 0; i != legalActions.size(); ++i) { const auto& action = legalActions[i]; float& pi = accessor[action.GetX()][action.GetY()][action.GetZ()]; out[i] = std::exchange(pi, -400.0f); // we exchange with -400 (exp(-400) ~ 0) because: // - two actions A and B can share the same policy output location // - the NN will then be trained to output the sum of their policy values // in that location // - if we give both actions that policy output, there will be a bias in // the MCTS towards exploring // A and B, and the sum of all policy values will be > 1 // - instead, we give the sum to one action and 0 to the others, preserving // the sum of probabilities // - the MCTS must compensate for this by forcefully visiting both A and B // whenever A or B is visited // other algorithms are unlikely to support multiple actions sharing // the same policy output // - it would be equivalent to divide pi by the number of actions that // share this policy value (2 in // this case), but it would be slower as we don't know beforehand how // many that is // this will set the source tensor to all -400 (it shouldn't be needed for // anything else) } } inline void getLegalPi(const State& state, const torch::Tensor& pi, std::vector& out) { auto accessor = pi.accessor(); return getLegalPi(state, accessor, out); } inline int64_t product(const std::vector& nums) { int64_t p = 1; for (auto n : nums) { p *= n; } return p; } template inline static void softmax_(T begin, T end) { if (begin == end) { return; } float max = *begin; for (auto i = std::next(begin); i != end; ++i) { max = std::max(max, *i); } float sum = 0.0f; for (auto i = begin; i != end; ++i) { *i = std::exp(*i - max); sum += *i; } for (auto i = begin; i != end; ++i) { *i /= sum; } } inline static void softmax_(std::vector& vec) { softmax_(vec.begin(), vec.end()); } template inline static void softmax_(T begin, T end, float temperature) { if (begin == end) { return; } float itemp = 1.0f / temperature; for (auto i = begin; i != end; ++i) { *i *= itemp; } float max = *begin; for (auto i = std::next(begin); i != end; ++i) { max = std::max(max, *i); } float sum = 0.0f; for (auto i = begin; i != end; ++i) { *i = std::exp(*i - max); sum += *i; } for (auto i = begin; i != end; ++i) { *i /= sum; } } inline static void softmax_(std::vector& vec, float temperature) { softmax_(vec.begin(), vec.end(), temperature); } } // namespace core ================================================ FILE: src/distributed/distributed.cc ================================================ #include "distributed.h" #include "rpc.h" #include "rdma.h" #define ZSTD_STATIC_LINKING_ONLY #include "zstd/lib/zstd.h" #include #include #include #include #include #include #include #include #include namespace distributed { struct NetStats { bool hasData = false; double sent = 0.0; double received = 0.0; double rpcCalls = 0.0; double latency = 0.0; std::chrono::steady_clock::time_point lastprint{}; std::mutex m; }; inline NetStats netstats; struct NetStatsCounter { std::chrono::steady_clock::time_point timestamp{}; size_t sent = 0; size_t received = 0; size_t rpcCalls = 0; }; template void addnetworkstats(const T& obj, NetStatsCounter& counter) { auto now = std::chrono::steady_clock::now(); auto elapsed = now - counter.timestamp; if (elapsed < (netstats.hasData ? std::chrono::seconds(1) : std::chrono::seconds(10))) { return; } std::unique_lock l(netstats.m, std::try_to_lock); if (!l.owns_lock()) { return; } counter.timestamp = now; double t = std::chrono::duration_cast< std::chrono::duration>>(elapsed) .count(); size_t newSent = obj.bytesSent(); size_t newReceived = obj.bytesReceived(); size_t newCalls = obj.numRpcCalls(); double sent = (newSent - std::exchange(counter.sent, newSent)) / t; double recv = (newReceived - std::exchange(counter.received, newReceived)) / t; double calls = (newCalls - std::exchange(counter.rpcCalls, newCalls)) / t; double alpha = std::pow(0.99, t); if (!netstats.hasData) { alpha = 0.0; netstats.hasData = true; } netstats.sent = netstats.sent * alpha + sent * (1.0 - alpha); netstats.received = netstats.received * alpha + recv * (1.0 - alpha); netstats.rpcCalls = netstats.rpcCalls * alpha + calls * (1.0 - alpha); constexpr bool haslatency = std::is_same_v; if constexpr (haslatency) { double ll = std::chrono::duration_cast< std::chrono::duration>>( obj.lastLatency()) .count(); netstats.latency = netstats.latency * alpha + ll * (1.0 - alpha); } if (now - netstats.lastprint >= std::chrono::seconds(60)) { netstats.lastprint = now; if (haslatency) { printf("Network stats: in: %.02fM/s out: %.02fM/s RPC calls: %.02f/s " "latency: %.02fms\n", netstats.received / 1024 / 1024, netstats.sent / 1024 / 1024, netstats.rpcCalls, netstats.latency); } else { printf("Network stats: in: %.02fM/s out: %.02fM/s RPC calls: %.02f/s\n", netstats.received / 1024 / 1024, netstats.sent / 1024 / 1024, netstats.rpcCalls); } } } inline rpc::Rpc& getRpc() { static std::unique_ptr rpc = []() { auto rpc = std::make_unique(); rpc->asyncRun(40); return rpc; }(); return *rpc; } struct RDMAModelInfo { uint32_t checksum; uint32_t key; uintptr_t address; size_t size; }; struct Crc32 { std::array lut; Crc32() { for (uint32_t i = 0; i != 256; ++i) { uint32_t v = i; for (size_t b = 0; b != 8; ++b) { v = (v >> 1) ^ (v & 1 ? 0xedb88320 : 0); } lut[i] = v; } } uint32_t operator()(const void* ptr, size_t size) { uint32_t r = 0xffffffff; unsigned char* c = (unsigned char*)ptr; unsigned char* end = c + size; while (c != end) { r = (r >> 8) ^ lut[(r ^ *c++) & 0xff]; } return r; } } crc32; class ServerImpl { std::shared_ptr server; std::minstd_rand rng{std::random_device()()}; float rollChance(std::string_view id) { auto i = models.find(id); if (i == models.end()) { return 0.0f; } float rating = i->second.rating; float max = 0.0f; std::vector> sorted; for (auto& [id, m] : models) { sorted.emplace_back(m.rating, id); max = std::max(max, m.rating); } std::sort(sorted.begin(), sorted.end(), std::greater<>()); float lo = 1.0f; float ret = 0.0f; for (size_t i = 0; i != sorted.size(); ++i) { auto [r, n] = sorted[i]; float x = r - max; float o = x == 0 ? 1.0f : std::min(std::log(1 - (2.0f * 200) / x) / 4, 1.0f); if (r < rating) { ret += (lo - o) / i; } lo = o; } ret += lo / sorted.size(); return ret; } std::string_view sampleModelId() { if (models.empty() || std::uniform_real_distribution(0.0, 1.0)(rng) < 0.5) { return "dev"; } if (std::uniform_real_distribution(0.0, 1.0)(rng) < 0.01) { auto it = models.begin(); std::advance( it, std::uniform_int_distribution(0, models.size() - 1)(rng)); return it->first; } float max = 0.0f; for (auto& [id, m] : models) { max = std::max(max, m.rating); } double x = std::uniform_real_distribution(0.0, 1.0)(rng); double target = -(2.0f / (std::exp(x * 4) - 1)) * 200; std::vector pool; for (auto& [id, m] : models) { double diff = m.rating - max; if (diff >= target) { pool.push_back(id); } } if (!pool.empty()) { return pool.at( std::uniform_int_distribution(0, pool.size() - 1)(rng)); } return "dev"; } std::chrono::steady_clock::time_point lastRatingPrint = std::chrono::steady_clock::now(); void addResult(std::string_view id, float ratio, float reward) { if (ratio < 0.9f) { return; } auto i = models.find(id); if (i == models.end()) { return; } auto di = models.find("dev"); if (di == models.end()) { return; } if (i == di) { return; } float rating = i->second.rating; float devrating = di->second.rating; auto calc = [&](float reward, float diff) { float k = 6; float scale = 400; float offset = 0.5f; if (reward > 0) { offset = 1.0f; } else if (reward < 0) { offset = 0.0f; } return k * (offset - 1.0 / (1.0 + std::pow(10.0f, diff / scale))); }; float delta = calc(reward, devrating - rating) * ratio; float delta2 = calc(-reward, rating - devrating) * ratio; rating += delta; devrating += delta2; i->second.rating = rating; di->second.rating = devrating; ++i->second.ngames; ++di->second.ngames; i->second.rewardsum += reward; di->second.rewardsum -= reward; i->second.avgreward = i->second.rewardsum / i->second.ngames; di->second.avgreward = di->second.rewardsum / di->second.ngames; auto now = std::chrono::steady_clock::now(); if (now - lastRatingPrint >= std::chrono::seconds(120)) { lastRatingPrint = now; std::vector> sorted; for (auto& [id, m] : models) { sorted.emplace_back(m.rating, id); m.curgames = m.ngames - m.prevngames; m.curreward = (m.rewardsum - m.prevrewardsum) / m.curgames; m.prevngames = m.ngames; m.prevrewardsum = m.rewardsum; } std::sort(sorted.begin(), sorted.end(), std::greater<>()); int devrank = 0; float devrating = 0; for (size_t i = 0; i != sorted.size(); ++i) { if (sorted[i].second == "dev") { devrank = (int)i + 1; devrating = sorted[i].first; break; } } if (sorted.size() > 20) { sorted.resize(20); } std::string str; int rank = 1; auto stringify = [&](int rank, float rating, std::string_view id) { return fmt::sprintf("%d. %g %s (roll chance %f) (total %d games, %f " "avg reward) (diff %d games, %f avg reward)\n", rank, rating, id, rollChance(id), models[id].ngames, models[id].avgreward, models[id].curgames, models[id].curreward); }; for (auto& [rating, id] : sorted) { str += stringify(rank, rating, id); ++rank; } if (devrank > 20) { str += stringify(devrank, devrating, "dev"); } fmt::printf("Top 20:\n%s", str); } } std::pair requestModel(bool wantsNewModelId, std::string_view modelId) { std::unique_lock l(mut); if (wantsNewModelId) { modelId = sampleModelId(); } int version = -1; auto i = models.find(modelId); if (i == models.end()) { modelId = "dev"; i = models.find(modelId); } if (i != models.end()) { version = i->second.version; } else { version = -1; } addnetworkstats(*server, netstatsCounter); return {modelId, version}; } std::optional> requestStateDict(std::string_view modelId) { std::unique_lock l(mut); auto i = models.find(modelId); if (i == models.end()) { return {}; } else { return i->second.stateDict; } } std::optional> requestCompressedStateDict( std::string_view modelId) { std::unique_lock l(mut); auto i = models.find(modelId); if (i == models.end()) { return {}; } else { if (i->second.compressedStateDict.empty()) { for (int n = 0; n != 500 && i->second.compressing.exchange(true); ++n) { l.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); l.lock(); i = models.find(modelId); if (i == models.end()) { return {}; } if (!i->second.compressedStateDict.empty()) { return i->second.compressedStateDict; } } auto copy = i->second.stateDict; l.unlock(); auto start = std::chrono::steady_clock::now(); rpc::Serializer s; rpc::Serialize ser(s); ser(copy); auto now = std::chrono::steady_clock::now(); double t1 = std::chrono::duration_cast< std::chrono::duration>>(now - start) .count(); start = now; size_t oldsize = s.size(); s.compress(15); size_t newsize = s.size(); s.buf.shrink_to_fit(); now = std::chrono::steady_clock::now(); double t2 = std::chrono::duration_cast< std::chrono::duration>>(now - start) .count(); start = now; fmt::printf("State dict serialized in %gms, compressed (from %gM to " "%gM) in %gms\n", t1, oldsize / 1024.0 / 1024.0, newsize / 1024.0 / 1024.0, t2); l.lock(); i = models.find(modelId); if (i == models.end()) { return {}; } i->second.compressedStateDict = std::move(s.buf); i->second.compressing = false; } return i->second.compressedStateDict; } } void trainData(const std::unordered_map data) { onTrainData(std::move(data)); } void gameResult( std::vector>> result) { std::lock_guard l(mut); for (auto& [reward, models] : result) { for (auto& [id, ratio] : models) { addResult(id, ratio, reward); } } } struct rdmaClient { std::chrono::steady_clock::time_point timestamp; std::unique_ptr host; rdma::Endpoint localEp; rdma::Endpoint remoteEp; }; std::unique_ptr rdmaContext; std::unique_ptr rdmaCq; std::list rdmaClients; std::mutex rdmaMut; rdma::Endpoint rdmaConnect(rdma::Endpoint ep) { auto host = rdmaContext->createHost(); auto localEp = host->init(*rdmaCq); host->connect(ep); // fmt::printf("rdmaConnect, remoteEp %d:%d localEp %d:%d\n", ep.lid, // ep.qpnum, localEp.lid, localEp.qpnum); std::lock_guard l(rdmaMut); auto now = std::chrono::steady_clock::now(); for (auto i = rdmaClients.begin(); i != rdmaClients.end();) { if (now - i->timestamp >= std::chrono::minutes(1)) { // fmt::printf("RDMA client %d:%d timed out\n", i->remoteEp.lid, // i->remoteEp.qpnum); i = rdmaClients.erase(i); } else { ++i; } } rdmaClients.emplace_back(); auto& c = rdmaClients.back(); c.host = std::move(host); c.localEp = localEp; c.remoteEp = ep; c.timestamp = now; return localEp; } bool rdmaKeepalive(rdma::Endpoint remoteEp) { std::unique_lock rl(rdmaMut); for (auto i = rdmaClients.begin(); i != rdmaClients.end(); ++i) { if (i->remoteEp == remoteEp) { // fmt::printf("keepalive: rdma client %d:%d found, timestamp // updated\n", remoteEp.lid, remoteEp.qpnum); i->timestamp = std::chrono::steady_clock::now(); return true; } } return false; } std::optional rdmaGetModel(rdma::Endpoint remoteEp, std::string_view modelId) { try { std::unique_lock rl(rdmaMut); rdma::Endpoint localEp; for (auto i = rdmaClients.begin(); i != rdmaClients.end(); ++i) { if (i->remoteEp == remoteEp) { i->timestamp = std::chrono::steady_clock::now(); localEp = i->localEp; } } rl.unlock(); std::unique_lock l(mut); auto i = models.find(modelId); if (i == models.end()) { return {}; } for (int n = 0;; ++n) { if (!i->second.rdmaBuffer || i->second.rdmaBufferVersion != i->second.version) { if (n < 500 && i->second.rdmaSerializing.exchange(true)) { l.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); l.lock(); i = models.find(modelId); if (i == models.end()) { return {}; } } else { auto copy = i->second.stateDict; int version = i->second.version; l.unlock(); auto start = std::chrono::steady_clock::now(); rpc::Serializer s; rpc::Serialize ser(s); ser((uint32_t)0); ser(copy); uint32_t checksum = s.size() > 4 ? crc32(s.data() + 4, s.size() - 4) : 0; std::memcpy((void*)s.data(), &checksum, 4); l.lock(); i = models.find(modelId); if (i == models.end()) { return {}; } auto buffer = std::move(i->second.rdmaBuffer); auto storage = std::move(i->second.rdmaBufferStorage); // if (buffer && storage.size() >= s.size()) { if (false) { storage.resize(s.size()); std::memcpy(storage.data(), s.data(), s.size()); auto now = std::chrono::steady_clock::now(); double t1 = std::chrono::duration_cast< std::chrono::duration>>(now - start) .count(); fmt::printf("State dict serialized and RDMA buffer updated in " "%gms, %gM (checksum %#x)\n", t1, storage.size() / 1024.0 / 1024.0, checksum); } else { i->second.rdmaBuffer_01 = std::move(buffer); i->second.rdmaBufferStorage_01 = std::move(storage); storage = std::move(s.buf); buffer = rdmaContext->createBuffer( (void*)storage.data(), storage.size()); auto now = std::chrono::steady_clock::now(); double t1 = std::chrono::duration_cast< std::chrono::duration>>(now - start) .count(); fmt::printf("State dict serialized and RDMA buffer created in " "%gms, %gM (checksum %#x)\n", t1, storage.size() / 1024.0 / 1024.0, checksum); } i->second.rdmaBuffer = std::move(buffer); i->second.rdmaBufferStorage = std::move(storage); i->second.rdmaSerializing = false; i->second.rdmaBufferVersion = version; } } else { RDMAModelInfo r; r.key = i->second.rdmaBuffer->keyFor(localEp); r.checksum = i->second.rdmaBufferChecksum; r.address = (uintptr_t)i->second.rdmaBufferStorage.data(); r.size = i->second.rdmaBufferStorage.size(); return r; } } } catch (const std::exception& e) { fmt::printf("rdmaGetModel error: %s\n", e.what()); return {}; } } struct ModelInfo { std::string id; int version = 0; float rating = 0.0f; std::unordered_map stateDict; std::vector compressedStateDict; std::atomic compressing{false}; uint64_t ngames = 0; double rewardsum = 0.0; float avgreward = 0.0f; uint64_t prevngames = 0; double prevrewardsum = 0.0; uint64_t curgames = 0; float curreward = 0.0f; double rollChance = 0.0; std::atomic rdmaSerializing{false}; std::vector rdmaBufferStorage; std::unique_ptr rdmaBuffer; int rdmaBufferVersion = -1; uint32_t rdmaBufferChecksum = 0; std::vector rdmaBufferStorage_01; std::unique_ptr rdmaBuffer_01; }; std::mutex mut; std::unordered_map models; std::mutex timemut; std::unordered_map calltimes; std::chrono::steady_clock::time_point lasttimereport; public: std::function)> onTrainData; NetStatsCounter netstatsCounter; template auto define(std::string name, R (ServerImpl::*f)(Args...)) { server->define( name, std::function([this, f, name](Args&&... args) { auto begin = std::chrono::steady_clock::now(); auto finish = [&]() { auto end = std::chrono::steady_clock::now(); double t = std::chrono::duration_cast< std::chrono::duration>>( end - begin) .count(); { std::unique_lock l(timemut); auto i = calltimes.find(name); if (i == calltimes.end()) { i = calltimes.emplace(name, t).first; } float& v = i->second; v = v * 0.99 + t * 0.01; if (end - lasttimereport >= std::chrono::seconds(60)) { lasttimereport = end; std::string s = "RPC call times (running average):\n"; for (auto& v : calltimes) { s += fmt::sprintf(" %s %fms\n", v.first, v.second); } l.unlock(); fmt::printf("%s", s); } } }; if constexpr (std::is_same_v) { (this->*f)(std::forward(args)...); finish(); } else { auto rv = (this->*f)(std::forward(args)...); finish(); return rv; } })); } void start(std::string_view endpoint) { if (endpoint.substr(0, 6) == "tcp://") { endpoint.remove_prefix(6); } printf("actual listen endpoint is %s\n", std::string(endpoint).c_str()); server = getRpc().listen(""); define("requestModel", &ServerImpl::requestModel); define("requestStateDict", &ServerImpl::requestStateDict); define( "requestCompressedStateDict", &ServerImpl::requestCompressedStateDict); define("trainData", &ServerImpl::trainData); define("gameResult", &ServerImpl::gameResult); try { rdmaContext = rdma::create(); if (!rdmaContext) { fmt::printf("RDMA/IB is not supported\n"); } else { rdmaCq = rdmaContext->createCQ(4); auto testHost = rdmaContext->createHost(); define("rdmaConnect", &ServerImpl::rdmaConnect); define("rdmaKeepalive", &ServerImpl::rdmaKeepalive); define("rdmaGetModel", &ServerImpl::rdmaGetModel); fmt::printf("RDMA over IB supported\n"); } } catch (const std::exception& e) { fmt::printf("RDMA error: %s\nRDMA/IB will not be used\n", e.what()); } server->listen(endpoint); } void updateModel(const std::string& id, std::unordered_map stateDict) { std::unique_lock l(mut); auto i = models.try_emplace(id); if (i.second) { i.first->second.version = std::uniform_int_distribution(0, 10000)(rng) * 1000; i.first->second.id = id; (std::string_view&)i.first->first = i.first->second.id; auto idev = models.find("dev"); if (idev != models.end()) { i.first->second.rating = idev->second.rating; } } auto& m = i.first->second; m.stateDict = std::move(stateDict); ++m.version; m.compressedStateDict.clear(); } }; class ClientImpl { std::shared_ptr client; mutable std::mutex mut; std::unordered_set allModelIds; std::string_view currentModelId = *allModelIds.emplace("dev").first; int currentModelVersion = -1; int gamesDoneWithCurrentModel = 0; bool wantsNewModelId = false; bool wantsTournamentResult_ = false; std::chrono::steady_clock::time_point lastCheckTournamentResult = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point lastTournamentResult = std::chrono::steady_clock::now(); std::vector>> resultQueue; NetStatsCounter netstatsCounter; std::unique_ptr rdmaContext; std::unique_ptr rdmaHost; std::unique_ptr rdmaBuffer; size_t rdmaBufferSize = 0; std::vector rdmaBufferStorage; std::optional rdmaEndpoint; std::unique_ptr rdmaCq; std::mutex trainDataMut; std::vector> trainDataFutures; struct Bandit { std::mutex mut; std::unordered_map value; std::minstd_rand rng{std::random_device{}()}; float sample(std::string name, float weight = 1.0f) { std::lock_guard l(mut); return std::uniform_real_distribution( 0.0f, std::exp(value[name] * 4) * weight)(rng); } float get(std::string name) { std::lock_guard l(mut); return value[name]; } }; struct BanditResultCounter { Bandit& b; std::string name; bool succeeded_ = false; BanditResultCounter(Bandit& b, std::string name) : b(b) , name(std::move(name)) { } void success(bool succeeded = true) { succeeded_ = succeeded; } ~BanditResultCounter() { std::lock_guard l(b.mut); float& v = b.value[name]; v = v * 0.95f + (succeeded_ ? 1.0f : -1.0f) * 0.05f; } }; Bandit bandit; bool createRdmaHost() { if (!rdmaContext) { return false; } if (rdmaHost) { return true; } try { rdmaHost = rdmaContext->createHost(); return true; } catch (const std::exception& e) { fmt::printf("RDMA error: %s\nRDMA/IB will not be used\n", e.what()); return false; } } void requestModelStateDict(std::string modelId, int modelVersion) { try { auto start = std::chrono::steady_clock::now(); float rdmaValue = bandit.get("rdma"); float rpcValue = bandit.get("rpc"); fmt::printf("bandit values: rdma %g rpc %g\n", rdmaValue, rpcValue); if ((rdmaHost || createRdmaHost()) && (rdmaValue >= 0.75f || (rdmaValue >= 0.0f && rpcValue < 0.5f) || bandit.sample("rdma", 4.0f) > bandit.sample("rpc"))) { BanditResultCounter bc(bandit, "rdma"); try { if (!rdmaEndpoint) { rdmaCq = rdmaContext->createCQ(4); rdmaEndpoint = rdmaHost->init(*rdmaCq); fmt::printf("local endpoint is %d:%d\n", rdmaEndpoint->lid, rdmaEndpoint->qpnum); auto remoteEp = client->sync("rdmaConnect", *rdmaEndpoint); addnetworkstats(*client, netstatsCounter); fmt::printf( "remote endpoint is %d:%d\n", remoteEp.lid, remoteEp.qpnum); rdmaHost->connect(remoteEp); } auto result = client->async>( "rdmaGetModel", *rdmaEndpoint, modelId); auto mi = result.get(); if (!mi) { std::lock_guard l(mut); currentModelId = "dev"; currentModelVersion = -1; } else { if (!rdmaBuffer || rdmaBufferSize < mi->size) { rdmaBufferStorage.resize(mi->size); rdmaBuffer = rdmaContext->createBuffer(rdmaBufferStorage.data(), mi->size); } rdmaHost->read(*rdmaBuffer, rdmaBufferStorage.data(), mi->key, mi->address, mi->size); rdmaHost->wait(); std::unordered_map stateDict; rpc::Deserializer d(rdmaBufferStorage.data(), mi->size); rpc::Deserialize des(d); uint32_t checksum = 0; des(checksum); if (mi->size > 4 && crc32(rdmaBufferStorage.data() + 4, mi->size - 4) == checksum) { fmt::printf("RDMA model checksum OK (%#x)\n", checksum); des(stateDict); onUpdateModel(modelId, stateDict); std::lock_guard l(mut); if (currentModelId != modelId) { currentModelId = *allModelIds.emplace(modelId).first; gamesDoneWithCurrentModel = 0; } currentModelVersion = modelVersion; fmt::printf("Got model '%s' version %d\n", modelId, modelVersion); bc.success(); } else { fmt::printf("RDMA model checksum error\n"); return; } } } catch (const rdma::Error& e) { fmt::printf("RDMA error: %s\n", e.what()); rdmaEndpoint.reset(); rdmaHost.reset(); rdmaCq.reset(); return; } } else { BanditResultCounter bc(bandit, "rpc"); auto result = client->async>>( "requestCompressedStateDict", modelId); auto compressed = result.get(); addnetworkstats(*client, netstatsCounter); if (!compressed) { std::unique_lock l(mut); currentModelId = "dev"; currentModelVersion = -1; } else { std::unordered_map stateDict; rpc::Deserializer d(compressed->data(), compressed->size()); d.decompress(); rpc::Deserialize des(d); des(stateDict); onUpdateModel(modelId, stateDict); std::unique_lock l(mut); if (currentModelId != modelId) { currentModelId = *allModelIds.emplace(modelId).first; gamesDoneWithCurrentModel = 0; } currentModelVersion = modelVersion; fmt::printf("Got model '%s' version %d\n", modelId, modelVersion); bc.success(); } } double t = std::chrono::duration_cast< std::chrono::duration>>( std::chrono::steady_clock::now() - start) .count(); fmt::printf("State dict received and updated in %gms\n", t); } catch (const rpc::RPCException& e) { fmt::printf("RPC exception: %s\n", e.what()); } } public: std::function)> onUpdateModel; ClientImpl() { try { rdmaContext = rdma::create(); if (!rdmaContext) { fmt::printf("RDMA/IB is not supported\n"); } else { rdmaHost = rdmaContext->createHost(); fmt::printf("Using RDMA over IB for model transfers\n"); } } catch (const std::exception& e) { fmt::printf("RDMA error: %s\nRDMA/IB will not be used\n", e.what()); } } void requestModel(bool isTournamentOpponent) { try { std::unique_lock l(mut); if (!resultQueue.empty()) { client->async("gameResult", resultQueue); resultQueue.clear(); } // fmt::printf( // "Request model, isTournamentOpponent %d, wantsNewModelId // %d\n", isTournamentOpponent, wantsNewModelId); auto result = client->async>( "requestModel", isTournamentOpponent ? std::exchange(wantsNewModelId, false) : false, currentModelId); l.unlock(); if (rdmaEndpoint) { if (!client->sync("rdmaKeepalive", *rdmaEndpoint)) { rdmaEndpoint.reset(); rdmaHost.reset(); rdmaCq.reset(); } } auto [newId, version] = result.get(); addnetworkstats(*client, netstatsCounter); // fmt::printf("Got model '%s'\n", newId); l.lock(); auto now = std::chrono::steady_clock::now(); if (isTournamentOpponent && now - lastCheckTournamentResult >= std::chrono::minutes(2)) { lastCheckTournamentResult = now; wantsTournamentResult_ = now - lastTournamentResult >= std::chrono::minutes(5); if (!wantsTournamentResult_) { wantsNewModelId = true; } // fmt::printf("wantsTournamentResult_ is %d, wantsNewModelId is // %d\n", // wantsTournamentResult_, // wantsNewModelId); } else if (!isTournamentOpponent) { wantsTournamentResult_ = false; } if (currentModelId != newId || version != currentModelVersion) { l.unlock(); requestModelStateDict(newId, version); } else { l.unlock(); } } catch (const rpc::RPCException& e) { fmt::printf("RPC exception: %s\n", e.what()); } } void connect(std::string_view endpoint) { if (endpoint.substr(0, 6) == "tcp://") { endpoint.remove_prefix(6); } printf("actual connect endpoint is %s\n", std::string(endpoint).c_str()); client = getRpc().connect(endpoint); } void sendTrainData( const std::unordered_map& data) { try { std::unique_lock l(trainDataMut); std::future fut; if (trainDataFutures.size() >= 32) { fut = std::move(trainDataFutures.front()); trainDataFutures.erase(trainDataFutures.begin()); } l.unlock(); if (fut.valid()) { fut.get(); } } catch (const rpc::RPCException& e) { fmt::printf("RPC exception: %s\n", e.what()); } try { auto fut = client->async("trainData", data); std::lock_guard l(trainDataMut); trainDataFutures.push_back(std::move(fut)); } catch (const rpc::RPCException& e) { fmt::printf("RPC exception: %s\n", e.what()); } } void sendResult(float reward, std::unordered_map models) { std::unique_lock l(mut); auto i = models.find(currentModelId); if (i != models.end()) { if (i->second >= 0.9f) { ++gamesDoneWithCurrentModel; if (gamesDoneWithCurrentModel >= 20) { lastTournamentResult = std::chrono::steady_clock::now(); wantsNewModelId = true; } } } resultQueue.emplace_back(reward, std::move(models)); } bool wantsTournamentResult() const { std::unique_lock l(mut); return wantsTournamentResult_; } std::string_view getModelId() const { std::unique_lock l(mut); return currentModelId; } }; Server::Server() { impl = std::make_unique(); } Server::~Server() { } void Server::setOnTrainData( std::function)> onTrainData) { impl->onTrainData = std::move(onTrainData); } void Server::start(std::string endpoint) { impl->start(endpoint); } void Server::updateModel( const std::string& id, std::unordered_map stateDict) { impl->updateModel(id, std::move(stateDict)); } Client::Client() { impl = std::make_unique(); } Client::~Client() { } void Client::setOnUpdateModel( std::function)> onUpdateModel) { impl->onUpdateModel = std::move(onUpdateModel); } void Client::connect(std::string endpoint) { impl->connect(endpoint); } void Client::requestModel(bool isTournamentOpponent) { impl->requestModel(isTournamentOpponent); } void Client::sendTrainData( const std::unordered_map& data) { impl->sendTrainData(data); } bool Client::wantsTournamentResult() { return impl->wantsTournamentResult(); } std::string_view Client::getModelId() { return impl->getModelId(); } void Client::sendResult(float reward, std::unordered_map models) { impl->sendResult(reward, std::move(models)); } } // namespace distributed ================================================ FILE: src/distributed/distributed.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include #include #include #include namespace rpc { template void serialize(X& x, const std::pair& v) { x(v.first, v.second); } template void serialize(X& x, std::pair& v) { x(v.first, v.second); } template void serialize(X& x, const std::optional& v) { x(v.has_value()); if (v.has_value()) { x(v.value()); } } template void serialize(X& x, std::optional& v) { if (x.template read()) { v.emplace(); x(v.value()); } else { v.reset(); } } template void serialize(X& x, const std::vector& v) { x(v.size()); for (auto& v2 : v) { x(v2); } } template void serialize(X& x, std::vector& v) { size_t n = x.template read(); v.resize(n); for (size_t i = 0; i != n; ++i) { x(v[i]); } } template void serialize(X& x, const std::unordered_map& v) { x(v.size()); for (auto& v2 : v) { x(v2.first, v2.second); } } template void serialize(X& x, std::unordered_map& v) { v.clear(); size_t n = x.template read(); for (; n; --n) { auto k = x.template read(); v.emplace(std::move(k), x.template read()); } } template void serialize(X& x, const torch::Tensor& v) { if (!v.is_contiguous()) { serialize(x, v.contiguous()); return; } x(v.scalar_type(), std::basic_string_view(v.sizes().data(), v.sizes().size())); void* data = v.data_ptr(); size_t size = v.numel() * v.dtype().itemsize(); x(std::string_view((const char*)data, size)); } template void serialize(X& x, torch::Tensor& v) { torch::ScalarType dtype; std::basic_string_view sizes; x(dtype, sizes); if (v.defined() && v.scalar_type() == dtype) { v.resize_(torch::IntArrayRef(sizes.begin(), sizes.end())); } else { v = torch::empty(torch::IntArrayRef(sizes.begin(), sizes.end()), dtype); } std::string_view data; x(data); if ((size_t)v.numel() != data.size() / v.dtype().itemsize()) { throw std::runtime_error("numel mismatch in tensor deserialize"); } std::memcpy(v.data_ptr(), data.data(), data.size()); } } // namespace rpc namespace distributed { class ServerImpl; class ClientImpl; class Server { std::unique_ptr impl; public: Server(); ~Server(); void setOnTrainData( std::function< void(const std::unordered_map)>); void start(std::string endpoint); void updateModel(const std::string& id, std::unordered_map stateDict); }; class Client { std::unique_ptr impl; public: Client(); ~Client(); void setOnUpdateModel( std::function)>); void connect(std::string endpoint); void requestModel(bool isTournamentOpponent); void sendTrainData( const std::unordered_map& data); bool wantsTournamentResult(); std::string_view getModelId(); void sendResult(float reward, std::unordered_map models); }; } // namespace distributed ================================================ FILE: src/distributed/ib.cc ================================================ #include "rdma.h" #include #include #include #include #include #include #include #include #include namespace ib { struct Device { std::string name; ibv_device* info; }; struct DeviceList { std::vector list; ibv_device** rawlist = nullptr; DeviceList() { int num = 0; rawlist = ibv_get_device_list(&num); for (int i = 0; i < num; ++i) { Device d; d.name = rawlist[i]->name; d.info = rawlist[i]; list.push_back(d); } } ~DeviceList() { if (rawlist) { ibv_free_device_list(rawlist); } } size_t size() const { return list.size(); } auto begin() const { return list.begin(); } auto end() const { return list.end(); } bool empty() const { return list.empty(); } decltype(auto) operator[](size_t index) const { return list[index]; } }; class Error : public rdma::Error { public: using rdma::Error::Error; }; std::string gidstr(std::array gid) { std::string s; for (auto& v : gid) { s += "0123456789abcdef"[unsigned(v) >> 4]; s += "0123456789abcdef"[unsigned(v) & 0xf]; } return s; } struct Port { ibv_context* context = nullptr; int num = 0; ibv_port_attr attr; uint32_t lid() { return attr.lid; } std::array gid() { std::array gid; static_assert(sizeof(gid) == sizeof(ibv_gid)); if (ibv_query_gid(context, num, 0, (ibv_gid*)&gid)) { throw Error("ibv_query_gid failed"); } return gid; } }; struct NoMove { NoMove() = default; NoMove(const NoMove&) = delete; NoMove(NoMove&&) = delete; NoMove& operator=(const NoMove&) = delete; NoMove& operator=(NoMove&&) = delete; }; struct Context : NoMove { ibv_context* context = nullptr; ibv_device_attr devattr; std::vector ports; Context(const Device& dev) { context = ibv_open_device(dev.info); if (!context) { throw Error("Failed to open device " + dev.name); } memset(&devattr, 0, sizeof(devattr)); ibv_query_device(context, &devattr); for (int i = 1; i <= devattr.phys_port_cnt; ++i) { ports.emplace_back(); ports.back().context = context; ports.back().num = i; auto& attr = ports.back().attr; memset(&attr, 0, sizeof(attr)); ibv_query_port(context, i, &attr); } } ~Context() { if (context) { ibv_close_device(context); context = nullptr; } } }; struct ProtectionDomain : NoMove { ibv_pd* pd = nullptr; ProtectionDomain(Context& ctx) { pd = ibv_alloc_pd(ctx.context); if (!pd) { throw Error("Failed to allocate protection domain"); } } ~ProtectionDomain() { if (pd) { ibv_dealloc_pd(pd); pd = nullptr; } } }; struct MemoryRegion : NoMove { ibv_mr* mr = nullptr; MemoryRegion(const ProtectionDomain& pd, void* address, size_t size, int access) { mr = ibv_reg_mr(pd.pd, address, size, access); if (!mr) { throw Error("Failed to register memory region"); } } ~MemoryRegion() { if (mr) { ibv_dereg_mr(mr); mr = nullptr; } } auto lkey() { return mr->lkey; } auto rkey() { return mr->rkey; } }; struct CompletionQueue : NoMove { ibv_cq* cq = nullptr; CompletionQueue(const Context& ctx, int size) { cq = ibv_create_cq(ctx.context, size, nullptr, nullptr, 0); if (!cq) { throw Error("Failed to create completion queue"); } } ~CompletionQueue() { if (cq) { int e = ibv_destroy_cq(cq); if (e) { throw std::runtime_error("ibv_destroy_cq failed with error " + std::to_string(e)); } cq = nullptr; } } void wait() { ibv_wc wc; auto start = std::chrono::steady_clock::now(); while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (std::chrono::steady_clock::now() - start >= std::chrono::seconds(10)) { throw Error("wait timed out"); } int r = ibv_poll_cq(cq, 1, &wc); if (r > 0) { if (wc.status != IBV_WC_SUCCESS) { throw Error(ibv_wc_status_str(wc.status)); } return; } else if (r < 0) { throw Error("Failed to poll the completion queue"); } } } }; struct QueuePair : NoMove { ibv_qp* qp = nullptr; QueuePair(const ProtectionDomain& pd, const CompletionQueue& cq) { ibv_qp_init_attr init; memset(&init, 0, sizeof(init)); init.send_cq = cq.cq; init.recv_cq = cq.cq; init.qp_type = IBV_QPT_RC; init.cap.max_send_wr = 2; init.cap.max_recv_wr = 2; init.cap.max_send_sge = 1; init.cap.max_recv_sge = 1; qp = ibv_create_qp(pd.pd, &init); if (!qp) { throw Error("Failed to create queue pair"); } } ~QueuePair() { if (qp) { ibv_destroy_qp(qp); } } uint32_t num() { return qp->qp_num; } void init(const Port& port, int accessFlags) { ibv_qp_attr attr; memset(&attr, 0, sizeof(attr)); attr.qp_state = IBV_QPS_INIT; attr.pkey_index = 0; attr.port_num = port.num; attr.qp_access_flags = accessFlags; int err = ibv_modify_qp( qp, &attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS); if (err) { throw Error("Failed to move queue pair to init state; error " + std::to_string(err)); } } void rtr(const Port& port, uint16_t remoteLid, uint32_t remoteQPNum, const std::array& gid) { ibv_qp_attr attr; memset(&attr, 0, sizeof(attr)); attr.qp_state = IBV_QPS_RTR; attr.path_mtu = port.attr.active_mtu; attr.dest_qp_num = remoteQPNum; attr.rq_psn = 4242; attr.max_dest_rd_atomic = 1; attr.min_rnr_timer = 12; attr.ah_attr.is_global = 0; attr.ah_attr.dlid = remoteLid; attr.ah_attr.sl = 0; attr.ah_attr.src_path_bits = 0; attr.ah_attr.port_num = port.num; attr.ah_attr.is_global = 1; attr.ah_attr.grh.hop_limit = 4; attr.ah_attr.grh.dgid = (ibv_gid&)gid; attr.ah_attr.grh.sgid_index = 0; int err = ibv_modify_qp( qp, &attr, IBV_QP_STATE | IBV_QP_AV | IBV_QP_PATH_MTU | IBV_QP_DEST_QPN | IBV_QP_RQ_PSN | IBV_QP_MAX_DEST_RD_ATOMIC | IBV_QP_MIN_RNR_TIMER); if (err) { throw Error("Failed to move queue pair to rtr state; error " + std::to_string(err)); } } void rts() { ibv_qp_attr attr; memset(&attr, 0, sizeof(attr)); attr.qp_state = IBV_QPS_RTS; attr.sq_psn = 4242; attr.timeout = 17; // 0.5s attr.retry_cnt = 7; attr.rnr_retry = 7; attr.max_rd_atomic = 1; int err = ibv_modify_qp(qp, &attr, IBV_QP_STATE | IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT | IBV_QP_RNR_RETRY | IBV_QP_SQ_PSN | IBV_QP_MAX_QP_RD_ATOMIC); if (err) { throw Error("Failed to move queue pair to rts state; error " + std::to_string(err)); } } void read(MemoryRegion& dstmr, void* dstbuf, uint32_t rkey, uintptr_t remoteAddress, size_t length) { ibv_sge sg; ibv_send_wr wr; ibv_send_wr* bad_wr; memset(&sg, 0, sizeof(sg)); sg.addr = (uintptr_t)dstbuf; sg.length = length; sg.lkey = dstmr.lkey(); memset(&wr, 0, sizeof(wr)); wr.wr_id = 0; wr.sg_list = &sg; wr.num_sge = 1; wr.opcode = IBV_WR_RDMA_READ; wr.send_flags = IBV_SEND_SIGNALED; wr.wr.rdma.remote_addr = remoteAddress; wr.wr.rdma.rkey = rkey; ibv_qp_attr qattr; ibv_qp_init_attr qiattr; if (ibv_query_qp(qp, &qattr, IBV_QP_STATE, &qiattr)) { throw Error("Failed to query qp"); } int err = ibv_post_send(qp, &wr, &bad_wr); if (err) { throw Error("RDMA read failed; error " + std::to_string(err)); } } }; } // namespace ib namespace rdma { struct ibBuffer : Buffer { std::optional mr; virtual ~ibBuffer() override { } virtual uint32_t key() override { return mr->rkey(); } virtual uint32_t keyFor(Endpoint ep) override { return mr->rkey(); } }; struct ibCompletionQueue : CompletionQueue { ib::CompletionQueue cq; virtual ~ibCompletionQueue() { } ibCompletionQueue(ib::Context& ctx, int size) : cq(ctx, size) { } virtual void wait() override { cq.wait(); } }; struct ibMultiBuffer : Buffer { std::deque mrs; std::vector lids; virtual ~ibMultiBuffer() override { } virtual uint32_t key() override { std::abort(); } ib::MemoryRegion& mrFor(Endpoint ep) { for (size_t i = 0; i != lids.size(); ++i) { if (lids[i] == ep.lid) { return mrs.at(i); } } throw Error("Endpoint not found for multibuffer"); } virtual uint32_t keyFor(Endpoint ep) override { return mrFor(ep).rkey(); } }; struct ibHost : Host { ib::Context* context = nullptr; ib::ProtectionDomain* pd = nullptr; std::optional port; ib::CompletionQueue* cq = nullptr; std::optional qp; bool inRts = false; virtual ~ibHost() override { } ibHost(ib::Context* context, ib::ProtectionDomain* pd) : context(context) , pd(pd) { if (context->ports.empty()) { throw ib::Error("Infiniband device has no ports!"); } port = context->ports.at(0); // printf("Host using %d:%d\n", port->lid(), port->num); } virtual Endpoint init(CompletionQueue& cqa) override { cq = &((ibCompletionQueue&)cqa).cq; qp.emplace(*pd, *cq); qp->init(*port, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ); inRts = false; // printf("QP %d:%d\n", port->lid(), qp->num()); return {port->lid(), qp->num(), port->gid()}; } virtual void connect(Endpoint ep) override { qp->rtr(*port, ep.lid, ep.qpnum, ep.gid); inRts = false; } virtual void read(Buffer& localBuffer, void* localAddress, uint32_t remoteKey, uintptr_t remoteAddress, size_t size) override { if (!inRts) { qp->rts(); inRts = true; } if (auto buf = dynamic_cast(&localBuffer)) { qp->read(*buf->mr, localAddress, remoteKey, remoteAddress, size); } else if (auto buf = dynamic_cast(&localBuffer)) { qp->read(buf->mrFor(Endpoint{port->lid(), qp->num(), port->gid()}), localAddress, remoteKey, remoteAddress, size); } } virtual void wait() override { cq->wait(); } }; struct ibContext : Context { ib::Device device; std::optional context; std::optional pd; ibContext(ib::Device device) : device(device) { context.emplace(device); pd.emplace(*context); } virtual ~ibContext() override { } virtual std::unique_ptr createHost() override { return std::make_unique(&*context, &*pd); } virtual std::unique_ptr createBuffer(void* address, size_t size) override { auto r = std::make_unique(); r->mr.emplace( *pd, address, size, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ); return r; } virtual std::unique_ptr createCQ(int size) override { return std::make_unique(*context, size); } }; struct ibMultiCompletionQueue : CompletionQueue { std::vector> cqs; virtual ~ibMultiCompletionQueue() override { } virtual void wait() override { std::abort(); } }; struct ibMultiHost : ibHost { size_t index; ibMultiHost(size_t index, ib::Context* context, ib::ProtectionDomain* pd) : ibHost(context, pd) , index(index) { } virtual ~ibMultiHost() override { } virtual Endpoint init(CompletionQueue& cqa) override { auto cq = (ibMultiCompletionQueue&)cqa; return ibHost::init(*cq.cqs.at(index)); } }; struct ibMultiContext : Context { ib::DeviceList devlist; std::deque contexts; std::minstd_rand rng; ibMultiContext() { if (devlist.empty()) { throw ib::Error("No infiniband devices found"); } rng.seed(std::random_device{}()); for (auto& v : devlist) { contexts.emplace_back(v); } } virtual ~ibMultiContext() override { } virtual std::unique_ptr createHost() override { size_t index = std::uniform_int_distribution(0, contexts.size() - 1)(rng); auto& ctx = contexts[index]; return std::make_unique(index, &*ctx.context, &*ctx.pd); } virtual std::unique_ptr createBuffer(void* address, size_t size) override { auto r = std::make_unique(); for (auto& ctx : contexts) { r->mrs.emplace_back(*ctx.pd, address, size, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ); r->lids.push_back(ctx.context->ports.at(0).lid()); } return r; } virtual std::unique_ptr createCQ(int size) override { auto r = std::make_unique(); for (auto& ctx : contexts) { r->cqs.push_back(std::make_unique(*ctx.context, size)); } return r; } }; std::unique_ptr create() { return std::make_unique(); } } // namespace rdma ================================================ FILE: src/distributed/network.cc ================================================ #include "network.h" #include "asio.hpp" #include #include #include namespace network { template struct Handle { T* obj = nullptr; Handle() { } Handle(T& obj) : obj(&obj) { ++obj.refcount; } Handle(std::nullptr_t) { } Handle(Handle&& n) { obj = std::exchange(n.obj, nullptr); } Handle(const Handle& n) { acquire(n.obj); } Handle& operator=(Handle&& n) { std::swap(obj, n.obj); return *this; } Handle& operator=(const Handle& n) { acquire(n.obj); return *this; } void acquire(T* newobj) { release(); obj = newobj; if (obj) ++obj->refcount; } void release() { if (obj) { if (--obj->refcount == 0) { obj->owner->free(obj); } obj = nullptr; } } ~Handle() { release(); } T& operator*() const { return *obj; } T* operator->() const { return obj; } explicit operator bool() const { return obj; } }; template struct Ref { std::atomic_int refcount = 0; Handle ref() { return *(T*)this; } }; template struct Cache { struct entry { entry* freenext = nullptr; Cache* owner = nullptr; std::aligned_storage_t buf; entry* storagenext = nullptr; }; std::atomic storagelist; std::atomic freelist; static entry* get(T* ptr) { uintptr_t v = (uintptr_t)(void*)ptr; v -= offsetof(entry, buf); return (entry*)v; } template T* allocate(A&&... args) { T* r; entry* e = freelist; while (e && !freelist.compare_exchange_weak(e, e->freenext)) ; if (!e) { e = new entry(); entry* s = storagelist; do { e->storagenext = s; } while (!storagelist.compare_exchange_weak(s, e)); } r = (T*)&e->buf; new (r) T(std::forward(args)...); e->owner = this; return r; } void free(T* obj) { entry* e = get(obj); if (e->owner != this) { std::terminate(); } e->owner = nullptr; obj->~T(); entry* f = freelist; do { e->freenext = f; } while (!freelist.compare_exchange_weak(f, e)); } ~Cache() { for (entry* e = storagelist; e; e = e->storagenext) { if (e->owner) { ((T&)e->buf).~T(); } } } template Handle make(A&&... args) { return (allocate(this, std::forward(args)...))->ref(); } }; template struct Wrapper : Ref> { Cache>* owner = nullptr; T obj; template Wrapper(Cache>* owner, A&&... args) : owner(owner) , obj(std::forward(args)...) { } T* operator->() { return &obj; } T& operator*() { return obj; } }; template struct Buffer : Ref> { Cache* owner = nullptr; std::array buf; size_t begin = 0; size_t end = 0; Buffer(Cache* owner) : owner(owner) { } size_t space() { return buf.size() - end; } size_t append(const void* data, size_t n) { n = std::min(n, space()); std::memcpy(buf.data() + end, data, n); end += n; return n; } void free(size_t n) { begin += n; } const void* data() const { return buf.data() + begin; } size_t size() const { return end - begin; } bool empty() const { return size() == 0; } }; std::pair decodeEndpoint(std::string_view endpoint) { std::string_view hostname = endpoint; int port = 0; auto bpos = endpoint.find('['); if (bpos != std::string_view::npos) { auto bepos = endpoint.find(']', bpos); if (bepos != std::string_view::npos) { hostname = endpoint.substr(bpos + 1, bepos - (bpos + 1)); endpoint = endpoint.substr(bepos + 1); } } auto cpos = endpoint.find(':'); if (cpos != std::string_view::npos) { if (hostname == endpoint) hostname = endpoint.substr(0, cpos); ++cpos; while (cpos != endpoint.size()) { char c = endpoint[cpos]; if (c < '0' || c > '9') break; port *= 10; port += c - '0'; ++cpos; } } return {hostname, port}; } class PeerImpl : public Ref { public: Cache* owner = nullptr; asio::io_context& context; Cache> resolverCache; Cache> timerCache; Cache> socketCache; Cache> bufferCache; asio::ip::tcp::socket socket; std::string connectEndpoint; std::string remoteHost; int remotePort = 0; bool connected = false; bool closed = false; std::vector readBuffer; Handle> writeBuffer; std::vector>> writeBufferQueue; std::mutex mutex; PeerImpl(Cache* owner, asio::io_context& context) : owner(owner) , context(context) , socket(context) { } void connect(std::string_view endpoint) { auto l = lock(); if (connected) return; if (endpoint.empty()) return; if (connectEndpoint != endpoint) connectEndpoint = endpoint; auto [hostname, port] = decodeEndpoint(endpoint); remoteHost = hostname; remotePort = port; asio::error_code ec; asio::ip::address address = asio::ip::make_address(hostname, ec); if (ec) { auto resolver = resolverCache.make(context); (*resolver)->async_resolve( remoteHost, "", [this, str = std::string(remoteHost), peer = ref(), resolver, port = port](const asio::error_code& ec, asio::ip::tcp::resolver::results_type results) mutable { if (!ec) { int n = 0; for (auto ep : results) { auto timer = timerCache.make(context); (*timer)->expires_from_now(std::chrono::seconds(n)); (*timer)->async_wait( [ep, timer, peer, port](const asio::error_code& ec) { if (!ec) { peer->connect( {ep.endpoint().address(), (unsigned short)port}); } }); ++n; } } else { printf("resolve(%s): %s\n", str.c_str(), ec.message().c_str()); } }); } else { connect({address, (unsigned short)port}); } auto timer = timerCache.make(context); (*timer)->expires_from_now(std::chrono::seconds(30)); (*timer)->async_wait( [this, timer, peer = ref()](const asio::error_code& ec) { if (!ec) { connect(connectEndpoint); } }); } void asyncRead(size_t offset = 0) { socket.async_receive( asio::buffer(readBuffer.data() + offset, readBuffer.size() - offset), [this, peer = ref()](auto&&... args) mutable { onReceive(std::forward(args)...); }); } void setConnected(asio::ip::tcp::socket sock) { if (connected) return; if (closed) { sock.close(); return; } connected = true; socket = std::move(sock); if (onReceiveCallback || onMessageCallback) asyncRead(); flush(); } void connect(asio::ip::tcp::endpoint ep) { if (connected || closed) return; auto h = socketCache.make(context); (*h)->async_connect( ep, [this, ep, h, peer = ref()](const asio::error_code& ec) { auto l = lock(); if (!ec && !connected) { setConnected(std::move(**h)); } else if (ec) { printf("connect(%s:%d): %s\n", ep.address().to_string().c_str(), (int)ep.port(), ec.message().c_str()); } }); } void failure() { auto l = lock(); if (!connected) return; connected = false; socket.close(); writeBuffer = nullptr; CallbackCounter cc(activeCallbacks); l.unlock(); if (onConnectionClosed) { onConnectionClosed(); } auto timer = timerCache.make(context); (*timer)->expires_from_now(std::chrono::seconds(5)); (*timer)->async_wait( [this, timer, peer = ref()](const asio::error_code& ec) { if (!ec) { connect(connectEndpoint); } }); } std::atomic sending = false; std::vector sendBuffer; void callSend(std::vector buffer, size_t offset) { auto ab = asio::buffer(buffer.data() + offset, buffer.size() - offset); socket.async_send( ab, [this, peer = ref(), buffer = std::move(buffer), offset]( const asio::error_code& ec, size_t n) mutable { if (ec) { sending = false; failure(); } else { size_t remaining = buffer.size() - offset - n; if (remaining) { auto l = lock(); callSend(std::move(buffer), offset + n); } else { sending = false; auto l = lock(); flush(); } } }); } void flush() { if (!connected) return; if (!sendBuffer.empty()) { if (sending.exchange(true)) return; callSend(std::move(sendBuffer), 0); sendBuffer.clear(); } } void sendNoFlush(const void* data, size_t n) { size_t offset = sendBuffer.size(); if (offset + n > sendBuffer.capacity()) { sendBuffer.reserve(std::max(offset + n, offset * 2)); } sendBuffer.resize(offset + n); std::memcpy(sendBuffer.data() + offset, data, n); } // std::vector sendBuffers; // // void flush() { // if (!connected) return; // if (sending) return; // sendBuffers.clear(); // if (!writeBufferQueue.empty()) { // for (auto& v : writeBufferQueue) { // sendBuffers.push_back(asio::buffer(v->data(), v->size())); // } // writeBufferQueue.clear(); // } // size_t freeN = 0; // if (writeBuffer && !writeBuffer->empty()) { // sendBuffers.push_back(asio::buffer(writeBuffer->data(), // writeBuffer->size())); freeN = writeBuffer->size(); // } // if (!sendBuffers.empty()) { // sending = true; // socket.async_send(sendBuffers, [this, freeSrc = writeBuffer->ref(), // freeN, peer = ref()](const asio::error_code& ec, size_t n) { // sending = false; // freeSrc->free(freeN); // if (ec) { // failure(); // } else { // flush(); // } // }); // } // } // void sendNoFlush(const void* data, size_t n) { // if (!writeBuffer || writeBuffer->space() == 0) { // writeBuffer = bufferCache.make(); // } // size_t s = writeBuffer->append(data, n); // while (writeBuffer->space() == 0) { // writeBufferQueue.push_back(writeBuffer); // writeBuffer = bufferCache.make(); // data = (const char*)data + s; // n -= s; // s = writeBuffer->append(data, n); // } // } void send(const void* data, size_t n) { auto l = lock(); sendNoFlush(data, n); if (!sending) { flush(); } } void sendMessage(const void* data, size_t n) { auto l = lock(); uint32_t len = n; sendNoFlush(&len, sizeof(len)); sendNoFlush(data, n); flush(); } struct CallbackCounter { std::atomic_int& c; CallbackCounter(std::atomic_int& c) : c(c) { ++c; } ~CallbackCounter() { --c; } }; std::atomic_int activeCallbacks; std::function onConnectionClosed; std::function onReceiveCallback; std::function onMessageCallback; void setOnReceive(std::function callback, size_t bufferSize = 0x10000) { auto l = lock(); if (!onReceiveCallback && connected) { asyncRead(); } readBuffer.resize(bufferSize); onReceiveCallback = std::move(callback); } int messageState = -1; size_t messageReceived = 0; size_t messageLength = 0; void setOnMessage(std::function callback, size_t bufferSize = 0x10000) { auto l = lock(); if (!onMessageCallback && callback) { if (connected) { asyncRead(); } readBuffer.resize(bufferSize); messageState = 0; } if (!callback) { messageState = -1; } onMessageCallback = std::move(callback); } void onReceive(const asio::error_code& ec, size_t n) { auto l = lock(); if (closed) { return; } CallbackCounter cc(activeCallbacks); if (!ec) { while (true) { if (messageState == 0) { messageReceived += n; n = 0; if (messageReceived >= 4) { messageLength = *(uint32_t*)readBuffer.data(); readBuffer.resize(std::max(readBuffer.size(), 4 + messageLength)); messageState = 1; continue; } else { asyncRead(messageReceived); } } else if (messageState == 1) { messageReceived += n; n = 0; if (messageReceived >= 4 + messageLength) { std::vector tmp( readBuffer.data() + 4, readBuffer.data() + 4 + messageLength); if (messageReceived == 4 + messageLength) { messageState = 0; messageReceived = 0; asyncRead(messageReceived); l.unlock(); } else { std::memmove(readBuffer.data(), readBuffer.data() + 4 + messageLength, messageReceived - (4 + messageLength)); messageReceived -= 4 + messageLength; messageState = 0; l.unlock(); context.post([this]() { onReceive({}, 0); }); } onMessageCallback(tmp.data(), tmp.size()); break; } else { if (readBuffer.size() - messageReceived == 0) { readBuffer.resize(readBuffer.size() * 2); } } asyncRead(messageReceived); } else if (onReceiveCallback) { asyncRead(); if (n) { l.unlock(); onReceiveCallback(readBuffer.data(), n); } } break; } } else { l.unlock(); failure(); } } std::unique_lock lock() { return std::unique_lock(mutex); } void close() { auto l = lock(); if (connected) { connected = false; socket.close(); writeBuffer = nullptr; } messageState = -1; closed = true; l.unlock(); while (activeCallbacks) { std::this_thread::yield(); } } void post_close() { context.post([peer = ref()] { peer->close(); }); } void setOnConnectionClosed(std::function callback) { onConnectionClosed = std::move(callback); } }; class ServerImpl : public Ref { public: Cache* owner = nullptr; asio::io_context& context; Cache> resolverCache; Cache> timerCache; Cache> acceptorCache; Cache> socketCache; Cache peerCache; std::string listenEndpoint; std::function peer)> onPeer; bool bound = false; std::vector>> sockets; std::mutex mutex; ServerImpl(Cache* owner, asio::io_context& context) : owner(owner) , context(context) { } ~ServerImpl() { close(); } void asyncAccept(Handle> h, Handle> socket) { (*h)->async_accept(**socket, [this, server = ref(), h, socket](const asio::error_code& ec) { if (!ec) { if (onPeer) { auto peer = peerCache.make(context); peer->setConnected(std::move(**socket)); onPeer(peer); } } asyncAccept(h, socket); }); } void bind(asio::ip::tcp::endpoint ep) { auto retry = [&](asio::error_code ec) { printf("bind(%s:%d): %s\n", ep.address().to_string().c_str(), (int)ep.port(), ec.message().c_str()); auto timer = timerCache.make(context); (*timer)->expires_from_now(std::chrono::seconds(30)); (*timer)->async_wait( [this, ep, timer, server = ref()](const asio::error_code& ec) { if (!ec) { bind(ep); } }); }; auto h = acceptorCache.make(context); asio::error_code ec; (*h)->open(ep.protocol()); (*h)->set_option(asio::socket_base::reuse_address(true)); (*h)->bind(ep, ec); if (ec) return retry(ec); (*h)->listen(asio::socket_base::max_connections, ec); if (ec) return retry(ec); auto socket = socketCache.make(context); asyncAccept(h, socket); auto l = lock(); sockets.push_back(socket); } void bind(std::string_view endpoint) { if (endpoint.empty()) { return; } bound = true; auto [hostname, port] = decodeEndpoint(endpoint); asio::error_code ec; asio::ip::address address; if (hostname != "*") { address = asio::ip::make_address(hostname, ec); } if (ec) { auto resolver = resolverCache.make(context); (*resolver)->async_resolve( hostname, "", [this, peer = ref(), resolver, port = port]( const asio::error_code& ec, asio::ip::tcp::resolver::results_type results) mutable { if (!ec) { for (auto ep : results) { bind({ep.endpoint().address(), (unsigned short)port}); } } else { auto timer = timerCache.make(context); (*timer)->expires_from_now(std::chrono::seconds(30)); (*timer)->async_wait( [this, timer, peer = ref()](const asio::error_code& ec) { if (!ec) { auto l = lock(); bind(listenEndpoint); } }); } }); } else { context.post([this, address, port = port, server = ref()] { bind({address, (unsigned short)port}); }); } } void listen(std::string_view endpoint) { auto l = lock(); listenEndpoint = endpoint; if (onPeer) bind(endpoint); } void setOnPeer(std::function)> callback) { auto l = lock(); onPeer = callback; if (!bound) bind(listenEndpoint); } std::unique_lock lock() { return std::unique_lock(mutex); } void close() { auto l = lock(); onPeer = nullptr; for (auto& v : sockets) { (*v)->close(); } sockets.clear(); } }; class NetworkImpl { public: Cache peerCache; Cache serverCache; asio::io_context context; asio::executor_work_guard work{ context.get_executor()}; ~NetworkImpl() { work.reset(); } Handle connect(std::string_view endpoint) { auto h = peerCache.make(context); h->connect(endpoint); return h; } Handle listen(std::string_view endpoint) { auto h = serverCache.make(context); h->listen(endpoint); return h; } template static std::unique_ptr> wrap(Handle h) { auto* ptr = &*h; return std::unique_ptr>( ptr, [h = std::move(h)](T* ptr) mutable { h = nullptr; }); } bool run_one() { return context.run_one() != 0; } void post(std::function f) { asio::post(std::move(f)); } }; Peer::Peer(std::unique_ptr> impl) : impl(std::move(impl)) { } Peer::~Peer() { } void Peer::send(const void* data, size_t n) { return impl->send(data, n); } void Peer::send(std::string_view buf) { return send(buf.data(), buf.size()); } void Peer::setOnReceive(std::function callback) { return impl->setOnReceive(std::move(callback)); } void Peer::setOnReceive(std::function callback) { setOnReceive([callback = std::move(callback)](const void* data, size_t n) { return callback(std::string_view((const char*)data, n)); }); } void Peer::sendMessage(const void* data, size_t n) { return impl->sendMessage(data, n); } void Peer::sendMessage(std::string_view buf) { return sendMessage(buf.data(), buf.size()); } void Peer::setOnMessage(std::function callback) { return impl->setOnMessage(std::move(callback)); } void Peer::setOnMessage(std::function callback) { if (!callback) setOnMessage(nullptr); else setOnMessage([callback = std::move(callback)](const void* data, size_t n) { return callback(std::string_view((const char*)data, n)); }); } void Peer::setOnMessage(std::nullptr_t) { impl->setOnMessage(nullptr); } void Peer::setOnConnectionClosed(std::function callback) { impl->setOnConnectionClosed(std::move(callback)); } bool Peer::connected() const { return impl->connected; } void Peer::close() { impl->close(); } void Peer::post_close() { impl->post_close(); } std::unique_lock Peer::lock() { return impl->lock(); } Server::Server( std::unique_ptr> impl) : impl(std::move(impl)) { } Server::~Server() { } void Server::setOnPeer(std::function callback) { impl->setOnPeer([callback = std::move(callback)](Handle peer) { callback(NetworkImpl::wrap(peer)); }); } void Server::close() { impl->close(); } std::unique_lock Server::lock() { return impl->lock(); } void Server::listen(std::string_view endpoint) { return impl->listen(endpoint); } Network::Network() { impl = std::make_unique(); } Network::Network( std::unique_ptr> impl) : impl(std::move(impl)) { } Network::~Network() { } Peer Network::connect(std::string_view endpoint) { return impl->wrap(impl->connect(endpoint)); } Server Network::listen(std::string_view endpoint) { return impl->wrap(impl->listen(endpoint)); } bool Network::run_one() { return impl->run_one(); } void Network::post(std::function f) { return impl->post(std::move(f)); } } // namespace network ================================================ FILE: src/distributed/network.h ================================================ #pragma once #include #include #include #include namespace network { class PeerImpl; class ServerImpl; class NetworkImpl; class Peer { public: Peer() = default; Peer(Peer&&) = default; Peer(std::unique_ptr> impl); ~Peer(); Peer& operator=(Peer&&) = default; void send(const void* data, size_t n); void send(std::string_view buf); void setOnReceive(std::function callback); void setOnReceive(std::function callback); void sendMessage(const void* data, size_t n); void sendMessage(std::string_view buf); void setOnMessage(std::function callback); void setOnMessage(std::function callback); void setOnMessage(std::nullptr_t); void setOnConnectionClosed(std::function callback); explicit operator bool() const { return impl != nullptr; } bool connected() const; void close(); void post_close(); std::unique_lock lock(); private: std::unique_ptr> impl; }; class Server { public: Server() = default; Server(Server&&) = default; Server(std::unique_ptr> impl); ~Server(); Server& operator=(Server&&) = default; void setOnPeer(std::function callback); void close(); std::unique_lock lock(); void listen(std::string_view endpoint); private: std::unique_ptr> impl; }; class Network { public: Network(); Network(Network&&) = default; Network(std::unique_ptr> impl); ~Network(); Peer connect(std::string_view endpoint); Server listen(std::string_view endpoint); bool run_one(); void post(std::function f); private: std::unique_ptr> impl; }; } // namespace network ================================================ FILE: src/distributed/rdma.h ================================================ #pragma once #include #include #include #include #include namespace rdma { class Error : public std::runtime_error { using std::runtime_error::runtime_error; }; struct Endpoint { uint32_t lid; uint32_t qpnum; std::array gid; bool operator==(const Endpoint& n) { return lid == n.lid && qpnum == n.qpnum; } bool operator!=(const Endpoint& n) { return !(*this == n); } }; struct Buffer { virtual ~Buffer() { } virtual uint32_t key() = 0; virtual uint32_t keyFor(Endpoint ep) = 0; }; struct CompletionQueue { virtual ~CompletionQueue() { } virtual void wait() = 0; }; struct Host { virtual ~Host() { } virtual Endpoint init(CompletionQueue& cq) = 0; virtual void connect(Endpoint ep) = 0; virtual void read(Buffer& localBuffer, void* localAddress, uint32_t remoteKey, uintptr_t remoteAddress, size_t size) = 0; virtual void wait() = 0; }; struct Context { virtual ~Context() { } virtual std::unique_ptr createHost() = 0; virtual std::unique_ptr createBuffer(void* address, size_t size) = 0; virtual std::unique_ptr createCQ(int size) = 0; }; std::unique_ptr create(); } // namespace rdma ================================================ FILE: src/distributed/rdma_nop.cc ================================================ #include "rdma.h" namespace rdma { std::unique_ptr create() { return nullptr; } } // namespace rdma ================================================ FILE: src/distributed/rpc.h ================================================ #define ZSTD_STATIC_LINKING_ONLY #include "zstd/lib/zstd.h" #include "network.h" #include "string_view" #include #include #include #include #include #include #include #include #include namespace rpc { // This is not a cross platform serializer struct Serializer { std::vector buf; void write(const void* data, size_t len) { size_t offset = buf.size(); if (buf.capacity() < offset + len) { buf.reserve( std::max(offset + len, std::max(buf.capacity() * 2, (size_t)16))); } buf.resize(offset + len); std::memcpy(buf.data() + offset, data, len); } template >* = nullptr> void write(T v) { write((void*)&v, sizeof(v)); } void write(std::string_view str) { write(str.size()); write(str.data(), str.size()); } template void write(std::basic_string_view str) { write(str.size()); write(str.data(), sizeof(T) * str.size()); } void clear() { buf.clear(); } const char* data() const { return buf.data(); } size_t size() const { return buf.size(); } void compress(int level = 0) { std::vector newbuf; newbuf.resize(sizeof(size_t) + ZSTD_compressBound(buf.size())); auto n = ZSTD_compress(newbuf.data() + sizeof(size_t), newbuf.size() - sizeof(size_t), buf.data(), buf.size(), level); if (!ZSTD_isError(n)) { size_t sn = buf.size(); std::memcpy(newbuf.data(), &sn, sizeof(sn)); newbuf.resize(sizeof(size_t) + n); std::swap(buf, newbuf); } else { buf.clear(); } } }; struct Deserializer { std::string_view buf; std::vector ownbuf; Deserializer() = default; Deserializer(std::string_view buf) : buf(buf) { } Deserializer(const void* data, size_t len) : buf((const char*)data, len) { } void consume(size_t len) { buf = {buf.data() + len, buf.size() - len}; } template std::basic_string_view readStringView() { size_t len = read(); if (buf.size() < sizeof(T) * len) { len = buf.size() / sizeof(T); } T* data = (T*)buf.data(); consume(sizeof(T) * len); return {data, len}; } std::string_view readString() { size_t len = read(); if (buf.size() < len) { len = buf.size(); } const char* data = buf.data(); consume(len); return {data, len}; } template >* = nullptr> void read(T& r) { if (buf.size() < sizeof(T)) { consume(buf.size()); r = {}; return; } std::memcpy(&r, buf.data(), sizeof(T)); consume(sizeof(T)); } void read(std::string_view& r) { r = readString(); } void read(std::string& r) { r = readString(); } template void read(std::basic_string_view& r) { r = readStringView(); } template T read() { T r; read(r); return r; } std::string_view read() { return readString(); } bool empty() { return buf.empty(); } void decompress() { size_t sn = read(); std::vector newbuf; newbuf.resize(sn); auto n = ZSTD_decompress(newbuf.data(), newbuf.size(), buf.data(), buf.size()); if (!ZSTD_isError(n)) { std::swap(ownbuf, newbuf); buf = {ownbuf.data(), ownbuf.size()}; } else { buf = {}; } } }; struct Serialize { Serialize(Serializer& ser) : ser(ser) { } Serializer& ser; template static std::false_type has_serialize_f(...); template ().serialize(std::declval()))> static std::true_type has_serialize_f(int); template static const bool has_serialize = decltype(Serialize::has_serialize_f(0))::value; template static std::false_type has_builtin_write_f(...); template < typename T, typename = decltype(std::declval().write(std::declval()))> static std::true_type has_builtin_write_f(int); template static const bool has_builtin_write = decltype(Serialize::has_builtin_write_f(0))::value; template void operator()(const T& v) { if constexpr (has_serialize) { v.serialize(*this); } else if constexpr (has_builtin_write) { ser.write(std::forward(v)); } else { serialize(*this, std::forward(v)); } } template void operator()(const T&... v) { (int[]){((*this)(std::forward(v)), 0)...}; } }; struct Deserialize { Deserialize(Deserializer& des) : des(des) { } Deserializer& des; template static std::false_type has_serialize_f(...); template ().serialize(std::declval()))> static std::true_type has_serialize_f(int); template static const bool has_serialize = decltype(Deserialize::has_serialize_f(0))::value; template static std::false_type has_builtin_read_f(...); template ().read(std::declval()))> static std::true_type has_builtin_read_f(int); template static const bool has_builtin_read = decltype(Deserialize::has_builtin_read_f(0))::value; template void operator()(T& v) { if constexpr (has_serialize) { v.serialize(*this); } else if constexpr (has_builtin_read) { des.read(v); } else { serialize(*this, v); } } template void operator()(T&... v) { (int[]){((*this)(v), 0)...}; } template T read() { if constexpr (has_serialize) { T r; r.serialize(*this); return r; } else if constexpr (has_builtin_read) { return des.read(); } else { T r; serialize(*this, r); return r; } } }; struct RPCException : std::exception {}; struct RPCExceptionConnectionError : RPCException { virtual const char* what() const noexcept override { return "RPC connection error"; } }; struct RPCExceptionFunctionNotFound : RPCException { virtual const char* what() const noexcept override { return "RPC function not found"; } }; struct RPCExceptionRemoteException : RPCException { virtual const char* what() const noexcept override { return "RPC remote exception"; } }; class Client : public std::enable_shared_from_this { public: Client() = default; Client(network::Peer peer) : peer(std::move(peer)) { this->peer.setOnMessage([this](std::string_view buf) { bytesReceived_ += buf.size(); Deserializer des(buf); des.decompress(); Deserialize x(des); uint32_t id; uint8_t status; x(id, status); std::unique_lock l(reqmut); auto i = requests.find(id); if (i != requests.end()) { auto r = std::move(i->second); requests.erase(i); l.unlock(); lastLatency_ = std::chrono::steady_clock::now() - r->timestamp; if (status == 0xff) { r->exception(std::make_exception_ptr(RPCExceptionFunctionNotFound())); } else if (status == 0xfe) { r->exception(std::make_exception_ptr(RPCExceptionRemoteException())); } else if (status != 0) { r->exception(std::make_exception_ptr(RPCExceptionConnectionError())); } else { r->handle(x); } } }); this->peer.setOnConnectionClosed([this]() { std::unique_lock l(reqmut); for (auto& v : requests) { v.second->exception( std::make_exception_ptr(RPCExceptionConnectionError())); } requests.clear(); }); } ~Client() { peer.close(); } void close() { peer.close(); } template void async(std::string_view funcname, Args&&... args) { Serializer ser; Serialize x(ser); uint32_t id = ++reqcounter; x(id, funcname, std::forward(args)...); ser.compress(); peer.sendMessage(ser.data(), ser.size()); bytesSent_ += ser.size(); ++numRpcCalls_; } struct RequestBase { std::chrono::steady_clock::time_point timestamp; virtual ~RequestBase() { } virtual void handle(Deserialize&) noexcept = 0; virtual void exception(std::exception_ptr e) noexcept = 0; }; template struct RequestImpl : RequestBase { std::promise p; std::atomic_bool handled = false; virtual ~RequestImpl() { } virtual void handle(Deserialize& x) noexcept override { if (handled.exchange(true)) { return; } if constexpr (std::is_same_v) { p.set_value(); } else { R r; x(r); p.set_value(r); } } virtual void exception(std::exception_ptr e) noexcept override { if (handled.exchange(true)) { return; } p.set_exception(e); } }; template std::future async(std::string_view funcname, Args&&... args) { Serializer ser; Serialize x(ser); uint32_t id = ++reqcounter; x(id, funcname, std::forward(args)...); auto req = std::make_unique>(); auto fut = req->p.get_future(); std::unique_lock l(reqmut); req->timestamp = std::chrono::steady_clock::now(); requests[id] = std::move(req); l.unlock(); ser.compress(); peer.sendMessage(ser.data(), ser.size()); bytesSent_ += ser.size(); ++numRpcCalls_; return fut; } template R sync(std::string_view funcname, Args&&... args) { auto f = async(funcname, std::forward(args)...); return f.get(); } template void sync(std::string_view funcname, Args&&... args) { return sync(funcname, std::forward(args)...); } size_t bytesSent() const { return bytesSent_; } size_t bytesReceived() const { return bytesReceived_; } size_t numRpcCalls() const { return numRpcCalls_; } std::chrono::steady_clock::duration lastLatency() const { return lastLatency_; } private: std::mutex reqmut; std::unordered_map> requests; std::atomic reqcounter = 0; network::Peer peer; std::atomic_size_t bytesSent_ = 0; std::atomic_size_t bytesReceived_ = 0; std::atomic_size_t numRpcCalls_ = 0; std::atomic lastLatency_{}; }; class Server { public: Server() = default; Server(network::Server server) : server(std::move(server)) { this->server.setOnPeer([this](network::Peer peer) { auto ref = std::make_shared(); ref->peer = std::move(peer); auto l = this->server.lock(); peers.push_back(ref); l.unlock(); ref->peer.setOnMessage( [this, ref](std::string_view buf) { handle(*ref, buf); }); ref->peer.setOnConnectionClosed([this, ref]() { auto l = this->server.lock(); for (auto i = peers.begin(); i != peers.end(); ++i) { if (*i == ref) { peers.erase(i); break; } } ref->peer.post_close(); }); }); } ~Server() { server.close(); for (auto& v : peers) { v->peer.close(); } peers.clear(); } Server(Server&&) = delete; Server(Server&) = delete; void listen(std::string_view endpoint) { server.listen(endpoint); } struct FBase { virtual ~FBase(){}; virtual void call(Deserialize& x, Serialize& sx) = 0; }; template struct FImpl : FBase { std::function f; FImpl(std::function f) : f(std::move(f)) { } virtual ~FImpl(){}; virtual void call(Deserialize& x, Serialize& sx) override { std::tuple args; unfold<0>(x, args); if constexpr (std::is_same_v) { std::apply(f, std::move(args)); } else { sx(std::apply(f, std::move(args))); } } template void unfold(Deserialize& x, T& tuple) { x(std::get(tuple)); if constexpr (n + 1 != std::tuple_size_v) { unfold(x, tuple); } } }; std::unordered_set funcnames; std::unordered_map> funcs; template void define(std::string_view name, std::function f) { auto ff = std::make_unique>(std::move(f)); funcs[*funcnames.emplace(name).first] = std::move(ff); } template void define(std::string_view name, R (*f)(Args...)) { define(name, std::function(f)); } template void define(std::string_view name, R (M::*f)(Args...), M* self) { define(name, std::function([self, f](Args&&... args) -> R { return (self->*f)(std::forward(args)...); })); } template void define(std::string_view name, T f) { auto ff = std::make_unique>(std::move(f)); funcs[*funcnames.emplace(name).first] = std::move(ff); } size_t bytesSent() const { return bytesSent_; } size_t bytesReceived() const { return bytesReceived_; } size_t numRpcCalls() const { return numRpcCalls_; } private: struct Peer { network::Peer peer; }; struct Message { Message* next = nullptr; std::vector buf; }; void handle(Peer& peer, std::string_view buf) { bytesReceived_ += buf.size(); Deserializer des(buf.data(), buf.size()); des.decompress(); Deserialize x(des); uint32_t id; std::string_view name; x(id, name); Serializer ser; Serialize sx(ser); ++numRpcCalls_; auto i = funcs.find(name); if (i != funcs.end()) { sx(id); sx((uint8_t)0); try { i->second->call(x, sx); } catch (...) { ser.clear(); sx(id); sx((uint8_t)0xfe); ser.compress(); peer.peer.sendMessage(ser.data(), ser.size()); bytesSent_ += ser.size(); throw; } } else { sx(id); sx((uint8_t)0xff); } ser.compress(); peer.peer.sendMessage(ser.data(), ser.size()); bytesSent_ += ser.size(); } network::Server server; std::vector> peers; std::atomic_size_t bytesSent_ = 0; std::atomic_size_t bytesReceived_ = 0; std::atomic_size_t numRpcCalls_ = 0; }; class Rpc { public: Rpc() = default; Rpc(Rpc&&) = delete; Rpc(Rpc&) = delete; ~Rpc() { terminate = true; for (auto& _ : threads) { (void)_; net.post([] {}); } } std::shared_ptr listen(std::string_view endpoint) { return std::make_shared(net.listen(endpoint)); } std::shared_ptr connect(std::string_view endpoint) { return std::make_shared(net.connect(endpoint)); } bool run_one() { return net.run_one(); } void asyncRun(int nThreads = 1) { for (; nThreads; --nThreads) { threads.emplace_back([this]() { while (!terminate) { net.run_one(); } }); } } private: network::Network net; std::atomic_bool terminate = false; std::vector threads; }; } // namespace rpc ================================================ FILE: src/games/amazons.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 林鈺錦 (Yù-Jǐn Lín) // - Github: https://github.com/abc1236762 // - Email: abc1236762@outlook.com // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #include "amazons.h" namespace Amazons { State::State(int seed) : core::State(seed) { std::call_once(setupCalled, [&] { setupBoard(_rng); }); } void State::Initialize() { _moves.clear(); _featSize = {chessKinds, Board::rows, Board::columns}; _features.resize(chessKinds * Board::squares); _actionSize = {Board::squares, Board::squares, Board::squares}; _legalActions.reserve(maxLegalActionsCnt); _status = GameStatus::player0Turn; board.initialize(); setInitialChesses(); _hash = board.getHash(); findLegalActions(Player::first); fillFeatures(); } std::unique_ptr State::clone_() const { return std::make_unique(*this); } void State::ApplyAction(const ::_Action& action) { Move move{}; std::tie(move.fromX, move.fromY) = Board::posTo2D(action.GetX()); std::tie(move.toX, move.toY) = Board::posTo2D(action.GetY()); std::tie(move.arrowX, move.arrowY) = Board::posTo2D(action.GetZ()); play(move); board.turnHash(); _hash = board.getHash(); Player nextPlayer = turnPlayer(); if (canGoNext(nextPlayer)) { fillFeatures(); } else { setTerminatedStatus(nextPlayer); _legalActions.clear(); } } void State::DoGoodAction() { DoRandomAction(); } void State::printCurrentBoard() const { std::cout << board.sprint(" "); } std::string State::stateDescription() const { return board.sprint(" "); } std::string State::actionDescription(const ::_Action& action) const { std::ostringstream oss; oss << "moved the chess from " << board.getPosStr(action.GetX()) << " to " << board.getPosStr(action.GetY()) << " and shooted an arrow at " << board.getPosStr(action.GetZ()); return oss.str(); } std::string State::actionsDescription() const { std::ostringstream oss; oss << "Position of queen chesses which are able to move: "; std::set xySet; for (auto& legalAction : _legalActions) xySet.insert(legalAction.GetX()); std::size_t i = 0; for (int xy : xySet) { oss << "`" << board.getPosStr(xy) << "`"; if (++i < xySet.size()) oss << ", "; } oss << std::endl; return oss.str(); } int State::parseAction(const std::string& str) const { auto getXY = [&](const std::set& xySet, const std::string& content) { std::cout << content << std::endl << "Allowed positions: ('" << Board::getMarkSymbol() << "' means an allowed position)"; std::set> markedPos; for (auto xy : xySet) markedPos.insert(Board::posTo2D(xy)); std::cout << std::endl << board.sprintBoard(" ", markedPos); std::cout << "> "; std::string str; std::getline(std::cin, str); auto xyResult = board.parsePosStr(str); if (!xyResult) return -1; auto [x, y] = xyResult.value(); int xy = Board::posTo1D(x, y); if (xySet.find(xy) == xySet.end()) return -1; return xy; }; auto result = board.parsePosStr(str); if (!result) return -1; auto [fromX, fromY] = result.value(); int fromXY = Board::posTo1D(fromX, fromY); std::set toXYSet; std::unordered_map> arrowXYSet; std::unordered_map> iMap; for (std::size_t i = 0; i < _legalActions.size(); i++) { if (fromXY != _legalActions[i].GetX()) continue; int toXY = _legalActions[i].GetY(); int arrowXY = _legalActions[i].GetZ(); toXYSet.insert(toXY); arrowXYSet[toXY].insert(arrowXY); iMap[toXY][arrowXY] = i; } if (toXYSet.empty()) return -1; int toXY = getXY(toXYSet, "Input the position of selected queen chess after moved:"); if (toXY < 0) return -1; int arrowXY = getXY( arrowXYSet[toXY], "Input the position of the arrow that wants to shoot:"); if (arrowXY < 0) return -1; return iMap[toXY][arrowXY]; } int State::humanInputAction( std::function(std::string)> specialAction) { std::cout << "Current board:" << std::endl << stateDescription() << std::endl; std::cout << "Input three positions to play: (uses format , e.g. `A1`, `b2`, `C03`...)" << std::endl; std::string str; int index = -1; while (index < 0) { std::cout << actionsDescription() << std::endl; std::cout << "Input the position of the queen chess which wants to move:"; std::cout << std::endl << "> "; std::getline(std::cin, str); index = parseAction(str); if (index < 0) { if (auto r = specialAction(str); r) return *r; std::cout << "invalid input, try again." << std::endl; } } return index; } template void State::setupBoard(const R& re) { Board::setup( {"Empty", "WhiteQueen", "BlackQueen", "WhiteArrow", "BlackArrow"}, {" ", "○", "●", "□", "■"}, re); } constexpr Player State::chessToPlayer(Chess chess) { if (chess == ChessKind::whiteQueen || chess == ChessKind::whiteArrow) return Player::first; else if (chess == ChessKind::blackQueen || chess == ChessKind::blackArrow) return Player::second; assert(chess == ChessKind::whiteQueen || chess == ChessKind::whiteArrow || chess == ChessKind::blackQueen || chess == ChessKind::blackArrow); return Player::none; } constexpr Chess State::playerToQueenChess(Player player) { if (player == Player::first) return ChessKind::whiteQueen; else if (player == Player::second) return ChessKind::blackQueen; assert(player == Player::first || player == Player::second); return ChessKind::empty; } constexpr Chess State::playerToArrowChess(Player player) { if (player == Player::first) return ChessKind::whiteArrow; else if (player == Player::second) return ChessKind::blackArrow; assert(player == Player::first || player == Player::second); return ChessKind::empty; } void State::setInitialChesses() { for (int p = 0; p < players; p++) { Chess queenChess = playerToQueenChess(Player::set(p)); int i = 0; for (auto [x, y] : initialQueenChessesPos[p]) { board.setChess(x, y, queenChess); queenChessesPos[p][i++] = {x, y}; } } } void State::play(const Move& move) { Chess queenChess = board.getChess(move.fromX, move.fromY); Player player = chessToPlayer(queenChess); assert(queenChess == ChessKind::whiteQueen || queenChess == ChessKind::blackQueen); for (auto& [x, y] : queenChessesPos[player.index()]) { if (x == move.fromX && y == move.fromY) { x = move.toX, y = move.toY; break; } } board.setChess(move.fromX, move.fromY, ChessKind::empty); board.setChess(move.toX, move.toY, queenChess); board.setChess(move.arrowX, move.arrowY, playerToArrowChess(player)); } bool State::canGoNext(Player nextPlayer) { findLegalActions(nextPlayer); return _legalActions.size() != 0; } void State::findLegalActions(Player player) { clearActions(); int i = 0; auto addLegalActions = [&](Move move) { int fromXY = Board::posTo1D(move.fromX, move.fromY); int toXY = Board::posTo1D(move.toX, move.toY); int arrowXY = Board::posTo1D(move.arrowX, move.arrowY); addAction(fromXY, toXY, arrowXY); assert(i <= maxLegalActionsCnt); }; auto findLegalArrowShoots = [&](int fromX, int fromY, int toX, int toY) { for (auto [dx, dy] : directions) { int arrowX = toX + dx, arrowY = toY + dy; while (Board::isPosInBoard(arrowX, arrowY)) { if (board.getChess(arrowX, arrowY) == ChessKind::empty || (arrowX == fromX && arrowY == fromY)) { addLegalActions(Move{fromX, fromY, toX, toY, arrowX, arrowY}); } else { break; } arrowX += dx, arrowY += dy; } } }; auto findLegalQueenMoves = [&](int fromX, int fromY) { for (auto [dx, dy] : directions) { int toX = fromX + dx, toY = fromY + dy; while (Board::isPosInBoard(toX, toY) && board.getChess(toX, toY) == ChessKind::empty) { findLegalArrowShoots(fromX, fromY, toX, toY); toX += dx, toY += dy; } } }; for (auto [fromX, fromY] : queenChessesPos[player.index()]) findLegalQueenMoves(fromX, fromY); } Player State::turnPlayer() { if (_status == GameStatus::player0Turn) { _status = GameStatus::player1Turn; return Player::second; } else if (_status == GameStatus::player1Turn) { _status = GameStatus::player0Turn; return Player::first; } assert(_status == GameStatus::player0Turn || _status == GameStatus::player1Turn); return Player::none; } void State::setTerminatedStatus(Player loser) { if (loser == Player::first) _status = GameStatus::player1Win; else if (loser == Player::second) _status = GameStatus::player0Win; assert(loser == Player::first || loser == Player::second); } void State::fillFeatures() { std::fill(_features.begin(), _features.end(), 0.0); auto* f = _features.data(); for (int c = 0; c < chessKinds; c++) { Chess chess = static_cast(c + 1); for (int xy = 0; xy < Board::squares; xy++, f++) if (board.getChess(xy) == chess) *f = 1.0; } fillFullFeatures(); } Action::Action(int i, int fromXY, int toXY, int arrowXY) : ::_Action() { _i = i; _loc = {fromXY, toXY, arrowXY}; _hash = State::Board::squares * State::Board::squares * fromXY + State::Board::squares * toXY + arrowXY; } } // namespace Amazons ================================================ FILE: src/games/amazons.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 林鈺錦 (Yù-Jǐn Lín) // - Github: https://github.com/abc1236762 // - Email: abc1236762@outlook.com // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "../core/state.h" #include "commons/chessboard.h" #include "commons/player.h" namespace Amazons { class ChessKind { public: static constexpr Chess empty = 0; static constexpr Chess whiteQueen = 1; static constexpr Chess blackQueen = 2; static constexpr Chess whiteArrow = 3; static constexpr Chess blackArrow = 4; }; struct Move { int fromX, fromY; int toX, toY; int arrowX, arrowY; }; class State : public core::State { public: using Board = Chessboard<10, 10>; State(int seed); void Initialize() override; std::unique_ptr clone_() const override; void ApplyAction(const ::_Action& action) override; void DoGoodAction() override; void printCurrentBoard() const override; std::string stateDescription() const override; std::string actionDescription(const ::_Action& action) const override; std::string actionsDescription() const override; int parseAction(const std::string& str) const override; int humanInputAction( std::function(std::string)> specialAction) override; private: template static void setupBoard(const R& re); static constexpr Player chessToPlayer(Chess chess); static constexpr Chess playerToQueenChess(Player player); static constexpr Chess playerToArrowChess(Player player); void setInitialChesses(); void play(const Move& move); bool canGoNext(Player nextPlayer); void findLegalActions(Player player); inline Player turnPlayer(); inline void setTerminatedStatus(Player loser); void fillFeatures(); static constexpr int players = 2; static constexpr int chessKinds = 4; static constexpr int maxHands = Board::squares - 8; // Maximum count of legal moves in ideal situations: ⌈(((9*4-9)*(10*4-4)+(9*4- // 7)*(8*4-4)+(9*4-5)*(6*4-4)+(9*4-3)*(4*4-4)+(9*4-1)*(2*4-4))/10^2)^2*4⌉=3458 static constexpr int maxLegalActionsCnt = 3458; static constexpr std::tuple directions[8] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; static constexpr std::tuple initialQueenChessesPos[players][chessKinds] = { {{0, 6}, {3, 9}, {6, 9}, {9, 6}}, {{0, 3}, {3, 0}, {6, 0}, {9, 3}}}; static inline std::once_flag setupCalled; Board board; std::array, 4>, 2> queenChessesPos; }; class Action : public ::_Action { public: Action(int i, int fromXY, int toXY, int arrowRelRD); }; } // namespace Amazons ================================================ FILE: src/games/block_go.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "../core/state.h" #include class StateForBlockGo : public core::State { public: class Point { public: int x, y; Point(int X, int Y) { x = X; y = Y; } Point() { x = y = 0; } void setxy(int X, int Y) { x = X, y = Y; } void turn90() { int tmp = x; x = -y; y = tmp; } }; class Piece { public: friend class StateForBlockGo; short count; // 1~4 short turn; bool onboard; Point s; Point tail[4]; Piece() { count = 1; turn = 4; // 0 90 180 270 onboard = false; } void turn90() { for (int i = 1; i < count; ++i) tail[i].turn90(); } }; class Move { public: int x, y; int piece; int dir; Move() { x = y = -1; piece = -1; dir = 0; } Move(int X, int Y, int p, int d) { x = X; y = Y; piece = p; dir = d; } }; public: static const int boardWidth = 13; static const int boardHeight = 13; int board[13][13]; int territory[13][13]; int round; unsigned long long HashArray[20][13][13]; // 20 different types unsigned long long HashTurn; std::vector player0; std::vector player1; std::vector moves; StateForBlockGo(int seed) : State(seed) { } virtual void Initialize() override { _moves.clear(); // _hash = 2166136261u; _hash = 0; _status = GameStatus::player0Turn; _featSize[0] = 2; _featSize[1] = boardHeight; _featSize[2] = boardWidth; _actionSize[0] = 36; // 9 pieces * 4 directions _actionSize[1] = boardHeight; _actionSize[2] = boardWidth; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); gameInit(); initHash(); // printCurrentBoard(); findFeature(); findActions(); fillFullFeatures(); } void initHash() { for (int x = 0; x < 20; ++x) for (int y = 0; y < boardHeight; ++y) for (int z = 0; z < boardWidth; ++z) { HashArray[x][y][z] = 0; for (int k = 0; k < 64; ++k) if ((rand() / (RAND_MAX + 1.0)) > 0.5) HashArray[x][y][z] |= (1ULL << k); } HashTurn = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) HashTurn |= (1ULL << k); } void gameInit() { round = 1; std::fill(&board[0][0], &board[0][0] + 169, 2); player0.clear(); player0.resize(9); player1.clear(); player1.resize(9); // s player0[0].turn = 1; player0[0].count = 1; // s player0[1].turn = 1; player0[1].count = 1; // s+ // ++ player0[2].turn = 1; player0[2].count = 4; player0[2].tail[1].setxy(1, 0); player0[2].tail[2].setxy(0, 1); player0[2].tail[3].setxy(1, 1); // s+++ player0[3].turn = 2; player0[3].count = 4; player0[3].tail[1].setxy(1, 0); player0[3].tail[2].setxy(2, 0); player0[3].tail[3].setxy(3, 0); // s+ // ++ player0[4].turn = 2; player0[4].count = 4; player0[4].tail[1].setxy(1, 0); player0[4].tail[2].setxy(1, 1); player0[4].tail[3].setxy(2, 1); // ++ // s+ player0[5].turn = 2; player0[5].count = 4; player0[5].tail[1].setxy(1, 0); player0[5].tail[2].setxy(1, -1); player0[5].tail[3].setxy(2, -1); // s++ // + player0[6].turn = 4; player0[6].count = 4; player0[6].tail[1].setxy(1, 0); player0[6].tail[2].setxy(2, 0); player0[6].tail[3].setxy(1, 1); // s++ // + player0[7].turn = 4; player0[7].count = 4; player0[7].tail[1].setxy(1, 0); player0[7].tail[2].setxy(2, 0); player0[7].tail[3].setxy(2, 1); // s++ // + player0[8].turn = 4; player0[8].count = 4; player0[8].tail[1].setxy(1, 0); player0[8].tail[2].setxy(2, 0); player0[8].tail[3].setxy(0, 1); // ============= // // s player1[0].turn = 1; player1[0].count = 1; // s player1[1].turn = 1; player1[1].count = 1; // s+ // ++ player1[2].turn = 1; player1[2].count = 4; player1[2].tail[1].setxy(1, 0); player1[2].tail[2].setxy(0, 1); player1[2].tail[3].setxy(1, 1); // s+++ player1[3].turn = 2; player1[3].count = 4; player1[3].tail[1].setxy(1, 0); player1[3].tail[2].setxy(2, 0); player1[3].tail[3].setxy(3, 0); // s+ // ++ player1[4].turn = 2; player1[4].count = 4; player1[4].tail[1].setxy(1, 0); player1[4].tail[2].setxy(1, 1); player1[4].tail[3].setxy(2, 1); // ++ // s+ player1[5].turn = 2; player1[5].count = 4; player1[5].tail[1].setxy(1, 0); player1[5].tail[2].setxy(1, -1); player1[5].tail[3].setxy(2, -1); // s++ // + player1[6].turn = 4; player1[6].count = 4; player1[6].tail[1].setxy(1, 0); player1[6].tail[2].setxy(2, 0); player1[6].tail[3].setxy(1, 1); // s++ // + player1[7].turn = 4; player1[7].count = 4; player1[7].tail[1].setxy(1, 0); player1[7].tail[2].setxy(2, 0); player1[7].tail[3].setxy(2, 1); // s++ // + player1[8].turn = 4; player1[8].count = 4; player1[8].tail[1].setxy(1, 0); player1[8].tail[2].setxy(2, 0); player1[8].tail[3].setxy(0, 1); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } virtual void printCurrentBoard() const override { fprintf(stderr, " 0 1 2 3 4 5 6 7 8 9 10 11 12\n"); for (int i = 0; i < boardHeight; ++i) { fprintf(stderr, "%2d", i); for (int j = 0; j < boardWidth; ++j) { switch (board[i][j]) { case 0: std::cerr << " O "; break; case 1: std::cerr << " X "; break; default: std::cerr << " - "; break; } } std::cerr << std::endl; } } void findFeature() { std::fill(_features.begin(), _features.end(), 0); for (int i = 0; i < 169; ++i) { switch (board[i / 13][i % 13]) { case 0: _features[i] = 1; break; case 1: _features[169 + i] = 1; break; default: break; } } // std::fill(_features.begin()+338, _features.end(), getCurrentPlayer()); } bool canDrop(int x, int y) { return (x >= 0 && y >= 0 && x < boardWidth && y < boardHeight && board[y][x] == 2); } void legalMoves(std::vector player, std::vector& moves) { if (round <= 4) { int dx[] = {3, 9, 3, 9}; int dy[] = {3, 3, 9, 9}; for (int d = 0; d < 4; ++d) { if (board[dy[d]][dx[d]] == 2) { // empty for (size_t p = 0; p < player.size(); ++p) { if (!player[p].onboard) { for (int t = 0; t < player[p].turn; ++t) { for (int i = 0; i < player[p].count; ++i) { Move* m = new Move(); m->dir = t; m->piece = p; m->x = dx[d] - player[p].tail[i].x; m->y = dy[d] - player[p].tail[i].y; // fprintf(stderr, "%d %d || %d %d\n", m->x, m->y, // player[p].tail[i].x, player[p].tail[i].y); moves.push_back(*m); delete m; } // fprintf(stderr, "\n\n"); player[p].turn90(); } if (p >= 3 && p <= 5) { player[p].turn90(); player[p].turn90(); } else if (p == 2) { player[p].turn90(); player[p].turn90(); player[p].turn90(); } } else continue; } } } } else { bool visited[boardHeight][boardWidth]; for (int j = 0; j < boardHeight; ++j) for (int i = 0; i < boardWidth; ++i) visited[j][i] = false; for (int j = 0; j < boardHeight; ++j) { for (int i = 0; i < boardWidth; ++i) { if ((int)_status == board[j][i]) { int dx[] = {1, 0, -1, 0}; int dy[] = {0, 1, 0, -1}; for (int k = 0; k < 4; ++k) { int x = i + dx[k]; int y = j + dy[k]; if (canDrop(x, y)) visited[y][x] = true; } } } } for (size_t p = 0; p < player.size(); ++p) { if (player[p].onboard) continue; for (int t = 0; t < player[p].turn; ++t) { for (int j = 0; j < boardHeight; ++j) { for (int i = 0; i < boardWidth; ++i) { if (board[j][i] != 2) continue; bool legal = false; for (int c = 0; c < player[p].count; ++c) { int x = i + player[p].tail[c].x; int y = j + player[p].tail[c].y; if (!canDrop(x, y)) { legal = false; break; } else if (visited[y][x]) { legal = true; } } if (legal) { Move* m = new Move(); m->dir = t; m->piece = p; m->x = i; m->y = j; moves.push_back(*m); delete m; } } } player[p].turn90(); } if (p >= 3 && p <= 5) { player[p].turn90(); player[p].turn90(); } else if (p == 2) { player[p].turn90(); player[p].turn90(); player[p].turn90(); } } } } void findActions() { moves.clear(); if (_status == GameStatus::player0Turn) { legalMoves(player0, moves); } else if (_status == GameStatus::player1Turn) { legalMoves(player1, moves); } // fprintf(stderr, "moves: %d\n", moves.size()); clearActions(); for (auto m : moves) { int x = m.x; int y = m.y; int p = m.piece * 4 + m.dir; addAction(p, x, y); } } void track(int x, int y) { if (!canDrop(x, y)) return; if (territory[y][x] == 4) return; territory[y][x] = 4; // fprintf(stderr, "xy: %d %d\n", x, y); track(x + 1, y); track(x, y - 1); track(x - 1, y); track(x, y + 1); } int edge() { int p[2] = {0}; for (int j = 0; j < boardHeight; ++j) { for (int i = 0; i < boardWidth; ++i) { if (territory[j][i] == 4) { if (i + 1 < boardWidth && board[j][i + 1] < 2) p[board[j][i + 1]]++; if (j - 1 >= 0 && board[j - 1][i] < 2) p[board[j - 1][i]]++; if (i - 1 >= 0 && board[j][i - 1] < 2) p[board[j][i - 1]]++; if (j + 1 < boardHeight && board[j + 1][i] < 2) p[board[j + 1][i]]++; } } } // fprintf(stderr, "p: %d %d\n", p[0], p[1]); if (p[0] && p[1]) return 2; else if (p[0]) return 0; else return 1; } void setTerritory(int a) { for (int j = 0; j < boardHeight; ++j) for (int i = 0; i < boardWidth; ++i) if (territory[j][i] == 4) territory[j][i] = a; } void printTerritory() { for (int i = 0; i < 13; ++i) { for (int j = 0; j < 13; ++j) fprintf(stderr, " %d ", territory[i][j]); fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } void findTerritory() { // fprintf(stderr, "findTerritory\n"); for (int j = 0; j < boardHeight; ++j) for (int i = 0; i < boardWidth; ++i) territory[j][i] = 3; for (int j = 0; j < boardHeight; ++j) { for (int i = 0; i < boardWidth; ++i) { if (canDrop(i, j) && territory[j][i] == 3) { // fprintf(stderr, "x: %d y: %d\n", i, j); track(i, j); // printTerritory(); setTerritory(edge()); } } } } GameStatus findWinner() { findTerritory(); int p[4] = {0}; for (int j = 0; j < boardHeight; ++j) for (int i = 0; i < boardWidth; ++i) p[territory[j][i]]++; // fprintf(stderr, "score: %d %d %d %d\n", p[0], p[1], p[2], p[3]); if (p[0] == p[1]) return GameStatus::tie; else if (p[0] > p[1]) return GameStatus::player0Win; else return GameStatus::player1Win; } int findType(int piece, int dir) { switch (piece) { case 0: case 1: return 0; case 2: return 1; case 3: return 2 + dir; case 4: return 4 + dir; case 5: return 6 + dir; case 6: return 8 + dir; case 7: return 12 + dir; case 8: return 16 + dir; default: fprintf(stderr, "piece error!!!!!\n"); return -1; } } virtual void ApplyAction(const _Action& action) override { _hash ^= HashTurn; // fprintf(stderr, "ApplyAction round %d\n", round); int x = action.GetY(); int y = action.GetZ(); int piece = action.GetX() >> 2; int dir = action.GetX() & 3; _hash ^= HashArray[findType(piece, dir)][x][y]; // fprintf(stderr, "(%d, %d) %d %d\n", x, y, piece, dir); // fprintf(stderr, "hash: %llu\n", _hash); if (_status == GameStatus::player0Turn) { for (int i = 0; i < dir; ++i) player0[piece].turn90(); for (int i = 0; i < player0[piece].count; ++i) board[y + player0[piece].tail[i].y][x + player0[piece].tail[i].x] = 0; player0[piece].onboard = true; _status = GameStatus::player1Turn; } else { for (int i = 0; i < dir; ++i) player1[piece].turn90(); for (int i = 0; i < player1[piece].count; ++i) board[y + player1[piece].tail[i].y][x + player1[piece].tail[i].x] = 1; player1[piece].onboard = true; _status = GameStatus::player0Turn; } if (round >= 18) { _status = findWinner(); // printTerritory(); } else { round += 1; findFeature(); findActions(); } // printCurrentBoard(); // fprintf(stderr, "end applyAction =======\n\n"); fillFullFeatures(); } virtual std::string stateDescription() const override { std::stringstream ss; ss << " 0 1 2 3 4 5 6 7 8 9 10 11 12\n"; for (int i = 0; i < boardHeight; ++i) { char buff[12]; sprintf(buff, "%2d ", i); ss << buff; for (int j = 0; j < boardWidth; ++j) { switch (board[i][j]) { case 0: ss << " O "; break; case 1: ss << " X "; break; default: ss << " - "; break; } } ss << std::endl; } ss << std::endl; return ss.str(); } struct Actions { int x, y, z, i; }; static bool compareAction(Actions a, Actions b) { if (a.z != b.z) return a.z < b.z; if (a.x != b.x) return a.x < b.x; return a.y < b.y; }; virtual std::string actionsDescription() const override { std::stringstream ss; Actions a[_legalActions.size()]; int i = 0; for (auto action : _legalActions) { a[i].x = action.GetY(); a[i].y = action.GetZ(); a[i].z = action.GetX(); a[i].i = i; i++; } std::sort(a, a + _legalActions.size(), compareAction); for (auto action : a) { char buff[54]; sprintf( buff, "%d: (%d %d) ---%d\n", action.z, action.x, action.y, action.i); ss << buff; } ss << "\nInput format: action index e.g. 0\n"; return ss.str(); } virtual std::string actionDescription(const _Action& action) const { std::stringstream ss; int z = action.GetX(); int x = action.GetY(); int y = action.GetZ(); ss << z << ": " << '(' << x << ' ' << y << ")\n"; return ss.str(); } virtual void DoGoodAction() override { // std::cerr << "DoGoodAction" << std::endl; return DoRandomAction(); } }; ================================================ FILE: src/games/breakthrough.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "breakthrough.h" #include #include #include #include #include #include #include using namespace std; unsigned long long BTHashArray[2][BTDx][BTDy]; unsigned long long BTHashTurn; // int level = 1; // unsigned long long nbPlay = 0; // timeval stop, start; // unsigned long long previousTime = 0; // bool BTinitHashCalled = false; std::once_flag BTinitHashCalled; void BTinitHash() { for (int player = 0; player < 2; player++) for (int i = 0; i < BTDx; i++) for (int j = 0; j < BTDy; j++) { BTHashArray[player][i][j] = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) BTHashArray[player][i][j] |= (1ULL << k); } BTHashTurn = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) BTHashTurn |= (1ULL << k); } ================================================ FILE: src/games/breakthrough.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include #include #include using namespace std; const int White = 0; const int Black = 1; const int Empty = 2; const int BTDx = 8; const int BTDy = 8; const int BTMaxLegalBTMoves = 3 * BTDx * 2; const int BTMaxPlayoutLength = 1000; // const int SizeTable = 1048575; // une puissance de 2 moins 1 extern unsigned long long BTHashArray[2][BTDx][BTDy]; extern unsigned long long BTHashTurn; // int level = 1; // unsigned long long nbPlay = 0; // timeval stop, start; // unsigned long long previousTime = 0; // extern bool BTinitHashCalled = false; extern std::once_flag BTinitHashCalled; extern void BTinitHash(); class BTPlayer { public: int player; bool operator==(BTPlayer p) { return (p.player == player); } }; // const int MaxBTMoveNumber = 2 * 2 * (3 * BTDx * BTDy) + 1; const int MaxBTMoveNumber = 80 * 2 * 2 * (3 * BTDx * BTDy) + 1; // bool BTuseCode = true; class BTMove { public: int x, y, x1, y1, color; int code; int codePrevious; BTMove() { x = -1; y = -1; x1 = -1; y1 = -1; color = -1; code = -1; codePrevious = -1; } int numberPrevious() { int c = 0; c = code; if (color == White) return c + 3 * (x + BTDx * y) + x1 - x + 1; else return c + 3 * BTDx * BTDy + 3 * (x + BTDx * y) + x1 - x + 1; } int number() { int c = 0; c = code + codePrevious; if (color == White) return c + 3 * (x + BTDx * y) + x1 - x + 1; else return c + 3 * BTDx * BTDy + 3 * (x + BTDx * y) + x1 - x + 1; } }; class BTBoard { public: int board[BTDx][BTDy]; unsigned long long hash; BTMove rollout[BTMaxPlayoutLength]; int length, turn; int orderBTMove[BTMaxLegalBTMoves]; void init() { for (int i = 0; i < BTDx; i++) for (int j = 0; j < BTDy; j++) board[i][j] = Empty; for (int i = 0; i < 2; i++) for (int j = 0; j < BTDx; j++) board[j][i] = Black; for (int i = BTDy - 2; i < BTDy; i++) for (int j = 0; j < BTDx; j++) board[j][i] = White; hash = 0; length = 0; turn = White; /*if (BTinitHashCalled == false) { BTinitHash(); BTinitHashCalled = true; }*/ std::call_once(BTinitHashCalled, BTinitHash); } int countPieces(int color) const { int r = 0; for (int i = 0; i < BTDx; i++) { for (int j = 0; j < BTDy; j++) { if (board[i][j] == color) { ++r; } } } return r; } bool won(int color) { if (color == White) { for (int j = 0; j < BTDx; j++) if (board[j][0] == White) return true; BTMove listeCoups[BTMaxLegalBTMoves]; int nb = legalBTMoves(Black, listeCoups); if (nb == 0) return true; } else { for (int j = 0; j < BTDx; j++) if (board[j][BTDy - 1] == Black) return true; BTMove listeCoups[BTMaxLegalBTMoves]; int nb = legalBTMoves(White, listeCoups); if (nb == 0) return true; } return false; } bool terminal() { // return won (Black) || won (White); for (int j = 0; j < BTDx; j++) if (board[j][0] == White) return true; for (int j = 0; j < BTDx; j++) if (board[j][BTDy - 1] == Black) return true; BTMove listeCoups[BTMaxLegalBTMoves]; int nb = legalBTMoves(turn, listeCoups); if (nb == 0) return true; return false; } int score() { if (won(White)) return 1; return 0; } float evaluation(int color) { if (won(color)) return 1000000.0; if (won(opponent(color))) return -1000000.0; BTMove moves[BTMaxLegalBTMoves]; int nb = legalBTMoves(turn, moves); if (nb == 0) { if (color == turn) return -1000000.0; else return 1000000.0; } int nbOpponent = legalBTMoves(opponent(turn), moves); if (color == turn) return (float)(nb - nbOpponent); return (float)(nbOpponent - nb); } int opponent(int joueur) const { if (joueur == White) return Black; return White; } bool losingBTMove(BTMove m) { if (m.color == Black) { for (int j = 0; j < BTDx; j++) if (board[j][BTDy - 2] == Black) if (m.y1 != BTDy - 1) return true; for (int j = 0; j < BTDx; j++) if (board[j][1] == White) if ((m.y1 != 1) || (m.x1 != j)) return true; } if (m.color == White) { for (int j = 0; j < BTDx; j++) if (board[j][1] == White) if (m.y1 != 0) return true; for (int j = 0; j < BTDx; j++) if (board[j][BTDy - 2] == Black) if ((m.y1 != BTDy - 2) || (m.x1 != j)) return true; } return false; } int order(BTMove m) { if (m.color == Black) { if (m.y1 == BTDy - 1) return 0; } if (m.color == White) { if (m.y1 == 0) return 0; } if (board[m.x1][m.y1] == opponent(m.color)) return 1; return 2; } bool legalBTMove(BTMove m) { if (board[m.x][m.y] != m.color) return false; if (board[m.x1][m.y1] == m.color) return false; if (m.color == White) if ((m.y1 == m.y - 1) && (m.x == m.x1)) if (board[m.x1][m.y1] == Black) return false; if (m.color == Black) if ((m.y1 == m.y + 1) && (m.x == m.x1)) if (board[m.x1][m.y1] == White) return false; return true; } void play(BTMove m) { board[m.x][m.y] = Empty; hash ^= BTHashArray[m.color][m.x][m.y]; if (board[m.x1][m.y1] != Empty) hash ^= BTHashArray[board[m.x1][m.y1]][m.x1][m.y1]; board[m.x1][m.y1] = m.color; hash ^= BTHashArray[m.color][m.x1][m.y1]; hash ^= BTHashTurn; if (length < BTMaxPlayoutLength) { rollout[length] = m; length++; } else fprintf(stderr, "Pb play,"); turn = opponent(turn); // nbPlay++; } void print(FILE* fp) { for (int i = 0; i < BTDy; i++) { for (int j = 0; j < BTDx; j++) if (board[j][i] == Empty) fprintf(fp, " +"); else if (board[j][i] == Black) fprintf(fp, " @"); else fprintf(fp, " O"); fprintf(fp, " \n"); } fprintf(fp, " \n"); } int legalBTMoves(int color, BTMove moves[BTMaxLegalBTMoves]) { int nb = 0; for (int i = 0; i < BTDx; i++) for (int j = 0; j < BTDy; j++) if (board[i][j] == color) { BTMove m; m.x = i; m.y = j; m.color = color; if (color == White) { if ((j - 1 >= 0) && (i + 1 < BTDx)) { m.x1 = i + 1; m.y1 = j - 1; if (board[m.x1][m.y1] == Empty) m.code = 0; else m.code = 6 * BTDx * BTDy; if (legalBTMove(m)) { moves[nb] = m; nb++; } } if ((j - 1 >= 0) && (i - 1 >= 0)) { m.x1 = i - 1; m.y1 = j - 1; if (board[m.x1][m.y1] == Empty) m.code = 0; else m.code = 6 * BTDx * BTDy; if (legalBTMove(m)) { moves[nb] = m; nb++; } } if ((j - 1 >= 0)) { m.x1 = i; m.y1 = j - 1; if (board[m.x1][m.y1] == Empty) m.code = 0; else m.code = 6 * BTDx * BTDy; if (legalBTMove(m)) { moves[nb] = m; nb++; } } } else { if ((j + 1 < BTDy) && (i + 1 < BTDx)) { m.x1 = i + 1; m.y1 = j + 1; if (board[m.x1][m.y1] == Empty) m.code = 0; else m.code = 6 * BTDx * BTDy; if (legalBTMove(m)) { moves[nb] = m; nb++; } } if ((j + 1 < BTDy) && (i - 1 >= 0)) { m.x1 = i - 1; m.y1 = j + 1; if (board[m.x1][m.y1] == Empty) m.code = 0; else m.code = 6 * BTDx * BTDy; if (legalBTMove(m)) { moves[nb] = m; nb++; } } if ((j + 1 < BTDy)) { m.x1 = i; m.y1 = j + 1; if (board[m.x1][m.y1] == Empty) m.code = 0; else m.code = 6 * BTDx * BTDy; if (legalBTMove(m)) { moves[nb] = m; nb++; } } } } for (int i = 0; i < nb; i++) orderBTMove[i] = order(moves[i]); for (int i = 0; i < nb; i++) { int imin = i; int o = orderBTMove[i]; for (int j = i + 1; j < nb; j++) { int o1 = orderBTMove[j]; if (o1 < o) { imin = j; o = o1; } } BTMove m = moves[i]; moves[i] = moves[imin]; moves[imin] = m; o = orderBTMove[i]; orderBTMove[i] = orderBTMove[imin]; orderBTMove[imin] = o; } /* for (int i = 0; i < nb; i++) if (order (moves [i]) == 1) { BTMove m = moves [0]; moves [0] = moves [i]; moves [i] = m; } for (int i = 0; i < nb; i++) if (order (moves [i]) == 0) { BTMove m = moves [0]; moves [0] = moves [i]; moves [i] = m; } */ int codePrevious = 0; if (length > 0) // codePrevious = rollout [length].numberPrevious () + 12 * BTDx * BTDy; codePrevious = (rollout[length].x1 + BTDx * rollout[length].y1) * 2 * 2 * (3 * BTDx * BTDy); for (int i = 0; i < nb; i++) { codePrevious = 0; if (color == White) { if (moves[i].y1 > 0) { if (moves[i].x1 == 0) codePrevious += 4; else codePrevious += board[moves[i].x1 - 1][moves[i].y1 - 1]; codePrevious += 4 * board[moves[i].x1][moves[i].y1 - 1]; if (moves[i].x1 == BTDx - 1) codePrevious += 16 * 4; else codePrevious += 16 * board[moves[i].x1 + 1][moves[i].y1 - 1]; } } else { if (moves[i].y1 < BTDy - 1) { if (moves[i].x1 == 0) codePrevious += 4; else codePrevious += board[moves[i].x1 - 1][moves[i].y1 + 1]; codePrevious += 4 * board[moves[i].x1][moves[i].y1 + 1]; if (moves[i].x1 == BTDx - 1) codePrevious += 16 * 4; else codePrevious += 16 * board[moves[i].x1 + 1][moves[i].y1 + 1]; } } moves[i].codePrevious = codePrevious * 12 * BTDx * BTDy; } return nb; } int playout(int joueur) { BTMove listeCoups[BTMaxLegalBTMoves]; while (true) { if (terminal()) return (score() > 0); int nb = legalBTMoves(joueur, listeCoups); int n = rand() % nb; play(listeCoups[n]); if (length >= BTMaxPlayoutLength - 20) { return 0; } joueur = opponent(joueur); } } float discountedPlayout(int joueur, int maxLength = BTMaxPlayoutLength - 20) { BTMove listeCoups[BTMaxLegalBTMoves]; while (true) { if (terminal()) { if (score() > 0) return 1.0 / (length + 1); else return -1.0 / (length + 1); } int nb = legalBTMoves(joueur, listeCoups); int n = rand() % nb; play(listeCoups[n]); if (length >= maxLength) { return 0; } joueur = opponent(joueur); } } }; ================================================ FILE: src/games/breakthrough_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "time.h" #include #include #include #include #include "breakthrough.h" //#include "game.h" #include "../core/state.h" #include "fmt/printf.h" const int StateForBreakthroughNumActions = 64 * 3; const int StateForBreakthroughX = 2; const int StateForBreakthroughY = 8; const int StateForBreakthroughZ = 8; const int BTMaxLegalMoves = 48; template class StateForBreakthrough : public core::State, BTBoard { public: StateForBreakthrough(int seed) : State(seed) { } virtual ~StateForBreakthrough() { } virtual void Initialize() override { // People implementing classes should not have much to do in _moves; just // _moves.clear(). _moves.clear(); // std::cout << "OTGBreakthrough initialize" << std::endl; // the features are just one number between 0 and 1 (the distance, // normalized). _featSize[0] = StateForBreakthroughX; _featSize[1] = StateForBreakthroughY; _featSize[2] = StateForBreakthroughZ; // size of the output of the neural network; this should cover the positions // of actions (above). _actionSize[0] = 3; _actionSize[1] = 8; _actionSize[2] = 8; // _hash is an unsigned int, it has to be *unique*. _hash = 0; _status = GameStatus::player0Turn; // std::cout << "restart!" << std::endl; // _features is a vector representing the current state. It can // (must...) be large for complex games; here just one number // between 0 and 1. trivial case in dimension 1. _features.resize(StateForBreakthroughX * StateForBreakthroughY * StateForBreakthroughZ); /* // _features[:_hash] = 1 for (int i = 0; i < DISTANCE; i++) { _features[i] = (float(_hash) > float(i)) ? 1. : 0.; } */ init(); findFeatures(); findActions(White); fillFullFeatures(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } std::string actionDescription(const _Action& action) const override { int dir = action.GetX(); int x = action.GetY(); int y = action.GetZ(); int tx = x; int ty = y + (turn == Black ? 1 : -1); if (dir == 0) { --tx; } else if (dir == 2) { ++tx; } return fmt::sprintf("%c%d%c%d", 'a' + x, BTDy - y, 'a' + tx, BTDy - ty); } void findActions(int color) { BTMove moves[BTMaxLegalMoves]; int nb = legalBTMoves(color, moves); _legalActions.clear(); for (int i = 0; i < nb; i++) { int x = moves[i].x; int y = moves[i].y; int dir = 2; if (moves[i].x1 == x - 1) dir = 0; else if (moves[i].x1 == x) dir = 1; _legalActions.emplace_back(i, dir, x, y); } } void findFeatures() { if ((_status == GameStatus::player0Win) || (_status == GameStatus::player1Win)) return; // init const size_t numFeats = StateForBreakthroughX * StateForBreakthroughY * StateForBreakthroughZ; std::fill(_features.begin(), _features.begin() + numFeats, 0.); for (int i = 0; i < 64; i++) { auto value = fixedPolicy ? board[i / 8][i % 8] : board[i % 8][i / 8]; if (value == Black) _features[i] = 1; else if (value == White) _features[64 + i] = 1; } } // The action just decreases the distance and swaps the turn to play. virtual void ApplyAction(const _Action& action) override { BTMove m; // print(stdout); if (_status == GameStatus::player0Turn) { // White m.color = White; m.x = action.GetY(); m.y = action.GetZ(); if (action.GetX() == 0) { m.x1 = m.x - 1; m.y1 = m.y - 1; } else if (action.GetX() == 1) { m.x1 = m.x; m.y1 = m.y - 1; } else if (action.GetX() == 2) { m.x1 = m.x + 1; m.y1 = m.y - 1; } play(m); findActions(Black); if (won(White)) _status = GameStatus::player0Win; else _status = GameStatus::player1Turn; } else { // Black m.color = Black; m.x = action.GetY(); m.y = action.GetZ(); if (action.GetX() == 0) { m.x1 = m.x - 1; m.y1 = m.y + 1; } else if (action.GetX() == 1) { m.x1 = m.x; m.y1 = m.y + 1; } else if (action.GetX() == 2) { m.x1 = m.x + 1; m.y1 = m.y + 1; } play(m); findActions(White); if (won(Black)) _status = GameStatus::player1Win; else _status = GameStatus::player0Turn; } findFeatures(); _hash = hash; fillFullFeatures(); } // For this trivial example we just compare to random play. Ok, this is not // really a good action. // By the way we need a good default DoGoodAction, e.g. one-ply at least. // FIXME virtual void DoGoodAction() override { int i = rand() % _legalActions.size(); _Action a = _legalActions[i]; ApplyAction(a); } std::string stateDescription() const override { std::string s; for (int i = 0; i < BTDy; i++) { s += std::to_string(BTDy - i); for (int j = 0; j < BTDx; j++) if (board[j][i] == Empty) s += " +"; else if (board[j][i] == Black) s += " @"; else s += " O"; s += " \n"; } s += " a b c d e f g h \n"; return s; } }; ================================================ FILE: src/games/chess.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "chess.h" namespace chess { struct ZobrishHash { std::array, 12 * 12> hash; ZobrishHash() { std::mt19937_64 rng(std::random_device{}() + 42); rng.discard(1024); for (auto& v : hash) { for (auto& v2 : v) { v2 = rng(); } } } }; static inline ZobrishHash zhash; void ChessBoard::init() { board.fill(0); for (int i = 0; i != boardDim; ++i) { board[i] = OOB; board[i + boardDim] = OOB; board[boardDim * i] = OOB; board[boardDim * i + 1] = OOB; board[boardDim * (boardDim - 1) + i] = OOB; board[boardDim * (boardDim - 2) + i] = OOB; board[boardDim * i + boardDim - 1] = OOB; board[boardDim * i + boardDim - 2] = OOB; } board[boardDim * 2 + 2] = WHITE | ROOK; board[boardDim * 2 + 3] = WHITE | KNIGHT; board[boardDim * 2 + 4] = WHITE | BISHOP; board[boardDim * 2 + 5] = WHITE | QUEEN; board[boardDim * 2 + 6] = WHITE | KING; board[boardDim * 2 + 7] = WHITE | BISHOP; board[boardDim * 2 + 8] = WHITE | KNIGHT; board[boardDim * 2 + 9] = WHITE | ROOK; board[boardDim * (boardDim - 3) + 2] = BLACK | ROOK; board[boardDim * (boardDim - 3) + 3] = BLACK | KNIGHT; board[boardDim * (boardDim - 3) + 4] = BLACK | BISHOP; board[boardDim * (boardDim - 3) + 5] = BLACK | QUEEN; board[boardDim * (boardDim - 3) + 6] = BLACK | KING; board[boardDim * (boardDim - 3) + 7] = BLACK | BISHOP; board[boardDim * (boardDim - 3) + 8] = BLACK | KNIGHT; board[boardDim * (boardDim - 3) + 9] = BLACK | ROOK; for (int i = 0; i != 8; ++i) { board[boardDim * 3 + 2 + i] = WHITE | PAWN; board[boardDim * (boardDim - 4) + 2 + i] = BLACK | PAWN; } moveflags = castleleft | castleright; moveflags |= (castleleft | castleright) << 1; turn = 0; moves.clear(); done = false; winner = -1; fiftyMoveCounter = 100; } void ChessBoard::findMoves() { int color = turn; const int ahead = color == 0 ? boardDim : -boardDim; char colorbit = 1 << (5 + color); char opponentcolorbit = 1 << (5 + (color ^ 1)); char occupied = colorbit | OOB; moves.clear(); size_t end = boardDim * (boardDim - 2) - 2; size_t king = 0; for (size_t i = 2 + boardDim * 2; i != end; ++i) { if (board[i] == (colorbit | KING)) { king = i; } } size_t kingx = king % boardDim; size_t kingy = king / boardDim; auto checkcheck = [&]() { uint8_t pawn = opponentcolorbit | PAWN; if ((board[king + ahead + 1] & pawn) == pawn) return true; if ((board[king + ahead - 1] & pawn) == pawn) return true; uint8_t rook = opponentcolorbit | ROOK; for (size_t xx = kingx + 1, ii = king + 1; xx != boardDim - 2; ++xx, ++ii) { if ((board[ii] & rook) == rook) return true; else if (board[ii] != EMPTY) break; } for (size_t xx = kingx - 1, ii = king - 1; xx != 1; --xx, --ii) { if ((board[ii] & rook) == rook) return true; else if (board[ii] != EMPTY) break; } for (size_t xx = kingy - 1, ii = king - boardDim; xx != 1; --xx, ii -= boardDim) { if ((board[ii] & rook) == rook) return true; else if (board[ii] != EMPTY) break; } for (size_t xx = kingy + 1, ii = king + boardDim; xx != boardDim - 2; ++xx, ii += boardDim) { if ((board[ii] & rook) == rook) return true; else if (board[ii] != EMPTY) break; } uint8_t bishop = opponentcolorbit | BISHOP; for (size_t xx = std::min(kingx, kingy) - 1, ii = king - 1 - boardDim; xx != 1; --xx, ii += -1 - boardDim) { if ((board[ii] & bishop) == bishop) return true; else if (board[ii] != EMPTY) break; } for (size_t xx = std::min(kingx, boardDim - 1 - kingy) - 1, ii = king - 1 + boardDim; xx != 1; --xx, ii += -1 + boardDim) { if ((board[ii] & bishop) == bishop) return true; else if (board[ii] != EMPTY) break; } for (size_t xx = std::min(boardDim - 1 - kingx, boardDim - 1 - kingy) - 1, ii = king + 1 + boardDim; xx != 1; --xx, ii += 1 + boardDim) { if ((board[ii] & bishop) == bishop) return true; else if (board[ii] != EMPTY) break; } for (size_t xx = std::min(boardDim - 1 - kingx, kingy) - 1, ii = king + 1 - boardDim; xx != 1; --xx, ii += 1 - boardDim) { if ((board[ii] & bishop) == bishop) return true; else if (board[ii] != EMPTY) break; } uint8_t knight = opponentcolorbit | KNIGHT; if (board[king + ahead + ahead - 1] == knight) return true; if (board[king + ahead + ahead + 1] == knight) return true; if (board[king - ahead - ahead - 1] == knight) return true; if (board[king - ahead - ahead + 1] == knight) return true; if (board[king - 1 - 1 - ahead] == knight) return true; if (board[king - 1 - 1 + ahead] == knight) return true; if (board[king + 1 + 1 - ahead] == knight) return true; if (board[king + 1 + 1 + ahead] == knight) return true; return false; }; for (size_t i = 2 + boardDim * 2; i != end; ++i) { if ((board[i] & colorbit) == 0) continue; int piece = board[i] & 0xf; unsigned char* relative = &board[i]; auto check = [&](size_t to) { auto dst = board[to]; auto src = board[i]; board[to] = src; board[i] = EMPTY; bool r; if (piece == KING) { uint8_t knight = opponentcolorbit | KNIGHT; uint8_t pawn = opponentcolorbit | PAWN; if ((board[to + ahead] & 0xf) == KING) r = true; else if ((board[to + ahead + 1] & pawn) == pawn) r = true; else if ((board[to + ahead - 1] & pawn) == pawn) r = true; else if ((board[to + 1] & 0xf) == KING) r = true; else if ((board[to - 1] & 0xf) == KING) r = true; else if ((board[to - ahead] & 0xf) == KING) r = true; else if ((board[to - ahead + 1] & 0xf) == KING) r = true; else if ((board[to - ahead - 1] & 0xf) == KING) r = true; else if (board[to + ahead + ahead - 1] == knight) r = true; else if (board[to + ahead + ahead + 1] == knight) r = true; else if (board[to - ahead - ahead - 1] == knight) r = true; else if (board[to - ahead - ahead + 1] == knight) r = true; else if (board[to - 1 - 1 - ahead] == knight) r = true; else if (board[to - 1 - 1 + ahead] == knight) r = true; else if (board[to + 1 + 1 - ahead] == knight) r = true; else if (board[to + 1 + 1 + ahead] == knight) r = true; else { king = to; kingx = to % boardDim; kingy = to / boardDim; r = checkcheck(); king = i; kingx = i % boardDim; kingy = i / boardDim; } } else { r = checkcheck(); } board[i] = src; board[to] = dst; return r; }; auto addMove = [&](size_t to) { if (!check(to)) { if (piece == PAWN && relative[ahead + ahead] == OOB) { moves.push_back(i | (to << 17)); moves.push_back(i | (to << 17) | 0x8000); moves.push_back(i | (to << 17) | 0x10000); moves.push_back(i | (to << 17) | 0x18000); } else { moves.push_back(i | (to << 17)); } } }; auto test = [&](size_t to) { board.at(i + to); if ((relative[to] & occupied) == 0) { addMove(i + to); return true; } else { return false; } }; auto tryMove = [&](size_t to) { board.at(to); int v = board[to]; if (v != EMPTY) { if (v & occupied) return false; addMove(to); return false; } addMove(to); return true; }; switch (piece) { case PAWN: if (relative[ahead] == EMPTY) { addMove(i + ahead); if (color == 0 ? i - boardDim * 3 < boardDim : i - boardDim * (boardDim - 4) < boardDim) { if (relative[ahead + ahead] == EMPTY && !check(i + ahead + ahead)) { moves.push_back(i | 0x8000 | ((i + ahead + ahead) << 17)); } } } if ((relative[ahead + 1] & opponentcolorbit) == opponentcolorbit) { addMove(i + ahead + 1); } if ((relative[ahead - 1] & opponentcolorbit) == opponentcolorbit) { addMove(i + ahead - 1); } if (moveflags & 0x8000) { size_t x = moveflags & 0x7fff; if (i + 1 == x) { int tmp = board[i + 1]; board[i + 1] = EMPTY; if (!check(i + ahead + 1)) { moves.push_back(i | 0x10000 | ((i + ahead + 1) << 17)); } board[i + 1] = tmp; } else if (i - 1 == x) { int tmp = board[i - 1]; board[i - 1] = EMPTY; if (!check(i + ahead - 1)) { moves.push_back(i | 0x10000 | ((i + ahead - 1) << 17)); } board[i - 1] = tmp; } } break; case KNIGHT: test(ahead + ahead + 1); test(ahead + ahead - 1); test(-ahead - ahead - 1); test(-ahead - ahead + 1); test(-1 - 1 - ahead); test(-1 - 1 + ahead); test(+1 + 1 - ahead); test(+1 + 1 + ahead); break; case KING: test(ahead); test(ahead + 1); test(ahead - 1); test(1); test(-1); test(-ahead); test(-ahead + 1); test(-ahead - 1); if ((moveflags & (castleleft << turn)) && !checkcheck()) { size_t x = i % boardDim; for (size_t xx = x - 1, ii = i - 1;; --xx, --ii) { if (xx == 2) { if (!check(i - 1) && !check(i - 2)) { moves.push_back(i | 0x8000 | ((i - 1 - 1) << 17)); } break; } if (board[ii] != EMPTY) break; } } if ((moveflags & (castleright << turn)) && !checkcheck()) { size_t x = i % boardDim; for (size_t xx = x + 1, ii = i + 1;; ++xx, ++ii) { if (xx == boardDim - 3) { if (!check(i + 1) && !check(i + 2)) { moves.push_back(i | 0x8000 | ((i + 1 + 1) << 17)); } break; } if (board[ii] != EMPTY) break; } } break; default: size_t x = i % boardDim; size_t y = i / boardDim; switch (piece) { case QUEEN: case ROOK: for (size_t xx = x + 1, ii = i + 1; xx != boardDim - 2 && tryMove(ii); ++xx, ++ii) ; for (size_t xx = x - 1, ii = i - 1; xx != 1 && tryMove(ii); --xx, --ii) ; for (size_t xx = y - 1, ii = i - boardDim; xx != 1 && tryMove(ii); --xx, ii -= boardDim) ; for (size_t xx = y + 1, ii = i + boardDim; xx != boardDim - 2 && tryMove(ii); ++xx, ii += boardDim) ; if (piece != QUEEN) break; [[fallthrough]]; case BISHOP: for (size_t xx = std::min(x, y) - 1, ii = i - 1 - boardDim; xx != 1 && tryMove(ii); --xx, ii += -1 - boardDim) ; for (size_t xx = std::min(x, boardDim - 1 - y) - 1, ii = i - 1 + boardDim; xx != 1 && tryMove(ii); --xx, ii += -1 + boardDim) ; for (size_t xx = std::min(boardDim - 1 - x, boardDim - 1 - y) - 1, ii = i + 1 + boardDim; xx != 1 && tryMove(ii); --xx, ii += 1 + boardDim) ; for (size_t xx = std::min(boardDim - 1 - x, y) - 1, ii = i + 1 - boardDim; xx != 1 && tryMove(ii); --xx, ii += 1 - boardDim) ; break; } } } if (moves.empty()) { done = true; if (checkcheck()) { winner = turn ^ 1; } } else if (fiftyMoveCounter <= 0) { done = true; winner = -1; } } void ChessBoard::move(uint_fast32_t move) { size_t to = move >> 17; size_t from = move & 0x7fff; int v = board[from]; int piece = v & 0xf; --fiftyMoveCounter; switch (piece) { case KING: moveflags &= ~((castleleft | castleright) << turn); break; case ROOK: { size_t x = from % boardDim; size_t y = from / boardDim; if (x == 2 || x == boardDim - 3) { if (y == (turn == 0 ? 2 : boardDim - 3)) { if (x == 2) moveflags &= ~(castleleft << turn); else moveflags &= ~(castleright << turn); } } break; } case PAWN: fiftyMoveCounter = 100; for (auto& v : repetitions) { v.clear(); } if (board[to + (turn == 0 ? boardDim : -boardDim)] == OOB) { v &= ~PAWN; switch ((move >> 15) & 3) { case 0: v |= QUEEN; break; case 1: v |= ROOK; break; case 2: v |= BISHOP; break; case 3: v |= KNIGHT; break; } move = 0; } break; } moveflags &= ~0xffff; if ((move & 0x8000) != 0) { if (piece == PAWN) { moveflags |= to | 0x8000; } else if (piece == KING) { size_t y = from / boardDim; if (to < from) { std::swap(board[y * boardDim + 2], board[to + 1]); } else { std::swap(board[y * boardDim + boardDim - 3], board[to - 1]); } } } else { if ((move & 0x10000) != 0) { int dx = to % boardDim - from % boardDim; board.at(from + dx) = EMPTY; fiftyMoveCounter = 100; for (auto& v : repetitions) { v.clear(); } } } if (board[to] != EMPTY) { fiftyMoveCounter = 100; for (auto& v : repetitions) { v.clear(); } } if ((board[to] & 0xf) == ROOK) { size_t x = to % boardDim; size_t y = to / boardDim; if (x == 2 || x == boardDim - 3) { if (y == (turn == 1 ? 2 : boardDim - 3)) { if (x == 2) moveflags &= ~(castleleft << (turn ^ 1)); else moveflags &= ~(castleright << (turn ^ 1)); } } } hash ^= zhash.hash.at(from).at(13 * turn + piece); hash ^= zhash.hash.at(to).at(13 * turn + piece); board[from] = EMPTY; board[to] = v; turn ^= 1; uint64_t fullhash = hash ^ moveflags ^ zhash.hash.at(5).at(turn); size_t index = fullhash % repetitions.size(); bool found = false; for (auto& v : repetitions[index]) { if (v.first == fullhash) { ++v.second; if (v.second >= 3) { done = true; winner = -1; } found = true; break; } } if (!found) { repetitions[index].emplace_back(fullhash, 1); } } std::string ChessBoard::moveString(uint_fast32_t move) const { size_t from = move & 0x7fff; size_t fx = from % boardDim - 2; size_t fy = from / boardDim - 2; size_t to = move >> 17; size_t tx = to % boardDim - 2; size_t ty = to / boardDim - 2; int piece = board[from]; bool disx = false; bool disy = false; for (auto& v : moves) { size_t vfrom = v & 0x7fff; size_t vto = v >> 17; if (vfrom != from && board[vfrom] == piece && vto == to) { size_t vx = vfrom % boardDim - 2; if (vx == fx) { disy = true; } else { disx = true; } } } std::string str; switch (piece & 0xf) { case KNIGHT: str += 'N'; break; case BISHOP: str += 'B'; break; case ROOK: str += 'R'; break; case QUEEN: str += 'Q'; break; case KING: str += 'K'; break; } bool promotion = false; if ((piece & 0xf) == PAWN) { if (board[to + (turn == 0 ? boardDim : -boardDim)] == OOB) { promotion = true; } } else if ((piece & 0xf) == KING) { if ((move & 0x8000) != 0) { if (to < from) { return "O-O-O"; } else { return "O-O"; } } } bool capture = board[to] != EMPTY; if (!promotion && (move & 0x10000) != 0) { capture = true; } if (capture && str.empty()) { disx = true; } if (disx) { str += char('a' + fx); } if (disy) { str += char('1' + fy); } if (capture != EMPTY) { str += 'x'; } str += char('a' + tx); str += char('1' + ty); if (promotion) { switch ((move >> 15) & 3) { case 0: str += "=Q"; break; case 1: str += "=R"; break; case 2: str += "=B"; break; case 3: str += "=N"; break; } } return str; } } // namespace chess ================================================ FILE: src/games/chess.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include "../core/state.h" namespace chess { struct ChessBoard { static const size_t boardSize = 8; static const size_t boardDim = boardSize + 4; std::array board; std::vector moves; uint_fast32_t moveflags = 0; std::array>, 16> repetitions; uint64_t hash = 0; static const uint32_t castleleft = 1u << 28; static const uint32_t castleright = 1u << 30; int turn = 0; static const uint8_t EMPTY = 0; static const uint8_t PAWN = 1; static const uint8_t KNIGHT = 2; static const uint8_t BISHOP = 4; static const uint8_t ROOK = 8; static const uint8_t QUEEN = 12; static const uint8_t KING = 3; static const uint8_t OOB = 0x80; static const uint8_t WHITE = 1 << 5; static const uint8_t BLACK = 2 << 5; void init(); void findMoves(); void move(uint_fast32_t move); std::string moveString(uint_fast32_t move) const; bool done = false; int winner = -1; int fiftyMoveCounter = 0; }; class State : public core::State { public: State(int seed) : core::State(seed) { } ChessBoard board; std::vector moves; static const int boardSize = 8; virtual void Initialize() override { _moves.clear(); _hash = 2166136261u; _status = GameStatus::player0Turn; _featSize[0] = 12; _featSize[1] = boardSize; _featSize[2] = boardSize; _actionSize[0] = 6; _actionSize[1] = boardSize; _actionSize[2] = boardSize; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); std::fill(_features.begin(), _features.end(), 0.0f); board.init(); board.findMoves(); featurize(); findActions(); fillFullFeatures(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } virtual std::string stateDescription() const override { std::string str; const size_t boardDim = 8 + 4; int y = 8; for (size_t iy = 2 + boardDim * 2;;) { str += '0' + y; --y; str += ' '; size_t ii = (boardDim - 1 - iy / boardDim) * boardDim + 2; for (size_t i = 0; i != 8; ++i, ++ii) { int v = board.board[ii]; if (v & ChessBoard::WHITE) { switch (v & 0xf) { case ChessBoard::PAWN: str += 'P'; break; case ChessBoard::KNIGHT: str += 'N'; break; case ChessBoard::BISHOP: str += 'B'; break; case ChessBoard::ROOK: str += 'R'; break; case ChessBoard::QUEEN: str += 'Q'; break; case ChessBoard::KING: str += 'K'; break; default: str += '.'; } } else { switch (v & 0xf) { case ChessBoard::PAWN: str += 'p'; break; case ChessBoard::KNIGHT: str += 'n'; break; case ChessBoard::BISHOP: str += 'b'; break; case ChessBoard::ROOK: str += 'r'; break; case ChessBoard::QUEEN: str += 'q'; break; case ChessBoard::KING: str += 'k'; break; default: str += '.'; } } str += ' '; } str += '\n'; iy += 8 + 2; if (iy == 12 + boardDim * 9) { break; } iy += 2; } str += " a b c d e f g h"; return str; } virtual std::string actionDescription(const _Action& action) const override { auto move = board.moves.at(action.GetIndex()); return board.moveString(move); } void featurize() { const size_t boardDim = 8 + 4; size_t findex = 0; std::fill(_features.begin(), _features.begin() + boardSize * boardSize * 12, 0.0f); for (size_t ii = 2 + boardDim * 2;;) { for (size_t i = 0; i != 8; ++i, ++ii) { int v = board.board[ii]; if (v) { size_t offset = 0; switch (v & 0xf) { case ChessBoard::PAWN: offset = 0; break; case ChessBoard::KNIGHT: offset = 1; break; case ChessBoard::BISHOP: offset = 2; break; case ChessBoard::ROOK: offset = 3; break; case ChessBoard::QUEEN: offset = 4; break; case ChessBoard::KING: offset = 5; break; } if (v & ChessBoard::BLACK) { offset += 6; } _features[boardSize * boardSize * offset + findex] = 1.0f; } ++findex; } ii += 2; if (ii == 12 + boardDim * 9) { break; } ii += 2; } } void findActions() { clearActions(); const size_t boardDim = 12; for (auto move : board.moves) { size_t to = move >> 17; size_t from = move & 0x7fff; int v = board.board[from]; size_t offset = 0; switch (v & 0xf) { case ChessBoard::PAWN: offset = 0; break; case ChessBoard::KNIGHT: offset = 1; break; case ChessBoard::BISHOP: offset = 2; break; case ChessBoard::ROOK: offset = 3; break; case ChessBoard::QUEEN: offset = 4; break; case ChessBoard::KING: offset = 5; break; } size_t x = to % boardDim - 2; size_t y = to / boardDim - 2; addAction(offset, y, x); } } virtual void ApplyAction(const _Action& action) override { auto move = board.moves.at(action.GetIndex()); board.move(move); board.findMoves(); findActions(); if (board.done) { if (board.winner == 0) { _status = GameStatus::player0Win; } else if (board.winner == 1) { _status = GameStatus::player1Win; } else { _status = GameStatus::tie; } } else { _status = board.turn == 0 ? GameStatus::player0Turn : GameStatus::player1Turn; featurize(); } fillFullFeatures(); } virtual void DoGoodAction() override { return DoRandomAction(); } }; } // namespace chess ================================================ FILE: src/games/chinesecheckers.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 葉士誠 (SHI-CHENG YE) // affiliation: National Dong Hwa University(NDHU) // email: 410521206@gms.ndhu.edu.tw / 0930164@gmail.com #include "chinesecheckers.h" namespace ChineseCheckers { string Board::sprintBoard(string_view prefix, const set>& markedPos) const { prefix.data(); // ignore compile warning assert(markedPos.size() == 0UL); // ignore compile warning return showBoard(false); } string Board::getPosStr(int p) const { assert(isPosInBoard(p)); int tp = p % 10 + 1; string curPOS = to_string(tp); if (p / 10 > 5) { tp = (p - 60) % 61 + 1; curPOS = to_string(tp); return tp + 1 > 10 ? "G" + curPOS : "G0" + curPOS; } else { switch (p / 10) { case 0: return tp + 1 > 10 ? "A" + curPOS : "A0" + curPOS; case 1: return tp + 1 > 10 ? "B" + curPOS : "B0" + curPOS; case 2: return tp + 1 > 10 ? "C" + curPOS : "C0" + curPOS; case 3: return tp + 1 > 10 ? "D" + curPOS : "D0" + curPOS; case 4: return tp + 1 > 10 ? "E" + curPOS : "E0" + curPOS; case 5: return tp + 1 > 10 ? "F" + curPOS : "F0" + curPOS; default: tp = (p - 60) % 61 + 1; curPOS = to_string(tp); return tp + 1 > 10 ? "G" + curPOS : "G0" + curPOS; } } } string Board::showBoard(bool prePlay) const { ostringstream ostr; auto f = [&](bool prePlay, int p) { string_view sv; ostringstream ostr; if (!prePlay && p != pass) { // show cur board sv = getChessSymbol(getChess(p)); } else { // show legal move board if (find(legal.begin(), legal.end(), p) != legal.end()) { if (p == pass) sv = "You can input \"p\" or \"pass\"to pass\n"; else sv = getPosStr(p); } else sv = getChessSymbol(Chesses::empty); } ostr << sv; return ostr.str(); }; ostr << " A\n"; ostr << " " << f(prePlay, P_A1).c_str() << endl; ostr << " / \\\n"; ostr << " " << f(prePlay, P_A2).c_str() << "-" << f(prePlay, P_A3).c_str() << endl; ostr << " / \\ / \\\n"; ostr << " " << f(prePlay, P_A4).c_str() << "-" << f(prePlay, P_A5).c_str() << "-" << f(prePlay, P_A6).c_str() << endl; ostr << " / \\ / \\ / \\\n"; ostr << " " << f(prePlay, P_A7).c_str() << "-" << f(prePlay, P_A8).c_str() << "-" << f(prePlay, P_A9).c_str() << "-" << f(prePlay, P_A10).c_str() << endl; ostr << "F / \\ / \\ / \\ / \\ B\n"; ostr << " " << f(prePlay, P_F1).c_str() << "-" << f(prePlay, P_F3).c_str() << "-" << f(prePlay, P_F6).c_str() << "-" << f(prePlay, P_F10).c_str() << "-" << f(prePlay, P_G1).c_str() << "-" << f(prePlay, P_G2).c_str() << "-" << f(prePlay, P_G3).c_str() << "-" << f(prePlay, P_G4).c_str() << "-" << f(prePlay, P_G5).c_str() << "-" << f(prePlay, P_B7).c_str() << "-" << f(prePlay, P_B4).c_str() << "-" << f(prePlay, P_B2).c_str() << "-" << f(prePlay, P_B1).c_str() << endl; ostr << " \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ /\n"; ostr << " " << f(prePlay, P_F2).c_str() << "-" << f(prePlay, P_F5).c_str() << "-" << f(prePlay, P_F9).c_str() << "-" << f(prePlay, P_G6).c_str() << "-" << f(prePlay, P_G7).c_str() << "-" << f(prePlay, P_G8).c_str() << "-" << f(prePlay, P_G9).c_str() << "-" << f(prePlay, P_G10).c_str() << "-" << f(prePlay, P_G11).c_str() << "-" << f(prePlay, P_B8).c_str() << "-" << f(prePlay, P_B5).c_str() << "-" << f(prePlay, P_B3).c_str() << endl; ostr << " \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ /\n"; ostr << " " << f(prePlay, P_F4).c_str() << "-" << f(prePlay, P_F8).c_str() << "-" << f(prePlay, P_G12).c_str() << "-" << f(prePlay, P_G13).c_str() << "-" << f(prePlay, P_G14).c_str() << "-" << f(prePlay, P_G15).c_str() << "-" << f(prePlay, P_G16).c_str() << "-" << f(prePlay, P_G17).c_str() << "-" << f(prePlay, P_G18).c_str() << "-" << f(prePlay, P_B9).c_str() << "-" << f(prePlay, P_B6).c_str() << endl; ostr << " \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ /\n"; ostr << " " << f(prePlay, P_F7).c_str() << "-" << f(prePlay, P_G19).c_str() << "-" << f(prePlay, P_G20).c_str() << "-" << f(prePlay, P_G21).c_str() << "-" << f(prePlay, P_G22).c_str() << "-" << f(prePlay, P_G23).c_str() << "-" << f(prePlay, P_G24).c_str() << "-" << f(prePlay, P_G25).c_str() << "-" << f(prePlay, P_G26).c_str() << "-" << f(prePlay, P_B10).c_str() << endl; ostr << " \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ /\n"; ostr << " " << f(prePlay, P_G27).c_str() << "-" << f(prePlay, P_G28).c_str() << "-" << f(prePlay, P_G29).c_str() << "-" << f(prePlay, P_G30).c_str() << "-" << f(prePlay, P_G31).c_str() << "-" << f(prePlay, P_G32).c_str() << "-" << f(prePlay, P_G33).c_str() << "-" << f(prePlay, P_G34).c_str() << "-" << f(prePlay, P_G35).c_str() << endl; ostr << " / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\\n"; ostr << " " << f(prePlay, P_E10).c_str() << "-" << f(prePlay, P_G36).c_str() << "-" << f(prePlay, P_G37).c_str() << "-" << f(prePlay, P_G38).c_str() << "-" << f(prePlay, P_G39).c_str() << "-" << f(prePlay, P_G40).c_str() << "-" << f(prePlay, P_G41).c_str() << "-" << f(prePlay, P_G42).c_str() << "-" << f(prePlay, P_G43).c_str() << "-" << f(prePlay, P_C7).c_str() << endl; ostr << " / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\\n"; ostr << " " << f(prePlay, P_E6).c_str() << "-" << f(prePlay, P_E9).c_str() << "-" << f(prePlay, P_G44).c_str() << "-" << f(prePlay, P_G45).c_str() << "-" << f(prePlay, P_G46).c_str() << "-" << f(prePlay, P_G47).c_str() << "-" << f(prePlay, P_G48).c_str() << "-" << f(prePlay, P_G49).c_str() << "-" << f(prePlay, P_G50).c_str() << "-" << f(prePlay, P_C8).c_str() << "-" << f(prePlay, P_C4).c_str() << endl; ostr << " / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\\n"; ostr << " " << f(prePlay, P_E3).c_str() << "-" << f(prePlay, P_E5).c_str() << "-" << f(prePlay, P_E8).c_str() << "-" << f(prePlay, P_G51).c_str() << "-" << f(prePlay, P_G52).c_str() << "-" << f(prePlay, P_G53).c_str() << "-" << f(prePlay, P_G54).c_str() << "-" << f(prePlay, P_G55).c_str() << "-" << f(prePlay, P_G56).c_str() << "-" << f(prePlay, P_C9).c_str() << "-" << f(prePlay, P_C5).c_str() << "-" << f(prePlay, P_C2).c_str() << endl; ostr << " / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\\n"; ostr << " " << f(prePlay, P_E1).c_str() << "-" << f(prePlay, P_E2).c_str() << "-" << f(prePlay, P_E4).c_str() << "-" << f(prePlay, P_E7).c_str() << "-" << f(prePlay, P_G57).c_str() << "-" << f(prePlay, P_G58).c_str() << "-" << f(prePlay, P_G59).c_str() << "-" << f(prePlay, P_G60).c_str() << "-" << f(prePlay, P_G61).c_str() << "-" << f(prePlay, P_C10).c_str() << "-" << f(prePlay, P_C6).c_str() << "-" << f(prePlay, P_C3).c_str() << "-" << f(prePlay, P_C1).c_str() << endl; ostr << "E \\ / \\ / \\ / \\ / C\n"; ostr << " " << f(prePlay, P_D10).c_str() << "-" << f(prePlay, P_D9).c_str() << "-" << f(prePlay, P_D8).c_str() << "-" << f(prePlay, P_D7).c_str() << endl; ostr << " \\ / \\ / \\ /\n"; ostr << " " << f(prePlay, P_D6).c_str() << "-" << f(prePlay, P_D5).c_str() << "-" << f(prePlay, P_D4).c_str() << endl; ostr << " \\ / \\ /\n"; ostr << " " << f(prePlay, P_D3).c_str() << "-" << f(prePlay, P_D2).c_str() << endl; ostr << " \\ /\n"; ostr << " " << f(prePlay, P_D1).c_str() << endl; ostr << " D\n"; ostr << f(prePlay, pass); return ostr.str(); } void Game::initialize() { board.initialize(); setInitialChesses(); hands = 0; prePos = -1; preChess = -1; continue_jump = false; winner = -1; legalMoves.clear(); way.clear(); } void Game::setInitialChesses() { Chess chess; for (int i = 0; i < boardWH * boardWH; i++) { if (i >= P_A1 && i <= P_A10) chess = Chesses::White; else if (i >= P_D1 && i <= P_D10) chess = Chesses::Black; else chess = Chesses::empty; board.setChess(i, chess); } } void Game::play(Move& m) { if (hands >= maxHands) fprintf(stderr, "hand %d out of range 0~%d", hands, maxHands - 1); assert(m.chess == board.getChess(m.x)); board.setChess(m.x, Chesses::empty); board.setChess(m.tx, m.chess); way.push_back(m); } bool Game::Won() { bool win = true; for (int i = P_D1; i <= P_D10; i++) if (board.getChess(i) != Chesses::White) { win = false; break; } if (win) { winner = Players::player0; return true; } win = true; for (int i = P_A1; i <= P_A10; i++) if (board.getChess(i) != Chesses::Black) { win = false; break; } if (win) { winner = Players::player1; return true; } return false; } void Game::findLegalMoves(Player player) { legalMoves.clear(); Chess chess = playerToChess(player); for (int i = 0; i < boardWH * boardWH; i++) if (board.getChess(i) == chess) { LegalMove(i, chess, true); LegalMove(i, chess, false); } } void Game::LegalMove(int cur, Chess chess, bool isJump) { Move m = Move{}; m.x = cur; m.chess = chess; m.method = isJump ? 1 : 0; // byJump is decide to whether change method, cur is transform from (x,y): // 2D -> 1D int next, byJump = isJump ? 6 : 0; for (int md = M_LU + byJump; md <= M_RD + byJump; md++) { next = canGo(cur, md, chess); if (next >= 0 && next <= 120) { m.tx = next; legalMoves.push_back(m); } } } int Game::canGo(int cur, int md, Chess chess) { // six direction, two method, refer to define in ChineseCheckers_graph.h // md%6 is take pure direction int dirct = md % 6, next; bool isJump = md / 6 == 1; if (cur >= 0 && cur <= 120 && board.getChess(cur) == chess) { // check choose right chess next = isJump ? JumpOBS(cur, dirct) : move_table[cur][dirct]; if (next >= 0 && next <= 120 && board.getChess(next) == Chesses::empty) return next; return -1; } return -1; } int Game::JumpOBS(int cur, int dirct) { for (int step = 1; step <= 6; step++) { // up to six steps, or it'll jump outside cur = move_table[cur][dirct]; if (cur >= 0 && cur <= 120) { if (board.getChess(cur) != Chesses::empty) { // find one obstacle for (int j = 0; j < step; j++) { cur = move_table[cur][dirct]; if (cur >= 0 && cur <= 120) { if (board.getChess(cur) != Chesses::empty) { return -1; // find >2 obstacles -> can't jump } } else { return -1; // out of chessboard } } return cur; } } else { return -1; // out of chessboard } } return -1; // must out of range } template void Game::setupBoard(const R& re) { Board::setup({"Empty", "White", "Black"}, {" ", " ● ", " ○ "}, re); } constexpr Player Game::chessToPlayer(Chess chess) { if (chess == Chesses::White) return Players::player0; else if (chess == Chesses::Black) return Players::player1; assert(chess == Chesses::White || chess == Chesses::Black); return -1; } constexpr Chess Game::playerToChess(Player player) { if (player == Players::player0) return Chesses::White; else if (player == Players::player1) return Chesses::Black; assert(player == Players::player0 || player == Players::player1); return 0xFF; } State::State(int seed) : core::State(seed) , Game() { // fprintf(stderr,"State(int seed)\n"); call_once(setupCalled, [&] { setupBoard(_rng); }); } void State::Initialize() { // fprintf(stderr,"Initialize()\n"); _moves.clear(); _featSize[0] = featuresSizeX; _featSize[1] = featuresSizeY; _featSize[2] = featuresSizeZ; _actionSize[0] = 3; // move + jump + pass _actionSize[1] = boardWH * boardWH; _actionSize[2] = boardWH * boardWH; _status = GameStatus::player0Turn; _features.resize(featuresSize); initialize(); findLegalMoves(Players::player0); findActions(); findFeatures(); _hash = board.getHash(); } unique_ptr State::clone_() const { // fprintf(stderr,"clone_()\n"); return make_unique(*this); } void State::ApplyAction(const _Action& action) { // fprintf(stderr,"ApplyAction()\n"); if (!terminated()) { Move m{}; Player Player = -1; // player0 plays white (●), player1 plays black (○) if (_status == GameStatus::player0Turn) { m.chess = Chesses::White; Player = Players::player0; } else if (_status == GameStatus::player1Turn) { m.chess = Chesses::Black; Player = Players::player1; } m.x = action.GetY(); m.tx = action.GetZ(); m.method = action.GetX(); // check pass hand if (action.GetX() == 2) { if (canChange(Player)) { findActions(); findFeatures(); } } else { play(m); legalMoves.clear(); if (m.method == 1) { // jump LegalMove(m.tx, m.chess, m.method); } if (legalMoves.empty()) { // move or no more jump if (canChange(Player)) { continue_jump = false; findActions(); findFeatures(); } } else { legalMoves.push_back(Pass); findActions(); continue_jump = true; } } } _hash = board.getHash(); } Player State::changeTurn(Player player) { Player nextPlayer = -1; if (player == Players::player1) { nextPlayer = Players::player0; _status = GameStatus::player0Turn; } else if (player == Players::player0) { nextPlayer = Players::player1; _status = GameStatus::player1Turn; } hands += 1; board.turnHash(); way.clear(); return nextPlayer; } bool State::canChange(Player player) { // fprintf(stderr,"canGoNext()\n"); Player nextPlayer = changeTurn(player); if (Won()) { if (winner == Players::player1) _status = GameStatus::player1Win; else if (winner == Players::player0) _status = GameStatus::player0Win; else assert(winner == Players::player1 || winner == Players::player0); return false; } if (hands >= maxHands) { _status = GameStatus::tie; return false; } findLegalMoves(nextPlayer); assert(!legalMoves.empty()); return true; } void State::findActions() { // fprintf(stderr,"findActions()\n"); clearActions(); for (auto& m : legalMoves) { if (m.x != pass && m.tx != pass) { addAction(m.method, m.x, m.tx); } else { addAction(2, 0, 0); } } } void State::findFeatures() { // fprintf(stderr,"findFeatures()\n"); std::fill(_features.begin(), _features.end(), 0.0); auto* f = _features.data(); for (size_t c = 0; c < chesses; c++) { Chess chess = static_cast(c + 1); for (int i = 0; i < boardWH * boardWH; i++) { if (board.getChess(i) == chess) *f = 1.0; f++; } } fillFullFeatures(); } void State::DoGoodAction() { // fprintf(stderr,"DoGoodAction()\n"); // DoRandomAction(); assert(!_legalActions.empty()); std::uniform_int_distribution distr(0, _legalActions.size() - 1); size_t i = distr(_rng); _Action a = _legalActions[i]; int cur = a.GetY(), next = a.GetZ(); Chess chess = board.getChess(cur); while (prePos == next && preChess == chess) { std::uniform_int_distribution distr(0, _legalActions.size() - 1); // size_t i = distr(_rng); //_Action a = _legalActions[i]; } prePos = cur; preChess = chess; ApplyAction(a); } void State::printCurrentBoard() const { // fprintf(stderr,"printCurrentBoard()\n"); cout << board.sprint(" "); } string State::stateDescription() const { // fprintf(stderr,"stateDescription()\n"); return board.sprint(" "); } string State::actionDescription(const ::_Action& action) const { ostringstream ostr; if (continue_jump) ostr << "\t"; int cur = way.front().x, goal = action.GetZ(), method = action.GetX(); if (method == 2) { ostr << " <-Pass-> "; goal = way[way.size() - 2].tx; } else if (method == 0) ostr << "move from "; else ostr << "jump from "; ostr << board.getPosStr(cur) << " to " << board.getPosStr(goal); return ostr.str(); } string State::actionsDescription() const { // fprintf(stderr,"actionsDescription()\n"); ostringstream ostr; auto board = this->board; board.legal.clear(); for (auto& m : legalMoves) { board.legal.push_back(m.x); } ostr << "Chesses which can move:\n" << board.showBoard(true); return ostr.str(); } int State::parseAction(const string& str) const { auto parse = [&](const string& s, int& x) { if (s == "pass" || s == "p") { x = pass; return true; } int pos = -1, len = 0; for (size_t i = 0; i < s.size(); i++) { if (!isalnum(s[i]) && pos >= 0) break; if (isalnum(s[i])) { if (pos < 0) pos = (int)i; len += 1; } } if (len == 0 || pos < 0) return false; string ts = s.substr(pos, len); if (ts.size() < 2) return false; else if (!isalpha(ts[0])) return false; string num = ts.substr(1, ts.size() - 1); int n = 0; for (char c : num) { if (!isdigit(c)) return false; n = c - '0' + n * 10; } char c = toupper(s[0]); if (c >= 'A' && c <= 'F') { if (n <= 0 || n >= 11) return false; n--; } if (c == 'G') { if (n <= 0 || n >= 62) return false; n--; } switch (c) { case 'A': n += 0; break; case 'B': n += 10; break; case 'C': n += 20; break; case 'D': n += 30; break; case 'E': n += 40; break; case 'F': n += 50; break; case 'G': n += 60; break; default: return false; } x = n; return true; }; int cur = -1, goal = -1; if (!parse(str, cur)) return -1; auto board = this->board; board.legal.clear(); bool found = false; for (auto& m : legalMoves) { if (m.x == cur) { board.legal.push_back(m.tx); found = true; } } if (!found) { cout << "Error! No any legal move." << endl; return -1; } if (cur != pass) { cout << board.showBoard(true); cout << "Where you wanna go:" << endl << "> "; string input; cin >> input; if (!parse(input, goal)) return -1; } auto& legalActions = GetLegalActions(); for (size_t i = 0; i < legalActions.size(); i++) { if (cur == pass) { if (legalActions[i].GetX() == 2) { return (int)i; } } else { if (legalActions[i].GetY() == cur && legalActions[i].GetZ() == goal) return (int)i; } } return -1; } int State::humanInputAction(function(string)> specialAction) { cout << "hands: " << hands << endl; cout << "Current Board:" << endl << stateDescription() << endl; cout << actionsDescription() << endl; cout << "Please choose chess and move to where: "; cout << "(Use \"a01\", \"B5\",\"C10\", etc. to correspond to the correct " "format in " "chess board)" << endl; string input; int index = -1; size_t max = GetLegalActions().size(); while (index < 0 || index >= (int)max) { cout << "Chess you choose is:" << endl << "> "; cin >> input; index = parseAction(input); if (index == -1) { if (auto r = specialAction(input); r) { return *r; } } if (index < 0 || index >= (int)max) { cout << "This is invalid Input! Please try again." << endl; cout << "Current Board:" << endl << stateDescription() << endl; cout << actionsDescription() << endl; } } return index; } } // namespace ChineseCheckers ================================================ FILE: src/games/chinesecheckers.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 葉士誠 (SHI-CHENG YE) // affiliation: National Dong Hwa University(NDHU) // email: 410521206@gms.ndhu.edu.tw / 0930164@gmail.com #pragma once #include #include #include #include #include #include #include "../core/state.h" #include "chinesecheckers_defines.h" #include "commons/chessboard.h" using namespace std; namespace ChineseCheckers { typedef int Player; class Players { public: static constexpr Player player0 = 0; static constexpr Player player1 = 1; }; class Chesses { // define Chess in commons/bitboard.h public: static constexpr Chess empty = 0; static constexpr Chess White = 1; static constexpr Chess Black = 2; }; class Board : public ::Chessboard<11, 11> { public: string sprintBoard(string_view prefix = "", const set>& markedPos = {}) const override; // string_view getPosStr(int x, int y) const override; string getPosStr(int p) const override; string showBoard(bool prePlay) const; vector legal; }; struct Move { // int x, y, tx, ty; int x, tx, method; Chess chess; }; class Game { public: void initialize(); void setInitialChesses(); void play(Move& m); bool Won(); void findLegalMoves(Player player); // void LegalMove(int x, int y, Chess chess, bool isJump); void LegalMove(int cur, Chess chess, bool isJump); int canGo(int cur, int md, Chess chess); template static void setupBoard(const R& re); static constexpr Player chessToPlayer(Chess chess); static constexpr Chess playerToChess(Player player); static constexpr size_t players = 2; static constexpr size_t chesses = 2; static constexpr int boardWH = 11; // width and height in board static constexpr int maxLegalMovesCnt = 5000; // boardWH * boardWH - 40; static constexpr int maxHands = maxLegalMovesCnt; // maxLegalMovesCnt * 2 * 10; static inline once_flag setupCalled; Board board; int hands, prePos, preChess; bool continue_jump; // for action description(enable to continue jump ) Player winner; vector legalMoves, way; Move Pass = {pass, pass, Chesses::empty, true}; static constexpr short int move_table[121][6] = { // position {LU,RU,L,R,LD,RD} {-1, -1, -1, -1, P_A2, P_A3}, // A1 {-1, P_A1, -1, P_A3, P_A4, P_A5}, // A2 {P_A1, -1, P_A2, -1, P_A5, P_A6}, // A3 {-1, P_A2, -1, P_A5, P_A7, P_A8}, // A4 {P_A2, P_A3, P_A4, P_A6, P_A8, P_A9}, // A5 {P_A3, -1, P_A5, -1, P_A9, P_A10}, // A6 {-1, P_A4, -1, P_A8, P_G1, P_G2}, // A7 {P_A4, P_A5, P_A7, P_A9, P_G2, P_G3}, // A8 {P_A5, P_A6, P_A8, P_A10, P_G3, P_G4}, // A9 {P_A6, -1, P_A9, -1, P_G4, P_G5}, // A10 {-1, -1, P_B2, -1, P_B3, -1}, // B1 {-1, -1, P_B4, P_B1, P_B5, P_B3}, // B2 {P_B2, P_B1, P_B5, -1, P_B6, -1}, // B3 {-1, -1, P_B7, P_B2, P_B8, P_B5}, // B4 {P_B4, P_B2, P_B8, P_B3, P_B9, P_B6}, // B5 {P_B5, P_B3, P_B9, -1, P_B10, -1}, // B6 {-1, -1, P_G5, P_B4, P_G11, P_B8}, // B7 {P_B7, P_B4, P_G11, P_B5, P_G18, P_B9}, // B8 {P_B8, P_B5, P_G18, P_B6, P_G26, P_B10}, // B9 {P_B9, P_B6, P_G26, -1, P_G35, -1}, // B10 {P_C2, -1, P_C3, -1, -1, -1}, // C1 {P_C4, -1, P_C5, -1, P_C3, P_C1}, // C2 {P_C5, P_C2, P_C6, P_C1, -1, -1}, // C3 {P_C7, -1, P_C8, -1, P_C5, P_C2}, // C4 {P_C8, P_C4, P_C9, P_C2, P_C6, P_C3}, // C5 {P_C9, P_C5, P_C10, P_C3, -1, -1}, // C6 {P_G35, -1, P_G43, -1, P_C8, P_C4}, // C7 {P_G43, P_C7, P_G50, P_C4, P_C9, P_C5}, // C8 {P_G50, P_C8, P_G56, P_C5, P_C10, P_C6}, // C9 {P_G56, P_C9, P_G61, P_C6, -1, -1}, // C10 {P_D3, P_D2, -1, -1, -1, -1}, // D1 {P_D5, P_D4, P_D3, -1, P_D1, -1}, // D2 {P_D6, P_D5, -1, P_D2, -1, P_D1}, // D3 {P_D8, P_D7, P_D5, -1, P_D2, -1}, // D4 {P_D9, P_D8, P_D6, P_D4, P_D3, P_D2}, // D5 {P_D10, P_D9, -1, P_D5, -1, P_D3}, // D6 {P_G60, P_G61, P_D8, -1, P_D4, -1}, // D7 {P_G59, P_G60, P_D9, P_D7, P_D5, P_D4}, // D8 {P_G58, P_G59, P_D10, P_D8, P_D6, P_D5}, // D9 {P_G57, P_G58, -1, P_D9, -1, P_D6}, // D10 {-1, P_E3, -1, P_E2, -1, -1}, // E1 {P_E3, P_E5, P_E1, P_E4, -1, -1}, // E2 {-1, P_E6, -1, P_E5, P_E1, P_E2}, // E3 {P_E5, P_E8, P_E2, P_E7, -1, -1}, // E4 {P_E6, P_E9, P_E3, P_E8, P_E2, P_E4}, // E5 {-1, P_E10, -1, P_E9, P_E3, P_E5}, // E6 {P_E8, P_G51, P_E4, P_G57, -1, -1}, // E7 {P_E9, P_G44, P_E5, P_G51, P_E4, P_E7}, // E8 {P_E10, P_G36, P_E6, P_G44, P_E5, P_E8}, // E9 {-1, P_G27, -1, P_G36, P_E6, P_E9}, // E10 {-1, -1, -1, P_F3, -1, P_F2}, // F1 {P_F1, P_F3, -1, P_F5, -1, P_F4}, // F2 {-1, -1, P_F1, P_F6, P_F2, P_F5}, // F3 {P_F2, P_F5, -1, P_F8, -1, P_F7}, // F4 {P_F3, P_F6, P_F2, P_F9, P_F4, P_F8}, // F5 {-1, -1, P_F3, P_F10, P_F5, P_F9}, // F6 {P_F4, P_F8, -1, P_G19, -1, P_G27}, // F7 {P_F5, P_F9, P_F4, P_G12, P_F7, P_G19}, // F8 {P_F6, P_F10, P_F5, P_G6, P_F8, P_G12}, // F9 {-1, -1, P_F6, P_G1, P_F9, P_G6}, // F10 {-1, P_A7, P_F10, P_G2, P_G6, P_G7}, // G1 {P_A7, P_A8, P_G1, P_G3, P_G7, P_G8}, // G2 {P_A8, P_A9, P_G2, P_G4, P_G8, P_G9}, // G3 {P_A9, P_A10, P_G3, P_G5, P_G9, P_G10}, // G4 {P_A10, -1, P_G4, P_B7, P_G10, P_G11}, // G5 {P_F10, P_G1, P_F9, P_G7, P_G12, P_G13}, // G6 {P_G1, P_G2, P_G6, P_G8, P_G13, P_G14}, // G7 {P_G2, P_G3, P_G7, P_G9, P_G14, P_G15}, // G8 {P_G3, P_G4, P_G8, P_G10, P_G15, P_G16}, // G9 {P_G4, P_G5, P_G9, P_G11, P_G16, P_G17}, // G10 {P_G5, P_B7, P_G10, P_B8, P_G17, P_G18}, // G11 {P_F9, P_G6, P_F8, P_G13, P_G19, P_G20}, // G12 {P_G6, P_G7, P_G12, P_G14, P_G20, P_G21}, // G13 {P_G7, P_G8, P_G13, P_G15, P_G21, P_G22}, // G14 {P_G8, P_G9, P_G14, P_G16, P_G22, P_G23}, // G15 {P_G9, P_G10, P_G15, P_G17, P_G23, P_G24}, // G16 {P_G10, P_G11, P_G16, P_G18, P_G24, P_G25}, // G17 {P_G11, P_B8, P_G17, P_B9, P_G25, P_G26}, // G18 {P_F8, P_G12, P_F7, P_G20, P_G27, P_G28}, // G19 {P_G12, P_G13, P_G19, P_G21, P_G28, P_G29}, // G20 {P_G13, P_G14, P_G20, P_G22, P_G29, P_G30}, // G21 {P_G14, P_G15, P_G21, P_G23, P_G30, P_G31}, // G22 {P_G15, P_G16, P_G22, P_G24, P_G31, P_G32}, // G23 {P_G16, P_G17, P_G23, P_G25, P_G32, P_G33}, // G24 {P_G17, P_G18, P_G24, P_G26, P_G33, P_G34}, // G25 {P_G18, P_B9, P_G25, P_B10, P_G34, P_G35}, // G26 {P_F7, P_G19, -1, P_G28, P_E10, P_G36}, // G27 {P_G19, P_G20, P_G27, P_G29, P_G36, P_G37}, // G28 {P_G20, P_G21, P_G28, P_G30, P_G37, P_G38}, // G29 {P_G21, P_G22, P_G29, P_G31, P_G38, P_G39}, // G30 {P_G22, P_G23, P_G30, P_G32, P_G39, P_G40}, // G31 {P_G23, P_G24, P_G31, P_G33, P_G40, P_G41}, // G32 {P_G24, P_G25, P_G32, P_G34, P_G41, P_G42}, // G33 {P_G25, P_G26, P_G33, P_G35, P_G42, P_G43}, // G34 {P_G26, P_B10, P_G34, -1, P_G43, P_C7}, // G35 {P_G27, P_G28, P_E10, P_G37, P_E9, P_G44}, // G36 {P_G28, P_G29, P_G36, P_G38, P_G44, P_G45}, // G37 {P_G29, P_G30, P_G37, P_G39, P_G45, P_G46}, // G38 {P_G30, P_G31, P_G38, P_G40, P_G46, P_G47}, // G39 {P_G31, P_G32, P_G39, P_G41, P_G47, P_G48}, // G40 {P_G32, P_G33, P_G40, P_G42, P_G48, P_G49}, // G41 {P_G33, P_G34, P_G41, P_G43, P_G49, P_G50}, // G42 {P_G34, P_G35, P_G42, P_C7, P_G50, P_C8}, // G43 {P_G36, P_G37, P_E9, P_G45, P_E8, P_G51}, // G44 {P_G37, P_G38, P_G44, P_G46, P_G51, P_G52}, // G45 {P_G38, P_G39, P_G45, P_G47, P_G52, P_G53}, // G46 {P_G39, P_G40, P_G46, P_G48, P_G53, P_G54}, // G47 {P_G40, P_G41, P_G47, P_G49, P_G54, P_G55}, // G48 {P_G41, P_G42, P_G48, P_G50, P_G55, P_G56}, // G49 {P_G42, P_G43, P_G49, P_C8, P_G56, P_C9}, // G50 {P_G44, P_G45, P_E8, P_G52, P_E7, P_G57}, // G51 {P_G45, P_G46, P_G51, P_G53, P_G57, P_G58}, // G52 {P_G46, P_G47, P_G52, P_G54, P_G58, P_G59}, // G53 {P_G47, P_G48, P_G53, P_G55, P_G59, P_G60}, // G54 {P_G48, P_G49, P_G54, P_G56, P_G60, P_G61}, // G55 {P_G49, P_G50, P_G55, P_C9, P_G61, P_C10}, // G56 {P_G51, P_G52, P_E7, P_G58, -1, P_D10}, // G57 {P_G52, P_G53, P_G57, P_G59, P_D10, P_D9}, // G58 {P_G53, P_G54, P_G58, P_G60, P_D9, P_D8}, // G59 {P_G54, P_G55, P_G59, P_G61, P_D8, P_D7}, // G60 {P_G55, P_G56, P_G60, P_C10, P_D7, -1} // G61 }; private: int JumpOBS(int cur, int dirct); }; class State : public core::State, public Game { public: State(int seed); void Initialize() override; unique_ptr clone_() const override; void ApplyAction(const _Action& action) override; void DoGoodAction() override; void printCurrentBoard() const override; string stateDescription() const override; string actionsDescription() const override; string actionDescription(const ::_Action& action) const override; int parseAction(const string& str) const override; int humanInputAction( std::function(std::string)> specialAction) override; private: Player changeTurn(Player player); bool canChange(Player Player); void findActions(); void findFeatures(); int seed; static constexpr size_t featuresSizeX = chesses; static constexpr size_t featuresSizeY = boardWH; static constexpr size_t featuresSizeZ = boardWH; static constexpr size_t featuresSize = featuresSizeX * featuresSizeY * featuresSizeZ; }; } // namespace ChineseCheckers ================================================ FILE: src/games/chinesecheckers_defines.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #define P_A1 0 #define P_A2 1 #define P_A3 2 #define P_A4 3 #define P_A5 4 #define P_A6 5 #define P_A7 6 #define P_A8 7 #define P_A9 8 #define P_A10 9 #define P_B1 10 #define P_B2 11 #define P_B3 12 #define P_B4 13 #define P_B5 14 #define P_B6 15 #define P_B7 16 #define P_B8 17 #define P_B9 18 #define P_B10 19 #define P_C1 20 #define P_C2 21 #define P_C3 22 #define P_C4 23 #define P_C5 24 #define P_C6 25 #define P_C7 26 #define P_C8 27 #define P_C9 28 #define P_C10 29 #define P_D1 30 #define P_D2 31 #define P_D3 32 #define P_D4 33 #define P_D5 34 #define P_D6 35 #define P_D7 36 #define P_D8 37 #define P_D9 38 #define P_D10 39 #define P_E1 40 #define P_E2 41 #define P_E3 42 #define P_E4 43 #define P_E5 44 #define P_E6 45 #define P_E7 46 #define P_E8 47 #define P_E9 48 #define P_E10 49 #define P_F1 50 #define P_F2 51 #define P_F3 52 #define P_F4 53 #define P_F5 54 #define P_F6 55 #define P_F7 56 #define P_F8 57 #define P_F9 58 #define P_F10 59 #define P_G1 60 #define P_G2 61 #define P_G3 62 #define P_G4 63 #define P_G5 64 #define P_G6 65 #define P_G7 66 #define P_G8 67 #define P_G9 68 #define P_G10 69 #define P_G11 70 #define P_G12 71 #define P_G13 72 #define P_G14 73 #define P_G15 74 #define P_G16 75 #define P_G17 76 #define P_G18 77 #define P_G19 78 #define P_G20 79 #define P_G21 80 #define P_G22 81 #define P_G23 82 #define P_G24 83 #define P_G25 84 #define P_G26 85 #define P_G27 86 #define P_G28 87 #define P_G29 88 #define P_G30 89 #define P_G31 90 #define P_G32 91 #define P_G33 92 #define P_G34 93 #define P_G35 94 #define P_G36 95 #define P_G37 96 #define P_G38 97 #define P_G39 98 #define P_G40 99 #define P_G41 100 #define P_G42 101 #define P_G43 102 #define P_G44 103 #define P_G45 104 #define P_G46 105 #define P_G47 106 #define P_G48 107 #define P_G49 108 #define P_G50 109 #define P_G51 110 #define P_G52 111 #define P_G53 112 #define P_G54 113 #define P_G55 114 #define P_G56 115 #define P_G57 116 #define P_G58 117 #define P_G59 118 #define P_G60 119 #define P_G61 120 #define pass 121 // direction #define M_LU 0 #define M_RU 1 #define M_L 2 #define M_R 3 #define M_LD 4 #define M_RD 5 #define J_LU 6 #define J_RU 7 #define J_L 8 #define J_R 9 #define J_LD 10 #define J_RD 11 ================================================ FILE: src/games/commons/chessboard.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 林鈺錦 (Yù-Jǐn Lín) // - Github: https://github.com/abc1236762 // - Email: abc1236762@outlook.com #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include using Chess = std::uint8_t; template class Chessboard { static_assert(ROW > 0 && ROW <= 26 && COL > 0 && COL <= 26, "rows and columns of chessboard must be in range [1,26]"); public: static constexpr int rows = ROW; static constexpr int columns = COL; static constexpr int squares = rows * columns; using Board = std::array; template static void setup(const std::vector& cn, const std::vector& cs, const RE& re); static constexpr bool isPosInBoard(int x, int y); static constexpr bool isPosInBoard(int xy); static constexpr int posTo1D(int x, int y); static constexpr std::tuple posTo2D(int xy); static constexpr std::string_view getMarkSymbol(); static constexpr std::string_view getChessName(Chess chess); static constexpr std::string_view getChessSymbol(Chess chess); void initialize(); void initialize(const Board& b); Chess getChess(int x, int y) const; Chess getChess(int xy) const; void setChess(int x, int y, Chess chess); void setChess(int xy, Chess chess); std::vector countChesses() const; void turnHash(); std::string sprint(std::string_view prefix = "") const; virtual std::string sprintBoard( std::string_view prefix = "", const std::set>& markedPos = {}) const; const Board& getBoard() const; std::uint64_t getHash() const; virtual std::string getPosStr(int xy) const; virtual std::string getPosStr(int x, int y) const; virtual std::optional> parsePosStr( const std::string& str) const; constexpr bool operator==(const Chessboard& cb) const; constexpr bool operator!=(const Chessboard& cb) const; protected: static inline std::string_view markSymbol = "?"; private: void updateHash(); void updateHash(int xy, Chess chess); static inline std::vector hashList; static inline std::uint64_t hashTurn; static inline std::size_t chessKinds; static inline std::vector chessesName; static inline std::vector chessesSymbol; Board board; std::uint64_t hash; }; template template void Chessboard::setup( const std::vector& cn, const std::vector& cs, const RE& re) { assert(cn.size() == cs.size()); chessKinds = cn.size(); chessesName = cn; chessesSymbol = cs; std::independent_bits_engine genRandomBits(re); hashList = std::vector(chessKinds * squares); for (std::uint64_t& hash : hashList) hash = genRandomBits(); hashTurn = genRandomBits(); } template constexpr bool Chessboard::isPosInBoard(int x, int y) { return x >= 0 && x < rows && y >= 0 && y < columns; } template constexpr bool Chessboard::isPosInBoard(int xy) { auto [x, y] = posTo2D(xy); return isPosInBoard(x, y); } template constexpr int Chessboard::posTo1D(int x, int y) { return rows * y + x; } template constexpr std::tuple Chessboard::posTo2D(int xy) { return {xy % rows, xy / rows}; } template constexpr std::string_view Chessboard::getMarkSymbol() { return markSymbol; } template constexpr std::string_view Chessboard::getChessName( Chess chess) { return chessesName.at(chess); } template constexpr std::string_view Chessboard::getChessSymbol( Chess chess) { return chessesSymbol.at(chess); } template void Chessboard::initialize() { board.fill(0U); updateHash(); } template void Chessboard::initialize( const Chessboard::Board& b) { board = b; updateHash(); } template Chess Chessboard::getChess(int x, int y) const { return getChess(posTo1D(x, y)); } template Chess Chessboard::getChess(int xy) const { return board[xy]; } template void Chessboard::setChess(int x, int y, Chess chess) { setChess(posTo1D(x, y), chess); } template void Chessboard::setChess(int xy, Chess chess) { updateHash(xy, getChess(xy)); board[xy] = chess; updateHash(xy, chess); } template std::vector Chessboard::countChesses() const { std::vector counts(chessKinds, 0); for (Chess chess : board) counts[chess]++; return counts; } template void Chessboard::turnHash() { hash ^= hashTurn; } template std::string Chessboard::sprint( std::string_view prefix) const { std::ostringstream oss; oss << prefix; for (std::size_t i = 0; i < chessKinds; i++) { oss << getChessName(i) << "='" << getChessSymbol(i) << "'"; if (i < chessKinds - 1) oss << " "; } oss << std::endl << sprintBoard(prefix); return oss.str(); } template std::string Chessboard::sprintBoard( std::string_view prefix, const std::set>& markedPos) const { auto hr = [&](std::string_view l, std::string_view m, std::string_view r) { std::ostringstream ossE; ossE << (columns < 10 ? " " : " ") << l; for (int x = 0; x < rows; x++) { ossE << "───"; if (x < rows - 1) ossE << m; } ossE << r << std::endl; return ossE.str(); }; std::ostringstream oss, ossW; ossW << (columns < 10 ? " " : " "); for (int x = 0; x < rows; x++) ossW << " " << std::string(1, 'A' + x); ossW << std::endl; oss << prefix << ossW.str() << prefix << hr("┌", "┬", "┐"); for (int y = 0; y < columns; y++) { char yStr[4]; sprintf( yStr, columns < 10 ? "%d" : "%02d", (INVERTY ? columns - y : y + 1)); oss << prefix << yStr << " │ "; for (int x = 0; x < rows; x++) { if (markedPos.count({x, y}) == 0) oss << getChessSymbol(getChess(x, y)) << " │ "; else oss << markSymbol << " │ "; } oss << yStr << std::endl; if (y < columns - 1) oss << prefix << hr("├", "┼", "┤"); } oss << prefix << hr("└", "┴", "┘") << prefix << ossW.str(); return oss.str(); } template const typename Chessboard::Board& Chessboard::getBoard() const { return board; } template std::uint64_t Chessboard::getHash() const { return hash; } template std::string Chessboard::getPosStr(int xy) const { auto [x, y] = posTo2D(xy); return getPosStr(x, y); } template std::string Chessboard::getPosStr(int x, int y) const { char str[4] = {0}; str[0] = 'A' + x; y = INVERTY ? columns - y : y + 1; if (columns >= 10) { str[1] = '0' + y / 10; str[2] = '0' + y % 10; } else { str[1] = '0' + y; } return std::string(str); } template std::optional> Chessboard::parsePosStr( const std::string& str) const { int x = -1, y = -1, yBegin = -1, yEnd = -1; for (std::size_t i = 0; i < str.size(); i++) { char c = str[i]; if (x < 0) { if (std::isspace(c)) continue; else if (!std::isalpha(c)) return std::nullopt; x = std::toupper(c) - 'A'; } else if (yBegin < 0) { if (std::isspace(c)) continue; else if (!std::isdigit(c)) return std::nullopt; yBegin = i; } else if (yEnd < 0) { if (std::isdigit(c)) continue; else if (!std::isspace(c)) return std::nullopt; yEnd = i; } else if (!std::isspace(c)) { return std::nullopt; } } if (x < 0 || yBegin < 0) return std::nullopt; if (yEnd < 0) yEnd = str.size(); std::string yStr(str, yBegin, yEnd - yBegin); try { y = std::stoul(yStr, nullptr, 10); y = (INVERTY ? columns - y : y - 1); } catch (...) { return std::nullopt; } if (isPosInBoard(x, y)) return std::tuple(x, y); return std::nullopt; } template constexpr bool Chessboard::operator==( const Chessboard& cb) const { if (hash == cb.hash && board == cb.board) return true; return false; } template constexpr bool Chessboard::operator!=( const Chessboard& cb) const { if (hash != cb.hash || board != cb.board) return true; return false; } template void Chessboard::updateHash() { hash = 0ULL; for (int xy = 0; xy < squares; xy++) updateHash(xy, getChess(xy)); } template void Chessboard::updateHash(int xy, Chess chess) { hash ^= hashList[squares * chess + xy]; } ================================================ FILE: src/games/commons/hash.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once template class HashBook { public: using Storage = std::array; HashBook() = default; template void setup(RngEngine& rng) { std::independent_bits_engine gen(rng); for (size_t i = 0; i < _book.size(); ++i) { _book[i] = gen(); } } constexpr T operator[](size_t i) const { return _book[i]; } private: HashBook(const HashBook&) = delete; HashBook& operator=(const HashBook&) = delete; Storage _book; }; template class Hasher { public: Hasher(const HashBook& hashBook) : _hashBook(&hashBook) , _hash(0) { } void reset() { _hash = 0; } void trigger(size_t i) { _hash ^= (*_hashBook)[i]; } uint64_t hash() const { return _hash; } private: const HashBook* _hashBook; uint64_t _hash; }; ================================================ FILE: src/games/commons/player.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 林鈺錦 (Yù-Jǐn Lín) // - Github: https://github.com/abc1236762 // - Email: abc1236762@outlook.com #pragma once class Player { public: enum Index : int { none = -1, first, second }; static constexpr Player set(int i) { return Player(static_cast(i)); } constexpr Player() : _i(Index::none) { } constexpr Player(Index i) : _i(i) { } constexpr bool operator==(const Player& p) const { return _i == p._i; } constexpr bool operator!=(const Player& p) const { return _i != p._i; } constexpr int index() { return static_cast(_i); } private: Index _i; }; ================================================ FILE: src/games/connect6.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author 1. CHEN,SHIH-YU leo03164@gmail.com // Author 2. CHIU,HSIEN-TUNG yumjelly@gmail.com #include #include #include #include #include #include #include using namespace std; namespace Connect6 { const int C6White = 0; const int C6Black = 1; const int C6Empty = 2; const int C6Dx = 19; const int C6Dy = 19; const int C6MaxLegalMoves = C6Dy * C6Dx; const int C6MaxPlayoutLength = C6Dx * C6Dy; // TODO: 原本沒有 BEGIN class C6Player { public: int player; bool operator==(C6Player p) { return (p.player == player); } }; // END TODO // const int MaxMoveNumber = 2 * 2 * (3 * C6Dx * C6Dy) + 1; // const int MaxMoveNumber = 80 * 2 * 2 * (3 * C6Dx * C6Dy) + 1; const int MaxMoveNumber = C6Dx * C6Dy; class C6Move { public: int x, y, color; }; class C6Board { public: int nb; char board[C6Dx][C6Dy]; unsigned long long hash; void init() { for (int i = 0; i < C6Dx; i++) for (int j = 0; j < C6Dy; j++) board[i][j] = C6Empty; hash = 0; // printf("init\n"); } bool won(C6Move m) { int Max_connect = 6; int current_coun = 1; int x = m.x; int y = m.y; int color = m.color; bool opsite = true; for (int i = 1; i <= Max_connect; i++) { if (x - i >= 0 && board[x - i][y] == color && opsite) { current_coun++; continue; } else { i = 7; opsite = false; for (int j = 1; j <= Max_connect; j++) { if (x + j < C6Dx && board[x + j][y] == color) { current_coun++; continue; } else break; } } } if (current_coun >= Max_connect) return true; current_coun = 1; opsite = true; //------------------------------------------------------------------------------ for (int i = 1; i <= Max_connect; i++) { if (y - i >= 0 && board[x][y - i] == color && opsite) { current_coun++; continue; } else { i = 7; opsite = false; for (int j = 1; j <= Max_connect; j++) { if (y + j < C6Dx && board[x][y + j] == color) { current_coun++; continue; } else break; } } } if (current_coun >= Max_connect) return true; current_coun = 1; opsite = true; //------------------------------------------------------------------------------ for (int i = 1; i <= Max_connect; i++) { if ((y - i >= 0) && (x + i < C6Dx) && board[x + i][y - i] == color && opsite) { current_coun++; continue; } else { i = 7; opsite = false; for (int j = 1; j <= Max_connect; j++) { if ((x - j >= 0) && (y + j < C6Dx) && board[x - j][y + j] == color) { current_coun++; continue; } else break; } } } if (current_coun >= Max_connect) return true; current_coun = 1; opsite = true; //------------------------------------------------------------------------------ for (int i = 1; i <= Max_connect; i++) { if ((y - i >= 0) && (x - i >= 0) && board[x - i][y - i] == color && opsite) { current_coun++; continue; } else { i = 7; opsite = false; for (int j = 1; j <= Max_connect; j++) { if ((y + j < C6Dx) && (x + j < C6Dy) && board[x + j][y + j] == color) { current_coun++; continue; } else break; } } } if (current_coun >= Max_connect) return true; else return false; } int opponent(int joueur) { // printf("opponent\n"); if (joueur == C6White) return C6Black; return C6White; } //找合法步 bool legalMove(C6Move m) { // printf("legalMove\n"); if (board[m.x][m.y] != C6Empty) return false; return true; } void play(C6Move m) { board[m.x][m.y] = m.color; } int legalMoves(C6Move moves[C6MaxLegalMoves]) { // printf("legalMoves\n"); nb = 0; for (int i = 0; i < C6Dx; i++) { for (int j = 0; j < C6Dy; j++) { if (board[i][j] == C6Empty) { moves[nb].x = i; moves[nb].y = j; nb++; } } } return nb; } }; } // namespace Connect6 ================================================ FILE: src/games/connect6_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author 1. CHEN,SHIH-YU leo03164@gmail.com // Author 2. CHIU,HSIEN-TUNG yumjelly@gmail.com #pragma once #include "../core/state.h" #include "connect6.h" #include #include #include #include #include namespace Connect6 { const int StateForConnect6NumActions = 19 * 19 * 3; // class ActionForConnect6 : public ::_Action { // public: // ActionForConnect6(int x, int y) // : _Action() { // _loc[0] = 0; // _loc[1] = x; // _loc[2] = y; // _hash = x + y * 19; // } // step is 2 or 3. //}; template class StateForConnect6 : public core::State, C6Board { public: int twice; int firhand; StateForConnect6(int seed) : State(seed) { } virtual void Initialize() override { // printf("Initialize\n"); // People implementing classes should not have much to do in _moves; just // _moves.clear(). _moves.clear(); const int StateForConnect6X = version == 2 ? 2 + 1 : 2 * 6 + 1; const int StateForConnect6Y = 19; const int StateForConnect6Z = 19; _featSize[0] = StateForConnect6X; _featSize[1] = StateForConnect6Y; _featSize[2] = StateForConnect6Z; // size of the output of the neural network; this should cover the positions // of actions (above). _actionSize[0] = 1; _actionSize[1] = 19; _actionSize[2] = 19; // _hash is an unsigned int, it has to be *unique*. _hash = 0; _status = GameStatus::player1Turn; _features.resize(StateForConnect6X * StateForConnect6Y * StateForConnect6Z); twice = 0; firhand = 1; init(); findFeatures(); findActions(); fillFullFeatures(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } void findActions() { // printf("findActions\n"); C6Move moves[C6MaxLegalMoves]; int nb = legalMoves(moves); _legalActions.clear(); for (int i = 0; i < nb; i++) { int x = moves[i].x; int y = moves[i].y; _legalActions.emplace_back(i, 0, x, y); } } void findFeatures() { // printf("findFeatures\n"); if ((_status == GameStatus::player0Win) || (_status == GameStatus::player1Win) || (_status == GameStatus::tie)) { return; } if (version == 2) { std::fill(_features.begin() + 2 * C6Dx * C6Dy, _features.end(), twice || firhand ? 1.0f : 0.0f); } else { std::vector old(_features); for (int i = 0; i < C6Dx * C6Dy * 2; i++) _features[i] = 0; for (int i = 0; i < C6Dx * C6Dy; i++) if (board[i % C6Dx][i / C6Dy] == C6Black) _features[i] = 1; for (int i = 0; i < C6Dx * C6Dy; i++) if (board[i % C6Dx][i / C6Dy] == C6White) _features[C6Dx * C6Dy + i] = 1; std::copy(old.begin(), old.begin() + 3610, _features.begin() + 722); // 4332-4693 std::fill(_features.begin() + 4332, _features.end(), getCurrentPlayer()); } } virtual void ApplyAction(const ::_Action& action) override { // printf("ApplyAction\n"); C6Move m; // print(stdout); if (_status == GameStatus::player0Turn) { // C6White m.color = C6White; m.x = action.GetY(); m.y = action.GetZ(); play(m); if (version == 2) { _features[m.x * C6Dy + m.y + C6Dx * C6Dy * 0] = 1.0f; } bool hasWon = won(m); if (hasWon) { _status = GameStatus::player0Win; } else { findActions(); if (nb == 0) { _status = GameStatus::tie; } else { if (twice == 0) { twice = 1; } else if (twice == 1) { twice = 0; _status = GameStatus::player1Turn; } } } } else if (_status == GameStatus::player1Turn) { // C6Black m.color = C6Black; m.x = action.GetY(); m.y = action.GetZ(); play(m); if (version == 2) { _features[m.x * C6Dy + m.y + C6Dx * C6Dy * 1] = 1.0f; } bool hasWon = won(m); if (hasWon) { _status = GameStatus::player1Win; } else { findActions(); if (nb == 0) { _status = GameStatus::tie; } else { if (firhand) { _status = GameStatus::player0Turn; firhand = 0; } else { if (twice == 0) twice = 1; else if (twice == 1) { twice = 0; _status = GameStatus::player0Turn; } } } } } findFeatures(); _hash = hash; fillFullFeatures(); } virtual void DoGoodAction() override { return DoRandomAction(); } std::string stateDescription() const override { std::string s; s += fmt::sprintf(" "); for (int k = 65; k < 84; k++) s += fmt::sprintf("%c ", k); s += fmt::sprintf("\n"); for (int i = 0; i < C6Dx; i++) { if (C6Dx - i < 10) s += fmt::sprintf("%d ", C6Dx - i); else s += fmt::sprintf("%d ", C6Dx - i); for (int j = 0; j < C6Dy; j++) { if (board[C6Dx - 1 - i][j] == C6Black) s += "X "; else if (board[C6Dx - 1 - i][j] == C6White) s += "O "; else s += ". "; } s += "\n"; } return s; } std::string actionDescription(const _Action& action) const override { return std::string(1, 'A' + action.GetZ()) + std::to_string(action.GetY() + 1); } int parseAction(const std::string& str) const override { if (str.size() < 2) { return -1; } int z = str[0] - 'A'; if (z < 0 || z >= 19) { z = str[0] - 'a'; if (z < 0 || z >= 19) { return -1; } } int y = std::atoi(str.data() + 1) - 1; if (y < 0 || y >= 19) { return -1; } for (auto& a : _legalActions) { if (a.GetZ() == z && a.GetY() == y) { return a.GetIndex(); } } return -1; } int humanInputAction( std::function(std::string)> specialAction) { std::cout << "Current board:" << std::endl << stateDescription() << std::endl; std::string str; int index = -1; while (index < 0) { std::cout << "Input action: "; std::getline(std::cin, str); index = parseAction(str); if (index < 0) { if (auto r = specialAction(str); r) return *r; std::cout << "invalid input, try again." << std::endl; } } return index; } }; } // namespace Connect6 ================================================ FILE: src/games/connectfour.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include "../core/state.h" class StateForConnectFour : public core::State { public: StateForConnectFour(int seed) : State(seed) { } virtual void Initialize() override { _moves.clear(); _hash = 2166136261u; _status = GameStatus::player0Turn; _featSize[0] = 3; _featSize[1] = boardHeight; _featSize[2] = boardWidth; _actionSize[0] = boardWidth; _actionSize[1] = 1; _actionSize[2] = 1; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); std::fill(_features.begin(), _features.end(), 1.0f); board.clear(); board.resize(boardWidth * boardHeight, 0); height.clear(); height.resize(boardWidth, 0); featurize(); findActions(); fillFullFeatures(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } virtual void printCurrentBoard() const override { std::cout << "printing board" << std::endl << std::flush; for (int r = boardHeight - 1; r >= 0; --r) { std::cout << "|"; for (int c = 0; c < boardWidth; ++c) { auto val = board[r * boardWidth + c]; if (val == 0) { std::cout << " "; } else if (val == 1) { std::cout << "X"; } else if (val == 2) { std::cout << "O"; } else { assert(false); } std::cout << "|"; } std::cout << std::endl; } } void featurize() { int player = 1 + getCurrentPlayer(); int otherPlayer = player == 1 ? 2 : 1; for (int i = 0; i != (int)board.size(); ++i) { int v = board[i]; _features[i] = v == player; _features[board.size() + i] = v == otherPlayer; } } void findActions() { clearActions(); for (int i = 0; i != boardWidth; ++i) { if (height[i] != boardHeight) { addAction(i, 0, 0); } } } virtual void ApplyAction(const _Action& action) override { int x = action.GetX(); int y = height.at(x); ++height[x]; int player = 1 + getCurrentPlayer(); size_t index = x + y * boardWidth; board.at(index) = player; _hash ^= index; _hash *= 16777619u; auto count = [&](int dx, int dy) { int nx = x + dx; int ny = y + dy; int r = 0; int stride = dx + dy * boardWidth; size_t nIndex = index + stride; while (nx >= 0 && nx < boardWidth && ny >= 0 && ny < boardHeight && board.at(nIndex) == player) { ++r; nIndex += stride; nx += dx; ny += dy; } return r; }; bool won = count(-1, 0) + count(1, 0) >= 3; won |= count(0, -1) + count(0, 1) >= 3; won |= count(-1, -1) + count(1, 1) >= 3; won |= count(1, -1) + count(-1, 1) >= 3; if (won) { _status = player == 1 ? GameStatus::player0Win : GameStatus::player1Win; } else { featurize(); findActions(); if (_legalActions.empty()) { _status = GameStatus::tie; } else { _status = player == 1 ? GameStatus::player1Turn : GameStatus::player0Turn; } } fillFullFeatures(); } virtual void DoGoodAction() override { return DoRandomAction(); } int boardWidth = 7; int boardHeight = 6; std::vector board; std::vector height; }; ================================================ FILE: src/games/diceshogi.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author1: Lin Hsin-I // - Github: https://github.com/free00000000000 // - Email: 410521233@gms.ndhu.edu.tw // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #pragma once #include "../core/state.h" #include "shogi.h" #include #include #include class StateForDiceshogi : public core::State, public Shogi { public: unsigned long long HashArray[2][10][Dx][Dy]; unsigned long long HashArrayJail[20]; unsigned long long HashTurn; unsigned long long hash; int length; short dice; // 0-5 int repeat; std::queue situation; StateForDiceshogi(int seed) : State(seed) , Shogi() { _stochasticReset = true; } virtual void Initialize() override { _stochastic = true; _moves.clear(); _hash = 0; _status = GameStatus::player0Turn; _featSize[0] = 225; _featSize[1] = Dy; _featSize[2] = Dx; _actionSize[0] = 19; // 11 pieces + 8 promoted _actionSize[1] = Dy; _actionSize[2] = Dx; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); // setFeatures(false, false, false, 0, 0, false); gameInit(); initHash(); // printCurrentBoard(); findFeature(); findActions(); // fixxx fillFullFeatures(); } void gameInit() { chess.clear(); chess.resize(2); for (int i = 0; i < Dx; ++i) for (int j = 0; j < Dy; ++j) board[i][j] = Piece(); for (int i = 0; i < Dx; ++i) { board[i][0] = Piece(White, PieceType(i + 1), false, Position(i, 0)); chess[White].push_back(board[i][0]); } board[0][1] = Piece(White, PieceType::Pawn, false, Position(0, 1)); chess[White].push_back(board[0][1]); for (int i = 1; i <= Dx; ++i) { int x = Dx - i; board[x][4] = Piece(Black, PieceType(i), false, Position(x, 4)); chess[Black].push_back(board[x][4]); } board[4][3] = Piece(Black, PieceType::Pawn, false, Position(4, 3)); chess[Black].push_back(board[4][3]); if (forcedDice > 0) { assert(forcedDice > 0); assert(forcedDice < 7); dice = forcedDice - 1; forcedDice = -1; } else { dice = _rng() % 6; } _hash = dice + 1; hash = 0; length = 0; repeat = 0; situation.push(hash); } void initHash() { for (int a = 0; a < 2; ++a) for (int b = 0; b < 10; ++b) for (int c = 0; c < 5; ++c) for (int d = 0; d < 5; ++d) { HashArray[a][b][c][d] = 0; for (int k = 0; k < 64; ++k) if ((_rng() / (RAND_MAX + 1.0)) > 0.5) HashArray[a][b][c][d] |= (1ULL << k); } for (int a = 0; a < 20; ++a) { for (int k = 0; k < 64; ++k) if ((_rng() / (RAND_MAX + 1.0)) > 0.5) HashArrayJail[a] |= (1ULL << k); } HashTurn = 0; for (int k = 0; k < 64; k++) if ((_rng() / (RAND_MAX + 1.0)) > 0.5) HashTurn |= (1ULL << k); } void findFeature() { std::vector old(_features); for (int i = 0; i < 5425; ++i) _features[i] = 0; // 0 ~ 500 for (int i = 0; i < 25; ++i) { Piece p = board[i % 5][i / 5]; if (p.color == White) { switch (p.type) { case PieceType::King: _features[i] = 1; break; case PieceType::Gold: case PieceType::Gold2: _features[25 + i] = 1; break; case PieceType::Silver: case PieceType::Silver2: if (p.promoted) _features[50 + i] = 1; else _features[75 + i] = 1; break; case PieceType::Bishop: case PieceType::Bishop2: if (p.promoted) _features[100 + i] = 1; else _features[125 + i] = 1; break; case PieceType::Rook: case PieceType::Rook2: if (p.promoted) _features[150 + i] = 1; else _features[175 + i] = 1; break; case PieceType::Pawn: case PieceType::Pawn2: if (p.promoted) _features[200 + i] = 1; else _features[225 + i] = 1; break; default: break; } } else { switch (p.type) { case PieceType::King: _features[250 + i] = 1; break; case PieceType::Gold: case PieceType::Gold2: _features[275 + i] = 1; break; case PieceType::Silver: case PieceType::Silver2: if (p.promoted) _features[300 + i] = 1; else _features[325 + i] = 1; break; case PieceType::Bishop: case PieceType::Bishop2: if (p.promoted) _features[350 + i] = 1; else _features[375 + i] = 1; break; case PieceType::Rook: case PieceType::Rook2: if (p.promoted) _features[400 + i] = 1; else _features[425 + i] = 1; break; case PieceType::Pawn: case PieceType::Pawn2: if (p.promoted) _features[450 + i] = 1; else _features[475 + i] = 1; break; default: break; } } } // 500 ~ 575 switch (repeat) { case 1: std::fill(_features.begin() + 500, _features.begin() + 525, 1); break; case 5: std::fill(_features.begin() + 525, _features.begin() + 550, 1); break; case 9: std::fill(_features.begin() + 550, _features.begin() + 575, 1); break; default: break; } // prison w 575 ~ 625 // prison b 625 ~ 675 int tmp = 575; for (int i = 0; i < 2; ++i) { std::vector::iterator it; for (it = chess[i].begin(); it != chess[i].end(); ++it) { if (!(*it).pos.on_board()) { switch ((*it).type) { case PieceType::Gold: std::fill(_features.begin() + tmp, _features.begin() + tmp + 5, 1); break; case PieceType::Silver: std::fill( _features.begin() + tmp + 5, _features.begin() + tmp + 10, 1); break; case PieceType::Bishop: std::fill( _features.begin() + tmp + 10, _features.begin() + tmp + 15, 1); break; case PieceType::Rook: std::fill( _features.begin() + tmp + 15, _features.begin() + tmp + 20, 1); break; case PieceType::Pawn: std::fill( _features.begin() + tmp + 20, _features.begin() + tmp + 25, 1); break; case PieceType::Gold2: std::fill( _features.begin() + tmp + 25, _features.begin() + tmp + 30, 1); break; case PieceType::Silver2: std::fill( _features.begin() + tmp + 30, _features.begin() + tmp + 35, 1); break; case PieceType::Bishop2: std::fill( _features.begin() + tmp + 35, _features.begin() + tmp + 40, 1); break; case PieceType::Rook2: std::fill( _features.begin() + tmp + 40, _features.begin() + tmp + 45, 1); break; case PieceType::Pawn2: std::fill( _features.begin() + tmp + 45, _features.begin() + tmp + 50, 1); break; default: break; } } } tmp += 50; } // dice 675 ~ 700 if (dice == 5) std::fill(_features.begin() + 675, _features.begin() + 700, 1); else std::fill( _features.begin() + dice * 5, _features.begin() + dice * 5 + 5, 1); // history 700 ~ 4900+700 std::copy(old.begin(), old.begin() + 4900, _features.begin() + 700); // 5600 ~ 5625 std::fill(_features.begin() + 5600, _features.end(), (int)_status); } void findActions() { std::vector moves; std::vector dice_moves; for (auto i : chess[(int)_status]) { legalMoves(i, moves); } // dice limit if (dice != 5) { for (auto m : moves) if (m.next.x == dice) dice_moves.push_back(m); } if (dice_moves.empty()) dice_moves = moves; clearActions(); for (auto m : dice_moves) { m.piece.promoted = m.promote; int x = m.next.x; int y = m.next.y; int z = type_to_z(m.piece); addAction(z, x, y); } } virtual void printCurrentBoard() const override { std::cerr << stateDescription(); // for(int i=0; i<2; ++i) { // for(auto j : chess[i]) { // fprintf(stderr, "(%c,%d) ", j.pos.x+'A', j.pos.y); // } // std::cerr << std::endl; // } } std::string print_chess(const int color) const { std::string str; if (color == White) str += "DiceWhite: "; else str += "DiceBlack: "; for (auto i : chess[color]) { if (!i.pos.on_board()) { str += '('; str += i.print(); str += ')'; } else str += i.print(); str += ' '; } str += '\n'; return str; } virtual std::string stateDescription() const override { std::string str; str += " A| B| C| D| E\n"; for (int i = Dy - 1; i >= 0; --i) { str += std::to_string(i + 1) + ' '; for (int j = 0; j < Dx; ++j) { if (j > 0) str += '|'; str += board[j][i].print(); } str += '\n'; } str += print_chess(White); str += print_chess(Black); return str; } virtual std::string actionsDescription() const override { std::stringstream ss; int i = 0; for (auto action : _legalActions) { int z = action.GetX(); int x = action.GetY(); int y = action.GetZ(); Piece p; p.type = z_to_type(z); p.promoted = z_promoted(z); p.color = (int)_status; for (auto i : chess[p.color]) if (i.type == p.type) p.pos = i.pos; ss << p.print(); char buff[53]; sprintf(buff, " (%c, %c) to (%c, %c) ---%d\n", p.pos.x + 'A', p.pos.y + '1', x + 'A', y + '1', i++); ss << buff; } ss << "\nInput format: action index e.g. 0\n"; return ss.str(); } virtual std::string actionDescription(const _Action& action) const { std::stringstream ss; int z = action.GetX(); int x = action.GetY(); int y = action.GetZ(); Piece p; p.type = z_to_type(z); p.promoted = z_promoted(z); p.color = opponent((int)_status); for (auto i : chess[p.color]) if (i.type == p.type) p.pos = i.pos; ss << p.print(); char buff[21]; sprintf(buff, " to (%c, %c)\n", x + 'A', y + '1'); ss << buff; return ss.str(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } int getHashNum(Piece p) { int num = (int)p.type; if (num >= 7) num -= 5; if (p.promoted) num += 5; // 7 8 9 10 11 // 1 2 3 4 5 6 | 7 8 9 10 num -= 1; return num; } int getHashNumjail(Piece p) { // 0~19 return (int)p.type - 2 + 10 * p.color; } void play(Move m) { // std::cerr << m.piece.print(); // fprintf(stderr, " play (%c, %d) to (%c, %d)\n\n", m.piece.pos.x+'A', // m.piece.pos.y, m.next.x+'A', m.next.y); m.piece.promoted |= m.promote; if (m.piece.pos.on_board()) { hash ^= HashArray[m.piece.color][getHashNum(m.piece)][m.piece.pos.x] [m.piece.pos.y]; // eat if (board[m.next.x][m.next.y].color != Empty) { int opp = opponent(m.piece.color); hash ^= HashArray[opp][getHashNum(board[m.next.x][m.next.y])][m.next.x] [m.next.y]; hash ^= HashArrayJail[getHashNumjail(m.piece)]; Piece tmp( m.piece.color, new_type(board[m.next.x][m.next.y].type), false); chess[m.piece.color].push_back(tmp); std::vector::iterator it; for (it = chess[opp].begin(); it != chess[opp].end(); ++it) { if ((*it).type == board[m.next.x][m.next.y].type) { chess[opp].erase(it); break; } } } std::vector::iterator it; for (it = chess[m.piece.color].begin(); it != chess[m.piece.color].end(); ++it) { if ((*it).type == m.piece.type) { (*it).pos = m.next; // decide promoted if ((m.piece.color == White && m.next.y == Dy - 1) || (m.piece.color == Black && m.next.y == 0)) { if (m.piece.promoted || (*it).type == PieceType::Pawn || (*it).type == PieceType::Pawn2) (*it).promoted = true; } board[m.next.x][m.next.y] = (*it); board[m.piece.pos.x][m.piece.pos.y] = Piece(); break; } } } else { // Drop move hash ^= HashArrayJail[getHashNumjail(m.piece)]; std::vector::iterator it; for (it = chess[m.piece.color].begin(); it != chess[m.piece.color].end(); ++it) { if ((*it).type == m.piece.type) { (*it).pos = m.next; board[m.next.x][m.next.y] = (*it); break; } } } hash ^= HashArray[m.piece.color][getHashNum(board[m.next.x][m.next.y])] [m.next.x][m.next.y]; hash ^= HashTurn; if (length < MaxPlayoutLength) { // rollout[length] = m; length++; } else { // set draw when the moves bigger than 1000 _status = GameStatus::tie; } // find repeat if (hash != situation.front()) repeat = 0; else repeat += 1; // fprintf(stderr, "end play\n"); } bool fourfold() { if (repeat < 9) return false; return true; } bool won(int color) { // fprintf(stderr, "won: "); // for(auto i : chess[opponent(color)]) { // if(i.type == PieceType::King) { // if(checkmate(i)) return true; // break; // } // } if (checkmate(opponent(color))) return true; if (fourfold() && opponent((int)_status) == opponent(color)) return true; return false; } virtual void ApplyAction(const _Action& action) override { // fprintf(stderr, "\nApply Action %d\n", (int)_status); Move m; int z = action.GetX(); int x = action.GetY(); int y = action.GetZ(); m.next.x = x; m.next.y = y; m.piece.type = z_to_type(z); m.promote = z_promoted(z); if (_status == GameStatus::player0Turn) { // White to move m.piece.color = White; // find original position for (auto i : chess[White]) { if (i.type == m.piece.type) m.piece.pos = i.pos; } play(m); // printCurrentBoard(); // fprintf(stderr, "hash: %llu\n", hash); // fprintf(stderr, "repeat: %d\n", repeat); if ((GameStatus)_status == GameStatus::tie) { } else if (!won(White)) _status = GameStatus::player1Turn; // Black turn else _status = GameStatus::player0Win; // White won } else { // Black to move m.piece.color = Black; // find original position for (auto i : chess[Black]) { if (i.type == m.piece.type) m.piece.pos = i.pos; } play(m); // printCurrentBoard(); // fprintf(stderr, "hash: %llu\n", hash); // fprintf(stderr, "repeat: %d\n", repeat); if ((GameStatus)_status == GameStatus::tie) { } else if (!won(Black)) _status = GameStatus::player0Turn; // White turn else _status = GameStatus::player1Win; // Black won } if (_status == GameStatus::player0Turn || _status == GameStatus::player1Turn) { if (forcedDice >= 0) { assert(forcedDice > 0); assert(forcedDice < 7); dice = forcedDice - 1; forcedDice = -1; } else { dice = _rng() % 6; } _hash = dice + 1; findFeature(); findActions(); fillFullFeatures(); if (situation.size() == 4) { situation.pop(); situation.push(hash); } else situation.push(hash); } else { _legalActions.clear(); // if(_status == GameStatus::player0Win) // fprintf(stderr, "white win\n"); // else if(_status == GameStatus::player1Win) // fprintf(stderr, "black win\n"); // else fprintf(stderr, "tie\n"); } // fprintf(stderr, "end apply action\n"); } virtual void DoGoodAction() override { // int i; // printCurrentBoard(); // std::cout << actionsDescription(); // std::cin >> i; // _Action a = *(_legalActions[i].get()); // ApplyAction(a); // std::cout << actionDescription(a); return DoRandomAction(); } }; ================================================ FILE: src/games/diceshogi_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: Lin Hsin-I // - Github: https://github.com/free00000000000 // - Email: 410521233@gms.ndhu.edu.tw // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #include "../core/state.h" typedef unsigned short Coord; #include "time.h" #include #include #include #include const int StateForDiceshogiX = 225; const int StateForDiceshogiY = 5; const int StateForDiceshogiZ = 5; #include "diceshogi.h" class ActionForDiceshogi : public _Action { public: // each action has a position (_x[0], _x[1], _x[2]) // here for Diceshogi, there is (0, 0, 0) and (1, 0, 0), // corresponding to steps 2 and 3 respectively. ActionForDiceshogi(int x, int y, int piece) : _Action() { _loc[0] = piece; _loc[1] = x; _loc[2] = y; _hash = (x + y * 5) * 19 + piece; } // step is 2 or 3. }; class StateForDiceshogi : public core::State { public: StateForDiceshogi(int seed) : State(seed) { _stochasticReset = true; } DSPiece board[DSDx][DSDy]; unsigned long long hash; DSMove rollout[DSMaxPlayoutLength]; int length, turn; int repeat; std::queue situation; // 0 = DiceWhite, 1 = DiceBlack std::vector> chess; // 0~5 short dice; void init() { chess.clear(); chess.resize(2); for (int i = 0; i < DSDx; ++i) { for (int j = 0; j < DSDy; ++j) { board[i][j] = DSPiece(DiceEmpty, DSPieceType::None, false); } } for (int i = 1; i <= DSDx; ++i) { board[i - 1][0].addDSPiece( DiceWhite, DSPieceType(i), false, DSPosition(i - 1, 0)); chess[DiceWhite].push_back(board[i - 1][0]); } board[0][1].addDSPiece( DiceWhite, DSPieceType::Pawn, false, DSPosition(0, 1)); chess[DiceWhite].push_back(board[0][1]); for (int i = 1; i <= DSDx; ++i) { board[DSDx - i][4].addDSPiece( DiceBlack, DSPieceType(i), false, DSPosition(DSDx - i, 4)); chess[DiceBlack].push_back(board[DSDx - i][4]); } board[4][3].addDSPiece( DiceBlack, DSPieceType::Pawn, false, DSPosition(4, 3)); chess[DiceBlack].push_back(board[4][3]); turn = DiceBlack; // black first if (forcedDice > 0) { assert(forcedDice > 0); assert(forcedDice < 7); dice = forcedDice - 1; forcedDice = -1; } else { dice = _rng() % 6; } _hash = dice + 1; hash = 0; length = 0; repeat = 0; situation.push(hash); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } bool fourfold() { if (repeat < 9) return false; return true; } bool won(int color) { if (chess[color].back().type == DSPieceType::King) return true; if (_legalActions.empty()) return true; if (fourfold() && opponent(turn) == color) return true; return false; } virtual std::string stateDescription() const override { std::string str; str += " A| B| C| D| E\n"; for (int i = DSDy - 1; i >= 0; --i) { str += to_string(i + 1) + ' '; for (int j = 0; j < DSDx; ++j) { if (j > 0) str += '|'; str += board[j][i].print(); } str += '\n'; } return str; } virtual std::string actionsDescription() override { std::stringstream ss; char x1, y1; for (int i = 0; i < (int)_legalActions.size(); i++) { _Action& action = *(_legalActions[i]); int color = (GameStatus)_status == GameStatus::player1Turn ? DiceWhite : DiceBlack; DSPieceType type = z_to_type(action.GetX()); bool promote = z_promoted(action.GetX()); DSPiece piece = DSPiece(color, type, promote); x1 = static_cast(action.GetY() + 'A'); y1 = static_cast(action.GetZ() + '1'); ss << "Action " << i << ": " << piece.print() << "-" << x1 << y1 << std::endl; } ss << "\nInput format : action index e.g. 0\n"; return ss.str(); } virtual std::string actionDescription(const _Action& action) const { std::stringstream ss; char x1, y1; int color = (turn + 1) % 2; DSPieceType type = z_to_type(action.GetX()); bool promote = z_promoted(action.GetX()); DSPiece piece = DSPiece(color, type, promote); x1 = static_cast(action.GetY() + 'A'); y1 = static_cast(action.GetZ() + '1'); ss << piece.print() << "-" << x1 << y1; return ss.str(); } void print_chess(int color, FILE* fp) { if (color == DiceWhite) fprintf(fp, "DiceWhite "); else fprintf(fp, "DiceBlack "); fprintf(fp, "%lu\n", chess[color].size()); std::vector::iterator it; for (it = chess[color].begin(); it != chess[color].end(); ++it) { if (!(*it).pos.on_board()) { fprintf(fp, "(%s)", (*it).print().c_str()); } else fprintf(fp, "%s", (*it).print().c_str()); } fprintf(fp, "\n"); } void legal_king_moves(DSMove origin, std::vector& moves) { origin.promote = false; short dx[] = {1, 1, 0, -1, -1, -1, 0, 1}; short dy[] = {0, 1, 1, 1, 0, -1, -1, -1}; for (int i = 0; i < 8; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) moves.push_back(origin); } } void legal_gold_moves(DSMove origin, std::vector& moves) { origin.promote = false; if (origin.piece.color == DiceWhite) { short dx[] = {1, 1, 0, -1, -1, 0}; short dy[] = {0, 1, 1, 1, 0, -1}; for (int i = 0; i < 6; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) moves.push_back(origin); } } else { short dx[] = {1, 0, -1, -1, 0, 1}; short dy[] = {0, 1, 0, -1, -1, -1}; for (int i = 0; i < 6; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) moves.push_back(origin); } } } void legal_silver_moves(DSMove origin, std::vector& moves) { origin.promote = false; if (origin.piece.promoted) { legal_gold_moves(origin, moves); return; } if (origin.piece.color == DiceWhite) { short dx[] = {1, 0, -1, -1, 1}; short dy[] = {1, 1, 1, -1, -1}; for (int i = 0; i < 5; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) { moves.push_back(origin); if (origin.next.y == 4) { origin.promote = true; moves.push_back(origin); origin.promote = false; } } } } else { short dx[] = {1, -1, -1, 0, 1}; short dy[] = {1, 1, -1, -1, -1}; for (int i = 0; i < 5; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) { moves.push_back(origin); if (origin.next.y == 0) { origin.promote = true; moves.push_back(origin); origin.promote = false; } } } } } void legal_bishop_moves(DSMove origin, std::vector& moves) { origin.promote = false; short dx[] = {1, -1, -1, 1}; short dy[] = {1, 1, -1, -1}; for (int i = 0; i < 4; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); while (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) { moves.push_back(origin); if (origin.piece.color == DiceWhite) { if (origin.next.y == 4 && !origin.piece.promoted) { origin.promote = true; moves.push_back(origin); origin.promote = false; } } else { // DiceBlack if (origin.next.y == 0 && !origin.piece.promoted) { origin.promote = true; moves.push_back(origin); origin.promote = false; } } if (board[origin.next.x][origin.next.y].color != DiceEmpty) break; origin.next = origin.next + DSPosition(dx[i], dy[i]); } } if (origin.piece.promoted) { short dx[] = {1, 0, -1, 0}; short dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) moves.push_back(origin); } } } void legal_rook_moves(DSMove origin, std::vector& moves) { origin.promote = false; short dx[] = {1, 0, -1, 0}; short dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); while (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) { moves.push_back(origin); if (origin.piece.color == DiceWhite) { if (origin.next.y == 4 && !origin.piece.promoted) { origin.promote = true; moves.push_back(origin); origin.promote = false; } } else { // DiceBlack if (origin.next.y == 0 && !origin.piece.promoted) { origin.promote = true; moves.push_back(origin); origin.promote = false; } } if (board[origin.next.x][origin.next.y].color != DiceEmpty) break; origin.next = origin.next + DSPosition(dx[i], dy[i]); } } if (origin.piece.promoted) { short dx[] = {1, -1, -1, 1}; short dy[] = {1, 1, -1, -1}; for (int i = 0; i < 4; ++i) { origin.next = origin.piece.pos + DSPosition(dx[i], dy[i]); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) moves.push_back(origin); } } } void legal_pawn_moves(DSMove origin, std::vector& moves) { origin.promote = false; if (origin.piece.promoted) { legal_gold_moves(origin, moves); return; } if (origin.piece.color == DiceWhite) { origin.next = origin.piece.pos + DSPosition(0, 1); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) { if (origin.next.y != 5) moves.push_back(origin); else { origin.promote = true; moves.push_back(origin); origin.promote = false; } } } else { origin.next = origin.piece.pos + DSPosition(0, -1); if (origin.next.on_board() && board[origin.next.x][origin.next.y].color != origin.piece.color) { if (origin.next.y != 0) moves.push_back(origin); else { origin.promote = true; moves.push_back(origin); origin.promote = false; } } } } void legal_drop(DSMove origin, std::vector& moves) { origin.promote = false; for (int i = 0; i < DSDx; ++i) { for (int j = 0; j < DSDy; ++j) { if (board[i][j].color == DiceEmpty) { origin.next = DSPosition(i, j); moves.push_back(origin); } } } } void legal_drop_pawn(DSMove origin, std::vector& moves) { origin.promote = false; // find another pawn std::vector::iterator it; int cannotdrop = DSDx; DSPieceType t = new_type(origin.piece.type); for (it = chess[origin.piece.color].begin(); it != chess[origin.piece.color].end(); ++it) { if ((*it).type == t) cannotdrop = (*it).pos.x; } if (origin.piece.color == DiceWhite) { for (int i = 0; i < DSDx; ++i) { if (i == cannotdrop) continue; for (int j = 0; j < DSDy - 1; ++j) { if (board[i][j].color == DiceEmpty) { if ((j - 1) >= 0 && board[i][j - 1].type == DSPieceType::King && board[i][j - 1].color != origin.piece.color) { if (checkmate(board[i][j - 1])) continue; } origin.next = DSPosition(i, j); moves.push_back(origin); } } } } else { for (int i = 0; i < DSDx; ++i) { if (i == cannotdrop) continue; for (int j = 1; j < DSDy; ++j) { if (board[i][j].color == DiceEmpty) { if (board[i][j - 1].type == DSPieceType::King && board[i][j - 1].color != origin.piece.color) { if (checkmate(board[i][j - 1])) continue; } origin.next = DSPosition(i, j); moves.push_back(origin); } } } } } bool can_eat(DSPosition tar, int color) { std::vector moves; legalDSMoves_onboard(opponent(color), moves); std::vector::iterator it; for (it = moves.begin(); it != moves.end(); ++it) if ((*it).next == tar) return true; return false; } bool checkmate(DSPiece king) { std::vector king_moves; DSMove m; m.piece = king; legal_king_moves(m, king_moves); if (king_moves.empty()) return true; std::vector::iterator it; for (it = king_moves.begin(); it != king_moves.end(); ++it) if (!can_eat((*it).next, king.color)) return false; return true; } void legalDSMoves(int color, std::vector& moves) { legalDSMoves_onboard(color, moves); std::vector::iterator it; for (it = chess[color].begin(); it != chess[color].end(); ++it) { DSPiece p = *it; if (!p.pos.on_board()) { DSMove m; m.piece = p; switch (m.piece.type) { case DSPieceType::Gold: case DSPieceType::Gold2: case DSPieceType::Silver: case DSPieceType::Silver2: case DSPieceType::Bishop: case DSPieceType::Bishop2: case DSPieceType::Rook: case DSPieceType::Rook2: legal_drop(m, moves); break; case DSPieceType::Pawn: case DSPieceType::Pawn2: legal_drop_pawn(m, moves); break; default: break; } } } } void legalDSMoves_onboard(int color, std::vector& moves) { std::vector::iterator it; for (it = chess[color].begin(); it != chess[color].end(); ++it) { DSPiece p = *it; DSMove m; m.piece = p; if (m.piece.pos.on_board()) { switch (m.piece.type) { case DSPieceType::King: legal_king_moves(m, moves); break; case DSPieceType::Gold: case DSPieceType::Gold2: legal_gold_moves(m, moves); break; case DSPieceType::Silver: case DSPieceType::Silver2: legal_silver_moves(m, moves); break; case DSPieceType::Bishop: case DSPieceType::Bishop2: legal_bishop_moves(m, moves); break; case DSPieceType::Rook: case DSPieceType::Rook2: legal_rook_moves(m, moves); break; case DSPieceType::Pawn: case DSPieceType::Pawn2: legal_pawn_moves(m, moves); break; default: break; } } } } int opponent(int player) { if (player == DiceWhite) return DiceBlack; return DiceWhite; } DSPieceType new_type(DSPieceType p) { DSPieceType t = p; switch (p) { case DSPieceType::Gold: t = DSPieceType::Gold2; break; case DSPieceType::Gold2: t = DSPieceType::Gold; break; case DSPieceType::Silver: t = DSPieceType::Silver2; break; case DSPieceType::Silver2: t = DSPieceType::Silver; break; case DSPieceType::Bishop: t = DSPieceType::Bishop2; break; case DSPieceType::Bishop2: t = DSPieceType::Bishop; break; case DSPieceType::Rook: t = DSPieceType::Rook2; break; case DSPieceType::Rook2: t = DSPieceType::Rook; break; case DSPieceType::Pawn: t = DSPieceType::Pawn2; break; case DSPieceType::Pawn2: t = DSPieceType::Pawn; break; default: break; } return t; } void play(DSMove m) { m.piece.promoted |= m.promote; turn = opponent(turn); if (m.piece.pos.on_board()) { hash ^= DSHashArray[m.piece.color][getHashNum(m.piece)][m.piece.pos.x] [m.piece.pos.y]; // eat if (board[m.next.x][m.next.y].color != DiceEmpty) { hash ^= DSHashArray[turn][getHashNum(board[m.next.x][m.next.y])] [m.next.x][m.next.y]; hash ^= DSHashArrayE[getHashNumE(m.piece)]; DSPiece tmp( m.piece.color, new_type(board[m.next.x][m.next.y].type), false); chess[m.piece.color].push_back(tmp); std::vector::iterator it; for (it = chess[turn].begin(); it != chess[turn].end(); ++it) { if ((*it).type == board[m.next.x][m.next.y].type) { chess[turn].erase(it); break; } } } std::vector::iterator it; for (it = chess[m.piece.color].begin(); it != chess[m.piece.color].end(); ++it) { if ((*it).type == m.piece.type) { (*it).pos = m.next; // decide promoted if ((m.piece.color == DiceWhite && m.next.y == DSDy - 1) || (m.piece.color == DiceBlack && m.next.y == 0)) { if (m.piece.promoted || (*it).type == DSPieceType::Pawn || (*it).type == DSPieceType::Pawn2) (*it).promoted = true; } board[m.next.x][m.next.y] = (*it); board[m.piece.pos.x][m.piece.pos.y] = DSPiece(DiceEmpty, DSPieceType::None, false); break; } } } else { hash ^= DSHashArrayE[getHashNumE(m.piece)]; std::vector::iterator it; for (it = chess[m.piece.color].begin(); it != chess[m.piece.color].end(); ++it) { if ((*it).type == m.piece.type) { (*it).pos = m.next; board[m.next.x][m.next.y] = (*it); break; } } } hash ^= DSHashArray[m.piece.color][getHashNum(board[m.next.x][m.next.y])] [m.next.x][m.next.y]; hash ^= DSHashTurn; if (length < DSMaxPlayoutLength) { rollout[length] = m; length++; } else { _status = GameStatus::tie; } // find repeat if (hash != situation.front()) repeat = 0; else repeat += 1; } int getHashNum(DSPiece p) { int num = static_cast(p.type); if (num >= 7) num -= 5; if (p.promoted) num += 5; // 7 8 9 10 11 // 1 2 3 4 5 6 | 7 8 9 10 num -= 1; return num; } int getHashNumE(DSPiece p) { // 0~19 return static_cast(p.type) - 2 + 10 * p.color; } // ############### board virtual void Initialize() override { // People implementing classes should not have much to do in _moves; just // _moves.clear(). _stochastic = true; _moves.clear(); // std::cout << "OTGDiceshogi initialize" << std::endl; // the features are just one number between 0 and 1 (the distance, // normalized). _featSize[0] = StateForDiceshogiX; _featSize[1] = StateForDiceshogiY; _featSize[2] = StateForDiceshogiZ; // size of the output of the neural network; this should cover the positions // of actions (above). _actionSize[0] = 19; _actionSize[1] = 5; _actionSize[2] = 5; // _hash is an unsigned int, it has to be *unique*. _hash = 0; // std::cout << "restart!" << std::endl; // _features is a vector representing the current state. It can // (must...) be large for complex games; here just one number // between 0 and 1. trivial case in dimension 1. _features.resize(StateForDiceshogiX * StateForDiceshogiY * StateForDiceshogiZ); std::fill(_features.begin(), _features.end(), 0); /* // _features[:_hash] = 1 for (int i = 0; i < DISTANCE; i++) { _features[i] = (float(_hash) > float(i)) ? 1. : 0.; } */ init(); _status = (GameStatus)opponent(turn); findFeatures(); findActions(turn); fillFullFeatures(); } int type_to_z(DSPiece p) { if (!p.promoted) return (int)p.type - 1; switch (p.type) { case DSPieceType::Silver: return (int)DSPieceZ::PSilver; case DSPieceType::Bishop: return (int)DSPieceZ::PBishop; case DSPieceType::Rook: return (int)DSPieceZ::PRook; case DSPieceType::Pawn: return (int)DSPieceZ::PPawn; case DSPieceType::Silver2: return (int)DSPieceZ::PSilver2; case DSPieceType::Bishop2: return (int)DSPieceZ::PBishop2; case DSPieceType::Rook2: return (int)DSPieceZ::PRook2; case DSPieceType::Pawn2: return (int)DSPieceZ::PPawn2; default: // fprintf(stderr); fprintf( stderr, "%s type to z error %d\n", p.print().c_str(), (int)p.type); break; } return -1; } DSPieceType z_to_type(int z) const { switch ((DSPieceZ)z) { case DSPieceZ::K: return DSPieceType::King; case DSPieceZ::G: return DSPieceType::Gold; case DSPieceZ::G2: return DSPieceType::Gold2; case DSPieceZ::PSilver: case DSPieceZ::S: return DSPieceType::Silver; case DSPieceZ::PBishop: case DSPieceZ::B: return DSPieceType::Bishop; case DSPieceZ::PRook: case DSPieceZ::R: return DSPieceType::Rook; case DSPieceZ::PPawn: case DSPieceZ::P: return DSPieceType::Pawn; case DSPieceZ::PSilver2: case DSPieceZ::S2: return DSPieceType::Silver2; case DSPieceZ::PBishop2: case DSPieceZ::B2: return DSPieceType::Bishop2; case DSPieceZ::PRook2: case DSPieceZ::R2: return DSPieceType::Rook2; case DSPieceZ::PPawn2: case DSPieceZ::P2: return DSPieceType::Pawn2; default: // print(stderr); fprintf(stderr, "%d", z); fprintf(stderr, "z to type error\n"); break; } return DSPieceType::None; } bool z_promoted(int z) const { return z >= 11; } void findActions(int color) { std::vector moves; std::vector dice_moves; legalDSMoves(color, moves); // diece limit if (dice != 5) { std::vector::iterator it; for (it = moves.begin(); it != moves.end(); ++it) { if ((*it).next.x == dice) dice_moves.push_back((*it)); } } if (dice_moves.empty()) dice_moves = moves; int nb = dice_moves.size(); clearActions(); for (int i = 0; i < nb; ++i) { int x = dice_moves[i].next.x; int y = dice_moves[i].next.y; dice_moves[i].piece.promoted |= dice_moves[i].promote; int z = type_to_z(dice_moves[i].piece); addAction(z, x, y); } } void findFeatures() { // fprintf(stderr, "rrrrrrrrrrrr%d\n", turn); std::vector old(_features); for (int i = 0; i < 5425; ++i) _features[i] = 0; // 0 ~ 500 for (int i = 0; i < 25; ++i) { DSPiece p = board[i % 5][i / 5]; if (p.color == DiceWhite) { switch (p.type) { case DSPieceType::King: _features[i] = 1; break; case DSPieceType::Gold: case DSPieceType::Gold2: _features[25 + i] = 1; break; case DSPieceType::Silver: case DSPieceType::Silver2: if (p.promoted) _features[50 + i] = 1; else _features[75 + i] = 1; break; case DSPieceType::Bishop: case DSPieceType::Bishop2: if (p.promoted) _features[100 + i] = 1; else _features[125 + i] = 1; break; case DSPieceType::Rook: case DSPieceType::Rook2: if (p.promoted) _features[150 + i] = 1; else _features[175 + i] = 1; break; case DSPieceType::Pawn: case DSPieceType::Pawn2: if (p.promoted) _features[200 + i] = 1; else _features[225 + i] = 1; break; default: break; } } else { switch (p.type) { case DSPieceType::King: _features[250 + i] = 1; break; case DSPieceType::Gold: case DSPieceType::Gold2: _features[275 + i] = 1; break; case DSPieceType::Silver: case DSPieceType::Silver2: if (p.promoted) _features[300 + i] = 1; else _features[325 + i] = 1; break; case DSPieceType::Bishop: case DSPieceType::Bishop2: if (p.promoted) _features[350 + i] = 1; else _features[375 + i] = 1; break; case DSPieceType::Rook: case DSPieceType::Rook2: if (p.promoted) _features[400 + i] = 1; else _features[425 + i] = 1; break; case DSPieceType::Pawn: case DSPieceType::Pawn2: if (p.promoted) _features[450 + i] = 1; else _features[475 + i] = 1; break; default: break; } } } // 500 ~ 575 switch (repeat) { case 1: std::fill(_features.begin() + 500, _features.begin() + 525, 1); break; case 5: std::fill(_features.begin() + 525, _features.begin() + 550, 1); break; case 9: std::fill(_features.begin() + 550, _features.begin() + 575, 1); break; default: break; } // prison w 575 ~ 625 // prison b 625 ~ 675 int tmp = 575; for (int i = 0; i < 2; ++i) { std::vector::iterator it; for (it = chess[i].begin(); it != chess[i].end(); ++it) { if (!(*it).pos.on_board()) { switch ((*it).type) { case DSPieceType::Gold: std::fill(_features.begin() + tmp, _features.begin() + tmp + 5, 1); break; case DSPieceType::Silver: std::fill( _features.begin() + tmp + 5, _features.begin() + tmp + 10, 1); break; case DSPieceType::Bishop: std::fill( _features.begin() + tmp + 10, _features.begin() + tmp + 15, 1); break; case DSPieceType::Rook: std::fill( _features.begin() + tmp + 15, _features.begin() + tmp + 20, 1); break; case DSPieceType::Pawn: std::fill( _features.begin() + tmp + 20, _features.begin() + tmp + 25, 1); break; case DSPieceType::Gold2: std::fill( _features.begin() + tmp + 25, _features.begin() + tmp + 30, 1); break; case DSPieceType::Silver2: std::fill( _features.begin() + tmp + 30, _features.begin() + tmp + 35, 1); break; case DSPieceType::Bishop2: std::fill( _features.begin() + tmp + 35, _features.begin() + tmp + 40, 1); break; case DSPieceType::Rook2: std::fill( _features.begin() + tmp + 40, _features.begin() + tmp + 45, 1); break; case DSPieceType::Pawn2: std::fill( _features.begin() + tmp + 45, _features.begin() + tmp + 50, 1); break; default: break; } } } tmp += 50; } // dice 675 ~ 700 if (dice == 5) std::fill(_features.begin() + 675, _features.begin() + 700, 1); else std::fill( _features.begin() + dice * 5, _features.begin() + dice * 5 + 5, 1); // history 700 ~ 4900+700 std::copy(old.begin(), old.begin() + 4900, _features.begin() + 700); // 5600 ~ 5625 std::fill(_features.begin() + 5600, _features.end(), turn); } // The action just decreases the distance and swaps the turn to play. virtual void ApplyAction(const _Action& action) override { DSMove m; if ((GameStatus)_status == GameStatus::player1Turn) { // 1 DiceWhite to move // fprintf(stderr, "DiceWhite "); m.piece.color = DiceWhite; m.next = DSPosition(action.GetY(), action.GetZ()); m.piece.type = z_to_type(action.GetX()); m.promote = z_promoted(action.GetX()); std::vector::iterator it; for (it = chess[DiceWhite].begin(); it != chess[DiceWhite].end(); ++it) { if ((*it).type == m.piece.type) m.piece.pos = (*it).pos; } play(m); if ((GameStatus)_status == GameStatus::tie) { } // fprintf(stderr, "draw "); // draw else if (!won(DiceWhite)) _status = GameStatus::player0Turn; // DiceBlack turn else _status = GameStatus::player1Win; // DiceWhite won } else { // DiceBlack // fprintf(stderr, "DiceBlack "); m.piece.color = DiceBlack; m.next = DSPosition(action.GetY(), action.GetZ()); m.piece.type = z_to_type(action.GetX()); m.promote = z_promoted(action.GetX()); std::vector::iterator it; for (it = chess[DiceBlack].begin(); it != chess[DiceBlack].end(); ++it) { if ((*it).type == m.piece.type) m.piece.pos = (*it).pos; } play(m); if ((GameStatus)_status == GameStatus::tie) fprintf(stderr, "draw "); // draw else if (!won(DiceBlack)) _status = GameStatus::player1Turn; // DiceWhite turn else _status = GameStatus::player0Win; // DiceBlack won } findFeatures(); if (situation.size() == 4) { situation.pop(); situation.push(hash); } else situation.push(hash); if (forcedDice >= 0) { assert(forcedDice > 0); assert(forcedDice < 7); dice = forcedDice - 1; forcedDice = -1; } else { dice = _rng() % 6; } // TODO useless now. _hash = dice + 1; // This is useful for the interaction with human. From // now on, _hash represented the random dice. findActions(turn); fillFullFeatures(); } // For this trivial example we just compare to random play virtual void DoGoodAction() override { DoRandomAction(); } }; ================================================ FILE: src/games/einstein.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "../core/state.h" class StateForEinstein : public core::State { public: class Piece { public: int color; int type; // 1~6 bool onboard; int x, y; Piece() { color = 2; type = 0; x = y = -1; } Piece(int c, int t) { color = c; type = t; onboard = false; x = y = -1; } void setPiece(int c, int t, bool isonboard) { color = c; type = t; onboard = isonboard; } void setPosition(int X, int Y) { x = X; y = Y; } }; class Move { public: int x, y; int type; Move() { x = y = -1; type = 0; } Move(int X, int Y, int p) { x = X; y = Y; type = p; } }; public: const static int boardWidth = 5; const static int boardHeight = 5; Move p0_drop; Piece player[2][6]; Piece board[5][5]; int dice; int round; std::vector moves; // unsigned long long HashArray[2][6][5][5]; unsigned long long HashTurn; StateForEinstein(int seed) : State(seed) { _stochasticReset = true; } /*~StateForEinstein() { }*/ virtual void Initialize() override { _moves.clear(); // _hash = 2166136261u; _hash = 0; _status = GameStatus::player0Turn; _featSize[0] = 14; // 2 players * 6 pieces + 1 dice + 1 turn _featSize[1] = boardHeight; _featSize[2] = boardWidth; _actionSize[0] = 6; // 6 pieces _actionSize[1] = boardHeight; _actionSize[2] = boardWidth; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); _stochastic = true; // setFeatures(false, false, false, 0, 0, false); gameInit(); // printCurrentBoard(); findFeature(); findActions(); } void initHash() { /* for (int i = 0; i < 2; ++i) for (int j = 0; j < 6; ++j) for (int x = 0; x < boardWidth; ++x) for (int y = 0; y < boardHeight; ++y) { HashArray[i][j][x][y] = 0; for (int k = 0; k < 64; ++k) if ((_rng() / (RAND_MAX + 1.0)) > 0.5) HashArray[i][j][x][y] |= (1ULL << k); } HashTurn = 0; for (int k = 0; k < 64; ++k) if ((_rng() / (RAND_MAX + 1.0)) > 0.5) HashTurn |= (1ULL << k);*/ } void gameInit() { for (int j = 0; j < boardHeight; ++j) for (int i = 0; i < boardWidth; ++i) board[j][i].setPiece(2, 0, false); // 2 = Empty for (int i = 0; i < 6; ++i) { player[0][i].setPiece(0, i + 1, false); player[1][i].setPiece(1, i + 1, false); } if (forcedDice > 0) { dice = forcedDice - 1; } else { dice = _rng() % 6; } _hash = dice; round = 1; } virtual void setStateFromStr(const std::string& str) override { // example: ABCDEF0000000000000abcdef /* -> x1 x2 x3 x4 x5 x6 0 0 0 0 0 0 0 0 0 0 0 0 0 o1 o2 o3 o4 o5 o6 */ assert(str.length() == 26); char turn = str[25]; _status = turn == '0' ? GameStatus::player0Turn : GameStatus::player1Turn; int color = -1; for (int i = 0; i < 25; i++) { int t = -1; int y = i / 5; int x = i % 5; char c = str[i]; if (c >= 'A' && c <= 'F') { t = int(c) - int('A'); color = 1; } if (c >= 'a' && c <= 'f') { t = int(c) - int('a'); color = 0; } if (t == -1) { continue; } player[color][t].onboard = true; player[color][t].setPosition(x, y); board[y][x] = player[color][t]; } if (forcedDice > 0) { dice = forcedDice - 1; } else { dice = _rng() % 6; } _hash = dice; round = 13; findActions(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } virtual std::string stateDescription() const override { std::string str; str += " A |B |C |D |E \n"; for (int j = 0; j < boardHeight; j++) { str += to_string(j + 1) + ' '; for (int i = 0; i < boardWidth; i++) { if (i > 0) str += '|'; if (board[j][i].color == 0) { str += 'x'; str += static_cast(board[j][i].type + '0'); } else if (board[j][i].color == 1) { str += 'o'; str += static_cast(board[j][i].type + '0'); } else str += " "; } str += '\n'; } return str; } virtual std::string actionsDescription() const override { std::stringstream ss; char c, p, x1, y1; for (int i = 0; i < (int)_legalActions.size(); i++) { const _Action& action = _legalActions[i]; c = (_status == GameStatus::player0Turn) ? 'x' : 'o'; p = static_cast(action.GetX() + ((round <= 12) ? '0' : '1')); x1 = static_cast(action.GetY() + 'A'); y1 = static_cast(action.GetZ() + '1'); ss << "Action " << i << ": " << c << p << " to " << x1 << y1 << std::endl; } ss << "\nInput format : action index e.g. 0\n"; return ss.str(); } virtual std::string actionDescription(const _Action& action) const override { std::stringstream ss; char c, p, x1, y1; c = (_status == GameStatus::player0Turn) ? 'o' : 'x'; p = static_cast(action.GetX() + ((round <= 12) ? '0' : '1')); x1 = static_cast(action.GetY() + 'A'); y1 = static_cast(action.GetZ() + '1'); ss << c << p << " to " << x1 << y1; return ss.str(); } void findFeature() { std::fill(_features.begin(), _features.end(), 0); if (_status == GameStatus::player1Turn) { // 0 ~ 150 for (int i = 0; i < 6; ++i) { Piece p = player[0][i]; if (p.onboard) _features[25 * p.type + p.y * 5 + p.x] = 1; } // 150 ~ 300 for (int i = 0; i < 6; ++i) { Piece p = player[1][i]; if (p.onboard) _features[25 * p.type + p.y * 5 + p.x + 150] = 1; } } else { // 0 ~ 150 for (int i = 0; i < 6; ++i) { Piece p = player[0][i]; if (p.onboard) _features[25 * p.type + (4 - p.y) * 5 + (4 - p.x)] = 1; } // 150 ~ 300 for (int i = 0; i < 6; ++i) { Piece p = player[1][i]; if (p.onboard) _features[25 * p.type + (4 - p.y) * 5 + (4 - p.x) + 150] = 1; } } // 300 ~ 325 if (dice == 5) std::fill(_features.begin() + 300, _features.begin() + 325, 1); else std::fill(_features.begin() + 300 + dice * 5, _features.begin() + 300 + dice * 5 + 5, 1); // 325 ~ std::fill(_features.begin() + 325, _features.end(), (float)_status); fillFullFeatures(); } void legalMoves(int color, std::vector& moves) { // fprintf(stderr, "dice: %d\n", dice+1); if (round <= 12) { if (color == 0) { // player0 int p = round >> 1; for (int j = 0; j < 3; ++j) { for (int i = 0; i < 3 - j; ++i) { if (board[j][i].type == 0) { // if empty Move m(i, j, p + 1); // p+1 = piece type moves.push_back(m); } } } } else { Move m(-p0_drop.y + 4, -p0_drop.x + 4, p0_drop.type); moves.push_back(m); } } else { if (player[color][dice].onboard) { if (color == 0) { short dx[] = {1, 1, 0}; short dy[] = {0, 1, 1}; for (int i = 0; i < 3; ++i) { int x = dx[i] + player[color][dice].x; int y = dy[i] + player[color][dice].y; if (x < 5 && y < 5) { Move m(x, y, player[color][dice].type); moves.push_back(m); } } } else { short dx[] = {0, -1, -1}; short dy[] = {-1, -1, 0}; for (int i = 0; i < 3; ++i) { int x = dx[i] + player[color][dice].x; int y = dy[i] + player[color][dice].y; if (x >= 0 && y >= 0) { Move m(x, y, player[color][dice].type); moves.push_back(m); } } } } else { bool find = false; for (int i = 1; i < 6; ++i) { for (int j = 0, k = 1; j < 2; ++j, k *= -1) { int closest = dice + i * k; if (closest < 6 && closest >= 0 && player[color][closest].onboard) { find = true; if (color == 0) { short dx[] = {1, 1, 0}; short dy[] = {0, 1, 1}; for (int ii = 0; ii < 3; ++ii) { int x = dx[ii] + player[color][closest].x; int y = dy[ii] + player[color][closest].y; if (x < 5 && y < 5) { Move m(x, y, player[color][closest].type); moves.push_back(m); } } } else { short dx[] = {0, -1, -1}; short dy[] = {-1, -1, 0}; for (int ii = 0; ii < 3; ++ii) { int x = dx[ii] + player[color][closest].x; int y = dy[ii] + player[color][closest].y; if (x >= 0 && y >= 0) { Move m(x, y, player[color][closest].type); moves.push_back(m); } } } } } if (find) break; } } } } void findActions() { moves.clear(); if (_status == GameStatus::player0Turn) { legalMoves(0, moves); } else if (_status == GameStatus::player1Turn) { legalMoves(1, moves); } // fprintf(stderr, "round %d moves: %d\n", round, moves.size()); clearActions(); for (auto m : moves) { // fprintf(stderr, "%d: (%d, %d)\n", m.type, m.x, m.y); addAction(m.type - 1, m.x, m.y); } } virtual void ApplyAction(const _Action& action) override { // fprintf(stderr, "Apply action round: %d\n", round); int color; if (_status == GameStatus::player0Turn) { color = 0; _status = GameStatus::player1Turn; } else { color = 1; _status = GameStatus::player0Turn; } int t = action.GetX(); assert(t < 6); int x = action.GetY(); int y = action.GetZ(); assert(y < 6); assert(x < 6); // fprintf(stderr, "get: %d %d %d\n", t, x, y); if (round <= 12) { p0_drop.type = t + 1; p0_drop.x = x; p0_drop.y = y; player[color][t].onboard = true; } else { board[player[color][t].y][player[color][t].x] = Piece(); } if (board[y][x].type != 0) { // eat player[board[y][x].color][board[y][x].type - 1].onboard = false; player[board[y][x].color][board[y][x].type - 1].setPosition(-1, -1); // _hash ^= HashArray[board[y][x].color][board[y][x].type - 1][x][y]; } player[color][t].onboard = true; player[color][t].setPosition(x, y); board[y][x] = player[color][t]; // _hash ^= HashArray[color][t][x][y]; // _hash ^= HashTurn; // fprintf(stderr, "(%d %d) t:%d c:%d\n", x, y, board[y][x].type, // board[y][x].color); if (color == 0 && x == 4 && y == 4) _status = GameStatus::player0Win; else if (color == 1 && x == 0 && y == 0) _status = GameStatus::player1Win; else { round += 1; if (forcedDice > 0) { assert(forcedDice > 0); assert(forcedDice < 7); dice = forcedDice - 1; forcedDice = -1; } else { dice = _rng() % 6; } _hash = dice; findActions(); } findFeature(); if (_legalActions.size() <= 0) _status = (GameStatus)(3 + color); // printCurrentBoard(); // fprintf(stderr, "end Apply Action\n\n"); } virtual void DoGoodAction() override { std::cerr << "DoGoodAction" << std::endl; DoRandomAction(); } }; ================================================ FILE: src/games/game_action.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #ifndef CZF_GAME_GAME_ACTION_H_ #define CZF_GAME_GAME_ACTION_H_ class GameAction {}; #endif // CZF_GAME_GAME_ACTION_H_ ================================================ FILE: src/games/game_base.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "game_base.h" ================================================ FILE: src/games/game_base.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #ifndef CZF_GAME_GAME_BASE_H_ #define CZF_GAME_GAME_BASE_H_ #include "game_action.h" #include "game_player.h" #include "game_state.h" #include #include template class GameBase { public: typedef ActionType Action; typedef StateType State; typedef std::vector History; protected: State state_; History history_; PLAYER turn_player_; bool is_terminal_; PLAYER win_player_; public: GameBase() { Reset(); } ~GameBase() { ; } void Reset() { state_.Reset(); history_.clear(); turn_player_ = PLAYER_0; is_terminal_ = false; win_player_ = PLAYER_NULL; } PLAYER GetTurnPlayer() const { return turn_player_; } int GetGameLength() const { return history_.size(); } void SetTurnPlayer(PLAYER turn_player) { turn_player_ = turn_player; } void GetHistory(History& history) const { history = history_; } Action GetLastAction() { if (history_.size() > 0) return history_.back(); else return Action(); } PLAYER GetWinPlayer() { return win_player_; } // pure virtual functions // need to save win player if game is terminal virtual bool PlayAction(Action action) = 0; virtual bool IsTerminalState() = 0; virtual bool IsLegalAction(Action action) = 0; virtual std::vector GetLegalActions() = 0; virtual std::vector GetIsLegalAction() = 0; }; #endif // CZF_GAME_GAME_BASE_H_ ================================================ FILE: src/games/game_player.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #ifndef CZF_GAME_GAME_PLAYER_H_ #define CZF_GAME_GAME_PLAYER_H_ enum PLAYER { PLAYER_0 = 0u, PLAYER_1 = 1u, PLAYER_NULL = 2u, // if an action's player is null, it is illegal PLAYER_SIZE = 3u }; inline PLAYER operator!(PLAYER player) { return (PLAYER)((unsigned int)player ^ 1); } inline PLAYER IntToPlayer(int i) { if (i == 0) return PLAYER_0; else return PLAYER_1; } #endif // CZF_GAME_GAME_PLAYER_H_ ================================================ FILE: src/games/game_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #ifndef CZF_GAME_GAME_STATE_H_ #define CZF_GAME_GAME_STATE_H_ class GameState {}; #endif // CZF_GAME_GAME_STATE_H_ ================================================ FILE: src/games/gomoku_swap2.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "gomoku_swap2.h" namespace GomokuSwap2 { void Game::initGame() { board.initialize(); hands = 0; winner = -1; } void Game::play(Move& m) { assert(hands < maxHands); hands += 1; if (!m.isColorChanged) { for (int x = 0; x < boardRadix; x++) { for (int y = 0; y < boardRadix; y++) { Chess chess = board.getChess(x, y); if (chess == Chesses::white) { board.setChess(x, y, Chesses::black); } else if (chess == Chesses::black) { board.setChess(x, y, Chesses::white); } } } } board.setChess(m.x, m.y, m.chess); board.turnHash(); } bool Game::isWon(Move& m) { Chess chess = board.getChess(m.x, m.y); auto suck = [&](int dx, int dy) { int count = 1; int x = m.x + dx, y = m.y + dy; while (board.getChess(x, y) == chess) { count += 1; x += dx; y += dy; if (Board::isPosInBoard(x, y)) break; } x = m.x - dx, y = m.y - dy; while (board.getChess(x, y) == chess) { count += 1; x -= dx; y -= dy; if (Board::isPosInBoard(x, y)) break; } return count; }; if (suck(0, 1) >= 5) return true; if (suck(1, 0) >= 5) return true; if (suck(1, 1) >= 5) return true; if (suck(1, -1) >= 5) return true; return false; } void Game::findLegalMoves(Player player) { legalMovesCnt = 0; Chess chess = playerToChess(player); for (int x = 0; x < boardRadix; x++) { for (int y = 0; y < boardRadix; y++) { Move m = Move{x, y, chess, false}; if (board.getChess(x, y) == Chesses::empty) { assert(legalMovesCnt < maxLegalMovesCnt); legalMoves[legalMovesCnt] = m; legalMovesCnt += 1; if (hands == 3 || (hands == 5 && !isTurned)) { m.isColorChanged = true; assert(legalMovesCnt < maxLegalMovesCnt); legalMoves[legalMovesCnt] = m; legalMovesCnt += 1; } } } } } Player Game::chessToPlayer(Chess chess) { if (chess == Chesses::black) return isTurned ? Players::player1 : Players::player0; else if (chess == Chesses::white) return isTurned ? Players::player0 : Players::player1; else assert(chess == Chesses::black || chess == Chesses::white); return -1; } Chess Game::playerToChess(Player player) { if (player == Players::player0) return isTurned ? Chesses::white : Chesses::black; else if (player == Players::player1) return isTurned ? Chesses::black : Chesses::white; else assert(player == Players::player0 || player == Players::player1); return 0xFF; } template void Game::setupBoard(const R& re) { Board::setup({"Empty", "Black", "White"}, {" ", "●", "○"}, re); } State::State(int seed) : core::State(seed) , Game() { std::call_once(setupCalled, [&] { setupBoard(_rng); }); } void State::Initialize() { _moves.clear(); _featSize[0] = featuresSizeX; _featSize[1] = featuresSizeY; _featSize[2] = featuresSizeZ; _actionSize[0] = 2; _actionSize[1] = boardRadix; _actionSize[2] = boardRadix; _status = GameStatus::player0Turn; _features.resize(featuresSize); initGame(); findLegalMoves(Players::player0); findActions(); findFeatures(); _hash = board.getHash(); } unique_ptr State::clone_() const { return make_unique(*this); } void State::ApplyAction(const _Action& action) { if (!terminated()) { Move m{}; Player nextPlayer = -1; m.isColorChanged = action.GetX(); if (m.isColorChanged) isTurned = true; if (_status == GameStatus::player0Turn) { m.chess = playerToChess(Players::player0); nextPlayer = Players::player1; _status = GameStatus::player1Turn; } else if (_status == GameStatus::player1Turn) { m.chess = playerToChess(Players::player1); nextPlayer = Players::player0; _status = GameStatus::player0Turn; } m.x = action.GetY(); m.y = action.GetZ(); play(m); if (canGoNext(m)) { findLegalMoves(nextPlayer); findActions(); findFeatures(); } } _hash = board.getHash(); } bool State::canGoNext(Move& m) { if (isWon(m)) { Player winner = chessToPlayer(m.chess); if (winner == Players::player0) _status = GameStatus::player0Win; else if (winner == Players::player1) _status = GameStatus::player1Win; else assert(winner == Players::player0 || winner == Players::player1); return false; } return true; } void State::DoGoodAction() { DoRandomAction(); } void State::findActions() { clearActions(); for (int i = 0; i < legalMovesCnt; i++) { Move& m = legalMoves[i]; addAction(m.isColorChanged, m.x, m.y); } } void State::findFeatures() { std::fill(_features.begin(), _features.end(), 0.0); auto* f = _features.data(); for (int c = 0; c < this->chesses; c++) { Chess chess = static_cast(c + 1); for (int i = 0; i < this->boardSize; i++) { if (this->board.getChess(i) == chess) *f = 1.0; f++; } } fillFullFeatures(); } } // namespace GomokuSwap2 ================================================ FILE: src/games/gomoku_swap2.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include "../core/state.h" #include "commons/chessboard.h" using namespace std; namespace GomokuSwap2 { typedef int Player; class Players { public: static constexpr Player player0 = 0; static constexpr Player player1 = 1; }; class Chesses { public: static constexpr Chess empty = 0; static constexpr Chess black = 1; static constexpr Chess white = 2; }; class Move { public: int x, y; Chess chess; bool isColorChanged; }; class Game { public: void initGame(); void play(Move& m); bool isBoardFulled(); bool isWon(Move& m); void findLegalMoves(Player player); Player chessToPlayer(Chess chess); Chess playerToChess(Player player); template static void setupBoard(const R& re); static constexpr int chesses = 2; static constexpr int boardRadix = 15; static constexpr int boardSize = boardRadix * boardRadix; static constexpr int maxLegalMovesCnt = 2 * boardRadix * boardRadix; static constexpr int maxHands = maxLegalMovesCnt; static inline std::once_flag setupCalled; using Board = Chessboard; Board board; int hands; bool isTurned; Player winner; Move legalMoves[maxLegalMovesCnt]; int legalMovesCnt; }; class State : public core::State, public Game { public: State(int seed); void Initialize() override; unique_ptr clone_() const override; void ApplyAction(const ::_Action& action) override; void DoGoodAction() override; // void printCurrentBoard() const override; // string stateDescription() const override; // std::string actionDescription(const ::_Action& action) const override; // string actionsDescription() override; // int parseAction(const string& str) override; private: bool canGoNext(Move& m); void findActions(); void findFeatures(); static constexpr int timesteps = 2; static constexpr size_t featuresSizeX = chesses * timesteps + 1; static constexpr size_t featuresSizeY = boardRadix; static constexpr size_t featuresSizeZ = boardRadix; static constexpr size_t featuresSize = featuresSizeX * featuresSizeY * featuresSizeZ; }; } // namespace GomokuSwap2 ================================================ FILE: src/games/havannah.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "game_player.h" #include #include #include #include #include #include namespace Havannah { // For Havannah, SIZE is the edge size of the board. FULLSIZE is 2*SIZE - 1 // and the number of playable cells is FULLSIZE - SIZE*(SIZE-1). enum Color { COLOR_BLACK, COLOR_WHITE, COLOR_NONE }; using Cell = std::pair; // (i, j) in [0, FULLSIZE) x [0, FULLSIZE) constexpr int fullsize(int size) { return 2 * size - 1; } template class Hash { protected: unsigned long long _array[2][fullsize(SIZE)][fullsize(SIZE)]; unsigned long long _turn; unsigned long long _value; public: Hash(); void init(); void updateArray(int color, int j, int i); void updateTurn(); unsigned long long getValue() const; }; struct PathInfo { // Minimal index, in a path array, to a connected path. // Can index itself. int _mainPathIndex; Color _color; unsigned _borders; unsigned _corners; PathInfo() = default; PathInfo(int index, Color color, unsigned borders, unsigned corners) : _mainPathIndex(index) , _color(color) , _borders(borders) , _corners(corners) { } }; template class Board { protected: int _nbFullIndices; int _nbIndices; Color _currentColor; Color _winnerColor; bool _hasPie; std::optional _lastIndex; int _nbEmptyIndices; // neighbours of each cell (indices) // end value: -1 std::array, fullsize(SIZE) * fullsize(SIZE)> _neighboursBoard; static inline Hash _hash; public: // TODO getter ? // PathInfo of the paths indexed from _pathBoard int _pathsEnd; std::array _paths; // path of each cell (index in _paths) std::array _pathBoard; public: Board(); bool canPie() const; Color getCurrentColor() const; Color getWinnerColor() const; PLAYER colorToPlayer(Color color) const; PLAYER getCurrentPlayer() const; PLAYER getWinnerPlayer() const; bool isGameFinished() const; std::optional getLastIndex() const; static Cell convertIndexToCell(int index); static int convertCellToIndex(const Cell& refCell); unsigned long long getHashValue() const; Color getColorAtIndex(int index) const; protected: void getPathIndexAndColorAtIndex(int index, int& pathIndex, Color& color) const; //////////////////////////////////////////////////////////// // Havannah-specific //////////////////////////////////////////////////////////// protected: int _winningCycle; public: void reset(); void play(int index); bool isValidCell(const Cell& refCell) const; bool isValidIndex(int index) const; std::vector findLegalIndices() const; std::vector findWinnerPath() const; protected: unsigned computeBorders(int index) const; unsigned computeCorners(int index) const; bool isWinningPath(const PathInfo& path, int pathIndex, int cellIndex); // isCycle: assume _paths[cellIndex] == pathIndex bool isCycle(int pathIndex, int cellIndex) const; int computeNbOnes(unsigned f) const; std::vector findPathIndices(int pathIndex) const; int computeNbNeighbours(int cellIndex, Color color) const; bool detectHole(const std::vector& indices) const; }; } // namespace Havannah /////////////////////////////////////////////////////////////////////////////// // Havannah::Hash /////////////////////////////////////////////////////////////////////////////// template Havannah::Hash::Hash() { for (int color = 0; color < 2; color++) for (int j = 0; j < fullsize(SIZE); j++) for (int i = 0; i < fullsize(SIZE); i++) { _array[color][j][i] = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) _array[color][j][i] |= (1ULL << k); } _turn = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) _turn |= (1ULL << k); } template void Havannah::Hash::init() { _value = 0; } template void Havannah::Hash::updateArray(int color, int j, int i) { _value ^= _array[color][j][i]; } template void Havannah::Hash::updateTurn() { _value ^= _turn; } template unsigned long long Havannah::Hash::getValue() const { return _value; } /////////////////////////////////////////////////////////////////////////////// // Havannah::Board /////////////////////////////////////////////////////////////////////////////// template Havannah::Board::Board() { _hash.init(); } template Havannah::Color Havannah::Board::getCurrentColor() const { return _currentColor; } template Havannah::Color Havannah::Board::getWinnerColor() const { return _winnerColor; } template PLAYER Havannah::Board::colorToPlayer(Color color) const { if (color == COLOR_NONE) return PLAYER_NULL; else if (color == COLOR_BLACK) return _hasPie ? PLAYER_1 : PLAYER_0; else return _hasPie ? PLAYER_0 : PLAYER_1; } template PLAYER Havannah::Board::getCurrentPlayer() const { return colorToPlayer(_currentColor); } template PLAYER Havannah::Board::getWinnerPlayer() const { return colorToPlayer(_winnerColor); } template bool Havannah::Board::isGameFinished() const { return _nbEmptyIndices == 0 or _winnerColor != COLOR_NONE; } template std::optional Havannah::Board::getLastIndex() const { return _lastIndex; } template bool Havannah::Board::canPie() const { return PIE and _nbEmptyIndices == _nbIndices - 1 and not _hasPie; } template Havannah::Cell Havannah::Board::convertIndexToCell(int index) { int i = index / fullsize(SIZE); int j = index % fullsize(SIZE); return Cell(i, j); } template int Havannah::Board::convertCellToIndex(const Cell& refCell) { return refCell.first * fullsize(SIZE) + refCell.second; } template unsigned long long Havannah::Board::getHashValue() const { return _hash.getValue(); } template void Havannah::Board::getPathIndexAndColorAtIndex( int index, int& pathIndex, Color& color) const { assert(index >= 0); assert(index < _nbFullIndices); // get path index from board pathIndex = _pathBoard[index]; assert(pathIndex >= 0); assert(pathIndex < _pathsEnd); // get color from paths color = _paths[pathIndex]._color; } template Havannah::Color Havannah::Board::getColorAtIndex(int index) const { int pathIndex; Color color; getPathIndexAndColorAtIndex(index, pathIndex, color); return color; } //////////////////////////////////////////////////////////// // Havannah-specific //////////////////////////////////////////////////////////// template void Havannah::Board::reset() { _nbFullIndices = fullsize(SIZE) * fullsize(SIZE); // nb indices for full hex board _nbIndices = _nbFullIndices - (SIZE - 1) * SIZE; _nbEmptyIndices = _nbIndices; // nb indices for havannah board _winningCycle = 0; _currentColor = COLOR_BLACK; _winnerColor = COLOR_NONE; _hasPie = false; _lastIndex.reset(); // _neighboursBoard // precompute all valid neighbours of each cell for (int i = 0; i < fullsize(SIZE); i++) { for (int j = 0; j < fullsize(SIZE); j++) { int index = convertCellToIndex(Cell(i, j)); int k = 0; std::array neighbours = {{Cell(i - 1, j), Cell(i - 1, j + 1), Cell(i, j - 1), Cell(i, j + 1), Cell(i + 1, j - 1), Cell(i + 1, j)}}; for (const Cell& refCell : neighbours) { if (isValidCell(refCell)) { _neighboursBoard[index][k] = convertCellToIndex(refCell); k++; } } _neighboursBoard[index][k] = -1; } } // _paths // no initial path // path 0 for empty cells _paths[0] = PathInfo(0, COLOR_NONE, 0, 0); _pathsEnd = 1; // _pathBoard // set all cells to 0 (empty path) _pathBoard.fill(0); } template void Havannah::Board::play(int index) { assert(isValidIndex(index)); assert(not isGameFinished()); if (_lastIndex and index == *_lastIndex) { assert(canPie()); _hasPie = true; /* // TODO player or color in hash ? Cell cell = convertIndexToCell(index); _hash.updateArray(_currentPlayer, cell.second, cell.first); _hash.updateTurn(); */ } else { assert(_pathBoard[index] == 0); // find previous path & cell at index int boardPathIndex; Color boardColor; getPathIndexAndColorAtIndex(index, boardPathIndex, boardColor); // if board cell is empty, update board if (boardColor == COLOR_NONE) { // update hash int color = getCurrentColor() == COLOR_BLACK ? 0 : 1; Cell cell = convertIndexToCell(index); _hash.updateArray(color, cell.second, cell.first); _hash.updateTurn(); // cell data int mainPathIndex = _pathsEnd; int borders = computeBorders(index); int corners = computeCorners(index); // find all connected paths std::set neighbourMainPathIndices; for (int neighbourIndex : _neighboursBoard[index]) { if (neighbourIndex == -1) break; int neighbourPathIndex; Color neighbourColor; getPathIndexAndColorAtIndex( neighbourIndex, neighbourPathIndex, neighbourColor); if (neighbourColor == _currentColor) { int neighbourMain = _paths[neighbourPathIndex]._mainPathIndex; const PathInfo& neighbourPath = _paths[neighbourMain]; // add neigbour in set neighbourMainPathIndices.insert(neighbourMain); // update cell data borders |= neighbourPath._borders; corners |= neighbourPath._corners; mainPathIndex = std::min(mainPathIndex, neighbourMain); } } // if the cell is not connected to any existing path, then create a // new path if (neighbourMainPathIndices.empty()) { _paths[_pathsEnd] = PathInfo(_pathsEnd, _currentColor, borders, corners); _pathsEnd++; _pathBoard[index] = mainPathIndex; } // if the cell is connected to an existing path, then update paths // and check end of game else { // update main path PathInfo& mainPath = _paths[mainPathIndex]; mainPath._borders |= borders; mainPath._corners |= corners; // update other paths neighbourMainPathIndices.erase(mainPathIndex); if (not neighbourMainPathIndices.empty()) { for (int k = mainPathIndex + 1; k < _pathsEnd; k++) { int mainK = _paths[k]._mainPathIndex; auto iter = neighbourMainPathIndices.find(mainK); if (iter != neighbourMainPathIndices.end()) _paths[k] = mainPath; } } _pathBoard[index] = mainPathIndex; // update winner if (isWinningPath(mainPath, mainPathIndex, index)) _winnerColor = _currentColor; } // end turn and prepare for next one _nbEmptyIndices--; _lastIndex = index; _currentColor = _currentColor == COLOR_BLACK ? COLOR_WHITE : COLOR_BLACK; } } } template bool Havannah::Board::isValidCell(const Cell& refCell) const { int i = refCell.first; int j = refCell.second; return i >= 0 and i < fullsize(SIZE) and j >= 0 and j < fullsize(SIZE) and i + j >= SIZE - 1 and i + j <= 3 * SIZE - 3; } template bool Havannah::Board::isValidIndex(int index) const { Cell c = convertIndexToCell(index); return isValidCell(c); } template std::vector Havannah::Board::findLegalIndices() const { std::vector emptyIndices; emptyIndices.reserve(_nbEmptyIndices + 1); for (int k = 0; k < _nbFullIndices; k++) if (isValidIndex(k) and _pathBoard[k] == 0) emptyIndices.push_back(k); if (canPie()) emptyIndices.push_back(*_lastIndex); return emptyIndices; } template std::vector Havannah::Board::findWinnerPath() const { assert(_winnerColor != COLOR_NONE); // find winning path int winPathIndex; if (_winningCycle != 0) winPathIndex = _winningCycle; else { winPathIndex = 1; while (true) { const PathInfo& path = _paths[winPathIndex]; if (computeNbOnes(path._borders) >= 3) break; if (computeNbOnes(path._corners) >= 2) break; winPathIndex++; } } assert(_paths[winPathIndex]._color == _winnerColor); // find all indices connected to winning path return findPathIndices(winPathIndex); } template bool Havannah::Board::isWinningPath(const PathInfo& path, int pathIndex, int cellIndex) { // test if path is connected to 3 borders if (computeNbOnes(path._borders) >= 3) { return true; } // test if path is connected to 2 corners if (computeNbOnes(path._corners) >= 2) { return true; } // test if path is a cycle if (isCycle(pathIndex, cellIndex)) { _winningCycle = pathIndex; return true; } return false; } template bool Havannah::Board::isCycle(int pathIndex, int cellIndex) const { Color currentColor = _paths[pathIndex]._color; // compute full path std::vector indices = findPathIndices(pathIndex); // check if full path has 6 cells at least if (indices.size() < 6) return false; // check if cell is connected to two previous cells at least if (computeNbNeighbours(cellIndex, currentColor) < 2) return false; // detect interior point for (int index : indices) if (computeNbNeighbours(index, currentColor) == 6) return true; // detect hole return detectHole(indices); } template unsigned Havannah::Board::computeBorders(int index) const { unsigned borders = 0; Cell c = convertIndexToCell(index); if (isValidCell(c)) { int i = c.first; int j = c.second; int e1 = SIZE - 1; int s1 = fullsize(SIZE) - 1; if (i == 0 and e1 < j and j < s1) borders += 1; if (0 < i and i < e1 and j == s1) borders += 2; if (i + j == 3 * e1 and i < s1 and j < s1) borders += 4; if (i == s1 and 0 < j and j < e1) borders += 8; if (e1 < i and i < s1 and j == 0) borders += 16; if (i + j == e1 and i > 0 and j > 0) borders += 32; } return borders; } template unsigned Havannah::Board::computeCorners(int index) const { unsigned corners = 0; Cell c = convertIndexToCell(index); if (isValidCell(c)) { int i = c.first; int j = c.second; int e1 = SIZE - 1; int s1 = fullsize(SIZE) - 1; if (i == 0 and j == e1) corners += 1; if (i == 0 and j == s1) corners += 2; if (i == e1 and j == s1) corners += 4; if (i == s1 and j == e1) corners += 8; if (i == s1 and j == 0) corners += 16; if (i == e1 and j == 0) corners += 32; } return corners; } template int Havannah::Board::computeNbOnes(unsigned f) const { int n = f & 1u; f >>= 1; n += f & 1u; f >>= 1; n += f & 1u; f >>= 1; n += f & 1u; f >>= 1; n += f & 1u; f >>= 1; n += f & 1u; return n; } template std::vector Havannah::Board::findPathIndices( int pathIndex) const { std::vector indices; indices.reserve(2 * fullsize(SIZE)); for (int k = 0; k < _nbFullIndices; k++) { int pathIndexOfK = _pathBoard[k]; int mainPathIndexOfK = _paths[pathIndexOfK]._mainPathIndex; if (mainPathIndexOfK == pathIndex) indices.push_back(k); } return indices; } template int Havannah::Board::computeNbNeighbours(int cellIndex, Color color) const { int nbNeighbours = 0; for (int neighbourIndex : _neighboursBoard[cellIndex]) { if (neighbourIndex == -1) break; if (getColorAtIndex(neighbourIndex) == color) nbNeighbours++; } return nbNeighbours; } template bool Havannah::Board::detectHole( const std::vector& indices) const { std::vector cells; cells.reserve(indices.size()); for (int i : indices) cells.emplace_back(convertIndexToCell(i)); // find bounding box int imin = fullsize(SIZE); int jmin = fullsize(SIZE); int imax = 0; int jmax = 0; for (const Cell& c : cells) { imin = std::min(imin, c.first); imax = std::max(imax, c.first); jmin = std::min(jmin, c.second); jmax = std::max(jmax, c.second); } // reset data int data[fullsize(SIZE) + 2][fullsize(SIZE) + 2]; std::memset((void*)data, 0, sizeof(int) * (fullsize(SIZE) + 2) * (fullsize(SIZE) + 2)); int di = imax - imin + 3; int dj = jmax - jmin + 3; for (int i = 0; i < di; i++) { data[i][0] = 1; data[i][dj - 1] = 1; } for (int j = 0; j < dj; j++) { data[0][j] = 1; data[di - 1][j] = 1; } // write object for (const Cell& c : cells) { int i = c.first - imin + 1; int j = c.second - jmin + 1; data[i][j] = -1; } // propagate background auto fMaxNeighbour = [&data](int i, int j) { int d = data[i][j]; if (d >= 0) { d = std::max(d, data[i - 1][j]); d = std::max(d, data[i - 1][j + 1]); d = std::max(d, data[i][j - 1]); d = std::max(d, data[i][j + 1]); d = std::max(d, data[i + 1][j - 1]); d = std::max(d, data[i + 1][j]); } return d; }; bool hasChanged = true; while (hasChanged) { hasChanged = false; for (int i = 1; i < di - 1; i++) { for (int j = 1; j < dj - 1; j++) { int d = fMaxNeighbour(i, j); if (data[i][j] != d) { data[i][j] = d; hasChanged = true; } } } for (int i = di - 2; i > 0; i--) { for (int j = dj - 2; j > 0; j--) { int d = fMaxNeighbour(i, j); if (data[i][j] != d) { data[i][j] = d; hasChanged = true; } } } } // check initial background for (int i = 0; i < di; i++) for (int j = 0; j < dj; j++) if (data[i][j] == 0) return true; return false; } ================================================ FILE: src/games/havannah_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "../core/state.h" #include "havannah.h" #include #include namespace Havannah { template class Action : public ::_Action { public: Action(int i, int j, int indexInActions); }; template class State : public core::State { private: Board _board; public: State(int seed); // State(int seed, int history, bool turnFeatures); void findActions(); void Initialize() override; void ApplyAction(const _Action& action) override; void DoGoodAction() override; std::unique_ptr clone_() const override; std::string stateDescription() const override; std::string actionDescription(const _Action& action) const override; std::string actionsDescription() const override; int parseAction(const std::string& str) const override; virtual int getCurrentPlayerColor() const override; }; } // namespace Havannah /////////////////////////////////////////////////////////////////////////////// // Havannah::Action /////////////////////////////////////////////////////////////////////////////// template Havannah::Action::Action(int i, int j, int indexInActions) { _loc[0] = 0; _loc[1] = i; _loc[2] = j; _hash = uint32_t(i * fullsize(SIZE) + j); _i = indexInActions; // (position in _legalActions) } /////////////////////////////////////////////////////////////////////////////// // Havannah::State /////////////////////////////////////////////////////////////////////////////// template Havannah::State::State(int seed) : core::State(seed) { } template void Havannah::State::findActions() { auto legalIndices = _board.findLegalIndices(); clearActions(); for (unsigned k = 0; k < legalIndices.size(); ++k) { auto c = _board.convertIndexToCell(legalIndices[k]); addAction(0, c.first, c.second); } } template void Havannah::State::Initialize() { _board.reset(); _moves.clear(); _hash = 0; _status = GameStatus::player0Turn; // features _featSize = {EXTENDED ? 27 : 3, fullsize(SIZE), fullsize(SIZE)}; _features = std::vector(_featSize[0] * _featSize[1] * _featSize[2], 0.f); for (int k = 0; k < fullsize(SIZE) * fullsize(SIZE); k++) _features[2 * fullsize(SIZE) * fullsize(SIZE) + k] = _board.isValidIndex(k); fillFullFeatures(); // actions _actionSize = {1, fullsize(SIZE), fullsize(SIZE)}; findActions(); } template void Havannah::State::ApplyAction(const _Action& action) { assert(not _board.isGameFinished()); // find board move from action int i = action.GetY(); int j = action.GetZ(); int index = _board.convertCellToIndex(Cell(i, j)); std::optional lastIndex = _board.getLastIndex(); // update features if (not lastIndex or *lastIndex != index) { Color currentColor = _board.getCurrentColor(); _features[((currentColor * fullsize(SIZE)) + i) * fullsize(SIZE) + j] = 1.f; } // add connections to borders/corners if (EXTENDED) { const int fs2 = fullsize(SIZE) * fullsize(SIZE); const unsigned mask = 1; for (int k = 0; k < fs2; k++) { if (_board.isValidIndex(k)) { int iPath = _board._pathBoard[k]; if (iPath != 0) { assert(iPath < _board._pathsEnd); const auto& pathInfo = _board._paths[iPath]; unsigned borders = pathInfo._borders; Color color = _board.getColorAtIndex(k); for (int iBorder = 0; iBorder < 6; iBorder++) { _features[(2 * iBorder + color + 3) * fs2 + k] = (borders >> iBorder) & mask; } unsigned corners = pathInfo._corners; for (int iCorner = 0; iCorner < 6; iCorner++) { _features[(2 * iCorner + 12 + color + 3) * fs2 + k] = (corners >> iCorner) & mask; } } } } } // play move _board.play(index); // update game status if (_board.isGameFinished()) { PLAYER winner = _board.getWinnerPlayer(); if (winner == PLAYER_0) _status = GameStatus::player0Win; else if (winner == PLAYER_1) _status = GameStatus::player1Win; else _status = GameStatus::tie; } else { _status = _board.getCurrentPlayer() == PLAYER_0 ? GameStatus::player0Turn : GameStatus::player1Turn; } fillFullFeatures(); // update actions findActions(); // update hash _hash = _board.getHashValue(); } template void Havannah::State::DoGoodAction() { return DoRandomAction(); } template std::unique_ptr Havannah::State::clone_() const { return std::make_unique>(*this); } template std::string Havannah::State::stateDescription() const { const auto& feats = _features; const auto& sizes = _featSize; int ni = sizes[1]; int nj = sizes[2]; auto ind = [ni, nj](int i, int j, int k) { return (k * ni + i) * nj + j; }; std::string str; str += "Havannah\n"; str += " "; for (int k = 0; k < ni; k++) { str += " "; if (k < 10) str += " "; str += std::to_string(k) + " "; } str += "\n"; for (int i = 0; i < ni; i++) { str += " "; for (int k = 0; k < i; k++) str += " "; for (int k = 0; k < SIZE - i - 1; k++) str += " "; for (int k = 0; k < SIZE + i and k < 3 * SIZE - i - 1; k++) str += "----"; str += "\n"; if (i < 10) str += " "; str += std::to_string(i) + " "; for (int k = 0; k < i; k++) str += " "; for (int j = 0; j < nj; j++) { if (_board.isValidCell({i, j})) str += "\\ "; else if (j < SIZE) str += " "; if (feats[ind(i, j, 0)] && feats[ind(i, j, 1)]) str += "! "; else if (feats[ind(i, j, 0)]) str += "X "; else if (feats[ind(i, j, 1)]) str += "O "; else if (_board.isValidCell({i, j})) str += ". "; else if (j < SIZE) str += " "; else continue; } str += "\\ \n"; } str += " "; for (int k = 0; k < ni; k++) str += " "; for (int k = SIZE - 2; _board.isValidCell({SIZE, k}); k++) str += "----"; str += "\n"; str += " "; for (int k = 0; k < SIZE - 1; k++) str += " "; for (int k = 0; k < ni; k++) { str += " "; if (k < 10) str += " "; str += std::to_string(k) + " "; } str += "\n"; return str; } template std::string Havannah::State::actionDescription( const _Action& action) const { return std::to_string(action.GetY()) + "," + std::to_string(action.GetZ()); } template std::string Havannah::State::actionsDescription() const { std::ostringstream oss; for (const auto& a : _legalActions) { oss << a.GetY() << "," << a.GetZ() << " "; } oss << std::endl; return oss.str(); } template int Havannah::State::parseAction( const std::string& str) const { std::istringstream iss(str); try { std::string token; if (not std::getline(iss, token, ',')) throw - 1; int i = std::stoi(token); if (not std::getline(iss, token)) throw - 1; int j = std::stoi(token); for (unsigned k = 0; k < _legalActions.size(); k++) if (_legalActions[k].GetY() == i and _legalActions[k].GetZ() == j) return k; } catch (...) { std::cout << "failed to parse action" << std::endl; } return -1; } template int Havannah ::State::getCurrentPlayerColor() const { return _board.getCurrentColor(); } ================================================ FILE: src/games/hex.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "game_player.h" #include #include #include #include #include namespace Hex { enum Color { COLOR_BLACK, COLOR_WHITE, COLOR_NONE }; using Cell = std::pair; // (i, j) in [0, SIZE) x [0, SIZE) template class Hash { protected: unsigned long long _array[2][SIZE][SIZE]; unsigned long long _turn; unsigned long long _value; public: Hash(); void init(); void updateArray(int Color, int j, int i); void updateTurn(); unsigned long long getValue() const; }; struct PathInfo { // Minimal index, in a path array, to a connected path. // Can index itself. int _mainPathIndex; Color _color; bool _isConnectedBorder1; bool _isConnectedBorder2; PathInfo() = default; PathInfo(int index, Color color, bool border1, bool border2) : _mainPathIndex(index) , _color(color) , _isConnectedBorder1(border1) , _isConnectedBorder2(border2) { } }; template class Board { protected: int _nbFullIndices; int _nbIndices; Color _currentColor; Color _winnerColor; bool _hasPie; std::optional _lastIndex; int _nbEmptyIndices; // neighbours of each cell (indices) // end value: -1 std::array, SIZE * SIZE> _neighboursBoard; // PathInfo of the paths indexed from _pathBoard int _pathsEnd; std::array _paths; // path of each cell (index in _paths) std::array _pathBoard; // static inline Hash _hash; public: Board(); bool canPie() const; Color getCurrentColor() const; Color getWinnerColor() const; PLAYER colorToPlayer(Color color) const; PLAYER getCurrentPlayer() const; PLAYER getWinnerPlayer() const; bool isGameFinished() const; std::optional getLastIndex() const; static Cell convertIndexToCell(int index); static int convertCellToIndex(const Cell& refCell); unsigned long long getHashValue() const; protected: void getPathIndexAndColorAtIndex(int index, int& pathIndex, Color& color) const; //////////////////////////////////////////////////////////// // hex-specific //////////////////////////////////////////////////////////// public: void reset(); void play(int index); bool isValidCell(const Cell& refCell) const; bool isValidIndex(int index) const; std::vector findLegalIndices() const; std::vector findWinnerPath() const; protected: void computeBorderConnection(int index, Color color, bool& isConnectedBorder1, bool& isConnectedBorder2) const; }; } // namespace Hex /////////////////////////////////////////////////////////////////////////////// // Hex::Hash /////////////////////////////////////////////////////////////////////////////// template Hex::Hash::Hash() { for (int color = 0; color < 2; color++) for (int j = 0; j < SIZE; j++) for (int i = 0; i < SIZE; i++) { _array[color][j][i] = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) _array[color][j][i] |= (1ULL << k); } _turn = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) _turn |= (1ULL << k); } template void Hex::Hash::init() { _value = 0; } template void Hex::Hash::updateArray(int color, int j, int i) { _value ^= _array[color][j][i]; } template void Hex::Hash::updateTurn() { _value ^= _turn; } template unsigned long long Hex::Hash::getValue() const { return _value; } /////////////////////////////////////////////////////////////////////////////// // Hex::Board /////////////////////////////////////////////////////////////////////////////// template Hex::Board::Board() { //_hash.init(); } template Hex::Color Hex::Board::getCurrentColor() const { return _currentColor; } template Hex::Color Hex::Board::getWinnerColor() const { return _winnerColor; } template PLAYER Hex::Board::colorToPlayer(Color color) const { if (color == COLOR_NONE) return PLAYER_NULL; else if (color == COLOR_BLACK) return _hasPie ? PLAYER_1 : PLAYER_0; else return _hasPie ? PLAYER_0 : PLAYER_1; } template PLAYER Hex::Board::getCurrentPlayer() const { return colorToPlayer(_currentColor); } template PLAYER Hex::Board::getWinnerPlayer() const { return colorToPlayer(_winnerColor); } template bool Hex::Board::isGameFinished() const { return _nbEmptyIndices == 0 or _winnerColor != COLOR_NONE; } template std::optional Hex::Board::getLastIndex() const { return _lastIndex; } template bool Hex::Board::canPie() const { return PIE and _nbEmptyIndices == _nbIndices - 1 and not _hasPie; } template Hex::Cell Hex::Board::convertIndexToCell(int index) { int i = index / SIZE; int j = index % SIZE; return Cell(i, j); } template int Hex::Board::convertCellToIndex(const Cell& refCell) { return refCell.first * SIZE + refCell.second; } template unsigned long long Hex::Board::getHashValue() const { return 0; // return _hash.getValue(); } template void Hex::Board::getPathIndexAndColorAtIndex(int index, int& pathIndex, Color& color) const { assert(index >= 0); assert(index < _nbFullIndices); // get path index from board pathIndex = _pathBoard[index]; assert(pathIndex >= 0); assert(pathIndex < _pathsEnd); // get color from paths color = _paths[pathIndex]._color; } //////////////////////////////////////////////////////////// // hex-specific //////////////////////////////////////////////////////////// template void Hex::Board::reset() { _nbFullIndices = SIZE * SIZE; _nbIndices = _nbFullIndices; _nbEmptyIndices = _nbIndices; _currentColor = COLOR_BLACK; _winnerColor = COLOR_NONE; _hasPie = false; _lastIndex.reset(); // _neighboursBoard // precompute all valid neighbours of each cell for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { int index = convertCellToIndex(Cell(i, j)); int k = 0; std::array neighbours = {{Cell(i - 1, j), Cell(i - 1, j + 1), Cell(i, j - 1), Cell(i, j + 1), Cell(i + 1, j - 1), Cell(i + 1, j)}}; for (const Cell& refCell : neighbours) { if (isValidCell(refCell)) { _neighboursBoard[index][k] = convertCellToIndex(refCell); k++; } } _neighboursBoard[index][k] = -1; } } // _paths // no initial path // path 0 for empty cells _paths[0] = PathInfo(0, COLOR_NONE, false, false); _pathsEnd = 1; // _pathBoard // set all cells to 0 (empty path) _pathBoard.fill(0); } template void Hex::Board::play(int index) { assert(isValidIndex(index)); assert(not isGameFinished()); if (_lastIndex and index == *_lastIndex) { assert(canPie()); _hasPie = true; /* // TODO player or color in hash ? Cell cell = convertIndexToCell(index); _hash.updateArray(_currentPlayer, cell.second, cell.first); _hash.updateTurn(); */ } else { assert(_pathBoard[index] == 0); // find previous path & cell at index int boardPathIndex; Color boardColor; getPathIndexAndColorAtIndex(index, boardPathIndex, boardColor); // if board cell is empty, update board if (boardColor == COLOR_NONE) { // update hash // int color = getCurrentColor() == COLOR_BLACK ? 0 : 1; // Cell cell = convertIndexToCell(index); //_hash.updateArray(color, cell.second, cell.first); //_hash.updateTurn(); // cell data int mainPathIndex = _pathsEnd; bool isConnectedBorder1, isConnectedBorder2; computeBorderConnection( index, _currentColor, isConnectedBorder1, isConnectedBorder2); // find all connected paths std::set neighbourMainPathIndices; for (int neighbourIndex : _neighboursBoard[index]) { if (neighbourIndex == -1) break; int neighbourPathIndex; Color neighbourColor; getPathIndexAndColorAtIndex( neighbourIndex, neighbourPathIndex, neighbourColor); if (neighbourColor == _currentColor) { int neighbourMain = _paths[neighbourPathIndex]._mainPathIndex; const PathInfo& neighbourPath = _paths[neighbourMain]; // add neigbour in set neighbourMainPathIndices.insert(neighbourMain); // update cell data isConnectedBorder1 |= neighbourPath._isConnectedBorder1; isConnectedBorder2 |= neighbourPath._isConnectedBorder2; mainPathIndex = std::min(mainPathIndex, neighbourMain); } } // if the cell is not connected to any existing path, then create a // new path if (neighbourMainPathIndices.empty()) { _paths[_pathsEnd] = PathInfo( _pathsEnd, _currentColor, isConnectedBorder1, isConnectedBorder2); _pathsEnd++; } // if the cell is connected to an existing path, then update paths // and check end of game else { // update main path PathInfo& mainPath = _paths[mainPathIndex]; mainPath._isConnectedBorder1 |= isConnectedBorder1; mainPath._isConnectedBorder2 |= isConnectedBorder2; // update other paths neighbourMainPathIndices.erase(mainPathIndex); if (not neighbourMainPathIndices.empty()) { for (int k = mainPathIndex + 1; k < _pathsEnd; k++) { int mainK = _paths[k]._mainPathIndex; auto iter = neighbourMainPathIndices.find(mainK); if (iter != neighbourMainPathIndices.end()) _paths[k] = mainPath; } } // update winner if (mainPath._isConnectedBorder1 and mainPath._isConnectedBorder2) _winnerColor = _currentColor; } // end turn and prepare for next one _pathBoard[index] = mainPathIndex; _nbEmptyIndices--; _lastIndex = index; _currentColor = _currentColor == COLOR_BLACK ? COLOR_WHITE : COLOR_BLACK; } } } template bool Hex::Board::isValidCell(const Cell& refCell) const { return refCell.first >= 0 and refCell.first < SIZE and refCell.second >= 0 and refCell.second < SIZE; } template bool Hex::Board::isValidIndex(int index) const { return (index >= 0 and index < _nbFullIndices); } template std::vector Hex::Board::findLegalIndices() const { std::vector emptyIndices; emptyIndices.reserve(_nbEmptyIndices + 1); for (int k = 0; k < _nbFullIndices; k++) if (_pathBoard[k] == 0) emptyIndices.push_back(k); if (canPie()) emptyIndices.push_back(*_lastIndex); return emptyIndices; } template std::vector Hex::Board::findWinnerPath() const { assert(_winnerColor != COLOR_NONE); // find winning main path index int winPathIndex = 1; while (not _paths[winPathIndex]._isConnectedBorder1 or not _paths[winPathIndex]._isConnectedBorder2) winPathIndex++; assert(_paths[winPathIndex]._color == _winnerColor); // find all indices connected to main path std::vector winIndices; winIndices.reserve(2 * SIZE); for (int k = 0; k < _nbFullIndices; k++) { int pathIndexOfK = _pathBoard[k]; int mainPathIndexOfK = _paths[pathIndexOfK]._mainPathIndex; if (mainPathIndexOfK == winPathIndex) winIndices.push_back(k); } return winIndices; } template void Hex::Board::computeBorderConnection( int index, Color color, bool& isConnectedBorder1, bool& isConnectedBorder2) const { if (color == COLOR_BLACK) { isConnectedBorder1 = (index < SIZE); isConnectedBorder2 = (index >= _nbFullIndices - SIZE); } else if (color == COLOR_WHITE) { int j = index % SIZE; isConnectedBorder1 = (j == 0); isConnectedBorder2 = (j == SIZE - 1); } else { isConnectedBorder1 = false; isConnectedBorder2 = false; } } ================================================ FILE: src/games/hex_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "../core/state.h" #include "hex.h" #include #include namespace Hex { template class State : public core::State { private: Board _board; public: State(int seed); // State(int seed, int history, bool turnFeatures); void findActions(); void Initialize() override; void ApplyAction(const _Action& action) override; void DoGoodAction() override; std::unique_ptr clone_() const override; std::string stateDescription() const override; std::string actionDescription(const _Action& action) const override; std::string actionsDescription() const override; int parseAction(const std::string& str) const override; virtual int getCurrentPlayerColor() const override; virtual int getNumPlayerColors() const override; }; } // namespace Hex /////////////////////////////////////////////////////////////////////////////// // Hex::State /////////////////////////////////////////////////////////////////////////////// template Hex::State::State(int seed) : core::State(seed) { } template void Hex::State::findActions() { auto legalIndices = _board.findLegalIndices(); clearActions(); for (unsigned k = 0; k < legalIndices.size(); ++k) { auto c = _board.convertIndexToCell(legalIndices[k]); addAction(0, c.first, c.second); } } template void Hex::State::Initialize() { _board.reset(); _moves.clear(); _hash = 0; _status = GameStatus::player0Turn; // features _featSize = {2, SIZE, SIZE}; _features = std::vector(_featSize[0] * _featSize[1] * _featSize[2], 0.f); fillFullFeatures(); // actions _actionSize = {1, SIZE, SIZE}; findActions(); } template void Hex::State::ApplyAction(const _Action& action) { assert(not _board.isGameFinished()); // find board move from action int i = action.GetY(); int j = action.GetZ(); int index = _board.convertCellToIndex(Cell(i, j)); std::optional lastIndex = _board.getLastIndex(); // update features // TODO assert action is in legal actions ? if (not lastIndex or *lastIndex != index) { Color currentColor = _board.getCurrentColor(); _features[((currentColor * SIZE) + i) * SIZE + j] = 1.f; } // play move _board.play(index); // update game status if (_board.isGameFinished()) { PLAYER winner = _board.getWinnerPlayer(); assert(winner == PLAYER_0 or winner == PLAYER_1); _status = winner == PLAYER_0 ? GameStatus::player0Win : GameStatus::player1Win; } else { PLAYER player = _board.getCurrentPlayer(); assert(player == PLAYER_0 or player == PLAYER_1); _status = player == PLAYER_0 ? GameStatus::player0Turn : GameStatus::player1Turn; } fillFullFeatures(); // update actions findActions(); // update hash _hash = _board.getHashValue(); } template void Hex::State::DoGoodAction() { return DoRandomAction(); } template std::unique_ptr Hex::State::clone_() const { return std::make_unique>(*this); } template std::string Hex::State::stateDescription() const { const auto& feats = _features; const auto& sizes = _featSize; int ni = sizes[1]; int nj = sizes[2]; assert(ni <= 26); auto ind = [ni, nj](int i, int j, int k) { return (k * ni + i) * nj + j; }; std::string str; str += "Hex\n"; str += " "; for (int k = 0; k < nj; k++) { str += " "; str += 'a' + k; } str += "\n"; for (int i = 0; i < ni; i++) { str += " "; for (int k = 0; k < i; k++) str += " "; str += "-"; for (int k = 0; k < nj; k++) str += "----"; str += "\n"; if (i < 9) str += " "; str += std::to_string(1 + i) + " "; for (int k = 0; k < i; k++) str += " "; for (int j = 0; j < nj; j++) { str += "\\ "; if (feats[ind(i, j, 0)] && feats[ind(i, j, 1)]) str += "! "; else if (feats[ind(i, j, 0)]) str += "B "; else if (feats[ind(i, j, 1)]) str += "W "; else str += ". "; } str += "\\ \n"; } str += " "; for (int k = 0; k < nj; k++) str += " "; for (int k = 0; k < nj; k++) str += "----"; str += "\n"; str += " "; for (int k = 0; k < SIZE - 1; k++) str += " "; for (int k = 0; k < nj; k++) { str += " "; str += 'a' + k; } str += "\n"; return str; } template std::string Hex::State::actionDescription( const _Action& action) const { return char('a' + action.GetZ()) + std::to_string(1 + action.GetY()); } template std::string Hex::State::actionsDescription() const { std::ostringstream oss; for (const auto& a : _legalActions) { oss << actionDescription(a) << " "; } oss << std::endl; return oss.str(); } template int Hex::State::parseAction(const std::string& str) const { std::istringstream iss(str); try { char c; iss >> c; std::string token; int j = int(c) - 'a'; if (not std::getline(iss, token)) throw - 1; int i = std::stoi(token) - 1; for (unsigned k = 0; k < _legalActions.size(); k++) if (_legalActions[k].GetY() == i and _legalActions[k].GetZ() == j) return k; } catch (...) { std::cout << "failed to parse action" << std::endl; } return -1; } template int Hex::State::getCurrentPlayerColor() const { return _board.getCurrentColor(); } template int Hex::State::getNumPlayerColors() const { return 2; } ================================================ FILE: src/games/kyotoshogi.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include #include #include const int KyotoWhite = 0; const int KyotoBlack = 1; const int KyotoEmpty = 2; const int KSDx = 5; const int KSDy = 5; const int KSMaxPlayoutLength = 1000; enum KSPieceType { KSNone, Tokin_Lance, Silver_Bishop, KSKing, Gold_Knight, Pawn_Rook, Tokin_Lance2, Silver_Bishop2, Gold_Knight2, Pawn_Rook2, }; enum KSPieceZ { TL, SB, KSK, GK, PR, TL2, SB2, GK2, PR2, PTokin_Lance, PSilver_Bishop, PGold_Knight, PPawn_Rook, PTokin_Lance2, PSilver_Bishop2, PGold_Knight2, PPawn_Rook2 }; // 2: players, 9: pieces+promoted const unsigned long long KSHashArray[2][10][KSDx][KSDy] = { {{{14514284786278117030ULL, 4620546740167642908ULL, 13109570281517897720ULL, 17462938647148434322ULL, 355488278567739596ULL}, {7469126240319926998ULL, 4635995468481642529ULL, 418970542659199878ULL, 9604170989252516556ULL, 6358044926049913402ULL}, {5058016125798318033ULL, 10349215569089701407ULL, 2583272014892537200ULL, 10032373690199166667ULL, 9627645531742285868ULL}, {15810285301089087632ULL, 9219209713614924562ULL, 7736011505917826031ULL, 13729552270962724157ULL, 4596340717661012313ULL}, {4413874586873285858ULL, 5904155143473820934ULL, 16795776195466785825ULL, 3040631852046752166ULL, 4529279813148173111ULL}}, {{3658352497551999605ULL, 13205889818278417278ULL, 17853215078830450730ULL, 14193508720503142180ULL, 1488787817663097441ULL}, {8484116316263611556ULL, 4745643133208116498ULL, 14333959900198994173ULL, 10770733876927207790ULL, 17529942701849009476ULL}, {8081518017574486547ULL, 5945178879512507902ULL, 9821139136195250096ULL, 4728986788662773602ULL, 840062144447779464ULL}, {9315169977352719788ULL, 12843335216705846126ULL, 1682692516156909696ULL, 16733405176195045732ULL, 570275675392078508ULL}, {2804578118555336986ULL, 18105853946332827420ULL, 11444576169427052165ULL, 5511269538150904327ULL, 6665263661402689669ULL}}, {{8872308438533970361ULL, 5494304472256329401ULL, 5260777597240341458ULL, 17048363385688465216ULL, 11601203342555724204ULL}, {13927871433293278342ULL, 13168989862813642697ULL, 13332527631701716084ULL, 1288265801825883165ULL, 8980511589347843149ULL}, {1639193574298669424ULL, 14012553476551396225ULL, 7818048564976445173ULL, 11012385938523194722ULL, 1594098091654903511ULL}, {5035242355473277827ULL, 11507220397369885600ULL, 4097669440061230013ULL, 4158775797243890311ULL, 8008476757622511610ULL}, {18212599999684195413ULL, 3892070972454396029ULL, 15739033291548026583ULL, 5240984520368774617ULL, 15428220128146522508ULL}}, {{6764778500174078837ULL, 17250425930626079997ULL, 15862445320841941901ULL, 9055707723866709616ULL, 407278260229756649ULL}, {6679883267401891436ULL, 13585010976506536654ULL, 9580697194899010248ULL, 7802093638911637786ULL, 535562807229422763ULL}, {16772549087470588412ULL, 2069348082463192648ULL, 18080878539236249869ULL, 12688200000096479737ULL, 8989665349769173357ULL}, {13575112928849473200ULL, 10859033464356012248ULL, 9748216112997718693ULL, 8405158063935141693ULL, 15279502632583570477ULL}, {16055899490125284200ULL, 9066388900883848980ULL, 17884680971936629565ULL, 16395391805201036549ULL, 2550532686790805254ULL}}, {{8052938288948613298ULL, 6344035301348514175ULL, 2193824757648316037ULL, 10113332896580941759ULL, 14001553499759966766ULL}, {597702890888347204ULL, 1874324574384293454ULL, 10826913572691111562ULL, 12821185545071087721ULL, 14606566723149387105ULL}, {15679487422249894303ULL, 16146086267469614290ULL, 11169330698794304272ULL, 17590151747242102595ULL, 18278229723818623796ULL}, {15994633360516603469ULL, 11881756471423721131ULL, 11153906733009525059ULL, 16836145075420168747ULL, 8614597919830747987ULL}, {1459907787369619658ULL, 16682004712721580156ULL, 15261848763679157527ULL, 2717413695111288049ULL, 14889665525641206303ULL}}, {{12338480473037317818ULL, 2557597240994564872ULL, 12402353581130313583ULL, 15355546302939095474ULL, 17651033590338072704ULL}, {11616809212196625943ULL, 6561978461173088746ULL, 5962436378610109024ULL, 1168012300494473422ULL, 5175053317267933097ULL}, {4740525681678845797ULL, 1614376253554691208ULL, 1358027693590031708ULL, 1856992378370522222ULL, 2410813678132517023ULL}, {11582456654366157909ULL, 5754940895753314317ULL, 17548218371729667895ULL, 17945642044770404276ULL, 3721164045489467070ULL}, {13394551493150992827ULL, 12475264300415171883ULL, 10462606688633056562ULL, 13251365510693735175ULL, 3876338822302790600ULL}}, {{13771801863059799470ULL, 13815564444636394855ULL, 16495110748802246170ULL, 2156091871580385249ULL, 12069080176326280986ULL}, {489805578737239572ULL, 5271183164515543116ULL, 11286401144444756863ULL, 6746000579485080744ULL, 5186625150343537151ULL}, {13119883039086991857ULL, 16025170396082521338ULL, 2259331576759215945ULL, 16362343102415556603ULL, 10982898132796723193ULL}, {14666888772828547003ULL, 10462483830193419334ULL, 18236154274104239589ULL, 17759599582309981676ULL, 9339512652453242670ULL}, {14635458573977612405ULL, 13273192362623128494ULL, 7419053614262815071ULL, 2139880725825605974ULL, 15336265650071823816ULL}}, {{6291952205449675957ULL, 14977329074317573394ULL, 4364768269648744391ULL, 17232241565077788317ULL, 8450549923677533764ULL}, {15732483035355013039ULL, 13831185231495622915ULL, 6819123640184841760ULL, 11886944798543888851ULL, 10879889186777890996ULL}, {15555433551230813341ULL, 105259452319848079ULL, 3441909642659419332ULL, 5480947869602487239ULL, 6247709904124292706ULL}, {13391610271247915041ULL, 18346462037123761313ULL, 16636317150577797347ULL, 14149179703416851896ULL, 2376171948756359367ULL}, {5152472389910152792ULL, 2368047066677070121ULL, 16396163399604156946ULL, 14864288050288048653ULL, 7393398358587456124ULL}}, {{9728143941576351989ULL, 5481913815176021747ULL, 16927964714362701213ULL, 14993236783745363262ULL, 9552302871570670457ULL}, {11071069341174528295ULL, 15381321939083200837ULL, 8816171210895558106ULL, 6071991122052964372ULL, 10925078611503375837ULL}, {15239629154712277871ULL, 8615167154188153180ULL, 4917230293625512515ULL, 14895742215835130464ULL, 2359753755290725009ULL}, {6783321469015983851ULL, 360705462143558065ULL, 2287732638733919300ULL, 2984153050512747353ULL, 8021412450653308816ULL}, {12759258587083258672ULL, 1585563973173997547ULL, 18209504305389149669ULL, 11416757620121532143ULL, 6846989578536141166ULL}}}, {{{4365862612957164362ULL, 2931876801952518067ULL, 680191398818283694ULL, 1834352496547951770ULL, 12616538556720116808ULL}, {17563613795929063197ULL, 14519515363534791688ULL, 4349527158980778739ULL, 6714794984698083967ULL, 6696141578113299617ULL}, {17231874453010340947ULL, 18425812703539835928ULL, 3707544366662920973ULL, 10197276740411893574ULL, 12864434420502416888ULL}, {12767250491273234520ULL, 1588549204908870909ULL, 6610295429674120152ULL, 5281895767268096036ULL, 1739897672032589486ULL}, {17406469206626426854ULL, 8710378533013875691ULL, 9587926405039941516ULL, 2805299725371867574ULL, 7146901261023555807ULL}}, {{1825062423171923931ULL, 3049052876249887095ULL, 10771741767689142181ULL, 8733642741329011601ULL, 11979515434717210935ULL}, {10043245691272652957ULL, 5830279975302858953ULL, 17190113074333440499ULL, 18260575806620923460ULL, 14335648769917655401ULL}, {4153816861017702156ULL, 14590500750979768984ULL, 810991542442466488ULL, 7089785717813579612ULL, 12357837562747114001ULL}, {5554121432788679660ULL, 5931025703748246718ULL, 2097835176693352889ULL, 12745618408404359587ULL, 6090924568528767236ULL}, {14734637834598564704ULL, 14439652293742648615ULL, 132405348116615733ULL, 13869945305505934743ULL, 7372953811704808036ULL}}, {{7756437368369298361ULL, 3794582695199039623ULL, 12917619229835701974ULL, 14320084076906478671ULL, 2606626751703588462ULL}, {3137561743724131360ULL, 13808802441028589896ULL, 14231944027275971054ULL, 16852581317945783254ULL, 10323673491841952054ULL}, {2313335010769237820ULL, 13955532667350441768ULL, 5747153089934705338ULL, 13377135145695875091ULL, 6830230899286657495ULL}, {81856298782858401ULL, 1754724887913860152ULL, 13750479713795882912ULL, 11120120136303124367ULL, 15046307382468953177ULL}, {3696979254055818020ULL, 15352898388246644384ULL, 1024778962410818770ULL, 2388728043318081123ULL, 6871857727931721608ULL}}, {{17721619206096294273ULL, 10585202864517959301ULL, 10898249199547365704ULL, 9663430180652362739ULL, 1737102419936989910ULL}, {5117227310201589790ULL, 16884367896390523102ULL, 10498150099412419335ULL, 1921007855220546564ULL, 7643484074408755248ULL}, {11318429053286342939ULL, 1370093900783164344ULL, 6776537281339823025ULL, 3450492372588984223ULL, 9401014545757436331ULL}, {7896519943553875907ULL, 14303443932332314010ULL, 281238069833157985ULL, 9628364435514671685ULL, 1035647896705322917ULL}, {940113500519447970ULL, 12858978713386075837ULL, 2103046007104782505ULL, 1170332608028903179ULL, 6569179731999105361ULL}}, {{9795365446060253382ULL, 3663276878692063340ULL, 11746321300354091749ULL, 5408361990473950532ULL, 9735653452670998906ULL}, {4324195634733601175ULL, 9037136744494003310ULL, 10715330324656609711ULL, 3474343689175121886ULL, 5794004792094061662ULL}, {13295581273946061060ULL, 7292949743142825837ULL, 10886028626057941279ULL, 10688849249577735178ULL, 17297010345160851373ULL}, {13658139148821214513ULL, 4468290234101910565ULL, 9583516840381960864ULL, 2100818272677130469ULL, 3835407486618772476ULL}, {11687972045781987867ULL, 2584265809482868424ULL, 2184370854727222683ULL, 17762352308671769689ULL, 10901114407297935135ULL}}, {{17932666452350314317ULL, 14800534017102555607ULL, 16233839909626358812ULL, 1704089397092793640ULL, 2891239861334407450ULL}, {18077585692287687954ULL, 2363047449739120434ULL, 5904357530901606076ULL, 16765772907460692007ULL, 8757786729323486734ULL}, {3706883612695347371ULL, 14958907430930711064ULL, 9624134580897548276ULL, 10298009507777483067ULL, 5667412839234900228ULL}, {6828701555684071915ULL, 10482797977665945217ULL, 13440894740881464138ULL, 12078258924098889769ULL, 5740761565098658841ULL}, {13914375003115830180ULL, 16808960379045776034ULL, 18421450170384511575ULL, 16478974619417516521ULL, 14381565232287562804ULL}}, {{12792472782420522791ULL, 6620422687983566193ULL, 12025299949416885293ULL, 6046334025019123ULL, 16769051888439418536ULL}, {10312203372653850423ULL, 720028297035890629ULL, 6441255456466558203ULL, 9874005816230679263ULL, 15903170012916142038ULL}, {7557768652767625223ULL, 17626605079857371651ULL, 9092603716684679963ULL, 15518831173015579794ULL, 300798272301981904ULL}, {13762040857722893585ULL, 3117104080838901168ULL, 4702649037537941245ULL, 14408238429167682374ULL, 17923200330177894118ULL}, {7470538549881440849ULL, 3664543122474851710ULL, 17626200978883719521ULL, 15355649603762884691ULL, 4749231114166154448ULL}}, {{11220859020615935192ULL, 4740127963151294603ULL, 16616708905207951068ULL, 9828299274924872726ULL, 8985762004928355786ULL}, {14578866413196595465ULL, 11009044264074492189ULL, 16196760954725621137ULL, 10725252972011913420ULL, 4601011175737567235ULL}, {1441938685024169613ULL, 1896485105672535586ULL, 6635496128279078494ULL, 7401072902622950072ULL, 16075245295895555285ULL}, {11009539992705810569ULL, 13666961049432909413ULL, 930044899627839572ULL, 7899294831116079515ULL, 7830402010660588539ULL}, {5485720725031791061ULL, 17051528642209786987ULL, 7280223907880312904ULL, 10641556535303807158ULL, 12639056541805784436ULL}}, {{12321318600465693220ULL, 10108223508416203621ULL, 16243972184205577210ULL, 8544062083712081766ULL, 11274622334580836223ULL}, {10844017387984539333ULL, 14774228730866078526ULL, 560237794062265107ULL, 5844494700804214355ULL, 12270220729021534083ULL}, {8560016492134621125ULL, 12198417933760222474ULL, 10133839346494565561ULL, 9295901871619786454ULL, 10849442312533122519ULL}, {18021432643418872607ULL, 10155396024449547909ULL, 10524212640889309144ULL, 16662796689072019468ULL, 965963318619140447ULL}, {8887484786999567242ULL, 15714444653107301219ULL, 1678356452623540647ULL, 11052117692502964420ULL, 14549914962216724919ULL}}}}; // eat const unsigned long long KSHashArrayE[18] = { 2062106447906584711ULL, 9160372737526136799ULL, 408961132483689555ULL, 16057982805180036489ULL, 3569128826873655261ULL, 9330490631980133992ULL, 1176328083272936519ULL, 11222898184704497134ULL, 9302091588024171405ULL, 10671057562378043302ULL, 4098229850247478874ULL, 8603114141751656125ULL, 5095034292565071557ULL, 17972196540767155575ULL, 17052421619317624598ULL, 1582078615100434096ULL, 12012345949788712038ULL, 16161371278263065802ULL}; const unsigned long long KSHashTurn = 2541771182459136706ULL; class KSPosition { public: int x, y; KSPosition() { x = y = -1; } KSPosition(int X, int Y) { x = X; y = Y; } bool on_board() { return (x >= 0 && y >= 0 && x < KSDx && y < KSDy); } KSPosition operator+(const KSPosition& p) { KSPosition tmp(x + p.x, y + p.y); return tmp; } bool operator==(const KSPosition& p) { return (x == p.x && y == p.y); } }; class KSPiece { public: int color; KSPieceType type; bool promoted; KSPosition pos; KSPiece() { color = KyotoEmpty; type = KSNone; promoted = false; pos = KSPosition(-1, -1); } KSPiece(int c, KSPieceType t, bool p) { color = c; type = t; promoted = p; } bool operator==(const KSPiece& p) { return (color == p.color && type == p.type && promoted == p.promoted && pos == p.pos); } void addKSPiece(int c, KSPieceType t, bool p, KSPosition position) { color = c; type = t; promoted = p; pos = position; } std::string print() const { std::string str; switch (type) { case KSNone: str += " "; break; case KSKing: if (color == KyotoBlack) str += " k"; else str += " K"; break; case Gold_Knight: case Gold_Knight2: if (color == KyotoBlack) { if (promoted) { str += "kn"; } else { str += " g"; } } else { if (promoted) { str += "KN"; } else { str += " G"; } } break; case Silver_Bishop: case Silver_Bishop2: if (color == KyotoBlack) { if (promoted) { str += " b"; } else { str += " s"; } } else { if (promoted) { str += " B"; } else { str += " S"; } } break; case Pawn_Rook: case Pawn_Rook2: if (color == KyotoBlack) { if (promoted) { str += " r"; } else { str += " p"; } } else { if (promoted) { str += " R"; } else { str += " P"; } } break; case Tokin_Lance: case Tokin_Lance2: if (color == KyotoBlack) { if (promoted) { str += " l"; } else { str += " t"; } } else { if (promoted) { str += " L"; } else { str += " T"; } } break; default: break; } return str; } }; class KSMove { public: KSPiece piece; KSPosition pos1; bool operator==(const KSMove& m) { return pos1 == m.pos1 && piece == m.piece; } }; ================================================ FILE: src/games/kyotoshogi_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "../core/state.h" typedef unsigned short Coord; #include "time.h" #include #include #include #include const int StateForKyotoshogiNumActions = 64 * 3; const int StateForKyotoshogiX = 201; //(9+9+3+2+2)*8 const int StateForKyotoshogiY = 5; const int StateForKyotoshogiZ = 5; #include "kyotoshogi.h" class StateForKyotoshogi : public core::State { public: StateForKyotoshogi(int seed) : State(seed) { } KSPiece board[KSDx][KSDy]; unsigned long long hash; KSMove rollout[KSMaxPlayoutLength]; int length, turn; int Repetition; std::queue situation; // 0 = White, 1 = Black std::vector> chess; std::queue repet; void init() { chess.clear(); chess.resize(2); for (int i = 0; i < KSDx; ++i) { for (int j = 0; j < KSDy; ++j) { board[i][j] = KSPiece(KyotoEmpty, KSNone, false); } } for (int i = 1; i <= KSDx; ++i) { board[i - 1][0].addKSPiece( KyotoWhite, KSPieceType(i), false, KSPosition(i - 1, 0)); chess[KyotoWhite].push_back(board[i - 1][0]); } for (int i = 1; i <= KSDx; ++i) { board[KSDx - i][4].addKSPiece( KyotoBlack, KSPieceType(i), false, KSPosition(KSDx - i, 4)); chess[KyotoBlack].push_back(board[KSDx - i][4]); } turn = KyotoBlack; // black first hash = 0; length = 0; Repetition = 0; repet.push(_hash); } bool fourfold() { if (Repetition < 9) return false; return true; } bool won(int color) { if (chess[color].back().type == KSKing) return true; if (_legalActions.empty()) return true; return false; } virtual std::string stateDescription() const override { std::string str; str += " A| B| C| D| E\n"; for (int i = KSDy - 1; i >= 0; --i) { str += std::to_string(i + 1) + ' '; for (int j = 0; j < KSDx; ++j) { if (j > 0) str += '|'; str += board[j][i].print(); } str += '\n'; } return str; } virtual std::string actionsDescription() const override { std::stringstream ss; char x1, y1; for (int i = 0; i < (int)_legalActions.size(); i++) { const _Action& action = _legalActions[i]; int color = (GameStatus)_status == GameStatus::player1Turn ? KyotoWhite : KyotoBlack; KSPieceType type = z_to_type(action.GetX()); bool promote = z_promoted(action.GetX()); KSPiece piece = KSPiece(color, type, promote); KSPiece flip = KSPiece(color, type, !promote); x1 = static_cast(action.GetY() + 'A'); y1 = static_cast(action.GetZ() + '1'); ss << "Action " << i << ": " << piece.print() << " -> " << flip.print() << "-" << x1 << y1 << std::endl; } ss << "\nInput format : action index e.g. 0\n"; return ss.str(); } virtual std::string actionDescription(const _Action& action) const { std::stringstream ss; char x1, y1; int color = (turn + 1) % 2; KSPieceType type = z_to_type(action.GetX()); bool promote = z_promoted(action.GetX()); KSPiece piece = KSPiece(color, type, promote); KSPiece flip = KSPiece(color, type, !promote); x1 = static_cast(action.GetY() + 'A'); y1 = static_cast(action.GetZ() + '1'); ss << piece.print() << " -> " << flip.print() << "-" << x1 << y1; return ss.str(); } void print_chess(int color, FILE* fp) { if (color == KyotoWhite) fprintf(fp, "KyotoWhite "); else fprintf(fp, "KyotoBlack "); fprintf(fp, "%lu\n", chess[color].size()); std::vector::iterator it; for (it = chess[color].begin(); it != chess[color].end(); ++it) { if (!(*it).pos.on_board()) { fprintf(fp, "(%s)", (*it).print().c_str()); } else fprintf(fp, "%s", (*it).print().c_str()); } fprintf(fp, "\n"); } void legal_king_moves(KSMove origin, std::vector& moves) { origin.piece.promoted = false; short dx[] = {1, 1, 0, -1, -1, -1, 0, 1}; short dy[] = {0, 1, 1, 1, 0, -1, -1, -1}; for (int i = 0; i < 8; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } void legal_gold_knight_moves(KSMove origin, std::vector& moves) { if (origin.piece.promoted) { if (origin.piece.color == KyotoWhite) { short dx[] = {-1, 1}; short dy[] = {2, 2}; for (int i = 0; i < 2; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } else { short dx[] = {-1, 1}; short dy[] = {-2, -2}; for (int i = 0; i < 2; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } } else { if (origin.piece.color == KyotoWhite) { short dx[] = {1, 1, 0, -1, -1, 0}; short dy[] = {0, 1, 1, 1, 0, -1}; for (int i = 0; i < 6; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } else { short dx[] = {1, 0, -1, -1, 0, 1}; short dy[] = {0, 1, 0, -1, -1, -1}; for (int i = 0; i < 6; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } } } void legal_silver_bishop_moves(KSMove origin, std::vector& moves) { if (origin.piece.promoted) { short dx[] = {1, -1, -1, 1}; short dy[] = {1, 1, -1, -1}; for (int i = 0; i < 4; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); while (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) { moves.push_back(origin); if (board[origin.pos1.x][origin.pos1.y].color != KyotoEmpty) break; origin.pos1 = origin.pos1 + KSPosition(dx[i], dy[i]); } } } else { if (origin.piece.color == KyotoWhite) { short dx[] = {1, 0, -1, -1, 1}; short dy[] = {1, 1, 1, -1, -1}; for (int i = 0; i < 5; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } else { short dx[] = {1, -1, -1, 0, 1}; short dy[] = {1, 1, -1, -1, -1}; for (int i = 0; i < 5; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } } } void legal_pawn_rook_moves(KSMove origin, std::vector& moves) { if (origin.piece.promoted) { short dx[] = {1, 0, -1, 0}; short dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); while (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) { moves.push_back(origin); if (board[origin.pos1.x][origin.pos1.y].color != KyotoEmpty) break; origin.pos1 = origin.pos1 + KSPosition(dx[i], dy[i]); } } } else { if (origin.piece.color == KyotoWhite) { origin.pos1 = origin.piece.pos + KSPosition(0, 1); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } else { origin.pos1 = origin.piece.pos + KSPosition(0, -1); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } } void legal_tokin_lance_moves(KSMove origin, std::vector& moves) { if (origin.piece.promoted) { if (origin.piece.color == KyotoWhite) { origin.pos1 = origin.piece.pos + KSPosition(0, 1); while (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) { moves.push_back(origin); if (board[origin.pos1.x][origin.pos1.y].color != KyotoEmpty) break; origin.pos1 = origin.pos1 + KSPosition(0, 1); } } else { origin.pos1 = origin.piece.pos + KSPosition(0, -1); while (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) { moves.push_back(origin); if (board[origin.pos1.x][origin.pos1.y].color != KyotoEmpty) break; origin.pos1 = origin.pos1 + KSPosition(0, -1); } } } else { if (origin.piece.color == KyotoWhite) { short dx[] = {1, 1, 0, -1, -1, 0}; short dy[] = {0, 1, 1, 1, 0, -1}; for (int i = 0; i < 6; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } else { short dx[] = {1, 0, -1, -1, 0, 1}; short dy[] = {0, 1, 0, -1, -1, -1}; for (int i = 0; i < 6; ++i) { origin.pos1 = origin.piece.pos + KSPosition(dx[i], dy[i]); if (origin.pos1.on_board() && board[origin.pos1.x][origin.pos1.y].color != origin.piece.color) moves.push_back(origin); } } } } void legal_drop(KSMove origin, std::vector& moves) { origin.piece.promoted = false; for (int i = 0; i < KSDx; ++i) { for (int j = 0; j < KSDy; ++j) { if (board[i][j].color == KyotoEmpty) { origin.pos1 = KSPosition(i, j); origin.piece.promoted = false; moves.push_back(origin); origin.piece.promoted = true; moves.push_back(origin); } } } } bool can_eat(KSPosition tar, int color) { std::vector moves; legalKSMoves_onboard(opponent(color), moves); std::vector::iterator it; for (it = moves.begin(); it != moves.end(); ++it) if ((*it).pos1 == tar) return true; return false; } bool checkmate(KSPiece king) { std::vector king_moves; KSMove m; m.piece = king; legal_king_moves(m, king_moves); if (king_moves.empty()) return true; std::vector::iterator it; for (it = king_moves.begin(); it != king_moves.end(); ++it) if (!can_eat((*it).pos1, king.color)) return false; return true; } void legalKSMoves(int color, std::vector& moves) { legalKSMoves_onboard(color, moves); std::vector::iterator it; for (it = chess[color].begin(); it != chess[color].end(); ++it) { KSPiece p = *it; if (!p.pos.on_board()) { KSMove m; m.piece = p; legal_drop(m, moves); } } } void legalKSMoves_onboard(int color, std::vector& moves) { std::vector::iterator it; for (it = chess[color].begin(); it != chess[color].end(); ++it) { KSPiece p = *it; KSMove m; m.piece = p; if (m.piece.pos.on_board()) { switch (m.piece.type) { case KSKing: legal_king_moves(m, moves); break; case Gold_Knight: case Gold_Knight2: legal_gold_knight_moves(m, moves); break; case Silver_Bishop: case Silver_Bishop2: legal_silver_bishop_moves(m, moves); break; case Tokin_Lance: case Tokin_Lance2: legal_tokin_lance_moves(m, moves); break; case Pawn_Rook: case Pawn_Rook2: legal_pawn_rook_moves(m, moves); break; default: break; } } } } int opponent(int player) { if (player == KyotoWhite) return KyotoBlack; return KyotoWhite; } KSPieceType new_type(KSPieceType p) { KSPieceType t = p; switch (p) { case Gold_Knight: t = Gold_Knight2; break; case Gold_Knight2: t = Gold_Knight; break; case Silver_Bishop: t = Silver_Bishop2; break; case Silver_Bishop2: t = Silver_Bishop; break; case Tokin_Lance: t = Tokin_Lance2; break; case Tokin_Lance2: t = Tokin_Lance; break; case Pawn_Rook: t = Pawn_Rook2; break; case Pawn_Rook2: t = Pawn_Rook; break; default: break; } return t; } void play(KSMove m) { turn = opponent(turn); if (m.piece.pos.on_board()) { hash ^= KSHashArray[m.piece.color][getHashNum(m.piece)][m.piece.pos.x] [m.piece.pos.y]; if (board[m.pos1.x][m.pos1.y].color != KyotoEmpty) { assert(m.pos1.on_board()); hash ^= KSHashArray[turn][getHashNum(board[m.pos1.x][m.pos1.y])] [m.pos1.x][m.pos1.y]; hash ^= KSHashArrayE[getHashNumE(m.piece)]; KSPiece tmp( m.piece.color, new_type(board[m.pos1.x][m.pos1.y].type), false); chess[m.piece.color].push_back(tmp); std::vector::iterator it; for (it = chess[turn].begin(); it != chess[turn].end(); ++it) if ((*it).type == board[m.pos1.x][m.pos1.y].type) { chess[turn].erase(it); break; } } board[m.pos1.x][m.pos1.y] = board[m.piece.pos.x][m.piece.pos.y]; board[m.pos1.x][m.pos1.y].pos = KSPosition(m.pos1.x, m.pos1.y); // decide promoted if (m.piece.type != KSKing) { board[m.pos1.x][m.pos1.y].promoted = !board[m.pos1.x][m.pos1.y].promoted; } board[m.piece.pos.x][m.piece.pos.y] = KSPiece(KyotoEmpty, KSNone, false); } else { hash ^= KSHashArrayE[getHashNumE(m.piece)]; board[m.pos1.x][m.pos1.y] = KSPiece(m.piece.color, m.piece.type, m.piece.promoted); board[m.pos1.x][m.pos1.y].pos = KSPosition(m.pos1.x, m.pos1.y); } std::vector::iterator it; for (it = chess[m.piece.color].begin(); it != chess[m.piece.color].end(); ++it) { if ((*it).type == m.piece.type) { (*it).pos = m.pos1; if (m.piece.pos.on_board()) { if (m.piece.type != KSKing) (*it).promoted = !(*it).promoted; } else { (*it).promoted = m.piece.promoted; } break; } } hash ^= KSHashArray[m.piece.color][getHashNum(board[m.pos1.x][m.pos1.y])] [m.pos1.x][m.pos1.y]; hash ^= KSHashTurn; if (length < KSMaxPlayoutLength) { rollout[length] = m; length++; } else { _status = GameStatus::tie; } if (hash == repet.front()) { Repetition += 1; } else { Repetition = 0; } } int getHashNum(KSPiece p) { int num = p.type; if (num == 3) { num = 1; } else if (num == 1 || num == 2) { num = num + 1; } else if (num >= 6) { num -= 4; } if (p.promoted) num += 4; num = num - 1; return num; } int getHashNumE(KSPiece p) { int num = p.type; if (num == 3) { num = 1; } else if (num == 1 || num == 2) { num = num + 1; } return num - 2 + 10 * p.color; } virtual void Initialize() override { _moves.clear(); // the features are just one number between 0 and 1 (the distance, // normalized). _featSize[0] = StateForKyotoshogiX; _featSize[1] = StateForKyotoshogiY; _featSize[2] = StateForKyotoshogiZ; // size of the output of the neural network; this should cover the positions // of actions (above). _actionSize[0] = 17; _actionSize[1] = 5; _actionSize[2] = 5; // _hash is an unsigned int, it has to be *unique*. _hash = 0; _features.resize(StateForKyotoshogiX * StateForKyotoshogiY * StateForKyotoshogiZ); std::fill(_features.begin(), _features.end(), 0); init(); _status = (GameStatus)opponent(turn); findFeatures(); findActions(turn); fillFullFeatures(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } int type_to_z(KSPiece p) { if (!p.promoted) return (int)p.type - 1; switch (p.type) { case Tokin_Lance: return PTokin_Lance; case Silver_Bishop: return PSilver_Bishop; case Gold_Knight: return PGold_Knight; case Pawn_Rook: return PPawn_Rook; case Tokin_Lance2: return PTokin_Lance2; case Silver_Bishop2: return PSilver_Bishop2; case Gold_Knight2: return PGold_Knight2; case Pawn_Rook2: return PPawn_Rook2; default: fprintf( stderr, "%s type to z error %d\n", p.print().c_str(), (int)p.type); break; } return -1; } KSPieceType z_to_type(int z) const { switch ((KSPieceZ)z) { case KSK: return KSKing; case GK: case PGold_Knight: return Gold_Knight; case GK2: case PGold_Knight2: return Gold_Knight2; case PSilver_Bishop: case SB: return Silver_Bishop; case PSilver_Bishop2: case SB2: return Silver_Bishop2; case PPawn_Rook: case PR: return Pawn_Rook; case PPawn_Rook2: case PR2: return Pawn_Rook2; case PTokin_Lance2: case TL2: return Tokin_Lance2; case PTokin_Lance: case TL: return Tokin_Lance; default: fprintf(stderr, "z %d to type error\n", z); break; } return KSNone; } bool z_promoted(int z) const { return z >= 9; } void findActions(int color) { std::vector moves; legalKSMoves(color, moves); int nb = moves.size(); clearActions(); for (int i = 0; i < nb; ++i) { int x = moves[i].pos1.x; int y = moves[i].pos1.y; int z = type_to_z(moves[i].piece); addAction(z, x, y); } } void findFeatures() { std::vector old(_features); for (int i = 0; i < 4865; ++i) _features[i] = 0; // 0 ~ 500 for (int i = 0; i < 25; ++i) { KSPiece p = board[i % 5][i / 5]; if (p.color == KyotoWhite) { switch (p.type) { case KSKing: _features[i] = 1; break; case Gold_Knight: case Gold_Knight2: if (p.promoted) _features[25 + i] = 1; else _features[50 + i] = 1; break; case Silver_Bishop: case Silver_Bishop2: if (p.promoted) _features[75 + i] = 1; else _features[100 + i] = 1; break; case Pawn_Rook: case Pawn_Rook2: if (p.promoted) _features[125 + i] = 1; else _features[150 + i] = 1; break; case Tokin_Lance: case Tokin_Lance2: if (p.promoted) _features[175 + i] = 1; else _features[200 + i] = 1; break; default: break; } } else { switch (p.type) { case KSKing: _features[225 + i] = 1; break; case Gold_Knight: case Gold_Knight2: if (p.promoted) _features[250 + i] = 1; else _features[275 + i] = 1; break; case Silver_Bishop: case Silver_Bishop2: if (p.promoted) _features[300 + i] = 1; else _features[325 + i] = 1; break; case Pawn_Rook: case Pawn_Rook2: if (p.promoted) _features[350 + i] = 1; else _features[375 + i] = 1; break; case Tokin_Lance: case Tokin_Lance2: if (p.promoted) _features[400 + i] = 1; else _features[425 + i] = 1; break; default: break; } } } // 450 ~ 525 switch (Repetition) { case 1: std::fill(_features.begin() + 450, _features.begin() + 475, 1); break; case 5: std::fill(_features.begin() + 475, _features.begin() + 500, 1); break; case 9: std::fill(_features.begin() + 500, _features.begin() + 525, 1); break; default: break; } int tmp = 525; for (int i = 0; i < 2; ++i) { std::vector::iterator it; for (it = chess[i].begin(); it != chess[i].end(); ++it) { if (!(*it).pos.on_board()) { switch ((*it).type) { case Gold_Knight: std::fill(_features.begin() + tmp, _features.begin() + tmp + 5, 1); break; case Silver_Bishop: std::fill( _features.begin() + tmp + 5, _features.begin() + tmp + 10, 1); break; case Pawn_Rook: std::fill( _features.begin() + tmp + 10, _features.begin() + tmp + 15, 1); break; case Tokin_Lance: std::fill( _features.begin() + tmp + 15, _features.begin() + tmp + 20, 1); break; case Gold_Knight2: std::fill( _features.begin() + tmp + 25, _features.begin() + tmp + 30, 1); break; case Silver_Bishop2: std::fill( _features.begin() + tmp + 30, _features.begin() + tmp + 35, 1); break; case Pawn_Rook2: std::fill( _features.begin() + tmp + 35, _features.begin() + tmp + 40, 1); break; case Tokin_Lance2: std::fill( _features.begin() + tmp + 40, _features.begin() + tmp + 45, 1); break; default: break; } } } std::fill(_features.begin() + tmp + 20, _features.begin() + tmp + 25, 0); std::fill(_features.begin() + tmp + 45, _features.begin() + tmp + 50, 0); tmp += 50; } // history 625 ~ 4375+625 std::copy(old.begin(), old.begin() + 4375, _features.begin() + 625); // 5000~5025 std::fill(_features.begin() + 5000, _features.end(), turn); } // The action just decreases the distance and swaps the turn to play. virtual void ApplyAction(const _Action& action) override { KSMove m; if ((GameStatus)_status == GameStatus::player1Turn) { // KyotoWhite to move m.piece.color = KyotoWhite; m.pos1 = KSPosition(action.GetY(), action.GetZ()); m.piece.type = z_to_type(action.GetX()); m.piece.promoted = z_promoted(action.GetX()); std::vector::iterator it; for (it = chess[KyotoWhite].begin(); it != chess[KyotoWhite].end(); ++it) { if ((*it).type == m.piece.type) m.piece.pos = (*it).pos; } play(m); findActions(KyotoBlack); if ((GameStatus)_status == GameStatus::tie || fourfold()) { _status = GameStatus::tie; _legalActions.clear(); } else if (won(KyotoWhite) || _legalActions.empty()) _status = GameStatus::player1Win; // KyotoWhite win else _status = GameStatus::player0Turn; // KyotoBlack turn } else { // KyotoBlack m.piece.color = KyotoBlack; m.pos1 = KSPosition(action.GetY(), action.GetZ()); m.piece.type = z_to_type(action.GetX()); m.piece.promoted = z_promoted(action.GetX()); std::vector::iterator it; for (it = chess[KyotoBlack].begin(); it != chess[KyotoBlack].end(); ++it) { if ((*it).type == m.piece.type) m.piece.pos = (*it).pos; } play(m); findActions(KyotoWhite); if ((GameStatus)_status == GameStatus::tie || fourfold()) { _status = GameStatus::tie; _legalActions.clear(); } else if (won(KyotoBlack) || _legalActions.empty()) _status = GameStatus::player0Win; // KyotoBlack won else _status = GameStatus::player1Turn; // KyotoWhite turn } findFeatures(); _hash = hash; if (repet.size() == 4) { repet.pop(); repet.push(_hash); } else repet.push(_hash); fillFullFeatures(); } // For this trivial example we just compare to random play. virtual void DoGoodAction() override { DoRandomAction(); } }; ================================================ FILE: src/games/ludii/README.md ================================================ # Polygames + Ludii integration We have implemented a bridge between Polygames' tree search and learning algorithms, and the large library of games implemented in the [Ludii general game system](https://ludii.games/). The game logic is run in Ludii, and training logic / action selection are performed by Polygames. In theory, this can work for **any game** that can be run in Ludii. In practice, there may be some games that fail (such as extremely large games that run out of memory, or games with a complex state representation for which appropriate support for building tensors has not yet been built into Ludii), but many hundreds of games should work. ## Requirements Since Ludii uses Java, the Ludii integration of Polygames requires the optional step of installing `openjdk` from [Polygames' main installation instructions](https://github.com/facebookincubator/Polygames) to be followed. When building Polygames, make sure **not** to use the `-DWITH_LUDII=OFF` argument for `cmake`, because that will disable support for Ludii. ## Installation After installing Polygames as per usual, Ludii itself must also be installed in the correct place such that Polygames can find and run it. More specifically: 1. Download any desired version of the Ludii player from https://ludii.games/download.php (at least versions 1.1.6 and higher should run correctly, some older versions may also still work well). 2. Rename the downloaded file from `Ludii-X.Y.Z.jar` to `Ludii.jar`, and place it in `/ludii/Ludii.jar` (create a new `ludii` directory under `Polygames` if it does not already exist). ## Using Ludii Games Any command-line option in Polygames that accepts `--game_name` arguments (such as `train`, `eval`, etc.) can also run any game through Ludii by specifying it in the following format: ``` --game_name="Ludii.lud" ``` The `` part of such an argument must match the name of the game as it is inside Ludii exactly, including whitespaces. This works in the same way as [programmatic loading of games in Java when using Ludii as a library for Java code](https://ludiitutorials.readthedocs.io/en/latest/loading_games.html). The exact game names are also displayed inside the game loader of the GUI of Ludii, which is visible when the Ludii jar is run as an executable. For example, a training run with otherwise default arguments for Ludii's implementation of Tic-Tac-Toe (as opposed to the built-in C++ implementation of the game in Polygames) can be launched using: ``` python -m pypolygames train --game_name="LudiiTic-Tac-Toe.lud" ``` ## Using Game Options For many of its games, Ludii also provides additional *options* that can be used to load different variants of a game, with different board sizes, board shapes, different rulesets, etc. Non-default variants of any Ludii game can also be loaded in Polygames, through an additional `--game_options` argument followed up by any arbitrary number of Strings, which are subsequently all passed into Ludii as options. These should again be provided in the same format as when options are provided [programmatically to Ludii from Java](https://ludiitutorials.readthedocs.io/en/latest/loading_games.html), and the exact strings to be entered can also be found in Ludii's GUI from the options menu after loading a particular game. For example, we can launch a training run in Ludii's implementation of Hex, with a board size of 13x13 and an inverted win condition ("Misere") as follows: ``` python -m pypolygames train --game_name="LudiiHex.lud" --game_options "Board Size/13x13" "End Rules/Misere" ``` ## Trained Models Checkpoints of training runs for some Ludii games have been made [publicly available here](http://dl.fbaipublicfiles.com/polygames/ludii_checkpoints/list.txt). Each of these checkpoints was trained on the default variant of its game (no custom options specified), for 20 hours on 8 GPUs and 80 CPU cores. ================================================ FILE: src/games/ludii/jni_utils.cc ================================================ // inspired from // https://gist.github.com/alexminnaar/90cf1ea3de45e79a1b14081d90d214b7 /* Copyright (c) 2020 Alex Minnaar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "jni_utils.h" #include #include #include #include namespace Ludii { JavaVM* JNIUtils::jvm = nullptr; jint JNIUtils::res = 0; thread_local JNIEnv* JNIUtils::env = nullptr; JNIEnv* JNIUtils::GetEnv() { if (jvm == nullptr) return nullptr; if (env == nullptr) { JavaVMAttachArgs args = {JNI_VERSION_1_2, 0, 0}; jvm->AttachCurrentThread((void**)&env, &args); } return env; } void JNIUtils::InitJVM(std::string jar_location) { if (jvm != nullptr) return; // We've already initialised the JVM JNIEnv* env = nullptr; std::cout << "intializing JVM" << std::endl; if (jar_location.empty()) jar_location = "ludii/Ludii.jar"; // Check if we can actually access the JAR file if (FILE* file = fopen(jar_location.c_str(), "rb")) { // The Ludii.jar file seems to be there, so we're fine! fclose(file); } else { // Can't find the Ludii.jar file return; } //#define CHECK_JNI // Uncomment this to run extra checks for JNI #ifdef JNI_VERSION_1_2 JavaVMInitArgs vm_args; #ifdef CHECK_JNI const size_t num_jvm_args = 3; #else const size_t num_jvm_args = 2; #endif JavaVMOption options[num_jvm_args]; std::string java_classpath = "-Djava.class.path=" + jar_location; options[0].optionString = java_classpath.data(); std::string heapdump_str = "-XX:+HeapDumpOnOutOfMemoryError"; options[1].optionString = heapdump_str.data(); #ifdef CHECK_JNI std::string check_jni = "-Xcheck:jni"; options[2].optionString = check_jni.data(); #endif vm_args.version = 0x00010002; vm_args.options = options; vm_args.nOptions = num_jvm_args; vm_args.ignoreUnrecognized = JNI_TRUE; /* Create the Java VM */ res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); #else JDK1_1InitArgs vm_args; std::string classpath = vm_args.classpath + ";" + jar_location; vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs(&vm_args); /* Append jar location to the default system class path */ vm_args.classpath = java_classpath.data(); /* Create the Java VM */ res = JNI_CreateJavaVM(&jvm, &env, &vm_args); #endif /* JNI_VERSION_1_2 */ // Find our LudiiGameWrapper Java class ludiiGameWrapperClass = (jclass)env->NewGlobalRef(env->FindClass("utils/LudiiGameWrapper")); CheckJniException(env); // Find our LudiiStateWrapper Java class ludiiStateWrapperClass = (jclass)env->NewGlobalRef(env->FindClass("utils/LudiiStateWrapper")); CheckJniException(env); // Find the method ID for the static method giving us the Ludii versio ludiiVersionMethodID = env->GetStaticMethodID( ludiiGameWrapperClass, "ludiiVersion", "()Ljava/lang/String;"); CheckJniException(env); std::cout << "Using Ludii version " << LudiiVersion() << std::endl; } void JNIUtils::CloseJVM() { JNIEnv* env = JNIUtils::GetEnv(); if (env != nullptr) { env->DeleteGlobalRef(ludiiStateWrapperClass); env->DeleteGlobalRef(ludiiGameWrapperClass); jvm->DestroyJavaVM(); jvm = nullptr; res = 0; } } // These will be assigned proper values by InitJVM() call jclass JNIUtils::ludiiGameWrapperClass = nullptr; jclass JNIUtils::ludiiStateWrapperClass = nullptr; jmethodID JNIUtils::ludiiVersionMethodID = nullptr; jclass JNIUtils::LudiiGameWrapperClass() { return ludiiGameWrapperClass; } jclass JNIUtils::LudiiStateWrapperClass() { return ludiiStateWrapperClass; } const std::string JNIUtils::LudiiVersion() { JNIEnv* env = JNIUtils::GetEnv(); jstring jstr = (jstring)( env->CallStaticObjectMethod(ludiiGameWrapperClass, ludiiVersionMethodID)); CheckJniException(env); const char* strReturn = env->GetStringUTFChars(jstr, (jboolean*)0); CheckJniException(env); const std::string str = strReturn; env->ReleaseStringUTFChars(jstr, strReturn); CheckJniException(env); env->DeleteLocalRef(jstr); CheckJniException(env); return str; } } // namespace Ludii ================================================ FILE: src/games/ludii/jni_utils.h ================================================ // strongly inspired from // https://gist.github.com/alexminnaar/90cf1ea3de45e79a1b14081d90d214b7 might // need something like export // LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/ maybe // also install jvm /* Copyright (c) 2020 Alex Minnaar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #include #include // NOLINT #include #include namespace Ludii { class JNIUtils { public: static JNIEnv* GetEnv(); static void InitJVM(std::string jar_location); static void CloseJVM(); static void CheckJniException(JNIEnv* jenv) { if (jenv->ExceptionCheck()) { jenv->ExceptionDescribe(); jenv->ExceptionClear(); printf("Java Exception at line %d of %s\n", __LINE__, __FILE__); throw std::runtime_error("Java exception thrown!"); } } static jclass LudiiGameWrapperClass(); static jclass LudiiStateWrapperClass(); /** * @return A string description of the version of Ludii that we're working * with. */ static const std::string LudiiVersion(); private: static JavaVM* jvm; static jint res; thread_local static JNIEnv* env; /** Our LudiiGameWrapper class in Java */ static jclass ludiiGameWrapperClass; /** Our LudiiStateWrapper class in Java */ static jclass ludiiStateWrapperClass; /** Method ID for the ludiiVersion() method in Java */ static jmethodID ludiiVersionMethodID; }; } // namespace Ludii ================================================ FILE: src/games/ludii/ludii_game_wrapper.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: Dennis Soemers // - Affiliation: Maastricht University, DKE, Digital Ludeme Project (Ludii // developer) // - Github: https://github.com/DennisSoemers/ // - Email: dennis.soemers@maastrichtuniversity.nl (or d.soemers@gmail.com) #include "ludii_game_wrapper.h" #include "jni_utils.h" namespace Ludii { // NOTE: String descriptions of signatures of Java methods can be found by // navigating to directory containing the .class files and using: // // javap -s LudiiGameWrapper::LudiiGameWrapper(const std::string lud_path) { JNIEnv* jenv = JNIUtils::GetEnv(); jclass ludiiGameWrapperClass = JNIUtils::LudiiGameWrapperClass(); // Find the LudiiGameWrapper Java construct method jmethodID ludiiGameWrapperConstruct = jenv->GetStaticMethodID(ludiiGameWrapperClass, "construct", "(Ljava/lang/String;)Lutils/LudiiGameWrapper;"); JNIUtils::CheckJniException(jenv); // Convert our lud path into a Java string jstring java_lud_path = jenv->NewStringUTF(lud_path.c_str()); JNIUtils::CheckJniException(jenv); // Call our Java construct method to instantiate new object jobject local_ref = jenv->CallStaticObjectMethod( ludiiGameWrapperClass, ludiiGameWrapperConstruct, java_lud_path); JNIUtils::CheckJniException(jenv); ludiiGameWrapperJavaObject = jenv->NewGlobalRef(local_ref); jenv->DeleteLocalRef(local_ref); // Find method IDs for the two tensor shape Java methods that we may be // calling frequently stateTensorsShapeMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "stateTensorsShape", "()[I"); JNIUtils::CheckJniException(jenv); moveTensorsShapeMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "moveTensorsShape", "()[I"); JNIUtils::CheckJniException(jenv); // Find the method ID for the stateTensorChannelNames() method in Java stateTensorChannelNamesMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "stateTensorChannelNames", "()[Ljava/lang/String;"); JNIUtils::CheckJniException(jenv); // Find the method ID for the numPlayers() method in Java numPlayersMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "numPlayers", "()I"); JNIUtils::CheckJniException(jenv); // Clean up memory jenv->DeleteLocalRef(java_lud_path); JNIUtils::CheckJniException(jenv); } LudiiGameWrapper::LudiiGameWrapper( const std::string lud_path, const std::vector game_options) { JNIEnv* jenv = JNIUtils::GetEnv(); jclass ludiiGameWrapperClass = JNIUtils::LudiiGameWrapperClass(); // Find the LudiiGameWrapper Java construct method (with extra argument for // options) jmethodID ludiiGameWrapperConstruct = jenv->GetStaticMethodID( ludiiGameWrapperClass, "construct", "(Ljava/lang/String;[Ljava/lang/String;)Lutils/LudiiGameWrapper;"); JNIUtils::CheckJniException(jenv); // Convert our lud path into a Java string jstring java_lud_path = jenv->NewStringUTF(lud_path.c_str()); JNIUtils::CheckJniException(jenv); // Convert vector of game options into array of Java strings const jobjectArray java_game_options = (jobjectArray)jenv->NewObjectArray( game_options.size(), jenv->FindClass("java/lang/String"), nullptr); JNIUtils::CheckJniException(jenv); for (size_t i = 0; i < game_options.size(); ++i) { jstring jstr = jenv->NewStringUTF(game_options[i].c_str()); jenv->SetObjectArrayElement(java_game_options, i, jstr); jenv->DeleteLocalRef(jstr); } // Call our Java construct method to instantiate new object jobject local_ref = jenv->CallStaticObjectMethod( ludiiGameWrapperClass, ludiiGameWrapperConstruct, java_lud_path, java_game_options); JNIUtils::CheckJniException(jenv); ludiiGameWrapperJavaObject = jenv->NewGlobalRef(local_ref); jenv->DeleteLocalRef(local_ref); // Find method IDs for the two tensor shape Java methods that we may be // calling frequently stateTensorsShapeMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "stateTensorsShape", "()[I"); JNIUtils::CheckJniException(jenv); moveTensorsShapeMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "moveTensorsShape", "()[I"); JNIUtils::CheckJniException(jenv); // Find the method ID for the stateTensorChannelNames() method in Java stateTensorChannelNamesMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "stateTensorChannelNames", "()[Ljava/lang/String;"); JNIUtils::CheckJniException(jenv); // Find the method ID for the numPlayers() method in Java numPlayersMethodID = jenv->GetMethodID(ludiiGameWrapperClass, "numPlayers", "()I"); JNIUtils::CheckJniException(jenv); // Clean up memory jenv->DeleteLocalRef(java_lud_path); jenv->DeleteLocalRef(java_game_options); } LudiiGameWrapper::LudiiGameWrapper(LudiiGameWrapper const& other) { JNIEnv* jenv = JNIUtils::GetEnv(); // We can just copy the pointer to the same Java Game object ludiiGameWrapperJavaObject = jenv->NewGlobalRef(other.ludiiGameWrapperJavaObject); JNIUtils::CheckJniException(jenv); // We can just copy all the pointers to methods stateTensorsShapeMethodID = other.stateTensorsShapeMethodID; moveTensorsShapeMethodID = other.moveTensorsShapeMethodID; stateTensorChannelNamesMethodID = other.stateTensorChannelNamesMethodID; numPlayersMethodID = other.numPlayersMethodID; } LudiiGameWrapper& LudiiGameWrapper::operator=(LudiiGameWrapper const& other) { JNIEnv* jenv = JNIUtils::GetEnv(); // We can just copy the pointer to the same Java Game object ludiiGameWrapperJavaObject = jenv->NewGlobalRef(other.ludiiGameWrapperJavaObject); JNIUtils::CheckJniException(jenv); // We can just copy all the pointers to methods stateTensorsShapeMethodID = other.stateTensorsShapeMethodID; moveTensorsShapeMethodID = other.moveTensorsShapeMethodID; stateTensorChannelNamesMethodID = other.stateTensorChannelNamesMethodID; numPlayersMethodID = other.numPlayersMethodID; return *this; } LudiiGameWrapper::~LudiiGameWrapper() { JNIEnv* jenv = JNIUtils::GetEnv(); if (jenv) { jenv->DeleteGlobalRef(ludiiGameWrapperJavaObject); } } const std::array& LudiiGameWrapper::StateTensorsShape() { if (not stateTensorsShape) { JNIEnv* jenv = JNIUtils::GetEnv(); // Get our array of Java ints const jintArray jint_array = static_cast(jenv->CallObjectMethod( ludiiGameWrapperJavaObject, stateTensorsShapeMethodID)); JNIUtils::CheckJniException(jenv); jint* jints = jenv->GetIntArrayElements(jint_array, nullptr); JNIUtils::CheckJniException(jenv); // Create our C++ array of 3 ints stateTensorsShape = std::make_unique>( std::array{jints[0], jints[1], jints[2]}); // Allow JVM to clean up memory now that we have our own ints jenv->ReleaseIntArrayElements(jint_array, jints, 0); jenv->DeleteLocalRef(jint_array); } return *stateTensorsShape; } const std::array& LudiiGameWrapper::MoveTensorsShape() { if (not moveTensorsShape) { JNIEnv* jenv = JNIUtils::GetEnv(); // Get our array of Java ints const jintArray jint_array = static_cast(jenv->CallObjectMethod( ludiiGameWrapperJavaObject, moveTensorsShapeMethodID)); JNIUtils::CheckJniException(jenv); jint* jints = jenv->GetIntArrayElements(jint_array, nullptr); JNIUtils::CheckJniException(jenv); // Create our C++ array of 3 ints moveTensorsShape = std::make_unique>( std::array{jints[0], jints[1], jints[2]}); // Allow JVM to clean up memory now that we have our own ints jenv->ReleaseIntArrayElements(jint_array, jints, 0); jenv->DeleteLocalRef(jint_array); } return *moveTensorsShape; } int LudiiGameWrapper::NumPlayers() { JNIEnv* jenv = JNIUtils::GetEnv(); const int numPlayers = (int)jenv->CallIntMethod(ludiiGameWrapperJavaObject, numPlayersMethodID); JNIUtils::CheckJniException(JNIUtils::GetEnv()); return numPlayers; } const std::vector LudiiGameWrapper::stateTensorChannelNames() { JNIEnv* jenv = JNIUtils::GetEnv(); std::vector channelNames; const jobjectArray java_arr = static_cast(jenv->CallObjectMethod( ludiiGameWrapperJavaObject, stateTensorChannelNamesMethodID)); JNIUtils::CheckJniException(jenv); const int len = jenv->GetArrayLength(java_arr); JNIUtils::CheckJniException(jenv); for (int i = 0; i < len; ++i) { jstring jstr = (jstring)(jenv->GetObjectArrayElement(java_arr, i)); JNIUtils::CheckJniException(jenv); // Convert Java string to C++ string const jsize jstr_len = jenv->GetStringUTFLength(jstr); JNIUtils::CheckJniException(jenv); const char* chars = jenv->GetStringUTFChars(jstr, (jboolean*)0); JNIUtils::CheckJniException(jenv); std::string str(chars, jstr_len); channelNames.push_back(str); // Allow JVM to clean up memory jenv->ReleaseStringUTFChars(jstr, chars); jenv->DeleteLocalRef(jstr); } jenv->DeleteLocalRef(java_arr); return channelNames; } } // namespace Ludii ================================================ FILE: src/games/ludii/ludii_game_wrapper.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: Dennis Soemers // - Affiliation: Maastricht University, DKE, Digital Ludeme Project (Ludii // developer) // - Github: https://github.com/DennisSoemers/ // - Email: dennis.soemers@maastrichtuniversity.nl (or d.soemers@gmail.com) #pragma once #include #include #include #include #include namespace Ludii { /** * C++ wrapper around Ludii's "LudiiGameWrapper" class. * * This class takes care of calling all the required Java methods from Ludii * games. */ class LudiiGameWrapper { public: /** * Constructor; calls the LudiiGameWrapper Java constructor * * @param lud_path String describing the path of the game to load. Should end * in .lud */ LudiiGameWrapper(const std::string lud_path); /** * Constructor; calls the LudiiGameWrapper Java constructor * * @param lud_path String describing the path of the game to load. Should end * in .lud * @param game_options Vector of additiona options to pass into Ludii, * describing variant of game to load. */ LudiiGameWrapper(const std::string lud_path, const std::vector game_options); /** * Copy constructor. Re-uses the same Java LudiiGameWrapper object. */ LudiiGameWrapper(LudiiGameWrapper const&); /** * Copy-assignment operator. Re-uses the same Java LudiiGameWrapper object. */ LudiiGameWrapper& operator=(LudiiGameWrapper const& other); /** * Destructor */ ~LudiiGameWrapper(); /** * @return Array of 3 ints describing the shape of state tensors; [channels, * x, y] */ const std::array& StateTensorsShape(); /** * @return Array of 3 ints describing the shape of move tensors; [channels, x, * y] */ const std::array& MoveTensorsShape(); /** * @return The number of players in this game. */ int NumPlayers(); /** * @return Vector with, for every channel in state tensors, a name describing * what data we have in that channel. */ const std::vector stateTensorChannelNames(); /** Our object of Java's LudiiGameWrapper type */ jobject ludiiGameWrapperJavaObject; private: /** Method ID for the stateTensorsShape() method in Java */ jmethodID stateTensorsShapeMethodID; /** Method ID for the moveTensorsShape() method in Java */ jmethodID moveTensorsShapeMethodID; /** Method ID for the stateTensorChannelNames() method in Java */ jmethodID stateTensorChannelNamesMethodID; /** Method ID for the numPlayers() method in Java */ jmethodID numPlayersMethodID; /** * Shape for state tensors. * This remains constant throughout episodes, so can just compute it once and * store */ std::unique_ptr> stateTensorsShape; /** * Shape for state tensors. * This remains constant throughout episodes, so can just compute it once and * store */ std::unique_ptr> moveTensorsShape; }; } // namespace Ludii ================================================ FILE: src/games/ludii/ludii_state_wrapper.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: Dennis Soemers // - Affiliation: Maastricht University, DKE, Digital Ludeme Project (Ludii // developer) // - Github: https://github.com/DennisSoemers/ // - Email: dennis.soemers@maastrichtuniversity.nl (or d.soemers@gmail.com) #include "ludii_state_wrapper.h" #include "jni_utils.h" namespace Ludii { // Action::Action(int i, int j, int k) { // _loc[0] = i; // _loc[1] = j; // _loc[2] = k; // _hash = uint32_t(0); // TODO implement hash for stochastic games //} void LudiiStateWrapper::Initialize() { Reset(); _hash = 0; // TODO implement hash for stochastic games _status = GameStatus::player0Turn; // Initializes Features. _featSize.resize(3); const std::array& sts = ludiiGameWrapper->StateTensorsShape(); std::copy(sts.begin(), sts.end(), _featSize.begin()); _features = std::vector(_featSize[0] * _featSize[1] * _featSize[2]); findFeatures(); fillFullFeatures(); // Initializes Actions. _actionSize.resize(3); const std::array& mts = ludiiGameWrapper->MoveTensorsShape(); std::copy(mts.begin(), mts.end(), _actionSize.begin()); findActions(); } void LudiiStateWrapper::findFeatures() { JNIEnv* jenv = JNIUtils::GetEnv(); const jfloatArray flatTensorArray = static_cast(jenv->CallObjectMethod( ludiiStateWrapperJavaObject, toTensorFlatMethodID)); JNIUtils::CheckJniException(jenv); const jsize numEntries = jenv->GetArrayLength(flatTensorArray); jfloat* jfloats = (jfloat*)jenv->GetPrimitiveArrayCritical(flatTensorArray, nullptr); std::copy(jfloats, jfloats + numEntries, _features.begin()); // Allow JVM to clean up memory now that we have our own floats jenv->ReleasePrimitiveArrayCritical(flatTensorArray, jfloats, JNI_ABORT); jenv->DeleteLocalRef(flatTensorArray); } void LudiiStateWrapper::findActions() { const std::vector> moves = LegalMovesTensors(); size_t nbMoves = moves.size(); _legalActions.clear(); _legalActions.reserve(nbMoves); for (size_t i = 0; i < nbMoves; ++i) { const std::array& move = moves[i]; _legalActions.emplace_back(i, move[0], move[1], move[2]); } } std::unique_ptr LudiiStateWrapper::clone_() const { return std::make_unique(*this); } void LudiiStateWrapper::ApplyAction(const _Action& action) { assert(not IsTerminal()); // play move ApplyNthMove(action.GetIndex()); // update game status if (IsTerminal()) { if (isOnePlayerGame()) { const double score = Returns(0); if (score >= 0.99) // Probably just 1.0 _status = GameStatus::player0Win; else if (score <= -0.99) // Probably just -1.0 _status = GameStatus::player1Win; else _status = GameStatus::tie; } else { const double score_0 = Returns(0); const double score_1 = Returns(1); if (score_0 > score_1) _status = score_0 > 0.0 ? GameStatus::player0Win : GameStatus::tie; else _status = score_1 > 0.0 ? GameStatus::player1Win : GameStatus::tie; } } else { const int player = CurrentPlayer(); _status = player == 0 ? GameStatus::player0Turn : GameStatus::player1Turn; } // update features findFeatures(); fillFullFeatures(); // update actions findActions(); // update hash // TODO } void LudiiStateWrapper::DoGoodAction() { return DoRandomAction(); } // NOTE: String descriptions of signatures of Java methods can be found by // navigating to directory containing the .class files and using: // // javap -s LudiiStateWrapper::LudiiStateWrapper(int seed, LudiiGameWrapper&& inLudiiGameWrapper) : core::State(seed) { JNIEnv* jenv = JNIUtils::GetEnv(); ludiiGameWrapper = std::make_shared(std::move(inLudiiGameWrapper)); jclass ludiiStateWrapperClass = JNIUtils::LudiiStateWrapperClass(); // Find the LudiiStateWrapper Java constructor jmethodID ludiiStateWrapperConstructor = jenv->GetMethodID( ludiiStateWrapperClass, "", "(Lutils/LudiiGameWrapper;)V"); JNIUtils::CheckJniException(jenv); // Call our Java constructor to instantiate new object jobject local_ref = jenv->NewObject(ludiiStateWrapperClass, ludiiStateWrapperConstructor, ludiiGameWrapper->ludiiGameWrapperJavaObject); JNIUtils::CheckJniException(jenv); ludiiStateWrapperJavaObject = jenv->NewGlobalRef(local_ref); jenv->DeleteLocalRef(local_ref); // Find method IDs for all the Java methods we may want to call legalMovesTensorsMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "legalMovesTensors", "()[[I"); JNIUtils::CheckJniException(jenv); numLegalMovesMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "numLegalMoves", "()I"); JNIUtils::CheckJniException(jenv); applyNthMoveMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "applyNthMove", "(I)V"); JNIUtils::CheckJniException(jenv); returnsMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "returns", "(I)D"); JNIUtils::CheckJniException(jenv); isTerminalMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "isTerminal", "()Z"); JNIUtils::CheckJniException(jenv); toTensorFlatMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "toTensorFlat", "()[F"); JNIUtils::CheckJniException(jenv); currentPlayerMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "currentPlayer", "()I"); JNIUtils::CheckJniException(jenv); resetMethodID = jenv->GetMethodID(ludiiStateWrapperClass, "reset", "()V"); JNIUtils::CheckJniException(jenv); copyFromMethodID = jenv->GetMethodID( ludiiStateWrapperClass, "copyFrom", "(Lutils/LudiiStateWrapper;)V"); JNIUtils::CheckJniException(jenv); getRandomRolloutsRewardMethodID = jenv->GetMethodID( ludiiStateWrapperClass, "getRandomRolloutsReward", "(III)D"); JNIUtils::CheckJniException(jenv); } LudiiStateWrapper::LudiiStateWrapper(const LudiiStateWrapper& other) : core::State(other) , ludiiGameWrapper(other.ludiiGameWrapper) { JNIEnv* jenv = JNIUtils::GetEnv(); jclass ludiiStateWrapperClass = JNIUtils::LudiiStateWrapperClass(); // Find the LudiiStateWrapper Java copy constructor jmethodID ludiiStateWrapperCopyConstructor = jenv->GetMethodID( ludiiStateWrapperClass, "", "(Lutils/LudiiStateWrapper;)V"); JNIUtils::CheckJniException(jenv); // Call our Java constructor to instantiate new object jobject local_ref = jenv->NewObject(ludiiStateWrapperClass, ludiiStateWrapperCopyConstructor, other.ludiiStateWrapperJavaObject); JNIUtils::CheckJniException(jenv); ludiiStateWrapperJavaObject = jenv->NewGlobalRef(local_ref); jenv->DeleteLocalRef(local_ref); // We can just copy all the pointers to methods legalMovesTensorsMethodID = other.legalMovesTensorsMethodID; numLegalMovesMethodID = other.numLegalMovesMethodID; applyNthMoveMethodID = other.applyNthMoveMethodID; returnsMethodID = other.returnsMethodID; isTerminalMethodID = other.isTerminalMethodID; toTensorFlatMethodID = other.toTensorFlatMethodID; currentPlayerMethodID = other.currentPlayerMethodID; resetMethodID = other.resetMethodID; copyFromMethodID = other.copyFromMethodID; getRandomRolloutsRewardMethodID = other.getRandomRolloutsRewardMethodID; } LudiiStateWrapper& LudiiStateWrapper::operator=( LudiiStateWrapper const& other) { if (&other == this) return *this; core::State::operator=(other); JNIEnv* jenv = JNIUtils::GetEnv(); jenv->CallVoidMethod(ludiiStateWrapperJavaObject, copyFromMethodID, other.ludiiStateWrapperJavaObject); JNIUtils::CheckJniException(jenv); // We can just copy all the pointers to methods legalMovesTensorsMethodID = other.legalMovesTensorsMethodID; numLegalMovesMethodID = other.numLegalMovesMethodID; applyNthMoveMethodID = other.applyNthMoveMethodID; returnsMethodID = other.returnsMethodID; isTerminalMethodID = other.isTerminalMethodID; toTensorFlatMethodID = other.toTensorFlatMethodID; currentPlayerMethodID = other.currentPlayerMethodID; resetMethodID = other.resetMethodID; copyFromMethodID = other.copyFromMethodID; getRandomRolloutsRewardMethodID = other.getRandomRolloutsRewardMethodID; return *this; } LudiiStateWrapper::~LudiiStateWrapper() { JNIEnv* jenv = JNIUtils::GetEnv(); if (jenv) { jenv->DeleteGlobalRef(ludiiStateWrapperJavaObject); } } std::vector> LudiiStateWrapper::LegalMovesTensors() const { JNIEnv* jenv = JNIUtils::GetEnv(); const jobjectArray javaArrOuter = static_cast(jenv->CallObjectMethod( ludiiStateWrapperJavaObject, legalMovesTensorsMethodID)); JNIUtils::CheckJniException(jenv); const jsize numLegalMoves = jenv->GetArrayLength(javaArrOuter); std::vector> matrix(numLegalMoves); for (jsize i = 0; i < numLegalMoves; ++i) { const jintArray inner = static_cast(jenv->GetObjectArrayElement(javaArrOuter, i)); jint* jints = (jint*)jenv->GetPrimitiveArrayCritical(inner, nullptr); matrix[i] = {jints[0], jints[1], jints[2]}; // Allow JVM to clean up memory now that we have our own ints jenv->ReleasePrimitiveArrayCritical(inner, jints, JNI_ABORT); jenv->DeleteLocalRef(inner); } jenv->DeleteLocalRef(javaArrOuter); return matrix; } int LudiiStateWrapper::NumLegalMoves() const { JNIEnv* jenv = JNIUtils::GetEnv(); const int num_legal_moves = (int)jenv->CallIntMethod( ludiiStateWrapperJavaObject, numLegalMovesMethodID); JNIUtils::CheckJniException(jenv); return num_legal_moves; } void LudiiStateWrapper::ApplyNthMove(const int n) const { JNIEnv* jenv = JNIUtils::GetEnv(); jenv->CallVoidMethod(ludiiStateWrapperJavaObject, applyNthMoveMethodID, n); JNIUtils::CheckJniException(jenv); } double LudiiStateWrapper::Returns(const int player) const { JNIEnv* jenv = JNIUtils::GetEnv(); const double returns = (double)jenv->CallDoubleMethod( ludiiStateWrapperJavaObject, returnsMethodID, player); JNIUtils::CheckJniException(jenv); return returns; } bool LudiiStateWrapper::IsTerminal() const { JNIEnv* jenv = JNIUtils::GetEnv(); const bool is_terminal = (bool)jenv->CallBooleanMethod( ludiiStateWrapperJavaObject, isTerminalMethodID); JNIUtils::CheckJniException(jenv); return is_terminal; } int LudiiStateWrapper::CurrentPlayer() const { JNIEnv* jenv = JNIUtils::GetEnv(); const int current_player = (int)jenv->CallIntMethod( ludiiStateWrapperJavaObject, currentPlayerMethodID); JNIUtils::CheckJniException(jenv); return current_player; } void LudiiStateWrapper::Reset() const { JNIEnv* jenv = JNIUtils::GetEnv(); jenv->CallVoidMethod(ludiiStateWrapperJavaObject, resetMethodID); JNIUtils::CheckJniException(jenv); } bool LudiiStateWrapper::isOnePlayerGame() const { return (ludiiGameWrapper->NumPlayers() == 1); } float LudiiStateWrapper::getRandomRolloutReward(int player) const { const int numSimulation = 10; const int rolloutRandomMovesCap = 200; // Use -1 for no cap on num moves in rollout JNIEnv* jenv = JNIUtils::GetEnv(); const double avgReward = (double)jenv->CallDoubleMethod( ludiiStateWrapperJavaObject, getRandomRolloutsRewardMethodID, player, numSimulation, rolloutRandomMovesCap); JNIUtils::CheckJniException(jenv); return (float)avgReward; } } // namespace Ludii ================================================ FILE: src/games/ludii/ludii_state_wrapper.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: Dennis Soemers // - Affiliation: Maastricht University, DKE, Digital Ludeme Project (Ludii // developer) // - Github: https://github.com/DennisSoemers/ // - Email: dennis.soemers@maastrichtuniversity.nl (or d.soemers@gmail.com) #pragma once #include #include #include #include #include #include #include "../../core/state.h" #include "ludii_game_wrapper.h" namespace Ludii { // class Action : public ::_Action { // public: // Action(int i, int j, int k); //}; /** * C++ wrapper around Ludii's "LudiiStateWrapper" class. * * This class takes care of calling all the required Java methods from Ludii * states. */ class LudiiStateWrapper : public core::State { public: void Initialize(); std::unique_ptr clone_() const; void ApplyAction(const _Action& action); void DoGoodAction(); public: /** * Constructor; calls the LudiiStateWrapper Java constructor */ LudiiStateWrapper(int seed, LudiiGameWrapper&& inLudiiGameWrapper); /** * Copy constructor; calls the Java copy constructor for LudiiStateWrapper * * @param other The LudiiStateWrapper object of which we wish to create a deep * copy */ LudiiStateWrapper(const LudiiStateWrapper& other); /** * Destructor */ ~LudiiStateWrapper(); /** * @return 2D int array; for every legal move, we have an array of * length 3 containing [channel, x, y] */ std::vector> LegalMovesTensors() const; /** * @return Number of legal moves in current state */ int NumLegalMoves() const; /** * Applies the n'th legal move in current game state */ void ApplyNthMove(const int n) const; /** * NOTE: The Java method that we call for this actually first computes * the array of scores for all players, and then only returns the score * for the queried player. If we often want to do this inside a loop * through all players, it'd be more efficient to call a Java method * that instantly returns the full array once. * * @return Score in [-1.0, 1.0] for given player index (starting at 0). * Will always return 0.0 for non-terminal game states. */ double Returns(const int player) const; /** * @return True if and only if the current game state is terminal; false * otherwise. */ bool IsTerminal() const; /** * @return The current player to move (0 for first, 1 for second, etc.) */ int CurrentPlayer() const; /** * Calls the Java reset() method on the Java game state object */ void Reset() const; virtual bool isOnePlayerGame() const override; virtual float getRandomRolloutReward(int player) const override; LudiiStateWrapper& operator=(LudiiStateWrapper const& other); private: void findFeatures(); void findActions(); // We don't want to be accidentally coyping objects of this class // (without having implemented our own, correct copy constructor or assignment // operator) // LudiiStateWrapper& operator=(LudiiStateWrapper const&) = delete; /** Pointer to our Game wrapper */ std::shared_ptr ludiiGameWrapper; /** Our object of Java's LudiiStateWrapper type */ jobject ludiiStateWrapperJavaObject; /** Method ID for the legalMovesTensors() method in Java */ jmethodID legalMovesTensorsMethodID; /** Method ID for the numLegalMoves() method in Java */ jmethodID numLegalMovesMethodID; /** Method ID for the applyNthMove() method in Java */ jmethodID applyNthMoveMethodID; /** Method ID for the returns() method in Java */ jmethodID returnsMethodID; /** Method ID for the isTerminal() method in Java */ jmethodID isTerminalMethodID; /** Method ID for the toTensorFlat() method in Java */ jmethodID toTensorFlatMethodID; /** Method ID for the currentPlayer() method in Java */ jmethodID currentPlayerMethodID; /** Method ID for the reset() method in Java */ jmethodID resetMethodID; /** Method ID for the copyFrom() method in Java */ jmethodID copyFromMethodID; /** Method ID for the getRandomRolloutsReward() method in Java */ jmethodID getRandomRolloutsRewardMethodID; }; } // namespace Ludii ================================================ FILE: src/games/mastermind_state.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "mastermind_state.h" #include ================================================ FILE: src/games/mastermind_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include "../core/state.h" // #include /***************************** Mastermind with black pegs only. Each time steps decides one color. HORIZON is the number of rows that player 1 can fill for trying to find the target. ARITY is the number of colors. SIZE is the number of slots per row (and, equivalently, the number of colors to guess). The number of time steps is HORIZON * SIZE because SIZE is the number of colors to decide at each row. */ namespace Mastermind { template class State : public core::State { private: // just for enabling verbosity bool mmverbose; // representation int _board[HORIZON][SIZE]; int _results[HORIZON]; int _currentAction[SIZE]; int real[SIZE]; int _timeStep; // helper functions int mmhamming(int real[], int action[]); void rejection(int real[], int board[][SIZE], int results[], int time); bool unicity(int real[], int board[][SIZE], int results[], int time); // representation of the state virtual std::string stateDescription() const override { std::string res; res += "time"; res += std::to_string(_timeStep); res += " corresponding to line "; res += std::to_string(_timeStep / SIZE); res += " and slot "; res += std::to_string(_timeStep % SIZE); res += "\n"; for (int i = 0; i < 1 + (_timeStep / SIZE); i++) { for (int j = 0; j < SIZE; j++) { if (i * SIZE + j < _timeStep) { res += " "; res += std::to_string(_board[i][j]); } } if (i * SIZE + SIZE - 1 < _timeStep) { res += " ==> score "; res += std::to_string(_results[i]); res += " win:"; res += std::to_string(_status == GameStatus::player0Win); res += "("; res += std::to_string(GetLegalActions().size()); res += ")"; res += "\n"; } } return res; } public: virtual bool isOnePlayerGame() const override { return true; } State(int seed); void findActions(); void Initialize() override; void ApplyAction(const _Action& action) override; void DoGoodAction() override; std::unique_ptr clone_() const override; }; // Hamming distance. template int State::mmhamming(int real[], int action[]) { int result = SIZE; for (int i = 0; i < SIZE; i++) { if (real[i] != action[i]) { result--; } } return result; } // Rejection sampling -- we need better than that TODO(oteytaud). template void State::rejection(int real[], int board[][SIZE], int results[], int time) { assert(time < HORIZON); std::uniform_int_distribution distribution(0, ARITY - 1); if (mmverbose) { std::cerr << "rejection" << std::endl; } auto dice = std::bind(distribution, _rng); bool found = false; while (!found) { if (mmverbose) { std::cerr << " let us try..." << std::endl; } for (int i = 0; i < SIZE; i++) { real[i] = dice(); } found = true; for (int j = 0; j < time; j++) { int localdistance = mmhamming(real, board[j]); if (localdistance != results[j]) { if (mmverbose) { std::cerr << "fail at time " << j << std::endl; } found = false; break; } } // if found, then it's ok we can proceed } if (mmverbose) { for (int i = 0; i < SIZE; i++) std::cout << real[i]; std::cout << "\n"; } } // end of rejection // Checking if the solution is unique template bool State::unicity(int real[], int board[][SIZE], int results[], int time) { int num_found = 0; assert(time < HORIZON); std::uniform_int_distribution distribution(0, ARITY - 1); if (mmverbose) { std::cout << "unicity == == == == == == == == == == == = " << std::endl; } bool found = false; int index = 0; int maxIndex = 1; for (int i = 0; i < SIZE; i++) maxIndex *= ARITY; while (index < maxIndex) { if (mmverbose) { std::cout << " let us try ... "; } int tempoIndex = index; for (int i = 0; i < SIZE; i++) { real[i] = tempoIndex % ARITY; if (mmverbose) { std::cout << real[i]; } tempoIndex /= ARITY; } found = true; if (mmverbose) { std::cout << std::endl; } for (int j = 0; j < time; j++) { int localdistance = mmhamming(real, board[j]); if (mmverbose) { std::cout << "distance " << localdistance << "/" << results[j] << std::endl; } if (localdistance != results[j]) { if (mmverbose) { std::cout << "fail at time " << j << std::endl; } found = false; } } if (found) { num_found++; if (mmverbose) { std::cout << "success"; } if (num_found > 1) { if (mmverbose) { std::cout << "several sols " << std::endl; } return false; } } index++; } if (num_found <= 0) { std::cout << "State with no solution : " << stateDescription() << std::endl; } assert(num_found == 1); return true; } // end of unicity } // namespace Mastermind /////////////////////////////////////////////////////////////////////////////// // Mastermind::State /////////////////////////////////////////////////////////////////////////////// template Mastermind::State::State(int seed) : core::State(seed) { mmverbose = false; if (mmverbose) { std::cerr << " cretion" << std::endl; } long s = std::chrono::system_clock::now().time_since_epoch().count(); _rng.seed(s); Initialize(); if (mmverbose) { std::cerr << " creation done" << std::endl; } } template void Mastermind::State::findActions() { clearActions(); int time = _timeStep / SIZE; int slot = _timeStep % SIZE; if (_status == GameStatus::player0Turn) { assert(time < HORIZON); for (int i = 0; i < ARITY; i++) { addAction(i, time, slot); } if (mmverbose) { std::cerr << " fa done" << std::endl; } } } template void Mastermind::State::Initialize() { if (mmverbose) { std::cerr << " initialize" << std::endl; } _timeStep = 0; memset(_board, 0, sizeof(_board)); memset(_currentAction, 0, sizeof(_currentAction)); for (int i = 0; i < HORIZON; i++) _results[i] = -1; _hash = 0; _status = GameStatus::player0Turn; // features _featSize = {ARITY + 1, HORIZON, SIZE}; _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); for (int i = 0; i < (int)_features.size(); i++) _features[i] = 0.; _actionSize = {(ARITY + 1), (HORIZON), (SIZE)}; if (mmverbose) { std::cerr << " init --> findactions " << std::endl; } findActions(); if (mmverbose) { std::cerr << " init --> fff " << std::endl; } fillFullFeatures(); _stochastic = false; if (mmverbose) { std::cerr << " init ok " << std::endl; } } template void Mastermind::State::ApplyAction( const _Action& action) { assert(_legalActions.size() > 0); assert(forcedDice < 0); // mastermind does not have a human mode for the moment. if (mmverbose) { std::cout << "before:\n" << stateDescription(); } if (_legalActions.size() == 0) { // std::cout << boost::stacktrace::stacktrace(); std::cout << "no legal action " << stateDescription() << std::endl; std::cout << "but playing " << actionDescription(action) << std::endl; std::cout << "wonstatus=" << (_status == GameStatus::player0Win) << std::endl; assert(_legalActions.size() > 0); } assert(_status == GameStatus::player0Turn); int time = _timeStep / SIZE; int slot = _timeStep % SIZE; if (mmverbose) { std::cerr << " timestep = " << _timeStep << std::endl; std::cerr << " slot=" << slot << "/" << SIZE << std::endl; std::cerr << " time=" << time << "/" << HORIZON << std::endl; } assert(time == action.GetY()); assert(slot == action.GetZ()); _currentAction[slot] = action.GetX(); assert(time < HORIZON); assert(slot < SIZE); _board[time][slot] = action.GetX(); assert(action.GetX() * HORIZON * SIZE + time * SIZE + slot < (int)_features.size()); _features[action.GetX() * HORIZON * SIZE + time * SIZE + slot] = 1; if (slot == SIZE - 1) { rejection(real, _board, _results, time); if (mmverbose) { std::cerr << " now computing distance" << std::endl; } unsigned int distance = mmhamming(real, _currentAction); if (mmverbose) { std::cerr << "ARITY=" << ARITY << std::endl << "HORIZON=" << HORIZON << std::endl << "SIZE=" << SIZE << std::endl << " AHS=" << ARITY * HORIZON * SIZE << std::endl << "time=" << time << std::endl << " timeSIZE=" << time * SIZE << std::endl << "AHS+timeSIZE+SIZE=" << ARITY * HORIZON * SIZE + time * SIZE + SIZE << std::endl << "versus " << _features.size() << std::endl; } { _results[time] = distance; assert(ARITY * HORIZON * SIZE + time * SIZE + SIZE - 1 < (int)_features.size()); for (int i = 0; i < SIZE; i++) { _features[ARITY * HORIZON * SIZE + time * SIZE + i] = float(distance) / float(ARITY); } } _hash = distance; if (distance == SIZE) { if (mmverbose) { std::cout << " won by found at time " << time << std::endl; } _status = GameStatus::player0Win; } else if ((time < HORIZON - 1) && (unicity(real, _board, _results, time))) { if (mmverbose) { std::cout << " won by unicity of solution and time=" << time << "<" << HORIZON - 1 << std::endl; std::cerr << " won!" << std::endl; } _status = GameStatus::player0Win; } else if (time == HORIZON - 1) { if (mmverbose) { std::cerr << " lost!" << std::endl; } _status = GameStatus::player1Win; } } // TODO(oteytaud): cartesian product of actions would be better! _timeStep++; // if slot is SIZE-2 then the next step corresponds // to the last slot and therefore the next state is stochastic. if (slot == SIZE - 2) { if (mmverbose) { std::cerr << " go on" << std::endl; } _stochastic = true; } else { _stochastic = false; } // TODO(oteytaud): cartesian product of actions would be better! if (mmverbose) { std::cerr << " findactions " << std::endl; } findActions(); if (mmverbose) { std::cerr << " fff " << std::endl; } fillFullFeatures(); if (mmverbose) { std::cerr << "AA done" << std::endl; } } template void Mastermind::State::DoGoodAction() { if (mmverbose) { std::cerr << " do random action" << std::endl; } DoRandomAction(); } template std::unique_ptr Mastermind::State::clone_() const { return std::make_unique>(*this); } ================================================ FILE: src/games/minesweeper.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include "minesweeper_common.h" namespace Minesweeper { static std::ostream& timestamp(std::ostream& os) { std::time_t result = std::time(nullptr); char buf[100]; if (std::strftime(buf, sizeof(buf), "%c", std::localtime(&result))) { os << buf; } return os; } // timestamp std::ostream& debug(std::ostream& os) { timestamp(os) << " [DEBUG] [Minesweeper] "; return os; } // debug std::string sparseMaskToString(const SparseMask& mask) { std::ostringstream oss; oss << '['; for (const auto& v : mask) { oss << '(' << v.row() << ',' << v.col() << "), "; } oss << ']'; return oss.str(); } // sparseMaskToString } // namespace Minesweeper ================================================ FILE: src/games/minesweeper_common.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include #define MINESWEEPER_DEBUG_COMMA , // Debug output disabled: #define MINESWEEPER_DEBUG(ARG) // Debug output enabled: //#define MINESWEEPER_DEBUG(ARG) ARG #define UNUSED(ARG) namespace Minesweeper { template struct NeighborOffsets {}; template struct NeighborOffsets { static constexpr std::array dindices = { -static_cast(STRIDE) - 1, -static_cast(STRIDE), -static_cast(STRIDE) + 1, -1, 1, static_cast(STRIDE) - 1, static_cast(STRIDE), static_cast(STRIDE) + 1}; static constexpr std::array drow = {-1, -1, -1, 0, 0, 1, 1, 1}; static constexpr std::array dcol = {-1, 0, 1, -1, 1, -1, 0, 1}; }; // class NeighborOffsets class BoardPosition { public: constexpr BoardPosition(int row, int col) noexcept : _r(row) , _c(col) { } constexpr int row() const noexcept { return _r; } constexpr int col() const noexcept { return _c; } private: int _r; int _c; }; // class BoardPosition template int rowColToIdx(int row, int col) { return row * static_cast(STRIDE) + col; } template void idxToRowCol(int idx, int& row, int& col) { row = idx / STRIDE; col = idx % STRIDE; } template constexpr bool isInBoard(int row, int col) { return (row >= 0) && (row < static_cast(HEIGHT)) && (col >= 0) && (col < static_cast(WIDTH)); } template typename T::const_reference arrGet(const T& arr, int row, int col) { return arr[rowColToIdx(row, col)]; } template typename T::reference arrGet(T& arr, int row, int col) { return arr[rowColToIdx(row, col)]; } using SparseMask = std::vector; static constexpr int UNKNOWN = -1; static constexpr int BOOM = -2; static constexpr size_t NUM_NEIGHBORS = 8; template struct GameDefs { using Board = std::array; using BoardProbas = std::array; using BoardMask = std::array; using Mines = std::array; using Neighbors = std::array; static std::string boardMaskToString(const BoardMask& mask) { std::ostringstream oss; int k = 0; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { oss << (mask[k++] ? 1 : 0); } oss << std::endl; } return oss.str(); } // boardMaskToString static std::string boardToString(const Board& board) { using BoardChars = std::array; BoardChars boardChars; int v; char c; int k = 0; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { v = board[k]; switch (v) { case UNKNOWN: c = '?'; break; case BOOM: c = 'X'; break; default: assert(v >= 0); c = '0' + v; } boardChars[k] = c; ++k; } } std::ostringstream oss; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { oss << arrGet(boardChars, row, col); } oss << std::endl; } return oss.str(); } // boardToString static std::string minesToString(const Mines& mines) { std::ostringstream oss; for (size_t i = 0; i < MINES; ++i) { oss << mines[i] << " "; } return oss.str(); } // minesToString template static std::vector getNeighbors(const Board& board, int row, int col, Predicate predicate) { std::vector result; result.reserve(NUM_NEIGHBORS); int row_i, col_i; for (size_t i = 0; i < NUM_NEIGHBORS; ++i) { row_i = row + NeighborOffsets::drow[i]; col_i = col + NeighborOffsets::dcol[i]; if (isInBoard(row_i, col_i) && predicate(arrGet(board, row_i, col_i), row_i, col_i)) { result.emplace_back(row_i, col_i); } } return result; } // getNeighbors template static void markNeighbors( const Board& board, int row, int col, Mask& mask, Predicate predicate) { int row_i, col_i; for (size_t i = 0; i < NUM_NEIGHBORS; ++i) { row_i = row + NeighborOffsets::drow[i]; col_i = col + NeighborOffsets::dcol[i]; if (isInBoard(row_i, col_i) && predicate(arrGet(board, row_i, col_i), row_i, col_i)) { mask.set(row_i, col_i); } } } // markNeighbors template static size_t countNeighbors(const Board& board, int row, int col, Predicate predicate) { size_t count = 0; int row_i, col_i; for (size_t i = 0; i < NUM_NEIGHBORS; ++i) { row_i = row + NeighborOffsets::drow[i]; col_i = col + NeighborOffsets::dcol[i]; if (isInBoard(row_i, col_i) && predicate(arrGet(board, row_i, col_i), row_i, col_i)) { ++count; } } return count; } // countNeighbors }; template class Mask { private: using BoardMask = typename GameDefs::BoardMask; public: explicit Mask(size_t sparseSize = MINES) { _maskSparse.reserve(sparseSize); } void zero() { memset(_maskDense.data(), 0, WIDTH * HEIGHT * sizeof(typename BoardMask::value_type)); _maskSparse.clear(); } void set(int row, int col) { if (!_maskDense[rowColToIdx(row, col)]) { _maskDense[rowColToIdx(row, col)] = 1; _maskSparse.emplace_back(row, col); } } typename BoardMask::value_type get(int row, int col) const { return _maskDense[rowColToIdx(row, col)]; } const BoardMask& dense() const { return _maskDense; } const std::vector& sparse() const { return _maskSparse; } private: BoardMask _maskDense; SparseMask _maskSparse; }; // class Mask std::ostream& debug(std::ostream& os); std::string sparseMaskToString(const SparseMask& mask); } // namespace Minesweeper ================================================ FILE: src/games/minesweeper_csp_vkms/CMakeLists.txt ================================================ CMAKE_MINIMUM_REQUIRED(VERSION 3.3) project(csp_vkms) set(CMAKE_CXX_STANDARD 17) if (${Torch_FOUND}) include_directories(${TORCH_INCLUDE_DIRS}) else() find_package(Torch REQUIRED) include_directories(${TORCH_INCLUDE_DIRS}) endif() find_package( PythonInterp 3.7 REQUIRED ) find_package( PythonLibs 3.7 REQUIRED ) include_directories( ${PYTHON_INCLUDE_DIRS} ) set(SRC_DIR ../..) add_executable(benchmark_csp_vkms ${SRC_DIR}/core/state.cc ${SRC_DIR}/games/minesweeper.cc csp_vkms.cc ) target_include_directories(benchmark_csp_vkms PUBLIC ${SRC_DIR}) target_link_libraries(benchmark_csp_vkms ${CMAKE_THREAD_LIBS_INIT} ${TORCH_LIBRARIES} fmt ) ================================================ FILE: src/games/minesweeper_csp_vkms/ConnectedComponent.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "../minesweeper_common.h" namespace csp { namespace vkms { struct ConnectedComponent { Minesweeper::SparseMask _constraints; Minesweeper::SparseMask _variables; }; // struct ConnectedComponent } // namespace vkms } // namespace csp ================================================ FILE: src/games/minesweeper_csp_vkms/CspStrategy.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "SolutionSetSampler.h" #include #include namespace csp { namespace vkms { template class CspStrategy { using _GameDefs = Minesweeper::GameDefs; using Board = typename _GameDefs::Board; using BoardMask = typename _GameDefs::BoardMask; using Mines = typename _GameDefs::Mines; using _Mask = Minesweeper::Mask; using _SolutionSet = SolutionSet; using _SolutionSetSampler = SolutionSetSampler; public: using MineProbas = std::array; CspStrategy() : _minesMask(MINES) , _notMinesMask(WIDTH * HEIGHT) , _activeConstraints(WIDTH * HEIGHT) , _unconstrainedVariables(WIDTH * HEIGHT) , _processed(WIDTH * HEIGHT) { } // CspStrategy template void sampleMines(Mines& mines, const Board& board, RngEngine& rng) { initializeMinesMasks(board); initializeActiveConstraints(board); initializeUnconstrainedVariables(board); MINESWEEPER_DEBUG(dumpMasks(std::cout)); std::vector connectedActiveConstraints = connectedConstraints(board); MINESWEEPER_DEBUG(dumpConstraints(std::cout, connectedActiveConstraints)); std::vector<_SolutionSet> solutionSets; solutionSets.reserve(connectedActiveConstraints.size()); for (const ConnectedComponent& component : connectedActiveConstraints) { solutionSets.emplace_back(component, board, _minesMask); } // sampleFromSolutionSets(solutionSets, mines, rng); _SolutionSetSampler sampler( solutionSets, _unconstrainedVariables, _minesMask); // computeMineProbabilities(solutionSets, sampler); sampler.sampleMines(mines, rng); std::sort(mines.begin(), mines.end()); } // sampleMines std::vector locateForSureMines(const Board& board) { initializeMinesMasks(board); const auto& minePositions = _minesMask.sparse(); std::vector mineIndices; mineIndices.reserve(minePositions.size()); for (const auto& minePosition : minePositions) { mineIndices.push_back( rowColToIdx(minePosition.row(), minePosition.col())); } std::sort(mineIndices.begin(), mineIndices.end()); return mineIndices; } // getForSureMines void computeMineProbabilities(const Board& board) { initializeMinesMasks(board); initializeActiveConstraints(board); initializeUnconstrainedVariables(board); std::vector connectedActiveConstraints = connectedConstraints(board); std::vector<_SolutionSet> solutionSets; solutionSets.reserve(connectedActiveConstraints.size()); for (const ConnectedComponent& component : connectedActiveConstraints) { solutionSets.emplace_back(component, board, _minesMask); } _SolutionSetSampler sampler( solutionSets, _unconstrainedVariables, _minesMask); computeMineProbabilities(solutionSets, sampler); } // computeMineProbabilities template void computeMineProbabilitiesAndSampleMines(Mines& mines, const Board& board, RngEngine& rng) { initializeMinesMasks(board); initializeActiveConstraints(board); initializeUnconstrainedVariables(board); std::vector connectedActiveConstraints = connectedConstraints(board); std::vector<_SolutionSet> solutionSets; solutionSets.reserve(connectedActiveConstraints.size()); for (const ConnectedComponent& component : connectedActiveConstraints) { solutionSets.emplace_back(component, board, _minesMask); } _SolutionSetSampler sampler( solutionSets, _unconstrainedVariables, _minesMask); computeMineProbabilities(solutionSets, sampler); sampler.sampleMines(mines, rng); std::sort(mines.begin(), mines.end()); } // computeMineProbabilities const MineProbas& getMineProbabilities() const { return _mineProbas; } // getMineProbabilities private: void computeMineProbabilities(const std::vector<_SolutionSet>& solutionSets, const _SolutionSetSampler& solutionSetSampler) { memset(_mineProbas.data(), 0, WIDTH * HEIGHT * sizeof(typename MineProbas::value_type)); // mines are 100% for (const auto& pos : _minesMask.sparse()) { arrGet(_mineProbas, pos.row(), pos.col()) = 1.0; } // not mines are 0% for (const auto& pos : _notMinesMask.sparse()) { arrGet(_mineProbas, pos.row(), pos.col()) = 0.0; } auto countsWithProbas = solutionSetSampler.countsWithProbabilities(); for (const auto& countsWithProba : countsWithProbas) { const auto& counts = countsWithProba.first; auto proba = countsWithProba.second; MINESWEEPER_DEBUG(debug(std::cout) << "Counts: "); MINESWEEPER_DEBUG(for (auto n : counts) { std::cout << n << " "; }); MINESWEEPER_DEBUG(std::cout << ", weight=" << proba << std::endl); assert(counts.size() == solutionSets.size() + 1); for (size_t j = 0; j < solutionSets.size(); ++j) { MINESWEEPER_DEBUG(debug(std::cout) << "Solution set " << j << ": " << counts[j] << " mines" << std::endl); auto count = counts[j]; if (!count) { continue; } const auto& vars = solutionSets[j].getVariables(); const auto& varProbas = solutionSets[j].getVarProbas(count); MINESWEEPER_DEBUG(debug(std::cout) << "Variable probabilities: "); MINESWEEPER_DEBUG(for (auto p : varProbas) { std::cout << p << " "; }); MINESWEEPER_DEBUG(std::cout << std::endl); assert(vars.size() == varProbas.size()); for (size_t i = 0; i < vars.size(); ++i) { arrGet(_mineProbas, vars[i].row(), vars[i].col()) += proba * varProbas[i]; } } auto count = counts[solutionSets.size()]; if (!count) { continue; } MINESWEEPER_DEBUG(debug(std::cout) << "Unconstrained solution set: "); MINESWEEPER_DEBUG(std::cout << _unconstrainedVariables.sparse().size()); MINESWEEPER_DEBUG(std::cout << " variables, " << count << " mines, "); MINESWEEPER_DEBUG(std::cout << "proba=" << getUnconstrainedVarProba(count)); MINESWEEPER_DEBUG(std::cout << std::endl); for (const auto& pos : _unconstrainedVariables.sparse()) { arrGet(_mineProbas, pos.row(), pos.col()) += proba * getUnconstrainedVarProba(count); } } } // computeMineProbabilities float getUnconstrainedVarProba(size_t count) const { assert(count > 0); size_t nUnconstr = _unconstrainedVariables.sparse().size(); assert(nUnconstr >= count); if (count == 1) { return 1.0f / nUnconstr; } return static_cast(count) / (static_cast(nUnconstr) * (nUnconstr - count + 1)); } // getUnconstrainedVarProba std::ostream& dumpMasks(std::ostream& os) { debug(os) << "Mines mask:" << std::endl << _GameDefs::boardMaskToString(_minesMask.dense()); debug(os) << "Not mines mask:" << std::endl << _GameDefs::boardMaskToString(_notMinesMask.dense()); debug(os) << "Active constraints mask:" << std::endl << _GameDefs::boardMaskToString(_activeConstraints.dense()); debug(os) << "Unconstrained variables mask:" << std::endl << _GameDefs::boardMaskToString(_unconstrainedVariables.dense()); return os; } // dumpMasks template std::ostream& dumpConstraints(std::ostream& os, const T& constraints) { debug(std::cout) << "Active constraints:" << std::endl; size_t i = 0; for (const auto& component : constraints) { debug(std::cout) << "Component " << i++ << std::endl; debug(std::cout) << "Constraints: " << sparseMaskToString(component._constraints) << std::endl; debug(std::cout) << "Variables: " << sparseMaskToString(component._variables) << std::endl; }; return os; } // dumpActiveConstraints std::vector connectedConstraints(const Board& board) { std::vector connectedComponents; const Minesweeper::SparseMask& constraintsSparse = _activeConstraints.sparse(); connectedComponents.reserve(constraintsSparse.size()); BoardMask processed; memset(processed.data(), 0, WIDTH * HEIGHT * sizeof(typename BoardMask::value_type)); for (const Minesweeper::BoardPosition& bp : constraintsSparse) { if (arrGet(processed, bp.row(), bp.col())) { continue; } ConnectedComponent component = connectedConstraintsFromSeed(board, bp.row(), bp.col(), processed); connectedComponents.push_back(component); } return connectedComponents; } // connectedComponents ConnectedComponent connectedConstraintsFromSeed(const Board& board, int row, int col, BoardMask& processed) { // collect together active constraints connected through variables const Minesweeper::SparseMask& constraintsSparse = _activeConstraints.sparse(); ConnectedComponent component; component._constraints.reserve(constraintsSparse.size()); component._variables.reserve(constraintsSparse.size()); auto select_unprocessed_variables = [this, &processed]( int v, int row, int col) { return (v == Minesweeper::UNKNOWN) && !this->_notMinesMask.get(row, col) && !this->_minesMask.get(row, col) && !arrGet(processed, row, col); }; auto select_unprocessed_constraints = [this, &processed]( int UNUSED(v), int row, int col) { return this->_activeConstraints.get(row, col) && !arrGet(processed, row, col); }; std::vector currentVariables = _GameDefs::getNeighbors(board, row, col, select_unprocessed_variables); // add variables to the queue std::list var_queue( currentVariables.begin(), currentVariables.end()); // mark variables as processed for (const Minesweeper::BoardPosition& bp : currentVariables) { arrGet(processed, bp.row(), bp.col()) = 1; } // add constraint to the connected component component._constraints.emplace_back(row, col); // mark constraint as processed arrGet(processed, row, col) = 1; // process the queue of variables while (!var_queue.empty()) { Minesweeper::BoardPosition currentVar = var_queue.front(); component._variables.push_back(currentVar); var_queue.pop_front(); std::vector currentConstraints = _GameDefs::getNeighbors(board, currentVar.row(), currentVar.col(), select_unprocessed_constraints); for (const auto& currentConstraint : currentConstraints) { currentVariables = _GameDefs::getNeighbors( board, currentConstraint.row(), currentConstraint.col(), select_unprocessed_variables); // add variables to the queue var_queue.insert( var_queue.end(), currentVariables.begin(), currentVariables.end()); // mark variables as processed for (const auto& var : currentVariables) { arrGet(processed, var.row(), var.col()) = 1; } // add constraint to the connected component component._constraints.emplace_back( currentConstraint.row(), currentConstraint.col()); // mark constraint as processed arrGet( processed, currentConstraint.row(), currentConstraint.col()) = 1; } } return component; } // connectedComponentFromSeed void initializeMinesMasks(const Board& board) { _notMinesMask.zero(); _minesMask.zero(); _processed.zero(); auto select_all = [](int UNUSED(v), int UNUSED(row), int UNUSED(col)) { return true; }; auto select_potential_mines = [=](int v, int row, int col) { return (v == Minesweeper::UNKNOWN) && !_notMinesMask.get(row, col) && !_minesMask.get(row, col); }; auto select_not_marked_mines = [=](int UNUSED(v), int row, int col) { return !_minesMask.get(row, col); }; auto select_marked_mines = [=](int UNUSED(v), int row, int col) { return _minesMask.get(row, col); }; int v; bool notchanged; do { notchanged = true; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { if (_processed.get(row, col)) { continue; } v = arrGet(board, row, col); switch (v) { case Minesweeper::UNKNOWN: _processed.set(row, col); break; case Minesweeper::BOOM: _minesMask.set(row, col); _processed.set(row, col); notchanged = false; break; case 0: // none of the neighbors are mines _GameDefs::markNeighbors( board, row, col, _notMinesMask, select_all); _notMinesMask.set(row, col); _processed.set(row, col); notchanged = false; break; default: assert(v > 0); size_t num_mines_total = static_cast(v); size_t num_mines = _GameDefs::countNeighbors(board, row, col, select_marked_mines); size_t num_potential_mines = _GameDefs::countNeighbors( board, row, col, select_potential_mines); assert(num_mines <= num_mines_total); assert(num_potential_mines + num_mines >= num_mines_total); if (num_mines == num_mines_total) { // the rest are not mines _GameDefs::markNeighbors( board, row, col, _notMinesMask, select_not_marked_mines); _processed.set(row, col); notchanged = false; } else if (num_potential_mines + num_mines == num_mines_total) { // all candidates are mines _GameDefs::markNeighbors( board, row, col, _minesMask, select_potential_mines); // the rest are not mines _GameDefs::markNeighbors( board, row, col, _notMinesMask, select_not_marked_mines); _processed.set(row, col); notchanged = false; } if (!_notMinesMask.get(row, col)) { _notMinesMask.set(row, col); notchanged = false; } } // switch(v) } // for col } // for row } while (!notchanged); } // initializeMinesMasks void initializeActiveConstraints(const Board& board) { _activeConstraints.zero(); auto select_potential_mines = [=](int v, int row, int col) { return (v == Minesweeper::UNKNOWN) && !_notMinesMask.get(row, col) && !_minesMask.get(row, col); }; auto select_mines = [=](int UNUSED(v), int row, int col) { return _minesMask.get(row, col); }; typename Board::value_type v; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { v = arrGet(board, row, col); if (v > 0) { size_t num_mines_total = static_cast(v); size_t num_mines = _GameDefs::countNeighbors(board, row, col, select_mines); size_t num_potential_mines = _GameDefs::countNeighbors( board, row, col, select_potential_mines); assert(num_mines <= num_mines_total); assert(num_potential_mines + num_mines >= num_mines_total); if (num_potential_mines + num_mines > num_mines_total) { // has unknown neighbors, not all of them are mines _activeConstraints.set(row, col); } } } // for col } // for row } // initializeActiveConstraints void initializeUnconstrainedVariables(const Board& board) { _unconstrainedVariables.zero(); auto select_active_constraints = [this](int UNUSED(v), int row, int col) { return this->_activeConstraints.get(row, col); }; typename Board::value_type v; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { v = arrGet(board, row, col); if ((v == Minesweeper::UNKNOWN) && !_minesMask.get(row, col) && !_notMinesMask.get(row, col) && !_GameDefs::countNeighbors( board, row, col, select_active_constraints)) { _unconstrainedVariables.set(row, col); } } // for col } // for row } // initializeUnconstrainedVariables _Mask _minesMask; _Mask _notMinesMask; _Mask _activeConstraints; _Mask _unconstrainedVariables; _Mask _processed; MineProbas _mineProbas; }; // class CspStrategy } // namespace vkms } // namespace csp ================================================ FILE: src/games/minesweeper_csp_vkms/SolutionSet.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "ConnectedComponent.h" namespace csp { namespace vkms { #define debug Minesweeper::debug #define rowColToIdx Minesweeper::rowColToIdx #define arrGet Minesweeper::arrGet template class SolutionSet { using _GameDefs = Minesweeper::GameDefs; using Board = typename _GameDefs::Board; using _Mask = Minesweeper::Mask; using IdxSizePair = std::pair; using IdxSizePairs = std::vector; using Indices = std::list; using Solution = std::list; using Solutions = std::list; public: SolutionSet(const ConnectedComponent& cc, const Board& board, const _Mask& mines) : _variables(cc._variables) , _constraints(cc._constraints) , _varToConstr(_variables.size()) , _constrToVar(_constraints.size()) , _minNumMines(MINES) , _maxNumMines(0) , _varStates(_variables.size(), -1) { initializeVariableIdxMap(); initializeMaps(); _constrCounts = computeConstraintNminesLeft(board, mines); _constrStates = _constrCounts; _varOrder = variablesOrderedByNconstraintsDescending(); enumerateSolutions(board, mines); MINESWEEPER_DEBUG(dumpSolutionStats(debug(std::cout)) << std::endl); } // SolutionSet size_t minNumMines() const { return _minNumMines; } // min_num_mines size_t maxNumMines() const { return _maxNumMines; } // max_num_mines bool hasSamples(size_t nmines) const { return _solutions.find(nmines) != _solutions.end(); } // hasSamples size_t numSamples(size_t nmines) const { return _solutions.at(nmines).size(); } // hasSamples const Minesweeper::SparseMask& getVariables() const { return _variables; } // getVariables std::vector getVarProbas(size_t nmines) const { std::vector probas(_variables.size(), 0); if (!hasSamples(nmines)) { return probas; } const auto& solutions = _solutions.at(nmines); for (const auto& solution : solutions) { for (auto mineIdx : solution) { probas[_mineIdxToVarIdx.at(mineIdx)] += 1; } } for (auto& proba : probas) { proba /= solutions.size(); } return probas; } // getVarProbas template std::vector sample(size_t nmines, RngEngine& rng) const { std::vector sample; if (!nmines) { return sample; } sample.reserve(nmines); assert(hasSamples(nmines)); const auto& solutions = _solutions.at(nmines); std::uniform_int_distribution distribution(0, solutions.size() - 1); size_t sampleIdx = distribution(rng); auto solutionsIt = solutions.begin(); for (size_t i = 0; i < sampleIdx; ++i, ++solutionsIt) ; const auto& solution = *solutionsIt; assert(solution.size() == nmines); for (auto mineIdx : solution) { sample.push_back(mineIdx); } return sample; } // sample private: void initializeVariableIdxMap() { int mineIdx; for (size_t i = 0; i < _variables.size(); ++i) { mineIdx = rowColToIdx(_variables[i].row(), _variables[i].col()); assert(mineIdx >= 0); _mineIdxToVarIdx[static_cast(mineIdx)] = i; } } // initializeVariableIdxMap void initializeMaps() { for (size_t i = 0; i < _variables.size(); ++i) { Minesweeper::BoardPosition bp_i = _variables[i]; for (size_t j = 0; j < _constraints.size(); ++j) { Minesweeper::BoardPosition bp_j = _constraints[j]; if ((bp_i.col() - bp_j.col() >= -1) && (bp_i.col() - bp_j.col() <= 1) && (bp_i.row() - bp_j.row() >= -1) && (bp_i.row() - bp_j.row() <= 1)) { _varToConstr[i].push_back(j); _constrToVar[j].push_back(i); } } // for j } // for i } // initializeMaps std::vector computeConstraintNminesLeft(const Board& board, const _Mask& mines) { std::vector counts(_constrToVar.size(), 0); auto select_mines = [&](int UNUSED(v), int row, int col) { return mines.get(row, col); }; int v, row, col; size_t count, nmines; for (size_t j = 0; j < _constrToVar.size(); ++j) { row = _constraints[j].row(); col = _constraints[j].col(); v = arrGet(board, row, col); assert(v > 0); count = static_cast(v); nmines = _GameDefs::countNeighbors(board, row, col, select_mines); assert(count > nmines); counts[j] = count - nmines; } return counts; } // computeConstraintNminesLeft std::vector variablesOrderedByNconstraintsDescending() { std::vector order(_varToConstr.size()); for (size_t i = 0; i < order.size(); ++i) { order[i] = i; } std::sort(order.begin(), order.end(), [this](size_t i, size_t j) { return this->_varToConstr[i].size() > this->_varToConstr[j].size(); }); return order; } // variablesOrderedByNconstraintsDescending void assignMine(size_t i) { _varStates[i] = 1; for (size_t j : _varToConstr[i]) { if (_constrStates[j]) { // IMPORTANT: this conditional constraint state decrease may lead to // inconsistent states, where some cells have more neighbor mines // than declared; consistency check is required after updates _constrStates[j]--; } } } // assignMine void assignNotMine(size_t i) { if (_varStates[i] == 1) { for (size_t j : _varToConstr[i]) { _constrStates[j]++; } } _varStates[i] = 0; } // assignNotMine int nextUnassignedVariable() const { for (size_t i = 0; i < _varOrder.size(); ++i) { if (_varStates[_varOrder[i]] == -1) { return static_cast(_varOrder[i]); } } return -1; } // nextUnassignedVariable bool constraintsSatisfied() const { for (size_t constrState : _constrStates) { if (constrState) { return false; } } return true; } // constraintsSatisfied bool updateStates() { bool changed = false; for (size_t j = 0; j < _constrStates.size(); ++j) { if (!_constrStates[j]) { // no more mines for this constraint, mark all free variables as // not mines for (size_t i : _constrToVar[j]) { if (_varStates[i] == -1) { assignNotMine(i); changed = true; } } } else { // check if the number of free variables is equal to the number of // mines left; assign all free variables to mines, if true size_t freeVars = 0; for (size_t i : _constrToVar[j]) { if (_varStates[i] == -1) { ++freeVars; } } if (freeVars == _constrStates[j]) { for (size_t i : _constrToVar[j]) { if (_varStates[i] == -1) { assignMine(i); } } changed = true; } } } // for j return changed; } // updateConstrStates void updateFromAssignments() { std::copy( _constrCounts.begin(), _constrCounts.end(), _constrStates.begin()); std::vector varStates(_varStates); std::fill(_varStates.begin(), _varStates.end(), -1); for (size_t v : _assignedVars) { assert((varStates[v] == 1) || (varStates[v] == 0)); if (varStates[v]) { assignMine(v); } else { assignNotMine(v); } } bool changed; do { changed = updateStates(); } while (changed); } // updateConstraint void assignVariable(size_t i) { _assignedVars.push_back(i); _varStates[i] = 1; updateFromAssignments(); } // assignVariable void triggerLastAssignment() { if (_assignedVars.empty()) { return; } size_t lastAssigned = _assignedVars.back(); while (!_varStates[lastAssigned]) { _assignedVars.pop_back(); if (_assignedVars.empty()) { return; } lastAssigned = _assignedVars.back(); } assert(_varStates[lastAssigned] == 1); _varStates[lastAssigned] = 0; updateFromAssignments(); } // triggerLastAssignment void enumerateSolution() { Solution mines; for (size_t i = 0; i < _varStates.size(); ++i) { if (_varStates[i] == 1) { int idx = rowColToIdx(_variables[i].row(), _variables[i].col()); assert(idx >= 0); mines.push_back(static_cast(idx)); } } if (_minNumMines > mines.size()) { _minNumMines = mines.size(); } if (_maxNumMines < mines.size()) { _maxNumMines = mines.size(); } _solutions[mines.size()].push_back(mines); } // enumerateSolution bool checkSolutionAgainstBoard(const Board& board, const _Mask& mines) { for (size_t i = 0; i < _constraints.size(); ++i) { const auto& varIndices = _constrToVar[i]; size_t nMines = 0; for (const auto& varIdx : varIndices) { if (_varStates[varIdx] > 0) { ++nMines; } } auto select_mines = [&](int UNUSED(v), int row, int col) { return mines.get(row, col); }; size_t nMinesMarked = _GameDefs::countNeighbors( board, _constraints[i].row(), _constraints[i].col(), select_mines); nMines += nMinesMarked; int v = arrGet( board, _constraints[i].row(), _constraints[i].col()); assert(v > 0); if (static_cast(v) != nMines) { /*MINESWEEPER_DEBUG(debug(std::cout) << "Constraint " << i \ << " (" << _constraints[i].row() << ", " \ << _constraints[i].col() << ")=" << v << " has " \ << nMines << " mines" << std::endl); MINESWEEPER_DEBUG(debug(std::cout) << "Board:" << std::endl; \ std::cout << _GameDefs::boardToString(board) << std::endl); MINESWEEPER_DEBUG(debug(std::cout) << "State Board:" << std::endl; \ std::cout << stateToString(board) << std::endl); dumpDebugInfo(board);*/ return false; } } return true; } // checkSolutionAgainstBoard std::string stateToString(const Board& board) { using BoardChars = std::array; BoardChars boardChars; int v; char c; int k = 0; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { v = board[k]; switch (v) { case Minesweeper::UNKNOWN: c = '.'; break; case Minesweeper::BOOM: c = 'X'; break; default: assert(v >= 0); c = '0' + v; } boardChars[k] = c; ++k; } } for (size_t i = 0; i < _varStates.size(); ++i) { if (_varStates[i] == 1) { arrGet( boardChars, _variables[i].row(), _variables[i].col()) = '*'; } else if (_varStates[i] == 0) { arrGet( boardChars, _variables[i].row(), _variables[i].col()) = '@'; } else { assert(_varStates[i] == -1); arrGet( boardChars, _variables[i].row(), _variables[i].col()) = '?'; } } std::ostringstream oss; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { oss << arrGet(boardChars, row, col); } oss << std::endl; } return oss.str(); } // stateToString void enumerateSolutions(const Board& board, const _Mask& mines) { _solutions.clear(); _minNumMines = MINES; _maxNumMines = 0; std::fill(_varStates.begin(), _varStates.end(), -1); std::copy( _constrCounts.begin(), _constrCounts.end(), _constrStates.begin()); _assignedVars.clear(); int v; do { if (constraintsSatisfied()) { // some constraints might have more mines than specified, // check more thoroughly if (checkSolutionAgainstBoard(board, mines)) { enumerateSolution(); } triggerLastAssignment(); } else { v = nextUnassignedVariable(); if (v == -1) { triggerLastAssignment(); } else { assignVariable(static_cast(v)); if (!checkConsistency()) { triggerLastAssignment(); } } } } while (!_assignedVars.empty()); MINESWEEPER_DEBUG( if (_solutions.empty()) { enumerateSolutionsDebug(board); }); assert(!_solutions.empty()); } // enumerateSolutions void enumerateSolutionsDebug(const Board& board) { debug(std::cout) << "Debugging session for solutions enumeration!" << std::endl; _solutions.clear(); _minNumMines = MINES; _maxNumMines = 0; std::fill(_varStates.begin(), _varStates.end(), -1); std::copy( _constrCounts.begin(), _constrCounts.end(), _constrStates.begin()); _assignedVars.clear(); int v; do { if (constraintsSatisfied()) { debug(std::cout) << "Constraints satisfied" << std::endl; dumpDebugInfo(board); enumerateSolution(); debug(std::cout) << "Enumerated solution" << std::endl; triggerLastAssignment(); debug(std::cout) << "Triggered last assignment" << std::endl; dumpDebugInfo(board); } else { debug(std::cout) << "Constraints not satisfied" << std::endl; dumpDebugInfo(board); v = nextUnassignedVariable(); debug(std::cout) << "Next variable: " << v << std::endl; if (v == -1) { debug(std::cout) << "No variable to assign" << std::endl; dumpDebugInfo(board); triggerLastAssignment(); debug(std::cout) << "Triggered last assignment" << std::endl; dumpDebugInfo(board); } else { debug(std::cout) << "Assign variable " << v << std::endl; assignVariable(static_cast(v)); if (!checkConsistency()) { debug(std::cout) << "Inconsistency found!" << std::endl; dumpDebugInfo(board); triggerLastAssignment(); debug(std::cout) << "Triggered last assignment" << std::endl; dumpDebugInfo(board); } } } } while (!_assignedVars.empty()); } // enumerateSolutionsDebug std::ostream& dumpSolutionStats(std::ostream& os) { os << "Solution set: "; for (const auto& [nmines, solution] : _solutions) { os << nmines << " mines (" << solution.size() << " solutions), "; } return os; } // printSolutionStats bool checkConsistency() { size_t i = 0; size_t nUnassigned; size_t nMines; for (const Indices& indices : _constrToVar) { nUnassigned = 0; nMines = 0; size_t constrCount = _constrCounts[i]; size_t constrState = _constrStates[i]; for (size_t j : indices) { switch (_varStates[j]) { case -1: nUnassigned++; break; case 1: nMines++; break; default:; } } if ((constrCount < constrState) || (constrCount < nMines) || (nUnassigned < constrState) || (nUnassigned + nMines < constrCount)) { // debug(std::cout) << "Inconsistency for constraint " << i // << ": constrCount=" << constrCount // << ", constrState=" << constrState // << ", varCount=" << varCount << std::endl; // dumpDebugInfo(); return false; } ++i; } return true; } // SolutionSet::checkConsistency void checkCanAssignVar(size_t varIdx) { for (size_t j : _varToConstr[varIdx]) { if (!_constrStates[j]) { /*debug(std::cout) << "Attempt to assign variable " << varIdx << " that must not be assigned: constraint " << j << " has 0" << std::endl; dumpDebugInfo();*/ assert(false); } } } // SolutionSet::checkCanAssignVar void dumpDebugInfo(const Board& board) { debug(std::cout) << "Solution set:" << std::endl; debug(std::cout) << "Variables: " << sparseMaskToString(_variables) << std::endl; debug(std::cout) << "Constraints: " << sparseMaskToString(_constraints) << std::endl; debug(std::cout) << "Variables to constraints: " << std::endl; size_t i = 0; for (const Indices& indices : _varToConstr) { debug(std::cout) << " " << i++ << ": " << valuesToString(indices) << std::endl; } debug(std::cout) << "Constraints to variables: " << std::endl; i = 0; for (const Indices& indices : _constrToVar) { debug(std::cout) << " " << i++ << ": " << valuesToString(indices) << std::endl; } debug(std::cout) << "Assigned variables: "; for (size_t i : _assignedVars) { std::cout << i << "=" << _varStates[i] << ", "; } std::cout << std::endl; debug(std::cout) << "Variable states: "; i = 0; for (int s : _varStates) { std::cout << i++ << "=" << s << ", "; } std::cout << std::endl; debug(std::cout) << "Variables order: " << valuesToString(_varOrder) << std::endl; debug(std::cout) << "Constraint counts: " << valuesToString(_constrCounts) << std::endl; debug(std::cout) << "Constraint states: " << valuesToString(_constrStates) << std::endl; debug(std::cout) << "State Board:" << std::endl; std::cout << stateToString(board) << std::endl; } // SolutionSet::dumpDebugInfo template std::string valuesToString(const T& values) { std::ostringstream oss; for (typename T::value_type v : values) { oss << v << ", "; } return oss.str(); } // SolutionSet::indicesToString private: const Minesweeper::SparseMask& _variables; const Minesweeper::SparseMask& _constraints; std::vector _varToConstr; std::vector _constrToVar; std::unordered_map _mineIdxToVarIdx; std::unordered_map _solutions; size_t _minNumMines; size_t _maxNumMines; // enumeration fields std::list _assignedVars; std::vector _varStates; std::vector _varOrder; std::vector _constrCounts; std::vector _constrStates; }; // class SolutionSet } // namespace vkms } // namespace csp ================================================ FILE: src/games/minesweeper_csp_vkms/SolutionSetSampler.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "SolutionSet.h" namespace csp { namespace vkms { template class SolutionSetSampler { using _GameDefs = Minesweeper::GameDefs; using Mines = typename _GameDefs::Mines; using _SolutionSet = SolutionSet; using _Mask = Minesweeper::Mask; using CountSample = std::vector; using CountSampleList = std::list; public: SolutionSetSampler(const std::vector<_SolutionSet>& solutionSets, const _Mask& unconstrainedVariables, const _Mask& mines) : _solutionSets(solutionSets) , _unconstrainedVariables(unconstrainedVariables) , _mines(mines) , _numMinesRemaining(MINES - mines.sparse().size()) , _unconstrVarSetIdx(solutionSets.size()) , _numUnconstrVars(unconstrainedVariables.sparse().size()) , _minMines(solutionSets.size() + 1, 0) , _maxMines(solutionSets.size() + 1, 0) , _firstBranchingSet(0) , _solutionSetsOrder(solutionSets.size() + 1, 0) , _numMinesToSample(solutionSets.size() + 1, 0) { assert(mines.sparse().size() <= MINES); assert(_numMinesRemaining <= MINES); initializeMinMaxMinesStats(); prepareSampling(); } // SolutionSetSampler::SolutionSetSampler std::vector> countsWithProbabilities() const { std::vector> countSamplesWithProbas; countSamplesWithProbas.reserve(_countSamples.size()); auto countSamplesIt = _countSamples.begin(); for (size_t k = 0; k < _countSamples.size(); ++k) { const auto& countSampleOrdered = *countSamplesIt++; CountSample countSample(countSampleOrdered.size()); for (size_t i = 0; i < countSample.size(); ++i) { countSample[_solutionSetsOrder[i]] = countSampleOrdered[i]; } countSamplesWithProbas.emplace_back(countSample, _countSampleProbas[k]); } return countSamplesWithProbas; } // countsWithProbabilities template void sampleMines(Mines& mines, RngEngine& rng) { auto mineSampleIt = mines.begin(); // add all marked mines for (const auto& v : _mines.sparse()) { *mineSampleIt++ = rowColToIdx(v.row(), v.col()); } // sample counts for each solution set CountSample countSample; if (_countSamples.size() > 1) { MINESWEEPER_DEBUG(debug(std::cout) << "Unnormalized probas: "; dumpCollection(std::cout, _countSampleProbas) << std::endl); std::discrete_distribution sampleDistribution( _countSampleProbas.begin(), _countSampleProbas.end()); size_t countSampleIdx = sampleDistribution(rng); auto countSampleIt = _countSamples.begin(); for (size_t i = 0; i < countSampleIdx; ++i, ++countSampleIt) ; countSample = *countSampleIt; } else { countSample = _countSamples.front(); } MINESWEEPER_DEBUG(debug(std::cout) << "Count sample: "; dumpCollection(std::cout, countSample) << std::endl); // sample according to counts size_t nMinesInSetJ, j; for (size_t i = 0; i < countSample.size(); ++i) { j = _solutionSetsOrder[i]; nMinesInSetJ = countSample[i]; if (!nMinesInSetJ) { continue; } if (j != _unconstrVarSetIdx) { auto mineSample = _solutionSets[j].sample(nMinesInSetJ, rng); mineSampleIt = std::copy(mineSample.begin(), mineSample.end(), mineSampleIt); } else { auto mineSample = sampleUnconstrained(nMinesInSetJ, rng); assert(mineSample.size() == nMinesInSetJ); mineSampleIt = std::copy(mineSample.begin(), mineSample.end(), mineSampleIt); } } assert(mineSampleIt == mines.end()); std::sort(mines.begin(), mines.end()); } // olutionSetSampler::sampleMines private: static constexpr size_t INVALID_COUNT = static_cast(-1); void prepareSampling() { adjustMinMaxMinesStats(); computeSolutionSetsOrder(); _countSamples = enumeratePlausibleCountSamples(); assert(!_countSamples.empty()); MINESWEEPER_DEBUG(dumpCountSamples(std::cout, _countSamples)); _countSampleProbas = computeSampleProbabilities(_countSamples); } // prepareSampling template std::vector sampleUnconstrained(size_t n, RngEngine& rng) { std::vector sample; if (!n) { return sample; } sample.reserve(n); std::vector unconstrained( _unconstrainedVariables.sparse()); std::shuffle(unconstrained.begin(), unconstrained.end(), rng); for (size_t i = 0; i < n; ++i) { std::uniform_int_distribution distribution( i, unconstrained.size() - 1); size_t varIdx = distribution(rng); const auto& boardPosition = unconstrained[varIdx]; sample.push_back( rowColToIdx(boardPosition.row(), boardPosition.col())); std::swap(unconstrained[i], unconstrained[varIdx]); } return sample; } std::vector computeSampleProbabilities( const CountSampleList& samples) { std::vector probas; probas.reserve(samples.size()); float unnormalizedLogProba; float maxLogProba = 0; size_t nSamples, nMinesInSetJ, j; for (const auto& sample : samples) { MINESWEEPER_DEBUG(debug(std::cout) << "Computing probabilities for sample counts:" << std::endl); MINESWEEPER_DEBUG(dumpCollection(debug(std::cout), sample) << std::endl); assert(sample.size() == _solutionSetsOrder.size()); unnormalizedLogProba = 0; for (size_t i = 0; i < sample.size(); ++i) { j = _solutionSetsOrder[i]; nMinesInSetJ = sample[i]; if (nMinesInSetJ > 0) { if (j != _unconstrVarSetIdx) { assert(_solutionSets[j].hasSamples(nMinesInSetJ)); nSamples = _solutionSets[j].numSamples(nMinesInSetJ); unnormalizedLogProba += log(nSamples); MINESWEEPER_DEBUG(debug(std::cout) << "Set " << j << " (constrained)" << ", #mines " << nMinesInSetJ << ", log proba " << log(nSamples) << std::endl); } else { assert(nMinesInSetJ <= _numUnconstrVars); MINESWEEPER_DEBUG(debug(std::cout) << "Set " << j << " (unconstrained)" << ", #mines " << nMinesInSetJ << ", log proba " << logCnk(_numUnconstrVars, nMinesInSetJ) << std::endl); unnormalizedLogProba += logCnk(_numUnconstrVars, nMinesInSetJ); } } } if (maxLogProba < unnormalizedLogProba) { maxLogProba = unnormalizedLogProba; } probas.push_back(unnormalizedLogProba); } // normalize float probaSum = 0; for (auto& proba : probas) { proba = exp(proba - maxLogProba); probaSum += proba; } MINESWEEPER_DEBUG(debug(std::cout) << "Probas: "); for (auto& proba : probas) { proba /= probaSum; MINESWEEPER_DEBUG(std::cout << probas << ", "); } MINESWEEPER_DEBUG(std::cout << std::endl); return probas; } // computeSampleProbabilities float logCnk(size_t n, size_t k) { // n! / (k! (n-k)!) float result = 0; assert(n >= k); result += sumLog(max(k, n - k) + 1, n); result -= sumLog(2, min(k, n - k)); return result; } float sumLog(size_t n1, size_t n2) { float result = 0; for (size_t n = n1; n <= n2; ++n) { result += log(n); } return result; } template std::ostream& dumpCollection(std::ostream& os, const T& collection) { for (const auto& v : collection) { os << v << ' '; } return os; } // dumpSample template std::ostream& dumpCountSamples(std::ostream& os, const T& samples) { debug(os) << "Count samples:" << std::endl; for (const auto& sample : samples) { debug(os) << " "; dumpCollection(os, sample) << std::endl; } return os; } // dumpCountSamples std::list> enumeratePlausibleCountSamples() { std::list> samples; // set mine counts for sets with deterministic counts size_t initNumMines = 0; for (size_t i = 0; i < _firstBranchingSet; ++i) { size_t j = _solutionSetsOrder[i]; assert(_minMines[j] == _maxMines[j]); _numMinesToSample[i] = _minMines[j]; initNumMines += _minMines[j]; } // finish if there are only deterministic counts if (_firstBranchingSet == _solutionSetsOrder.size()) { samples.push_back(_numMinesToSample); return samples; } // traverse the rest and select valid combinations std::vector currentCounts; assert(_solutionSetsOrder.size() > _firstBranchingSet); const size_t currentCountsCapacity = _solutionSetsOrder.size() - _firstBranchingSet; currentCounts.reserve(currentCountsCapacity); size_t cursor = _firstBranchingSet; size_t setIdx = _solutionSetsOrder[cursor]; size_t numMines = nextMinesCount(_minMines[setIdx], setIdx); assert(numMines != INVALID_COUNT); currentCounts.push_back(numMines); size_t sumNumMines = initNumMines + numMines; while (!currentCounts.empty()) { // fill with min number of mines for each set if (currentCounts.size() < currentCountsCapacity - 1) { ++cursor; setIdx = _solutionSetsOrder[cursor]; numMines = nextMinesCount(_minMines[setIdx], setIdx); assert(numMines != INVALID_COUNT); currentCounts.push_back(numMines); sumNumMines += numMines; if (sumNumMines > _numMinesRemaining) { break; } continue; } assert(currentCounts.size() == currentCountsCapacity - 1); assert(cursor == _solutionSetsOrder.size() - 2); assert(sumNumMines == initNumMines + std::accumulate(currentCounts.begin(), currentCounts.end(), 0u)); // check if can sample the missing mines from the last set if (sumNumMines <= _numMinesRemaining) { ++cursor; setIdx = _solutionSetsOrder[cursor]; numMines = _numMinesRemaining - sumNumMines; if (canSampleNumMinesFromSet(numMines, setIdx)) { currentCounts.push_back(numMines); std::copy(currentCounts.begin(), currentCounts.end(), &_numMinesToSample[_firstBranchingSet]); samples.push_back(_numMinesToSample); currentCounts.pop_back(); } // next counts configuration --cursor; setIdx = _solutionSetsOrder[cursor]; numMines = nextMinesCount(currentCounts.back() + 1, setIdx); } else { // next counts configuration numMines = INVALID_COUNT; } while ((numMines == INVALID_COUNT) && !currentCounts.empty()) { sumNumMines -= currentCounts.back(); currentCounts.pop_back(); if (cursor > _firstBranchingSet) { --cursor; setIdx = _solutionSetsOrder[cursor]; numMines = nextMinesCount(currentCounts.back() + 1, setIdx); } else { assert(currentCounts.empty()); } } if (numMines != INVALID_COUNT) { sumNumMines -= currentCounts.back(); sumNumMines += numMines; currentCounts.back() = numMines; } } return samples; } // determineNumberOfSamples bool canSampleNumMinesFromSet(size_t numMines, size_t setIdx) { if (setIdx == _unconstrVarSetIdx) { // set of unconstrained variables return numMines <= _numUnconstrVars; } else { return _solutionSets[setIdx].hasSamples(numMines); } } // canSampleNumMinesFromSet size_t nextMinesCount(size_t countHint, size_t setIdx) { assert(setIdx < _maxMines.size()); if (countHint > _maxMines[setIdx]) { return INVALID_COUNT; } if (setIdx == _unconstrVarSetIdx) { return countHint; } while (!_solutionSets[setIdx].hasSamples(countHint)) { ++countHint; if (countHint > _maxMines[setIdx]) { return INVALID_COUNT; } } assert(_solutionSets[setIdx].hasSamples(countHint)); return countHint; } // nextMinesCount void computeSolutionSetsOrder() { assert(_solutionSetsOrder.size() > 0); assert(_solutionSetsOrder.size() == _minMines.size()); assert(_solutionSetsOrder.size() == _maxMines.size()); _firstBranchingSet = 0; size_t head = 0; size_t tail = _solutionSetsOrder.size() - 1; for (size_t i = 0; i < _solutionSetsOrder.size(); ++i) { if (_minMines[i] == _maxMines[i]) { _solutionSetsOrder[head++] = i; } else { _solutionSetsOrder[tail--] = i; } } assert(tail + 1 == head); // if unconstrained set does not have a fixed number of mines to sample // swap it with the last one if (_solutionSetsOrder[head] == _unconstrVarSetIdx) { size_t tmp = _solutionSetsOrder.back(); _solutionSetsOrder.back() = _unconstrVarSetIdx; _solutionSetsOrder[head] = tmp; } _firstBranchingSet = head; } // computeSolutionSetsOrder void initializeMinMaxMinesStats() { for (size_t i = 0; i < _solutionSets.size(); ++i) { _minMines[i] = _solutionSets[i].minNumMines(); _maxMines[i] = _solutionSets[i].maxNumMines(); } _minMines[_solutionSets.size()] = 0; _maxMines[_solutionSets.size()] = _unconstrainedVariables.sparse().size(); MINESWEEPER_DEBUG( debug(std::cout) << "Min mines init: "; for (size_t n : _minMines) { std::cout << n << " "; } std::cout << std::endl;); MINESWEEPER_DEBUG( debug(std::cout) << "Max mines init: "; for (size_t n : _maxMines) { std::cout << n << " "; } std::cout << std::endl;); } // SolutionSetSampler::initializeMinMaxMinesStats void adjustMinMaxMinesStats() { size_t sumMax = std::accumulate(_maxMines.begin(), _maxMines.end(), 0u); size_t sumMin = std::accumulate(_minMines.begin(), _minMines.end(), 0u); const size_t nsets = _maxMines.size(); size_t delta; bool changed; do { changed = false; for (size_t i = 0; i < nsets; ++i) { if (_maxMines[i] + sumMin > _numMinesRemaining + _minMines[i]) { delta = _maxMines[i] + sumMin - (_numMinesRemaining + _minMines[i]); _maxMines[i] -= delta; sumMax -= delta; changed = true; } if (_minMines[i] + sumMax < _numMinesRemaining + _maxMines[i]) { delta = _numMinesRemaining + _maxMines[i] - (_minMines[i] + sumMax); _minMines[i] += delta; sumMin += delta; changed = true; } } } while (changed); MINESWEEPER_DEBUG(debug(std::cout) << "Min mines adj: "; for (size_t n : _minMines) { std::cout << n << " "; } std::cout << std::endl;); MINESWEEPER_DEBUG(debug(std::cout) << "Max mines adj: "; for (size_t n : _maxMines) { std::cout << n << " "; } std::cout << std::endl;); } // SolutionSetSampler::adjustMinMaxMinesStats const std::vector<_SolutionSet>& _solutionSets; const _Mask& _unconstrainedVariables; const _Mask& _mines; const size_t _numMinesRemaining; const size_t _unconstrVarSetIdx; const size_t _numUnconstrVars; std::vector _minMines; std::vector _maxMines; size_t _firstBranchingSet; std::vector _solutionSetsOrder; std::vector _numMinesToSample; CountSampleList _countSamples; std::vector _countSampleProbas; }; // class SolutionSetSampler } // namespace vkms } // namespace csp ================================================ FILE: src/games/minesweeper_csp_vkms/csp_vkms.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include #include #include using namespace csp::vkms; using namespace std; template float good_action_eval(core::State& s) { size_t game_count{0}; float sum_score{0}; size_t n_actions_cur_game = 0; while (game_count < NTOTAL) { s.reset(); n_actions_cur_game = 0; while (!s.terminated()) { s.DoGoodAction(); ++n_actions_cur_game; } sum_score += 0.5 * (1 + s.getReward(0)); ++game_count; } const float avg_score = sum_score / float(game_count); return avg_score; } // good_action_eval template std::string get_map_str() { ostringstream oss; oss << "Minesweeper"; return oss.str(); } // get_map_str template void benchmark_vkms() { using namespace std::chrono; high_resolution_clock::time_point t1 = high_resolution_clock::now(); auto state = Minesweeper::State(SEED); float win_rate = good_action_eval(state); high_resolution_clock::time_point t2 = high_resolution_clock::now(); double duration_s = duration(t2 - t1).count(); auto map_str = get_map_str(); std::cout << map_str << ", win rate = " << win_rate << ", took " << duration_s << "s (" << static_cast(NTOTAL) / duration_s << " games/s)" << std::endl; } // benchmark_vkms int main(int, char**) { static constexpr int master_seed = 999; benchmark_vkms<4, 4, 4, master_seed, 100000>(); benchmark_vkms<3, 1, 1, master_seed, 100000>(); benchmark_vkms<5, 2, 3, master_seed, 100000>(); benchmark_vkms<5, 5, 10, master_seed, 100000>(); benchmark_vkms<10, 1, 5, master_seed, 100000>(); benchmark_vkms<7, 3, 10, master_seed, 100000>(); benchmark_vkms<5, 5, 15, master_seed, 100000>(); benchmark_vkms<8, 8, 10, master_seed, 100000>(); benchmark_vkms<9, 9, 10, master_seed, 100000>(); benchmark_vkms<16, 16, 40, master_seed, 10000>(); benchmark_vkms<30, 16, 99, master_seed, 10000>(); } ================================================ FILE: src/games/minesweeper_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include #include #include "../core/state.h" #include "commons/hash.h" #include "minesweeper_common.h" #include "minesweeper_csp_vkms/CspStrategy.h" #define EXPAND_ZEROS #define FLAG_MINES namespace Minesweeper { template class State : public core::State { static constexpr size_t HASHBOOK_SIZE = WIDTH * HEIGHT * 11; using _Mask = Mask; using _HashBook = HashBook; using _Hasher = Hasher; public: using Act = ::_Action; using _GameDefs = GameDefs; using Board = typename _GameDefs::Board; using BoardProbas = typename _GameDefs::BoardProbas; using Mines = typename _GameDefs::Mines; using Neighbors = typename _GameDefs::Neighbors; State(int seed) : core::State(seed) , _hasher(hashBook) { _board.fill(UNKNOWN); _boardSample.fill(UNKNOWN); _minesSample.fill(-1); std::call_once(hashBookConfigured, [this]() { hashBook.setup(_rng); }); } // State::State virtual void Initialize() override { MINESWEEPER_DEBUG(debug(std::cout) << "Initialize" << std::endl); _status = GameStatus::player0Turn; _featSize = {2, HEIGHT, WIDTH}; _features.resize(_featSize[0] * _featSize[1] * _featSize[2], 0); fillFullFeatures(); _actionSize = {1, HEIGHT, WIDTH}; _stochastic = true; _board.fill(UNKNOWN); _boardSample.fill(UNKNOWN); _legalActions.clear(); fillLegalActions(_legalActions, _board, std::vector()); MINESWEEPER_DEBUG(debug(std::cout) << "Num legal actions: " << _legalActions.size() << std::endl); _hash = boardHash(); } // State::Initialize virtual std::unique_ptr clone_() const override { return std::make_unique>(*this); } // State::clone_ virtual void ApplyAction(const _Action& action) override { MINESWEEPER_DEBUG(debug(std::cout) << "ApplyAction" << std::endl); assert(_status == GameStatus::player0Turn); assert(!_legalActions.empty()); int row = action.GetY(); int col = action.GetZ(); assert((isInBoard(row, col))); sampleMines(_minesSample, _board, _rng, row, col); minesToBoard(_minesSample, _boardSample); applyActionToSampledBoard(row, col); _hash = boardHash(); } // State::ApplyAction virtual void DoGoodAction() override { assert(!_legalActions.empty()); if (isFirstMove(_board)) { MINESWEEPER_DEBUG(debug(std::cout) << "Apply Random Action" << ", rng=\"" << _rng << "\"" << std::endl); DoRandomAction(); return; } using CspStrategy = csp::vkms::CspStrategy; CspStrategy cspStrategy; cspStrategy.computeMineProbabilitiesAndSampleMines( _minesSample, _board, _rng); // greedy choice of the best location to probe using MineProbas = std::array; const MineProbas& mineProbas = cspStrategy.getMineProbabilities(); MINESWEEPER_DEBUG( debug(std::cout) << "Mine probabilities:" << std::endl; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { std::cout << setw(10) << arrGet( mineProbas, row, col); } std::cout << std::endl; }); int row = -1, row_i; int col = -1, col_i; float proba = 1.0, probaMin = -1.0; for (size_t i = 0; i < _legalActions.size(); i++) { row_i = _legalActions[i].GetY(); col_i = _legalActions[i].GetZ(); proba = arrGet( mineProbas, row_i, col_i); if ((proba < probaMin) || (probaMin < 0)) { probaMin = proba; row = row_i; col = col_i; } } minesToBoard(_minesSample, _boardSample); applyActionToSampledBoard(row, col); } // State::ApplyAction /** * Expects action in format "r,c", where r and c are row and column * of a cell to be probed. The coordinates must be non-negative integers * that do not exceed board size. Action validity is performed */ virtual int parseAction(const std::string& str) const override { int row = -1; int col = -1; char c = 0; std::istringstream iss(str); iss >> c; if (!iss.good() || (c != '(')) { return -1; } iss >> row; if (!iss.good() || (row < 0) || (row >= static_cast(HEIGHT))) { return -1; } iss >> c; if (!iss.good() || (c != ',')) { return -1; } iss >> col; if (!iss.good() || (col < 0) || (col >= static_cast(WIDTH))) { return -1; } if (!(iss.good() || iss.eof()) || (c != ')')) { return -1; } for (size_t i = 0; i < _legalActions.size(); i++) { if ((_legalActions[i].GetY() == row) && (_legalActions[i].GetZ() == col)) { return (int)i; } } return -1; } // State::parseAction virtual bool isOnePlayerGame() const override { return true; } std::array getMineProbas() { using CspStrategy = csp::vkms::CspStrategy; CspStrategy cspStrategy; cspStrategy.computeMineProbabilitiesAndSampleMines( _minesSample, _board, _rng); using MineProbas = std::array; const MineProbas& mineProbas = cspStrategy.getMineProbabilities(); return mineProbas; } /* * -1 means "unknown, could be a mine" * k >=0 means "k mines in the neighborhood" */ virtual std::string stateDescription() const override { std::string boardStr = _GameDefs::boardToString(_board); return boardStr; } // State::stateDescription private: void applyActionToSampledBoard(int row, int col) { MINESWEEPER_DEBUG(displayBoard("Current board:", _board)); MINESWEEPER_DEBUG(displayBoard("Sampled board:", _boardSample)); MINESWEEPER_DEBUG(checkConsistency(_boardSample, _board)); MINESWEEPER_DEBUG(debug(std::cout) << "Probe: row=" << row << ", col=" << col << ": "); int value = arrGet(_boardSample, row, col); if (value == BOOM) { MINESWEEPER_DEBUG(std::cout << "BOOM!" << std::endl); _status = GameStatus::player1Win; _legalActions.clear(); fillFeatures(_features, _board); fillFullFeatures(); return; } arrGet(_board, row, col) = value; MINESWEEPER_DEBUG(std::cout << "value=" << value << std::endl); #ifdef EXPAND_ZEROS if (!value) { expandZeros(_board, _boardSample, row, col); MINESWEEPER_DEBUG(debug(std::cout) << "Expanded zeros" << std::endl); MINESWEEPER_DEBUG(displayBoard("Current board:", _board)); } #endif if (done()) { MINESWEEPER_DEBUG(debug(std::cout) << "Done." << std::endl); _status = GameStatus::player0Win; _legalActions.clear(); fillFeatures(_features, _board); fillFullFeatures(); return; } using CspStrategy = csp::vkms::CspStrategy; CspStrategy cspStrategy; auto forSureMines = cspStrategy.locateForSureMines(_board); _legalActions.clear(); if (_status == GameStatus::player0Turn) { fillLegalActions(_legalActions, _board, forSureMines); MINESWEEPER_DEBUG(debug(std::cout) << "Num legal actions: " << _legalActions.size() << std::endl); } fillFeatures(_features, _board); fillFullFeatures(); } void expandZeros(Board& board, const Board& boardSample, int row, int col) { int value = arrGet(board, row, col); assert(!value); _expandZerosProcessedMask.zero(); auto select_unprocessed = [this](int UNUSED(v), int row, int col) { return !this->_expandZerosProcessedMask.get(row, col); }; std::list queue; int idx = rowColToIdx(row, col); queue.push_back(idx); _expandZerosProcessedMask.set(row, col); while (!queue.empty()) { idx = queue.front(); queue.pop_front(); idxToRowCol(idx, row, col); auto neighborPositions = _GameDefs::getNeighbors(board, row, col, select_unprocessed); for (const auto& pos : neighborPositions) { value = arrGet(boardSample, pos.row(), pos.col()); arrGet(board, pos.row(), pos.col()) = value; if (!value) { idx = rowColToIdx(pos.row(), pos.col()); queue.push_back(idx); _expandZerosProcessedMask.set(pos.row(), pos.col()); } } } } // expandZeros template void sampleMines(Mines& minesSample, const Board& board, RngEngine& rng, int row, int col) { int probeIdx = rowColToIdx(row, col); MINESWEEPER_DEBUG(debug(std::cout) << "Is first move? " << (isFirstMove(board) ? "yes" : "no") << std::endl); if (isFirstMove(board)) { MINESWEEPER_DEBUG(debug(std::cout) << "Sample mines uniformly " << "without duplicates" << std::endl); std::vector cellIndices(HEIGHT * WIDTH); for (size_t i = 0; i < HEIGHT * WIDTH; ++i) { cellIndices[i] = i; } std::swap(cellIndices[0], cellIndices[probeIdx]); for (size_t i = 0; i < MINES; ++i) { std::uniform_int_distribution distribution( i + 1, cellIndices.size() - 1); size_t varIdx = distribution(rng); minesSample[i] = cellIndices[varIdx]; std::swap(cellIndices[i + 1], cellIndices[varIdx]); } std::sort(minesSample.begin(), minesSample.end()); } else { // do CSP sampling MINESWEEPER_DEBUG(debug(std::cout) << "Sample mines with CSP: " << std::endl); using CspStrategy = csp::vkms::CspStrategy; CspStrategy cspStrategy; cspStrategy.sampleMines(minesSample, board, rng); } MINESWEEPER_DEBUG(displayMines("Sampled mines:", minesSample)); checkMinesSample(minesSample); } // sampleMines static bool isFirstMove(const Board& board) { size_t unknown = 0; for (size_t k = 0; k < HEIGHT * WIDTH; ++k) { if (board[k] == UNKNOWN) { ++unknown; } } return (unknown == HEIGHT * WIDTH); } // shouldDoRejectionSampling static bool hasDuplicates(const Mines& mines) { for (size_t k = 1; k < MINES; ++k) { if (mines[k - 1] == mines[k]) { return true; } } return false; } // hasDuplicates /** * Check that mine indices are valid and are in srtrictly ascending order */ static void checkMinesSample(Mines& minesSample) { #ifndef NDEBUG int prevMineIdx = -1; for (int mineIdx : minesSample) { assert(mineIdx >= 0); assert(mineIdx < static_cast(HEIGHT * WIDTH)); assert(mineIdx > prevMineIdx); prevMineIdx = mineIdx; } #endif } // checkMinesSample /** * Check that sampled board complies with the current board */ static void checkConsistency(const Board& boardSample, const Board& board) { for (size_t i = 0; i < WIDTH * HEIGHT; ++i) { if (board[i] != UNKNOWN) { assert(boardSample[i] == board[i]); } } } // checkConsistency void minesToBoard(const Mines& mines, Board& board) { memset(board.data(), 0, WIDTH * HEIGHT * sizeof(int)); int idx, row, col; for (size_t i = 0; i < NUM_NEIGHBORS; ++i) { for (size_t j = 0; j < MINES; ++j) { idx = mines[j]; idxToRowCol(idx, row, col); idx += _minesToBoardDeltaIdx[i]; row += _minesToBoardDeltaRow[i]; col += _minesToBoardDeltaCol[i]; if ((row >= 0) && (row < static_cast(HEIGHT)) && (col >= 0) && (col < static_cast(WIDTH))) { board[idx]++; } } } for (size_t j = 0; j < MINES; ++j) { board[mines[j]] = BOOM; } } // minesToBoard static void fillLegalActions(std::vector<::_Action>& legalActions, const Board& board, #ifdef FLAG_MINES const std::vector& forSureMines #else const std::vector& UNUSED(forSureMines) #endif ) { legalActions.reserve(HEIGHT * WIDTH); auto k = 0; auto n = 0; for (size_t row = 0; row < HEIGHT; ++row) { for (size_t col = 0; col < WIDTH; ++col) { if (board[k++] == UNKNOWN) { ::_Action act = Act(0, 0, row, col); #ifdef FLAG_MINES if (std::binary_search( forSureMines.begin(), forSureMines.end(), /*Minesweeper::template*/ rowColToIdx(row, col))) { continue; } #endif act.SetIndex(n++); legalActions.push_back(act); } } } } // fillLegalActions static void fillFeatures(std::vector& features, const Board& board) { for (size_t k = 0; k < HEIGHT * WIDTH; ++k) { features[k] = board[k]; features[HEIGHT * WIDTH + k] = (board[k] < 0 ? 1 : 0); } } // fillFeatures static void displayBoard(const std::string& title, const Board& board) { std::cout << title << std::endl; std::string boardStr = _GameDefs::boardToString(board); std::cout << boardStr; } // displayBoard static void displayMines(const std::string& title, const Mines& mines) { std::cout << title << std::endl; std::string minesStr = _GameDefs::minesToString(mines); std::cout << minesStr << std::endl; } // displayMines static bool boardAllUnknown(const Board& board) { for (size_t k = 0; k < HEIGHT * WIDTH; ++k) { if (board[k] != UNKNOWN) { return false; } } return true; } // boardAllUnknown bool done() const { size_t nUnknown = 0; for (size_t k = 0; k < HEIGHT * WIDTH; ++k) { if (_board[k] == UNKNOWN) { ++nUnknown; } } return (nUnknown == MINES); } // done uint64_t boardHash() { _hasher.reset(); int v; for (unsigned i = 0; i < _board.size(); ++i) { v = _board[i] + 2; assert(v >= 0); _hasher.trigger(static_cast(v) * WIDTH * HEIGHT + i); } return _hasher.hash(); } // boardHash Board _board; Board _boardSample; Mines _minesSample; _Mask _expandZerosProcessedMask; static constexpr Neighbors _minesToBoardDeltaIdx = NeighborOffsets::dindices; static constexpr Neighbors _minesToBoardDeltaRow = NeighborOffsets::drow; static constexpr Neighbors _minesToBoardDeltaCol = NeighborOffsets::dcol; static std::once_flag hashBookConfigured; static _HashBook hashBook; _Hasher _hasher; }; // class State template std::once_flag State::hashBookConfigured; template typename State::_HashBook State::hashBook; } // namespace Minesweeper ================================================ FILE: src/games/minishogi.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author1: Maria Elsa // - Github: https://github.com/melsaa // - Email: m_elsa@ymail.com // Author2: Lin Hsin-I // - Github: https://github.com/free00000000000 // - Email: 410521233@gms.ndhu.edu.tw // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #pragma once #include "../core/state.h" #include "shogi.h" #include #include #include #include template class StateForMinishogi : public core::State, public Shogi { public: static inline uint64_t HashArray[2][10][Dx][Dy]; static inline uint64_t HashArrayJail[20]; static inline uint64_t HashTurn; int length; std::array checkCount; struct Repetition { uint64_t hash; char count; int lastStepIdx; }; std::array, 16> repetitions; int repeatCount; StateForMinishogi(int seed) : State(seed) , Shogi() { } virtual void Initialize() override { _moves.clear(); // _hash = 2166136261u; _hash = 0; _status = GameStatus::player0Turn; _featSize[0] = 217; if (version == 2) { _featSize[0] = (6 + 4 + 6) * 2 + 3; // (6 pieces + 4 promoted + 6 off board // (counts)) * 2 + 3 repeat counts } _featSize[1] = Dy; _featSize[2] = Dx; _actionSize[0] = 19; // 11 pieces + 8 promoted if (version == 2) { _actionSize[0] = 6 + 6; } _actionSize[1] = Dy; _actionSize[2] = Dx; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); gameInit(); static std::once_flag initFlag; std::call_once(initFlag, initHash); findFeature(); findActions(); fillFullFeatures(); } void gameInit() { chess.clear(); chess.resize(2); for (int i = 0; i < Dx; ++i) for (int j = 0; j < Dy; ++j) board[i][j] = Piece(); for (int i = 0; i < Dx; ++i) { board[i][0] = Piece(White, PieceType(i + 1), false, Position(i, 0)); chess[White].push_back(board[i][0]); } board[0][1] = Piece(White, PieceType::Pawn, false, Position(0, 1)); chess[White].push_back(board[0][1]); for (int i = 1; i <= Dx; ++i) { int x = Dx - i; board[x][4] = Piece(Black, PieceType(i), false, Position(x, 4)); chess[Black].push_back(board[x][4]); } board[4][3] = Piece(Black, PieceType::Pawn, false, Position(4, 3)); chess[Black].push_back(board[4][3]); length = 0; _hash = 0; checkCount = {0, 0}; for (auto& v : repetitions) { v.clear(); } repetitions[_hash % repetitions.size()].push_back({_hash, 1, 0}); repeatCount = 0; } static void initHash() { std::mt19937_64 rng( std::random_device{}() ^ std::chrono::steady_clock::now().time_since_epoch().count()); rng.discard(1024); for (int a = 0; a < 2; ++a) for (int b = 0; b < 10; ++b) for (int c = 0; c < 5; ++c) for (int d = 0; d < 5; ++d) { HashArray[a][b][c][d] = rng(); } for (int a = 0; a < 20; ++a) { HashArrayJail[a] = rng(); } HashTurn = rng(); } void findFeature() { if (version == 2) { std::fill(_features.begin(), _features.end(), 0); for (auto& v : chess) { for (const Piece& p : v) { if (p.pos.on_board()) { int x = p.pos.x; int y = p.pos.y; size_t offset = y * Dx + x; size_t index = (int)p.type - 1; if (p.color == Black) { index += 6 + 4; } _features[offset + Dx * Dy * index] = 1.0f; if (p.promoted) { index = 6 + (int)p.type - 3; if (p.color == Black) { index += 6 + 4; } _features[offset + Dx * Dy * index] = 1.0f; } } else { size_t index = (6 + 4) * 2 + (int)p.type - 1; if (p.color == Black) { index += 6; } size_t begin = Dx * Dy * index; size_t end = Dx * Dy * (index + 1); for (size_t i = begin; i != end; ++i) { _features[i] += 1.0f; } } } } if (repeatCount) { size_t index = (6 + 4 + 6) * 2; index += std::max(std::min(repeatCount, 3), 1) - 1; size_t begin = Dx * Dy * index; size_t end = Dx * Dy * (index + 1); for (size_t i = begin; i != end; ++i) { _features[i] += 1.0f; } } return; } std::vector old(_features); for (int i = 0; i < 5425; ++i) _features[i] = 0; // 0 ~ 500 for (int i = 0; i < 25; ++i) { Piece p = board[i % 5][i / 5]; if (p.color == White) { switch (p.type) { case PieceType::King: _features[i] = 1; break; case PieceType::Gold: case PieceType::Gold2: _features[25 + i] = 1; break; case PieceType::Silver: case PieceType::Silver2: if (p.promoted) _features[50 + i] = 1; else _features[75 + i] = 1; break; case PieceType::Bishop: case PieceType::Bishop2: if (p.promoted) _features[100 + i] = 1; else _features[125 + i] = 1; break; case PieceType::Rook: case PieceType::Rook2: if (p.promoted) _features[150 + i] = 1; else _features[175 + i] = 1; break; case PieceType::Pawn: case PieceType::Pawn2: if (p.promoted) _features[200 + i] = 1; else _features[225 + i] = 1; break; default: break; } } else { switch (p.type) { case PieceType::King: _features[250 + i] = 1; break; case PieceType::Gold: case PieceType::Gold2: _features[275 + i] = 1; break; case PieceType::Silver: case PieceType::Silver2: if (p.promoted) _features[300 + i] = 1; else _features[325 + i] = 1; break; case PieceType::Bishop: case PieceType::Bishop2: if (p.promoted) _features[350 + i] = 1; else _features[375 + i] = 1; break; case PieceType::Rook: case PieceType::Rook2: if (p.promoted) _features[400 + i] = 1; else _features[425 + i] = 1; break; case PieceType::Pawn: case PieceType::Pawn2: if (p.promoted) _features[450 + i] = 1; else _features[475 + i] = 1; break; default: break; } } } // // 500 ~ 575 // switch (repeat) { // case 1: // std::fill(_features.begin() + 500, _features.begin() + 525, 1); // break; // case 5: // std::fill(_features.begin() + 525, _features.begin() + 550, 1); // break; // case 9: // std::fill(_features.begin() + 550, _features.begin() + 575, 1); // break; // default: // break; // } // prison w 575 ~ 625 // prison b 625 ~ 675 int tmp = 575; for (int i = 0; i < 2; ++i) { std::vector::iterator it; for (it = chess[i].begin(); it != chess[i].end(); ++it) { if (!(*it).pos.on_board()) { switch ((*it).type) { case PieceType::Gold: std::fill(_features.begin() + tmp, _features.begin() + tmp + 5, 1); break; case PieceType::Silver: std::fill( _features.begin() + tmp + 5, _features.begin() + tmp + 10, 1); break; case PieceType::Bishop: std::fill( _features.begin() + tmp + 10, _features.begin() + tmp + 15, 1); break; case PieceType::Rook: std::fill( _features.begin() + tmp + 15, _features.begin() + tmp + 20, 1); break; case PieceType::Pawn: std::fill( _features.begin() + tmp + 20, _features.begin() + tmp + 25, 1); break; case PieceType::Gold2: std::fill( _features.begin() + tmp + 25, _features.begin() + tmp + 30, 1); break; case PieceType::Silver2: std::fill( _features.begin() + tmp + 30, _features.begin() + tmp + 35, 1); break; case PieceType::Bishop2: std::fill( _features.begin() + tmp + 35, _features.begin() + tmp + 40, 1); break; case PieceType::Rook2: std::fill( _features.begin() + tmp + 40, _features.begin() + tmp + 45, 1); break; case PieceType::Pawn2: std::fill( _features.begin() + tmp + 45, _features.begin() + tmp + 50, 1); break; default: break; } } } tmp += 50; } // history 675 ~ 4725+675 std::copy(old.begin(), old.begin() + 4725, _features.begin() + 675); // 5400 ~ 5425 std::fill(_features.begin() + 5400, _features.end(), (int)_status); } std::vector moves; void findActions() { moves.clear(); auto& list = chess[(int)_status]; for (size_t i = 0; i != list.size(); ++i) { const Piece& p = list[i]; if (!p.pos.on_board()) { bool duplicate = false; for (size_t i2 = 0; i2 != i; ++i2) { const Piece& p2 = list[i2]; if (p2.type == p.type && !p2.pos.on_board()) { duplicate = true; break; } } if (duplicate) { continue; } } legalMoves(p, moves); } int i = 0; clearActions(); for (auto m : moves) { m.piece.promoted = m.promote; if (version == 2) { addAction((int)m.piece.type - 1 + (m.piece.pos.on_board() ? 0 : 6), m.next.y, m.next.x); } else { int x = m.next.x; int y = m.next.y; int z = type_to_z(m.piece); addAction(z, x, y); } i++; } } virtual void printCurrentBoard() const override { std::cerr << stateDescription() << "\n"; } std::string print_chess(const int color) const { std::string str; if (color == White) str += "MiniWhite: "; else str += "MiniBlack: "; for (auto i : chess[color]) { if (!i.pos.on_board()) { str += '('; str += i.print(); str += ')'; } else str += i.print(); str += ' '; } str += '\n'; return str; } virtual std::string stateDescription() const override { std::string str; str += " A| B| C| D| E\n"; for (int i = Dy - 1; i >= 0; --i) { str += std::to_string(i + 1) + ' '; for (int j = 0; j < Dx; ++j) { if (j > 0) { str += '|'; } auto x = board[j][i].print(); if (x.size() == 1) { str += ' '; } str += x; } str += '\n'; } str += print_chess(White); str += print_chess(Black); return str; } virtual std::string actionDescription(const _Action& action) const { const Move& move = moves.at(action.GetIndex()); const Piece& p = move.piece; bool disy = false; bool disx = false; if (p.pos.on_board()) { for (const Move& m : moves) { if ((m.piece.type == p.type || new_type(m.piece.type) == p.type) && m.piece.promoted == p.promoted && m.piece.pos.on_board() && m.piece.pos != p.pos && m.next == move.next) { if (m.piece.pos.x == p.pos.x) { disy = true; } else { disx = true; } } } } std::string s = p.print(); for (auto& v : s) { v = std::toupper(v); } if (s == "P") { if (p.pos.on_board() && board[move.next.x][move.next.y].color == Empty) { s = ""; } } if (disx) { s += char('a' + p.pos.x); } if (disy) { s += std::to_string(1 + p.pos.y); } if (board[move.next.x][move.next.y].color != Empty) { s += 'x'; } else if (!p.pos.on_board()) { s += '@'; } s += 'a' + move.next.x; s += std::to_string(1 + move.next.y); if (move.promote) { s += '+'; } return s; } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } int getHashNum(Piece p) { int num = (int)p.type; if (num >= 7) num -= 5; if (p.promoted) num += 5; // 7 8 9 10 11 // 1 2 3 4 5 6 | 7 8 9 10 num -= 1; return num; } int getHashNumjail(Piece p) { // 0~19 return (int)p.type - 2 + 10 * p.color; } void play(Move m) { if (m.piece.pos.on_board()) { _hash ^= HashArray[m.piece.color][getHashNum(m.piece)][m.piece.pos.x] [m.piece.pos.y]; m.piece.promoted |= m.promote; // eat if (board[m.next.x][m.next.y].color != Empty) { int opp = opponent(m.piece.color); _hash ^= HashArray[opp][getHashNum(board[m.next.x][m.next.y])][m.next.x] [m.next.y]; auto type = board[m.next.x][m.next.y].type; if (version == 1) { type = new_type(type); } Piece tmp(m.piece.color, type, false); chess[m.piece.color].push_back(tmp); _hash ^= HashArrayJail[getHashNumjail(tmp)]; bool found = false; std::vector::iterator it; for (it = chess[opp].begin(); it != chess[opp].end(); ++it) { if (it->pos == m.next) { chess[opp].erase(it); found = true; break; } } if (!found) throw std::runtime_error("Could not find piece to erase"); } std::vector::iterator it; bool found = false; for (it = chess[m.piece.color].begin(); it != chess[m.piece.color].end(); ++it) { if ((*it).pos == m.piece.pos) { (*it).pos = m.next; // decide promoted if (m.piece.promoted) { (*it).promoted = true; } found = true; board[m.next.x][m.next.y] = (*it); board[m.piece.pos.x][m.piece.pos.y] = Piece(); break; } } if (!found) { throw std::runtime_error("could not find piece to move"); } } else { // Drop move _hash ^= HashArrayJail[getHashNumjail(m.piece)]; std::vector::iterator it; for (it = chess[m.piece.color].begin(); it != chess[m.piece.color].end(); ++it) { if ((*it).type == m.piece.type && !it->pos.on_board()) { (*it).pos = m.next; board[m.next.x][m.next.y] = (*it); break; } } } _hash ^= HashArray[m.piece.color][getHashNum(board[m.next.x][m.next.y])] [m.next.x][m.next.y]; _hash ^= HashTurn; if (length < MaxPlayoutLength) { // rollout[length] = m; length++; } else { // set draw when the moves bigger than 1000 _status = GameStatus::tie; } for (auto i : chess[opponent(m.piece.color)]) { if (i.type == PieceType::King) { if (check(i.pos, m.piece.color)) { ++checkCount.at(m.piece.color); } else { checkCount.at(m.piece.color) = 0; } break; } } // find repeat repeatCount = 0; bool found = false; size_t index = _hash % repetitions.size(); for (auto& v : repetitions[index]) { if (v.hash == _hash) { ++v.count; repeatCount = v.count; int repetitionLength = _moves.size() - v.lastStepIdx; v.lastStepIdx = _moves.size(); if (v.count >= 4) { // sennichite if (checkCount[Black] * 2 >= repetitionLength) { _status = GameStatus::player0Win; } else { _status = GameStatus::player1Win; } } found = true; break; } } if (!found) { repetitions[index].push_back({_hash, 1, (int)_moves.size()}); } } virtual void ApplyAction(const _Action& action) override { play(moves.at(action.GetIndex())); if (_status == GameStatus::player0Turn || _status == GameStatus::player1Turn) { _status = _status == GameStatus::player0Turn ? GameStatus::player1Turn : GameStatus::player0Turn; findActions(); if (moves.empty()) { _status = _status == GameStatus::player1Turn ? GameStatus::player0Win : GameStatus::player1Win; } } if (_status == GameStatus::player0Turn || _status == GameStatus::player1Turn) { findFeature(); fillFullFeatures(); } else { clearActions(); } } virtual void DoGoodAction() override { return DoRandomAction(); } }; ================================================ FILE: src/games/mnkgame.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 林鈺錦 (Yù-Jǐn Lín) // - Github: https://github.com/abc1236762 // - Email: abc1236762@outlook.com #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "../core/state.h" #include "commons/chessboard.h" #include "commons/player.h" namespace MNKGame { class ChessKind { public: static constexpr Chess empty = 0; static constexpr Chess black = 1; static constexpr Chess white = 2; }; struct Move { Chess chess; int x, y; }; template class State : public core::State { static_assert(M > 0 && N > 0 && K > 0, "m, n, and k must be greater then 0"); static_assert(K <= M || K <= N, "k must be less than or equal to m or n"); public: using Board = Chessboard; State(int seed); void Initialize() override; std::unique_ptr clone_() const override; void ApplyAction(const ::_Action& action) override; void DoGoodAction() override; void printCurrentBoard() const override; std::string stateDescription() const override; std::string actionDescription(const ::_Action& action) const override; std::string actionsDescription() const override; int parseAction(const std::string& str) const override; int humanInputAction( std::function(std::string)> specialAction) override; private: template static void setupBoard(const RE& re); static constexpr Player chessToPlayer(Chess chess); static constexpr Chess playerToChess(Player player); virtual void play(const Move& move); std::optional findWinner(const Move& move); bool isConnected(const Move& move); virtual void findLegalActions(); inline Player getCurrentPlayer(); inline void turnPlayer(); inline void setTerminatedStatus(Player winner); void fillFeatures(); static constexpr int chessKinds = 2; static constexpr int connections = K; static constexpr int maxLegalActionsCnt = Board::squares; static constexpr std::tuple directions[4] = { {0, 1}, {1, -1}, {1, 0}, {1, 1}}; static inline std::once_flag setupCalled; Board board; std::bitset areEmpty; }; template State::State(int seed) : core::State(seed) { std::call_once(setupCalled, [&] { setupBoard(_rng); }); } template void State::Initialize() { _moves.clear(); _featSize = {chessKinds, Board::rows, Board::columns}; _features.resize(chessKinds * Board::squares); _actionSize = {1, Board::rows, Board::columns}; _legalActions.reserve(maxLegalActionsCnt); _status = GameStatus::player0Turn; board.initialize(); areEmpty.set(); _hash = board.getHash(); findLegalActions(); fillFeatures(); } template std::unique_ptr State::clone_() const { return std::make_unique(*this); } template void State::ApplyAction(const ::_Action& action) { Move move{}; move.chess = playerToChess(getCurrentPlayer()); move.x = action.GetY(); move.y = action.GetZ(); play(move); board.turnHash(); _hash = board.getHash(); if (auto hasWinner = findWinner(move); !hasWinner) { turnPlayer(); findLegalActions(); fillFeatures(); } else { setTerminatedStatus(hasWinner.value()); } } template void State::DoGoodAction() { DoRandomAction(); } template void State::printCurrentBoard() const { std::cout << board.sprint(" "); } template std::string State::stateDescription() const { return board.sprint(" "); } template std::string State::actionDescription(const ::_Action& action) const { std::ostringstream oss; oss << "put a chess at " << board.getPosStr(action.GetY(), action.GetZ()); return oss.str(); } template std::string State::actionsDescription() const { std::set> markedPos; for (auto& legalAction : _legalActions) markedPos.insert({legalAction.GetY(), legalAction.GetZ()}); return board.sprintBoard(" ", markedPos); } template int State::parseAction(const std::string& str) const { auto result = board.parsePosStr(str); if (!result) return -1; auto [x, y] = result.value(); int i = 0; for (auto& legalAction : _legalActions) { if (legalAction.GetY() == x && legalAction.GetZ() == y) return i; i++; } return -1; } template int State::humanInputAction( std::function(std::string)> specialAction) { std::cout << "Current board:" << std::endl << stateDescription() << std::endl; std::cout << "Allowed positions: ('" << Board::getMarkSymbol() << "' means an allowed position)" << std::endl << actionsDescription() << std::endl; std::cout << "Input a position to play: (uses format " << ", e.g. `A1`, `b2`, `C03`...)" << std::endl; std::string str; int index = -1; while (index < 0) { std::cout << "> "; std::getline(std::cin, str); index = parseAction(str); if (index < 0) { if (auto r = specialAction(str); r) return *r; std::cout << "invalid input, try again." << std::endl; } } return index; } template template void State::setupBoard(const RE& re) { Board::setup({"Empty", "Black", "White"}, {" ", "●", "○"}, re); } template constexpr Player State::chessToPlayer(Chess chess) { if (chess == ChessKind::black) return Player::first; else if (chess == ChessKind::white) return Player::second; assert(chess == ChessKind::black || chess == ChessKind::white); return Player::none; } template constexpr Chess State::playerToChess(Player player) { if (player == Player::first) return ChessKind::black; else if (player == Player::second) return ChessKind::white; assert(player == Player::first || player == Player::second); return ChessKind::empty; } template void State::play(const Move& move) { board.setChess(move.x, move.y, move.chess); areEmpty.reset(Board::posTo1D(move.x, move.y)); } template std::optional State::findWinner(const Move& move) { if (isConnected(move)) return chessToPlayer(move.chess); else if (areEmpty.none()) return Player::none; return std::nullopt; } template bool State::isConnected(const Move& move) { if (connections == 1) return true; auto areChessesEnough = [&](int& count, int dx, int dy) { int x = move.x + dx, y = move.y + dy; while (Board::isPosInBoard(x, y)) { if (board.getChess(x, y) == move.chess) { if (++count == connections) return true; } else { return false; } x += dx, y += dy; } return false; }; for (auto [dx, dy] : directions) { int count = 1; if (areChessesEnough(count, dx, dy) || areChessesEnough(count, -dx, -dy)) return true; } return false; } template void State::findLegalActions() { clearActions(); for (int xy = 0; xy < Board::squares; xy++) { if (areEmpty[xy]) { auto [x, y] = Board::posTo2D(xy); addAction(0, x, y); assert(_legalActions.size() <= maxLegalActionsCnt); } } } template Player State::getCurrentPlayer() { if (_status == GameStatus::player0Turn) return Player::first; else if (_status == GameStatus::player1Turn) return Player::second; assert(_status == GameStatus::player0Turn || _status == GameStatus::player1Turn); return Player::none; } template void State::turnPlayer() { if (_status == GameStatus::player0Turn) _status = GameStatus::player1Turn; else if (_status == GameStatus::player1Turn) _status = GameStatus::player0Turn; assert(_status == GameStatus::player0Turn || _status == GameStatus::player1Turn); } template void State::setTerminatedStatus(Player winner) { if (winner == Player::first) _status = GameStatus::player0Win; else if (winner == Player::second) _status = GameStatus::player1Win; else _status = GameStatus::tie; } template void State::fillFeatures() { std::fill(_features.begin(), _features.end(), 0.0); auto* f = _features.data(); for (int c = 0; c < chessKinds; c++) { Chess chess = static_cast(c + 1); for (int xy = 0; xy < Board::squares; xy++, f++) if (board.getChess(xy) == chess) *f = 1.0; } fillFullFeatures(); } } // namespace MNKGame ================================================ FILE: src/games/nogo_action.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "nogo_action.h" NoGoAction::NoGoAction(PLAYER player, Position position) { Set(player, position); } void NoGoAction::Set(PLAYER player, Position position) { SetPlayer(player); SetPosition(position); } void NoGoAction::SetPosition(Position position) { position_ = position; } Position NoGoAction::GetPosition() const { return position_; } bool NoGoAction::operator==(const NoGoAction& rhs) { return ((GetPlayer() == rhs.GetPlayer()) && (position_ == rhs.position_)); } bool NoGoAction::operator!=(const NoGoAction& rhs) { return !(*this == rhs); } int NoGoAction::x() const { return position_ / kNOGO_BOARD_SIZE; } int NoGoAction::y() const { return position_ % kNOGO_BOARD_SIZE; } std::string NoGoAction::ToString() { return ToGTPString(true); } std::string NoGoAction::ToGTPString(bool with_color) const { std::ostringstream oss; if (with_color) { if (GetPlayer() == PLAYER_0) { oss << "B("; } else { oss << "W("; } } oss << (char)(y() + 'A' + (y() >= 8)) << (char)(kNOGO_BOARD_SIZE - x() - 1 + '1'); if (with_color) { oss << ")"; } return oss.str(); } std::string NoGoAction::ToSgfString(bool with_color) const { std::ostringstream oss; if (with_color) { if (GetPlayer() == PLAYER_0) { oss << "B["; } else { oss << "W["; } } if (GetPlayer() == PLAYER_NULL || GetPosition() == kNOGO_GRIDS_NUM) { oss << "tt"; } else { oss << (char)(y() + 'a') << (char)(x() + 'a'); } if (with_color) { oss << "]"; } return oss.str(); } void NoGoAction::Rotate(SYMMETRYTYPE type) { Point point(position_); point.ToSymmetryOf(type); position_ = point.GetPosition(); } ================================================ FILE: src/games/nogo_action.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "game_action.h" #include "game_player.h" #include "nogo_position.h" #include #include #include class NoGoAction : public GameAction { private: PLAYER player_; Position position_; public: NoGoAction(PLAYER player = PLAYER_NULL, Position position = kNOGO_GRIDS_NUM); PLAYER GetPlayer() const { return player_; } Position GetPosition() const; void SetPlayer(PLAYER player) { player_ = player; } bool IsIllegalAction() const { return player_ == PLAYER_NULL; } void Set(PLAYER player, Position position); void SetPosition(Position position); bool operator==(const NoGoAction& rhs); bool operator!=(const NoGoAction& rhs); int x() const; int y() const; std::string ToString(); std::string ToGTPString(bool with_color = false) const; std::string ToSgfString(bool with_color = false) const; void Rotate(SYMMETRYTYPE type); int GetID() { return position_; } void SetID(int id) { position_ = id; } }; #include "nogo_action.cc" ================================================ FILE: src/games/nogo_bitboard.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #ifndef CZF_NOGO_NOGO_BITBOARD_H_ #define CZF_NOGO_NOGO_BITBOARD_H_ #include "nogo_position.h" class NoGoBitBoard { static const long long kMASK_55 = 0x5555555555555555ULL; static const long long kMASK_33 = 0x3333333333333333ULL; static const long long kMASK_0F = 0x0f0f0f0f0f0f0f0fULL; static const long long kMASK_01 = 0x0101010101010101ULL; static const long long kMASK_00FF = 0x00ff00ff00ff00ffULL; static const long long kMASK_0000FFFF = 0x0000ffff0000ffffULL; static const long long kMASK_00000000FFFFFFFF = 0x00000000ffffffffULL; static const long long kMASK_FFFFFFFFFFFFFFFF = 0xffffffffffffffffULL; long long bitboard_[(kNOGO_GRIDS_NUM / 64) + 1]; public: NoGoBitBoard() { Reset(); } void Reset() { bitboard_[0] = 0; bitboard_[1] = 0; } NoGoBitBoard& operator=(const NoGoBitBoard& rhs) { bitboard_[0] = rhs.bitboard_[0]; bitboard_[1] = rhs.bitboard_[1]; return *this; } int Count() const { unsigned long long v, v1; v = (bitboard_[0] & kMASK_55) + ((bitboard_[0] >> 1) & kMASK_55); v1 = (bitboard_[1] & kMASK_55) + ((bitboard_[1] >> 1) & kMASK_55); v = (v & kMASK_33) + ((v >> 2) & kMASK_33); v1 = (v1 & kMASK_33) + ((v1 >> 2) & kMASK_33); v += v1; v = (v & kMASK_0F) + ((v >> 4) & kMASK_0F); v = (v & kMASK_00FF) + ((v >> 8) & kMASK_00FF); v = (v & kMASK_0000FFFF) + ((v >> 16) & kMASK_0000FFFF); return (int)((v & kMASK_00000000FFFFFFFF) + (v >> 32)); } bool GetPosition(int i) const { return (bitboard_[i >> 6] & (1LL << (i & 63))) != 0; } void DeletePosition(int i) { bitboard_[i >> 6] &= ~(1LL << (i & 63)); } void AddPosition(int i) { bitboard_[i >> 6] |= (1LL << (i & 63)); } void operator|=(NoGoBitBoard rhs) { bitboard_[0] |= rhs.bitboard_[0]; bitboard_[1] |= rhs.bitboard_[1]; return; } bool Isempty() const { return (bitboard_[0] == 0) && (bitboard_[1] == 0); } bool CheckIsOne() const { if (bitboard_[0] == 0) { return (bitboard_[1] != 0) && ((bitboard_[1] ^ ((-bitboard_[1]) & (bitboard_[1]))) == 0); } else if (bitboard_[1] == 0) { return (bitboard_[0] ^ ((-bitboard_[0]) & (bitboard_[0]))) == 0; } return false; } }; #endif // CZF_NOGO_NOGO_BITBOARD_H_ ================================================ FILE: src/games/nogo_game.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "nogo_game.h" NoGoGame::NoGoGame() { Reset(); } NoGoGame::~NoGoGame() { ; } bool NoGoGame::PlayAction(Action action) { if (is_terminal_) return false; if (!state_.IsLegalAction(action)) { is_terminal_ = true; win_player_ = !turn_player_; return false; } history_.push_back(action); turn_player_ = !action.GetPlayer(); state_.PlayAction(action); return true; } NoGoGame& NoGoGame::operator=(const NoGoGame& rhs) { history_ = rhs.history_; turn_player_ = rhs.turn_player_; state_ = rhs.state_; is_terminal_ = rhs.is_terminal_; win_player_ = rhs.win_player_; return *this; } NoGoState NoGoGame::GetNoGoState() { return state_; } std::vector NoGoGame::GetLegalActions() { std::vector legal_actions; for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { if (state_.IsLegalAction(turn_player_, i)) { legal_actions.push_back(Action(turn_player_, i)); } } return legal_actions; } std::vector NoGoGame::GetIsLegalAction() { std::vector is_legal(kNOGO_GRIDS_NUM, false); for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { if (IsLegalAction(Action(turn_player_, i))) { is_legal[i] = true; } } return is_legal; } bool NoGoGame::IsTerminalState() { if (is_terminal_) return true; for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { if (state_.IsLegalAction(turn_player_, i)) return false; } win_player_ = !turn_player_; is_terminal_ = true; return true; } NoGoBitBoard NoGoGame::GetIllegalBitBoard() { NoGoBitBoard bitBoard; for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { if (!state_.IsLegalAction(turn_player_, i)) { bitBoard.AddPosition(i); } } return bitBoard; } bool NoGoGame::IsLegalAction(Action action) { return state_.IsLegalAction(action); } bool NoGoGame::IsLegalAction(PLAYER player, Position position) { return state_.IsLegalAction(player, position); } bool NoGoGame::IsLegalAction(Position position) { return state_.IsLegalAction(turn_player_, position); } PLAYER NoGoGame::GetPositionPlayer(Position position) { return state_.GetPlayer(position); } void NoGoGame::ShowState() { if (GetTurnPlayer() == PLAYER_0) std::cerr << "PLAYER 0\n"; if (GetTurnPlayer() == PLAYER_1) std::cerr << "PLAYER 1\n"; state_.ShowBoard(); } std::string NoGoGame::ShowBoard() { return state_.ToString(); } std::string NoGoGame::GetGtpResultString() { if (!IsTerminalState()) { return "0"; } if (GetTurnPlayer() == PLAYER_0) { return "W+R"; } else { return "B+R"; } } std::string NoGoGame::ToSgfFilePrefix(std::string player0, std::string player1, std::string event_name = "") { std::ostringstream oss; oss << "(;FF[4]CA[UTF-8]SZ[" << kNOGO_BOARD_SIZE << "]" << "KM[0]" << "EV[" << event_name << "]" << "PB[" << player0 << "]" << "PW[" << player1 << "]" << "RE[" << GetGtpResultString() << "]"; return oss.str(); } std::string NoGoGame::ToMoveString(bool with_semicolon = false) { std::ostringstream oss; for (size_t i = 0; i < history_.size(); i++) { if (with_semicolon) oss << ";"; oss << history_[i].ToSgfString(with_semicolon); } return oss.str(); } std::string NoGoGame::ToMoveString(bool with_semicolon, bool with_comments, std::vector& comments) { std::ostringstream oss; for (size_t i = 0; i < history_.size(); i++) { if (with_semicolon) oss << ";"; oss << history_[i].ToSgfString(with_semicolon); if (with_comments) oss << "C[" << comments[i] << "]"; } return oss.str(); } std::string NoGoGame::ToSgfFileString(std::string player0, std::string player1, std::string event_name, bool with_semicolon = false) { std::ostringstream oss; oss << ToSgfFilePrefix(player0, player1, event_name) << ToMoveString(with_semicolon) << ")"; return oss.str(); } std::string NoGoGame::ToSgfFileString(std::string player0, std::string player1, std::string event_name, bool with_semicolon, bool with_comments, std::vector& comments) { std::ostringstream oss; oss << ToSgfFilePrefix(player0, player1, event_name) << ToMoveString(with_semicolon, with_comments, comments) << ")"; return oss.str(); } ================================================ FILE: src/games/nogo_game.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "game_base.h" #include "nogo_action.h" #include "nogo_state.h" #include #include class NoGoGame : public GameBase { public: NoGoGame(); ~NoGoGame(); NoGoGame& operator=(const NoGoGame& rhs); bool IsTerminalState() override; bool IsLegalAction(Action action) override; std::vector GetLegalActions() override; std::vector GetIsLegalAction() override; bool PlayAction(Action action) override; NoGoBitBoard GetIllegalBitBoard(); NoGoState GetNoGoState(); PLAYER GetPositionPlayer(Position position); bool IsLegalAction(PLAYER player, Position position); bool IsLegalAction(Position position); void ShowState(); std::string ShowBoard(); std::string GetGtpResultString(); std::string ToSgfFilePrefix(std::string player0, std::string player1, std::string sEventName); std::string ToMoveString(bool with_semicolon); std::string ToMoveString(bool with_semicolon, bool with_comments, std::vector& comments); std::string ToSgfFileString(std::string player0, std::string player1, std::string sEventName, bool with_semicolon); std::string ToSgfFileString(std::string player0, std::string player1, std::string sEventName, bool with_semicolon, bool with_comments, std::vector& comments); }; #include "nogo_game.cc" ================================================ FILE: src/games/nogo_position.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #ifndef CZF_NOGO_NOGO_POSITION_H_ #define CZF_NOGO_NOGO_POSITION_H_ #include #include #include const int kNOGO_BOARD_SIZE = 9; const int kNOGO_GRIDS_NUM = kNOGO_BOARD_SIZE * kNOGO_BOARD_SIZE; typedef int Position; // just for represent X and Y and do some symmetric enum SYMMETRYTYPE { SYM_NORMAL, SYM_ROTATE_90, SYM_ROTATE_180, SYM_ROTATE_270, SYM_HORIZONTAL_REFLECTION, SYM_HORIZONTAL_REFLECTION_ROTATE_90, SYM_HORIZONTAL_REFLECTION_ROTATE_180, SYM_HORIZONTAL_REFLECTION_ROTATE_270, SYMMETRY_SIZE }; namespace symmetry { const std::vector kSYMMETRY_LIST{ SYM_NORMAL, SYM_ROTATE_90, SYM_ROTATE_180, SYM_ROTATE_270, SYM_HORIZONTAL_REFLECTION, SYM_HORIZONTAL_REFLECTION_ROTATE_90, SYM_HORIZONTAL_REFLECTION_ROTATE_180, SYM_HORIZONTAL_REFLECTION_ROTATE_270}; const std::string kSYMMETRY_TYPE_STRING[SYMMETRY_SIZE] = { "SYM_NORMAL", "SYM_ROTATE_90", "SYM_ROTATE_180", "SYM_ROTATE_270", "SYM_HORIZONTAL_REFLECTION", "SYM_HORIZONTAL_REFLECTION_ROTATE_90", "SYM_HORIZONTAL_REFLECTION_ROTATE_180", "SYM_HORIZONTAL_REFLECTION_ROTATE_270"}; inline std::string GetSymmetryTypeString(SYMMETRYTYPE type) { return kSYMMETRY_TYPE_STRING[type]; } inline SYMMETRYTYPE GetSymmetryType(std::string sType) { for (int i = 0; i < SYMMETRY_SIZE; i++) { if (sType == kSYMMETRY_TYPE_STRING[i]) { return static_cast(i); } } return SYMMETRY_SIZE; } const SYMMETRYTYPE kREVERSE_SYMMETRIC_TYPE[SYMMETRY_SIZE] = { SYM_NORMAL, SYM_ROTATE_270, SYM_ROTATE_180, SYM_ROTATE_90, SYM_HORIZONTAL_REFLECTION, SYM_HORIZONTAL_REFLECTION_ROTATE_90, SYM_HORIZONTAL_REFLECTION_ROTATE_180, SYM_HORIZONTAL_REFLECTION_ROTATE_270}; } // namespace symmetry class Point { public: int x_; int y_; Point() { ; } Point(int x, int y) { x_ = x; y_ = y; } Point(const Position p) { x_ = p % kNOGO_BOARD_SIZE; y_ = p / kNOGO_BOARD_SIZE; } inline bool operator==(const Point& rhs) const { return (x_ == rhs.x_ && y_ == rhs.y_) ? true : false; } inline bool operator!=(const Point& rhs) const { return !(*this == rhs); } Point& operator=(const Point& rhs) { x_ = rhs.x_; y_ = rhs.y_; return *this; } Point& operator=(const Position& rhs) { *this = Point(rhs); return *this; } inline Position GetPosition() { return y_ * kNOGO_BOARD_SIZE + x_; } inline void ToSymmetryOf(SYMMETRYTYPE type) { /* symmetric radius pattern: ( ChangeXY x*(-1) y*(-1) ) 0 NORMAL : 1 ROTATE_90 : ChangeXY y*(-1) 2 ROTATE_180 : x*(-1) y*(-1) 3 ROTATE_270 : ChangeXY x*(-1) 4 HORIZONTAL_REFLECTION : x*(-1) 5 HORIZONTAL_REFLECTION_ROTATE_90 : ChangeXY 6 HORIZONTAL_REFLECTION_ROTATE_180 : y*(-1) 7 HORIZONTAL_REFLECTION_ROTATE_270 : ChangeXY x*(-1) y*(-1) */ Shift(); switch (type) { case SYM_NORMAL: break; case SYM_ROTATE_90: ChangeXY(); MinusY(); break; case SYM_ROTATE_180: MinusX(); MinusY(); break; case SYM_ROTATE_270: ChangeXY(); MinusX(); break; case SYM_HORIZONTAL_REFLECTION: MinusX(); break; case SYM_HORIZONTAL_REFLECTION_ROTATE_90: ChangeXY(); break; case SYM_HORIZONTAL_REFLECTION_ROTATE_180: MinusY(); break; case SYM_HORIZONTAL_REFLECTION_ROTATE_270: ChangeXY(); MinusX(); MinusY(); break; default: // should not be here assert(false); } ShiftBack(); return; } private: inline void MinusX() { x_ = -x_; } inline void MinusY() { y_ = -y_; } inline void ChangeXY() { int tmp = x_; x_ = y_; y_ = tmp; } inline void Shift() { int center = kNOGO_BOARD_SIZE / 2; x_ -= center; y_ -= center; } inline void ShiftBack() { int center = kNOGO_BOARD_SIZE / 2; x_ += center; y_ += center; } }; #endif // CZF_NOGO_NOGO_POSITION_H_ ================================================ FILE: src/games/nogo_state.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "nogo_state.h" #include NoGoState::NoGoState() { InitNeighborList(); Reset(); } void NoGoState::Reset() { for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { parent_[i] = i; liberty_[i].Reset(); } bm_board_[PLAYER_0].Reset(); illegal_[PLAYER_0].Reset(); warning_[PLAYER_0].Reset(); bm_board_[PLAYER_1].Reset(); illegal_[PLAYER_1].Reset(); warning_[PLAYER_1].Reset(); liberty_is_one_.Reset(); } bool NoGoState::PlayAction(NoGoAction action) { PLAYER player = action.GetPlayer(); Position position = action.GetPosition(); if (!IsLegalAction(player, position)) { return false; } illegal_[PLAYER_0].AddPosition(position); illegal_[PLAYER_1].AddPosition(position); bm_board_[player].AddPosition(position); Position parent_position = position; NoGoBitBoard parent_new_liberty; for (size_t i = 0; i < neighbor_list_[position].size(); i++) { Position neighbor = neighbor_list_[position][i]; if (bm_board_[player].GetPosition(neighbor)) { Position parent_of_neighbor = FindParent(neighbor); parent_new_liberty |= liberty_[parent_of_neighbor]; if (parent_position < parent_of_neighbor) // unite { parent_[parent_of_neighbor] = parent_position; } else { parent_[parent_position] = parent_of_neighbor; parent_position = parent_of_neighbor; } } else if (bm_board_[!player].GetPosition(neighbor)) { Position parent_of_neighbor = FindParent(neighbor); liberty_[parent_of_neighbor].DeletePosition(position); if (liberty_[parent_of_neighbor].CheckIsOne()) { liberty_is_one_.AddPosition(parent_of_neighbor); illegal_[player] |= liberty_[parent_of_neighbor]; warning_[!player] |= liberty_[parent_of_neighbor]; } } else { warning_[!player].AddPosition(neighbor); parent_new_liberty.AddPosition(neighbor); } } parent_new_liberty.DeletePosition(position); liberty_[parent_position] = parent_new_liberty; if (parent_new_liberty.CheckIsOne()) { liberty_is_one_.AddPosition(parent_position); illegal_[!player] |= parent_new_liberty; warning_[player] |= parent_new_liberty; } else { liberty_is_one_.DeletePosition(parent_position); } return true; } NoGoState& NoGoState::operator=(const NoGoState& rhs) { for (int i = 0; i < 2; i++) // two players { bm_board_[i] = rhs.bm_board_[i]; illegal_[i] = rhs.illegal_[i]; warning_[i] = rhs.warning_[i]; } for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { parent_[i] = rhs.parent_[i]; liberty_[i] = rhs.liberty_[i]; } liberty_is_one_ = rhs.liberty_is_one_; return *this; } void NoGoState::Rotate(SYMMETRYTYPE type) { std::vector action_list; for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { PLAYER player = GetPlayer(i); if (player == PLAYER_NULL) continue; Point point((Position)i); point.ToSymmetryOf(type); action_list.push_back(NoGoAction(player, point.GetPosition())); } Reset(); for (size_t i = 0; i < action_list.size(); i++) { PlayAction(action_list[i]); } } PLAYER NoGoState::GetPlayer(Position position) const { if (bm_board_[PLAYER_0].GetPosition(position)) return PLAYER_0; if (bm_board_[PLAYER_1].GetPosition(position)) return PLAYER_1; return PLAYER_NULL; } bool NoGoState::IsLegalAction(PLAYER player, Position position) { if (player == PLAYER_NULL) return false; if (illegal_[player].GetPosition(position)) return false; else if (!warning_[player].GetPosition(position)) return true; warning_[player].DeletePosition(position); // start check warning (is the action a suicide action) for (size_t i = 0; i < neighbor_list_[position].size(); i++) { Position neighbor = neighbor_list_[position][i]; if (bm_board_[player].GetPosition(neighbor)) { if (!liberty_is_one_.GetPosition(FindParent(neighbor))) return true; } else if (!bm_board_[!player].GetPosition(neighbor)) // have liberty { return true; } } illegal_[player].AddPosition(position); return false; } bool NoGoState::IsLegalAction(NoGoAction action) { return IsLegalAction(action.GetPlayer(), action.GetPosition()); } void NoGoState::ShowBoard() const { std::cerr << ToString() << std::endl; } void NoGoState::ShowLegalMove(PLAYER turn_player) { for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { PLAYER player = GetPlayer(i); if (player == PLAYER_0) std::cerr << '@'; if (player == PLAYER_1) std::cerr << 'O'; if (player == PLAYER_NULL) { if (IsLegalAction(turn_player, i)) { std::cerr << "#"; } else { std::cerr << "."; } } if (i % kNOGO_BOARD_SIZE == kNOGO_BOARD_SIZE - 1) std::cerr << '\n'; } } std::string NoGoState::ToString() const { std::ostringstream oss; for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { PLAYER player = GetPlayer(i); if (player == PLAYER_0) oss << '@'; if (player == PLAYER_1) oss << 'O'; if (player == PLAYER_NULL) oss << '.'; if (i % kNOGO_BOARD_SIZE == kNOGO_BOARD_SIZE - 1) oss << '\n'; } return oss.str(); } void NoGoState::PrintNeighborNum() const { for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { std::cerr << neighbor_list_[i].size() << ' '; if (i % kNOGO_BOARD_SIZE == kNOGO_BOARD_SIZE - 1) std::cerr << '\n'; } } void NoGoState::PrintLiberty() { for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { if (!bm_board_[0].GetPosition(i) && !bm_board_[1].GetPosition(i)) { std::cerr << ".\t"; } else if (FindParent(i) == i) { std::cerr << liberty_[i].Count() << '\t'; } else { std::cerr << "0\t"; } if (i % kNOGO_BOARD_SIZE == kNOGO_BOARD_SIZE - 1) std::cerr << '\n'; } } void NoGoState::PrintLibertyIsOne(bool check_again) { for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { if (!bm_board_[0].GetPosition(i) && !bm_board_[1].GetPosition(i)) { std::cerr << ".\t"; } else if (FindParent(i) == i) { if (check_again) { std::cerr << liberty_[i].CheckIsOne() << '\t'; if (liberty_[i].CheckIsOne()) liberty_is_one_.AddPosition(i); else liberty_is_one_.DeletePosition(i); } else { std::cerr << liberty_is_one_.GetPosition(i) << '\t'; } } else { std::cerr << "0\t"; } if (i % kNOGO_BOARD_SIZE == kNOGO_BOARD_SIZE - 1) std::cerr << '\n'; } } void NoGoState::PrintParent() { for (int i = 0; i < kNOGO_GRIDS_NUM; i++) { if (!bm_board_[0].GetPosition(i) && !bm_board_[1].GetPosition(i)) { std::cerr << ".\t"; } else { std::cerr << FindParent(i) << '\t'; } if (i % kNOGO_BOARD_SIZE == kNOGO_BOARD_SIZE - 1) std::cerr << '\n'; } } Position NoGoState::FindParent(Position position) { Position& parent_position = parent_[position]; if (parent_position == parent_[parent_position]) return parent_position; return parent_position = FindParent(parent_position); } void NoGoState::InitNeighborList() { for (int i = 0; i < kNOGO_BOARD_SIZE; i++) { for (int j = 0; j < kNOGO_BOARD_SIZE; j++) { int position = i * kNOGO_BOARD_SIZE + j; if (i > 0) neighbor_list_[position].push_back(position - kNOGO_BOARD_SIZE); if (j > 0) neighbor_list_[position].push_back(position - 1); if (i < kNOGO_BOARD_SIZE - 1) neighbor_list_[position].push_back(position + kNOGO_BOARD_SIZE); if (j < kNOGO_BOARD_SIZE - 1) neighbor_list_[position].push_back(position + 1); } } } ================================================ FILE: src/games/nogo_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "game_state.h" #include "nogo_action.h" #include "nogo_bitboard.h" #include class NoGoState : public GameState { private: NoGoBitBoard bm_board_[2]; std::vector neighbor_list_[kNOGO_GRIDS_NUM]; Position parent_[kNOGO_GRIDS_NUM]; NoGoBitBoard liberty_[kNOGO_GRIDS_NUM]; NoGoBitBoard illegal_[2]; NoGoBitBoard warning_[2]; // might be suicide NoGoBitBoard liberty_is_one_; public: NoGoState(); void Reset(); bool PlayAction(NoGoAction action); // return success or not NoGoState& operator=(const NoGoState& rhs); void Rotate(SYMMETRYTYPE type); PLAYER GetPlayer(Position position) const; bool IsLegalAction(NoGoAction action); bool IsLegalAction(PLAYER player, Position position); void ShowBoard() const; void ShowLegalMove(PLAYER turn_player); std::string ToString() const; void PrintNeighborNum() const; void PrintLiberty(); void PrintLibertyIsOne(bool check_again = false); void PrintParent(); private: Position FindParent(Position p); void InitNeighborList(); }; #include "nogo_state.cc" ================================================ FILE: src/games/nogo_zestate.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "game.h" typedef unsigned short Coord; #include "nogo_game.h" #include "nogo_state.h" #include "time.h" #include #include #include #include //#include "base/common.h" //#include "breakthrough.h" class StateForNogo : public State { public: StateForNogo() : State() { Initialize(); _history = 0; _outFeatures = false; } virtual ~StateForNogo() { } virtual void Initialize() override { // People implementing classes should not have much to do in _moves; just // _moves.clear(). _moves.clear(); _featSize[0] = 3; _featSize[1] = 9; _featSize[2] = 9; // size of the output of the neural network; this should cover the positions // of actions (above). _actionSize[0] = 1; _actionSize[1] = 9; _actionSize[2] = 9; // _hash is an unsigned int, it has to be *unique*. _hash = 0; _nogoGame.Reset(); _status = GameStatus::player0Turn; // std::cout << "restart!" << std::endl; // _features is a vector representing the current state. It can // (must...) be large for complex games; here just one number // between 0 and 1. trivial case in dimension 1. _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); for (int i = 0; i < _features.size(); i++) _features[i] = 0.; clearActions(); for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) { addAction(0, i, j); } fillFullFeatures(); } virtual std::unique_ptr clone() const override { auto newState = std::make_unique(); *newState = *this; return newState; } // The action just decreases the distance and swaps the turn to play. virtual void ApplyAction(const _Action& action) override { assert(_status != GameStatus::player0Win); assert(_status != GameStatus::player1Win); NoGoAction nogoAction(_nogoGame.GetTurnPlayer(), action.GetHash()); if (_nogoGame.GetTurnPlayer() == PLAYER_0) { _features[action.GetHash()] = 1.; for (int i = 0; i < 81; i++) _features[81 * 2 + i] = 1.; } else { _features[9 * 9 + action.GetHash()] = 1.; for (int i = 0; i < 81; i++) _features[81 * 2 + i] = 0.; } if (!_nogoGame.IsLegalAction(nogoAction)) { // if (true) { std::cerr << " before move" << std::endl; _nogoGame.ShowState(); std::cerr << " the proposed action " << nogoAction.ToString() << " is legal ? " << _nogoGame.IsLegalAction(nogoAction) << std::endl; _nogoGame.PlayAction(nogoAction); std::cerr << " after move" << std::endl; _nogoGame.ShowState(); /*assert(false);*/ } else { _nogoGame.PlayAction(nogoAction); } // let us remove the nogoAction from legal actions clearActions(); auto legal_actions = _nogoGame.GetLegalActions(); int index = 0; for (const auto& action : legal_actions) { addAction(0, action.GetPosition() % 9, action.GetPosition() / 9); } // _nogoGame.ShowState(); // std::cerr << " number of legal actions : " << _legalActions.size() << // std::endl; // first channel: black stones. // second channel: white stones. // third channel: 0 if player black to play, 1 otherwise. // assert(false); if (_legalActions.size() == 0) { // if (_nogoGame.IsTerminalState()) { assert(_nogoGame.IsTerminalState()); if (_status == GameStatus::player0Turn) _status = GameStatus::player0Win; else _status = GameStatus::player1Win; // _nogoGame.ShowState(); assert((_status == GameStatus::player0Win) == (_nogoGame.GetWinPlayer() == PLAYER_0)); assert((_status == GameStatus::player1Win) == (_nogoGame.GetWinPlayer() == PLAYER_1)); } else { if (_status == GameStatus::player0Turn) _status = GameStatus::player1Turn; else _status = GameStatus::player0Turn; } assert(_status == GameStatus::player1Win || _status == GameStatus::player0Win || _legalActions.size() > 0); // std::cerr << " play 0 wins:" << (_status == GameStatus::player0Win) // << std::endl; // std::cerr << " play 1 wins:" << (_status == GameStatus::player1Win) // << std::endl; fillFullFeatures(); } // For this trivial example we just compare to random play. Ok, this is not // really a good action. // By the way we need a good default DoGoodAction, e.g. one-ply at least. // FIXME virtual void DoGoodAction() override { int i = rand() % _legalActions.size(); _Action a = *(_legalActions[i].get()); ApplyAction(a); } private: NoGoGame _nogoGame; }; ================================================ FILE: src/games/othello.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: 林鈺錦 (Yù-Jǐn Lín) // - Github: https://github.com/abc1236762 // - Email: abc1236762@outlook.com // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "../core/state.h" #include "commons/chessboard.h" #include "commons/player.h" namespace Othello { class ChessKind { public: static constexpr Chess empty = 0; static constexpr Chess black = 1; static constexpr Chess white = 2; }; struct Move { Chess chess; int x, y; }; template class State : public core::State { static_assert(BR >= 4 && BR % 2 == 0, "radix of board must be greater than or equal to 4 and even"); public: using Board = Chessboard; State(int seed); void Initialize() override; std::unique_ptr clone_() const override; void ApplyAction(const ::_Action& action) override; void DoGoodAction() override; void printCurrentBoard() const override; std::string stateDescription() const override; std::string actionDescription(const ::_Action& action) const override; std::string actionsDescription() const override; int parseAction(const std::string& str) const override; int humanInputAction( std::function(std::string)> specialAction) override; private: template static void setupBoard(const R& re); static constexpr Player chessToPlayer(Chess chess); static constexpr Chess playerToChess(Player player); void setInitialChesses(); void play(const Move& move); bool canGoNext(Player nextPlayer, bool isPassMove); Player findWinner(); void findLegalActions(Player player); int countReverseChesses(const Move& move, int dx, int dy); bool canDoReverse(const Move& move); void doReverse(const Move& move); inline Player getCurrentPlayer(); inline Player turnPlayer(); inline void setTerminatedStatus(Player winner); void fillFeatures(); static constexpr int players = 2; static constexpr int chessKinds = 2; static constexpr int maxLegalActionsCnt = Board::squares - 4; static constexpr std::tuple directions[8] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; static constexpr std::tuple initialChessesPos[players][chessKinds] = {{{Board::rows / 2 - 1, Board::columns / 2}, {Board::rows / 2, Board::columns / 2 - 1}}, {{Board::rows / 2 - 1, Board::columns / 2 - 1}, {Board::rows / 2, Board::columns / 2}}}; static inline std::once_flag setupCalled; Board board; std::bitset areEmpty, candi; }; // template class Action : public ::_Action { // public: // Action(int i, int x, int y, bool isPassMove); //}; template State
::State(int seed) : core::State(seed) { std::call_once(setupCalled, [&] { setupBoard(_rng); }); } template void State
::Initialize() { _moves.clear(); _featSize = {chessKinds, Board::rows, Board::columns}; _features.resize(chessKinds * Board::squares); _actionSize = {2, Board::rows, Board::columns}; _legalActions.reserve(maxLegalActionsCnt); _status = GameStatus::player0Turn; board.initialize(); areEmpty.set(); candi.reset(); setInitialChesses(); _hash = board.getHash(); findLegalActions(Player::first); fillFeatures(); } template std::unique_ptr State
::clone_() const { return std::make_unique(*this); } template void State
::ApplyAction(const ::_Action& action) { bool isPassMove = action.GetX(); if (!isPassMove) { Move move{}; move.chess = playerToChess(getCurrentPlayer()); move.x = action.GetY(); move.y = action.GetZ(); play(move); } board.turnHash(); _hash = board.getHash(); Player nextPlayer = turnPlayer(); if (canGoNext(nextPlayer, isPassMove)) { if (_legalActions.size() == 0) { _legalActions.emplace_back( _legalActions.size(), 1, Board::rows / 2, Board::columns / 2); } fillFeatures(); } else { Player winner = findWinner(); setTerminatedStatus(winner); _legalActions.clear(); } } template void State
::DoGoodAction() { DoRandomAction(); } template void State
::printCurrentBoard() const { std::cout << board.sprint(" "); } template std::string State
::stateDescription() const { return board.sprint(" "); } template std::string State
::actionDescription(const ::_Action& action) const { bool isPassMove = (bool)action.GetX(); if (isPassMove) return "passed"; std::ostringstream oss; oss << board.getPosStr(action.GetY(), action.GetZ()); return oss.str(); } template std::string State
::actionsDescription() const { std::set> markedPos; if (_legalActions.size() >= 1 && _legalActions[0].GetX() == 0) for (auto& legalAction : _legalActions) markedPos.insert({legalAction.GetY(), legalAction.GetZ()}); return board.sprintBoard(" ", markedPos); } template int State
::parseAction(const std::string& str) const { if (_legalActions.size() == 1 && _legalActions[0].GetX() == 1) return 0; auto result = board.parsePosStr(str); if (!result) return -1; auto [x, y] = result.value(); int i = 0; for (auto& legalAction : _legalActions) { if (legalAction.GetY() == x && legalAction.GetZ() == y) return i; i++; } return -1; } template int State
::humanInputAction( std::function(std::string)> specialAction) { std::cout << "Current board:" << std::endl << stateDescription() << std::endl; if (_legalActions.size() == 1 && _legalActions[0].GetX() == 1) { std::cout << "No positions to play." << std::endl; std::cout << "Input nothing to pass." << std::endl; } else { std::cout << "Allowed positions: ('" << Board::getMarkSymbol() << "' means an allowed position)" << std::endl << actionsDescription() << std::endl; std::cout << "Input a position to play: (uses format " << ", e.g. `A1`, `b2`, `C03`...)" << std::endl; } std::string str; int index = -1; while (index < 0) { std::cout << "Input action: "; std::getline(std::cin, str); index = parseAction(str); if (index < 0) { if (auto r = specialAction(str); r) return *r; std::cout << "invalid input, try again." << std::endl; } } return index; } template template void State
::setupBoard(const R& re) { Board::setup({"Empty", "Black", "White"}, {" ", "●", "○"}, re); } template constexpr Player State
::chessToPlayer(Chess chess) { if (chess == ChessKind::black) return Player::first; else if (chess == ChessKind::white) return Player::second; assert(chess == ChessKind::black || chess == ChessKind::white); return Player::none; } template constexpr Chess State
::playerToChess(Player player) { if (player == Player::first) return ChessKind::black; else if (player == Player::second) return ChessKind::white; assert(player == Player::first || player == Player::second); return ChessKind::empty; } template void State
::setInitialChesses() { for (int p = 0; p < players; p++) { Chess chess = playerToChess(Player::set(p)); for (auto [x, y] : initialChessesPos[p]) { board.setChess(x, y, chess); areEmpty.reset(Board::posTo1D(x, y)); } } for (int y = Board::columns / 2 - 2; y < Board::columns / 2 + 2; y++) for (int x = Board::rows / 2 - 2; x < Board::rows / 2 + 2; x++) candi.set(Board::posTo1D(x, y)); } template void State
::play(const Move& move) { board.setChess(move.x, move.y, move.chess); areEmpty.reset(Board::posTo1D(move.x, move.y)); doReverse(move); } template bool State
::canGoNext(Player nextPlayer, bool isPassMove) { if (areEmpty.none()) return false; findLegalActions(nextPlayer); return _legalActions.size() != 0 || !isPassMove; } template Player State
::findWinner() { auto counts = board.countChesses(); if (counts[ChessKind::black] > counts[ChessKind::white]) return Player::first; else if (counts[ChessKind::black] < counts[ChessKind::white]) return Player::second; return Player::none; } template void State
::findLegalActions(Player player) { _legalActions.clear(); auto possibles = areEmpty & candi; Chess chess = playerToChess(player); int i = 0; for (int xy = 0; xy < Board::squares; xy++) { if (possibles[xy]) { auto [x, y] = Board::posTo2D(xy); Move legalMove = Move{chess, x, y}; if (canDoReverse(legalMove)) { _legalActions.emplace_back(i++, 0, legalMove.x, legalMove.y); assert(i <= maxLegalActionsCnt); } } } } template int State
::countReverseChesses(const Move& move, int dx, int dy) { int x = move.x + dx, y = move.y + dy, chessCnt = 0; while (Board::isPosInBoard(x, y)) { if (Chess chess = board.getChess(x, y); chess == ChessKind::empty) return 0; else if (chess != move.chess) chessCnt++; else return chessCnt; x += dx, y += dy; } return 0; } template bool State
::canDoReverse(const Move& move) { for (auto [dx, dy] : directions) if (countReverseChesses(move, dx, dy) > 0) return true; return false; } template void State
::doReverse(const Move& move) { for (auto [dx, dy] : directions) { int x = move.x + dx, y = move.y + dy; if (Board::isPosInBoard(x, y)) { candi.set(Board::posTo1D(x, y)); int chessCnt = countReverseChesses(move, dx, dy); for (int j = 0; j < chessCnt; j++) { board.setChess(x, y, move.chess); x += dx, y += dy; } } } } template Player State
::getCurrentPlayer() { if (_status == GameStatus::player0Turn) return Player::first; else if (_status == GameStatus::player1Turn) return Player::second; assert(_status == GameStatus::player0Turn || _status == GameStatus::player1Turn); return Player::none; } template Player State
::turnPlayer() { if (_status == GameStatus::player0Turn) { _status = GameStatus::player1Turn; return Player::second; } else if (_status == GameStatus::player1Turn) { _status = GameStatus::player0Turn; return Player::first; } assert(_status == GameStatus::player0Turn || _status == GameStatus::player1Turn); return Player::none; } template void State
::setTerminatedStatus(Player winner) { if (winner == Player::first) _status = GameStatus::player0Win; else if (winner == Player::second) _status = GameStatus::player1Win; else _status = GameStatus::tie; } template void State
::fillFeatures() { std::fill(_features.begin(), _features.end(), 0.0); auto* f = _features.data(); for (int c = 0; c < chessKinds; c++) { Chess chess = static_cast(c + 1); for (int xy = 0; xy < Board::squares; xy++, f++) if (board.getChess(xy) == chess) *f = 1.0; } fillFullFeatures(); } // template // Action
::Action(int i, int x, int y, bool isPassMove) // : ::_Action() { // _i = i; // _loc = {isPassMove, x, y}; // _hash = // isPassMove ? State
::Board::squares : State
::Board::rows * y + x; //} } // namespace Othello ================================================ FILE: src/games/othello_opt.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include "othello_opt.h" //#define OTHELLO_DEBUG(arg) #define OTHELLO_DEBUG(arg) arg namespace Othello2 { static constexpr size_t NUM_NEIGHBORS = 8; static constexpr std::array DROW = {-1, -1, -1, 0, 0, 1, 1, 1}; static constexpr std::array DCOL = {-1, 0, 1, -1, 1, -1, 0, 1}; static constexpr char BOARD_COORD_SMALL_LETTERS[] = "abcdefghijkmnopqrstuvwxyz"; static constexpr char BOARD_COORD_CAPITAL_LETTERS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; template static constexpr bool isInBoard(int row, int col) { return (row >= 0) && (col >= 0) && (row < static_cast(SIZE)) && (col < static_cast(SIZE)); } // isInBoard template static typename Array::reference arrGet(Array& arr, size_t row, size_t col) { return arr[row * SIZE + col]; } // arrGet template static typename Array::const_reference arrGet(const Array& arr, size_t row, size_t col) { return arr[row * SIZE + col]; } // arrGet template State::State(int seed) : core::State(seed) , _hasher(hashBook) { std::call_once(hashBookConfigured, [this]() { hashBook.setup(_rng); }); } // State::State template /* virtual */ void State::Initialize() { _status = GameStatus::player0Turn; initializeBoard(); initializeHasher(); initializeCache(); _featSize = {NUM_PIECE_TYPES, SIZE, SIZE}; _features.resize(NUM_PIECE_TYPES * SIZE * SIZE, 0); fillFeatures(); fillFullFeatures(); _actionSize = {NUM_PIECE_TYPES, SIZE, SIZE}; _legalActions.reserve(SIZE * SIZE - 4); RefillLegalActions(); _hash = _hasher.hash(); } // State::Initialize template /* virtual */ std::unique_ptr State::clone_() const { return std::make_unique(*this); } // State::clone_ template /* virtual */ void State::ApplyAction(const ::_Action& action) { assert((_status == GameStatus::player0Turn) || (_status == GameStatus::player1Turn)); auto stone = stoneToPlay(); bool skipTurn = (action.GetX() != 0); if (skipTurn) { // assert(!CanPutStone(stone)); nextTurn(); stone = stoneToPlay(); if (!CanPutStone(stone)) { _legalActions.clear(); setTerminalStatus(); } else { RefillLegalActions(); fillFeatures(); fillFullFeatures(); _hash = _hasher.hash(); } return; } int col = action.GetY(); int row = action.GetZ(); PutStone(stone, row, col); if (boardFilled()) { setTerminalStatus(); return; } nextTurn(); RefillLegalActions(); fillFeatures(); fillFullFeatures(); _hash = _hasher.hash(); } // State::ApplyAction template /* virtual */ void State::DoGoodAction() { DoRandomAction(); } template /* virtual */ void State::printCurrentBoard() const { std::cout << boardToString() << std::endl; } // State::printCurrentBoard template std::string State::boardToString() const { static constexpr bool SHOW_BOARD_COORDS = SIZE < sizeof(BOARD_COORD_CAPITAL_LETTERS); // static constexpr bool SHOW_BOARD_COORDS = false; std::ostringstream oss; if (SHOW_BOARD_COORDS) { oss << std::setfill(' ') << std::setw(SIZE / 10 + 1) << ' ' << " "; oss << std::string(BOARD_COORD_CAPITAL_LETTERS, SIZE) << std::endl; oss << std::setfill(' ') << std::setw(SIZE / 10 + 1) << ' ' << " "; oss << std::string(SIZE, '-') << std::endl; } for (size_t row = 0; row < SIZE; ++row) { if (SHOW_BOARD_COORDS) { oss << std::setfill(' ') << std::setw(SIZE / 10 + 1) << SIZE - row << " |"; } for (size_t col = 0; col < SIZE; ++col) { switch (arrGet(_board, row, col)) { case EMPTY: oss << EMPTY_STR; break; case BLACK: oss << BLACK_STR; break; case WHITE: oss << WHITE_STR; break; default: oss << '?'; } } if (SHOW_BOARD_COORDS) { oss << "| " << std::setfill(' ') << std::setw(SIZE / 10 + 1) << SIZE - row; } oss << std::endl; } if (SHOW_BOARD_COORDS) { oss << std::setfill(' ') << std::setw(SIZE / 10 + 1) << ' ' << " "; oss << std::string(SIZE, '-') << std::endl; oss << std::setfill(' ') << std::setw(SIZE / 10 + 1) << ' ' << " "; oss << std::string(BOARD_COORD_CAPITAL_LETTERS, SIZE) << std::endl; } return oss.str(); } // State::boardToString template bool State::CanPutStone(Field stone) const { for (size_t row = 0; row < SIZE; ++row) { for (size_t col = 0; col < SIZE; ++col) { if (CanPutStone(stone, row, col)) { return true; } } } return false; } // State::CanPutStone template bool State::CanPutStone(Field stone, size_t row, size_t col) const { Field field = arrGet(_board, row, col); if ((field != EMPTY) || !arrGet(_cache, row, col)) { return false; } size_t count; int dr, dc, r, c; for (size_t i = 0; i < NUM_NEIGHBORS; ++i) { count = 0; r = static_cast(row); c = static_cast(col); dr = DROW[i]; dc = DCOL[i]; while (isInBoard(r + dr, c + dc)) { field = arrGet(_board, r + dr, c + dc); if (field == EMPTY) { break; } else if (field != stone) { // opponent piece ++count; } else if (!count) { // our piece straight after the location break; } else { // our piece after a number of opponent pieces return true; } r += dr; c += dc; } } return false; } // State::CanPutStone template void State::PutStone(Field stone, size_t row, size_t col) { assert(isInBoard(row, col)); // assert(CanPutStone(stone, row, col)); const size_t myHashOffset = (stone == BLACK ? HASH_BLACK_OFFSET : HASH_WHITE_OFFSET); const size_t theirHashOffset = (stone == BLACK ? HASH_WHITE_OFFSET : HASH_BLACK_OFFSET); Field field; size_t count; int dr, dc, r, c; bool isInside; arrGet(_board, row, col) = stone; _hasher.trigger(SIZE * row + col); _hasher.trigger(myHashOffset + SIZE * row + col); for (size_t i = 0; i < NUM_NEIGHBORS; ++i) { count = 0; r = static_cast(row); c = static_cast(col); dr = DROW[i]; dc = DCOL[i]; isInside = isInBoard(r + dr, c + dc); if (isInside) { arrGet(_cache, r + dr, c + dc) = 1; } while (isInside) { field = arrGet(_board, r + dr, c + dc); if (field == EMPTY) { break; } else if (field != stone) { // opponent piece ++count; } else if (!count) { // our piece straight after the location break; } else { // our piece after a number of opponent pieces // move back and reverse stones for (size_t j = 0; j < count; ++j) { arrGet(_board, r, c) = stone; _hasher.trigger(theirHashOffset + SIZE * r + c); _hasher.trigger(myHashOffset + SIZE * r + c); r -= dr; c -= dc; } break; } r += dr; c += dc; isInside = isInBoard(r + dr, c + dc); } } } // State::PutStone template bool State::boardFilled() const { for (size_t i = 0; i < SIZE * SIZE; ++i) { if (_board[i] == EMPTY) { return false; } } return true; } // boardFilled template constexpr typename State::Field State::stoneToPlay() const { switch (_status) { case GameStatus::player0Turn: return BLACK; case GameStatus::player1Turn: return WHITE; default: return EMPTY; } } // State::stoneByStatus template void State::nextTurn() { _status = (_status == GameStatus::player0Turn) ? GameStatus::player1Turn : GameStatus::player0Turn; _hasher.trigger(HASHBOOK_SIZE - 1); } // State::nextTurn template void State::RefillLegalActions() { assert((_status == GameStatus::player0Turn) || (_status == GameStatus::player1Turn)); _legalActions.clear(); Field stoneToPlay = (_status == GameStatus::player0Turn ? BLACK : WHITE); for (size_t row = 0; row < SIZE; ++row) { for (size_t col = 0; col < SIZE; ++col) { if ((arrGet(_board, row, col) == EMPTY) && CanPutStone(stoneToPlay, row, col)) { // add action _legalActions.emplace_back(_legalActions.size(), 0, col, row); } } } if (_legalActions.empty() && !boardFilled()) { _legalActions.emplace_back(_legalActions.size(), 1, SIZE / 2, SIZE / 2); } } // State::RefillLegalAction template void State::fillFeatures() { auto* featuresBlack = _features.data(); auto* featuresWhite = featuresBlack + SIZE * SIZE; memset(featuresBlack, 0, NUM_PIECE_TYPES * SIZE * SIZE * sizeof(float)); for (size_t i = 0; i < SIZE * SIZE; ++i) { switch (_board[i]) { case BLACK: featuresBlack[i] = 1.0; break; case WHITE: featuresWhite[i] = 1.0; break; default: break; } } } // State::fillFeatures template void State::initializeBoard() { memset(_board.data(), 0, SIZE * SIZE * sizeof(typename Board::value_type)); _board[WHITE_INIT_OFFSET_1] = WHITE; _board[WHITE_INIT_OFFSET_2] = WHITE; _board[BLACK_INIT_OFFSET_1] = BLACK; _board[BLACK_INIT_OFFSET_2] = BLACK; } // State::initializeBoard template void State::initializeHasher() { _hasher.reset(); for (unsigned i = 0; i < _board.size(); ++i) { _hasher.trigger(i); } // black stones _hasher.trigger(BLACK_INIT_OFFSET_1); _hasher.trigger(HASH_BLACK_OFFSET + BLACK_INIT_OFFSET_1); _hasher.trigger(BLACK_INIT_OFFSET_2); _hasher.trigger(HASH_BLACK_OFFSET + BLACK_INIT_OFFSET_2); // white stones _hasher.trigger(WHITE_INIT_OFFSET_1); _hasher.trigger(HASH_WHITE_OFFSET + WHITE_INIT_OFFSET_1); _hasher.trigger(WHITE_INIT_OFFSET_2); _hasher.trigger(HASH_WHITE_OFFSET + WHITE_INIT_OFFSET_2); } // State::initializeHasher template void State::initializeCache() { memset(_cache.data(), 0, SIZE * SIZE * sizeof(typename Cache::value_type)); for (size_t row = SIZE / 2 - 2; row < SIZE / 2 + 2; ++row) { for (size_t col = SIZE / 2 - 2; col < SIZE / 2 + 2; ++col) { arrGet(_cache, row, col) = 1; } } } // State::initializeCache template void State::setTerminalStatus() { size_t nWhite = 0; size_t nBlack = 0; for (size_t i = 0; i < SIZE * SIZE; ++i) { switch (_board[i]) { case WHITE: ++nWhite; break; case BLACK: ++nBlack; break; default: break; } } if (nWhite > nBlack) { _status = GameStatus::player1Win; } else if (nBlack > nWhite) { _status = GameStatus::player0Win; } else { _status = GameStatus::tie; } } // State::setTerminalStatus template class State<4>; template class State<6>; template class State<8>; template class State<10>; template class State<12>; template class State<14>; template class State<16>; } // namespace Othello2 ================================================ FILE: src/games/othello_opt.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "../core/state.h" #include "commons/hash.h" #include #include namespace Othello2 { template class State : public core::State { static_assert(SIZE >= 4, "Board too small"); static_assert(SIZE % 2 == 0, "Board has odd size"); static constexpr size_t NUM_PIECE_TYPES = 2; static constexpr size_t NUM_FIELD_TYPES = NUM_PIECE_TYPES + 1; // using _Action = Action; static constexpr size_t HASHBOOK_SIZE = SIZE * SIZE * NUM_FIELD_TYPES + 1; static constexpr size_t HASH_BLACK_OFFSET = SIZE * SIZE; static constexpr size_t HASH_WHITE_OFFSET = 2 * SIZE * SIZE; static constexpr size_t WHITE_INIT_OFFSET_1 = SIZE * (SIZE / 2 - 1) + SIZE / 2 - 1; static constexpr size_t WHITE_INIT_OFFSET_2 = SIZE * SIZE / 2 + SIZE / 2; static constexpr size_t BLACK_INIT_OFFSET_1 = SIZE * (SIZE / 2 - 1) + SIZE / 2; static constexpr size_t BLACK_INIT_OFFSET_2 = SIZE * SIZE / 2 + SIZE / 2 - 1; using _HashBook = HashBook; using _Hasher = Hasher; using Cache = std::array; public: using Field = uint8_t; using Board = std::array; static constexpr Field EMPTY = 0; static constexpr Field BLACK = 1; static constexpr Field WHITE = 2; static constexpr char EMPTY_STR[] = "."; static constexpr char BLACK_STR[] = "x"; static constexpr char WHITE_STR[] = "o"; State(int seed); virtual void Initialize() override; virtual std::unique_ptr clone_() const override; virtual void ApplyAction(const ::_Action& action) override; virtual void DoGoodAction() override; virtual void printCurrentBoard() const override; const Board& GetBoard() const { return _board; } private: std::string boardToString() const; bool CanPutStone(Field stone) const; bool CanPutStone(Field stone, size_t row, size_t col) const; void PutStone(Field stone, size_t row, size_t col); bool boardFilled() const; constexpr Field stoneToPlay() const; void nextTurn(); void RefillLegalActions(); void fillFeatures(); void initializeBoard(); void initializeHasher(); void initializeCache(); void setTerminalStatus(); static std::once_flag hashBookConfigured; static _HashBook hashBook; _Hasher _hasher; Board _board; Cache _cache; }; // class State template std::once_flag State::hashBookConfigured; template typename State::_HashBook State::hashBook; } // namespace Othello2 ================================================ FILE: src/games/outeropengomoku_new.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include "../core/state.h" class StateForOOGomoku : public core::State { public: StateForOOGomoku(int seed) : State(seed) { } virtual void Initialize() override { _moves.clear(); _hash = 2166136261u; _status = GameStatus::player0Turn; _featSize[0] = 3; _featSize[1] = boardHeight; _featSize[2] = boardWidth; _actionSize[0] = 1; _actionSize[1] = boardWidth; _actionSize[2] = boardHeight; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); std::fill(_features.begin(), _features.end(), 1.0f); board.clear(); board.resize(boardWidth * boardHeight, 0); FirstMove = 1; featurize(); findActions(); fillFullFeatures(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } virtual void printCurrentBoard() const override { std::cout << "printing board" << std::endl << std::flush; for (int r = boardHeight - 1; r >= 0; --r) { std::cout << "|"; for (int c = 0; c < boardWidth; ++c) { auto val = board[r * boardWidth + c]; if (val == 0) { std::cout << " "; } else if (val == 1) { std::cout << "X"; } else if (val == 2) { std::cout << "O"; } else { assert(false); } std::cout << "|"; } std::cout << std::endl; } } void featurize() { int player = 1 + getCurrentPlayer(); int otherPlayer = player == 1 ? 2 : 1; for (int i = 0; i != (int)board.size(); ++i) { int v = board[i]; _features[i] = v == player; _features[board.size() + i] = v == otherPlayer; } } void findActions() { clearActions(); if (FirstMove) { FirstMove = 0; for (int i = 0; i < boardWidth; ++i) { for (int j = 0; j < boardHeight; ++j) { if ((i == 0 || i == 1 || i == 13 || i == 14 || j == 0 || j == 1 || j == 13 || j == 14)) addAction(0, i, j); } } } else { for (int i = 0; i < boardWidth; ++i) { for (int j = 0; j < boardHeight; ++j) { auto pos = i + j * boardHeight; if (board[pos] == 0) addAction(0, i, j); } } } } virtual void ApplyAction(const _Action& action) override { int x = action.GetY(); int y = action.GetZ(); int player = 1 + getCurrentPlayer(); size_t index = x + y * boardWidth; board.at(index) = player; _hash ^= index; _hash *= 16777619u; auto count = [&](int dx, int dy) { int nx = x + dx; int ny = y + dy; int r = 0; int stride = dx + dy * boardWidth; size_t nIndex = index + stride; while (nx >= 0 && nx < boardWidth && ny >= 0 && ny < boardHeight && board.at(nIndex) == player) { ++r; nIndex += stride; nx += dx; ny += dy; } return r; }; bool won = count(-1, 0) + count(1, 0) >= 4; won |= count(0, -1) + count(0, 1) >= 4; won |= count(-1, -1) + count(1, 1) >= 4; won |= count(1, -1) + count(-1, 1) >= 4; if (won) { _status = player == 1 ? GameStatus::player0Win : GameStatus::player1Win; } else { featurize(); findActions(); if (_legalActions.empty()) { _status = GameStatus::tie; } else { _status = player == 1 ? GameStatus::player1Turn : GameStatus::player0Turn; } } fillFullFeatures(); } virtual void DoGoodAction() override { return DoRandomAction(); } static const int boardWidth = 15; static const int boardHeight = 15; bool FirstMove; std::vector board; }; ================================================ FILE: src/games/shogi.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include class Shogi { public: const static int Dx = 5; const static int Dy = 5; const static int White = 0; // player0 const static int Black = 1; // player1 const static int Empty = 2; const static int MaxPlayoutLength = 1000; enum class PieceType { None = 0, King, Gold, Silver, Bishop, Rook, Pawn, Gold2, Silver2, Bishop2, Rook2, Pawn2 }; class Position { public: int x, y; Position() { x = y = -1; } Position(int X, int Y) { x = X; y = Y; } bool on_board() const { assert((x == -1 && y == -1) || (x >= -1 && y >= -1 && x <= Dx && y <= Dy)); return (x >= 0 && y >= 0 && x < Dx && y < Dy); } Position operator+(const Position& p) { return Position(x + p.x, y + p.y); } bool operator==(const Position& p) const { return (x == p.x && y == p.y); } bool operator!=(const Position& p) const { return x != p.x || y != p.y; } }; class Piece { public: PieceType type; int color; bool promoted; Position pos; Piece() { color = Empty; type = PieceType::None; promoted = false; } Piece(int c, PieceType t, bool p, Position P = Position(-1, -1)) { color = c; type = t; promoted = p; pos = P; } std::string print() const { std::string str; switch (type) { case PieceType::None: str += " "; break; case PieceType::King: if (color == Black) str += "k"; else str += "K"; break; case PieceType::Gold: case PieceType::Gold2: if (color == Black) str += "g"; else str += "G"; break; case PieceType::Silver: case PieceType::Silver2: if (promoted) str += "+"; if (color == Black) str += "s"; else str += "S"; break; case PieceType::Bishop: case PieceType::Bishop2: if (promoted) str += "+"; if (color == Black) str += "b"; else str += "B"; break; case PieceType::Rook: case PieceType::Rook2: if (promoted) str += "+"; if (color == Black) str += "r"; else str += "R"; break; case PieceType::Pawn: case PieceType::Pawn2: if (promoted) str += "+"; if (color == Black) str += "p"; else str += "P"; break; default: break; } return str; } }; class Move { public: Piece piece; Position next; bool promote; }; Piece board[5][5]; std::vector> chess; // 0 = White, 1 = Black // Move rollout[1000]; void king_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; short dx[] = {1, 1, 0, -1, -1, -1, 0, 1}; short dy[] = {0, 1, 1, 1, 0, -1, -1, -1}; for (int i = 0; i < 8; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); // 在棋盤上、是對方的棋或空 if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) moves.push_back(m); } } void gold_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; if (m.piece.color == White) { short dx[] = {1, 1, 0, -1, -1, 0}; short dy[] = {0, 1, 1, 1, 0, -1}; for (int i = 0; i < 6; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) moves.push_back(m); } } else { short dx[] = {1, 0, -1, -1, 0, 1}; short dy[] = {0, 1, 0, -1, -1, -1}; for (int i = 0; i < 6; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) moves.push_back(m); } } } void silver_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; if (m.piece.promoted) { gold_moves(p, moves); return; } if (m.piece.color == White) { short dx[] = {1, 0, -1, -1, 1}; short dy[] = {1, 1, 1, -1, -1}; for (int i = 0; i < 5; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { moves.push_back(m); if (m.next.y == 4) { m.promote = true; moves.push_back(m); m.promote = false; } } } } else { short dx[] = {1, -1, -1, 0, 1}; short dy[] = {1, 1, -1, -1, -1}; for (int i = 0; i < 5; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { moves.push_back(m); if (m.next.y == 0) { m.promote = true; moves.push_back(m); m.promote = false; } } } } } void bishop_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; short dx[] = {1, -1, -1, 1}; short dy[] = {1, 1, -1, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); while (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { moves.push_back(m); if (m.piece.color == White) { if (m.next.y == 4 && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } else { // Black if (m.next.y == 0 && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } if (board[m.next.x][m.next.y].color != Empty) break; m.next = m.next + Position(dx[i], dy[i]); } } if (m.piece.promoted) { short dx[] = {1, 0, -1, 0}; short dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) moves.push_back(m); } } } void rook_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; short dx[] = {1, 0, -1, 0}; short dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); while (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { moves.push_back(m); if (m.piece.color == White) { if (m.next.y == 4 && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } else { // Black if (m.next.y == 0 && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } if (board[m.next.x][m.next.y].color != Empty) break; m.next = m.next + Position(dx[i], dy[i]); } } if (m.piece.promoted) { short dx[] = {1, -1, -1, 1}; short dy[] = {1, 1, -1, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) moves.push_back(m); } } } void pawn_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; if (m.piece.promoted) { gold_moves(p, moves); return; } if (m.piece.color == White) { m.next = m.piece.pos + Position(0, 1); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { if (m.next.y != 4) moves.push_back(m); else { m.promote = true; moves.push_back(m); m.promote = false; } } } else { m.next = m.piece.pos + Position(0, -1); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { if (m.next.y != 0) moves.push_back(m); else { m.promote = true; moves.push_back(m); m.promote = false; } } } } void legal_king_moves(Piece p, std::vector& moves) { // fprintf(stderr, "legal king moves (%c, %d)\n", p.pos.x+'A', p.pos.y); Move m; m.piece = p; m.promote = false; short dx[] = {1, 1, 0, -1, -1, -1, 0, 1}; short dy[] = {0, 1, 1, 1, 0, -1, -1, -1}; for (int i = 0; i < 8; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(m.next, opponent(m.piece.color))) { moves.push_back(m); } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } // fprintf(stderr, "end legal king moves\n"); } void legal_gold_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; Piece king; for (auto i : chess[p.color]) { if (i.type == PieceType::King) { king = i; break; } } if (m.piece.color == White) { short dx[] = {1, 1, 0, -1, -1, 0}; short dy[] = {0, 1, 1, 1, 0, -1}; for (int i = 0; i < 6; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); // fprintf(stderr, "g next: %c %d\n", m.next.x+'A', m.next.y); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; // std::string str; // str += " A| B| C| D| E\n"; // for(int i=Dy-1; i>=0; --i) { // str += std::to_string(i) + ' '; // for(int j=0; j 0) str += '|'; // str += board[j][i].print(); // } // str += '\n'; // } // std::cerr << str; if (!check(king.pos, opponent(king.color))) moves.push_back(m); board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } } else { short dx[] = {1, 0, -1, -1, 0, 1}; short dy[] = {0, 1, 0, -1, -1, -1}; for (int i = 0; i < 6; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); // fprintf(stderr, "g next: %c %d\n", m.next.x+'A', m.next.y); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) moves.push_back(m); board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } } } void legal_silver_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; if (m.piece.promoted) { legal_gold_moves(p, moves); return; } Piece king; for (auto i : chess[p.color]) { if (i.type == PieceType::King) { king = i; break; } } if (m.piece.color == White) { short dx[] = {1, 0, -1, -1, 1}; short dy[] = {1, 1, 1, -1, -1}; for (int i = 0; i < 5; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); if ((m.next.y == 4 || m.piece.pos.y == 4) && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } } else { short dx[] = {1, -1, -1, 0, 1}; short dy[] = {1, 1, -1, -1, -1}; for (int i = 0; i < 5; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); if ((m.next.y == 0 || m.piece.pos.y == 0) && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } } } void legal_bishop_moves(Piece p, std::vector& moves) { // fprintf(stderr, "innnnnnnnnnnnnnBishop\n"); // for(int i=0; i<2; ++i) { // for(auto j : chess[i]) { // fprintf(stderr, "(%c,%d) ", j.pos.x+'A', j.pos.y); // } // std::cerr << std::endl; // } Move m; m.piece = p; m.promote = false; Piece king; for (auto i : chess[p.color]) { if (i.type == PieceType::King) { king = i; break; } } short dx[] = {1, -1, -1, 1}; short dy[] = {1, 1, -1, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); while (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); if (m.piece.color == White) { if ((m.next.y == 4 || m.piece.pos.y == 4) && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } else { // Black if ((m.next.y == 0 || m.piece.pos.y == 0) && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } if (board[m.next.x][m.next.y].color != Empty) break; m.next = m.next + Position(dx[i], dy[i]); } } if (m.piece.promoted) { short dx[] = {1, 0, -1, 0}; short dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } } // fprintf(stderr, "innnnnnnnnnnnnnBiiiiiii\n"); // for(int i=0; i<2; ++i) { // for(auto j : chess[i]) { // fprintf(stderr, "(%c,%d) ", j.pos.x+'A', j.pos.y); // } // std::cerr << std::endl; // } } void legal_rook_moves(Piece p, std::vector& moves) { // fprintf(stderr, "innnnnnnnnnnnnnRook\n"); // for(int i=0; i<2; ++i) { // for(auto j : chess[i]) { // fprintf(stderr, "(%c,%d) ", j.pos.x+'A', j.pos.y); // } // std::cerr << std::endl; // } Move m; m.piece = p; m.promote = false; Piece king; for (auto i : chess[p.color]) { if (i.type == PieceType::King) { king = i; break; } } short dx[] = {1, 0, -1, 0}; short dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); while (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); if (m.piece.color == White) { if ((m.next.y == 4 || m.piece.pos.y == 4) && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } else { // Black if ((m.next.y == 0 || m.piece.pos.y == 0) && !m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } if (board[m.next.x][m.next.y].color != Empty) break; m.next = m.next + Position(dx[i], dy[i]); } } if (m.piece.promoted) { short dx[] = {1, -1, -1, 1}; short dy[] = {1, 1, -1, -1}; for (int i = 0; i < 4; ++i) { m.next = m.piece.pos + Position(dx[i], dy[i]); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } } // fprintf(stderr, "innnnnnnnnnnnnnRook\n"); // for(int i=0; i<2; ++i) { // for(auto j : chess[i]) { // fprintf(stderr, "(%c,%d) ", j.pos.x+'A', j.pos.y); // } // std::cerr << std::endl; // } } void legal_pawn_moves(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; if (m.piece.promoted) { legal_gold_moves(p, moves); return; } Piece king; for (auto i : chess[p.color]) { if (i.type == PieceType::King) { king = i; break; } } if (m.piece.color == White) { m.next = m.piece.pos + Position(0, 1); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { if (m.next.y != 4) moves.push_back(m); else if (!m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } else { m.next = m.piece.pos + Position(0, -1); // fprintf(stderr, "pawn: %d %d\n", m.next.x, m.next.y); if (m.next.on_board() && board[m.next.x][m.next.y].color != m.piece.color) { Piece pp; if (board[m.next.x][m.next.y].color != Empty) { pp = board[m.next.x][m.next.y]; for (auto& i : chess[opponent(m.piece.color)]) { if (i.pos == pp.pos) { i.pos = Position(-1, -1); break; } } } board[m.piece.pos.x][m.piece.pos.y] = Piece(); board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { if (m.next.y != 0) moves.push_back(m); else if (!m.piece.promoted) { m.promote = true; moves.push_back(m); m.promote = false; } } board[m.next.x][m.next.y] = pp; board[m.piece.pos.x][m.piece.pos.y] = m.piece; for (auto& i : chess[opponent(m.piece.color)]) { if (i.type == pp.type && !i.pos.on_board()) { i.pos = pp.pos; break; } } } } } void legal_pawn_drop(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; Piece king; for (auto i : chess[p.color]) { if (i.type == PieceType::King) { king = i; break; } } // find another pawn int cannotdrop = Dx; for (auto c : chess[p.color]) { if ((c.type == PieceType::Pawn || c.type == PieceType::Pawn2) && c.pos.x != -1) cannotdrop = c.pos.x; } if (p.color == White) { for (int i = 0; i < Dx; ++i) { if (i == cannotdrop) continue; for (int j = 0; j < Dy - 1; ++j) { if (board[i][j].color == Empty) { if (board[i][j + 1].type == PieceType::King && board[i][j + 1].color != p.color) { board[i][j] = p; for (auto& v : chess[m.piece.color]) { if (v.type == p.type && !v.pos.on_board()) { v.pos = Position(i, j); break; } } bool cm = checkmate(board[i][j + 1].color); board[i][j] = Piece(); for (auto& v : chess[m.piece.color]) { if (v.pos == Position(i, j)) { v.pos = Position(-1, -1); break; } } if (cm) { continue; } } m.next = Position(i, j); Piece pp; board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); } board[m.next.x][m.next.y] = pp; } } } } else { for (int i = 0; i < Dx; ++i) { if (i == cannotdrop) continue; for (int j = 1; j < Dy; ++j) { if (board[i][j].color == Empty) { if (board[i][j - 1].type == PieceType::King && board[i][j - 1].color != p.color) { board[i][j] = p; for (auto& v : chess[m.piece.color]) { if (v.type == p.type && !v.pos.on_board()) { v.pos = Position(i, j); break; } } bool cm = checkmate(board[i][j - 1].color); board[i][j] = Piece(); for (auto& v : chess[m.piece.color]) { if (v.pos == Position(i, j)) { v.pos = Position(-1, -1); break; } } if (cm) { continue; } } m.next = Position(i, j); Piece pp; board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) { moves.push_back(m); } board[m.next.x][m.next.y] = pp; } } } } } void legal_drop(Piece p, std::vector& moves) { Move m; m.piece = p; m.promote = false; Piece king; for (auto i : chess[p.color]) { if (i.type == PieceType::King) { king = i; break; } } for (int i = 0; i < Dx; ++i) { for (int j = 0; j < Dy; ++j) { if (board[i][j].color == Empty) { m.next = Position(i, j); Piece pp; board[m.next.x][m.next.y] = m.piece; if (!check(king.pos, opponent(king.color))) moves.push_back(m); board[m.next.x][m.next.y] = pp; } } } } int opponent(int player) const { if (player == White) return Black; return White; } // pos: king position // opponent can eat king bool check(Position pos, int op) { for (auto i : chess[op]) { std::vector moves; if (i.pos.on_board()) { switch (i.type) { case PieceType::King: king_moves(i, moves); break; case PieceType::Gold: case PieceType::Gold2: gold_moves(i, moves); break; case PieceType::Silver: case PieceType::Silver2: silver_moves(i, moves); break; case PieceType::Bishop: case PieceType::Bishop2: bishop_moves(i, moves); break; case PieceType::Rook: case PieceType::Rook2: rook_moves(i, moves); break; case PieceType::Pawn: case PieceType::Pawn2: pawn_moves(i, moves); break; default: break; } } for (auto m : moves) { if (m.next == pos) { return true; } } } return false; } bool checkmate(int color) { std::vector moves; for (auto i : chess[color]) { legalMoves(i, moves); } return moves.empty(); } void legalMoves(Piece p, std::vector& moves) { if (p.pos.on_board()) { switch (p.type) { case PieceType::King: legal_king_moves(p, moves); break; case PieceType::Gold: case PieceType::Gold2: legal_gold_moves(p, moves); break; case PieceType::Silver: case PieceType::Silver2: legal_silver_moves(p, moves); break; case PieceType::Bishop: case PieceType::Bishop2: legal_bishop_moves(p, moves); break; case PieceType::Rook: case PieceType::Rook2: legal_rook_moves(p, moves); break; case PieceType::Pawn: case PieceType::Pawn2: legal_pawn_moves(p, moves); break; default: break; } } else { switch (p.type) { case PieceType::King: fprintf(stderr, "Error: King drop\n"); break; case PieceType::Gold: case PieceType::Gold2: case PieceType::Silver: case PieceType::Silver2: case PieceType::Bishop: case PieceType::Bishop2: case PieceType::Rook: case PieceType::Rook2: legal_drop(p, moves); break; case PieceType::Pawn: case PieceType::Pawn2: legal_pawn_drop(p, moves); break; default: break; } } } int type_to_z(Piece p) { if (!p.promoted) return (int)p.type - 1; switch (p.type) { case PieceType::Silver: return 11; case PieceType::Bishop: return 12; case PieceType::Rook: return 13; case PieceType::Pawn: return 14; case PieceType::Silver2: return 15; case PieceType::Bishop2: return 16; case PieceType::Rook2: return 17; case PieceType::Pawn2: return 18; default: fprintf( stderr, "%s type to z error %d\n", p.print().c_str(), (int)p.type); return -1; } } bool z_promoted(int z) const { return z >= 11; } PieceType z_to_type(int z) const { switch (z) { case 0: return PieceType::King; case 1: return PieceType::Gold; case 2: return PieceType::Silver; case 3: return PieceType::Bishop; case 4: return PieceType::Rook; case 5: return PieceType::Pawn; case 6: return PieceType::Gold2; case 7: return PieceType::Silver2; case 8: return PieceType::Bishop2; case 9: return PieceType::Rook2; case 10: return PieceType::Pawn2; case 11: return PieceType::Silver; case 12: return PieceType::Bishop; case 13: return PieceType::Rook; case 14: return PieceType::Pawn; case 15: return PieceType::Silver2; case 16: return PieceType::Bishop2; case 17: return PieceType::Rook2; case 18: return PieceType::Pawn2; default: fprintf(stderr, "z to type error %d\n", z); return PieceType::None; } } PieceType new_type(PieceType p) const { PieceType t = p; switch (p) { case PieceType::Gold: t = PieceType::Gold2; break; case PieceType::Gold2: t = PieceType::Gold; break; case PieceType::Silver: t = PieceType::Silver2; break; case PieceType::Silver2: t = PieceType::Silver; break; case PieceType::Bishop: t = PieceType::Bishop2; break; case PieceType::Bishop2: t = PieceType::Bishop; break; case PieceType::Rook: t = PieceType::Rook2; break; case PieceType::Rook2: t = PieceType::Rook; break; case PieceType::Pawn: t = PieceType::Pawn2; break; case PieceType::Pawn2: t = PieceType::Pawn; break; default: break; } return t; } }; ================================================ FILE: src/games/surakarta.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: Maria Elsa // - Github: https://github.com/melsaa // - Email: m_elsa@ymail.com // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #pragma once #include #include #include #include #include #include #include #include using namespace std; const int SuraWhite = 0; const int SuraBlack = 1; const int SuraEmpty = 2; const int SKDx = 6; const int SKDy = 6; const int SuraMaxPlayoutLength = 1000; class SKHash { public: unsigned long long HashArray[2][SKDx][SKDy]; unsigned long long HashTurn; bool InitHashCalled = false; void InitHash() { for (int player = 0; player < 2; player++) for (int i = 0; i < SKDx; i++) for (int j = 0; j < SKDy; j++) { HashArray[player][i][j] = 0; for (int k = 0; k < 36; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) HashArray[player][i][j] |= (1ULL << k); } HashTurn = 0; for (int k = 0; k < 36; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) HashTurn |= (1ULL << k); } }; class SKPlayer { public: int player; bool operator==(SKPlayer p) { return (p.player == player); } }; class SKMove { public: int x, y, x1, y1, color; bool operator==(const SKMove& m) { return (x == m.x && y == m.y && x1 == m.x1 && y1 == m.y1 && color == m.color); } bool operator!=(const SKMove& m) { return !(x == m.x && y == m.y && x1 == m.x1 && y1 == m.y1 && color == m.color); } }; class SKBoard { public: int board[SKDx][SKDy]; unsigned long long hash; SKMove rollout[SuraMaxPlayoutLength]; int length, turn, nbPlay, repetition; bool isCapture, draw; vector history_move; SKHash Sura; void init() { for (int i = 0; i < SKDx; i++) for (int j = 0; j < SKDy; j++) board[i][j] = SuraEmpty; for (int i = 0; i < 2; i++) for (int j = 0; j < SKDx; j++) board[j][i] = SuraWhite; for (int i = SKDy - 2; i < SKDy; i++) for (int j = 0; j < SKDx; j++) board[j][i] = SuraBlack; hash = 0; length = 0; turn = SuraWhite; nbPlay = 0; repetition = 0; isCapture = false; draw = false; history_move.clear(); history_move.push_back(hash); if (Sura.InitHashCalled == false) { Sura.InitHash(); Sura.InitHashCalled = true; } } void print_board(FILE* fp) { fprintf(fp, "====================\n"); for (int i = SKDy - 1; i >= 0; i--) { for (int j = 0; j < SKDx; j++) if (board[j][i] == SuraBlack) fprintf(fp, "x "); else if (board[j][i] == SuraWhite) fprintf(fp, "o "); else if (board[j][i] == SuraEmpty) fprintf(fp, "- "); fprintf(fp, "\n"); } fprintf(fp, "====================\n"); } bool won(int color) { if (color == SuraWhite) { for (int i = 0; i < SKDy; i++) for (int j = 0; j < SKDx; j++) if (board[j][i] == SuraBlack) return false; vector moves; int nb = legalMoves(SuraBlack, moves); if (nb == 0) return true; } else if (color == SuraBlack) { for (int i = 0; i < SKDy; i++) for (int j = 0; j < SKDx; j++) if (board[j][i] == SuraWhite) return false; vector moves; int nb = legalMoves(SuraWhite, moves); if (nb == 0) return true; } return false; } bool is_draw() { if (repetition == 3) draw = true; if (draw == true) return true; return false; } int opponent(int color) { if (color == SuraWhite) return SuraBlack; return SuraWhite; } bool legalMove(SKMove m, bool capture) { if (m.x1 < 0 || m.y1 < 0 || m.x1 >= SKDx || m.y1 >= SKDy) return false; if (board[m.x][m.y] != m.color) return false; if (board[m.x1][m.y1] == m.color) return false; if (capture == false && board[m.x1][m.y1] == opponent(m.color)) return false; return true; } void play(SKMove m) { board[m.x][m.y] = SuraEmpty; hash ^= Sura.HashArray[m.color][m.x][m.y]; if (board[m.x1][m.y1] != SuraEmpty) { hash ^= Sura.HashArray[board[m.x1][m.y1]][m.x1][m.y1]; isCapture = true; } board[m.x1][m.y1] = m.color; hash ^= Sura.HashArray[m.color][m.x1][m.y1]; hash ^= Sura.HashTurn; if (length < SuraMaxPlayoutLength) { rollout[length] = m; length++; } check_repetition(); turn = opponent(turn); nbPlay++; if (nbPlay == 50 && isCapture == false) { draw = true; } else if (isCapture == true) { nbPlay = 0; isCapture = false; } } void check_repetition() { history_move.push_back(hash); int cur_index = history_move.size() - 1; if (cur_index >= 8 && history_move[cur_index] == history_move[cur_index - 4] && history_move[cur_index] == history_move[cur_index - 8]) { // std::cout << "Three fold Repetitions\n"; repetition = 3; } else if (cur_index >= 4 && history_move[cur_index] == history_move[cur_index - 4]) { // std::cout << "Two fold Repetitions\n"; repetition = 2; } } int legalMoves(int color, vector& moves) { int nb = 0; bool capture = false; int dir[8][2] = { {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}; for (int i = 0; i < SKDx; i++) for (int j = 0; j < SKDy; j++) if (board[i][j] == color) { SKMove m; m.x = i; m.y = j; m.color = color; for (int k = 0; k < 8; k++) { int mx = dir[k][0]; int my = dir[k][1]; m.x1 = i + mx; m.y1 = j + my; if (legalMove(m, capture)) { moves.push_back(m); nb++; } } } return nb; } int legalCaptures(int nb, int color, vector& moves) { int nc = nb; bool capture = true; int dir[4][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // up, right, down, left for (int i = 0; i < SKDx; i++) for (int j = 0; j < SKDy; j++) if (board[i][j] == color && ((i >= 1 && i <= 4) || (j >= 1 && j <= 4))) { SKMove m; m.x = i; m.y = j; m.color = color; // std::cout << "origin = " << i << "," << j << std::endl; for (int k = 0; k < 4; k++) { int curK = k; int curX = i + dir[curK][0]; int curY = j + dir[curK][1]; bool loop = false; int step = 0; while (curX >= -1 && curY >= -1 && curX <= SKDx && curY <= SKDy) { step++; // std::cout << "dir = " << curK << " to " << curX << "," << curY // << std::endl; if (!(curX == i && curY == j) && curX >= 0 && curY >= 0 && curX < SKDx && curY < SKDy && board[curX][curY] == color) { // std::cout << "same color\n"; break; } else if (curX >= 0 && curY >= 0 && curX < SKDx && curY < SKDy && board[curX][curY] == opponent(color)) { if (loop) { // already go through a loop m.x1 = curX; m.y1 = curY; if (legalMove(m, capture) && find(moves.begin(), moves.end(), m) == moves.end()) { moves.push_back(m); nc++; } } // else std::cout << "opponent but no loop\n"; break; } else if (curX == i && curY == j && step >= 28) break; // return to origin else if ((curX == 0 && curY == 0) || (curX == 0 && curY == SKDy - 1) || (curX == SKDx - 1 && curY == 0) || (curX == SKDx - 1 && curY == SKDy - 1)) break; // corner else { if (curX < 0 || curY < 0 || curX >= SKDx || curY >= SKDy) { // std::cout << "go through a loop\n"; // std::cout << "prev " << curX << "," << curY << std::endl; if (curX == 1 || curX == 2) { curK = 1; // right if (curY > 0) curY -= (curX + 1); else curY += (curX + 1); curX = 0; loop = true; } else if (curX == 3 || curX == 4) { curK = 3; // left if (curY > 0 && curX == 3) curY -= 3; else if (curY > 0 && curX == 4) curY -= 2; else if (curY < 0 && curX == 3) curY += 3; else if (curY < 0 && curX == 4) curY += 2; curX = 5; loop = true; } else if (curY == 1 || curY == 2) { curK = 0; // up if (curX > 0) curX -= (curY + 1); else curX += (curY + 1); curY = 0; loop = true; } else if (curY == 3 || curY == 4) { curK = 2; // down if (curX > 0 && curY == 3) curX -= 3; else if (curX > 0 && curY == 4) curX -= 2; else if (curX < 0 && curY == 3) curX += 3; else if (curX < 0 && curY == 4) curX += 2; curY = 5; loop = true; } // std::cout << "cur = " << curX << "," << curY << " dir = " // << curK << std::endl; } else { // std::cout << "continue to next one under same direction\n"; curX += dir[curK][0]; curY += dir[curK][1]; } } } } } return nc; } }; ================================================ FILE: src/games/surakarta_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // Author: Maria Elsa // - Github: https://github.com/melsaa // - Email: m_elsa@ymail.com // Facilitator: 邱顯棟 (Xiǎn-Dòng Qiū) // - Github: https://github.com/YumJelly // - Email: yumjelly@gmail.com #include "../core/state.h" typedef unsigned short Coord; #include "time.h" #include #include #include #include const int StateForSurakartaX = 2; const int StateForSurakartaY = 6; const int StateForSurakartaZ = 6; #include "surakarta.h" class StateForSurakarta : public core::State, public SKBoard { public: StateForSurakarta(int seed) : State(seed) { } virtual void Initialize() override { _moves.clear(); // the features are just one number between 0 and 1 (the distance, // normalized). _featSize[0] = StateForSurakartaX; _featSize[1] = StateForSurakartaY; _featSize[2] = StateForSurakartaZ; // size of the output of the neural network; this should cover the positions // of actions (above). _actionSize[0] = 36; _actionSize[1] = 6; _actionSize[2] = 6; _hash = 0; _status = GameStatus::player0Turn; _features.resize(StateForSurakartaX * StateForSurakartaY * StateForSurakartaZ); init(); findFeatures(); findActions(SuraWhite); fillFullFeatures(); } virtual std::string stateDescription() const override { std::string str; str += " A|B|C|D|E|F\n"; for (int i = SKDy - 1; i >= 0; i--) { str += to_string(i + 1) + ' '; for (int j = 0; j < SKDx; j++) { if (j > 0) str += '|'; if (board[j][i] == SuraEmpty) str += ' '; else if (board[j][i] == SuraBlack) str += 'x'; else str += 'o'; } str += '\n'; } return str; } virtual std::string actionsDescription() const override { std::stringstream ss; char x, y, x1, y1; for (int i = 0; i < (int)_legalActions.size(); i++) { const _Action& action = _legalActions[i]; x = static_cast(action.GetY() + 'A'); y = static_cast(action.GetZ() + '1'); int curY = action.GetX() / SKDx; y1 = static_cast(curY + '1'); x1 = static_cast(action.GetX() - curY * SKDx + 'A'); ss << "Action " << i << ": " << x << y << "-" << x1 << y1 << std::endl; } ss << "\nInput format : - e.g. A1-A2\n"; return ss.str(); } virtual std::string actionDescription(const _Action& action) const { std::stringstream ss; char x, y, x1, y1; x = static_cast(action.GetY() + 'A'); y = static_cast(action.GetZ() + '1'); int curY = action.GetX() / SKDx; y1 = static_cast(curY + '1'); x1 = static_cast(action.GetX() - curY * SKDx + 'A'); ss << x << y << "-" << x1 << y1; return ss.str(); } virtual int parseAction(const std::string& str) const override { int x = -1, y = -1, x1 = -1, y1 = -1; if (!isalpha(str[0]) || !isalpha(str[3])) return -1; if (!isdigit(str[1]) || !isdigit(str[4])) return -1; x = static_cast(toupper(str[0]) - 'A'); y = static_cast(str[1] - '1'); x1 = static_cast(toupper(str[3]) - 'A'); y1 = static_cast(str[4] - '1'); if (x < 0 || y < 0 || x1 < 0 || y1 < 0 || x >= SKDx || y >= SKDy || x1 >= SKDx || y1 >= SKDy) return -1; for (int i = 0; i < (int)_legalActions.size(); i++) { if (_legalActions[i].GetX() == (y1 * SKDy + x1) && _legalActions[i].GetY() == x && _legalActions[i].GetZ() == y) return i; } return -1; } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } void findActions(int color) { vector moves; int nb = legalMoves(color, moves); int nc = legalCaptures(nb, color, moves); clearActions(); for (int i = 0; i < nc; i++) { int x = moves[i].x; int y = moves[i].y; int final_pos = moves[i].y1 * SKDy + moves[i].x1; addAction(final_pos, x, y); } } void findFeatures() { if ((_status == GameStatus::player0Win) || (_status == GameStatus::player1Win) || (_status == GameStatus::tie)) return; if (_status == GameStatus::player0Turn) { // SuraWhite for (int i = 0; i < 72; i++) _features[i] = 0; for (int i = 0; i < 36; i++) if (board[i % 6][i / 6] == SuraBlack) _features[i] = 1; for (int i = 0; i < 36; i++) if (board[i % 6][i / 6] == SuraWhite) _features[36 + i] = 1; } else if (_status == GameStatus::player1Turn) { // SuraBlack assert(_status == GameStatus::player1Turn); for (int i = 0; i < 72; i++) _features[i] = 0; for (int i = 0; i < 36; i++) if (board[i % 6][5 - (i / 6)] == SuraWhite) _features[i] = 1; for (int i = 0; i < 36; i++) if (board[i % 6][5 - (i / 6)] == SuraBlack) _features[36 + i] = 1; } } // The action just decreases the distance and swaps the turn to play. virtual void ApplyAction(const _Action& action) override { SKMove m; if (_status == GameStatus::player0Turn) { // SuraWhite m.color = SuraWhite; m.x = action.GetY(); m.y = action.GetZ(); m.y1 = action.GetX() / SKDx; m.x1 = action.GetX() - m.y1 * SKDx; play(m); findActions(SuraBlack); if (won(SuraWhite) || _legalActions.size() == 0) { _legalActions.clear(); _status = GameStatus::player0Win; } else if (is_draw()) { _status = GameStatus::tie; _legalActions.clear(); } else _status = GameStatus::player1Turn; } else { // SuraBlack m.color = SuraBlack; m.x = action.GetY(); m.y = action.GetZ(); m.y1 = action.GetX() / SKDx; m.x1 = action.GetX() - m.y1 * SKDx; play(m); findActions(SuraWhite); if (won(SuraBlack) || _legalActions.size() == 0) { _legalActions.clear(); _status = GameStatus::player1Win; } else if (is_draw()) { _legalActions.clear(); _status = GameStatus::tie; } else _status = GameStatus::player0Turn; } findFeatures(); _hash = hash; fillFullFeatures(); } // For this trivial example we just compare to random play virtual void DoGoodAction() override { DoRandomAction(); } }; ================================================ FILE: src/games/tristan_nogo.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include #include #include #include #include #include "tristan_nogo.h" using namespace std; unsigned long long HashArray[3000]; bool useOrderMoves = true; bool MonteCarloMoveOrdering = true; bool printGame = false; unsigned long long nbPlay = 0; int level = 1; timeval stop, start; unsigned long long previousTime = 0; bool useNotLosing = false; bool useOrderPPAF = false; void initHash() { for (int i = 0; i < 3000; i++) { HashArray[i] = 0; for (int k = 0; k < 64; k++) if ((rand() / (RAND_MAX + 1.0)) > 0.5) HashArray[i] |= (1ULL << k); } } bool useCode = true; double history[MaxMoveNumber]; int interMove[MaxSize], moveInter[MaxSize]; bool ajoute(int* stack, int elt) { for (int i = 1; i <= stack[0]; i++) if (stack[i] == elt) return false; stack[0]++; stack[stack[0]] = elt; return true; } ================================================ FILE: src/games/tristan_nogo.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include #include #include #include #include #include using namespace std; extern const int White; extern const int Black; extern const int Empty; const int Dx = 9; const int Dy = 9; const int MaxLegalMoves = Dx * Dy; const int MaxPlayoutLength = 1000; const int SizeTable = 1048575; // une puissance de 2 moins 1 extern unsigned long long HashArray[3000]; extern bool useOrderMoves; extern bool MonteCarloMoveOrdering; extern bool printGame; extern unsigned long long nbPlay; extern int level; extern timeval stop, start; extern unsigned long long previousTime; extern bool useNotLosing; class NogoBoard; extern void initHash(); /* class Player { public: int player; bool operator==(Player p) { return (p.player == player); } }; */ const int MaxMoveNumber = 256 * 2 * (Dx * Dy + 1) + 1; extern bool useCode; class NogoMove { public: int inter, color; int code; int number() { int c = 0; if (useCode) c = code; if (color == White) return c * 2 * (Dx * Dy + 1) + inter; else return c * 2 * (Dx * Dy + 1) + Dx * Dy + 1 + inter; } }; extern double history[MaxMoveNumber]; const int MaxSize = (Dx + 2) * (Dy + 2); const int MaxIntersections = Dx * Dy; const int Exterieur = 3; const int Haut = 0; const int Bas = 1; const int Gauche = 2; const int Droite = 3; extern int interMove[MaxSize], moveInter[MaxSize]; extern bool ajoute(int* stack, int elt); class NogoBoard { public: int start, end, size, dxNogoBoard, dyNogoBoard; char board[MaxSize]; unsigned long long hash; int turn; int orderMove[MaxLegalMoves]; NogoMove rollout[MaxPlayoutLength]; int length; int nbVides, vides[MaxSize], indiceVide[MaxSize]; int nbChaines, chaines[MaxSize], indiceChaine[MaxSize]; int nbPierres[MaxSize]; int premierePierre[MaxSize]; int pierreSuivante[MaxSize]; int nbPseudoLibertes[MaxSize]; int premierePseudoLiberte[MaxSize]; int pseudoLiberteSuivante[4 * MaxSize]; int pseudoLibertePrecedente[4 * MaxSize]; NogoBoard() { init(); } void init() { dxNogoBoard = Dx + 2; dyNogoBoard = Dy + 2; start = dxNogoBoard + 1; end = dxNogoBoard * dyNogoBoard - dxNogoBoard - 1; size = Dx * Dy; nbVides = 0; nbChaines = 0; hash = 0; for (int i = 0; i < dxNogoBoard * dyNogoBoard; i++) { if ((i < start) || (i % dxNogoBoard == 0) || ((i + 1) % dxNogoBoard == 0) || (i >= end)) board[i] = Exterieur; else { board[i] = Empty; vides[nbVides] = i; indiceVide[i] = nbVides; interMove[nbVides] = i; moveInter[i] = nbVides; nbVides++; } } turn = White; length = 0; } void winningMove(int depth, NogoMove m, NogoMove) { unsigned long long l = 4ULL << (depth - 70); // fprintf (stderr, "depth = %d, history [%d] += %llu, ", depth - 70, // m.number (), l); history[m.number()] += l; } int order(NogoMove m) { return 4; // return rand () % 1000; return history[m.number()]; } int legalNogoMoves(int joueur, NogoMove moves[MaxLegalMoves]) { NogoMove coup; int nb = 0; coup.color = joueur; for (coup.inter = 0; coup.inter < size; coup.inter++) if (board[interMove[coup.inter]] == Empty) if (legal(interMove[coup.inter], joueur)) { // - ajouter joueur ? coup.code = board[interMove[coup.inter] - dxNogoBoard] + 4 * board[interMove[coup.inter] - 1] + 16 * board[interMove[coup.inter] + 1] + 64 * board[interMove[coup.inter] + dxNogoBoard]; moves[nb] = coup; nb++; } if (useOrderMoves) { for (int i = 0; i < nb; i++) orderMove[i] = order(moves[i]); for (int i = 0; i < nb; i++) { int imin = i; int o = orderMove[i]; for (int j = i + 1; j < nb; j++) { int o1 = orderMove[j]; if (o1 < o) { imin = j; o = o1; } } NogoMove m = moves[i]; moves[i] = moves[imin]; moves[imin] = m; o = orderMove[i]; orderMove[i] = orderMove[imin]; orderMove[imin] = o; } } return nb; } bool losingMove(NogoMove) { return false; } bool legalMove(NogoMove m) { return legal(interMove[m.inter], m.color); } bool legal(int inter, char color) { if (board[inter] != Empty) return false; char autre = opponent(color); // check if capture if (board[inter - 1] == autre) if (atari(premierePierre[inter - 1])) return false; if (board[inter + 1] == autre) if (atari(premierePierre[inter + 1])) return false; if (board[inter - dxNogoBoard] == autre) if (atari(premierePierre[inter - dxNogoBoard])) return false; if (board[inter + dxNogoBoard] == autre) if (atari(premierePierre[inter + dxNogoBoard])) return false; // check if suicide if (board[inter - 1] == Empty) return true; if (board[inter + 1] == Empty) return true; if (board[inter - dxNogoBoard] == Empty) return true; if (board[inter + dxNogoBoard] == Empty) return true; int nb = 0; if (board[inter - 1] == color) { nb += nbPseudoLibertes[premierePierre[inter - 1]] - 1; if (board[inter + 1] == color) { if (premierePierre[inter - 1] != premierePierre[inter + 1]) nb += nbPseudoLibertes[premierePierre[inter + 1]] - 1; else nb--; if (board[inter - dxNogoBoard] == color) { if ((premierePierre[inter - 1] != premierePierre[inter - dxNogoBoard]) && (premierePierre[inter + 1] != premierePierre[inter - dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter - dxNogoBoard]] - 1; else nb--; if (board[inter + dxNogoBoard] == color) { if ((premierePierre[inter - 1] != premierePierre[inter + dxNogoBoard]) && (premierePierre[inter + 1] != premierePierre[inter + dxNogoBoard]) && (premierePierre[inter - dxNogoBoard] != premierePierre[inter + dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; else nb--; } } else if (board[inter + dxNogoBoard] == color) { if ((premierePierre[inter - 1] != premierePierre[inter + dxNogoBoard]) && (premierePierre[inter + 1] != premierePierre[inter + dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; else nb--; } } else { if (board[inter - dxNogoBoard] == color) { if ((premierePierre[inter - 1] != premierePierre[inter - dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter - dxNogoBoard]] - 1; else nb--; if (board[inter + dxNogoBoard] == color) { if ((premierePierre[inter - 1] != premierePierre[inter + dxNogoBoard]) && (premierePierre[inter - dxNogoBoard] != premierePierre[inter + dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; else nb--; } } else if (board[inter + dxNogoBoard] == color) { if ((premierePierre[inter - 1] != premierePierre[inter + dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; else nb--; } } } else { if (board[inter + 1] == color) { nb += nbPseudoLibertes[premierePierre[inter + 1]] - 1; if (board[inter - dxNogoBoard] == color) { if ((premierePierre[inter + 1] != premierePierre[inter - dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter - dxNogoBoard]] - 1; else nb--; if (board[inter + dxNogoBoard] == color) { if ((premierePierre[inter + 1] != premierePierre[inter + dxNogoBoard]) && (premierePierre[inter - dxNogoBoard] != premierePierre[inter + dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; else nb--; } } else if (board[inter + dxNogoBoard] == color) { if ((premierePierre[inter + 1] != premierePierre[inter + dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; else nb--; } } else { if (board[inter - dxNogoBoard] == color) { nb += nbPseudoLibertes[premierePierre[inter - dxNogoBoard]] - 1; if (board[inter + dxNogoBoard] == color) { if ((premierePierre[inter - dxNogoBoard] != premierePierre[inter + dxNogoBoard])) nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; else nb--; } } else if (board[inter + dxNogoBoard] == color) { nb += nbPseudoLibertes[premierePierre[inter + dxNogoBoard]] - 1; } } } if (nb > 0) return true; return false; } bool atari(int p) { if (nbPseudoLibertes[premierePierre[p]] > 4) return false; int premiere = premierePseudoLiberte[premierePierre[p]]; int lib = premiere >> 2; int suivante = pseudoLiberteSuivante[premiere]; while (suivante != premiere) { if ((suivante >> 2) != lib) return false; suivante = pseudoLiberteSuivante[suivante]; } return true; } void ajouteChaine(int chaine1, int chaine2) { int pierre = chaine1; do { premierePierre[pierre] = chaine2; pierre = pierreSuivante[pierre]; } while (pierre != chaine1); int suivante = pierreSuivante[chaine1]; pierreSuivante[chaine1] = pierreSuivante[chaine2]; pierreSuivante[chaine2] = suivante; nbPierres[chaine2] += nbPierres[chaine1]; chaines[indiceChaine[chaine1]] = chaines[nbChaines - 1]; indiceChaine[chaines[nbChaines - 1]] = indiceChaine[chaine1]; nbChaines--; if (nbPseudoLibertes[chaine1] > 0) { if (nbPseudoLibertes[chaine2] == 0) { premierePseudoLiberte[chaine2] = premierePseudoLiberte[chaine1]; } else { int premiereChaine2 = premierePseudoLiberte[chaine2]; int suivanteChaine2 = pseudoLiberteSuivante[premiereChaine2]; int premiereChaine1 = premierePseudoLiberte[chaine1]; int derniereChaine1 = pseudoLibertePrecedente[premiereChaine1]; pseudoLiberteSuivante[premiereChaine2] = premiereChaine1; pseudoLibertePrecedente[premiereChaine1] = premiereChaine2; pseudoLiberteSuivante[derniereChaine1] = suivanteChaine2; pseudoLibertePrecedente[suivanteChaine2] = derniereChaine1; } } nbPseudoLibertes[chaine2] += nbPseudoLibertes[chaine1]; } void otePseudoLiberte(int chaine, int lib) { nbPseudoLibertes[chaine]--; if (nbPseudoLibertes[chaine] > 0) { int precedente = pseudoLibertePrecedente[lib]; int suivante = pseudoLiberteSuivante[lib]; pseudoLiberteSuivante[precedente] = suivante; pseudoLibertePrecedente[suivante] = precedente; if (premierePseudoLiberte[chaine] == lib) premierePseudoLiberte[chaine] = suivante; } } void ajoutePseudoLiberte(int chaine, int lib) { if (nbPseudoLibertes[chaine] == 0) { premierePseudoLiberte[chaine] = lib; pseudoLiberteSuivante[lib] = lib; pseudoLibertePrecedente[lib] = lib; } else { int premiere = premierePseudoLiberte[chaine]; int suivante = pseudoLiberteSuivante[premiere]; pseudoLiberteSuivante[premiere] = lib; pseudoLibertePrecedente[lib] = premiere; pseudoLiberteSuivante[lib] = suivante; pseudoLibertePrecedente[suivante] = lib; } nbPseudoLibertes[chaine]++; } void play(NogoMove c) { // std::cerr << " before:" << std::endl; // print(stderr); // std::cerr << c.inter % Dx << "," << c.inter / Dx << std::endl; joue(interMove[c.inter], c.color); // std::cerr << " after:" << std::endl; // print(stderr); turn = opponent(turn); if (length < MaxPlayoutLength) { rollout[length] = c; length++; } else fprintf(stderr, "Pb play,"); } void joue(int inter, char color) { nbPlay++; board[inter] = color; if (color == Black) hash ^= HashArray[moveInter[inter]]; else hash ^= HashArray[MaxIntersections + moveInter[inter]]; nbVides--; indiceVide[vides[nbVides]] = indiceVide[inter]; vides[indiceVide[inter]] = vides[nbVides]; nbPierres[inter] = 1; premierePierre[inter] = inter; pierreSuivante[inter] = inter; nbPseudoLibertes[inter] = 0; indiceChaine[inter] = nbChaines; chaines[nbChaines] = inter; nbChaines++; if (board[inter - 1] == color) { if (premierePierre[inter] != premierePierre[inter - 1]) ajouteChaine(premierePierre[inter], premierePierre[inter - 1]); otePseudoLiberte(premierePierre[inter], (inter << 2) | Gauche); } else if (board[inter - 1] == Empty) { ajoutePseudoLiberte(premierePierre[inter], ((inter - 1) << 2) | Droite); } else if (board[inter - 1] != Exterieur) { otePseudoLiberte(premierePierre[inter - 1], (inter << 2) | Gauche); } if (board[inter + 1] == color) { if (premierePierre[inter] != premierePierre[inter + 1]) ajouteChaine(premierePierre[inter], premierePierre[inter + 1]); otePseudoLiberte(premierePierre[inter], (inter << 2) | Droite); } else if (board[inter + 1] == Empty) { ajoutePseudoLiberte(premierePierre[inter], ((inter + 1) << 2) | Gauche); } else if (board[inter + 1] != Exterieur) { otePseudoLiberte(premierePierre[inter + 1], (inter << 2) | Droite); } if (board[inter - dxNogoBoard] == color) { if (premierePierre[inter] != premierePierre[inter - dxNogoBoard]) ajouteChaine( premierePierre[inter], premierePierre[inter - dxNogoBoard]); otePseudoLiberte(premierePierre[inter], (inter << 2) | Haut); } else if (board[inter - dxNogoBoard] == Empty) { ajoutePseudoLiberte( premierePierre[inter], ((inter - dxNogoBoard) << 2) | Bas); } else if (board[inter - dxNogoBoard] != Exterieur) { otePseudoLiberte( premierePierre[inter - dxNogoBoard], (inter << 2) | Haut); } if (board[inter + dxNogoBoard] == color) { if (premierePierre[inter] != premierePierre[inter + dxNogoBoard]) ajouteChaine( premierePierre[inter], premierePierre[inter + dxNogoBoard]); otePseudoLiberte(premierePierre[inter], (inter << 2) | Bas); } else if (board[inter + dxNogoBoard] == Empty) { ajoutePseudoLiberte( premierePierre[inter], ((inter + dxNogoBoard) << 2) | Haut); } else if (board[inter + dxNogoBoard] != Exterieur) { otePseudoLiberte(premierePierre[inter + dxNogoBoard], (inter << 2) | Bas); } } int choisitUnCoup(char color) { int debut = rand() % nbVides; for (int i = debut; i < nbVides; i++) if (legal(vides[i], color)) return vides[i]; for (int i = 0; i < debut; i++) if (legal(vides[i], color)) return vides[i]; return -1; } /**/ int fastPlayout(int color) { for (;;) { int pos = choisitUnCoup(color); if (pos == -1) break; joue(pos, color); color = opponent(color); } if (color == Black) return 1; return 0; } /**/ void print(FILE* fp) { int i; fprintf(fp, " "); for (i = 0; i < dxNogoBoard - 2; i++) fprintf(fp, "%-3c", 'A' + i + (i > 7)); fprintf(fp, "\n"); fprintf(fp, " / "); for (i = 0; i < dxNogoBoard - 2; i++) fprintf(fp, "- "); fprintf(fp, "\\ \n"); for (i = start - 1; i <= end; i++) { if (((i) % dxNogoBoard == 0)) fprintf(fp, "%3d | ", dyNogoBoard - 1 - (i / dxNogoBoard)); else if (((i + 1) % (dxNogoBoard) == 0)) fprintf(fp, "| %2d\n", dyNogoBoard - 1 - (i / dxNogoBoard)); else if (board[i] == Empty) fprintf(fp, "+ "); else if (board[i] == Black) fprintf(fp, "@ "); else if (board[i] == White) fprintf(fp, "O "); else fprintf(fp, "%d ", board[i]); } fprintf(fp, " \\ "); for (i = 0; i < dxNogoBoard - 2; i++) fprintf(fp, "- "); fprintf(fp, "/ \n"); fprintf(fp, " "); for (i = 0; i < dxNogoBoard - 2; i++) fprintf(fp, "%-3c", 'A' + i + (i > 7)); fprintf(fp, "\n"); fprintf(fp, "hash = %llu\n", hash); } bool won(int color) { NogoMove moves[MaxLegalMoves]; int nb = legalNogoMoves(opponent(color), moves); return nb == 0; } float evaluation(int color) { NogoMove moves[MaxLegalMoves]; int nb = legalNogoMoves(turn, moves); if (nb == 0) { if (color == turn) return -1000000.0; else return 1000000.0; } int nbOpponent = legalNogoMoves(opponent(turn), moves); if (color == turn) return (float)(nb - nbOpponent); return (float)(nbOpponent - nb); } bool terminal() { NogoMove moves[MaxLegalMoves]; int nb = legalNogoMoves(turn, moves); return nb == 0; } int score() { if (turn == Black) return 1; return 0; } int opponent(int joueur) { if (joueur == White) return Black; return White; } int playout(int joueur) { return fastPlayout(joueur); NogoMove listeCoups[MaxLegalMoves]; while (true) { int nb = legalNogoMoves(joueur, listeCoups); if (nb == 0) { if (joueur == Black) return 1; else return 0; } int n = rand() % nb; play(listeCoups[n]); if (length >= MaxPlayoutLength - 20) { return 0; } joueur = opponent(joueur); } } float discountedPlayout(int joueur, int maxLength = MaxPlayoutLength - 20) { NogoMove listeCoups[MaxLegalMoves]; while (true) { int nb = legalNogoMoves(joueur, listeCoups); if (nb == 0) { if (joueur == Black) return 1.0 / (length + 1); else return -1.0 / (length + 1); // if (joueur == Black) // return 1.0 * (length + 1); // else // return -1.0 * (length + 1); } int n = rand() % nb; play(listeCoups[n]); if (length >= maxLength) { return 0; } joueur = opponent(joueur); } } }; ================================================ FILE: src/games/tristannogo_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "time.h" #include #include #include #include #include "../core/game.h" #include "tristan_nogo.h" const int StateForTristannogoNumActions = Dx * Dy; const int StateForTristannogoX = 5; const int StateForTristannogoY = Dx; const int StateForTristannogoZ = Dy; const int NogoMaxLegalMoves = Dx * Dy; class StateForTristannogo : public core::State, NogoBoard { public: StateForTristannogo(int seed) : State(seed) { } virtual ~StateForTristannogo() { } virtual void Initialize() override { // People implementing classes should not have much to do in _moves; just // _moves.clear(). _moves.clear(); // std::cout << "OTGTristannogo initialize" << std::endl; // the features are just one number between 0 and 1 (the distance, // normalized). _featSize[0] = StateForTristannogoX; _featSize[1] = StateForTristannogoY; _featSize[2] = StateForTristannogoZ; // size of the output of the neural network; this should cover the positions // of actions (above). _actionSize[0] = 1; _actionSize[1] = Dx; _actionSize[2] = Dy; // _hash is an unsigned int, it has to be *unique*. _hash = 0; _status = GameStatus::player0Turn; // std::cout << "restart!" << std::endl; // _features is a vector representing the current state. It can // (must...) be large for complex games; here just one number // between 0 and 1. trivial case in dimension 1. _features.resize(StateForTristannogoX * StateForTristannogoY * StateForTristannogoZ); /* // _features[:_hash] = 1 for (int i = 0; i < DISTANCE; i++) { _features[i] = (float(_hash) > float(i)) ? 1. : 0.; } */ init(); findFeatures(); findActions(White); fillFullFeatures(); } virtual std::unique_ptr clone_() const override { return std::make_unique(*this); } void findActions(int color) { NogoMove moves[NogoMaxLegalMoves]; int nb = legalNogoMoves(color, moves); clearActions(); for (int i = 0; i < nb; i++) { int x = moves[i].inter % Dx; int y = moves[i].inter / Dx; addAction(0, x, y); } } void findFeatures() { if ((_status == GameStatus::player0Win) || (_status == GameStatus::player1Win)) return; if (_status == GameStatus::player0Turn) { // Black for (int i = 0; i < 5 * Dx * Dy; i++) _features[i] = 0; for (int i = 0; i < Dx * Dy; i++) if (board[interMove[i]] == Black) _features[i] = 1; for (int i = 0; i < Dx * Dy; i++) if (board[interMove[i]] == White) _features[Dx * Dy + i] = 1; for (int i = 0; i < Dx * Dy; i++) if (legal(interMove[i], Black)) _features[3 * Dx * Dy + i] = 1; for (int i = 0; i < Dx * Dy; i++) if (legal(interMove[i], White)) _features[4 * Dx * Dy + i] = 1; } else { assert(_status == GameStatus::player1Turn); // White for (int i = 0; i < 5 * Dx * Dy; i++) _features[i] = 0; for (int i = 0; i < Dx * Dy; i++) if (board[interMove[i]] == Black) _features[i] = 1; for (int i = 0; i < Dx * Dy; i++) if (board[interMove[i]] == White) _features[Dx * Dy + i] = 1; for (int i = 0; i < Dx * Dy; i++) _features[2 * Dx * Dy + i] = 1; for (int i = 0; i < Dx * Dy; i++) if (legal(interMove[i], Black)) _features[3 * Dx * Dy + i] = 1; for (int i = 0; i < Dx * Dy; i++) if (legal(interMove[i], White)) _features[4 * Dx * Dy + i] = 1; } } // The action just decreases the distance and swaps the turn to play. virtual void ApplyAction(const _Action& action) override { NogoMove m; // print(stdout); if (_status == GameStatus::player0Turn) { // Black m.color = Black; m.inter = action.GetY() + Dx * action.GetZ(); play(m); findActions(White); if (won(Black)) _status = GameStatus::player0Win; else _status = GameStatus::player1Turn; } else { // White m.color = White; m.inter = action.GetY() + Dx * action.GetZ(); play(m); findActions(Black); if (won(White)) _status = GameStatus::player1Win; else _status = GameStatus::player0Turn; } findFeatures(); _hash = hash; fillFullFeatures(); } // For this trivial example we just compare to random play. Ok, this is not // really a good action. // By the way we need a good default DoGoodAction, e.g. one-ply at least. // FIXME virtual void DoGoodAction() override { int i = rand() % _legalActions.size(); const _Action& a = _legalActions[i]; ApplyAction(a); } std::string stateDescription() const override { std::string s(" 0 1 2 3 4 5 6 7 8\n"); for (int i = 0; i < Dy; i++) { s += std::to_string(i); for (int j = 0; j < Dx; j++) { if (board[interMove[i * Dy + j]] == Black) s += " @"; else if (board[interMove[i * Dy + j]] == White) s += " O"; else if (board[interMove[i * Dy + j]] == Empty) s += " +"; } s += " \n"; } s += " \n"; return s; } }; ================================================ FILE: src/games/weakschur/SchurMatrix.cpp ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "SchurMatrix.hpp" #include SchurMatrix::SchurMatrix(int nbSubsets, int maxNumber) : _nbSubsets(nbSubsets), _maxNumber(maxNumber), _data(_nbSubsets*_maxNumber) {} void SchurMatrix::reset(bool value) { std::fill(_data.begin(), _data.end(), value); } bool SchurMatrix::get(int i, int j) const { assert(i >= 1); assert(i <= _nbSubsets); assert(j >= 1); assert(j <= _maxNumber); return _data[(i-1) * _maxNumber + (j-1)]; } void SchurMatrix::set(int i, int j, bool b) { assert(i >= 1); assert(i <= _nbSubsets); assert(j >= 1); assert(j <= _maxNumber); _data[(i-1) * _maxNumber + (j-1)] = b; } const std::vector & SchurMatrix::data() const { return _data; } ================================================ FILE: src/games/weakschur/SchurMatrix.hpp ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include // A _nbSubsets x _maxNumber matrix storing if subset i can host number j, // where (i, j) in [1, _nbSubsets] x [1, _maxNumber] class SchurMatrix { private: int _nbSubsets; int _maxNumber; std::vector _data; public: SchurMatrix(int nbSubsets, int maxNumber); void reset(bool value); bool get(int i, int j) const; void set(int i, int j, bool b); const std::vector & data() const; }; ================================================ FILE: src/games/weakschur/SchurVector.cpp ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "SchurVector.hpp" #include SchurVector::SchurVector(int maxIndex) : _maxIndex(maxIndex), _data(maxIndex) { } void SchurVector::reset(int value) { std::fill(_data.begin(), _data.end(), value); } int SchurVector::get(int i) const { assert(i >= 1); assert(i <= _maxIndex); return _data[i-1]; } void SchurVector::set(int i, int value) { assert(i >= 1); assert(i <= _maxIndex); _data[i-1] = value; } const std::vector & SchurVector::data() const { return _data; } ================================================ FILE: src/games/weakschur/SchurVector.hpp ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include // 1-based indexed vector of int class SchurVector { private: int _maxIndex; std::vector _data; public: SchurVector(int maxIndex); void reset(int value); int get(int i) const; void set(int i, int value); const std::vector & data() const; }; ================================================ FILE: src/games/weakschur/WeakSchur.cpp ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "WeakSchur.hpp" #include #include WeakSchur::WeakSchur(int nbSubsets, int maxNumber) : _nbSubsets(nbSubsets), _maxNumber(maxNumber), _freeActions(nbSubsets, maxNumber), _nbFreeNumbersOfSubset(nbSubsets), _nbNumbersOfSubset(nbSubsets), _nbFreeSubsetsOfNumber(maxNumber), _subsetOfNumber(maxNumber) { reset(); } void WeakSchur::reset() { _freeActions.reset(true); _nbFreeActions = _nbSubsets * _maxNumber; _nbFreeNumbersOfSubset.reset(_maxNumber); _nbNumbersOfSubset.reset(0); _nbFreeSubsetsOfNumber.reset(_nbSubsets); _subsetOfNumber.reset(0); _score = 0; applyAction({1, 1}); } bool WeakSchur::isTerminated() const { return _score == _maxNumber or _nbFreeSubsetsOfNumber.get(_score+1) == 0; } int WeakSchur::getScore() const { return _score; } int WeakSchur::getFirstLegalNumber() const { assert(not isTerminated()); return _score + 1; } int WeakSchur::getMostConstrainedNumber() const { assert(not isTerminated()); int bestNumber = _score + 1; int nbSubsetsBest = _nbFreeSubsetsOfNumber.get(bestNumber); for (int number = bestNumber + 1; number < _maxNumber; number++) { const int nbSubsets = _nbFreeSubsetsOfNumber.get(number); if (nbSubsets != 0 and nbSubsets < nbSubsetsBest) { nbSubsetsBest = nbSubsets; bestNumber = number; } } return bestNumber; } std::vector WeakSchur::getLegalSubsets(int number) const { const int nbSubsetsOfNumber = _nbFreeSubsetsOfNumber.get(number); std::vector legalSubsets; legalSubsets.reserve(nbSubsetsOfNumber); for (int i = 1; i <= _nbSubsets; i++) //if ((_freeActions.get(i, number) and i<=2) or // (_freeActions.get(i, number) and i>2 and _nbNumbersOfSubset.get(i-1) > 0)) if (_freeActions.get(i, number) and (i<=2 or _nbNumbersOfSubset.get(i-1) > 0)) legalSubsets.push_back(i); //assert(int(legalSubsets.size()) == nbSubsetsOfNumber); // TODO return legalSubsets; } std::pair WeakSchur::getLongestSeq(int subset) const { int longest = 0; int nbLongest = 0; int currLongest = 0; for (int n=1; n<=_maxNumber; n++) { if (_subsetOfNumber.get(n) == subset) { currLongest++; } else { if (currLongest > longest) { longest = currLongest; nbLongest = 1; } else if (currLongest == longest) { nbLongest++; } currLongest = 0; } } return {longest, nbLongest}; } void WeakSchur::applyAction(const Action & action) { const int subset = action.first; const int number = action.second; // assert action assert(subset >= 1); assert(subset <= _nbSubsets); assert(number >= 1); assert(number <= _maxNumber); assert(_nbFreeSubsetsOfNumber.get(number) > 0); assert(_subsetOfNumber.get(number) == 0); assert(_freeActions.get(subset, number)); // update subset data for (int s = 1; s <= _nbSubsets; s++) _freeActions.set(s, number, false); _nbFreeActions -= _nbFreeSubsetsOfNumber.get(number); _nbFreeSubsetsOfNumber.set(number, 0); _nbNumbersOfSubset.set(subset, _nbNumbersOfSubset.get(subset) + 1); // update number data for (int n = 1; n <= _maxNumber; n++) { if (subset == _subsetOfNumber.get(n)) { removeAction({subset, n + number}); removeAction({subset, n - number}); removeAction({subset, number - n}); _nbFreeNumbersOfSubset.set(subset, _nbFreeNumbersOfSubset.get(subset)-1); } } // store action _subsetOfNumber.set(number, subset); // update score while (_score < _maxNumber and _subsetOfNumber.get(_score+1) != 0) _score++; } void WeakSchur::removeAction(const Action & action) { const int subset = action.first; const int numberToRemove = action.second; if (numberToRemove >= 1 and numberToRemove <= _maxNumber and _freeActions.get(subset, numberToRemove)) { _freeActions.set(subset, numberToRemove, false); _nbFreeActions--; const int oldNbSubsets = _nbFreeSubsetsOfNumber.get(numberToRemove); _nbFreeSubsetsOfNumber.set(numberToRemove, oldNbSubsets - 1); } } std::ostream & operator<<(std::ostream & os, const WeakSchur & ws) { os << "freeActions: " << std::endl; for (int s = 1; s <= ws._nbSubsets; s++) { os << " "; for (int n = 1; n <= ws._maxNumber; n++) { os << " " << ws._freeActions.get(s, n); } os << std::endl; } os << "nbFreeActions: \n " << ws._nbFreeActions << std::endl; os << "nbSubsetsOfNumber:\n "; for (int n = 1; n <= ws._maxNumber; n++) { os << " " << ws._nbFreeSubsetsOfNumber.get(n); } os << std::endl; os << "subsetOfNumber:\n "; for (int n = 1; n <= ws._maxNumber; n++) { os << " " << ws._subsetOfNumber.get(n); } os << std::endl; os << "score: \n " << ws._score << std::endl; os << "subsets: " << std::endl; for (int s = 1; s <= ws._nbSubsets; s++) { os << " "; for (int n = 1; n <= ws._maxNumber; n++) { if (ws._subsetOfNumber.get(n) == s) os << " " << n; } os << std::endl; } os << std::endl; return os; } ================================================ FILE: src/games/weakschur/WeakSchur.hpp ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "SchurMatrix.hpp" #include "SchurVector.hpp" #include class WeakSchur { // Action = (subset, number) using Action = std::pair; public: int _nbSubsets; int _maxNumber; protected: public: // todo getters ? SchurMatrix _freeActions; int _nbFreeActions; // how many possible numbers, for each subset SchurVector _nbFreeNumbersOfSubset; // TODO SchurVector _nbNumbersOfSubset; // how many possible subsets, for each number SchurVector _nbFreeSubsetsOfNumber; // vector storing, for each number, the selected subset // (or 0 where no subset has been selected) SchurVector _subsetOfNumber; // the current score is the max of the successive numbers validly // placed in the subsets, i.e. n where 1, ..., n are validly placed // in the subsets and (n+1) is not int _score; public: WeakSchur(int nbSubsets, int maxNumber); void reset(); void applyAction(const Action & action); bool isTerminated() const; int getScore() const; int getFirstLegalNumber() const; int getMostConstrainedNumber() const; std::vector getLegalSubsets(int number) const; std::pair getLongestSeq(int subset) const; friend std::ostream & operator<<(std::ostream & os, const WeakSchur & ws); protected: void removeAction(const Action & action); }; std::ostream & operator<<(std::ostream & os, const WeakSchur & ws); ================================================ FILE: src/games/weakschur/weakschur_state.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "../../core/state.h" #include "WeakSchur.hpp" // #include // TODO #ifdef #include namespace weakschur { template class State : public core::State { private: WeakSchur _weakschur; public: State(int seed); bool isOnePlayerGame() const override; void Initialize() override; void ApplyAction(const _Action& action) override; void DoGoodAction() override; float getReward(int player) const override final { // if (player != 0) // std::cout << boost::stacktrace::stacktrace(); if (_weakschur.getScore() == MAXNUMBER) { std::cout << "Found Good Schur:" << _weakschur << std::endl; std::cerr << "Found Good Schur:" << _weakschur << std::endl; abort(); } float value = float(_weakschur.getScore()) / float(MAXNUMBER); return player == 0 ? value : -value; }; std::unique_ptr clone_() const override; private: std::string stateDescription() const override; void findActions(); }; } // namespace weakschur /////////////////////////////////////////////////////////////////////////////// // weakschur::State /////////////////////////////////////////////////////////////////////////////// template weakschur::State::State(int seed) : core::State(seed) , _weakschur(NBSUBSETS, MAXNUMBER) { } template bool weakschur::State::isOnePlayerGame() const { return true; } template void weakschur::State::DoGoodAction() { DoRandomAction(); } template std::unique_ptr weakschur::State::clone_() const { return std::make_unique>(*this); } template std::string weakschur::State::stateDescription() const { std::ostringstream oss; oss << _weakschur; return oss.str(); } template void weakschur::State::Initialize() { // _weakschur _weakschur.reset(); // state _hash = 0; _status = GameStatus::player0Turn; // features // TODO channels _featSize = {9, NBSUBSETS, MAXNUMBER}; _features = std::vector(_featSize[0] * _featSize[1] * _featSize[2], 0.f); _features[0] = 1.f; // _weakschur always does the first action {1, 1} const int channelSize = NBSUBSETS * MAXNUMBER; // 1 features: i / first(t) // 2 features: longest seq(t) / maxnumber // 3 features: #longest // 4 features: #possible for i / nbsubsets for (int i = 0; i < channelSize; i++) _features[channelSize * 4 + i] = 1.f; // 5 features: #possible for t / maxnumber for (int i = 0; i < channelSize; i++) _features[channelSize * 5 + i] = (MAXNUMBER - 1) / float(MAXNUMBER); // 6 features: board (t, i-1) // 7 features: board (t, i-2) // 8 features: board (t, i-3) fillFullFeatures(); // actions _actionSize = {1, NBSUBSETS + 1, MAXNUMBER + 1}; findActions(); } template void weakschur::State::ApplyAction( const _Action& action) { const int channelSize = NBSUBSETS * MAXNUMBER; auto feature = [channelSize, this](int c, int subset, int number) -> float& { return this ->_features[channelSize * c + (subset - 1) * MAXNUMBER + number - 1]; }; // update weakschur assert(not _weakschur.isTerminated()); int subset = action.GetY(); int number = action.GetZ(); _weakschur.applyAction({subset, number}); // update status if (_weakschur.isTerminated()) { // std::cout << "WS:" << _weakschur.getScore() << "," << MAXNUMBER << // std::endl; _status = _weakschur.getScore() == MAXNUMBER ? GameStatus::player0Win : GameStatus::player1Win; } // update state int k = (subset - 1) * MAXNUMBER + (number - 1); assert(_features[k] == 0.f); _features[k] = 1.f; // 1 features: i / first(t) int firstT = MAXNUMBER + 1; for (int n = 1; n <= MAXNUMBER; n++) { if (_weakschur._subsetOfNumber.get(n) == subset) { firstT = n; break; } } for (int n = 1; n <= MAXNUMBER; n++) { feature(1, subset, n) = n / float(firstT); } // 2 features: longest seq(t) / maxnumber // 3 features: #longest auto longestAndNb = _weakschur.getLongestSeq(subset); for (int n = 1; n <= MAXNUMBER; n++) { feature(2, subset, n) = longestAndNb.first / float(MAXNUMBER); feature(3, subset, n) = longestAndNb.second / float(MAXNUMBER); } // 4 features: #possible for i / nbsubsets for (int n = 1; n <= MAXNUMBER; n++) if (_weakschur._subsetOfNumber.get(n) != 0) feature(4, subset, n) = _weakschur.getLegalSubsets(n).size() / float(NBSUBSETS); else feature(4, subset, n) = 0.f; // 5 features: #possible for t / maxnumber for (int n = 1; n <= MAXNUMBER; n++) for (int s = 1; s <= NBSUBSETS; s++) feature(5, s, n) = _weakschur._nbFreeNumbersOfSubset.get(s) / float(MAXNUMBER); // 6 features: board (t, i-1) for (int n = 2; n <= MAXNUMBER; n++) for (int s = 1; s <= NBSUBSETS; s++) feature(6, s, n) = _weakschur._subsetOfNumber.get(n - 1) == s ? 1.f : 0.f; // 7 features: board (t, i-2) for (int n = 3; n <= MAXNUMBER; n++) for (int s = 1; s <= NBSUBSETS; s++) feature(7, s, n) = _weakschur._subsetOfNumber.get(n - 2) == s ? 1.f : 0.f; // 8 features: board (t, i-3) for (int n = 4; n <= MAXNUMBER; n++) for (int s = 1; s <= NBSUBSETS; s++) feature(8, s, n) = _weakschur._subsetOfNumber.get(n - 3) == s ? 1.f : 0.f; fillFullFeatures(); // update actions findActions(); } template void weakschur::State::findActions() { // TODO multiple "most contrained" numbers ? clearActions(); if (not _weakschur.isTerminated()) { // get possible numbers int number1 = _weakschur.getFirstLegalNumber(); int number2 = _weakschur.getMostConstrainedNumber(); // get subsets and update actions if (number1 == number2) { std::vector subsets1 = _weakschur.getLegalSubsets(number1); _legalActions.reserve(subsets1.size()); for (unsigned k = 0; k < subsets1.size(); ++k) addAction(0, subsets1[k], number1); } else { std::vector subsets1 = _weakschur.getLegalSubsets(number1); std::vector subsets2 = _weakschur.getLegalSubsets(number2); _legalActions.reserve(subsets1.size() + subsets2.size()); for (unsigned k = 0; k < subsets1.size(); ++k) addAction(0, subsets1[k], number1); for (unsigned k = 0; k < subsets2.size(); ++k) addAction(0, subsets2[k], number2); } } } ================================================ FILE: src/games/yinsh.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // testing push #include "yinsh.h" #include #include // #include // PAKKA GALTI // FIX LATER // premature optimisation is the source of all evil // relisting the types for reference // std::vector _features; // neural network input // std::vector> _legalActions; // DNU: shared pointer // draw ka rule is different- no of rings pe aa jaati hai baat // namespace Yinsh{ uint64_t StateForYinsh::hash_table[5][BOARD_X][BOARD_Y] = {0}; std::once_flag StateForYinsh::table_flag = once_flag(); string StateForYinsh::stateDescription(void) const { return "empty_state"; } string StateForYinsh::actionsDescription(void) const { return "empty_act"; } char StateForYinsh::map_piece_to_char(int p) const { // printf("enter: map_piece_to_char\n"); char ans; if (p == (int)(piece::invalid)) ans = ' '; else if (p == (int)(piece::p0_marker)) ans = 'a'; else if (p == (int)(piece::p0_ring)) ans = 'A'; else if (p == (int)(piece::p1_marker)) ans = 'b'; else if (p == (int)(piece::p1_ring)) ans = 'B'; else if (p == (int)(piece::empty)) ans = '.'; else ans = '!'; // printf("leave: map_piece_to_char\n"); return ans; } void StateForYinsh::set_vars() { // printf("enter: set_vars\n"); // my_rings starts with p0 // cout<<"player is "< distribution( 0, 0xFFFFFFFFFFFFFFFF); for (int i = 0; i < 5; i++) { for (int j = 0; j < BOARD_X; j++) { for (int k = 0; k < BOARD_Y; k++) { hash_table[i][j][k] = (uint64_t)(distribution(generator)); } } } } void StateForYinsh::Initialize() { // printf("enter: Initialize\n"); _moves.clear(); // DNU _status = GameStatus::player0Turn; _featSize[0] = NUM_PIECES; _featSize[1] = BOARD_X; _featSize[2] = BOARD_Y; _actionSize[0] = NUM_ACTIONS; _actionSize[1] = BOARD_X; _actionSize[2] = BOARD_Y; _hash = 0ULL; // DNU _status = GameStatus::player0Turn; _features.clear(); _features.resize(_featSize[0] * _featSize[1] * _featSize[2]); std::call_once(table_flag, fill_hash_table); // initGame(); // hard code your init yahan // TODO // all empty pehle for (int i = 0; i < (BOARD_X + 2); i++) { for (int j = 0; j < (BOARD_Y + 2); j++) { board[i][j] = (int)(piece::empty); // mark invalid if (i == 0 || j == 0 || i == 12 || j == 12 || (i - j) >= 6 || (j - i) >= 6) { board[i][j] = (int)(piece::invalid); } } } // corners of my hexagon board[1][1] = (int)(piece::invalid); board[1][6] = (int)(piece::invalid); board[6][11] = (int)(piece::invalid); board[11][11] = (int)(piece::invalid); board[6][1] = (int)(piece::invalid); board[11][6] = (int)(piece::invalid); // rings[0].clear(); // // printf("LOOK HERE // _____________________________________%d\n",rings[0].size() ); // rings[1].clear(); vector> temp1, temp2; // printf("num of rings are %d\n",rings.size() ); // sleep(10); rings.clear(); // printf("num of rings are %d\n",rings.size() ); rings.push_back(temp1); rings.push_back(temp2); // printf("LOOK HERE // _____________________________________%d\n",rings[1].size() ); initial_fill = 0; places_filled = 0; // rings[0].resize(5); // rings[1].resize(5); still_have_to_remove_ring = false; still_have_to_remove_marker = false; free_lunch = false; // ended = false; set_vars(); findActions(); findFeatures(); fillFullFeatures(); // printf("leave: Initialize\n"); } bool StateForYinsh::ended() { // printf("enter: ended\n"); if (_status == GameStatus::player0Win || _status == GameStatus::player1Win || _status == GameStatus::tie) { // printf("leave: ended\n"); return true; } // printf("leave: ended\n"); return false; } void StateForYinsh::printCurrentBoard() const { // printf("enter: printCurrentBoard\n"); for (int j = 0; j < (BOARD_Y + 2); j++) { for (int i = 0; i < (BOARD_X + 2); i++) { cout << map_piece_to_char(board[i][BOARD_Y + 1 - j]) << " "; } cout << endl; } cout << endl; // printf("leave: printCurrentBoard\n"); } tuple StateForYinsh::find_first_invalid(int x, int y, int d0, int d1) { // printf("enter: find_first_invalid\n"); /// PENDING, shayad zaroorat nhi int ex_x, ex_y; int i = d0; int j = d1; // PE- assumes that x and y are non extremes for (int c = 0; c < 13; c++) { if (board[x + c * i][y + c * j] == (int)(piece::invalid)) { ex_x = x + c * i; ex_y = y + c * j; break; } if (c == 10) { cout << "Debug here" << endl; } } // printf("leave: find_first_invalid\n"); return make_tuple(ex_x, ex_y); } vector StateForYinsh::find_first_5_for_specific_pt(int x, int y) { // printf("enter: find_first_5_for_specific_pt\n"); // returns the start point and direction int start_x, start_y; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { if ((i + j) != 0) { // my three directions to check tuple temp = find_first_invalid(x, y, -i, -j); // since x,y is included it cant be invlaid and hence my func should // work just fine int count = 0; int type; start_x = get<0>(temp); start_y = get<1>(temp); // PE kis extreme se start kar raha hai for (int k = 1; k < 13; k++) { start_x = start_x + i; // one step in the direction with each iteration start_y = start_y + j; type = board[start_x][start_y]; if (type == (int)(piece::invalid)) { break; } else if (type == my_marker) { count++; } else { count = 0; } if (count == 5) { vector answer; answer.push_back(start_x - 4 * i); answer.push_back(start_y - 4 * j); answer.push_back(i); answer.push_back(j); // printf("leave: find_first_5_for_specific_pt\n"); return answer; } } } } } vector wrong; printf("Wrong answer in find_first_5_for_specific_pt\n"); printf("x: %d and y: %d\n", x, y); printCurrentBoard(); raise(SIGSEGV); // printf("leave: find_first_5_for_specific_pt\n"); return wrong; } tuple StateForYinsh::map_num_to_direction(int n) { // printf("enter: map_num_to_direction\n"); // if else // PENDING tuple ans; if (n == 0) ans = make_tuple(0, 1); else if (n == 1) ans = make_tuple(1, 1); else if (n == 2) ans = make_tuple(1, 0); else if (n == 3) ans = make_tuple(0, -1); else if (n == 4) ans = make_tuple(-1, -1); else if (n == 5) ans = make_tuple(-1, 0); else { cout << "invalid number for direciton" << endl; // return NULL; ans = make_tuple(-7, -7); } // printf("leave: map_num_to_direction\n"); return ans; } int StateForYinsh::map_direction_to_num(int i, int j) { // printf("enter: map_direction_to_num\n"); int ans; if (i == 0 and j == 1) ans = 0; else if (i == 1 and j == 1) ans = 1; else if (i == 1 and j == 0) ans = 2; else if (i == 0 and j == -1) ans = 3; else if (i == -1 and j == -1) ans = 4; else if (i == -1 and j == 0) ans = 5; else { cout << "invalid direciton" << endl; ans = -8; } // printf("leave: map_direction_to_num\n"); return ans; } vector> StateForYinsh::find_all_5s(bool my) { // printf("enter: find_all_5s\n"); vector> all_5s; // empty abhi // 3 baaar likhlo same cheez kya dikat hai // PENDING int local_marker; if (my) { local_marker = my_marker; // local_ring = my_ring; } else { local_marker = opp_marker; // local_ring = opp_ring; } for (int d_x = 0; d_x < 2; d_x++) { for (int d_y = 0; d_y < 2; d_y++) { if ((d_x + d_y) != 0) { // for all axes // all pts on x axis and y int x, y; // bool start = false; int count = 0; for (int types = 0; types < 2; types++) { for (int pt = 0; pt < 13; pt++) { if (types == 0) { x = 0; y = pt; } else { if (pt == 0) break; x = pt; y = 0; } // start = false; count = 0; int poi; for (int jump = 0; jump < 13; jump++) { if (x + jump * d_x > 12 || y + jump * d_y > 12) break; // this will definitely go out of bounds // %13 lagaden yahan? // PAKKA GALTI //PE poi = board[(x + jump * d_x)][(y + jump * d_y)]; if (poi == local_marker) count++; else count = 0; if (count >= 5) { // store vector temporary_vec; temporary_vec.push_back((x + (jump - 4) * d_x)); // start_x temporary_vec.push_back((y + (jump - 4) * d_y)); // start_y temporary_vec.push_back(d_x); // d_x temporary_vec.push_back(d_y); // d_y all_5s.push_back(temporary_vec); } } } } } } } // printf("leave: find_all_5s\n"); return all_5s; } // vector> StateForYinsh::find_all_5s(bool my){ // printf("enter: find_all_5s\n"); // vector> all_5s; //empty abhi // //3 baaar likhlo same cheez kya dikat hai // //PENDING // int local_marker; // if(my){ // local_marker = my_marker; // // local_ring = my_ring; // } // else{ // local_marker = opp_marker; // // local_ring = opp_ring; // } // for(int d_x = 0; d_x < 2; d_x ++){ // for(int d_y = 0; d_y <2; d_y ++){ // if((d_x + d_y) != 0){ // //for all axes // //all pts on x axis and y // int x, y; // // bool start = false; // int count = 0; // for(int types = 0 ; types<2; types ++){ // for(int pt = 0; pt<13; pt++){ // if(types == 0){ // x = 0; // y = pt; // } // else{ // x = pt; // y = 0; // } // // start = false; // count = 0; // int poi; // for(int jump = 0; jump<13; // jump++){ // //this will definitely go out of // bounds // // %13 lagaden yahan? // //PAKKA GALTI //PE // poi = board[(x + jump*d_x)%13][(y + // jump*d_y)%13]; if(poi == local_marker) count++; else count = 0; // if (count // >=5){ // //store // vector // temporary_vec; temporary_vec.push_back((x + // (jump-4)*d_x)%13);//start_x // temporary_vec.push_back((y + // (jump-4)*d_y)%13);//start_y temporary_vec.push_back(d_x);//d_x // temporary_vec.push_back(d_y);//d_y // all_5s.push_back(temporary_vec); // } // } // } // } // } // } // } // printf("leave: find_all_5s\n"); // return all_5s; // } void StateForYinsh::ApplyAction(const _Action& action) { // printf("enter: ApplyAction\n"); // fetch args // for every update manage hash set_vars(); // printCurrentBoard(); // printf("following move was played by player %d\n", player); int action_num = action.GetX(); int x = action.GetY() + 1; // PE int y = action.GetZ() + 1; // PE // printf("no of rings left %d\n", ((rings[player]).size())); // decide player_number // set_vars(); // since _status is a protected variable StateForYinsh being a subclass should // be able to access // depending on the action num do different things // till 2:30 // cout<<"for p0"; // for(int i=0; i<(rings[0]).size(); i++){ // printf("(%d, %d) ", get<0>((rings[0])[i]),get<1>((rings[0])[i])); // } // cout<((rings[1])[i]),get<1>((rings[1])[i])); // } // cout< placed_ring(x, y); // if(player == 0) rings[0].push_back(placed_ring); // else rings[1].push_back(placed_ring); // cout<<"placed at "<= 5) { printf("WRONG NUM OF RINGS\n"); raise(SIGSEGV); } (rings[player]).push_back(placed_ring); // cout<<"debug"<((rings[player])[i]); b = get<1>((rings[player])[i]); if (a == x && b == y) (rings[player]).erase((rings[player]).begin() + i); } still_have_to_remove_ring = false; still_have_to_remove_marker = true; places_filled--; // dont change turn } else if (action_num == 58) { // sequence selection // find the 5 and then delete // for all directions ' // cout<<"LOOK HERE"< temp; // temp = find_first_5_for_specific_pt(x,y); temp = find_first_5_for_specific_pt(x, y); // cout<<"hey"<> temp; // // temp = find_first_5_for_specific_pt(x,y); // temp = find_all_5s(true); // if (temp.size() == 0 ){ // cout<<"couldnt find 5, shouldnt have happened"<> temp2 = find_all_5s(true); if (temp2.size() == 0) { // change turn if (!free_lunch) { if (player == 0) _status = GameStatus::player1Turn; else _status = GameStatus::player0Turn; } else { // continue you turn now // cout<<"FREE"<= 0 && action_num < 56) { // normal movement // dont check for legality int direction = action_num / 9; int jump = action_num % 9 + 1; tuple dir = map_num_to_direction(direction); int d_x = get<0>(dir); int d_y = get<1>(dir); // ismei invert kardo bas // ring at x,y // cout<<"ring pos, direction and jump were-"; // printf("(%d ,%d), (%d, %d) and %d respectively\n",x,y, d_x, d_y, jump); if (board[x][y] == my_ring) { _hash ^= hash_table[board[x][y] - 1][x - 1][y - 1]; board[x][y] = my_marker; _hash ^= hash_table[board[x][y] - 1][x - 1][y - 1]; } else { cout << "trying to move non_ring " << x << " " << y << ", actually found " << board[x][y] << endl; raise(SIGSEGV); } int x1, y1; for (int i = 1; i < jump; i++) { int found = board[x + (i)*d_x][y + (i)*d_y]; if (found == (int)(piece::empty)) { // do nothing } else if (found == my_marker || found == opp_marker) { // flip it x1 = x + (i)*d_x; y1 = y + (i)*d_y; _hash ^= hash_table[board[x1][y1] - 1][x1 - 1][y1 - 1]; board[x1][y1] = 6 - found; _hash ^= hash_table[board[x1][y1] - 1][x1 - 1][y1 - 1]; } else { cout << "invalid move, dude" << endl; } } x1 = x + jump * d_x; y1 = y + jump * d_y; _hash ^= hash_table[board[x1][y1] - 1][x1 - 1][y1 - 1]; board[x1][y1] = my_ring; _hash ^= hash_table[board[x1][y1] - 1][x1 - 1][y1 - 1]; // update my_rings for (int i = 0; i < (int)rings[player].size(); i++) { int a, b; a = get<0>((rings[player])[i]); b = get<1>((rings[player])[i]); if (a == x && b == y) (rings[player]).erase((rings[player]).begin() + i); } (rings[player]).push_back(make_tuple(x + jump * d_x, y + jump * d_y)); // check for 5 places_filled++; vector> all_5s = find_all_5s(true); vector> all_5s_other = find_all_5s(false); // cout<<"places filled are "< rings[1].size()) _status = GameStatus::player1Win; else _status = GameStatus::tie; // rings[0].clear(); // rings[1].clear(); // break; // raise(SIGSEGV); fillFullFeatures(); // printf("leave: ApplyAction\n"); return; } else { // CHANGE TURN if (player == 0) _status = GameStatus::player1Turn; else _status = GameStatus::player0Turn; } } else { // cout<<"hi4"< t = all_5s_other[0]; // cout<<"sequence_removed, starting and ending were-"; // printf("(%d ,%d) and (%d, %d) ",t[0],t[1], t[0] + 4*t[2], t[1] + // 4*t[3]); free_lunch = true; still_have_to_remove_ring = true; still_have_to_remove_marker = true; if (player == 0) _status = GameStatus::player1Turn; else _status = GameStatus::player0Turn; } } else { // cout<<"hi2"< t = all_5s[0]; // cout<<"sequence_removed, starting and ending were-"; // printf("(%d ,%d)/ and (%d, %d) ",t[0],t[1], t[0] + 4*t[2], t[1] + // 4*t[3]); still_have_to_remove_ring = true; still_have_to_remove_marker = true; // dont change turn } // you have to set the flags in appply to } else { cout << "You fucked up something" << endl; } // cout<<"before calling others"<((rings[player])[i]) - 1, get<1>((rings[player])[i]) - 1); } } else if (still_have_to_remove_marker) { vector> all_5s = find_all_5s(true); vector> till_now; int m_x, m_y, d_x, d_y, k, j; bool matched = false; // printf("num of 5s are %d\n", all_5s.size()); for (int i = 0; i < (int)all_5s.size(); i++) { // FIX LATER // i just put the first point to make this quick // _legalActions.push_back(make_shared( // 58, (all_5s[i][0]) - 1, (all_5s[i][1]) - 1, // _legalActions.size())); m_x = all_5s[i][0]; m_y = all_5s[i][1]; d_x = all_5s[i][2]; d_y = all_5s[i][3]; // printf("mx, my, dx, dy are %d %d %d %d \n",m_x, m_y, d_x, d_y); for (j = 0; j < 5; j++) { matched = false; // for all 5 markers for (k = 0; k < (int)till_now.size(); k++) { if (((till_now[k][0] == m_x + d_x * j) && (till_now[k][1] == m_y + d_y * j))) matched = true; } if (!matched) break; } // fill the chosen marker // printf("chose %d, %d \n", (m_x + d_x*j), (m_y + d_y*j)); addAction(58, (m_x + d_x * j) - 1, (m_y + d_y * j) - 1); vector temp_pt; temp_pt.push_back(m_x + d_x * j); temp_pt.push_back(m_y + d_y * j); till_now.push_back(temp_pt); } } else { // normal move // for all rings // go in all directions // cout<<"enter"<((rings[player])[k]); start_y = get<1>((rings[player])[k]); // cout<<"ring "< rings[1].size()) _status = GameStatus::player1Win; else _status = GameStatus::tie; fillFullFeatures(); // printf("leave: findActions\n"); return; } // printf("leave: findActions\n"); } unique_ptr StateForYinsh::clone_() const { // printf("enter: clone_\n"); unique_ptr temp = std::make_unique(*this); // printf("leave: clone_\n"); return temp; } void StateForYinsh::DoGoodAction() { // printf("enter: DoGoodAction\n"); // return DoRandomAction(); int i = rand() % _legalActions.size(); if (_legalActions.size() == 0) cout << "NO MOVES" << endl; // printf("No of legal moves are %d\n",_legalActions.size() ); _Action a = _legalActions[i]; ApplyAction(a); // printf("leave: DoGoodAction\n"); } void StateForYinsh::findFeatures() { // printf("enter: findFeatures\n"); // yeh toh chill function hai // simply just map the board to the 3 dimensions discussed // NUM_PIECES, BOARD_X, BOARD_Y; // cout<<"enter" < #include #include #include #include #include "../core/state.h" // declare helper classes and functions #define NUM_ACTIONS 59 // (6 directions * 9 max jump) + 1(initial placement) + 1(ring selection for // removal) + 1(seq selection via choosing a marker) #define BOARD_X 11 #define BOARD_Y 11 #define NUM_PIECES 5 using namespace std; // PE the coordinates returned by the output of the net are actually shifted // namespace Yinsh{ enum class piece : int { invalid, empty, p0_marker, p0_ring, p1_marker, p1_ring }; class StateForYinsh : public core::State { public: StateForYinsh(int seed) : State(seed) { } void Initialize() override; // virtual unique_ptr clone_() const override; unique_ptr clone_(void) const override; void ApplyAction(const _Action& action) override; void DoGoodAction(void) override; void printCurrentBoard(void) const override; bool ended(); string stateDescription(void) const override; // DNU string actionsDescription(void) const override; // DNU static void fill_hash_table(); static uint64_t hash_table[5][BOARD_X][BOARD_Y]; static std::once_flag table_flag; private: void findActions(void); // i have to maintain legal actions by myself void findFeatures( void); // after every move i have to call these two because the // base(State class expects that it would be filled) char map_piece_to_char(int p) const; // void printCurrentBoard(); tuple map_num_to_direction(int n); int map_direction_to_num(int i, int j); void set_vars(); tuple find_first_invalid(int x, int y, int d0, int d1); vector find_first_5_for_specific_pt(int x, int y); vector> find_all_5s(bool my); int places_filled; int initial_fill; bool still_have_to_remove_ring; bool still_have_to_remove_marker; int board[13][13]; // vector > *my_rings;//not necessary but makes it faster // vector > *opp_rings; // vector > p0_rings; // vector > p1_rings; vector>> rings; int player, my_ring, my_marker, opp_ring, opp_marker; // set all these with set_vars() bool free_lunch; }; // } ================================================ FILE: src/mcts/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.0 FATAL_ERROR) # lib for other c++ programs add_library(_mcts node.cc mcts.cc storage.cc ) target_link_libraries(_mcts PUBLIC pthread) target_include_directories(_mcts PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) target_include_directories(_mcts PUBLIC ${TORCH_INCLUDE_DIRS}) target_include_directories(_mcts PUBLIC ${PYTHON_INCLUDE_DIRS}) target_link_libraries(_mcts PUBLIC ${TORCH_LIBRARIES} _tube) # pybind lib pybind11_add_module(mcts pybind.cc) target_link_libraries(mcts PUBLIC libpolygames) # tests #add_executable(test_mcts test.cc) #target_link_libraries(test_mcts PUBLIC _mcts) ================================================ FILE: src/mcts/actor.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "mcts/state.h" #include "mcts/utils.h" #include namespace mcts { // this is a minimal interface class, // should ONLY keep functions used by mcts class Actor { public: Actor() = default; Actor(const Actor&) = delete; Actor& operator=(const Actor&) = delete; virtual PiVal evaluate(const State& s) = 0; virtual ~Actor() { } virtual void evaluate( const std::vector& s, const std::function& resultCallback) { for (size_t i = 0; i != s.size(); ++i) { resultCallback(i, evaluate(*s[i])); } }; virtual void terminate() { } virtual void recordMove(const mcts::State* state) { } virtual void result(const State* state, float reward) { } virtual bool isTournamentOpponent() const { return false; } }; } // namespace mcts ================================================ FILE: src/mcts/mcts.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "mcts/mcts.h" #include "common/async.h" #include "common/thread_id.h" #include "common/threads.h" #include "core/state.h" #include namespace mcts { int forcedRollouts(float piValue, int numVisits, const MctsOption& option) { return (int)std::sqrt(option.forcedRolloutsMultiplier * piValue * numVisits); } // TODO: eliminate duplicate code shared with pickBestAction below float puctValue(int rootPlayerId, float puct, const Node* node, mcts::Action action) { const auto& pi = node->legalPolicy_; const Node* child = node->getChild(action); auto childNumVisit = child->getMctsStats().getNumVisit(); float piValue = pi[action]; auto parentNumVisit = node->getMctsStats().getNumVisit(); float priorScore = (float)piValue / (1 + childNumVisit) * (float)std::sqrt(parentNumVisit); int flip = (node->getPiVal().playerId == rootPlayerId) ? 1 : -1; float value = child->getMctsStats().getValue(); float vloss = child->getMctsStats().getVirtualLoss(); float q = (value * flip - vloss) / (childNumVisit + vloss); float score = priorScore * puct + q; return score; } template Action pickBestAction(int rootPlayerId, const Node* const node, const MctsOption& option, std::minstd_rand& rng, int maxNumRollouts) { const auto& pi = node->legalPolicy_; if (pi.empty()) { return InvalidAction; } float puct = option.puct; bool useValuePrior = option.useValuePrior; // We need to flip here because at opponent's step, we need to find // opponent's best action which minimizes our value. Careful not to // flip the exploration term. int flip = (node->getPiVal().playerId == rootPlayerId) ? 1 : -1; float priorValue = node->getMctsStats().getAvgChildV() * flip; auto getScore = [&](Action actionIndex, const Node* child) { float q = 0; int childNumVisit = 0; float vloss = 0; float value = 0; float piValue = pi[actionIndex]; auto parentNumVisit = node->getMctsStats().getNumVisit(); if (child) { const MctsStats& mctsStats = child->getMctsStats(); childNumVisit += mctsStats.getNumVisit(); vloss += mctsStats.getVirtualLoss(); value += mctsStats.getValue(); } if (childNumVisit != 0) { q = (value * flip - vloss) / (childNumVisit + vloss); } else { // When there are no child nodes under this action, replace the q value // with prior. // This prior is estimated from the values of other explored child. // q = 0 if this is the first child to be explroed. In this case, all q = // 0 and we start with the child with highest policy probability. if (useValuePrior) { q = priorValue; } } float priorScore = (float)piValue / (1 + childNumVisit) * (float)std::sqrt(parentNumVisit); return priorScore * puct + q; }; if (option.forcedRolloutsMultiplier && !node->getParent()) { // Forced rollouts; this only happens at the root node int maxForcedRollouts = forcedRollouts(1.0f, maxNumRollouts, option); for (auto& v : node->getChildren()) { Action actionIndex = v.first; const Node* child = v.second; int childNumVisit = child->getMctsStats().getNumVisit(); if (childNumVisit < maxForcedRollouts && childNumVisit < forcedRollouts(pi[actionIndex], maxNumRollouts, option)) { return actionIndex; } } } if (sample) { return sampleDiscreteProbability(pi.size(), [&](size_t index) { float score = getScore( index, node->getChild(index)); return std::exp(score * 4); }, rng); } else { float bestScore = -std::numeric_limits::infinity(); Action bestAction = InvalidAction; for (mcts::Action actionIndex = 0; actionIndex != (mcts::Action)pi.size(); ++actionIndex) { const Node* child = node->getChild(actionIndex); float score = getScore(actionIndex, child); if (score > bestScore) { bestScore = score; bestAction = actionIndex; } } return bestAction; } } namespace { std::atomic_uint64_t rolloutCount; std::chrono::steady_clock::time_point starttime; bool started = false; } // namespace int computeRolloutsImpl(const std::vector& rootNode, const std::vector& rootState, const std::vector& rnnState, core::Actor& actor, const MctsOption& option, double max_time, std::minstd_rand& rng) { double elapsedTime = 0; auto begin = std::chrono::steady_clock::now(); struct RolloutState { Node* root = nullptr; Node* node = nullptr; std::unique_ptr state; bool terminated = false; Storage* storage = nullptr; torch::Tensor rnnState; Node* forcedParent = nullptr; Action forcedAction = InvalidAction; }; std::vector states(rootNode.size()); async::Task task(threads::threads); size_t stride = (states.size() + threads::threads.size() - 1) / threads::threads.size(); std::vector reservedThreads(states.size()); for (size_t i = 0; i < states.size(); i += stride) { reservedThreads[i] = &threads::threads.getThread(); } int numRollout = 0; std::vector functionHandles(states.size()); int rollouts = option.totalTime ? 0 : option.numRolloutPerThread; bool keepGoing = false; for (size_t i = 0; i < states.size(); i += stride) { rng.discard(1); size_t n = std::min(states.size() - i, stride); auto f = [&, ii = i, n, rng]() mutable { size_t i = ii; for (size_t s = 0; s != n; ++s, ++i) { auto& st = states[i]; Node* root = rootNode[i]; st.root = root; if (!st.storage) { st.storage = Storage::getStorage(); } Storage* storage = st.storage; if (numRollout != 0) { Node* node = st.node; if (!st.terminated) { auto& state = *st.state; actor.batchResult(i, state, node->piVal_); core::getLegalPi( state, node->piVal_.logitPolicy, node->legalPolicy_); core::softmax_(node->legalPolicy_); node->piVal_.logitPolicy.reset(); } node->settle(st.root->getPiVal().playerId); float value = node->getPiVal().value; int flip = st.root->getPiVal().playerId == node->getPiVal().playerId ? 1 : -1; value = value * flip; // We need to flip here because at opponent's node, we have opponent's // value. We need to sum up our value. while (node != nullptr) { MctsStats& mctsStats = node->getMctsStats(); mctsStats.atomicUpdate(value, 0.0f); node = node->getParent(); } } if (!keepGoing) { continue; } Node* node = root; std::unique_ptr localState = std::move(st.state); const core::State* src = st.forcedParent ? &*st.forcedParent->localState() : rootState[i]; if (!src) { throw std::runtime_error("src state is null"); } if (!localState) { localState = src->clone(); } else { localState->copy(*src); } const torch::Tensor* rsp = nullptr; if (!rnnState.empty()) { rsp = &rnnState[i]; } // 1. Selection thread_local std::vector queuedActions; queuedActions.clear(); const core::State* checkpointState = nullptr; auto flushActions = [&]() { if (checkpointState) { localState->copy(*checkpointState); } if (!queuedActions.empty()) { for (Action a : queuedActions) { localState->forward(a); } queuedActions.clear(); } }; Node* parent = nullptr; Action action = InvalidAction; bool save = false; if (st.forcedParent) { parent = st.forcedParent; action = st.forcedAction; st.forcedParent = nullptr; node = parent->newChild(storage->newNode(), action); auto& state = *localState; if ((size_t)action >= state.GetLegalActions().size()) { throw std::runtime_error("forced rollout bad action :(("); } } else if (node->isVisited()) { while (true) { rsp = &node->piVal_.rnnState; Action bestAction = (option.samplingMcts ? pickBestAction : pickBestAction)(root->getPiVal().playerId, node, option, rng, rollouts); // this is a terminal state that has been visited if (bestAction == InvalidAction) { flushActions(); break; } Node* childNode = node->getChild(bestAction); if (childNode) { node = childNode; if (node->hasState()) { checkpointState = &node->getState(); queuedActions.clear(); } else { queuedActions.push_back(bestAction); } continue; } save = queuedActions.size() >= (size_t)option.storeStateInterval; flushActions(); childNode = node->newChild(storage->newNode(), bestAction); action = bestAction; parent = node; node = childNode; break; } auto& state = *localState; if (node->isVisited() && !state.terminated()) { if (state.GetLegalActions().empty()) { throw std::runtime_error( "MCTS error - no legal actions in unterminated game state"); } throw std::runtime_error("MCTS error - rollout ended on unvisited " "node with unterminated game state"); } } auto& state = *localState; auto saveState = [&](Node* saveNode) { if (saveNode->localState() && saveNode->localState()->typeId() == state.typeId()) { core::State* dst = &*saveNode->localState(); dst->copy(state); saveNode->setState(dst); } else { saveNode->localState() = localState->clone(); saveNode->setState(&*saveNode->localState()); } }; if (parent) { // Force visits to any children that share this policy output // location. const _Action& a = state.GetLegalActions().at(action); for (auto& x : state.GetLegalActions()) { if (x.GetIndex() != action && x.GetX() == a.GetX() && x.GetY() == a.GetY() && x.GetZ() == a.GetZ()) { if (!parent->getChild(x.GetIndex())) { st.forcedParent = parent; st.forcedAction = x.GetIndex(); if (!parent->hasState()) { saveState(parent); } break; } } } localState->forward(action); if (save) { saveState(node); } } // 2. Expansion if (state.terminated()) { PiVal& piVal = node->piVal_; piVal.value = state.getReward(state.getCurrentPlayer()) * 2.0f; piVal.playerId = state.getCurrentPlayer(); st.terminated = true; } else { st.terminated = false; } st.node = node; st.state = std::move(localState); actor.batchPrepare(i, state, rsp ? *rsp : torch::Tensor()); } }; functionHandles[i] = task.getHandle(*reservedThreads[i], std::move(f)); functionHandles[i].setPriority(common::getThreadId()); } actor.batchResize(states.size()); if (option.randomizedRollouts && rollouts >= 4) { float mean = std::uniform_int_distribution(0, 3)(rng) != 0 ? rollouts / 8.0f : rollouts * 2.0f; std::normal_distribution r(mean, rollouts / 4.0f); int max = rollouts * 4; do { rollouts = r(rng); } while (rollouts < 1 || rollouts > max); } while (true) { keepGoing = (option.totalTime ? elapsedTime < max_time : numRollout < option.numRolloutPerThread) || numRollout < 2; for (size_t i = 0; i < states.size(); i += stride) { task.enqueue(functionHandles[i]); } task.wait(); if (!keepGoing) { break; } actor.batchEvaluate(states.size()); rolloutCount += states.size(); ++numRollout; auto end = std::chrono::steady_clock::now(); elapsedTime = std::chrono::duration_cast< std::chrono::duration>>(end - begin) .count(); } for (const Node* root : rootNode) { mcts::Action bestAction = -1; int best = 0; for (auto& v : root->getChildren()) { const Node* child = v.second; if (child->getMctsStats().getNumVisit() > best) { best = child->getMctsStats().getNumVisit(); bestAction = v.first; } } if (bestAction != -1) { float bestPuct = puctValue(root->getPiVal().playerId, option.puct, root, bestAction); for (auto& v : root->getChildren()) { if (v.first == bestAction) { continue; } Node* child = v.second; int forced = forcedRollouts(root->legalPolicy_[v.first], rollouts, option); for (; forced && child->getMctsStats().getNumVisit(); --forced) { child->getMctsStats().subtractVisit(); float pv = puctValue(root->getPiVal().playerId, option.puct, root, v.first); if (pv > bestPuct) { child->getMctsStats().addVisit(); break; } } } } } return rollouts; } int computeRollouts(const std::vector& rootNode, const std::vector& rootState, const std::vector& rnnState, core::Actor& actor, const MctsOption& option, double max_time, std::minstd_rand& rng) { return computeRolloutsImpl( rootNode, rootState, rnnState, actor, option, max_time, rng); } std::vector MctsPlayer::actMcts( const std::vector& states, const std::vector& rnnState) { std::vector result(states.size(), &rng_); auto begin = std::chrono::steady_clock::now(); uint64_t beginRolloutCount = rolloutCount; if (!started) { started = true; starttime = begin; } std::vector roots; Storage* storage = Storage::getStorage(); for (auto* state : states) { Node* rootNode = storage->newNode(); rootNode->init(nullptr); roots.push_back(rootNode); if (state->terminated()) { throw std::runtime_error("Attempt to run MCTS from terminated state"); } } double thisMoveTime = remaining_time * option_.timeRatio; if (option_.totalTime) { std::cerr << "Remaining time:" << remaining_time << std::endl; std::cerr << "This move time:" << thisMoveTime << std::endl; } int rollouts = computeRollouts( roots, states, rnnState, *actor_, option_, thisMoveTime, rng_); if (option_.totalTime) { auto end = std::chrono::steady_clock::now(); remaining_time -= std::chrono::duration_cast< std::chrono::duration>>(end - begin) .count(); } for (size_t i = 0; i != states.size(); ++i) { Node* rootNode = roots[i]; assert(rootNode->getMctsStats().getVirtualLoss() == 0); if (option_.totalTime > 0) { std::cerr << "Value : " << rootNode->getMctsStats().getValue() << " total rollouts : " << rootNode->getMctsStats().getNumVisit() << std::endl; std::cerr << "Current value is (-1 to 1): " << rootNode->getMctsStats().getValue() / rootNode->getMctsStats().getNumVisit() << std::endl; } result[i].rollouts = rollouts; result[i].rootValue = rootNode->getMctsStats().getAvgValue(); for (auto& v : rootNode->getChildren()) { int visits = v.second->getMctsStats().getNumVisit(); if (visits > 1) { result[i].add(v.first, visits); } } if (result[i].bestAction == InvalidAction) { for (auto& v : rootNode->getChildren()) { int visits = v.second->getMctsStats().getNumVisit(); result[i].add(v.first, visits); } } result[i].normalize(); } for (size_t i = 0; i != states.size(); ++i) { if (result[i].bestAction == InvalidAction) { throw std::runtime_error( "MCTS could not find any valid actions at state " + states[i]->history()); } if (states[i]->getStepIdx() < option_.sampleBeforeStepIdx) { // std::cout << "sample:" << std::endl; result[i].sample(); } } for (size_t i = 0; i != states.size(); ++i) { auto* n = roots[i]->getChild(result[i].bestAction); if (n && n->getPiVal().rnnState.defined()) { result[i].rnnState = n->getPiVal().rnnState; } roots[i]->freeTree(); } bool verbose = false; if (verbose) { uint64_t n = rolloutCount - beginRolloutCount; double s = std::chrono::duration_cast< std::chrono::duration>>( std::chrono::steady_clock::now() - begin) .count(); rolloutsPerSecond_ = n / s; printf("rollouts per second: %g\n", rolloutsPerSecond_); double sx = std::chrono::duration_cast< std::chrono::duration>>( std::chrono::steady_clock::now() - starttime) .count(); printf("total rollouts per second: %g\n", rolloutCount / sx); } return result; } } // namespace mcts ================================================ FILE: src/mcts/mcts.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include #include #include "core/actor.h" #include "core/actor_player.h" #include "core/state.h" #include "mcts/node.h" #include "mcts/storage.h" #include "mcts/utils.h" namespace mcts { int computeRollouts(const std::vector& rootNode, const std::vector& rootState, const std::vector>& rnnState, core::Actor& actor, const MctsOption& option, double thisMoveTime, std::minstd_rand& rng); class MctsPlayer : public core::ActorPlayer { public: MctsPlayer(const MctsOption& option) : option_(option) , rng_(option.seed) { reset(); } std::vector actMcts(const std::vector& states, const std::vector& rnnState); MctsResult actMcts(const core::State& state) { return actMcts({&state}, {}).at(0); } MctsResult actMcts(const core::State& state, const torch::Tensor& rnnState) { return actMcts({&state}, {rnnState}).at(0); } double rolloutsPerSecond() { return rolloutsPerSecond_; } MctsOption& option() { return option_; } const MctsOption& option() const { return option_; } virtual void reset() override { remaining_time = option_.totalTime; } private: MctsOption option_; double remaining_time; std::minstd_rand rng_; // Storage storage_; double rolloutsPerSecond_ = 0.0; }; } // namespace mcts ================================================ FILE: src/mcts/node.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include "mcts/node.h" #include "mcts/storage.h" namespace mcts { void Node::init(Node* parent) { parent_ = nullptr; state_ = nullptr; children_.clear(); visited_ = false; mctsStats_.reset(); piVal_.reset(); legalPolicy_.clear(); parent_ = parent; } void Node::acquire() { // mSelf_.lock(); // holderThreadId_ = std::this_thread::get_id(); } void Node::release() { // assert(holderThreadId_ == std::this_thread::get_id()); // mSelf_.unlock(); } Node* Node::newChild(Node* child, Action action) { child->init(this); auto i = std::lower_bound(children_.begin(), children_.end(), action, [](auto& a, Action b) { return a.first < b; }); children_.insert(i, std::make_pair(action, child)); return child; } namespace { const std::vector emptyList; } Node* Node::getChild(Action action) const { auto i = std::lower_bound(children_.begin(), children_.end(), action, [](auto& a, Action b) { return a.first < b; }); return i == children_.end() || i->first != action ? nullptr : i->second; } void Node::freeTree() { piVal_.rnnState.reset(); for (auto& v : children_) { v.second->freeTree(); } storage_->freeNode(this); } void Node::printTree(int level, int maxLevel, int action) const { if (level > maxLevel) { return; } for (int i = 0; i < level; ++i) { std::cout << " "; } std::cout << action << " " << mctsStats_.getValue() << "/" << mctsStats_.getNumVisit(); std::cout << "(" << mctsStats_.getValue() / mctsStats_.getNumVisit() << ")"; std::cout << ", vloss:" << mctsStats_.getVirtualLoss() << std::endl; for (auto& v : getChildren()) { v.second->printTree(level + 1, maxLevel, v.first); } } } // namespace mcts ================================================ FILE: src/mcts/node.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include "core/state.h" #include "mcts/types.h" #include "mcts/utils.h" namespace mcts { class Storage; class Node { public: Node() : storage_(nullptr) , id_(0) { } void setStorageAndId(Storage* storage, NodeId id) { storage_ = storage; id_ = id; } Node(const Node&) = delete; Node& operator=(const Node&) = delete; void init(Node* parent); void acquire(); void release(); // caller is responsible for holding locks in case of multi-threading Node* newChild(Node* childNode, Action action); Node* getChild(Action action) const; MctsStats& getMctsStats() { return mctsStats_; } const MctsStats& getMctsStats() const { return mctsStats_; } const core::State& getState() const { return *state_; } bool hasState() const { return state_ != nullptr; } void setState(core::State* state) { state_ = state; } std::unique_ptr& localState() { return localState_; } NodeId getId() const { return id_; } const auto& getChildren() const { return children_; } Node* getParent() const { return parent_; } const PiVal& getPiVal() const { return piVal_; } void settle(int rootPlayerId) { // Only called when the node is locked. if (parent_ != nullptr) { auto& stats = parent_->getMctsStats(); float upValue = rootPlayerId == piVal_.playerId ? piVal_.value : -piVal_.value; stats.atomicUpdateChildV(upValue); } visited_ = true; } // free the entire tree rooted at this node void freeTree(); bool isVisited() { return visited_; } uint64_t getStateHash() { return stateHash_; } void printTree(int level, int maxLevel, int action) const; // private: // std::pair link; // set in constructor, should never be changed Storage* storage_; NodeId id_; // sync tools // std::mutex mSelf_; // std::thread::id holderThreadId_; // actual attributes Node* parent_; std::unique_ptr localState_; core::State* state_; uint64_t stateHash_; // std::unordered_map> children_; std::vector> children_; // int depth_; bool visited_; MctsStats mctsStats_; PiVal piVal_; std::vector legalPolicy_; }; } // namespace mcts ================================================ FILE: src/mcts/player.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include namespace mcts { class State; class Player { public: Player(bool isHuman) : isHuman_(isHuman) { isTP_ = false; } bool isHuman() const { return isHuman_; } bool isTP() const { return isTP_; } virtual void terminate() { } virtual void reset() { } virtual void newEpisode() { } virtual void recordMove(const State* state) { } virtual void result(const State*, float reward) { } virtual void setName(std::string name) { name_ = std::move(name); } const std::string& getName() { return name_; } private: std::string name_ = "unnamed"; bool isHuman_; protected: bool isTP_; }; } // namespace mcts ================================================ FILE: src/mcts/pybind.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include "mcts/mcts.h" namespace py = pybind11; PYBIND11_MODULE(mcts, m) { using namespace mcts; py::class_>( m, "MctsPlayer") .def(py::init(), py::call_guard()); py::class_(m, "MctsOption") .def(py::init<>()) .def(py::init()) .def_readwrite("puct", &MctsOption::puct) .def_readwrite("sample_before_step_idx", &MctsOption::sampleBeforeStepIdx) .def_readwrite("num_rollout_per_thread", &MctsOption::numRolloutPerThread) .def_readwrite("seed", &MctsOption::seed) .def_readwrite("virtual_loss", &MctsOption::virtualLoss) .def_readwrite("store_state_interval", &MctsOption::storeStateInterval) .def_readwrite("use_value_prior", &MctsOption::useValuePrior) .def_readwrite("time_ratio", &MctsOption::timeRatio) .def_readwrite("total_time", &MctsOption::totalTime) .def_readwrite("randomized_rollouts", &MctsOption::randomizedRollouts) .def_readwrite("sampling_mcts", &MctsOption::samplingMcts) .def_readwrite( "forced_rollouts_multiplier", &MctsOption::forcedRolloutsMultiplier); } ================================================ FILE: src/mcts/storage.cc ================================================ #include "storage.h" namespace mcts { std::mutex freeStoragesMutex; std::list freeStorages; Node* Storage::newNode() { if (chunkIndex >= chunks.size()) { Node* newChunk = (Node*)std::aligned_alloc(128, sizeof(Node) * chunkSize); new (newChunk) Node[chunkSize]; for (size_t i = 0; i != chunkSize; ++i) { newChunk[i].setStorageAndId(this, i); } chunks.push_back(newChunk); } Node* r = chunks[chunkIndex] + subIndex; ++subIndex; if (subIndex == chunkSize) { subIndex = 0; ++chunkIndex; } ++allocated; return r; } void Storage::freeNode(Node* node) { --allocated; if (allocated == 0) { chunkIndex = 0; subIndex = 0; std::lock_guard l(freeStoragesMutex); freeStorages.push_back(this); } } Storage* Storage::getStorage() { std::unique_lock l(freeStoragesMutex); if (freeStorages.empty()) { l.unlock(); return new Storage(); } Storage* r = freeStorages.back(); freeStorages.pop_back(); return r; } } // namespace mcts ================================================ FILE: src/mcts/storage.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "mcts/node.h" #include #include namespace mcts { class Storage { std::vector chunks; size_t chunkIndex = 0; size_t subIndex = 0; size_t allocated = 0; const size_t chunkSize = 16; public: Storage() = default; Storage(const Storage&) = delete; Storage& operator=(const Storage&) = delete; Node* newNode(); void freeNode(Node* node); static Storage* getStorage(); }; } // namespace mcts ================================================ FILE: src/mcts/test.cc ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "actor.h" #include "mcts.h" #include "types.h" #include "utils.h" #include #include #include #include #include using namespace mcts; std::atomic seed(0); class TicTacToeState : public State { public: TicTacToeState() : State() , rng_(seed++) { board.resize(9); std::fill(board.begin(), board.end(), 0); currentPlayer = 1; } int getCurrentPlayer() const override { return currentPlayer; } uint64_t getHash() const override { return 0; } float getReward(int player) const override { int r = winner; if (r == 0) r = checkWinner(); return r * player; }; // bool isStochastic() const override { // return false; // }; std::vector getLegalActions() const { std::vector actions; for (int i = 0; i < 9; i++) { if (board[i] == 0) { actions.push_back(i); } } return actions; } float getRandomRolloutReward(int player) const override { int numRandomRollout = 100; int totalReward = 0; for (int i = 0; i < numRandomRollout; ++i) { TicTacToeState state; // std::cout << "start random rollout" << std::endl; // state.printState(); state.board = board; state.currentPlayer = currentPlayer; state.moveIdx = moveIdx; while (!state.terminated()) { // state.printState(); auto actions = state.getLegalActions(); int idx = state.rng_() % actions.size(); // std::cout << idx << "," << actions[idx] << ";; "; state.forward(actions[idx]); // std::cout << "player " << player << ", action: " << actions[idx] << // std::endl; // state.printState(); } // std::cout << "+++++++end of random rollout +++++++, winner: " // << checkWinner() << std::endl; // state.winner = state.checkWinner(); totalReward += state.checkWinner() * player; } return totalReward / (float)numRandomRollout; } bool operator==(const State&) const override { return false; } int getStepIdx() const override { return moveIdx; } std::unique_ptr clone() const override { auto other = std::make_unique(); other->moveIdx = moveIdx; other->board = board; other->currentPlayer = currentPlayer; return other; // return std::make_unique(other); } const std::vector& getMoves() const override { return {}; } bool forward(const Action& a) override { assert(a >= 0 && a <= 8); if (board[a] != 0) { winner = -currentPlayer; } board[a] = currentPlayer; currentPlayer = -currentPlayer; moveIdx += 1; return true; } bool terminated() const override { return winner != 0 || checkWinner() != 0 || moveIdx == 9; } int at(int i, int j) const { // std::cout << i << j << std::endl; assert(i >= 0 && i < 3 && j >= 0 && j < 3); return board[i * 3 + j]; } void checkSum(int sum, int* winner) const { if (sum == 3) *winner = 1; if (sum == -3) *winner = -1; } int checkWinner() const { int w = 0; int sum = 0; for (int i = 0; i < 3; i++) { sum = 0; for (int j = 0; j < 3; j++) { sum += at(i, j); checkSum(sum, &w); } sum = 0; for (int j = 0; j < 3; j++) { sum += at(j, i); checkSum(sum, &w); } } sum = 0; for (int i = 0; i < 3; i++) { sum += at(i, i); checkSum(sum, &w); } sum = 0; for (int i = 0; i < 3; i++) { sum += at(i, 2 - i); checkSum(sum, &w); } return w; } void printState() { std::cout << "PRINT STATE===" << std::endl; std::cout << "current player is " << currentPlayer << std::endl; for (int i = 0; i < 9; ++i) { std::cout << std::setw(2); std::cout << board[i] << " "; if (i % 3 == 2) { std::cout << std::endl; } } // std::cout << std::endl; } std::vector board; int currentPlayer = 1; int winner = 0; int moveIdx = 0; std::mt19937 rng_; }; class TestActor : public Actor { public: TestActor() { } PiVal& evaluate(const State& s, PiVal& pival) override { const auto& state = dynamic_cast(&s); const auto& actions = state->getLegalActions(); std::vector pi; pi.resize(actions.size()); for (size_t i = 0; i < actions.size(); ++i) { pi[i] = 1.0 / actions.size(); } auto player = state->getCurrentPlayer(); float value = state->getRandomRolloutReward(state->getCurrentPlayer()); pival = PiVal(player, value, std::move(pi)); return pival; } }; int main(int argc, char* argv[]) { // args are thread, rollouts assert(argc == 3); TicTacToeState state; MctsOption option; // option.numThread = 2; option.numRolloutPerThread = std::stoi(std::string(argv[2])); option.puct = 1.0; option.virtualLoss = 1.0; std::vector> players; for (int i = 0; i < 2; ++i) { players.push_back(std::make_unique(option)); for (int j = 0; j < std::stoi(std::string(argv[1])); ++j) { players.at(i)->addActor(std::make_shared()); } } int i = 0; while (!state.terminated()) { int playerIdx = state.getCurrentPlayer() == 1 ? 0 : 1; MctsResult result = players.at(playerIdx)->actMcts(state); std::cout << "best action is " << result.bestAction << std::endl; state.forward(result.bestAction); state.printState(); std::cout << "-----------" << std::endl; ++i; // if (i > 1) { // break; // } } std::cout << "winner is " << state.checkWinner() << std::endl; assert(state.checkWinner() == 0); return 0; } ================================================ FILE: src/mcts/types.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include namespace mcts { using Action = int64_t; using NodeId = int64_t; const int InvalidAction = -1; } // namespace mcts ================================================ FILE: src/mcts/utils.h ================================================ /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include #include #include #include #include "core/actor.h" #include "mcts/types.h" namespace mcts { class MctsOption { public: float totalTime = 0; float timeRatio = 0.035; // coefficient of prior score float puct = 0.0; // first K steps in the game where we use sample instead of greedily // pick the best action. For example, if K = 6, then each player will // sample action based on mcts probability for their first 3 steps // in a two player game. int sampleBeforeStepIdx = 0; // num of rollout for each move int numRolloutPerThread = -1; int seed = 123; float virtualLoss = 0.0; // If true, initialize unvisited node with prior values from siblings bool useValuePrior = true; // Store the state in the MCTS node at multiples of this tree depth. int storeStateInterval = 1; bool randomizedRollouts = false; bool samplingMcts = false; float forcedRolloutsMultiplier = 2.0f; }; class MctsStats { public: MctsStats() { reset(); } void reset() { value_ = 0.0; numVisit_ = 0; virtualLoss_ = 0.0; sumChildV_ = 0.0; numChild_ = 0; } float getValue() const { // std::lock_guard lock(mSelf_); return value_; } int getNumVisit() const { // std::lock_guard lock(mSelf_); return numVisit_; } // Get prior child value (from the perspective of the current node). // // When a child hasn't been explored yet, we don't know its value and need to // use the "prior" from other children that has been explored before. // This is very important, otherwise the tree search could be overly- // optimistic and explore all actions once and waste a lot of rollouts (which // is bad for cases with high-branching factor). float getAvgChildV() const { if (numChild_ == 0) { return 0.0; } else { return sumChildV_ / numChild_; } } float getAvgValue() const { assert(numVisit_ > 0); return value_ / numVisit_; } float getVirtualLoss() const { return virtualLoss_; } void addVirtualLoss(float virtualLoss) { // std::lock_guard lock(mSelf_); virtualLoss_ += virtualLoss; } void atomicUpdate(float value, float virtualLoss) { // std::lock_guard lock(mSelf_); value_ += value; numVisit_++; virtualLoss_ -= virtualLoss; } // Update child value estimate with a new obtained child value // (from the perspective of the root node void atomicUpdateChildV(float childV) { // std::lock_guard lock(mSelf_); sumChildV_ += childV; numChild_++; } std::string summary() const { std::stringstream ss; ss << value_ << "/" << numVisit_ << " (" << value_ / numVisit_ << "), vloss: " << virtualLoss_; return ss.str(); } void subtractVisit() { --numVisit_; } void addVisit() { ++numVisit_; } private: float value_; int numVisit_; float virtualLoss_; // Summation of the value prediction from a child float sumChildV_; // # child that has been explored. int numChild_; // std::mutex mSelf_; }; template size_t sampleDiscreteProbability(size_t nElements, float maxValue, F&& getValue, Rng& rng) { if (nElements == 0) { throw std::runtime_error("sampleDiscreteProbability was passed 0 elements"); } for (size_t i = 0; i != 4; ++i) { size_t index = std::uniform_int_distribution(0.0f, nElements - 1)(rng); if (std::generate_canonical(rng) <= getValue(index) / maxValue) { return index; } } thread_local std::vector probs; probs.resize(nElements); float sum = 0.0f; for (size_t i = 0; i != nElements; ++i) { sum += getValue(i); probs[i] = sum; } float v = std::uniform_real_distribution(0.0f, sum)(rng); return std::lower_bound(probs.begin(), std::prev(probs.end()), v) - probs.begin(); } template size_t sampleDiscreteProbability(size_t nElements, F&& getValue, Rng& rng) { if (nElements == 0) { throw std::runtime_error("sampleDiscreteProbability was passed 0 elements"); } thread_local std::vector probs; probs.resize(nElements); float sum = 0.0f; for (size_t i = 0; i != nElements; ++i) { sum += getValue(i); probs[i] = sum; } float v = std::uniform_real_distribution(0.0f, sum)(rng); return std::lower_bound(probs.begin(), std::prev(probs.end()), v) - probs.begin(); } class MctsResult { public: MctsResult() = default; MctsResult(std::minstd_rand* rng) : maxVisits(-1000) , sumVisits(0) , bestAction(InvalidAction) , rng_(rng) { } void add(Action a, float visits) { if (mctsPolicy.size() <= (size_t)a) { if (mctsPolicy.capacity() <= (size_t)a) { mctsPolicy.reserve(mctsPolicy.size() * 2); } mctsPolicy.resize(a + 1); } mctsPolicy[a] = visits; sumVisits += visits; if (visits > maxVisits) { maxVisits = visits; bestAction = a; } } void normalize() { for (auto& value : mctsPolicy) { value = value / (float)sumVisits; } } // assume already normalized void sample() { auto weight = [this](float pival) { return std::exp(pival * pival * 2) - (1.0f - 0.5f / mctsPolicy.size()); }; float maxWeight = 0.0f; for (size_t i = 0; i != mctsPolicy.size(); ++i) { if (mctsPolicy[i] > maxWeight) { maxWeight = mctsPolicy[i]; } } maxWeight = weight(maxWeight); bestAction = sampleDiscreteProbability( mctsPolicy.size(), maxWeight, [&](size_t i) { return weight(mctsPolicy[i]); }, *rng_); } void setMctsPolicy(std::vector pi) { mctsPolicy = std::move(pi); } float maxVisits; float sumVisits; Action bestAction; std::vector mctsPolicy; float rootValue = 0.0f; int rollouts = 0; torch::Tensor rnnState; private: std::minstd_rand* rng_; }; using core::PiVal; inline void printPolicy(const std::vector& pi) { for (mcts::Action i = 0; i != (mcts::Action)pi.size(); ++i) { std::cout << i << ":" << pi[i] << std::endl; } } } // namespace mcts ================================================ FILE: src/third_party/asio/associated_allocator.hpp ================================================ // // associated_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_ASSOCIATED_ALLOCATOR_HPP #define ASIO_ASSOCIATED_ALLOCATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct associated_allocator_check { typedef void type; }; template struct associated_allocator_impl { typedef E type; static type get(const T&, const E& e) ASIO_NOEXCEPT { return e; } }; template struct associated_allocator_impl::type> { typedef typename T::allocator_type type; static type get(const T& t, const E&) ASIO_NOEXCEPT { return t.get_allocator(); } }; } // namespace detail /// Traits type used to obtain the allocator associated with an object. /** * A program may specialise this traits type if the @c T template parameter in * the specialisation is a user-defined type. The template parameter @c * Allocator shall be a type meeting the Allocator requirements. * * Specialisations shall meet the following requirements, where @c t is a const * reference to an object of type @c T, and @c a is an object of type @c * Allocator. * * @li Provide a nested typedef @c type that identifies a type meeting the * Allocator requirements. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t) and with return type @c type. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t,a) and with return type @c type. */ template > struct associated_allocator { /// If @c T has a nested type @c allocator_type, T::allocator_type. /// Otherwise @c Allocator. #if defined(GENERATING_DOCUMENTATION) typedef see_below type; #else // defined(GENERATING_DOCUMENTATION) typedef typename detail::associated_allocator_impl::type type; #endif // defined(GENERATING_DOCUMENTATION) /// If @c T has a nested type @c allocator_type, returns /// t.get_allocator(). Otherwise returns @c a. static type get(const T& t, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return detail::associated_allocator_impl::get(t, a); } }; /// Helper function to obtain an object's associated allocator. /** * @returns associated_allocator::get(t) */ template inline typename associated_allocator::type get_associated_allocator(const T& t) ASIO_NOEXCEPT { return associated_allocator::get(t); } /// Helper function to obtain an object's associated allocator. /** * @returns associated_allocator::get(t, a) */ template inline typename associated_allocator::type get_associated_allocator(const T& t, const Allocator& a) ASIO_NOEXCEPT { return associated_allocator::get(t, a); } #if defined(ASIO_HAS_ALIAS_TEMPLATES) template > using associated_allocator_t = typename associated_allocator::type; #endif // defined(ASIO_HAS_ALIAS_TEMPLATES) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_ASSOCIATED_ALLOCATOR_HPP ================================================ FILE: src/third_party/asio/associated_executor.hpp ================================================ // // associated_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_ASSOCIATED_EXECUTOR_HPP #define ASIO_ASSOCIATED_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/is_executor.hpp" #include "asio/system_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct associated_executor_check { typedef void type; }; template struct associated_executor_impl { typedef E type; static type get(const T&, const E& e) ASIO_NOEXCEPT { return e; } }; template struct associated_executor_impl::type> { typedef typename T::executor_type type; static type get(const T& t, const E&) ASIO_NOEXCEPT { return t.get_executor(); } }; } // namespace detail /// Traits type used to obtain the executor associated with an object. /** * A program may specialise this traits type if the @c T template parameter in * the specialisation is a user-defined type. The template parameter @c * Executor shall be a type meeting the Executor requirements. * * Specialisations shall meet the following requirements, where @c t is a const * reference to an object of type @c T, and @c e is an object of type @c * Executor. * * @li Provide a nested typedef @c type that identifies a type meeting the * Executor requirements. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t) and with return type @c type. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t,e) and with return type @c type. */ template struct associated_executor { /// If @c T has a nested type @c executor_type, T::executor_type. /// Otherwise @c Executor. #if defined(GENERATING_DOCUMENTATION) typedef see_below type; #else // defined(GENERATING_DOCUMENTATION) typedef typename detail::associated_executor_impl::type type; #endif // defined(GENERATING_DOCUMENTATION) /// If @c T has a nested type @c executor_type, returns /// t.get_executor(). Otherwise returns @c ex. static type get(const T& t, const Executor& ex = Executor()) ASIO_NOEXCEPT { return detail::associated_executor_impl::get(t, ex); } }; /// Helper function to obtain an object's associated executor. /** * @returns associated_executor::get(t) */ template inline typename associated_executor::type get_associated_executor(const T& t) ASIO_NOEXCEPT { return associated_executor::get(t); } /// Helper function to obtain an object's associated executor. /** * @returns associated_executor::get(t, ex) */ template inline typename associated_executor::type get_associated_executor(const T& t, const Executor& ex, typename enable_if::value>::type* = 0) ASIO_NOEXCEPT { return associated_executor::get(t, ex); } /// Helper function to obtain an object's associated executor. /** * @returns associated_executor::get(t, ctx.get_executor()) */ template inline typename associated_executor::type get_associated_executor(const T& t, ExecutionContext& ctx, typename enable_if::value>::type* = 0) ASIO_NOEXCEPT { return associated_executor::get(t, ctx.get_executor()); } #if defined(ASIO_HAS_ALIAS_TEMPLATES) template using associated_executor_t = typename associated_executor::type; #endif // defined(ASIO_HAS_ALIAS_TEMPLATES) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_ASSOCIATED_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/async_result.hpp ================================================ // // async_result.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_ASYNC_RESULT_HPP #define ASIO_ASYNC_RESULT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if defined(ASIO_HAS_CONCEPTS) \ && defined(ASIO_HAS_VARIADIC_TEMPLATES) \ && defined(ASIO_HAS_DECLTYPE) namespace detail { template struct is_completion_signature : false_type { }; template struct is_completion_signature : true_type { }; template ASIO_CONCEPT callable_with = requires(T t, Args&&... args) { t(static_cast(args)...); }; template struct is_completion_handler_for : false_type { }; template struct is_completion_handler_for : integral_constant)> { }; } // namespace detail template ASIO_CONCEPT completion_signature = detail::is_completion_signature::value; #define ASIO_COMPLETION_SIGNATURE \ ::asio::completion_signature template ASIO_CONCEPT completion_handler_for = detail::is_completion_handler_for::value; #define ASIO_COMPLETION_HANDLER_FOR(s) \ ::asio::completion_handler_for #else // defined(ASIO_HAS_CONCEPTS) // && defined(ASIO_HAS_VARIADIC_TEMPLATES) // && defined(ASIO_HAS_DECLTYPE) #define ASIO_COMPLETION_SIGNATURE typename #define ASIO_COMPLETION_HANDLER_FOR(s) typename #endif // defined(ASIO_HAS_CONCEPTS) // && defined(ASIO_HAS_VARIADIC_TEMPLATES) // && defined(ASIO_HAS_DECLTYPE) /// An interface for customising the behaviour of an initiating function. /** * The async_result traits class is used for determining: * * @li the concrete completion handler type to be called at the end of the * asynchronous operation; * * @li the initiating function return type; and * * @li how the return value of the initiating function is obtained. * * The trait allows the handler and return types to be determined at the point * where the specific completion handler signature is known. * * This template may be specialised for user-defined completion token types. * The primary template assumes that the CompletionToken is the completion * handler. */ template class async_result { public: /// The concrete completion handler type for the specific signature. typedef CompletionToken completion_handler_type; /// The return type of the initiating function. typedef void return_type; /// Construct an async result from a given handler. /** * When using a specalised async_result, the constructor has an opportunity * to initialise some state associated with the completion handler, which is * then returned from the initiating function. */ explicit async_result(completion_handler_type& h) { (void)h; } /// Obtain the value to be returned from the initiating function. return_type get() { } #if defined(GENERATING_DOCUMENTATION) /// Initiate the asynchronous operation that will produce the result, and /// obtain the value to be returned from the initiating function. template static return_type initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token, ASIO_MOVE_ARG(Args)... args); #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template static return_type initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token, ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_CAST(Initiation)(initiation)( ASIO_MOVE_CAST(RawCompletionToken)(token), ASIO_MOVE_CAST(Args)(args)...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template static return_type initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token) { ASIO_MOVE_CAST(Initiation)(initiation)( ASIO_MOVE_CAST(RawCompletionToken)(token)); } #define ASIO_PRIVATE_INITIATE_DEF(n) \ template \ static return_type initiate( \ ASIO_MOVE_ARG(Initiation) initiation, \ ASIO_MOVE_ARG(RawCompletionToken) token, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ ASIO_MOVE_CAST(Initiation)(initiation)( \ ASIO_MOVE_CAST(RawCompletionToken)(token), \ ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF) #undef ASIO_PRIVATE_INITIATE_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) private: async_result(const async_result&) ASIO_DELETED; async_result& operator=(const async_result&) ASIO_DELETED; }; #if !defined(GENERATING_DOCUMENTATION) template class async_result { // Empty. }; #endif // !defined(GENERATING_DOCUMENTATION) /// Helper template to deduce the handler type from a CompletionToken, capture /// a local copy of the handler, and then create an async_result for the /// handler. template struct async_completion { /// The real handler type to be used for the asynchronous operation. typedef typename asio::async_result< typename decay::type, Signature>::completion_handler_type completion_handler_type; #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Constructor. /** * The constructor creates the concrete completion handler and makes the link * between the handler and the asynchronous result. */ explicit async_completion(CompletionToken& token) : completion_handler(static_cast::value, completion_handler_type&, CompletionToken&&>::type>(token)), result(completion_handler) { } #else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) explicit async_completion(typename decay::type& token) : completion_handler(token), result(completion_handler) { } explicit async_completion(const typename decay::type& token) : completion_handler(token), result(completion_handler) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// A copy of, or reference to, a real handler object. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) typename conditional< is_same::value, completion_handler_type&, completion_handler_type>::type completion_handler; #else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) completion_handler_type completion_handler; #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// The result of the asynchronous operation's initiating function. async_result::type, Signature> result; }; namespace detail { template struct async_result_helper : async_result::type, Signature> { }; struct async_result_memfns_base { void initiate(); }; template struct async_result_memfns_derived : T, async_result_memfns_base { }; template struct async_result_memfns_check { }; template char (&async_result_initiate_memfn_helper(...))[2]; template char async_result_initiate_memfn_helper( async_result_memfns_check< void (async_result_memfns_base::*)(), &async_result_memfns_derived::initiate>*); template struct async_result_has_initiate_memfn : integral_constant::type, Signature> >(0)) != 1> { }; } // namespace detail #if defined(GENERATING_DOCUMENTATION) # define ASIO_INITFN_RESULT_TYPE(ct, sig) \ void_or_deduced #elif defined(_MSC_VER) && (_MSC_VER < 1500) # define ASIO_INITFN_RESULT_TYPE(ct, sig) \ typename ::asio::detail::async_result_helper< \ ct, sig>::return_type #define ASIO_HANDLER_TYPE(ct, sig) \ typename ::asio::detail::async_result_helper< \ ct, sig>::completion_handler_type #else # define ASIO_INITFN_RESULT_TYPE(ct, sig) \ typename ::asio::async_result< \ typename ::asio::decay::type, sig>::return_type #define ASIO_HANDLER_TYPE(ct, sig) \ typename ::asio::async_result< \ typename ::asio::decay::type, sig>::completion_handler_type #endif #if defined(GENERATION_DOCUMENTATION) # define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \ auto #elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION) # define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \ auto #else # define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \ ASIO_INITFN_RESULT_TYPE(ct, sig) #endif #if defined(GENERATION_DOCUMENTATION) # define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \ void_or_deduced #elif defined(ASIO_HAS_DECLTYPE) # define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \ decltype expr #else # define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \ ASIO_INITFN_RESULT_TYPE(ct, sig) #endif #if defined(GENERATING_DOCUMENTATION) template void_or_deduced async_initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken), ASIO_MOVE_ARG(Args)... args); #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template inline typename enable_if< detail::async_result_has_initiate_memfn::value, ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, (async_result::type, Signature>::initiate(declval(), declval(), declval()...)))>::type async_initiate(ASIO_MOVE_ARG(Initiation) initiation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, ASIO_MOVE_ARG(Args)... args) { return async_result::type, Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), ASIO_MOVE_CAST(CompletionToken)(token), ASIO_MOVE_CAST(Args)(args)...); } template inline typename enable_if< !detail::async_result_has_initiate_memfn::value, ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type async_initiate(ASIO_MOVE_ARG(Initiation) initiation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, ASIO_MOVE_ARG(Args)... args) { async_completion completion(token); ASIO_MOVE_CAST(Initiation)(initiation)( ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, Signature))(completion.completion_handler), ASIO_MOVE_CAST(Args)(args)...); return completion.result.get(); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template inline typename enable_if< detail::async_result_has_initiate_memfn::value, ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, (async_result::type, Signature>::initiate(declval(), declval())))>::type async_initiate(ASIO_MOVE_ARG(Initiation) initiation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) { return async_result::type, Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), ASIO_MOVE_CAST(CompletionToken)(token)); } template inline typename enable_if< !detail::async_result_has_initiate_memfn::value, ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type async_initiate(ASIO_MOVE_ARG(Initiation) initiation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) { async_completion completion(token); ASIO_MOVE_CAST(Initiation)(initiation)( ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, Signature))(completion.completion_handler)); return completion.result.get(); } #define ASIO_PRIVATE_INITIATE_DEF(n) \ template \ inline typename enable_if< \ detail::async_result_has_initiate_memfn< \ CompletionToken, Signature>::value, \ ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, \ (async_result::type, \ Signature>::initiate(declval(), \ declval(), \ ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ return async_result::type, \ Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), \ ASIO_MOVE_CAST(CompletionToken)(token), \ ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template \ inline typename enable_if< \ !detail::async_result_has_initiate_memfn< \ CompletionToken, Signature>::value, \ ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ async_completion completion(token); \ \ ASIO_MOVE_CAST(Initiation)(initiation)( \ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, \ Signature))(completion.completion_handler), \ ASIO_VARIADIC_MOVE_ARGS(n)); \ \ return completion.result.get(); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF) #undef ASIO_PRIVATE_INITIATE_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) #if defined(ASIO_HAS_CONCEPTS) \ && defined(ASIO_HAS_VARIADIC_TEMPLATES) \ && defined(ASIO_HAS_DECLTYPE) namespace detail { template struct initiation_archetype { template CompletionHandler> void operator()(CompletionHandler&&) const { } }; } // namespace detail template ASIO_CONCEPT completion_token_for = requires(T&& t) { async_initiate(detail::initiation_archetype{}, t); }; #define ASIO_COMPLETION_TOKEN_FOR(s) \ ::asio::completion_token_for #else // defined(ASIO_HAS_CONCEPTS) // && defined(ASIO_HAS_VARIADIC_TEMPLATES) // && defined(ASIO_HAS_DECLTYPE) #define ASIO_COMPLETION_TOKEN_FOR(s) typename #endif // defined(ASIO_HAS_CONCEPTS) // && defined(ASIO_HAS_VARIADIC_TEMPLATES) // && defined(ASIO_HAS_DECLTYPE) namespace detail { template struct default_completion_token_check { typedef void type; }; template struct default_completion_token_impl { typedef void type; }; template struct default_completion_token_impl::type> { typedef typename T::default_completion_token_type type; }; } // namespace detail #if defined(GENERATING_DOCUMENTATION) /// Traits type used to determine the default completion token type associated /// with a type (such as an executor). /** * A program may specialise this traits type if the @c T template parameter in * the specialisation is a user-defined type. * * Specialisations of this trait may provide a nested typedef @c type, which is * a default-constructible completion token type. */ template struct default_completion_token { /// If @c T has a nested type @c default_completion_token_type, /// T::default_completion_token_type. Otherwise the typedef @c type /// is not defined. typedef see_below type; }; #else template struct default_completion_token : detail::default_completion_token_impl { }; #endif #if defined(ASIO_HAS_ALIAS_TEMPLATES) template using default_completion_token_t = typename default_completion_token::type; #endif // defined(ASIO_HAS_ALIAS_TEMPLATES) #if defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) #define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \ = typename ::asio::default_completion_token::type #define ASIO_DEFAULT_COMPLETION_TOKEN(e) \ = typename ::asio::default_completion_token::type() #else // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) #define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) #define ASIO_DEFAULT_COMPLETION_TOKEN(e) #endif // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_ASYNC_RESULT_HPP ================================================ FILE: src/third_party/asio/awaitable.hpp ================================================ // // awaitable.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_AWAITABLE_HPP #define ASIO_AWAITABLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) #include #include "asio/executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { using std::experimental::coroutine_handle; using std::experimental::suspend_always; template class awaitable_thread; template class awaitable_frame; } // namespace detail /// The return type of a coroutine or asynchronous operation. template class awaitable { public: /// The type of the awaited value. typedef T value_type; /// The executor type that will be used for the coroutine. typedef Executor executor_type; /// Default constructor. constexpr awaitable() noexcept : frame_(nullptr) { } /// Move constructor. awaitable(awaitable&& other) noexcept : frame_(std::exchange(other.frame_, nullptr)) { } /// Destructor ~awaitable() { if (frame_) frame_->destroy(); } /// Checks if the awaitable refers to a future result. bool valid() const noexcept { return !!frame_; } #if !defined(GENERATING_DOCUMENTATION) // Support for co_await keyword. bool await_ready() const noexcept { return false; } // Support for co_await keyword. template void await_suspend( detail::coroutine_handle> h) { frame_->push_frame(&h.promise()); } // Support for co_await keyword. T await_resume() { return frame_->get(); } #endif // !defined(GENERATING_DOCUMENTATION) private: template friend class detail::awaitable_thread; template friend class detail::awaitable_frame; // Not copy constructible or copy assignable. awaitable(const awaitable&) = delete; awaitable& operator=(const awaitable&) = delete; // Construct the awaitable from a coroutine's frame object. explicit awaitable(detail::awaitable_frame* a) : frame_(a) { } detail::awaitable_frame* frame_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/awaitable.hpp" #endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_AWAITABLE_HPP ================================================ FILE: src/third_party/asio/basic_datagram_socket.hpp ================================================ // // basic_datagram_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_DATAGRAM_SOCKET_HPP #define ASIO_BASIC_DATAGRAM_SOCKET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) #define ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL // Forward declaration with defaulted arguments. template class basic_datagram_socket; #endif // !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) /// Provides datagram-oriented socket functionality. /** * The basic_datagram_socket class template provides asynchronous and blocking * datagram-oriented socket functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_datagram_socket : public basic_socket { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the socket type to another executor. template struct rebind_executor { /// The socket type when rebound to the specified executor. typedef basic_datagram_socket other; }; /// The native representation of a socket. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef typename basic_socket::native_handle_type native_handle_type; #endif /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; /// Construct a basic_datagram_socket without opening it. /** * This constructor creates a datagram socket without opening it. The open() * function must be called before data can be sent or received on the socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. */ explicit basic_datagram_socket(const executor_type& ex) : basic_socket(ex) { } /// Construct a basic_datagram_socket without opening it. /** * This constructor creates a datagram socket without opening it. The open() * function must be called before data can be sent or received on the socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. */ template explicit basic_datagram_socket(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context) { } /// Construct and open a basic_datagram_socket. /** * This constructor creates and opens a datagram socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ basic_datagram_socket(const executor_type& ex, const protocol_type& protocol) : basic_socket(ex, protocol) { } /// Construct and open a basic_datagram_socket. /** * This constructor creates and opens a datagram socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ template basic_datagram_socket(ExecutionContext& context, const protocol_type& protocol, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol) { } /// Construct a basic_datagram_socket, opening it and binding it to the given /// local endpoint. /** * This constructor creates a datagram socket and automatically opens it bound * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the datagram * socket will be bound. * * @throws asio::system_error Thrown on failure. */ basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint) : basic_socket(ex, endpoint) { } /// Construct a basic_datagram_socket, opening it and binding it to the given /// local endpoint. /** * This constructor creates a datagram socket and automatically opens it bound * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the datagram * socket will be bound. * * @throws asio::system_error Thrown on failure. */ template basic_datagram_socket(ExecutionContext& context, const endpoint_type& endpoint, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, endpoint) { } /// Construct a basic_datagram_socket on an existing native socket. /** * This constructor creates a datagram socket object to hold an existing * native socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ basic_datagram_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) : basic_socket(ex, protocol, native_socket) { } /// Construct a basic_datagram_socket on an existing native socket. /** * This constructor creates a datagram socket object to hold an existing * native socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ template basic_datagram_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol, native_socket) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_datagram_socket from another. /** * This constructor moves a datagram socket from one object to another. * * @param other The other basic_datagram_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_datagram_socket(const executor_type&) * constructor. */ basic_datagram_socket(basic_datagram_socket&& other) ASIO_NOEXCEPT : basic_socket(std::move(other)) { } /// Move-assign a basic_datagram_socket from another. /** * This assignment operator moves a datagram socket from one object to * another. * * @param other The other basic_datagram_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_datagram_socket(const executor_type&) * constructor. */ basic_datagram_socket& operator=(basic_datagram_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } /// Move-construct a basic_datagram_socket from a socket of another protocol /// type. /** * This constructor moves a datagram socket from one object to another. * * @param other The other basic_datagram_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_datagram_socket(const executor_type&) * constructor. */ template basic_datagram_socket(basic_datagram_socket&& other, typename enable_if< is_convertible::value && is_convertible::value >::type* = 0) : basic_socket(std::move(other)) { } /// Move-assign a basic_datagram_socket from a socket of another protocol /// type. /** * This assignment operator moves a datagram socket from one object to * another. * * @param other The other basic_datagram_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_datagram_socket(const executor_type&) * constructor. */ template typename enable_if< is_convertible::value && is_convertible::value, basic_datagram_socket& >::type operator=(basic_datagram_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /** * This function destroys the socket, cancelling any outstanding asynchronous * operations associated with the socket as if by calling @c cancel. */ ~basic_datagram_socket() { } /// Send some data on a connected socket. /** * This function is used to send data on the datagram socket. The function * call will block until the data has been sent successfully or an error * occurs. * * @param buffers One ore more data buffers to be sent on the socket. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected datagram socket. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code socket.send(asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t send(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "send"); return s; } /// Send some data on a connected socket. /** * This function is used to send data on the datagram socket. The function * call will block until the data has been sent successfully or an error * occurs. * * @param buffers One ore more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected datagram socket. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); asio::detail::throw_error(ec, "send"); return s; } /// Send some data on a connected socket. /** * This function is used to send data on the datagram socket. The function * call will block until the data has been sent successfully or an error * occurs. * * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected datagram socket. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous send on a connected socket. /** * This function is used to asynchronously send data on the datagram socket. * The function call always returns immediately. * * @param buffers One or more data buffers to be sent on the socket. Although * the buffers object may be copied as necessary, ownership of the underlying * memory blocks is retained by the caller, which must guarantee that they * remain valid until the handler is called. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected datagram * socket. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.async_send(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, socket_base::message_flags(0)); } /// Start an asynchronous send on a connected socket. /** * This function is used to asynchronously send data on the datagram socket. * The function call always returns immediately. * * @param buffers One or more data buffers to be sent on the socket. Although * the buffers object may be copied as necessary, ownership of the underlying * memory blocks is retained by the caller, which must guarantee that they * remain valid until the handler is called. * * @param flags Flags specifying how the send call is to be made. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected datagram * socket. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, flags); } /// Send a datagram to the specified endpoint. /** * This function is used to send a datagram to the specified remote endpoint. * The function call will block until the data has been sent successfully or * an error occurs. * * @param buffers One or more data buffers to be sent to the remote endpoint. * * @param destination The remote endpoint to which the data will be sent. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * asio::ip::udp::endpoint destination( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.send_to(asio::buffer(data, size), destination); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t send_to(const ConstBufferSequence& buffers, const endpoint_type& destination) { asio::error_code ec; std::size_t s = this->impl_.get_service().send_to( this->impl_.get_implementation(), buffers, destination, 0, ec); asio::detail::throw_error(ec, "send_to"); return s; } /// Send a datagram to the specified endpoint. /** * This function is used to send a datagram to the specified remote endpoint. * The function call will block until the data has been sent successfully or * an error occurs. * * @param buffers One or more data buffers to be sent to the remote endpoint. * * @param destination The remote endpoint to which the data will be sent. * * @param flags Flags specifying how the send call is to be made. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. */ template std::size_t send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().send_to( this->impl_.get_implementation(), buffers, destination, flags, ec); asio::detail::throw_error(ec, "send_to"); return s; } /// Send a datagram to the specified endpoint. /** * This function is used to send a datagram to the specified remote endpoint. * The function call will block until the data has been sent successfully or * an error occurs. * * @param buffers One or more data buffers to be sent to the remote endpoint. * * @param destination The remote endpoint to which the data will be sent. * * @param flags Flags specifying how the send call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. */ template std::size_t send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().send_to(this->impl_.get_implementation(), buffers, destination, flags, ec); } /// Start an asynchronous send. /** * This function is used to asynchronously send a datagram to the specified * remote endpoint. The function call always returns immediately. * * @param buffers One or more data buffers to be sent to the remote endpoint. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param destination The remote endpoint to which the data will be sent. * Copies will be made of the endpoint as required. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * asio::ip::udp::endpoint destination( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.async_send_to( * asio::buffer(data, size), destination, handler); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send_to(this), handler, buffers, destination, socket_base::message_flags(0)); } /// Start an asynchronous send. /** * This function is used to asynchronously send a datagram to the specified * remote endpoint. The function call always returns immediately. * * @param buffers One or more data buffers to be sent to the remote endpoint. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param flags Flags specifying how the send call is to be made. * * @param destination The remote endpoint to which the data will be sent. * Copies will be made of the endpoint as required. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send_to(this), handler, buffers, destination, flags); } /// Receive some data on a connected socket. /** * This function is used to receive data on the datagram socket. The function * call will block until data has been received successfully or an error * occurs. * * @param buffers One or more buffers into which the data will be received. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected datagram * socket. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code socket.receive(asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on a connected socket. /** * This function is used to receive data on the datagram socket. The function * call will block until data has been received successfully or an error * occurs. * * @param buffers One or more buffers into which the data will be received. * * @param flags Flags specifying how the receive call is to be made. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected datagram * socket. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, flags, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on a connected socket. /** * This function is used to receive data on the datagram socket. The function * call will block until data has been received successfully or an error * occurs. * * @param buffers One or more buffers into which the data will be received. * * @param flags Flags specifying how the receive call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected datagram * socket. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous receive on a connected socket. /** * This function is used to asynchronously receive data from the datagram * socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected * datagram socket. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.async_receive(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive(this), handler, buffers, socket_base::message_flags(0)); } /// Start an asynchronous receive on a connected socket. /** * This function is used to asynchronously receive data from the datagram * socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param flags Flags specifying how the receive call is to be made. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected * datagram socket. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive(this), handler, buffers, flags); } /// Receive a datagram with the endpoint of the sender. /** * This function is used to receive a datagram. The function call will block * until data has been received successfully or an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the datagram. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * asio::ip::udp::endpoint sender_endpoint; * socket.receive_from( * asio::buffer(data, size), sender_endpoint); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive_from( this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); asio::detail::throw_error(ec, "receive_from"); return s; } /// Receive a datagram with the endpoint of the sender. /** * This function is used to receive a datagram. The function call will block * until data has been received successfully or an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the datagram. * * @param flags Flags specifying how the receive call is to be made. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. */ template std::size_t receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive_from( this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); asio::detail::throw_error(ec, "receive_from"); return s; } /// Receive a datagram with the endpoint of the sender. /** * This function is used to receive a datagram. The function call will block * until data has been received successfully or an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the datagram. * * @param flags Flags specifying how the receive call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. */ template std::size_t receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().receive_from( this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive a datagram. The function * call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the datagram. Ownership of the sender_endpoint object * is retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code socket.async_receive_from( * asio::buffer(data, size), sender_endpoint, handler); @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive_from(this), handler, buffers, &sender_endpoint, socket_base::message_flags(0)); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive a datagram. The function * call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the datagram. Ownership of the sender_endpoint object * is retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param flags Flags specifying how the receive call is to be made. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive_from(this), handler, buffers, &sender_endpoint, flags); } private: class initiate_async_send { public: typedef Executor executor_type; explicit initiate_async_send(basic_datagram_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_send( self_->impl_.get_implementation(), buffers, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_datagram_socket* self_; }; class initiate_async_send_to { public: typedef Executor executor_type; explicit initiate_async_send_to(basic_datagram_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_send_to( self_->impl_.get_implementation(), buffers, destination, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_datagram_socket* self_; }; class initiate_async_receive { public: typedef Executor executor_type; explicit initiate_async_receive(basic_datagram_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_receive( self_->impl_.get_implementation(), buffers, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_datagram_socket* self_; }; class initiate_async_receive_from { public: typedef Executor executor_type; explicit initiate_async_receive_from(basic_datagram_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, endpoint_type* sender_endpoint, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_receive_from( self_->impl_.get_implementation(), buffers, *sender_endpoint, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_datagram_socket* self_; }; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_DATAGRAM_SOCKET_HPP ================================================ FILE: src/third_party/asio/basic_deadline_timer.hpp ================================================ // // basic_deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_DEADLINE_TIMER_HPP #define ASIO_BASIC_DEADLINE_TIMER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) #include #include "asio/detail/deadline_timer_service.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/time_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Provides waitable timer functionality. /** * The basic_deadline_timer class template provides the ability to perform a * blocking or asynchronous wait for a timer to expire. * * A deadline timer is always in one of two states: "expired" or "not expired". * If the wait() or async_wait() function is called on an expired timer, the * wait operation will complete immediately. * * Most applications will use the asio::deadline_timer typedef. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Examples * Performing a blocking wait: * @code * // Construct a timer without setting an expiry time. * asio::deadline_timer timer(my_context); * * // Set an expiry time relative to now. * timer.expires_from_now(boost::posix_time::seconds(5)); * * // Wait for the timer to expire. * timer.wait(); * @endcode * * @par * Performing an asynchronous wait: * @code * void handler(const asio::error_code& error) * { * if (!error) * { * // Timer expired. * } * } * * ... * * // Construct a timer with an absolute expiry time. * asio::deadline_timer timer(my_context, * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); * * // Start an asynchronous wait. * timer.async_wait(handler); * @endcode * * @par Changing an active deadline_timer's expiry time * * Changing the expiry time of a timer while there are pending asynchronous * waits causes those wait operations to be cancelled. To ensure that the action * associated with the timer is performed only once, use something like this: * used: * * @code * void on_some_event() * { * if (my_timer.expires_from_now(seconds(5)) > 0) * { * // We managed to cancel the timer. Start new asynchronous wait. * my_timer.async_wait(on_timeout); * } * else * { * // Too late, timer has already expired! * } * } * * void on_timeout(const asio::error_code& e) * { * if (e != asio::error::operation_aborted) * { * // Timer was not cancelled, take necessary action. * } * } * @endcode * * @li The asio::basic_deadline_timer::expires_from_now() function * cancels any pending asynchronous waits, and returns the number of * asynchronous waits that were cancelled. If it returns 0 then you were too * late and the wait handler has already been executed, or will soon be * executed. If it returns 1 then the wait handler was successfully cancelled. * * @li If a wait handler is cancelled, the asio::error_code passed to * it contains the value asio::error::operation_aborted. */ template , typename Executor = executor> class basic_deadline_timer { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the timer type to another executor. template struct rebind_executor { /// The timer type when rebound to the specified executor. typedef basic_deadline_timer other; }; /// The time traits type. typedef TimeTraits traits_type; /// The time type. typedef typename traits_type::time_type time_type; /// The duration type. typedef typename traits_type::duration_type duration_type; /// Constructor. /** * This constructor creates a timer without setting an expiry time. The * expires_at() or expires_from_now() functions must be called to set an * expiry time before the timer can be waited on. * * @param ex The I/O executor that the timer will use, by default, to * dispatch handlers for any asynchronous operations performed on the timer. */ explicit basic_deadline_timer(const executor_type& ex) : impl_(ex) { } /// Constructor. /** * This constructor creates a timer without setting an expiry time. The * expires_at() or expires_from_now() functions must be called to set an * expiry time before the timer can be waited on. * * @param context An execution context which provides the I/O executor that * the timer will use, by default, to dispatch handlers for any asynchronous * operations performed on the timer. */ template explicit basic_deadline_timer(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { } /// Constructor to set a particular expiry time as an absolute time. /** * This constructor creates a timer and sets the expiry time. * * @param ex The I/O executor that the timer will use, by default, to * dispatch handlers for any asynchronous operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, expressed * as an absolute time. */ basic_deadline_timer(const executor_type& ex, const time_type& expiry_time) : impl_(ex) { asio::error_code ec; impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); } /// Constructor to set a particular expiry time as an absolute time. /** * This constructor creates a timer and sets the expiry time. * * @param context An execution context which provides the I/O executor that * the timer will use, by default, to dispatch handlers for any asynchronous * operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, expressed * as an absolute time. */ template basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); } /// Constructor to set a particular expiry time relative to now. /** * This constructor creates a timer and sets the expiry time. * * @param ex The I/O executor that the timer will use, by default, to * dispatch handlers for any asynchronous operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, relative to * now. */ basic_deadline_timer(const executor_type& ex, const duration_type& expiry_time) : impl_(ex) { asio::error_code ec; impl_.get_service().expires_from_now( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_from_now"); } /// Constructor to set a particular expiry time relative to now. /** * This constructor creates a timer and sets the expiry time. * * @param context An execution context which provides the I/O executor that * the timer will use, by default, to dispatch handlers for any asynchronous * operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, relative to * now. */ template basic_deadline_timer(ExecutionContext& context, const duration_type& expiry_time, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().expires_from_now( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_from_now"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_deadline_timer from another. /** * This constructor moves a timer from one object to another. * * @param other The other basic_deadline_timer object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_deadline_timer(const executor_type&) * constructor. */ basic_deadline_timer(basic_deadline_timer&& other) : impl_(std::move(other.impl_)) { } /// Move-assign a basic_deadline_timer from another. /** * This assignment operator moves a timer from one object to another. Cancels * any outstanding asynchronous operations associated with the target object. * * @param other The other basic_deadline_timer object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_deadline_timer(const executor_type&) * constructor. */ basic_deadline_timer& operator=(basic_deadline_timer&& other) { impl_ = std::move(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the timer. /** * This function destroys the timer, cancelling any outstanding asynchronous * wait operations associated with the timer as if by calling @c cancel. */ ~basic_deadline_timer() { } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Cancel any asynchronous operations that are waiting on the timer. /** * This function forces the completion of any pending asynchronous wait * operations against the timer. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @return The number of asynchronous operations that were cancelled. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when cancel() is called, then the * handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel() { asio::error_code ec; std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); return s; } /// Cancel any asynchronous operations that are waiting on the timer. /** * This function forces the completion of any pending asynchronous wait * operations against the timer. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. * * @note If the timer has already expired when cancel() is called, then the * handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel(asio::error_code& ec) { return impl_.get_service().cancel(impl_.get_implementation(), ec); } /// Cancels one asynchronous operation that is waiting on the timer. /** * This function forces the completion of one pending asynchronous wait * operation against the timer. Handlers are cancelled in FIFO order. The * handler for the cancelled operation will be invoked with the * asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @return The number of asynchronous operations that were cancelled. That is, * either 0 or 1. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when cancel_one() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel_one() { asio::error_code ec; std::size_t s = impl_.get_service().cancel_one( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel_one"); return s; } /// Cancels one asynchronous operation that is waiting on the timer. /** * This function forces the completion of one pending asynchronous wait * operation against the timer. Handlers are cancelled in FIFO order. The * handler for the cancelled operation will be invoked with the * asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. That is, * either 0 or 1. * * @note If the timer has already expired when cancel_one() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel_one(asio::error_code& ec) { return impl_.get_service().cancel_one(impl_.get_implementation(), ec); } /// Get the timer's expiry time as an absolute time. /** * This function may be used to obtain the timer's current expiry time. * Whether the timer has expired or not does not affect this value. */ time_type expires_at() const { return impl_.get_service().expires_at(impl_.get_implementation()); } /// Set the timer's expiry time as an absolute time. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @return The number of asynchronous operations that were cancelled. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when expires_at() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_at(const time_type& expiry_time) { asio::error_code ec; std::size_t s = impl_.get_service().expires_at( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); return s; } /// Set the timer's expiry time as an absolute time. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. * * @note If the timer has already expired when expires_at() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_at(const time_type& expiry_time, asio::error_code& ec) { return impl_.get_service().expires_at( impl_.get_implementation(), expiry_time, ec); } /// Get the timer's expiry time relative to now. /** * This function may be used to obtain the timer's current expiry time. * Whether the timer has expired or not does not affect this value. */ duration_type expires_from_now() const { return impl_.get_service().expires_from_now(impl_.get_implementation()); } /// Set the timer's expiry time relative to now. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @return The number of asynchronous operations that were cancelled. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when expires_from_now() is called, * then the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_from_now(const duration_type& expiry_time) { asio::error_code ec; std::size_t s = impl_.get_service().expires_from_now( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_from_now"); return s; } /// Set the timer's expiry time relative to now. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. * * @note If the timer has already expired when expires_from_now() is called, * then the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_from_now(const duration_type& expiry_time, asio::error_code& ec) { return impl_.get_service().expires_from_now( impl_.get_implementation(), expiry_time, ec); } /// Perform a blocking wait on the timer. /** * This function is used to wait for the timer to expire. This function * blocks and does not return until the timer has expired. * * @throws asio::system_error Thrown on failure. */ void wait() { asio::error_code ec; impl_.get_service().wait(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "wait"); } /// Perform a blocking wait on the timer. /** * This function is used to wait for the timer to expire. This function * blocks and does not return until the timer has expired. * * @param ec Set to indicate what error occurred, if any. */ void wait(asio::error_code& ec) { impl_.get_service().wait(impl_.get_implementation(), ec); } /// Start an asynchronous wait on the timer. /** * This function may be used to initiate an asynchronous wait against the * timer. It always returns immediately. * * For each call to async_wait(), the supplied handler will be called exactly * once. The handler will be called when: * * @li The timer has expired. * * @li The timer was cancelled, in which case the handler is passed the error * code asio::error::operation_aborted. * * @param handler The handler to be called when the timer expires. Copies * will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (asio::error_code)) async_wait( ASIO_MOVE_ARG(WaitHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_wait(this), handler); } private: // Disallow copying and assignment. basic_deadline_timer(const basic_deadline_timer&) ASIO_DELETED; basic_deadline_timer& operator=( const basic_deadline_timer&) ASIO_DELETED; class initiate_async_wait { public: typedef Executor executor_type; explicit initiate_async_wait(basic_deadline_timer* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler. ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_wait( self_->impl_.get_implementation(), handler2.value, self_->impl_.get_implementation_executor()); } private: basic_deadline_timer* self_; }; detail::io_object_impl< detail::deadline_timer_service, Executor> impl_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_BASIC_DEADLINE_TIMER_HPP ================================================ FILE: src/third_party/asio/basic_io_object.hpp ================================================ // // basic_io_object.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_IO_OBJECT_HPP #define ASIO_BASIC_IO_OBJECT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if defined(ASIO_HAS_MOVE) namespace detail { // Type trait used to determine whether a service supports move. template class service_has_move { private: typedef IoObjectService service_type; typedef typename service_type::implementation_type implementation_type; template static auto asio_service_has_move_eval(T* t, U* u) -> decltype(t->move_construct(*u, *u), char()); static char (&asio_service_has_move_eval(...))[2]; public: static const bool value = sizeof(asio_service_has_move_eval( static_cast(0), static_cast(0))) == 1; }; } #endif // defined(ASIO_HAS_MOVE) /// Base class for all I/O objects. /** * @note All I/O objects are non-copyable. However, when using C++0x, certain * I/O objects do support move construction and move assignment. */ #if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template #else template ::value> #endif class basic_io_object { public: /// The type of the service that will be used to provide I/O operations. typedef IoObjectService service_type; /// The underlying implementation type of I/O object. typedef typename service_type::implementation_type implementation_type; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use get_executor().) Get the io_context associated with the /// object. /** * This function may be used to obtain the io_context object that the I/O * object uses to dispatch handlers for asynchronous operations. * * @return A reference to the io_context object that the I/O object will use * to dispatch handlers. Ownership is not transferred to the caller. */ asio::io_context& get_io_context() { return service_.get_io_context(); } /// (Deprecated: Use get_executor().) Get the io_context associated with the /// object. /** * This function may be used to obtain the io_context object that the I/O * object uses to dispatch handlers for asynchronous operations. * * @return A reference to the io_context object that the I/O object will use * to dispatch handlers. Ownership is not transferred to the caller. */ asio::io_context& get_io_service() { return service_.get_io_context(); } #endif // !defined(ASIO_NO_DEPRECATED) /// The type of the executor associated with the object. typedef asio::io_context::executor_type executor_type; /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return service_.get_io_context().get_executor(); } protected: /// Construct a basic_io_object. /** * Performs: * @code get_service().construct(get_implementation()); @endcode */ explicit basic_io_object(asio::io_context& io_context) : service_(asio::use_service(io_context)) { service_.construct(implementation_); } #if defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_io_object. /** * Performs: * @code get_service().move_construct( * get_implementation(), other.get_implementation()); @endcode * * @note Available only for services that support movability, */ basic_io_object(basic_io_object&& other); /// Move-assign a basic_io_object. /** * Performs: * @code get_service().move_assign(get_implementation(), * other.get_service(), other.get_implementation()); @endcode * * @note Available only for services that support movability, */ basic_io_object& operator=(basic_io_object&& other); /// Perform a converting move-construction of a basic_io_object. template basic_io_object(IoObjectService1& other_service, typename IoObjectService1::implementation_type& other_implementation); #endif // defined(GENERATING_DOCUMENTATION) /// Protected destructor to prevent deletion through this type. /** * Performs: * @code get_service().destroy(get_implementation()); @endcode */ ~basic_io_object() { service_.destroy(implementation_); } /// Get the service associated with the I/O object. service_type& get_service() { return service_; } /// Get the service associated with the I/O object. const service_type& get_service() const { return service_; } /// Get the underlying implementation of the I/O object. implementation_type& get_implementation() { return implementation_; } /// Get the underlying implementation of the I/O object. const implementation_type& get_implementation() const { return implementation_; } private: basic_io_object(const basic_io_object&); basic_io_object& operator=(const basic_io_object&); // The service associated with the I/O object. service_type& service_; /// The underlying implementation of the I/O object. implementation_type implementation_; }; #if defined(ASIO_HAS_MOVE) // Specialisation for movable objects. template class basic_io_object { public: typedef IoObjectService service_type; typedef typename service_type::implementation_type implementation_type; #if !defined(ASIO_NO_DEPRECATED) asio::io_context& get_io_context() { return service_->get_io_context(); } asio::io_context& get_io_service() { return service_->get_io_context(); } #endif // !defined(ASIO_NO_DEPRECATED) typedef asio::io_context::executor_type executor_type; executor_type get_executor() ASIO_NOEXCEPT { return service_->get_io_context().get_executor(); } protected: explicit basic_io_object(asio::io_context& io_context) : service_(&asio::use_service(io_context)) { service_->construct(implementation_); } basic_io_object(basic_io_object&& other) : service_(&other.get_service()) { service_->move_construct(implementation_, other.implementation_); } template basic_io_object(IoObjectService1& other_service, typename IoObjectService1::implementation_type& other_implementation) : service_(&asio::use_service( other_service.get_io_context())) { service_->converting_move_construct(implementation_, other_service, other_implementation); } ~basic_io_object() { service_->destroy(implementation_); } basic_io_object& operator=(basic_io_object&& other) { service_->move_assign(implementation_, *other.service_, other.implementation_); service_ = other.service_; return *this; } service_type& get_service() { return *service_; } const service_type& get_service() const { return *service_; } implementation_type& get_implementation() { return implementation_; } const implementation_type& get_implementation() const { return implementation_; } private: basic_io_object(const basic_io_object&); void operator=(const basic_io_object&); IoObjectService* service_; implementation_type implementation_; }; #endif // defined(ASIO_HAS_MOVE) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_IO_OBJECT_HPP ================================================ FILE: src/third_party/asio/basic_raw_socket.hpp ================================================ // // basic_raw_socket.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_RAW_SOCKET_HPP #define ASIO_BASIC_RAW_SOCKET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_BASIC_RAW_SOCKET_FWD_DECL) #define ASIO_BASIC_RAW_SOCKET_FWD_DECL // Forward declaration with defaulted arguments. template class basic_raw_socket; #endif // !defined(ASIO_BASIC_RAW_SOCKET_FWD_DECL) /// Provides raw-oriented socket functionality. /** * The basic_raw_socket class template provides asynchronous and blocking * raw-oriented socket functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_raw_socket : public basic_socket { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the socket type to another executor. template struct rebind_executor { /// The socket type when rebound to the specified executor. typedef basic_raw_socket other; }; /// The native representation of a socket. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef typename basic_socket::native_handle_type native_handle_type; #endif /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; /// Construct a basic_raw_socket without opening it. /** * This constructor creates a raw socket without opening it. The open() * function must be called before data can be sent or received on the socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. */ explicit basic_raw_socket(const executor_type& ex) : basic_socket(ex) { } /// Construct a basic_raw_socket without opening it. /** * This constructor creates a raw socket without opening it. The open() * function must be called before data can be sent or received on the socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. */ template explicit basic_raw_socket(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context) { } /// Construct and open a basic_raw_socket. /** * This constructor creates and opens a raw socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ basic_raw_socket(const executor_type& ex, const protocol_type& protocol) : basic_socket(ex, protocol) { } /// Construct and open a basic_raw_socket. /** * This constructor creates and opens a raw socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ template basic_raw_socket(ExecutionContext& context, const protocol_type& protocol, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol) { } /// Construct a basic_raw_socket, opening it and binding it to the given /// local endpoint. /** * This constructor creates a raw socket and automatically opens it bound * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the raw * socket will be bound. * * @throws asio::system_error Thrown on failure. */ basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint) : basic_socket(ex, endpoint) { } /// Construct a basic_raw_socket, opening it and binding it to the given /// local endpoint. /** * This constructor creates a raw socket and automatically opens it bound * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the raw * socket will be bound. * * @throws asio::system_error Thrown on failure. */ template basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, endpoint) { } /// Construct a basic_raw_socket on an existing native socket. /** * This constructor creates a raw socket object to hold an existing * native socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ basic_raw_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) : basic_socket(ex, protocol, native_socket) { } /// Construct a basic_raw_socket on an existing native socket. /** * This constructor creates a raw socket object to hold an existing * native socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ template basic_raw_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol, native_socket) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_raw_socket from another. /** * This constructor moves a raw socket from one object to another. * * @param other The other basic_raw_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_raw_socket(const executor_type&) * constructor. */ basic_raw_socket(basic_raw_socket&& other) ASIO_NOEXCEPT : basic_socket(std::move(other)) { } /// Move-assign a basic_raw_socket from another. /** * This assignment operator moves a raw socket from one object to another. * * @param other The other basic_raw_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_raw_socket(const executor_type&) * constructor. */ basic_raw_socket& operator=(basic_raw_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } /// Move-construct a basic_raw_socket from a socket of another protocol /// type. /** * This constructor moves a raw socket from one object to another. * * @param other The other basic_raw_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_raw_socket(const executor_type&) * constructor. */ template basic_raw_socket(basic_raw_socket&& other, typename enable_if< is_convertible::value && is_convertible::value >::type* = 0) : basic_socket(std::move(other)) { } /// Move-assign a basic_raw_socket from a socket of another protocol type. /** * This assignment operator moves a raw socket from one object to another. * * @param other The other basic_raw_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_raw_socket(const executor_type&) * constructor. */ template typename enable_if< is_convertible::value && is_convertible::value, basic_raw_socket& >::type operator=(basic_raw_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /** * This function destroys the socket, cancelling any outstanding asynchronous * operations associated with the socket as if by calling @c cancel. */ ~basic_raw_socket() { } /// Send some data on a connected socket. /** * This function is used to send data on the raw socket. The function call * will block until the data has been sent successfully or an error occurs. * * @param buffers One ore more data buffers to be sent on the socket. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected raw socket. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code socket.send(asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t send(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "send"); return s; } /// Send some data on a connected socket. /** * This function is used to send data on the raw socket. The function call * will block until the data has been sent successfully or an error occurs. * * @param buffers One ore more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected raw socket. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); asio::detail::throw_error(ec, "send"); return s; } /// Send some data on a connected socket. /** * This function is used to send data on the raw socket. The function call * will block until the data has been sent successfully or an error occurs. * * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected raw socket. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous send on a connected socket. /** * This function is used to send data on the raw socket. The function call * will block until the data has been sent successfully or an error occurs. * * @param buffers One or more data buffers to be sent on the socket. Although * the buffers object may be copied as necessary, ownership of the underlying * memory blocks is retained by the caller, which must guarantee that they * remain valid until the handler is called. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected raw * socket. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.async_send(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, socket_base::message_flags(0)); } /// Start an asynchronous send on a connected socket. /** * This function is used to send data on the raw socket. The function call * will block until the data has been sent successfully or an error occurs. * * @param buffers One or more data buffers to be sent on the socket. Although * the buffers object may be copied as necessary, ownership of the underlying * memory blocks is retained by the caller, which must guarantee that they * remain valid until the handler is called. * * @param flags Flags specifying how the send call is to be made. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected raw * socket. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, flags); } /// Send raw data to the specified endpoint. /** * This function is used to send raw data to the specified remote endpoint. * The function call will block until the data has been sent successfully or * an error occurs. * * @param buffers One or more data buffers to be sent to the remote endpoint. * * @param destination The remote endpoint to which the data will be sent. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * asio::ip::udp::endpoint destination( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.send_to(asio::buffer(data, size), destination); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t send_to(const ConstBufferSequence& buffers, const endpoint_type& destination) { asio::error_code ec; std::size_t s = this->impl_.get_service().send_to( this->impl_.get_implementation(), buffers, destination, 0, ec); asio::detail::throw_error(ec, "send_to"); return s; } /// Send raw data to the specified endpoint. /** * This function is used to send raw data to the specified remote endpoint. * The function call will block until the data has been sent successfully or * an error occurs. * * @param buffers One or more data buffers to be sent to the remote endpoint. * * @param destination The remote endpoint to which the data will be sent. * * @param flags Flags specifying how the send call is to be made. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. */ template std::size_t send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().send_to( this->impl_.get_implementation(), buffers, destination, flags, ec); asio::detail::throw_error(ec, "send_to"); return s; } /// Send raw data to the specified endpoint. /** * This function is used to send raw data to the specified remote endpoint. * The function call will block until the data has been sent successfully or * an error occurs. * * @param buffers One or more data buffers to be sent to the remote endpoint. * * @param destination The remote endpoint to which the data will be sent. * * @param flags Flags specifying how the send call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. */ template std::size_t send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().send_to(this->impl_.get_implementation(), buffers, destination, flags, ec); } /// Start an asynchronous send. /** * This function is used to asynchronously send raw data to the specified * remote endpoint. The function call always returns immediately. * * @param buffers One or more data buffers to be sent to the remote endpoint. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param destination The remote endpoint to which the data will be sent. * Copies will be made of the endpoint as required. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * asio::ip::udp::endpoint destination( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.async_send_to( * asio::buffer(data, size), destination, handler); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send_to(this), handler, buffers, destination, socket_base::message_flags(0)); } /// Start an asynchronous send. /** * This function is used to asynchronously send raw data to the specified * remote endpoint. The function call always returns immediately. * * @param buffers One or more data buffers to be sent to the remote endpoint. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param flags Flags specifying how the send call is to be made. * * @param destination The remote endpoint to which the data will be sent. * Copies will be made of the endpoint as required. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send_to(this), handler, buffers, destination, flags); } /// Receive some data on a connected socket. /** * This function is used to receive data on the raw socket. The function * call will block until data has been received successfully or an error * occurs. * * @param buffers One or more buffers into which the data will be received. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected raw * socket. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code socket.receive(asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on a connected socket. /** * This function is used to receive data on the raw socket. The function * call will block until data has been received successfully or an error * occurs. * * @param buffers One or more buffers into which the data will be received. * * @param flags Flags specifying how the receive call is to be made. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected raw * socket. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, flags, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on a connected socket. /** * This function is used to receive data on the raw socket. The function * call will block until data has been received successfully or an error * occurs. * * @param buffers One or more buffers into which the data will be received. * * @param flags Flags specifying how the receive call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected raw * socket. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous receive on a connected socket. /** * This function is used to asynchronously receive data from the raw * socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected * raw socket. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.async_receive(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive(this), handler, buffers, socket_base::message_flags(0)); } /// Start an asynchronous receive on a connected socket. /** * This function is used to asynchronously receive data from the raw * socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param flags Flags specifying how the receive call is to be made. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected * raw socket. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive(this), handler, buffers, flags); } /// Receive raw data with the endpoint of the sender. /** * This function is used to receive raw data. The function call will block * until data has been received successfully or an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the data. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * asio::ip::udp::endpoint sender_endpoint; * socket.receive_from( * asio::buffer(data, size), sender_endpoint); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive_from( this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); asio::detail::throw_error(ec, "receive_from"); return s; } /// Receive raw data with the endpoint of the sender. /** * This function is used to receive raw data. The function call will block * until data has been received successfully or an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the data. * * @param flags Flags specifying how the receive call is to be made. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. */ template std::size_t receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive_from( this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); asio::detail::throw_error(ec, "receive_from"); return s; } /// Receive raw data with the endpoint of the sender. /** * This function is used to receive raw data. The function call will block * until data has been received successfully or an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the data. * * @param flags Flags specifying how the receive call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. */ template std::size_t receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().receive_from( this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive raw data. The function * call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the data. Ownership of the sender_endpoint object * is retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code socket.async_receive_from( * asio::buffer(data, size), 0, sender_endpoint, handler); @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive_from(this), handler, buffers, &sender_endpoint, socket_base::message_flags(0)); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive raw data. The function * call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param sender_endpoint An endpoint object that receives the endpoint of * the remote sender of the data. Ownership of the sender_endpoint object * is retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param flags Flags specifying how the receive call is to be made. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive_from(this), handler, buffers, &sender_endpoint, flags); } private: class initiate_async_send { public: typedef Executor executor_type; explicit initiate_async_send(basic_raw_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_send( self_->impl_.get_implementation(), buffers, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_raw_socket* self_; }; class initiate_async_send_to { public: typedef Executor executor_type; explicit initiate_async_send_to(basic_raw_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_send_to( self_->impl_.get_implementation(), buffers, destination, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_raw_socket* self_; }; class initiate_async_receive { public: typedef Executor executor_type; explicit initiate_async_receive(basic_raw_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_receive( self_->impl_.get_implementation(), buffers, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_raw_socket* self_; }; class initiate_async_receive_from { public: typedef Executor executor_type; explicit initiate_async_receive_from(basic_raw_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, endpoint_type* sender_endpoint, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_receive_from( self_->impl_.get_implementation(), buffers, *sender_endpoint, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_raw_socket* self_; }; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_RAW_SOCKET_HPP ================================================ FILE: src/third_party/asio/basic_seq_packet_socket.hpp ================================================ // // basic_seq_packet_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_SEQ_PACKET_SOCKET_HPP #define ASIO_BASIC_SEQ_PACKET_SOCKET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) #define ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL // Forward declaration with defaulted arguments. template class basic_seq_packet_socket; #endif // !defined(ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) /// Provides sequenced packet socket functionality. /** * The basic_seq_packet_socket class template provides asynchronous and blocking * sequenced packet socket functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_seq_packet_socket : public basic_socket { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the socket type to another executor. template struct rebind_executor { /// The socket type when rebound to the specified executor. typedef basic_seq_packet_socket other; }; /// The native representation of a socket. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef typename basic_socket::native_handle_type native_handle_type; #endif /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; /// Construct a basic_seq_packet_socket without opening it. /** * This constructor creates a sequenced packet socket without opening it. The * socket needs to be opened and then connected or accepted before data can * be sent or received on it. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. */ explicit basic_seq_packet_socket(const executor_type& ex) : basic_socket(ex) { } /// Construct a basic_seq_packet_socket without opening it. /** * This constructor creates a sequenced packet socket without opening it. The * socket needs to be opened and then connected or accepted before data can * be sent or received on it. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. */ template explicit basic_seq_packet_socket(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context) { } /// Construct and open a basic_seq_packet_socket. /** * This constructor creates and opens a sequenced_packet socket. The socket * needs to be connected or accepted before data can be sent or received on * it. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ basic_seq_packet_socket(const executor_type& ex, const protocol_type& protocol) : basic_socket(ex, protocol) { } /// Construct and open a basic_seq_packet_socket. /** * This constructor creates and opens a sequenced_packet socket. The socket * needs to be connected or accepted before data can be sent or received on * it. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ template basic_seq_packet_socket(ExecutionContext& context, const protocol_type& protocol, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol) { } /// Construct a basic_seq_packet_socket, opening it and binding it to the /// given local endpoint. /** * This constructor creates a sequenced packet socket and automatically opens * it bound to the specified endpoint on the local machine. The protocol used * is the protocol associated with the given endpoint. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the sequenced * packet socket will be bound. * * @throws asio::system_error Thrown on failure. */ basic_seq_packet_socket(const executor_type& ex, const endpoint_type& endpoint) : basic_socket(ex, endpoint) { } /// Construct a basic_seq_packet_socket, opening it and binding it to the /// given local endpoint. /** * This constructor creates a sequenced packet socket and automatically opens * it bound to the specified endpoint on the local machine. The protocol used * is the protocol associated with the given endpoint. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the sequenced * packet socket will be bound. * * @throws asio::system_error Thrown on failure. */ template basic_seq_packet_socket(ExecutionContext& context, const endpoint_type& endpoint, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, endpoint) { } /// Construct a basic_seq_packet_socket on an existing native socket. /** * This constructor creates a sequenced packet socket object to hold an * existing native socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ basic_seq_packet_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) : basic_socket(ex, protocol, native_socket) { } /// Construct a basic_seq_packet_socket on an existing native socket. /** * This constructor creates a sequenced packet socket object to hold an * existing native socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ template basic_seq_packet_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol, native_socket) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_seq_packet_socket from another. /** * This constructor moves a sequenced packet socket from one object to * another. * * @param other The other basic_seq_packet_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_seq_packet_socket(const executor_type&) * constructor. */ basic_seq_packet_socket(basic_seq_packet_socket&& other) ASIO_NOEXCEPT : basic_socket(std::move(other)) { } /// Move-assign a basic_seq_packet_socket from another. /** * This assignment operator moves a sequenced packet socket from one object to * another. * * @param other The other basic_seq_packet_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_seq_packet_socket(const executor_type&) * constructor. */ basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } /// Move-construct a basic_seq_packet_socket from a socket of another protocol /// type. /** * This constructor moves a sequenced packet socket from one object to * another. * * @param other The other basic_seq_packet_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_seq_packet_socket(const executor_type&) * constructor. */ template basic_seq_packet_socket(basic_seq_packet_socket&& other, typename enable_if< is_convertible::value && is_convertible::value >::type* = 0) : basic_socket(std::move(other)) { } /// Move-assign a basic_seq_packet_socket from a socket of another protocol /// type. /** * This assignment operator moves a sequenced packet socket from one object to * another. * * @param other The other basic_seq_packet_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_seq_packet_socket(const executor_type&) * constructor. */ template typename enable_if< is_convertible::value && is_convertible::value, basic_seq_packet_socket& >::type operator=(basic_seq_packet_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /** * This function destroys the socket, cancelling any outstanding asynchronous * operations associated with the socket as if by calling @c cancel. */ ~basic_seq_packet_socket() { } /// Send some data on the socket. /** * This function is used to send data on the sequenced packet socket. The * function call will block until the data has been sent successfully, or an * until error occurs. * * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.send(asio::buffer(data, size), 0); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); asio::detail::throw_error(ec, "send"); return s; } /// Send some data on the socket. /** * This function is used to send data on the sequenced packet socket. The * function call will block the data has been sent successfully, or an until * error occurs. * * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. Returns 0 if an error occurred. * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref write function if you need to ensure that all data * is written before the blocking operation completes. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous send. /** * This function is used to asynchronously send data on the sequenced packet * socket. The function call always returns immediately. * * @param buffers One or more data buffers to be sent on the socket. Although * the buffers object may be copied as necessary, ownership of the underlying * memory blocks is retained by the caller, which must guarantee that they * remain valid until the handler is called. * * @param flags Flags specifying how the send call is to be made. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.async_send(asio::buffer(data, size), 0, handler); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, flags); } /// Receive some data on the socket. /** * This function is used to receive data on the sequenced packet socket. The * function call will block until data has been received successfully, or * until an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param out_flags After the receive call completes, contains flags * associated with the received data. For example, if the * socket_base::message_end_of_record bit is set then the received data marks * the end of a record. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.receive(asio::buffer(data, size), out_flags); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags& out_flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive_with_flags( this->impl_.get_implementation(), buffers, 0, out_flags, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on the socket. /** * This function is used to receive data on the sequenced packet socket. The * function call will block until data has been received successfully, or * until an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param in_flags Flags specifying how the receive call is to be made. * * @param out_flags After the receive call completes, contains flags * associated with the received data. For example, if the * socket_base::message_end_of_record bit is set then the received data marks * the end of a record. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.receive(asio::buffer(data, size), 0, out_flags); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive_with_flags( this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on a connected socket. /** * This function is used to receive data on the sequenced packet socket. The * function call will block until data has been received successfully, or * until an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param in_flags Flags specifying how the receive call is to be made. * * @param out_flags After the receive call completes, contains flags * associated with the received data. For example, if the * socket_base::message_end_of_record bit is set then the received data marks * the end of a record. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. Returns 0 if an error occurred. * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, asio::error_code& ec) { return this->impl_.get_service().receive_with_flags( this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive data from the sequenced * packet socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param out_flags Once the asynchronous operation completes, contains flags * associated with the received data. For example, if the * socket_base::message_end_of_record bit is set then the received data marks * the end of a record. The caller must guarantee that the referenced * variable remains valid until the handler is called. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.async_receive(asio::buffer(data, size), out_flags, handler); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, socket_base::message_flags& out_flags, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive_with_flags(this), handler, buffers, socket_base::message_flags(0), &out_flags); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive data from the sequenced * data socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param in_flags Flags specifying how the receive call is to be made. * * @param out_flags Once the asynchronous operation completes, contains flags * associated with the received data. For example, if the * socket_base::message_end_of_record bit is set then the received data marks * the end of a record. The caller must guarantee that the referenced * variable remains valid until the handler is called. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.async_receive( * asio::buffer(data, size), * 0, out_flags, handler); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive_with_flags(this), handler, buffers, in_flags, &out_flags); } private: class initiate_async_send { public: typedef Executor executor_type; explicit initiate_async_send(basic_seq_packet_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_send( self_->impl_.get_implementation(), buffers, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_seq_packet_socket* self_; }; class initiate_async_receive_with_flags { public: typedef Executor executor_type; explicit initiate_async_receive_with_flags(basic_seq_packet_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags* out_flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_receive_with_flags( self_->impl_.get_implementation(), buffers, in_flags, *out_flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_seq_packet_socket* self_; }; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_SEQ_PACKET_SOCKET_HPP ================================================ FILE: src/third_party/asio/basic_serial_port.hpp ================================================ // // basic_serial_port.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_SERIAL_PORT_HPP #define ASIO_BASIC_SERIAL_PORT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_SERIAL_PORT) \ || defined(GENERATING_DOCUMENTATION) #include #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/serial_port_base.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_serial_port_service.hpp" #else # include "asio/detail/reactive_serial_port_service.hpp" #endif #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { /// Provides serial port functionality. /** * The basic_serial_port class provides a wrapper over serial port * functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_serial_port : public serial_port_base { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the serial port type to another executor. template struct rebind_executor { /// The serial port type when rebound to the specified executor. typedef basic_serial_port other; }; /// The native representation of a serial port. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #elif defined(ASIO_HAS_IOCP) typedef detail::win_iocp_serial_port_service::native_handle_type native_handle_type; #else typedef detail::reactive_serial_port_service::native_handle_type native_handle_type; #endif /// A basic_basic_serial_port is always the lowest layer. typedef basic_serial_port lowest_layer_type; /// Construct a basic_serial_port without opening it. /** * This constructor creates a serial port without opening it. * * @param ex The I/O executor that the serial port will use, by default, to * dispatch handlers for any asynchronous operations performed on the * serial port. */ explicit basic_serial_port(const executor_type& ex) : impl_(ex) { } /// Construct a basic_serial_port without opening it. /** * This constructor creates a serial port without opening it. * * @param context An execution context which provides the I/O executor that * the serial port will use, by default, to dispatch handlers for any * asynchronous operations performed on the serial port. */ template explicit basic_serial_port(ExecutionContext& context, typename enable_if< is_convertible::value, basic_serial_port >::type* = 0) : impl_(context) { } /// Construct and open a basic_serial_port. /** * This constructor creates and opens a serial port for the specified device * name. * * @param ex The I/O executor that the serial port will use, by default, to * dispatch handlers for any asynchronous operations performed on the * serial port. * * @param device The platform-specific device name for this serial * port. */ basic_serial_port(const executor_type& ex, const char* device) : impl_(ex) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } /// Construct and open a basic_serial_port. /** * This constructor creates and opens a serial port for the specified device * name. * * @param context An execution context which provides the I/O executor that * the serial port will use, by default, to dispatch handlers for any * asynchronous operations performed on the serial port. * * @param device The platform-specific device name for this serial * port. */ template basic_serial_port(ExecutionContext& context, const char* device, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } /// Construct and open a basic_serial_port. /** * This constructor creates and opens a serial port for the specified device * name. * * @param ex The I/O executor that the serial port will use, by default, to * dispatch handlers for any asynchronous operations performed on the * serial port. * * @param device The platform-specific device name for this serial * port. */ basic_serial_port(const executor_type& ex, const std::string& device) : impl_(ex) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } /// Construct and open a basic_serial_port. /** * This constructor creates and opens a serial port for the specified device * name. * * @param context An execution context which provides the I/O executor that * the serial port will use, by default, to dispatch handlers for any * asynchronous operations performed on the serial port. * * @param device The platform-specific device name for this serial * port. */ template basic_serial_port(ExecutionContext& context, const std::string& device, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } /// Construct a basic_serial_port on an existing native serial port. /** * This constructor creates a serial port object to hold an existing native * serial port. * * @param ex The I/O executor that the serial port will use, by default, to * dispatch handlers for any asynchronous operations performed on the * serial port. * * @param native_serial_port A native serial port. * * @throws asio::system_error Thrown on failure. */ basic_serial_port(const executor_type& ex, const native_handle_type& native_serial_port) : impl_(ex) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); asio::detail::throw_error(ec, "assign"); } /// Construct a basic_serial_port on an existing native serial port. /** * This constructor creates a serial port object to hold an existing native * serial port. * * @param context An execution context which provides the I/O executor that * the serial port will use, by default, to dispatch handlers for any * asynchronous operations performed on the serial port. * * @param native_serial_port A native serial port. * * @throws asio::system_error Thrown on failure. */ template basic_serial_port(ExecutionContext& context, const native_handle_type& native_serial_port, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); asio::detail::throw_error(ec, "assign"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_serial_port from another. /** * This constructor moves a serial port from one object to another. * * @param other The other basic_serial_port object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_serial_port(const executor_type&) * constructor. */ basic_serial_port(basic_serial_port&& other) : impl_(std::move(other.impl_)) { } /// Move-assign a basic_serial_port from another. /** * This assignment operator moves a serial port from one object to another. * * @param other The other basic_serial_port object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_serial_port(const executor_type&) * constructor. */ basic_serial_port& operator=(basic_serial_port&& other) { impl_ = std::move(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the serial port. /** * This function destroys the serial port, cancelling any outstanding * asynchronous wait operations associated with the serial port as if by * calling @c cancel. */ ~basic_serial_port() { } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of * layers. Since a basic_serial_port cannot contain any further layers, it * simply returns a reference to itself. * * @return A reference to the lowest layer in the stack of layers. Ownership * is not transferred to the caller. */ lowest_layer_type& lowest_layer() { return *this; } /// Get a const reference to the lowest layer. /** * This function returns a const reference to the lowest layer in a stack of * layers. Since a basic_serial_port cannot contain any further layers, it * simply returns a reference to itself. * * @return A const reference to the lowest layer in the stack of layers. * Ownership is not transferred to the caller. */ const lowest_layer_type& lowest_layer() const { return *this; } /// Open the serial port using the specified device name. /** * This function opens the serial port for the specified device name. * * @param device The platform-specific device name. * * @throws asio::system_error Thrown on failure. */ void open(const std::string& device) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } /// Open the serial port using the specified device name. /** * This function opens the serial port using the given platform-specific * device name. * * @param device The platform-specific device name. * * @param ec Set the indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID open(const std::string& device, asio::error_code& ec) { impl_.get_service().open(impl_.get_implementation(), device, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assign an existing native serial port to the serial port. /* * This function opens the serial port to hold an existing native serial port. * * @param native_serial_port A native serial port. * * @throws asio::system_error Thrown on failure. */ void assign(const native_handle_type& native_serial_port) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); asio::detail::throw_error(ec, "assign"); } /// Assign an existing native serial port to the serial port. /* * This function opens the serial port to hold an existing native serial port. * * @param native_serial_port A native serial port. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, asio::error_code& ec) { impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the serial port is open. bool is_open() const { return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the serial port. /** * This function is used to close the serial port. Any asynchronous read or * write operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void close() { asio::error_code ec; impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } /// Close the serial port. /** * This function is used to close the serial port. Any asynchronous read or * write operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID close(asio::error_code& ec) { impl_.get_service().close(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the native serial port representation. /** * This function may be used to obtain the underlying representation of the * serial port. This is intended to allow access to native serial port * functionality that is not otherwise provided. */ native_handle_type native_handle() { return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the serial port. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void cancel() { asio::error_code ec; impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } /// Cancel all asynchronous operations associated with the serial port. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { impl_.get_service().cancel(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Send a break sequence to the serial port. /** * This function causes a break sequence of platform-specific duration to be * sent out the serial port. * * @throws asio::system_error Thrown on failure. */ void send_break() { asio::error_code ec; impl_.get_service().send_break(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "send_break"); } /// Send a break sequence to the serial port. /** * This function causes a break sequence of platform-specific duration to be * sent out the serial port. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID send_break(asio::error_code& ec) { impl_.get_service().send_break(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set an option on the serial port. /** * This function is used to set an option on the serial port. * * @param option The option value to be set on the serial port. * * @throws asio::system_error Thrown on failure. * * @sa SettableSerialPortOption @n * asio::serial_port_base::baud_rate @n * asio::serial_port_base::flow_control @n * asio::serial_port_base::parity @n * asio::serial_port_base::stop_bits @n * asio::serial_port_base::character_size */ template void set_option(const SettableSerialPortOption& option) { asio::error_code ec; impl_.get_service().set_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "set_option"); } /// Set an option on the serial port. /** * This function is used to set an option on the serial port. * * @param option The option value to be set on the serial port. * * @param ec Set to indicate what error occurred, if any. * * @sa SettableSerialPortOption @n * asio::serial_port_base::baud_rate @n * asio::serial_port_base::flow_control @n * asio::serial_port_base::parity @n * asio::serial_port_base::stop_bits @n * asio::serial_port_base::character_size */ template ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, asio::error_code& ec) { impl_.get_service().set_option(impl_.get_implementation(), option, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the serial port. /** * This function is used to get the current value of an option on the serial * port. * * @param option The option value to be obtained from the serial port. * * @throws asio::system_error Thrown on failure. * * @sa GettableSerialPortOption @n * asio::serial_port_base::baud_rate @n * asio::serial_port_base::flow_control @n * asio::serial_port_base::parity @n * asio::serial_port_base::stop_bits @n * asio::serial_port_base::character_size */ template void get_option(GettableSerialPortOption& option) const { asio::error_code ec; impl_.get_service().get_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "get_option"); } /// Get an option from the serial port. /** * This function is used to get the current value of an option on the serial * port. * * @param option The option value to be obtained from the serial port. * * @param ec Set to indicate what error occurred, if any. * * @sa GettableSerialPortOption @n * asio::serial_port_base::baud_rate @n * asio::serial_port_base::flow_control @n * asio::serial_port_base::parity @n * asio::serial_port_base::stop_bits @n * asio::serial_port_base::character_size */ template ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, asio::error_code& ec) const { impl_.get_service().get_option(impl_.get_implementation(), option, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Write some data to the serial port. /** * This function is used to write data to the serial port. The function call * will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the serial port. * * @returns The number of bytes written. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * basic_serial_port.write_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t write_some(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = impl_.get_service().write_some( impl_.get_implementation(), buffers, ec); asio::detail::throw_error(ec, "write_some"); return s; } /// Write some data to the serial port. /** * This function is used to write data to the serial port. The function call * will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the serial port. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. */ template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { return impl_.get_service().write_some( impl_.get_implementation(), buffers, ec); } /// Start an asynchronous write. /** * This function is used to asynchronously write data to the serial port. * The function call always returns immediately. * * @param buffers One or more data buffers to be written to the serial port. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The write operation may not transmit all of the data to the peer. * Consider using the @ref async_write function if you need to ensure that all * data is written before the asynchronous operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * basic_serial_port.async_write_some( * asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_write_some(this), handler, buffers); } /// Read some data from the serial port. /** * This function is used to read data from the serial port. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @returns The number of bytes read. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * basic_serial_port.read_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t read_some(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = impl_.get_service().read_some( impl_.get_implementation(), buffers, ec); asio::detail::throw_error(ec, "read_some"); return s; } /// Read some data from the serial port. /** * This function is used to read data from the serial port. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. */ template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { return impl_.get_service().read_some( impl_.get_implementation(), buffers, ec); } /// Start an asynchronous read. /** * This function is used to asynchronously read data from the serial port. * The function call always returns immediately. * * @param buffers One or more buffers into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The read operation may not read all of the requested number of bytes. * Consider using the @ref async_read function if you need to ensure that the * requested amount of data is read before the asynchronous operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * basic_serial_port.async_read_some( * asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_read_some(this), handler, buffers); } private: // Disallow copying and assignment. basic_serial_port(const basic_serial_port&) ASIO_DELETED; basic_serial_port& operator=(const basic_serial_port&) ASIO_DELETED; class initiate_async_write_some { public: typedef Executor executor_type; explicit initiate_async_write_some(basic_serial_port* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_write_some( self_->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_serial_port* self_; }; class initiate_async_read_some { public: typedef Executor executor_type; explicit initiate_async_read_some(basic_serial_port* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_read_some( self_->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_serial_port* self_; }; #if defined(ASIO_HAS_IOCP) detail::io_object_impl impl_; #else detail::io_object_impl impl_; #endif }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_SERIAL_PORT) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_BASIC_SERIAL_PORT_HPP ================================================ FILE: src/third_party/asio/basic_signal_set.hpp ================================================ // // basic_signal_set.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_SIGNAL_SET_HPP #define ASIO_BASIC_SIGNAL_SET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/signal_set_service.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" namespace asio { /// Provides signal functionality. /** * The basic_signal_set class provides the ability to perform an asynchronous * wait for one or more signals to occur. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Example * Performing an asynchronous wait: * @code * void handler( * const asio::error_code& error, * int signal_number) * { * if (!error) * { * // A signal occurred. * } * } * * ... * * // Construct a signal set registered for process termination. * asio::signal_set signals(my_context, SIGINT, SIGTERM); * * // Start an asynchronous wait for one of the signals to occur. * signals.async_wait(handler); * @endcode * * @par Queueing of signal notifications * * If a signal is registered with a signal_set, and the signal occurs when * there are no waiting handlers, then the signal notification is queued. The * next async_wait operation on that signal_set will dequeue the notification. * If multiple notifications are queued, subsequent async_wait operations * dequeue them one at a time. Signal notifications are dequeued in order of * ascending signal number. * * If a signal number is removed from a signal_set (using the @c remove or @c * erase member functions) then any queued notifications for that signal are * discarded. * * @par Multiple registration of signals * * The same signal number may be registered with different signal_set objects. * When the signal occurs, one handler is called for each signal_set object. * * Note that multiple registration only works for signals that are registered * using Asio. The application must not also register a signal handler using * functions such as @c signal() or @c sigaction(). * * @par Signal masking on POSIX platforms * * POSIX allows signals to be blocked using functions such as @c sigprocmask() * and @c pthread_sigmask(). For signals to be delivered, programs must ensure * that any signals registered using signal_set objects are unblocked in at * least one thread. */ template class basic_signal_set { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the signal set type to another executor. template struct rebind_executor { /// The signal set type when rebound to the specified executor. typedef basic_signal_set other; }; /// Construct a signal set without adding any signals. /** * This constructor creates a signal set without registering for any signals. * * @param ex The I/O executor that the signal set will use, by default, to * dispatch handlers for any asynchronous operations performed on the * signal set. */ explicit basic_signal_set(const executor_type& ex) : impl_(ex) { } /// Construct a signal set without adding any signals. /** * This constructor creates a signal set without registering for any signals. * * @param context An execution context which provides the I/O executor that * the signal set will use, by default, to dispatch handlers for any * asynchronous operations performed on the signal set. */ template explicit basic_signal_set(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { } /// Construct a signal set and add one signal. /** * This constructor creates a signal set and registers for one signal. * * @param ex The I/O executor that the signal set will use, by default, to * dispatch handlers for any asynchronous operations performed on the * signal set. * * @param signal_number_1 The signal number to be added. * * @note This constructor is equivalent to performing: * @code asio::signal_set signals(ex); * signals.add(signal_number_1); @endcode */ basic_signal_set(const executor_type& ex, int signal_number_1) : impl_(ex) { asio::error_code ec; impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); } /// Construct a signal set and add one signal. /** * This constructor creates a signal set and registers for one signal. * * @param context An execution context which provides the I/O executor that * the signal set will use, by default, to dispatch handlers for any * asynchronous operations performed on the signal set. * * @param signal_number_1 The signal number to be added. * * @note This constructor is equivalent to performing: * @code asio::signal_set signals(context); * signals.add(signal_number_1); @endcode */ template basic_signal_set(ExecutionContext& context, int signal_number_1, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); } /// Construct a signal set and add two signals. /** * This constructor creates a signal set and registers for two signals. * * @param ex The I/O executor that the signal set will use, by default, to * dispatch handlers for any asynchronous operations performed on the * signal set. * * @param signal_number_1 The first signal number to be added. * * @param signal_number_2 The second signal number to be added. * * @note This constructor is equivalent to performing: * @code asio::signal_set signals(ex); * signals.add(signal_number_1); * signals.add(signal_number_2); @endcode */ basic_signal_set(const executor_type& ex, int signal_number_1, int signal_number_2) : impl_(ex) { asio::error_code ec; impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); asio::detail::throw_error(ec, "add"); } /// Construct a signal set and add two signals. /** * This constructor creates a signal set and registers for two signals. * * @param context An execution context which provides the I/O executor that * the signal set will use, by default, to dispatch handlers for any * asynchronous operations performed on the signal set. * * @param signal_number_1 The first signal number to be added. * * @param signal_number_2 The second signal number to be added. * * @note This constructor is equivalent to performing: * @code asio::signal_set signals(context); * signals.add(signal_number_1); * signals.add(signal_number_2); @endcode */ template basic_signal_set(ExecutionContext& context, int signal_number_1, int signal_number_2, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); asio::detail::throw_error(ec, "add"); } /// Construct a signal set and add three signals. /** * This constructor creates a signal set and registers for three signals. * * @param ex The I/O executor that the signal set will use, by default, to * dispatch handlers for any asynchronous operations performed on the * signal set. * * @param signal_number_1 The first signal number to be added. * * @param signal_number_2 The second signal number to be added. * * @param signal_number_3 The third signal number to be added. * * @note This constructor is equivalent to performing: * @code asio::signal_set signals(ex); * signals.add(signal_number_1); * signals.add(signal_number_2); * signals.add(signal_number_3); @endcode */ basic_signal_set(const executor_type& ex, int signal_number_1, int signal_number_2, int signal_number_3) : impl_(ex) { asio::error_code ec; impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); asio::detail::throw_error(ec, "add"); impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec); asio::detail::throw_error(ec, "add"); } /// Construct a signal set and add three signals. /** * This constructor creates a signal set and registers for three signals. * * @param context An execution context which provides the I/O executor that * the signal set will use, by default, to dispatch handlers for any * asynchronous operations performed on the signal set. * * @param signal_number_1 The first signal number to be added. * * @param signal_number_2 The second signal number to be added. * * @param signal_number_3 The third signal number to be added. * * @note This constructor is equivalent to performing: * @code asio::signal_set signals(context); * signals.add(signal_number_1); * signals.add(signal_number_2); * signals.add(signal_number_3); @endcode */ template basic_signal_set(ExecutionContext& context, int signal_number_1, int signal_number_2, int signal_number_3, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); asio::detail::throw_error(ec, "add"); impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec); asio::detail::throw_error(ec, "add"); } /// Destroys the signal set. /** * This function destroys the signal set, cancelling any outstanding * asynchronous wait operations associated with the signal set as if by * calling @c cancel. */ ~basic_signal_set() { } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Add a signal to a signal_set. /** * This function adds the specified signal to the set. It has no effect if the * signal is already in the set. * * @param signal_number The signal to be added to the set. * * @throws asio::system_error Thrown on failure. */ void add(int signal_number) { asio::error_code ec; impl_.get_service().add(impl_.get_implementation(), signal_number, ec); asio::detail::throw_error(ec, "add"); } /// Add a signal to a signal_set. /** * This function adds the specified signal to the set. It has no effect if the * signal is already in the set. * * @param signal_number The signal to be added to the set. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID add(int signal_number, asio::error_code& ec) { impl_.get_service().add(impl_.get_implementation(), signal_number, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Remove a signal from a signal_set. /** * This function removes the specified signal from the set. It has no effect * if the signal is not in the set. * * @param signal_number The signal to be removed from the set. * * @throws asio::system_error Thrown on failure. * * @note Removes any notifications that have been queued for the specified * signal number. */ void remove(int signal_number) { asio::error_code ec; impl_.get_service().remove(impl_.get_implementation(), signal_number, ec); asio::detail::throw_error(ec, "remove"); } /// Remove a signal from a signal_set. /** * This function removes the specified signal from the set. It has no effect * if the signal is not in the set. * * @param signal_number The signal to be removed from the set. * * @param ec Set to indicate what error occurred, if any. * * @note Removes any notifications that have been queued for the specified * signal number. */ ASIO_SYNC_OP_VOID remove(int signal_number, asio::error_code& ec) { impl_.get_service().remove(impl_.get_implementation(), signal_number, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Remove all signals from a signal_set. /** * This function removes all signals from the set. It has no effect if the set * is already empty. * * @throws asio::system_error Thrown on failure. * * @note Removes all queued notifications. */ void clear() { asio::error_code ec; impl_.get_service().clear(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "clear"); } /// Remove all signals from a signal_set. /** * This function removes all signals from the set. It has no effect if the set * is already empty. * * @param ec Set to indicate what error occurred, if any. * * @note Removes all queued notifications. */ ASIO_SYNC_OP_VOID clear(asio::error_code& ec) { impl_.get_service().clear(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Cancel all operations associated with the signal set. /** * This function forces the completion of any pending asynchronous wait * operations against the signal set. The handler for each cancelled * operation will be invoked with the asio::error::operation_aborted * error code. * * Cancellation does not alter the set of registered signals. * * @throws asio::system_error Thrown on failure. * * @note If a registered signal occurred before cancel() is called, then the * handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ void cancel() { asio::error_code ec; impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } /// Cancel all operations associated with the signal set. /** * This function forces the completion of any pending asynchronous wait * operations against the signal set. The handler for each cancelled * operation will be invoked with the asio::error::operation_aborted * error code. * * Cancellation does not alter the set of registered signals. * * @param ec Set to indicate what error occurred, if any. * * @note If a registered signal occurred before cancel() is called, then the * handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { impl_.get_service().cancel(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous operation to wait for a signal to be delivered. /** * This function may be used to initiate an asynchronous wait against the * signal set. It always returns immediately. * * For each call to async_wait(), the supplied handler will be called exactly * once. The handler will be called when: * * @li One of the registered signals in the signal set occurs; or * * @li The signal set was cancelled, in which case the handler is passed the * error code asio::error::operation_aborted. * * @param handler The handler to be called when the signal occurs. Copies * will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * int signal_number // Indicates which signal occurred. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, int)) SignalHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(SignalHandler, void (asio::error_code, int)) async_wait( ASIO_MOVE_ARG(SignalHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_wait(this), handler); } private: // Disallow copying and assignment. basic_signal_set(const basic_signal_set&) ASIO_DELETED; basic_signal_set& operator=(const basic_signal_set&) ASIO_DELETED; class initiate_async_wait { public: typedef Executor executor_type; explicit initiate_async_wait(basic_signal_set* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(SignalHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a SignalHandler. ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_wait( self_->impl_.get_implementation(), handler2.value, self_->impl_.get_implementation_executor()); } private: basic_signal_set* self_; }; detail::io_object_impl impl_; }; } // namespace asio #endif // ASIO_BASIC_SIGNAL_SET_HPP ================================================ FILE: src/third_party/asio/basic_socket.hpp ================================================ // // basic_socket.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_SOCKET_HPP #define ASIO_BASIC_SOCKET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/post.hpp" #include "asio/socket_base.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/null_socket_service.hpp" #elif defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_socket_service.hpp" #else # include "asio/detail/reactive_socket_service.hpp" #endif #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_BASIC_SOCKET_FWD_DECL) #define ASIO_BASIC_SOCKET_FWD_DECL // Forward declaration with defaulted arguments. template class basic_socket; #endif // !defined(ASIO_BASIC_SOCKET_FWD_DECL) /// Provides socket functionality. /** * The basic_socket class template provides functionality that is common to both * stream-oriented and datagram-oriented sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_socket : public socket_base { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the socket type to another executor. template struct rebind_executor { /// The socket type when rebound to the specified executor. typedef basic_socket other; }; /// The native representation of a socket. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #elif defined(ASIO_WINDOWS_RUNTIME) typedef typename detail::null_socket_service< Protocol>::native_handle_type native_handle_type; #elif defined(ASIO_HAS_IOCP) typedef typename detail::win_iocp_socket_service< Protocol>::native_handle_type native_handle_type; #else typedef typename detail::reactive_socket_service< Protocol>::native_handle_type native_handle_type; #endif /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; #if !defined(ASIO_NO_EXTENSIONS) /// A basic_socket is always the lowest layer. typedef basic_socket lowest_layer_type; #endif // !defined(ASIO_NO_EXTENSIONS) /// Construct a basic_socket without opening it. /** * This constructor creates a socket without opening it. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. */ explicit basic_socket(const executor_type& ex) : impl_(ex) { } /// Construct a basic_socket without opening it. /** * This constructor creates a socket without opening it. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. */ template explicit basic_socket(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { } /// Construct and open a basic_socket. /** * This constructor creates and opens a socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ basic_socket(const executor_type& ex, const protocol_type& protocol) : impl_(ex) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } /// Construct and open a basic_socket. /** * This constructor creates and opens a socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ template basic_socket(ExecutionContext& context, const protocol_type& protocol, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } /// Construct a basic_socket, opening it and binding it to the given local /// endpoint. /** * This constructor creates a socket and automatically opens it bound to the * specified endpoint on the local machine. The protocol used is the protocol * associated with the given endpoint. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the socket will * be bound. * * @throws asio::system_error Thrown on failure. */ basic_socket(const executor_type& ex, const endpoint_type& endpoint) : impl_(ex) { asio::error_code ec; const protocol_type protocol = endpoint.protocol(); impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); } /// Construct a basic_socket, opening it and binding it to the given local /// endpoint. /** * This constructor creates a socket and automatically opens it bound to the * specified endpoint on the local machine. The protocol used is the protocol * associated with the given endpoint. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the socket will * be bound. * * @throws asio::system_error Thrown on failure. */ template basic_socket(ExecutionContext& context, const endpoint_type& endpoint, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; const protocol_type protocol = endpoint.protocol(); impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); } /// Construct a basic_socket on an existing native socket. /** * This constructor creates a socket object to hold an existing native socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket A native socket. * * @throws asio::system_error Thrown on failure. */ basic_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) : impl_(ex) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); asio::detail::throw_error(ec, "assign"); } /// Construct a basic_socket on an existing native socket. /** * This constructor creates a socket object to hold an existing native socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket A native socket. * * @throws asio::system_error Thrown on failure. */ template basic_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); asio::detail::throw_error(ec, "assign"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_socket from another. /** * This constructor moves a socket from one object to another. * * @param other The other basic_socket object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket(const executor_type&) constructor. */ basic_socket(basic_socket&& other) ASIO_NOEXCEPT : impl_(std::move(other.impl_)) { } /// Move-assign a basic_socket from another. /** * This assignment operator moves a socket from one object to another. * * @param other The other basic_socket object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket(const executor_type&) constructor. */ basic_socket& operator=(basic_socket&& other) { impl_ = std::move(other.impl_); return *this; } // All sockets have access to each other's implementations. template friend class basic_socket; /// Move-construct a basic_socket from a socket of another protocol type. /** * This constructor moves a socket from one object to another. * * @param other The other basic_socket object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket(const executor_type&) constructor. */ template basic_socket(basic_socket&& other, typename enable_if< is_convertible::value && is_convertible::value >::type* = 0) : impl_(std::move(other.impl_)) { } /// Move-assign a basic_socket from a socket of another protocol type. /** * This assignment operator moves a socket from one object to another. * * @param other The other basic_socket object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket(const executor_type&) constructor. */ template typename enable_if< is_convertible::value && is_convertible::value, basic_socket& >::type operator=(basic_socket && other) { basic_socket tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } #if !defined(ASIO_NO_EXTENSIONS) /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of * layers. Since a basic_socket cannot contain any further layers, it simply * returns a reference to itself. * * @return A reference to the lowest layer in the stack of layers. Ownership * is not transferred to the caller. */ lowest_layer_type& lowest_layer() { return *this; } /// Get a const reference to the lowest layer. /** * This function returns a const reference to the lowest layer in a stack of * layers. Since a basic_socket cannot contain any further layers, it simply * returns a reference to itself. * * @return A const reference to the lowest layer in the stack of layers. * Ownership is not transferred to the caller. */ const lowest_layer_type& lowest_layer() const { return *this; } #endif // !defined(ASIO_NO_EXTENSIONS) /// Open the socket using the specified protocol. /** * This function opens the socket so that it will use the specified protocol. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * socket.open(asio::ip::tcp::v4()); * @endcode */ void open(const protocol_type& protocol = protocol_type()) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } /// Open the socket using the specified protocol. /** * This function opens the socket so that it will use the specified protocol. * * @param protocol An object specifying which protocol is to be used. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * asio::error_code ec; * socket.open(asio::ip::tcp::v4(), ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID open(const protocol_type& protocol, asio::error_code& ec) { impl_.get_service().open(impl_.get_implementation(), protocol, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assign an existing native socket to the socket. /* * This function opens the socket to hold an existing native socket. * * @param protocol An object specifying which protocol is to be used. * * @param native_socket A native socket. * * @throws asio::system_error Thrown on failure. */ void assign(const protocol_type& protocol, const native_handle_type& native_socket) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); asio::detail::throw_error(ec, "assign"); } /// Assign an existing native socket to the socket. /* * This function opens the socket to hold an existing native socket. * * @param protocol An object specifying which protocol is to be used. * * @param native_socket A native socket. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, const native_handle_type& native_socket, asio::error_code& ec) { impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the socket is open. bool is_open() const { return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the socket. /** * This function is used to close the socket. Any asynchronous send, receive * or connect operations will be cancelled immediately, and will complete * with the asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. Note that, even if * the function indicates an error, the underlying descriptor is closed. * * @note For portable behaviour with respect to graceful closure of a * connected socket, call shutdown() before closing the socket. */ void close() { asio::error_code ec; impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } /// Close the socket. /** * This function is used to close the socket. Any asynchronous send, receive * or connect operations will be cancelled immediately, and will complete * with the asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. Note that, even if * the function indicates an error, the underlying descriptor is closed. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * socket.close(ec); * if (ec) * { * // An error occurred. * } * @endcode * * @note For portable behaviour with respect to graceful closure of a * connected socket, call shutdown() before closing the socket. */ ASIO_SYNC_OP_VOID close(asio::error_code& ec) { impl_.get_service().close(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Release ownership of the underlying native socket. /** * This function causes all outstanding asynchronous connect, send and receive * operations to finish immediately, and the handlers for cancelled operations * will be passed the asio::error::operation_aborted error. Ownership * of the native socket is then transferred to the caller. * * @throws asio::system_error Thrown on failure. * * @note This function is unsupported on Windows versions prior to Windows * 8.1, and will fail with asio::error::operation_not_supported on * these platforms. */ #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) __declspec(deprecated("This function always fails with " "operation_not_supported when used on Windows versions " "prior to Windows 8.1.")) #endif native_handle_type release() { asio::error_code ec; native_handle_type s = impl_.get_service().release( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "release"); return s; } /// Release ownership of the underlying native socket. /** * This function causes all outstanding asynchronous connect, send and receive * operations to finish immediately, and the handlers for cancelled operations * will be passed the asio::error::operation_aborted error. Ownership * of the native socket is then transferred to the caller. * * @param ec Set to indicate what error occurred, if any. * * @note This function is unsupported on Windows versions prior to Windows * 8.1, and will fail with asio::error::operation_not_supported on * these platforms. */ #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) __declspec(deprecated("This function always fails with " "operation_not_supported when used on Windows versions " "prior to Windows 8.1.")) #endif native_handle_type release(asio::error_code& ec) { return impl_.get_service().release(impl_.get_implementation(), ec); } /// Get the native socket representation. /** * This function may be used to obtain the underlying representation of the * socket. This is intended to allow access to native socket functionality * that is not otherwise provided. */ native_handle_type native_handle() { return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the socket. /** * This function causes all outstanding asynchronous connect, send and receive * operations to finish immediately, and the handlers for cancelled operations * will be passed the asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. * * @note Calls to cancel() will always fail with * asio::error::operation_not_supported when run on Windows XP, Windows * Server 2003, and earlier versions of Windows, unless * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has * two issues that should be considered before enabling its use: * * @li It will only cancel asynchronous operations that were initiated in the * current thread. * * @li It can appear to complete without error, but the request to cancel the * unfinished operations may be silently ignored by the operating system. * Whether it works or not seems to depend on the drivers that are installed. * * For portable cancellation, consider using one of the following * alternatives: * * @li Disable asio's I/O completion port backend by defining * ASIO_DISABLE_IOCP. * * @li Use the close() function to simultaneously cancel the outstanding * operations and close the socket. * * When running on Windows Vista, Windows Server 2008, and later, the * CancelIoEx function is always used. This function does not have the * problems described above. */ #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ && !defined(ASIO_ENABLE_CANCELIO) __declspec(deprecated("By default, this function always fails with " "operation_not_supported when used on Windows XP, Windows Server 2003, " "or earlier. Consult documentation for details.")) #endif void cancel() { asio::error_code ec; impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } /// Cancel all asynchronous operations associated with the socket. /** * This function causes all outstanding asynchronous connect, send and receive * operations to finish immediately, and the handlers for cancelled operations * will be passed the asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. * * @note Calls to cancel() will always fail with * asio::error::operation_not_supported when run on Windows XP, Windows * Server 2003, and earlier versions of Windows, unless * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has * two issues that should be considered before enabling its use: * * @li It will only cancel asynchronous operations that were initiated in the * current thread. * * @li It can appear to complete without error, but the request to cancel the * unfinished operations may be silently ignored by the operating system. * Whether it works or not seems to depend on the drivers that are installed. * * For portable cancellation, consider using one of the following * alternatives: * * @li Disable asio's I/O completion port backend by defining * ASIO_DISABLE_IOCP. * * @li Use the close() function to simultaneously cancel the outstanding * operations and close the socket. * * When running on Windows Vista, Windows Server 2008, and later, the * CancelIoEx function is always used. This function does not have the * problems described above. */ #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ && !defined(ASIO_ENABLE_CANCELIO) __declspec(deprecated("By default, this function always fails with " "operation_not_supported when used on Windows XP, Windows Server 2003, " "or earlier. Consult documentation for details.")) #endif ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { impl_.get_service().cancel(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the socket is at the out-of-band data mark. /** * This function is used to check whether the socket input is currently * positioned at the out-of-band data mark. * * @return A bool indicating whether the socket is at the out-of-band data * mark. * * @throws asio::system_error Thrown on failure. */ bool at_mark() const { asio::error_code ec; bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "at_mark"); return b; } /// Determine whether the socket is at the out-of-band data mark. /** * This function is used to check whether the socket input is currently * positioned at the out-of-band data mark. * * @param ec Set to indicate what error occurred, if any. * * @return A bool indicating whether the socket is at the out-of-band data * mark. */ bool at_mark(asio::error_code& ec) const { return impl_.get_service().at_mark(impl_.get_implementation(), ec); } /// Determine the number of bytes available for reading. /** * This function is used to determine the number of bytes that may be read * without blocking. * * @return The number of bytes that may be read without blocking, or 0 if an * error occurs. * * @throws asio::system_error Thrown on failure. */ std::size_t available() const { asio::error_code ec; std::size_t s = impl_.get_service().available( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "available"); return s; } /// Determine the number of bytes available for reading. /** * This function is used to determine the number of bytes that may be read * without blocking. * * @param ec Set to indicate what error occurred, if any. * * @return The number of bytes that may be read without blocking, or 0 if an * error occurs. */ std::size_t available(asio::error_code& ec) const { return impl_.get_service().available(impl_.get_implementation(), ec); } /// Bind the socket to the given local endpoint. /** * This function binds the socket to the specified endpoint on the local * machine. * * @param endpoint An endpoint on the local machine to which the socket will * be bound. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * socket.open(asio::ip::tcp::v4()); * socket.bind(asio::ip::tcp::endpoint( * asio::ip::tcp::v4(), 12345)); * @endcode */ void bind(const endpoint_type& endpoint) { asio::error_code ec; impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); } /// Bind the socket to the given local endpoint. /** * This function binds the socket to the specified endpoint on the local * machine. * * @param endpoint An endpoint on the local machine to which the socket will * be bound. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * socket.open(asio::ip::tcp::v4()); * asio::error_code ec; * socket.bind(asio::ip::tcp::endpoint( * asio::ip::tcp::v4(), 12345), ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, asio::error_code& ec) { impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Connect the socket to the specified endpoint. /** * This function is used to connect a socket to the specified remote endpoint. * The function call will block until the connection is successfully made or * an error occurs. * * The socket is automatically opened if it is not already open. If the * connect fails, and the socket was automatically opened, the socket is * not returned to the closed state. * * @param peer_endpoint The remote endpoint to which the socket will be * connected. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.connect(endpoint); * @endcode */ void connect(const endpoint_type& peer_endpoint) { asio::error_code ec; if (!is_open()) { impl_.get_service().open(impl_.get_implementation(), peer_endpoint.protocol(), ec); asio::detail::throw_error(ec, "connect"); } impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); asio::detail::throw_error(ec, "connect"); } /// Connect the socket to the specified endpoint. /** * This function is used to connect a socket to the specified remote endpoint. * The function call will block until the connection is successfully made or * an error occurs. * * The socket is automatically opened if it is not already open. If the * connect fails, and the socket was automatically opened, the socket is * not returned to the closed state. * * @param peer_endpoint The remote endpoint to which the socket will be * connected. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint( * asio::ip::address::from_string("1.2.3.4"), 12345); * asio::error_code ec; * socket.connect(endpoint, ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, asio::error_code& ec) { if (!is_open()) { impl_.get_service().open(impl_.get_implementation(), peer_endpoint.protocol(), ec); if (ec) { ASIO_SYNC_OP_VOID_RETURN(ec); } } impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous connect. /** * This function is used to asynchronously connect a socket to the specified * remote endpoint. The function call always returns immediately. * * The socket is automatically opened if it is not already open. If the * connect fails, and the socket was automatically opened, the socket is * not returned to the closed state. * * @param peer_endpoint The remote endpoint to which the socket will be * connected. Copies will be made of the endpoint object as required. * * @param handler The handler to be called when the connection operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error // Result of operation * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void connect_handler(const asio::error_code& error) * { * if (!error) * { * // Connect succeeded. * } * } * * ... * * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.async_connect(endpoint, connect_handler); * @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) ConnectHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler, void (asio::error_code)) async_connect(const endpoint_type& peer_endpoint, ASIO_MOVE_ARG(ConnectHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { asio::error_code open_ec; if (!is_open()) { const protocol_type protocol = peer_endpoint.protocol(); impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); } return async_initiate( initiate_async_connect(this), handler, peer_endpoint, open_ec); } /// Set an option on the socket. /** * This function is used to set an option on the socket. * * @param option The new option value to be set on the socket. * * @throws asio::system_error Thrown on failure. * * @sa SettableSocketOption @n * asio::socket_base::broadcast @n * asio::socket_base::do_not_route @n * asio::socket_base::keep_alive @n * asio::socket_base::linger @n * asio::socket_base::receive_buffer_size @n * asio::socket_base::receive_low_watermark @n * asio::socket_base::reuse_address @n * asio::socket_base::send_buffer_size @n * asio::socket_base::send_low_watermark @n * asio::ip::multicast::join_group @n * asio::ip::multicast::leave_group @n * asio::ip::multicast::enable_loopback @n * asio::ip::multicast::outbound_interface @n * asio::ip::multicast::hops @n * asio::ip::tcp::no_delay * * @par Example * Setting the IPPROTO_TCP/TCP_NODELAY option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::no_delay option(true); * socket.set_option(option); * @endcode */ template void set_option(const SettableSocketOption& option) { asio::error_code ec; impl_.get_service().set_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "set_option"); } /// Set an option on the socket. /** * This function is used to set an option on the socket. * * @param option The new option value to be set on the socket. * * @param ec Set to indicate what error occurred, if any. * * @sa SettableSocketOption @n * asio::socket_base::broadcast @n * asio::socket_base::do_not_route @n * asio::socket_base::keep_alive @n * asio::socket_base::linger @n * asio::socket_base::receive_buffer_size @n * asio::socket_base::receive_low_watermark @n * asio::socket_base::reuse_address @n * asio::socket_base::send_buffer_size @n * asio::socket_base::send_low_watermark @n * asio::ip::multicast::join_group @n * asio::ip::multicast::leave_group @n * asio::ip::multicast::enable_loopback @n * asio::ip::multicast::outbound_interface @n * asio::ip::multicast::hops @n * asio::ip::tcp::no_delay * * @par Example * Setting the IPPROTO_TCP/TCP_NODELAY option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::no_delay option(true); * asio::error_code ec; * socket.set_option(option, ec); * if (ec) * { * // An error occurred. * } * @endcode */ template ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, asio::error_code& ec) { impl_.get_service().set_option(impl_.get_implementation(), option, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the socket. /** * This function is used to get the current value of an option on the socket. * * @param option The option value to be obtained from the socket. * * @throws asio::system_error Thrown on failure. * * @sa GettableSocketOption @n * asio::socket_base::broadcast @n * asio::socket_base::do_not_route @n * asio::socket_base::keep_alive @n * asio::socket_base::linger @n * asio::socket_base::receive_buffer_size @n * asio::socket_base::receive_low_watermark @n * asio::socket_base::reuse_address @n * asio::socket_base::send_buffer_size @n * asio::socket_base::send_low_watermark @n * asio::ip::multicast::join_group @n * asio::ip::multicast::leave_group @n * asio::ip::multicast::enable_loopback @n * asio::ip::multicast::outbound_interface @n * asio::ip::multicast::hops @n * asio::ip::tcp::no_delay * * @par Example * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::keep_alive option; * socket.get_option(option); * bool is_set = option.value(); * @endcode */ template void get_option(GettableSocketOption& option) const { asio::error_code ec; impl_.get_service().get_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "get_option"); } /// Get an option from the socket. /** * This function is used to get the current value of an option on the socket. * * @param option The option value to be obtained from the socket. * * @param ec Set to indicate what error occurred, if any. * * @sa GettableSocketOption @n * asio::socket_base::broadcast @n * asio::socket_base::do_not_route @n * asio::socket_base::keep_alive @n * asio::socket_base::linger @n * asio::socket_base::receive_buffer_size @n * asio::socket_base::receive_low_watermark @n * asio::socket_base::reuse_address @n * asio::socket_base::send_buffer_size @n * asio::socket_base::send_low_watermark @n * asio::ip::multicast::join_group @n * asio::ip::multicast::leave_group @n * asio::ip::multicast::enable_loopback @n * asio::ip::multicast::outbound_interface @n * asio::ip::multicast::hops @n * asio::ip::tcp::no_delay * * @par Example * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::keep_alive option; * asio::error_code ec; * socket.get_option(option, ec); * if (ec) * { * // An error occurred. * } * bool is_set = option.value(); * @endcode */ template ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, asio::error_code& ec) const { impl_.get_service().get_option(impl_.get_implementation(), option, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform an IO control command on the socket. /** * This function is used to execute an IO control command on the socket. * * @param command The IO control command to be performed on the socket. * * @throws asio::system_error Thrown on failure. * * @sa IoControlCommand @n * asio::socket_base::bytes_readable @n * asio::socket_base::non_blocking_io * * @par Example * Getting the number of bytes ready to read: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::bytes_readable command; * socket.io_control(command); * std::size_t bytes_readable = command.get(); * @endcode */ template void io_control(IoControlCommand& command) { asio::error_code ec; impl_.get_service().io_control(impl_.get_implementation(), command, ec); asio::detail::throw_error(ec, "io_control"); } /// Perform an IO control command on the socket. /** * This function is used to execute an IO control command on the socket. * * @param command The IO control command to be performed on the socket. * * @param ec Set to indicate what error occurred, if any. * * @sa IoControlCommand @n * asio::socket_base::bytes_readable @n * asio::socket_base::non_blocking_io * * @par Example * Getting the number of bytes ready to read: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::bytes_readable command; * asio::error_code ec; * socket.io_control(command, ec); * if (ec) * { * // An error occurred. * } * std::size_t bytes_readable = command.get(); * @endcode */ template ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, asio::error_code& ec) { impl_.get_service().io_control(impl_.get_implementation(), command, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the socket. /** * @returns @c true if the socket's synchronous operations will fail with * asio::error::would_block if they are unable to perform the requested * operation immediately. If @c false, synchronous operations will block * until complete. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ bool non_blocking() const { return impl_.get_service().non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the socket. /** * @param mode If @c true, the socket's synchronous operations will fail with * asio::error::would_block if they are unable to perform the requested * operation immediately. If @c false, synchronous operations will block * until complete. * * @throws asio::system_error Thrown on failure. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ void non_blocking(bool mode) { asio::error_code ec; impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "non_blocking"); } /// Sets the non-blocking mode of the socket. /** * @param mode If @c true, the socket's synchronous operations will fail with * asio::error::would_block if they are unable to perform the requested * operation immediately. If @c false, synchronous operations will block * until complete. * * @param ec Set to indicate what error occurred, if any. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ ASIO_SYNC_OP_VOID non_blocking( bool mode, asio::error_code& ec) { impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the native socket implementation. /** * This function is used to retrieve the non-blocking mode of the underlying * native socket. This mode has no effect on the behaviour of the socket * object's synchronous operations. * * @returns @c true if the underlying socket is in non-blocking mode and * direct system calls may fail with asio::error::would_block (or the * equivalent system error). * * @note The current non-blocking mode is cached by the socket object. * Consequently, the return value may be incorrect if the non-blocking mode * was set directly on the native socket. * * @par Example * This function is intended to allow the encapsulation of arbitrary * non-blocking system calls as asynchronous operations, in a way that is * transparent to the user of the socket object. The following example * illustrates how Linux's @c sendfile system call might be encapsulated: * @code template * struct sendfile_op * { * tcp::socket& sock_; * int fd_; * Handler handler_; * off_t offset_; * std::size_t total_bytes_transferred_; * * // Function call operator meeting WriteHandler requirements. * // Used as the handler for the async_write_some operation. * void operator()(asio::error_code ec, std::size_t) * { * // Put the underlying socket into non-blocking mode. * if (!ec) * if (!sock_.native_non_blocking()) * sock_.native_non_blocking(true, ec); * * if (!ec) * { * for (;;) * { * // Try the system call. * errno = 0; * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); * ec = asio::error_code(n < 0 ? errno : 0, * asio::error::get_system_category()); * total_bytes_transferred_ += ec ? 0 : n; * * // Retry operation immediately if interrupted by signal. * if (ec == asio::error::interrupted) * continue; * * // Check if we need to run the operation again. * if (ec == asio::error::would_block * || ec == asio::error::try_again) * { * // We have to wait for the socket to become ready again. * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * * if (ec || n == 0) * { * // An error occurred, or we have reached the end of the file. * // Either way we must exit the loop so we can call the handler. * break; * } * * // Loop around to try calling sendfile again. * } * } * * // Pass result back to user's handler. * handler_(ec, total_bytes_transferred_); * } * }; * * template * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ bool native_non_blocking() const { return impl_.get_service().native_non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the native socket implementation. /** * This function is used to modify the non-blocking mode of the underlying * native socket. It has no effect on the behaviour of the socket object's * synchronous operations. * * @param mode If @c true, the underlying socket is put into non-blocking * mode and direct system calls may fail with asio::error::would_block * (or the equivalent system error). * * @throws asio::system_error Thrown on failure. If the @c mode is * @c false, but the current value of @c non_blocking() is @c true, this * function fails with asio::error::invalid_argument, as the * combination does not make sense. * * @par Example * This function is intended to allow the encapsulation of arbitrary * non-blocking system calls as asynchronous operations, in a way that is * transparent to the user of the socket object. The following example * illustrates how Linux's @c sendfile system call might be encapsulated: * @code template * struct sendfile_op * { * tcp::socket& sock_; * int fd_; * Handler handler_; * off_t offset_; * std::size_t total_bytes_transferred_; * * // Function call operator meeting WriteHandler requirements. * // Used as the handler for the async_write_some operation. * void operator()(asio::error_code ec, std::size_t) * { * // Put the underlying socket into non-blocking mode. * if (!ec) * if (!sock_.native_non_blocking()) * sock_.native_non_blocking(true, ec); * * if (!ec) * { * for (;;) * { * // Try the system call. * errno = 0; * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); * ec = asio::error_code(n < 0 ? errno : 0, * asio::error::get_system_category()); * total_bytes_transferred_ += ec ? 0 : n; * * // Retry operation immediately if interrupted by signal. * if (ec == asio::error::interrupted) * continue; * * // Check if we need to run the operation again. * if (ec == asio::error::would_block * || ec == asio::error::try_again) * { * // We have to wait for the socket to become ready again. * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * * if (ec || n == 0) * { * // An error occurred, or we have reached the end of the file. * // Either way we must exit the loop so we can call the handler. * break; * } * * // Loop around to try calling sendfile again. * } * } * * // Pass result back to user's handler. * handler_(ec, total_bytes_transferred_); * } * }; * * template * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ void native_non_blocking(bool mode) { asio::error_code ec; impl_.get_service().native_non_blocking( impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "native_non_blocking"); } /// Sets the non-blocking mode of the native socket implementation. /** * This function is used to modify the non-blocking mode of the underlying * native socket. It has no effect on the behaviour of the socket object's * synchronous operations. * * @param mode If @c true, the underlying socket is put into non-blocking * mode and direct system calls may fail with asio::error::would_block * (or the equivalent system error). * * @param ec Set to indicate what error occurred, if any. If the @c mode is * @c false, but the current value of @c non_blocking() is @c true, this * function fails with asio::error::invalid_argument, as the * combination does not make sense. * * @par Example * This function is intended to allow the encapsulation of arbitrary * non-blocking system calls as asynchronous operations, in a way that is * transparent to the user of the socket object. The following example * illustrates how Linux's @c sendfile system call might be encapsulated: * @code template * struct sendfile_op * { * tcp::socket& sock_; * int fd_; * Handler handler_; * off_t offset_; * std::size_t total_bytes_transferred_; * * // Function call operator meeting WriteHandler requirements. * // Used as the handler for the async_write_some operation. * void operator()(asio::error_code ec, std::size_t) * { * // Put the underlying socket into non-blocking mode. * if (!ec) * if (!sock_.native_non_blocking()) * sock_.native_non_blocking(true, ec); * * if (!ec) * { * for (;;) * { * // Try the system call. * errno = 0; * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); * ec = asio::error_code(n < 0 ? errno : 0, * asio::error::get_system_category()); * total_bytes_transferred_ += ec ? 0 : n; * * // Retry operation immediately if interrupted by signal. * if (ec == asio::error::interrupted) * continue; * * // Check if we need to run the operation again. * if (ec == asio::error::would_block * || ec == asio::error::try_again) * { * // We have to wait for the socket to become ready again. * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * * if (ec || n == 0) * { * // An error occurred, or we have reached the end of the file. * // Either way we must exit the loop so we can call the handler. * break; * } * * // Loop around to try calling sendfile again. * } * } * * // Pass result back to user's handler. * handler_(ec, total_bytes_transferred_); * } * }; * * template * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ ASIO_SYNC_OP_VOID native_non_blocking( bool mode, asio::error_code& ec) { impl_.get_service().native_non_blocking( impl_.get_implementation(), mode, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the local endpoint of the socket. /** * This function is used to obtain the locally bound endpoint of the socket. * * @returns An object that represents the local endpoint of the socket. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); * @endcode */ endpoint_type local_endpoint() const { asio::error_code ec; endpoint_type ep = impl_.get_service().local_endpoint( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "local_endpoint"); return ep; } /// Get the local endpoint of the socket. /** * This function is used to obtain the locally bound endpoint of the socket. * * @param ec Set to indicate what error occurred, if any. * * @returns An object that represents the local endpoint of the socket. * Returns a default-constructed endpoint object if an error occurred. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); * if (ec) * { * // An error occurred. * } * @endcode */ endpoint_type local_endpoint(asio::error_code& ec) const { return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); } /// Get the remote endpoint of the socket. /** * This function is used to obtain the remote endpoint of the socket. * * @returns An object that represents the remote endpoint of the socket. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); * @endcode */ endpoint_type remote_endpoint() const { asio::error_code ec; endpoint_type ep = impl_.get_service().remote_endpoint( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "remote_endpoint"); return ep; } /// Get the remote endpoint of the socket. /** * This function is used to obtain the remote endpoint of the socket. * * @param ec Set to indicate what error occurred, if any. * * @returns An object that represents the remote endpoint of the socket. * Returns a default-constructed endpoint object if an error occurred. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); * if (ec) * { * // An error occurred. * } * @endcode */ endpoint_type remote_endpoint(asio::error_code& ec) const { return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); } /// Disable sends or receives on the socket. /** * This function is used to disable send operations, receive operations, or * both. * * @param what Determines what types of operation will no longer be allowed. * * @throws asio::system_error Thrown on failure. * * @par Example * Shutting down the send side of the socket: * @code * asio::ip::tcp::socket socket(my_context); * ... * socket.shutdown(asio::ip::tcp::socket::shutdown_send); * @endcode */ void shutdown(shutdown_type what) { asio::error_code ec; impl_.get_service().shutdown(impl_.get_implementation(), what, ec); asio::detail::throw_error(ec, "shutdown"); } /// Disable sends or receives on the socket. /** * This function is used to disable send operations, receive operations, or * both. * * @param what Determines what types of operation will no longer be allowed. * * @param ec Set to indicate what error occurred, if any. * * @par Example * Shutting down the send side of the socket: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID shutdown(shutdown_type what, asio::error_code& ec) { impl_.get_service().shutdown(impl_.get_implementation(), what, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Wait for the socket to become ready to read, ready to write, or to have /// pending error conditions. /** * This function is used to perform a blocking wait for a socket to enter * a ready to read, write or error condition state. * * @param w Specifies the desired socket state. * * @par Example * Waiting for a socket to become readable. * @code * asio::ip::tcp::socket socket(my_context); * ... * socket.wait(asio::ip::tcp::socket::wait_read); * @endcode */ void wait(wait_type w) { asio::error_code ec; impl_.get_service().wait(impl_.get_implementation(), w, ec); asio::detail::throw_error(ec, "wait"); } /// Wait for the socket to become ready to read, ready to write, or to have /// pending error conditions. /** * This function is used to perform a blocking wait for a socket to enter * a ready to read, write or error condition state. * * @param w Specifies the desired socket state. * * @param ec Set to indicate what error occurred, if any. * * @par Example * Waiting for a socket to become readable. * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * socket.wait(asio::ip::tcp::socket::wait_read, ec); * @endcode */ ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) { impl_.get_service().wait(impl_.get_implementation(), w, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Asynchronously wait for the socket to become ready to read, ready to /// write, or to have pending error conditions. /** * This function is used to perform an asynchronous wait for a socket to enter * a ready to read, write or error condition state. * * @param w Specifies the desired socket state. * * @param handler The handler to be called when the wait operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error // Result of operation * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void wait_handler(const asio::error_code& error) * { * if (!error) * { * // Wait succeeded. * } * } * * ... * * asio::ip::tcp::socket socket(my_context); * ... * socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler); * @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (asio::error_code)) async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_wait(this), handler, w); } protected: /// Protected destructor to prevent deletion through this type. /** * This function destroys the socket, cancelling any outstanding asynchronous * operations associated with the socket as if by calling @c cancel. */ ~basic_socket() { } #if defined(ASIO_WINDOWS_RUNTIME) detail::io_object_impl< detail::null_socket_service, Executor> impl_; #elif defined(ASIO_HAS_IOCP) detail::io_object_impl< detail::win_iocp_socket_service, Executor> impl_; #else detail::io_object_impl< detail::reactive_socket_service, Executor> impl_; #endif private: // Disallow copying and assignment. basic_socket(const basic_socket&) ASIO_DELETED; basic_socket& operator=(const basic_socket&) ASIO_DELETED; class initiate_async_connect { public: typedef Executor executor_type; explicit initiate_async_connect(basic_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ConnectHandler) handler, const endpoint_type& peer_endpoint, const asio::error_code& open_ec) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ConnectHandler. ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; if (open_ec) { asio::post(self_->impl_.get_executor(), asio::detail::bind_handler( ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); } else { detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_connect( self_->impl_.get_implementation(), peer_endpoint, handler2.value, self_->impl_.get_implementation_executor()); } } private: basic_socket* self_; }; class initiate_async_wait { public: typedef Executor executor_type; explicit initiate_async_wait(basic_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler. ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_wait( self_->impl_.get_implementation(), w, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_socket* self_; }; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_SOCKET_HPP ================================================ FILE: src/third_party/asio/basic_socket_acceptor.hpp ================================================ // // basic_socket_acceptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_SOCKET_ACCEPTOR_HPP #define ASIO_BASIC_SOCKET_ACCEPTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/socket_base.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/null_socket_service.hpp" #elif defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_socket_service.hpp" #else # include "asio/detail/reactive_socket_service.hpp" #endif #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) #define ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL // Forward declaration with defaulted arguments. template class basic_socket_acceptor; #endif // !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) /// Provides the ability to accept new connections. /** * The basic_socket_acceptor class template is used for accepting new socket * connections. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Example * Opening a socket acceptor with the SO_REUSEADDR option enabled: * @code * asio::ip::tcp::acceptor acceptor(my_context); * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port); * acceptor.open(endpoint.protocol()); * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); * acceptor.bind(endpoint); * acceptor.listen(); * @endcode */ template class basic_socket_acceptor : public socket_base { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the acceptor type to another executor. template struct rebind_executor { /// The socket type when rebound to the specified executor. typedef basic_socket_acceptor other; }; /// The native representation of an acceptor. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #elif defined(ASIO_WINDOWS_RUNTIME) typedef typename detail::null_socket_service< Protocol>::native_handle_type native_handle_type; #elif defined(ASIO_HAS_IOCP) typedef typename detail::win_iocp_socket_service< Protocol>::native_handle_type native_handle_type; #else typedef typename detail::reactive_socket_service< Protocol>::native_handle_type native_handle_type; #endif /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; /// Construct an acceptor without opening it. /** * This constructor creates an acceptor without opening it to listen for new * connections. The open() function must be called before the acceptor can * accept new socket connections. * * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. */ explicit basic_socket_acceptor(const executor_type& ex) : impl_(ex) { } /// Construct an acceptor without opening it. /** * This constructor creates an acceptor without opening it to listen for new * connections. The open() function must be called before the acceptor can * accept new socket connections. * * @param context An execution context which provides the I/O executor that * the acceptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the acceptor. */ template explicit basic_socket_acceptor(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { } /// Construct an open acceptor. /** * This constructor creates an acceptor and automatically opens it. * * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol) : impl_(ex) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } /// Construct an open acceptor. /** * This constructor creates an acceptor and automatically opens it. * * @param context An execution context which provides the I/O executor that * the acceptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the acceptor. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ template basic_socket_acceptor(ExecutionContext& context, const protocol_type& protocol, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } /// Construct an acceptor opened on the given endpoint. /** * This constructor creates an acceptor and automatically opens it to listen * for new connections on the specified endpoint. * * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. * * @param endpoint An endpoint on the local machine on which the acceptor * will listen for new connections. * * @param reuse_addr Whether the constructor should set the socket option * socket_base::reuse_address. * * @throws asio::system_error Thrown on failure. * * @note This constructor is equivalent to the following code: * @code * basic_socket_acceptor acceptor(my_context); * acceptor.open(endpoint.protocol()); * if (reuse_addr) * acceptor.set_option(socket_base::reuse_address(true)); * acceptor.bind(endpoint); * acceptor.listen(); * @endcode */ basic_socket_acceptor(const executor_type& ex, const endpoint_type& endpoint, bool reuse_addr = true) : impl_(ex) { asio::error_code ec; const protocol_type protocol = endpoint.protocol(); impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); if (reuse_addr) { impl_.get_service().set_option(impl_.get_implementation(), socket_base::reuse_address(true), ec); asio::detail::throw_error(ec, "set_option"); } impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); impl_.get_service().listen(impl_.get_implementation(), socket_base::max_listen_connections, ec); asio::detail::throw_error(ec, "listen"); } /// Construct an acceptor opened on the given endpoint. /** * This constructor creates an acceptor and automatically opens it to listen * for new connections on the specified endpoint. * * @param context An execution context which provides the I/O executor that * the acceptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the acceptor. * * @param endpoint An endpoint on the local machine on which the acceptor * will listen for new connections. * * @param reuse_addr Whether the constructor should set the socket option * socket_base::reuse_address. * * @throws asio::system_error Thrown on failure. * * @note This constructor is equivalent to the following code: * @code * basic_socket_acceptor acceptor(my_context); * acceptor.open(endpoint.protocol()); * if (reuse_addr) * acceptor.set_option(socket_base::reuse_address(true)); * acceptor.bind(endpoint); * acceptor.listen(); * @endcode */ template basic_socket_acceptor(ExecutionContext& context, const endpoint_type& endpoint, bool reuse_addr = true, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; const protocol_type protocol = endpoint.protocol(); impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); if (reuse_addr) { impl_.get_service().set_option(impl_.get_implementation(), socket_base::reuse_address(true), ec); asio::detail::throw_error(ec, "set_option"); } impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); impl_.get_service().listen(impl_.get_implementation(), socket_base::max_listen_connections, ec); asio::detail::throw_error(ec, "listen"); } /// Construct a basic_socket_acceptor on an existing native acceptor. /** * This constructor creates an acceptor object to hold an existing native * acceptor. * * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. * * @param protocol An object specifying protocol parameters to be used. * * @param native_acceptor A native acceptor. * * @throws asio::system_error Thrown on failure. */ basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_acceptor) : impl_(ex) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); asio::detail::throw_error(ec, "assign"); } /// Construct a basic_socket_acceptor on an existing native acceptor. /** * This constructor creates an acceptor object to hold an existing native * acceptor. * * @param context An execution context which provides the I/O executor that * the acceptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the acceptor. * * @param protocol An object specifying protocol parameters to be used. * * @param native_acceptor A native acceptor. * * @throws asio::system_error Thrown on failure. */ template basic_socket_acceptor(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_acceptor, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); asio::detail::throw_error(ec, "assign"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_socket_acceptor from another. /** * This constructor moves an acceptor from one object to another. * * @param other The other basic_socket_acceptor object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket_acceptor(const executor_type&) * constructor. */ basic_socket_acceptor(basic_socket_acceptor&& other) : impl_(std::move(other.impl_)) { } /// Move-assign a basic_socket_acceptor from another. /** * This assignment operator moves an acceptor from one object to another. * * @param other The other basic_socket_acceptor object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket_acceptor(const executor_type&) * constructor. */ basic_socket_acceptor& operator=(basic_socket_acceptor&& other) { impl_ = std::move(other.impl_); return *this; } // All socket acceptors have access to each other's implementations. template friend class basic_socket_acceptor; /// Move-construct a basic_socket_acceptor from an acceptor of another /// protocol type. /** * This constructor moves an acceptor from one object to another. * * @param other The other basic_socket_acceptor object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket_acceptor(const executor_type&) * constructor. */ template basic_socket_acceptor(basic_socket_acceptor&& other, typename enable_if< is_convertible::value && is_convertible::value >::type* = 0) : impl_(std::move(other.impl_)) { } /// Move-assign a basic_socket_acceptor from an acceptor of another protocol /// type. /** * This assignment operator moves an acceptor from one object to another. * * @param other The other basic_socket_acceptor object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket_acceptor(const executor_type&) * constructor. */ template typename enable_if< is_convertible::value && is_convertible::value, basic_socket_acceptor& >::type operator=(basic_socket_acceptor&& other) { basic_socket_acceptor tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the acceptor. /** * This function destroys the acceptor, cancelling any outstanding * asynchronous operations associated with the acceptor as if by calling * @c cancel. */ ~basic_socket_acceptor() { } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Open the acceptor using the specified protocol. /** * This function opens the socket acceptor so that it will use the specified * protocol. * * @param protocol An object specifying which protocol is to be used. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * acceptor.open(asio::ip::tcp::v4()); * @endcode */ void open(const protocol_type& protocol = protocol_type()) { asio::error_code ec; impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } /// Open the acceptor using the specified protocol. /** * This function opens the socket acceptor so that it will use the specified * protocol. * * @param protocol An object specifying which protocol is to be used. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * asio::error_code ec; * acceptor.open(asio::ip::tcp::v4(), ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID open(const protocol_type& protocol, asio::error_code& ec) { impl_.get_service().open(impl_.get_implementation(), protocol, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assigns an existing native acceptor to the acceptor. /* * This function opens the acceptor to hold an existing native acceptor. * * @param protocol An object specifying which protocol is to be used. * * @param native_acceptor A native acceptor. * * @throws asio::system_error Thrown on failure. */ void assign(const protocol_type& protocol, const native_handle_type& native_acceptor) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); asio::detail::throw_error(ec, "assign"); } /// Assigns an existing native acceptor to the acceptor. /* * This function opens the acceptor to hold an existing native acceptor. * * @param protocol An object specifying which protocol is to be used. * * @param native_acceptor A native acceptor. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, const native_handle_type& native_acceptor, asio::error_code& ec) { impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the acceptor is open. bool is_open() const { return impl_.get_service().is_open(impl_.get_implementation()); } /// Bind the acceptor to the given local endpoint. /** * This function binds the socket acceptor to the specified endpoint on the * local machine. * * @param endpoint An endpoint on the local machine to which the socket * acceptor will be bound. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); * acceptor.open(endpoint.protocol()); * acceptor.bind(endpoint); * @endcode */ void bind(const endpoint_type& endpoint) { asio::error_code ec; impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); } /// Bind the acceptor to the given local endpoint. /** * This function binds the socket acceptor to the specified endpoint on the * local machine. * * @param endpoint An endpoint on the local machine to which the socket * acceptor will be bound. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); * acceptor.open(endpoint.protocol()); * asio::error_code ec; * acceptor.bind(endpoint, ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, asio::error_code& ec) { impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Place the acceptor into the state where it will listen for new /// connections. /** * This function puts the socket acceptor into the state where it may accept * new connections. * * @param backlog The maximum length of the queue of pending connections. * * @throws asio::system_error Thrown on failure. */ void listen(int backlog = socket_base::max_listen_connections) { asio::error_code ec; impl_.get_service().listen(impl_.get_implementation(), backlog, ec); asio::detail::throw_error(ec, "listen"); } /// Place the acceptor into the state where it will listen for new /// connections. /** * This function puts the socket acceptor into the state where it may accept * new connections. * * @param backlog The maximum length of the queue of pending connections. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::error_code ec; * acceptor.listen(asio::socket_base::max_listen_connections, ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec) { impl_.get_service().listen(impl_.get_implementation(), backlog, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Close the acceptor. /** * This function is used to close the acceptor. Any asynchronous accept * operations will be cancelled immediately. * * A subsequent call to open() is required before the acceptor can again be * used to again perform socket accept operations. * * @throws asio::system_error Thrown on failure. */ void close() { asio::error_code ec; impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } /// Close the acceptor. /** * This function is used to close the acceptor. Any asynchronous accept * operations will be cancelled immediately. * * A subsequent call to open() is required before the acceptor can again be * used to again perform socket accept operations. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::error_code ec; * acceptor.close(ec); * if (ec) * { * // An error occurred. * } * @endcode */ ASIO_SYNC_OP_VOID close(asio::error_code& ec) { impl_.get_service().close(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Release ownership of the underlying native acceptor. /** * This function causes all outstanding asynchronous accept operations to * finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. Ownership of the * native acceptor is then transferred to the caller. * * @throws asio::system_error Thrown on failure. * * @note This function is unsupported on Windows versions prior to Windows * 8.1, and will fail with asio::error::operation_not_supported on * these platforms. */ #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) __declspec(deprecated("This function always fails with " "operation_not_supported when used on Windows versions " "prior to Windows 8.1.")) #endif native_handle_type release() { asio::error_code ec; native_handle_type s = impl_.get_service().release( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "release"); return s; } /// Release ownership of the underlying native acceptor. /** * This function causes all outstanding asynchronous accept operations to * finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. Ownership of the * native acceptor is then transferred to the caller. * * @param ec Set to indicate what error occurred, if any. * * @note This function is unsupported on Windows versions prior to Windows * 8.1, and will fail with asio::error::operation_not_supported on * these platforms. */ #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) __declspec(deprecated("This function always fails with " "operation_not_supported when used on Windows versions " "prior to Windows 8.1.")) #endif native_handle_type release(asio::error_code& ec) { return impl_.get_service().release(impl_.get_implementation(), ec); } /// Get the native acceptor representation. /** * This function may be used to obtain the underlying representation of the * acceptor. This is intended to allow access to native acceptor functionality * that is not otherwise provided. */ native_handle_type native_handle() { return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the acceptor. /** * This function causes all outstanding asynchronous connect, send and receive * operations to finish immediately, and the handlers for cancelled operations * will be passed the asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void cancel() { asio::error_code ec; impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } /// Cancel all asynchronous operations associated with the acceptor. /** * This function causes all outstanding asynchronous connect, send and receive * operations to finish immediately, and the handlers for cancelled operations * will be passed the asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { impl_.get_service().cancel(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set an option on the acceptor. /** * This function is used to set an option on the acceptor. * * @param option The new option value to be set on the acceptor. * * @throws asio::system_error Thrown on failure. * * @sa SettableSocketOption @n * asio::socket_base::reuse_address * asio::socket_base::enable_connection_aborted * * @par Example * Setting the SOL_SOCKET/SO_REUSEADDR option: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option(true); * acceptor.set_option(option); * @endcode */ template void set_option(const SettableSocketOption& option) { asio::error_code ec; impl_.get_service().set_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "set_option"); } /// Set an option on the acceptor. /** * This function is used to set an option on the acceptor. * * @param option The new option value to be set on the acceptor. * * @param ec Set to indicate what error occurred, if any. * * @sa SettableSocketOption @n * asio::socket_base::reuse_address * asio::socket_base::enable_connection_aborted * * @par Example * Setting the SOL_SOCKET/SO_REUSEADDR option: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option(true); * asio::error_code ec; * acceptor.set_option(option, ec); * if (ec) * { * // An error occurred. * } * @endcode */ template ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, asio::error_code& ec) { impl_.get_service().set_option(impl_.get_implementation(), option, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the acceptor. /** * This function is used to get the current value of an option on the * acceptor. * * @param option The option value to be obtained from the acceptor. * * @throws asio::system_error Thrown on failure. * * @sa GettableSocketOption @n * asio::socket_base::reuse_address * * @par Example * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option; * acceptor.get_option(option); * bool is_set = option.get(); * @endcode */ template void get_option(GettableSocketOption& option) const { asio::error_code ec; impl_.get_service().get_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "get_option"); } /// Get an option from the acceptor. /** * This function is used to get the current value of an option on the * acceptor. * * @param option The option value to be obtained from the acceptor. * * @param ec Set to indicate what error occurred, if any. * * @sa GettableSocketOption @n * asio::socket_base::reuse_address * * @par Example * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option; * asio::error_code ec; * acceptor.get_option(option, ec); * if (ec) * { * // An error occurred. * } * bool is_set = option.get(); * @endcode */ template ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, asio::error_code& ec) const { impl_.get_service().get_option(impl_.get_implementation(), option, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform an IO control command on the acceptor. /** * This function is used to execute an IO control command on the acceptor. * * @param command The IO control command to be performed on the acceptor. * * @throws asio::system_error Thrown on failure. * * @sa IoControlCommand @n * asio::socket_base::non_blocking_io * * @par Example * Getting the number of bytes ready to read: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::non_blocking_io command(true); * socket.io_control(command); * @endcode */ template void io_control(IoControlCommand& command) { asio::error_code ec; impl_.get_service().io_control(impl_.get_implementation(), command, ec); asio::detail::throw_error(ec, "io_control"); } /// Perform an IO control command on the acceptor. /** * This function is used to execute an IO control command on the acceptor. * * @param command The IO control command to be performed on the acceptor. * * @param ec Set to indicate what error occurred, if any. * * @sa IoControlCommand @n * asio::socket_base::non_blocking_io * * @par Example * Getting the number of bytes ready to read: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::non_blocking_io command(true); * asio::error_code ec; * socket.io_control(command, ec); * if (ec) * { * // An error occurred. * } * @endcode */ template ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, asio::error_code& ec) { impl_.get_service().io_control(impl_.get_implementation(), command, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the acceptor. /** * @returns @c true if the acceptor's synchronous operations will fail with * asio::error::would_block if they are unable to perform the requested * operation immediately. If @c false, synchronous operations will block * until complete. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ bool non_blocking() const { return impl_.get_service().non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the acceptor. /** * @param mode If @c true, the acceptor's synchronous operations will fail * with asio::error::would_block if they are unable to perform the * requested operation immediately. If @c false, synchronous operations will * block until complete. * * @throws asio::system_error Thrown on failure. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ void non_blocking(bool mode) { asio::error_code ec; impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "non_blocking"); } /// Sets the non-blocking mode of the acceptor. /** * @param mode If @c true, the acceptor's synchronous operations will fail * with asio::error::would_block if they are unable to perform the * requested operation immediately. If @c false, synchronous operations will * block until complete. * * @param ec Set to indicate what error occurred, if any. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ ASIO_SYNC_OP_VOID non_blocking( bool mode, asio::error_code& ec) { impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the native acceptor implementation. /** * This function is used to retrieve the non-blocking mode of the underlying * native acceptor. This mode has no effect on the behaviour of the acceptor * object's synchronous operations. * * @returns @c true if the underlying acceptor is in non-blocking mode and * direct system calls may fail with asio::error::would_block (or the * equivalent system error). * * @note The current non-blocking mode is cached by the acceptor object. * Consequently, the return value may be incorrect if the non-blocking mode * was set directly on the native acceptor. */ bool native_non_blocking() const { return impl_.get_service().native_non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the native acceptor implementation. /** * This function is used to modify the non-blocking mode of the underlying * native acceptor. It has no effect on the behaviour of the acceptor object's * synchronous operations. * * @param mode If @c true, the underlying acceptor is put into non-blocking * mode and direct system calls may fail with asio::error::would_block * (or the equivalent system error). * * @throws asio::system_error Thrown on failure. If the @c mode is * @c false, but the current value of @c non_blocking() is @c true, this * function fails with asio::error::invalid_argument, as the * combination does not make sense. */ void native_non_blocking(bool mode) { asio::error_code ec; impl_.get_service().native_non_blocking( impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "native_non_blocking"); } /// Sets the non-blocking mode of the native acceptor implementation. /** * This function is used to modify the non-blocking mode of the underlying * native acceptor. It has no effect on the behaviour of the acceptor object's * synchronous operations. * * @param mode If @c true, the underlying acceptor is put into non-blocking * mode and direct system calls may fail with asio::error::would_block * (or the equivalent system error). * * @param ec Set to indicate what error occurred, if any. If the @c mode is * @c false, but the current value of @c non_blocking() is @c true, this * function fails with asio::error::invalid_argument, as the * combination does not make sense. */ ASIO_SYNC_OP_VOID native_non_blocking( bool mode, asio::error_code& ec) { impl_.get_service().native_non_blocking( impl_.get_implementation(), mode, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the local endpoint of the acceptor. /** * This function is used to obtain the locally bound endpoint of the acceptor. * * @returns An object that represents the local endpoint of the acceptor. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); * @endcode */ endpoint_type local_endpoint() const { asio::error_code ec; endpoint_type ep = impl_.get_service().local_endpoint( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "local_endpoint"); return ep; } /// Get the local endpoint of the acceptor. /** * This function is used to obtain the locally bound endpoint of the acceptor. * * @param ec Set to indicate what error occurred, if any. * * @returns An object that represents the local endpoint of the acceptor. * Returns a default-constructed endpoint object if an error occurred and the * error handler did not throw an exception. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::error_code ec; * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); * if (ec) * { * // An error occurred. * } * @endcode */ endpoint_type local_endpoint(asio::error_code& ec) const { return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); } /// Wait for the acceptor to become ready to read, ready to write, or to have /// pending error conditions. /** * This function is used to perform a blocking wait for an acceptor to enter * a ready to read, write or error condition state. * * @param w Specifies the desired acceptor state. * * @par Example * Waiting for an acceptor to become readable. * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * acceptor.wait(asio::ip::tcp::acceptor::wait_read); * @endcode */ void wait(wait_type w) { asio::error_code ec; impl_.get_service().wait(impl_.get_implementation(), w, ec); asio::detail::throw_error(ec, "wait"); } /// Wait for the acceptor to become ready to read, ready to write, or to have /// pending error conditions. /** * This function is used to perform a blocking wait for an acceptor to enter * a ready to read, write or error condition state. * * @param w Specifies the desired acceptor state. * * @param ec Set to indicate what error occurred, if any. * * @par Example * Waiting for an acceptor to become readable. * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::error_code ec; * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec); * @endcode */ ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) { impl_.get_service().wait(impl_.get_implementation(), w, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Asynchronously wait for the acceptor to become ready to read, ready to /// write, or to have pending error conditions. /** * This function is used to perform an asynchronous wait for an acceptor to * enter a ready to read, write or error condition state. * * @param w Specifies the desired acceptor state. * * @param handler The handler to be called when the wait operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error // Result of operation * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void wait_handler(const asio::error_code& error) * { * if (!error) * { * // Wait succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * acceptor.async_wait( * asio::ip::tcp::acceptor::wait_read, * wait_handler); * @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (asio::error_code)) async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_wait(this), handler, w); } #if !defined(ASIO_NO_EXTENSIONS) /// Accept a new connection. /** * This function is used to accept a new connection from a peer into the * given socket. The function call will block until a new connection has been * accepted successfully or an error occurs. * * @param peer The socket into which the new connection will be accepted. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(my_context); * acceptor.accept(socket); * @endcode */ template void accept(basic_socket& peer, typename enable_if< is_convertible::value >::type* = 0) { asio::error_code ec; impl_.get_service().accept(impl_.get_implementation(), peer, static_cast(0), ec); asio::detail::throw_error(ec, "accept"); } /// Accept a new connection. /** * This function is used to accept a new connection from a peer into the * given socket. The function call will block until a new connection has been * accepted successfully or an error occurs. * * @param peer The socket into which the new connection will be accepted. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(my_context); * asio::error_code ec; * acceptor.accept(socket, ec); * if (ec) * { * // An error occurred. * } * @endcode */ template ASIO_SYNC_OP_VOID accept( basic_socket& peer, asio::error_code& ec, typename enable_if< is_convertible::value >::type* = 0) { impl_.get_service().accept(impl_.get_implementation(), peer, static_cast(0), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection into a * socket. The function call always returns immediately. * * @param peer The socket into which the new connection will be accepted. * Ownership of the peer object is retained by the caller, which must * guarantee that it is valid until the handler is called. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void accept_handler(const asio::error_code& error) * { * if (!error) * { * // Accept succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(my_context); * acceptor.async_accept(socket, accept_handler); * @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler, void (asio::error_code)) async_accept(basic_socket& peer, ASIO_MOVE_ARG(AcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), typename enable_if< is_convertible::value >::type* = 0) { return async_initiate( initiate_async_accept(this), handler, &peer, static_cast(0)); } /// Accept a new connection and obtain the endpoint of the peer /** * This function is used to accept a new connection from a peer into the * given socket, and additionally provide the endpoint of the remote peer. * The function call will block until a new connection has been accepted * successfully or an error occurs. * * @param peer The socket into which the new connection will be accepted. * * @param peer_endpoint An endpoint object which will receive the endpoint of * the remote peer. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint; * acceptor.accept(socket, endpoint); * @endcode */ template void accept(basic_socket& peer, endpoint_type& peer_endpoint) { asio::error_code ec; impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); asio::detail::throw_error(ec, "accept"); } /// Accept a new connection and obtain the endpoint of the peer /** * This function is used to accept a new connection from a peer into the * given socket, and additionally provide the endpoint of the remote peer. * The function call will block until a new connection has been accepted * successfully or an error occurs. * * @param peer The socket into which the new connection will be accepted. * * @param peer_endpoint An endpoint object which will receive the endpoint of * the remote peer. * * @param ec Set to indicate what error occurred, if any. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint; * asio::error_code ec; * acceptor.accept(socket, endpoint, ec); * if (ec) * { * // An error occurred. * } * @endcode */ template ASIO_SYNC_OP_VOID accept(basic_socket& peer, endpoint_type& peer_endpoint, asio::error_code& ec) { impl_.get_service().accept( impl_.get_implementation(), peer, &peer_endpoint, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection into a * socket, and additionally obtain the endpoint of the remote peer. The * function call always returns immediately. * * @param peer The socket into which the new connection will be accepted. * Ownership of the peer object is retained by the caller, which must * guarantee that it is valid until the handler is called. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. Ownership of the peer_endpoint object is * retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler, void (asio::error_code)) async_accept(basic_socket& peer, endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_accept(this), handler, &peer, &peer_endpoint); } #endif // !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @returns A socket object representing the newly accepted connection. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(acceptor.accept()); * @endcode */ typename Protocol::socket::template rebind_executor::other accept() { asio::error_code ec; typename Protocol::socket::template rebind_executor< executor_type>::other peer(impl_.get_executor()); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); asio::detail::throw_error(ec, "accept"); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param ec Set to indicate what error occurred, if any. * * @returns On success, a socket object representing the newly accepted * connection. On error, a socket object where is_open() is false. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(acceptor.accept(ec)); * if (ec) * { * // An error occurred. * } * @endcode */ typename Protocol::socket::template rebind_executor::other accept(asio::error_code& ec) { typename Protocol::socket::template rebind_executor< executor_type>::other peer(impl_.get_executor()); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); return peer; } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection. The * function call always returns immediately. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * // On success, the newly accepted socket. * typename Protocol::socket::template * rebind_executor::other peer * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void accept_handler(const asio::error_code& error, * asio::ip::tcp::socket peer) * { * if (!error) * { * // Accept succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * acceptor.async_accept(accept_handler); * @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< executor_type>::other)) MoveAcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, void (asio::error_code, typename Protocol::socket::template rebind_executor::other)) async_accept( ASIO_MOVE_ARG(MoveAcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate::other)>( initiate_async_move_accept(this), handler, impl_.get_executor(), static_cast(0), static_cast::other*>(0)); } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param ex The I/O executor object to be used for the newly * accepted socket. * * @returns A socket object representing the newly accepted connection. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(acceptor.accept()); * @endcode */ template typename Protocol::socket::template rebind_executor::other accept(const Executor1& ex, typename enable_if< is_executor::value >::type* = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor::other peer(ex); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); asio::detail::throw_error(ec, "accept"); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param context The I/O execution context object to be used for the newly * accepted socket. * * @returns A socket object representing the newly accepted connection. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(acceptor.accept()); * @endcode */ template typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); asio::detail::throw_error(ec, "accept"); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param ex The I/O executor object to be used for the newly accepted * socket. * * @param ec Set to indicate what error occurred, if any. * * @returns On success, a socket object representing the newly accepted * connection. On error, a socket object where is_open() is false. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); * if (ec) * { * // An error occurred. * } * @endcode */ template typename Protocol::socket::template rebind_executor::other accept(const Executor1& ex, asio::error_code& ec, typename enable_if< is_executor::value >::type* = 0) { typename Protocol::socket::template rebind_executor::other peer(ex); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param context The I/O execution context object to be used for the newly * accepted socket. * * @param ec Set to indicate what error occurred, if any. * * @returns On success, a socket object representing the newly accepted * connection. On error, a socket object where is_open() is false. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); * if (ec) * { * // An error occurred. * } * @endcode */ template typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, asio::error_code& ec, typename enable_if< is_convertible::value >::type* = 0) { typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); return peer; } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection. The * function call always returns immediately. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param ex The I/O executor object to be used for the newly accepted * socket. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * typename Protocol::socket::template rebind_executor< * Executor1>::other peer // On success, the newly accepted socket. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void accept_handler(const asio::error_code& error, * asio::ip::tcp::socket peer) * { * if (!error) * { * // Accept succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * acceptor.async_accept(my_context2, accept_handler); * @endcode */ template ::other)) MoveAcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, void (asio::error_code, typename Protocol::socket::template rebind_executor< Executor1>::other)) async_accept(const Executor1& ex, ASIO_MOVE_ARG(MoveAcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), typename enable_if< is_executor::value >::type* = 0) { typedef typename Protocol::socket::template rebind_executor< Executor1>::other other_socket_type; return async_initiate( initiate_async_move_accept(this), handler, ex, static_cast(0), static_cast(0)); } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection. The * function call always returns immediately. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param context The I/O execution context object to be used for the newly * accepted socket. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * typename Protocol::socket::template rebind_executor< * typename ExecutionContext::executor_type>::other peer * // On success, the newly accepted socket. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void accept_handler(const asio::error_code& error, * asio::ip::tcp::socket peer) * { * if (!error) * { * // Accept succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * acceptor.async_accept(my_context2, accept_handler); * @endcode */ template ::other)) MoveAcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, void (asio::error_code, typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other)) async_accept(ExecutionContext& context, ASIO_MOVE_ARG(MoveAcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), typename enable_if< is_convertible::value >::type* = 0) { typedef typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other other_socket_type; return async_initiate( initiate_async_move_accept(this), handler, context.get_executor(), static_cast(0), static_cast(0)); } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. * * @returns A socket object representing the newly accepted connection. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * asio::ip::tcp::socket socket(acceptor.accept(endpoint)); * @endcode */ typename Protocol::socket::template rebind_executor::other accept(endpoint_type& peer_endpoint) { asio::error_code ec; typename Protocol::socket::template rebind_executor< executor_type>::other peer(impl_.get_executor()); impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); asio::detail::throw_error(ec, "accept"); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. * * @param ec Set to indicate what error occurred, if any. * * @returns On success, a socket object representing the newly accepted * connection. On error, a socket object where is_open() is false. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); * if (ec) * { * // An error occurred. * } * @endcode */ typename Protocol::socket::template rebind_executor::other accept(endpoint_type& peer_endpoint, asio::error_code& ec) { typename Protocol::socket::template rebind_executor< executor_type>::other peer(impl_.get_executor()); impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); return peer; } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection. The * function call always returns immediately. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. Ownership of the peer_endpoint object is * retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * // On success, the newly accepted socket. * typename Protocol::socket::template * rebind_executor::other peer * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void accept_handler(const asio::error_code& error, * asio::ip::tcp::socket peer) * { * if (!error) * { * // Accept succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * acceptor.async_accept(endpoint, accept_handler); * @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< executor_type>::other)) MoveAcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, void (asio::error_code, typename Protocol::socket::template rebind_executor::other)) async_accept(endpoint_type& peer_endpoint, ASIO_MOVE_ARG(MoveAcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate::other)>( initiate_async_move_accept(this), handler, impl_.get_executor(), &peer_endpoint, static_cast::other*>(0)); } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param ex The I/O executor object to be used for the newly accepted * socket. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. * * @returns A socket object representing the newly accepted connection. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * asio::ip::tcp::socket socket( * acceptor.accept(my_context2, endpoint)); * @endcode */ template typename Protocol::socket::template rebind_executor::other accept(const Executor1& ex, endpoint_type& peer_endpoint, typename enable_if< is_executor::value >::type* = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor::other peer(ex); impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); asio::detail::throw_error(ec, "accept"); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param context The I/O execution context object to be used for the newly * accepted socket. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. * * @returns A socket object representing the newly accepted connection. * * @throws asio::system_error Thrown on failure. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * asio::ip::tcp::socket socket( * acceptor.accept(my_context2, endpoint)); * @endcode */ template typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, endpoint_type& peer_endpoint, typename enable_if< is_convertible::value >::type* = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context); impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); asio::detail::throw_error(ec, "accept"); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param ex The I/O executor object to be used for the newly accepted * socket. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. * * @param ec Set to indicate what error occurred, if any. * * @returns On success, a socket object representing the newly accepted * connection. On error, a socket object where is_open() is false. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * asio::ip::tcp::socket socket( * acceptor.accept(my_context2, endpoint, ec)); * if (ec) * { * // An error occurred. * } * @endcode */ template typename Protocol::socket::template rebind_executor::other accept(const executor_type& ex, endpoint_type& peer_endpoint, asio::error_code& ec, typename enable_if< is_executor::value >::type* = 0) { typename Protocol::socket::template rebind_executor::other peer(ex); impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); return peer; } /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function * call will block until a new connection has been accepted successfully or * an error occurs. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param context The I/O execution context object to be used for the newly * accepted socket. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. * * @param ec Set to indicate what error occurred, if any. * * @returns On success, a socket object representing the newly accepted * connection. On error, a socket object where is_open() is false. * * @par Example * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * asio::ip::tcp::socket socket( * acceptor.accept(my_context2, endpoint, ec)); * if (ec) * { * // An error occurred. * } * @endcode */ template typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, endpoint_type& peer_endpoint, asio::error_code& ec, typename enable_if< is_convertible::value >::type* = 0) { typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context); impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); return peer; } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection. The * function call always returns immediately. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param ex The I/O executor object to be used for the newly accepted * socket. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. Ownership of the peer_endpoint object is * retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * typename Protocol::socket::template rebind_executor< * Executor1>::other peer // On success, the newly accepted socket. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void accept_handler(const asio::error_code& error, * asio::ip::tcp::socket peer) * { * if (!error) * { * // Accept succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * acceptor.async_accept(my_context2, endpoint, accept_handler); * @endcode */ template ::other)) MoveAcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, void (asio::error_code, typename Protocol::socket::template rebind_executor< Executor1>::other)) async_accept(const Executor1& ex, endpoint_type& peer_endpoint, ASIO_MOVE_ARG(MoveAcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), typename enable_if< is_executor::value >::type* = 0) { typedef typename Protocol::socket::template rebind_executor< Executor1>::other other_socket_type; return async_initiate( initiate_async_move_accept(this), handler, ex, &peer_endpoint, static_cast(0)); } /// Start an asynchronous accept. /** * This function is used to asynchronously accept a new connection. The * function call always returns immediately. * * This overload requires that the Protocol template parameter satisfy the * AcceptableProtocol type requirements. * * @param context The I/O execution context object to be used for the newly * accepted socket. * * @param peer_endpoint An endpoint object into which the endpoint of the * remote peer will be written. Ownership of the peer_endpoint object is * retained by the caller, which must guarantee that it is valid until the * handler is called. * * @param handler The handler to be called when the accept operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * typename Protocol::socket::template rebind_executor< * typename ExecutionContext::executor_type>::other peer * // On success, the newly accepted socket. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void accept_handler(const asio::error_code& error, * asio::ip::tcp::socket peer) * { * if (!error) * { * // Accept succeeded. * } * } * * ... * * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint; * acceptor.async_accept(my_context2, endpoint, accept_handler); * @endcode */ template ::other)) MoveAcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler, void (asio::error_code, typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other)) async_accept(ExecutionContext& context, endpoint_type& peer_endpoint, ASIO_MOVE_ARG(MoveAcceptHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type), typename enable_if< is_convertible::value >::type* = 0) { typedef typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other other_socket_type; return async_initiate( initiate_async_move_accept(this), handler, context.get_executor(), &peer_endpoint, static_cast(0)); } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) private: // Disallow copying and assignment. basic_socket_acceptor(const basic_socket_acceptor&) ASIO_DELETED; basic_socket_acceptor& operator=( const basic_socket_acceptor&) ASIO_DELETED; class initiate_async_wait { public: typedef Executor executor_type; explicit initiate_async_wait(basic_socket_acceptor* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler. ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_wait( self_->impl_.get_implementation(), w, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_socket_acceptor* self_; }; class initiate_async_accept { public: typedef Executor executor_type; explicit initiate_async_accept(basic_socket_acceptor* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(AcceptHandler) handler, basic_socket* peer, endpoint_type* peer_endpoint) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a AcceptHandler. ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_accept( self_->impl_.get_implementation(), *peer, peer_endpoint, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_socket_acceptor* self_; }; class initiate_async_move_accept { public: typedef Executor executor_type; explicit initiate_async_move_accept(basic_socket_acceptor* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler, const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a MoveAcceptHandler. ASIO_MOVE_ACCEPT_HANDLER_CHECK( MoveAcceptHandler, handler, Socket) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_move_accept( self_->impl_.get_implementation(), peer_ex, peer_endpoint, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_socket_acceptor* self_; }; #if defined(ASIO_WINDOWS_RUNTIME) detail::io_object_impl< detail::null_socket_service, Executor> impl_; #elif defined(ASIO_HAS_IOCP) detail::io_object_impl< detail::win_iocp_socket_service, Executor> impl_; #else detail::io_object_impl< detail::reactive_socket_service, Executor> impl_; #endif }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP ================================================ FILE: src/third_party/asio/basic_socket_iostream.hpp ================================================ // // basic_socket_iostream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_SOCKET_IOSTREAM_HPP #define ASIO_BASIC_SOCKET_IOSTREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_NO_IOSTREAM) #include #include #include "asio/basic_socket_streambuf.hpp" #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) # include "asio/detail/variadic_templates.hpp" // A macro that should expand to: // template // explicit basic_socket_iostream(T1 x1, ..., Tn xn) // : std::basic_iostream( // &this->detail::socket_iostream_base< // Protocol, Clock, WaitTraits>::streambuf_) // { // if (rdbuf()->connect(x1, ..., xn) == 0) // this->setstate(std::ios_base::failbit); // } // This macro should only persist within this file. # define ASIO_PRIVATE_CTR_DEF(n) \ template \ explicit basic_socket_iostream(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ : std::basic_iostream( \ &this->detail::socket_iostream_base< \ Protocol, Clock, WaitTraits>::streambuf_) \ { \ this->setf(std::ios_base::unitbuf); \ if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ this->setstate(std::ios_base::failbit); \ } \ /**/ // A macro that should expand to: // template // void connect(T1 x1, ..., Tn xn) // { // if (rdbuf()->connect(x1, ..., xn) == 0) // this->setstate(std::ios_base::failbit); // } // This macro should only persist within this file. # define ASIO_PRIVATE_CONNECT_DEF(n) \ template \ void connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ { \ if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ this->setstate(std::ios_base::failbit); \ } \ /**/ #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // A separate base class is used to ensure that the streambuf is initialised // prior to the basic_socket_iostream's basic_iostream base class. template class socket_iostream_base { protected: socket_iostream_base() { } #if defined(ASIO_HAS_MOVE) socket_iostream_base(socket_iostream_base&& other) : streambuf_(std::move(other.streambuf_)) { } socket_iostream_base(basic_stream_socket s) : streambuf_(std::move(s)) { } socket_iostream_base& operator=(socket_iostream_base&& other) { streambuf_ = std::move(other.streambuf_); return *this; } #endif // defined(ASIO_HAS_MOVE) basic_socket_streambuf streambuf_; }; } // namespace detail #if !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) #define ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL // Forward declaration with defaulted arguments. template > #else // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typename Clock = chrono::steady_clock, typename WaitTraits = wait_traits > #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) class basic_socket_iostream; #endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) /// Iostream interface for a socket. #if defined(GENERATING_DOCUMENTATION) template > #else // defined(GENERATING_DOCUMENTATION) template #endif // defined(GENERATING_DOCUMENTATION) class basic_socket_iostream : private detail::socket_iostream_base, public std::basic_iostream { private: // These typedefs are intended keep this class's implementation independent // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono. #if defined(ASIO_HAS_BOOST_DATE_TIME) \ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typedef WaitTraits traits_helper; #else // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typedef detail::chrono_time_traits traits_helper; #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) public: /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; /// The clock type. typedef Clock clock_type; #if defined(GENERATING_DOCUMENTATION) /// (Deprecated: Use time_point.) The time type. typedef typename WaitTraits::time_type time_type; /// The time type. typedef typename WaitTraits::time_point time_point; /// (Deprecated: Use duration.) The duration type. typedef typename WaitTraits::duration_type duration_type; /// The duration type. typedef typename WaitTraits::duration duration; #else # if !defined(ASIO_NO_DEPRECATED) typedef typename traits_helper::time_type time_type; typedef typename traits_helper::duration_type duration_type; # endif // !defined(ASIO_NO_DEPRECATED) typedef typename traits_helper::time_type time_point; typedef typename traits_helper::duration_type duration; #endif /// Construct a basic_socket_iostream without establishing a connection. basic_socket_iostream() : std::basic_iostream( &this->detail::socket_iostream_base< Protocol, Clock, WaitTraits>::streambuf_) { this->setf(std::ios_base::unitbuf); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a basic_socket_iostream from the supplied socket. explicit basic_socket_iostream(basic_stream_socket s) : detail::socket_iostream_base< Protocol, Clock, WaitTraits>(std::move(s)), std::basic_iostream( &this->detail::socket_iostream_base< Protocol, Clock, WaitTraits>::streambuf_) { this->setf(std::ios_base::unitbuf); } #if defined(ASIO_HAS_STD_IOSTREAM_MOVE) \ || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_socket_iostream from another. basic_socket_iostream(basic_socket_iostream&& other) : detail::socket_iostream_base< Protocol, Clock, WaitTraits>(std::move(other)), std::basic_iostream(std::move(other)) { this->set_rdbuf(&this->detail::socket_iostream_base< Protocol, Clock, WaitTraits>::streambuf_); } /// Move-assign a basic_socket_iostream from another. basic_socket_iostream& operator=(basic_socket_iostream&& other) { std::basic_iostream::operator=(std::move(other)); detail::socket_iostream_base< Protocol, Clock, WaitTraits>::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_STD_IOSTREAM_MOVE) // || defined(GENERATING_DOCUMENTATION) #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION) /// Establish a connection to an endpoint corresponding to a resolver query. /** * This constructor automatically establishes a connection based on the * supplied resolver query parameters. The arguments are used to construct * a resolver query object. */ template explicit basic_socket_iostream(T1 t1, ..., TN tn); #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template explicit basic_socket_iostream(T... x) : std::basic_iostream( &this->detail::socket_iostream_base< Protocol, Clock, WaitTraits>::streambuf_) { this->setf(std::ios_base::unitbuf); if (rdbuf()->connect(x...) == 0) this->setstate(std::ios_base::failbit); } #else ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CTR_DEF) #endif #if defined(GENERATING_DOCUMENTATION) /// Establish a connection to an endpoint corresponding to a resolver query. /** * This function automatically establishes a connection based on the supplied * resolver query parameters. The arguments are used to construct a resolver * query object. */ template void connect(T1 t1, ..., TN tn); #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template void connect(T... x) { if (rdbuf()->connect(x...) == 0) this->setstate(std::ios_base::failbit); } #else ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF) #endif /// Close the connection. void close() { if (rdbuf()->close() == 0) this->setstate(std::ios_base::failbit); } /// Return a pointer to the underlying streambuf. basic_socket_streambuf* rdbuf() const { return const_cast*>( &this->detail::socket_iostream_base< Protocol, Clock, WaitTraits>::streambuf_); } /// Get a reference to the underlying socket. basic_socket& socket() { return rdbuf()->socket(); } /// Get the last error associated with the stream. /** * @return An \c error_code corresponding to the last error from the stream. * * @par Example * To print the error associated with a failure to establish a connection: * @code tcp::iostream s("www.boost.org", "http"); * if (!s) * { * std::cout << "Error: " << s.error().message() << std::endl; * } @endcode */ const asio::error_code& error() const { return rdbuf()->error(); } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use expiry().) Get the stream's expiry time as an absolute /// time. /** * @return An absolute time value representing the stream's expiry time. */ time_point expires_at() const { return rdbuf()->expires_at(); } #endif // !defined(ASIO_NO_DEPRECATED) /// Get the stream's expiry time as an absolute time. /** * @return An absolute time value representing the stream's expiry time. */ time_point expiry() const { return rdbuf()->expiry(); } /// Set the stream's expiry time as an absolute time. /** * This function sets the expiry time associated with the stream. Stream * operations performed after this time (where the operations cannot be * completed using the internal buffers) will fail with the error * asio::error::operation_aborted. * * @param expiry_time The expiry time to be used for the stream. */ void expires_at(const time_point& expiry_time) { rdbuf()->expires_at(expiry_time); } /// Set the stream's expiry time relative to now. /** * This function sets the expiry time associated with the stream. Stream * operations performed after this time (where the operations cannot be * completed using the internal buffers) will fail with the error * asio::error::operation_aborted. * * @param expiry_time The expiry time to be used for the timer. */ void expires_after(const duration& expiry_time) { rdbuf()->expires_after(expiry_time); } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use expiry().) Get the stream's expiry time relative to now. /** * @return A relative time value representing the stream's expiry time. */ duration expires_from_now() const { return rdbuf()->expires_from_now(); } /// (Deprecated: Use expires_after().) Set the stream's expiry time relative /// to now. /** * This function sets the expiry time associated with the stream. Stream * operations performed after this time (where the operations cannot be * completed using the internal buffers) will fail with the error * asio::error::operation_aborted. * * @param expiry_time The expiry time to be used for the timer. */ void expires_from_now(const duration& expiry_time) { rdbuf()->expires_from_now(expiry_time); } #endif // !defined(ASIO_NO_DEPRECATED) private: // Disallow copying and assignment. basic_socket_iostream(const basic_socket_iostream&) ASIO_DELETED; basic_socket_iostream& operator=( const basic_socket_iostream&) ASIO_DELETED; }; } // namespace asio #include "asio/detail/pop_options.hpp" #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) # undef ASIO_PRIVATE_CTR_DEF # undef ASIO_PRIVATE_CONNECT_DEF #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_BASIC_SOCKET_IOSTREAM_HPP ================================================ FILE: src/third_party/asio/basic_socket_streambuf.hpp ================================================ // // basic_socket_streambuf.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_SOCKET_STREAMBUF_HPP #define ASIO_BASIC_SOCKET_STREAMBUF_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_NO_IOSTREAM) #include #include #include "asio/basic_socket.hpp" #include "asio/basic_stream_socket.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/throw_error.hpp" #include "asio/io_context.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) \ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) # include "asio/detail/deadline_timer_service.hpp" #else // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) # include "asio/steady_timer.hpp" #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) # include "asio/detail/variadic_templates.hpp" // A macro that should expand to: // template // basic_socket_streambuf* connect(T1 x1, ..., Tn xn) // { // init_buffers(); // typedef typename Protocol::resolver resolver_type; // resolver_type resolver(socket().get_executor()); // connect_to_endpoints( // resolver.resolve(x1, ..., xn, ec_)); // return !ec_ ? this : 0; // } // This macro should only persist within this file. # define ASIO_PRIVATE_CONNECT_DEF(n) \ template \ basic_socket_streambuf* connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ { \ init_buffers(); \ typedef typename Protocol::resolver resolver_type; \ resolver_type resolver(socket().get_executor()); \ connect_to_endpoints( \ resolver.resolve(ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \ return !ec_ ? this : 0; \ } \ /**/ #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // A separate base class is used to ensure that the io_context member is // initialised prior to the basic_socket_streambuf's basic_socket base class. class socket_streambuf_io_context { protected: socket_streambuf_io_context(io_context* ctx) : default_io_context_(ctx) { } shared_ptr default_io_context_; }; // A separate base class is used to ensure that the dynamically allocated // buffers are constructed prior to the basic_socket_streambuf's basic_socket // base class. This makes moving the socket is the last potentially throwing // step in the streambuf's move constructor, giving the constructor a strong // exception safety guarantee. class socket_streambuf_buffers { protected: socket_streambuf_buffers() : get_buffer_(buffer_size), put_buffer_(buffer_size) { } enum { buffer_size = 512 }; std::vector get_buffer_; std::vector put_buffer_; }; } // namespace detail #if !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) #define ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL // Forward declaration with defaulted arguments. template > #else // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typename Clock = chrono::steady_clock, typename WaitTraits = wait_traits > #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) class basic_socket_streambuf; #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) /// Iostream streambuf for a socket. #if defined(GENERATING_DOCUMENTATION) template > #else // defined(GENERATING_DOCUMENTATION) template #endif // defined(GENERATING_DOCUMENTATION) class basic_socket_streambuf : public std::streambuf, private detail::socket_streambuf_io_context, private detail::socket_streambuf_buffers, #if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) private basic_socket #else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) public basic_socket #endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) { private: // These typedefs are intended keep this class's implementation independent // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono. #if defined(ASIO_HAS_BOOST_DATE_TIME) \ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typedef WaitTraits traits_helper; #else // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typedef detail::chrono_time_traits traits_helper; #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) public: /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; /// The clock type. typedef Clock clock_type; #if defined(GENERATING_DOCUMENTATION) /// (Deprecated: Use time_point.) The time type. typedef typename WaitTraits::time_type time_type; /// The time type. typedef typename WaitTraits::time_point time_point; /// (Deprecated: Use duration.) The duration type. typedef typename WaitTraits::duration_type duration_type; /// The duration type. typedef typename WaitTraits::duration duration; #else # if !defined(ASIO_NO_DEPRECATED) typedef typename traits_helper::time_type time_type; typedef typename traits_helper::duration_type duration_type; # endif // !defined(ASIO_NO_DEPRECATED) typedef typename traits_helper::time_type time_point; typedef typename traits_helper::duration_type duration; #endif /// Construct a basic_socket_streambuf without establishing a connection. basic_socket_streambuf() : detail::socket_streambuf_io_context(new io_context), basic_socket(*default_io_context_), expiry_time_(max_expiry_time()) { init_buffers(); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a basic_socket_streambuf from the supplied socket. explicit basic_socket_streambuf(basic_stream_socket s) : detail::socket_streambuf_io_context(0), basic_socket(std::move(s)), expiry_time_(max_expiry_time()) { init_buffers(); } /// Move-construct a basic_socket_streambuf from another. basic_socket_streambuf(basic_socket_streambuf&& other) : detail::socket_streambuf_io_context(other), basic_socket(std::move(other.socket())), ec_(other.ec_), expiry_time_(other.expiry_time_) { get_buffer_.swap(other.get_buffer_); put_buffer_.swap(other.put_buffer_); setg(other.eback(), other.gptr(), other.egptr()); setp(other.pptr(), other.epptr()); other.ec_ = asio::error_code(); other.expiry_time_ = max_expiry_time(); other.init_buffers(); } /// Move-assign a basic_socket_streambuf from another. basic_socket_streambuf& operator=(basic_socket_streambuf&& other) { this->close(); socket() = std::move(other.socket()); detail::socket_streambuf_io_context::operator=(other); ec_ = other.ec_; expiry_time_ = other.expiry_time_; get_buffer_.swap(other.get_buffer_); put_buffer_.swap(other.put_buffer_); setg(other.eback(), other.gptr(), other.egptr()); setp(other.pptr(), other.epptr()); other.ec_ = asio::error_code(); other.expiry_time_ = max_expiry_time(); other.put_buffer_.resize(buffer_size); other.init_buffers(); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor flushes buffered data. virtual ~basic_socket_streambuf() { if (pptr() != pbase()) overflow(traits_type::eof()); } /// Establish a connection. /** * This function establishes a connection to the specified endpoint. * * @return \c this if a connection was successfully established, a null * pointer otherwise. */ basic_socket_streambuf* connect(const endpoint_type& endpoint) { init_buffers(); ec_ = asio::error_code(); this->connect_to_endpoints(&endpoint, &endpoint + 1); return !ec_ ? this : 0; } #if defined(GENERATING_DOCUMENTATION) /// Establish a connection. /** * This function automatically establishes a connection based on the supplied * resolver query parameters. The arguments are used to construct a resolver * query object. * * @return \c this if a connection was successfully established, a null * pointer otherwise. */ template basic_socket_streambuf* connect(T1 t1, ..., TN tn); #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template basic_socket_streambuf* connect(T... x) { init_buffers(); typedef typename Protocol::resolver resolver_type; resolver_type resolver(socket().get_executor()); connect_to_endpoints(resolver.resolve(x..., ec_)); return !ec_ ? this : 0; } #else ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF) #endif /// Close the connection. /** * @return \c this if a connection was successfully established, a null * pointer otherwise. */ basic_socket_streambuf* close() { sync(); socket().close(ec_); if (!ec_) init_buffers(); return !ec_ ? this : 0; } /// Get a reference to the underlying socket. basic_socket& socket() { return *this; } /// Get the last error associated with the stream buffer. /** * @return An \c error_code corresponding to the last error from the stream * buffer. */ const asio::error_code& error() const { return ec_; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use error().) Get the last error associated with the stream /// buffer. /** * @return An \c error_code corresponding to the last error from the stream * buffer. */ const asio::error_code& puberror() const { return error(); } /// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an /// absolute time. /** * @return An absolute time value representing the stream buffer's expiry * time. */ time_point expires_at() const { return expiry_time_; } #endif // !defined(ASIO_NO_DEPRECATED) /// Get the stream buffer's expiry time as an absolute time. /** * @return An absolute time value representing the stream buffer's expiry * time. */ time_point expiry() const { return expiry_time_; } /// Set the stream buffer's expiry time as an absolute time. /** * This function sets the expiry time associated with the stream. Stream * operations performed after this time (where the operations cannot be * completed using the internal buffers) will fail with the error * asio::error::operation_aborted. * * @param expiry_time The expiry time to be used for the stream. */ void expires_at(const time_point& expiry_time) { expiry_time_ = expiry_time; } /// Set the stream buffer's expiry time relative to now. /** * This function sets the expiry time associated with the stream. Stream * operations performed after this time (where the operations cannot be * completed using the internal buffers) will fail with the error * asio::error::operation_aborted. * * @param expiry_time The expiry time to be used for the timer. */ void expires_after(const duration& expiry_time) { expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time); } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative /// to now. /** * @return A relative time value representing the stream buffer's expiry time. */ duration expires_from_now() const { return traits_helper::subtract(expires_at(), traits_helper::now()); } /// (Deprecated: Use expires_after().) Set the stream buffer's expiry time /// relative to now. /** * This function sets the expiry time associated with the stream. Stream * operations performed after this time (where the operations cannot be * completed using the internal buffers) will fail with the error * asio::error::operation_aborted. * * @param expiry_time The expiry time to be used for the timer. */ void expires_from_now(const duration& expiry_time) { expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time); } #endif // !defined(ASIO_NO_DEPRECATED) protected: int_type underflow() { #if defined(ASIO_WINDOWS_RUNTIME) ec_ = asio::error::operation_not_supported; return traits_type::eof(); #else // defined(ASIO_WINDOWS_RUNTIME) if (gptr() != egptr()) return traits_type::eof(); for (;;) { // Check if we are past the expiry time. if (traits_helper::less_than(expiry_time_, traits_helper::now())) { ec_ = asio::error::timed_out; return traits_type::eof(); } // Try to complete the operation without blocking. if (!socket().native_non_blocking()) socket().native_non_blocking(true, ec_); detail::buffer_sequence_adapter bufs(asio::buffer(get_buffer_) + putback_max); detail::signed_size_type bytes = detail::socket_ops::recv( socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_); // Check if operation succeeded. if (bytes > 0) { setg(&get_buffer_[0], &get_buffer_[0] + putback_max, &get_buffer_[0] + putback_max + bytes); return traits_type::to_int_type(*gptr()); } // Check for EOF. if (bytes == 0) { ec_ = asio::error::eof; return traits_type::eof(); } // Operation failed. if (ec_ != asio::error::would_block && ec_ != asio::error::try_again) return traits_type::eof(); // Wait for socket to become ready. if (detail::socket_ops::poll_read( socket().native_handle(), 0, timeout(), ec_) < 0) return traits_type::eof(); } #endif // defined(ASIO_WINDOWS_RUNTIME) } int_type overflow(int_type c) { #if defined(ASIO_WINDOWS_RUNTIME) ec_ = asio::error::operation_not_supported; return traits_type::eof(); #else // defined(ASIO_WINDOWS_RUNTIME) char_type ch = traits_type::to_char_type(c); // Determine what needs to be sent. const_buffer output_buffer; if (put_buffer_.empty()) { if (traits_type::eq_int_type(c, traits_type::eof())) return traits_type::not_eof(c); // Nothing to do. output_buffer = asio::buffer(&ch, sizeof(char_type)); } else { output_buffer = asio::buffer(pbase(), (pptr() - pbase()) * sizeof(char_type)); } while (output_buffer.size() > 0) { // Check if we are past the expiry time. if (traits_helper::less_than(expiry_time_, traits_helper::now())) { ec_ = asio::error::timed_out; return traits_type::eof(); } // Try to complete the operation without blocking. if (!socket().native_non_blocking()) socket().native_non_blocking(true, ec_); detail::buffer_sequence_adapter< const_buffer, const_buffer> bufs(output_buffer); detail::signed_size_type bytes = detail::socket_ops::send( socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_); // Check if operation succeeded. if (bytes > 0) { output_buffer += static_cast(bytes); continue; } // Operation failed. if (ec_ != asio::error::would_block && ec_ != asio::error::try_again) return traits_type::eof(); // Wait for socket to become ready. if (detail::socket_ops::poll_write( socket().native_handle(), 0, timeout(), ec_) < 0) return traits_type::eof(); } if (!put_buffer_.empty()) { setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size()); // If the new character is eof then our work here is done. if (traits_type::eq_int_type(c, traits_type::eof())) return traits_type::not_eof(c); // Add the new character to the output buffer. *pptr() = ch; pbump(1); } return c; #endif // defined(ASIO_WINDOWS_RUNTIME) } int sync() { return overflow(traits_type::eof()); } std::streambuf* setbuf(char_type* s, std::streamsize n) { if (pptr() == pbase() && s == 0 && n == 0) { put_buffer_.clear(); setp(0, 0); sync(); return this; } return 0; } private: // Disallow copying and assignment. basic_socket_streambuf(const basic_socket_streambuf&) ASIO_DELETED; basic_socket_streambuf& operator=( const basic_socket_streambuf&) ASIO_DELETED; void init_buffers() { setg(&get_buffer_[0], &get_buffer_[0] + putback_max, &get_buffer_[0] + putback_max); if (put_buffer_.empty()) setp(0, 0); else setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size()); } int timeout() const { int64_t msec = traits_helper::to_posix_duration( traits_helper::subtract(expiry_time_, traits_helper::now())).total_milliseconds(); if (msec > (std::numeric_limits::max)()) msec = (std::numeric_limits::max)(); else if (msec < 0) msec = 0; return static_cast(msec); } template void connect_to_endpoints(const EndpointSequence& endpoints) { this->connect_to_endpoints(endpoints.begin(), endpoints.end()); } template void connect_to_endpoints(EndpointIterator begin, EndpointIterator end) { #if defined(ASIO_WINDOWS_RUNTIME) ec_ = asio::error::operation_not_supported; #else // defined(ASIO_WINDOWS_RUNTIME) if (ec_) return; ec_ = asio::error::not_found; for (EndpointIterator i = begin; i != end; ++i) { // Check if we are past the expiry time. if (traits_helper::less_than(expiry_time_, traits_helper::now())) { ec_ = asio::error::timed_out; return; } // Close and reopen the socket. typename Protocol::endpoint ep(*i); socket().close(ec_); socket().open(ep.protocol(), ec_); if (ec_) continue; // Try to complete the operation without blocking. if (!socket().native_non_blocking()) socket().native_non_blocking(true, ec_); detail::socket_ops::connect(socket().native_handle(), ep.data(), ep.size(), ec_); // Check if operation succeeded. if (!ec_) return; // Operation failed. if (ec_ != asio::error::in_progress && ec_ != asio::error::would_block) continue; // Wait for socket to become ready. if (detail::socket_ops::poll_connect( socket().native_handle(), timeout(), ec_) < 0) continue; // Get the error code from the connect operation. int connect_error = 0; size_t connect_error_len = sizeof(connect_error); if (detail::socket_ops::getsockopt(socket().native_handle(), 0, SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec_) == detail::socket_error_retval) return; // Check the result of the connect operation. ec_ = asio::error_code(connect_error, asio::error::get_system_category()); if (!ec_) return; } #endif // defined(ASIO_WINDOWS_RUNTIME) } // Helper function to get the maximum expiry time. static time_point max_expiry_time() { #if defined(ASIO_HAS_BOOST_DATE_TIME) \ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) return boost::posix_time::pos_infin; #else // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) return (time_point::max)(); #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) } enum { putback_max = 8 }; asio::error_code ec_; time_point expiry_time_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) # undef ASIO_PRIVATE_CONNECT_DEF #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_BASIC_SOCKET_STREAMBUF_HPP ================================================ FILE: src/third_party/asio/basic_stream_socket.hpp ================================================ // // basic_stream_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_STREAM_SOCKET_HPP #define ASIO_BASIC_STREAM_SOCKET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL) #define ASIO_BASIC_STREAM_SOCKET_FWD_DECL // Forward declaration with defaulted arguments. template class basic_stream_socket; #endif // !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL) /// Provides stream-oriented socket functionality. /** * The basic_stream_socket class template provides asynchronous and blocking * stream-oriented socket functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template class basic_stream_socket : public basic_socket { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the socket type to another executor. template struct rebind_executor { /// The socket type when rebound to the specified executor. typedef basic_stream_socket other; }; /// The native representation of a socket. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef typename basic_socket::native_handle_type native_handle_type; #endif /// The protocol type. typedef Protocol protocol_type; /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; /// Construct a basic_stream_socket without opening it. /** * This constructor creates a stream socket without opening it. The socket * needs to be opened and then connected or accepted before data can be sent * or received on it. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. */ explicit basic_stream_socket(const executor_type& ex) : basic_socket(ex) { } /// Construct a basic_stream_socket without opening it. /** * This constructor creates a stream socket without opening it. The socket * needs to be opened and then connected or accepted before data can be sent * or received on it. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. */ template explicit basic_stream_socket(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context) { } /// Construct and open a basic_stream_socket. /** * This constructor creates and opens a stream socket. The socket needs to be * connected or accepted before data can be sent or received on it. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ basic_stream_socket(const executor_type& ex, const protocol_type& protocol) : basic_socket(ex, protocol) { } /// Construct and open a basic_stream_socket. /** * This constructor creates and opens a stream socket. The socket needs to be * connected or accepted before data can be sent or received on it. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws asio::system_error Thrown on failure. */ template basic_stream_socket(ExecutionContext& context, const protocol_type& protocol, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol) { } /// Construct a basic_stream_socket, opening it and binding it to the given /// local endpoint. /** * This constructor creates a stream socket and automatically opens it bound * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the stream * socket will be bound. * * @throws asio::system_error Thrown on failure. */ basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint) : basic_socket(ex, endpoint) { } /// Construct a basic_stream_socket, opening it and binding it to the given /// local endpoint. /** * This constructor creates a stream socket and automatically opens it bound * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the stream * socket will be bound. * * @throws asio::system_error Thrown on failure. */ template basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, endpoint) { } /// Construct a basic_stream_socket on an existing native socket. /** * This constructor creates a stream socket object to hold an existing native * socket. * * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ basic_stream_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) : basic_socket(ex, protocol, native_socket) { } /// Construct a basic_stream_socket on an existing native socket. /** * This constructor creates a stream socket object to hold an existing native * socket. * * @param context An execution context which provides the I/O executor that * the socket will use, by default, to dispatch handlers for any asynchronous * operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @param native_socket The new underlying socket implementation. * * @throws asio::system_error Thrown on failure. */ template basic_stream_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket, typename enable_if< is_convertible::value >::type* = 0) : basic_socket(context, protocol, native_socket) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_stream_socket from another. /** * This constructor moves a stream socket from one object to another. * * @param other The other basic_stream_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_socket(const executor_type&) * constructor. */ basic_stream_socket(basic_stream_socket&& other) ASIO_NOEXCEPT : basic_socket(std::move(other)) { } /// Move-assign a basic_stream_socket from another. /** * This assignment operator moves a stream socket from one object to another. * * @param other The other basic_stream_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_socket(const executor_type&) * constructor. */ basic_stream_socket& operator=(basic_stream_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } /// Move-construct a basic_stream_socket from a socket of another protocol /// type. /** * This constructor moves a stream socket from one object to another. * * @param other The other basic_stream_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_socket(const executor_type&) * constructor. */ template basic_stream_socket(basic_stream_socket&& other, typename enable_if< is_convertible::value && is_convertible::value >::type* = 0) : basic_socket(std::move(other)) { } /// Move-assign a basic_stream_socket from a socket of another protocol type. /** * This assignment operator moves a stream socket from one object to another. * * @param other The other basic_stream_socket object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_socket(const executor_type&) * constructor. */ template typename enable_if< is_convertible::value && is_convertible::value, basic_stream_socket& >::type operator=(basic_stream_socket&& other) { basic_socket::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /** * This function destroys the socket, cancelling any outstanding asynchronous * operations associated with the socket as if by calling @c cancel. */ ~basic_stream_socket() { } /// Send some data on the socket. /** * This function is used to send data on the stream socket. The function * call will block until one or more bytes of the data has been sent * successfully, or an until error occurs. * * @param buffers One or more data buffers to be sent on the socket. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref write function if you need to ensure that all data * is written before the blocking operation completes. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.send(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t send(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "send"); return s; } /// Send some data on the socket. /** * This function is used to send data on the stream socket. The function * call will block until one or more bytes of the data has been sent * successfully, or an until error occurs. * * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @returns The number of bytes sent. * * @throws asio::system_error Thrown on failure. * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref write function if you need to ensure that all data * is written before the blocking operation completes. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.send(asio::buffer(data, size), 0); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); asio::detail::throw_error(ec, "send"); return s; } /// Send some data on the socket. /** * This function is used to send data on the stream socket. The function * call will block until one or more bytes of the data has been sent * successfully, or an until error occurs. * * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. Returns 0 if an error occurred. * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref write function if you need to ensure that all data * is written before the blocking operation completes. */ template std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().send( this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous send. /** * This function is used to asynchronously send data on the stream socket. * The function call always returns immediately. * * @param buffers One or more data buffers to be sent on the socket. Although * the buffers object may be copied as necessary, ownership of the underlying * memory blocks is retained by the caller, which must guarantee that they * remain valid until the handler is called. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref async_write function if you need to ensure that all * data is written before the asynchronous operation completes. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.async_send(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, socket_base::message_flags(0)); } /// Start an asynchronous send. /** * This function is used to asynchronously send data on the stream socket. * The function call always returns immediately. * * @param buffers One or more data buffers to be sent on the socket. Although * the buffers object may be copied as necessary, ownership of the underlying * memory blocks is retained by the caller, which must guarantee that they * remain valid until the handler is called. * * @param flags Flags specifying how the send call is to be made. * * @param handler The handler to be called when the send operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref async_write function if you need to ensure that all * data is written before the asynchronous operation completes. * * @par Example * To send a single data buffer use the @ref buffer function as follows: * @code * socket.async_send(asio::buffer(data, size), 0, handler); * @endcode * See the @ref buffer documentation for information on sending multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, flags); } /// Receive some data on the socket. /** * This function is used to receive data on the stream socket. The function * call will block until one or more bytes of data has been received * successfully, or until an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.receive(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on the socket. /** * This function is used to receive data on the stream socket. The function * call will block until one or more bytes of data has been received * successfully, or until an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param flags Flags specifying how the receive call is to be made. * * @returns The number of bytes received. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.receive(asio::buffer(data, size), 0); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, flags, ec); asio::detail::throw_error(ec, "receive"); return s; } /// Receive some data on a connected socket. /** * This function is used to receive data on the stream socket. The function * call will block until one or more bytes of data has been received * successfully, or until an error occurs. * * @param buffers One or more buffers into which the data will be received. * * @param flags Flags specifying how the receive call is to be made. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. Returns 0 if an error occurred. * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. */ template std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive data from the stream * socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref async_read function if you need to ensure * that the requested amount of data is received before the asynchronous * operation completes. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.async_receive(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive(this), handler, buffers, socket_base::message_flags(0)); } /// Start an asynchronous receive. /** * This function is used to asynchronously receive data from the stream * socket. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be received. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param flags Flags specifying how the receive call is to be made. * * @param handler The handler to be called when the receive operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref async_read function if you need to ensure * that the requested amount of data is received before the asynchronous * operation completes. * * @par Example * To receive into a single data buffer use the @ref buffer function as * follows: * @code * socket.async_receive(asio::buffer(data, size), 0, handler); * @endcode * See the @ref buffer documentation for information on receiving into * multiple buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive(this), handler, buffers, flags); } /// Write some data to the socket. /** * This function is used to write data to the stream socket. The function call * will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the socket. * * @returns The number of bytes written. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * socket.write_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t write_some(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().send( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "write_some"); return s; } /// Write some data to the socket. /** * This function is used to write data to the stream socket. The function call * will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the socket. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. */ template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().send( this->impl_.get_implementation(), buffers, 0, ec); } /// Start an asynchronous write. /** * This function is used to asynchronously write data to the stream socket. * The function call always returns immediately. * * @param buffers One or more data buffers to be written to the socket. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The write operation may not transmit all of the data to the peer. * Consider using the @ref async_write function if you need to ensure that all * data is written before the asynchronous operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * socket.async_write_some(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_send(this), handler, buffers, socket_base::message_flags(0)); } /// Read some data from the socket. /** * This function is used to read data from the stream socket. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @returns The number of bytes read. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * socket.read_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t read_some(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, 0, ec); asio::detail::throw_error(ec, "read_some"); return s; } /// Read some data from the socket. /** * This function is used to read data from the stream socket. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. */ template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().receive( this->impl_.get_implementation(), buffers, 0, ec); } /// Start an asynchronous read. /** * This function is used to asynchronously read data from the stream socket. * The function call always returns immediately. * * @param buffers One or more buffers into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The read operation may not read all of the requested number of bytes. * Consider using the @ref async_read function if you need to ensure that the * requested amount of data is read before the asynchronous operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * socket.async_read_some(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_receive(this), handler, buffers, socket_base::message_flags(0)); } private: class initiate_async_send { public: typedef Executor executor_type; explicit initiate_async_send(basic_stream_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_send( self_->impl_.get_implementation(), buffers, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_stream_socket* self_; }; class initiate_async_receive { public: typedef Executor executor_type; explicit initiate_async_receive(basic_stream_socket* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_receive( self_->impl_.get_implementation(), buffers, flags, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_stream_socket* self_; }; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_STREAM_SOCKET_HPP ================================================ FILE: src/third_party/asio/basic_streambuf.hpp ================================================ // // basic_streambuf.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_STREAMBUF_HPP #define ASIO_BASIC_STREAMBUF_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_NO_IOSTREAM) #include #include #include #include #include #include "asio/basic_streambuf_fwd.hpp" #include "asio/buffer.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Automatically resizable buffer class based on std::streambuf. /** * The @c basic_streambuf class is derived from @c std::streambuf to associate * the streambuf's input and output sequences with one or more character * arrays. These character arrays are internal to the @c basic_streambuf * object, but direct access to the array elements is provided to permit them * to be used efficiently with I/O operations. Characters written to the output * sequence of a @c basic_streambuf object are appended to the input sequence * of the same object. * * The @c basic_streambuf class's public interface is intended to permit the * following implementation strategies: * * @li A single contiguous character array, which is reallocated as necessary * to accommodate changes in the size of the character sequence. This is the * implementation approach currently used in Asio. * * @li A sequence of one or more character arrays, where each array is of the * same size. Additional character array objects are appended to the sequence * to accommodate changes in the size of the character sequence. * * @li A sequence of one or more character arrays of varying sizes. Additional * character array objects are appended to the sequence to accommodate changes * in the size of the character sequence. * * The constructor for basic_streambuf accepts a @c size_t argument specifying * the maximum of the sum of the sizes of the input sequence and output * sequence. During the lifetime of the @c basic_streambuf object, the following * invariant holds: * @code size() <= max_size()@endcode * Any member function that would, if successful, cause the invariant to be * violated shall throw an exception of class @c std::length_error. * * The constructor for @c basic_streambuf takes an Allocator argument. A copy * of this argument is used for any memory allocation performed, by the * constructor and by all member functions, during the lifetime of each @c * basic_streambuf object. * * @par Examples * Writing directly from an streambuf to a socket: * @code * asio::streambuf b; * std::ostream os(&b); * os << "Hello, World!\n"; * * // try sending some data in input sequence * size_t n = sock.send(b.data()); * * b.consume(n); // sent data is removed from input sequence * @endcode * * Reading from a socket directly into a streambuf: * @code * asio::streambuf b; * * // reserve 512 bytes in output sequence * asio::streambuf::mutable_buffers_type bufs = b.prepare(512); * * size_t n = sock.receive(bufs); * * // received data is "committed" from output sequence to input sequence * b.commit(n); * * std::istream is(&b); * std::string s; * is >> s; * @endcode */ #if defined(GENERATING_DOCUMENTATION) template > #else template #endif class basic_streambuf : public std::streambuf, private noncopyable { public: #if defined(GENERATING_DOCUMENTATION) /// The type used to represent the input sequence as a list of buffers. typedef implementation_defined const_buffers_type; /// The type used to represent the output sequence as a list of buffers. typedef implementation_defined mutable_buffers_type; #else typedef ASIO_CONST_BUFFER const_buffers_type; typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; #endif /// Construct a basic_streambuf object. /** * Constructs a streambuf with the specified maximum size. The initial size * of the streambuf's input sequence is 0. */ explicit basic_streambuf( std::size_t maximum_size = (std::numeric_limits::max)(), const Allocator& allocator = Allocator()) : max_size_(maximum_size), buffer_(allocator) { std::size_t pend = (std::min)(max_size_, buffer_delta); buffer_.resize((std::max)(pend, 1)); setg(&buffer_[0], &buffer_[0], &buffer_[0]); setp(&buffer_[0], &buffer_[0] + pend); } /// Get the size of the input sequence. /** * @returns The size of the input sequence. The value is equal to that * calculated for @c s in the following code: * @code * size_t s = 0; * const_buffers_type bufs = data(); * const_buffers_type::const_iterator i = bufs.begin(); * while (i != bufs.end()) * { * const_buffer buf(*i++); * s += buf.size(); * } * @endcode */ std::size_t size() const ASIO_NOEXCEPT { return pptr() - gptr(); } /// Get the maximum size of the basic_streambuf. /** * @returns The allowed maximum of the sum of the sizes of the input sequence * and output sequence. */ std::size_t max_size() const ASIO_NOEXCEPT { return max_size_; } /// Get the current capacity of the basic_streambuf. /** * @returns The current total capacity of the streambuf, i.e. for both the * input sequence and output sequence. */ std::size_t capacity() const ASIO_NOEXCEPT { return buffer_.capacity(); } /// Get a list of buffers that represents the input sequence. /** * @returns An object of type @c const_buffers_type that satisfies * ConstBufferSequence requirements, representing all character arrays in the * input sequence. * * @note The returned object is invalidated by any @c basic_streambuf member * function that modifies the input sequence or output sequence. */ const_buffers_type data() const ASIO_NOEXCEPT { return asio::buffer(asio::const_buffer(gptr(), (pptr() - gptr()) * sizeof(char_type))); } /// Get a list of buffers that represents the output sequence, with the given /// size. /** * Ensures that the output sequence can accommodate @c n characters, * reallocating character array objects as necessary. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing character array objects * at the start of the output sequence such that the sum of the buffer sizes * is @c n. * * @throws std::length_error If size() + n > max_size(). * * @note The returned object is invalidated by any @c basic_streambuf member * function that modifies the input sequence or output sequence. */ mutable_buffers_type prepare(std::size_t n) { reserve(n); return asio::buffer(asio::mutable_buffer( pptr(), n * sizeof(char_type))); } /// Move characters from the output sequence to the input sequence. /** * Appends @c n characters from the start of the output sequence to the input * sequence. The beginning of the output sequence is advanced by @c n * characters. * * Requires a preceding call prepare(x) where x >= n, and * no intervening operations that modify the input or output sequence. * * @note If @c n is greater than the size of the output sequence, the entire * output sequence is moved to the input sequence and no error is issued. */ void commit(std::size_t n) { n = std::min(n, epptr() - pptr()); pbump(static_cast(n)); setg(eback(), gptr(), pptr()); } /// Remove characters from the input sequence. /** * Removes @c n characters from the beginning of the input sequence. * * @note If @c n is greater than the size of the input sequence, the entire * input sequence is consumed and no error is issued. */ void consume(std::size_t n) { if (egptr() < pptr()) setg(&buffer_[0], gptr(), pptr()); if (gptr() + n > pptr()) n = pptr() - gptr(); gbump(static_cast(n)); } protected: enum { buffer_delta = 128 }; /// Override std::streambuf behaviour. /** * Behaves according to the specification of @c std::streambuf::underflow(). */ int_type underflow() { if (gptr() < pptr()) { setg(&buffer_[0], gptr(), pptr()); return traits_type::to_int_type(*gptr()); } else { return traits_type::eof(); } } /// Override std::streambuf behaviour. /** * Behaves according to the specification of @c std::streambuf::overflow(), * with the specialisation that @c std::length_error is thrown if appending * the character to the input sequence would require the condition * size() > max_size() to be true. */ int_type overflow(int_type c) { if (!traits_type::eq_int_type(c, traits_type::eof())) { if (pptr() == epptr()) { std::size_t buffer_size = pptr() - gptr(); if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta) { reserve(max_size_ - buffer_size); } else { reserve(buffer_delta); } } *pptr() = traits_type::to_char_type(c); pbump(1); return c; } return traits_type::not_eof(c); } void reserve(std::size_t n) { // Get current stream positions as offsets. std::size_t gnext = gptr() - &buffer_[0]; std::size_t pnext = pptr() - &buffer_[0]; std::size_t pend = epptr() - &buffer_[0]; // Check if there is already enough space in the put area. if (n <= pend - pnext) { return; } // Shift existing contents of get area to start of buffer. if (gnext > 0) { pnext -= gnext; std::memmove(&buffer_[0], &buffer_[0] + gnext, pnext); } // Ensure buffer is large enough to hold at least the specified size. if (n > pend - pnext) { if (n <= max_size_ && pnext <= max_size_ - n) { pend = pnext + n; buffer_.resize((std::max)(pend, 1)); } else { std::length_error ex("asio::streambuf too long"); asio::detail::throw_exception(ex); } } // Update stream positions. setg(&buffer_[0], &buffer_[0], &buffer_[0] + pnext); setp(&buffer_[0] + pnext, &buffer_[0] + pend); } private: std::size_t max_size_; std::vector buffer_; // Helper function to get the preferred size for reading data. friend std::size_t read_size_helper( basic_streambuf& sb, std::size_t max_size) { return std::min( std::max(512, sb.buffer_.capacity() - sb.size()), std::min(max_size, sb.max_size() - sb.size())); } }; /// Adapts basic_streambuf to the dynamic buffer sequence type requirements. #if defined(GENERATING_DOCUMENTATION) template > #else template #endif class basic_streambuf_ref { public: /// The type used to represent the input sequence as a list of buffers. typedef typename basic_streambuf::const_buffers_type const_buffers_type; /// The type used to represent the output sequence as a list of buffers. typedef typename basic_streambuf::mutable_buffers_type mutable_buffers_type; /// Construct a basic_streambuf_ref for the given basic_streambuf object. explicit basic_streambuf_ref(basic_streambuf& sb) : sb_(sb) { } /// Copy construct a basic_streambuf_ref. basic_streambuf_ref(const basic_streambuf_ref& other) ASIO_NOEXCEPT : sb_(other.sb_) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move construct a basic_streambuf_ref. basic_streambuf_ref(basic_streambuf_ref&& other) ASIO_NOEXCEPT : sb_(other.sb_) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the size of the input sequence. std::size_t size() const ASIO_NOEXCEPT { return sb_.size(); } /// Get the maximum size of the dynamic buffer. std::size_t max_size() const ASIO_NOEXCEPT { return sb_.max_size(); } /// Get the current capacity of the dynamic buffer. std::size_t capacity() const ASIO_NOEXCEPT { return sb_.capacity(); } /// Get a list of buffers that represents the input sequence. const_buffers_type data() const ASIO_NOEXCEPT { return sb_.data(); } /// Get a list of buffers that represents the output sequence, with the given /// size. mutable_buffers_type prepare(std::size_t n) { return sb_.prepare(n); } /// Move bytes from the output sequence to the input sequence. void commit(std::size_t n) { return sb_.commit(n); } /// Remove characters from the input sequence. void consume(std::size_t n) { return sb_.consume(n); } private: basic_streambuf& sb_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_BASIC_STREAMBUF_HPP ================================================ FILE: src/third_party/asio/basic_streambuf_fwd.hpp ================================================ // // basic_streambuf_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_STREAMBUF_FWD_HPP #define ASIO_BASIC_STREAMBUF_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_NO_IOSTREAM) #include namespace asio { template > class basic_streambuf; template > class basic_streambuf_ref; } // namespace asio #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_BASIC_STREAMBUF_FWD_HPP ================================================ FILE: src/third_party/asio/basic_waitable_timer.hpp ================================================ // // basic_waitable_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BASIC_WAITABLE_TIMER_HPP #define ASIO_BASIC_WAITABLE_TIMER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/chrono_time_traits.hpp" #include "asio/detail/deadline_timer_service.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/executor.hpp" #include "asio/wait_traits.hpp" #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) #define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL // Forward declaration with defaulted arguments. template , typename Executor = executor> class basic_waitable_timer; #endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) /// Provides waitable timer functionality. /** * The basic_waitable_timer class template provides the ability to perform a * blocking or asynchronous wait for a timer to expire. * * A waitable timer is always in one of two states: "expired" or "not expired". * If the wait() or async_wait() function is called on an expired timer, the * wait operation will complete immediately. * * Most applications will use one of the asio::steady_timer, * asio::system_timer or asio::high_resolution_timer typedefs. * * @note This waitable timer functionality is for use with the C++11 standard * library's @c <chrono> facility, or with the Boost.Chrono library. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Examples * Performing a blocking wait (C++11): * @code * // Construct a timer without setting an expiry time. * asio::steady_timer timer(my_context); * * // Set an expiry time relative to now. * timer.expires_after(std::chrono::seconds(5)); * * // Wait for the timer to expire. * timer.wait(); * @endcode * * @par * Performing an asynchronous wait (C++11): * @code * void handler(const asio::error_code& error) * { * if (!error) * { * // Timer expired. * } * } * * ... * * // Construct a timer with an absolute expiry time. * asio::steady_timer timer(my_context, * std::chrono::steady_clock::now() + std::chrono::seconds(60)); * * // Start an asynchronous wait. * timer.async_wait(handler); * @endcode * * @par Changing an active waitable timer's expiry time * * Changing the expiry time of a timer while there are pending asynchronous * waits causes those wait operations to be cancelled. To ensure that the action * associated with the timer is performed only once, use something like this: * used: * * @code * void on_some_event() * { * if (my_timer.expires_after(seconds(5)) > 0) * { * // We managed to cancel the timer. Start new asynchronous wait. * my_timer.async_wait(on_timeout); * } * else * { * // Too late, timer has already expired! * } * } * * void on_timeout(const asio::error_code& e) * { * if (e != asio::error::operation_aborted) * { * // Timer was not cancelled, take necessary action. * } * } * @endcode * * @li The asio::basic_waitable_timer::expires_after() function * cancels any pending asynchronous waits, and returns the number of * asynchronous waits that were cancelled. If it returns 0 then you were too * late and the wait handler has already been executed, or will soon be * executed. If it returns 1 then the wait handler was successfully cancelled. * * @li If a wait handler is cancelled, the asio::error_code passed to * it contains the value asio::error::operation_aborted. */ template class basic_waitable_timer { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the timer type to another executor. template struct rebind_executor { /// The timer type when rebound to the specified executor. typedef basic_waitable_timer other; }; /// The clock type. typedef Clock clock_type; /// The duration type of the clock. typedef typename clock_type::duration duration; /// The time point type of the clock. typedef typename clock_type::time_point time_point; /// The wait traits type. typedef WaitTraits traits_type; /// Constructor. /** * This constructor creates a timer without setting an expiry time. The * expires_at() or expires_after() functions must be called to set an expiry * time before the timer can be waited on. * * @param ex The I/O executor that the timer will use, by default, to * dispatch handlers for any asynchronous operations performed on the timer. */ explicit basic_waitable_timer(const executor_type& ex) : impl_(ex) { } /// Constructor. /** * This constructor creates a timer without setting an expiry time. The * expires_at() or expires_after() functions must be called to set an expiry * time before the timer can be waited on. * * @param context An execution context which provides the I/O executor that * the timer will use, by default, to dispatch handlers for any asynchronous * operations performed on the timer. */ template explicit basic_waitable_timer(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { } /// Constructor to set a particular expiry time as an absolute time. /** * This constructor creates a timer and sets the expiry time. * * @param ex The I/O executor object that the timer will use, by default, to * dispatch handlers for any asynchronous operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, expressed * as an absolute time. */ basic_waitable_timer(const executor_type& ex, const time_point& expiry_time) : impl_(ex) { asio::error_code ec; impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); } /// Constructor to set a particular expiry time as an absolute time. /** * This constructor creates a timer and sets the expiry time. * * @param context An execution context which provides the I/O executor that * the timer will use, by default, to dispatch handlers for any asynchronous * operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, expressed * as an absolute time. */ template explicit basic_waitable_timer(ExecutionContext& context, const time_point& expiry_time, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); } /// Constructor to set a particular expiry time relative to now. /** * This constructor creates a timer and sets the expiry time. * * @param ex The I/O executor that the timer will use, by default, to * dispatch handlers for any asynchronous operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, relative to * now. */ basic_waitable_timer(const executor_type& ex, const duration& expiry_time) : impl_(ex) { asio::error_code ec; impl_.get_service().expires_after( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_after"); } /// Constructor to set a particular expiry time relative to now. /** * This constructor creates a timer and sets the expiry time. * * @param context An execution context which provides the I/O executor that * the timer will use, by default, to dispatch handlers for any asynchronous * operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, relative to * now. */ template explicit basic_waitable_timer(ExecutionContext& context, const duration& expiry_time, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().expires_after( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_after"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_waitable_timer from another. /** * This constructor moves a timer from one object to another. * * @param other The other basic_waitable_timer object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_waitable_timer(const executor_type&) * constructor. */ basic_waitable_timer(basic_waitable_timer&& other) : impl_(std::move(other.impl_)) { } /// Move-assign a basic_waitable_timer from another. /** * This assignment operator moves a timer from one object to another. Cancels * any outstanding asynchronous operations associated with the target object. * * @param other The other basic_waitable_timer object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_waitable_timer(const executor_type&) * constructor. */ basic_waitable_timer& operator=(basic_waitable_timer&& other) { impl_ = std::move(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the timer. /** * This function destroys the timer, cancelling any outstanding asynchronous * wait operations associated with the timer as if by calling @c cancel. */ ~basic_waitable_timer() { } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Cancel any asynchronous operations that are waiting on the timer. /** * This function forces the completion of any pending asynchronous wait * operations against the timer. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @return The number of asynchronous operations that were cancelled. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when cancel() is called, then the * handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel() { asio::error_code ec; std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); return s; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use non-error_code overload.) Cancel any asynchronous /// operations that are waiting on the timer. /** * This function forces the completion of any pending asynchronous wait * operations against the timer. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. * * @note If the timer has already expired when cancel() is called, then the * handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel(asio::error_code& ec) { return impl_.get_service().cancel(impl_.get_implementation(), ec); } #endif // !defined(ASIO_NO_DEPRECATED) /// Cancels one asynchronous operation that is waiting on the timer. /** * This function forces the completion of one pending asynchronous wait * operation against the timer. Handlers are cancelled in FIFO order. The * handler for the cancelled operation will be invoked with the * asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @return The number of asynchronous operations that were cancelled. That is, * either 0 or 1. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when cancel_one() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel_one() { asio::error_code ec; std::size_t s = impl_.get_service().cancel_one( impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel_one"); return s; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use non-error_code overload.) Cancels one asynchronous /// operation that is waiting on the timer. /** * This function forces the completion of one pending asynchronous wait * operation against the timer. Handlers are cancelled in FIFO order. The * handler for the cancelled operation will be invoked with the * asio::error::operation_aborted error code. * * Cancelling the timer does not change the expiry time. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. That is, * either 0 or 1. * * @note If the timer has already expired when cancel_one() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t cancel_one(asio::error_code& ec) { return impl_.get_service().cancel_one(impl_.get_implementation(), ec); } /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute /// time. /** * This function may be used to obtain the timer's current expiry time. * Whether the timer has expired or not does not affect this value. */ time_point expires_at() const { return impl_.get_service().expires_at(impl_.get_implementation()); } #endif // !defined(ASIO_NO_DEPRECATED) /// Get the timer's expiry time as an absolute time. /** * This function may be used to obtain the timer's current expiry time. * Whether the timer has expired or not does not affect this value. */ time_point expiry() const { return impl_.get_service().expiry(impl_.get_implementation()); } /// Set the timer's expiry time as an absolute time. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @return The number of asynchronous operations that were cancelled. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when expires_at() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_at(const time_point& expiry_time) { asio::error_code ec; std::size_t s = impl_.get_service().expires_at( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); return s; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use non-error_code overload.) Set the timer's expiry time as /// an absolute time. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. * * @note If the timer has already expired when expires_at() is called, then * the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_at(const time_point& expiry_time, asio::error_code& ec) { return impl_.get_service().expires_at( impl_.get_implementation(), expiry_time, ec); } #endif // !defined(ASIO_NO_DEPRECATED) /// Set the timer's expiry time relative to now. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @return The number of asynchronous operations that were cancelled. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when expires_after() is called, * then the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_after(const duration& expiry_time) { asio::error_code ec; std::size_t s = impl_.get_service().expires_after( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_after"); return s; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use expiry().) Get the timer's expiry time relative to now. /** * This function may be used to obtain the timer's current expiry time. * Whether the timer has expired or not does not affect this value. */ duration expires_from_now() const { return impl_.get_service().expires_from_now(impl_.get_implementation()); } /// (Deprecated: Use expires_after().) Set the timer's expiry time relative /// to now. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @return The number of asynchronous operations that were cancelled. * * @throws asio::system_error Thrown on failure. * * @note If the timer has already expired when expires_from_now() is called, * then the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_from_now(const duration& expiry_time) { asio::error_code ec; std::size_t s = impl_.get_service().expires_from_now( impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_from_now"); return s; } /// (Deprecated: Use expires_after().) Set the timer's expiry time relative /// to now. /** * This function sets the expiry time. Any pending asynchronous wait * operations will be cancelled. The handler for each cancelled operation will * be invoked with the asio::error::operation_aborted error code. * * @param expiry_time The expiry time to be used for the timer. * * @param ec Set to indicate what error occurred, if any. * * @return The number of asynchronous operations that were cancelled. * * @note If the timer has already expired when expires_from_now() is called, * then the handlers for asynchronous wait operations will: * * @li have already been invoked; or * * @li have been queued for invocation in the near future. * * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ std::size_t expires_from_now(const duration& expiry_time, asio::error_code& ec) { return impl_.get_service().expires_from_now( impl_.get_implementation(), expiry_time, ec); } #endif // !defined(ASIO_NO_DEPRECATED) /// Perform a blocking wait on the timer. /** * This function is used to wait for the timer to expire. This function * blocks and does not return until the timer has expired. * * @throws asio::system_error Thrown on failure. */ void wait() { asio::error_code ec; impl_.get_service().wait(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "wait"); } /// Perform a blocking wait on the timer. /** * This function is used to wait for the timer to expire. This function * blocks and does not return until the timer has expired. * * @param ec Set to indicate what error occurred, if any. */ void wait(asio::error_code& ec) { impl_.get_service().wait(impl_.get_implementation(), ec); } /// Start an asynchronous wait on the timer. /** * This function may be used to initiate an asynchronous wait against the * timer. It always returns immediately. * * For each call to async_wait(), the supplied handler will be called exactly * once. The handler will be called when: * * @li The timer has expired. * * @li The timer was cancelled, in which case the handler is passed the error * code asio::error::operation_aborted. * * @param handler The handler to be called when the timer expires. Copies * will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (asio::error_code)) async_wait( ASIO_MOVE_ARG(WaitHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_wait(this), handler); } private: // Disallow copying and assignment. basic_waitable_timer(const basic_waitable_timer&) ASIO_DELETED; basic_waitable_timer& operator=( const basic_waitable_timer&) ASIO_DELETED; class initiate_async_wait { public: typedef Executor executor_type; explicit initiate_async_wait(basic_waitable_timer* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler. ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_wait( self_->impl_.get_implementation(), handler2.value, self_->impl_.get_implementation_executor()); } private: basic_waitable_timer* self_; }; detail::io_object_impl< detail::deadline_timer_service< detail::chrono_time_traits >, executor_type > impl_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BASIC_WAITABLE_TIMER_HPP ================================================ FILE: src/third_party/asio/bind_executor.hpp ================================================ // // bind_executor.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BIND_EXECUTOR_HPP #define ASIO_BIND_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/associated_executor.hpp" #include "asio/associated_allocator.hpp" #include "asio/async_result.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp" #include "asio/uses_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct executor_binder_check { typedef void type; }; // Helper to automatically define nested typedef result_type. template struct executor_binder_result_type { protected: typedef void result_type_or_void; }; template struct executor_binder_result_type::type> { typedef typename T::result_type result_type; protected: typedef result_type result_type_or_void; }; template struct executor_binder_result_type { typedef R result_type; protected: typedef result_type result_type_or_void; }; template struct executor_binder_result_type { typedef R result_type; protected: typedef result_type result_type_or_void; }; template struct executor_binder_result_type { typedef R result_type; protected: typedef result_type result_type_or_void; }; template struct executor_binder_result_type { typedef R result_type; protected: typedef result_type result_type_or_void; }; template struct executor_binder_result_type { typedef R result_type; protected: typedef result_type result_type_or_void; }; template struct executor_binder_result_type { typedef R result_type; protected: typedef result_type result_type_or_void; }; // Helper to automatically define nested typedef argument_type. template struct executor_binder_argument_type {}; template struct executor_binder_argument_type::type> { typedef typename T::argument_type argument_type; }; template struct executor_binder_argument_type { typedef A1 argument_type; }; template struct executor_binder_argument_type { typedef A1 argument_type; }; // Helper to automatically define nested typedefs first_argument_type and // second_argument_type. template struct executor_binder_argument_types {}; template struct executor_binder_argument_types::type> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type; }; template struct executor_binder_argument_type { typedef A1 first_argument_type; typedef A2 second_argument_type; }; template struct executor_binder_argument_type { typedef A1 first_argument_type; typedef A2 second_argument_type; }; // Helper to: // - Apply the empty base optimisation to the executor. // - Perform uses_executor construction of the target type, if required. template class executor_binder_base; template class executor_binder_base : protected Executor { protected: template executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) : executor_(ASIO_MOVE_CAST(E)(e)), target_(executor_arg_t(), executor_, ASIO_MOVE_CAST(U)(u)) { } Executor executor_; T target_; }; template class executor_binder_base { protected: template executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) : executor_(ASIO_MOVE_CAST(E)(e)), target_(ASIO_MOVE_CAST(U)(u)) { } Executor executor_; T target_; }; // Helper to enable SFINAE on zero-argument operator() below. template struct executor_binder_result_of0 { typedef void type; }; template struct executor_binder_result_of0::type>::type> { typedef typename result_of::type type; }; } // namespace detail /// A call wrapper type to bind an executor of type @c Executor to an object of /// type @c T. template class executor_binder #if !defined(GENERATING_DOCUMENTATION) : public detail::executor_binder_result_type, public detail::executor_binder_argument_type, public detail::executor_binder_argument_types, private detail::executor_binder_base< T, Executor, uses_executor::value> #endif // !defined(GENERATING_DOCUMENTATION) { public: /// The type of the target object. typedef T target_type; /// The type of the associated executor. typedef Executor executor_type; #if defined(GENERATING_DOCUMENTATION) /// The return type if a function. /** * The type of @c result_type is based on the type @c T of the wrapper's * target object: * * @li if @c T is a pointer to function type, @c result_type is a synonym for * the return type of @c T; * * @li if @c T is a class type with a member type @c result_type, then @c * result_type is a synonym for @c T::result_type; * * @li otherwise @c result_type is not defined. */ typedef see_below result_type; /// The type of the function's argument. /** * The type of @c argument_type is based on the type @c T of the wrapper's * target object: * * @li if @c T is a pointer to a function type accepting a single argument, * @c argument_type is a synonym for the return type of @c T; * * @li if @c T is a class type with a member type @c argument_type, then @c * argument_type is a synonym for @c T::argument_type; * * @li otherwise @c argument_type is not defined. */ typedef see_below argument_type; /// The type of the function's first argument. /** * The type of @c first_argument_type is based on the type @c T of the * wrapper's target object: * * @li if @c T is a pointer to a function type accepting two arguments, @c * first_argument_type is a synonym for the return type of @c T; * * @li if @c T is a class type with a member type @c first_argument_type, * then @c first_argument_type is a synonym for @c T::first_argument_type; * * @li otherwise @c first_argument_type is not defined. */ typedef see_below first_argument_type; /// The type of the function's second argument. /** * The type of @c second_argument_type is based on the type @c T of the * wrapper's target object: * * @li if @c T is a pointer to a function type accepting two arguments, @c * second_argument_type is a synonym for the return type of @c T; * * @li if @c T is a class type with a member type @c first_argument_type, * then @c second_argument_type is a synonym for @c T::second_argument_type; * * @li otherwise @c second_argument_type is not defined. */ typedef see_below second_argument_type; #endif // defined(GENERATING_DOCUMENTATION) /// Construct an executor wrapper for the specified object. /** * This constructor is only valid if the type @c T is constructible from type * @c U. */ template executor_binder(executor_arg_t, const executor_type& e, ASIO_MOVE_ARG(U) u) : base_type(e, ASIO_MOVE_CAST(U)(u)) { } /// Copy constructor. executor_binder(const executor_binder& other) : base_type(other.get_executor(), other.get()) { } /// Construct a copy, but specify a different executor. executor_binder(executor_arg_t, const executor_type& e, const executor_binder& other) : base_type(e, other.get()) { } /// Construct a copy of a different executor wrapper type. /** * This constructor is only valid if the @c Executor type is constructible * from type @c OtherExecutor, and the type @c T is constructible from type * @c U. */ template executor_binder(const executor_binder& other) : base_type(other.get_executor(), other.get()) { } /// Construct a copy of a different executor wrapper type, but specify a /// different executor. /** * This constructor is only valid if the type @c T is constructible from type * @c U. */ template executor_binder(executor_arg_t, const executor_type& e, const executor_binder& other) : base_type(e, other.get()) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. executor_binder(executor_binder&& other) : base_type(ASIO_MOVE_CAST(executor_type)(other.get_executor()), ASIO_MOVE_CAST(T)(other.get())) { } /// Move construct the target object, but specify a different executor. executor_binder(executor_arg_t, const executor_type& e, executor_binder&& other) : base_type(e, ASIO_MOVE_CAST(T)(other.get())) { } /// Move construct from a different executor wrapper type. template executor_binder(executor_binder&& other) : base_type(ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()), ASIO_MOVE_CAST(U)(other.get())) { } /// Move construct from a different executor wrapper type, but specify a /// different executor. template executor_binder(executor_arg_t, const executor_type& e, executor_binder&& other) : base_type(e, ASIO_MOVE_CAST(U)(other.get())) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ~executor_binder() { } /// Obtain a reference to the target object. target_type& get() ASIO_NOEXCEPT { return this->target_; } /// Obtain a reference to the target object. const target_type& get() const ASIO_NOEXCEPT { return this->target_; } /// Obtain the associated executor. executor_type get_executor() const ASIO_NOEXCEPT { return this->executor_; } #if defined(GENERATING_DOCUMENTATION) template auto operator()(Args&& ...); template auto operator()(Args&& ...) const; #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) /// Forwarding function call operator. template typename result_of::type operator()( ASIO_MOVE_ARG(Args)... args) { return this->target_(ASIO_MOVE_CAST(Args)(args)...); } /// Forwarding function call operator. template typename result_of::type operator()( ASIO_MOVE_ARG(Args)... args) const { return this->target_(ASIO_MOVE_CAST(Args)(args)...); } #elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) typename detail::executor_binder_result_of0::type operator()() { return this->target_(); } typename detail::executor_binder_result_of0::type operator()() const { return this->target_(); } #define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \ template \ typename result_of::type operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template \ typename result_of::type operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) const \ { \ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF) #undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF #else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) typedef typename detail::executor_binder_result_type::result_type_or_void result_type_or_void; result_type_or_void operator()() { return this->target_(); } result_type_or_void operator()() const { return this->target_(); } #define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \ template \ result_type_or_void operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template \ result_type_or_void operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) const \ { \ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF) #undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF #endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) private: typedef detail::executor_binder_base::value> base_type; }; /// Associate an object of type @c T with an executor of type @c Executor. template inline executor_binder::type, Executor> bind_executor(const Executor& ex, ASIO_MOVE_ARG(T) t, typename enable_if::value>::type* = 0) { return executor_binder::type, Executor>( executor_arg_t(), ex, ASIO_MOVE_CAST(T)(t)); } /// Associate an object of type @c T with an execution context's executor. template inline executor_binder::type, typename ExecutionContext::executor_type> bind_executor(ExecutionContext& ctx, ASIO_MOVE_ARG(T) t, typename enable_if::value>::type* = 0) { return executor_binder::type, typename ExecutionContext::executor_type>( executor_arg_t(), ctx.get_executor(), ASIO_MOVE_CAST(T)(t)); } #if !defined(GENERATING_DOCUMENTATION) template struct uses_executor, Executor> : true_type {}; template class async_result, Signature> { public: typedef executor_binder< typename async_result::completion_handler_type, Executor> completion_handler_type; typedef typename async_result::return_type return_type; explicit async_result(executor_binder& b) : target_(b.get()) { } return_type get() { return target_.get(); } private: async_result(const async_result&) ASIO_DELETED; async_result& operator=(const async_result&) ASIO_DELETED; async_result target_; }; template struct associated_allocator, Allocator> { typedef typename associated_allocator::type type; static type get(const executor_binder& b, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(b.get(), a); } }; template struct associated_executor, Executor1> { typedef Executor type; static type get(const executor_binder& b, const Executor1& = Executor1()) ASIO_NOEXCEPT { return b.get_executor(); } }; #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BIND_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/buffer.hpp ================================================ // // buffer.hpp // ~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFER_HPP #define ASIO_BUFFER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include #include #include #include "asio/detail/array_fwd.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/string_view.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/detail/type_traits.hpp" #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1700) # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0) # if !defined(ASIO_DISABLE_BUFFER_DEBUGGING) # define ASIO_ENABLE_BUFFER_DEBUGGING # endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING) # endif // defined(_HAS_ITERATOR_DEBUGGING) #endif // defined(ASIO_MSVC) && (ASIO_MSVC >= 1700) #if defined(__GNUC__) # if defined(_GLIBCXX_DEBUG) # if !defined(ASIO_DISABLE_BUFFER_DEBUGGING) # define ASIO_ENABLE_BUFFER_DEBUGGING # endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING) # endif // defined(_GLIBCXX_DEBUG) #endif // defined(__GNUC__) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) # include "asio/detail/functional.hpp" #endif // ASIO_ENABLE_BUFFER_DEBUGGING #if defined(ASIO_HAS_BOOST_WORKAROUND) # include # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \ || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) # define ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND # endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) #endif // defined(ASIO_HAS_BOOST_WORKAROUND) #if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) # include "asio/detail/type_traits.hpp" #endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) #include "asio/detail/push_options.hpp" namespace asio { class mutable_buffer; class const_buffer; /// Holds a buffer that can be modified. /** * The mutable_buffer class provides a safe representation of a buffer that can * be modified. It does not own the underlying data, and so is cheap to copy or * assign. * * @par Accessing Buffer Contents * * The contents of a buffer may be accessed using the @c data() and @c size() * member functions: * * @code asio::mutable_buffer b1 = ...; * std::size_t s1 = b1.size(); * unsigned char* p1 = static_cast(b1.data()); * @endcode * * The @c data() member function permits violations of type safety, so uses of * it in application code should be carefully considered. */ class mutable_buffer { public: /// Construct an empty buffer. mutable_buffer() ASIO_NOEXCEPT : data_(0), size_(0) { } /// Construct a buffer to represent a given memory range. mutable_buffer(void* data, std::size_t size) ASIO_NOEXCEPT : data_(data), size_(size) { } #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) mutable_buffer(void* data, std::size_t size, asio::detail::function debug_check) : data_(data), size_(size), debug_check_(debug_check) { } const asio::detail::function& get_debug_check() const { return debug_check_; } #endif // ASIO_ENABLE_BUFFER_DEBUGGING /// Get a pointer to the beginning of the memory range. void* data() const ASIO_NOEXCEPT { #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) if (size_ && debug_check_) debug_check_(); #endif // ASIO_ENABLE_BUFFER_DEBUGGING return data_; } /// Get the size of the memory range. std::size_t size() const ASIO_NOEXCEPT { return size_; } /// Move the start of the buffer by the specified number of bytes. mutable_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT { std::size_t offset = n < size_ ? n : size_; data_ = static_cast(data_) + offset; size_ -= offset; return *this; } private: void* data_; std::size_t size_; #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) asio::detail::function debug_check_; #endif // ASIO_ENABLE_BUFFER_DEBUGGING }; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use mutable_buffer.) Adapts a single modifiable buffer so that /// it meets the requirements of the MutableBufferSequence concept. class mutable_buffers_1 : public mutable_buffer { public: /// The type for each element in the list of buffers. typedef mutable_buffer value_type; /// A random-access iterator type that may be used to read elements. typedef const mutable_buffer* const_iterator; /// Construct to represent a given memory range. mutable_buffers_1(void* data, std::size_t size) ASIO_NOEXCEPT : mutable_buffer(data, size) { } #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) mutable_buffers_1(void* data, std::size_t size, asio::detail::function debug_check) : mutable_buffer(data, size, debug_check) { } #endif // ASIO_ENABLE_BUFFER_DEBUGGING /// Construct to represent a single modifiable buffer. explicit mutable_buffers_1(const mutable_buffer& b) ASIO_NOEXCEPT : mutable_buffer(b) { } /// Get a random-access iterator to the first element. const_iterator begin() const ASIO_NOEXCEPT { return this; } /// Get a random-access iterator for one past the last element. const_iterator end() const ASIO_NOEXCEPT { return begin() + 1; } }; #endif // !defined(ASIO_NO_DEPRECATED) /// Holds a buffer that cannot be modified. /** * The const_buffer class provides a safe representation of a buffer that cannot * be modified. It does not own the underlying data, and so is cheap to copy or * assign. * * @par Accessing Buffer Contents * * The contents of a buffer may be accessed using the @c data() and @c size() * member functions: * * @code asio::const_buffer b1 = ...; * std::size_t s1 = b1.size(); * const unsigned char* p1 = static_cast(b1.data()); * @endcode * * The @c data() member function permits violations of type safety, so uses of * it in application code should be carefully considered. */ class const_buffer { public: /// Construct an empty buffer. const_buffer() ASIO_NOEXCEPT : data_(0), size_(0) { } /// Construct a buffer to represent a given memory range. const_buffer(const void* data, std::size_t size) ASIO_NOEXCEPT : data_(data), size_(size) { } /// Construct a non-modifiable buffer from a modifiable one. const_buffer(const mutable_buffer& b) ASIO_NOEXCEPT : data_(b.data()), size_(b.size()) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , debug_check_(b.get_debug_check()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING { } #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) const_buffer(const void* data, std::size_t size, asio::detail::function debug_check) : data_(data), size_(size), debug_check_(debug_check) { } const asio::detail::function& get_debug_check() const { return debug_check_; } #endif // ASIO_ENABLE_BUFFER_DEBUGGING /// Get a pointer to the beginning of the memory range. const void* data() const ASIO_NOEXCEPT { #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) if (size_ && debug_check_) debug_check_(); #endif // ASIO_ENABLE_BUFFER_DEBUGGING return data_; } /// Get the size of the memory range. std::size_t size() const ASIO_NOEXCEPT { return size_; } /// Move the start of the buffer by the specified number of bytes. const_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT { std::size_t offset = n < size_ ? n : size_; data_ = static_cast(data_) + offset; size_ -= offset; return *this; } private: const void* data_; std::size_t size_; #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) asio::detail::function debug_check_; #endif // ASIO_ENABLE_BUFFER_DEBUGGING }; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use const_buffer.) Adapts a single non-modifiable buffer so /// that it meets the requirements of the ConstBufferSequence concept. class const_buffers_1 : public const_buffer { public: /// The type for each element in the list of buffers. typedef const_buffer value_type; /// A random-access iterator type that may be used to read elements. typedef const const_buffer* const_iterator; /// Construct to represent a given memory range. const_buffers_1(const void* data, std::size_t size) ASIO_NOEXCEPT : const_buffer(data, size) { } #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) const_buffers_1(const void* data, std::size_t size, asio::detail::function debug_check) : const_buffer(data, size, debug_check) { } #endif // ASIO_ENABLE_BUFFER_DEBUGGING /// Construct to represent a single non-modifiable buffer. explicit const_buffers_1(const const_buffer& b) ASIO_NOEXCEPT : const_buffer(b) { } /// Get a random-access iterator to the first element. const_iterator begin() const ASIO_NOEXCEPT { return this; } /// Get a random-access iterator for one past the last element. const_iterator end() const ASIO_NOEXCEPT { return begin() + 1; } }; #endif // !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use the socket/descriptor wait() and async_wait() member /// functions.) An implementation of both the ConstBufferSequence and /// MutableBufferSequence concepts to represent a null buffer sequence. class null_buffers { public: /// The type for each element in the list of buffers. typedef mutable_buffer value_type; /// A random-access iterator type that may be used to read elements. typedef const mutable_buffer* const_iterator; /// Get a random-access iterator to the first element. const_iterator begin() const ASIO_NOEXCEPT { return &buf_; } /// Get a random-access iterator for one past the last element. const_iterator end() const ASIO_NOEXCEPT { return &buf_; } private: mutable_buffer buf_; }; /** @defgroup buffer_sequence_begin asio::buffer_sequence_begin * * @brief The asio::buffer_sequence_begin function returns an iterator * pointing to the first element in a buffer sequence. */ /*@{*/ /// Get an iterator to the first element in a buffer sequence. template inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b, typename enable_if< is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return static_cast(detail::addressof(b)); } /// Get an iterator to the first element in a buffer sequence. template inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b, typename enable_if< is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return static_cast(detail::addressof(b)); } #if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /// Get an iterator to the first element in a buffer sequence. template inline auto buffer_sequence_begin(C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT -> decltype(c.begin()) { return c.begin(); } /// Get an iterator to the first element in a buffer sequence. template inline auto buffer_sequence_begin(const C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT -> decltype(c.begin()) { return c.begin(); } #else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) template inline typename C::iterator buffer_sequence_begin(C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return c.begin(); } template inline typename C::const_iterator buffer_sequence_begin(const C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return c.begin(); } #endif // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /*@}*/ /** @defgroup buffer_sequence_end asio::buffer_sequence_end * * @brief The asio::buffer_sequence_end function returns an iterator * pointing to one past the end element in a buffer sequence. */ /*@{*/ /// Get an iterator to one past the end element in a buffer sequence. template inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b, typename enable_if< is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return static_cast(detail::addressof(b)) + 1; } /// Get an iterator to one past the end element in a buffer sequence. template inline const const_buffer* buffer_sequence_end(const ConstBuffer& b, typename enable_if< is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return static_cast(detail::addressof(b)) + 1; } #if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /// Get an iterator to one past the end element in a buffer sequence. template inline auto buffer_sequence_end(C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT -> decltype(c.end()) { return c.end(); } /// Get an iterator to one past the end element in a buffer sequence. template inline auto buffer_sequence_end(const C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT -> decltype(c.end()) { return c.end(); } #else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) template inline typename C::iterator buffer_sequence_end(C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return c.end(); } template inline typename C::const_iterator buffer_sequence_end(const C& c, typename enable_if< !is_convertible::value && !is_convertible::value >::type* = 0) ASIO_NOEXCEPT { return c.end(); } #endif // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /*@}*/ namespace detail { // Tag types used to select appropriately optimised overloads. struct one_buffer {}; struct multiple_buffers {}; // Helper trait to detect single buffers. template struct buffer_sequence_cardinality : conditional< is_same::value #if !defined(ASIO_NO_DEPRECATED) || is_same::value || is_same::value #endif // !defined(ASIO_NO_DEPRECATED) || is_same::value, one_buffer, multiple_buffers>::type {}; template inline std::size_t buffer_size(one_buffer, Iterator begin, Iterator) ASIO_NOEXCEPT { return const_buffer(*begin).size(); } template inline std::size_t buffer_size(multiple_buffers, Iterator begin, Iterator end) ASIO_NOEXCEPT { std::size_t total_buffer_size = 0; Iterator iter = begin; for (; iter != end; ++iter) { const_buffer b(*iter); total_buffer_size += b.size(); } return total_buffer_size; } } // namespace detail /// Get the total number of bytes in a buffer sequence. /** * The @c buffer_size function determines the total size of all buffers in the * buffer sequence, as if computed as follows: * * @code size_t total_size = 0; * auto i = asio::buffer_sequence_begin(buffers); * auto end = asio::buffer_sequence_end(buffers); * for (; i != end; ++i) * { * const_buffer b(*i); * total_size += b.size(); * } * return total_size; @endcode * * The @c BufferSequence template parameter may meet either of the @c * ConstBufferSequence or @c MutableBufferSequence type requirements. */ template inline std::size_t buffer_size(const BufferSequence& b) ASIO_NOEXCEPT { return detail::buffer_size( detail::buffer_sequence_cardinality(), asio::buffer_sequence_begin(b), asio::buffer_sequence_end(b)); } #if !defined(ASIO_NO_DEPRECATED) /** @defgroup buffer_cast asio::buffer_cast * * @brief (Deprecated: Use the @c data() member function.) The * asio::buffer_cast function is used to obtain a pointer to the * underlying memory region associated with a buffer. * * @par Examples: * * To access the memory of a non-modifiable buffer, use: * @code asio::const_buffer b1 = ...; * const unsigned char* p1 = asio::buffer_cast(b1); * @endcode * * To access the memory of a modifiable buffer, use: * @code asio::mutable_buffer b2 = ...; * unsigned char* p2 = asio::buffer_cast(b2); * @endcode * * The asio::buffer_cast function permits violations of type safety, so * uses of it in application code should be carefully considered. */ /*@{*/ /// Cast a non-modifiable buffer to a specified pointer to POD type. template inline PointerToPodType buffer_cast(const mutable_buffer& b) ASIO_NOEXCEPT { return static_cast(b.data()); } /// Cast a non-modifiable buffer to a specified pointer to POD type. template inline PointerToPodType buffer_cast(const const_buffer& b) ASIO_NOEXCEPT { return static_cast(b.data()); } /*@}*/ #endif // !defined(ASIO_NO_DEPRECATED) /// Create a new modifiable buffer that is offset from the start of another. /** * @relates mutable_buffer */ inline mutable_buffer operator+(const mutable_buffer& b, std::size_t n) ASIO_NOEXCEPT { std::size_t offset = n < b.size() ? n : b.size(); char* new_data = static_cast(b.data()) + offset; std::size_t new_size = b.size() - offset; return mutable_buffer(new_data, new_size #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that is offset from the start of another. /** * @relates mutable_buffer */ inline mutable_buffer operator+(std::size_t n, const mutable_buffer& b) ASIO_NOEXCEPT { return b + n; } /// Create a new non-modifiable buffer that is offset from the start of another. /** * @relates const_buffer */ inline const_buffer operator+(const const_buffer& b, std::size_t n) ASIO_NOEXCEPT { std::size_t offset = n < b.size() ? n : b.size(); const char* new_data = static_cast(b.data()) + offset; std::size_t new_size = b.size() - offset; return const_buffer(new_data, new_size #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that is offset from the start of another. /** * @relates const_buffer */ inline const_buffer operator+(std::size_t n, const const_buffer& b) ASIO_NOEXCEPT { return b + n; } #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) namespace detail { template class buffer_debug_check { public: buffer_debug_check(Iterator iter) : iter_(iter) { } ~buffer_debug_check() { #if defined(ASIO_MSVC) && (ASIO_MSVC == 1400) // MSVC 8's string iterator checking may crash in a std::string::iterator // object's destructor when the iterator points to an already-destroyed // std::string object, unless the iterator is cleared first. iter_ = Iterator(); #endif // defined(ASIO_MSVC) && (ASIO_MSVC == 1400) } void operator()() { (void)*iter_; } private: Iterator iter_; }; } // namespace detail #endif // ASIO_ENABLE_BUFFER_DEBUGGING /** @defgroup buffer asio::buffer * * @brief The asio::buffer function is used to create a buffer object to * represent raw memory, an array of POD elements, a vector of POD elements, * or a std::string. * * A buffer object represents a contiguous region of memory as a 2-tuple * consisting of a pointer and size in bytes. A tuple of the form {void*, * size_t} specifies a mutable (modifiable) region of memory. Similarly, a * tuple of the form {const void*, size_t} specifies a const * (non-modifiable) region of memory. These two forms correspond to the classes * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the * opposite conversion is not permitted. * * The simplest use case involves reading or writing a single buffer of a * specified size: * * @code sock.send(asio::buffer(data, size)); @endcode * * In the above example, the return value of asio::buffer meets the * requirements of the ConstBufferSequence concept so that it may be directly * passed to the socket's write function. A buffer created for modifiable * memory also meets the requirements of the MutableBufferSequence concept. * * An individual buffer may be created from a builtin array, std::vector, * std::array or boost::array of POD elements. This helps prevent buffer * overruns by automatically determining the size of the buffer: * * @code char d1[128]; * size_t bytes_transferred = sock.receive(asio::buffer(d1)); * * std::vector d2(128); * bytes_transferred = sock.receive(asio::buffer(d2)); * * std::array d3; * bytes_transferred = sock.receive(asio::buffer(d3)); * * boost::array d4; * bytes_transferred = sock.receive(asio::buffer(d4)); @endcode * * In all three cases above, the buffers created are exactly 128 bytes long. * Note that a vector is @e never automatically resized when creating or using * a buffer. The buffer size is determined using the vector's size() * member function, and not its capacity. * * @par Accessing Buffer Contents * * The contents of a buffer may be accessed using the @c data() and @c size() * member functions: * * @code asio::mutable_buffer b1 = ...; * std::size_t s1 = b1.size(); * unsigned char* p1 = static_cast(b1.data()); * * asio::const_buffer b2 = ...; * std::size_t s2 = b2.size(); * const void* p2 = b2.data(); @endcode * * The @c data() member function permits violations of type safety, so * uses of it in application code should be carefully considered. * * For convenience, a @ref buffer_size function is provided that works with * both buffers and buffer sequences (that is, types meeting the * ConstBufferSequence or MutableBufferSequence type requirements). In this * case, the function returns the total size of all buffers in the sequence. * * @par Buffer Copying * * The @ref buffer_copy function may be used to copy raw bytes between * individual buffers and buffer sequences. * * In particular, when used with the @ref buffer_size function, the @ref * buffer_copy function can be used to linearise a sequence of buffers. For * example: * * @code vector buffers = ...; * * vector data(asio::buffer_size(buffers)); * asio::buffer_copy(asio::buffer(data), buffers); @endcode * * Note that @ref buffer_copy is implemented in terms of @c memcpy, and * consequently it cannot be used to copy between overlapping memory regions. * * @par Buffer Invalidation * * A buffer object does not have any ownership of the memory it refers to. It * is the responsibility of the application to ensure the memory region remains * valid until it is no longer required for an I/O operation. When the memory * is no longer available, the buffer is said to have been invalidated. * * For the asio::buffer overloads that accept an argument of type * std::vector, the buffer objects returned are invalidated by any vector * operation that also invalidates all references, pointers and iterators * referring to the elements in the sequence (C++ Std, 23.2.4) * * For the asio::buffer overloads that accept an argument of type * std::basic_string, the buffer objects returned are invalidated according to * the rules defined for invalidation of references, pointers and iterators * referring to elements of the sequence (C++ Std, 21.3). * * @par Buffer Arithmetic * * Buffer objects may be manipulated using simple arithmetic in a safe way * which helps prevent buffer overruns. Consider an array initialised as * follows: * * @code boost::array a = { 'a', 'b', 'c', 'd', 'e' }; @endcode * * A buffer object @c b1 created using: * * @code b1 = asio::buffer(a); @endcode * * represents the entire array, { 'a', 'b', 'c', 'd', 'e' }. An * optional second argument to the asio::buffer function may be used to * limit the size, in bytes, of the buffer: * * @code b2 = asio::buffer(a, 3); @endcode * * such that @c b2 represents the data { 'a', 'b', 'c' }. Even if the * size argument exceeds the actual size of the array, the size of the buffer * object created will be limited to the array size. * * An offset may be applied to an existing buffer to create a new one: * * @code b3 = b1 + 2; @endcode * * where @c b3 will set to represent { 'c', 'd', 'e' }. If the offset * exceeds the size of the existing buffer, the newly created buffer will be * empty. * * Both an offset and size may be specified to create a buffer that corresponds * to a specific range of bytes within an existing buffer: * * @code b4 = asio::buffer(b1 + 1, 3); @endcode * * so that @c b4 will refer to the bytes { 'b', 'c', 'd' }. * * @par Buffers and Scatter-Gather I/O * * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple * buffer objects may be assigned into a container that supports the * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts: * * @code * char d1[128]; * std::vector d2(128); * boost::array d3; * * boost::array bufs1 = { * asio::buffer(d1), * asio::buffer(d2), * asio::buffer(d3) }; * bytes_transferred = sock.receive(bufs1); * * std::vector bufs2; * bufs2.push_back(asio::buffer(d1)); * bufs2.push_back(asio::buffer(d2)); * bufs2.push_back(asio::buffer(d3)); * bytes_transferred = sock.send(bufs2); @endcode */ /*@{*/ #if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) # define ASIO_MUTABLE_BUFFER mutable_buffer # define ASIO_CONST_BUFFER const_buffer #else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) # define ASIO_MUTABLE_BUFFER mutable_buffers_1 # define ASIO_CONST_BUFFER const_buffers_1 #endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer from an existing buffer. /** * @returns mutable_buffer(b). */ inline ASIO_MUTABLE_BUFFER buffer( const mutable_buffer& b) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(b); } /// Create a new modifiable buffer from an existing buffer. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * b.data(), * min(b.size(), max_size_in_bytes)); @endcode */ inline ASIO_MUTABLE_BUFFER buffer(const mutable_buffer& b, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER( mutable_buffer(b.data(), b.size() < max_size_in_bytes ? b.size() : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // ASIO_ENABLE_BUFFER_DEBUGGING )); } /// Create a new non-modifiable buffer from an existing buffer. /** * @returns const_buffer(b). */ inline ASIO_CONST_BUFFER buffer( const const_buffer& b) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(b); } /// Create a new non-modifiable buffer from an existing buffer. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * b.data(), * min(b.size(), max_size_in_bytes)); @endcode */ inline ASIO_CONST_BUFFER buffer(const const_buffer& b, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(b.data(), b.size() < max_size_in_bytes ? b.size() : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given memory range. /** * @returns mutable_buffer(data, size_in_bytes). */ inline ASIO_MUTABLE_BUFFER buffer(void* data, std::size_t size_in_bytes) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data, size_in_bytes); } /// Create a new non-modifiable buffer that represents the given memory range. /** * @returns const_buffer(data, size_in_bytes). */ inline ASIO_CONST_BUFFER buffer(const void* data, std::size_t size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data, size_in_bytes); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * static_cast(data), * N * sizeof(PodType)); @endcode */ template inline ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N]) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType)); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * static_cast(data), * min(N * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N], std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType) < max_size_in_bytes ? N * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * static_cast(data), * N * sizeof(PodType)); @endcode */ template inline ASIO_CONST_BUFFER buffer( const PodType (&data)[N]) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data, N * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * static_cast(data), * min(N * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_CONST_BUFFER buffer(const PodType (&data)[N], std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data, N * sizeof(PodType) < max_size_in_bytes ? N * sizeof(PodType) : max_size_in_bytes); } #if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) // Borland C++ and Sun Studio think the overloads: // // unspecified buffer(boost::array& array ...); // // and // // unspecified buffer(boost::array& array ...); // // are ambiguous. This will be worked around by using a buffer_types traits // class that contains typedefs for the appropriate buffer and container // classes, based on whether PodType is const or non-const. namespace detail { template struct buffer_types_base; template <> struct buffer_types_base { typedef mutable_buffer buffer_type; typedef ASIO_MUTABLE_BUFFER container_type; }; template <> struct buffer_types_base { typedef const_buffer buffer_type; typedef ASIO_CONST_BUFFER container_type; }; template struct buffer_types : public buffer_types_base::value> { }; } // namespace detail template inline typename detail::buffer_types::container_type buffer(boost::array& data) ASIO_NOEXCEPT { typedef typename asio::detail::buffer_types::buffer_type buffer_type; typedef typename asio::detail::buffer_types::container_type container_type; return container_type( buffer_type(data.c_array(), data.size() * sizeof(PodType))); } template inline typename detail::buffer_types::container_type buffer(boost::array& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { typedef typename asio::detail::buffer_types::buffer_type buffer_type; typedef typename asio::detail::buffer_types::container_type container_type; return container_type( buffer_type(data.c_array(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes)); } #else // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template inline ASIO_MUTABLE_BUFFER buffer( boost::array& data) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER( data.c_array(), data.size() * sizeof(PodType)); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_MUTABLE_BUFFER buffer(boost::array& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data.c_array(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template inline ASIO_CONST_BUFFER buffer( boost::array& data) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_CONST_BUFFER buffer(boost::array& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } #endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template inline ASIO_CONST_BUFFER buffer( const boost::array& data) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_CONST_BUFFER buffer(const boost::array& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } #if defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template inline ASIO_MUTABLE_BUFFER buffer( std::array& data) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_MUTABLE_BUFFER buffer(std::array& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template inline ASIO_CONST_BUFFER buffer( std::array& data) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_CONST_BUFFER buffer(std::array& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template inline ASIO_CONST_BUFFER buffer( const std::array& data) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template inline ASIO_CONST_BUFFER buffer(const std::array& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } #endif // defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer that represents the given POD vector. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * data.size() * sizeof(PodType)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template inline ASIO_MUTABLE_BUFFER buffer( std::vector& data) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER( data.size() ? &data[0] : 0, data.size() * sizeof(PodType) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector::iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given POD vector. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template inline ASIO_MUTABLE_BUFFER buffer(std::vector& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector::iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given POD vector. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.size() ? &data[0] : 0, * data.size() * sizeof(PodType)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template inline ASIO_CONST_BUFFER buffer( const std::vector& data) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER( data.size() ? &data[0] : 0, data.size() * sizeof(PodType) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector::const_iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given POD vector. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template inline ASIO_CONST_BUFFER buffer( const std::vector& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector::const_iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given string. /** * @returns mutable_buffer(data.size() ? &data[0] : 0, * data.size() * sizeof(Elem)). * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template inline ASIO_MUTABLE_BUFFER buffer( std::basic_string& data) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string::iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given string. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template inline ASIO_MUTABLE_BUFFER buffer( std::basic_string& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) < max_size_in_bytes ? data.size() * sizeof(Elem) : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string::iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given string. /** * @returns const_buffer(data.data(), data.size() * sizeof(Elem)). * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template inline ASIO_CONST_BUFFER buffer( const std::basic_string& data) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string::const_iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given string. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template inline ASIO_CONST_BUFFER buffer( const std::basic_string& data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem) < max_size_in_bytes ? data.size() * sizeof(Elem) : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string::const_iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer that represents the given string_view. /** * @returns mutable_buffer(data.size() ? &data[0] : 0, * data.size() * sizeof(Elem)). */ template inline ASIO_CONST_BUFFER buffer( basic_string_view data) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename basic_string_view::iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given string. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode */ template inline ASIO_CONST_BUFFER buffer( basic_string_view data, std::size_t max_size_in_bytes) ASIO_NOEXCEPT { return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) < max_size_in_bytes ? data.size() * sizeof(Elem) : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename basic_string_view::iterator >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING ); } #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION) /*@}*/ /// Adapt a basic_string to the DynamicBuffer requirements. /** * Requires that sizeof(Elem) == 1. */ template class dynamic_string_buffer { public: /// The type used to represent a sequence of constant buffers that refers to /// the underlying memory. typedef ASIO_CONST_BUFFER const_buffers_type; /// The type used to represent a sequence of mutable buffers that refers to /// the underlying memory. typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; /// Construct a dynamic buffer from a string. /** * @param s The string to be used as backing storage for the dynamic buffer. * The object stores a reference to the string and the user is responsible * for ensuring that the string object remains valid while the * dynamic_string_buffer object, and copies of the object, are in use. * * @b DynamicBuffer_v1: Any existing data in the string is treated as the * dynamic buffer's input sequence. * * @param maximum_size Specifies a maximum size for the buffer, in bytes. */ explicit dynamic_string_buffer(std::basic_string& s, std::size_t maximum_size = (std::numeric_limits::max)()) ASIO_NOEXCEPT : string_(s), #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) size_((std::numeric_limits::max)()), #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(maximum_size) { } /// @b DynamicBuffer_v2: Copy construct a dynamic buffer. dynamic_string_buffer(const dynamic_string_buffer& other) ASIO_NOEXCEPT : string_(other.string_), #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move construct a dynamic buffer. dynamic_string_buffer(dynamic_string_buffer&& other) ASIO_NOEXCEPT : string_(other.string_), #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// @b DynamicBuffer_v1: Get the size of the input sequence. /// @b DynamicBuffer_v2: Get the current size of the underlying memory. /** * @returns @b DynamicBuffer_v1 The current size of the input sequence. * @b DynamicBuffer_v2: The current size of the underlying string if less than * max_size(). Otherwise returns max_size(). */ std::size_t size() const ASIO_NOEXCEPT { #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits::max)()) return size_; #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) return (std::min)(string_.size(), max_size()); } /// Get the maximum size of the dynamic buffer. /** * @returns The allowed maximum size of the underlying memory. */ std::size_t max_size() const ASIO_NOEXCEPT { return max_size_; } /// Get the maximum size that the buffer may grow to without triggering /// reallocation. /** * @returns The current capacity of the underlying string if less than * max_size(). Otherwise returns max_size(). */ std::size_t capacity() const ASIO_NOEXCEPT { return (std::min)(string_.capacity(), max_size()); } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the input /// sequence. /** * @returns An object of type @c const_buffers_type that satisfies * ConstBufferSequence requirements, representing the basic_string memory in * the input sequence. * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that resizes or erases the string. */ const_buffers_type data() const ASIO_NOEXCEPT { return const_buffers_type(asio::buffer(string_, size_)); } #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing the basic_string memory. * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that resizes or erases the string. */ mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT { return mutable_buffers_type(asio::buffer( asio::buffer(string_, max_size_) + pos, n)); } /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that resizes or erases the string. */ const_buffers_type data(std::size_t pos, std::size_t n) const ASIO_NOEXCEPT { return const_buffers_type(asio::buffer( asio::buffer(string_, max_size_) + pos, n)); } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the output /// sequence, with the given size. /** * Ensures that the output sequence can accommodate @c n bytes, resizing the * basic_string object as necessary. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing basic_string memory * at the start of the output sequence of size @c n. * * @throws std::length_error If size() + n > max_size(). * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that modifies the input sequence or * output sequence. */ mutable_buffers_type prepare(std::size_t n) { if (size() > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_string_buffer too long"); asio::detail::throw_exception(ex); } if (size_ == (std::numeric_limits::max)()) size_ = string_.size(); // Enable v1 behaviour. string_.resize(size_ + n); return asio::buffer(asio::buffer(string_) + size_, n); } /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input /// sequence. /** * @param n The number of bytes to append from the start of the output * sequence to the end of the input sequence. The remainder of the output * sequence is discarded. * * Requires a preceding call prepare(x) where x >= n, and * no intervening operations that modify the input or output sequence. * * @note If @c n is greater than the size of the output sequence, the entire * output sequence is moved to the input sequence and no error is issued. */ void commit(std::size_t n) { size_ += (std::min)(n, string_.size() - size_); string_.resize(size_); } #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of /// bytes. /** * Resizes the string to accommodate an additional @c n bytes at the end. * * @throws std::length_error If size() + n > max_size(). */ void grow(std::size_t n) { if (size() > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_string_buffer too long"); asio::detail::throw_exception(ex); } string_.resize(size() + n); } /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number /// of bytes. /** * Erases @c n bytes from the end of the string by resizing the basic_string * object. If @c n is greater than the current size of the string, the string * is emptied. */ void shrink(std::size_t n) { string_.resize(n > size() ? 0 : size() - n); } /// @b DynamicBuffer_v1: Remove characters from the input sequence. /// @b DynamicBuffer_v2: Consume the specified number of bytes from the /// beginning of the underlying memory. /** * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the * input sequence. @note If @c n is greater than the size of the input * sequence, the entire input sequence is consumed and no error is issued. * * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string. * If @c n is greater than the current size of the string, the string is * emptied. */ void consume(std::size_t n) { #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits::max)()) { std::size_t consume_length = (std::min)(n, size_); string_.erase(0, consume_length); size_ -= consume_length; return; } #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) string_.erase(0, n); } private: std::basic_string& string_; #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) std::size_t size_; #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) const std::size_t max_size_; }; /// Adapt a vector to the DynamicBuffer requirements. /** * Requires that sizeof(Elem) == 1. */ template class dynamic_vector_buffer { public: /// The type used to represent a sequence of constant buffers that refers to /// the underlying memory. typedef ASIO_CONST_BUFFER const_buffers_type; /// The type used to represent a sequence of mutable buffers that refers to /// the underlying memory. typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; /// Construct a dynamic buffer from a vector. /** * @param v The vector to be used as backing storage for the dynamic buffer. * The object stores a reference to the vector and the user is responsible * for ensuring that the vector object remains valid while the * dynamic_vector_buffer object, and copies of the object, are in use. * * @param maximum_size Specifies a maximum size for the buffer, in bytes. */ explicit dynamic_vector_buffer(std::vector& v, std::size_t maximum_size = (std::numeric_limits::max)()) ASIO_NOEXCEPT : vector_(v), #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) size_((std::numeric_limits::max)()), #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(maximum_size) { } /// @b DynamicBuffer_v2: Copy construct a dynamic buffer. dynamic_vector_buffer(const dynamic_vector_buffer& other) ASIO_NOEXCEPT : vector_(other.vector_), #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move construct a dynamic buffer. dynamic_vector_buffer(dynamic_vector_buffer&& other) ASIO_NOEXCEPT : vector_(other.vector_), #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// @b DynamicBuffer_v1: Get the size of the input sequence. /// @b DynamicBuffer_v2: Get the current size of the underlying memory. /** * @returns @b DynamicBuffer_v1 The current size of the input sequence. * @b DynamicBuffer_v2: The current size of the underlying vector if less than * max_size(). Otherwise returns max_size(). */ std::size_t size() const ASIO_NOEXCEPT { #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits::max)()) return size_; #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) return (std::min)(vector_.size(), max_size()); } /// Get the maximum size of the dynamic buffer. /** * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed * maximum size of the underlying memory. */ std::size_t max_size() const ASIO_NOEXCEPT { return max_size_; } /// Get the maximum size that the buffer may grow to without triggering /// reallocation. /** * @returns @b DynamicBuffer_v1: The current total capacity of the buffer, * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2: * The current capacity of the underlying vector if less than max_size(). * Otherwise returns max_size(). */ std::size_t capacity() const ASIO_NOEXCEPT { return (std::min)(vector_.capacity(), max_size()); } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the input /// sequence. /** * @returns An object of type @c const_buffers_type that satisfies * ConstBufferSequence requirements, representing the vector memory in the * input sequence. * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that modifies the input sequence or output * sequence. */ const_buffers_type data() const ASIO_NOEXCEPT { return const_buffers_type(asio::buffer(vector_, size_)); } #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing the vector memory. * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that resizes or erases the vector. */ mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT { return mutable_buffers_type(asio::buffer( asio::buffer(vector_, max_size_) + pos, n)); } /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that resizes or erases the vector. */ const_buffers_type data(std::size_t pos, std::size_t n) const ASIO_NOEXCEPT { return const_buffers_type(asio::buffer( asio::buffer(vector_, max_size_) + pos, n)); } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the output /// sequence, with the given size. /** * Ensures that the output sequence can accommodate @c n bytes, resizing the * vector object as necessary. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing vector memory at the * start of the output sequence of size @c n. * * @throws std::length_error If size() + n > max_size(). * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that modifies the input sequence or output * sequence. */ mutable_buffers_type prepare(std::size_t n) { if (size () > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_vector_buffer too long"); asio::detail::throw_exception(ex); } if (size_ == (std::numeric_limits::max)()) size_ = vector_.size(); // Enable v1 behaviour. vector_.resize(size_ + n); return asio::buffer(asio::buffer(vector_) + size_, n); } /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input /// sequence. /** * @param n The number of bytes to append from the start of the output * sequence to the end of the input sequence. The remainder of the output * sequence is discarded. * * Requires a preceding call prepare(x) where x >= n, and * no intervening operations that modify the input or output sequence. * * @note If @c n is greater than the size of the output sequence, the entire * output sequence is moved to the input sequence and no error is issued. */ void commit(std::size_t n) { size_ += (std::min)(n, vector_.size() - size_); vector_.resize(size_); } #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of /// bytes. /** * Resizes the vector to accommodate an additional @c n bytes at the end. * * @throws std::length_error If size() + n > max_size(). */ void grow(std::size_t n) { if (size() > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_vector_buffer too long"); asio::detail::throw_exception(ex); } vector_.resize(size() + n); } /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number /// of bytes. /** * Erases @c n bytes from the end of the vector by resizing the vector * object. If @c n is greater than the current size of the vector, the vector * is emptied. */ void shrink(std::size_t n) { vector_.resize(n > size() ? 0 : size() - n); } /// @b DynamicBuffer_v1: Remove characters from the input sequence. /// @b DynamicBuffer_v2: Consume the specified number of bytes from the /// beginning of the underlying memory. /** * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the * input sequence. @note If @c n is greater than the size of the input * sequence, the entire input sequence is consumed and no error is issued. * * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector. * If @c n is greater than the current size of the vector, the vector is * emptied. */ void consume(std::size_t n) { #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits::max)()) { std::size_t consume_length = (std::min)(n, size_); vector_.erase(vector_.begin(), vector_.begin() + consume_length); size_ -= consume_length; return; } #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n)); } private: std::vector& vector_; #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) std::size_t size_; #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) const std::size_t max_size_; }; /** @defgroup dynamic_buffer asio::dynamic_buffer * * @brief The asio::dynamic_buffer function is used to create a * dynamically resized buffer from a @c std::basic_string or @c std::vector. */ /*@{*/ /// Create a new dynamic buffer that represents the given string. /** * @returns dynamic_string_buffer(data). */ template inline dynamic_string_buffer dynamic_buffer( std::basic_string& data) ASIO_NOEXCEPT { return dynamic_string_buffer(data); } /// Create a new dynamic buffer that represents the given string. /** * @returns dynamic_string_buffer(data, * max_size). */ template inline dynamic_string_buffer dynamic_buffer( std::basic_string& data, std::size_t max_size) ASIO_NOEXCEPT { return dynamic_string_buffer(data, max_size); } /// Create a new dynamic buffer that represents the given vector. /** * @returns dynamic_vector_buffer(data). */ template inline dynamic_vector_buffer dynamic_buffer( std::vector& data) ASIO_NOEXCEPT { return dynamic_vector_buffer(data); } /// Create a new dynamic buffer that represents the given vector. /** * @returns dynamic_vector_buffer(data, max_size). */ template inline dynamic_vector_buffer dynamic_buffer( std::vector& data, std::size_t max_size) ASIO_NOEXCEPT { return dynamic_vector_buffer(data, max_size); } /*@}*/ /** @defgroup buffer_copy asio::buffer_copy * * @brief The asio::buffer_copy function is used to copy bytes from a * source buffer (or buffer sequence) to a target buffer (or buffer sequence). * * The @c buffer_copy function is available in two forms: * * @li A 2-argument form: @c buffer_copy(target, source) * * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy) * * Both forms return the number of bytes actually copied. The number of bytes * copied is the lesser of: * * @li @c buffer_size(target) * * @li @c buffer_size(source) * * @li @c If specified, @c max_bytes_to_copy. * * This prevents buffer overflow, regardless of the buffer sizes used in the * copy operation. * * Note that @ref buffer_copy is implemented in terms of @c memcpy, and * consequently it cannot be used to copy between overlapping memory regions. */ /*@{*/ namespace detail { inline std::size_t buffer_copy_1(const mutable_buffer& target, const const_buffer& source) { using namespace std; // For memcpy. std::size_t target_size = target.size(); std::size_t source_size = source.size(); std::size_t n = target_size < source_size ? target_size : source_size; if (n > 0) memcpy(target.data(), source.data(), n); return n; } template inline std::size_t buffer_copy(one_buffer, one_buffer, TargetIterator target_begin, TargetIterator, SourceIterator source_begin, SourceIterator) ASIO_NOEXCEPT { return (buffer_copy_1)(*target_begin, *source_begin); } template inline std::size_t buffer_copy(one_buffer, one_buffer, TargetIterator target_begin, TargetIterator, SourceIterator source_begin, SourceIterator, std::size_t max_bytes_to_copy) ASIO_NOEXCEPT { return (buffer_copy_1)(*target_begin, asio::buffer(*source_begin, max_bytes_to_copy)); } template std::size_t buffer_copy(one_buffer, multiple_buffers, TargetIterator target_begin, TargetIterator, SourceIterator source_begin, SourceIterator source_end, std::size_t max_bytes_to_copy = (std::numeric_limits::max)()) ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; SourceIterator source_iter = source_begin; for (mutable_buffer target_buffer( asio::buffer(*target_begin, max_bytes_to_copy)); target_buffer.size() && source_iter != source_end; ++source_iter) { const_buffer source_buffer(*source_iter); std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); total_bytes_copied += bytes_copied; target_buffer += bytes_copied; } return total_bytes_copied; } template std::size_t buffer_copy(multiple_buffers, one_buffer, TargetIterator target_begin, TargetIterator target_end, SourceIterator source_begin, SourceIterator, std::size_t max_bytes_to_copy = (std::numeric_limits::max)()) ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; TargetIterator target_iter = target_begin; for (const_buffer source_buffer( asio::buffer(*source_begin, max_bytes_to_copy)); source_buffer.size() && target_iter != target_end; ++target_iter) { mutable_buffer target_buffer(*target_iter); std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); total_bytes_copied += bytes_copied; source_buffer += bytes_copied; } return total_bytes_copied; } template std::size_t buffer_copy(multiple_buffers, multiple_buffers, TargetIterator target_begin, TargetIterator target_end, SourceIterator source_begin, SourceIterator source_end) ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; TargetIterator target_iter = target_begin; std::size_t target_buffer_offset = 0; SourceIterator source_iter = source_begin; std::size_t source_buffer_offset = 0; while (target_iter != target_end && source_iter != source_end) { mutable_buffer target_buffer = mutable_buffer(*target_iter) + target_buffer_offset; const_buffer source_buffer = const_buffer(*source_iter) + source_buffer_offset; std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); total_bytes_copied += bytes_copied; if (bytes_copied == target_buffer.size()) { ++target_iter; target_buffer_offset = 0; } else target_buffer_offset += bytes_copied; if (bytes_copied == source_buffer.size()) { ++source_iter; source_buffer_offset = 0; } else source_buffer_offset += bytes_copied; } return total_bytes_copied; } template std::size_t buffer_copy(multiple_buffers, multiple_buffers, TargetIterator target_begin, TargetIterator target_end, SourceIterator source_begin, SourceIterator source_end, std::size_t max_bytes_to_copy) ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; TargetIterator target_iter = target_begin; std::size_t target_buffer_offset = 0; SourceIterator source_iter = source_begin; std::size_t source_buffer_offset = 0; while (total_bytes_copied != max_bytes_to_copy && target_iter != target_end && source_iter != source_end) { mutable_buffer target_buffer = mutable_buffer(*target_iter) + target_buffer_offset; const_buffer source_buffer = const_buffer(*source_iter) + source_buffer_offset; std::size_t bytes_copied = (buffer_copy_1)( target_buffer, asio::buffer(source_buffer, max_bytes_to_copy - total_bytes_copied)); total_bytes_copied += bytes_copied; if (bytes_copied == target_buffer.size()) { ++target_iter; target_buffer_offset = 0; } else target_buffer_offset += bytes_copied; if (bytes_copied == source_buffer.size()) { ++source_iter; source_buffer_offset = 0; } else source_buffer_offset += bytes_copied; } return total_bytes_copied; } } // namespace detail /// Copies bytes from a source buffer sequence to a target buffer sequence. /** * @param target A modifiable buffer sequence representing the memory regions to * which the bytes will be copied. * * @param source A non-modifiable buffer sequence representing the memory * regions from which the bytes will be copied. * * @returns The number of bytes copied. * * @note The number of bytes copied is the lesser of: * * @li @c buffer_size(target) * * @li @c buffer_size(source) * * This function is implemented in terms of @c memcpy, and consequently it * cannot be used to copy between overlapping memory regions. */ template inline std::size_t buffer_copy(const MutableBufferSequence& target, const ConstBufferSequence& source) ASIO_NOEXCEPT { return detail::buffer_copy( detail::buffer_sequence_cardinality(), detail::buffer_sequence_cardinality(), asio::buffer_sequence_begin(target), asio::buffer_sequence_end(target), asio::buffer_sequence_begin(source), asio::buffer_sequence_end(source)); } /// Copies a limited number of bytes from a source buffer sequence to a target /// buffer sequence. /** * @param target A modifiable buffer sequence representing the memory regions to * which the bytes will be copied. * * @param source A non-modifiable buffer sequence representing the memory * regions from which the bytes will be copied. * * @param max_bytes_to_copy The maximum number of bytes to be copied. * * @returns The number of bytes copied. * * @note The number of bytes copied is the lesser of: * * @li @c buffer_size(target) * * @li @c buffer_size(source) * * @li @c max_bytes_to_copy * * This function is implemented in terms of @c memcpy, and consequently it * cannot be used to copy between overlapping memory regions. */ template inline std::size_t buffer_copy(const MutableBufferSequence& target, const ConstBufferSequence& source, std::size_t max_bytes_to_copy) ASIO_NOEXCEPT { return detail::buffer_copy( detail::buffer_sequence_cardinality(), detail::buffer_sequence_cardinality(), asio::buffer_sequence_begin(target), asio::buffer_sequence_end(target), asio::buffer_sequence_begin(source), asio::buffer_sequence_end(source), max_bytes_to_copy); } /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/is_buffer_sequence.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Trait to determine whether a type satisfies the MutableBufferSequence /// requirements. template struct is_mutable_buffer_sequence #if defined(GENERATING_DOCUMENTATION) : integral_constant #else // defined(GENERATING_DOCUMENTATION) : asio::detail::is_buffer_sequence #endif // defined(GENERATING_DOCUMENTATION) { }; /// Trait to determine whether a type satisfies the ConstBufferSequence /// requirements. template struct is_const_buffer_sequence #if defined(GENERATING_DOCUMENTATION) : integral_constant #else // defined(GENERATING_DOCUMENTATION) : asio::detail::is_buffer_sequence #endif // defined(GENERATING_DOCUMENTATION) { }; #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Trait to determine whether a type satisfies the DynamicBuffer_v1 /// requirements. template struct is_dynamic_buffer_v1 #if defined(GENERATING_DOCUMENTATION) : integral_constant #else // defined(GENERATING_DOCUMENTATION) : asio::detail::is_dynamic_buffer_v1 #endif // defined(GENERATING_DOCUMENTATION) { }; #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Trait to determine whether a type satisfies the DynamicBuffer_v2 /// requirements. template struct is_dynamic_buffer_v2 #if defined(GENERATING_DOCUMENTATION) : integral_constant #else // defined(GENERATING_DOCUMENTATION) : asio::detail::is_dynamic_buffer_v2 #endif // defined(GENERATING_DOCUMENTATION) { }; /// Trait to determine whether a type satisfies the DynamicBuffer requirements. /** * If @c ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the * type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c * ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type * satisfies the DynamicBuffer_v2 requirements. */ template struct is_dynamic_buffer #if defined(GENERATING_DOCUMENTATION) : integral_constant #elif defined(ASIO_NO_DYNAMIC_BUFFER_V1) : asio::is_dynamic_buffer_v2 #else // defined(ASIO_NO_DYNAMIC_BUFFER_V1) : asio::is_dynamic_buffer_v1 #endif // defined(ASIO_NO_DYNAMIC_BUFFER_V1) { }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BUFFER_HPP ================================================ FILE: src/third_party/asio/buffered_read_stream.hpp ================================================ // // buffered_read_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFERED_READ_STREAM_HPP #define ASIO_BUFFERED_READ_STREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/buffered_read_stream_fwd.hpp" #include "asio/buffer.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_resize_guard.hpp" #include "asio/detail/buffered_stream_storage.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Adds buffering to the read-related operations of a stream. /** * The buffered_read_stream class template can be used to add buffering to the * synchronous and asynchronous read operations of a stream. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template class buffered_read_stream : private noncopyable { public: /// The type of the next layer. typedef typename remove_reference::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; /// The type of the executor associated with the object. typedef typename lowest_layer_type::executor_type executor_type; #if defined(GENERATING_DOCUMENTATION) /// The default buffer size. static const std::size_t default_buffer_size = implementation_defined; #else ASIO_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); #endif /// Construct, passing the specified argument to initialise the next layer. template explicit buffered_read_stream(Arg& a) : next_layer_(a), storage_(default_buffer_size) { } /// Construct, passing the specified argument to initialise the next layer. template buffered_read_stream(Arg& a, std::size_t buffer_size) : next_layer_(a), storage_(buffer_size) { } /// Get a reference to the next layer. next_layer_type& next_layer() { return next_layer_; } /// Get a reference to the lowest layer. lowest_layer_type& lowest_layer() { return next_layer_.lowest_layer(); } /// Get a const reference to the lowest layer. const lowest_layer_type& lowest_layer() const { return next_layer_.lowest_layer(); } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } /// Close the stream. void close() { next_layer_.close(); } /// Close the stream. ASIO_SYNC_OP_VOID close(asio::error_code& ec) { next_layer_.close(ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Write the given data to the stream. Returns the number of bytes written. /// Throws an exception on failure. template std::size_t write_some(const ConstBufferSequence& buffers) { return next_layer_.write_some(buffers); } /// Write the given data to the stream. Returns the number of bytes written, /// or 0 if an error occurred. template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { return next_layer_.write_some(buffers, ec); } /// Start an asynchronous write. The data being written must be valid for the /// lifetime of the asynchronous operation. template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return next_layer_.async_write_some(buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Fill the buffer with some data. Returns the number of bytes placed in the /// buffer as a result of the operation. Throws an exception on failure. std::size_t fill(); /// Fill the buffer with some data. Returns the number of bytes placed in the /// buffer as a result of the operation, or 0 if an error occurred. std::size_t fill(asio::error_code& ec); /// Start an asynchronous fill. template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_fill( ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)); /// Read some data from the stream. Returns the number of bytes read. Throws /// an exception on failure. template std::size_t read_some(const MutableBufferSequence& buffers); /// Read some data from the stream. Returns the number of bytes read or 0 if /// an error occurred. template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec); /// Start an asynchronous read. The buffer into which the data will be read /// must be valid for the lifetime of the asynchronous operation. template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)); /// Peek at the incoming data on the stream. Returns the number of bytes read. /// Throws an exception on failure. template std::size_t peek(const MutableBufferSequence& buffers); /// Peek at the incoming data on the stream. Returns the number of bytes read, /// or 0 if an error occurred. template std::size_t peek(const MutableBufferSequence& buffers, asio::error_code& ec); /// Determine the amount of data that may be read without blocking. std::size_t in_avail() { return storage_.size(); } /// Determine the amount of data that may be read without blocking. std::size_t in_avail(asio::error_code& ec) { ec = asio::error_code(); return storage_.size(); } private: /// Copy data out of the internal buffer to the specified target buffer. /// Returns the number of bytes copied. template std::size_t copy(const MutableBufferSequence& buffers) { std::size_t bytes_copied = asio::buffer_copy( buffers, storage_.data(), storage_.size()); storage_.consume(bytes_copied); return bytes_copied; } /// Copy data from the internal buffer to the specified target buffer, without /// removing the data from the internal buffer. Returns the number of bytes /// copied. template std::size_t peek_copy(const MutableBufferSequence& buffers) { return asio::buffer_copy(buffers, storage_.data(), storage_.size()); } /// The next layer. Stream next_layer_; // The data in the buffer. detail::buffered_stream_storage storage_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/buffered_read_stream.hpp" #endif // ASIO_BUFFERED_READ_STREAM_HPP ================================================ FILE: src/third_party/asio/buffered_read_stream_fwd.hpp ================================================ // // buffered_read_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFERED_READ_STREAM_FWD_HPP #define ASIO_BUFFERED_READ_STREAM_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) namespace asio { template class buffered_read_stream; } // namespace asio #endif // ASIO_BUFFERED_READ_STREAM_FWD_HPP ================================================ FILE: src/third_party/asio/buffered_stream.hpp ================================================ // // buffered_stream.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFERED_STREAM_HPP #define ASIO_BUFFERED_STREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/buffered_read_stream.hpp" #include "asio/buffered_write_stream.hpp" #include "asio/buffered_stream_fwd.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Adds buffering to the read- and write-related operations of a stream. /** * The buffered_stream class template can be used to add buffering to the * synchronous and asynchronous read and write operations of a stream. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template class buffered_stream : private noncopyable { public: /// The type of the next layer. typedef typename remove_reference::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; /// The type of the executor associated with the object. typedef typename lowest_layer_type::executor_type executor_type; /// Construct, passing the specified argument to initialise the next layer. template explicit buffered_stream(Arg& a) : inner_stream_impl_(a), stream_impl_(inner_stream_impl_) { } /// Construct, passing the specified argument to initialise the next layer. template explicit buffered_stream(Arg& a, std::size_t read_buffer_size, std::size_t write_buffer_size) : inner_stream_impl_(a, write_buffer_size), stream_impl_(inner_stream_impl_, read_buffer_size) { } /// Get a reference to the next layer. next_layer_type& next_layer() { return stream_impl_.next_layer().next_layer(); } /// Get a reference to the lowest layer. lowest_layer_type& lowest_layer() { return stream_impl_.lowest_layer(); } /// Get a const reference to the lowest layer. const lowest_layer_type& lowest_layer() const { return stream_impl_.lowest_layer(); } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return stream_impl_.lowest_layer().get_executor(); } /// Close the stream. void close() { stream_impl_.close(); } /// Close the stream. ASIO_SYNC_OP_VOID close(asio::error_code& ec) { stream_impl_.close(ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation. Throws an /// exception on failure. std::size_t flush() { return stream_impl_.next_layer().flush(); } /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation, or 0 if an /// error occurred. std::size_t flush(asio::error_code& ec) { return stream_impl_.next_layer().flush(ec); } /// Start an asynchronous flush. template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_flush( ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return stream_impl_.next_layer().async_flush( ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Write the given data to the stream. Returns the number of bytes written. /// Throws an exception on failure. template std::size_t write_some(const ConstBufferSequence& buffers) { return stream_impl_.write_some(buffers); } /// Write the given data to the stream. Returns the number of bytes written, /// or 0 if an error occurred. template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { return stream_impl_.write_some(buffers, ec); } /// Start an asynchronous write. The data being written must be valid for the /// lifetime of the asynchronous operation. template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return stream_impl_.async_write_some(buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Fill the buffer with some data. Returns the number of bytes placed in the /// buffer as a result of the operation. Throws an exception on failure. std::size_t fill() { return stream_impl_.fill(); } /// Fill the buffer with some data. Returns the number of bytes placed in the /// buffer as a result of the operation, or 0 if an error occurred. std::size_t fill(asio::error_code& ec) { return stream_impl_.fill(ec); } /// Start an asynchronous fill. template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_fill( ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return stream_impl_.async_fill(ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Read some data from the stream. Returns the number of bytes read. Throws /// an exception on failure. template std::size_t read_some(const MutableBufferSequence& buffers) { return stream_impl_.read_some(buffers); } /// Read some data from the stream. Returns the number of bytes read or 0 if /// an error occurred. template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { return stream_impl_.read_some(buffers, ec); } /// Start an asynchronous read. The buffer into which the data will be read /// must be valid for the lifetime of the asynchronous operation. template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return stream_impl_.async_read_some(buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Peek at the incoming data on the stream. Returns the number of bytes read. /// Throws an exception on failure. template std::size_t peek(const MutableBufferSequence& buffers) { return stream_impl_.peek(buffers); } /// Peek at the incoming data on the stream. Returns the number of bytes read, /// or 0 if an error occurred. template std::size_t peek(const MutableBufferSequence& buffers, asio::error_code& ec) { return stream_impl_.peek(buffers, ec); } /// Determine the amount of data that may be read without blocking. std::size_t in_avail() { return stream_impl_.in_avail(); } /// Determine the amount of data that may be read without blocking. std::size_t in_avail(asio::error_code& ec) { return stream_impl_.in_avail(ec); } private: // The buffered write stream. typedef buffered_write_stream write_stream_type; write_stream_type inner_stream_impl_; // The buffered read stream. typedef buffered_read_stream read_stream_type; read_stream_type stream_impl_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BUFFERED_STREAM_HPP ================================================ FILE: src/third_party/asio/buffered_stream_fwd.hpp ================================================ // // buffered_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFERED_STREAM_FWD_HPP #define ASIO_BUFFERED_STREAM_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) namespace asio { template class buffered_stream; } // namespace asio #endif // ASIO_BUFFERED_STREAM_FWD_HPP ================================================ FILE: src/third_party/asio/buffered_write_stream.hpp ================================================ // // buffered_write_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFERED_WRITE_STREAM_HPP #define ASIO_BUFFERED_WRITE_STREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/buffered_write_stream_fwd.hpp" #include "asio/buffer.hpp" #include "asio/completion_condition.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffered_stream_storage.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/write.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Adds buffering to the write-related operations of a stream. /** * The buffered_write_stream class template can be used to add buffering to the * synchronous and asynchronous write operations of a stream. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template class buffered_write_stream : private noncopyable { public: /// The type of the next layer. typedef typename remove_reference::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; /// The type of the executor associated with the object. typedef typename lowest_layer_type::executor_type executor_type; #if defined(GENERATING_DOCUMENTATION) /// The default buffer size. static const std::size_t default_buffer_size = implementation_defined; #else ASIO_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); #endif /// Construct, passing the specified argument to initialise the next layer. template explicit buffered_write_stream(Arg& a) : next_layer_(a), storage_(default_buffer_size) { } /// Construct, passing the specified argument to initialise the next layer. template buffered_write_stream(Arg& a, std::size_t buffer_size) : next_layer_(a), storage_(buffer_size) { } /// Get a reference to the next layer. next_layer_type& next_layer() { return next_layer_; } /// Get a reference to the lowest layer. lowest_layer_type& lowest_layer() { return next_layer_.lowest_layer(); } /// Get a const reference to the lowest layer. const lowest_layer_type& lowest_layer() const { return next_layer_.lowest_layer(); } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } /// Close the stream. void close() { next_layer_.close(); } /// Close the stream. ASIO_SYNC_OP_VOID close(asio::error_code& ec) { next_layer_.close(ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation. Throws an /// exception on failure. std::size_t flush(); /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation, or 0 if an /// error occurred. std::size_t flush(asio::error_code& ec); /// Start an asynchronous flush. template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_flush( ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)); /// Write the given data to the stream. Returns the number of bytes written. /// Throws an exception on failure. template std::size_t write_some(const ConstBufferSequence& buffers); /// Write the given data to the stream. Returns the number of bytes written, /// or 0 if an error occurred and the error handler did not throw. template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec); /// Start an asynchronous write. The data being written must be valid for the /// lifetime of the asynchronous operation. template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)); /// Read some data from the stream. Returns the number of bytes read. Throws /// an exception on failure. template std::size_t read_some(const MutableBufferSequence& buffers) { return next_layer_.read_some(buffers); } /// Read some data from the stream. Returns the number of bytes read or 0 if /// an error occurred. template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { return next_layer_.read_some(buffers, ec); } /// Start an asynchronous read. The buffer into which the data will be read /// must be valid for the lifetime of the asynchronous operation. template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return next_layer_.async_read_some(buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Peek at the incoming data on the stream. Returns the number of bytes read. /// Throws an exception on failure. template std::size_t peek(const MutableBufferSequence& buffers) { return next_layer_.peek(buffers); } /// Peek at the incoming data on the stream. Returns the number of bytes read, /// or 0 if an error occurred. template std::size_t peek(const MutableBufferSequence& buffers, asio::error_code& ec) { return next_layer_.peek(buffers, ec); } /// Determine the amount of data that may be read without blocking. std::size_t in_avail() { return next_layer_.in_avail(); } /// Determine the amount of data that may be read without blocking. std::size_t in_avail(asio::error_code& ec) { return next_layer_.in_avail(ec); } private: /// Copy data into the internal buffer from the specified source buffer. /// Returns the number of bytes copied. template std::size_t copy(const ConstBufferSequence& buffers); /// The next layer. Stream next_layer_; // The data in the buffer. detail::buffered_stream_storage storage_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/buffered_write_stream.hpp" #endif // ASIO_BUFFERED_WRITE_STREAM_HPP ================================================ FILE: src/third_party/asio/buffered_write_stream_fwd.hpp ================================================ // // buffered_write_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFERED_WRITE_STREAM_FWD_HPP #define ASIO_BUFFERED_WRITE_STREAM_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) namespace asio { template class buffered_write_stream; } // namespace asio #endif // ASIO_BUFFERED_WRITE_STREAM_FWD_HPP ================================================ FILE: src/third_party/asio/buffers_iterator.hpp ================================================ // // buffers_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_BUFFERS_ITERATOR_HPP #define ASIO_BUFFERS_ITERATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/buffer.hpp" #include "asio/detail/assert.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct buffers_iterator_types_helper; template <> struct buffers_iterator_types_helper { typedef const_buffer buffer_type; template struct byte_type { typedef typename add_const::type type; }; }; template <> struct buffers_iterator_types_helper { typedef mutable_buffer buffer_type; template struct byte_type { typedef ByteType type; }; }; template struct buffers_iterator_types { enum { is_mutable = is_convertible< typename BufferSequence::value_type, mutable_buffer>::value }; typedef buffers_iterator_types_helper helper; typedef typename helper::buffer_type buffer_type; typedef typename helper::template byte_type::type byte_type; typedef typename BufferSequence::const_iterator const_iterator; }; template struct buffers_iterator_types { typedef mutable_buffer buffer_type; typedef ByteType byte_type; typedef const mutable_buffer* const_iterator; }; template struct buffers_iterator_types { typedef const_buffer buffer_type; typedef typename add_const::type byte_type; typedef const const_buffer* const_iterator; }; #if !defined(ASIO_NO_DEPRECATED) template struct buffers_iterator_types { typedef mutable_buffer buffer_type; typedef ByteType byte_type; typedef const mutable_buffer* const_iterator; }; template struct buffers_iterator_types { typedef const_buffer buffer_type; typedef typename add_const::type byte_type; typedef const const_buffer* const_iterator; }; #endif // !defined(ASIO_NO_DEPRECATED) } /// A random access iterator over the bytes in a buffer sequence. template class buffers_iterator { private: typedef typename detail::buffers_iterator_types< BufferSequence, ByteType>::buffer_type buffer_type; typedef typename detail::buffers_iterator_types::const_iterator buffer_sequence_iterator_type; public: /// The type used for the distance between two iterators. typedef std::ptrdiff_t difference_type; /// The type of the value pointed to by the iterator. typedef ByteType value_type; #if defined(GENERATING_DOCUMENTATION) /// The type of the result of applying operator->() to the iterator. /** * If the buffer sequence stores buffer objects that are convertible to * mutable_buffer, this is a pointer to a non-const ByteType. Otherwise, a * pointer to a const ByteType. */ typedef const_or_non_const_ByteType* pointer; #else // defined(GENERATING_DOCUMENTATION) typedef typename detail::buffers_iterator_types< BufferSequence, ByteType>::byte_type* pointer; #endif // defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION) /// The type of the result of applying operator*() to the iterator. /** * If the buffer sequence stores buffer objects that are convertible to * mutable_buffer, this is a reference to a non-const ByteType. Otherwise, a * reference to a const ByteType. */ typedef const_or_non_const_ByteType& reference; #else // defined(GENERATING_DOCUMENTATION) typedef typename detail::buffers_iterator_types< BufferSequence, ByteType>::byte_type& reference; #endif // defined(GENERATING_DOCUMENTATION) /// The iterator category. typedef std::random_access_iterator_tag iterator_category; /// Default constructor. Creates an iterator in an undefined state. buffers_iterator() : current_buffer_(), current_buffer_position_(0), begin_(), current_(), end_(), position_(0) { } /// Construct an iterator representing the beginning of the buffers' data. static buffers_iterator begin(const BufferSequence& buffers) #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) __attribute__ ((__noinline__)) #endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) { buffers_iterator new_iter; new_iter.begin_ = asio::buffer_sequence_begin(buffers); new_iter.current_ = asio::buffer_sequence_begin(buffers); new_iter.end_ = asio::buffer_sequence_end(buffers); while (new_iter.current_ != new_iter.end_) { new_iter.current_buffer_ = *new_iter.current_; if (new_iter.current_buffer_.size() > 0) break; ++new_iter.current_; } return new_iter; } /// Construct an iterator representing the end of the buffers' data. static buffers_iterator end(const BufferSequence& buffers) #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) __attribute__ ((__noinline__)) #endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) { buffers_iterator new_iter; new_iter.begin_ = asio::buffer_sequence_begin(buffers); new_iter.current_ = asio::buffer_sequence_begin(buffers); new_iter.end_ = asio::buffer_sequence_end(buffers); while (new_iter.current_ != new_iter.end_) { buffer_type buffer = *new_iter.current_; new_iter.position_ += buffer.size(); ++new_iter.current_; } return new_iter; } /// Dereference an iterator. reference operator*() const { return dereference(); } /// Dereference an iterator. pointer operator->() const { return &dereference(); } /// Access an individual element. reference operator[](std::ptrdiff_t difference) const { buffers_iterator tmp(*this); tmp.advance(difference); return *tmp; } /// Increment operator (prefix). buffers_iterator& operator++() { increment(); return *this; } /// Increment operator (postfix). buffers_iterator operator++(int) { buffers_iterator tmp(*this); ++*this; return tmp; } /// Decrement operator (prefix). buffers_iterator& operator--() { decrement(); return *this; } /// Decrement operator (postfix). buffers_iterator operator--(int) { buffers_iterator tmp(*this); --*this; return tmp; } /// Addition operator. buffers_iterator& operator+=(std::ptrdiff_t difference) { advance(difference); return *this; } /// Subtraction operator. buffers_iterator& operator-=(std::ptrdiff_t difference) { advance(-difference); return *this; } /// Addition operator. friend buffers_iterator operator+(const buffers_iterator& iter, std::ptrdiff_t difference) { buffers_iterator tmp(iter); tmp.advance(difference); return tmp; } /// Addition operator. friend buffers_iterator operator+(std::ptrdiff_t difference, const buffers_iterator& iter) { buffers_iterator tmp(iter); tmp.advance(difference); return tmp; } /// Subtraction operator. friend buffers_iterator operator-(const buffers_iterator& iter, std::ptrdiff_t difference) { buffers_iterator tmp(iter); tmp.advance(-difference); return tmp; } /// Subtraction operator. friend std::ptrdiff_t operator-(const buffers_iterator& a, const buffers_iterator& b) { return b.distance_to(a); } /// Test two iterators for equality. friend bool operator==(const buffers_iterator& a, const buffers_iterator& b) { return a.equal(b); } /// Test two iterators for inequality. friend bool operator!=(const buffers_iterator& a, const buffers_iterator& b) { return !a.equal(b); } /// Compare two iterators. friend bool operator<(const buffers_iterator& a, const buffers_iterator& b) { return a.distance_to(b) > 0; } /// Compare two iterators. friend bool operator<=(const buffers_iterator& a, const buffers_iterator& b) { return !(b < a); } /// Compare two iterators. friend bool operator>(const buffers_iterator& a, const buffers_iterator& b) { return b < a; } /// Compare two iterators. friend bool operator>=(const buffers_iterator& a, const buffers_iterator& b) { return !(a < b); } private: // Dereference the iterator. reference dereference() const { return static_cast( current_buffer_.data())[current_buffer_position_]; } // Compare two iterators for equality. bool equal(const buffers_iterator& other) const { return position_ == other.position_; } // Increment the iterator. void increment() { ASIO_ASSERT(current_ != end_ && "iterator out of bounds"); ++position_; // Check if the increment can be satisfied by the current buffer. ++current_buffer_position_; if (current_buffer_position_ != current_buffer_.size()) return; // Find the next non-empty buffer. ++current_; current_buffer_position_ = 0; while (current_ != end_) { current_buffer_ = *current_; if (current_buffer_.size() > 0) return; ++current_; } } // Decrement the iterator. void decrement() { ASIO_ASSERT(position_ > 0 && "iterator out of bounds"); --position_; // Check if the decrement can be satisfied by the current buffer. if (current_buffer_position_ != 0) { --current_buffer_position_; return; } // Find the previous non-empty buffer. buffer_sequence_iterator_type iter = current_; while (iter != begin_) { --iter; buffer_type buffer = *iter; std::size_t buffer_size = buffer.size(); if (buffer_size > 0) { current_ = iter; current_buffer_ = buffer; current_buffer_position_ = buffer_size - 1; return; } } } // Advance the iterator by the specified distance. void advance(std::ptrdiff_t n) { if (n > 0) { ASIO_ASSERT(current_ != end_ && "iterator out of bounds"); for (;;) { std::ptrdiff_t current_buffer_balance = current_buffer_.size() - current_buffer_position_; // Check if the advance can be satisfied by the current buffer. if (current_buffer_balance > n) { position_ += n; current_buffer_position_ += n; return; } // Update position. n -= current_buffer_balance; position_ += current_buffer_balance; // Move to next buffer. If it is empty then it will be skipped on the // next iteration of this loop. if (++current_ == end_) { ASIO_ASSERT(n == 0 && "iterator out of bounds"); current_buffer_ = buffer_type(); current_buffer_position_ = 0; return; } current_buffer_ = *current_; current_buffer_position_ = 0; } } else if (n < 0) { std::size_t abs_n = -n; ASIO_ASSERT(position_ >= abs_n && "iterator out of bounds"); for (;;) { // Check if the advance can be satisfied by the current buffer. if (current_buffer_position_ >= abs_n) { position_ -= abs_n; current_buffer_position_ -= abs_n; return; } // Update position. abs_n -= current_buffer_position_; position_ -= current_buffer_position_; // Check if we've reached the beginning of the buffers. if (current_ == begin_) { ASIO_ASSERT(abs_n == 0 && "iterator out of bounds"); current_buffer_position_ = 0; return; } // Find the previous non-empty buffer. buffer_sequence_iterator_type iter = current_; while (iter != begin_) { --iter; buffer_type buffer = *iter; std::size_t buffer_size = buffer.size(); if (buffer_size > 0) { current_ = iter; current_buffer_ = buffer; current_buffer_position_ = buffer_size; break; } } } } } // Determine the distance between two iterators. std::ptrdiff_t distance_to(const buffers_iterator& other) const { return other.position_ - position_; } buffer_type current_buffer_; std::size_t current_buffer_position_; buffer_sequence_iterator_type begin_; buffer_sequence_iterator_type current_; buffer_sequence_iterator_type end_; std::size_t position_; }; /// Construct an iterator representing the beginning of the buffers' data. template inline buffers_iterator buffers_begin( const BufferSequence& buffers) { return buffers_iterator::begin(buffers); } /// Construct an iterator representing the end of the buffers' data. template inline buffers_iterator buffers_end( const BufferSequence& buffers) { return buffers_iterator::end(buffers); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_BUFFERS_ITERATOR_HPP ================================================ FILE: src/third_party/asio/co_spawn.hpp ================================================ // // co_spawn.hpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_CO_SPAWN_HPP #define ASIO_CO_SPAWN_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) #include "asio/awaitable.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct awaitable_signature; template struct awaitable_signature> { typedef void type(std::exception_ptr, T); }; template struct awaitable_signature> { typedef void type(std::exception_ptr); }; } // namespace detail /// Spawn a new thread of execution. /** * The entry point function object @c f must have the signature: * * @code awaitable f(); @endcode * * where @c E is convertible from @c Executor. */ template ::type>::type) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, typename detail::awaitable_signature::type>::type) co_spawn(const Executor& ex, F&& f, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if< is_executor::value >::type* = 0); /// Spawn a new thread of execution. /** * The entry point function object @c f must have the signature: * * @code awaitable f(); @endcode * * where @c E is convertible from @c ExecutionContext::executor_type. */ template ::type>::type) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE( typename ExecutionContext::executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, typename detail::awaitable_signature::type>::type) co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type), typename enable_if< is_convertible::value >::type* = 0); } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/co_spawn.hpp" #endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_CO_SPAWN_HPP ================================================ FILE: src/third_party/asio/completion_condition.hpp ================================================ // // completion_condition.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_COMPLETION_CONDITION_HPP #define ASIO_COMPLETION_CONDITION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // The default maximum number of bytes to transfer in a single operation. enum default_max_transfer_size_t { default_max_transfer_size = 65536 }; // Adapt result of old-style completion conditions (which had a bool result // where true indicated that the operation was complete). inline std::size_t adapt_completion_condition_result(bool result) { return result ? 0 : default_max_transfer_size; } // Adapt result of current completion conditions (which have a size_t result // where 0 means the operation is complete, and otherwise the result is the // maximum number of bytes to transfer on the next underlying operation). inline std::size_t adapt_completion_condition_result(std::size_t result) { return result; } class transfer_all_t { public: typedef std::size_t result_type; template std::size_t operator()(const Error& err, std::size_t) { return !!err ? 0 : default_max_transfer_size; } }; class transfer_at_least_t { public: typedef std::size_t result_type; explicit transfer_at_least_t(std::size_t minimum) : minimum_(minimum) { } template std::size_t operator()(const Error& err, std::size_t bytes_transferred) { return (!!err || bytes_transferred >= minimum_) ? 0 : default_max_transfer_size; } private: std::size_t minimum_; }; class transfer_exactly_t { public: typedef std::size_t result_type; explicit transfer_exactly_t(std::size_t size) : size_(size) { } template std::size_t operator()(const Error& err, std::size_t bytes_transferred) { return (!!err || bytes_transferred >= size_) ? 0 : (size_ - bytes_transferred < default_max_transfer_size ? size_ - bytes_transferred : std::size_t(default_max_transfer_size)); } private: std::size_t size_; }; } // namespace detail /** * @defgroup completion_condition Completion Condition Function Objects * * Function objects used for determining when a read or write operation should * complete. */ /*@{*/ /// Return a completion condition function object that indicates that a read or /// write operation should continue until all of the data has been transferred, /// or until an error occurs. /** * This function is used to create an object, of unspecified type, that meets * CompletionCondition requirements. * * @par Example * Reading until a buffer is full: * @code * boost::array buf; * asio::error_code ec; * std::size_t n = asio::read( * sock, asio::buffer(buf), * asio::transfer_all(), ec); * if (ec) * { * // An error occurred. * } * else * { * // n == 128 * } * @endcode */ #if defined(GENERATING_DOCUMENTATION) unspecified transfer_all(); #else inline detail::transfer_all_t transfer_all() { return detail::transfer_all_t(); } #endif /// Return a completion condition function object that indicates that a read or /// write operation should continue until a minimum number of bytes has been /// transferred, or until an error occurs. /** * This function is used to create an object, of unspecified type, that meets * CompletionCondition requirements. * * @par Example * Reading until a buffer is full or contains at least 64 bytes: * @code * boost::array buf; * asio::error_code ec; * std::size_t n = asio::read( * sock, asio::buffer(buf), * asio::transfer_at_least(64), ec); * if (ec) * { * // An error occurred. * } * else * { * // n >= 64 && n <= 128 * } * @endcode */ #if defined(GENERATING_DOCUMENTATION) unspecified transfer_at_least(std::size_t minimum); #else inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum) { return detail::transfer_at_least_t(minimum); } #endif /// Return a completion condition function object that indicates that a read or /// write operation should continue until an exact number of bytes has been /// transferred, or until an error occurs. /** * This function is used to create an object, of unspecified type, that meets * CompletionCondition requirements. * * @par Example * Reading until a buffer is full or contains exactly 64 bytes: * @code * boost::array buf; * asio::error_code ec; * std::size_t n = asio::read( * sock, asio::buffer(buf), * asio::transfer_exactly(64), ec); * if (ec) * { * // An error occurred. * } * else * { * // n == 64 * } * @endcode */ #if defined(GENERATING_DOCUMENTATION) unspecified transfer_exactly(std::size_t size); #else inline detail::transfer_exactly_t transfer_exactly(std::size_t size) { return detail::transfer_exactly_t(size); } #endif /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_COMPLETION_CONDITION_HPP ================================================ FILE: src/third_party/asio/compose.hpp ================================================ // // compose.hpp // ~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_COMPOSE_HPP #define ASIO_COMPOSE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if defined(ASIO_HAS_VARIADIC_TEMPLATES) \ || defined(GENERATING_DOCUMENTATION) /// Launch an asynchronous operation with a stateful implementation. /** * The async_compose function simplifies the implementation of composed * asynchronous operations automatically wrapping a stateful function object * with a conforming intermediate completion handler. * * @param implementation A function object that contains the implementation of * the composed asynchronous operation. The first argument to the function * object is a non-const reference to the enclosing intermediate completion * handler. The remaining arguments are any arguments that originate from the * completion handlers of any asynchronous operations performed by the * implementation. * @param token The completion token. * * @param io_objects_or_executors Zero or more I/O objects or I/O executors for * which outstanding work must be maintained. * * @par Example: * * @code struct async_echo_implementation * { * tcp::socket& socket_; * asio::mutable_buffer buffer_; * enum { starting, reading, writing } state_; * * template * void operator()(Self& self, * asio::error_code error = {}, * std::size_t n = 0) * { * switch (state_) * { * case starting: * state_ = reading; * socket_.async_read_some( * buffer_, std::move(self)); * break; * case reading: * if (error) * { * self.complete(error, 0); * } * else * { * state_ = writing; * asio::async_write(socket_, buffer_, * asio::transfer_exactly(n), * std::move(self)); * } * break; * case writing: * self.complete(error, n); * break; * } * } * }; * * template * auto async_echo(tcp::socket& socket, * asio::mutable_buffer buffer, * CompletionToken&& token) -> * typename asio::async_result< * typename std::decay::type, * void(asio::error_code, std::size_t)>::return_type * { * return asio::async_compose( * async_echo_implementation{socket, buffer, * async_echo_implementation::starting}, * token, socket); * } @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) async_compose(ASIO_MOVE_ARG(Implementation) implementation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors); #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) async_compose(ASIO_MOVE_ARG(Implementation) implementation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token); #define ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \ template \ ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) \ async_compose(ASIO_MOVE_ARG(Implementation) implementation, \ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ ASIO_VARIADIC_MOVE_PARAMS(n)); /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_COMPOSE_DEF) #undef ASIO_PRIVATE_ASYNC_COMPOSE_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/compose.hpp" #endif // ASIO_COMPOSE_HPP ================================================ FILE: src/third_party/asio/connect.hpp ================================================ // // connect.hpp // ~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_CONNECT_HPP #define ASIO_CONNECT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/basic_socket.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { char (&has_iterator_helper(...))[2]; template char has_iterator_helper(T*, typename T::iterator* = 0); template struct has_iterator_typedef { enum { value = (sizeof((has_iterator_helper)((T*)(0))) == 1) }; }; } // namespace detail /// Type trait used to determine whether a type is an endpoint sequence that can /// be used with with @c connect and @c async_connect. template struct is_endpoint_sequence { #if defined(GENERATING_DOCUMENTATION) /// The value member is true if the type may be used as an endpoint sequence. static const bool value; #else enum { value = detail::has_iterator_typedef::value }; #endif }; /** * @defgroup connect asio::connect * * @brief The @c connect function is a composed operation that establishes a * socket connection by trying each endpoint in a sequence. */ /*@{*/ /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param endpoints A sequence of endpoints. * * @returns The successfully connected endpoint. * * @throws asio::system_error Thrown on failure. If the sequence is * empty, the associated @c error_code is asio::error::not_found. * Otherwise, contains the error from the last connection attempt. * * @par Example * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::socket s(my_context); * asio::connect(s, r.resolve(q)); @endcode */ template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, typename enable_if::value>::type* = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param endpoints A sequence of endpoints. * * @param ec Set to indicate what error occurred, if any. If the sequence is * empty, set to asio::error::not_found. Otherwise, contains the error * from the last connection attempt. * * @returns On success, the successfully connected endpoint. Otherwise, a * default-constructed endpoint. * * @par Example * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::socket s(my_context); * asio::error_code ec; * asio::connect(s, r.resolve(q), ec); * if (ec) * { * // An error occurred. * } @endcode */ template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, asio::error_code& ec, typename enable_if::value>::type* = 0); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use range overload.) Establishes a socket connection by trying /// each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @returns On success, an iterator denoting the successfully connected * endpoint. Otherwise, the end iterator. * * @throws asio::system_error Thrown on failure. If the sequence is * empty, the associated @c error_code is asio::error::not_found. * Otherwise, contains the error from the last connection attempt. * * @note This overload assumes that a default constructed object of type @c * Iterator represents the end of the sequence. This is a valid assumption for * iterator types such as @c asio::ip::tcp::resolver::iterator. */ template Iterator connect(basic_socket& s, Iterator begin, typename enable_if::value>::type* = 0); /// (Deprecated: Use range overload.) Establishes a socket connection by trying /// each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param ec Set to indicate what error occurred, if any. If the sequence is * empty, set to asio::error::not_found. Otherwise, contains the error * from the last connection attempt. * * @returns On success, an iterator denoting the successfully connected * endpoint. Otherwise, the end iterator. * * @note This overload assumes that a default constructed object of type @c * Iterator represents the end of the sequence. This is a valid assumption for * iterator types such as @c asio::ip::tcp::resolver::iterator. */ template Iterator connect(basic_socket& s, Iterator begin, asio::error_code& ec, typename enable_if::value>::type* = 0); #endif // !defined(ASIO_NO_DEPRECATED) /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param end An iterator pointing to the end of a sequence of endpoints. * * @returns An iterator denoting the successfully connected endpoint. * * @throws asio::system_error Thrown on failure. If the sequence is * empty, the associated @c error_code is asio::error::not_found. * Otherwise, contains the error from the last connection attempt. * * @par Example * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::resolver::results_type e = r.resolve(q); * tcp::socket s(my_context); * asio::connect(s, e.begin(), e.end()); @endcode */ template Iterator connect(basic_socket& s, Iterator begin, Iterator end); /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param end An iterator pointing to the end of a sequence of endpoints. * * @param ec Set to indicate what error occurred, if any. If the sequence is * empty, set to asio::error::not_found. Otherwise, contains the error * from the last connection attempt. * * @returns On success, an iterator denoting the successfully connected * endpoint. Otherwise, the end iterator. * * @par Example * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::resolver::results_type e = r.resolve(q); * tcp::socket s(my_context); * asio::error_code ec; * asio::connect(s, e.begin(), e.end(), ec); * if (ec) * { * // An error occurred. * } @endcode */ template Iterator connect(basic_socket& s, Iterator begin, Iterator end, asio::error_code& ec); /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param endpoints A sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @returns The successfully connected endpoint. * * @throws asio::system_error Thrown on failure. If the sequence is * empty, the associated @c error_code is asio::error::not_found. * Otherwise, contains the error from the last connection attempt. * * @par Example * The following connect condition function object can be used to output * information about the individual connection attempts: * @code struct my_connect_condition * { * bool operator()( * const asio::error_code& ec, * const::tcp::endpoint& next) * { * if (ec) std::cout << "Error: " << ec.message() << std::endl; * std::cout << "Trying: " << next << std::endl; * return true; * } * }; @endcode * It would be used with the asio::connect function as follows: * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::socket s(my_context); * tcp::endpoint e = asio::connect(s, * r.resolve(q), my_connect_condition()); * std::cout << "Connected to: " << e << std::endl; @endcode */ template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, typename enable_if::value>::type* = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param endpoints A sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @param ec Set to indicate what error occurred, if any. If the sequence is * empty, set to asio::error::not_found. Otherwise, contains the error * from the last connection attempt. * * @returns On success, the successfully connected endpoint. Otherwise, a * default-constructed endpoint. * * @par Example * The following connect condition function object can be used to output * information about the individual connection attempts: * @code struct my_connect_condition * { * bool operator()( * const asio::error_code& ec, * const::tcp::endpoint& next) * { * if (ec) std::cout << "Error: " << ec.message() << std::endl; * std::cout << "Trying: " << next << std::endl; * return true; * } * }; @endcode * It would be used with the asio::connect function as follows: * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::socket s(my_context); * asio::error_code ec; * tcp::endpoint e = asio::connect(s, * r.resolve(q), my_connect_condition(), ec); * if (ec) * { * // An error occurred. * } * else * { * std::cout << "Connected to: " << e << std::endl; * } @endcode */ template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, asio::error_code& ec, typename enable_if::value>::type* = 0); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use range overload.) Establishes a socket connection by trying /// each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @returns On success, an iterator denoting the successfully connected * endpoint. Otherwise, the end iterator. * * @throws asio::system_error Thrown on failure. If the sequence is * empty, the associated @c error_code is asio::error::not_found. * Otherwise, contains the error from the last connection attempt. * * @note This overload assumes that a default constructed object of type @c * Iterator represents the end of the sequence. This is a valid assumption for * iterator types such as @c asio::ip::tcp::resolver::iterator. */ template Iterator connect(basic_socket& s, Iterator begin, ConnectCondition connect_condition, typename enable_if::value>::type* = 0); /// (Deprecated: Use range overload.) Establishes a socket connection by trying /// each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @param ec Set to indicate what error occurred, if any. If the sequence is * empty, set to asio::error::not_found. Otherwise, contains the error * from the last connection attempt. * * @returns On success, an iterator denoting the successfully connected * endpoint. Otherwise, the end iterator. * * @note This overload assumes that a default constructed object of type @c * Iterator represents the end of the sequence. This is a valid assumption for * iterator types such as @c asio::ip::tcp::resolver::iterator. */ template Iterator connect(basic_socket& s, Iterator begin, ConnectCondition connect_condition, asio::error_code& ec, typename enable_if::value>::type* = 0); #endif // !defined(ASIO_NO_DEPRECATED) /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param end An iterator pointing to the end of a sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @returns An iterator denoting the successfully connected endpoint. * * @throws asio::system_error Thrown on failure. If the sequence is * empty, the associated @c error_code is asio::error::not_found. * Otherwise, contains the error from the last connection attempt. * * @par Example * The following connect condition function object can be used to output * information about the individual connection attempts: * @code struct my_connect_condition * { * bool operator()( * const asio::error_code& ec, * const::tcp::endpoint& next) * { * if (ec) std::cout << "Error: " << ec.message() << std::endl; * std::cout << "Trying: " << next << std::endl; * return true; * } * }; @endcode * It would be used with the asio::connect function as follows: * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::resolver::results_type e = r.resolve(q); * tcp::socket s(my_context); * tcp::resolver::results_type::iterator i = asio::connect( * s, e.begin(), e.end(), my_connect_condition()); * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode */ template Iterator connect(basic_socket& s, Iterator begin, Iterator end, ConnectCondition connect_condition); /// Establishes a socket connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c connect member * function, once for each endpoint in the sequence, until a connection is * successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param end An iterator pointing to the end of a sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @param ec Set to indicate what error occurred, if any. If the sequence is * empty, set to asio::error::not_found. Otherwise, contains the error * from the last connection attempt. * * @returns On success, an iterator denoting the successfully connected * endpoint. Otherwise, the end iterator. * * @par Example * The following connect condition function object can be used to output * information about the individual connection attempts: * @code struct my_connect_condition * { * bool operator()( * const asio::error_code& ec, * const::tcp::endpoint& next) * { * if (ec) std::cout << "Error: " << ec.message() << std::endl; * std::cout << "Trying: " << next << std::endl; * return true; * } * }; @endcode * It would be used with the asio::connect function as follows: * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::resolver::results_type e = r.resolve(q); * tcp::socket s(my_context); * asio::error_code ec; * tcp::resolver::results_type::iterator i = asio::connect( * s, e.begin(), e.end(), my_connect_condition()); * if (ec) * { * // An error occurred. * } * else * { * std::cout << "Connected to: " << i->endpoint() << std::endl; * } @endcode */ template Iterator connect(basic_socket& s, Iterator begin, Iterator end, ConnectCondition connect_condition, asio::error_code& ec); /*@}*/ /** * @defgroup async_connect asio::async_connect * * @brief The @c async_connect function is a composed asynchronous operation * that establishes a socket connection by trying each endpoint in a sequence. */ /*@{*/ /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c async_connect * member function, once for each endpoint in the sequence, until a connection * is successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param endpoints A sequence of endpoints. * * @param handler The handler to be called when the connect operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. if the sequence is empty, set to * // asio::error::not_found. Otherwise, contains the * // error from the last connection attempt. * const asio::error_code& error, * * // On success, the successfully connected endpoint. * // Otherwise, a default-constructed endpoint. * const typename Protocol::endpoint& endpoint * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::socket s(my_context); * * // ... * * r.async_resolve(q, resolve_handler); * * // ... * * void resolve_handler( * const asio::error_code& ec, * tcp::resolver::results_type results) * { * if (!ec) * { * asio::async_connect(s, results, connect_handler); * } * } * * // ... * * void connect_handler( * const asio::error_code& ec, * const tcp::endpoint& endpoint) * { * // ... * } @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler, void (asio::error_code, typename Protocol::endpoint)) async_connect(basic_socket& s, const EndpointSequence& endpoints, ASIO_MOVE_ARG(RangeConnectHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if::value>::type* = 0); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use range overload.) Asynchronously establishes a socket /// connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c async_connect * member function, once for each endpoint in the sequence, until a connection * is successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param handler The handler to be called when the connect operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. if the sequence is empty, set to * // asio::error::not_found. Otherwise, contains the * // error from the last connection attempt. * const asio::error_code& error, * * // On success, an iterator denoting the successfully * // connected endpoint. Otherwise, the end iterator. * Iterator iterator * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note This overload assumes that a default constructed object of type @c * Iterator represents the end of the sequence. This is a valid assumption for * iterator types such as @c asio::ip::tcp::resolver::iterator. */ template ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, ASIO_MOVE_ARG(IteratorConnectHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if::value>::type* = 0); #endif // !defined(ASIO_NO_DEPRECATED) /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c async_connect * member function, once for each endpoint in the sequence, until a connection * is successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param end An iterator pointing to the end of a sequence of endpoints. * * @param handler The handler to be called when the connect operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. if the sequence is empty, set to * // asio::error::not_found. Otherwise, contains the * // error from the last connection attempt. * const asio::error_code& error, * * // On success, an iterator denoting the successfully * // connected endpoint. Otherwise, the end iterator. * Iterator iterator * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code std::vector endpoints = ...; * tcp::socket s(my_context); * asio::async_connect(s, * endpoints.begin(), endpoints.end(), * connect_handler); * * // ... * * void connect_handler( * const asio::error_code& ec, * std::vector::iterator i) * { * // ... * } @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, Iterator end, ASIO_MOVE_ARG(IteratorConnectHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(Executor)); /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c async_connect * member function, once for each endpoint in the sequence, until a connection * is successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param endpoints A sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @param handler The handler to be called when the connect operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. if the sequence is empty, set to * // asio::error::not_found. Otherwise, contains the * // error from the last connection attempt. * const asio::error_code& error, * * // On success, an iterator denoting the successfully * // connected endpoint. Otherwise, the end iterator. * Iterator iterator * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * The following connect condition function object can be used to output * information about the individual connection attempts: * @code struct my_connect_condition * { * bool operator()( * const asio::error_code& ec, * const::tcp::endpoint& next) * { * if (ec) std::cout << "Error: " << ec.message() << std::endl; * std::cout << "Trying: " << next << std::endl; * return true; * } * }; @endcode * It would be used with the asio::connect function as follows: * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::socket s(my_context); * * // ... * * r.async_resolve(q, resolve_handler); * * // ... * * void resolve_handler( * const asio::error_code& ec, * tcp::resolver::results_type results) * { * if (!ec) * { * asio::async_connect(s, results, * my_connect_condition(), * connect_handler); * } * } * * // ... * * void connect_handler( * const asio::error_code& ec, * const tcp::endpoint& endpoint) * { * if (ec) * { * // An error occurred. * } * else * { * std::cout << "Connected to: " << endpoint << std::endl; * } * } @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler, void (asio::error_code, typename Protocol::endpoint)) async_connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, ASIO_MOVE_ARG(RangeConnectHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if::value>::type* = 0); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use range overload.) Asynchronously establishes a socket /// connection by trying each endpoint in a sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c async_connect * member function, once for each endpoint in the sequence, until a connection * is successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @param handler The handler to be called when the connect operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. if the sequence is empty, set to * // asio::error::not_found. Otherwise, contains the * // error from the last connection attempt. * const asio::error_code& error, * * // On success, an iterator denoting the successfully * // connected endpoint. Otherwise, the end iterator. * Iterator iterator * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note This overload assumes that a default constructed object of type @c * Iterator represents the end of the sequence. This is a valid assumption for * iterator types such as @c asio::ip::tcp::resolver::iterator. */ template ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, ConnectCondition connect_condition, ASIO_MOVE_ARG(IteratorConnectHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if::value>::type* = 0); #endif // !defined(ASIO_NO_DEPRECATED) /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /** * This function attempts to connect a socket to one of a sequence of * endpoints. It does this by repeated calls to the socket's @c async_connect * member function, once for each endpoint in the sequence, until a connection * is successfully established. * * @param s The socket to be connected. If the socket is already open, it will * be closed. * * @param begin An iterator pointing to the start of a sequence of endpoints. * * @param end An iterator pointing to the end of a sequence of endpoints. * * @param connect_condition A function object that is called prior to each * connection attempt. The signature of the function object must be: * @code bool connect_condition( * const asio::error_code& ec, * const typename Protocol::endpoint& next); @endcode * The @c ec parameter contains the result from the most recent connect * operation. Before the first connection attempt, @c ec is always set to * indicate success. The @c next parameter is the next endpoint to be tried. * The function object should return true if the next endpoint should be tried, * and false if it should be skipped. * * @param handler The handler to be called when the connect operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * // Result of operation. if the sequence is empty, set to * // asio::error::not_found. Otherwise, contains the * // error from the last connection attempt. * const asio::error_code& error, * * // On success, an iterator denoting the successfully * // connected endpoint. Otherwise, the end iterator. * Iterator iterator * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * The following connect condition function object can be used to output * information about the individual connection attempts: * @code struct my_connect_condition * { * bool operator()( * const asio::error_code& ec, * const::tcp::endpoint& next) * { * if (ec) std::cout << "Error: " << ec.message() << std::endl; * std::cout << "Trying: " << next << std::endl; * return true; * } * }; @endcode * It would be used with the asio::connect function as follows: * @code tcp::resolver r(my_context); * tcp::resolver::query q("host", "service"); * tcp::socket s(my_context); * * // ... * * r.async_resolve(q, resolve_handler); * * // ... * * void resolve_handler( * const asio::error_code& ec, * tcp::resolver::iterator i) * { * if (!ec) * { * tcp::resolver::iterator end; * asio::async_connect(s, i, end, * my_connect_condition(), * connect_handler); * } * } * * // ... * * void connect_handler( * const asio::error_code& ec, * tcp::resolver::iterator i) * { * if (ec) * { * // An error occurred. * } * else * { * std::cout << "Connected to: " << i->endpoint() << std::endl; * } * } @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, Iterator end, ConnectCondition connect_condition, ASIO_MOVE_ARG(IteratorConnectHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(Executor)); /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/connect.hpp" #endif ================================================ FILE: src/third_party/asio/coroutine.hpp ================================================ // // coroutine.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_COROUTINE_HPP #define ASIO_COROUTINE_HPP namespace asio { namespace detail { class coroutine_ref; } // namespace detail /// Provides support for implementing stackless coroutines. /** * The @c coroutine class may be used to implement stackless coroutines. The * class itself is used to store the current state of the coroutine. * * Coroutines are copy-constructible and assignable, and the space overhead is * a single int. They can be used as a base class: * * @code class session : coroutine * { * ... * }; @endcode * * or as a data member: * * @code class session * { * ... * coroutine coro_; * }; @endcode * * or even bound in as a function argument using lambdas or @c bind(). The * important thing is that as the application maintains a copy of the object * for as long as the coroutine must be kept alive. * * @par Pseudo-keywords * * A coroutine is used in conjunction with certain "pseudo-keywords", which * are implemented as macros. These macros are defined by a header file: * * @code #include @endcode * * and may conversely be undefined as follows: * * @code #include @endcode * * reenter * * The @c reenter macro is used to define the body of a coroutine. It takes a * single argument: a pointer or reference to a coroutine object. For example, * if the base class is a coroutine object you may write: * * @code reenter (this) * { * ... coroutine body ... * } @endcode * * and if a data member or other variable you can write: * * @code reenter (coro_) * { * ... coroutine body ... * } @endcode * * When @c reenter is executed at runtime, control jumps to the location of the * last @c yield or @c fork. * * The coroutine body may also be a single statement, such as: * * @code reenter (this) for (;;) * { * ... * } @endcode * * @b Limitation: The @c reenter macro is implemented using a switch. This * means that you must take care when using local variables within the * coroutine body. The local variable is not allowed in a position where * reentering the coroutine could bypass the variable definition. * * yield statement * * This form of the @c yield keyword is often used with asynchronous operations: * * @code yield socket_->async_read_some(buffer(*buffer_), *this); @endcode * * This divides into four logical steps: * * @li @c yield saves the current state of the coroutine. * @li The statement initiates the asynchronous operation. * @li The resume point is defined immediately following the statement. * @li Control is transferred to the end of the coroutine body. * * When the asynchronous operation completes, the function object is invoked * and @c reenter causes control to transfer to the resume point. It is * important to remember to carry the coroutine state forward with the * asynchronous operation. In the above snippet, the current class is a * function object object with a coroutine object as base class or data member. * * The statement may also be a compound statement, and this permits us to * define local variables with limited scope: * * @code yield * { * mutable_buffers_1 b = buffer(*buffer_); * socket_->async_read_some(b, *this); * } @endcode * * yield return expression ; * * This form of @c yield is often used in generators or coroutine-based parsers. * For example, the function object: * * @code struct interleave : coroutine * { * istream& is1; * istream& is2; * char operator()(char c) * { * reenter (this) for (;;) * { * yield return is1.get(); * yield return is2.get(); * } * } * }; @endcode * * defines a trivial coroutine that interleaves the characters from two input * streams. * * This type of @c yield divides into three logical steps: * * @li @c yield saves the current state of the coroutine. * @li The resume point is defined immediately following the semicolon. * @li The value of the expression is returned from the function. * * yield ; * * This form of @c yield is equivalent to the following steps: * * @li @c yield saves the current state of the coroutine. * @li The resume point is defined immediately following the semicolon. * @li Control is transferred to the end of the coroutine body. * * This form might be applied when coroutines are used for cooperative * threading and scheduling is explicitly managed. For example: * * @code struct task : coroutine * { * ... * void operator()() * { * reenter (this) * { * while (... not finished ...) * { * ... do something ... * yield; * ... do some more ... * yield; * } * } * } * ... * }; * ... * task t1, t2; * for (;;) * { * t1(); * t2(); * } @endcode * * yield break ; * * The final form of @c yield is used to explicitly terminate the coroutine. * This form is comprised of two steps: * * @li @c yield sets the coroutine state to indicate termination. * @li Control is transferred to the end of the coroutine body. * * Once terminated, calls to is_complete() return true and the coroutine cannot * be reentered. * * Note that a coroutine may also be implicitly terminated if the coroutine * body is exited without a yield, e.g. by return, throw or by running to the * end of the body. * * fork statement * * The @c fork pseudo-keyword is used when "forking" a coroutine, i.e. splitting * it into two (or more) copies. One use of @c fork is in a server, where a new * coroutine is created to handle each client connection: * * @code reenter (this) * { * do * { * socket_.reset(new tcp::socket(my_context_)); * yield acceptor->async_accept(*socket_, *this); * fork server(*this)(); * } while (is_parent()); * ... client-specific handling follows ... * } @endcode * * The logical steps involved in a @c fork are: * * @li @c fork saves the current state of the coroutine. * @li The statement creates a copy of the coroutine and either executes it * immediately or schedules it for later execution. * @li The resume point is defined immediately following the semicolon. * @li For the "parent", control immediately continues from the next line. * * The functions is_parent() and is_child() can be used to differentiate * between parent and child. You would use these functions to alter subsequent * control flow. * * Note that @c fork doesn't do the actual forking by itself. It is the * application's responsibility to create a clone of the coroutine and call it. * The clone can be called immediately, as above, or scheduled for delayed * execution using something like asio::post(). * * @par Alternate macro names * * If preferred, an application can use macro names that follow a more typical * naming convention, rather than the pseudo-keywords. These are: * * @li @c ASIO_CORO_REENTER instead of @c reenter * @li @c ASIO_CORO_YIELD instead of @c yield * @li @c ASIO_CORO_FORK instead of @c fork */ class coroutine { public: /// Constructs a coroutine in its initial state. coroutine() : value_(0) {} /// Returns true if the coroutine is the child of a fork. bool is_child() const { return value_ < 0; } /// Returns true if the coroutine is the parent of a fork. bool is_parent() const { return !is_child(); } /// Returns true if the coroutine has reached its terminal state. bool is_complete() const { return value_ == -1; } private: friend class detail::coroutine_ref; int value_; }; namespace detail { class coroutine_ref { public: coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {} coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {} ~coroutine_ref() { if (!modified_) value_ = -1; } operator int() const { return value_; } int& operator=(int v) { modified_ = true; return value_ = v; } private: void operator=(const coroutine_ref&); int& value_; bool modified_; }; } // namespace detail } // namespace asio #define ASIO_CORO_REENTER(c) \ switch (::asio::detail::coroutine_ref _coro_value = c) \ case -1: if (_coro_value) \ { \ goto terminate_coroutine; \ terminate_coroutine: \ _coro_value = -1; \ goto bail_out_of_coroutine; \ bail_out_of_coroutine: \ break; \ } \ else /* fall-through */ case 0: #define ASIO_CORO_YIELD_IMPL(n) \ for (_coro_value = (n);;) \ if (_coro_value == 0) \ { \ case (n): ; \ break; \ } \ else \ switch (_coro_value ? 0 : 1) \ for (;;) \ /* fall-through */ case -1: if (_coro_value) \ goto terminate_coroutine; \ else for (;;) \ /* fall-through */ case 1: if (_coro_value) \ goto bail_out_of_coroutine; \ else /* fall-through */ case 0: #define ASIO_CORO_FORK_IMPL(n) \ for (_coro_value = -(n);; _coro_value = (n)) \ if (_coro_value == (n)) \ { \ case -(n): ; \ break; \ } \ else #if defined(_MSC_VER) # define ASIO_CORO_YIELD ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1) # define ASIO_CORO_FORK ASIO_CORO_FORK_IMPL(__COUNTER__ + 1) #else // defined(_MSC_VER) # define ASIO_CORO_YIELD ASIO_CORO_YIELD_IMPL(__LINE__) # define ASIO_CORO_FORK ASIO_CORO_FORK_IMPL(__LINE__) #endif // defined(_MSC_VER) #endif // ASIO_COROUTINE_HPP ================================================ FILE: src/third_party/asio/deadline_timer.hpp ================================================ // // deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DEADLINE_TIMER_HPP #define ASIO_DEADLINE_TIMER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) #include "asio/detail/socket_types.hpp" // Must come before posix_time. #include "asio/basic_deadline_timer.hpp" #include namespace asio { /// Typedef for the typical usage of timer. Uses a UTC clock. typedef basic_deadline_timer deadline_timer; } // namespace asio #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_DEADLINE_TIMER_HPP ================================================ FILE: src/third_party/asio/defer.hpp ================================================ // // defer.hpp // ~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DEFER_HPP #define ASIO_DEFER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Submits a completion token or function object for execution. /** * This function submits an object for execution using the object's associated * executor. The function object is queued for execution, and is never called * from the current thread prior to returning from defer(). * * The use of @c defer(), rather than @ref post(), indicates the caller's * preference that the executor defer the queueing of the function object. This * may allow the executor to optimise queueing for cases when the function * object represents a continuation of the current call context. * * This function has the following effects: * * @li Constructs a function object handler of type @c Handler, initialized * with handler(forward(token)). * * @li Constructs an object @c result of type async_result, * initializing the object as result(handler). * * @li Obtains the handler's associated executor object @c ex by performing * get_associated_executor(handler). * * @li Obtains the handler's associated allocator object @c alloc by performing * get_associated_allocator(handler). * * @li Performs ex.defer(std::move(handler), alloc). * * @li Returns result.get(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer( ASIO_MOVE_ARG(CompletionToken) token); /// Submits a completion token or function object for execution. /** * This function submits an object for execution using the specified executor. * The function object is queued for execution, and is never called from the * current thread prior to returning from defer(). * * The use of @c defer(), rather than @ref post(), indicates the caller's * preference that the executor defer the queueing of the function object. This * may allow the executor to optimise queueing for cases when the function * object represents a continuation of the current call context. * * This function has the following effects: * * @li Constructs a function object handler of type @c Handler, initialized * with handler(forward(token)). * * @li Constructs an object @c result of type async_result, * initializing the object as result(handler). * * @li Obtains the handler's associated executor object @c ex1 by performing * get_associated_executor(handler). * * @li Creates a work object @c w by performing make_work(ex1). * * @li Obtains the handler's associated allocator object @c alloc by performing * get_associated_allocator(handler). * * @li Constructs a function object @c f with a function call operator that * performs ex1.dispatch(std::move(handler), alloc) followed by * w.reset(). * * @li Performs Executor(ex).defer(std::move(f), alloc). * * @li Returns result.get(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer( const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if::value>::type* = 0); /// Submits a completion token or function object for execution. /** * @returns defer(ctx.get_executor(), forward(token)). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer( ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type), typename enable_if::value>::type* = 0); } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/defer.hpp" #endif // ASIO_DEFER_HPP ================================================ FILE: src/third_party/asio/detached.hpp ================================================ // // detached.hpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETACHED_HPP #define ASIO_DETACHED_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/push_options.hpp" namespace asio { /// Class used to specify that an asynchronous operation is detached. /** * The detached_t class is used to indicate that an asynchronous operation is * detached. That is, there is no completion handler waiting for the * operation's result. A detached_t object may be passed as a handler to an * asynchronous operation, typically using the special value * @c asio::detached. For example: * @code my_socket.async_send(my_buffer, asio::detached); * @endcode */ class detached_t { public: /// Constructor. ASIO_CONSTEXPR detached_t() { } }; /// A special value, similar to std::nothrow. /** * See the documentation for asio::detached_t for a usage example. */ #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr detached_t detached; #elif defined(ASIO_MSVC) __declspec(selectany) detached_t detached; #endif } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/detached.hpp" #endif // ASIO_DETACHED_HPP ================================================ FILE: src/third_party/asio/detail/array.hpp ================================================ // // detail/array.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_ARRAY_HPP #define ASIO_DETAIL_ARRAY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_ARRAY) # include #else // defined(ASIO_HAS_STD_ARRAY) # include #endif // defined(ASIO_HAS_STD_ARRAY) namespace asio { namespace detail { #if defined(ASIO_HAS_STD_ARRAY) using std::array; #else // defined(ASIO_HAS_STD_ARRAY) using boost::array; #endif // defined(ASIO_HAS_STD_ARRAY) } // namespace detail } // namespace asio #endif // ASIO_DETAIL_ARRAY_HPP ================================================ FILE: src/third_party/asio/detail/array_fwd.hpp ================================================ // // detail/array_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_ARRAY_FWD_HPP #define ASIO_DETAIL_ARRAY_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" namespace boost { template class array; } // namespace boost // Standard library components can't be forward declared, so we'll have to // include the array header. Fortunately, it's fairly lightweight and doesn't // add significantly to the compile time. #if defined(ASIO_HAS_STD_ARRAY) # include #endif // defined(ASIO_HAS_STD_ARRAY) #endif // ASIO_DETAIL_ARRAY_FWD_HPP ================================================ FILE: src/third_party/asio/detail/assert.hpp ================================================ // // detail/assert.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_ASSERT_HPP #define ASIO_DETAIL_ASSERT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_ASSERT) # include #else // defined(ASIO_HAS_BOOST_ASSERT) # include #endif // defined(ASIO_HAS_BOOST_ASSERT) #if defined(ASIO_HAS_BOOST_ASSERT) # define ASIO_ASSERT(expr) BOOST_ASSERT(expr) #else // defined(ASIO_HAS_BOOST_ASSERT) # define ASIO_ASSERT(expr) assert(expr) #endif // defined(ASIO_HAS_BOOST_ASSERT) #endif // ASIO_DETAIL_ASSERT_HPP ================================================ FILE: src/third_party/asio/detail/atomic_count.hpp ================================================ // // detail/atomic_count.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_ATOMIC_COUNT_HPP #define ASIO_DETAIL_ATOMIC_COUNT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) // Nothing to include. #elif defined(ASIO_HAS_STD_ATOMIC) # include #else // defined(ASIO_HAS_STD_ATOMIC) # include #endif // defined(ASIO_HAS_STD_ATOMIC) namespace asio { namespace detail { #if !defined(ASIO_HAS_THREADS) typedef long atomic_count; inline void increment(atomic_count& a, long b) { a += b; } #elif defined(ASIO_HAS_STD_ATOMIC) typedef std::atomic atomic_count; inline void increment(atomic_count& a, long b) { a += b; } #else // defined(ASIO_HAS_STD_ATOMIC) typedef boost::detail::atomic_count atomic_count; inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; } #endif // defined(ASIO_HAS_STD_ATOMIC) } // namespace detail } // namespace asio #endif // ASIO_DETAIL_ATOMIC_COUNT_HPP ================================================ FILE: src/third_party/asio/detail/base_from_completion_cond.hpp ================================================ // // detail/base_from_completion_cond.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP #define ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/completion_condition.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class base_from_completion_cond { protected: explicit base_from_completion_cond(CompletionCondition& completion_condition) : completion_condition_( ASIO_MOVE_CAST(CompletionCondition)(completion_condition)) { } std::size_t check_for_completion( const asio::error_code& ec, std::size_t total_transferred) { return detail::adapt_completion_condition_result( completion_condition_(ec, total_transferred)); } private: CompletionCondition completion_condition_; }; template <> class base_from_completion_cond { protected: explicit base_from_completion_cond(transfer_all_t) { } static std::size_t check_for_completion( const asio::error_code& ec, std::size_t total_transferred) { return transfer_all_t()(ec, total_transferred); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP ================================================ FILE: src/third_party/asio/detail/bind_handler.hpp ================================================ // // detail/bind_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_BIND_HANDLER_HPP #define ASIO_DETAIL_BIND_HANDLER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class binder1 { public: template binder1(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1) : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1) { } binder1(Handler& handler, const Arg1& arg1) : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1) { } #if defined(ASIO_HAS_MOVE) binder1(const binder1& other) : handler_(other.handler_), arg1_(other.arg1_) { } binder1(binder1&& other) : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { handler_(static_cast(arg1_)); } void operator()() const { handler_(arg1_); } //private: Handler handler_; Arg1 arg1_; }; template inline void* asio_handler_allocate(std::size_t size, binder1* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, binder1* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( binder1* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, binder1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, binder1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline binder1::type, Arg1> bind_handler( ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1) { return binder1::type, Arg1>(0, ASIO_MOVE_CAST(Handler)(handler), arg1); } template class binder2 { public: template binder2(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2) : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2) { } binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2) : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2) { } #if defined(ASIO_HAS_MOVE) binder2(const binder2& other) : handler_(other.handler_), arg1_(other.arg1_), arg2_(other.arg2_) { } binder2(binder2&& other) : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { handler_(static_cast(arg1_), static_cast(arg2_)); } void operator()() const { handler_(arg1_, arg2_); } //private: Handler handler_; Arg1 arg1_; Arg2 arg2_; }; template inline void* asio_handler_allocate(std::size_t size, binder2* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, binder2* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( binder2* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, binder2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, binder2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline binder2::type, Arg1, Arg2> bind_handler( ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2) { return binder2::type, Arg1, Arg2>(0, ASIO_MOVE_CAST(Handler)(handler), arg1, arg2); } template class binder3 { public: template binder3(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3) { } binder3(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3) { } #if defined(ASIO_HAS_MOVE) binder3(const binder3& other) : handler_(other.handler_), arg1_(other.arg1_), arg2_(other.arg2_), arg3_(other.arg3_) { } binder3(binder3&& other) : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)), arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { handler_(static_cast(arg1_), static_cast(arg2_), static_cast(arg3_)); } void operator()() const { handler_(arg1_, arg2_, arg3_); } //private: Handler handler_; Arg1 arg1_; Arg2 arg2_; Arg3 arg3_; }; template inline void* asio_handler_allocate(std::size_t size, binder3* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, binder3* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( binder3* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, binder3* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, binder3* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline binder3::type, Arg1, Arg2, Arg3> bind_handler( ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { return binder3::type, Arg1, Arg2, Arg3>(0, ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3); } template class binder4 { public: template binder4(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3), arg4_(arg4) { } binder4(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3), arg4_(arg4) { } #if defined(ASIO_HAS_MOVE) binder4(const binder4& other) : handler_(other.handler_), arg1_(other.arg1_), arg2_(other.arg2_), arg3_(other.arg3_), arg4_(other.arg4_) { } binder4(binder4&& other) : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)), arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)), arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { handler_(static_cast(arg1_), static_cast(arg2_), static_cast(arg3_), static_cast(arg4_)); } void operator()() const { handler_(arg1_, arg2_, arg3_, arg4_); } //private: Handler handler_; Arg1 arg1_; Arg2 arg2_; Arg3 arg3_; Arg4 arg4_; }; template inline void* asio_handler_allocate(std::size_t size, binder4* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, binder4* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( binder4* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, binder4* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, binder4* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline binder4::type, Arg1, Arg2, Arg3, Arg4> bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { return binder4::type, Arg1, Arg2, Arg3, Arg4>(0, ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4); } template class binder5 { public: template binder5(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3), arg4_(arg4), arg5_(arg5) { } binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3), arg4_(arg4), arg5_(arg5) { } #if defined(ASIO_HAS_MOVE) binder5(const binder5& other) : handler_(other.handler_), arg1_(other.arg1_), arg2_(other.arg2_), arg3_(other.arg3_), arg4_(other.arg4_), arg5_(other.arg5_) { } binder5(binder5&& other) : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)), arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)), arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)), arg5_(ASIO_MOVE_CAST(Arg5)(other.arg5_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { handler_(static_cast(arg1_), static_cast(arg2_), static_cast(arg3_), static_cast(arg4_), static_cast(arg5_)); } void operator()() const { handler_(arg1_, arg2_, arg3_, arg4_, arg5_); } //private: Handler handler_; Arg1 arg1_; Arg2 arg2_; Arg3 arg3_; Arg4 arg4_; Arg5 arg5_; }; template inline void* asio_handler_allocate(std::size_t size, binder5* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, binder5* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( binder5* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, binder5* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, binder5* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline binder5::type, Arg1, Arg2, Arg3, Arg4, Arg5> bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) { return binder5::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0, ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5); } #if defined(ASIO_HAS_MOVE) template class move_binder1 { public: move_binder1(int, ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Arg1) arg1) : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(ASIO_MOVE_CAST(Arg1)(arg1)) { } move_binder1(move_binder1&& other) : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)) { } void operator()() { handler_(ASIO_MOVE_CAST(Arg1)(arg1_)); } //private: Handler handler_; Arg1 arg1_; }; template inline void* asio_handler_allocate(std::size_t size, move_binder1* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, move_binder1* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( move_binder1* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(ASIO_MOVE_ARG(Function) function, move_binder1* this_handler) { asio_handler_invoke_helpers::invoke( ASIO_MOVE_CAST(Function)(function), this_handler->handler_); } template class move_binder2 { public: move_binder2(int, ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, ASIO_MOVE_ARG(Arg2) arg2) : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(ASIO_MOVE_CAST(Arg2)(arg2)) { } move_binder2(move_binder2&& other) : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)), arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)) { } void operator()() { handler_(static_cast(arg1_), ASIO_MOVE_CAST(Arg2)(arg2_)); } //private: Handler handler_; Arg1 arg1_; Arg2 arg2_; }; template inline void* asio_handler_allocate(std::size_t size, move_binder2* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, move_binder2* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( move_binder2* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(ASIO_MOVE_ARG(Function) function, move_binder2* this_handler) { asio_handler_invoke_helpers::invoke( ASIO_MOVE_CAST(Function)(function), this_handler->handler_); } #endif // defined(ASIO_HAS_MOVE) } // namespace detail template struct associated_allocator, Allocator> { typedef typename associated_allocator::type type; static type get(const detail::binder1& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_allocator, Allocator> { typedef typename associated_allocator::type type; static type get(const detail::binder2& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor, Executor> { typedef typename associated_executor::type type; static type get(const detail::binder1& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; template struct associated_executor, Executor> { typedef typename associated_executor::type type; static type get(const detail::binder2& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #if defined(ASIO_HAS_MOVE) template struct associated_allocator, Allocator> { typedef typename associated_allocator::type type; static type get(const detail::move_binder1& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_allocator< detail::move_binder2, Allocator> { typedef typename associated_allocator::type type; static type get(const detail::move_binder2& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor, Executor> { typedef typename associated_executor::type type; static type get(const detail::move_binder1& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; template struct associated_executor, Executor> { typedef typename associated_executor::type type; static type get(const detail::move_binder2& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // defined(ASIO_HAS_MOVE) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_BIND_HANDLER_HPP ================================================ FILE: src/third_party/asio/detail/buffer_resize_guard.hpp ================================================ // // detail/buffer_resize_guard.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP #define ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Helper class to manage buffer resizing in an exception safe way. template class buffer_resize_guard { public: // Constructor. buffer_resize_guard(Buffer& buffer) : buffer_(buffer), old_size_(buffer.size()) { } // Destructor rolls back the buffer resize unless commit was called. ~buffer_resize_guard() { if (old_size_ != (std::numeric_limits::max)()) { buffer_.resize(old_size_); } } // Commit the resize transaction. void commit() { old_size_ = (std::numeric_limits::max)(); } private: // The buffer being managed. Buffer& buffer_; // The size of the buffer at the time the guard was constructed. size_t old_size_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP ================================================ FILE: src/third_party/asio/detail/buffer_sequence_adapter.hpp ================================================ // // detail/buffer_sequence_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP #define ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/buffer.hpp" #include "asio/detail/array_fwd.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class buffer_sequence_adapter_base { #if defined(ASIO_WINDOWS_RUNTIME) public: // The maximum number of buffers to support in a single operation. enum { max_buffers = 1 }; protected: typedef Windows::Storage::Streams::IBuffer^ native_buffer_type; ASIO_DECL static void init_native_buffer( native_buffer_type& buf, const asio::mutable_buffer& buffer); ASIO_DECL static void init_native_buffer( native_buffer_type& buf, const asio::const_buffer& buffer); #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) public: // The maximum number of buffers to support in a single operation. enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; protected: typedef WSABUF native_buffer_type; static void init_native_buffer(WSABUF& buf, const asio::mutable_buffer& buffer) { buf.buf = static_cast(buffer.data()); buf.len = static_cast(buffer.size()); } static void init_native_buffer(WSABUF& buf, const asio::const_buffer& buffer) { buf.buf = const_cast(static_cast(buffer.data())); buf.len = static_cast(buffer.size()); } #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) public: // The maximum number of buffers to support in a single operation. enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; protected: typedef iovec native_buffer_type; static void init_iov_base(void*& base, void* addr) { base = addr; } template static void init_iov_base(T& base, void* addr) { base = static_cast(addr); } static void init_native_buffer(iovec& iov, const asio::mutable_buffer& buffer) { init_iov_base(iov.iov_base, buffer.data()); iov.iov_len = buffer.size(); } static void init_native_buffer(iovec& iov, const asio::const_buffer& buffer) { init_iov_base(iov.iov_base, const_cast(buffer.data())); iov.iov_len = buffer.size(); } #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) }; // Helper class to translate buffers into the native buffer representation. template class buffer_sequence_adapter : buffer_sequence_adapter_base { public: explicit buffer_sequence_adapter(const Buffers& buffer_sequence) : count_(0), total_buffer_size_(0) { buffer_sequence_adapter::init( asio::buffer_sequence_begin(buffer_sequence), asio::buffer_sequence_end(buffer_sequence)); } native_buffer_type* buffers() { return buffers_; } std::size_t count() const { return count_; } std::size_t total_size() const { return total_buffer_size_; } bool all_empty() const { return total_buffer_size_ == 0; } static bool all_empty(const Buffers& buffer_sequence) { return buffer_sequence_adapter::all_empty( asio::buffer_sequence_begin(buffer_sequence), asio::buffer_sequence_end(buffer_sequence)); } static void validate(const Buffers& buffer_sequence) { buffer_sequence_adapter::validate( asio::buffer_sequence_begin(buffer_sequence), asio::buffer_sequence_end(buffer_sequence)); } static Buffer first(const Buffers& buffer_sequence) { return buffer_sequence_adapter::first( asio::buffer_sequence_begin(buffer_sequence), asio::buffer_sequence_end(buffer_sequence)); } private: template void init(Iterator begin, Iterator end) { Iterator iter = begin; for (; iter != end && count_ < max_buffers; ++iter, ++count_) { Buffer buffer(*iter); init_native_buffer(buffers_[count_], buffer); total_buffer_size_ += buffer.size(); } } template static bool all_empty(Iterator begin, Iterator end) { Iterator iter = begin; std::size_t i = 0; for (; iter != end && i < max_buffers; ++iter, ++i) if (Buffer(*iter).size() > 0) return false; return true; } template static void validate(Iterator begin, Iterator end) { Iterator iter = begin; for (; iter != end; ++iter) { Buffer buffer(*iter); buffer.data(); } } template static Buffer first(Iterator begin, Iterator end) { Iterator iter = begin; for (; iter != end; ++iter) { Buffer buffer(*iter); if (buffer.size() != 0) return buffer; } return Buffer(); } native_buffer_type buffers_[max_buffers]; std::size_t count_; std::size_t total_buffer_size_; }; template class buffer_sequence_adapter : buffer_sequence_adapter_base { public: explicit buffer_sequence_adapter( const asio::mutable_buffer& buffer_sequence) { init_native_buffer(buffer_, Buffer(buffer_sequence)); total_buffer_size_ = buffer_sequence.size(); } native_buffer_type* buffers() { return &buffer_; } std::size_t count() const { return 1; } std::size_t total_size() const { return total_buffer_size_; } bool all_empty() const { return total_buffer_size_ == 0; } static bool all_empty(const asio::mutable_buffer& buffer_sequence) { return buffer_sequence.size() == 0; } static void validate(const asio::mutable_buffer& buffer_sequence) { buffer_sequence.data(); } static Buffer first(const asio::mutable_buffer& buffer_sequence) { return Buffer(buffer_sequence); } private: native_buffer_type buffer_; std::size_t total_buffer_size_; }; template class buffer_sequence_adapter : buffer_sequence_adapter_base { public: explicit buffer_sequence_adapter( const asio::const_buffer& buffer_sequence) { init_native_buffer(buffer_, Buffer(buffer_sequence)); total_buffer_size_ = buffer_sequence.size(); } native_buffer_type* buffers() { return &buffer_; } std::size_t count() const { return 1; } std::size_t total_size() const { return total_buffer_size_; } bool all_empty() const { return total_buffer_size_ == 0; } static bool all_empty(const asio::const_buffer& buffer_sequence) { return buffer_sequence.size() == 0; } static void validate(const asio::const_buffer& buffer_sequence) { buffer_sequence.data(); } static Buffer first(const asio::const_buffer& buffer_sequence) { return Buffer(buffer_sequence); } private: native_buffer_type buffer_; std::size_t total_buffer_size_; }; #if !defined(ASIO_NO_DEPRECATED) template class buffer_sequence_adapter : buffer_sequence_adapter_base { public: explicit buffer_sequence_adapter( const asio::mutable_buffers_1& buffer_sequence) { init_native_buffer(buffer_, Buffer(buffer_sequence)); total_buffer_size_ = buffer_sequence.size(); } native_buffer_type* buffers() { return &buffer_; } std::size_t count() const { return 1; } std::size_t total_size() const { return total_buffer_size_; } bool all_empty() const { return total_buffer_size_ == 0; } static bool all_empty(const asio::mutable_buffers_1& buffer_sequence) { return buffer_sequence.size() == 0; } static void validate(const asio::mutable_buffers_1& buffer_sequence) { buffer_sequence.data(); } static Buffer first(const asio::mutable_buffers_1& buffer_sequence) { return Buffer(buffer_sequence); } private: native_buffer_type buffer_; std::size_t total_buffer_size_; }; template class buffer_sequence_adapter : buffer_sequence_adapter_base { public: explicit buffer_sequence_adapter( const asio::const_buffers_1& buffer_sequence) { init_native_buffer(buffer_, Buffer(buffer_sequence)); total_buffer_size_ = buffer_sequence.size(); } native_buffer_type* buffers() { return &buffer_; } std::size_t count() const { return 1; } std::size_t total_size() const { return total_buffer_size_; } bool all_empty() const { return total_buffer_size_ == 0; } static bool all_empty(const asio::const_buffers_1& buffer_sequence) { return buffer_sequence.size() == 0; } static void validate(const asio::const_buffers_1& buffer_sequence) { buffer_sequence.data(); } static Buffer first(const asio::const_buffers_1& buffer_sequence) { return Buffer(buffer_sequence); } private: native_buffer_type buffer_; std::size_t total_buffer_size_; }; #endif // !defined(ASIO_NO_DEPRECATED) template class buffer_sequence_adapter > : buffer_sequence_adapter_base { public: explicit buffer_sequence_adapter( const boost::array& buffer_sequence) { init_native_buffer(buffers_[0], Buffer(buffer_sequence[0])); init_native_buffer(buffers_[1], Buffer(buffer_sequence[1])); total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size(); } native_buffer_type* buffers() { return buffers_; } std::size_t count() const { return 2; } std::size_t total_size() const { return total_buffer_size_; } bool all_empty() const { return total_buffer_size_ == 0; } static bool all_empty(const boost::array& buffer_sequence) { return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0; } static void validate(const boost::array& buffer_sequence) { buffer_sequence[0].data(); buffer_sequence[1].data(); } static Buffer first(const boost::array& buffer_sequence) { return Buffer(buffer_sequence[0].size() != 0 ? buffer_sequence[0] : buffer_sequence[1]); } private: native_buffer_type buffers_[2]; std::size_t total_buffer_size_; }; #if defined(ASIO_HAS_STD_ARRAY) template class buffer_sequence_adapter > : buffer_sequence_adapter_base { public: explicit buffer_sequence_adapter( const std::array& buffer_sequence) { init_native_buffer(buffers_[0], Buffer(buffer_sequence[0])); init_native_buffer(buffers_[1], Buffer(buffer_sequence[1])); total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size(); } native_buffer_type* buffers() { return buffers_; } std::size_t count() const { return 2; } std::size_t total_size() const { return total_buffer_size_; } bool all_empty() const { return total_buffer_size_ == 0; } static bool all_empty(const std::array& buffer_sequence) { return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0; } static void validate(const std::array& buffer_sequence) { buffer_sequence[0].data(); buffer_sequence[1].data(); } static Buffer first(const std::array& buffer_sequence) { return Buffer(buffer_sequence[0].size() != 0 ? buffer_sequence[0] : buffer_sequence[1]); } private: native_buffer_type buffers_[2]; std::size_t total_buffer_size_; }; #endif // defined(ASIO_HAS_STD_ARRAY) } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/buffer_sequence_adapter.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP ================================================ FILE: src/third_party/asio/detail/buffered_stream_storage.hpp ================================================ // // detail/buffered_stream_storage.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP #define ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/buffer.hpp" #include "asio/detail/assert.hpp" #include #include #include #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class buffered_stream_storage { public: // The type of the bytes stored in the buffer. typedef unsigned char byte_type; // The type used for offsets into the buffer. typedef std::size_t size_type; // Constructor. explicit buffered_stream_storage(std::size_t buffer_capacity) : begin_offset_(0), end_offset_(0), buffer_(buffer_capacity) { } /// Clear the buffer. void clear() { begin_offset_ = 0; end_offset_ = 0; } // Return a pointer to the beginning of the unread data. mutable_buffer data() { return asio::buffer(buffer_) + begin_offset_; } // Return a pointer to the beginning of the unread data. const_buffer data() const { return asio::buffer(buffer_) + begin_offset_; } // Is there no unread data in the buffer. bool empty() const { return begin_offset_ == end_offset_; } // Return the amount of unread data the is in the buffer. size_type size() const { return end_offset_ - begin_offset_; } // Resize the buffer to the specified length. void resize(size_type length) { ASIO_ASSERT(length <= capacity()); if (begin_offset_ + length <= capacity()) { end_offset_ = begin_offset_ + length; } else { using namespace std; // For memmove. memmove(&buffer_[0], &buffer_[0] + begin_offset_, size()); end_offset_ = length; begin_offset_ = 0; } } // Return the maximum size for data in the buffer. size_type capacity() const { return buffer_.size(); } // Consume multiple bytes from the beginning of the buffer. void consume(size_type count) { ASIO_ASSERT(begin_offset_ + count <= end_offset_); begin_offset_ += count; if (empty()) clear(); } private: // The offset to the beginning of the unread data. size_type begin_offset_; // The offset to the end of the unread data. size_type end_offset_; // The data in the buffer. std::vector buffer_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP ================================================ FILE: src/third_party/asio/detail/call_stack.hpp ================================================ // // detail/call_stack.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CALL_STACK_HPP #define ASIO_DETAIL_CALL_STACK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/tss_ptr.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Helper class to determine whether or not the current thread is inside an // invocation of io_context::run() for a specified io_context object. template class call_stack { public: // Context class automatically pushes the key/value pair on to the stack. class context : private noncopyable { public: // Push the key on to the stack. explicit context(Key* k) : key_(k), next_(call_stack::top_) { value_ = reinterpret_cast(this); call_stack::top_ = this; } // Push the key/value pair on to the stack. context(Key* k, Value& v) : key_(k), value_(&v), next_(call_stack::top_) { call_stack::top_ = this; } // Pop the key/value pair from the stack. ~context() { call_stack::top_ = next_; } // Find the next context with the same key. Value* next_by_key() const { context* elem = next_; while (elem) { if (elem->key_ == key_) return elem->value_; elem = elem->next_; } return 0; } private: friend class call_stack; // The key associated with the context. Key* key_; // The value associated with the context. Value* value_; // The next element in the stack. context* next_; }; friend class context; // Determine whether the specified owner is on the stack. Returns address of // key if present, 0 otherwise. static Value* contains(Key* k) { context* elem = top_; while (elem) { if (elem->key_ == k) return elem->value_; elem = elem->next_; } return 0; } // Obtain the value at the top of the stack. static Value* top() { context* elem = top_; return elem ? elem->value_ : 0; } private: // The top of the stack of calls for the current thread. static tss_ptr top_; }; template tss_ptr::context> call_stack::top_; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_CALL_STACK_HPP ================================================ FILE: src/third_party/asio/detail/chrono.hpp ================================================ // // detail/chrono.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CHRONO_HPP #define ASIO_DETAIL_CHRONO_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_CHRONO) # include #elif defined(ASIO_HAS_BOOST_CHRONO) # include #endif // defined(ASIO_HAS_BOOST_CHRONO) namespace asio { namespace chrono { #if defined(ASIO_HAS_STD_CHRONO) using std::chrono::duration; using std::chrono::time_point; using std::chrono::duration_cast; using std::chrono::nanoseconds; using std::chrono::microseconds; using std::chrono::milliseconds; using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; using std::chrono::time_point_cast; #if defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) typedef std::chrono::monotonic_clock steady_clock; #else // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) using std::chrono::steady_clock; #endif // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) using std::chrono::system_clock; using std::chrono::high_resolution_clock; #elif defined(ASIO_HAS_BOOST_CHRONO) using boost::chrono::duration; using boost::chrono::time_point; using boost::chrono::duration_cast; using boost::chrono::nanoseconds; using boost::chrono::microseconds; using boost::chrono::milliseconds; using boost::chrono::seconds; using boost::chrono::minutes; using boost::chrono::hours; using boost::chrono::time_point_cast; using boost::chrono::system_clock; using boost::chrono::steady_clock; using boost::chrono::high_resolution_clock; #endif // defined(ASIO_HAS_BOOST_CHRONO) } // namespace chrono } // namespace asio #endif // ASIO_DETAIL_CHRONO_HPP ================================================ FILE: src/third_party/asio/detail/chrono_time_traits.hpp ================================================ // // detail/chrono_time_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP #define ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/cstdint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Helper template to compute the greatest common divisor. template struct gcd { enum { value = gcd::value }; }; template struct gcd { enum { value = v1 }; }; // Adapts std::chrono clocks for use with a deadline timer. template struct chrono_time_traits { // The clock type. typedef Clock clock_type; // The duration type of the clock. typedef typename clock_type::duration duration_type; // The time point type of the clock. typedef typename clock_type::time_point time_type; // The period of the clock. typedef typename duration_type::period period_type; // Get the current time. static time_type now() { return clock_type::now(); } // Add a duration to a time. static time_type add(const time_type& t, const duration_type& d) { const time_type epoch; if (t >= epoch) { if ((time_type::max)() - t < d) return (time_type::max)(); } else // t < epoch { if (-(t - (time_type::min)()) > d) return (time_type::min)(); } return t + d; } // Subtract one time from another. static duration_type subtract(const time_type& t1, const time_type& t2) { const time_type epoch; if (t1 >= epoch) { if (t2 >= epoch) { return t1 - t2; } else if (t2 == (time_type::min)()) { return (duration_type::max)(); } else if ((time_type::max)() - t1 < epoch - t2) { return (duration_type::max)(); } else { return t1 - t2; } } else // t1 < epoch { if (t2 < epoch) { return t1 - t2; } else if (t1 == (time_type::min)()) { return (duration_type::min)(); } else if ((time_type::max)() - t2 < epoch - t1) { return (duration_type::min)(); } else { return -(t2 - t1); } } } // Test whether one time is less than another. static bool less_than(const time_type& t1, const time_type& t2) { return t1 < t2; } // Implement just enough of the posix_time::time_duration interface to supply // what the timer_queue requires. class posix_time_duration { public: explicit posix_time_duration(const duration_type& d) : d_(d) { } int64_t ticks() const { return d_.count(); } int64_t total_seconds() const { return duration_cast<1, 1>(); } int64_t total_milliseconds() const { return duration_cast<1, 1000>(); } int64_t total_microseconds() const { return duration_cast<1, 1000000>(); } private: template int64_t duration_cast() const { const int64_t num1 = period_type::num / gcd::value; const int64_t num2 = Num / gcd::value; const int64_t den1 = period_type::den / gcd::value; const int64_t den2 = Den / gcd::value; const int64_t num = num1 * den2; const int64_t den = num2 * den1; if (num == 1 && den == 1) return ticks(); else if (num != 1 && den == 1) return ticks() * num; else if (num == 1 && period_type::den != 1) return ticks() / den; else return ticks() * num / den; } duration_type d_; }; // Convert to POSIX duration type. static posix_time_duration to_posix_duration(const duration_type& d) { return posix_time_duration(WaitTraits::to_wait_duration(d)); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP ================================================ FILE: src/third_party/asio/detail/completion_handler.hpp ================================================ // // detail/completion_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_COMPLETION_HANDLER_HPP #define ASIO_DETAIL_COMPLETION_HANDLER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class completion_handler : public operation { public: ASIO_DEFINE_HANDLER_PTR(completion_handler); completion_handler(Handler& h) : operation(&completion_handler::do_complete), handler_(ASIO_MOVE_CAST(Handler)(h)) { handler_work::start(handler_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. completion_handler* h(static_cast(base)); ptr p = { asio::detail::addressof(h->handler_), h, h }; handler_work w(h->handler_); ASIO_HANDLER_COMPLETION((*h)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. Handler handler(ASIO_MOVE_CAST(Handler)(h->handler_)); p.h = asio::detail::addressof(handler); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN(()); w.complete(handler, handler); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_COMPLETION_HANDLER_HPP ================================================ FILE: src/third_party/asio/detail/concurrency_hint.hpp ================================================ // // detail/concurrency_hint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CONCURRENCY_HINT_HPP #define ASIO_DETAIL_CONCURRENCY_HINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" // The concurrency hint ID and mask are used to identify when a "well-known" // concurrency hint value has been passed to the io_context. #define ASIO_CONCURRENCY_HINT_ID 0xA5100000u #define ASIO_CONCURRENCY_HINT_ID_MASK 0xFFFF0000u // If set, this bit indicates that the scheduler should perform locking. #define ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER 0x1u // If set, this bit indicates that the reactor should perform locking when // managing descriptor registrations. #define ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION 0x2u // If set, this bit indicates that the reactor should perform locking for I/O. #define ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO 0x4u // Helper macro to determine if we have a special concurrency hint. #define ASIO_CONCURRENCY_HINT_IS_SPECIAL(hint) \ ((static_cast(hint) \ & ASIO_CONCURRENCY_HINT_ID_MASK) \ == ASIO_CONCURRENCY_HINT_ID) // Helper macro to determine if locking is enabled for a given facility. #define ASIO_CONCURRENCY_HINT_IS_LOCKING(facility, hint) \ (((static_cast(hint) \ & (ASIO_CONCURRENCY_HINT_ID_MASK \ | ASIO_CONCURRENCY_HINT_LOCKING_ ## facility)) \ ^ ASIO_CONCURRENCY_HINT_ID) != 0) // This special concurrency hint disables locking in both the scheduler and // reactor I/O. This hint has the following restrictions: // // - Care must be taken to ensure that all operations on the io_context and any // of its associated I/O objects (such as sockets and timers) occur in only // one thread at a time. // // - Asynchronous resolve operations fail with operation_not_supported. // // - If a signal_set is used with the io_context, signal_set objects cannot be // used with any other io_context in the program. #define ASIO_CONCURRENCY_HINT_UNSAFE \ static_cast(ASIO_CONCURRENCY_HINT_ID) // This special concurrency hint disables locking in the reactor I/O. This hint // has the following restrictions: // // - Care must be taken to ensure that run functions on the io_context, and all // operations on the io_context's associated I/O objects (such as sockets and // timers), occur in only one thread at a time. #define ASIO_CONCURRENCY_HINT_UNSAFE_IO \ static_cast(ASIO_CONCURRENCY_HINT_ID \ | ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \ | ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION) // The special concurrency hint provides full thread safety. #define ASIO_CONCURRENCY_HINT_SAFE \ static_cast(ASIO_CONCURRENCY_HINT_ID \ | ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \ | ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION \ | ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO) // This #define may be overridden at compile time to specify a program-wide // default concurrency hint, used by the zero-argument io_context constructor. #if !defined(ASIO_CONCURRENCY_HINT_DEFAULT) # define ASIO_CONCURRENCY_HINT_DEFAULT -1 #endif // !defined(ASIO_CONCURRENCY_HINT_DEFAULT) // This #define may be overridden at compile time to specify a program-wide // concurrency hint, used by the one-argument io_context constructor when // passed a value of 1. #if !defined(ASIO_CONCURRENCY_HINT_1) # define ASIO_CONCURRENCY_HINT_1 1 #endif // !defined(ASIO_CONCURRENCY_HINT_DEFAULT) #endif // ASIO_DETAIL_CONCURRENCY_HINT_HPP ================================================ FILE: src/third_party/asio/detail/conditionally_enabled_event.hpp ================================================ // // detail/conditionally_enabled_event.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP #define ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/conditionally_enabled_mutex.hpp" #include "asio/detail/event.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/null_event.hpp" #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Mutex adapter used to conditionally enable or disable locking. class conditionally_enabled_event : private noncopyable { public: // Constructor. conditionally_enabled_event() { } // Destructor. ~conditionally_enabled_event() { } // Signal the event. (Retained for backward compatibility.) void signal(conditionally_enabled_mutex::scoped_lock& lock) { if (lock.mutex_.enabled_) event_.signal(lock); } // Signal all waiters. void signal_all(conditionally_enabled_mutex::scoped_lock& lock) { if (lock.mutex_.enabled_) event_.signal_all(lock); } // Unlock the mutex and signal one waiter. void unlock_and_signal_one( conditionally_enabled_mutex::scoped_lock& lock) { if (lock.mutex_.enabled_) event_.unlock_and_signal_one(lock); } // If there's a waiter, unlock the mutex and signal it. bool maybe_unlock_and_signal_one( conditionally_enabled_mutex::scoped_lock& lock) { if (lock.mutex_.enabled_) return event_.maybe_unlock_and_signal_one(lock); else return false; } // Reset the event. void clear(conditionally_enabled_mutex::scoped_lock& lock) { if (lock.mutex_.enabled_) event_.clear(lock); } // Wait for the event to become signalled. void wait(conditionally_enabled_mutex::scoped_lock& lock) { if (lock.mutex_.enabled_) event_.wait(lock); else null_event().wait(lock); } // Timed wait for the event to become signalled. bool wait_for_usec( conditionally_enabled_mutex::scoped_lock& lock, long usec) { if (lock.mutex_.enabled_) return event_.wait_for_usec(lock, usec); else return null_event().wait_for_usec(lock, usec); } private: asio::detail::event event_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP ================================================ FILE: src/third_party/asio/detail/conditionally_enabled_mutex.hpp ================================================ // // detail/conditionally_enabled_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP #define ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Mutex adapter used to conditionally enable or disable locking. class conditionally_enabled_mutex : private noncopyable { public: // Helper class to lock and unlock a mutex automatically. class scoped_lock : private noncopyable { public: // Tag type used to distinguish constructors. enum adopt_lock_t { adopt_lock }; // Constructor adopts a lock that is already held. scoped_lock(conditionally_enabled_mutex& m, adopt_lock_t) : mutex_(m), locked_(m.enabled_) { } // Constructor acquires the lock. explicit scoped_lock(conditionally_enabled_mutex& m) : mutex_(m) { if (m.enabled_) { mutex_.mutex_.lock(); locked_ = true; } else locked_ = false; } // Destructor releases the lock. ~scoped_lock() { if (locked_) mutex_.mutex_.unlock(); } // Explicitly acquire the lock. void lock() { if (mutex_.enabled_ && !locked_) { mutex_.mutex_.lock(); locked_ = true; } } // Explicitly release the lock. void unlock() { if (locked_) { mutex_.unlock(); locked_ = false; } } // Test whether the lock is held. bool locked() const { return locked_; } // Get the underlying mutex. asio::detail::mutex& mutex() { return mutex_.mutex_; } private: friend class conditionally_enabled_event; conditionally_enabled_mutex& mutex_; bool locked_; }; // Constructor. explicit conditionally_enabled_mutex(bool enabled) : enabled_(enabled) { } // Destructor. ~conditionally_enabled_mutex() { } // Determine whether locking is enabled. bool enabled() const { return enabled_; } // Lock the mutex. void lock() { if (enabled_) mutex_.lock(); } // Unlock the mutex. void unlock() { if (enabled_) mutex_.unlock(); } private: friend class scoped_lock; friend class conditionally_enabled_event; asio::detail::mutex mutex_; const bool enabled_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/config.hpp ================================================ // // detail/config.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CONFIG_HPP #define ASIO_DETAIL_CONFIG_HPP // boostify: non-boost code starts here #if !defined(ASIO_STANDALONE) # if !defined(ASIO_ENABLE_BOOST) # if (__cplusplus >= 201103) # define ASIO_STANDALONE 1 # elif defined(_MSC_VER) && defined(_MSVC_LANG) # if (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103) # define ASIO_STANDALONE 1 # endif // (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103) # endif // defined(_MSC_VER) && defined(_MSVC_LANG) # endif // !defined(ASIO_ENABLE_BOOST) #endif // !defined(ASIO_STANDALONE) // boostify: non-boost code ends here #if defined(ASIO_STANDALONE) # define ASIO_DISABLE_BOOST_ARRAY 1 # define ASIO_DISABLE_BOOST_ASSERT 1 # define ASIO_DISABLE_BOOST_BIND 1 # define ASIO_DISABLE_BOOST_CHRONO 1 # define ASIO_DISABLE_BOOST_DATE_TIME 1 # define ASIO_DISABLE_BOOST_LIMITS 1 # define ASIO_DISABLE_BOOST_REGEX 1 # define ASIO_DISABLE_BOOST_STATIC_CONSTANT 1 # define ASIO_DISABLE_BOOST_THROW_EXCEPTION 1 # define ASIO_DISABLE_BOOST_WORKAROUND 1 #else // defined(ASIO_STANDALONE) # include # include # define ASIO_HAS_BOOST_CONFIG 1 #endif // defined(ASIO_STANDALONE) // Default to a header-only implementation. The user must specifically request // separate compilation by defining either ASIO_SEPARATE_COMPILATION or // ASIO_DYN_LINK (as a DLL/shared library implies separate compilation). #if !defined(ASIO_HEADER_ONLY) # if !defined(ASIO_SEPARATE_COMPILATION) # if !defined(ASIO_DYN_LINK) # define ASIO_HEADER_ONLY 1 # endif // !defined(ASIO_DYN_LINK) # endif // !defined(ASIO_SEPARATE_COMPILATION) #endif // !defined(ASIO_HEADER_ONLY) #if defined(ASIO_HEADER_ONLY) # define ASIO_DECL inline #else // defined(ASIO_HEADER_ONLY) # if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__) // We need to import/export our code only if the user has specifically asked // for it by defining ASIO_DYN_LINK. # if defined(ASIO_DYN_LINK) // Export if this is our own source, otherwise import. # if defined(ASIO_SOURCE) # define ASIO_DECL __declspec(dllexport) # else // defined(ASIO_SOURCE) # define ASIO_DECL __declspec(dllimport) # endif // defined(ASIO_SOURCE) # endif // defined(ASIO_DYN_LINK) # endif // defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__) #endif // defined(ASIO_HEADER_ONLY) // If ASIO_DECL isn't defined yet define it now. #if !defined(ASIO_DECL) # define ASIO_DECL #endif // !defined(ASIO_DECL) // Microsoft Visual C++ detection. #if !defined(ASIO_MSVC) # if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC) # define ASIO_MSVC BOOST_MSVC # elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \ || (!defined(__MWERKS__) && !defined(__EDG_VERSION__))) # define ASIO_MSVC _MSC_VER # endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC) #endif // !defined(ASIO_MSVC) // Clang / libc++ detection. #if defined(__clang__) # if (__cplusplus >= 201103) # if __has_include(<__config>) # include <__config> # if defined(_LIBCPP_VERSION) # define ASIO_HAS_CLANG_LIBCXX 1 # endif // defined(_LIBCPP_VERSION) # endif // __has_include(<__config>) # endif // (__cplusplus >= 201103) #endif // defined(__clang__) // Android platform detection. #if defined(__ANDROID__) # include #endif // defined(__ANDROID__) // Support move construction and assignment on compilers known to allow it. #if !defined(ASIO_HAS_MOVE) # if !defined(ASIO_DISABLE_MOVE) # if defined(__clang__) # if __has_feature(__cxx_rvalue_references__) # define ASIO_HAS_MOVE 1 # endif // __has_feature(__cxx_rvalue_references__) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_MOVE 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_MOVE 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # if defined(__INTEL_CXX11_MODE__) # if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) # define BOOST_ASIO_HAS_MOVE 1 # endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) # if defined(__ICL) && (__ICL >= 1500) # define BOOST_ASIO_HAS_MOVE 1 # endif // defined(__ICL) && (__ICL >= 1500) # endif // defined(__INTEL_CXX11_MODE__) # endif // !defined(ASIO_DISABLE_MOVE) #endif // !defined(ASIO_HAS_MOVE) // If ASIO_MOVE_CAST isn't defined, and move support is available, define // * ASIO_MOVE_ARG, // * ASIO_NONDEDUCED_MOVE_ARG, and // * ASIO_MOVE_CAST // to take advantage of rvalue references and perfect forwarding. #if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST) # define ASIO_MOVE_ARG(type) type&& # define ASIO_MOVE_ARG2(type1, type2) type1, type2&& # define ASIO_NONDEDUCED_MOVE_ARG(type) type& # define ASIO_MOVE_CAST(type) static_cast # define ASIO_MOVE_CAST2(type1, type2) static_cast #endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST) // If ASIO_MOVE_CAST still isn't defined, default to a C++03-compatible // implementation. Note that older g++ and MSVC versions don't like it when you // pass a non-member function through a const reference, so for most compilers // we'll play it safe and stick with the old approach of passing the handler by // value. #if !defined(ASIO_MOVE_CAST) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4) # define ASIO_MOVE_ARG(type) const type& # else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4) # define ASIO_MOVE_ARG(type) type # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4) # elif defined(ASIO_MSVC) # if (_MSC_VER >= 1400) # define ASIO_MOVE_ARG(type) const type& # else // (_MSC_VER >= 1400) # define ASIO_MOVE_ARG(type) type # endif // (_MSC_VER >= 1400) # else # define ASIO_MOVE_ARG(type) type # endif # define ASIO_NONDEDUCED_MOVE_ARG(type) const type& # define ASIO_MOVE_CAST(type) static_cast # define ASIO_MOVE_CAST2(type1, type2) static_cast #endif // !defined(ASIO_MOVE_CAST) // Support variadic templates on compilers known to allow it. #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) # if !defined(ASIO_DISABLE_VARIADIC_TEMPLATES) # if defined(__clang__) # if __has_feature(__cxx_variadic_templates__) # define ASIO_HAS_VARIADIC_TEMPLATES 1 # endif // __has_feature(__cxx_variadic_templates__) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_VARIADIC_TEMPLATES 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1900) # define ASIO_HAS_VARIADIC_TEMPLATES 1 # endif // (_MSC_VER >= 1900) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_VARIADIC_TEMPLATES) #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) // Support deleted functions on compilers known to allow it. #if !defined(ASIO_DELETED) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_DELETED = delete # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(__clang__) # if __has_feature(__cxx_deleted_functions__) # define ASIO_DELETED = delete # endif // __has_feature(__cxx_deleted_functions__) # endif // defined(__clang__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1900) # define ASIO_DELETED = delete # endif // (_MSC_VER >= 1900) # endif // defined(ASIO_MSVC) # if !defined(ASIO_DELETED) # define ASIO_DELETED # endif // !defined(ASIO_DELETED) #endif // !defined(ASIO_DELETED) // Support constexpr on compilers known to allow it. #if !defined(ASIO_HAS_CONSTEXPR) # if !defined(ASIO_DISABLE_CONSTEXPR) # if defined(__clang__) # if __has_feature(__cxx_constexpr__) # define ASIO_HAS_CONSTEXPR 1 # endif // __has_feature(__cxx_constexr__) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_CONSTEXPR 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1900) # define ASIO_HAS_CONSTEXPR 1 # endif // (_MSC_VER >= 1900) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_CONSTEXPR) #endif // !defined(ASIO_HAS_CONSTEXPR) #if !defined(ASIO_CONSTEXPR) # if defined(ASIO_HAS_CONSTEXPR) # define ASIO_CONSTEXPR constexpr # else // defined(ASIO_HAS_CONSTEXPR) # define ASIO_CONSTEXPR # endif // defined(ASIO_HAS_CONSTEXPR) #endif // !defined(ASIO_CONSTEXPR) // Support noexcept on compilers known to allow it. #if !defined(ASIO_NOEXCEPT) # if !defined(ASIO_DISABLE_NOEXCEPT) # if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300) # define ASIO_NOEXCEPT BOOST_NOEXCEPT # define ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW # elif defined(__clang__) # if __has_feature(__cxx_noexcept__) # define ASIO_NOEXCEPT noexcept(true) # define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true) # endif // __has_feature(__cxx_noexcept__) # elif defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_NOEXCEPT noexcept(true) # define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true) # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # elif defined(ASIO_MSVC) # if (_MSC_VER >= 1900) # define ASIO_NOEXCEPT noexcept(true) # define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true) # endif // (_MSC_VER >= 1900) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_NOEXCEPT) # if !defined(ASIO_NOEXCEPT) # define ASIO_NOEXCEPT # endif // !defined(ASIO_NOEXCEPT) # if !defined(ASIO_NOEXCEPT_OR_NOTHROW) # define ASIO_NOEXCEPT_OR_NOTHROW throw() # endif // !defined(ASIO_NOEXCEPT_OR_NOTHROW) #endif // !defined(ASIO_NOEXCEPT) // Support automatic type deduction on compilers known to support it. #if !defined(ASIO_HAS_DECLTYPE) # if !defined(ASIO_DISABLE_DECLTYPE) # if defined(__clang__) # if __has_feature(__cxx_decltype__) # define ASIO_HAS_DECLTYPE 1 # endif // __has_feature(__cxx_decltype__) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_DECLTYPE 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1800) # define ASIO_HAS_DECLTYPE 1 # endif // (_MSC_VER >= 1800) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_DECLTYPE) #endif // !defined(ASIO_HAS_DECLTYPE) // Support alias templates on compilers known to allow it. #if !defined(ASIO_HAS_ALIAS_TEMPLATES) # if !defined(ASIO_DISABLE_ALIAS_TEMPLATES) # if defined(__clang__) # if __has_feature(__cxx_alias_templates__) # define ASIO_HAS_ALIAS_TEMPLATES 1 # endif // __has_feature(__cxx_alias_templates__) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_ALIAS_TEMPLATES 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1900) # define ASIO_HAS_ALIAS_TEMPLATES 1 # endif // (_MSC_VER >= 1900) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_ALIAS_TEMPLATES) #endif // !defined(ASIO_HAS_ALIAS_TEMPLATES) // Support return type deduction on compilers known to allow it. #if !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION) # if !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION) # if defined(__clang__) # if __has_feature(__cxx_return_type_deduction__) # define ASIO_HAS_RETURN_TYPE_DEDUCTION 1 # endif // __has_feature(__cxx_alias_templates__) # elif (__cplusplus >= 201402) # define ASIO_HAS_RETURN_TYPE_DEDUCTION 1 # endif // (__cplusplus >= 201402) # endif // !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION) #endif // !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION) // Support default function template arguments on compilers known to allow it. #if !defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) # if !defined(ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) # if (__cplusplus >= 201103) # define ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1 # endif // (__cplusplus >= 201103) # endif // !defined(ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) #endif // !defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) // Support concepts on compilers known to allow them. #if !defined(ASIO_HAS_CONCEPTS) # if !defined(ASIO_DISABLE_CONCEPTS) # if __cpp_concepts # define ASIO_HAS_CONCEPTS 1 # define ASIO_CONCEPT concept bool # endif // __cpp_concepts # endif // !defined(ASIO_DISABLE_CONCEPTS) #endif // !defined(ASIO_HAS_CONCEPTS) // Standard library support for system errors. #if !defined(ASIO_HAS_STD_SYSTEM_ERROR) # if !defined(ASIO_DISABLE_STD_SYSTEM_ERROR) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_SYSTEM_ERROR 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_SYSTEM_ERROR 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_SYSTEM_ERROR 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_SYSTEM_ERROR 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_SYSTEM_ERROR) #endif // !defined(ASIO_HAS_STD_SYSTEM_ERROR) // Compliant C++11 compilers put noexcept specifiers on error_category members. #if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) # if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300) # define ASIO_ERROR_CATEGORY_NOEXCEPT BOOST_NOEXCEPT # elif defined(__clang__) # if __has_feature(__cxx_noexcept__) # define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true) # endif // __has_feature(__cxx_noexcept__) # elif defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true) # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # elif defined(ASIO_MSVC) # if (_MSC_VER >= 1900) # define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true) # endif // (_MSC_VER >= 1900) # endif // defined(ASIO_MSVC) # if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) # define ASIO_ERROR_CATEGORY_NOEXCEPT # endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) #endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT) // Standard library support for arrays. #if !defined(ASIO_HAS_STD_ARRAY) # if !defined(ASIO_DISABLE_STD_ARRAY) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_ARRAY 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_ARRAY 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_ARRAY 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1600) # define ASIO_HAS_STD_ARRAY 1 # endif // (_MSC_VER >= 1600) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_ARRAY) #endif // !defined(ASIO_HAS_STD_ARRAY) // Standard library support for shared_ptr and weak_ptr. #if !defined(ASIO_HAS_STD_SHARED_PTR) # if !defined(ASIO_DISABLE_STD_SHARED_PTR) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_SHARED_PTR 1 # elif (__cplusplus >= 201103) # define ASIO_HAS_STD_SHARED_PTR 1 # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_SHARED_PTR 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1600) # define ASIO_HAS_STD_SHARED_PTR 1 # endif // (_MSC_VER >= 1600) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_SHARED_PTR) #endif // !defined(ASIO_HAS_STD_SHARED_PTR) // Standard library support for allocator_arg_t. #if !defined(ASIO_HAS_STD_ALLOCATOR_ARG) # if !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_ALLOCATOR_ARG 1 # elif (__cplusplus >= 201103) # define ASIO_HAS_STD_ALLOCATOR_ARG 1 # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_ALLOCATOR_ARG 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1600) # define ASIO_HAS_STD_ALLOCATOR_ARG 1 # endif // (_MSC_VER >= 1600) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG) #endif // !defined(ASIO_HAS_STD_ALLOCATOR_ARG) // Standard library support for atomic operations. #if !defined(ASIO_HAS_STD_ATOMIC) # if !defined(ASIO_DISABLE_STD_ATOMIC) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_ATOMIC 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_ATOMIC 1 # endif // __has_include() # elif defined(__apple_build_version__) && defined(_LIBCPP_VERSION) # if (__clang_major__ >= 10) # if __has_include() # define ASIO_HAS_STD_ATOMIC 1 # endif // __has_include() # endif // (__clang_major__ >= 10) # endif /// defined(__apple_build_version__) && defined(_LIBCPP_VERSION) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_ATOMIC 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_ATOMIC 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_ATOMIC) #endif // !defined(ASIO_HAS_STD_ATOMIC) // Standard library support for chrono. Some standard libraries (such as the // libstdc++ shipped with gcc 4.6) provide monotonic_clock as per early C++0x // drafts, rather than the eventually standardised name of steady_clock. #if !defined(ASIO_HAS_STD_CHRONO) # if !defined(ASIO_DISABLE_STD_CHRONO) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_CHRONO 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_CHRONO 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_CHRONO 1 # if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6)) # define ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK 1 # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6)) # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_CHRONO 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_CHRONO) #endif // !defined(ASIO_HAS_STD_CHRONO) // Boost support for chrono. #if !defined(ASIO_HAS_BOOST_CHRONO) # if !defined(ASIO_DISABLE_BOOST_CHRONO) # if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700) # define ASIO_HAS_BOOST_CHRONO 1 # endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700) # endif // !defined(ASIO_DISABLE_BOOST_CHRONO) #endif // !defined(ASIO_HAS_BOOST_CHRONO) // Some form of chrono library is available. #if !defined(ASIO_HAS_CHRONO) # if defined(ASIO_HAS_STD_CHRONO) \ || defined(ASIO_HAS_BOOST_CHRONO) # define ASIO_HAS_CHRONO 1 # endif // defined(ASIO_HAS_STD_CHRONO) // || defined(ASIO_HAS_BOOST_CHRONO) #endif // !defined(ASIO_HAS_CHRONO) // Boost support for the DateTime library. #if !defined(ASIO_HAS_BOOST_DATE_TIME) # if !defined(ASIO_DISABLE_BOOST_DATE_TIME) # define ASIO_HAS_BOOST_DATE_TIME 1 # endif // !defined(ASIO_DISABLE_BOOST_DATE_TIME) #endif // !defined(ASIO_HAS_BOOST_DATE_TIME) // Standard library support for addressof. #if !defined(ASIO_HAS_STD_ADDRESSOF) # if !defined(ASIO_DISABLE_STD_ADDRESSOF) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_ADDRESSOF 1 # elif (__cplusplus >= 201103) # define ASIO_HAS_STD_ADDRESSOF 1 # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_ADDRESSOF 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_ADDRESSOF 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_ADDRESSOF) #endif // !defined(ASIO_HAS_STD_ADDRESSOF) // Standard library support for the function class. #if !defined(ASIO_HAS_STD_FUNCTION) # if !defined(ASIO_DISABLE_STD_FUNCTION) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_FUNCTION 1 # elif (__cplusplus >= 201103) # define ASIO_HAS_STD_FUNCTION 1 # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_FUNCTION 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_FUNCTION 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_FUNCTION) #endif // !defined(ASIO_HAS_STD_FUNCTION) // Standard library support for type traits. #if !defined(ASIO_HAS_STD_TYPE_TRAITS) # if !defined(ASIO_DISABLE_STD_TYPE_TRAITS) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_TYPE_TRAITS 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_TYPE_TRAITS 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_TYPE_TRAITS 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_TYPE_TRAITS 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_TYPE_TRAITS) #endif // !defined(ASIO_HAS_STD_TYPE_TRAITS) // Standard library support for the nullptr_t type. #if !defined(ASIO_HAS_NULLPTR) # if !defined(ASIO_DISABLE_NULLPTR) # if defined(__clang__) # if __has_feature(__cxx_nullptr__) # define ASIO_HAS_NULLPTR 1 # endif // __has_feature(__cxx_rvalue_references__) # elif defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_NULLPTR 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_NULLPTR 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_NULLPTR) #endif // !defined(ASIO_HAS_NULLPTR) // Standard library support for the C++11 allocator additions. #if !defined(ASIO_HAS_CXX11_ALLOCATORS) # if !defined(ASIO_DISABLE_CXX11_ALLOCATORS) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_CXX11_ALLOCATORS 1 # elif (__cplusplus >= 201103) # define ASIO_HAS_CXX11_ALLOCATORS 1 # endif // (__cplusplus >= 201103) # elif defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_CXX11_ALLOCATORS 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1800) # define ASIO_HAS_CXX11_ALLOCATORS 1 # endif // (_MSC_VER >= 1800) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_CXX11_ALLOCATORS) #endif // !defined(ASIO_HAS_CXX11_ALLOCATORS) // Standard library support for the cstdint header. #if !defined(ASIO_HAS_CSTDINT) # if !defined(ASIO_DISABLE_CSTDINT) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_CSTDINT 1 # elif (__cplusplus >= 201103) # define ASIO_HAS_CSTDINT 1 # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_CSTDINT 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_CSTDINT 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_CSTDINT) #endif // !defined(ASIO_HAS_CSTDINT) // Standard library support for the thread class. #if !defined(ASIO_HAS_STD_THREAD) # if !defined(ASIO_DISABLE_STD_THREAD) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_THREAD 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_THREAD 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_THREAD 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_THREAD 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_THREAD) #endif // !defined(ASIO_HAS_STD_THREAD) // Standard library support for the mutex and condition variable classes. #if !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # if !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR) #endif // !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) // Standard library support for the call_once function. #if !defined(ASIO_HAS_STD_CALL_ONCE) # if !defined(ASIO_DISABLE_STD_CALL_ONCE) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_CALL_ONCE 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_CALL_ONCE 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_CALL_ONCE 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_CALL_ONCE 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_CALL_ONCE) #endif // !defined(ASIO_HAS_STD_CALL_ONCE) // Standard library support for futures. #if !defined(ASIO_HAS_STD_FUTURE) # if !defined(ASIO_DISABLE_STD_FUTURE) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_FUTURE 1 # elif (__cplusplus >= 201103) # if __has_include() # define ASIO_HAS_STD_FUTURE 1 # endif // __has_include() # endif // (__cplusplus >= 201103) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_FUTURE 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_FUTURE 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_FUTURE) #endif // !defined(ASIO_HAS_STD_FUTURE) // Standard library support for std::string_view. #if !defined(ASIO_HAS_STD_STRING_VIEW) # if !defined(ASIO_DISABLE_STD_STRING_VIEW) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # if (__cplusplus >= 201402) # if __has_include() # define ASIO_HAS_STD_STRING_VIEW 1 # endif // __has_include() # endif // (__cplusplus >= 201402) # else // defined(ASIO_HAS_CLANG_LIBCXX) # if (__cplusplus >= 201703) # if __has_include() # define ASIO_HAS_STD_STRING_VIEW 1 # endif // __has_include() # endif // (__cplusplus >= 201703) # endif // defined(ASIO_HAS_CLANG_LIBCXX) # elif defined(__GNUC__) # if (__GNUC__ >= 7) # if (__cplusplus >= 201703) # define ASIO_HAS_STD_STRING_VIEW 1 # endif // (__cplusplus >= 201703) # endif // (__GNUC__ >= 7) # elif defined(ASIO_MSVC) # if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) # define ASIO_HAS_STD_STRING_VIEW 1 # endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_STRING_VIEW) #endif // !defined(ASIO_HAS_STD_STRING_VIEW) // Standard library support for std::experimental::string_view. #if !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) # if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) # if defined(__clang__) # if defined(ASIO_HAS_CLANG_LIBCXX) # if (_LIBCPP_VERSION < 7000) # if (__cplusplus >= 201402) # if __has_include() # define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1 # endif // __has_include() # endif // (__cplusplus >= 201402) # endif // (_LIBCPP_VERSION < 7000) # else // defined(ASIO_HAS_CLANG_LIBCXX) # if (__cplusplus >= 201402) # if __has_include() # define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1 # endif // __has_include() # endif // (__cplusplus >= 201402) # endif // // defined(ASIO_HAS_CLANG_LIBCXX) # endif // defined(__clang__) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4) # if (__cplusplus >= 201402) # define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1 # endif // (__cplusplus >= 201402) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) #endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) // Standard library has a string_view that we can use. #if !defined(ASIO_HAS_STRING_VIEW) # if !defined(ASIO_DISABLE_STRING_VIEW) # if defined(ASIO_HAS_STD_STRING_VIEW) # define ASIO_HAS_STRING_VIEW 1 # elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) # define ASIO_HAS_STRING_VIEW 1 # endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) # endif // !defined(ASIO_DISABLE_STRING_VIEW) #endif // !defined(ASIO_HAS_STRING_VIEW) // Standard library support for iostream move construction and assignment. #if !defined(ASIO_HAS_STD_IOSTREAM_MOVE) # if !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE) # if defined(__GNUC__) # if (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_HAS_STD_IOSTREAM_MOVE 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1700) # define ASIO_HAS_STD_IOSTREAM_MOVE 1 # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE) #endif // !defined(ASIO_HAS_STD_IOSTREAM_MOVE) // Standard library has invoke_result (which supersedes result_of). #if !defined(ASIO_HAS_STD_INVOKE_RESULT) # if !defined(ASIO_DISABLE_STD_INVOKE_RESULT) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703) # define ASIO_HAS_STD_INVOKE_RESULT 1 # endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_STD_INVOKE_RESULT) #endif // !defined(ASIO_HAS_STD_INVOKE_RESULT) // Windows App target. Windows but with a limited API. #if !defined(ASIO_WINDOWS_APP) # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603) # include # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \ && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # define ASIO_WINDOWS_APP 1 # endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603) #endif // !defined(ASIO_WINDOWS_APP) // Legacy WinRT target. Windows App is preferred. #if !defined(ASIO_WINDOWS_RUNTIME) # if !defined(ASIO_WINDOWS_APP) # if defined(__cplusplus_winrt) # include # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \ && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # define ASIO_WINDOWS_RUNTIME 1 # endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # endif // defined(__cplusplus_winrt) # endif // !defined(ASIO_WINDOWS_APP) #endif // !defined(ASIO_WINDOWS_RUNTIME) // Windows target. Excludes WinRT but includes Windows App targets. #if !defined(ASIO_WINDOWS) # if !defined(ASIO_WINDOWS_RUNTIME) # if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS) # define ASIO_WINDOWS 1 # elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) # define ASIO_WINDOWS 1 # elif defined(ASIO_WINDOWS_APP) # define ASIO_WINDOWS 1 # endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS) # endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // !defined(ASIO_WINDOWS) // Windows: target OS version. #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) # if defined(_MSC_VER) || defined(__BORLANDC__) # pragma message( \ "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\ "- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\ "- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\ "Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).") # else // defined(_MSC_VER) || defined(__BORLANDC__) # warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. # warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line. # warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target). # endif // defined(_MSC_VER) || defined(__BORLANDC__) # define _WIN32_WINNT 0x0601 # endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) # if defined(_MSC_VER) # if defined(_WIN32) && !defined(WIN32) # if !defined(_WINSOCK2API_) # define WIN32 // Needed for correct types in winsock2.h # else // !defined(_WINSOCK2API_) # error Please define the macro WIN32 in your compiler options # endif // !defined(_WINSOCK2API_) # endif // defined(_WIN32) && !defined(WIN32) # endif // defined(_MSC_VER) # if defined(__BORLANDC__) # if defined(__WIN32__) && !defined(WIN32) # if !defined(_WINSOCK2API_) # define WIN32 // Needed for correct types in winsock2.h # else // !defined(_WINSOCK2API_) # error Please define the macro WIN32 in your compiler options # endif // !defined(_WINSOCK2API_) # endif // defined(__WIN32__) && !defined(WIN32) # endif // defined(__BORLANDC__) # if defined(__CYGWIN__) # if !defined(__USE_W32_SOCKETS) # error You must add -D__USE_W32_SOCKETS to your compiler options. # endif // !defined(__USE_W32_SOCKETS) # endif // defined(__CYGWIN__) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Windows: minimise header inclusion. #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if !defined(ASIO_NO_WIN32_LEAN_AND_MEAN) # if !defined(WIN32_LEAN_AND_MEAN) # define WIN32_LEAN_AND_MEAN # endif // !defined(WIN32_LEAN_AND_MEAN) # endif // !defined(ASIO_NO_WIN32_LEAN_AND_MEAN) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Windows: suppress definition of "min" and "max" macros. #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if !defined(ASIO_NO_NOMINMAX) # if !defined(NOMINMAX) # define NOMINMAX 1 # endif // !defined(NOMINMAX) # endif // !defined(ASIO_NO_NOMINMAX) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Windows: IO Completion Ports. #if !defined(ASIO_HAS_IOCP) # if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) # if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) # if !defined(ASIO_DISABLE_IOCP) # define ASIO_HAS_IOCP 1 # endif // !defined(ASIO_DISABLE_IOCP) # endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) # endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) # endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #endif // !defined(ASIO_HAS_IOCP) // On POSIX (and POSIX-like) platforms we need to include unistd.h in order to // get access to the various platform feature macros, e.g. to be able to test // for threads support. #if !defined(ASIO_HAS_UNISTD_H) # if !defined(ASIO_HAS_BOOST_CONFIG) # if defined(unix) \ || defined(__unix) \ || defined(_XOPEN_SOURCE) \ || defined(_POSIX_SOURCE) \ || (defined(__MACH__) && defined(__APPLE__)) \ || defined(__FreeBSD__) \ || defined(__NetBSD__) \ || defined(__OpenBSD__) \ || defined(__linux__) \ || defined(__HAIKU__) # define ASIO_HAS_UNISTD_H 1 # endif # endif // !defined(ASIO_HAS_BOOST_CONFIG) #endif // !defined(ASIO_HAS_UNISTD_H) #if defined(ASIO_HAS_UNISTD_H) # include #endif // defined(ASIO_HAS_UNISTD_H) // Linux: epoll, eventfd and timerfd. #if defined(__linux__) # include # if !defined(ASIO_HAS_EPOLL) # if !defined(ASIO_DISABLE_EPOLL) # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) # define ASIO_HAS_EPOLL 1 # endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) # endif // !defined(ASIO_DISABLE_EPOLL) # endif // !defined(ASIO_HAS_EPOLL) # if !defined(ASIO_HAS_EVENTFD) # if !defined(ASIO_DISABLE_EVENTFD) # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) # define ASIO_HAS_EVENTFD 1 # endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) # endif // !defined(ASIO_DISABLE_EVENTFD) # endif // !defined(ASIO_HAS_EVENTFD) # if !defined(ASIO_HAS_TIMERFD) # if defined(ASIO_HAS_EPOLL) # if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) # define ASIO_HAS_TIMERFD 1 # endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) # endif // defined(ASIO_HAS_EPOLL) # endif // !defined(ASIO_HAS_TIMERFD) #endif // defined(__linux__) // Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue. #if (defined(__MACH__) && defined(__APPLE__)) \ || defined(__FreeBSD__) \ || defined(__NetBSD__) \ || defined(__OpenBSD__) # if !defined(ASIO_HAS_KQUEUE) # if !defined(ASIO_DISABLE_KQUEUE) # define ASIO_HAS_KQUEUE 1 # endif // !defined(ASIO_DISABLE_KQUEUE) # endif // !defined(ASIO_HAS_KQUEUE) #endif // (defined(__MACH__) && defined(__APPLE__)) // || defined(__FreeBSD__) // || defined(__NetBSD__) // || defined(__OpenBSD__) // Solaris: /dev/poll. #if defined(__sun) # if !defined(ASIO_HAS_DEV_POLL) # if !defined(ASIO_DISABLE_DEV_POLL) # define ASIO_HAS_DEV_POLL 1 # endif // !defined(ASIO_DISABLE_DEV_POLL) # endif // !defined(ASIO_HAS_DEV_POLL) #endif // defined(__sun) // Serial ports. #if !defined(ASIO_HAS_SERIAL_PORT) # if defined(ASIO_HAS_IOCP) \ || !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) # if !defined(__SYMBIAN32__) # if !defined(ASIO_DISABLE_SERIAL_PORT) # define ASIO_HAS_SERIAL_PORT 1 # endif // !defined(ASIO_DISABLE_SERIAL_PORT) # endif // !defined(__SYMBIAN32__) # endif // defined(ASIO_HAS_IOCP) // || !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) #endif // !defined(ASIO_HAS_SERIAL_PORT) // Windows: stream handles. #if !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) # if !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE) # if defined(ASIO_HAS_IOCP) # define ASIO_HAS_WINDOWS_STREAM_HANDLE 1 # endif // defined(ASIO_HAS_IOCP) # endif // !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE) #endif // !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) // Windows: random access handles. #if !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) # if !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) # if defined(ASIO_HAS_IOCP) # define ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1 # endif // defined(ASIO_HAS_IOCP) # endif // !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) #endif // !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // Windows: object handles. #if !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) # if !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE) # if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) # define ASIO_HAS_WINDOWS_OBJECT_HANDLE 1 # endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP) # endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) # endif // !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE) #endif // !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) // Windows: OVERLAPPED wrapper. #if !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) # if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) # if defined(ASIO_HAS_IOCP) # define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1 # endif // defined(ASIO_HAS_IOCP) # endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) #endif // !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) // POSIX: stream-oriented file descriptors. #if !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) # if !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) # if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) # define ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1 # endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) # endif // !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) #endif // !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // UNIX domain sockets. #if !defined(ASIO_HAS_LOCAL_SOCKETS) # if !defined(ASIO_DISABLE_LOCAL_SOCKETS) # if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) # define ASIO_HAS_LOCAL_SOCKETS 1 # endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) # endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS) #endif // !defined(ASIO_HAS_LOCAL_SOCKETS) // Can use sigaction() instead of signal(). #if !defined(ASIO_HAS_SIGACTION) # if !defined(ASIO_DISABLE_SIGACTION) # if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) # define ASIO_HAS_SIGACTION 1 # endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) # endif // !defined(ASIO_DISABLE_SIGACTION) #endif // !defined(ASIO_HAS_SIGACTION) // Can use signal(). #if !defined(ASIO_HAS_SIGNAL) # if !defined(ASIO_DISABLE_SIGNAL) # if !defined(UNDER_CE) # define ASIO_HAS_SIGNAL 1 # endif // !defined(UNDER_CE) # endif // !defined(ASIO_DISABLE_SIGNAL) #endif // !defined(ASIO_HAS_SIGNAL) // Can use getaddrinfo() and getnameinfo(). #if !defined(ASIO_HAS_GETADDRINFO) # if !defined(ASIO_DISABLE_GETADDRINFO) # if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) # define ASIO_HAS_GETADDRINFO 1 # elif defined(UNDER_CE) # define ASIO_HAS_GETADDRINFO 1 # endif // defined(UNDER_CE) # elif defined(__MACH__) && defined(__APPLE__) # if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) # if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) # define ASIO_HAS_GETADDRINFO 1 # endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) # else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED) # define ASIO_HAS_GETADDRINFO 1 # endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED) # else // defined(__MACH__) && defined(__APPLE__) # define ASIO_HAS_GETADDRINFO 1 # endif // defined(__MACH__) && defined(__APPLE__) # endif // !defined(ASIO_DISABLE_GETADDRINFO) #endif // !defined(ASIO_HAS_GETADDRINFO) // Whether standard iostreams are disabled. #if !defined(ASIO_NO_IOSTREAM) # if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_IOSTREAM) # define ASIO_NO_IOSTREAM 1 # endif // !defined(BOOST_NO_IOSTREAM) #endif // !defined(ASIO_NO_IOSTREAM) // Whether exception handling is disabled. #if !defined(ASIO_NO_EXCEPTIONS) # if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_EXCEPTIONS) # define ASIO_NO_EXCEPTIONS 1 # endif // !defined(BOOST_NO_EXCEPTIONS) #endif // !defined(ASIO_NO_EXCEPTIONS) // Whether the typeid operator is supported. #if !defined(ASIO_NO_TYPEID) # if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_TYPEID) # define ASIO_NO_TYPEID 1 # endif // !defined(BOOST_NO_TYPEID) #endif // !defined(ASIO_NO_TYPEID) // Threads. #if !defined(ASIO_HAS_THREADS) # if !defined(ASIO_DISABLE_THREADS) # if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS) # define ASIO_HAS_THREADS 1 # elif defined(__GNUC__) && !defined(__MINGW32__) \ && !defined(linux) && !defined(__linux) && !defined(__linux__) # define ASIO_HAS_THREADS 1 # elif defined(_MT) || defined(__MT__) # define ASIO_HAS_THREADS 1 # elif defined(_REENTRANT) # define ASIO_HAS_THREADS 1 # elif defined(__APPLE__) # define ASIO_HAS_THREADS 1 # elif defined(__HAIKU__) # define ASIO_HAS_THREADS 1 # elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0) # define ASIO_HAS_THREADS 1 # elif defined(_PTHREADS) # define ASIO_HAS_THREADS 1 # endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS) # endif // !defined(ASIO_DISABLE_THREADS) #endif // !defined(ASIO_HAS_THREADS) // POSIX threads. #if !defined(ASIO_HAS_PTHREADS) # if defined(ASIO_HAS_THREADS) # if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS) # define ASIO_HAS_PTHREADS 1 # elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0) # define ASIO_HAS_PTHREADS 1 # elif defined(__HAIKU__) # define ASIO_HAS_PTHREADS 1 # endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS) # endif // defined(ASIO_HAS_THREADS) #endif // !defined(ASIO_HAS_PTHREADS) // Helper to prevent macro expansion. #define ASIO_PREVENT_MACRO_SUBSTITUTION // Helper to define in-class constants. #if !defined(ASIO_STATIC_CONSTANT) # if !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT) # define ASIO_STATIC_CONSTANT(type, assignment) \ BOOST_STATIC_CONSTANT(type, assignment) # else // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT) # define ASIO_STATIC_CONSTANT(type, assignment) \ static const type assignment # endif // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT) #endif // !defined(ASIO_STATIC_CONSTANT) // Boost array library. #if !defined(ASIO_HAS_BOOST_ARRAY) # if !defined(ASIO_DISABLE_BOOST_ARRAY) # define ASIO_HAS_BOOST_ARRAY 1 # endif // !defined(ASIO_DISABLE_BOOST_ARRAY) #endif // !defined(ASIO_HAS_BOOST_ARRAY) // Boost assert macro. #if !defined(ASIO_HAS_BOOST_ASSERT) # if !defined(ASIO_DISABLE_BOOST_ASSERT) # define ASIO_HAS_BOOST_ASSERT 1 # endif // !defined(ASIO_DISABLE_BOOST_ASSERT) #endif // !defined(ASIO_HAS_BOOST_ASSERT) // Boost limits header. #if !defined(ASIO_HAS_BOOST_LIMITS) # if !defined(ASIO_DISABLE_BOOST_LIMITS) # define ASIO_HAS_BOOST_LIMITS 1 # endif // !defined(ASIO_DISABLE_BOOST_LIMITS) #endif // !defined(ASIO_HAS_BOOST_LIMITS) // Boost throw_exception function. #if !defined(ASIO_HAS_BOOST_THROW_EXCEPTION) # if !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION) # define ASIO_HAS_BOOST_THROW_EXCEPTION 1 # endif // !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION) #endif // !defined(ASIO_HAS_BOOST_THROW_EXCEPTION) // Boost regex library. #if !defined(ASIO_HAS_BOOST_REGEX) # if !defined(ASIO_DISABLE_BOOST_REGEX) # define ASIO_HAS_BOOST_REGEX 1 # endif // !defined(ASIO_DISABLE_BOOST_REGEX) #endif // !defined(ASIO_HAS_BOOST_REGEX) // Boost bind function. #if !defined(ASIO_HAS_BOOST_BIND) # if !defined(ASIO_DISABLE_BOOST_BIND) # define ASIO_HAS_BOOST_BIND 1 # endif // !defined(ASIO_DISABLE_BOOST_BIND) #endif // !defined(ASIO_HAS_BOOST_BIND) // Boost's BOOST_WORKAROUND macro. #if !defined(ASIO_HAS_BOOST_WORKAROUND) # if !defined(ASIO_DISABLE_BOOST_WORKAROUND) # define ASIO_HAS_BOOST_WORKAROUND 1 # endif // !defined(ASIO_DISABLE_BOOST_WORKAROUND) #endif // !defined(ASIO_HAS_BOOST_WORKAROUND) // Microsoft Visual C++'s secure C runtime library. #if !defined(ASIO_HAS_SECURE_RTL) # if !defined(ASIO_DISABLE_SECURE_RTL) # if defined(ASIO_MSVC) \ && (ASIO_MSVC >= 1400) \ && !defined(UNDER_CE) # define ASIO_HAS_SECURE_RTL 1 # endif // defined(ASIO_MSVC) // && (ASIO_MSVC >= 1400) // && !defined(UNDER_CE) # endif // !defined(ASIO_DISABLE_SECURE_RTL) #endif // !defined(ASIO_HAS_SECURE_RTL) // Handler hooking. Disabled for ancient Borland C++ and gcc compilers. #if !defined(ASIO_HAS_HANDLER_HOOKS) # if !defined(ASIO_DISABLE_HANDLER_HOOKS) # if defined(__GNUC__) # if (__GNUC__ >= 3) # define ASIO_HAS_HANDLER_HOOKS 1 # endif // (__GNUC__ >= 3) # elif !defined(__BORLANDC__) # define ASIO_HAS_HANDLER_HOOKS 1 # endif // !defined(__BORLANDC__) # endif // !defined(ASIO_DISABLE_HANDLER_HOOKS) #endif // !defined(ASIO_HAS_HANDLER_HOOKS) // Support for the __thread keyword extension. #if !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION) # if defined(__linux__) # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) # if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3) # if !defined(__INTEL_COMPILER) && !defined(__ICL) \ && !(defined(__clang__) && defined(__ANDROID__)) # define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1 # define ASIO_THREAD_KEYWORD __thread # elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) # define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1 # endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) // && !(defined(__clang__) && defined(__ANDROID__)) # endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3) # endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) # endif // defined(__linux__) # if defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME) # if (_MSC_VER >= 1700) # define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1 # define ASIO_THREAD_KEYWORD __declspec(thread) # endif // (_MSC_VER >= 1700) # endif // defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME) #endif // !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION) #if !defined(ASIO_THREAD_KEYWORD) # define ASIO_THREAD_KEYWORD __thread #endif // !defined(ASIO_THREAD_KEYWORD) // Support for POSIX ssize_t typedef. #if !defined(ASIO_DISABLE_SSIZE_T) # if defined(__linux__) \ || (defined(__MACH__) && defined(__APPLE__)) # define ASIO_HAS_SSIZE_T 1 # endif // defined(__linux__) // || (defined(__MACH__) && defined(__APPLE__)) #endif // !defined(ASIO_DISABLE_SSIZE_T) // Helper macros to manage transition away from error_code return values. #if defined(ASIO_NO_DEPRECATED) # define ASIO_SYNC_OP_VOID void # define ASIO_SYNC_OP_VOID_RETURN(e) return #else // defined(ASIO_NO_DEPRECATED) # define ASIO_SYNC_OP_VOID asio::error_code # define ASIO_SYNC_OP_VOID_RETURN(e) return e #endif // defined(ASIO_NO_DEPRECATED) // Newer gcc, clang need special treatment to suppress unused typedef warnings. #if defined(__clang__) # if defined(__apple_build_version__) # if (__clang_major__ >= 7) # define ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) # endif // (__clang_major__ >= 7) # elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ || (__clang_major__ > 3) # define ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) # endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) // || (__clang_major__ > 3) #elif defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) # define ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) #endif // defined(__GNUC__) #if !defined(ASIO_UNUSED_TYPEDEF) # define ASIO_UNUSED_TYPEDEF #endif // !defined(ASIO_UNUSED_TYPEDEF) // Some versions of gcc generate spurious warnings about unused variables. #if defined(__GNUC__) # if (__GNUC__ >= 4) # define ASIO_UNUSED_VARIABLE __attribute__((__unused__)) # endif // (__GNUC__ >= 4) #endif // defined(__GNUC__) #if !defined(ASIO_UNUSED_VARIABLE) # define ASIO_UNUSED_VARIABLE #endif // !defined(ASIO_UNUSED_VARIABLE) // Support co_await on compilers known to allow it. #if !defined(ASIO_HAS_CO_AWAIT) # if !defined(ASIO_DISABLE_CO_AWAIT) # if defined(ASIO_MSVC) # if (_MSC_FULL_VER >= 190023506) # if defined(_RESUMABLE_FUNCTIONS_SUPPORTED) # define ASIO_HAS_CO_AWAIT 1 # endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED) # endif // (_MSC_FULL_VER >= 190023506) # endif // defined(ASIO_MSVC) # endif // !defined(ASIO_DISABLE_CO_AWAIT) # if defined(__clang__) # if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703) # if __has_include() # define ASIO_HAS_CO_AWAIT 1 # endif // __has_include() # endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703) # endif // defined(__clang__) #endif // !defined(ASIO_HAS_CO_AWAIT) #endif // ASIO_DETAIL_CONFIG_HPP ================================================ FILE: src/third_party/asio/detail/consuming_buffers.hpp ================================================ // // detail/consuming_buffers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CONSUMING_BUFFERS_HPP #define ASIO_DETAIL_CONSUMING_BUFFERS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/buffer.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Helper template to determine the maximum number of prepared buffers. template struct prepared_buffers_max { enum { value = buffer_sequence_adapter_base::max_buffers }; }; template struct prepared_buffers_max > { enum { value = N }; }; #if defined(ASIO_HAS_STD_ARRAY) template struct prepared_buffers_max > { enum { value = N }; }; #endif // defined(ASIO_HAS_STD_ARRAY) // A buffer sequence used to represent a subsequence of the buffers. template struct prepared_buffers { typedef Buffer value_type; typedef const Buffer* const_iterator; enum { max_buffers = MaxBuffers < 16 ? MaxBuffers : 16 }; prepared_buffers() : count(0) {} const_iterator begin() const { return elems; } const_iterator end() const { return elems + count; } Buffer elems[max_buffers]; std::size_t count; }; // A proxy for a sub-range in a list of buffers. template class consuming_buffers { public: typedef prepared_buffers::value> prepared_buffers_type; // Construct to represent the entire list of buffers. explicit consuming_buffers(const Buffers& buffers) : buffers_(buffers), total_consumed_(0), next_elem_(0), next_elem_offset_(0) { using asio::buffer_size; total_size_ = buffer_size(buffers); } // Determine if we are at the end of the buffers. bool empty() const { return total_consumed_ >= total_size_; } // Get the buffer for a single transfer, with a size. prepared_buffers_type prepare(std::size_t max_size) { prepared_buffers_type result; Buffer_Iterator next = asio::buffer_sequence_begin(buffers_); Buffer_Iterator end = asio::buffer_sequence_end(buffers_); std::advance(next, next_elem_); std::size_t elem_offset = next_elem_offset_; while (next != end && max_size > 0 && (result.count) < result.max_buffers) { Buffer next_buf = Buffer(*next) + elem_offset; result.elems[result.count] = asio::buffer(next_buf, max_size); max_size -= result.elems[result.count].size(); elem_offset = 0; if (result.elems[result.count].size() > 0) ++result.count; ++next; } return result; } // Consume the specified number of bytes from the buffers. void consume(std::size_t size) { total_consumed_ += size; Buffer_Iterator next = asio::buffer_sequence_begin(buffers_); Buffer_Iterator end = asio::buffer_sequence_end(buffers_); std::advance(next, next_elem_); while (next != end && size > 0) { Buffer next_buf = Buffer(*next) + next_elem_offset_; if (size < next_buf.size()) { next_elem_offset_ += size; size = 0; } else { size -= next_buf.size(); next_elem_offset_ = 0; ++next_elem_; ++next; } } } // Get the total number of bytes consumed from the buffers. std::size_t total_consumed() const { return total_consumed_; } private: Buffers buffers_; std::size_t total_size_; std::size_t total_consumed_; std::size_t next_elem_; std::size_t next_elem_offset_; }; // Base class of all consuming_buffers specialisations for single buffers. template class consuming_single_buffer { public: // Construct to represent the entire list of buffers. template explicit consuming_single_buffer(const Buffer1& buffer) : buffer_(buffer), total_consumed_(0) { } // Determine if we are at the end of the buffers. bool empty() const { return total_consumed_ >= buffer_.size(); } // Get the buffer for a single transfer, with a size. Buffer prepare(std::size_t max_size) { return asio::buffer(buffer_ + total_consumed_, max_size); } // Consume the specified number of bytes from the buffers. void consume(std::size_t size) { total_consumed_ += size; } // Get the total number of bytes consumed from the buffers. std::size_t total_consumed() const { return total_consumed_; } private: Buffer buffer_; std::size_t total_consumed_; }; template <> class consuming_buffers : public consuming_single_buffer { public: explicit consuming_buffers(const mutable_buffer& buffer) : consuming_single_buffer(buffer) { } }; template <> class consuming_buffers : public consuming_single_buffer { public: explicit consuming_buffers(const mutable_buffer& buffer) : consuming_single_buffer(buffer) { } }; template <> class consuming_buffers : public consuming_single_buffer { public: explicit consuming_buffers(const const_buffer& buffer) : consuming_single_buffer(buffer) { } }; #if !defined(ASIO_NO_DEPRECATED) template <> class consuming_buffers : public consuming_single_buffer { public: explicit consuming_buffers(const mutable_buffers_1& buffer) : consuming_single_buffer(buffer) { } }; template <> class consuming_buffers : public consuming_single_buffer { public: explicit consuming_buffers(const mutable_buffers_1& buffer) : consuming_single_buffer(buffer) { } }; template <> class consuming_buffers : public consuming_single_buffer { public: explicit consuming_buffers(const const_buffers_1& buffer) : consuming_single_buffer(buffer) { } }; #endif // !defined(ASIO_NO_DEPRECATED) template class consuming_buffers, typename boost::array::const_iterator> { public: // Construct to represent the entire list of buffers. explicit consuming_buffers(const boost::array& buffers) : buffers_(buffers), total_consumed_(0) { } // Determine if we are at the end of the buffers. bool empty() const { return total_consumed_ >= Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size(); } // Get the buffer for a single transfer, with a size. boost::array prepare(std::size_t max_size) { boost::array result = {{ Buffer(buffers_[0]), Buffer(buffers_[1]) }}; std::size_t buffer0_size = result[0].size(); result[0] = asio::buffer(result[0] + total_consumed_, max_size); result[1] = asio::buffer( result[1] + (total_consumed_ < buffer0_size ? 0 : total_consumed_ - buffer0_size), max_size - result[0].size()); return result; } // Consume the specified number of bytes from the buffers. void consume(std::size_t size) { total_consumed_ += size; } // Get the total number of bytes consumed from the buffers. std::size_t total_consumed() const { return total_consumed_; } private: boost::array buffers_; std::size_t total_consumed_; }; #if defined(ASIO_HAS_STD_ARRAY) template class consuming_buffers, typename std::array::const_iterator> { public: // Construct to represent the entire list of buffers. explicit consuming_buffers(const std::array& buffers) : buffers_(buffers), total_consumed_(0) { } // Determine if we are at the end of the buffers. bool empty() const { return total_consumed_ >= Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size(); } // Get the buffer for a single transfer, with a size. std::array prepare(std::size_t max_size) { std::array result = {{ Buffer(buffers_[0]), Buffer(buffers_[1]) }}; std::size_t buffer0_size = result[0].size(); result[0] = asio::buffer(result[0] + total_consumed_, max_size); result[1] = asio::buffer( result[1] + (total_consumed_ < buffer0_size ? 0 : total_consumed_ - buffer0_size), max_size - result[0].size()); return result; } // Consume the specified number of bytes from the buffers. void consume(std::size_t size) { total_consumed_ += size; } // Get the total number of bytes consumed from the buffers. std::size_t total_consumed() const { return total_consumed_; } private: std::array buffers_; std::size_t total_consumed_; }; #endif // defined(ASIO_HAS_STD_ARRAY) // Specialisation for null_buffers to ensure that the null_buffers type is // always passed through to the underlying read or write operation. template class consuming_buffers : public asio::null_buffers { public: consuming_buffers(const null_buffers&) { // No-op. } bool empty() { return false; } null_buffers prepare(std::size_t) { return null_buffers(); } void consume(std::size_t) { // No-op. } std::size_t total_consumed() const { return 0; } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_CONSUMING_BUFFERS_HPP ================================================ FILE: src/third_party/asio/detail/cstddef.hpp ================================================ // // detail/cstddef.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CSTDDEF_HPP #define ASIO_DETAIL_CSTDDEF_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include namespace asio { #if defined(ASIO_HAS_NULLPTR) using std::nullptr_t; #else // defined(ASIO_HAS_NULLPTR) struct nullptr_t {}; #endif // defined(ASIO_HAS_NULLPTR) } // namespace asio #endif // ASIO_DETAIL_CSTDDEF_HPP ================================================ FILE: src/third_party/asio/detail/cstdint.hpp ================================================ // // detail/cstdint.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_CSTDINT_HPP #define ASIO_DETAIL_CSTDINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CSTDINT) # include #else // defined(ASIO_HAS_CSTDINT) # include #endif // defined(ASIO_HAS_CSTDINT) namespace asio { #if defined(ASIO_HAS_CSTDINT) using std::int16_t; using std::int_least16_t; using std::uint16_t; using std::uint_least16_t; using std::int32_t; using std::int_least32_t; using std::uint32_t; using std::uint_least32_t; using std::int64_t; using std::int_least64_t; using std::uint64_t; using std::uint_least64_t; using std::uintmax_t; #else // defined(ASIO_HAS_CSTDINT) using boost::int16_t; using boost::int_least16_t; using boost::uint16_t; using boost::uint_least16_t; using boost::int32_t; using boost::int_least32_t; using boost::uint32_t; using boost::uint_least32_t; using boost::int64_t; using boost::int_least64_t; using boost::uint64_t; using boost::uint_least64_t; using boost::uintmax_t; #endif // defined(ASIO_HAS_CSTDINT) } // namespace asio #endif // ASIO_DETAIL_CSTDINT_HPP ================================================ FILE: src/third_party/asio/detail/date_time_fwd.hpp ================================================ // // detail/date_time_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_DATE_TIME_FWD_HPP #define ASIO_DETAIL_DATE_TIME_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" namespace boost { namespace date_time { template class base_time; } // namespace date_time namespace posix_time { class ptime; } // namespace posix_time } // namespace boost #endif // ASIO_DETAIL_DATE_TIME_FWD_HPP ================================================ FILE: src/third_party/asio/detail/deadline_timer_service.hpp ================================================ // // detail/deadline_timer_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP #define ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/timer_queue.hpp" #include "asio/detail/timer_queue_ptime.hpp" #include "asio/detail/timer_scheduler.hpp" #include "asio/detail/wait_handler.hpp" #include "asio/detail/wait_op.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include # include #endif // defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class deadline_timer_service : public execution_context_service_base > { public: // The time type. typedef typename Time_Traits::time_type time_type; // The duration type. typedef typename Time_Traits::duration_type duration_type; // The implementation type of the timer. This type is dependent on the // underlying implementation of the timer service. struct implementation_type : private asio::detail::noncopyable { time_type expiry; bool might_have_pending_waits; typename timer_queue::per_timer_data timer_data; }; // Constructor. deadline_timer_service(execution_context& context) : execution_context_service_base< deadline_timer_service >(context), scheduler_(asio::use_service(context)) { scheduler_.init_task(); scheduler_.add_timer_queue(timer_queue_); } // Destructor. ~deadline_timer_service() { scheduler_.remove_timer_queue(timer_queue_); } // Destroy all user-defined handler objects owned by the service. void shutdown() { } // Construct a new timer implementation. void construct(implementation_type& impl) { impl.expiry = time_type(); impl.might_have_pending_waits = false; } // Destroy a timer implementation. void destroy(implementation_type& impl) { asio::error_code ec; cancel(impl, ec); } // Move-construct a new serial port implementation. void move_construct(implementation_type& impl, implementation_type& other_impl) { scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data); impl.expiry = other_impl.expiry; other_impl.expiry = time_type(); impl.might_have_pending_waits = other_impl.might_have_pending_waits; other_impl.might_have_pending_waits = false; } // Move-assign from another serial port implementation. void move_assign(implementation_type& impl, deadline_timer_service& other_service, implementation_type& other_impl) { if (this != &other_service) if (impl.might_have_pending_waits) scheduler_.cancel_timer(timer_queue_, impl.timer_data); other_service.scheduler_.move_timer(other_service.timer_queue_, impl.timer_data, other_impl.timer_data); impl.expiry = other_impl.expiry; other_impl.expiry = time_type(); impl.might_have_pending_waits = other_impl.might_have_pending_waits; other_impl.might_have_pending_waits = false; } // Cancel any asynchronous wait operations associated with the timer. std::size_t cancel(implementation_type& impl, asio::error_code& ec) { if (!impl.might_have_pending_waits) { ec = asio::error_code(); return 0; } ASIO_HANDLER_OPERATION((scheduler_.context(), "deadline_timer", &impl, 0, "cancel")); std::size_t count = scheduler_.cancel_timer(timer_queue_, impl.timer_data); impl.might_have_pending_waits = false; ec = asio::error_code(); return count; } // Cancels one asynchronous wait operation associated with the timer. std::size_t cancel_one(implementation_type& impl, asio::error_code& ec) { if (!impl.might_have_pending_waits) { ec = asio::error_code(); return 0; } ASIO_HANDLER_OPERATION((scheduler_.context(), "deadline_timer", &impl, 0, "cancel_one")); std::size_t count = scheduler_.cancel_timer( timer_queue_, impl.timer_data, 1); if (count == 0) impl.might_have_pending_waits = false; ec = asio::error_code(); return count; } // Get the expiry time for the timer as an absolute time. time_type expiry(const implementation_type& impl) const { return impl.expiry; } // Get the expiry time for the timer as an absolute time. time_type expires_at(const implementation_type& impl) const { return impl.expiry; } // Get the expiry time for the timer relative to now. duration_type expires_from_now(const implementation_type& impl) const { return Time_Traits::subtract(this->expiry(impl), Time_Traits::now()); } // Set the expiry time for the timer as an absolute time. std::size_t expires_at(implementation_type& impl, const time_type& expiry_time, asio::error_code& ec) { std::size_t count = cancel(impl, ec); impl.expiry = expiry_time; ec = asio::error_code(); return count; } // Set the expiry time for the timer relative to now. std::size_t expires_after(implementation_type& impl, const duration_type& expiry_time, asio::error_code& ec) { return expires_at(impl, Time_Traits::add(Time_Traits::now(), expiry_time), ec); } // Set the expiry time for the timer relative to now. std::size_t expires_from_now(implementation_type& impl, const duration_type& expiry_time, asio::error_code& ec) { return expires_at(impl, Time_Traits::add(Time_Traits::now(), expiry_time), ec); } // Perform a blocking wait on the timer. void wait(implementation_type& impl, asio::error_code& ec) { time_type now = Time_Traits::now(); ec = asio::error_code(); while (Time_Traits::less_than(now, impl.expiry) && !ec) { this->do_wait(Time_Traits::to_posix_duration( Time_Traits::subtract(impl.expiry, now)), ec); now = Time_Traits::now(); } } // Start an asynchronous wait on the timer. template void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef wait_handler op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); impl.might_have_pending_waits = true; ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "deadline_timer", &impl, 0, "async_wait")); scheduler_.schedule_timer(timer_queue_, impl.expiry, impl.timer_data, p.p); p.v = p.p = 0; } private: // Helper function to wait given a duration type. The duration type should // either be of type boost::posix_time::time_duration, or implement the // required subset of its interface. template void do_wait(const Duration& timeout, asio::error_code& ec) { #if defined(ASIO_WINDOWS_RUNTIME) std::this_thread::sleep_for( std::chrono::seconds(timeout.total_seconds()) + std::chrono::microseconds(timeout.total_microseconds())); ec = asio::error_code(); #else // defined(ASIO_WINDOWS_RUNTIME) ::timeval tv; tv.tv_sec = timeout.total_seconds(); tv.tv_usec = timeout.total_microseconds() % 1000000; socket_ops::select(0, 0, 0, 0, &tv, ec); #endif // defined(ASIO_WINDOWS_RUNTIME) } // The queue of timers. timer_queue timer_queue_; // The object that schedules and executes timers. Usually a reactor. timer_scheduler& scheduler_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/dependent_type.hpp ================================================ // // detail/dependent_type.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_DEPENDENT_TYPE_HPP #define ASIO_DETAIL_DEPENDENT_TYPE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct dependent_type { typedef T type; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_DEPENDENT_TYPE_HPP ================================================ FILE: src/third_party/asio/detail/descriptor_ops.hpp ================================================ // // detail/descriptor_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_DESCRIPTOR_OPS_HPP #define ASIO_DETAIL_DESCRIPTOR_OPS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) #include #include "asio/error.hpp" #include "asio/error_code.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { namespace descriptor_ops { // Descriptor state bits. enum { // The user wants a non-blocking descriptor. user_set_non_blocking = 1, // The descriptor has been set non-blocking. internal_non_blocking = 2, // Helper "state" used to determine whether the descriptor is non-blocking. non_blocking = user_set_non_blocking | internal_non_blocking, // The descriptor may have been dup()-ed. possible_dup = 4 }; typedef unsigned char state_type; template inline ReturnType error_wrapper(ReturnType return_value, asio::error_code& ec) { ec = asio::error_code(errno, asio::error::get_system_category()); return return_value; } ASIO_DECL int open(const char* path, int flags, asio::error_code& ec); ASIO_DECL int close(int d, state_type& state, asio::error_code& ec); ASIO_DECL bool set_user_non_blocking(int d, state_type& state, bool value, asio::error_code& ec); ASIO_DECL bool set_internal_non_blocking(int d, state_type& state, bool value, asio::error_code& ec); typedef iovec buf; ASIO_DECL std::size_t sync_read(int d, state_type state, buf* bufs, std::size_t count, bool all_empty, asio::error_code& ec); ASIO_DECL bool non_blocking_read(int d, buf* bufs, std::size_t count, asio::error_code& ec, std::size_t& bytes_transferred); ASIO_DECL std::size_t sync_write(int d, state_type state, const buf* bufs, std::size_t count, bool all_empty, asio::error_code& ec); ASIO_DECL bool non_blocking_write(int d, const buf* bufs, std::size_t count, asio::error_code& ec, std::size_t& bytes_transferred); ASIO_DECL int ioctl(int d, state_type& state, long cmd, ioctl_arg_type* arg, asio::error_code& ec); ASIO_DECL int fcntl(int d, int cmd, asio::error_code& ec); ASIO_DECL int fcntl(int d, int cmd, long arg, asio::error_code& ec); ASIO_DECL int poll_read(int d, state_type state, asio::error_code& ec); ASIO_DECL int poll_write(int d, state_type state, asio::error_code& ec); ASIO_DECL int poll_error(int d, state_type state, asio::error_code& ec); } // namespace descriptor_ops } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/descriptor_ops.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) #endif // ASIO_DETAIL_DESCRIPTOR_OPS_HPP ================================================ FILE: src/third_party/asio/detail/descriptor_read_op.hpp ================================================ // // detail/descriptor_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP #define ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/descriptor_ops.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class descriptor_read_op_base : public reactor_op { public: descriptor_read_op_base(int descriptor, const MutableBufferSequence& buffers, func_type complete_func) : reactor_op(&descriptor_read_op_base::do_perform, complete_func), descriptor_(descriptor), buffers_(buffers) { } static status do_perform(reactor_op* base) { descriptor_read_op_base* o(static_cast(base)); buffer_sequence_adapter bufs(o->buffers_); status result = descriptor_ops::non_blocking_read(o->descriptor_, bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_) ? done : not_done; ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_read", o->ec_, o->bytes_transferred_)); return result; } private: int descriptor_; MutableBufferSequence buffers_; }; template class descriptor_read_op : public descriptor_read_op_base { public: ASIO_DEFINE_HANDLER_PTR(descriptor_read_op); descriptor_read_op(int descriptor, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : descriptor_read_op_base( descriptor, buffers, &descriptor_read_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. descriptor_read_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #endif // ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP ================================================ FILE: src/third_party/asio/detail/descriptor_write_op.hpp ================================================ // // detail/descriptor_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP #define ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/descriptor_ops.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class descriptor_write_op_base : public reactor_op { public: descriptor_write_op_base(int descriptor, const ConstBufferSequence& buffers, func_type complete_func) : reactor_op(&descriptor_write_op_base::do_perform, complete_func), descriptor_(descriptor), buffers_(buffers) { } static status do_perform(reactor_op* base) { descriptor_write_op_base* o(static_cast(base)); buffer_sequence_adapter bufs(o->buffers_); status result = descriptor_ops::non_blocking_write(o->descriptor_, bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_) ? done : not_done; ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_write", o->ec_, o->bytes_transferred_)); return result; } private: int descriptor_; ConstBufferSequence buffers_; }; template class descriptor_write_op : public descriptor_write_op_base { public: ASIO_DEFINE_HANDLER_PTR(descriptor_write_op); descriptor_write_op(int descriptor, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : descriptor_write_op_base( descriptor, buffers, &descriptor_write_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. descriptor_write_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #endif // ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP ================================================ FILE: src/third_party/asio/detail/dev_poll_reactor.hpp ================================================ // // detail/dev_poll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_DEV_POLL_REACTOR_HPP #define ASIO_DETAIL_DEV_POLL_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_DEV_POLL) #include #include #include #include "asio/detail/hash_map.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/reactor_op_queue.hpp" #include "asio/detail/select_interrupter.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/timer_queue_set.hpp" #include "asio/detail/wait_op.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class dev_poll_reactor : public execution_context_service_base { public: enum op_types { read_op = 0, write_op = 1, connect_op = 1, except_op = 2, max_ops = 3 }; // Per-descriptor data. struct per_descriptor_data { }; // Constructor. ASIO_DECL dev_poll_reactor(asio::execution_context& ctx); // Destructor. ASIO_DECL ~dev_poll_reactor(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Recreate internal descriptors following a fork. ASIO_DECL void notify_fork( asio::execution_context::fork_event fork_ev); // Initialise the task. ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&); // Register a descriptor with an associated single operation. Returns 0 on // success, system error code on failure. ASIO_DECL int register_internal_descriptor( int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, reactor_op* op); // Move descriptor registration from one descriptor_data object to another. ASIO_DECL void move_descriptor(socket_type descriptor, per_descriptor_data& target_descriptor_data, per_descriptor_data& source_descriptor_data); // Post a reactor operation for immediate completion. void post_immediate_completion(reactor_op* op, bool is_continuation) { scheduler_.post_immediate_completion(op, is_continuation); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. ASIO_DECL void start_op(int op_type, socket_type descriptor, per_descriptor_data&, reactor_op* op, bool is_continuation, bool allow_speculative); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. The reactor resources associated with // the descriptor must be released by calling cleanup_descriptor_data. ASIO_DECL void deregister_descriptor(socket_type descriptor, per_descriptor_data&, bool closing); // Remove the descriptor's registration from the reactor. The reactor // resources associated with the descriptor must be released by calling // cleanup_descriptor_data. ASIO_DECL void deregister_internal_descriptor( socket_type descriptor, per_descriptor_data&); // Perform any post-deregistration cleanup tasks associated with the // descriptor data. ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&); // Add a new timer queue to the reactor. template void add_timer_queue(timer_queue& queue); // Remove a timer queue from the reactor. template void remove_timer_queue(timer_queue& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template void schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template std::size_t cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits::max)()); // Move the timer operations associated with the given timer. template void move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source); // Run /dev/poll once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue& ops); // Interrupt the select loop. ASIO_DECL void interrupt(); private: // Create the /dev/poll file descriptor. Throws an exception if the descriptor // cannot be created. ASIO_DECL static int do_dev_poll_create(); // Helper function to add a new timer queue. ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); // Helper function to remove a timer queue. ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Get the timeout value for the /dev/poll DP_POLL operation. The timeout // value is returned as a number of milliseconds. A return value of -1 // indicates that the poll should block indefinitely. ASIO_DECL int get_timeout(int msec); // Cancel all operations associated with the given descriptor. The do_cancel // function of the handler objects will be invoked. This function does not // acquire the dev_poll_reactor's mutex. ASIO_DECL void cancel_ops_unlocked(socket_type descriptor, const asio::error_code& ec); // Add a pending event entry for the given descriptor. ASIO_DECL ::pollfd& add_pending_event_change(int descriptor); // The scheduler implementation used to post completions. scheduler& scheduler_; // Mutex to protect access to internal data. asio::detail::mutex mutex_; // The /dev/poll file descriptor. int dev_poll_fd_; // Vector of /dev/poll events waiting to be written to the descriptor. std::vector< ::pollfd> pending_event_changes_; // Hash map to associate a descriptor with a pending event change index. hash_map pending_event_change_index_; // The interrupter is used to break a blocking DP_POLL operation. select_interrupter interrupter_; // The queues of read, write and except operations. reactor_op_queue op_queue_[max_ops]; // The timer queues. timer_queue_set timer_queues_; // Whether the service has been shut down. bool shutdown_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/dev_poll_reactor.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/dev_poll_reactor.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_DEV_POLL) #endif // ASIO_DETAIL_DEV_POLL_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/epoll_reactor.hpp ================================================ // // detail/epoll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_EPOLL_REACTOR_HPP #define ASIO_DETAIL_EPOLL_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_EPOLL) #include "asio/detail/atomic_count.hpp" #include "asio/detail/conditionally_enabled_mutex.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/object_pool.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/select_interrupter.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/timer_queue_set.hpp" #include "asio/detail/wait_op.hpp" #include "asio/execution_context.hpp" #if defined(ASIO_HAS_TIMERFD) # include #endif // defined(ASIO_HAS_TIMERFD) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class epoll_reactor : public execution_context_service_base { private: // The mutex type used by this reactor. typedef conditionally_enabled_mutex mutex; public: enum op_types { read_op = 0, write_op = 1, connect_op = 1, except_op = 2, max_ops = 3 }; // Per-descriptor queues. class descriptor_state : operation { friend class epoll_reactor; friend class object_pool_access; descriptor_state* next_; descriptor_state* prev_; mutex mutex_; epoll_reactor* reactor_; int descriptor_; uint32_t registered_events_; op_queue op_queue_[max_ops]; bool try_speculative_[max_ops]; bool shutdown_; ASIO_DECL descriptor_state(bool locking); void set_ready_events(uint32_t events) { task_result_ = events; } void add_ready_events(uint32_t events) { task_result_ |= events; } ASIO_DECL operation* perform_io(uint32_t events); ASIO_DECL static void do_complete( void* owner, operation* base, const asio::error_code& ec, std::size_t bytes_transferred); }; // Per-descriptor data. typedef descriptor_state* per_descriptor_data; // Constructor. ASIO_DECL epoll_reactor(asio::execution_context& ctx); // Destructor. ASIO_DECL ~epoll_reactor(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Recreate internal descriptors following a fork. ASIO_DECL void notify_fork( asio::execution_context::fork_event fork_ev); // Initialise the task. ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. ASIO_DECL int register_descriptor(socket_type descriptor, per_descriptor_data& descriptor_data); // Register a descriptor with an associated single operation. Returns 0 on // success, system error code on failure. ASIO_DECL int register_internal_descriptor( int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, reactor_op* op); // Move descriptor registration from one descriptor_data object to another. ASIO_DECL void move_descriptor(socket_type descriptor, per_descriptor_data& target_descriptor_data, per_descriptor_data& source_descriptor_data); // Post a reactor operation for immediate completion. void post_immediate_completion(reactor_op* op, bool is_continuation) { scheduler_.post_immediate_completion(op, is_continuation); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. ASIO_DECL void start_op(int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, reactor_op* op, bool is_continuation, bool allow_speculative); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data& descriptor_data); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. The reactor resources associated with // the descriptor must be released by calling cleanup_descriptor_data. ASIO_DECL void deregister_descriptor(socket_type descriptor, per_descriptor_data& descriptor_data, bool closing); // Remove the descriptor's registration from the reactor. The reactor // resources associated with the descriptor must be released by calling // cleanup_descriptor_data. ASIO_DECL void deregister_internal_descriptor( socket_type descriptor, per_descriptor_data& descriptor_data); // Perform any post-deregistration cleanup tasks associated with the // descriptor data. ASIO_DECL void cleanup_descriptor_data( per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor. template void add_timer_queue(timer_queue& timer_queue); // Remove a timer queue from the reactor. template void remove_timer_queue(timer_queue& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template void schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template std::size_t cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits::max)()); // Move the timer operations associated with the given timer. template void move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source); // Run epoll once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue& ops); // Interrupt the select loop. ASIO_DECL void interrupt(); private: // The hint to pass to epoll_create to size its data structures. enum { epoll_size = 20000 }; // Create the epoll file descriptor. Throws an exception if the descriptor // cannot be created. ASIO_DECL static int do_epoll_create(); // Create the timerfd file descriptor. Does not throw. ASIO_DECL static int do_timerfd_create(); // Allocate a new descriptor state object. ASIO_DECL descriptor_state* allocate_descriptor_state(); // Free an existing descriptor state object. ASIO_DECL void free_descriptor_state(descriptor_state* s); // Helper function to add a new timer queue. ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); // Helper function to remove a timer queue. ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Called to recalculate and update the timeout. ASIO_DECL void update_timeout(); // Get the timeout value for the epoll_wait call. The timeout value is // returned as a number of milliseconds. A return value of -1 indicates // that epoll_wait should block indefinitely. ASIO_DECL int get_timeout(int msec); #if defined(ASIO_HAS_TIMERFD) // Get the timeout value for the timer descriptor. The return value is the // flag argument to be used when calling timerfd_settime. ASIO_DECL int get_timeout(itimerspec& ts); #endif // defined(ASIO_HAS_TIMERFD) // The scheduler implementation used to post completions. scheduler& scheduler_; // Mutex to protect access to internal data. mutex mutex_; // The interrupter is used to break a blocking epoll_wait call. select_interrupter interrupter_; // The epoll file descriptor. int epoll_fd_; // The timer file descriptor. int timer_fd_; // The timer queues. timer_queue_set timer_queues_; // Whether the service has been shut down. bool shutdown_; // Mutex to protect access to the registered descriptors. mutex registered_descriptors_mutex_; // Keep track of all registered descriptors. object_pool registered_descriptors_; // Helper class to do post-perform_io cleanup. struct perform_io_cleanup_on_block_exit; friend struct perform_io_cleanup_on_block_exit; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/epoll_reactor.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/epoll_reactor.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_EPOLL) #endif // ASIO_DETAIL_EPOLL_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/event.hpp ================================================ // // detail/event.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_EVENT_HPP #define ASIO_DETAIL_EVENT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) # include "asio/detail/null_event.hpp" #elif defined(ASIO_WINDOWS) # include "asio/detail/win_event.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_event.hpp" #elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_event.hpp" #else # error Only Windows, POSIX and std::condition_variable are supported! #endif namespace asio { namespace detail { #if !defined(ASIO_HAS_THREADS) typedef null_event event; #elif defined(ASIO_WINDOWS) typedef win_event event; #elif defined(ASIO_HAS_PTHREADS) typedef posix_event event; #elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_event event; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_EVENT_HPP ================================================ FILE: src/third_party/asio/detail/eventfd_select_interrupter.hpp ================================================ // // detail/eventfd_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP #define ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_EVENTFD) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class eventfd_select_interrupter { public: // Constructor. ASIO_DECL eventfd_select_interrupter(); // Destructor. ASIO_DECL ~eventfd_select_interrupter(); // Recreate the interrupter's descriptors. Used after a fork. ASIO_DECL void recreate(); // Interrupt the select call. ASIO_DECL void interrupt(); // Reset the select interrupt. Returns true if the call was interrupted. ASIO_DECL bool reset(); // Get the read descriptor to be passed to select. int read_descriptor() const { return read_descriptor_; } private: // Open the descriptors. Throws on error. ASIO_DECL void open_descriptors(); // Close the descriptors. ASIO_DECL void close_descriptors(); // The read end of a connection used to interrupt the select call. This file // descriptor is passed to select such that when it is time to stop, a single // 64bit value will be written on the other end of the connection and this // descriptor will become readable. int read_descriptor_; // The write end of a connection used to interrupt the select call. A single // 64bit non-zero value may be written to this to wake up the select which is // waiting for the other end to become readable. This descriptor will only // differ from the read descriptor when a pipe is used. int write_descriptor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/eventfd_select_interrupter.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_EVENTFD) #endif // ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP ================================================ FILE: src/third_party/asio/detail/executor_function.hpp ================================================ // // detail/executor_function.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_EXECUTOR_FUNCTION_HPP #define ASIO_DETAIL_EXECUTOR_FUNCTION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class executor_function_base { public: void complete() { func_(this, true); } void destroy() { func_(this, false); } protected: typedef void (*func_type)(executor_function_base*, bool); executor_function_base(func_type func) : func_(func) { } // Prevents deletion through this type. ~executor_function_base() { } private: func_type func_; }; template class executor_function : public executor_function_base { public: ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( thread_info_base::executor_function_tag, executor_function); template executor_function(ASIO_MOVE_ARG(F) f, const Alloc& allocator) : executor_function_base(&executor_function::do_complete), function_(ASIO_MOVE_CAST(F)(f)), allocator_(allocator) { } static void do_complete(executor_function_base* base, bool call) { // Take ownership of the function object. executor_function* o(static_cast(base)); Alloc allocator(o->allocator_); ptr p = { detail::addressof(allocator), o, o }; // Make a copy of the function so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the function may be the true owner of the memory // associated with the function. Consequently, a local copy of the function // is required to ensure that any owning sub-object remains valid until // after we have deallocated the memory here. Function function(ASIO_MOVE_CAST(Function)(o->function_)); p.reset(); // Make the upcall if required. if (call) { function(); } } private: Function function_; Alloc allocator_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_EXECUTOR_FUNCTION_HPP ================================================ FILE: src/third_party/asio/detail/executor_op.hpp ================================================ // // detail/executor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_EXECUTOR_OP_HPP #define ASIO_DETAIL_EXECUTOR_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/scheduler_operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class executor_op : public Operation { public: ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(executor_op); template executor_op(ASIO_MOVE_ARG(H) h, const Alloc& allocator) : Operation(&executor_op::do_complete), handler_(ASIO_MOVE_CAST(H)(h)), allocator_(allocator) { } static void do_complete(void* owner, Operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. executor_op* o(static_cast(base)); Alloc allocator(o->allocator_); ptr p = { detail::addressof(allocator), o, o }; ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. Handler handler(ASIO_MOVE_CAST(Handler)(o->handler_)); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN(()); asio_handler_invoke_helpers::invoke(handler, handler); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; Alloc allocator_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_EXECUTOR_OP_HPP ================================================ FILE: src/third_party/asio/detail/fd_set_adapter.hpp ================================================ // // detail/fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_FD_SET_ADAPTER_HPP #define ASIO_DETAIL_FD_SET_ADAPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/posix_fd_set_adapter.hpp" #include "asio/detail/win_fd_set_adapter.hpp" namespace asio { namespace detail { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) typedef win_fd_set_adapter fd_set_adapter; #else typedef posix_fd_set_adapter fd_set_adapter; #endif } // namespace detail } // namespace asio #endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_FD_SET_ADAPTER_HPP ================================================ FILE: src/third_party/asio/detail/fenced_block.hpp ================================================ // // detail/fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_FENCED_BLOCK_HPP #define ASIO_DETAIL_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) \ || defined(ASIO_DISABLE_FENCED_BLOCK) # include "asio/detail/null_fenced_block.hpp" #elif defined(ASIO_HAS_STD_ATOMIC) # include "asio/detail/std_fenced_block.hpp" #elif defined(__MACH__) && defined(__APPLE__) # include "asio/detail/macos_fenced_block.hpp" #elif defined(__sun) # include "asio/detail/solaris_fenced_block.hpp" #elif defined(__GNUC__) && defined(__arm__) \ && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) # include "asio/detail/gcc_arm_fenced_block.hpp" #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) # include "asio/detail/gcc_hppa_fenced_block.hpp" #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) # include "asio/detail/gcc_x86_fenced_block.hpp" #elif defined(__GNUC__) \ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ && !defined(__INTEL_COMPILER) && !defined(__ICL) \ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) # include "asio/detail/gcc_sync_fenced_block.hpp" #elif defined(ASIO_WINDOWS) && !defined(UNDER_CE) # include "asio/detail/win_fenced_block.hpp" #else # include "asio/detail/null_fenced_block.hpp" #endif namespace asio { namespace detail { #if !defined(ASIO_HAS_THREADS) \ || defined(ASIO_DISABLE_FENCED_BLOCK) typedef null_fenced_block fenced_block; #elif defined(ASIO_HAS_STD_ATOMIC) typedef std_fenced_block fenced_block; #elif defined(__MACH__) && defined(__APPLE__) typedef macos_fenced_block fenced_block; #elif defined(__sun) typedef solaris_fenced_block fenced_block; #elif defined(__GNUC__) && defined(__arm__) \ && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) typedef gcc_arm_fenced_block fenced_block; #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) typedef gcc_hppa_fenced_block fenced_block; #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) typedef gcc_x86_fenced_block fenced_block; #elif defined(__GNUC__) \ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ && !defined(__INTEL_COMPILER) && !defined(__ICL) \ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) typedef gcc_sync_fenced_block fenced_block; #elif defined(ASIO_WINDOWS) && !defined(UNDER_CE) typedef win_fenced_block fenced_block; #else typedef null_fenced_block fenced_block; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/functional.hpp ================================================ // // detail/functional.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_FUNCTIONAL_HPP #define ASIO_DETAIL_FUNCTIONAL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #if !defined(ASIO_HAS_STD_FUNCTION) # include #endif // !defined(ASIO_HAS_STD_FUNCTION) namespace asio { namespace detail { #if defined(ASIO_HAS_STD_FUNCTION) using std::function; #else // defined(ASIO_HAS_STD_FUNCTION) using boost::function; #endif // defined(ASIO_HAS_STD_FUNCTION) } // namespace detail } // namespace asio #endif // ASIO_DETAIL_FUNCTIONAL_HPP ================================================ FILE: src/third_party/asio/detail/future.hpp ================================================ // // detail/future.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_FUTURE_HPP #define ASIO_DETAIL_FUTURE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_FUTURE) # include // Even though the future header is available, libstdc++ may not implement the // std::future class itself. However, we need to have already included the // future header to reliably test for _GLIBCXX_HAS_GTHREADS. # if defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX) # if defined(_GLIBCXX_HAS_GTHREADS) # define ASIO_HAS_STD_FUTURE_CLASS 1 # endif // defined(_GLIBCXX_HAS_GTHREADS) # else // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_FUTURE_CLASS 1 # endif // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX) #endif // defined(ASIO_HAS_STD_FUTURE) #endif // ASIO_DETAIL_FUTURE_HPP ================================================ FILE: src/third_party/asio/detail/gcc_arm_fenced_block.hpp ================================================ // // detail/gcc_arm_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP #define ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(__GNUC__) && defined(__arm__) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class gcc_arm_fenced_block : private noncopyable { public: enum half_t { half }; enum full_t { full }; // Constructor for a half fenced block. explicit gcc_arm_fenced_block(half_t) { } // Constructor for a full fenced block. explicit gcc_arm_fenced_block(full_t) { barrier(); } // Destructor. ~gcc_arm_fenced_block() { barrier(); } private: static void barrier() { #if defined(__ARM_ARCH_4__) \ || defined(__ARM_ARCH_4T__) \ || defined(__ARM_ARCH_5__) \ || defined(__ARM_ARCH_5E__) \ || defined(__ARM_ARCH_5T__) \ || defined(__ARM_ARCH_5TE__) \ || defined(__ARM_ARCH_5TEJ__) \ || defined(__ARM_ARCH_6__) \ || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6K__) \ || defined(__ARM_ARCH_6Z__) \ || defined(__ARM_ARCH_6ZK__) \ || defined(__ARM_ARCH_6T2__) # if defined(__thumb__) // This is just a placeholder and almost certainly not sufficient. __asm__ __volatile__ ("" : : : "memory"); # else // defined(__thumb__) int a = 0, b = 0; __asm__ __volatile__ ("swp %0, %1, [%2]" : "=&r"(a) : "r"(1), "r"(&b) : "memory", "cc"); # endif // defined(__thumb__) #else // ARMv7 and later. __asm__ __volatile__ ("dmb" : : : "memory"); #endif } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(__GNUC__) && defined(__arm__) #endif // ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/gcc_hppa_fenced_block.hpp ================================================ // // detail/gcc_hppa_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP #define ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class gcc_hppa_fenced_block : private noncopyable { public: enum half_t { half }; enum full_t { full }; // Constructor for a half fenced block. explicit gcc_hppa_fenced_block(half_t) { } // Constructor for a full fenced block. explicit gcc_hppa_fenced_block(full_t) { barrier(); } // Destructor. ~gcc_hppa_fenced_block() { barrier(); } private: static void barrier() { // This is just a placeholder and almost certainly not sufficient. __asm__ __volatile__ ("" : : : "memory"); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) #endif // ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/gcc_sync_fenced_block.hpp ================================================ // // detail/gcc_sync_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP #define ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(__GNUC__) \ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ && !defined(__INTEL_COMPILER) && !defined(__ICL) \ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class gcc_sync_fenced_block : private noncopyable { public: enum half_or_full_t { half, full }; // Constructor. explicit gcc_sync_fenced_block(half_or_full_t) : value_(0) { __sync_lock_test_and_set(&value_, 1); } // Destructor. ~gcc_sync_fenced_block() { __sync_lock_release(&value_); } private: int value_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(__GNUC__) // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) // && !defined(__INTEL_COMPILER) && !defined(__ICL) // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) #endif // ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/gcc_x86_fenced_block.hpp ================================================ // // detail/gcc_x86_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP #define ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class gcc_x86_fenced_block : private noncopyable { public: enum half_t { half }; enum full_t { full }; // Constructor for a half fenced block. explicit gcc_x86_fenced_block(half_t) { } // Constructor for a full fenced block. explicit gcc_x86_fenced_block(full_t) { lbarrier(); } // Destructor. ~gcc_x86_fenced_block() { sbarrier(); } private: static int barrier() { int r = 0, m = 1; __asm__ __volatile__ ( "xchgl %0, %1" : "=r"(r), "=m"(m) : "0"(1), "m"(m) : "memory", "cc"); return r; } static void lbarrier() { #if defined(__SSE2__) # if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) __builtin_ia32_lfence(); # else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) __asm__ __volatile__ ("lfence" ::: "memory"); # endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) #else // defined(__SSE2__) barrier(); #endif // defined(__SSE2__) } static void sbarrier() { #if defined(__SSE2__) # if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) __builtin_ia32_sfence(); # else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) __asm__ __volatile__ ("sfence" ::: "memory"); # endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) #else // defined(__SSE2__) barrier(); #endif // defined(__SSE2__) } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #endif // ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/global.hpp ================================================ // // detail/global.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_GLOBAL_HPP #define ASIO_DETAIL_GLOBAL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) # include "asio/detail/null_global.hpp" #elif defined(ASIO_WINDOWS) # include "asio/detail/win_global.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_global.hpp" #elif defined(ASIO_HAS_STD_CALL_ONCE) # include "asio/detail/std_global.hpp" #else # error Only Windows, POSIX and std::call_once are supported! #endif namespace asio { namespace detail { template inline T& global() { #if !defined(ASIO_HAS_THREADS) return null_global(); #elif defined(ASIO_WINDOWS) return win_global(); #elif defined(ASIO_HAS_PTHREADS) return posix_global(); #elif defined(ASIO_HAS_STD_CALL_ONCE) return std_global(); #endif } } // namespace detail } // namespace asio #endif // ASIO_DETAIL_GLOBAL_HPP ================================================ FILE: src/third_party/asio/detail/handler_alloc_helpers.hpp ================================================ // // detail/handler_alloc_helpers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP #define ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/associated_allocator.hpp" #include "asio/handler_alloc_hook.hpp" #include "asio/detail/push_options.hpp" // Calls to asio_handler_allocate and asio_handler_deallocate must be made from // a namespace that does not contain any overloads of these functions. The // asio_handler_alloc_helpers namespace is defined here for that purpose. namespace asio_handler_alloc_helpers { template inline void* allocate(std::size_t s, Handler& h) { #if !defined(ASIO_HAS_HANDLER_HOOKS) return ::operator new(s); #else using asio::asio_handler_allocate; return asio_handler_allocate(s, asio::detail::addressof(h)); #endif } template inline void deallocate(void* p, std::size_t s, Handler& h) { #if !defined(ASIO_HAS_HANDLER_HOOKS) ::operator delete(p); #else using asio::asio_handler_deallocate; asio_handler_deallocate(p, s, asio::detail::addressof(h)); #endif } } // namespace asio_handler_alloc_helpers namespace asio { namespace detail { template class hook_allocator { public: typedef T value_type; template struct rebind { typedef hook_allocator other; }; explicit hook_allocator(Handler& h) : handler_(h) { } template hook_allocator(const hook_allocator& a) : handler_(a.handler_) { } T* allocate(std::size_t n) { return static_cast( asio_handler_alloc_helpers::allocate(sizeof(T) * n, handler_)); } void deallocate(T* p, std::size_t n) { asio_handler_alloc_helpers::deallocate(p, sizeof(T) * n, handler_); } //private: Handler& handler_; }; template class hook_allocator { public: typedef void value_type; template struct rebind { typedef hook_allocator other; }; explicit hook_allocator(Handler& h) : handler_(h) { } template hook_allocator(const hook_allocator& a) : handler_(a.handler_) { } //private: Handler& handler_; }; template struct get_hook_allocator { typedef Allocator type; static type get(Handler&, const Allocator& a) { return a; } }; template struct get_hook_allocator > { typedef hook_allocator type; static type get(Handler& handler, const std::allocator&) { return type(handler); } }; } // namespace detail } // namespace asio #define ASIO_DEFINE_HANDLER_PTR(op) \ struct ptr \ { \ Handler* h; \ op* v; \ op* p; \ ~ptr() \ { \ reset(); \ } \ static op* allocate(Handler& handler) \ { \ typedef typename ::asio::associated_allocator< \ Handler>::type associated_allocator_type; \ typedef typename ::asio::detail::get_hook_allocator< \ Handler, associated_allocator_type>::type hook_allocator_type; \ ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \ ::asio::detail::get_hook_allocator< \ Handler, associated_allocator_type>::get( \ handler, ::asio::get_associated_allocator(handler))); \ return a.allocate(1); \ } \ void reset() \ { \ if (p) \ { \ p->~op(); \ p = 0; \ } \ if (v) \ { \ typedef typename ::asio::associated_allocator< \ Handler>::type associated_allocator_type; \ typedef typename ::asio::detail::get_hook_allocator< \ Handler, associated_allocator_type>::type hook_allocator_type; \ ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \ ::asio::detail::get_hook_allocator< \ Handler, associated_allocator_type>::get( \ *h, ::asio::get_associated_allocator(*h))); \ a.deallocate(static_cast(v), 1); \ v = 0; \ } \ } \ } \ /**/ #define ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \ struct ptr \ { \ const Alloc* a; \ void* v; \ op* p; \ ~ptr() \ { \ reset(); \ } \ static op* allocate(const Alloc& a) \ { \ typedef typename ::asio::detail::get_recycling_allocator< \ Alloc, purpose>::type recycling_allocator_type; \ ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \ ::asio::detail::get_recycling_allocator< \ Alloc, purpose>::get(a)); \ return a1.allocate(1); \ } \ void reset() \ { \ if (p) \ { \ p->~op(); \ p = 0; \ } \ if (v) \ { \ typedef typename ::asio::detail::get_recycling_allocator< \ Alloc, purpose>::type recycling_allocator_type; \ ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \ ::asio::detail::get_recycling_allocator< \ Alloc, purpose>::get(*a)); \ a1.deallocate(static_cast(v), 1); \ v = 0; \ } \ } \ } \ /**/ #define ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \ ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( \ ::asio::detail::thread_info_base::default_tag, op ) \ /**/ #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP ================================================ FILE: src/third_party/asio/detail/handler_cont_helpers.hpp ================================================ // // detail/handler_cont_helpers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP #define ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/memory.hpp" #include "asio/handler_continuation_hook.hpp" #include "asio/detail/push_options.hpp" // Calls to asio_handler_is_continuation must be made from a namespace that // does not contain overloads of this function. This namespace is defined here // for that purpose. namespace asio_handler_cont_helpers { template inline bool is_continuation(Context& context) { #if !defined(ASIO_HAS_HANDLER_HOOKS) return false; #else using asio::asio_handler_is_continuation; return asio_handler_is_continuation( asio::detail::addressof(context)); #endif } } // namespace asio_handler_cont_helpers #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP ================================================ FILE: src/third_party/asio/detail/handler_invoke_helpers.hpp ================================================ // // detail/handler_invoke_helpers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP #define ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/memory.hpp" #include "asio/handler_invoke_hook.hpp" #include "asio/detail/push_options.hpp" // Calls to asio_handler_invoke must be made from a namespace that does not // contain overloads of this function. The asio_handler_invoke_helpers // namespace is defined here for that purpose. namespace asio_handler_invoke_helpers { template inline void invoke(Function& function, Context& context) { #if !defined(ASIO_HAS_HANDLER_HOOKS) Function tmp(function); tmp(); #else using asio::asio_handler_invoke; asio_handler_invoke(function, asio::detail::addressof(context)); #endif } template inline void invoke(const Function& function, Context& context) { #if !defined(ASIO_HAS_HANDLER_HOOKS) Function tmp(function); tmp(); #else using asio::asio_handler_invoke; asio_handler_invoke(function, asio::detail::addressof(context)); #endif } } // namespace asio_handler_invoke_helpers #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP ================================================ FILE: src/third_party/asio/detail/handler_tracking.hpp ================================================ // // detail/handler_tracking.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_HANDLER_TRACKING_HPP #define ASIO_DETAIL_HANDLER_TRACKING_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" namespace asio { class execution_context; } // namespace asio #if defined(ASIO_CUSTOM_HANDLER_TRACKING) # include ASIO_CUSTOM_HANDLER_TRACKING #elif defined(ASIO_ENABLE_HANDLER_TRACKING) # include "asio/error_code.hpp" # include "asio/detail/cstdint.hpp" # include "asio/detail/static_mutex.hpp" # include "asio/detail/tss_ptr.hpp" #endif // defined(ASIO_ENABLE_HANDLER_TRACKING) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { #if defined(ASIO_CUSTOM_HANDLER_TRACKING) // The user-specified header must define the following macros: // - ASIO_INHERIT_TRACKED_HANDLER // - ASIO_ALSO_INHERIT_TRACKED_HANDLER // - ASIO_HANDLER_TRACKING_INIT // - ASIO_HANDLER_CREATION(args) // - ASIO_HANDLER_COMPLETION(args) // - ASIO_HANDLER_INVOCATION_BEGIN(args) // - ASIO_HANDLER_INVOCATION_END // - ASIO_HANDLER_OPERATION(args) // - ASIO_HANDLER_REACTOR_REGISTRATION(args) // - ASIO_HANDLER_REACTOR_DEREGISTRATION(args) // - ASIO_HANDLER_REACTOR_READ_EVENT // - ASIO_HANDLER_REACTOR_WRITE_EVENT // - ASIO_HANDLER_REACTOR_ERROR_EVENT // - ASIO_HANDLER_REACTOR_EVENTS(args) // - ASIO_HANDLER_REACTOR_OPERATION(args) # if !defined(ASIO_ENABLE_HANDLER_TRACKING) # define ASIO_ENABLE_HANDLER_TRACKING 1 # endif /// !defined(ASIO_ENABLE_HANDLER_TRACKING) #elif defined(ASIO_ENABLE_HANDLER_TRACKING) class handler_tracking { public: class completion; // Base class for objects containing tracked handlers. class tracked_handler { private: // Only the handler_tracking class will have access to the id. friend class handler_tracking; friend class completion; uint64_t id_; protected: // Constructor initialises with no id. tracked_handler() : id_(0) {} // Prevent deletion through this type. ~tracked_handler() {} }; // Initialise the tracking system. ASIO_DECL static void init(); // Record the creation of a tracked handler. ASIO_DECL static void creation( execution_context& context, tracked_handler& h, const char* object_type, void* object, uintmax_t native_handle, const char* op_name); class completion { public: // Constructor records that handler is to be invoked with no arguments. ASIO_DECL explicit completion(const tracked_handler& h); // Destructor records only when an exception is thrown from the handler, or // if the memory is being freed without the handler having been invoked. ASIO_DECL ~completion(); // Records that handler is to be invoked with no arguments. ASIO_DECL void invocation_begin(); // Records that handler is to be invoked with one arguments. ASIO_DECL void invocation_begin(const asio::error_code& ec); // Constructor records that handler is to be invoked with two arguments. ASIO_DECL void invocation_begin( const asio::error_code& ec, std::size_t bytes_transferred); // Constructor records that handler is to be invoked with two arguments. ASIO_DECL void invocation_begin( const asio::error_code& ec, int signal_number); // Constructor records that handler is to be invoked with two arguments. ASIO_DECL void invocation_begin( const asio::error_code& ec, const char* arg); // Record that handler invocation has ended. ASIO_DECL void invocation_end(); private: friend class handler_tracking; uint64_t id_; bool invoked_; completion* next_; }; // Record an operation that is not directly associated with a handler. ASIO_DECL static void operation(execution_context& context, const char* object_type, void* object, uintmax_t native_handle, const char* op_name); // Record that a descriptor has been registered with the reactor. ASIO_DECL static void reactor_registration(execution_context& context, uintmax_t native_handle, uintmax_t registration); // Record that a descriptor has been deregistered from the reactor. ASIO_DECL static void reactor_deregistration(execution_context& context, uintmax_t native_handle, uintmax_t registration); // Record a reactor-based operation that is associated with a handler. ASIO_DECL static void reactor_events(execution_context& context, uintmax_t registration, unsigned events); // Record a reactor-based operation that is associated with a handler. ASIO_DECL static void reactor_operation( const tracked_handler& h, const char* op_name, const asio::error_code& ec); // Record a reactor-based operation that is associated with a handler. ASIO_DECL static void reactor_operation( const tracked_handler& h, const char* op_name, const asio::error_code& ec, std::size_t bytes_transferred); // Write a line of output. ASIO_DECL static void write_line(const char* format, ...); private: struct tracking_state; ASIO_DECL static tracking_state* get_state(); }; # define ASIO_INHERIT_TRACKED_HANDLER \ : public asio::detail::handler_tracking::tracked_handler # define ASIO_ALSO_INHERIT_TRACKED_HANDLER \ , public asio::detail::handler_tracking::tracked_handler # define ASIO_HANDLER_TRACKING_INIT \ asio::detail::handler_tracking::init() # define ASIO_HANDLER_CREATION(args) \ asio::detail::handler_tracking::creation args # define ASIO_HANDLER_COMPLETION(args) \ asio::detail::handler_tracking::completion tracked_completion args # define ASIO_HANDLER_INVOCATION_BEGIN(args) \ tracked_completion.invocation_begin args # define ASIO_HANDLER_INVOCATION_END \ tracked_completion.invocation_end() # define ASIO_HANDLER_OPERATION(args) \ asio::detail::handler_tracking::operation args # define ASIO_HANDLER_REACTOR_REGISTRATION(args) \ asio::detail::handler_tracking::reactor_registration args # define ASIO_HANDLER_REACTOR_DEREGISTRATION(args) \ asio::detail::handler_tracking::reactor_deregistration args # define ASIO_HANDLER_REACTOR_READ_EVENT 1 # define ASIO_HANDLER_REACTOR_WRITE_EVENT 2 # define ASIO_HANDLER_REACTOR_ERROR_EVENT 4 # define ASIO_HANDLER_REACTOR_EVENTS(args) \ asio::detail::handler_tracking::reactor_events args # define ASIO_HANDLER_REACTOR_OPERATION(args) \ asio::detail::handler_tracking::reactor_operation args #else // defined(ASIO_ENABLE_HANDLER_TRACKING) # define ASIO_INHERIT_TRACKED_HANDLER # define ASIO_ALSO_INHERIT_TRACKED_HANDLER # define ASIO_HANDLER_TRACKING_INIT (void)0 # define ASIO_HANDLER_CREATION(args) (void)0 # define ASIO_HANDLER_COMPLETION(args) (void)0 # define ASIO_HANDLER_INVOCATION_BEGIN(args) (void)0 # define ASIO_HANDLER_INVOCATION_END (void)0 # define ASIO_HANDLER_OPERATION(args) (void)0 # define ASIO_HANDLER_REACTOR_REGISTRATION(args) (void)0 # define ASIO_HANDLER_REACTOR_DEREGISTRATION(args) (void)0 # define ASIO_HANDLER_REACTOR_READ_EVENT 0 # define ASIO_HANDLER_REACTOR_WRITE_EVENT 0 # define ASIO_HANDLER_REACTOR_ERROR_EVENT 0 # define ASIO_HANDLER_REACTOR_EVENTS(args) (void)0 # define ASIO_HANDLER_REACTOR_OPERATION(args) (void)0 #endif // defined(ASIO_ENABLE_HANDLER_TRACKING) } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/handler_tracking.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_HANDLER_TRACKING_HPP ================================================ FILE: src/third_party/asio/detail/handler_type_requirements.hpp ================================================ // // detail/handler_type_requirements.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP #define ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" // Older versions of gcc have difficulty compiling the sizeof expressions where // we test the handler type requirements. We'll disable checking of handler type // requirements for those compilers, but otherwise enable it by default. #if !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) # if !defined(__GNUC__) || (__GNUC__ >= 4) # define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 # endif // !defined(__GNUC__) || (__GNUC__ >= 4) #endif // !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) // With C++0x we can use a combination of enhanced SFINAE and static_assert to // generate better template error messages. As this technique is not yet widely // portable, we'll only enable it for tested compilers. #if !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) # if defined(__GNUC__) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # if defined(__GXX_EXPERIMENTAL_CXX0X__) # define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 # endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) # endif // defined(__GNUC__) # if defined(ASIO_MSVC) # if (_MSC_VER >= 1600) # define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 # endif // (_MSC_VER >= 1600) # endif // defined(ASIO_MSVC) # if defined(__clang__) # if __has_feature(__cxx_static_assert__) # define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 # endif // __has_feature(cxx_static_assert) # endif // defined(__clang__) #endif // !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) #if defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) # include "asio/async_result.hpp" #endif // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) namespace asio { namespace detail { #if defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) # if defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) template auto zero_arg_copyable_handler_test(Handler h, void*) -> decltype( sizeof(Handler(static_cast(h))), ((h)()), char(0)); template char (&zero_arg_copyable_handler_test(Handler, ...))[2]; template auto one_arg_handler_test(Handler h, Arg1* a1) -> decltype( sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))), ((h)(*a1)), char(0)); template char (&one_arg_handler_test(Handler h, ...))[2]; template auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) -> decltype( sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))), ((h)(*a1, *a2)), char(0)); template char (&two_arg_handler_test(Handler, ...))[2]; template auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) -> decltype( sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))), ((h)(*a1, ASIO_MOVE_CAST(Arg2)(*a2))), char(0)); template char (&two_arg_move_handler_test(Handler, ...))[2]; # define ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ static_assert(expr, msg); # else // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) # define ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) # endif // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) template T& lvref(); template T& lvref(T); template const T& clvref(); template const T& clvref(T); #if defined(ASIO_HAS_MOVE) template T rvref(); template T rvref(T); #else // defined(ASIO_HAS_MOVE) template const T& rvref(); template const T& rvref(T); #endif // defined(ASIO_HAS_MOVE) template char argbyv(T); template struct handler_type_requirements { }; #define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void()) asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::zero_arg_copyable_handler_test( \ asio::detail::clvref< \ asio_true_handler_type>(), 0)) == 1, \ "CompletionHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::clvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()(), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_READ_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, std::size_t)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "ReadHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_WRITE_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, std::size_t)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "WriteHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_ACCEPT_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::one_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0))) == 1, \ "AcceptHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ handler_type, handler, socket_type) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, socket_type)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_move_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "MoveAcceptHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::rvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_CONNECT_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::one_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0))) == 1, \ "ConnectHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_RANGE_CONNECT_HANDLER_CHECK( \ handler_type, handler, endpoint_type) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, endpoint_type)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "RangeConnectHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ handler_type, handler, iter_type) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, iter_type)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "IteratorConnectHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_RESOLVE_HANDLER_CHECK( \ handler_type, handler, range_type) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, range_type)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "ResolveHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_WAIT_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::one_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0))) == 1, \ "WaitHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_SIGNAL_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, int)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "SignalHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_HANDSHAKE_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::one_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0))) == 1, \ "HandshakeHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code, std::size_t)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::two_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0), \ static_cast(0))) == 1, \ "BufferedHandshakeHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref(), \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_SHUTDOWN_HANDLER_CHECK( \ handler_type, handler) \ \ typedef ASIO_HANDLER_TYPE(handler_type, \ void(asio::error_code)) \ asio_true_handler_type; \ \ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ sizeof(asio::detail::one_arg_handler_test( \ asio::detail::rvref< \ asio_true_handler_type>(), \ static_cast(0))) == 1, \ "ShutdownHandler type requirements not met") \ \ typedef asio::detail::handler_type_requirements< \ sizeof( \ asio::detail::argbyv( \ asio::detail::rvref< \ asio_true_handler_type>())) + \ sizeof( \ asio::detail::lvref< \ asio_true_handler_type>()( \ asio::detail::lvref()), \ char(0))> ASIO_UNUSED_TYPEDEF #else // !defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) #define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_READ_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_WRITE_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_ACCEPT_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ handler_type, handler, socket_type) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_CONNECT_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_RANGE_CONNECT_HANDLER_CHECK( \ handler_type, handler, iter_type) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ handler_type, handler, iter_type) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_RESOLVE_HANDLER_CHECK( \ handler_type, handler, iter_type) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_WAIT_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_SIGNAL_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_HANDSHAKE_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #define ASIO_SHUTDOWN_HANDLER_CHECK( \ handler_type, handler) \ typedef int ASIO_UNUSED_TYPEDEF #endif // !defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) } // namespace detail } // namespace asio #endif // ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP ================================================ FILE: src/third_party/asio/detail/handler_work.hpp ================================================ // // detail/handler_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_HANDLER_WORK_HPP #define ASIO_DETAIL_HANDLER_WORK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // A helper class template to allow completion handlers to be dispatched // through either the new executors framework or the old invocaton hook. The // primary template uses the new executors framework. template ::type> class handler_work { public: explicit handler_work(Handler& handler) ASIO_NOEXCEPT : io_executor_(), executor_(asio::get_associated_executor(handler, io_executor_)) { } handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT : io_executor_(io_ex), executor_(asio::get_associated_executor(handler, io_executor_)) { } static void start(Handler& handler) ASIO_NOEXCEPT { HandlerExecutor ex(asio::get_associated_executor(handler)); ex.on_work_started(); } static void start(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT { HandlerExecutor ex(asio::get_associated_executor(handler, io_ex)); ex.on_work_started(); io_ex.on_work_started(); } ~handler_work() { io_executor_.on_work_finished(); executor_.on_work_finished(); } template void complete(Function& function, Handler& handler) { executor_.dispatch(ASIO_MOVE_CAST(Function)(function), asio::get_associated_allocator(handler)); } private: // Disallow copying and assignment. handler_work(const handler_work&); handler_work& operator=(const handler_work&); IoExecutor io_executor_; HandlerExecutor executor_; }; // This specialisation dispatches a handler through the old invocation hook. // The specialisation is not strictly required for correctness, as the // system_executor will dispatch through the hook anyway. However, by doing // this we avoid an extra copy of the handler. template class handler_work { public: explicit handler_work(Handler&) ASIO_NOEXCEPT {} static void start(Handler&) ASIO_NOEXCEPT {} ~handler_work() {} template void complete(Function& function, Handler& handler) { asio_handler_invoke_helpers::invoke(function, handler); } private: // Disallow copying and assignment. handler_work(const handler_work&); handler_work& operator=(const handler_work&); }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_HANDLER_WORK_HPP ================================================ FILE: src/third_party/asio/detail/hash_map.hpp ================================================ // // detail/hash_map.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_HASH_MAP_HPP #define ASIO_DETAIL_HASH_MAP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/detail/assert.hpp" #include "asio/detail/noncopyable.hpp" #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # include "asio/detail/socket_types.hpp" #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { inline std::size_t calculate_hash_value(int i) { return static_cast(i); } inline std::size_t calculate_hash_value(void* p) { return reinterpret_cast(p) + (reinterpret_cast(p) >> 3); } #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) inline std::size_t calculate_hash_value(SOCKET s) { return static_cast(s); } #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Note: assumes K and V are POD types. template class hash_map : private noncopyable { public: // The type of a value in the map. typedef std::pair value_type; // The type of a non-const iterator over the hash map. typedef typename std::list::iterator iterator; // The type of a const iterator over the hash map. typedef typename std::list::const_iterator const_iterator; // Constructor. hash_map() : size_(0), buckets_(0), num_buckets_(0) { } // Destructor. ~hash_map() { delete[] buckets_; } // Get an iterator for the beginning of the map. iterator begin() { return values_.begin(); } // Get an iterator for the beginning of the map. const_iterator begin() const { return values_.begin(); } // Get an iterator for the end of the map. iterator end() { return values_.end(); } // Get an iterator for the end of the map. const_iterator end() const { return values_.end(); } // Check whether the map is empty. bool empty() const { return values_.empty(); } // Find an entry in the map. iterator find(const K& k) { if (num_buckets_) { size_t bucket = calculate_hash_value(k) % num_buckets_; iterator it = buckets_[bucket].first; if (it == values_.end()) return values_.end(); iterator end_it = buckets_[bucket].last; ++end_it; while (it != end_it) { if (it->first == k) return it; ++it; } } return values_.end(); } // Find an entry in the map. const_iterator find(const K& k) const { if (num_buckets_) { size_t bucket = calculate_hash_value(k) % num_buckets_; const_iterator it = buckets_[bucket].first; if (it == values_.end()) return it; const_iterator end_it = buckets_[bucket].last; ++end_it; while (it != end_it) { if (it->first == k) return it; ++it; } } return values_.end(); } // Insert a new entry into the map. std::pair insert(const value_type& v) { if (size_ + 1 >= num_buckets_) rehash(hash_size(size_ + 1)); size_t bucket = calculate_hash_value(v.first) % num_buckets_; iterator it = buckets_[bucket].first; if (it == values_.end()) { buckets_[bucket].first = buckets_[bucket].last = values_insert(values_.end(), v); ++size_; return std::pair(buckets_[bucket].last, true); } iterator end_it = buckets_[bucket].last; ++end_it; while (it != end_it) { if (it->first == v.first) return std::pair(it, false); ++it; } buckets_[bucket].last = values_insert(end_it, v); ++size_; return std::pair(buckets_[bucket].last, true); } // Erase an entry from the map. void erase(iterator it) { ASIO_ASSERT(it != values_.end()); ASIO_ASSERT(num_buckets_ != 0); size_t bucket = calculate_hash_value(it->first) % num_buckets_; bool is_first = (it == buckets_[bucket].first); bool is_last = (it == buckets_[bucket].last); if (is_first && is_last) buckets_[bucket].first = buckets_[bucket].last = values_.end(); else if (is_first) ++buckets_[bucket].first; else if (is_last) --buckets_[bucket].last; values_erase(it); --size_; } // Erase a key from the map. void erase(const K& k) { iterator it = find(k); if (it != values_.end()) erase(it); } // Remove all entries from the map. void clear() { // Clear the values. values_.clear(); size_ = 0; // Initialise all buckets to empty. iterator end_it = values_.end(); for (size_t i = 0; i < num_buckets_; ++i) buckets_[i].first = buckets_[i].last = end_it; } private: // Calculate the hash size for the specified number of elements. static std::size_t hash_size(std::size_t num_elems) { static std::size_t sizes[] = { #if defined(ASIO_HASH_MAP_BUCKETS) ASIO_HASH_MAP_BUCKETS #else // ASIO_HASH_MAP_BUCKETS 3, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843 #endif // ASIO_HASH_MAP_BUCKETS }; const std::size_t nth_size = sizeof(sizes) / sizeof(std::size_t) - 1; for (std::size_t i = 0; i < nth_size; ++i) if (num_elems < sizes[i]) return sizes[i]; return sizes[nth_size]; } // Re-initialise the hash from the values already contained in the list. void rehash(std::size_t num_buckets) { if (num_buckets == num_buckets_) return; ASIO_ASSERT(num_buckets != 0); iterator end_iter = values_.end(); // Update number of buckets and initialise all buckets to empty. bucket_type* tmp = new bucket_type[num_buckets]; delete[] buckets_; buckets_ = tmp; num_buckets_ = num_buckets; for (std::size_t i = 0; i < num_buckets_; ++i) buckets_[i].first = buckets_[i].last = end_iter; // Put all values back into the hash. iterator iter = values_.begin(); while (iter != end_iter) { std::size_t bucket = calculate_hash_value(iter->first) % num_buckets_; if (buckets_[bucket].last == end_iter) { buckets_[bucket].first = buckets_[bucket].last = iter++; } else if (++buckets_[bucket].last == iter) { ++iter; } else { values_.splice(buckets_[bucket].last, values_, iter++); --buckets_[bucket].last; } } } // Insert an element into the values list by splicing from the spares list, // if a spare is available, and otherwise by inserting a new element. iterator values_insert(iterator it, const value_type& v) { if (spares_.empty()) { return values_.insert(it, v); } else { spares_.front() = v; values_.splice(it, spares_, spares_.begin()); return --it; } } // Erase an element from the values list by splicing it to the spares list. void values_erase(iterator it) { *it = value_type(); spares_.splice(spares_.begin(), values_, it); } // The number of elements in the hash. std::size_t size_; // The list of all values in the hash map. std::list values_; // The list of spare nodes waiting to be recycled. Assumes that POD types only // are stored in the hash map. std::list spares_; // The type for a bucket in the hash table. struct bucket_type { iterator first; iterator last; }; // The buckets in the hash. bucket_type* buckets_; // The number of buckets in the hash. std::size_t num_buckets_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_HASH_MAP_HPP ================================================ FILE: src/third_party/asio/detail/impl/buffer_sequence_adapter.ipp ================================================ // // detail/impl/buffer_sequence_adapter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP #define ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include #include #include #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class winrt_buffer_impl : public Microsoft::WRL::RuntimeClass< Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>, ABI::Windows::Storage::Streams::IBuffer, Windows::Storage::Streams::IBufferByteAccess> { public: explicit winrt_buffer_impl(const asio::const_buffer& b) { bytes_ = const_cast(static_cast(b.data())); length_ = b.size(); capacity_ = b.size(); } explicit winrt_buffer_impl(const asio::mutable_buffer& b) { bytes_ = static_cast(b.data()); length_ = 0; capacity_ = b.size(); } ~winrt_buffer_impl() { } STDMETHODIMP Buffer(byte** value) { *value = bytes_; return S_OK; } STDMETHODIMP get_Capacity(UINT32* value) { *value = capacity_; return S_OK; } STDMETHODIMP get_Length(UINT32 *value) { *value = length_; return S_OK; } STDMETHODIMP put_Length(UINT32 value) { if (value > capacity_) return E_INVALIDARG; length_ = value; return S_OK; } private: byte* bytes_; UINT32 length_; UINT32 capacity_; }; void buffer_sequence_adapter_base::init_native_buffer( buffer_sequence_adapter_base::native_buffer_type& buf, const asio::mutable_buffer& buffer) { std::memset(&buf, 0, sizeof(native_buffer_type)); Microsoft::WRL::ComPtr insp = Microsoft::WRL::Make(buffer); buf = reinterpret_cast(insp.Get()); } void buffer_sequence_adapter_base::init_native_buffer( buffer_sequence_adapter_base::native_buffer_type& buf, const asio::const_buffer& buffer) { std::memset(&buf, 0, sizeof(native_buffer_type)); Microsoft::WRL::ComPtr insp = Microsoft::WRL::Make(buffer); Platform::Object^ buf_obj = reinterpret_cast(insp.Get()); buf = reinterpret_cast(insp.Get()); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP ================================================ FILE: src/third_party/asio/detail/impl/descriptor_ops.ipp ================================================ // // detail/impl/descriptor_ops.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP #define ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/descriptor_ops.hpp" #include "asio/error.hpp" #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { namespace descriptor_ops { int open(const char* path, int flags, asio::error_code& ec) { errno = 0; int result = error_wrapper(::open(path, flags), ec); if (result >= 0) ec = asio::error_code(); return result; } int close(int d, state_type& state, asio::error_code& ec) { int result = 0; if (d != -1) { errno = 0; result = error_wrapper(::close(d), ec); if (result != 0 && (ec == asio::error::would_block || ec == asio::error::try_again)) { // According to UNIX Network Programming Vol. 1, it is possible for // close() to fail with EWOULDBLOCK under certain circumstances. What // isn't clear is the state of the descriptor after this error. The one // current OS where this behaviour is seen, Windows, says that the socket // remains open. Therefore we'll put the descriptor back into blocking // mode and have another attempt at closing it. #if defined(__SYMBIAN32__) int flags = ::fcntl(d, F_GETFL, 0); if (flags >= 0) ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK); #else // defined(__SYMBIAN32__) ioctl_arg_type arg = 0; ::ioctl(d, FIONBIO, &arg); #endif // defined(__SYMBIAN32__) state &= ~non_blocking; errno = 0; result = error_wrapper(::close(d), ec); } } if (result == 0) ec = asio::error_code(); return result; } bool set_user_non_blocking(int d, state_type& state, bool value, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return false; } errno = 0; #if defined(__SYMBIAN32__) int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec); if (result >= 0) { errno = 0; int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK)); result = error_wrapper(::fcntl(d, F_SETFL, flag), ec); } #else // defined(__SYMBIAN32__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec); #endif // defined(__SYMBIAN32__) if (result >= 0) { ec = asio::error_code(); if (value) state |= user_set_non_blocking; else { // Clearing the user-set non-blocking mode always overrides any // internally-set non-blocking flag. Any subsequent asynchronous // operations will need to re-enable non-blocking I/O. state &= ~(user_set_non_blocking | internal_non_blocking); } return true; } return false; } bool set_internal_non_blocking(int d, state_type& state, bool value, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return false; } if (!value && (state & user_set_non_blocking)) { // It does not make sense to clear the internal non-blocking flag if the // user still wants non-blocking behaviour. Return an error and let the // caller figure out whether to update the user-set non-blocking flag. ec = asio::error::invalid_argument; return false; } errno = 0; #if defined(__SYMBIAN32__) int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec); if (result >= 0) { errno = 0; int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK)); result = error_wrapper(::fcntl(d, F_SETFL, flag), ec); } #else // defined(__SYMBIAN32__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec); #endif // defined(__SYMBIAN32__) if (result >= 0) { ec = asio::error_code(); if (value) state |= internal_non_blocking; else state &= ~internal_non_blocking; return true; } return false; } std::size_t sync_read(int d, state_type state, buf* bufs, std::size_t count, bool all_empty, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return 0; } // A request to read 0 bytes on a stream is a no-op. if (all_empty) { ec = asio::error_code(); return 0; } // Read some data. for (;;) { // Try to complete the operation without blocking. errno = 0; signed_size_type bytes = error_wrapper(::readv( d, bufs, static_cast(count)), ec); // Check if operation succeeded. if (bytes > 0) return bytes; // Check for EOF. if (bytes == 0) { ec = asio::error::eof; return 0; } // Operation failed. if ((state & user_set_non_blocking) || (ec != asio::error::would_block && ec != asio::error::try_again)) return 0; // Wait for descriptor to become ready. if (descriptor_ops::poll_read(d, 0, ec) < 0) return 0; } } bool non_blocking_read(int d, buf* bufs, std::size_t count, asio::error_code& ec, std::size_t& bytes_transferred) { for (;;) { // Read some data. errno = 0; signed_size_type bytes = error_wrapper(::readv( d, bufs, static_cast(count)), ec); // Check for end of stream. if (bytes == 0) { ec = asio::error::eof; return true; } // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == asio::error::would_block || ec == asio::error::try_again) return false; // Operation is complete. if (bytes > 0) { ec = asio::error_code(); bytes_transferred = bytes; } else bytes_transferred = 0; return true; } } std::size_t sync_write(int d, state_type state, const buf* bufs, std::size_t count, bool all_empty, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return 0; } // A request to write 0 bytes on a stream is a no-op. if (all_empty) { ec = asio::error_code(); return 0; } // Write some data. for (;;) { // Try to complete the operation without blocking. errno = 0; signed_size_type bytes = error_wrapper(::writev( d, bufs, static_cast(count)), ec); // Check if operation succeeded. if (bytes > 0) return bytes; // Operation failed. if ((state & user_set_non_blocking) || (ec != asio::error::would_block && ec != asio::error::try_again)) return 0; // Wait for descriptor to become ready. if (descriptor_ops::poll_write(d, 0, ec) < 0) return 0; } } bool non_blocking_write(int d, const buf* bufs, std::size_t count, asio::error_code& ec, std::size_t& bytes_transferred) { for (;;) { // Write some data. errno = 0; signed_size_type bytes = error_wrapper(::writev( d, bufs, static_cast(count)), ec); // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == asio::error::would_block || ec == asio::error::try_again) return false; // Operation is complete. if (bytes >= 0) { ec = asio::error_code(); bytes_transferred = bytes; } else bytes_transferred = 0; return true; } } int ioctl(int d, state_type& state, long cmd, ioctl_arg_type* arg, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return -1; } errno = 0; int result = error_wrapper(::ioctl(d, cmd, arg), ec); if (result >= 0) { ec = asio::error_code(); // When updating the non-blocking mode we always perform the ioctl syscall, // even if the flags would otherwise indicate that the descriptor is // already in the correct state. This ensures that the underlying // descriptor is put into the state that has been requested by the user. If // the ioctl syscall was successful then we need to update the flags to // match. if (cmd == static_cast(FIONBIO)) { if (*arg) { state |= user_set_non_blocking; } else { // Clearing the non-blocking mode always overrides any internally-set // non-blocking flag. Any subsequent asynchronous operations will need // to re-enable non-blocking I/O. state &= ~(user_set_non_blocking | internal_non_blocking); } } } return result; } int fcntl(int d, int cmd, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return -1; } errno = 0; int result = error_wrapper(::fcntl(d, cmd), ec); if (result != -1) ec = asio::error_code(); return result; } int fcntl(int d, int cmd, long arg, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return -1; } errno = 0; int result = error_wrapper(::fcntl(d, cmd, arg), ec); if (result != -1) ec = asio::error_code(); return result; } int poll_read(int d, state_type state, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return -1; } pollfd fds; fds.fd = d; fds.events = POLLIN; fds.revents = 0; int timeout = (state & user_set_non_blocking) ? 0 : -1; errno = 0; int result = error_wrapper(::poll(&fds, 1, timeout), ec); if (result == 0) ec = (state & user_set_non_blocking) ? asio::error::would_block : asio::error_code(); else if (result > 0) ec = asio::error_code(); return result; } int poll_write(int d, state_type state, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return -1; } pollfd fds; fds.fd = d; fds.events = POLLOUT; fds.revents = 0; int timeout = (state & user_set_non_blocking) ? 0 : -1; errno = 0; int result = error_wrapper(::poll(&fds, 1, timeout), ec); if (result == 0) ec = (state & user_set_non_blocking) ? asio::error::would_block : asio::error_code(); else if (result > 0) ec = asio::error_code(); return result; } int poll_error(int d, state_type state, asio::error_code& ec) { if (d == -1) { ec = asio::error::bad_descriptor; return -1; } pollfd fds; fds.fd = d; fds.events = POLLPRI | POLLERR | POLLHUP; fds.revents = 0; int timeout = (state & user_set_non_blocking) ? 0 : -1; errno = 0; int result = error_wrapper(::poll(&fds, 1, timeout), ec); if (result == 0) ec = (state & user_set_non_blocking) ? asio::error::would_block : asio::error_code(); else if (result > 0) ec = asio::error_code(); return result; } } // namespace descriptor_ops } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) #endif // ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP ================================================ FILE: src/third_party/asio/detail/impl/dev_poll_reactor.hpp ================================================ // // detail/impl/dev_poll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP #define ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_DEV_POLL) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template void dev_poll_reactor::add_timer_queue(timer_queue& queue) { do_add_timer_queue(queue); } template void dev_poll_reactor::remove_timer_queue(timer_queue& queue) { do_remove_timer_queue(queue); } template void dev_poll_reactor::schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); if (shutdown_) { scheduler_.post_immediate_completion(op, false); return; } bool earliest = queue.enqueue_timer(time, timer, op); scheduler_.work_started(); if (earliest) interrupter_.interrupt(); } template std::size_t dev_poll_reactor::cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue ops; std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); lock.unlock(); scheduler_.post_deferred_completions(ops); return n; } template void dev_poll_reactor::move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue ops; queue.cancel_timer(target, ops); queue.move_timer(target, source); lock.unlock(); scheduler_.post_deferred_completions(ops); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_DEV_POLL) #endif // ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/impl/dev_poll_reactor.ipp ================================================ // // detail/impl/dev_poll_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP #define ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_DEV_POLL) #include "asio/detail/dev_poll_reactor.hpp" #include "asio/detail/assert.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { dev_poll_reactor::dev_poll_reactor(asio::execution_context& ctx) : asio::detail::execution_context_service_base(ctx), scheduler_(use_service(ctx)), mutex_(), dev_poll_fd_(do_dev_poll_create()), interrupter_(), shutdown_(false) { // Add the interrupter's descriptor to /dev/poll. ::pollfd ev = { 0, 0, 0 }; ev.fd = interrupter_.read_descriptor(); ev.events = POLLIN | POLLERR; ev.revents = 0; ::write(dev_poll_fd_, &ev, sizeof(ev)); } dev_poll_reactor::~dev_poll_reactor() { shutdown(); ::close(dev_poll_fd_); } void dev_poll_reactor::shutdown() { asio::detail::mutex::scoped_lock lock(mutex_); shutdown_ = true; lock.unlock(); op_queue ops; for (int i = 0; i < max_ops; ++i) op_queue_[i].get_all_operations(ops); timer_queues_.get_all_timers(ops); scheduler_.abandon_operations(ops); } void dev_poll_reactor::notify_fork( asio::execution_context::fork_event fork_ev) { if (fork_ev == asio::execution_context::fork_child) { detail::mutex::scoped_lock lock(mutex_); if (dev_poll_fd_ != -1) ::close(dev_poll_fd_); dev_poll_fd_ = -1; dev_poll_fd_ = do_dev_poll_create(); interrupter_.recreate(); // Add the interrupter's descriptor to /dev/poll. ::pollfd ev = { 0, 0, 0 }; ev.fd = interrupter_.read_descriptor(); ev.events = POLLIN | POLLERR; ev.revents = 0; ::write(dev_poll_fd_, &ev, sizeof(ev)); // Re-register all descriptors with /dev/poll. The changes will be written // to the /dev/poll descriptor the next time the reactor is run. for (int i = 0; i < max_ops; ++i) { reactor_op_queue::iterator iter = op_queue_[i].begin(); reactor_op_queue::iterator end = op_queue_[i].end(); for (; iter != end; ++iter) { ::pollfd& pending_ev = add_pending_event_change(iter->first); pending_ev.events |= POLLERR | POLLHUP; switch (i) { case read_op: pending_ev.events |= POLLIN; break; case write_op: pending_ev.events |= POLLOUT; break; case except_op: pending_ev.events |= POLLPRI; break; default: break; } } } interrupter_.interrupt(); } } void dev_poll_reactor::init_task() { scheduler_.init_task(); } int dev_poll_reactor::register_descriptor(socket_type, per_descriptor_data&) { return 0; } int dev_poll_reactor::register_internal_descriptor(int op_type, socket_type descriptor, per_descriptor_data&, reactor_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue_[op_type].enqueue_operation(descriptor, op); ::pollfd& ev = add_pending_event_change(descriptor); ev.events = POLLERR | POLLHUP; switch (op_type) { case read_op: ev.events |= POLLIN; break; case write_op: ev.events |= POLLOUT; break; case except_op: ev.events |= POLLPRI; break; default: break; } interrupter_.interrupt(); return 0; } void dev_poll_reactor::move_descriptor(socket_type, dev_poll_reactor::per_descriptor_data&, dev_poll_reactor::per_descriptor_data&) { } void dev_poll_reactor::start_op(int op_type, socket_type descriptor, dev_poll_reactor::per_descriptor_data&, reactor_op* op, bool is_continuation, bool allow_speculative) { asio::detail::mutex::scoped_lock lock(mutex_); if (shutdown_) { post_immediate_completion(op, is_continuation); return; } if (allow_speculative) { if (op_type != read_op || !op_queue_[except_op].has_operation(descriptor)) { if (!op_queue_[op_type].has_operation(descriptor)) { if (op->perform()) { lock.unlock(); scheduler_.post_immediate_completion(op, is_continuation); return; } } } } bool first = op_queue_[op_type].enqueue_operation(descriptor, op); scheduler_.work_started(); if (first) { ::pollfd& ev = add_pending_event_change(descriptor); ev.events = POLLERR | POLLHUP; if (op_type == read_op || op_queue_[read_op].has_operation(descriptor)) ev.events |= POLLIN; if (op_type == write_op || op_queue_[write_op].has_operation(descriptor)) ev.events |= POLLOUT; if (op_type == except_op || op_queue_[except_op].has_operation(descriptor)) ev.events |= POLLPRI; interrupter_.interrupt(); } } void dev_poll_reactor::cancel_ops(socket_type descriptor, dev_poll_reactor::per_descriptor_data&) { asio::detail::mutex::scoped_lock lock(mutex_); cancel_ops_unlocked(descriptor, asio::error::operation_aborted); } void dev_poll_reactor::deregister_descriptor(socket_type descriptor, dev_poll_reactor::per_descriptor_data&, bool) { asio::detail::mutex::scoped_lock lock(mutex_); // Remove the descriptor from /dev/poll. ::pollfd& ev = add_pending_event_change(descriptor); ev.events = POLLREMOVE; interrupter_.interrupt(); // Cancel any outstanding operations associated with the descriptor. cancel_ops_unlocked(descriptor, asio::error::operation_aborted); } void dev_poll_reactor::deregister_internal_descriptor( socket_type descriptor, dev_poll_reactor::per_descriptor_data&) { asio::detail::mutex::scoped_lock lock(mutex_); // Remove the descriptor from /dev/poll. Since this function is only called // during a fork, we can apply the change immediately. ::pollfd ev = { 0, 0, 0 }; ev.fd = descriptor; ev.events = POLLREMOVE; ev.revents = 0; ::write(dev_poll_fd_, &ev, sizeof(ev)); // Destroy all operations associated with the descriptor. op_queue ops; asio::error_code ec; for (int i = 0; i < max_ops; ++i) op_queue_[i].cancel_operations(descriptor, ops, ec); } void dev_poll_reactor::cleanup_descriptor_data( dev_poll_reactor::per_descriptor_data&) { } void dev_poll_reactor::run(long usec, op_queue& ops) { asio::detail::mutex::scoped_lock lock(mutex_); // We can return immediately if there's no work to do and the reactor is // not supposed to block. if (usec == 0 && op_queue_[read_op].empty() && op_queue_[write_op].empty() && op_queue_[except_op].empty() && timer_queues_.all_empty()) return; // Write the pending event registration changes to the /dev/poll descriptor. std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size(); if (events_size > 0) { errno = 0; int result = ::write(dev_poll_fd_, &pending_event_changes_[0], events_size); if (result != static_cast(events_size)) { asio::error_code ec = asio::error_code( errno, asio::error::get_system_category()); for (std::size_t i = 0; i < pending_event_changes_.size(); ++i) { int descriptor = pending_event_changes_[i].fd; for (int j = 0; j < max_ops; ++j) op_queue_[j].cancel_operations(descriptor, ops, ec); } } pending_event_changes_.clear(); pending_event_change_index_.clear(); } // Calculate timeout. int timeout; if (usec == 0) timeout = 0; else { timeout = (usec < 0) ? -1 : ((usec - 1) / 1000 + 1); timeout = get_timeout(timeout); } lock.unlock(); // Block on the /dev/poll descriptor. ::pollfd events[128] = { { 0, 0, 0 } }; ::dvpoll dp = { 0, 0, 0 }; dp.dp_fds = events; dp.dp_nfds = 128; dp.dp_timeout = timeout; int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp); lock.lock(); // Dispatch the waiting events. for (int i = 0; i < num_events; ++i) { int descriptor = events[i].fd; if (descriptor == interrupter_.read_descriptor()) { interrupter_.reset(); } else { bool more_reads = false; bool more_writes = false; bool more_except = false; // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. if (events[i].events & (POLLPRI | POLLERR | POLLHUP)) more_except = op_queue_[except_op].perform_operations(descriptor, ops); else more_except = op_queue_[except_op].has_operation(descriptor); if (events[i].events & (POLLIN | POLLERR | POLLHUP)) more_reads = op_queue_[read_op].perform_operations(descriptor, ops); else more_reads = op_queue_[read_op].has_operation(descriptor); if (events[i].events & (POLLOUT | POLLERR | POLLHUP)) more_writes = op_queue_[write_op].perform_operations(descriptor, ops); else more_writes = op_queue_[write_op].has_operation(descriptor); if ((events[i].events & (POLLERR | POLLHUP)) != 0 && !more_except && !more_reads && !more_writes) { // If we have an event and no operations associated with the // descriptor then we need to delete the descriptor from /dev/poll. // The poll operation can produce POLLHUP or POLLERR events when there // is no operation pending, so if we do not remove the descriptor we // can end up in a tight polling loop. ::pollfd ev = { 0, 0, 0 }; ev.fd = descriptor; ev.events = POLLREMOVE; ev.revents = 0; ::write(dev_poll_fd_, &ev, sizeof(ev)); } else { ::pollfd ev = { 0, 0, 0 }; ev.fd = descriptor; ev.events = POLLERR | POLLHUP; if (more_reads) ev.events |= POLLIN; if (more_writes) ev.events |= POLLOUT; if (more_except) ev.events |= POLLPRI; ev.revents = 0; int result = ::write(dev_poll_fd_, &ev, sizeof(ev)); if (result != sizeof(ev)) { asio::error_code ec(errno, asio::error::get_system_category()); for (int j = 0; j < max_ops; ++j) op_queue_[j].cancel_operations(descriptor, ops, ec); } } } } timer_queues_.get_ready_timers(ops); } void dev_poll_reactor::interrupt() { interrupter_.interrupt(); } int dev_poll_reactor::do_dev_poll_create() { int fd = ::open("/dev/poll", O_RDWR); if (fd == -1) { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "/dev/poll"); } return fd; } void dev_poll_reactor::do_add_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.insert(&queue); } void dev_poll_reactor::do_remove_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.erase(&queue); } int dev_poll_reactor::get_timeout(int msec) { // By default we will wait no longer than 5 minutes. This will ensure that // any changes to the system clock are detected after no longer than this. const int max_msec = 5 * 60 * 1000; return timer_queues_.wait_duration_msec( (msec < 0 || max_msec < msec) ? max_msec : msec); } void dev_poll_reactor::cancel_ops_unlocked(socket_type descriptor, const asio::error_code& ec) { bool need_interrupt = false; op_queue ops; for (int i = 0; i < max_ops; ++i) need_interrupt = op_queue_[i].cancel_operations( descriptor, ops, ec) || need_interrupt; scheduler_.post_deferred_completions(ops); if (need_interrupt) interrupter_.interrupt(); } ::pollfd& dev_poll_reactor::add_pending_event_change(int descriptor) { hash_map::iterator iter = pending_event_change_index_.find(descriptor); if (iter == pending_event_change_index_.end()) { std::size_t index = pending_event_changes_.size(); pending_event_changes_.reserve(pending_event_changes_.size() + 1); pending_event_change_index_.insert(std::make_pair(descriptor, index)); pending_event_changes_.push_back(::pollfd()); pending_event_changes_[index].fd = descriptor; pending_event_changes_[index].revents = 0; return pending_event_changes_[index]; } else { return pending_event_changes_[iter->second]; } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_DEV_POLL) #endif // ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP ================================================ FILE: src/third_party/asio/detail/impl/epoll_reactor.hpp ================================================ // // detail/impl/epoll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP #define ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if defined(ASIO_HAS_EPOLL) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template void epoll_reactor::add_timer_queue(timer_queue& queue) { do_add_timer_queue(queue); } template void epoll_reactor::remove_timer_queue(timer_queue& queue) { do_remove_timer_queue(queue); } template void epoll_reactor::schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op) { mutex::scoped_lock lock(mutex_); if (shutdown_) { scheduler_.post_immediate_completion(op, false); return; } bool earliest = queue.enqueue_timer(time, timer, op); scheduler_.work_started(); if (earliest) update_timeout(); } template std::size_t epoll_reactor::cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_); op_queue ops; std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); lock.unlock(); scheduler_.post_deferred_completions(ops); return n; } template void epoll_reactor::move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source) { mutex::scoped_lock lock(mutex_); op_queue ops; queue.cancel_timer(target, ops); queue.move_timer(target, source); lock.unlock(); scheduler_.post_deferred_completions(ops); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_EPOLL) #endif // ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/impl/epoll_reactor.ipp ================================================ // // detail/impl/epoll_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP #define ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_EPOLL) #include #include #include "asio/detail/epoll_reactor.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #if defined(ASIO_HAS_TIMERFD) # include #endif // defined(ASIO_HAS_TIMERFD) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { epoll_reactor::epoll_reactor(asio::execution_context& ctx) : execution_context_service_base(ctx), scheduler_(use_service(ctx)), mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING( REACTOR_REGISTRATION, scheduler_.concurrency_hint())), interrupter_(), epoll_fd_(do_epoll_create()), timer_fd_(do_timerfd_create()), shutdown_(false), registered_descriptors_mutex_(mutex_.enabled()) { // Add the interrupter's descriptor to epoll. epoll_event ev = { 0, { 0 } }; ev.events = EPOLLIN | EPOLLERR | EPOLLET; ev.data.ptr = &interrupter_; epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev); interrupter_.interrupt(); // Add the timer descriptor to epoll. if (timer_fd_ != -1) { ev.events = EPOLLIN | EPOLLERR; ev.data.ptr = &timer_fd_; epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev); } } epoll_reactor::~epoll_reactor() { if (epoll_fd_ != -1) close(epoll_fd_); if (timer_fd_ != -1) close(timer_fd_); } void epoll_reactor::shutdown() { mutex::scoped_lock lock(mutex_); shutdown_ = true; lock.unlock(); op_queue ops; while (descriptor_state* state = registered_descriptors_.first()) { for (int i = 0; i < max_ops; ++i) ops.push(state->op_queue_[i]); state->shutdown_ = true; registered_descriptors_.free(state); } timer_queues_.get_all_timers(ops); scheduler_.abandon_operations(ops); } void epoll_reactor::notify_fork( asio::execution_context::fork_event fork_ev) { if (fork_ev == asio::execution_context::fork_child) { if (epoll_fd_ != -1) ::close(epoll_fd_); epoll_fd_ = -1; epoll_fd_ = do_epoll_create(); if (timer_fd_ != -1) ::close(timer_fd_); timer_fd_ = -1; timer_fd_ = do_timerfd_create(); interrupter_.recreate(); // Add the interrupter's descriptor to epoll. epoll_event ev = { 0, { 0 } }; ev.events = EPOLLIN | EPOLLERR | EPOLLET; ev.data.ptr = &interrupter_; epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev); interrupter_.interrupt(); // Add the timer descriptor to epoll. if (timer_fd_ != -1) { ev.events = EPOLLIN | EPOLLERR; ev.data.ptr = &timer_fd_; epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev); } update_timeout(); // Re-register all descriptors with epoll. mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); for (descriptor_state* state = registered_descriptors_.first(); state != 0; state = state->next_) { ev.events = state->registered_events_; ev.data.ptr = state; int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev); if (result != 0) { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "epoll re-registration"); } } } } void epoll_reactor::init_task() { scheduler_.init_task(); } int epoll_reactor::register_descriptor(socket_type descriptor, epoll_reactor::per_descriptor_data& descriptor_data) { descriptor_data = allocate_descriptor_state(); ASIO_HANDLER_REACTOR_REGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); { mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); descriptor_data->reactor_ = this; descriptor_data->descriptor_ = descriptor; descriptor_data->shutdown_ = false; for (int i = 0; i < max_ops; ++i) descriptor_data->try_speculative_[i] = true; } epoll_event ev = { 0, { 0 } }; ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET; descriptor_data->registered_events_ = ev.events; ev.data.ptr = descriptor_data; int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); if (result != 0) { if (errno == EPERM) { // This file descriptor type is not supported by epoll. However, if it is // a regular file then operations on it will not block. We will allow // this descriptor to be used and fail later if an operation on it would // otherwise require a trip through the reactor. descriptor_data->registered_events_ = 0; return 0; } return errno; } return 0; } int epoll_reactor::register_internal_descriptor( int op_type, socket_type descriptor, epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op) { descriptor_data = allocate_descriptor_state(); ASIO_HANDLER_REACTOR_REGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); { mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); descriptor_data->reactor_ = this; descriptor_data->descriptor_ = descriptor; descriptor_data->shutdown_ = false; descriptor_data->op_queue_[op_type].push(op); for (int i = 0; i < max_ops; ++i) descriptor_data->try_speculative_[i] = true; } epoll_event ev = { 0, { 0 } }; ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET; descriptor_data->registered_events_ = ev.events; ev.data.ptr = descriptor_data; int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); if (result != 0) return errno; return 0; } void epoll_reactor::move_descriptor(socket_type, epoll_reactor::per_descriptor_data& target_descriptor_data, epoll_reactor::per_descriptor_data& source_descriptor_data) { target_descriptor_data = source_descriptor_data; source_descriptor_data = 0; } void epoll_reactor::start_op(int op_type, socket_type descriptor, epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op, bool is_continuation, bool allow_speculative) { if (!descriptor_data) { op->ec_ = asio::error::bad_descriptor; post_immediate_completion(op, is_continuation); return; } mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (descriptor_data->shutdown_) { post_immediate_completion(op, is_continuation); return; } if (descriptor_data->op_queue_[op_type].empty()) { if (allow_speculative && (op_type != read_op || descriptor_data->op_queue_[except_op].empty())) { if (descriptor_data->try_speculative_[op_type]) { if (reactor_op::status status = op->perform()) { if (status == reactor_op::done_and_exhausted) if (descriptor_data->registered_events_ != 0) descriptor_data->try_speculative_[op_type] = false; descriptor_lock.unlock(); scheduler_.post_immediate_completion(op, is_continuation); return; } } if (descriptor_data->registered_events_ == 0) { op->ec_ = asio::error::operation_not_supported; scheduler_.post_immediate_completion(op, is_continuation); return; } if (op_type == write_op) { if ((descriptor_data->registered_events_ & EPOLLOUT) == 0) { epoll_event ev = { 0, { 0 } }; ev.events = descriptor_data->registered_events_ | EPOLLOUT; ev.data.ptr = descriptor_data; if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev) == 0) { descriptor_data->registered_events_ |= ev.events; } else { op->ec_ = asio::error_code(errno, asio::error::get_system_category()); scheduler_.post_immediate_completion(op, is_continuation); return; } } } } else if (descriptor_data->registered_events_ == 0) { op->ec_ = asio::error::operation_not_supported; scheduler_.post_immediate_completion(op, is_continuation); return; } else { if (op_type == write_op) { descriptor_data->registered_events_ |= EPOLLOUT; } epoll_event ev = { 0, { 0 } }; ev.events = descriptor_data->registered_events_; ev.data.ptr = descriptor_data; epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); } } descriptor_data->op_queue_[op_type].push(op); scheduler_.work_started(); } void epoll_reactor::cancel_ops(socket_type, epoll_reactor::per_descriptor_data& descriptor_data) { if (!descriptor_data) return; mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); op_queue ops; for (int i = 0; i < max_ops; ++i) { while (reactor_op* op = descriptor_data->op_queue_[i].front()) { op->ec_ = asio::error::operation_aborted; descriptor_data->op_queue_[i].pop(); ops.push(op); } } descriptor_lock.unlock(); scheduler_.post_deferred_completions(ops); } void epoll_reactor::deregister_descriptor(socket_type descriptor, epoll_reactor::per_descriptor_data& descriptor_data, bool closing) { if (!descriptor_data) return; mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (!descriptor_data->shutdown_) { if (closing) { // The descriptor will be automatically removed from the epoll set when // it is closed. } else if (descriptor_data->registered_events_ != 0) { epoll_event ev = { 0, { 0 } }; epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev); } op_queue ops; for (int i = 0; i < max_ops; ++i) { while (reactor_op* op = descriptor_data->op_queue_[i].front()) { op->ec_ = asio::error::operation_aborted; descriptor_data->op_queue_[i].pop(); ops.push(op); } } descriptor_data->descriptor_ = -1; descriptor_data->shutdown_ = true; descriptor_lock.unlock(); ASIO_HANDLER_REACTOR_DEREGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); scheduler_.post_deferred_completions(ops); // Leave descriptor_data set so that it will be freed by the subsequent // call to cleanup_descriptor_data. } else { // We are shutting down, so prevent cleanup_descriptor_data from freeing // the descriptor_data object and let the destructor free it instead. descriptor_data = 0; } } void epoll_reactor::deregister_internal_descriptor(socket_type descriptor, epoll_reactor::per_descriptor_data& descriptor_data) { if (!descriptor_data) return; mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (!descriptor_data->shutdown_) { epoll_event ev = { 0, { 0 } }; epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev); op_queue ops; for (int i = 0; i < max_ops; ++i) ops.push(descriptor_data->op_queue_[i]); descriptor_data->descriptor_ = -1; descriptor_data->shutdown_ = true; descriptor_lock.unlock(); ASIO_HANDLER_REACTOR_DEREGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); // Leave descriptor_data set so that it will be freed by the subsequent // call to cleanup_descriptor_data. } else { // We are shutting down, so prevent cleanup_descriptor_data from freeing // the descriptor_data object and let the destructor free it instead. descriptor_data = 0; } } void epoll_reactor::cleanup_descriptor_data( per_descriptor_data& descriptor_data) { if (descriptor_data) { free_descriptor_state(descriptor_data); descriptor_data = 0; } } void epoll_reactor::run(long usec, op_queue& ops) { // This code relies on the fact that the scheduler queues the reactor task // behind all descriptor operations generated by this function. This means, // that by the time we reach this point, any previously returned descriptor // operations have already been dequeued. Therefore it is now safe for us to // reuse and return them for the scheduler to queue again. // Calculate timeout. Check the timer queues only if timerfd is not in use. int timeout; if (usec == 0) timeout = 0; else { timeout = (usec < 0) ? -1 : ((usec - 1) / 1000 + 1); if (timer_fd_ == -1) { mutex::scoped_lock lock(mutex_); timeout = get_timeout(timeout); } } // Block on the epoll descriptor. epoll_event events[128]; int num_events = epoll_wait(epoll_fd_, events, 128, timeout); #if defined(ASIO_ENABLE_HANDLER_TRACKING) // Trace the waiting events. for (int i = 0; i < num_events; ++i) { void* ptr = events[i].data.ptr; if (ptr == &interrupter_) { // Ignore. } # if defined(ASIO_HAS_TIMERFD) else if (ptr == &timer_fd_) { // Ignore. } # endif // defined(ASIO_HAS_TIMERFD) else { unsigned event_mask = 0; if ((events[i].events & EPOLLIN) != 0) event_mask |= ASIO_HANDLER_REACTOR_READ_EVENT; if ((events[i].events & EPOLLOUT)) event_mask |= ASIO_HANDLER_REACTOR_WRITE_EVENT; if ((events[i].events & (EPOLLERR | EPOLLHUP)) != 0) event_mask |= ASIO_HANDLER_REACTOR_ERROR_EVENT; ASIO_HANDLER_REACTOR_EVENTS((context(), reinterpret_cast(ptr), event_mask)); } } #endif // defined(ASIO_ENABLE_HANDLER_TRACKING) #if defined(ASIO_HAS_TIMERFD) bool check_timers = (timer_fd_ == -1); #else // defined(ASIO_HAS_TIMERFD) bool check_timers = true; #endif // defined(ASIO_HAS_TIMERFD) // Dispatch the waiting events. for (int i = 0; i < num_events; ++i) { void* ptr = events[i].data.ptr; if (ptr == &interrupter_) { // No need to reset the interrupter since we're leaving the descriptor // in a ready-to-read state and relying on edge-triggered notifications // to make it so that we only get woken up when the descriptor's epoll // registration is updated. #if defined(ASIO_HAS_TIMERFD) if (timer_fd_ == -1) check_timers = true; #else // defined(ASIO_HAS_TIMERFD) check_timers = true; #endif // defined(ASIO_HAS_TIMERFD) } #if defined(ASIO_HAS_TIMERFD) else if (ptr == &timer_fd_) { check_timers = true; } #endif // defined(ASIO_HAS_TIMERFD) else { // The descriptor operation doesn't count as work in and of itself, so we // don't call work_started() here. This still allows the scheduler to // stop if the only remaining operations are descriptor operations. descriptor_state* descriptor_data = static_cast(ptr); if (!ops.is_enqueued(descriptor_data)) { descriptor_data->set_ready_events(events[i].events); ops.push(descriptor_data); } else { descriptor_data->add_ready_events(events[i].events); } } } if (check_timers) { mutex::scoped_lock common_lock(mutex_); timer_queues_.get_ready_timers(ops); #if defined(ASIO_HAS_TIMERFD) if (timer_fd_ != -1) { itimerspec new_timeout; itimerspec old_timeout; int flags = get_timeout(new_timeout); timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); } #endif // defined(ASIO_HAS_TIMERFD) } } void epoll_reactor::interrupt() { epoll_event ev = { 0, { 0 } }; ev.events = EPOLLIN | EPOLLERR | EPOLLET; ev.data.ptr = &interrupter_; epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev); } int epoll_reactor::do_epoll_create() { #if defined(EPOLL_CLOEXEC) int fd = epoll_create1(EPOLL_CLOEXEC); #else // defined(EPOLL_CLOEXEC) int fd = -1; errno = EINVAL; #endif // defined(EPOLL_CLOEXEC) if (fd == -1 && (errno == EINVAL || errno == ENOSYS)) { fd = epoll_create(epoll_size); if (fd != -1) ::fcntl(fd, F_SETFD, FD_CLOEXEC); } if (fd == -1) { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "epoll"); } return fd; } int epoll_reactor::do_timerfd_create() { #if defined(ASIO_HAS_TIMERFD) # if defined(TFD_CLOEXEC) int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); # else // defined(TFD_CLOEXEC) int fd = -1; errno = EINVAL; # endif // defined(TFD_CLOEXEC) if (fd == -1 && errno == EINVAL) { fd = timerfd_create(CLOCK_MONOTONIC, 0); if (fd != -1) ::fcntl(fd, F_SETFD, FD_CLOEXEC); } return fd; #else // defined(ASIO_HAS_TIMERFD) return -1; #endif // defined(ASIO_HAS_TIMERFD) } epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state() { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING( REACTOR_IO, scheduler_.concurrency_hint())); } void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s) { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); registered_descriptors_.free(s); } void epoll_reactor::do_add_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.insert(&queue); } void epoll_reactor::do_remove_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.erase(&queue); } void epoll_reactor::update_timeout() { #if defined(ASIO_HAS_TIMERFD) if (timer_fd_ != -1) { itimerspec new_timeout; itimerspec old_timeout; int flags = get_timeout(new_timeout); timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); return; } #endif // defined(ASIO_HAS_TIMERFD) interrupt(); } int epoll_reactor::get_timeout(int msec) { // By default we will wait no longer than 5 minutes. This will ensure that // any changes to the system clock are detected after no longer than this. const int max_msec = 5 * 60 * 1000; return timer_queues_.wait_duration_msec( (msec < 0 || max_msec < msec) ? max_msec : msec); } #if defined(ASIO_HAS_TIMERFD) int epoll_reactor::get_timeout(itimerspec& ts) { ts.it_interval.tv_sec = 0; ts.it_interval.tv_nsec = 0; long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); ts.it_value.tv_sec = usec / 1000000; ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1; return usec ? 0 : TFD_TIMER_ABSTIME; } #endif // defined(ASIO_HAS_TIMERFD) struct epoll_reactor::perform_io_cleanup_on_block_exit { explicit perform_io_cleanup_on_block_exit(epoll_reactor* r) : reactor_(r), first_op_(0) { } ~perform_io_cleanup_on_block_exit() { if (first_op_) { // Post the remaining completed operations for invocation. if (!ops_.empty()) reactor_->scheduler_.post_deferred_completions(ops_); // A user-initiated operation has completed, but there's no need to // explicitly call work_finished() here. Instead, we'll take advantage of // the fact that the scheduler will call work_finished() once we return. } else { // No user-initiated operations have completed, so we need to compensate // for the work_finished() call that the scheduler will make once this // operation returns. reactor_->scheduler_.compensating_work_started(); } } epoll_reactor* reactor_; op_queue ops_; operation* first_op_; }; epoll_reactor::descriptor_state::descriptor_state(bool locking) : operation(&epoll_reactor::descriptor_state::do_complete), mutex_(locking) { } operation* epoll_reactor::descriptor_state::perform_io(uint32_t events) { mutex_.lock(); perform_io_cleanup_on_block_exit io_cleanup(reactor_); mutex::scoped_lock descriptor_lock(mutex_, mutex::scoped_lock::adopt_lock); // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI }; for (int j = max_ops - 1; j >= 0; --j) { if (events & (flag[j] | EPOLLERR | EPOLLHUP)) { try_speculative_[j] = true; while (reactor_op* op = op_queue_[j].front()) { if (reactor_op::status status = op->perform()) { op_queue_[j].pop(); io_cleanup.ops_.push(op); if (status == reactor_op::done_and_exhausted) { try_speculative_[j] = false; break; } } else break; } } } // The first operation will be returned for completion now. The others will // be posted for later by the io_cleanup object's destructor. io_cleanup.first_op_ = io_cleanup.ops_.front(); io_cleanup.ops_.pop(); return io_cleanup.first_op_; } void epoll_reactor::descriptor_state::do_complete( void* owner, operation* base, const asio::error_code& ec, std::size_t bytes_transferred) { if (owner) { descriptor_state* descriptor_data = static_cast(base); uint32_t events = static_cast(bytes_transferred); if (operation* op = descriptor_data->perform_io(events)) { op->complete(owner, ec, 0); } } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_EPOLL) #endif // ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP ================================================ FILE: src/third_party/asio/detail/impl/eventfd_select_interrupter.ipp ================================================ // // detail/impl/eventfd_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP #define ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_EVENTFD) #include #include #include #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 # include #else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 # include #endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 #include "asio/detail/cstdint.hpp" #include "asio/detail/eventfd_select_interrupter.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { eventfd_select_interrupter::eventfd_select_interrupter() { open_descriptors(); } void eventfd_select_interrupter::open_descriptors() { #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0); if (read_descriptor_ != -1) { ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC); } #else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 # if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK) write_descriptor_ = read_descriptor_ = ::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); # else // defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK) errno = EINVAL; write_descriptor_ = read_descriptor_ = -1; # endif // defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK) if (read_descriptor_ == -1 && errno == EINVAL) { write_descriptor_ = read_descriptor_ = ::eventfd(0, 0); if (read_descriptor_ != -1) { ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC); } } #endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 if (read_descriptor_ == -1) { int pipe_fds[2]; if (pipe(pipe_fds) == 0) { read_descriptor_ = pipe_fds[0]; ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC); write_descriptor_ = pipe_fds[1]; ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); ::fcntl(write_descriptor_, F_SETFD, FD_CLOEXEC); } else { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "eventfd_select_interrupter"); } } } eventfd_select_interrupter::~eventfd_select_interrupter() { close_descriptors(); } void eventfd_select_interrupter::close_descriptors() { if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_) ::close(write_descriptor_); if (read_descriptor_ != -1) ::close(read_descriptor_); } void eventfd_select_interrupter::recreate() { close_descriptors(); write_descriptor_ = -1; read_descriptor_ = -1; open_descriptors(); } void eventfd_select_interrupter::interrupt() { uint64_t counter(1UL); int result = ::write(write_descriptor_, &counter, sizeof(uint64_t)); (void)result; } bool eventfd_select_interrupter::reset() { if (write_descriptor_ == read_descriptor_) { for (;;) { // Only perform one read. The kernel maintains an atomic counter. uint64_t counter(0); errno = 0; int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t)); if (bytes_read < 0 && errno == EINTR) continue; bool was_interrupted = (bytes_read > 0); return was_interrupted; } } else { for (;;) { // Clear all data from the pipe. char data[1024]; int bytes_read = ::read(read_descriptor_, data, sizeof(data)); if (bytes_read < 0 && errno == EINTR) continue; bool was_interrupted = (bytes_read > 0); while (bytes_read == sizeof(data)) bytes_read = ::read(read_descriptor_, data, sizeof(data)); return was_interrupted; } } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_EVENTFD) #endif // ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP ================================================ FILE: src/third_party/asio/detail/impl/handler_tracking.ipp ================================================ // // detail/impl/handler_tracking.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP #define ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_CUSTOM_HANDLER_TRACKING) // The handler tracking implementation is provided by the user-specified header. #elif defined(ASIO_ENABLE_HANDLER_TRACKING) #include #include #include "asio/detail/handler_tracking.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) # include "asio/time_traits.hpp" #elif defined(ASIO_HAS_CHRONO) # include "asio/detail/chrono.hpp" # include "asio/detail/chrono_time_traits.hpp" # include "asio/wait_traits.hpp" #endif // defined(ASIO_HAS_BOOST_DATE_TIME) #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/socket_types.hpp" #elif !defined(ASIO_WINDOWS) # include #endif // !defined(ASIO_WINDOWS) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct handler_tracking_timestamp { uint64_t seconds; uint64_t microseconds; handler_tracking_timestamp() { #if defined(ASIO_HAS_BOOST_DATE_TIME) boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); boost::posix_time::time_duration now = boost::posix_time::microsec_clock::universal_time() - epoch; #elif defined(ASIO_HAS_CHRONO) typedef chrono_time_traits > traits_helper; traits_helper::posix_time_duration now( chrono::system_clock::now().time_since_epoch()); #endif seconds = static_cast(now.total_seconds()); microseconds = static_cast(now.total_microseconds() % 1000000); } }; struct handler_tracking::tracking_state { static_mutex mutex_; uint64_t next_id_; tss_ptr* current_completion_; }; handler_tracking::tracking_state* handler_tracking::get_state() { static tracking_state state = { ASIO_STATIC_MUTEX_INIT, 1, 0 }; return &state; } void handler_tracking::init() { static tracking_state* state = get_state(); state->mutex_.init(); static_mutex::scoped_lock lock(state->mutex_); if (state->current_completion_ == 0) state->current_completion_ = new tss_ptr; } void handler_tracking::creation(execution_context&, handler_tracking::tracked_handler& h, const char* object_type, void* object, uintmax_t /*native_handle*/, const char* op_name) { static tracking_state* state = get_state(); static_mutex::scoped_lock lock(state->mutex_); h.id_ = state->next_id_++; lock.unlock(); handler_tracking_timestamp timestamp; uint64_t current_id = 0; if (completion* current_completion = *state->current_completion_) current_id = current_completion->id_; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|%I64u*%I64u|%.20s@%p.%.50s\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|%llu*%llu|%.20s@%p.%.50s\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, current_id, h.id_, object_type, object, op_name); } handler_tracking::completion::completion( const handler_tracking::tracked_handler& h) : id_(h.id_), invoked_(false), next_(*get_state()->current_completion_) { *get_state()->current_completion_ = this; } handler_tracking::completion::~completion() { if (id_) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|%c%I64u|\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|%c%llu|\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, invoked_ ? '!' : '~', id_); } *get_state()->current_completion_ = next_; } void handler_tracking::completion::invocation_begin() { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, id_); invoked_ = true; } void handler_tracking::completion::invocation_begin( const asio::error_code& ec) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value()); invoked_ = true; } void handler_tracking::completion::invocation_begin( const asio::error_code& ec, std::size_t bytes_transferred) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,bytes_transferred=%I64u\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,bytes_transferred=%llu\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value(), static_cast(bytes_transferred)); invoked_ = true; } void handler_tracking::completion::invocation_begin( const asio::error_code& ec, int signal_number) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,signal_number=%d\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,signal_number=%d\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value(), signal_number); invoked_ = true; } void handler_tracking::completion::invocation_begin( const asio::error_code& ec, const char* arg) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,%.50s\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,%.50s\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value(), arg); invoked_ = true; } void handler_tracking::completion::invocation_end() { if (id_) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|<%I64u|\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|<%llu|\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, id_); id_ = 0; } } void handler_tracking::operation(execution_context&, const char* object_type, void* object, uintmax_t /*native_handle*/, const char* op_name) { static tracking_state* state = get_state(); handler_tracking_timestamp timestamp; unsigned long long current_id = 0; if (completion* current_completion = *state->current_completion_) current_id = current_completion->id_; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|%I64u|%.20s@%p.%.50s\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|%llu|%.20s@%p.%.50s\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, current_id, object_type, object, op_name); } void handler_tracking::reactor_registration(execution_context& /*context*/, uintmax_t /*native_handle*/, uintmax_t /*registration*/) { } void handler_tracking::reactor_deregistration(execution_context& /*context*/, uintmax_t /*native_handle*/, uintmax_t /*registration*/) { } void handler_tracking::reactor_events(execution_context& /*context*/, uintmax_t /*native_handle*/, unsigned /*events*/) { } void handler_tracking::reactor_operation( const tracked_handler& h, const char* op_name, const asio::error_code& ec) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, h.id_, op_name, ec.category().name(), ec.value()); } void handler_tracking::reactor_operation( const tracked_handler& h, const char* op_name, const asio::error_code& ec, std::size_t bytes_transferred) { handler_tracking_timestamp timestamp; write_line( #if defined(ASIO_WINDOWS) "@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d,bytes_transferred=%I64u\n", #else // defined(ASIO_WINDOWS) "@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d,bytes_transferred=%llu\n", #endif // defined(ASIO_WINDOWS) timestamp.seconds, timestamp.microseconds, h.id_, op_name, ec.category().name(), ec.value(), static_cast(bytes_transferred)); } void handler_tracking::write_line(const char* format, ...) { using namespace std; // For sprintf (or equivalent). va_list args; va_start(args, format); char line[256] = ""; #if defined(ASIO_HAS_SECURE_RTL) int length = vsprintf_s(line, sizeof(line), format, args); #else // defined(ASIO_HAS_SECURE_RTL) int length = vsprintf(line, format, args); #endif // defined(ASIO_HAS_SECURE_RTL) va_end(args); #if defined(ASIO_WINDOWS_RUNTIME) wchar_t wline[256] = L""; mbstowcs_s(0, wline, sizeof(wline) / sizeof(wchar_t), line, length); ::OutputDebugStringW(wline); #elif defined(ASIO_WINDOWS) HANDLE stderr_handle = ::GetStdHandle(STD_ERROR_HANDLE); DWORD bytes_written = 0; ::WriteFile(stderr_handle, line, length, &bytes_written, 0); #else // defined(ASIO_WINDOWS) ::write(STDERR_FILENO, line, length); #endif // defined(ASIO_WINDOWS) } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_ENABLE_HANDLER_TRACKING) #endif // ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP ================================================ FILE: src/third_party/asio/detail/impl/kqueue_reactor.hpp ================================================ // // detail/impl/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP #define ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_KQUEUE) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template void kqueue_reactor::add_timer_queue(timer_queue& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor. template void kqueue_reactor::remove_timer_queue(timer_queue& queue) { do_remove_timer_queue(queue); } template void kqueue_reactor::schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op) { mutex::scoped_lock lock(mutex_); if (shutdown_) { scheduler_.post_immediate_completion(op, false); return; } bool earliest = queue.enqueue_timer(time, timer, op); scheduler_.work_started(); if (earliest) interrupt(); } template std::size_t kqueue_reactor::cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_); op_queue ops; std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); lock.unlock(); scheduler_.post_deferred_completions(ops); return n; } template void kqueue_reactor::move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source) { mutex::scoped_lock lock(mutex_); op_queue ops; queue.cancel_timer(target, ops); queue.move_timer(target, source); lock.unlock(); scheduler_.post_deferred_completions(ops); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_KQUEUE) #endif // ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/impl/kqueue_reactor.ipp ================================================ // // detail/impl/kqueue_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP #define ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_KQUEUE) #include "asio/detail/kqueue_reactor.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" #if defined(__NetBSD__) # define ASIO_KQUEUE_EV_SET(ev, ident, filt, flags, fflags, data, udata) \ EV_SET(ev, ident, filt, flags, fflags, data, \ reinterpret_cast(static_cast(udata))) #else # define ASIO_KQUEUE_EV_SET(ev, ident, filt, flags, fflags, data, udata) \ EV_SET(ev, ident, filt, flags, fflags, data, udata) #endif namespace asio { namespace detail { kqueue_reactor::kqueue_reactor(asio::execution_context& ctx) : execution_context_service_base(ctx), scheduler_(use_service(ctx)), mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING( REACTOR_REGISTRATION, scheduler_.concurrency_hint())), kqueue_fd_(do_kqueue_create()), interrupter_(), shutdown_(false), registered_descriptors_mutex_(mutex_.enabled()) { struct kevent events[1]; ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(), EVFILT_READ, EV_ADD, 0, 0, &interrupter_); if (::kevent(kqueue_fd_, events, 1, 0, 0, 0) == -1) { asio::error_code error(errno, asio::error::get_system_category()); asio::detail::throw_error(error); } } kqueue_reactor::~kqueue_reactor() { close(kqueue_fd_); } void kqueue_reactor::shutdown() { mutex::scoped_lock lock(mutex_); shutdown_ = true; lock.unlock(); op_queue ops; while (descriptor_state* state = registered_descriptors_.first()) { for (int i = 0; i < max_ops; ++i) ops.push(state->op_queue_[i]); state->shutdown_ = true; registered_descriptors_.free(state); } timer_queues_.get_all_timers(ops); scheduler_.abandon_operations(ops); } void kqueue_reactor::notify_fork( asio::execution_context::fork_event fork_ev) { if (fork_ev == asio::execution_context::fork_child) { // The kqueue descriptor is automatically closed in the child. kqueue_fd_ = -1; kqueue_fd_ = do_kqueue_create(); interrupter_.recreate(); struct kevent events[2]; ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(), EVFILT_READ, EV_ADD, 0, 0, &interrupter_); if (::kevent(kqueue_fd_, events, 1, 0, 0, 0) == -1) { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "kqueue interrupter registration"); } // Re-register all descriptors with kqueue. mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); for (descriptor_state* state = registered_descriptors_.first(); state != 0; state = state->next_) { if (state->num_kevents_ > 0) { ASIO_KQUEUE_EV_SET(&events[0], state->descriptor_, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, state); ASIO_KQUEUE_EV_SET(&events[1], state->descriptor_, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, state); if (::kevent(kqueue_fd_, events, state->num_kevents_, 0, 0, 0) == -1) { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "kqueue re-registration"); } } } } } void kqueue_reactor::init_task() { scheduler_.init_task(); } int kqueue_reactor::register_descriptor(socket_type descriptor, kqueue_reactor::per_descriptor_data& descriptor_data) { descriptor_data = allocate_descriptor_state(); ASIO_HANDLER_REACTOR_REGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); mutex::scoped_lock lock(descriptor_data->mutex_); descriptor_data->descriptor_ = descriptor; descriptor_data->num_kevents_ = 0; descriptor_data->shutdown_ = false; return 0; } int kqueue_reactor::register_internal_descriptor( int op_type, socket_type descriptor, kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op) { descriptor_data = allocate_descriptor_state(); ASIO_HANDLER_REACTOR_REGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); mutex::scoped_lock lock(descriptor_data->mutex_); descriptor_data->descriptor_ = descriptor; descriptor_data->num_kevents_ = 1; descriptor_data->shutdown_ = false; descriptor_data->op_queue_[op_type].push(op); struct kevent events[1]; ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, descriptor_data); if (::kevent(kqueue_fd_, events, 1, 0, 0, 0) == -1) return errno; return 0; } void kqueue_reactor::move_descriptor(socket_type, kqueue_reactor::per_descriptor_data& target_descriptor_data, kqueue_reactor::per_descriptor_data& source_descriptor_data) { target_descriptor_data = source_descriptor_data; source_descriptor_data = 0; } void kqueue_reactor::start_op(int op_type, socket_type descriptor, kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op, bool is_continuation, bool allow_speculative) { if (!descriptor_data) { op->ec_ = asio::error::bad_descriptor; post_immediate_completion(op, is_continuation); return; } mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (descriptor_data->shutdown_) { post_immediate_completion(op, is_continuation); return; } if (descriptor_data->op_queue_[op_type].empty()) { static const int num_kevents[max_ops] = { 1, 2, 1 }; if (allow_speculative && (op_type != read_op || descriptor_data->op_queue_[except_op].empty())) { if (op->perform()) { descriptor_lock.unlock(); scheduler_.post_immediate_completion(op, is_continuation); return; } if (descriptor_data->num_kevents_ < num_kevents[op_type]) { struct kevent events[2]; ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, descriptor_data); ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, descriptor_data); if (::kevent(kqueue_fd_, events, num_kevents[op_type], 0, 0, 0) != -1) { descriptor_data->num_kevents_ = num_kevents[op_type]; } else { op->ec_ = asio::error_code(errno, asio::error::get_system_category()); scheduler_.post_immediate_completion(op, is_continuation); return; } } } else { if (descriptor_data->num_kevents_ < num_kevents[op_type]) descriptor_data->num_kevents_ = num_kevents[op_type]; struct kevent events[2]; ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, descriptor_data); ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, descriptor_data); ::kevent(kqueue_fd_, events, descriptor_data->num_kevents_, 0, 0, 0); } } descriptor_data->op_queue_[op_type].push(op); scheduler_.work_started(); } void kqueue_reactor::cancel_ops(socket_type, kqueue_reactor::per_descriptor_data& descriptor_data) { if (!descriptor_data) return; mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); op_queue ops; for (int i = 0; i < max_ops; ++i) { while (reactor_op* op = descriptor_data->op_queue_[i].front()) { op->ec_ = asio::error::operation_aborted; descriptor_data->op_queue_[i].pop(); ops.push(op); } } descriptor_lock.unlock(); scheduler_.post_deferred_completions(ops); } void kqueue_reactor::deregister_descriptor(socket_type descriptor, kqueue_reactor::per_descriptor_data& descriptor_data, bool closing) { if (!descriptor_data) return; mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (!descriptor_data->shutdown_) { if (closing) { // The descriptor will be automatically removed from the kqueue when it // is closed. } else { struct kevent events[2]; ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0); ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0); ::kevent(kqueue_fd_, events, descriptor_data->num_kevents_, 0, 0, 0); } op_queue ops; for (int i = 0; i < max_ops; ++i) { while (reactor_op* op = descriptor_data->op_queue_[i].front()) { op->ec_ = asio::error::operation_aborted; descriptor_data->op_queue_[i].pop(); ops.push(op); } } descriptor_data->descriptor_ = -1; descriptor_data->shutdown_ = true; descriptor_lock.unlock(); ASIO_HANDLER_REACTOR_DEREGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); scheduler_.post_deferred_completions(ops); // Leave descriptor_data set so that it will be freed by the subsequent // call to cleanup_descriptor_data. } else { // We are shutting down, so prevent cleanup_descriptor_data from freeing // the descriptor_data object and let the destructor free it instead. descriptor_data = 0; } } void kqueue_reactor::deregister_internal_descriptor(socket_type descriptor, kqueue_reactor::per_descriptor_data& descriptor_data) { if (!descriptor_data) return; mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (!descriptor_data->shutdown_) { struct kevent events[2]; ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0); ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0); ::kevent(kqueue_fd_, events, descriptor_data->num_kevents_, 0, 0, 0); op_queue ops; for (int i = 0; i < max_ops; ++i) ops.push(descriptor_data->op_queue_[i]); descriptor_data->descriptor_ = -1; descriptor_data->shutdown_ = true; descriptor_lock.unlock(); ASIO_HANDLER_REACTOR_DEREGISTRATION(( context(), static_cast(descriptor), reinterpret_cast(descriptor_data))); // Leave descriptor_data set so that it will be freed by the subsequent // call to cleanup_descriptor_data. } else { // We are shutting down, so prevent cleanup_descriptor_data from freeing // the descriptor_data object and let the destructor free it instead. descriptor_data = 0; } } void kqueue_reactor::cleanup_descriptor_data( per_descriptor_data& descriptor_data) { if (descriptor_data) { free_descriptor_state(descriptor_data); descriptor_data = 0; } } void kqueue_reactor::run(long usec, op_queue& ops) { mutex::scoped_lock lock(mutex_); // Determine how long to block while waiting for events. timespec timeout_buf = { 0, 0 }; timespec* timeout = usec ? get_timeout(usec, timeout_buf) : &timeout_buf; lock.unlock(); // Block on the kqueue descriptor. struct kevent events[128]; int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout); #if defined(ASIO_ENABLE_HANDLER_TRACKING) // Trace the waiting events. for (int i = 0; i < num_events; ++i) { void* ptr = reinterpret_cast(events[i].udata); if (ptr != &interrupter_) { unsigned event_mask = 0; switch (events[i].filter) { case EVFILT_READ: event_mask |= ASIO_HANDLER_REACTOR_READ_EVENT; break; case EVFILT_WRITE: event_mask |= ASIO_HANDLER_REACTOR_WRITE_EVENT; break; } if ((events[i].flags & (EV_ERROR | EV_OOBAND)) != 0) event_mask |= ASIO_HANDLER_REACTOR_ERROR_EVENT; ASIO_HANDLER_REACTOR_EVENTS((context(), reinterpret_cast(ptr), event_mask)); } } #endif // defined(ASIO_ENABLE_HANDLER_TRACKING) // Dispatch the waiting events. for (int i = 0; i < num_events; ++i) { void* ptr = reinterpret_cast(events[i].udata); if (ptr == &interrupter_) { interrupter_.reset(); } else { descriptor_state* descriptor_data = static_cast(ptr); mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (events[i].filter == EVFILT_WRITE && descriptor_data->num_kevents_ == 2 && descriptor_data->op_queue_[write_op].empty()) { // Some descriptor types, like serial ports, don't seem to support // EV_CLEAR with EVFILT_WRITE. Since we have no pending write // operations we'll remove the EVFILT_WRITE registration here so that // we don't end up in a tight spin. struct kevent delete_events[1]; ASIO_KQUEUE_EV_SET(&delete_events[0], descriptor_data->descriptor_, EVFILT_WRITE, EV_DELETE, 0, 0, 0); ::kevent(kqueue_fd_, delete_events, 1, 0, 0, 0); descriptor_data->num_kevents_ = 1; } // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. #if defined(__NetBSD__) static const unsigned int filter[max_ops] = #else static const int filter[max_ops] = #endif { EVFILT_READ, EVFILT_WRITE, EVFILT_READ }; for (int j = max_ops - 1; j >= 0; --j) { if (events[i].filter == filter[j]) { if (j != except_op || events[i].flags & EV_OOBAND) { while (reactor_op* op = descriptor_data->op_queue_[j].front()) { if (events[i].flags & EV_ERROR) { op->ec_ = asio::error_code( static_cast(events[i].data), asio::error::get_system_category()); descriptor_data->op_queue_[j].pop(); ops.push(op); } if (op->perform()) { descriptor_data->op_queue_[j].pop(); ops.push(op); } else break; } } } } } } lock.lock(); timer_queues_.get_ready_timers(ops); } void kqueue_reactor::interrupt() { interrupter_.interrupt(); } int kqueue_reactor::do_kqueue_create() { int fd = ::kqueue(); if (fd == -1) { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "kqueue"); } return fd; } kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state() { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING( REACTOR_IO, scheduler_.concurrency_hint())); } void kqueue_reactor::free_descriptor_state(kqueue_reactor::descriptor_state* s) { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); registered_descriptors_.free(s); } void kqueue_reactor::do_add_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.insert(&queue); } void kqueue_reactor::do_remove_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.erase(&queue); } timespec* kqueue_reactor::get_timeout(long usec, timespec& ts) { // By default we will wait no longer than 5 minutes. This will ensure that // any changes to the system clock are detected after no longer than this. const long max_usec = 5 * 60 * 1000 * 1000; usec = timer_queues_.wait_duration_usec( (usec < 0 || max_usec < usec) ? max_usec : usec); ts.tv_sec = usec / 1000000; ts.tv_nsec = (usec % 1000000) * 1000; return &ts; } } // namespace detail } // namespace asio #undef ASIO_KQUEUE_EV_SET #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_KQUEUE) #endif // ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP ================================================ FILE: src/third_party/asio/detail/impl/null_event.ipp ================================================ // // detail/impl/null_event.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_NULL_EVENT_IPP #define ASIO_DETAIL_IMPL_NULL_EVENT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) # include "asio/detail/socket_types.hpp" #else # include # if defined(__hpux) # include # endif # if !defined(__hpux) || defined(__SELECT) # include # endif #endif #include "asio/detail/push_options.hpp" namespace asio { namespace detail { void null_event::do_wait() { #if defined(ASIO_WINDOWS_RUNTIME) std::this_thread::sleep_until((std::chrono::steady_clock::time_point::max)()); #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) ::Sleep(INFINITE); #else ::pause(); #endif } void null_event::do_wait_for_usec(long usec) { #if defined(ASIO_WINDOWS_RUNTIME) std::this_thread::sleep_for(std::chrono::microseconds(usec)); #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) ::Sleep(usec / 1000); #elif defined(__hpux) && defined(__SELECT) timespec ts; ts.tv_sec = usec / 1000000; ts.tv_nsec = (usec % 1000000) * 1000; ::pselect(0, 0, 0, 0, &ts, 0); #else timeval tv; tv.tv_sec = usec / 1000000; tv.tv_usec = usec % 1000000; ::select(0, 0, 0, 0, &tv); #endif } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_NULL_EVENT_IPP ================================================ FILE: src/third_party/asio/detail/impl/pipe_select_interrupter.ipp ================================================ // // detail/impl/pipe_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP #define ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS_RUNTIME) #if !defined(ASIO_WINDOWS) #if !defined(__CYGWIN__) #if !defined(__SYMBIAN32__) #if !defined(ASIO_HAS_EVENTFD) #include #include #include #include #include "asio/detail/pipe_select_interrupter.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { pipe_select_interrupter::pipe_select_interrupter() { open_descriptors(); } void pipe_select_interrupter::open_descriptors() { int pipe_fds[2]; if (pipe(pipe_fds) == 0) { read_descriptor_ = pipe_fds[0]; ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); write_descriptor_ = pipe_fds[1]; ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); #if defined(FD_CLOEXEC) ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC); ::fcntl(write_descriptor_, F_SETFD, FD_CLOEXEC); #endif // defined(FD_CLOEXEC) } else { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "pipe_select_interrupter"); } } pipe_select_interrupter::~pipe_select_interrupter() { close_descriptors(); } void pipe_select_interrupter::close_descriptors() { if (read_descriptor_ != -1) ::close(read_descriptor_); if (write_descriptor_ != -1) ::close(write_descriptor_); } void pipe_select_interrupter::recreate() { close_descriptors(); write_descriptor_ = -1; read_descriptor_ = -1; open_descriptors(); } void pipe_select_interrupter::interrupt() { char byte = 0; signed_size_type result = ::write(write_descriptor_, &byte, 1); (void)result; } bool pipe_select_interrupter::reset() { for (;;) { char data[1024]; signed_size_type bytes_read = ::read(read_descriptor_, data, sizeof(data)); if (bytes_read < 0 && errno == EINTR) continue; bool was_interrupted = (bytes_read > 0); while (bytes_read == sizeof(data)) bytes_read = ::read(read_descriptor_, data, sizeof(data)); return was_interrupted; } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_EVENTFD) #endif // !defined(__SYMBIAN32__) #endif // !defined(__CYGWIN__) #endif // !defined(ASIO_WINDOWS) #endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP ================================================ FILE: src/third_party/asio/detail/impl/posix_event.ipp ================================================ // // detail/impl/posix_event.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_POSIX_EVENT_IPP #define ASIO_DETAIL_IMPL_POSIX_EVENT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include "asio/detail/posix_event.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { posix_event::posix_event() : state_(0) { #if (defined(__MACH__) && defined(__APPLE__)) \ || (defined(__ANDROID__) && (__ANDROID_API__ < 21)) int error = ::pthread_cond_init(&cond_, 0); #else // (defined(__MACH__) && defined(__APPLE__)) // || (defined(__ANDROID__) && (__ANDROID_API__ < 21)) ::pthread_condattr_t attr; ::pthread_condattr_init(&attr); int error = ::pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); if (error == 0) error = ::pthread_cond_init(&cond_, &attr); #endif // (defined(__MACH__) && defined(__APPLE__)) // || (defined(__ANDROID__) && (__ANDROID_API__ < 21)) asio::error_code ec(error, asio::error::get_system_category()); asio::detail::throw_error(ec, "event"); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_IMPL_POSIX_EVENT_IPP ================================================ FILE: src/third_party/asio/detail/impl/posix_mutex.ipp ================================================ // // detail/impl/posix_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP #define ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include "asio/detail/posix_mutex.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { posix_mutex::posix_mutex() { int error = ::pthread_mutex_init(&mutex_, 0); asio::error_code ec(error, asio::error::get_system_category()); asio::detail::throw_error(ec, "mutex"); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP ================================================ FILE: src/third_party/asio/detail/impl/posix_thread.ipp ================================================ // // detail/impl/posix_thread.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_POSIX_THREAD_IPP #define ASIO_DETAIL_IMPL_POSIX_THREAD_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include "asio/detail/posix_thread.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { posix_thread::~posix_thread() { if (!joined_) ::pthread_detach(thread_); } void posix_thread::join() { if (!joined_) { ::pthread_join(thread_, 0); joined_ = true; } } std::size_t posix_thread::hardware_concurrency() { #if defined(_SC_NPROCESSORS_ONLN) long result = sysconf(_SC_NPROCESSORS_ONLN); if (result > 0) return result; #endif // defined(_SC_NPROCESSORS_ONLN) return 0; } void posix_thread::start_thread(func_base* arg) { int error = ::pthread_create(&thread_, 0, asio_detail_posix_thread_function, arg); if (error != 0) { delete arg; asio::error_code ec(error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread"); } } void* asio_detail_posix_thread_function(void* arg) { posix_thread::auto_func_base_ptr func = { static_cast(arg) }; func.ptr->run(); return 0; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_IMPL_POSIX_THREAD_IPP ================================================ FILE: src/third_party/asio/detail/impl/posix_tss_ptr.ipp ================================================ // // detail/impl/posix_tss_ptr.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP #define ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include "asio/detail/posix_tss_ptr.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { void posix_tss_ptr_create(pthread_key_t& key) { int error = ::pthread_key_create(&key, 0); asio::error_code ec(error, asio::error::get_system_category()); asio::detail::throw_error(ec, "tss"); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP ================================================ FILE: src/third_party/asio/detail/impl/reactive_descriptor_service.ipp ================================================ // // detail/impl/reactive_descriptor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP #define ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) #include "asio/error.hpp" #include "asio/detail/reactive_descriptor_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { reactive_descriptor_service::reactive_descriptor_service( execution_context& context) : execution_context_service_base(context), reactor_(asio::use_service(context)) { reactor_.init_task(); } void reactive_descriptor_service::shutdown() { } void reactive_descriptor_service::construct( reactive_descriptor_service::implementation_type& impl) { impl.descriptor_ = -1; impl.state_ = 0; } void reactive_descriptor_service::move_construct( reactive_descriptor_service::implementation_type& impl, reactive_descriptor_service::implementation_type& other_impl) { impl.descriptor_ = other_impl.descriptor_; other_impl.descriptor_ = -1; impl.state_ = other_impl.state_; other_impl.state_ = 0; reactor_.move_descriptor(impl.descriptor_, impl.reactor_data_, other_impl.reactor_data_); } void reactive_descriptor_service::move_assign( reactive_descriptor_service::implementation_type& impl, reactive_descriptor_service& other_service, reactive_descriptor_service::implementation_type& other_impl) { destroy(impl); impl.descriptor_ = other_impl.descriptor_; other_impl.descriptor_ = -1; impl.state_ = other_impl.state_; other_impl.state_ = 0; other_service.reactor_.move_descriptor(impl.descriptor_, impl.reactor_data_, other_impl.reactor_data_); } void reactive_descriptor_service::destroy( reactive_descriptor_service::implementation_type& impl) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((reactor_.context(), "descriptor", &impl, impl.descriptor_, "close")); reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, (impl.state_ & descriptor_ops::possible_dup) == 0); asio::error_code ignored_ec; descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec); reactor_.cleanup_descriptor_data(impl.reactor_data_); } } asio::error_code reactive_descriptor_service::assign( reactive_descriptor_service::implementation_type& impl, const native_handle_type& native_descriptor, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } if (int err = reactor_.register_descriptor( native_descriptor, impl.reactor_data_)) { ec = asio::error_code(err, asio::error::get_system_category()); return ec; } impl.descriptor_ = native_descriptor; impl.state_ = descriptor_ops::possible_dup; ec = asio::error_code(); return ec; } asio::error_code reactive_descriptor_service::close( reactive_descriptor_service::implementation_type& impl, asio::error_code& ec) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((reactor_.context(), "descriptor", &impl, impl.descriptor_, "close")); reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, (impl.state_ & descriptor_ops::possible_dup) == 0); descriptor_ops::close(impl.descriptor_, impl.state_, ec); reactor_.cleanup_descriptor_data(impl.reactor_data_); } else { ec = asio::error_code(); } // The descriptor is closed by the OS even if close() returns an error. // // (Actually, POSIX says the state of the descriptor is unspecified. On // Linux the descriptor is apparently closed anyway; e.g. see // http://lkml.org/lkml/2005/9/10/129 // We'll just have to assume that other OSes follow the same behaviour.) construct(impl); return ec; } reactive_descriptor_service::native_handle_type reactive_descriptor_service::release( reactive_descriptor_service::implementation_type& impl) { native_handle_type descriptor = impl.descriptor_; if (is_open(impl)) { ASIO_HANDLER_OPERATION((reactor_.context(), "descriptor", &impl, impl.descriptor_, "release")); reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, false); reactor_.cleanup_descriptor_data(impl.reactor_data_); construct(impl); } return descriptor; } asio::error_code reactive_descriptor_service::cancel( reactive_descriptor_service::implementation_type& impl, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return ec; } ASIO_HANDLER_OPERATION((reactor_.context(), "descriptor", &impl, impl.descriptor_, "cancel")); reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_); ec = asio::error_code(); return ec; } void reactive_descriptor_service::start_op( reactive_descriptor_service::implementation_type& impl, int op_type, reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop) { if (!noop) { if ((impl.state_ & descriptor_ops::non_blocking) || descriptor_ops::set_internal_non_blocking( impl.descriptor_, impl.state_, true, op->ec_)) { reactor_.start_op(op_type, impl.descriptor_, impl.reactor_data_, op, is_continuation, is_non_blocking); return; } } reactor_.post_immediate_completion(op, is_continuation); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) #endif // ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/reactive_serial_port_service.ipp ================================================ // // detail/impl/reactive_serial_port_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP #define ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_SERIAL_PORT) #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #include #include "asio/detail/reactive_serial_port_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { reactive_serial_port_service::reactive_serial_port_service( execution_context& context) : execution_context_service_base(context), descriptor_service_(context) { } void reactive_serial_port_service::shutdown() { descriptor_service_.shutdown(); } asio::error_code reactive_serial_port_service::open( reactive_serial_port_service::implementation_type& impl, const std::string& device, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } descriptor_ops::state_type state = 0; int fd = descriptor_ops::open(device.c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY, ec); if (fd < 0) return ec; int s = descriptor_ops::fcntl(fd, F_GETFL, ec); if (s >= 0) s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec); if (s < 0) { asio::error_code ignored_ec; descriptor_ops::close(fd, state, ignored_ec); return ec; } // Set up default serial port options. termios ios; errno = 0; s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec); if (s >= 0) { #if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE) ::cfmakeraw(&ios); #else ios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); ios.c_oflag &= ~OPOST; ios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); ios.c_cflag &= ~(CSIZE | PARENB); ios.c_cflag |= CS8; #endif ios.c_iflag |= IGNPAR; ios.c_cflag |= CREAD | CLOCAL; errno = 0; s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec); } if (s < 0) { asio::error_code ignored_ec; descriptor_ops::close(fd, state, ignored_ec); return ec; } // We're done. Take ownership of the serial port descriptor. if (descriptor_service_.assign(impl, fd, ec)) { asio::error_code ignored_ec; descriptor_ops::close(fd, state, ignored_ec); } return ec; } asio::error_code reactive_serial_port_service::do_set_option( reactive_serial_port_service::implementation_type& impl, reactive_serial_port_service::store_function_type store, const void* option, asio::error_code& ec) { termios ios; errno = 0; descriptor_ops::error_wrapper(::tcgetattr( descriptor_service_.native_handle(impl), &ios), ec); if (ec) return ec; if (store(option, ios, ec)) return ec; errno = 0; descriptor_ops::error_wrapper(::tcsetattr( descriptor_service_.native_handle(impl), TCSANOW, &ios), ec); return ec; } asio::error_code reactive_serial_port_service::do_get_option( const reactive_serial_port_service::implementation_type& impl, reactive_serial_port_service::load_function_type load, void* option, asio::error_code& ec) const { termios ios; errno = 0; descriptor_ops::error_wrapper(::tcgetattr( descriptor_service_.native_handle(impl), &ios), ec); if (ec) return ec; return load(option, ios, ec); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #endif // defined(ASIO_HAS_SERIAL_PORT) #endif // ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/reactive_socket_service_base.ipp ================================================ // // detail/reactive_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP #define ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_IOCP) \ && !defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/reactive_socket_service_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { reactive_socket_service_base::reactive_socket_service_base( execution_context& context) : reactor_(use_service(context)) { reactor_.init_task(); } void reactive_socket_service_base::base_shutdown() { } void reactive_socket_service_base::construct( reactive_socket_service_base::base_implementation_type& impl) { impl.socket_ = invalid_socket; impl.state_ = 0; } void reactive_socket_service_base::base_move_construct( reactive_socket_service_base::base_implementation_type& impl, reactive_socket_service_base::base_implementation_type& other_impl) ASIO_NOEXCEPT { impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket; impl.state_ = other_impl.state_; other_impl.state_ = 0; reactor_.move_descriptor(impl.socket_, impl.reactor_data_, other_impl.reactor_data_); } void reactive_socket_service_base::base_move_assign( reactive_socket_service_base::base_implementation_type& impl, reactive_socket_service_base& other_service, reactive_socket_service_base::base_implementation_type& other_impl) { destroy(impl); impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket; impl.state_ = other_impl.state_; other_impl.state_ = 0; other_service.reactor_.move_descriptor(impl.socket_, impl.reactor_data_, other_impl.reactor_data_); } void reactive_socket_service_base::destroy( reactive_socket_service_base::base_implementation_type& impl) { if (impl.socket_ != invalid_socket) { ASIO_HANDLER_OPERATION((reactor_.context(), "socket", &impl, impl.socket_, "close")); reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, (impl.state_ & socket_ops::possible_dup) == 0); asio::error_code ignored_ec; socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); reactor_.cleanup_descriptor_data(impl.reactor_data_); } } asio::error_code reactive_socket_service_base::close( reactive_socket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((reactor_.context(), "socket", &impl, impl.socket_, "close")); reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, (impl.state_ & socket_ops::possible_dup) == 0); socket_ops::close(impl.socket_, impl.state_, false, ec); reactor_.cleanup_descriptor_data(impl.reactor_data_); } else { ec = asio::error_code(); } // The descriptor is closed by the OS even if close() returns an error. // // (Actually, POSIX says the state of the descriptor is unspecified. On // Linux the descriptor is apparently closed anyway; e.g. see // http://lkml.org/lkml/2005/9/10/129 // We'll just have to assume that other OSes follow the same behaviour. The // known exception is when Windows's closesocket() function fails with // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). construct(impl); return ec; } socket_type reactive_socket_service_base::release( reactive_socket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return invalid_socket; } ASIO_HANDLER_OPERATION((reactor_.context(), "socket", &impl, impl.socket_, "release")); reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); reactor_.cleanup_descriptor_data(impl.reactor_data_); socket_type sock = impl.socket_; construct(impl); ec = asio::error_code(); return sock; } asio::error_code reactive_socket_service_base::cancel( reactive_socket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return ec; } ASIO_HANDLER_OPERATION((reactor_.context(), "socket", &impl, impl.socket_, "cancel")); reactor_.cancel_ops(impl.socket_, impl.reactor_data_); ec = asio::error_code(); return ec; } asio::error_code reactive_socket_service_base::do_open( reactive_socket_service_base::base_implementation_type& impl, int af, int type, int protocol, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } socket_holder sock(socket_ops::socket(af, type, protocol, ec)); if (sock.get() == invalid_socket) return ec; if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) { ec = asio::error_code(err, asio::error::get_system_category()); return ec; } impl.socket_ = sock.release(); switch (type) { case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; default: impl.state_ = 0; break; } ec = asio::error_code(); return ec; } asio::error_code reactive_socket_service_base::do_assign( reactive_socket_service_base::base_implementation_type& impl, int type, const reactive_socket_service_base::native_handle_type& native_socket, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } if (int err = reactor_.register_descriptor( native_socket, impl.reactor_data_)) { ec = asio::error_code(err, asio::error::get_system_category()); return ec; } impl.socket_ = native_socket; switch (type) { case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; default: impl.state_ = 0; break; } impl.state_ |= socket_ops::possible_dup; ec = asio::error_code(); return ec; } void reactive_socket_service_base::start_op( reactive_socket_service_base::base_implementation_type& impl, int op_type, reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop) { if (!noop) { if ((impl.state_ & socket_ops::non_blocking) || socket_ops::set_internal_non_blocking( impl.socket_, impl.state_, true, op->ec_)) { reactor_.start_op(op_type, impl.socket_, impl.reactor_data_, op, is_continuation, is_non_blocking); return; } } reactor_.post_immediate_completion(op, is_continuation); } void reactive_socket_service_base::start_accept_op( reactive_socket_service_base::base_implementation_type& impl, reactor_op* op, bool is_continuation, bool peer_is_open) { if (!peer_is_open) start_op(impl, reactor::read_op, op, is_continuation, true, false); else { op->ec_ = asio::error::already_open; reactor_.post_immediate_completion(op, is_continuation); } } void reactive_socket_service_base::start_connect_op( reactive_socket_service_base::base_implementation_type& impl, reactor_op* op, bool is_continuation, const socket_addr_type* addr, size_t addrlen) { if ((impl.state_ & socket_ops::non_blocking) || socket_ops::set_internal_non_blocking( impl.socket_, impl.state_, true, op->ec_)) { if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) { if (op->ec_ == asio::error::in_progress || op->ec_ == asio::error::would_block) { op->ec_ = asio::error_code(); reactor_.start_op(reactor::connect_op, impl.socket_, impl.reactor_data_, op, is_continuation, false); return; } } } reactor_.post_immediate_completion(op, is_continuation); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_IOCP) // && !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP ================================================ FILE: src/third_party/asio/detail/impl/resolver_service_base.ipp ================================================ // // detail/impl/resolver_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP #define ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/resolver_service_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class resolver_service_base::work_scheduler_runner { public: work_scheduler_runner(scheduler_impl& work_scheduler) : work_scheduler_(work_scheduler) { } void operator()() { asio::error_code ec; work_scheduler_.run(ec); } private: scheduler_impl& work_scheduler_; }; resolver_service_base::resolver_service_base(execution_context& context) : scheduler_(asio::use_service(context)), work_scheduler_(new scheduler_impl(context, -1, false)), work_thread_(0) { work_scheduler_->work_started(); } resolver_service_base::~resolver_service_base() { base_shutdown(); } void resolver_service_base::base_shutdown() { if (work_scheduler_.get()) { work_scheduler_->work_finished(); work_scheduler_->stop(); if (work_thread_.get()) { work_thread_->join(); work_thread_.reset(); } work_scheduler_.reset(); } } void resolver_service_base::base_notify_fork( execution_context::fork_event fork_ev) { if (work_thread_.get()) { if (fork_ev == execution_context::fork_prepare) { work_scheduler_->stop(); work_thread_->join(); work_thread_.reset(); } else { work_scheduler_->restart(); work_thread_.reset(new asio::detail::thread( work_scheduler_runner(*work_scheduler_))); } } } void resolver_service_base::construct( resolver_service_base::implementation_type& impl) { impl.reset(static_cast(0), socket_ops::noop_deleter()); } void resolver_service_base::destroy( resolver_service_base::implementation_type& impl) { ASIO_HANDLER_OPERATION((scheduler_.context(), "resolver", &impl, 0, "cancel")); impl.reset(); } void resolver_service_base::move_construct(implementation_type& impl, implementation_type& other_impl) { impl = ASIO_MOVE_CAST(implementation_type)(other_impl); } void resolver_service_base::move_assign(implementation_type& impl, resolver_service_base&, implementation_type& other_impl) { destroy(impl); impl = ASIO_MOVE_CAST(implementation_type)(other_impl); } void resolver_service_base::cancel( resolver_service_base::implementation_type& impl) { ASIO_HANDLER_OPERATION((scheduler_.context(), "resolver", &impl, 0, "cancel")); impl.reset(static_cast(0), socket_ops::noop_deleter()); } void resolver_service_base::start_resolve_op(resolve_op* op) { if (ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER, scheduler_.concurrency_hint())) { start_work_thread(); scheduler_.work_started(); work_scheduler_->post_immediate_completion(op, false); } else { op->ec_ = asio::error::operation_not_supported; scheduler_.post_immediate_completion(op, false); } } void resolver_service_base::start_work_thread() { asio::detail::mutex::scoped_lock lock(mutex_); if (!work_thread_.get()) { work_thread_.reset(new asio::detail::thread( work_scheduler_runner(*work_scheduler_))); } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP ================================================ FILE: src/third_party/asio/detail/impl/scheduler.ipp ================================================ // // detail/impl/scheduler.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_SCHEDULER_IPP #define ASIO_DETAIL_IMPL_SCHEDULER_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/concurrency_hint.hpp" #include "asio/detail/event.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/reactor.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/scheduler_thread_info.hpp" #include "asio/detail/signal_blocker.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class scheduler::thread_function { public: explicit thread_function(scheduler* s) : this_(s) { } void operator()() { asio::error_code ec; this_->run(ec); } private: scheduler* this_; }; struct scheduler::task_cleanup { ~task_cleanup() { if (this_thread_->private_outstanding_work > 0) { asio::detail::increment( scheduler_->outstanding_work_, this_thread_->private_outstanding_work); } this_thread_->private_outstanding_work = 0; // Enqueue the completed operations and reinsert the task at the end of // the operation queue. lock_->lock(); scheduler_->task_interrupted_ = true; scheduler_->op_queue_.push(this_thread_->private_op_queue); scheduler_->op_queue_.push(&scheduler_->task_operation_); } scheduler* scheduler_; mutex::scoped_lock* lock_; thread_info* this_thread_; }; struct scheduler::work_cleanup { ~work_cleanup() { if (this_thread_->private_outstanding_work > 1) { asio::detail::increment( scheduler_->outstanding_work_, this_thread_->private_outstanding_work - 1); } else if (this_thread_->private_outstanding_work < 1) { scheduler_->work_finished(); } this_thread_->private_outstanding_work = 0; #if defined(ASIO_HAS_THREADS) if (!this_thread_->private_op_queue.empty()) { lock_->lock(); scheduler_->op_queue_.push(this_thread_->private_op_queue); } #endif // defined(ASIO_HAS_THREADS) } scheduler* scheduler_; mutex::scoped_lock* lock_; thread_info* this_thread_; }; scheduler::scheduler(asio::execution_context& ctx, int concurrency_hint, bool own_thread) : asio::detail::execution_context_service_base(ctx), one_thread_(concurrency_hint == 1 || !ASIO_CONCURRENCY_HINT_IS_LOCKING( SCHEDULER, concurrency_hint) || !ASIO_CONCURRENCY_HINT_IS_LOCKING( REACTOR_IO, concurrency_hint)), mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING( SCHEDULER, concurrency_hint)), task_(0), task_interrupted_(true), outstanding_work_(0), stopped_(false), shutdown_(false), concurrency_hint_(concurrency_hint), thread_(0) { ASIO_HANDLER_TRACKING_INIT; if (own_thread) { ++outstanding_work_; asio::detail::signal_blocker sb; thread_ = new asio::detail::thread(thread_function(this)); } } scheduler::~scheduler() { if (thread_) { thread_->join(); delete thread_; } } void scheduler::shutdown() { mutex::scoped_lock lock(mutex_); shutdown_ = true; if (thread_) stop_all_threads(lock); lock.unlock(); // Join thread to ensure task operation is returned to queue. if (thread_) { thread_->join(); delete thread_; thread_ = 0; } // Destroy handler objects. while (!op_queue_.empty()) { operation* o = op_queue_.front(); op_queue_.pop(); if (o != &task_operation_) o->destroy(); } // Reset to initial state. task_ = 0; } void scheduler::init_task() { mutex::scoped_lock lock(mutex_); if (!shutdown_ && !task_) { task_ = &use_service(this->context()); op_queue_.push(&task_operation_); wake_one_thread_and_unlock(lock); } } std::size_t scheduler::run(asio::error_code& ec) { ec = asio::error_code(); if (outstanding_work_ == 0) { stop(); return 0; } thread_info this_thread; this_thread.private_outstanding_work = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); std::size_t n = 0; for (; do_run_one(lock, this_thread, ec); lock.lock()) if (n != (std::numeric_limits::max)()) ++n; return n; } std::size_t scheduler::run_one(asio::error_code& ec) { ec = asio::error_code(); if (outstanding_work_ == 0) { stop(); return 0; } thread_info this_thread; this_thread.private_outstanding_work = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); return do_run_one(lock, this_thread, ec); } std::size_t scheduler::wait_one(long usec, asio::error_code& ec) { ec = asio::error_code(); if (outstanding_work_ == 0) { stop(); return 0; } thread_info this_thread; this_thread.private_outstanding_work = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); return do_wait_one(lock, this_thread, usec, ec); } std::size_t scheduler::poll(asio::error_code& ec) { ec = asio::error_code(); if (outstanding_work_ == 0) { stop(); return 0; } thread_info this_thread; this_thread.private_outstanding_work = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); #if defined(ASIO_HAS_THREADS) // We want to support nested calls to poll() and poll_one(), so any handlers // that are already on a thread-private queue need to be put on to the main // queue now. if (one_thread_) if (thread_info* outer_info = static_cast(ctx.next_by_key())) op_queue_.push(outer_info->private_op_queue); #endif // defined(ASIO_HAS_THREADS) std::size_t n = 0; for (; do_poll_one(lock, this_thread, ec); lock.lock()) if (n != (std::numeric_limits::max)()) ++n; return n; } std::size_t scheduler::poll_one(asio::error_code& ec) { ec = asio::error_code(); if (outstanding_work_ == 0) { stop(); return 0; } thread_info this_thread; this_thread.private_outstanding_work = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); #if defined(ASIO_HAS_THREADS) // We want to support nested calls to poll() and poll_one(), so any handlers // that are already on a thread-private queue need to be put on to the main // queue now. if (one_thread_) if (thread_info* outer_info = static_cast(ctx.next_by_key())) op_queue_.push(outer_info->private_op_queue); #endif // defined(ASIO_HAS_THREADS) return do_poll_one(lock, this_thread, ec); } void scheduler::stop() { mutex::scoped_lock lock(mutex_); stop_all_threads(lock); } bool scheduler::stopped() const { mutex::scoped_lock lock(mutex_); return stopped_; } void scheduler::restart() { mutex::scoped_lock lock(mutex_); stopped_ = false; } void scheduler::compensating_work_started() { thread_info_base* this_thread = thread_call_stack::contains(this); ++static_cast(this_thread)->private_outstanding_work; } void scheduler::post_immediate_completion( scheduler::operation* op, bool is_continuation) { #if defined(ASIO_HAS_THREADS) if (one_thread_ || is_continuation) { if (thread_info_base* this_thread = thread_call_stack::contains(this)) { ++static_cast(this_thread)->private_outstanding_work; static_cast(this_thread)->private_op_queue.push(op); return; } } #else // defined(ASIO_HAS_THREADS) (void)is_continuation; #endif // defined(ASIO_HAS_THREADS) work_started(); mutex::scoped_lock lock(mutex_); op_queue_.push(op); wake_one_thread_and_unlock(lock); } void scheduler::post_deferred_completion(scheduler::operation* op) { #if defined(ASIO_HAS_THREADS) if (one_thread_) { if (thread_info_base* this_thread = thread_call_stack::contains(this)) { static_cast(this_thread)->private_op_queue.push(op); return; } } #endif // defined(ASIO_HAS_THREADS) mutex::scoped_lock lock(mutex_); op_queue_.push(op); wake_one_thread_and_unlock(lock); } void scheduler::post_deferred_completions( op_queue& ops) { if (!ops.empty()) { #if defined(ASIO_HAS_THREADS) if (one_thread_) { if (thread_info_base* this_thread = thread_call_stack::contains(this)) { static_cast(this_thread)->private_op_queue.push(ops); return; } } #endif // defined(ASIO_HAS_THREADS) mutex::scoped_lock lock(mutex_); op_queue_.push(ops); wake_one_thread_and_unlock(lock); } } void scheduler::do_dispatch( scheduler::operation* op) { work_started(); mutex::scoped_lock lock(mutex_); op_queue_.push(op); wake_one_thread_and_unlock(lock); } void scheduler::abandon_operations( op_queue& ops) { op_queue ops2; ops2.push(ops); } std::size_t scheduler::do_run_one(mutex::scoped_lock& lock, scheduler::thread_info& this_thread, const asio::error_code& ec) { while (!stopped_) { if (!op_queue_.empty()) { // Prepare to execute first handler from queue. operation* o = op_queue_.front(); op_queue_.pop(); bool more_handlers = (!op_queue_.empty()); if (o == &task_operation_) { task_interrupted_ = more_handlers; if (more_handlers && !one_thread_) wakeup_event_.unlock_and_signal_one(lock); else lock.unlock(); task_cleanup on_exit = { this, &lock, &this_thread }; (void)on_exit; // Run the task. May throw an exception. Only block if the operation // queue is empty and we're not polling, otherwise we want to return // as soon as possible. task_->run(more_handlers ? 0 : -1, this_thread.private_op_queue); } else { std::size_t task_result = o->task_result_; if (more_handlers && !one_thread_) wake_one_thread_and_unlock(lock); else lock.unlock(); // Ensure the count of outstanding work is decremented on block exit. work_cleanup on_exit = { this, &lock, &this_thread }; (void)on_exit; // Complete the operation. May throw an exception. Deletes the object. o->complete(this, ec, task_result); return 1; } } else { wakeup_event_.clear(lock); wakeup_event_.wait(lock); } } return 0; } std::size_t scheduler::do_wait_one(mutex::scoped_lock& lock, scheduler::thread_info& this_thread, long usec, const asio::error_code& ec) { if (stopped_) return 0; operation* o = op_queue_.front(); if (o == 0) { wakeup_event_.clear(lock); wakeup_event_.wait_for_usec(lock, usec); usec = 0; // Wait at most once. o = op_queue_.front(); } if (o == &task_operation_) { op_queue_.pop(); bool more_handlers = (!op_queue_.empty()); task_interrupted_ = more_handlers; if (more_handlers && !one_thread_) wakeup_event_.unlock_and_signal_one(lock); else lock.unlock(); { task_cleanup on_exit = { this, &lock, &this_thread }; (void)on_exit; // Run the task. May throw an exception. Only block if the operation // queue is empty and we're not polling, otherwise we want to return // as soon as possible. task_->run(more_handlers ? 0 : usec, this_thread.private_op_queue); } o = op_queue_.front(); if (o == &task_operation_) { if (!one_thread_) wakeup_event_.maybe_unlock_and_signal_one(lock); return 0; } } if (o == 0) return 0; op_queue_.pop(); bool more_handlers = (!op_queue_.empty()); std::size_t task_result = o->task_result_; if (more_handlers && !one_thread_) wake_one_thread_and_unlock(lock); else lock.unlock(); // Ensure the count of outstanding work is decremented on block exit. work_cleanup on_exit = { this, &lock, &this_thread }; (void)on_exit; // Complete the operation. May throw an exception. Deletes the object. o->complete(this, ec, task_result); return 1; } std::size_t scheduler::do_poll_one(mutex::scoped_lock& lock, scheduler::thread_info& this_thread, const asio::error_code& ec) { if (stopped_) return 0; operation* o = op_queue_.front(); if (o == &task_operation_) { op_queue_.pop(); lock.unlock(); { task_cleanup c = { this, &lock, &this_thread }; (void)c; // Run the task. May throw an exception. Only block if the operation // queue is empty and we're not polling, otherwise we want to return // as soon as possible. task_->run(0, this_thread.private_op_queue); } o = op_queue_.front(); if (o == &task_operation_) { wakeup_event_.maybe_unlock_and_signal_one(lock); return 0; } } if (o == 0) return 0; op_queue_.pop(); bool more_handlers = (!op_queue_.empty()); std::size_t task_result = o->task_result_; if (more_handlers && !one_thread_) wake_one_thread_and_unlock(lock); else lock.unlock(); // Ensure the count of outstanding work is decremented on block exit. work_cleanup on_exit = { this, &lock, &this_thread }; (void)on_exit; // Complete the operation. May throw an exception. Deletes the object. o->complete(this, ec, task_result); return 1; } void scheduler::stop_all_threads( mutex::scoped_lock& lock) { stopped_ = true; wakeup_event_.signal_all(lock); if (!task_interrupted_ && task_) { task_interrupted_ = true; task_->interrupt(); } } void scheduler::wake_one_thread_and_unlock( mutex::scoped_lock& lock) { if (!wakeup_event_.maybe_unlock_and_signal_one(lock)) { if (!task_interrupted_ && task_) { task_interrupted_ = true; task_->interrupt(); } lock.unlock(); } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_SCHEDULER_IPP ================================================ FILE: src/third_party/asio/detail/impl/select_reactor.hpp ================================================ // // detail/impl/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP #define ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) \ || (!defined(ASIO_HAS_DEV_POLL) \ && !defined(ASIO_HAS_EPOLL) \ && !defined(ASIO_HAS_KQUEUE) \ && !defined(ASIO_WINDOWS_RUNTIME)) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template void select_reactor::add_timer_queue(timer_queue& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor. template void select_reactor::remove_timer_queue(timer_queue& queue) { do_remove_timer_queue(queue); } template void select_reactor::schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); if (shutdown_) { scheduler_.post_immediate_completion(op, false); return; } bool earliest = queue.enqueue_timer(time, timer, op); scheduler_.work_started(); if (earliest) interrupter_.interrupt(); } template std::size_t select_reactor::cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue ops; std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); lock.unlock(); scheduler_.post_deferred_completions(ops); return n; } template void select_reactor::move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue ops; queue.cancel_timer(target, ops); queue.move_timer(target, source); lock.unlock(); scheduler_.post_deferred_completions(ops); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) // || (!defined(ASIO_HAS_DEV_POLL) // && !defined(ASIO_HAS_EPOLL) // && !defined(ASIO_HAS_KQUEUE) // && !defined(ASIO_WINDOWS_RUNTIME)) #endif // ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/impl/select_reactor.ipp ================================================ // // detail/impl/select_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP #define ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) \ || (!defined(ASIO_HAS_DEV_POLL) \ && !defined(ASIO_HAS_EPOLL) \ && !defined(ASIO_HAS_KQUEUE) \ && !defined(ASIO_WINDOWS_RUNTIME)) #include "asio/detail/fd_set_adapter.hpp" #include "asio/detail/select_reactor.hpp" #include "asio/detail/signal_blocker.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { #if defined(ASIO_HAS_IOCP) class select_reactor::thread_function { public: explicit thread_function(select_reactor* r) : this_(r) { } void operator()() { this_->run_thread(); } private: select_reactor* this_; }; #endif // defined(ASIO_HAS_IOCP) select_reactor::select_reactor(asio::execution_context& ctx) : execution_context_service_base(ctx), scheduler_(use_service(ctx)), mutex_(), interrupter_(), #if defined(ASIO_HAS_IOCP) stop_thread_(false), thread_(0), #endif // defined(ASIO_HAS_IOCP) shutdown_(false) { #if defined(ASIO_HAS_IOCP) asio::detail::signal_blocker sb; thread_ = new asio::detail::thread(thread_function(this)); #endif // defined(ASIO_HAS_IOCP) } select_reactor::~select_reactor() { shutdown(); } void select_reactor::shutdown() { asio::detail::mutex::scoped_lock lock(mutex_); shutdown_ = true; #if defined(ASIO_HAS_IOCP) stop_thread_ = true; #endif // defined(ASIO_HAS_IOCP) lock.unlock(); #if defined(ASIO_HAS_IOCP) if (thread_) { interrupter_.interrupt(); thread_->join(); delete thread_; thread_ = 0; } #endif // defined(ASIO_HAS_IOCP) op_queue ops; for (int i = 0; i < max_ops; ++i) op_queue_[i].get_all_operations(ops); timer_queues_.get_all_timers(ops); scheduler_.abandon_operations(ops); } void select_reactor::notify_fork( asio::execution_context::fork_event fork_ev) { if (fork_ev == asio::execution_context::fork_child) interrupter_.recreate(); } void select_reactor::init_task() { scheduler_.init_task(); } int select_reactor::register_descriptor(socket_type, select_reactor::per_descriptor_data&) { return 0; } int select_reactor::register_internal_descriptor( int op_type, socket_type descriptor, select_reactor::per_descriptor_data&, reactor_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue_[op_type].enqueue_operation(descriptor, op); interrupter_.interrupt(); return 0; } void select_reactor::move_descriptor(socket_type, select_reactor::per_descriptor_data&, select_reactor::per_descriptor_data&) { } void select_reactor::start_op(int op_type, socket_type descriptor, select_reactor::per_descriptor_data&, reactor_op* op, bool is_continuation, bool) { asio::detail::mutex::scoped_lock lock(mutex_); if (shutdown_) { post_immediate_completion(op, is_continuation); return; } bool first = op_queue_[op_type].enqueue_operation(descriptor, op); scheduler_.work_started(); if (first) interrupter_.interrupt(); } void select_reactor::cancel_ops(socket_type descriptor, select_reactor::per_descriptor_data&) { asio::detail::mutex::scoped_lock lock(mutex_); cancel_ops_unlocked(descriptor, asio::error::operation_aborted); } void select_reactor::deregister_descriptor(socket_type descriptor, select_reactor::per_descriptor_data&, bool) { asio::detail::mutex::scoped_lock lock(mutex_); cancel_ops_unlocked(descriptor, asio::error::operation_aborted); } void select_reactor::deregister_internal_descriptor( socket_type descriptor, select_reactor::per_descriptor_data&) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue ops; for (int i = 0; i < max_ops; ++i) op_queue_[i].cancel_operations(descriptor, ops); } void select_reactor::cleanup_descriptor_data( select_reactor::per_descriptor_data&) { } void select_reactor::run(long usec, op_queue& ops) { asio::detail::mutex::scoped_lock lock(mutex_); #if defined(ASIO_HAS_IOCP) // Check if the thread is supposed to stop. if (stop_thread_) return; #endif // defined(ASIO_HAS_IOCP) // Set up the descriptor sets. for (int i = 0; i < max_select_ops; ++i) fd_sets_[i].reset(); fd_sets_[read_op].set(interrupter_.read_descriptor()); socket_type max_fd = 0; bool have_work_to_do = !timer_queues_.all_empty(); for (int i = 0; i < max_select_ops; ++i) { have_work_to_do = have_work_to_do || !op_queue_[i].empty(); fd_sets_[i].set(op_queue_[i], ops); if (fd_sets_[i].max_descriptor() > max_fd) max_fd = fd_sets_[i].max_descriptor(); } #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Connection operations on Windows use both except and write fd_sets. have_work_to_do = have_work_to_do || !op_queue_[connect_op].empty(); fd_sets_[write_op].set(op_queue_[connect_op], ops); if (fd_sets_[write_op].max_descriptor() > max_fd) max_fd = fd_sets_[write_op].max_descriptor(); fd_sets_[except_op].set(op_queue_[connect_op], ops); if (fd_sets_[except_op].max_descriptor() > max_fd) max_fd = fd_sets_[except_op].max_descriptor(); #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // We can return immediately if there's no work to do and the reactor is // not supposed to block. if (!usec && !have_work_to_do) return; // Determine how long to block while waiting for events. timeval tv_buf = { 0, 0 }; timeval* tv = usec ? get_timeout(usec, tv_buf) : &tv_buf; lock.unlock(); // Block on the select call until descriptors become ready. asio::error_code ec; int retval = socket_ops::select(static_cast(max_fd + 1), fd_sets_[read_op], fd_sets_[write_op], fd_sets_[except_op], tv, ec); // Reset the interrupter. if (retval > 0 && fd_sets_[read_op].is_set(interrupter_.read_descriptor())) { interrupter_.reset(); --retval; } lock.lock(); // Dispatch all ready operations. if (retval > 0) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Connection operations on Windows use both except and write fd_sets. fd_sets_[except_op].perform(op_queue_[connect_op], ops); fd_sets_[write_op].perform(op_queue_[connect_op], ops); #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. for (int i = max_select_ops - 1; i >= 0; --i) fd_sets_[i].perform(op_queue_[i], ops); } timer_queues_.get_ready_timers(ops); } void select_reactor::interrupt() { interrupter_.interrupt(); } #if defined(ASIO_HAS_IOCP) void select_reactor::run_thread() { asio::detail::mutex::scoped_lock lock(mutex_); while (!stop_thread_) { lock.unlock(); op_queue ops; run(true, ops); scheduler_.post_deferred_completions(ops); lock.lock(); } } #endif // defined(ASIO_HAS_IOCP) void select_reactor::do_add_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.insert(&queue); } void select_reactor::do_remove_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.erase(&queue); } timeval* select_reactor::get_timeout(long usec, timeval& tv) { // By default we will wait no longer than 5 minutes. This will ensure that // any changes to the system clock are detected after no longer than this. const long max_usec = 5 * 60 * 1000 * 1000; usec = timer_queues_.wait_duration_usec( (usec < 0 || max_usec < usec) ? max_usec : usec); tv.tv_sec = usec / 1000000; tv.tv_usec = usec % 1000000; return &tv; } void select_reactor::cancel_ops_unlocked(socket_type descriptor, const asio::error_code& ec) { bool need_interrupt = false; op_queue ops; for (int i = 0; i < max_ops; ++i) need_interrupt = op_queue_[i].cancel_operations( descriptor, ops, ec) || need_interrupt; scheduler_.post_deferred_completions(ops); if (need_interrupt) interrupter_.interrupt(); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) // || (!defined(ASIO_HAS_DEV_POLL) // && !defined(ASIO_HAS_EPOLL) // && !defined(ASIO_HAS_KQUEUE)) // && !defined(ASIO_WINDOWS_RUNTIME)) #endif // ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP ================================================ FILE: src/third_party/asio/detail/impl/service_registry.hpp ================================================ // // detail/impl/service_registry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP #define ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template Service& service_registry::use_service() { execution_context::service::key key; init_key(key, 0); factory_type factory = &service_registry::create; return *static_cast(do_use_service(key, factory, &owner_)); } template Service& service_registry::use_service(io_context& owner) { execution_context::service::key key; init_key(key, 0); factory_type factory = &service_registry::create; return *static_cast(do_use_service(key, factory, &owner)); } template void service_registry::add_service(Service* new_service) { execution_context::service::key key; init_key(key, 0); return do_add_service(key, new_service); } template bool service_registry::has_service() const { execution_context::service::key key; init_key(key, 0); return do_has_service(key); } template inline void service_registry::init_key( execution_context::service::key& key, ...) { init_key_from_id(key, Service::id); } #if !defined(ASIO_NO_TYPEID) template void service_registry::init_key(execution_context::service::key& key, typename enable_if< is_base_of::value>::type*) { key.type_info_ = &typeid(typeid_wrapper); key.id_ = 0; } template void service_registry::init_key_from_id(execution_context::service::key& key, const service_id& /*id*/) { key.type_info_ = &typeid(typeid_wrapper); key.id_ = 0; } #endif // !defined(ASIO_NO_TYPEID) template execution_context::service* service_registry::create(void* owner) { return new Service(*static_cast(owner)); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP ================================================ FILE: src/third_party/asio/detail/impl/service_registry.ipp ================================================ // // detail/impl/service_registry.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP #define ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/service_registry.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { service_registry::service_registry(execution_context& owner) : owner_(owner), first_service_(0) { } service_registry::~service_registry() { } void service_registry::shutdown_services() { execution_context::service* service = first_service_; while (service) { service->shutdown(); service = service->next_; } } void service_registry::destroy_services() { while (first_service_) { execution_context::service* next_service = first_service_->next_; destroy(first_service_); first_service_ = next_service; } } void service_registry::notify_fork(execution_context::fork_event fork_ev) { // Make a copy of all of the services while holding the lock. We don't want // to hold the lock while calling into each service, as it may try to call // back into this class. std::vector services; { asio::detail::mutex::scoped_lock lock(mutex_); execution_context::service* service = first_service_; while (service) { services.push_back(service); service = service->next_; } } // If processing the fork_prepare event, we want to go in reverse order of // service registration, which happens to be the existing order of the // services in the vector. For the other events we want to go in the other // direction. std::size_t num_services = services.size(); if (fork_ev == execution_context::fork_prepare) for (std::size_t i = 0; i < num_services; ++i) services[i]->notify_fork(fork_ev); else for (std::size_t i = num_services; i > 0; --i) services[i - 1]->notify_fork(fork_ev); } void service_registry::init_key_from_id(execution_context::service::key& key, const execution_context::id& id) { key.type_info_ = 0; key.id_ = &id; } bool service_registry::keys_match( const execution_context::service::key& key1, const execution_context::service::key& key2) { if (key1.id_ && key2.id_) if (key1.id_ == key2.id_) return true; if (key1.type_info_ && key2.type_info_) if (*key1.type_info_ == *key2.type_info_) return true; return false; } void service_registry::destroy(execution_context::service* service) { delete service; } execution_context::service* service_registry::do_use_service( const execution_context::service::key& key, factory_type factory, void* owner) { asio::detail::mutex::scoped_lock lock(mutex_); // First see if there is an existing service object with the given key. execution_context::service* service = first_service_; while (service) { if (keys_match(service->key_, key)) return service; service = service->next_; } // Create a new service object. The service registry's mutex is not locked // at this time to allow for nested calls into this function from the new // service's constructor. lock.unlock(); auto_service_ptr new_service = { factory(owner) }; new_service.ptr_->key_ = key; lock.lock(); // Check that nobody else created another service object of the same type // while the lock was released. service = first_service_; while (service) { if (keys_match(service->key_, key)) return service; service = service->next_; } // Service was successfully initialised, pass ownership to registry. new_service.ptr_->next_ = first_service_; first_service_ = new_service.ptr_; new_service.ptr_ = 0; return first_service_; } void service_registry::do_add_service( const execution_context::service::key& key, execution_context::service* new_service) { if (&owner_ != &new_service->context()) asio::detail::throw_exception(invalid_service_owner()); asio::detail::mutex::scoped_lock lock(mutex_); // Check if there is an existing service object with the given key. execution_context::service* service = first_service_; while (service) { if (keys_match(service->key_, key)) asio::detail::throw_exception(service_already_exists()); service = service->next_; } // Take ownership of the service object. new_service->key_ = key; new_service->next_ = first_service_; first_service_ = new_service; } bool service_registry::do_has_service( const execution_context::service::key& key) const { asio::detail::mutex::scoped_lock lock(mutex_); execution_context::service* service = first_service_; while (service) { if (keys_match(service->key_, key)) return true; service = service->next_; } return false; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP ================================================ FILE: src/third_party/asio/detail/impl/signal_set_service.ipp ================================================ // // detail/impl/signal_set_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_SIGNAL_SET_SERVICE_IPP #define ASIO_DETAIL_IMPL_SIGNAL_SET_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/detail/reactor.hpp" #include "asio/detail/signal_blocker.hpp" #include "asio/detail/signal_set_service.hpp" #include "asio/detail/static_mutex.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct signal_state { // Mutex used for protecting global state. static_mutex mutex_; // The read end of the pipe used for signal notifications. int read_descriptor_; // The write end of the pipe used for signal notifications. int write_descriptor_; // Whether the signal state has been prepared for a fork. bool fork_prepared_; // The head of a linked list of all signal_set_service instances. class signal_set_service* service_list_; // A count of the number of objects that are registered for each signal. std::size_t registration_count_[max_signal_number]; }; signal_state* get_signal_state() { static signal_state state = { ASIO_STATIC_MUTEX_INIT, -1, -1, false, 0, { 0 } }; return &state; } void asio_signal_handler(int signal_number) { #if defined(ASIO_WINDOWS) \ || defined(ASIO_WINDOWS_RUNTIME) \ || defined(__CYGWIN__) signal_set_service::deliver_signal(signal_number); #else // defined(ASIO_WINDOWS) // || defined(ASIO_WINDOWS_RUNTIME) // || defined(__CYGWIN__) int saved_errno = errno; signal_state* state = get_signal_state(); signed_size_type result = ::write(state->write_descriptor_, &signal_number, sizeof(signal_number)); (void)result; errno = saved_errno; #endif // defined(ASIO_WINDOWS) // || defined(ASIO_WINDOWS_RUNTIME) // || defined(__CYGWIN__) #if defined(ASIO_HAS_SIGNAL) && !defined(ASIO_HAS_SIGACTION) ::signal(signal_number, asio_signal_handler); #endif // defined(ASIO_HAS_SIGNAL) && !defined(ASIO_HAS_SIGACTION) } #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) class signal_set_service::pipe_read_op : public reactor_op { public: pipe_read_op() : reactor_op(&pipe_read_op::do_perform, pipe_read_op::do_complete) { } static status do_perform(reactor_op*) { signal_state* state = get_signal_state(); int fd = state->read_descriptor_; int signal_number = 0; while (::read(fd, &signal_number, sizeof(int)) == sizeof(int)) if (signal_number >= 0 && signal_number < max_signal_number) signal_set_service::deliver_signal(signal_number); return not_done; } static void do_complete(void* /*owner*/, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { pipe_read_op* o(static_cast(base)); delete o; } }; #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) signal_set_service::signal_set_service(execution_context& context) : execution_context_service_base(context), scheduler_(asio::use_service(context)), #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) reactor_(asio::use_service(context)), #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) next_(0), prev_(0) { get_signal_state()->mutex_.init(); #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) reactor_.init_task(); #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) for (int i = 0; i < max_signal_number; ++i) registrations_[i] = 0; add_service(this); } signal_set_service::~signal_set_service() { remove_service(this); } void signal_set_service::shutdown() { remove_service(this); op_queue ops; for (int i = 0; i < max_signal_number; ++i) { registration* reg = registrations_[i]; while (reg) { ops.push(*reg->queue_); reg = reg->next_in_table_; } } scheduler_.abandon_operations(ops); } void signal_set_service::notify_fork(execution_context::fork_event fork_ev) { #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); switch (fork_ev) { case execution_context::fork_prepare: { int read_descriptor = state->read_descriptor_; state->fork_prepared_ = true; lock.unlock(); reactor_.deregister_internal_descriptor(read_descriptor, reactor_data_); reactor_.cleanup_descriptor_data(reactor_data_); } break; case execution_context::fork_parent: if (state->fork_prepared_) { int read_descriptor = state->read_descriptor_; state->fork_prepared_ = false; lock.unlock(); reactor_.register_internal_descriptor(reactor::read_op, read_descriptor, reactor_data_, new pipe_read_op); } break; case execution_context::fork_child: if (state->fork_prepared_) { asio::detail::signal_blocker blocker; close_descriptors(); open_descriptors(); int read_descriptor = state->read_descriptor_; state->fork_prepared_ = false; lock.unlock(); reactor_.register_internal_descriptor(reactor::read_op, read_descriptor, reactor_data_, new pipe_read_op); } break; default: break; } #else // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) (void)fork_ev; #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) } void signal_set_service::construct( signal_set_service::implementation_type& impl) { impl.signals_ = 0; } void signal_set_service::destroy( signal_set_service::implementation_type& impl) { asio::error_code ignored_ec; clear(impl, ignored_ec); cancel(impl, ignored_ec); } asio::error_code signal_set_service::add( signal_set_service::implementation_type& impl, int signal_number, asio::error_code& ec) { // Check that the signal number is valid. if (signal_number < 0 || signal_number >= max_signal_number) { ec = asio::error::invalid_argument; return ec; } signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); // Find the appropriate place to insert the registration. registration** insertion_point = &impl.signals_; registration* next = impl.signals_; while (next && next->signal_number_ < signal_number) { insertion_point = &next->next_in_set_; next = next->next_in_set_; } // Only do something if the signal is not already registered. if (next == 0 || next->signal_number_ != signal_number) { registration* new_registration = new registration; #if defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION) // Register for the signal if we're the first. if (state->registration_count_[signal_number] == 0) { # if defined(ASIO_HAS_SIGACTION) using namespace std; // For memset. struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = asio_signal_handler; sigfillset(&sa.sa_mask); if (::sigaction(signal_number, &sa, 0) == -1) # else // defined(ASIO_HAS_SIGACTION) if (::signal(signal_number, asio_signal_handler) == SIG_ERR) # endif // defined(ASIO_HAS_SIGACTION) { # if defined(ASIO_WINDOWS) || defined(__CYGWIN__) ec = asio::error::invalid_argument; # else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) ec = asio::error_code(errno, asio::error::get_system_category()); # endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) delete new_registration; return ec; } } #endif // defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION) // Record the new registration in the set. new_registration->signal_number_ = signal_number; new_registration->queue_ = &impl.queue_; new_registration->next_in_set_ = next; *insertion_point = new_registration; // Insert registration into the registration table. new_registration->next_in_table_ = registrations_[signal_number]; if (registrations_[signal_number]) registrations_[signal_number]->prev_in_table_ = new_registration; registrations_[signal_number] = new_registration; ++state->registration_count_[signal_number]; } ec = asio::error_code(); return ec; } asio::error_code signal_set_service::remove( signal_set_service::implementation_type& impl, int signal_number, asio::error_code& ec) { // Check that the signal number is valid. if (signal_number < 0 || signal_number >= max_signal_number) { ec = asio::error::invalid_argument; return ec; } signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); // Find the signal number in the list of registrations. registration** deletion_point = &impl.signals_; registration* reg = impl.signals_; while (reg && reg->signal_number_ < signal_number) { deletion_point = ®->next_in_set_; reg = reg->next_in_set_; } if (reg != 0 && reg->signal_number_ == signal_number) { #if defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION) // Set signal handler back to the default if we're the last. if (state->registration_count_[signal_number] == 1) { # if defined(ASIO_HAS_SIGACTION) using namespace std; // For memset. struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; if (::sigaction(signal_number, &sa, 0) == -1) # else // defined(ASIO_HAS_SIGACTION) if (::signal(signal_number, SIG_DFL) == SIG_ERR) # endif // defined(ASIO_HAS_SIGACTION) { # if defined(ASIO_WINDOWS) || defined(__CYGWIN__) ec = asio::error::invalid_argument; # else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) ec = asio::error_code(errno, asio::error::get_system_category()); # endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) return ec; } } #endif // defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION) // Remove the registration from the set. *deletion_point = reg->next_in_set_; // Remove the registration from the registration table. if (registrations_[signal_number] == reg) registrations_[signal_number] = reg->next_in_table_; if (reg->prev_in_table_) reg->prev_in_table_->next_in_table_ = reg->next_in_table_; if (reg->next_in_table_) reg->next_in_table_->prev_in_table_ = reg->prev_in_table_; --state->registration_count_[signal_number]; delete reg; } ec = asio::error_code(); return ec; } asio::error_code signal_set_service::clear( signal_set_service::implementation_type& impl, asio::error_code& ec) { signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); while (registration* reg = impl.signals_) { #if defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION) // Set signal handler back to the default if we're the last. if (state->registration_count_[reg->signal_number_] == 1) { # if defined(ASIO_HAS_SIGACTION) using namespace std; // For memset. struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; if (::sigaction(reg->signal_number_, &sa, 0) == -1) # else // defined(ASIO_HAS_SIGACTION) if (::signal(reg->signal_number_, SIG_DFL) == SIG_ERR) # endif // defined(ASIO_HAS_SIGACTION) { # if defined(ASIO_WINDOWS) || defined(__CYGWIN__) ec = asio::error::invalid_argument; # else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) ec = asio::error_code(errno, asio::error::get_system_category()); # endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) return ec; } } #endif // defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION) // Remove the registration from the registration table. if (registrations_[reg->signal_number_] == reg) registrations_[reg->signal_number_] = reg->next_in_table_; if (reg->prev_in_table_) reg->prev_in_table_->next_in_table_ = reg->next_in_table_; if (reg->next_in_table_) reg->next_in_table_->prev_in_table_ = reg->prev_in_table_; --state->registration_count_[reg->signal_number_]; impl.signals_ = reg->next_in_set_; delete reg; } ec = asio::error_code(); return ec; } asio::error_code signal_set_service::cancel( signal_set_service::implementation_type& impl, asio::error_code& ec) { ASIO_HANDLER_OPERATION((scheduler_.context(), "signal_set", &impl, 0, "cancel")); op_queue ops; { signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); while (signal_op* op = impl.queue_.front()) { op->ec_ = asio::error::operation_aborted; impl.queue_.pop(); ops.push(op); } } scheduler_.post_deferred_completions(ops); ec = asio::error_code(); return ec; } void signal_set_service::deliver_signal(int signal_number) { signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); signal_set_service* service = state->service_list_; while (service) { op_queue ops; registration* reg = service->registrations_[signal_number]; while (reg) { if (reg->queue_->empty()) { ++reg->undelivered_; } else { while (signal_op* op = reg->queue_->front()) { op->signal_number_ = signal_number; reg->queue_->pop(); ops.push(op); } } reg = reg->next_in_table_; } service->scheduler_.post_deferred_completions(ops); service = service->next_; } } void signal_set_service::add_service(signal_set_service* service) { signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) // If this is the first service to be created, open a new pipe. if (state->service_list_ == 0) open_descriptors(); #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) // If a scheduler_ object is thread-unsafe then it must be the only // scheduler used to create signal_set objects. if (state->service_list_ != 0) { if (!ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER, service->scheduler_.concurrency_hint()) || !ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER, state->service_list_->scheduler_.concurrency_hint())) { std::logic_error ex( "Thread-unsafe execution context objects require " "exclusive access to signal handling."); asio::detail::throw_exception(ex); } } // Insert service into linked list of all services. service->next_ = state->service_list_; service->prev_ = 0; if (state->service_list_) state->service_list_->prev_ = service; state->service_list_ = service; #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) // Register for pipe readiness notifications. int read_descriptor = state->read_descriptor_; lock.unlock(); service->reactor_.register_internal_descriptor(reactor::read_op, read_descriptor, service->reactor_data_, new pipe_read_op); #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) } void signal_set_service::remove_service(signal_set_service* service) { signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); if (service->next_ || service->prev_ || state->service_list_ == service) { #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) // Disable the pipe readiness notifications. int read_descriptor = state->read_descriptor_; lock.unlock(); service->reactor_.deregister_internal_descriptor( read_descriptor, service->reactor_data_); service->reactor_.cleanup_descriptor_data(service->reactor_data_); lock.lock(); #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) // Remove service from linked list of all services. if (state->service_list_ == service) state->service_list_ = service->next_; if (service->prev_) service->prev_->next_ = service->next_; if (service->next_) service->next_->prev_= service->prev_; service->next_ = 0; service->prev_ = 0; #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) // If this is the last service to be removed, close the pipe. if (state->service_list_ == 0) close_descriptors(); #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) } } void signal_set_service::open_descriptors() { #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) signal_state* state = get_signal_state(); int pipe_fds[2]; if (::pipe(pipe_fds) == 0) { state->read_descriptor_ = pipe_fds[0]; ::fcntl(state->read_descriptor_, F_SETFL, O_NONBLOCK); state->write_descriptor_ = pipe_fds[1]; ::fcntl(state->write_descriptor_, F_SETFL, O_NONBLOCK); #if defined(FD_CLOEXEC) ::fcntl(state->read_descriptor_, F_SETFD, FD_CLOEXEC); ::fcntl(state->write_descriptor_, F_SETFD, FD_CLOEXEC); #endif // defined(FD_CLOEXEC) } else { asio::error_code ec(errno, asio::error::get_system_category()); asio::detail::throw_error(ec, "signal_set_service pipe"); } #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) } void signal_set_service::close_descriptors() { #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) signal_state* state = get_signal_state(); if (state->read_descriptor_ != -1) ::close(state->read_descriptor_); state->read_descriptor_ = -1; if (state->write_descriptor_ != -1) ::close(state->write_descriptor_); state->write_descriptor_ = -1; #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) } void signal_set_service::start_wait_op( signal_set_service::implementation_type& impl, signal_op* op) { scheduler_.work_started(); signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); registration* reg = impl.signals_; while (reg) { if (reg->undelivered_ > 0) { --reg->undelivered_; op->signal_number_ = reg->signal_number_; scheduler_.post_deferred_completion(op); return; } reg = reg->next_in_set_; } impl.queue_.push(op); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_SIGNAL_SET_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/socket_ops.ipp ================================================ // // detail/impl/socket_ops.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SOCKET_OPS_IPP #define ASIO_DETAIL_SOCKET_OPS_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include #include #include #include "asio/detail/assert.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include # include # include #endif // defined(ASIO_WINDOWS_RUNTIME) #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) \ || defined(__MACH__) && defined(__APPLE__) # if defined(ASIO_HAS_PTHREADS) # include # endif // defined(ASIO_HAS_PTHREADS) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // || defined(__MACH__) && defined(__APPLE__) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { namespace socket_ops { #if !defined(ASIO_WINDOWS_RUNTIME) #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) struct msghdr { int msg_namelen; }; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #if defined(__hpux) // HP-UX doesn't declare these functions extern "C", so they are declared again // here to avoid linker errors about undefined symbols. extern "C" char* if_indextoname(unsigned int, char*); extern "C" unsigned int if_nametoindex(const char*); #endif // defined(__hpux) #endif // !defined(ASIO_WINDOWS_RUNTIME) inline void clear_last_error() { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) WSASetLastError(0); #else errno = 0; #endif } #if !defined(ASIO_WINDOWS_RUNTIME) template inline ReturnType error_wrapper(ReturnType return_value, asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) ec = asio::error_code(WSAGetLastError(), asio::error::get_system_category()); #else ec = asio::error_code(errno, asio::error::get_system_category()); #endif return return_value; } template inline socket_type call_accept(SockLenType msghdr::*, socket_type s, socket_addr_type* addr, std::size_t* addrlen) { SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0; socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0); if (addrlen) *addrlen = (std::size_t)tmp_addrlen; return result; } socket_type accept(socket_type s, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return invalid_socket; } clear_last_error(); socket_type new_s = error_wrapper(call_accept( &msghdr::msg_namelen, s, addr, addrlen), ec); if (new_s == invalid_socket) return new_s; #if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) int optval = 1; int result = error_wrapper(::setsockopt(new_s, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); if (result != 0) { ::close(new_s); return invalid_socket; } #endif ec = asio::error_code(); return new_s; } socket_type sync_accept(socket_type s, state_type state, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec) { // Accept a socket. for (;;) { // Try to complete the operation without blocking. socket_type new_socket = socket_ops::accept(s, addr, addrlen, ec); // Check if operation succeeded. if (new_socket != invalid_socket) return new_socket; // Operation failed. if (ec == asio::error::would_block || ec == asio::error::try_again) { if (state & user_set_non_blocking) return invalid_socket; // Fall through to retry operation. } else if (ec == asio::error::connection_aborted) { if (state & enable_connection_aborted) return invalid_socket; // Fall through to retry operation. } #if defined(EPROTO) else if (ec.value() == EPROTO) { if (state & enable_connection_aborted) return invalid_socket; // Fall through to retry operation. } #endif // defined(EPROTO) else return invalid_socket; // Wait for socket to become ready. if (socket_ops::poll_read(s, 0, -1, ec) < 0) return invalid_socket; } } #if defined(ASIO_HAS_IOCP) void complete_iocp_accept(socket_type s, void* output_buffer, DWORD address_length, socket_addr_type* addr, std::size_t* addrlen, socket_type new_socket, asio::error_code& ec) { // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_NETNAME_DELETED) ec = asio::error::connection_aborted; if (!ec) { // Get the address of the peer. if (addr && addrlen) { LPSOCKADDR local_addr = 0; int local_addr_length = 0; LPSOCKADDR remote_addr = 0; int remote_addr_length = 0; GetAcceptExSockaddrs(output_buffer, 0, address_length, address_length, &local_addr, &local_addr_length, &remote_addr, &remote_addr_length); if (static_cast(remote_addr_length) > *addrlen) { ec = asio::error::invalid_argument; } else { using namespace std; // For memcpy. memcpy(addr, remote_addr, remote_addr_length); *addrlen = static_cast(remote_addr_length); } } // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname // and getpeername will work on the accepted socket. SOCKET update_ctx_param = s; socket_ops::state_type state = 0; socket_ops::setsockopt(new_socket, state, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, &update_ctx_param, sizeof(SOCKET), ec); } } #else // defined(ASIO_HAS_IOCP) bool non_blocking_accept(socket_type s, state_type state, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec, socket_type& new_socket) { for (;;) { // Accept the waiting connection. new_socket = socket_ops::accept(s, addr, addrlen, ec); // Check if operation succeeded. if (new_socket != invalid_socket) return true; // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Operation failed. if (ec == asio::error::would_block || ec == asio::error::try_again) { // Fall through to retry operation. } else if (ec == asio::error::connection_aborted) { if (state & enable_connection_aborted) return true; // Fall through to retry operation. } #if defined(EPROTO) else if (ec.value() == EPROTO) { if (state & enable_connection_aborted) return true; // Fall through to retry operation. } #endif // defined(EPROTO) else return true; return false; } } #endif // defined(ASIO_HAS_IOCP) template inline int call_bind(SockLenType msghdr::*, socket_type s, const socket_addr_type* addr, std::size_t addrlen) { return ::bind(s, addr, (SockLenType)addrlen); } int bind(socket_type s, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } clear_last_error(); int result = error_wrapper(call_bind( &msghdr::msg_namelen, s, addr, addrlen), ec); if (result == 0) ec = asio::error_code(); return result; } int close(socket_type s, state_type& state, bool destruction, asio::error_code& ec) { int result = 0; if (s != invalid_socket) { // We don't want the destructor to block, so set the socket to linger in // the background. If the user doesn't like this behaviour then they need // to explicitly close the socket. if (destruction && (state & user_set_linger)) { ::linger opt; opt.l_onoff = 0; opt.l_linger = 0; asio::error_code ignored_ec; socket_ops::setsockopt(s, state, SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); } clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::closesocket(s), ec); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::close(s), ec); #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) if (result != 0 && (ec == asio::error::would_block || ec == asio::error::try_again)) { // According to UNIX Network Programming Vol. 1, it is possible for // close() to fail with EWOULDBLOCK under certain circumstances. What // isn't clear is the state of the descriptor after this error. The one // current OS where this behaviour is seen, Windows, says that the socket // remains open. Therefore we'll put the descriptor back into blocking // mode and have another attempt at closing it. #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = 0; ::ioctlsocket(s, FIONBIO, &arg); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(__SYMBIAN32__) int flags = ::fcntl(s, F_GETFL, 0); if (flags >= 0) ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK); # else // defined(__SYMBIAN32__) ioctl_arg_type arg = 0; ::ioctl(s, FIONBIO, &arg); # endif // defined(__SYMBIAN32__) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) state &= ~non_blocking; clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::closesocket(s), ec); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::close(s), ec); #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } } if (result == 0) ec = asio::error_code(); return result; } bool set_user_non_blocking(socket_type s, state_type& state, bool value, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return false; } clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec); #elif defined(__SYMBIAN32__) int result = error_wrapper(::fcntl(s, F_GETFL, 0), ec); if (result >= 0) { clear_last_error(); int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK)); result = error_wrapper(::fcntl(s, F_SETFL, flag), ec); } #else ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec); #endif if (result >= 0) { ec = asio::error_code(); if (value) state |= user_set_non_blocking; else { // Clearing the user-set non-blocking mode always overrides any // internally-set non-blocking flag. Any subsequent asynchronous // operations will need to re-enable non-blocking I/O. state &= ~(user_set_non_blocking | internal_non_blocking); } return true; } return false; } bool set_internal_non_blocking(socket_type s, state_type& state, bool value, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return false; } if (!value && (state & user_set_non_blocking)) { // It does not make sense to clear the internal non-blocking flag if the // user still wants non-blocking behaviour. Return an error and let the // caller figure out whether to update the user-set non-blocking flag. ec = asio::error::invalid_argument; return false; } clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec); #elif defined(__SYMBIAN32__) int result = error_wrapper(::fcntl(s, F_GETFL, 0), ec); if (result >= 0) { clear_last_error(); int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK)); result = error_wrapper(::fcntl(s, F_SETFL, flag), ec); } #else ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec); #endif if (result >= 0) { ec = asio::error_code(); if (value) state |= internal_non_blocking; else state &= ~internal_non_blocking; return true; } return false; } int shutdown(socket_type s, int what, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } clear_last_error(); int result = error_wrapper(::shutdown(s, what), ec); if (result == 0) ec = asio::error_code(); return result; } template inline int call_connect(SockLenType msghdr::*, socket_type s, const socket_addr_type* addr, std::size_t addrlen) { return ::connect(s, addr, (SockLenType)addrlen); } int connect(socket_type s, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } clear_last_error(); int result = error_wrapper(call_connect( &msghdr::msg_namelen, s, addr, addrlen), ec); if (result == 0) ec = asio::error_code(); #if defined(__linux__) else if (ec == asio::error::try_again) ec = asio::error::no_buffer_space; #endif // defined(__linux__) return result; } void sync_connect(socket_type s, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec) { // Perform the connect operation. socket_ops::connect(s, addr, addrlen, ec); if (ec != asio::error::in_progress && ec != asio::error::would_block) { // The connect operation finished immediately. return; } // Wait for socket to become ready. if (socket_ops::poll_connect(s, -1, ec) < 0) return; // Get the error code from the connect operation. int connect_error = 0; size_t connect_error_len = sizeof(connect_error); if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec) == socket_error_retval) return; // Return the result of the connect operation. ec = asio::error_code(connect_error, asio::error::get_system_category()); } #if defined(ASIO_HAS_IOCP) void complete_iocp_connect(socket_type s, asio::error_code& ec) { // Map non-portable errors to their portable counterparts. switch (ec.value()) { case ERROR_CONNECTION_REFUSED: ec = asio::error::connection_refused; break; case ERROR_NETWORK_UNREACHABLE: ec = asio::error::network_unreachable; break; case ERROR_HOST_UNREACHABLE: ec = asio::error::host_unreachable; break; case ERROR_SEM_TIMEOUT: ec = asio::error::timed_out; break; default: break; } if (!ec) { // Need to set the SO_UPDATE_CONNECT_CONTEXT option so that getsockname // and getpeername will work on the connected socket. socket_ops::state_type state = 0; const int so_update_connect_context = 0x7010; socket_ops::setsockopt(s, state, SOL_SOCKET, so_update_connect_context, 0, 0, ec); } } #endif // defined(ASIO_HAS_IOCP) bool non_blocking_connect(socket_type s, asio::error_code& ec) { // Check if the connect operation has finished. This is required since we may // get spurious readiness notifications from the reactor. #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set write_fds; FD_ZERO(&write_fds); FD_SET(s, &write_fds); fd_set except_fds; FD_ZERO(&except_fds); FD_SET(s, &except_fds); timeval zero_timeout; zero_timeout.tv_sec = 0; zero_timeout.tv_usec = 0; int ready = ::select(s + 1, 0, &write_fds, &except_fds, &zero_timeout); #else // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; fds.fd = s; fds.events = POLLOUT; fds.revents = 0; int ready = ::poll(&fds, 1, 0); #endif // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (ready == 0) { // The asynchronous connect operation is still in progress. return false; } // Get the error code from the connect operation. int connect_error = 0; size_t connect_error_len = sizeof(connect_error); if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec) == 0) { if (connect_error) { ec = asio::error_code(connect_error, asio::error::get_system_category()); } else ec = asio::error_code(); } return true; } int socketpair(int af, int type, int protocol, socket_type sv[2], asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) (void)(af); (void)(type); (void)(protocol); (void)(sv); ec = asio::error::operation_not_supported; return socket_error_retval; #else clear_last_error(); int result = error_wrapper(::socketpair(af, type, protocol, sv), ec); if (result == 0) ec = asio::error_code(); return result; #endif } bool sockatmark(socket_type s, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return false; } #if defined(SIOCATMARK) ioctl_arg_type value = 0; # if defined(ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, SIOCATMARK, &value), ec); # else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec); # endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) if (result == 0) ec = asio::error_code(); # if defined(ENOTTY) if (ec.value() == ENOTTY) ec = asio::error::not_socket; # endif // defined(ENOTTY) #else // defined(SIOCATMARK) int value = error_wrapper(::sockatmark(s), ec); if (value != -1) ec = asio::error_code(); #endif // defined(SIOCATMARK) return ec ? false : value != 0; } size_t available(socket_type s, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return 0; } ioctl_arg_type value = 0; #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, FIONREAD, &value), ec); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec); #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) if (result == 0) ec = asio::error_code(); #if defined(ENOTTY) if (ec.value() == ENOTTY) ec = asio::error::not_socket; #endif // defined(ENOTTY) return ec ? static_cast(0) : static_cast(value); } int listen(socket_type s, int backlog, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } clear_last_error(); int result = error_wrapper(::listen(s, backlog), ec); if (result == 0) ec = asio::error_code(); return result; } inline void init_buf_iov_base(void*& base, void* addr) { base = addr; } template inline void init_buf_iov_base(T& base, void* addr) { base = static_cast(addr); } #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) typedef WSABUF buf; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) typedef iovec buf; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) void init_buf(buf& b, void* data, size_t size) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) b.buf = static_cast(data); b.len = static_cast(size); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) init_buf_iov_base(b.iov_base, data); b.iov_len = size; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } void init_buf(buf& b, const void* data, size_t size) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) b.buf = static_cast(const_cast(data)); b.len = static_cast(size); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) init_buf_iov_base(b.iov_base, const_cast(data)); b.iov_len = size; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr) { name = addr; } inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr) { name = const_cast(addr); } template inline void init_msghdr_msg_name(T& name, socket_addr_type* addr) { name = reinterpret_cast(addr); } template inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr) { name = reinterpret_cast(const_cast(addr)); } signed_size_type recv(socket_type s, buf* bufs, size_t count, int flags, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast(count); DWORD bytes_transferred = 0; DWORD recv_flags = flags; int result = error_wrapper(::WSARecv(s, bufs, recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); if (ec.value() == ERROR_NETNAME_DELETED) ec = asio::error::connection_reset; else if (ec.value() == ERROR_PORT_UNREACHABLE) ec = asio::error::connection_refused; else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA) result = 0; if (result != 0) return socket_error_retval; ec = asio::error_code(); return bytes_transferred; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = bufs; msg.msg_iovlen = static_cast(count); signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); if (result >= 0) ec = asio::error_code(); return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recv(socket_type s, state_type state, buf* bufs, size_t count, int flags, bool all_empty, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return 0; } // A request to read 0 bytes on a stream is a no-op. if (all_empty && (state & stream_oriented)) { ec = asio::error_code(); return 0; } // Read some data. for (;;) { // Try to complete the operation without blocking. signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec); // Check if operation succeeded. if (bytes > 0) return bytes; // Check for EOF. if ((state & stream_oriented) && bytes == 0) { ec = asio::error::eof; return 0; } // Operation failed. if ((state & user_set_non_blocking) || (ec != asio::error::would_block && ec != asio::error::try_again)) return 0; // Wait for socket to become ready. if (socket_ops::poll_read(s, 0, -1, ec) < 0) return 0; } } #if defined(ASIO_HAS_IOCP) void complete_iocp_recv(state_type state, const weak_cancel_token_type& cancel_token, bool all_empty, asio::error_code& ec, size_t bytes_transferred) { // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_NETNAME_DELETED) { if (cancel_token.expired()) ec = asio::error::operation_aborted; else ec = asio::error::connection_reset; } else if (ec.value() == ERROR_PORT_UNREACHABLE) { ec = asio::error::connection_refused; } else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA) { ec.assign(0, ec.category()); } // Check for connection closed. else if (!ec && bytes_transferred == 0 && (state & stream_oriented) != 0 && !all_empty) { ec = asio::error::eof; } } #else // defined(ASIO_HAS_IOCP) bool non_blocking_recv(socket_type s, buf* bufs, size_t count, int flags, bool is_stream, asio::error_code& ec, size_t& bytes_transferred) { for (;;) { // Read some data. signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec); // Check for end of stream. if (is_stream && bytes == 0) { ec = asio::error::eof; return true; } // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == asio::error::would_block || ec == asio::error::try_again) return false; // Operation is complete. if (bytes >= 0) { ec = asio::error_code(); bytes_transferred = bytes; } else bytes_transferred = 0; return true; } } #endif // defined(ASIO_HAS_IOCP) signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast(count); DWORD bytes_transferred = 0; DWORD recv_flags = flags; int tmp_addrlen = (int)*addrlen; int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); *addrlen = (std::size_t)tmp_addrlen; if (ec.value() == ERROR_NETNAME_DELETED) ec = asio::error::connection_reset; else if (ec.value() == ERROR_PORT_UNREACHABLE) ec = asio::error::connection_refused; else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA) result = 0; if (result != 0) return socket_error_retval; ec = asio::error_code(); return bytes_transferred; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); init_msghdr_msg_name(msg.msg_name, addr); msg.msg_namelen = static_cast(*addrlen); msg.msg_iov = bufs; msg.msg_iovlen = static_cast(count); signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); *addrlen = msg.msg_namelen; if (result >= 0) ec = asio::error_code(); return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return 0; } // Read some data. for (;;) { // Try to complete the operation without blocking. signed_size_type bytes = socket_ops::recvfrom( s, bufs, count, flags, addr, addrlen, ec); // Check if operation succeeded. if (bytes >= 0) return bytes; // Operation failed. if ((state & user_set_non_blocking) || (ec != asio::error::would_block && ec != asio::error::try_again)) return 0; // Wait for socket to become ready. if (socket_ops::poll_read(s, 0, -1, ec) < 0) return 0; } } #if defined(ASIO_HAS_IOCP) void complete_iocp_recvfrom( const weak_cancel_token_type& cancel_token, asio::error_code& ec) { // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_NETNAME_DELETED) { if (cancel_token.expired()) ec = asio::error::operation_aborted; else ec = asio::error::connection_reset; } else if (ec.value() == ERROR_PORT_UNREACHABLE) { ec = asio::error::connection_refused; } else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA) { ec.assign(0, ec.category()); } } #else // defined(ASIO_HAS_IOCP) bool non_blocking_recvfrom(socket_type s, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec, size_t& bytes_transferred) { for (;;) { // Read some data. signed_size_type bytes = socket_ops::recvfrom( s, bufs, count, flags, addr, addrlen, ec); // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == asio::error::would_block || ec == asio::error::try_again) return false; // Operation is complete. if (bytes >= 0) { ec = asio::error_code(); bytes_transferred = bytes; } else bytes_transferred = 0; return true; } } #endif // defined(ASIO_HAS_IOCP) signed_size_type recvmsg(socket_type s, buf* bufs, size_t count, int in_flags, int& out_flags, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) out_flags = 0; return socket_ops::recv(s, bufs, count, in_flags, ec); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = bufs; msg.msg_iovlen = static_cast(count); signed_size_type result = error_wrapper(::recvmsg(s, &msg, in_flags), ec); if (result >= 0) { ec = asio::error_code(); out_flags = msg.msg_flags; } else out_flags = 0; return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recvmsg(socket_type s, state_type state, buf* bufs, size_t count, int in_flags, int& out_flags, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return 0; } // Read some data. for (;;) { // Try to complete the operation without blocking. signed_size_type bytes = socket_ops::recvmsg( s, bufs, count, in_flags, out_flags, ec); // Check if operation succeeded. if (bytes >= 0) return bytes; // Operation failed. if ((state & user_set_non_blocking) || (ec != asio::error::would_block && ec != asio::error::try_again)) return 0; // Wait for socket to become ready. if (socket_ops::poll_read(s, 0, -1, ec) < 0) return 0; } } #if defined(ASIO_HAS_IOCP) void complete_iocp_recvmsg( const weak_cancel_token_type& cancel_token, asio::error_code& ec) { // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_NETNAME_DELETED) { if (cancel_token.expired()) ec = asio::error::operation_aborted; else ec = asio::error::connection_reset; } else if (ec.value() == ERROR_PORT_UNREACHABLE) { ec = asio::error::connection_refused; } else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA) { ec.assign(0, ec.category()); } } #else // defined(ASIO_HAS_IOCP) bool non_blocking_recvmsg(socket_type s, buf* bufs, size_t count, int in_flags, int& out_flags, asio::error_code& ec, size_t& bytes_transferred) { for (;;) { // Read some data. signed_size_type bytes = socket_ops::recvmsg( s, bufs, count, in_flags, out_flags, ec); // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == asio::error::would_block || ec == asio::error::try_again) return false; // Operation is complete. if (bytes >= 0) { ec = asio::error_code(); bytes_transferred = bytes; } else bytes_transferred = 0; return true; } } #endif // defined(ASIO_HAS_IOCP) signed_size_type send(socket_type s, const buf* bufs, size_t count, int flags, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast(count); DWORD bytes_transferred = 0; DWORD send_flags = flags; int result = error_wrapper(::WSASend(s, const_cast(bufs), send_buf_count, &bytes_transferred, send_flags, 0, 0), ec); if (ec.value() == ERROR_NETNAME_DELETED) ec = asio::error::connection_reset; else if (ec.value() == ERROR_PORT_UNREACHABLE) ec = asio::error::connection_refused; if (result != 0) return socket_error_retval; ec = asio::error_code(); return bytes_transferred; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = const_cast(bufs); msg.msg_iovlen = static_cast(count); #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec); if (result >= 0) ec = asio::error_code(); return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_send(socket_type s, state_type state, const buf* bufs, size_t count, int flags, bool all_empty, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return 0; } // A request to write 0 bytes to a stream is a no-op. if (all_empty && (state & stream_oriented)) { ec = asio::error_code(); return 0; } // Read some data. for (;;) { // Try to complete the operation without blocking. signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec); // Check if operation succeeded. if (bytes >= 0) return bytes; // Operation failed. if ((state & user_set_non_blocking) || (ec != asio::error::would_block && ec != asio::error::try_again)) return 0; // Wait for socket to become ready. if (socket_ops::poll_write(s, 0, -1, ec) < 0) return 0; } } #if defined(ASIO_HAS_IOCP) void complete_iocp_send( const weak_cancel_token_type& cancel_token, asio::error_code& ec) { // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_NETNAME_DELETED) { if (cancel_token.expired()) ec = asio::error::operation_aborted; else ec = asio::error::connection_reset; } else if (ec.value() == ERROR_PORT_UNREACHABLE) { ec = asio::error::connection_refused; } } #else // defined(ASIO_HAS_IOCP) bool non_blocking_send(socket_type s, const buf* bufs, size_t count, int flags, asio::error_code& ec, size_t& bytes_transferred) { for (;;) { // Write some data. signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec); // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == asio::error::would_block || ec == asio::error::try_again) return false; // Operation is complete. if (bytes >= 0) { ec = asio::error_code(); bytes_transferred = bytes; } else bytes_transferred = 0; return true; } } #endif // defined(ASIO_HAS_IOCP) signed_size_type sendto(socket_type s, const buf* bufs, size_t count, int flags, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast(count); DWORD bytes_transferred = 0; int result = error_wrapper(::WSASendTo(s, const_cast(bufs), send_buf_count, &bytes_transferred, flags, addr, static_cast(addrlen), 0, 0), ec); if (ec.value() == ERROR_NETNAME_DELETED) ec = asio::error::connection_reset; else if (ec.value() == ERROR_PORT_UNREACHABLE) ec = asio::error::connection_refused; if (result != 0) return socket_error_retval; ec = asio::error_code(); return bytes_transferred; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); init_msghdr_msg_name(msg.msg_name, addr); msg.msg_namelen = static_cast(addrlen); msg.msg_iov = const_cast(bufs); msg.msg_iovlen = static_cast(count); #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec); if (result >= 0) ec = asio::error_code(); return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_sendto(socket_type s, state_type state, const buf* bufs, size_t count, int flags, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return 0; } // Write some data. for (;;) { // Try to complete the operation without blocking. signed_size_type bytes = socket_ops::sendto( s, bufs, count, flags, addr, addrlen, ec); // Check if operation succeeded. if (bytes >= 0) return bytes; // Operation failed. if ((state & user_set_non_blocking) || (ec != asio::error::would_block && ec != asio::error::try_again)) return 0; // Wait for socket to become ready. if (socket_ops::poll_write(s, 0, -1, ec) < 0) return 0; } } #if !defined(ASIO_HAS_IOCP) bool non_blocking_sendto(socket_type s, const buf* bufs, size_t count, int flags, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec, size_t& bytes_transferred) { for (;;) { // Write some data. signed_size_type bytes = socket_ops::sendto( s, bufs, count, flags, addr, addrlen, ec); // Retry operation if interrupted by signal. if (ec == asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == asio::error::would_block || ec == asio::error::try_again) return false; // Operation is complete. if (bytes >= 0) { ec = asio::error_code(); bytes_transferred = bytes; } else bytes_transferred = 0; return true; } } #endif // !defined(ASIO_HAS_IOCP) socket_type socket(int af, int type, int protocol, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) socket_type s = error_wrapper(::WSASocketW(af, type, protocol, 0, 0, WSA_FLAG_OVERLAPPED), ec); if (s == invalid_socket) return s; if (af == ASIO_OS_DEF(AF_INET6)) { // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to // false. This will only succeed on Windows Vista and later versions of // Windows, where a dual-stack IPv4/v6 implementation is available. DWORD optval = 0; ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast(&optval), sizeof(optval)); } ec = asio::error_code(); return s; #elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) socket_type s = error_wrapper(::socket(af, type, protocol), ec); if (s == invalid_socket) return s; int optval = 1; int result = error_wrapper(::setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); if (result != 0) { ::close(s); return invalid_socket; } return s; #else int s = error_wrapper(::socket(af, type, protocol), ec); if (s >= 0) ec = asio::error_code(); return s; #endif } template inline int call_setsockopt(SockLenType msghdr::*, socket_type s, int level, int optname, const void* optval, std::size_t optlen) { return ::setsockopt(s, level, optname, (const char*)optval, (SockLenType)optlen); } int setsockopt(socket_type s, state_type& state, int level, int optname, const void* optval, std::size_t optlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } if (level == custom_socket_option_level && optname == always_fail_option) { ec = asio::error::invalid_argument; return socket_error_retval; } if (level == custom_socket_option_level && optname == enable_connection_aborted_option) { if (optlen != sizeof(int)) { ec = asio::error::invalid_argument; return socket_error_retval; } if (*static_cast(optval)) state |= enable_connection_aborted; else state &= ~enable_connection_aborted; ec = asio::error_code(); return 0; } if (level == SOL_SOCKET && optname == SO_LINGER) state |= user_set_linger; #if defined(__BORLANDC__) // Mysteriously, using the getsockopt and setsockopt functions directly with // Borland C++ results in incorrect values being set and read. The bug can be // worked around by using function addresses resolved with GetProcAddress. if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) { typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int); if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt")) { clear_last_error(); return error_wrapper(sso(s, level, optname, reinterpret_cast(optval), static_cast(optlen)), ec); } } ec = asio::error::fault; return socket_error_retval; #else // defined(__BORLANDC__) clear_last_error(); int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); if (result == 0) { ec = asio::error_code(); #if defined(__MACH__) && defined(__APPLE__) \ || defined(__NetBSD__) || defined(__FreeBSD__) \ || defined(__OpenBSD__) || defined(__QNX__) // To implement portable behaviour for SO_REUSEADDR with UDP sockets we // need to also set SO_REUSEPORT on BSD-based platforms. if ((state & datagram_oriented) && level == SOL_SOCKET && optname == SO_REUSEADDR) { call_setsockopt(&msghdr::msg_namelen, s, SOL_SOCKET, SO_REUSEPORT, optval, optlen); } #endif } return result; #endif // defined(__BORLANDC__) } template inline int call_getsockopt(SockLenType msghdr::*, socket_type s, int level, int optname, void* optval, std::size_t* optlen) { SockLenType tmp_optlen = (SockLenType)*optlen; int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen); *optlen = (std::size_t)tmp_optlen; return result; } int getsockopt(socket_type s, state_type state, int level, int optname, void* optval, size_t* optlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } if (level == custom_socket_option_level && optname == always_fail_option) { ec = asio::error::invalid_argument; return socket_error_retval; } if (level == custom_socket_option_level && optname == enable_connection_aborted_option) { if (*optlen != sizeof(int)) { ec = asio::error::invalid_argument; return socket_error_retval; } *static_cast(optval) = (state & enable_connection_aborted) ? 1 : 0; ec = asio::error_code(); return 0; } #if defined(__BORLANDC__) // Mysteriously, using the getsockopt and setsockopt functions directly with // Borland C++ results in incorrect values being set and read. The bug can be // worked around by using function addresses resolved with GetProcAddress. if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) { typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*); if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt")) { clear_last_error(); int tmp_optlen = static_cast(*optlen); int result = error_wrapper(gso(s, level, optname, reinterpret_cast(optval), &tmp_optlen), ec); *optlen = static_cast(tmp_optlen); if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) { // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are // only supported on Windows Vista and later. To simplify program logic // we will fake success of getting this option and specify that the // value is non-zero (i.e. true). This corresponds to the behavior of // IPv6 sockets on Windows platforms pre-Vista. *static_cast(optval) = 1; ec = asio::error_code(); } return result; } } ec = asio::error::fault; return socket_error_retval; #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) { // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only // supported on Windows Vista and later. To simplify program logic we will // fake success of getting this option and specify that the value is // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets // on Windows platforms pre-Vista. *static_cast(optval) = 1; ec = asio::error_code(); } if (result == 0) ec = asio::error_code(); return result; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); #if defined(__linux__) if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int) && (optname == SO_SNDBUF || optname == SO_RCVBUF)) { // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel // to set the buffer size to N*2. Linux puts additional stuff into the // buffers so that only about half is actually available to the application. // The retrieved value is divided by 2 here to make it appear as though the // correct value has been set. *static_cast(optval) /= 2; } #endif // defined(__linux__) if (result == 0) ec = asio::error_code(); return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } template inline int call_getpeername(SockLenType msghdr::*, socket_type s, socket_addr_type* addr, std::size_t* addrlen) { SockLenType tmp_addrlen = (SockLenType)*addrlen; int result = ::getpeername(s, addr, &tmp_addrlen); *addrlen = (std::size_t)tmp_addrlen; return result; } int getpeername(socket_type s, socket_addr_type* addr, std::size_t* addrlen, bool cached, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } #if defined(ASIO_WINDOWS) && !defined(ASIO_WINDOWS_APP) \ || defined(__CYGWIN__) if (cached) { // Check if socket is still connected. DWORD connect_time = 0; size_t connect_time_len = sizeof(connect_time); if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_CONNECT_TIME, &connect_time, &connect_time_len, ec) == socket_error_retval) { return socket_error_retval; } if (connect_time == 0xFFFFFFFF) { ec = asio::error::not_connected; return socket_error_retval; } // The cached value is still valid. ec = asio::error_code(); return 0; } #else // defined(ASIO_WINDOWS) && !defined(ASIO_WINDOWS_APP) // || defined(__CYGWIN__) (void)cached; #endif // defined(ASIO_WINDOWS) && !defined(ASIO_WINDOWS_APP) // || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getpeername( &msghdr::msg_namelen, s, addr, addrlen), ec); if (result == 0) ec = asio::error_code(); return result; } template inline int call_getsockname(SockLenType msghdr::*, socket_type s, socket_addr_type* addr, std::size_t* addrlen) { SockLenType tmp_addrlen = (SockLenType)*addrlen; int result = ::getsockname(s, addr, &tmp_addrlen); *addrlen = (std::size_t)tmp_addrlen; return result; } int getsockname(socket_type s, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } clear_last_error(); int result = error_wrapper(call_getsockname( &msghdr::msg_namelen, s, addr, addrlen), ec); if (result == 0) ec = asio::error_code(); return result; } int ioctl(socket_type s, state_type& state, int cmd, ioctl_arg_type* arg, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); #elif defined(__MACH__) && defined(__APPLE__) \ || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) int result = error_wrapper(::ioctl(s, static_cast(cmd), arg), ec); #else int result = error_wrapper(::ioctl(s, cmd, arg), ec); #endif if (result >= 0) { ec = asio::error_code(); // When updating the non-blocking mode we always perform the ioctl syscall, // even if the flags would otherwise indicate that the socket is already in // the correct state. This ensures that the underlying socket is put into // the state that has been requested by the user. If the ioctl syscall was // successful then we need to update the flags to match. if (cmd == static_cast(FIONBIO)) { if (*arg) { state |= user_set_non_blocking; } else { // Clearing the non-blocking mode always overrides any internally-set // non-blocking flag. Any subsequent asynchronous operations will need // to re-enable non-blocking I/O. state &= ~(user_set_non_blocking | internal_non_blocking); } } } return result; } int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) if (!readfds && !writefds && !exceptfds && timeout) { DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; if (milliseconds == 0) milliseconds = 1; // Force context switch. ::Sleep(milliseconds); ec = asio::error_code(); return 0; } // The select() call allows timeout values measured in microseconds, but the // system clock (as wrapped by boost::posix_time::microsec_clock) typically // has a resolution of 10 milliseconds. This can lead to a spinning select // reactor, meaning increased CPU usage, when waiting for the earliest // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight // spin we'll use a minimum timeout of 1 millisecond. if (timeout && timeout->tv_sec == 0 && timeout->tv_usec > 0 && timeout->tv_usec < 1000) timeout->tv_usec = 1000; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #if defined(__hpux) && defined(__SELECT) timespec ts; ts.tv_sec = timeout ? timeout->tv_sec : 0; ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0; return error_wrapper(::pselect(nfds, readfds, writefds, exceptfds, timeout ? &ts : 0, 0), ec); #else int result = error_wrapper(::select(nfds, readfds, writefds, exceptfds, timeout), ec); if (result >= 0) ec = asio::error_code(); return result; #endif } int poll_read(socket_type s, state_type state, int msec, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set fds; FD_ZERO(&fds); FD_SET(s, &fds); timeval timeout_obj; timeval* timeout; if (state & user_set_non_blocking) { timeout_obj.tv_sec = 0; timeout_obj.tv_usec = 0; timeout = &timeout_obj; } else if (msec >= 0) { timeout_obj.tv_sec = msec / 1000; timeout_obj.tv_usec = (msec % 1000) * 1000; timeout = &timeout_obj; } else timeout = 0; clear_last_error(); int result = error_wrapper(::select(s + 1, &fds, 0, 0, timeout), ec); #else // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; fds.fd = s; fds.events = POLLIN; fds.revents = 0; int timeout = (state & user_set_non_blocking) ? 0 : msec; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, timeout), ec); #endif // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (result == 0) ec = (state & user_set_non_blocking) ? asio::error::would_block : asio::error_code(); else if (result > 0) ec = asio::error_code(); return result; } int poll_write(socket_type s, state_type state, int msec, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set fds; FD_ZERO(&fds); FD_SET(s, &fds); timeval timeout_obj; timeval* timeout; if (state & user_set_non_blocking) { timeout_obj.tv_sec = 0; timeout_obj.tv_usec = 0; timeout = &timeout_obj; } else if (msec >= 0) { timeout_obj.tv_sec = msec / 1000; timeout_obj.tv_usec = (msec % 1000) * 1000; timeout = &timeout_obj; } else timeout = 0; clear_last_error(); int result = error_wrapper(::select(s + 1, 0, &fds, 0, timeout), ec); #else // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; fds.fd = s; fds.events = POLLOUT; fds.revents = 0; int timeout = (state & user_set_non_blocking) ? 0 : msec; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, timeout), ec); #endif // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (result == 0) ec = (state & user_set_non_blocking) ? asio::error::would_block : asio::error_code(); else if (result > 0) ec = asio::error_code(); return result; } int poll_error(socket_type s, state_type state, int msec, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set fds; FD_ZERO(&fds); FD_SET(s, &fds); timeval timeout_obj; timeval* timeout; if (state & user_set_non_blocking) { timeout_obj.tv_sec = 0; timeout_obj.tv_usec = 0; timeout = &timeout_obj; } else if (msec >= 0) { timeout_obj.tv_sec = msec / 1000; timeout_obj.tv_usec = (msec % 1000) * 1000; timeout = &timeout_obj; } else timeout = 0; clear_last_error(); int result = error_wrapper(::select(s + 1, 0, 0, &fds, timeout), ec); #else // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; fds.fd = s; fds.events = POLLPRI | POLLERR | POLLHUP; fds.revents = 0; int timeout = (state & user_set_non_blocking) ? 0 : msec; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, timeout), ec); #endif // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (result == 0) ec = (state & user_set_non_blocking) ? asio::error::would_block : asio::error_code(); else if (result > 0) ec = asio::error_code(); return result; } int poll_connect(socket_type s, int msec, asio::error_code& ec) { if (s == invalid_socket) { ec = asio::error::bad_descriptor; return socket_error_retval; } #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set write_fds; FD_ZERO(&write_fds); FD_SET(s, &write_fds); fd_set except_fds; FD_ZERO(&except_fds); FD_SET(s, &except_fds); timeval timeout_obj; timeval* timeout; if (msec >= 0) { timeout_obj.tv_sec = msec / 1000; timeout_obj.tv_usec = (msec % 1000) * 1000; timeout = &timeout_obj; } else timeout = 0; clear_last_error(); int result = error_wrapper(::select( s + 1, 0, &write_fds, &except_fds, timeout), ec); if (result >= 0) ec = asio::error_code(); return result; #else // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; fds.fd = s; fds.events = POLLOUT; fds.revents = 0; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, msec), ec); if (result >= 0) ec = asio::error_code(); return result; #endif // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) } #endif // !defined(ASIO_WINDOWS_RUNTIME) const char* inet_ntop(int af, const void* src, char* dest, size_t length, unsigned long scope_id, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS_RUNTIME) using namespace std; // For sprintf. const unsigned char* bytes = static_cast(src); if (af == ASIO_OS_DEF(AF_INET)) { sprintf_s(dest, length, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]); return dest; } else if (af == ASIO_OS_DEF(AF_INET6)) { size_t n = 0, b = 0, z = 0; while (n < length && b < 16) { if (bytes[b] == 0 && bytes[b + 1] == 0 && z == 0) { do b += 2; while (b < 16 && bytes[b] == 0 && bytes[b + 1] == 0); n += sprintf_s(dest + n, length - n, ":%s", b < 16 ? "" : ":"), ++z; } else { n += sprintf_s(dest + n, length - n, "%s%x", b ? ":" : "", (static_cast(bytes[b]) << 8) | bytes[b + 1]); b += 2; } } if (scope_id) n += sprintf_s(dest + n, length - n, "%%%lu", scope_id); return dest; } else { ec = asio::error::address_family_not_supported; return 0; } #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy. if (af != ASIO_OS_DEF(AF_INET) && af != ASIO_OS_DEF(AF_INET6)) { ec = asio::error::address_family_not_supported; return 0; } union { socket_addr_type base; sockaddr_storage_type storage; sockaddr_in4_type v4; sockaddr_in6_type v6; } address; DWORD address_length; if (af == ASIO_OS_DEF(AF_INET)) { address_length = sizeof(sockaddr_in4_type); address.v4.sin_family = ASIO_OS_DEF(AF_INET); address.v4.sin_port = 0; memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type)); } else // AF_INET6 { address_length = sizeof(sockaddr_in6_type); address.v6.sin6_family = ASIO_OS_DEF(AF_INET6); address.v6.sin6_port = 0; address.v6.sin6_flowinfo = 0; address.v6.sin6_scope_id = scope_id; memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type)); } DWORD string_length = static_cast(length); #if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800)) LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR)); int result = error_wrapper(::WSAAddressToStringW(&address.base, address_length, 0, string_buffer, &string_length), ec); ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, static_cast(length), 0, 0); #else int result = error_wrapper(::WSAAddressToStringA( &address.base, address_length, 0, dest, &string_length), ec); #endif // Windows may set error code on success. if (result != socket_error_retval) ec = asio::error_code(); // Windows may not set an error code on failure. else if (result == socket_error_retval && !ec) ec = asio::error::invalid_argument; return result == socket_error_retval ? 0 : dest; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) const char* result = error_wrapper(::inet_ntop( af, src, dest, static_cast(length)), ec); if (result == 0 && !ec) ec = asio::error::invalid_argument; if (result != 0 && af == ASIO_OS_DEF(AF_INET6) && scope_id != 0) { using namespace std; // For strcat and sprintf. char if_name[(IF_NAMESIZE > 21 ? IF_NAMESIZE : 21) + 1] = "%"; const in6_addr_type* ipv6_address = static_cast(src); bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe) && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80)); bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff) && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02)); if ((!is_link_local && !is_multicast_link_local) || if_indextoname(static_cast(scope_id), if_name + 1) == 0) sprintf(if_name + 1, "%lu", scope_id); strcat(dest, if_name); } return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } int inet_pton(int af, const char* src, void* dest, unsigned long* scope_id, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS_RUNTIME) using namespace std; // For sscanf. unsigned char* bytes = static_cast(dest); if (af == ASIO_OS_DEF(AF_INET)) { unsigned int b0, b1, b2, b3; if (sscanf_s(src, "%u.%u.%u.%u", &b0, &b1, &b2, &b3) != 4) { ec = asio::error::invalid_argument; return -1; } if (b0 > 255 || b1 > 255 || b2 > 255 || b3 > 255) { ec = asio::error::invalid_argument; return -1; } bytes[0] = static_cast(b0); bytes[1] = static_cast(b1); bytes[2] = static_cast(b2); bytes[3] = static_cast(b3); ec = asio::error_code(); return 1; } else if (af == ASIO_OS_DEF(AF_INET6)) { unsigned char* bytes = static_cast(dest); std::memset(bytes, 0, 16); unsigned char back_bytes[16] = { 0 }; int num_front_bytes = 0, num_back_bytes = 0; const char* p = src; enum { fword, fcolon, bword, scope, done } state = fword; unsigned long current_word = 0; while (state != done) { if (current_word > 0xFFFF) { ec = asio::error::invalid_argument; return -1; } switch (state) { case fword: if (*p >= '0' && *p <= '9') current_word = current_word * 16 + *p++ - '0'; else if (*p >= 'a' && *p <= 'f') current_word = current_word * 16 + *p++ - 'a' + 10; else if (*p >= 'A' && *p <= 'F') current_word = current_word * 16 + *p++ - 'A' + 10; else { if (num_front_bytes == 16) { ec = asio::error::invalid_argument; return -1; } bytes[num_front_bytes++] = (current_word >> 8) & 0xFF; bytes[num_front_bytes++] = current_word & 0xFF; current_word = 0; if (*p == ':') state = fcolon, ++p; else if (*p == '%') state = scope, ++p; else if (*p == 0) state = done; else { ec = asio::error::invalid_argument; return -1; } } break; case fcolon: if (*p == ':') state = bword, ++p; else state = fword; break; case bword: if (*p >= '0' && *p <= '9') current_word = current_word * 16 + *p++ - '0'; else if (*p >= 'a' && *p <= 'f') current_word = current_word * 16 + *p++ - 'a' + 10; else if (*p >= 'A' && *p <= 'F') current_word = current_word * 16 + *p++ - 'A' + 10; else { if (num_front_bytes + num_back_bytes == 16) { ec = asio::error::invalid_argument; return -1; } back_bytes[num_back_bytes++] = (current_word >> 8) & 0xFF; back_bytes[num_back_bytes++] = current_word & 0xFF; current_word = 0; if (*p == ':') state = bword, ++p; else if (*p == '%') state = scope, ++p; else if (*p == 0) state = done; else { ec = asio::error::invalid_argument; return -1; } } break; case scope: if (*p >= '0' && *p <= '9') current_word = current_word * 10 + *p++ - '0'; else if (*p == 0) *scope_id = current_word, state = done; else { ec = asio::error::invalid_argument; return -1; } break; default: break; } } for (int i = 0; i < num_back_bytes; ++i) bytes[16 - num_back_bytes + i] = back_bytes[i]; ec = asio::error_code(); return 1; } else { ec = asio::error::address_family_not_supported; return -1; } #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy and strcmp. if (af != ASIO_OS_DEF(AF_INET) && af != ASIO_OS_DEF(AF_INET6)) { ec = asio::error::address_family_not_supported; return -1; } union { socket_addr_type base; sockaddr_storage_type storage; sockaddr_in4_type v4; sockaddr_in6_type v6; } address; int address_length = sizeof(sockaddr_storage_type); #if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800)) int num_wide_chars = static_cast(strlen(src)) + 1; LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR)); ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars); int result = error_wrapper(::WSAStringToAddressW( wide_buffer, af, 0, &address.base, &address_length), ec); #else int result = error_wrapper(::WSAStringToAddressA( const_cast(src), af, 0, &address.base, &address_length), ec); #endif if (af == ASIO_OS_DEF(AF_INET)) { if (result != socket_error_retval) { memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type)); ec = asio::error_code(); } else if (strcmp(src, "255.255.255.255") == 0) { static_cast(dest)->s_addr = INADDR_NONE; ec = asio::error_code(); } } else // AF_INET6 { if (result != socket_error_retval) { memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type)); if (scope_id) *scope_id = address.v6.sin6_scope_id; ec = asio::error_code(); } } // Windows may not set an error code on failure. if (result == socket_error_retval && !ec) ec = asio::error::invalid_argument; if (result != socket_error_retval) ec = asio::error_code(); return result == socket_error_retval ? -1 : 1; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) using namespace std; // For strchr, memcpy and atoi. // On some platforms, inet_pton fails if an address string contains a scope // id. Detect and remove the scope id before passing the string to inet_pton. const bool is_v6 = (af == ASIO_OS_DEF(AF_INET6)); const char* if_name = is_v6 ? strchr(src, '%') : 0; char src_buf[max_addr_v6_str_len + 1]; const char* src_ptr = src; if (if_name != 0) { if (if_name - src > max_addr_v6_str_len) { ec = asio::error::invalid_argument; return 0; } memcpy(src_buf, src, if_name - src); src_buf[if_name - src] = 0; src_ptr = src_buf; } int result = error_wrapper(::inet_pton(af, src_ptr, dest), ec); if (result <= 0 && !ec) ec = asio::error::invalid_argument; if (result > 0 && is_v6 && scope_id) { using namespace std; // For strchr and atoi. *scope_id = 0; if (if_name != 0) { in6_addr_type* ipv6_address = static_cast(dest); bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe) && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80)); bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff) && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02)); if (is_link_local || is_multicast_link_local) *scope_id = if_nametoindex(if_name + 1); if (*scope_id == 0) *scope_id = atoi(if_name + 1); } } return result; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } int gethostname(char* name, int namelen, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS_RUNTIME) try { using namespace Windows::Foundation::Collections; using namespace Windows::Networking; using namespace Windows::Networking::Connectivity; IVectorView^ hostnames = NetworkInformation::GetHostNames(); for (unsigned i = 0; i < hostnames->Size; ++i) { HostName^ hostname = hostnames->GetAt(i); if (hostname->Type == HostNameType::DomainName) { std::wstring_convert> converter; std::string raw_name = converter.to_bytes(hostname->RawName->Data()); if (namelen > 0 && raw_name.size() < static_cast(namelen)) { strcpy_s(name, namelen, raw_name.c_str()); return 0; } } } return -1; } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); return -1; } #else // defined(ASIO_WINDOWS_RUNTIME) int result = error_wrapper(::gethostname(name, namelen), ec); # if defined(ASIO_WINDOWS) if (result == 0) ec = asio::error_code(); # endif // defined(ASIO_WINDOWS) return result; #endif // defined(ASIO_WINDOWS_RUNTIME) } #if !defined(ASIO_WINDOWS_RUNTIME) #if !defined(ASIO_HAS_GETADDRINFO) // The following functions are only needed for emulation of getaddrinfo and // getnameinfo. inline asio::error_code translate_netdb_error(int error) { switch (error) { case 0: return asio::error_code(); case HOST_NOT_FOUND: return asio::error::host_not_found; case TRY_AGAIN: return asio::error::host_not_found_try_again; case NO_RECOVERY: return asio::error::no_recovery; case NO_DATA: return asio::error::no_data; default: ASIO_ASSERT(false); return asio::error::invalid_argument; } } inline hostent* gethostbyaddr(const char* addr, int length, int af, hostent* result, char* buffer, int buflength, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); if (!retval) return 0; ec = asio::error_code(); *result = *retval; return retval; #elif defined(__sun) || defined(__QNX__) int error = 0; hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer, buflength, &error), ec); if (error) ec = translate_netdb_error(error); return retval; #elif defined(__MACH__) && defined(__APPLE__) (void)(buffer); (void)(buflength); int error = 0; hostent* retval = error_wrapper(::getipnodebyaddr( addr, length, af, &error), ec); if (error) ec = translate_netdb_error(error); if (!retval) return 0; *result = *retval; return retval; #else hostent* retval = 0; int error = 0; error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer, buflength, &retval, &error), ec); if (error) ec = translate_netdb_error(error); return retval; #endif } inline hostent* gethostbyname(const char* name, int af, struct hostent* result, char* buffer, int buflength, int ai_flags, asio::error_code& ec) { clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); (void)(ai_flags); if (af != ASIO_OS_DEF(AF_INET)) { ec = asio::error::address_family_not_supported; return 0; } hostent* retval = error_wrapper(::gethostbyname(name), ec); if (!retval) return 0; ec = asio::error_code(); *result = *retval; return result; #elif defined(__sun) || defined(__QNX__) (void)(ai_flags); if (af != ASIO_OS_DEF(AF_INET)) { ec = asio::error::address_family_not_supported; return 0; } int error = 0; hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer, buflength, &error), ec); if (error) ec = translate_netdb_error(error); return retval; #elif defined(__MACH__) && defined(__APPLE__) (void)(buffer); (void)(buflength); int error = 0; hostent* retval = error_wrapper(::getipnodebyname( name, af, ai_flags, &error), ec); if (error) ec = translate_netdb_error(error); if (!retval) return 0; *result = *retval; return retval; #else (void)(ai_flags); if (af != ASIO_OS_DEF(AF_INET)) { ec = asio::error::address_family_not_supported; return 0; } hostent* retval = 0; int error = 0; error_wrapper(::gethostbyname_r(name, result, buffer, buflength, &retval, &error), ec); if (error) ec = translate_netdb_error(error); return retval; #endif } inline void freehostent(hostent* h) { #if defined(__MACH__) && defined(__APPLE__) if (h) ::freehostent(h); #else (void)(h); #endif } // Emulation of getaddrinfo based on implementation in: // Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998. struct gai_search { const char* host; int family; }; inline int gai_nsearch(const char* host, const addrinfo_type* hints, gai_search (&search)[2]) { int search_count = 0; if (host == 0 || host[0] == '\0') { if (hints->ai_flags & AI_PASSIVE) { // No host and AI_PASSIVE implies wildcard bind. switch (hints->ai_family) { case ASIO_OS_DEF(AF_INET): search[search_count].host = "0.0.0.0"; search[search_count].family = ASIO_OS_DEF(AF_INET); ++search_count; break; case ASIO_OS_DEF(AF_INET6): search[search_count].host = "0::0"; search[search_count].family = ASIO_OS_DEF(AF_INET6); ++search_count; break; case ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = "0::0"; search[search_count].family = ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = "0.0.0.0"; search[search_count].family = ASIO_OS_DEF(AF_INET); ++search_count; break; default: break; } } else { // No host and not AI_PASSIVE means connect to local host. switch (hints->ai_family) { case ASIO_OS_DEF(AF_INET): search[search_count].host = "localhost"; search[search_count].family = ASIO_OS_DEF(AF_INET); ++search_count; break; case ASIO_OS_DEF(AF_INET6): search[search_count].host = "localhost"; search[search_count].family = ASIO_OS_DEF(AF_INET6); ++search_count; break; case ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = "localhost"; search[search_count].family = ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = "localhost"; search[search_count].family = ASIO_OS_DEF(AF_INET); ++search_count; break; default: break; } } } else { // Host is specified. switch (hints->ai_family) { case ASIO_OS_DEF(AF_INET): search[search_count].host = host; search[search_count].family = ASIO_OS_DEF(AF_INET); ++search_count; break; case ASIO_OS_DEF(AF_INET6): search[search_count].host = host; search[search_count].family = ASIO_OS_DEF(AF_INET6); ++search_count; break; case ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = host; search[search_count].family = ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = host; search[search_count].family = ASIO_OS_DEF(AF_INET); ++search_count; break; default: break; } } return search_count; } template inline T* gai_alloc(std::size_t size = sizeof(T)) { using namespace std; T* p = static_cast(::operator new(size, std::nothrow)); if (p) memset(p, 0, size); return p; } inline void gai_free(void* p) { ::operator delete(p); } inline void gai_strcpy(char* target, const char* source, std::size_t max_size) { using namespace std; #if defined(ASIO_HAS_SECURE_RTL) strcpy_s(target, max_size, source); #else // defined(ASIO_HAS_SECURE_RTL) *target = 0; if (max_size > 0) strncat(target, source, max_size - 1); #endif // defined(ASIO_HAS_SECURE_RTL) } enum { gai_clone_flag = 1 << 30 }; inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints, const void* addr, int family) { using namespace std; addrinfo_type* ai = gai_alloc(); if (ai == 0) return EAI_MEMORY; ai->ai_next = 0; **next = ai; *next = &ai->ai_next; ai->ai_canonname = 0; ai->ai_socktype = hints->ai_socktype; if (ai->ai_socktype == 0) ai->ai_flags |= gai_clone_flag; ai->ai_protocol = hints->ai_protocol; ai->ai_family = family; switch (ai->ai_family) { case ASIO_OS_DEF(AF_INET): { sockaddr_in4_type* sinptr = gai_alloc(); if (sinptr == 0) return EAI_MEMORY; sinptr->sin_family = ASIO_OS_DEF(AF_INET); memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type)); ai->ai_addr = reinterpret_cast(sinptr); ai->ai_addrlen = sizeof(sockaddr_in4_type); break; } case ASIO_OS_DEF(AF_INET6): { sockaddr_in6_type* sin6ptr = gai_alloc(); if (sin6ptr == 0) return EAI_MEMORY; sin6ptr->sin6_family = ASIO_OS_DEF(AF_INET6); memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type)); ai->ai_addr = reinterpret_cast(sin6ptr); ai->ai_addrlen = sizeof(sockaddr_in6_type); break; } default: break; } return 0; } inline addrinfo_type* gai_clone(addrinfo_type* ai) { using namespace std; addrinfo_type* new_ai = gai_alloc(); if (new_ai == 0) return new_ai; new_ai->ai_next = ai->ai_next; ai->ai_next = new_ai; new_ai->ai_flags = 0; new_ai->ai_family = ai->ai_family; new_ai->ai_socktype = ai->ai_socktype; new_ai->ai_protocol = ai->ai_protocol; new_ai->ai_canonname = 0; new_ai->ai_addrlen = ai->ai_addrlen; new_ai->ai_addr = gai_alloc(ai->ai_addrlen); memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen); return new_ai; } inline int gai_port(addrinfo_type* aihead, int port, int socktype) { int num_found = 0; for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next) { if (ai->ai_flags & gai_clone_flag) { if (ai->ai_socktype != 0) { ai = gai_clone(ai); if (ai == 0) return -1; // ai now points to newly cloned entry. } } else if (ai->ai_socktype != socktype) { // Ignore if mismatch on socket type. continue; } ai->ai_socktype = socktype; switch (ai->ai_family) { case ASIO_OS_DEF(AF_INET): { sockaddr_in4_type* sinptr = reinterpret_cast(ai->ai_addr); sinptr->sin_port = port; ++num_found; break; } case ASIO_OS_DEF(AF_INET6): { sockaddr_in6_type* sin6ptr = reinterpret_cast(ai->ai_addr); sin6ptr->sin6_port = port; ++num_found; break; } default: break; } } return num_found; } inline int gai_serv(addrinfo_type* aihead, const addrinfo_type* hints, const char* serv) { using namespace std; int num_found = 0; if ( #if defined(AI_NUMERICSERV) (hints->ai_flags & AI_NUMERICSERV) || #endif isdigit(static_cast(serv[0]))) { int port = htons(atoi(serv)); if (hints->ai_socktype) { // Caller specifies socket type. int rc = gai_port(aihead, port, hints->ai_socktype); if (rc < 0) return EAI_MEMORY; num_found += rc; } else { // Caller does not specify socket type. int rc = gai_port(aihead, port, SOCK_STREAM); if (rc < 0) return EAI_MEMORY; num_found += rc; rc = gai_port(aihead, port, SOCK_DGRAM); if (rc < 0) return EAI_MEMORY; num_found += rc; } } else { // Try service name with TCP first, then UDP. if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM) { servent* sptr = getservbyname(serv, "tcp"); if (sptr != 0) { int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM); if (rc < 0) return EAI_MEMORY; num_found += rc; } } if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM) { servent* sptr = getservbyname(serv, "udp"); if (sptr != 0) { int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM); if (rc < 0) return EAI_MEMORY; num_found += rc; } } } if (num_found == 0) { if (hints->ai_socktype == 0) { // All calls to getservbyname() failed. return EAI_NONAME; } else { // Service not supported for socket type. return EAI_SERVICE; } } return 0; } inline int gai_echeck(const char* host, const char* service, int flags, int family, int socktype, int protocol) { (void)(flags); (void)(protocol); // Host or service must be specified. if (host == 0 || host[0] == '\0') if (service == 0 || service[0] == '\0') return EAI_NONAME; // Check combination of family and socket type. switch (family) { case ASIO_OS_DEF(AF_UNSPEC): break; case ASIO_OS_DEF(AF_INET): case ASIO_OS_DEF(AF_INET6): if (service != 0 && service[0] != '\0') if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) return EAI_SOCKTYPE; break; default: return EAI_FAMILY; } return 0; } inline void freeaddrinfo_emulation(addrinfo_type* aihead) { addrinfo_type* ai = aihead; while (ai) { gai_free(ai->ai_addr); gai_free(ai->ai_canonname); addrinfo_type* ainext = ai->ai_next; gai_free(ai); ai = ainext; } } inline int getaddrinfo_emulation(const char* host, const char* service, const addrinfo_type* hintsp, addrinfo_type** result) { // Set up linked list of addrinfo structures. addrinfo_type* aihead = 0; addrinfo_type** ainext = &aihead; char* canon = 0; // Supply default hints if not specified by caller. addrinfo_type hints = addrinfo_type(); hints.ai_family = ASIO_OS_DEF(AF_UNSPEC); if (hintsp) hints = *hintsp; // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED // and AI_ALL flags. #if defined(AI_V4MAPPED) if (hints.ai_family != ASIO_OS_DEF(AF_INET6)) hints.ai_flags &= ~AI_V4MAPPED; #endif #if defined(AI_ALL) if (hints.ai_family != ASIO_OS_DEF(AF_INET6)) hints.ai_flags &= ~AI_ALL; #endif // Basic error checking. int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family, hints.ai_socktype, hints.ai_protocol); if (rc != 0) { freeaddrinfo_emulation(aihead); return rc; } gai_search search[2]; int search_count = gai_nsearch(host, &hints, search); for (gai_search* sptr = search; sptr < search + search_count; ++sptr) { // Check for IPv4 dotted decimal string. in4_addr_type inaddr; asio::error_code ec; if (socket_ops::inet_pton(ASIO_OS_DEF(AF_INET), sptr->host, &inaddr, 0, ec) == 1) { if (hints.ai_family != ASIO_OS_DEF(AF_UNSPEC) && hints.ai_family != ASIO_OS_DEF(AF_INET)) { freeaddrinfo_emulation(aihead); gai_free(canon); return EAI_FAMILY; } if (sptr->family == ASIO_OS_DEF(AF_INET)) { rc = gai_aistruct(&ainext, &hints, &inaddr, ASIO_OS_DEF(AF_INET)); if (rc != 0) { freeaddrinfo_emulation(aihead); gai_free(canon); return rc; } } continue; } // Check for IPv6 hex string. in6_addr_type in6addr; if (socket_ops::inet_pton(ASIO_OS_DEF(AF_INET6), sptr->host, &in6addr, 0, ec) == 1) { if (hints.ai_family != ASIO_OS_DEF(AF_UNSPEC) && hints.ai_family != ASIO_OS_DEF(AF_INET6)) { freeaddrinfo_emulation(aihead); gai_free(canon); return EAI_FAMILY; } if (sptr->family == ASIO_OS_DEF(AF_INET6)) { rc = gai_aistruct(&ainext, &hints, &in6addr, ASIO_OS_DEF(AF_INET6)); if (rc != 0) { freeaddrinfo_emulation(aihead); gai_free(canon); return rc; } } continue; } // Look up hostname. hostent hent; char hbuf[8192] = ""; hostent* hptr = socket_ops::gethostbyname(sptr->host, sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec); if (hptr == 0) { if (search_count == 2) { // Failure is OK if there are multiple searches. continue; } freeaddrinfo_emulation(aihead); gai_free(canon); if (ec == asio::error::host_not_found) return EAI_NONAME; if (ec == asio::error::host_not_found_try_again) return EAI_AGAIN; if (ec == asio::error::no_recovery) return EAI_FAIL; if (ec == asio::error::no_data) return EAI_NONAME; return EAI_NONAME; } // Check for address family mismatch if one was specified. if (hints.ai_family != ASIO_OS_DEF(AF_UNSPEC) && hints.ai_family != hptr->h_addrtype) { freeaddrinfo_emulation(aihead); gai_free(canon); socket_ops::freehostent(hptr); return EAI_FAMILY; } // Save canonical name first time. if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0] && (hints.ai_flags & AI_CANONNAME) && canon == 0) { std::size_t canon_len = strlen(hptr->h_name) + 1; canon = gai_alloc(canon_len); if (canon == 0) { freeaddrinfo_emulation(aihead); socket_ops::freehostent(hptr); return EAI_MEMORY; } gai_strcpy(canon, hptr->h_name, canon_len); } // Create an addrinfo structure for each returned address. for (char** ap = hptr->h_addr_list; *ap; ++ap) { rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype); if (rc != 0) { freeaddrinfo_emulation(aihead); gai_free(canon); socket_ops::freehostent(hptr); return EAI_FAMILY; } } socket_ops::freehostent(hptr); } // Check if we found anything. if (aihead == 0) { gai_free(canon); return EAI_NONAME; } // Return canonical name in first entry. if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME)) { if (canon) { aihead->ai_canonname = canon; canon = 0; } else { std::size_t canonname_len = strlen(search[0].host) + 1; aihead->ai_canonname = gai_alloc(canonname_len); if (aihead->ai_canonname == 0) { freeaddrinfo_emulation(aihead); return EAI_MEMORY; } gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len); } } gai_free(canon); // Process the service name. if (service != 0 && service[0] != '\0') { rc = gai_serv(aihead, &hints, service); if (rc != 0) { freeaddrinfo_emulation(aihead); return rc; } } // Return result to caller. *result = aihead; return 0; } inline asio::error_code getnameinfo_emulation( const socket_addr_type* sa, std::size_t salen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int flags, asio::error_code& ec) { using namespace std; const char* addr; size_t addr_len; unsigned short port; switch (sa->sa_family) { case ASIO_OS_DEF(AF_INET): if (salen != sizeof(sockaddr_in4_type)) { return ec = asio::error::invalid_argument; } addr = reinterpret_cast( &reinterpret_cast(sa)->sin_addr); addr_len = sizeof(in4_addr_type); port = reinterpret_cast(sa)->sin_port; break; case ASIO_OS_DEF(AF_INET6): if (salen != sizeof(sockaddr_in6_type)) { return ec = asio::error::invalid_argument; } addr = reinterpret_cast( &reinterpret_cast(sa)->sin6_addr); addr_len = sizeof(in6_addr_type); port = reinterpret_cast(sa)->sin6_port; break; default: return ec = asio::error::address_family_not_supported; } if (host && hostlen > 0) { if (flags & NI_NUMERICHOST) { if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0) { return ec; } } else { hostent hent; char hbuf[8192] = ""; hostent* hptr = socket_ops::gethostbyaddr(addr, static_cast(addr_len), sa->sa_family, &hent, hbuf, sizeof(hbuf), ec); if (hptr && hptr->h_name && hptr->h_name[0] != '\0') { if (flags & NI_NOFQDN) { char* dot = strchr(hptr->h_name, '.'); if (dot) { *dot = 0; } } gai_strcpy(host, hptr->h_name, hostlen); socket_ops::freehostent(hptr); } else { socket_ops::freehostent(hptr); if (flags & NI_NAMEREQD) { return ec = asio::error::host_not_found; } if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0) { return ec; } } } } if (serv && servlen > 0) { if (flags & NI_NUMERICSERV) { if (servlen < 6) { return ec = asio::error::no_buffer_space; } #if defined(ASIO_HAS_SECURE_RTL) sprintf_s(serv, servlen, "%u", ntohs(port)); #else // defined(ASIO_HAS_SECURE_RTL) sprintf(serv, "%u", ntohs(port)); #endif // defined(ASIO_HAS_SECURE_RTL) } else { #if defined(ASIO_HAS_PTHREADS) static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ::pthread_mutex_lock(&mutex); #endif // defined(ASIO_HAS_PTHREADS) servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0); if (sptr && sptr->s_name && sptr->s_name[0] != '\0') { gai_strcpy(serv, sptr->s_name, servlen); } else { if (servlen < 6) { return ec = asio::error::no_buffer_space; } #if defined(ASIO_HAS_SECURE_RTL) sprintf_s(serv, servlen, "%u", ntohs(port)); #else // defined(ASIO_HAS_SECURE_RTL) sprintf(serv, "%u", ntohs(port)); #endif // defined(ASIO_HAS_SECURE_RTL) } #if defined(ASIO_HAS_PTHREADS) ::pthread_mutex_unlock(&mutex); #endif // defined(ASIO_HAS_PTHREADS) } } ec = asio::error_code(); return ec; } #endif // !defined(ASIO_HAS_GETADDRINFO) inline asio::error_code translate_addrinfo_error(int error) { switch (error) { case 0: return asio::error_code(); case EAI_AGAIN: return asio::error::host_not_found_try_again; case EAI_BADFLAGS: return asio::error::invalid_argument; case EAI_FAIL: return asio::error::no_recovery; case EAI_FAMILY: return asio::error::address_family_not_supported; case EAI_MEMORY: return asio::error::no_memory; case EAI_NONAME: #if defined(EAI_ADDRFAMILY) case EAI_ADDRFAMILY: #endif #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: #endif return asio::error::host_not_found; case EAI_SERVICE: return asio::error::service_not_found; case EAI_SOCKTYPE: return asio::error::socket_type_not_supported; default: // Possibly the non-portable EAI_SYSTEM. #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) return asio::error_code( WSAGetLastError(), asio::error::get_system_category()); #else return asio::error_code( errno, asio::error::get_system_category()); #endif } } asio::error_code getaddrinfo(const char* host, const char* service, const addrinfo_type& hints, addrinfo_type** result, asio::error_code& ec) { host = (host && *host) ? host : 0; service = (service && *service) ? service : 0; clear_last_error(); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. int error = ::getaddrinfo(host, service, &hints, result); return ec = translate_addrinfo_error(error); # else // Building for Windows 2000 or earlier. typedef int (WSAAPI *gai_t)(const char*, const char*, const addrinfo_type*, addrinfo_type**); if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) { if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo")) { int error = gai(host, service, &hints, result); return ec = translate_addrinfo_error(error); } } int error = getaddrinfo_emulation(host, service, &hints, result); return ec = translate_addrinfo_error(error); # endif #elif !defined(ASIO_HAS_GETADDRINFO) int error = getaddrinfo_emulation(host, service, &hints, result); return ec = translate_addrinfo_error(error); #else int error = ::getaddrinfo(host, service, &hints, result); #if defined(__MACH__) && defined(__APPLE__) using namespace std; // For isdigit and atoi. if (error == 0 && service && isdigit(static_cast(service[0]))) { u_short_type port = host_to_network_short(atoi(service)); for (addrinfo_type* ai = *result; ai; ai = ai->ai_next) { switch (ai->ai_family) { case ASIO_OS_DEF(AF_INET): { sockaddr_in4_type* sinptr = reinterpret_cast(ai->ai_addr); if (sinptr->sin_port == 0) sinptr->sin_port = port; break; } case ASIO_OS_DEF(AF_INET6): { sockaddr_in6_type* sin6ptr = reinterpret_cast(ai->ai_addr); if (sin6ptr->sin6_port == 0) sin6ptr->sin6_port = port; break; } default: break; } } } #endif return ec = translate_addrinfo_error(error); #endif } asio::error_code background_getaddrinfo( const weak_cancel_token_type& cancel_token, const char* host, const char* service, const addrinfo_type& hints, addrinfo_type** result, asio::error_code& ec) { if (cancel_token.expired()) ec = asio::error::operation_aborted; else socket_ops::getaddrinfo(host, service, hints, result, ec); return ec; } void freeaddrinfo(addrinfo_type* ai) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. ::freeaddrinfo(ai); # else // Building for Windows 2000 or earlier. typedef int (WSAAPI *fai_t)(addrinfo_type*); if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) { if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo")) { fai(ai); return; } } freeaddrinfo_emulation(ai); # endif #elif !defined(ASIO_HAS_GETADDRINFO) freeaddrinfo_emulation(ai); #else ::freeaddrinfo(ai); #endif } asio::error_code getnameinfo(const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int flags, asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. clear_last_error(); int error = ::getnameinfo(addr, static_cast(addrlen), host, static_cast(hostlen), serv, static_cast(servlen), flags); return ec = translate_addrinfo_error(error); # else // Building for Windows 2000 or earlier. typedef int (WSAAPI *gni_t)(const socket_addr_type*, int, char*, DWORD, char*, DWORD, int); if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) { if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo")) { clear_last_error(); int error = gni(addr, static_cast(addrlen), host, static_cast(hostlen), serv, static_cast(servlen), flags); return ec = translate_addrinfo_error(error); } } clear_last_error(); return getnameinfo_emulation(addr, addrlen, host, hostlen, serv, servlen, flags, ec); # endif #elif !defined(ASIO_HAS_GETADDRINFO) using namespace std; // For memcpy. sockaddr_storage_type tmp_addr; memcpy(&tmp_addr, addr, addrlen); addr = reinterpret_cast(&tmp_addr); clear_last_error(); return getnameinfo_emulation(addr, addrlen, host, hostlen, serv, servlen, flags, ec); #else clear_last_error(); int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags); return ec = translate_addrinfo_error(error); #endif } asio::error_code sync_getnameinfo( const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int sock_type, asio::error_code& ec) { // First try resolving with the service name. If that fails try resolving // but allow the service to be returned as a number. int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0; socket_ops::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags, ec); if (ec) { socket_ops::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags | NI_NUMERICSERV, ec); } return ec; } asio::error_code background_getnameinfo( const weak_cancel_token_type& cancel_token, const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int sock_type, asio::error_code& ec) { if (cancel_token.expired()) { ec = asio::error::operation_aborted; } else { // First try resolving with the service name. If that fails try resolving // but allow the service to be returned as a number. int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0; socket_ops::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags, ec); if (ec) { socket_ops::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags | NI_NUMERICSERV, ec); } } return ec; } #endif // !defined(ASIO_WINDOWS_RUNTIME) u_long_type network_to_host_long(u_long_type value) { #if defined(ASIO_WINDOWS_RUNTIME) unsigned char* value_p = reinterpret_cast(&value); u_long_type result = (static_cast(value_p[0]) << 24) | (static_cast(value_p[1]) << 16) | (static_cast(value_p[2]) << 8) | static_cast(value_p[3]); return result; #else // defined(ASIO_WINDOWS_RUNTIME) return ntohl(value); #endif // defined(ASIO_WINDOWS_RUNTIME) } u_long_type host_to_network_long(u_long_type value) { #if defined(ASIO_WINDOWS_RUNTIME) u_long_type result; unsigned char* result_p = reinterpret_cast(&result); result_p[0] = static_cast((value >> 24) & 0xFF); result_p[1] = static_cast((value >> 16) & 0xFF); result_p[2] = static_cast((value >> 8) & 0xFF); result_p[3] = static_cast(value & 0xFF); return result; #else // defined(ASIO_WINDOWS_RUNTIME) return htonl(value); #endif // defined(ASIO_WINDOWS_RUNTIME) } u_short_type network_to_host_short(u_short_type value) { #if defined(ASIO_WINDOWS_RUNTIME) unsigned char* value_p = reinterpret_cast(&value); u_short_type result = (static_cast(value_p[0]) << 8) | static_cast(value_p[1]); return result; #else // defined(ASIO_WINDOWS_RUNTIME) return ntohs(value); #endif // defined(ASIO_WINDOWS_RUNTIME) } u_short_type host_to_network_short(u_short_type value) { #if defined(ASIO_WINDOWS_RUNTIME) u_short_type result; unsigned char* result_p = reinterpret_cast(&result); result_p[0] = static_cast((value >> 8) & 0xFF); result_p[1] = static_cast(value & 0xFF); return result; #else // defined(ASIO_WINDOWS_RUNTIME) return htons(value); #endif // defined(ASIO_WINDOWS_RUNTIME) } } // namespace socket_ops } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SOCKET_OPS_IPP ================================================ FILE: src/third_party/asio/detail/impl/socket_select_interrupter.ipp ================================================ // // detail/impl/socket_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP #define ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS_RUNTIME) #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) #include #include "asio/detail/socket_holder.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_select_interrupter.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { socket_select_interrupter::socket_select_interrupter() { open_descriptors(); } void socket_select_interrupter::open_descriptors() { asio::error_code ec; socket_holder acceptor(socket_ops::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); if (acceptor.get() == invalid_socket) asio::detail::throw_error(ec, "socket_select_interrupter"); int opt = 1; socket_ops::state_type acceptor_state = 0; socket_ops::setsockopt(acceptor.get(), acceptor_state, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec); using namespace std; // For memset. sockaddr_in4_type addr; std::size_t addr_len = sizeof(addr); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK); addr.sin_port = 0; if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr, addr_len, ec) == socket_error_retval) asio::detail::throw_error(ec, "socket_select_interrupter"); if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr, &addr_len, ec) == socket_error_retval) asio::detail::throw_error(ec, "socket_select_interrupter"); // Some broken firewalls on Windows will intermittently cause getsockname to // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We // explicitly specify the target address here to work around this problem. if (addr.sin_addr.s_addr == socket_ops::host_to_network_long(INADDR_ANY)) addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK); if (socket_ops::listen(acceptor.get(), SOMAXCONN, ec) == socket_error_retval) asio::detail::throw_error(ec, "socket_select_interrupter"); socket_holder client(socket_ops::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); if (client.get() == invalid_socket) asio::detail::throw_error(ec, "socket_select_interrupter"); if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr, addr_len, ec) == socket_error_retval) asio::detail::throw_error(ec, "socket_select_interrupter"); socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec)); if (server.get() == invalid_socket) asio::detail::throw_error(ec, "socket_select_interrupter"); ioctl_arg_type non_blocking = 1; socket_ops::state_type client_state = 0; if (socket_ops::ioctl(client.get(), client_state, FIONBIO, &non_blocking, ec)) asio::detail::throw_error(ec, "socket_select_interrupter"); opt = 1; socket_ops::setsockopt(client.get(), client_state, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); non_blocking = 1; socket_ops::state_type server_state = 0; if (socket_ops::ioctl(server.get(), server_state, FIONBIO, &non_blocking, ec)) asio::detail::throw_error(ec, "socket_select_interrupter"); opt = 1; socket_ops::setsockopt(server.get(), server_state, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); read_descriptor_ = server.release(); write_descriptor_ = client.release(); } socket_select_interrupter::~socket_select_interrupter() { close_descriptors(); } void socket_select_interrupter::close_descriptors() { asio::error_code ec; socket_ops::state_type state = socket_ops::internal_non_blocking; if (read_descriptor_ != invalid_socket) socket_ops::close(read_descriptor_, state, true, ec); if (write_descriptor_ != invalid_socket) socket_ops::close(write_descriptor_, state, true, ec); } void socket_select_interrupter::recreate() { close_descriptors(); write_descriptor_ = invalid_socket; read_descriptor_ = invalid_socket; open_descriptors(); } void socket_select_interrupter::interrupt() { char byte = 0; socket_ops::buf b; socket_ops::init_buf(b, &byte, 1); asio::error_code ec; socket_ops::send(write_descriptor_, &b, 1, 0, ec); } bool socket_select_interrupter::reset() { char data[1024]; socket_ops::buf b; socket_ops::init_buf(b, data, sizeof(data)); asio::error_code ec; int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); bool was_interrupted = (bytes_read > 0); while (bytes_read == sizeof(data)) bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); return was_interrupted; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) #endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP ================================================ FILE: src/third_party/asio/detail/impl/strand_executor_service.hpp ================================================ // // detail/impl/strand_executor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_HPP #define ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/call_stack.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/executor_work_guard.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class strand_executor_service::invoker { public: invoker(const implementation_type& impl, Executor& ex) : impl_(impl), work_(ex) { } invoker(const invoker& other) : impl_(other.impl_), work_(other.work_) { } #if defined(ASIO_HAS_MOVE) invoker(invoker&& other) : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)), work_(ASIO_MOVE_CAST(executor_work_guard)(other.work_)) { } #endif // defined(ASIO_HAS_MOVE) struct on_invoker_exit { invoker* this_; ~on_invoker_exit() { this_->impl_->mutex_->lock(); this_->impl_->ready_queue_.push(this_->impl_->waiting_queue_); bool more_handlers = this_->impl_->locked_ = !this_->impl_->ready_queue_.empty(); this_->impl_->mutex_->unlock(); if (more_handlers) { Executor ex(this_->work_.get_executor()); recycling_allocator allocator; ex.post(ASIO_MOVE_CAST(invoker)(*this_), allocator); } } }; void operator()() { // Indicate that this strand is executing on the current thread. call_stack::context ctx(impl_.get()); // Ensure the next handler, if any, is scheduled on block exit. on_invoker_exit on_exit = { this }; (void)on_exit; // Run all ready handlers. No lock is required since the ready queue is // accessed only within the strand. asio::error_code ec; while (scheduler_operation* o = impl_->ready_queue_.front()) { impl_->ready_queue_.pop(); o->complete(impl_.get(), ec, 0); } } private: implementation_type impl_; executor_work_guard work_; }; template void strand_executor_service::dispatch(const implementation_type& impl, Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) { typedef typename decay::type function_type; // If we are already in the strand then the function can run immediately. if (call_stack::contains(impl.get())) { // Make a local, non-const copy of the function. function_type tmp(ASIO_MOVE_CAST(Function)(function)); fenced_block b(fenced_block::full); asio_handler_invoke_helpers::invoke(tmp, tmp); return; } // Allocate and construct an operation to wrap the function. typedef executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "dispatch")); // Add the function to the strand and schedule the strand if required. bool first = enqueue(impl, p.p); p.v = p.p = 0; if (first) ex.dispatch(invoker(impl, ex), a); } // Request invocation of the given function and return immediately. template void strand_executor_service::post(const implementation_type& impl, Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) { typedef typename decay::type function_type; // Allocate and construct an operation to wrap the function. typedef executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "post")); // Add the function to the strand and schedule the strand if required. bool first = enqueue(impl, p.p); p.v = p.p = 0; if (first) ex.post(invoker(impl, ex), a); } // Request invocation of the given function and return immediately. template void strand_executor_service::defer(const implementation_type& impl, Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) { typedef typename decay::type function_type; // Allocate and construct an operation to wrap the function. typedef executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "defer")); // Add the function to the strand and schedule the strand if required. bool first = enqueue(impl, p.p); p.v = p.p = 0; if (first) ex.defer(invoker(impl, ex), a); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/impl/strand_executor_service.ipp ================================================ // // detail/impl/strand_executor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_IPP #define ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/strand_executor_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { strand_executor_service::strand_executor_service(execution_context& ctx) : execution_context_service_base(ctx), mutex_(), salt_(0), impl_list_(0) { } void strand_executor_service::shutdown() { op_queue ops; asio::detail::mutex::scoped_lock lock(mutex_); strand_impl* impl = impl_list_; while (impl) { impl->mutex_->lock(); impl->shutdown_ = true; ops.push(impl->waiting_queue_); ops.push(impl->ready_queue_); impl->mutex_->unlock(); impl = impl->next_; } } strand_executor_service::implementation_type strand_executor_service::create_implementation() { implementation_type new_impl(new strand_impl); new_impl->locked_ = false; new_impl->shutdown_ = false; asio::detail::mutex::scoped_lock lock(mutex_); // Select a mutex from the pool of shared mutexes. std::size_t salt = salt_++; std::size_t mutex_index = reinterpret_cast(new_impl.get()); mutex_index += (reinterpret_cast(new_impl.get()) >> 3); mutex_index ^= salt + 0x9e3779b9 + (mutex_index << 6) + (mutex_index >> 2); mutex_index = mutex_index % num_mutexes; if (!mutexes_[mutex_index].get()) mutexes_[mutex_index].reset(new mutex); new_impl->mutex_ = mutexes_[mutex_index].get(); // Insert implementation into linked list of all implementations. new_impl->next_ = impl_list_; new_impl->prev_ = 0; if (impl_list_) impl_list_->prev_ = new_impl.get(); impl_list_ = new_impl.get(); new_impl->service_ = this; return new_impl; } strand_executor_service::strand_impl::~strand_impl() { asio::detail::mutex::scoped_lock lock(service_->mutex_); // Remove implementation from linked list of all implementations. if (service_->impl_list_ == this) service_->impl_list_ = next_; if (prev_) prev_->next_ = next_; if (next_) next_->prev_= prev_; } bool strand_executor_service::enqueue(const implementation_type& impl, scheduler_operation* op) { impl->mutex_->lock(); if (impl->shutdown_) { impl->mutex_->unlock(); op->destroy(); return false; } else if (impl->locked_) { // Some other function already holds the strand lock. Enqueue for later. impl->waiting_queue_.push(op); impl->mutex_->unlock(); return false; } else { // The function is acquiring the strand lock and so is responsible for // scheduling the strand. impl->locked_ = true; impl->mutex_->unlock(); impl->ready_queue_.push(op); return true; } } bool strand_executor_service::running_in_this_thread( const implementation_type& impl) { return !!call_stack::contains(impl.get()); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_STRAND_EXECUTOR_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/strand_service.hpp ================================================ // // detail/impl/strand_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP #define ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/call_stack.hpp" #include "asio/detail/completion_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { inline strand_service::strand_impl::strand_impl() : operation(&strand_service::do_complete), locked_(false) { } struct strand_service::on_dispatch_exit { io_context_impl* io_context_; strand_impl* impl_; ~on_dispatch_exit() { impl_->mutex_.lock(); impl_->ready_queue_.push(impl_->waiting_queue_); bool more_handlers = impl_->locked_ = !impl_->ready_queue_.empty(); impl_->mutex_.unlock(); if (more_handlers) io_context_->post_immediate_completion(impl_, false); } }; template void strand_service::dispatch(strand_service::implementation_type& impl, Handler& handler) { // If we are already in the strand then the handler can run immediately. if (call_stack::contains(impl)) { fenced_block b(fenced_block::full); asio_handler_invoke_helpers::invoke(handler, handler); return; } // Allocate and construct an operation to wrap the handler. typedef completion_handler op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler); ASIO_HANDLER_CREATION((this->context(), *p.p, "strand", impl, 0, "dispatch")); bool dispatch_immediately = do_dispatch(impl, p.p); operation* o = p.p; p.v = p.p = 0; if (dispatch_immediately) { // Indicate that this strand is executing on the current thread. call_stack::context ctx(impl); // Ensure the next handler, if any, is scheduled on block exit. on_dispatch_exit on_exit = { &io_context_, impl }; (void)on_exit; completion_handler::do_complete( &io_context_, o, asio::error_code(), 0); } } // Request the io_context to invoke the given handler and return immediately. template void strand_service::post(strand_service::implementation_type& impl, Handler& handler) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef completion_handler op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler); ASIO_HANDLER_CREATION((this->context(), *p.p, "strand", impl, 0, "post")); do_post(impl, p.p, is_continuation); p.v = p.p = 0; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/impl/strand_service.ipp ================================================ // // detail/impl/strand_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP #define ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/call_stack.hpp" #include "asio/detail/strand_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct strand_service::on_do_complete_exit { io_context_impl* owner_; strand_impl* impl_; ~on_do_complete_exit() { impl_->mutex_.lock(); impl_->ready_queue_.push(impl_->waiting_queue_); bool more_handlers = impl_->locked_ = !impl_->ready_queue_.empty(); impl_->mutex_.unlock(); if (more_handlers) owner_->post_immediate_completion(impl_, true); } }; strand_service::strand_service(asio::io_context& io_context) : asio::detail::service_base(io_context), io_context_(asio::use_service(io_context)), mutex_(), salt_(0) { } void strand_service::shutdown() { op_queue ops; asio::detail::mutex::scoped_lock lock(mutex_); for (std::size_t i = 0; i < num_implementations; ++i) { if (strand_impl* impl = implementations_[i].get()) { ops.push(impl->waiting_queue_); ops.push(impl->ready_queue_); } } } void strand_service::construct(strand_service::implementation_type& impl) { asio::detail::mutex::scoped_lock lock(mutex_); std::size_t salt = salt_++; #if defined(ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION) std::size_t index = salt; #else // defined(ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION) std::size_t index = reinterpret_cast(&impl); index += (reinterpret_cast(&impl) >> 3); index ^= salt + 0x9e3779b9 + (index << 6) + (index >> 2); #endif // defined(ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION) index = index % num_implementations; if (!implementations_[index].get()) implementations_[index].reset(new strand_impl); impl = implementations_[index].get(); } bool strand_service::running_in_this_thread( const implementation_type& impl) const { return call_stack::contains(impl) != 0; } bool strand_service::do_dispatch(implementation_type& impl, operation* op) { // If we are running inside the io_context, and no other handler already // holds the strand lock, then the handler can run immediately. bool can_dispatch = io_context_.can_dispatch(); impl->mutex_.lock(); if (can_dispatch && !impl->locked_) { // Immediate invocation is allowed. impl->locked_ = true; impl->mutex_.unlock(); return true; } if (impl->locked_) { // Some other handler already holds the strand lock. Enqueue for later. impl->waiting_queue_.push(op); impl->mutex_.unlock(); } else { // The handler is acquiring the strand lock and so is responsible for // scheduling the strand. impl->locked_ = true; impl->mutex_.unlock(); impl->ready_queue_.push(op); io_context_.post_immediate_completion(impl, false); } return false; } void strand_service::do_post(implementation_type& impl, operation* op, bool is_continuation) { impl->mutex_.lock(); if (impl->locked_) { // Some other handler already holds the strand lock. Enqueue for later. impl->waiting_queue_.push(op); impl->mutex_.unlock(); } else { // The handler is acquiring the strand lock and so is responsible for // scheduling the strand. impl->locked_ = true; impl->mutex_.unlock(); impl->ready_queue_.push(op); io_context_.post_immediate_completion(impl, is_continuation); } } void strand_service::do_complete(void* owner, operation* base, const asio::error_code& ec, std::size_t /*bytes_transferred*/) { if (owner) { strand_impl* impl = static_cast(base); // Indicate that this strand is executing on the current thread. call_stack::context ctx(impl); // Ensure the next handler, if any, is scheduled on block exit. on_do_complete_exit on_exit; on_exit.owner_ = static_cast(owner); on_exit.impl_ = impl; // Run all ready handlers. No lock is required since the ready queue is // accessed only within the strand. while (operation* o = impl->ready_queue_.front()) { impl->ready_queue_.pop(); o->complete(owner, ec, 0); } } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/throw_error.ipp ================================================ // // detail/impl/throw_error.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_THROW_ERROR_IPP #define ASIO_DETAIL_IMPL_THROW_ERROR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/system_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { void do_throw_error(const asio::error_code& err) { asio::system_error e(err); asio::detail::throw_exception(e); } void do_throw_error(const asio::error_code& err, const char* location) { // boostify: non-boost code starts here #if defined(ASIO_MSVC) && defined(ASIO_HAS_STD_SYSTEM_ERROR) // Microsoft's implementation of std::system_error is non-conformant in that // it ignores the error code's message when a "what" string is supplied. We'll // work around this by explicitly formatting the "what" string. std::string what_msg = location; what_msg += ": "; what_msg += err.message(); asio::system_error e(err, what_msg); asio::detail::throw_exception(e); #else // defined(ASIO_MSVC) && defined(ASIO_HAS_STD_SYSTEM_ERROR) // boostify: non-boost code ends here asio::system_error e(err, location); asio::detail::throw_exception(e); // boostify: non-boost code starts here #endif // defined(ASIO_MSVC) && defined(ASIO_HAS_STD_SYSTEM_ERROR) // boostify: non-boost code ends here } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_THROW_ERROR_IPP ================================================ FILE: src/third_party/asio/detail/impl/timer_queue_ptime.ipp ================================================ // // detail/impl/timer_queue_ptime.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP #define ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) #include "asio/detail/timer_queue_ptime.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { timer_queue >::timer_queue() { } timer_queue >::~timer_queue() { } bool timer_queue >::enqueue_timer( const time_type& time, per_timer_data& timer, wait_op* op) { return impl_.enqueue_timer(time, timer, op); } bool timer_queue >::empty() const { return impl_.empty(); } long timer_queue >::wait_duration_msec( long max_duration) const { return impl_.wait_duration_msec(max_duration); } long timer_queue >::wait_duration_usec( long max_duration) const { return impl_.wait_duration_usec(max_duration); } void timer_queue >::get_ready_timers( op_queue& ops) { impl_.get_ready_timers(ops); } void timer_queue >::get_all_timers( op_queue& ops) { impl_.get_all_timers(ops); } std::size_t timer_queue >::cancel_timer( per_timer_data& timer, op_queue& ops, std::size_t max_cancelled) { return impl_.cancel_timer(timer, ops, max_cancelled); } void timer_queue >::move_timer( per_timer_data& target, per_timer_data& source) { impl_.move_timer(target, source); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_BOOST_DATE_TIME) #endif // ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP ================================================ FILE: src/third_party/asio/detail/impl/timer_queue_set.ipp ================================================ // // detail/impl/timer_queue_set.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP #define ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/timer_queue_set.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { timer_queue_set::timer_queue_set() : first_(0) { } void timer_queue_set::insert(timer_queue_base* q) { q->next_ = first_; first_ = q; } void timer_queue_set::erase(timer_queue_base* q) { if (first_) { if (q == first_) { first_ = q->next_; q->next_ = 0; return; } for (timer_queue_base* p = first_; p->next_; p = p->next_) { if (p->next_ == q) { p->next_ = q->next_; q->next_ = 0; return; } } } } bool timer_queue_set::all_empty() const { for (timer_queue_base* p = first_; p; p = p->next_) if (!p->empty()) return false; return true; } long timer_queue_set::wait_duration_msec(long max_duration) const { long min_duration = max_duration; for (timer_queue_base* p = first_; p; p = p->next_) min_duration = p->wait_duration_msec(min_duration); return min_duration; } long timer_queue_set::wait_duration_usec(long max_duration) const { long min_duration = max_duration; for (timer_queue_base* p = first_; p; p = p->next_) min_duration = p->wait_duration_usec(min_duration); return min_duration; } void timer_queue_set::get_ready_timers(op_queue& ops) { for (timer_queue_base* p = first_; p; p = p->next_) p->get_ready_timers(ops); } void timer_queue_set::get_all_timers(op_queue& ops) { for (timer_queue_base* p = first_; p; p = p->next_) p->get_all_timers(ops); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_event.ipp ================================================ // // detail/win_event.ipp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_EVENT_IPP #define ASIO_DETAIL_IMPL_WIN_EVENT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include "asio/detail/throw_error.hpp" #include "asio/detail/win_event.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { win_event::win_event() : state_(0) { #if defined(ASIO_WINDOWS_APP) events_[0] = ::CreateEventExW(0, 0, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); #else // defined(ASIO_WINDOWS_APP) events_[0] = ::CreateEventW(0, true, false, 0); #endif // defined(ASIO_WINDOWS_APP) if (!events_[0]) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "event"); } #if defined(ASIO_WINDOWS_APP) events_[1] = ::CreateEventExW(0, 0, 0, EVENT_ALL_ACCESS); #else // defined(ASIO_WINDOWS_APP) events_[1] = ::CreateEventW(0, false, false, 0); #endif // defined(ASIO_WINDOWS_APP) if (!events_[1]) { DWORD last_error = ::GetLastError(); ::CloseHandle(events_[0]); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "event"); } } win_event::~win_event() { ::CloseHandle(events_[0]); ::CloseHandle(events_[1]); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_IMPL_WIN_EVENT_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_iocp_handle_service.ipp ================================================ // // detail/impl/win_iocp_handle_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP #define ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/win_iocp_handle_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_iocp_handle_service::overlapped_wrapper : public OVERLAPPED { public: explicit overlapped_wrapper(asio::error_code& ec) { Internal = 0; InternalHigh = 0; Offset = 0; OffsetHigh = 0; // Create a non-signalled manual-reset event, for GetOverlappedResult. hEvent = ::CreateEventW(0, TRUE, FALSE, 0); if (hEvent) { // As documented in GetQueuedCompletionStatus, setting the low order // bit of this event prevents our synchronous writes from being treated // as completion port events. DWORD_PTR tmp = reinterpret_cast(hEvent); hEvent = reinterpret_cast(tmp | 1); } else { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); } } ~overlapped_wrapper() { if (hEvent) { ::CloseHandle(hEvent); } } }; win_iocp_handle_service::win_iocp_handle_service(execution_context& context) : execution_context_service_base(context), iocp_service_(asio::use_service(context)), mutex_(), impl_list_(0) { } void win_iocp_handle_service::shutdown() { // Close all implementations, causing all operations to complete. asio::detail::mutex::scoped_lock lock(mutex_); implementation_type* impl = impl_list_; while (impl) { close_for_destruction(*impl); impl = impl->next_; } } void win_iocp_handle_service::construct( win_iocp_handle_service::implementation_type& impl) { impl.handle_ = INVALID_HANDLE_VALUE; impl.safe_cancellation_thread_id_ = 0; // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } void win_iocp_handle_service::move_construct( win_iocp_handle_service::implementation_type& impl, win_iocp_handle_service::implementation_type& other_impl) { impl.handle_ = other_impl.handle_; other_impl.handle_ = INVALID_HANDLE_VALUE; impl.safe_cancellation_thread_id_ = other_impl.safe_cancellation_thread_id_; other_impl.safe_cancellation_thread_id_ = 0; // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } void win_iocp_handle_service::move_assign( win_iocp_handle_service::implementation_type& impl, win_iocp_handle_service& other_service, win_iocp_handle_service::implementation_type& other_impl) { close_for_destruction(impl); if (this != &other_service) { // Remove implementation from linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } impl.handle_ = other_impl.handle_; other_impl.handle_ = INVALID_HANDLE_VALUE; impl.safe_cancellation_thread_id_ = other_impl.safe_cancellation_thread_id_; other_impl.safe_cancellation_thread_id_ = 0; if (this != &other_service) { // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(other_service.mutex_); impl.next_ = other_service.impl_list_; impl.prev_ = 0; if (other_service.impl_list_) other_service.impl_list_->prev_ = &impl; other_service.impl_list_ = &impl; } } void win_iocp_handle_service::destroy( win_iocp_handle_service::implementation_type& impl) { close_for_destruction(impl); // Remove implementation from linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } asio::error_code win_iocp_handle_service::assign( win_iocp_handle_service::implementation_type& impl, const native_handle_type& handle, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } if (iocp_service_.register_handle(handle, ec)) return ec; impl.handle_ = handle; ec = asio::error_code(); return ec; } asio::error_code win_iocp_handle_service::close( win_iocp_handle_service::implementation_type& impl, asio::error_code& ec) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((iocp_service_.context(), "handle", &impl, reinterpret_cast(impl.handle_), "close")); if (!::CloseHandle(impl.handle_)) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); } else { ec = asio::error_code(); } impl.handle_ = INVALID_HANDLE_VALUE; impl.safe_cancellation_thread_id_ = 0; } else { ec = asio::error_code(); } return ec; } asio::error_code win_iocp_handle_service::cancel( win_iocp_handle_service::implementation_type& impl, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return ec; } ASIO_HANDLER_OPERATION((iocp_service_.context(), "handle", &impl, reinterpret_cast(impl.handle_), "cancel")); if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) { // The version of Windows supports cancellation from any thread. typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); cancel_io_ex_t cancel_io_ex = reinterpret_cast( reinterpret_cast(cancel_io_ex_ptr)); if (!cancel_io_ex(impl.handle_, 0)) { DWORD last_error = ::GetLastError(); if (last_error == ERROR_NOT_FOUND) { // ERROR_NOT_FOUND means that there were no operations to be // cancelled. We swallow this error to match the behaviour on other // platforms. ec = asio::error_code(); } else { ec = asio::error_code(last_error, asio::error::get_system_category()); } } else { ec = asio::error_code(); } } else if (impl.safe_cancellation_thread_id_ == 0) { // No operations have been started, so there's nothing to cancel. ec = asio::error_code(); } else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) { // Asynchronous operations have been started from the current thread only, // so it is safe to try to cancel them using CancelIo. if (!::CancelIo(impl.handle_)) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); } else { ec = asio::error_code(); } } else { // Asynchronous operations have been started from more than one thread, // so cancellation is not safe. ec = asio::error::operation_not_supported; } return ec; } size_t win_iocp_handle_service::do_write( win_iocp_handle_service::implementation_type& impl, uint64_t offset, const asio::const_buffer& buffer, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return 0; } // A request to write 0 bytes on a handle is a no-op. if (buffer.size() == 0) { ec = asio::error_code(); return 0; } overlapped_wrapper overlapped(ec); if (ec) { return 0; } // Write the data. overlapped.Offset = offset & 0xFFFFFFFF; overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::WriteFile(impl.handle_, buffer.data(), static_cast(buffer.size()), 0, &overlapped); if (!ok) { DWORD last_error = ::GetLastError(); if (last_error != ERROR_IO_PENDING) { ec = asio::error_code(last_error, asio::error::get_system_category()); return 0; } } // Wait for the operation to complete. DWORD bytes_transferred = 0; ok = ::GetOverlappedResult(impl.handle_, &overlapped, &bytes_transferred, TRUE); if (!ok) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); return 0; } ec = asio::error_code(); return bytes_transferred; } void win_iocp_handle_service::start_write_op( win_iocp_handle_service::implementation_type& impl, uint64_t offset, const asio::const_buffer& buffer, operation* op) { update_cancellation_thread_id(impl); iocp_service_.work_started(); if (!is_open(impl)) { iocp_service_.on_completion(op, asio::error::bad_descriptor); } else if (buffer.size() == 0) { // A request to write 0 bytes on a handle is a no-op. iocp_service_.on_completion(op); } else { DWORD bytes_transferred = 0; op->Offset = offset & 0xFFFFFFFF; op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::WriteFile(impl.handle_, buffer.data(), static_cast(buffer.size()), &bytes_transferred, op); DWORD last_error = ::GetLastError(); if (!ok && last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) { iocp_service_.on_completion(op, last_error, bytes_transferred); } else { iocp_service_.on_pending(op); } } } size_t win_iocp_handle_service::do_read( win_iocp_handle_service::implementation_type& impl, uint64_t offset, const asio::mutable_buffer& buffer, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return 0; } // A request to read 0 bytes on a stream handle is a no-op. if (buffer.size() == 0) { ec = asio::error_code(); return 0; } overlapped_wrapper overlapped(ec); if (ec) { return 0; } // Read some data. overlapped.Offset = offset & 0xFFFFFFFF; overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::ReadFile(impl.handle_, buffer.data(), static_cast(buffer.size()), 0, &overlapped); if (!ok) { DWORD last_error = ::GetLastError(); if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) { if (last_error == ERROR_HANDLE_EOF) { ec = asio::error::eof; } else { ec = asio::error_code(last_error, asio::error::get_system_category()); } return 0; } } // Wait for the operation to complete. DWORD bytes_transferred = 0; ok = ::GetOverlappedResult(impl.handle_, &overlapped, &bytes_transferred, TRUE); if (!ok) { DWORD last_error = ::GetLastError(); if (last_error == ERROR_HANDLE_EOF) { ec = asio::error::eof; } else { ec = asio::error_code(last_error, asio::error::get_system_category()); } return (last_error == ERROR_MORE_DATA) ? bytes_transferred : 0; } ec = asio::error_code(); return bytes_transferred; } void win_iocp_handle_service::start_read_op( win_iocp_handle_service::implementation_type& impl, uint64_t offset, const asio::mutable_buffer& buffer, operation* op) { update_cancellation_thread_id(impl); iocp_service_.work_started(); if (!is_open(impl)) { iocp_service_.on_completion(op, asio::error::bad_descriptor); } else if (buffer.size() == 0) { // A request to read 0 bytes on a handle is a no-op. iocp_service_.on_completion(op); } else { DWORD bytes_transferred = 0; op->Offset = offset & 0xFFFFFFFF; op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::ReadFile(impl.handle_, buffer.data(), static_cast(buffer.size()), &bytes_transferred, op); DWORD last_error = ::GetLastError(); if (!ok && last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) { iocp_service_.on_completion(op, last_error, bytes_transferred); } else { iocp_service_.on_pending(op); } } } void win_iocp_handle_service::update_cancellation_thread_id( win_iocp_handle_service::implementation_type& impl) { if (impl.safe_cancellation_thread_id_ == 0) impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) impl.safe_cancellation_thread_id_ = ~DWORD(0); } void win_iocp_handle_service::close_for_destruction(implementation_type& impl) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((iocp_service_.context(), "handle", &impl, reinterpret_cast(impl.handle_), "close")); ::CloseHandle(impl.handle_); impl.handle_ = INVALID_HANDLE_VALUE; impl.safe_cancellation_thread_id_ = 0; } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_iocp_io_context.hpp ================================================ // // detail/impl/win_iocp_io_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_HPP #define ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/completion_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template void win_iocp_io_context::add_timer_queue( timer_queue& queue) { do_add_timer_queue(queue); } template void win_iocp_io_context::remove_timer_queue( timer_queue& queue) { do_remove_timer_queue(queue); } template void win_iocp_io_context::schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op) { // If the service has been shut down we silently discard the timer. if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) { post_immediate_completion(op, false); return; } mutex::scoped_lock lock(dispatch_mutex_); bool earliest = queue.enqueue_timer(time, timer, op); work_started(); if (earliest) update_timeout(); } template std::size_t win_iocp_io_context::cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled) { // If the service has been shut down we silently ignore the cancellation. if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) return 0; mutex::scoped_lock lock(dispatch_mutex_); op_queue ops; std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); post_deferred_completions(ops); return n; } template void win_iocp_io_context::move_timer(timer_queue& queue, typename timer_queue::per_timer_data& to, typename timer_queue::per_timer_data& from) { asio::detail::mutex::scoped_lock lock(dispatch_mutex_); op_queue ops; queue.cancel_timer(to, ops); queue.move_timer(to, from); lock.unlock(); post_deferred_completions(ops); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_HPP ================================================ FILE: src/third_party/asio/detail/impl/win_iocp_io_context.ipp ================================================ // // detail/impl/win_iocp_io_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_IPP #define ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/error.hpp" #include "asio/detail/cstdint.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/win_iocp_io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct win_iocp_io_context::thread_function { explicit thread_function(win_iocp_io_context* s) : this_(s) { } void operator()() { asio::error_code ec; this_->run(ec); } win_iocp_io_context* this_; }; struct win_iocp_io_context::work_finished_on_block_exit { ~work_finished_on_block_exit() { io_context_->work_finished(); } win_iocp_io_context* io_context_; }; struct win_iocp_io_context::timer_thread_function { void operator()() { while (::InterlockedExchangeAdd(&io_context_->shutdown_, 0) == 0) { if (::WaitForSingleObject(io_context_->waitable_timer_.handle, INFINITE) == WAIT_OBJECT_0) { ::InterlockedExchange(&io_context_->dispatch_required_, 1); ::PostQueuedCompletionStatus(io_context_->iocp_.handle, 0, wake_for_dispatch, 0); } } } win_iocp_io_context* io_context_; }; win_iocp_io_context::win_iocp_io_context( asio::execution_context& ctx, int concurrency_hint, bool own_thread) : execution_context_service_base(ctx), iocp_(), outstanding_work_(0), stopped_(0), stop_event_posted_(0), shutdown_(0), gqcs_timeout_(get_gqcs_timeout()), dispatch_required_(0), concurrency_hint_(concurrency_hint) { ASIO_HANDLER_TRACKING_INIT; iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, static_cast(concurrency_hint >= 0 ? concurrency_hint : DWORD(~0))); if (!iocp_.handle) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "iocp"); } if (own_thread) { ::InterlockedIncrement(&outstanding_work_); thread_.reset(new asio::detail::thread(thread_function(this))); } } win_iocp_io_context::~win_iocp_io_context() { if (thread_.get()) { thread_->join(); thread_.reset(); } } void win_iocp_io_context::shutdown() { ::InterlockedExchange(&shutdown_, 1); if (timer_thread_.get()) { LARGE_INTEGER timeout; timeout.QuadPart = 1; ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE); } if (thread_.get()) { thread_->join(); thread_.reset(); ::InterlockedDecrement(&outstanding_work_); } while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0) { op_queue ops; timer_queues_.get_all_timers(ops); ops.push(completed_ops_); if (!ops.empty()) { while (win_iocp_operation* op = ops.front()) { ops.pop(); ::InterlockedDecrement(&outstanding_work_); op->destroy(); } } else { DWORD bytes_transferred = 0; dword_ptr_t completion_key = 0; LPOVERLAPPED overlapped = 0; ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, &completion_key, &overlapped, gqcs_timeout_); if (overlapped) { ::InterlockedDecrement(&outstanding_work_); static_cast(overlapped)->destroy(); } } } if (timer_thread_.get()) timer_thread_->join(); } asio::error_code win_iocp_io_context::register_handle( HANDLE handle, asio::error_code& ec) { if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); } else { ec = asio::error_code(); } return ec; } size_t win_iocp_io_context::run(asio::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = asio::error_code(); return 0; } win_iocp_thread_info this_thread; thread_call_stack::context ctx(this, this_thread); size_t n = 0; while (do_one(INFINITE, ec)) if (n != (std::numeric_limits::max)()) ++n; return n; } size_t win_iocp_io_context::run_one(asio::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = asio::error_code(); return 0; } win_iocp_thread_info this_thread; thread_call_stack::context ctx(this, this_thread); return do_one(INFINITE, ec); } size_t win_iocp_io_context::wait_one(long usec, asio::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = asio::error_code(); return 0; } win_iocp_thread_info this_thread; thread_call_stack::context ctx(this, this_thread); return do_one(usec < 0 ? INFINITE : ((usec - 1) / 1000 + 1), ec); } size_t win_iocp_io_context::poll(asio::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = asio::error_code(); return 0; } win_iocp_thread_info this_thread; thread_call_stack::context ctx(this, this_thread); size_t n = 0; while (do_one(0, ec)) if (n != (std::numeric_limits::max)()) ++n; return n; } size_t win_iocp_io_context::poll_one(asio::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = asio::error_code(); return 0; } win_iocp_thread_info this_thread; thread_call_stack::context ctx(this, this_thread); return do_one(0, ec); } void win_iocp_io_context::stop() { if (::InterlockedExchange(&stopped_, 1) == 0) { if (::InterlockedExchange(&stop_event_posted_, 1) == 0) { if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "pqcs"); } } } } void win_iocp_io_context::post_deferred_completion(win_iocp_operation* op) { // Flag the operation as ready. op->ready_ = 1; // Enqueue the operation on the I/O completion port. if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, op)) { // Out of resources. Put on completed queue instead. mutex::scoped_lock lock(dispatch_mutex_); completed_ops_.push(op); ::InterlockedExchange(&dispatch_required_, 1); } } void win_iocp_io_context::post_deferred_completions( op_queue& ops) { while (win_iocp_operation* op = ops.front()) { ops.pop(); // Flag the operation as ready. op->ready_ = 1; // Enqueue the operation on the I/O completion port. if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, op)) { // Out of resources. Put on completed queue instead. mutex::scoped_lock lock(dispatch_mutex_); completed_ops_.push(op); completed_ops_.push(ops); ::InterlockedExchange(&dispatch_required_, 1); } } } void win_iocp_io_context::abandon_operations( op_queue& ops) { while (win_iocp_operation* op = ops.front()) { ops.pop(); ::InterlockedDecrement(&outstanding_work_); op->destroy(); } } void win_iocp_io_context::on_pending(win_iocp_operation* op) { if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) { // Enqueue the operation on the I/O completion port. if (!::PostQueuedCompletionStatus(iocp_.handle, 0, overlapped_contains_result, op)) { // Out of resources. Put on completed queue instead. mutex::scoped_lock lock(dispatch_mutex_); completed_ops_.push(op); ::InterlockedExchange(&dispatch_required_, 1); } } } void win_iocp_io_context::on_completion(win_iocp_operation* op, DWORD last_error, DWORD bytes_transferred) { // Flag that the operation is ready for invocation. op->ready_ = 1; // Store results in the OVERLAPPED structure. op->Internal = reinterpret_cast( &asio::error::get_system_category()); op->Offset = last_error; op->OffsetHigh = bytes_transferred; // Enqueue the operation on the I/O completion port. if (!::PostQueuedCompletionStatus(iocp_.handle, 0, overlapped_contains_result, op)) { // Out of resources. Put on completed queue instead. mutex::scoped_lock lock(dispatch_mutex_); completed_ops_.push(op); ::InterlockedExchange(&dispatch_required_, 1); } } void win_iocp_io_context::on_completion(win_iocp_operation* op, const asio::error_code& ec, DWORD bytes_transferred) { // Flag that the operation is ready for invocation. op->ready_ = 1; // Store results in the OVERLAPPED structure. op->Internal = reinterpret_cast(&ec.category()); op->Offset = ec.value(); op->OffsetHigh = bytes_transferred; // Enqueue the operation on the I/O completion port. if (!::PostQueuedCompletionStatus(iocp_.handle, 0, overlapped_contains_result, op)) { // Out of resources. Put on completed queue instead. mutex::scoped_lock lock(dispatch_mutex_); completed_ops_.push(op); ::InterlockedExchange(&dispatch_required_, 1); } } size_t win_iocp_io_context::do_one(DWORD msec, asio::error_code& ec) { for (;;) { // Try to acquire responsibility for dispatching timers and completed ops. if (::InterlockedCompareExchange(&dispatch_required_, 0, 1) == 1) { mutex::scoped_lock lock(dispatch_mutex_); // Dispatch pending timers and operations. op_queue ops; ops.push(completed_ops_); timer_queues_.get_ready_timers(ops); post_deferred_completions(ops); update_timeout(); } // Get the next operation from the queue. DWORD bytes_transferred = 0; dword_ptr_t completion_key = 0; LPOVERLAPPED overlapped = 0; ::SetLastError(0); BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, &completion_key, &overlapped, msec < gqcs_timeout_ ? msec : gqcs_timeout_); DWORD last_error = ::GetLastError(); if (overlapped) { win_iocp_operation* op = static_cast(overlapped); asio::error_code result_ec(last_error, asio::error::get_system_category()); // We may have been passed the last_error and bytes_transferred in the // OVERLAPPED structure itself. if (completion_key == overlapped_contains_result) { result_ec = asio::error_code(static_cast(op->Offset), *reinterpret_cast(op->Internal)); bytes_transferred = op->OffsetHigh; } // Otherwise ensure any result has been saved into the OVERLAPPED // structure. else { op->Internal = reinterpret_cast(&result_ec.category()); op->Offset = result_ec.value(); op->OffsetHigh = bytes_transferred; } // Dispatch the operation only if ready. The operation may not be ready // if the initiating function (e.g. a call to WSARecv) has not yet // returned. This is because the initiating function still wants access // to the operation's OVERLAPPED structure. if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) { // Ensure the count of outstanding work is decremented on block exit. work_finished_on_block_exit on_exit = { this }; (void)on_exit; op->complete(this, result_ec, bytes_transferred); ec = asio::error_code(); return 1; } } else if (!ok) { if (last_error != WAIT_TIMEOUT) { ec = asio::error_code(last_error, asio::error::get_system_category()); return 0; } // If we're waiting indefinitely we need to keep going until we get a // real handler. if (msec == INFINITE) continue; ec = asio::error_code(); return 0; } else if (completion_key == wake_for_dispatch) { // We have been woken up to try to acquire responsibility for dispatching // timers and completed operations. } else { // Indicate that there is no longer an in-flight stop event. ::InterlockedExchange(&stop_event_posted_, 0); // The stopped_ flag is always checked to ensure that any leftover // stop events from a previous run invocation are ignored. if (::InterlockedExchangeAdd(&stopped_, 0) != 0) { // Wake up next thread that is blocked on GetQueuedCompletionStatus. if (::InterlockedExchange(&stop_event_posted_, 1) == 0) { if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) { last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); return 0; } } ec = asio::error_code(); return 0; } } } } DWORD win_iocp_io_context::get_gqcs_timeout() { OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(osvi); osvi.dwMajorVersion = 6ul; const uint64_t condition_mask = ::VerSetConditionMask( 0, VER_MAJORVERSION, VER_GREATER_EQUAL); if (!!::VerifyVersionInfo(&osvi, VER_MAJORVERSION, condition_mask)) return INFINITE; return default_gqcs_timeout; } void win_iocp_io_context::do_add_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(dispatch_mutex_); timer_queues_.insert(&queue); if (!waitable_timer_.handle) { waitable_timer_.handle = ::CreateWaitableTimer(0, FALSE, 0); if (waitable_timer_.handle == 0) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "timer"); } LARGE_INTEGER timeout; timeout.QuadPart = -max_timeout_usec; timeout.QuadPart *= 10; ::SetWaitableTimer(waitable_timer_.handle, &timeout, max_timeout_msec, 0, 0, FALSE); } if (!timer_thread_.get()) { timer_thread_function thread_function = { this }; timer_thread_.reset(new thread(thread_function, 65536)); } } void win_iocp_io_context::do_remove_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(dispatch_mutex_); timer_queues_.erase(&queue); } void win_iocp_io_context::update_timeout() { if (timer_thread_.get()) { // There's no point updating the waitable timer if the new timeout period // exceeds the maximum timeout. In that case, we might as well wait for the // existing period of the timer to expire. long timeout_usec = timer_queues_.wait_duration_usec(max_timeout_usec); if (timeout_usec < max_timeout_usec) { LARGE_INTEGER timeout; timeout.QuadPart = -timeout_usec; timeout.QuadPart *= 10; ::SetWaitableTimer(waitable_timer_.handle, &timeout, max_timeout_msec, 0, 0, FALSE); } } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_IMPL_WIN_IOCP_IO_CONTEXT_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_iocp_serial_port_service.ipp ================================================ // // detail/impl/win_iocp_serial_port_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP #define ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) && defined(ASIO_HAS_SERIAL_PORT) #include #include "asio/detail/win_iocp_serial_port_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { win_iocp_serial_port_service::win_iocp_serial_port_service( execution_context& context) : execution_context_service_base(context), handle_service_(context) { } void win_iocp_serial_port_service::shutdown() { } asio::error_code win_iocp_serial_port_service::open( win_iocp_serial_port_service::implementation_type& impl, const std::string& device, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } // For convenience, add a leading \\.\ sequence if not already present. std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device; // Open a handle to the serial port. ::HANDLE handle = ::CreateFileA(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (handle == INVALID_HANDLE_VALUE) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); return ec; } // Determine the initial serial port parameters. using namespace std; // For memset. ::DCB dcb; memset(&dcb, 0, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); if (!::GetCommState(handle, &dcb)) { DWORD last_error = ::GetLastError(); ::CloseHandle(handle); ec = asio::error_code(last_error, asio::error::get_system_category()); return ec; } // Set some default serial port parameters. This implementation does not // support changing all of these, so they might as well be in a known state. dcb.fBinary = TRUE; // Win32 only supports binary mode. dcb.fNull = FALSE; // Do not ignore NULL characters. dcb.fAbortOnError = FALSE; // Ignore serial framing errors. dcb.BaudRate = 0; // 0 baud by default dcb.ByteSize = 8; // 8 bit bytes dcb.fOutxCtsFlow = FALSE; // No flow control dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = FALSE; dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fRtsControl = DTR_CONTROL_DISABLE; dcb.fParity = FALSE; // No parity dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; // One stop bit if (!::SetCommState(handle, &dcb)) { DWORD last_error = ::GetLastError(); ::CloseHandle(handle); ec = asio::error_code(last_error, asio::error::get_system_category()); return ec; } // Set up timeouts so that the serial port will behave similarly to a // network socket. Reads wait for at least one byte, then return with // whatever they have. Writes return once everything is out the door. ::COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = 1; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (!::SetCommTimeouts(handle, &timeouts)) { DWORD last_error = ::GetLastError(); ::CloseHandle(handle); ec = asio::error_code(last_error, asio::error::get_system_category()); return ec; } // We're done. Take ownership of the serial port handle. if (handle_service_.assign(impl, handle, ec)) ::CloseHandle(handle); return ec; } asio::error_code win_iocp_serial_port_service::do_set_option( win_iocp_serial_port_service::implementation_type& impl, win_iocp_serial_port_service::store_function_type store, const void* option, asio::error_code& ec) { using namespace std; // For memcpy. ::DCB dcb; memset(&dcb, 0, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); if (!::GetCommState(handle_service_.native_handle(impl), &dcb)) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); return ec; } if (store(option, dcb, ec)) return ec; if (!::SetCommState(handle_service_.native_handle(impl), &dcb)) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); return ec; } ec = asio::error_code(); return ec; } asio::error_code win_iocp_serial_port_service::do_get_option( const win_iocp_serial_port_service::implementation_type& impl, win_iocp_serial_port_service::load_function_type load, void* option, asio::error_code& ec) const { using namespace std; // For memset. ::DCB dcb; memset(&dcb, 0, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); if (!::GetCommState(handle_service_.native_handle(impl), &dcb)) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); return ec; } return load(option, dcb, ec); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) && defined(ASIO_HAS_SERIAL_PORT) #endif // ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_iocp_socket_service_base.ipp ================================================ // // detail/impl/win_iocp_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP #define ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/win_iocp_socket_service_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { win_iocp_socket_service_base::win_iocp_socket_service_base( execution_context& context) : context_(context), iocp_service_(use_service(context)), reactor_(0), connect_ex_(0), nt_set_info_(0), mutex_(), impl_list_(0) { } void win_iocp_socket_service_base::base_shutdown() { // Close all implementations, causing all operations to complete. asio::detail::mutex::scoped_lock lock(mutex_); base_implementation_type* impl = impl_list_; while (impl) { close_for_destruction(*impl); impl = impl->next_; } } void win_iocp_socket_service_base::construct( win_iocp_socket_service_base::base_implementation_type& impl) { impl.socket_ = invalid_socket; impl.state_ = 0; impl.cancel_token_.reset(); #if defined(ASIO_ENABLE_CANCELIO) impl.safe_cancellation_thread_id_ = 0; #endif // defined(ASIO_ENABLE_CANCELIO) // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } void win_iocp_socket_service_base::base_move_construct( win_iocp_socket_service_base::base_implementation_type& impl, win_iocp_socket_service_base::base_implementation_type& other_impl) ASIO_NOEXCEPT { impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket; impl.state_ = other_impl.state_; other_impl.state_ = 0; impl.cancel_token_ = other_impl.cancel_token_; other_impl.cancel_token_.reset(); #if defined(ASIO_ENABLE_CANCELIO) impl.safe_cancellation_thread_id_ = other_impl.safe_cancellation_thread_id_; other_impl.safe_cancellation_thread_id_ = 0; #endif // defined(ASIO_ENABLE_CANCELIO) // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } void win_iocp_socket_service_base::base_move_assign( win_iocp_socket_service_base::base_implementation_type& impl, win_iocp_socket_service_base& other_service, win_iocp_socket_service_base::base_implementation_type& other_impl) { close_for_destruction(impl); if (this != &other_service) { // Remove implementation from linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket; impl.state_ = other_impl.state_; other_impl.state_ = 0; impl.cancel_token_ = other_impl.cancel_token_; other_impl.cancel_token_.reset(); #if defined(ASIO_ENABLE_CANCELIO) impl.safe_cancellation_thread_id_ = other_impl.safe_cancellation_thread_id_; other_impl.safe_cancellation_thread_id_ = 0; #endif // defined(ASIO_ENABLE_CANCELIO) if (this != &other_service) { // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(other_service.mutex_); impl.next_ = other_service.impl_list_; impl.prev_ = 0; if (other_service.impl_list_) other_service.impl_list_->prev_ = &impl; other_service.impl_list_ = &impl; } } void win_iocp_socket_service_base::destroy( win_iocp_socket_service_base::base_implementation_type& impl) { close_for_destruction(impl); // Remove implementation from linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } asio::error_code win_iocp_socket_service_base::close( win_iocp_socket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((iocp_service_.context(), "socket", &impl, impl.socket_, "close")); // Check if the reactor was created, in which case we need to close the // socket on the reactor as well to cancel any operations that might be // running there. select_reactor* r = static_cast( interlocked_compare_exchange_pointer( reinterpret_cast(&reactor_), 0, 0)); if (r) r->deregister_descriptor(impl.socket_, impl.reactor_data_, true); socket_ops::close(impl.socket_, impl.state_, false, ec); if (r) r->cleanup_descriptor_data(impl.reactor_data_); } else { ec = asio::error_code(); } impl.socket_ = invalid_socket; impl.state_ = 0; impl.cancel_token_.reset(); #if defined(ASIO_ENABLE_CANCELIO) impl.safe_cancellation_thread_id_ = 0; #endif // defined(ASIO_ENABLE_CANCELIO) return ec; } socket_type win_iocp_socket_service_base::release( win_iocp_socket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (!is_open(impl)) return invalid_socket; cancel(impl, ec); if (ec) return invalid_socket; nt_set_info_fn fn = get_nt_set_info(); if (fn == 0) { ec = asio::error::operation_not_supported; return invalid_socket; } HANDLE sock_as_handle = reinterpret_cast(impl.socket_); ULONG_PTR iosb[2] = { 0, 0 }; void* info[2] = { 0, 0 }; if (fn(sock_as_handle, iosb, &info, sizeof(info), 61 /* FileReplaceCompletionInformation */)) { ec = asio::error::operation_not_supported; return invalid_socket; } socket_type tmp = impl.socket_; impl.socket_ = invalid_socket; return tmp; } asio::error_code win_iocp_socket_service_base::cancel( win_iocp_socket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return ec; } ASIO_HANDLER_OPERATION((iocp_service_.context(), "socket", &impl, impl.socket_, "cancel")); if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) { // The version of Windows supports cancellation from any thread. typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); cancel_io_ex_t cancel_io_ex = reinterpret_cast( reinterpret_cast(cancel_io_ex_ptr)); socket_type sock = impl.socket_; HANDLE sock_as_handle = reinterpret_cast(sock); if (!cancel_io_ex(sock_as_handle, 0)) { DWORD last_error = ::GetLastError(); if (last_error == ERROR_NOT_FOUND) { // ERROR_NOT_FOUND means that there were no operations to be // cancelled. We swallow this error to match the behaviour on other // platforms. ec = asio::error_code(); } else { ec = asio::error_code(last_error, asio::error::get_system_category()); } } else { ec = asio::error_code(); } } #if defined(ASIO_ENABLE_CANCELIO) else if (impl.safe_cancellation_thread_id_ == 0) { // No operations have been started, so there's nothing to cancel. ec = asio::error_code(); } else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) { // Asynchronous operations have been started from the current thread only, // so it is safe to try to cancel them using CancelIo. socket_type sock = impl.socket_; HANDLE sock_as_handle = reinterpret_cast(sock); if (!::CancelIo(sock_as_handle)) { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); } else { ec = asio::error_code(); } } else { // Asynchronous operations have been started from more than one thread, // so cancellation is not safe. ec = asio::error::operation_not_supported; } #else // defined(ASIO_ENABLE_CANCELIO) else { // Cancellation is not supported as CancelIo may not be used. ec = asio::error::operation_not_supported; } #endif // defined(ASIO_ENABLE_CANCELIO) // Cancel any operations started via the reactor. if (!ec) { select_reactor* r = static_cast( interlocked_compare_exchange_pointer( reinterpret_cast(&reactor_), 0, 0)); if (r) r->cancel_ops(impl.socket_, impl.reactor_data_); } return ec; } asio::error_code win_iocp_socket_service_base::do_open( win_iocp_socket_service_base::base_implementation_type& impl, int family, int type, int protocol, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } socket_holder sock(socket_ops::socket(family, type, protocol, ec)); if (sock.get() == invalid_socket) return ec; HANDLE sock_as_handle = reinterpret_cast(sock.get()); if (iocp_service_.register_handle(sock_as_handle, ec)) return ec; impl.socket_ = sock.release(); switch (type) { case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; default: impl.state_ = 0; break; } impl.cancel_token_.reset(static_cast(0), socket_ops::noop_deleter()); ec = asio::error_code(); return ec; } asio::error_code win_iocp_socket_service_base::do_assign( win_iocp_socket_service_base::base_implementation_type& impl, int type, socket_type native_socket, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } HANDLE sock_as_handle = reinterpret_cast(native_socket); if (iocp_service_.register_handle(sock_as_handle, ec)) return ec; impl.socket_ = native_socket; switch (type) { case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; default: impl.state_ = 0; break; } impl.cancel_token_.reset(static_cast(0), socket_ops::noop_deleter()); ec = asio::error_code(); return ec; } void win_iocp_socket_service_base::start_send_op( win_iocp_socket_service_base::base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, socket_base::message_flags flags, bool noop, operation* op) { update_cancellation_thread_id(impl); iocp_service_.work_started(); if (noop) iocp_service_.on_completion(op); else if (!is_open(impl)) iocp_service_.on_completion(op, asio::error::bad_descriptor); else { DWORD bytes_transferred = 0; int result = ::WSASend(impl.socket_, buffers, static_cast(buffer_count), &bytes_transferred, flags, op, 0); DWORD last_error = ::WSAGetLastError(); if (last_error == ERROR_PORT_UNREACHABLE) last_error = WSAECONNREFUSED; if (result != 0 && last_error != WSA_IO_PENDING) iocp_service_.on_completion(op, last_error, bytes_transferred); else iocp_service_.on_pending(op); } } void win_iocp_socket_service_base::start_send_to_op( win_iocp_socket_service_base::base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, const socket_addr_type* addr, int addrlen, socket_base::message_flags flags, operation* op) { update_cancellation_thread_id(impl); iocp_service_.work_started(); if (!is_open(impl)) iocp_service_.on_completion(op, asio::error::bad_descriptor); else { DWORD bytes_transferred = 0; int result = ::WSASendTo(impl.socket_, buffers, static_cast(buffer_count), &bytes_transferred, flags, addr, addrlen, op, 0); DWORD last_error = ::WSAGetLastError(); if (last_error == ERROR_PORT_UNREACHABLE) last_error = WSAECONNREFUSED; if (result != 0 && last_error != WSA_IO_PENDING) iocp_service_.on_completion(op, last_error, bytes_transferred); else iocp_service_.on_pending(op); } } void win_iocp_socket_service_base::start_receive_op( win_iocp_socket_service_base::base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, socket_base::message_flags flags, bool noop, operation* op) { update_cancellation_thread_id(impl); iocp_service_.work_started(); if (noop) iocp_service_.on_completion(op); else if (!is_open(impl)) iocp_service_.on_completion(op, asio::error::bad_descriptor); else { DWORD bytes_transferred = 0; DWORD recv_flags = flags; int result = ::WSARecv(impl.socket_, buffers, static_cast(buffer_count), &bytes_transferred, &recv_flags, op, 0); DWORD last_error = ::WSAGetLastError(); if (last_error == ERROR_NETNAME_DELETED) last_error = WSAECONNRESET; else if (last_error == ERROR_PORT_UNREACHABLE) last_error = WSAECONNREFUSED; if (result != 0 && last_error != WSA_IO_PENDING) iocp_service_.on_completion(op, last_error, bytes_transferred); else iocp_service_.on_pending(op); } } void win_iocp_socket_service_base::start_null_buffers_receive_op( win_iocp_socket_service_base::base_implementation_type& impl, socket_base::message_flags flags, reactor_op* op) { if ((impl.state_ & socket_ops::stream_oriented) != 0) { // For stream sockets on Windows, we may issue a 0-byte overlapped // WSARecv to wait until there is data available on the socket. ::WSABUF buf = { 0, 0 }; start_receive_op(impl, &buf, 1, flags, false, op); } else { start_reactor_op(impl, (flags & socket_base::message_out_of_band) ? select_reactor::except_op : select_reactor::read_op, op); } } void win_iocp_socket_service_base::start_receive_from_op( win_iocp_socket_service_base::base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr, socket_base::message_flags flags, int* addrlen, operation* op) { update_cancellation_thread_id(impl); iocp_service_.work_started(); if (!is_open(impl)) iocp_service_.on_completion(op, asio::error::bad_descriptor); else { DWORD bytes_transferred = 0; DWORD recv_flags = flags; int result = ::WSARecvFrom(impl.socket_, buffers, static_cast(buffer_count), &bytes_transferred, &recv_flags, addr, addrlen, op, 0); DWORD last_error = ::WSAGetLastError(); if (last_error == ERROR_PORT_UNREACHABLE) last_error = WSAECONNREFUSED; if (result != 0 && last_error != WSA_IO_PENDING) iocp_service_.on_completion(op, last_error, bytes_transferred); else iocp_service_.on_pending(op); } } void win_iocp_socket_service_base::start_accept_op( win_iocp_socket_service_base::base_implementation_type& impl, bool peer_is_open, socket_holder& new_socket, int family, int type, int protocol, void* output_buffer, DWORD address_length, operation* op) { update_cancellation_thread_id(impl); iocp_service_.work_started(); if (!is_open(impl)) iocp_service_.on_completion(op, asio::error::bad_descriptor); else if (peer_is_open) iocp_service_.on_completion(op, asio::error::already_open); else { asio::error_code ec; new_socket.reset(socket_ops::socket(family, type, protocol, ec)); if (new_socket.get() == invalid_socket) iocp_service_.on_completion(op, ec); else { DWORD bytes_read = 0; BOOL result = ::AcceptEx(impl.socket_, new_socket.get(), output_buffer, 0, address_length, address_length, &bytes_read, op); DWORD last_error = ::WSAGetLastError(); if (!result && last_error != WSA_IO_PENDING) iocp_service_.on_completion(op, last_error); else iocp_service_.on_pending(op); } } } void win_iocp_socket_service_base::restart_accept_op( socket_type s, socket_holder& new_socket, int family, int type, int protocol, void* output_buffer, DWORD address_length, operation* op) { new_socket.reset(); iocp_service_.work_started(); asio::error_code ec; new_socket.reset(socket_ops::socket(family, type, protocol, ec)); if (new_socket.get() == invalid_socket) iocp_service_.on_completion(op, ec); else { DWORD bytes_read = 0; BOOL result = ::AcceptEx(s, new_socket.get(), output_buffer, 0, address_length, address_length, &bytes_read, op); DWORD last_error = ::WSAGetLastError(); if (!result && last_error != WSA_IO_PENDING) iocp_service_.on_completion(op, last_error); else iocp_service_.on_pending(op); } } void win_iocp_socket_service_base::start_reactor_op( win_iocp_socket_service_base::base_implementation_type& impl, int op_type, reactor_op* op) { select_reactor& r = get_reactor(); update_cancellation_thread_id(impl); if (is_open(impl)) { r.start_op(op_type, impl.socket_, impl.reactor_data_, op, false, false); return; } else op->ec_ = asio::error::bad_descriptor; iocp_service_.post_immediate_completion(op, false); } void win_iocp_socket_service_base::start_connect_op( win_iocp_socket_service_base::base_implementation_type& impl, int family, int type, const socket_addr_type* addr, std::size_t addrlen, win_iocp_socket_connect_op_base* op) { // If ConnectEx is available, use that. if (family == ASIO_OS_DEF(AF_INET) || family == ASIO_OS_DEF(AF_INET6)) { if (connect_ex_fn connect_ex = get_connect_ex(impl, type)) { union address_union { socket_addr_type base; sockaddr_in4_type v4; sockaddr_in6_type v6; } a; using namespace std; // For memset. memset(&a, 0, sizeof(a)); a.base.sa_family = family; socket_ops::bind(impl.socket_, &a.base, family == ASIO_OS_DEF(AF_INET) ? sizeof(a.v4) : sizeof(a.v6), op->ec_); if (op->ec_ && op->ec_ != asio::error::invalid_argument) { iocp_service_.post_immediate_completion(op, false); return; } op->connect_ex_ = true; update_cancellation_thread_id(impl); iocp_service_.work_started(); BOOL result = connect_ex(impl.socket_, addr, static_cast(addrlen), 0, 0, 0, op); DWORD last_error = ::WSAGetLastError(); if (!result && last_error != WSA_IO_PENDING) iocp_service_.on_completion(op, last_error); else iocp_service_.on_pending(op); return; } } // Otherwise, fall back to a reactor-based implementation. select_reactor& r = get_reactor(); update_cancellation_thread_id(impl); if ((impl.state_ & socket_ops::non_blocking) != 0 || socket_ops::set_internal_non_blocking( impl.socket_, impl.state_, true, op->ec_)) { if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) { if (op->ec_ == asio::error::in_progress || op->ec_ == asio::error::would_block) { op->ec_ = asio::error_code(); r.start_op(select_reactor::connect_op, impl.socket_, impl.reactor_data_, op, false, false); return; } } } r.post_immediate_completion(op, false); } void win_iocp_socket_service_base::close_for_destruction( win_iocp_socket_service_base::base_implementation_type& impl) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((iocp_service_.context(), "socket", &impl, impl.socket_, "close")); // Check if the reactor was created, in which case we need to close the // socket on the reactor as well to cancel any operations that might be // running there. select_reactor* r = static_cast( interlocked_compare_exchange_pointer( reinterpret_cast(&reactor_), 0, 0)); if (r) r->deregister_descriptor(impl.socket_, impl.reactor_data_, true); asio::error_code ignored_ec; socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); if (r) r->cleanup_descriptor_data(impl.reactor_data_); } impl.socket_ = invalid_socket; impl.state_ = 0; impl.cancel_token_.reset(); #if defined(ASIO_ENABLE_CANCELIO) impl.safe_cancellation_thread_id_ = 0; #endif // defined(ASIO_ENABLE_CANCELIO) } void win_iocp_socket_service_base::update_cancellation_thread_id( win_iocp_socket_service_base::base_implementation_type& impl) { #if defined(ASIO_ENABLE_CANCELIO) if (impl.safe_cancellation_thread_id_ == 0) impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) impl.safe_cancellation_thread_id_ = ~DWORD(0); #else // defined(ASIO_ENABLE_CANCELIO) (void)impl; #endif // defined(ASIO_ENABLE_CANCELIO) } select_reactor& win_iocp_socket_service_base::get_reactor() { select_reactor* r = static_cast( interlocked_compare_exchange_pointer( reinterpret_cast(&reactor_), 0, 0)); if (!r) { r = &(use_service(context_)); interlocked_exchange_pointer(reinterpret_cast(&reactor_), r); } return *r; } win_iocp_socket_service_base::connect_ex_fn win_iocp_socket_service_base::get_connect_ex( win_iocp_socket_service_base::base_implementation_type& impl, int type) { #if defined(ASIO_DISABLE_CONNECTEX) (void)impl; (void)type; return 0; #else // defined(ASIO_DISABLE_CONNECTEX) if (type != ASIO_OS_DEF(SOCK_STREAM) && type != ASIO_OS_DEF(SOCK_SEQPACKET)) return 0; void* ptr = interlocked_compare_exchange_pointer(&connect_ex_, 0, 0); if (!ptr) { GUID guid = { 0x25a207b9, 0xddf3, 0x4660, { 0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e } }; DWORD bytes = 0; if (::WSAIoctl(impl.socket_, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &ptr, sizeof(ptr), &bytes, 0, 0) != 0) { // Set connect_ex_ to a special value to indicate that ConnectEx is // unavailable. That way we won't bother trying to look it up again. ptr = this; } interlocked_exchange_pointer(&connect_ex_, ptr); } return reinterpret_cast(ptr == this ? 0 : ptr); #endif // defined(ASIO_DISABLE_CONNECTEX) } win_iocp_socket_service_base::nt_set_info_fn win_iocp_socket_service_base::get_nt_set_info() { void* ptr = interlocked_compare_exchange_pointer(&nt_set_info_, 0, 0); if (!ptr) { if (HMODULE h = ::GetModuleHandleA("NTDLL.DLL")) ptr = reinterpret_cast(GetProcAddress(h, "NtSetInformationFile")); // On failure, set nt_set_info_ to a special value to indicate that the // NtSetInformationFile function is unavailable. That way we won't bother // trying to look it up again. interlocked_exchange_pointer(&nt_set_info_, ptr ? ptr : this); } return reinterpret_cast(ptr == this ? 0 : ptr); } void* win_iocp_socket_service_base::interlocked_compare_exchange_pointer( void** dest, void* exch, void* cmp) { #if defined(_M_IX86) return reinterpret_cast(InterlockedCompareExchange( reinterpret_cast(dest), reinterpret_cast(exch), reinterpret_cast(cmp))); #else return InterlockedCompareExchangePointer(dest, exch, cmp); #endif } void* win_iocp_socket_service_base::interlocked_exchange_pointer( void** dest, void* val) { #if defined(_M_IX86) return reinterpret_cast(InterlockedExchange( reinterpret_cast(dest), reinterpret_cast(val))); #else return InterlockedExchangePointer(dest, val); #endif } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_mutex.ipp ================================================ // // detail/impl/win_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_MUTEX_IPP #define ASIO_DETAIL_IMPL_WIN_MUTEX_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include "asio/detail/throw_error.hpp" #include "asio/detail/win_mutex.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { win_mutex::win_mutex() { int error = do_init(); asio::error_code ec(error, asio::error::get_system_category()); asio::detail::throw_error(ec, "mutex"); } int win_mutex::do_init() { #if defined(__MINGW32__) // Not sure if MinGW supports structured exception handling, so for now // we'll just call the Windows API and hope. # if defined(UNDER_CE) ::InitializeCriticalSection(&crit_section_); # elif defined(ASIO_WINDOWS_APP) if (!::InitializeCriticalSectionEx(&crit_section_, 0, 0)) return ::GetLastError(); # else if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)) return ::GetLastError(); # endif return 0; #else __try { # if defined(UNDER_CE) ::InitializeCriticalSection(&crit_section_); # elif defined(ASIO_WINDOWS_APP) if (!::InitializeCriticalSectionEx(&crit_section_, 0, 0)) return ::GetLastError(); # else if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)) return ::GetLastError(); # endif } __except(GetExceptionCode() == STATUS_NO_MEMORY ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { return ERROR_OUTOFMEMORY; } return 0; #endif } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_IMPL_WIN_MUTEX_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_object_handle_service.ipp ================================================ // // detail/impl/win_object_handle_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_OBJECT_HANDLE_SERVICE_IPP #define ASIO_DETAIL_IMPL_WIN_OBJECT_HANDLE_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) #include "asio/detail/win_object_handle_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { win_object_handle_service::win_object_handle_service(execution_context& context) : execution_context_service_base(context), scheduler_(asio::use_service(context)), mutex_(), impl_list_(0), shutdown_(false) { } void win_object_handle_service::shutdown() { mutex::scoped_lock lock(mutex_); // Setting this flag to true prevents new objects from being registered, and // new asynchronous wait operations from being started. We only need to worry // about cleaning up the operations that are currently in progress. shutdown_ = true; op_queue ops; for (implementation_type* impl = impl_list_; impl; impl = impl->next_) ops.push(impl->op_queue_); lock.unlock(); scheduler_.abandon_operations(ops); } void win_object_handle_service::construct( win_object_handle_service::implementation_type& impl) { impl.handle_ = INVALID_HANDLE_VALUE; impl.wait_handle_ = INVALID_HANDLE_VALUE; impl.owner_ = this; // Insert implementation into linked list of all implementations. mutex::scoped_lock lock(mutex_); if (!shutdown_) { impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } } void win_object_handle_service::move_construct( win_object_handle_service::implementation_type& impl, win_object_handle_service::implementation_type& other_impl) { mutex::scoped_lock lock(mutex_); // Insert implementation into linked list of all implementations. if (!shutdown_) { impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } impl.handle_ = other_impl.handle_; other_impl.handle_ = INVALID_HANDLE_VALUE; impl.wait_handle_ = other_impl.wait_handle_; other_impl.wait_handle_ = INVALID_HANDLE_VALUE; impl.op_queue_.push(other_impl.op_queue_); impl.owner_ = this; // We must not hold the lock while calling UnregisterWaitEx. This is because // the registered callback function might be invoked while we are waiting for // UnregisterWaitEx to complete. lock.unlock(); if (impl.wait_handle_ != INVALID_HANDLE_VALUE) ::UnregisterWaitEx(impl.wait_handle_, INVALID_HANDLE_VALUE); if (!impl.op_queue_.empty()) register_wait_callback(impl, lock); } void win_object_handle_service::move_assign( win_object_handle_service::implementation_type& impl, win_object_handle_service& other_service, win_object_handle_service::implementation_type& other_impl) { asio::error_code ignored_ec; close(impl, ignored_ec); mutex::scoped_lock lock(mutex_); if (this != &other_service) { // Remove implementation from linked list of all implementations. if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } impl.handle_ = other_impl.handle_; other_impl.handle_ = INVALID_HANDLE_VALUE; impl.wait_handle_ = other_impl.wait_handle_; other_impl.wait_handle_ = INVALID_HANDLE_VALUE; impl.op_queue_.push(other_impl.op_queue_); impl.owner_ = this; if (this != &other_service) { // Insert implementation into linked list of all implementations. impl.next_ = other_service.impl_list_; impl.prev_ = 0; if (other_service.impl_list_) other_service.impl_list_->prev_ = &impl; other_service.impl_list_ = &impl; } // We must not hold the lock while calling UnregisterWaitEx. This is because // the registered callback function might be invoked while we are waiting for // UnregisterWaitEx to complete. lock.unlock(); if (impl.wait_handle_ != INVALID_HANDLE_VALUE) ::UnregisterWaitEx(impl.wait_handle_, INVALID_HANDLE_VALUE); if (!impl.op_queue_.empty()) register_wait_callback(impl, lock); } void win_object_handle_service::destroy( win_object_handle_service::implementation_type& impl) { mutex::scoped_lock lock(mutex_); // Remove implementation from linked list of all implementations. if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; if (is_open(impl)) { ASIO_HANDLER_OPERATION((scheduler_.context(), "object_handle", &impl, reinterpret_cast(impl.wait_handle_), "close")); HANDLE wait_handle = impl.wait_handle_; impl.wait_handle_ = INVALID_HANDLE_VALUE; op_queue ops; while (wait_op* op = impl.op_queue_.front()) { op->ec_ = asio::error::operation_aborted; impl.op_queue_.pop(); ops.push(op); } // We must not hold the lock while calling UnregisterWaitEx. This is // because the registered callback function might be invoked while we are // waiting for UnregisterWaitEx to complete. lock.unlock(); if (wait_handle != INVALID_HANDLE_VALUE) ::UnregisterWaitEx(wait_handle, INVALID_HANDLE_VALUE); ::CloseHandle(impl.handle_); impl.handle_ = INVALID_HANDLE_VALUE; scheduler_.post_deferred_completions(ops); } } asio::error_code win_object_handle_service::assign( win_object_handle_service::implementation_type& impl, const native_handle_type& handle, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } impl.handle_ = handle; ec = asio::error_code(); return ec; } asio::error_code win_object_handle_service::close( win_object_handle_service::implementation_type& impl, asio::error_code& ec) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((scheduler_.context(), "object_handle", &impl, reinterpret_cast(impl.wait_handle_), "close")); mutex::scoped_lock lock(mutex_); HANDLE wait_handle = impl.wait_handle_; impl.wait_handle_ = INVALID_HANDLE_VALUE; op_queue completed_ops; while (wait_op* op = impl.op_queue_.front()) { impl.op_queue_.pop(); op->ec_ = asio::error::operation_aborted; completed_ops.push(op); } // We must not hold the lock while calling UnregisterWaitEx. This is // because the registered callback function might be invoked while we are // waiting for UnregisterWaitEx to complete. lock.unlock(); if (wait_handle != INVALID_HANDLE_VALUE) ::UnregisterWaitEx(wait_handle, INVALID_HANDLE_VALUE); if (::CloseHandle(impl.handle_)) { impl.handle_ = INVALID_HANDLE_VALUE; ec = asio::error_code(); } else { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); } scheduler_.post_deferred_completions(completed_ops); } else { ec = asio::error_code(); } return ec; } asio::error_code win_object_handle_service::cancel( win_object_handle_service::implementation_type& impl, asio::error_code& ec) { if (is_open(impl)) { ASIO_HANDLER_OPERATION((scheduler_.context(), "object_handle", &impl, reinterpret_cast(impl.wait_handle_), "cancel")); mutex::scoped_lock lock(mutex_); HANDLE wait_handle = impl.wait_handle_; impl.wait_handle_ = INVALID_HANDLE_VALUE; op_queue completed_ops; while (wait_op* op = impl.op_queue_.front()) { op->ec_ = asio::error::operation_aborted; impl.op_queue_.pop(); completed_ops.push(op); } // We must not hold the lock while calling UnregisterWaitEx. This is // because the registered callback function might be invoked while we are // waiting for UnregisterWaitEx to complete. lock.unlock(); if (wait_handle != INVALID_HANDLE_VALUE) ::UnregisterWaitEx(wait_handle, INVALID_HANDLE_VALUE); ec = asio::error_code(); scheduler_.post_deferred_completions(completed_ops); } else { ec = asio::error::bad_descriptor; } return ec; } void win_object_handle_service::wait( win_object_handle_service::implementation_type& impl, asio::error_code& ec) { switch (::WaitForSingleObject(impl.handle_, INFINITE)) { case WAIT_FAILED: { DWORD last_error = ::GetLastError(); ec = asio::error_code(last_error, asio::error::get_system_category()); break; } case WAIT_OBJECT_0: case WAIT_ABANDONED: default: ec = asio::error_code(); break; } } void win_object_handle_service::start_wait_op( win_object_handle_service::implementation_type& impl, wait_op* op) { scheduler_.work_started(); if (is_open(impl)) { mutex::scoped_lock lock(mutex_); if (!shutdown_) { impl.op_queue_.push(op); // Only the first operation to be queued gets to register a wait callback. // Subsequent operations have to wait for the first to finish. if (impl.op_queue_.front() == op) register_wait_callback(impl, lock); } else { lock.unlock(); scheduler_.post_deferred_completion(op); } } else { op->ec_ = asio::error::bad_descriptor; scheduler_.post_deferred_completion(op); } } void win_object_handle_service::register_wait_callback( win_object_handle_service::implementation_type& impl, mutex::scoped_lock& lock) { lock.lock(); if (!RegisterWaitForSingleObject(&impl.wait_handle_, impl.handle_, &win_object_handle_service::wait_callback, &impl, INFINITE, WT_EXECUTEONLYONCE)) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); op_queue completed_ops; while (wait_op* op = impl.op_queue_.front()) { op->ec_ = ec; impl.op_queue_.pop(); completed_ops.push(op); } lock.unlock(); scheduler_.post_deferred_completions(completed_ops); } } void win_object_handle_service::wait_callback(PVOID param, BOOLEAN) { implementation_type* impl = static_cast(param); mutex::scoped_lock lock(impl->owner_->mutex_); if (impl->wait_handle_ != INVALID_HANDLE_VALUE) { ::UnregisterWaitEx(impl->wait_handle_, NULL); impl->wait_handle_ = INVALID_HANDLE_VALUE; } if (wait_op* op = impl->op_queue_.front()) { op_queue completed_ops; op->ec_ = asio::error_code(); impl->op_queue_.pop(); completed_ops.push(op); if (!impl->op_queue_.empty()) { if (!RegisterWaitForSingleObject(&impl->wait_handle_, impl->handle_, &win_object_handle_service::wait_callback, param, INFINITE, WT_EXECUTEONLYONCE)) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); while ((op = impl->op_queue_.front()) != 0) { op->ec_ = ec; impl->op_queue_.pop(); completed_ops.push(op); } } } scheduler_impl& sched = impl->owner_->scheduler_; lock.unlock(); sched.post_deferred_completions(completed_ops); } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) #endif // ASIO_DETAIL_IMPL_WIN_OBJECT_HANDLE_SERVICE_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_static_mutex.ipp ================================================ // // detail/impl/win_static_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_STATIC_MUTEX_IPP #define ASIO_DETAIL_IMPL_WIN_STATIC_MUTEX_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include #include "asio/detail/throw_error.hpp" #include "asio/detail/win_static_mutex.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { void win_static_mutex::init() { int error = do_init(); asio::error_code ec(error, asio::error::get_system_category()); asio::detail::throw_error(ec, "static_mutex"); } int win_static_mutex::do_init() { using namespace std; // For sprintf. wchar_t mutex_name[128]; #if defined(ASIO_HAS_SECURE_RTL) swprintf_s( #else // defined(ASIO_HAS_SECURE_RTL) _snwprintf( #endif // defined(ASIO_HAS_SECURE_RTL) mutex_name, 128, L"asio-58CCDC44-6264-4842-90C2-F3C545CB8AA7-%u-%p", static_cast(::GetCurrentProcessId()), this); #if defined(ASIO_WINDOWS_APP) HANDLE mutex = ::CreateMutexExW(0, mutex_name, CREATE_MUTEX_INITIAL_OWNER, 0); #else // defined(ASIO_WINDOWS_APP) HANDLE mutex = ::CreateMutexW(0, TRUE, mutex_name); #endif // defined(ASIO_WINDOWS_APP) DWORD last_error = ::GetLastError(); if (mutex == 0) return ::GetLastError(); if (last_error == ERROR_ALREADY_EXISTS) { #if defined(ASIO_WINDOWS_APP) ::WaitForSingleObjectEx(mutex, INFINITE, false); #else // defined(ASIO_WINDOWS_APP) ::WaitForSingleObject(mutex, INFINITE); #endif // defined(ASIO_WINDOWS_APP) } if (initialised_) { ::ReleaseMutex(mutex); ::CloseHandle(mutex); return 0; } #if defined(__MINGW32__) // Not sure if MinGW supports structured exception handling, so for now // we'll just call the Windows API and hope. # if defined(UNDER_CE) ::InitializeCriticalSection(&crit_section_); # else if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)) { last_error = ::GetLastError(); ::ReleaseMutex(mutex); ::CloseHandle(mutex); return last_error; } # endif #else __try { # if defined(UNDER_CE) ::InitializeCriticalSection(&crit_section_); # elif defined(ASIO_WINDOWS_APP) if (!::InitializeCriticalSectionEx(&crit_section_, 0, 0)) { last_error = ::GetLastError(); ::ReleaseMutex(mutex); ::CloseHandle(mutex); return last_error; } # else if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)) { last_error = ::GetLastError(); ::ReleaseMutex(mutex); ::CloseHandle(mutex); return last_error; } # endif } __except(GetExceptionCode() == STATUS_NO_MEMORY ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { ::ReleaseMutex(mutex); ::CloseHandle(mutex); return ERROR_OUTOFMEMORY; } #endif initialised_ = true; ::ReleaseMutex(mutex); ::CloseHandle(mutex); return 0; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_IMPL_WIN_STATIC_MUTEX_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_thread.ipp ================================================ // // detail/impl/win_thread.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_THREAD_IPP #define ASIO_DETAIL_IMPL_WIN_THREAD_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_APP) \ && !defined(UNDER_CE) #include #include "asio/detail/throw_error.hpp" #include "asio/detail/win_thread.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { win_thread::~win_thread() { ::CloseHandle(thread_); // The exit_event_ handle is deliberately allowed to leak here since it // is an error for the owner of an internal thread not to join() it. } void win_thread::join() { HANDLE handles[2] = { exit_event_, thread_ }; ::WaitForMultipleObjects(2, handles, FALSE, INFINITE); ::CloseHandle(exit_event_); if (terminate_threads()) { ::TerminateThread(thread_, 0); } else { ::QueueUserAPC(apc_function, thread_, 0); ::WaitForSingleObject(thread_, INFINITE); } } std::size_t win_thread::hardware_concurrency() { SYSTEM_INFO system_info; ::GetSystemInfo(&system_info); return system_info.dwNumberOfProcessors; } void win_thread::start_thread(func_base* arg, unsigned int stack_size) { ::HANDLE entry_event = 0; arg->entry_event_ = entry_event = ::CreateEventW(0, true, false, 0); if (!entry_event) { DWORD last_error = ::GetLastError(); delete arg; asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread.entry_event"); } arg->exit_event_ = exit_event_ = ::CreateEventW(0, true, false, 0); if (!exit_event_) { DWORD last_error = ::GetLastError(); delete arg; asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread.exit_event"); } unsigned int thread_id = 0; thread_ = reinterpret_cast(::_beginthreadex(0, stack_size, win_thread_function, arg, 0, &thread_id)); if (!thread_) { DWORD last_error = ::GetLastError(); delete arg; if (entry_event) ::CloseHandle(entry_event); if (exit_event_) ::CloseHandle(exit_event_); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread"); } if (entry_event) { ::WaitForSingleObject(entry_event, INFINITE); ::CloseHandle(entry_event); } } unsigned int __stdcall win_thread_function(void* arg) { win_thread::auto_func_base_ptr func = { static_cast(arg) }; ::SetEvent(func.ptr->entry_event_); func.ptr->run(); // Signal that the thread has finished its work, but rather than returning go // to sleep to put the thread into a well known state. If the thread is being // joined during global object destruction then it may be killed using // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx // call will be interrupted using QueueUserAPC and the thread will shut down // cleanly. HANDLE exit_event = func.ptr->exit_event_; delete func.ptr; func.ptr = 0; ::SetEvent(exit_event); ::SleepEx(INFINITE, TRUE); return 0; } #if defined(WINVER) && (WINVER < 0x0500) void __stdcall apc_function(ULONG) {} #else void __stdcall apc_function(ULONG_PTR) {} #endif } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_APP) // && !defined(UNDER_CE) #endif // ASIO_DETAIL_IMPL_WIN_THREAD_IPP ================================================ FILE: src/third_party/asio/detail/impl/win_tss_ptr.ipp ================================================ // // detail/impl/win_tss_ptr.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP #define ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include "asio/detail/throw_error.hpp" #include "asio/detail/win_tss_ptr.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { DWORD win_tss_ptr_create() { #if defined(UNDER_CE) const DWORD out_of_indexes = 0xFFFFFFFF; #else const DWORD out_of_indexes = TLS_OUT_OF_INDEXES; #endif DWORD tss_key = ::TlsAlloc(); if (tss_key == out_of_indexes) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "tss"); } return tss_key; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP ================================================ FILE: src/third_party/asio/detail/impl/winrt_ssocket_service_base.ipp ================================================ // // detail/impl/winrt_ssocket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP #define ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include #include "asio/detail/winrt_ssocket_service_base.hpp" #include "asio/detail/winrt_async_op.hpp" #include "asio/detail/winrt_utils.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { winrt_ssocket_service_base::winrt_ssocket_service_base( execution_context& context) : scheduler_(use_service(context)), async_manager_(use_service(context)), mutex_(), impl_list_(0) { } void winrt_ssocket_service_base::base_shutdown() { // Close all implementations, causing all operations to complete. asio::detail::mutex::scoped_lock lock(mutex_); base_implementation_type* impl = impl_list_; while (impl) { asio::error_code ignored_ec; close(*impl, ignored_ec); impl = impl->next_; } } void winrt_ssocket_service_base::construct( winrt_ssocket_service_base::base_implementation_type& impl) { // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } void winrt_ssocket_service_base::base_move_construct( winrt_ssocket_service_base::base_implementation_type& impl, winrt_ssocket_service_base::base_implementation_type& other_impl) ASIO_NOEXCEPT { impl.socket_ = other_impl.socket_; other_impl.socket_ = nullptr; // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); impl.next_ = impl_list_; impl.prev_ = 0; if (impl_list_) impl_list_->prev_ = &impl; impl_list_ = &impl; } void winrt_ssocket_service_base::base_move_assign( winrt_ssocket_service_base::base_implementation_type& impl, winrt_ssocket_service_base& other_service, winrt_ssocket_service_base::base_implementation_type& other_impl) { asio::error_code ignored_ec; close(impl, ignored_ec); if (this != &other_service) { // Remove implementation from linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } impl.socket_ = other_impl.socket_; other_impl.socket_ = nullptr; if (this != &other_service) { // Insert implementation into linked list of all implementations. asio::detail::mutex::scoped_lock lock(other_service.mutex_); impl.next_ = other_service.impl_list_; impl.prev_ = 0; if (other_service.impl_list_) other_service.impl_list_->prev_ = &impl; other_service.impl_list_ = &impl; } } void winrt_ssocket_service_base::destroy( winrt_ssocket_service_base::base_implementation_type& impl) { asio::error_code ignored_ec; close(impl, ignored_ec); // Remove implementation from linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl) impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } asio::error_code winrt_ssocket_service_base::close( winrt_ssocket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (impl.socket_) { delete impl.socket_; impl.socket_ = nullptr; } ec = asio::error_code(); return ec; } winrt_ssocket_service_base::native_handle_type winrt_ssocket_service_base::release( winrt_ssocket_service_base::base_implementation_type& impl, asio::error_code& ec) { if (!is_open(impl)) return nullptr; cancel(impl, ec); if (ec) return nullptr; native_handle_type tmp = impl.socket_; impl.socket_ = nullptr; return tmp; } std::size_t winrt_ssocket_service_base::do_get_endpoint( const base_implementation_type& impl, bool local, void* addr, std::size_t addr_len, asio::error_code& ec) const { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return addr_len; } try { std::string addr_string = winrt_utils::string(local ? impl.socket_->Information->LocalAddress->CanonicalName : impl.socket_->Information->RemoteAddress->CanonicalName); unsigned short port = winrt_utils::integer(local ? impl.socket_->Information->LocalPort : impl.socket_->Information->RemotePort); unsigned long scope = 0; switch (reinterpret_cast(addr)->sa_family) { case ASIO_OS_DEF(AF_INET): if (addr_len < sizeof(sockaddr_in4_type)) { ec = asio::error::invalid_argument; return addr_len; } else { socket_ops::inet_pton(ASIO_OS_DEF(AF_INET), addr_string.c_str(), &reinterpret_cast(addr)->sin_addr, &scope, ec); reinterpret_cast(addr)->sin_port = socket_ops::host_to_network_short(port); ec = asio::error_code(); return sizeof(sockaddr_in4_type); } case ASIO_OS_DEF(AF_INET6): if (addr_len < sizeof(sockaddr_in6_type)) { ec = asio::error::invalid_argument; return addr_len; } else { socket_ops::inet_pton(ASIO_OS_DEF(AF_INET6), addr_string.c_str(), &reinterpret_cast(addr)->sin6_addr, &scope, ec); reinterpret_cast(addr)->sin6_port = socket_ops::host_to_network_short(port); ec = asio::error_code(); return sizeof(sockaddr_in6_type); } default: ec = asio::error::address_family_not_supported; return addr_len; } } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); return addr_len; } } asio::error_code winrt_ssocket_service_base::do_set_option( winrt_ssocket_service_base::base_implementation_type& impl, int level, int optname, const void* optval, std::size_t optlen, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return ec; } try { if (level == ASIO_OS_DEF(SOL_SOCKET) && optname == ASIO_OS_DEF(SO_KEEPALIVE)) { if (optlen == sizeof(int)) { int value = 0; std::memcpy(&value, optval, optlen); impl.socket_->Control->KeepAlive = !!value; ec = asio::error_code(); } else { ec = asio::error::invalid_argument; } } else if (level == ASIO_OS_DEF(IPPROTO_TCP) && optname == ASIO_OS_DEF(TCP_NODELAY)) { if (optlen == sizeof(int)) { int value = 0; std::memcpy(&value, optval, optlen); impl.socket_->Control->NoDelay = !!value; ec = asio::error_code(); } else { ec = asio::error::invalid_argument; } } else { ec = asio::error::invalid_argument; } } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); } return ec; } void winrt_ssocket_service_base::do_get_option( const winrt_ssocket_service_base::base_implementation_type& impl, int level, int optname, void* optval, std::size_t* optlen, asio::error_code& ec) const { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return; } try { if (level == ASIO_OS_DEF(SOL_SOCKET) && optname == ASIO_OS_DEF(SO_KEEPALIVE)) { if (*optlen >= sizeof(int)) { int value = impl.socket_->Control->KeepAlive ? 1 : 0; std::memcpy(optval, &value, sizeof(int)); *optlen = sizeof(int); ec = asio::error_code(); } else { ec = asio::error::invalid_argument; } } else if (level == ASIO_OS_DEF(IPPROTO_TCP) && optname == ASIO_OS_DEF(TCP_NODELAY)) { if (*optlen >= sizeof(int)) { int value = impl.socket_->Control->NoDelay ? 1 : 0; std::memcpy(optval, &value, sizeof(int)); *optlen = sizeof(int); ec = asio::error_code(); } else { ec = asio::error::invalid_argument; } } else { ec = asio::error::invalid_argument; } } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); } } asio::error_code winrt_ssocket_service_base::do_connect( winrt_ssocket_service_base::base_implementation_type& impl, const void* addr, asio::error_code& ec) { if (!is_open(impl)) { ec = asio::error::bad_descriptor; return ec; } char addr_string[max_addr_v6_str_len]; unsigned short port; switch (reinterpret_cast(addr)->sa_family) { case ASIO_OS_DEF(AF_INET): socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET), &reinterpret_cast(addr)->sin_addr, addr_string, sizeof(addr_string), 0, ec); port = socket_ops::network_to_host_short( reinterpret_cast(addr)->sin_port); break; case ASIO_OS_DEF(AF_INET6): socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET6), &reinterpret_cast(addr)->sin6_addr, addr_string, sizeof(addr_string), 0, ec); port = socket_ops::network_to_host_short( reinterpret_cast(addr)->sin6_port); break; default: ec = asio::error::address_family_not_supported; return ec; } if (!ec) try { async_manager_.sync(impl.socket_->ConnectAsync( ref new Windows::Networking::HostName( winrt_utils::string(addr_string)), winrt_utils::string(port)), ec); } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); } return ec; } void winrt_ssocket_service_base::start_connect_op( winrt_ssocket_service_base::base_implementation_type& impl, const void* addr, winrt_async_op* op, bool is_continuation) { if (!is_open(impl)) { op->ec_ = asio::error::bad_descriptor; scheduler_.post_immediate_completion(op, is_continuation); return; } char addr_string[max_addr_v6_str_len]; unsigned short port = 0; switch (reinterpret_cast(addr)->sa_family) { case ASIO_OS_DEF(AF_INET): socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET), &reinterpret_cast(addr)->sin_addr, addr_string, sizeof(addr_string), 0, op->ec_); port = socket_ops::network_to_host_short( reinterpret_cast(addr)->sin_port); break; case ASIO_OS_DEF(AF_INET6): socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET6), &reinterpret_cast(addr)->sin6_addr, addr_string, sizeof(addr_string), 0, op->ec_); port = socket_ops::network_to_host_short( reinterpret_cast(addr)->sin6_port); break; default: op->ec_ = asio::error::address_family_not_supported; break; } if (op->ec_) { scheduler_.post_immediate_completion(op, is_continuation); return; } try { async_manager_.async(impl.socket_->ConnectAsync( ref new Windows::Networking::HostName( winrt_utils::string(addr_string)), winrt_utils::string(port)), op); } catch (Platform::Exception^ e) { op->ec_ = asio::error_code( e->HResult, asio::system_category()); scheduler_.post_immediate_completion(op, is_continuation); } } std::size_t winrt_ssocket_service_base::do_send( winrt_ssocket_service_base::base_implementation_type& impl, const asio::const_buffer& data, socket_base::message_flags flags, asio::error_code& ec) { if (flags) { ec = asio::error::operation_not_supported; return 0; } if (!is_open(impl)) { ec = asio::error::bad_descriptor; return 0; } try { buffer_sequence_adapter bufs(asio::buffer(data)); if (bufs.all_empty()) { ec = asio::error_code(); return 0; } return async_manager_.sync( impl.socket_->OutputStream->WriteAsync(bufs.buffers()[0]), ec); } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); return 0; } } void winrt_ssocket_service_base::start_send_op( winrt_ssocket_service_base::base_implementation_type& impl, const asio::const_buffer& data, socket_base::message_flags flags, winrt_async_op* op, bool is_continuation) { if (flags) { op->ec_ = asio::error::operation_not_supported; scheduler_.post_immediate_completion(op, is_continuation); return; } if (!is_open(impl)) { op->ec_ = asio::error::bad_descriptor; scheduler_.post_immediate_completion(op, is_continuation); return; } try { buffer_sequence_adapter bufs(asio::buffer(data)); if (bufs.all_empty()) { scheduler_.post_immediate_completion(op, is_continuation); return; } async_manager_.async( impl.socket_->OutputStream->WriteAsync(bufs.buffers()[0]), op); } catch (Platform::Exception^ e) { op->ec_ = asio::error_code(e->HResult, asio::system_category()); scheduler_.post_immediate_completion(op, is_continuation); } } std::size_t winrt_ssocket_service_base::do_receive( winrt_ssocket_service_base::base_implementation_type& impl, const asio::mutable_buffer& data, socket_base::message_flags flags, asio::error_code& ec) { if (flags) { ec = asio::error::operation_not_supported; return 0; } if (!is_open(impl)) { ec = asio::error::bad_descriptor; return 0; } try { buffer_sequence_adapter bufs(asio::buffer(data)); if (bufs.all_empty()) { ec = asio::error_code(); return 0; } async_manager_.sync( impl.socket_->InputStream->ReadAsync( bufs.buffers()[0], bufs.buffers()[0]->Capacity, Windows::Storage::Streams::InputStreamOptions::Partial), ec); std::size_t bytes_transferred = bufs.buffers()[0]->Length; if (bytes_transferred == 0 && !ec) { ec = asio::error::eof; } return bytes_transferred; } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); return 0; } } void winrt_ssocket_service_base::start_receive_op( winrt_ssocket_service_base::base_implementation_type& impl, const asio::mutable_buffer& data, socket_base::message_flags flags, winrt_async_op* op, bool is_continuation) { if (flags) { op->ec_ = asio::error::operation_not_supported; scheduler_.post_immediate_completion(op, is_continuation); return; } if (!is_open(impl)) { op->ec_ = asio::error::bad_descriptor; scheduler_.post_immediate_completion(op, is_continuation); return; } try { buffer_sequence_adapter bufs(asio::buffer(data)); if (bufs.all_empty()) { scheduler_.post_immediate_completion(op, is_continuation); return; } async_manager_.async( impl.socket_->InputStream->ReadAsync( bufs.buffers()[0], bufs.buffers()[0]->Capacity, Windows::Storage::Streams::InputStreamOptions::Partial), op); } catch (Platform::Exception^ e) { op->ec_ = asio::error_code(e->HResult, asio::system_category()); scheduler_.post_immediate_completion(op, is_continuation); } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP ================================================ FILE: src/third_party/asio/detail/impl/winrt_timer_scheduler.hpp ================================================ // // detail/impl/winrt_timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP #define ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template void winrt_timer_scheduler::add_timer_queue(timer_queue& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor. template void winrt_timer_scheduler::remove_timer_queue(timer_queue& queue) { do_remove_timer_queue(queue); } template void winrt_timer_scheduler::schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); if (shutdown_) { scheduler_.post_immediate_completion(op, false); return; } bool earliest = queue.enqueue_timer(time, timer, op); scheduler_.work_started(); if (earliest) event_.signal(lock); } template std::size_t winrt_timer_scheduler::cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue ops; std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); lock.unlock(); scheduler_.post_deferred_completions(ops); return n; } template void winrt_timer_scheduler::move_timer(timer_queue& queue, typename timer_queue::per_timer_data& to, typename timer_queue::per_timer_data& from) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue ops; queue.cancel_timer(to, ops); queue.move_timer(to, from); lock.unlock(); scheduler_.post_deferred_completions(ops); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP ================================================ FILE: src/third_party/asio/detail/impl/winrt_timer_scheduler.ipp ================================================ // // detail/impl/winrt_timer_scheduler.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_IPP #define ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/bind_handler.hpp" #include "asio/detail/winrt_timer_scheduler.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { winrt_timer_scheduler::winrt_timer_scheduler(execution_context& context) : execution_context_service_base(context), scheduler_(use_service(context)), mutex_(), event_(), timer_queues_(), thread_(0), stop_thread_(false), shutdown_(false) { thread_ = new asio::detail::thread( bind_handler(&winrt_timer_scheduler::call_run_thread, this)); } winrt_timer_scheduler::~winrt_timer_scheduler() { shutdown(); } void winrt_timer_scheduler::shutdown() { asio::detail::mutex::scoped_lock lock(mutex_); shutdown_ = true; stop_thread_ = true; event_.signal(lock); lock.unlock(); if (thread_) { thread_->join(); delete thread_; thread_ = 0; } op_queue ops; timer_queues_.get_all_timers(ops); scheduler_.abandon_operations(ops); } void winrt_timer_scheduler::notify_fork(execution_context::fork_event) { } void winrt_timer_scheduler::init_task() { } void winrt_timer_scheduler::run_thread() { asio::detail::mutex::scoped_lock lock(mutex_); while (!stop_thread_) { const long max_wait_duration = 5 * 60 * 1000000; long wait_duration = timer_queues_.wait_duration_usec(max_wait_duration); event_.wait_for_usec(lock, wait_duration); event_.clear(lock); op_queue ops; timer_queues_.get_ready_timers(ops); if (!ops.empty()) { lock.unlock(); scheduler_.post_deferred_completions(ops); lock.lock(); } } } void winrt_timer_scheduler::call_run_thread(winrt_timer_scheduler* scheduler) { scheduler->run_thread(); } void winrt_timer_scheduler::do_add_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.insert(&queue); } void winrt_timer_scheduler::do_remove_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(mutex_); timer_queues_.erase(&queue); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_IPP ================================================ FILE: src/third_party/asio/detail/impl/winsock_init.ipp ================================================ // // detail/impl/winsock_init.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP #define ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) #include "asio/detail/socket_types.hpp" #include "asio/detail/winsock_init.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { void winsock_init_base::startup(data& d, unsigned char major, unsigned char minor) { if (::InterlockedIncrement(&d.init_count_) == 1) { WSADATA wsa_data; long result = ::WSAStartup(MAKEWORD(major, minor), &wsa_data); ::InterlockedExchange(&d.result_, result); } } void winsock_init_base::manual_startup(data& d) { if (::InterlockedIncrement(&d.init_count_) == 1) { ::InterlockedExchange(&d.result_, 0); } } void winsock_init_base::cleanup(data& d) { if (::InterlockedDecrement(&d.init_count_) == 0) { ::WSACleanup(); } } void winsock_init_base::manual_cleanup(data& d) { ::InterlockedDecrement(&d.init_count_); } void winsock_init_base::throw_on_error(data& d) { long result = ::InterlockedExchangeAdd(&d.result_, 0); if (result != 0) { asio::error_code ec(result, asio::error::get_system_category()); asio::detail::throw_error(ec, "winsock"); } } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #endif // ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP ================================================ FILE: src/third_party/asio/detail/io_control.hpp ================================================ // // detail/io_control.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IO_CONTROL_HPP #define ASIO_DETAIL_IO_CONTROL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { namespace io_control { // I/O control command for getting number of bytes available. class bytes_readable { public: // Default constructor. bytes_readable() : value_(0) { } // Construct with a specific command value. bytes_readable(std::size_t value) : value_(static_cast(value)) { } // Get the name of the IO control command. int name() const { return static_cast(ASIO_OS_DEF(FIONREAD)); } // Set the value of the I/O control command. void set(std::size_t value) { value_ = static_cast(value); } // Get the current value of the I/O control command. std::size_t get() const { return static_cast(value_); } // Get the address of the command data. detail::ioctl_arg_type* data() { return &value_; } // Get the address of the command data. const detail::ioctl_arg_type* data() const { return &value_; } private: detail::ioctl_arg_type value_; }; } // namespace io_control } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IO_CONTROL_HPP ================================================ FILE: src/third_party/asio/detail/io_object_executor.hpp ================================================ // // io_object_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IO_OBJECT_EXECUTOR_HPP #define ASIO_DETAIL_IO_OBJECT_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Wrap the (potentially polymorphic) executor so that we can bypass it when // dispatching on a target executor that has a native I/O implementation. template class io_object_executor { public: io_object_executor(const Executor& ex, bool native_implementation) ASIO_NOEXCEPT : executor_(ex), has_native_impl_(native_implementation) { } io_object_executor(const io_object_executor& other) ASIO_NOEXCEPT : executor_(other.executor_), has_native_impl_(other.has_native_impl_) { } template io_object_executor( const io_object_executor& other) ASIO_NOEXCEPT : executor_(other.inner_executor()), has_native_impl_(other.has_native_implementation()) { } #if defined(ASIO_HAS_MOVE) io_object_executor(io_object_executor&& other) ASIO_NOEXCEPT : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), has_native_impl_(other.has_native_impl_) { } #endif // defined(ASIO_HAS_MOVE) const Executor& inner_executor() const ASIO_NOEXCEPT { return executor_; } bool has_native_implementation() const ASIO_NOEXCEPT { return has_native_impl_; } execution_context& context() const ASIO_NOEXCEPT { return executor_.context(); } void on_work_started() const ASIO_NOEXCEPT { if (is_same::value || has_native_impl_) { // When using a native implementation, work is already counted by the // execution context. } else { executor_.on_work_started(); } } void on_work_finished() const ASIO_NOEXCEPT { if (is_same::value || has_native_impl_) { // When using a native implementation, work is already counted by the // execution context. } else { executor_.on_work_finished(); } } template void dispatch(ASIO_MOVE_ARG(F) f, const A& a) const { if (is_same::value || has_native_impl_) { // When using a native implementation, I/O completion handlers are // already dispatched according to the execution context's executor's // rules. We can call the function directly. #if defined(ASIO_HAS_MOVE) if (is_same::type>::value) { asio_handler_invoke_helpers::invoke(f, f); return; } #endif // defined(ASIO_HAS_MOVE) typename decay::type function(ASIO_MOVE_CAST(F)(f)); asio_handler_invoke_helpers::invoke(function, function); } else { executor_.dispatch(ASIO_MOVE_CAST(F)(f), a); } } template void post(ASIO_MOVE_ARG(F) f, const A& a) const { executor_.post(ASIO_MOVE_CAST(F)(f), a); } template void defer(ASIO_MOVE_ARG(F) f, const A& a) const { executor_.defer(ASIO_MOVE_CAST(F)(f), a); } friend bool operator==(const io_object_executor& a, const io_object_executor& b) ASIO_NOEXCEPT { return a.executor_ == b.executor_ && a.has_native_impl_ == b.has_native_impl_; } friend bool operator!=(const io_object_executor& a, const io_object_executor& b) ASIO_NOEXCEPT { return a.executor_ != b.executor_ || a.has_native_impl_ != b.has_native_impl_; } private: Executor executor_; const bool has_native_impl_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IO_OBJECT_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/detail/io_object_impl.hpp ================================================ // // io_object_impl.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IO_OBJECT_IMPL_HPP #define ASIO_DETAIL_IO_OBJECT_IMPL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include "asio/detail/config.hpp" #include "asio/detail/io_object_executor.hpp" #include "asio/detail/type_traits.hpp" #include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { class executor; namespace detail { inline bool is_native_io_executor(const io_context::executor_type&) { return true; } template inline bool is_native_io_executor(const Executor&, typename enable_if::value>::type* = 0) { return false; } template inline bool is_native_io_executor(const Executor& ex, typename enable_if::value>::type* = 0) { #if !defined (ASIO_NO_TYPEID) return ex.target_type() == typeid(io_context::executor_type); #else // !defined (ASIO_NO_TYPEID) return false; #endif // !defined (ASIO_NO_TYPEID) } template class io_object_impl { public: // The type of the service that will be used to provide I/O operations. typedef IoObjectService service_type; // The underlying implementation type of I/O object. typedef typename service_type::implementation_type implementation_type; // The type of the executor associated with the object. typedef Executor executor_type; // The type of executor to be used when implementing asynchronous operations. typedef io_object_executor implementation_executor_type; // Construct an I/O object using an executor. explicit io_object_impl(const executor_type& ex) : service_(&asio::use_service(ex.context())), implementation_executor_(ex, (is_native_io_executor)(ex)) { service_->construct(implementation_); } // Construct an I/O object using an execution context. template explicit io_object_impl(ExecutionContext& context, typename enable_if::value>::type* = 0) : service_(&asio::use_service(context)), implementation_executor_(context.get_executor(), is_same::value) { service_->construct(implementation_); } #if defined(ASIO_HAS_MOVE) // Move-construct an I/O object. io_object_impl(io_object_impl&& other) : service_(&other.get_service()), implementation_executor_(other.get_implementation_executor()) { service_->move_construct(implementation_, other.implementation_); } // Perform a converting move-construction of an I/O object. template io_object_impl(io_object_impl&& other) : service_(&asio::use_service( other.get_implementation_executor().context())), implementation_executor_(other.get_implementation_executor()) { service_->converting_move_construct(implementation_, other.get_service(), other.get_implementation()); } #endif // defined(ASIO_HAS_MOVE) // Destructor. ~io_object_impl() { service_->destroy(implementation_); } #if defined(ASIO_HAS_MOVE) // Move-assign an I/O object. io_object_impl& operator=(io_object_impl&& other) { if (this != &other) { service_->move_assign(implementation_, *other.service_, other.implementation_); implementation_executor_.~implementation_executor_type(); new (&implementation_executor_) implementation_executor_type( std::move(other.implementation_executor_)); service_ = other.service_; } return *this; } #endif // defined(ASIO_HAS_MOVE) // Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return implementation_executor_.inner_executor(); } // Get the executor to be used when implementing asynchronous operations. const implementation_executor_type& get_implementation_executor() ASIO_NOEXCEPT { return implementation_executor_; } // Get the service associated with the I/O object. service_type& get_service() { return *service_; } // Get the service associated with the I/O object. const service_type& get_service() const { return *service_; } // Get the underlying implementation of the I/O object. implementation_type& get_implementation() { return implementation_; } // Get the underlying implementation of the I/O object. const implementation_type& get_implementation() const { return implementation_; } private: // Disallow copying and copy assignment. io_object_impl(const io_object_impl&); io_object_impl& operator=(const io_object_impl&); // The service associated with the I/O object. service_type* service_; // The underlying implementation of the I/O object. implementation_type implementation_; // The associated executor. implementation_executor_type implementation_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IO_OBJECT_IMPL_HPP ================================================ FILE: src/third_party/asio/detail/is_buffer_sequence.hpp ================================================ // // detail/is_buffer_sequence.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP #define ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { class mutable_buffer; class const_buffer; namespace detail { struct buffer_sequence_memfns_base { void begin(); void end(); void size(); void max_size(); void capacity(); void data(); void prepare(); void commit(); void consume(); void grow(); void shrink(); }; template struct buffer_sequence_memfns_derived : T, buffer_sequence_memfns_base { }; template struct buffer_sequence_memfns_check { }; #if defined(ASIO_HAS_DECLTYPE) template char buffer_sequence_begin_helper(...); template char (&buffer_sequence_begin_helper(T* t, typename enable_if::value>::type*))[2]; #else // defined(ASIO_HAS_DECLTYPE) template char (&buffer_sequence_begin_helper(...))[2]; template char buffer_sequence_begin_helper(T* t, buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::begin>*); #endif // defined(ASIO_HAS_DECLTYPE) #if defined(ASIO_HAS_DECLTYPE) template char buffer_sequence_end_helper(...); template char (&buffer_sequence_end_helper(T* t, typename enable_if::value>::type*))[2]; #else // defined(ASIO_HAS_DECLTYPE) template char (&buffer_sequence_end_helper(...))[2]; template char buffer_sequence_end_helper(T* t, buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::end>*); #endif // defined(ASIO_HAS_DECLTYPE) template char (&size_memfn_helper(...))[2]; template char size_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::size>*); template char (&max_size_memfn_helper(...))[2]; template char max_size_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::max_size>*); template char (&capacity_memfn_helper(...))[2]; template char capacity_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::capacity>*); template char (&data_memfn_helper(...))[2]; template char data_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::data>*); template char (&prepare_memfn_helper(...))[2]; template char prepare_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::prepare>*); template char (&commit_memfn_helper(...))[2]; template char commit_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::commit>*); template char (&consume_memfn_helper(...))[2]; template char consume_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::consume>*); template char (&grow_memfn_helper(...))[2]; template char grow_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::grow>*); template char (&shrink_memfn_helper(...))[2]; template char shrink_memfn_helper( buffer_sequence_memfns_check< void (buffer_sequence_memfns_base::*)(), &buffer_sequence_memfns_derived::shrink>*); template char (&buffer_sequence_element_type_helper(...))[2]; #if defined(ASIO_HAS_DECLTYPE) template char buffer_sequence_element_type_helper(T* t, typename enable_if::value>::type*); #else // defined(ASIO_HAS_DECLTYPE) template char buffer_sequence_element_type_helper( typename T::const_iterator*, typename enable_if::value>::type*); #endif // defined(ASIO_HAS_DECLTYPE) template char (&const_buffers_type_typedef_helper(...))[2]; template char const_buffers_type_typedef_helper( typename T::const_buffers_type*); template char (&mutable_buffers_type_typedef_helper(...))[2]; template char mutable_buffers_type_typedef_helper( typename T::mutable_buffers_type*); template struct is_buffer_sequence_class : integral_constant(0, 0)) != 1 && sizeof(buffer_sequence_end_helper(0, 0)) != 1 && sizeof(buffer_sequence_element_type_helper(0, 0)) == 1> { }; template struct is_buffer_sequence : conditional::value, is_buffer_sequence_class, false_type>::type { }; template <> struct is_buffer_sequence : true_type { }; template <> struct is_buffer_sequence : true_type { }; template <> struct is_buffer_sequence : true_type { }; template <> struct is_buffer_sequence : false_type { }; template struct is_dynamic_buffer_class_v1 : integral_constant(0)) != 1 && sizeof(max_size_memfn_helper(0)) != 1 && sizeof(capacity_memfn_helper(0)) != 1 && sizeof(data_memfn_helper(0)) != 1 && sizeof(consume_memfn_helper(0)) != 1 && sizeof(prepare_memfn_helper(0)) != 1 && sizeof(commit_memfn_helper(0)) != 1 && sizeof(const_buffers_type_typedef_helper(0)) == 1 && sizeof(mutable_buffers_type_typedef_helper(0)) == 1> { }; template struct is_dynamic_buffer_v1 : conditional::value, is_dynamic_buffer_class_v1, false_type>::type { }; template struct is_dynamic_buffer_class_v2 : integral_constant(0)) != 1 && sizeof(max_size_memfn_helper(0)) != 1 && sizeof(capacity_memfn_helper(0)) != 1 && sizeof(data_memfn_helper(0)) != 1 && sizeof(consume_memfn_helper(0)) != 1 && sizeof(grow_memfn_helper(0)) != 1 && sizeof(shrink_memfn_helper(0)) != 1 && sizeof(const_buffers_type_typedef_helper(0)) == 1 && sizeof(mutable_buffers_type_typedef_helper(0)) == 1> { }; template struct is_dynamic_buffer_v2 : conditional::value, is_dynamic_buffer_class_v2, false_type>::type { }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP ================================================ FILE: src/third_party/asio/detail/is_executor.hpp ================================================ // // detail/is_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_IS_EXECUTOR_HPP #define ASIO_DETAIL_IS_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct executor_memfns_base { void context(); void on_work_started(); void on_work_finished(); void dispatch(); void post(); void defer(); }; template struct executor_memfns_derived : T, executor_memfns_base { }; template struct executor_memfns_check { }; template char (&context_memfn_helper(...))[2]; template char context_memfn_helper( executor_memfns_check< void (executor_memfns_base::*)(), &executor_memfns_derived::context>*); template char (&on_work_started_memfn_helper(...))[2]; template char on_work_started_memfn_helper( executor_memfns_check< void (executor_memfns_base::*)(), &executor_memfns_derived::on_work_started>*); template char (&on_work_finished_memfn_helper(...))[2]; template char on_work_finished_memfn_helper( executor_memfns_check< void (executor_memfns_base::*)(), &executor_memfns_derived::on_work_finished>*); template char (&dispatch_memfn_helper(...))[2]; template char dispatch_memfn_helper( executor_memfns_check< void (executor_memfns_base::*)(), &executor_memfns_derived::dispatch>*); template char (&post_memfn_helper(...))[2]; template char post_memfn_helper( executor_memfns_check< void (executor_memfns_base::*)(), &executor_memfns_derived::post>*); template char (&defer_memfn_helper(...))[2]; template char defer_memfn_helper( executor_memfns_check< void (executor_memfns_base::*)(), &executor_memfns_derived::defer>*); template struct is_executor_class : integral_constant(0)) != 1 && sizeof(on_work_started_memfn_helper(0)) != 1 && sizeof(on_work_finished_memfn_helper(0)) != 1 && sizeof(dispatch_memfn_helper(0)) != 1 && sizeof(post_memfn_helper(0)) != 1 && sizeof(defer_memfn_helper(0)) != 1> { }; template struct is_executor : conditional::value, is_executor_class, false_type>::type { }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_IS_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/detail/keyword_tss_ptr.hpp ================================================ // // detail/keyword_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_KEYWORD_TSS_PTR_HPP #define ASIO_DETAIL_KEYWORD_TSS_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class keyword_tss_ptr : private noncopyable { public: // Constructor. keyword_tss_ptr() { } // Destructor. ~keyword_tss_ptr() { } // Get the value. operator T*() const { return value_; } // Set the value. void operator=(T* value) { value_ = value; } private: static ASIO_THREAD_KEYWORD T* value_; }; template ASIO_THREAD_KEYWORD T* keyword_tss_ptr::value_; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) #endif // ASIO_DETAIL_KEYWORD_TSS_PTR_HPP ================================================ FILE: src/third_party/asio/detail/kqueue_reactor.hpp ================================================ // // detail/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_KQUEUE_REACTOR_HPP #define ASIO_DETAIL_KQUEUE_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_KQUEUE) #include #include #include #include #include "asio/detail/limits.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/object_pool.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/select_interrupter.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/timer_queue_set.hpp" #include "asio/detail/wait_op.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" // Older versions of Mac OS X may not define EV_OOBAND. #if !defined(EV_OOBAND) # define EV_OOBAND EV_FLAG1 #endif // !defined(EV_OOBAND) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class scheduler; class kqueue_reactor : public execution_context_service_base { private: // The mutex type used by this reactor. typedef conditionally_enabled_mutex mutex; public: enum op_types { read_op = 0, write_op = 1, connect_op = 1, except_op = 2, max_ops = 3 }; // Per-descriptor queues. struct descriptor_state { descriptor_state(bool locking) : mutex_(locking) {} friend class kqueue_reactor; friend class object_pool_access; descriptor_state* next_; descriptor_state* prev_; mutex mutex_; int descriptor_; int num_kevents_; // 1 == read only, 2 == read and write op_queue op_queue_[max_ops]; bool shutdown_; }; // Per-descriptor data. typedef descriptor_state* per_descriptor_data; // Constructor. ASIO_DECL kqueue_reactor(asio::execution_context& ctx); // Destructor. ASIO_DECL ~kqueue_reactor(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Recreate internal descriptors following a fork. ASIO_DECL void notify_fork( asio::execution_context::fork_event fork_ev); // Initialise the task. ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. ASIO_DECL int register_descriptor(socket_type descriptor, per_descriptor_data& descriptor_data); // Register a descriptor with an associated single operation. Returns 0 on // success, system error code on failure. ASIO_DECL int register_internal_descriptor( int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, reactor_op* op); // Move descriptor registration from one descriptor_data object to another. ASIO_DECL void move_descriptor(socket_type descriptor, per_descriptor_data& target_descriptor_data, per_descriptor_data& source_descriptor_data); // Post a reactor operation for immediate completion. void post_immediate_completion(reactor_op* op, bool is_continuation) { scheduler_.post_immediate_completion(op, is_continuation); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. ASIO_DECL void start_op(int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, reactor_op* op, bool is_continuation, bool allow_speculative); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data& descriptor_data); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. The reactor resources associated with // the descriptor must be released by calling cleanup_descriptor_data. ASIO_DECL void deregister_descriptor(socket_type descriptor, per_descriptor_data& descriptor_data, bool closing); // Remove the descriptor's registration from the reactor. The reactor // resources associated with the descriptor must be released by calling // cleanup_descriptor_data. ASIO_DECL void deregister_internal_descriptor( socket_type descriptor, per_descriptor_data& descriptor_data); // Perform any post-deregistration cleanup tasks associated with the // descriptor data. ASIO_DECL void cleanup_descriptor_data( per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor. template void add_timer_queue(timer_queue& queue); // Remove a timer queue from the reactor. template void remove_timer_queue(timer_queue& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template void schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template std::size_t cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits::max)()); // Move the timer operations associated with the given timer. template void move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source); // Run the kqueue loop. ASIO_DECL void run(long usec, op_queue& ops); // Interrupt the kqueue loop. ASIO_DECL void interrupt(); private: // Create the kqueue file descriptor. Throws an exception if the descriptor // cannot be created. ASIO_DECL static int do_kqueue_create(); // Allocate a new descriptor state object. ASIO_DECL descriptor_state* allocate_descriptor_state(); // Free an existing descriptor state object. ASIO_DECL void free_descriptor_state(descriptor_state* s); // Helper function to add a new timer queue. ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); // Helper function to remove a timer queue. ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Get the timeout value for the kevent call. ASIO_DECL timespec* get_timeout(long usec, timespec& ts); // The scheduler used to post completions. scheduler& scheduler_; // Mutex to protect access to internal data. mutex mutex_; // The kqueue file descriptor. int kqueue_fd_; // The interrupter is used to break a blocking kevent call. select_interrupter interrupter_; // The timer queues. timer_queue_set timer_queues_; // Whether the service has been shut down. bool shutdown_; // Mutex to protect access to the registered descriptors. mutex registered_descriptors_mutex_; // Keep track of all registered descriptors. object_pool registered_descriptors_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/kqueue_reactor.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/kqueue_reactor.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_KQUEUE) #endif // ASIO_DETAIL_KQUEUE_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/limits.hpp ================================================ // // detail/limits.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_LIMITS_HPP #define ASIO_DETAIL_LIMITS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_LIMITS) # include #else // defined(ASIO_HAS_BOOST_LIMITS) # include #endif // defined(ASIO_HAS_BOOST_LIMITS) #endif // ASIO_DETAIL_LIMITS_HPP ================================================ FILE: src/third_party/asio/detail/local_free_on_block_exit.hpp ================================================ // // detail/local_free_on_block_exit.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP #define ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) #if !defined(ASIO_WINDOWS_APP) #include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class local_free_on_block_exit : private noncopyable { public: // Constructor blocks all signals for the calling thread. explicit local_free_on_block_exit(void* p) : p_(p) { } // Destructor restores the previous signal mask. ~local_free_on_block_exit() { ::LocalFree(p_); } private: void* p_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS_APP) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #endif // ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP ================================================ FILE: src/third_party/asio/detail/macos_fenced_block.hpp ================================================ // // detail/macos_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP #define ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(__MACH__) && defined(__APPLE__) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class macos_fenced_block : private noncopyable { public: enum half_t { half }; enum full_t { full }; // Constructor for a half fenced block. explicit macos_fenced_block(half_t) { } // Constructor for a full fenced block. explicit macos_fenced_block(full_t) { OSMemoryBarrier(); } // Destructor. ~macos_fenced_block() { OSMemoryBarrier(); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(__MACH__) && defined(__APPLE__) #endif // ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/memory.hpp ================================================ // // detail/memory.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_MEMORY_HPP #define ASIO_DETAIL_MEMORY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #if !defined(ASIO_HAS_STD_SHARED_PTR) # include # include #endif // !defined(ASIO_HAS_STD_SHARED_PTR) #if !defined(ASIO_HAS_STD_ADDRESSOF) # include #endif // !defined(ASIO_HAS_STD_ADDRESSOF) namespace asio { namespace detail { #if defined(ASIO_HAS_STD_SHARED_PTR) using std::shared_ptr; using std::weak_ptr; #else // defined(ASIO_HAS_STD_SHARED_PTR) using boost::shared_ptr; using boost::weak_ptr; #endif // defined(ASIO_HAS_STD_SHARED_PTR) #if defined(ASIO_HAS_STD_ADDRESSOF) using std::addressof; #else // defined(ASIO_HAS_STD_ADDRESSOF) using boost::addressof; #endif // defined(ASIO_HAS_STD_ADDRESSOF) } // namespace detail #if defined(ASIO_HAS_CXX11_ALLOCATORS) using std::allocator_arg_t; # define ASIO_USES_ALLOCATOR(t) \ namespace std { \ template \ struct uses_allocator : true_type {}; \ } \ /**/ # define ASIO_REBIND_ALLOC(alloc, t) \ typename std::allocator_traits::template rebind_alloc /**/ #else // defined(ASIO_HAS_CXX11_ALLOCATORS) struct allocator_arg_t {}; # define ASIO_USES_ALLOCATOR(t) # define ASIO_REBIND_ALLOC(alloc, t) \ typename alloc::template rebind::other /**/ #endif // defined(ASIO_HAS_CXX11_ALLOCATORS) } // namespace asio #endif // ASIO_DETAIL_MEMORY_HPP ================================================ FILE: src/third_party/asio/detail/mutex.hpp ================================================ // // detail/mutex.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_MUTEX_HPP #define ASIO_DETAIL_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) # include "asio/detail/null_mutex.hpp" #elif defined(ASIO_WINDOWS) # include "asio/detail/win_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_mutex.hpp" #elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_mutex.hpp" #else # error Only Windows, POSIX and std::mutex are supported! #endif namespace asio { namespace detail { #if !defined(ASIO_HAS_THREADS) typedef null_mutex mutex; #elif defined(ASIO_WINDOWS) typedef win_mutex mutex; #elif defined(ASIO_HAS_PTHREADS) typedef posix_mutex mutex; #elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_mutex mutex; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/non_const_lvalue.hpp ================================================ // // detail/non_const_lvalue.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NON_CONST_LVALUE_HPP #define ASIO_DETAIL_NON_CONST_LVALUE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct non_const_lvalue { #if defined(ASIO_HAS_MOVE) explicit non_const_lvalue(T& t) : value(static_cast::type>::value, typename decay::type&, T&&>::type>(t)) { } typename conditional::type>::value, typename decay::type&, typename decay::type>::type value; #else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) explicit non_const_lvalue(const typename decay::type& t) : value(t) { } typename decay::type value; #endif // defined(ASIO_HAS_MOVE) }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_NON_CONST_LVALUE_HPP ================================================ FILE: src/third_party/asio/detail/noncopyable.hpp ================================================ // // detail/noncopyable.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NONCOPYABLE_HPP #define ASIO_DETAIL_NONCOPYABLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class noncopyable { protected: noncopyable() {} ~noncopyable() {} private: noncopyable(const noncopyable&); const noncopyable& operator=(const noncopyable&); }; } // namespace detail using asio::detail::noncopyable; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_NONCOPYABLE_HPP ================================================ FILE: src/third_party/asio/detail/null_event.hpp ================================================ // // detail/null_event.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_EVENT_HPP #define ASIO_DETAIL_NULL_EVENT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class null_event : private noncopyable { public: // Constructor. null_event() { } // Destructor. ~null_event() { } // Signal the event. (Retained for backward compatibility.) template void signal(Lock&) { } // Signal all waiters. template void signal_all(Lock&) { } // Unlock the mutex and signal one waiter. template void unlock_and_signal_one(Lock&) { } // If there's a waiter, unlock the mutex and signal it. template bool maybe_unlock_and_signal_one(Lock&) { return false; } // Reset the event. template void clear(Lock&) { } // Wait for the event to become signalled. template void wait(Lock&) { do_wait(); } // Timed wait for the event to become signalled. template bool wait_for_usec(Lock&, long usec) { do_wait_for_usec(usec); return true; } private: ASIO_DECL static void do_wait(); ASIO_DECL static void do_wait_for_usec(long usec); }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/null_event.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_NULL_EVENT_HPP ================================================ FILE: src/third_party/asio/detail/null_fenced_block.hpp ================================================ // // detail/null_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_FENCED_BLOCK_HPP #define ASIO_DETAIL_NULL_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class null_fenced_block : private noncopyable { public: enum half_or_full_t { half, full }; // Constructor. explicit null_fenced_block(half_or_full_t) { } // Destructor. ~null_fenced_block() { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_NULL_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/null_global.hpp ================================================ // // detail/null_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_GLOBAL_HPP #define ASIO_DETAIL_NULL_GLOBAL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct null_global_impl { null_global_impl() : ptr_(0) { } // Destructor automatically cleans up the global. ~null_global_impl() { delete ptr_; } static null_global_impl instance_; T* ptr_; }; template null_global_impl null_global_impl::instance_; template T& null_global() { if (null_global_impl::instance_.ptr_ == 0) null_global_impl::instance_.ptr_ = new T; return *null_global_impl::instance_.ptr_; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_NULL_GLOBAL_HPP ================================================ FILE: src/third_party/asio/detail/null_mutex.hpp ================================================ // // detail/null_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_MUTEX_HPP #define ASIO_DETAIL_NULL_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class null_mutex : private noncopyable { public: typedef asio::detail::scoped_lock scoped_lock; // Constructor. null_mutex() { } // Destructor. ~null_mutex() { } // Lock the mutex. void lock() { } // Unlock the mutex. void unlock() { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_THREADS) #endif // ASIO_DETAIL_NULL_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/null_reactor.hpp ================================================ // // detail/null_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_REACTOR_HPP #define ASIO_DETAIL_NULL_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/scheduler_operation.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class null_reactor : public execution_context_service_base { public: // Constructor. null_reactor(asio::execution_context& ctx) : execution_context_service_base(ctx) { } // Destructor. ~null_reactor() { } // Destroy all user-defined handler objects owned by the service. void shutdown() { } // No-op because should never be called. void run(long /*usec*/, op_queue& /*ops*/) { } // No-op. void interrupt() { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_NULL_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/null_signal_blocker.hpp ================================================ // // detail/null_signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP #define ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) \ || defined(ASIO_WINDOWS) \ || defined(ASIO_WINDOWS_RUNTIME) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class null_signal_blocker : private noncopyable { public: // Constructor blocks all signals for the calling thread. null_signal_blocker() { } // Destructor restores the previous signal mask. ~null_signal_blocker() { } // Block all signals for the calling thread. void block() { } // Restore the previous signal mask. void unblock() { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_THREADS) // || defined(ASIO_WINDOWS) // || defined(ASIO_WINDOWS_RUNTIME) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) #endif // ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP ================================================ FILE: src/third_party/asio/detail/null_socket_service.hpp ================================================ // // detail/null_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP #define ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/buffer.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/post.hpp" #include "asio/socket_base.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class null_socket_service : public execution_context_service_base > { public: // The protocol type. typedef Protocol protocol_type; // The endpoint type. typedef typename Protocol::endpoint endpoint_type; // The native type of a socket. typedef int native_handle_type; // The implementation type of the socket. struct implementation_type { }; // Constructor. null_socket_service(execution_context& context) : execution_context_service_base >(context) { } // Destroy all user-defined handler objects owned by the service. void shutdown() { } // Construct a new socket implementation. void construct(implementation_type&) { } // Move-construct a new socket implementation. void move_construct(implementation_type&, implementation_type&) { } // Move-assign from another socket implementation. void move_assign(implementation_type&, null_socket_service&, implementation_type&) { } // Move-construct a new socket implementation from another protocol type. template void converting_move_construct(implementation_type&, null_socket_service&, typename null_socket_service::implementation_type&) { } // Destroy a socket implementation. void destroy(implementation_type&) { } // Open a new socket implementation. asio::error_code open(implementation_type&, const protocol_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Assign a native socket to a socket implementation. asio::error_code assign(implementation_type&, const protocol_type&, const native_handle_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Determine whether the socket is open. bool is_open(const implementation_type&) const { return false; } // Destroy a socket implementation. asio::error_code close(implementation_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Release ownership of the socket. native_handle_type release(implementation_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Get the native socket representation. native_handle_type native_handle(implementation_type&) { return 0; } // Cancel all operations associated with the socket. asio::error_code cancel(implementation_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Determine whether the socket is at the out-of-band data mark. bool at_mark(const implementation_type&, asio::error_code& ec) const { ec = asio::error::operation_not_supported; return false; } // Determine the number of bytes available for reading. std::size_t available(const implementation_type&, asio::error_code& ec) const { ec = asio::error::operation_not_supported; return 0; } // Place the socket into the state where it will listen for new connections. asio::error_code listen(implementation_type&, int, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Perform an IO control command on the socket. template asio::error_code io_control(implementation_type&, IO_Control_Command&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Gets the non-blocking mode of the socket. bool non_blocking(const implementation_type&) const { return false; } // Sets the non-blocking mode of the socket. asio::error_code non_blocking(implementation_type&, bool, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Gets the non-blocking mode of the native socket implementation. bool native_non_blocking(const implementation_type&) const { return false; } // Sets the non-blocking mode of the native socket implementation. asio::error_code native_non_blocking(implementation_type&, bool, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Disable sends or receives on the socket. asio::error_code shutdown(implementation_type&, socket_base::shutdown_type, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Bind the socket to the specified local endpoint. asio::error_code bind(implementation_type&, const endpoint_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Set a socket option. template asio::error_code set_option(implementation_type&, const Option&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Set a socket option. template asio::error_code get_option(const implementation_type&, Option&, asio::error_code& ec) const { ec = asio::error::operation_not_supported; return ec; } // Get the local endpoint. endpoint_type local_endpoint(const implementation_type&, asio::error_code& ec) const { ec = asio::error::operation_not_supported; return endpoint_type(); } // Get the remote endpoint. endpoint_type remote_endpoint(const implementation_type&, asio::error_code& ec) const { ec = asio::error::operation_not_supported; return endpoint_type(); } // Send the given data to the peer. template std::size_t send(implementation_type&, const ConstBufferSequence&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Wait until data can be sent without blocking. std::size_t send(implementation_type&, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_send(implementation_type&, const ConstBufferSequence&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Start an asynchronous wait until data can be sent without blocking. template void async_send(implementation_type&, const null_buffers&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Receive some data from the peer. Returns the number of bytes received. template std::size_t receive(implementation_type&, const MutableBufferSequence&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Wait until data can be received without blocking. std::size_t receive(implementation_type&, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Start an asynchronous receive. The buffer for the data being received // must be valid for the lifetime of the asynchronous operation. template void async_receive(implementation_type&, const MutableBufferSequence&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Wait until data can be received without blocking. template void async_receive(implementation_type&, const null_buffers&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Receive some data with associated flags. Returns the number of bytes // received. template std::size_t receive_with_flags(implementation_type&, const MutableBufferSequence&, socket_base::message_flags, socket_base::message_flags&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Wait until data can be received without blocking. std::size_t receive_with_flags(implementation_type&, const null_buffers&, socket_base::message_flags, socket_base::message_flags&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Start an asynchronous receive. The buffer for the data being received // must be valid for the lifetime of the asynchronous operation. template void async_receive_with_flags(implementation_type&, const MutableBufferSequence&, socket_base::message_flags, socket_base::message_flags&, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Wait until data can be received without blocking. template void async_receive_with_flags(implementation_type&, const null_buffers&, socket_base::message_flags, socket_base::message_flags&, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Send a datagram to the specified endpoint. Returns the number of bytes // sent. template std::size_t send_to(implementation_type&, const ConstBufferSequence&, const endpoint_type&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Wait until data can be sent without blocking. std::size_t send_to(implementation_type&, const null_buffers&, const endpoint_type&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_send_to(implementation_type&, const ConstBufferSequence&, const endpoint_type&, socket_base::message_flags, Handler& handler) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Start an asynchronous wait until data can be sent without blocking. template void async_send_to(implementation_type&, const null_buffers&, const endpoint_type&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Receive a datagram with the endpoint of the sender. Returns the number of // bytes received. template std::size_t receive_from(implementation_type&, const MutableBufferSequence&, endpoint_type&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Wait until data can be received without blocking. std::size_t receive_from(implementation_type&, const null_buffers&, endpoint_type&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Start an asynchronous receive. The buffer for the data being received and // the sender_endpoint object must both be valid for the lifetime of the // asynchronous operation. template void async_receive_from(implementation_type&, const MutableBufferSequence&, endpoint_type&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Wait until data can be received without blocking. template void async_receive_from(implementation_type&, const null_buffers&, endpoint_type&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler( handler, ec, bytes_transferred)); } // Accept a new connection. template asio::error_code accept(implementation_type&, Socket&, endpoint_type*, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Start an asynchronous accept. The peer and peer_endpoint objects // must be valid until the accept's handler is invoked. template void async_accept(implementation_type&, Socket&, endpoint_type*, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; asio::post(io_ex, detail::bind_handler(handler, ec)); } // Connect the socket to the specified endpoint. asio::error_code connect(implementation_type&, const endpoint_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Start an asynchronous connect. template void async_connect(implementation_type&, const endpoint_type&, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; asio::post(io_ex, detail::bind_handler(handler, ec)); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_NULL_SOCKET_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/null_static_mutex.hpp ================================================ // // detail/null_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_STATIC_MUTEX_HPP #define ASIO_DETAIL_NULL_STATIC_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct null_static_mutex { typedef asio::detail::scoped_lock scoped_lock; // Initialise the mutex. void init() { } // Lock the mutex. void lock() { } // Unlock the mutex. void unlock() { } int unused_; }; #define ASIO_NULL_STATIC_MUTEX_INIT { 0 } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_THREADS) #endif // ASIO_DETAIL_NULL_STATIC_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/null_thread.hpp ================================================ // // detail/null_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_THREAD_HPP #define ASIO_DETAIL_NULL_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) #include "asio/detail/noncopyable.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class null_thread : private noncopyable { public: // Constructor. template null_thread(Function, unsigned int = 0) { asio::detail::throw_error( asio::error::operation_not_supported, "thread"); } // Destructor. ~null_thread() { } // Wait for the thread to exit. void join() { } // Get number of CPUs. static std::size_t hardware_concurrency() { return 1; } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_THREADS) #endif // ASIO_DETAIL_NULL_THREAD_HPP ================================================ FILE: src/third_party/asio/detail/null_tss_ptr.hpp ================================================ // // detail/null_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_NULL_TSS_PTR_HPP #define ASIO_DETAIL_NULL_TSS_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class null_tss_ptr : private noncopyable { public: // Constructor. null_tss_ptr() : value_(0) { } // Destructor. ~null_tss_ptr() { } // Get the value. operator T*() const { return value_; } // Set the value. void operator=(T* value) { value_ = value; } private: T* value_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_THREADS) #endif // ASIO_DETAIL_NULL_TSS_PTR_HPP ================================================ FILE: src/third_party/asio/detail/object_pool.hpp ================================================ // // detail/object_pool.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_OBJECT_POOL_HPP #define ASIO_DETAIL_OBJECT_POOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class object_pool; class object_pool_access { public: template static Object* create() { return new Object; } template static Object* create(Arg arg) { return new Object(arg); } template static void destroy(Object* o) { delete o; } template static Object*& next(Object* o) { return o->next_; } template static Object*& prev(Object* o) { return o->prev_; } }; template class object_pool : private noncopyable { public: // Constructor. object_pool() : live_list_(0), free_list_(0) { } // Destructor destroys all objects. ~object_pool() { destroy_list(live_list_); destroy_list(free_list_); } // Get the object at the start of the live list. Object* first() { return live_list_; } // Allocate a new object. Object* alloc() { Object* o = free_list_; if (o) free_list_ = object_pool_access::next(free_list_); else o = object_pool_access::create(); object_pool_access::next(o) = live_list_; object_pool_access::prev(o) = 0; if (live_list_) object_pool_access::prev(live_list_) = o; live_list_ = o; return o; } // Allocate a new object with an argument. template Object* alloc(Arg arg) { Object* o = free_list_; if (o) free_list_ = object_pool_access::next(free_list_); else o = object_pool_access::create(arg); object_pool_access::next(o) = live_list_; object_pool_access::prev(o) = 0; if (live_list_) object_pool_access::prev(live_list_) = o; live_list_ = o; return o; } // Free an object. Moves it to the free list. No destructors are run. void free(Object* o) { if (live_list_ == o) live_list_ = object_pool_access::next(o); if (object_pool_access::prev(o)) { object_pool_access::next(object_pool_access::prev(o)) = object_pool_access::next(o); } if (object_pool_access::next(o)) { object_pool_access::prev(object_pool_access::next(o)) = object_pool_access::prev(o); } object_pool_access::next(o) = free_list_; object_pool_access::prev(o) = 0; free_list_ = o; } private: // Helper function to destroy all elements in a list. void destroy_list(Object* list) { while (list) { Object* o = list; list = object_pool_access::next(o); object_pool_access::destroy(o); } } // The list of live objects. Object* live_list_; // The free list. Object* free_list_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_OBJECT_POOL_HPP ================================================ FILE: src/third_party/asio/detail/old_win_sdk_compat.hpp ================================================ // // detail/old_win_sdk_compat.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP #define ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Guess whether we are building against on old Platform SDK. #if !defined(IN6ADDR_ANY_INIT) #define ASIO_HAS_OLD_WIN_SDK 1 #endif // !defined(IN6ADDR_ANY_INIT) #if defined(ASIO_HAS_OLD_WIN_SDK) // Emulation of types that are missing from old Platform SDKs. // // N.B. this emulation is also used if building for a Windows 2000 target with // a recent (i.e. Vista or later) SDK, as the SDK does not provide IPv6 support // in that case. #include "asio/detail/push_options.hpp" namespace asio { namespace detail { enum { sockaddr_storage_maxsize = 128, // Maximum size. sockaddr_storage_alignsize = (sizeof(__int64)), // Desired alignment. sockaddr_storage_pad1size = (sockaddr_storage_alignsize - sizeof(short)), sockaddr_storage_pad2size = (sockaddr_storage_maxsize - (sizeof(short) + sockaddr_storage_pad1size + sockaddr_storage_alignsize)) }; struct sockaddr_storage_emulation { short ss_family; char __ss_pad1[sockaddr_storage_pad1size]; __int64 __ss_align; char __ss_pad2[sockaddr_storage_pad2size]; }; struct in6_addr_emulation { union { u_char Byte[16]; u_short Word[8]; } u; }; #if !defined(s6_addr) # define _S6_un u # define _S6_u8 Byte # define s6_addr _S6_un._S6_u8 #endif // !defined(s6_addr) struct sockaddr_in6_emulation { short sin6_family; u_short sin6_port; u_long sin6_flowinfo; in6_addr_emulation sin6_addr; u_long sin6_scope_id; }; struct ipv6_mreq_emulation { in6_addr_emulation ipv6mr_multiaddr; unsigned int ipv6mr_interface; }; struct addrinfo_emulation { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char* ai_canonname; sockaddr* ai_addr; addrinfo_emulation* ai_next; }; #if !defined(AI_PASSIVE) # define AI_PASSIVE 0x1 #endif #if !defined(AI_CANONNAME) # define AI_CANONNAME 0x2 #endif #if !defined(AI_NUMERICHOST) # define AI_NUMERICHOST 0x4 #endif #if !defined(EAI_AGAIN) # define EAI_AGAIN WSATRY_AGAIN #endif #if !defined(EAI_BADFLAGS) # define EAI_BADFLAGS WSAEINVAL #endif #if !defined(EAI_FAIL) # define EAI_FAIL WSANO_RECOVERY #endif #if !defined(EAI_FAMILY) # define EAI_FAMILY WSAEAFNOSUPPORT #endif #if !defined(EAI_MEMORY) # define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY #endif #if !defined(EAI_NODATA) # define EAI_NODATA WSANO_DATA #endif #if !defined(EAI_NONAME) # define EAI_NONAME WSAHOST_NOT_FOUND #endif #if !defined(EAI_SERVICE) # define EAI_SERVICE WSATYPE_NOT_FOUND #endif #if !defined(EAI_SOCKTYPE) # define EAI_SOCKTYPE WSAESOCKTNOSUPPORT #endif #if !defined(NI_NOFQDN) # define NI_NOFQDN 0x01 #endif #if !defined(NI_NUMERICHOST) # define NI_NUMERICHOST 0x02 #endif #if !defined(NI_NAMEREQD) # define NI_NAMEREQD 0x04 #endif #if !defined(NI_NUMERICSERV) # define NI_NUMERICSERV 0x08 #endif #if !defined(NI_DGRAM) # define NI_DGRAM 0x10 #endif #if !defined(IPPROTO_IPV6) # define IPPROTO_IPV6 41 #endif #if !defined(IPV6_UNICAST_HOPS) # define IPV6_UNICAST_HOPS 4 #endif #if !defined(IPV6_MULTICAST_IF) # define IPV6_MULTICAST_IF 9 #endif #if !defined(IPV6_MULTICAST_HOPS) # define IPV6_MULTICAST_HOPS 10 #endif #if !defined(IPV6_MULTICAST_LOOP) # define IPV6_MULTICAST_LOOP 11 #endif #if !defined(IPV6_JOIN_GROUP) # define IPV6_JOIN_GROUP 12 #endif #if !defined(IPV6_LEAVE_GROUP) # define IPV6_LEAVE_GROUP 13 #endif } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_OLD_WIN_SDK) // Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY. #if !defined(IPV6_V6ONLY) # define IPV6_V6ONLY 27 #endif // Some SDKs (e.g. Windows CE) don't define IPPROTO_ICMPV6. #if !defined(IPPROTO_ICMPV6) # define IPPROTO_ICMPV6 58 #endif #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #endif // ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP ================================================ FILE: src/third_party/asio/detail/op_queue.hpp ================================================ // // detail/op_queue.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_OP_QUEUE_HPP #define ASIO_DETAIL_OP_QUEUE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class op_queue; class op_queue_access { public: template static Operation* next(Operation* o) { return static_cast(o->next_); } template static void next(Operation1*& o1, Operation2* o2) { o1->next_ = o2; } template static void destroy(Operation* o) { o->destroy(); } template static Operation*& front(op_queue& q) { return q.front_; } template static Operation*& back(op_queue& q) { return q.back_; } }; template class op_queue : private noncopyable { public: // Constructor. op_queue() : front_(0), back_(0) { } // Destructor destroys all operations. ~op_queue() { while (Operation* op = front_) { pop(); op_queue_access::destroy(op); } } // Get the operation at the front of the queue. Operation* front() { return front_; } // Pop an operation from the front of the queue. void pop() { if (front_) { Operation* tmp = front_; front_ = op_queue_access::next(front_); if (front_ == 0) back_ = 0; op_queue_access::next(tmp, static_cast(0)); } } // Push an operation on to the back of the queue. void push(Operation* h) { op_queue_access::next(h, static_cast(0)); if (back_) { op_queue_access::next(back_, h); back_ = h; } else { front_ = back_ = h; } } // Push all operations from another queue on to the back of the queue. The // source queue may contain operations of a derived type. template void push(op_queue& q) { if (Operation* other_front = op_queue_access::front(q)) { if (back_) op_queue_access::next(back_, other_front); else front_ = other_front; back_ = op_queue_access::back(q); op_queue_access::front(q) = 0; op_queue_access::back(q) = 0; } } // Whether the queue is empty. bool empty() const { return front_ == 0; } // Test whether an operation is already enqueued. bool is_enqueued(Operation* o) const { return op_queue_access::next(o) != 0 || back_ == o; } private: friend class op_queue_access; // The front of the queue. Operation* front_; // The back of the queue. Operation* back_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_OP_QUEUE_HPP ================================================ FILE: src/third_party/asio/detail/operation.hpp ================================================ // // detail/operation.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_OPERATION_HPP #define ASIO_DETAIL_OPERATION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_operation.hpp" #else # include "asio/detail/scheduler_operation.hpp" #endif namespace asio { namespace detail { #if defined(ASIO_HAS_IOCP) typedef win_iocp_operation operation; #else typedef scheduler_operation operation; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_OPERATION_HPP ================================================ FILE: src/third_party/asio/detail/pipe_select_interrupter.hpp ================================================ // // detail/pipe_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP #define ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) #if !defined(ASIO_WINDOWS_RUNTIME) #if !defined(__CYGWIN__) #if !defined(__SYMBIAN32__) #if !defined(ASIO_HAS_EVENTFD) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class pipe_select_interrupter { public: // Constructor. ASIO_DECL pipe_select_interrupter(); // Destructor. ASIO_DECL ~pipe_select_interrupter(); // Recreate the interrupter's descriptors. Used after a fork. ASIO_DECL void recreate(); // Interrupt the select call. ASIO_DECL void interrupt(); // Reset the select interrupt. Returns true if the call was interrupted. ASIO_DECL bool reset(); // Get the read descriptor to be passed to select. int read_descriptor() const { return read_descriptor_; } private: // Open the descriptors. Throws on error. ASIO_DECL void open_descriptors(); // Close the descriptors. ASIO_DECL void close_descriptors(); // The read end of a connection used to interrupt the select call. This file // descriptor is passed to select such that when it is time to stop, a single // byte will be written on the other end of the connection and this // descriptor will become readable. int read_descriptor_; // The write end of a connection used to interrupt the select call. A single // byte may be written to this to wake up the select which is waiting for the // other end to become readable. int write_descriptor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/pipe_select_interrupter.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // !defined(ASIO_HAS_EVENTFD) #endif // !defined(__SYMBIAN32__) #endif // !defined(__CYGWIN__) #endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // !defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP ================================================ FILE: src/third_party/asio/detail/pop_options.hpp ================================================ // // detail/pop_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // No header guard #if defined(__COMO__) // Comeau C++ #elif defined(__DMC__) // Digital Mars C++ #elif defined(__INTEL_COMPILER) || defined(__ICL) \ || defined(__ICC) || defined(__ECC) // Intel C++ # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # if !defined(ASIO_DISABLE_VISIBILITY) # pragma GCC visibility pop # endif // !defined(ASIO_DISABLE_VISIBILITY) # endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) #elif defined(__clang__) // Clang # if defined(__OBJC__) # if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) # if defined(ASIO_OBJC_WORKAROUND) # undef Protocol # undef id # undef ASIO_OBJC_WORKAROUND # endif # endif # endif # if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) # if !defined(ASIO_DISABLE_VISIBILITY) # pragma GCC visibility pop # endif // !defined(ASIO_DISABLE_VISIBILITY) # endif // !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) #elif defined(__GNUC__) // GNU C++ # if defined(__MINGW32__) || defined(__CYGWIN__) # pragma pack (pop) # endif # if defined(__OBJC__) # if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) # if defined(ASIO_OBJC_WORKAROUND) # undef Protocol # undef id # undef ASIO_OBJC_WORKAROUND # endif # endif # endif # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # if !defined(ASIO_DISABLE_VISIBILITY) # pragma GCC visibility pop # endif // !defined(ASIO_DISABLE_VISIBILITY) # endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # if (__GNUC__ >= 7) # pragma GCC diagnostic pop # endif // (__GNUC__ >= 7) #elif defined(__KCC) // Kai C++ #elif defined(__sgi) // SGI MIPSpro C++ #elif defined(__DECCXX) // Compaq Tru64 Unix cxx #elif defined(__ghs) // Greenhills C++ #elif defined(__BORLANDC__) // Borland C++ # pragma option pop # pragma nopushoptwarn # pragma nopackwarning #elif defined(__MWERKS__) // Metrowerks CodeWarrior #elif defined(__SUNPRO_CC) // Sun Workshop Compiler C++ #elif defined(__HP_aCC) // HP aCC #elif defined(__MRC__) || defined(__SC__) // MPW MrCpp or SCpp #elif defined(__IBMCPP__) // IBM Visual Age #elif defined(_MSC_VER) // Microsoft Visual C++ // // Must remain the last #elif since some other vendors (Metrowerks, for example) // also #define _MSC_VER # pragma warning (pop) # pragma pack (pop) # if defined(__cplusplus_cli) || defined(__cplusplus_winrt) # if defined(ASIO_CLR_WORKAROUND) # undef generic # undef ASIO_CLR_WORKAROUND # endif # endif #endif ================================================ FILE: src/third_party/asio/detail/posix_event.hpp ================================================ // // detail/posix_event.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_EVENT_HPP #define ASIO_DETAIL_POSIX_EVENT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include #include "asio/detail/assert.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class posix_event : private noncopyable { public: // Constructor. ASIO_DECL posix_event(); // Destructor. ~posix_event() { ::pthread_cond_destroy(&cond_); } // Signal the event. (Retained for backward compatibility.) template void signal(Lock& lock) { this->signal_all(lock); } // Signal all waiters. template void signal_all(Lock& lock) { ASIO_ASSERT(lock.locked()); (void)lock; state_ |= 1; ::pthread_cond_broadcast(&cond_); // Ignore EINVAL. } // Unlock the mutex and signal one waiter. template void unlock_and_signal_one(Lock& lock) { ASIO_ASSERT(lock.locked()); state_ |= 1; bool have_waiters = (state_ > 1); lock.unlock(); if (have_waiters) ::pthread_cond_signal(&cond_); // Ignore EINVAL. } // If there's a waiter, unlock the mutex and signal it. template bool maybe_unlock_and_signal_one(Lock& lock) { ASIO_ASSERT(lock.locked()); state_ |= 1; if (state_ > 1) { lock.unlock(); ::pthread_cond_signal(&cond_); // Ignore EINVAL. return true; } return false; } // Reset the event. template void clear(Lock& lock) { ASIO_ASSERT(lock.locked()); (void)lock; state_ &= ~std::size_t(1); } // Wait for the event to become signalled. template void wait(Lock& lock) { ASIO_ASSERT(lock.locked()); while ((state_ & 1) == 0) { state_ += 2; ::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL. state_ -= 2; } } // Timed wait for the event to become signalled. template bool wait_for_usec(Lock& lock, long usec) { ASIO_ASSERT(lock.locked()); if ((state_ & 1) == 0) { state_ += 2; timespec ts; #if (defined(__MACH__) && defined(__APPLE__)) \ || (defined(__ANDROID__) && (__ANDROID_API__ < 21) \ && defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)) ts.tv_sec = usec / 1000000; ts.tv_nsec = (usec % 1000000) * 1000; ::pthread_cond_timedwait_relative_np( &cond_, &lock.mutex().mutex_, &ts); // Ignore EINVAL. #else // (defined(__MACH__) && defined(__APPLE__)) // || (defined(__ANDROID__) && (__ANDROID_API__ < 21) // && defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)) if (::clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { ts.tv_sec += usec / 1000000; ts.tv_nsec += (usec % 1000000) * 1000; ts.tv_sec += ts.tv_nsec / 1000000000; ts.tv_nsec = ts.tv_nsec % 1000000000; ::pthread_cond_timedwait(&cond_, &lock.mutex().mutex_, &ts); // Ignore EINVAL. } #endif // (defined(__MACH__) && defined(__APPLE__)) // || (defined(__ANDROID__) && (__ANDROID_API__ < 21) // && defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)) state_ -= 2; } return (state_ & 1) != 0; } private: ::pthread_cond_t cond_; std::size_t state_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/posix_event.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_POSIX_EVENT_HPP ================================================ FILE: src/third_party/asio/detail/posix_fd_set_adapter.hpp ================================================ // // detail/posix_fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP #define ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) \ && !defined(__CYGWIN__) \ && !defined(ASIO_WINDOWS_RUNTIME) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/reactor_op_queue.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. class posix_fd_set_adapter : noncopyable { public: posix_fd_set_adapter() : max_descriptor_(invalid_socket) { using namespace std; // Needed for memset on Solaris. FD_ZERO(&fd_set_); } void reset() { using namespace std; // Needed for memset on Solaris. FD_ZERO(&fd_set_); } bool set(socket_type descriptor) { if (descriptor < (socket_type)FD_SETSIZE) { if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_) max_descriptor_ = descriptor; FD_SET(descriptor, &fd_set_); return true; } return false; } void set(reactor_op_queue& operations, op_queue& ops) { reactor_op_queue::iterator i = operations.begin(); while (i != operations.end()) { reactor_op_queue::iterator op_iter = i++; if (!set(op_iter->first)) { asio::error_code ec(error::fd_set_failure); operations.cancel_operations(op_iter, ops, ec); } } } bool is_set(socket_type descriptor) const { return FD_ISSET(descriptor, &fd_set_) != 0; } operator fd_set*() { return &fd_set_; } socket_type max_descriptor() const { return max_descriptor_; } void perform(reactor_op_queue& operations, op_queue& ops) const { reactor_op_queue::iterator i = operations.begin(); while (i != operations.end()) { reactor_op_queue::iterator op_iter = i++; if (is_set(op_iter->first)) operations.perform_operations(op_iter, ops); } } private: mutable fd_set fd_set_; socket_type max_descriptor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS) // && !defined(__CYGWIN__) // && !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP ================================================ FILE: src/third_party/asio/detail/posix_global.hpp ================================================ // // detail/posix_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_GLOBAL_HPP #define ASIO_DETAIL_POSIX_GLOBAL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include #include #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct posix_global_impl { // Helper function to perform initialisation. static void do_init() { instance_.static_ptr_ = instance_.ptr_ = new T; } // Destructor automatically cleans up the global. ~posix_global_impl() { delete static_ptr_; } static ::pthread_once_t init_once_; static T* static_ptr_; static posix_global_impl instance_; T* ptr_; }; template ::pthread_once_t posix_global_impl::init_once_ = PTHREAD_ONCE_INIT; template T* posix_global_impl::static_ptr_ = 0; template posix_global_impl posix_global_impl::instance_; template T& posix_global() { int result = ::pthread_once( &posix_global_impl::init_once_, &posix_global_impl::do_init); if (result != 0) std::terminate(); return *posix_global_impl::instance_.ptr_; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_POSIX_GLOBAL_HPP ================================================ FILE: src/third_party/asio/detail/posix_mutex.hpp ================================================ // // detail/posix_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_MUTEX_HPP #define ASIO_DETAIL_POSIX_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class posix_event; class posix_mutex : private noncopyable { public: typedef asio::detail::scoped_lock scoped_lock; // Constructor. ASIO_DECL posix_mutex(); // Destructor. ~posix_mutex() { ::pthread_mutex_destroy(&mutex_); // Ignore EBUSY. } // Lock the mutex. void lock() { (void)::pthread_mutex_lock(&mutex_); // Ignore EINVAL. } // Unlock the mutex. void unlock() { (void)::pthread_mutex_unlock(&mutex_); // Ignore EINVAL. } private: friend class posix_event; ::pthread_mutex_t mutex_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/posix_mutex.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_POSIX_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/posix_signal_blocker.hpp ================================================ // // detail/posix_signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP #define ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include #include #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class posix_signal_blocker : private noncopyable { public: // Constructor blocks all signals for the calling thread. posix_signal_blocker() : blocked_(false) { sigset_t new_mask; sigfillset(&new_mask); blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); } // Destructor restores the previous signal mask. ~posix_signal_blocker() { if (blocked_) pthread_sigmask(SIG_SETMASK, &old_mask_, 0); } // Block all signals for the calling thread. void block() { if (!blocked_) { sigset_t new_mask; sigfillset(&new_mask); blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); } } // Restore the previous signal mask. void unblock() { if (blocked_) blocked_ = (pthread_sigmask(SIG_SETMASK, &old_mask_, 0) != 0); } private: // Have signals been blocked. bool blocked_; // The previous signal mask. sigset_t old_mask_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP ================================================ FILE: src/third_party/asio/detail/posix_static_mutex.hpp ================================================ // // detail/posix_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_STATIC_MUTEX_HPP #define ASIO_DETAIL_POSIX_STATIC_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct posix_static_mutex { typedef asio::detail::scoped_lock scoped_lock; // Initialise the mutex. void init() { // Nothing to do. } // Lock the mutex. void lock() { (void)::pthread_mutex_lock(&mutex_); // Ignore EINVAL. } // Unlock the mutex. void unlock() { (void)::pthread_mutex_unlock(&mutex_); // Ignore EINVAL. } ::pthread_mutex_t mutex_; }; #define ASIO_POSIX_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_POSIX_STATIC_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/posix_thread.hpp ================================================ // // detail/posix_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_THREAD_HPP #define ASIO_DETAIL_POSIX_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { extern "C" { ASIO_DECL void* asio_detail_posix_thread_function(void* arg); } class posix_thread : private noncopyable { public: // Constructor. template posix_thread(Function f, unsigned int = 0) : joined_(false) { start_thread(new func(f)); } // Destructor. ASIO_DECL ~posix_thread(); // Wait for the thread to exit. ASIO_DECL void join(); // Get number of CPUs. ASIO_DECL static std::size_t hardware_concurrency(); private: friend void* asio_detail_posix_thread_function(void* arg); class func_base { public: virtual ~func_base() {} virtual void run() = 0; }; struct auto_func_base_ptr { func_base* ptr; ~auto_func_base_ptr() { delete ptr; } }; template class func : public func_base { public: func(Function f) : f_(f) { } virtual void run() { f_(); } private: Function f_; }; ASIO_DECL void start_thread(func_base* arg); ::pthread_t thread_; bool joined_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/posix_thread.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_POSIX_THREAD_HPP ================================================ FILE: src/third_party/asio/detail/posix_tss_ptr.hpp ================================================ // // detail/posix_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_POSIX_TSS_PTR_HPP #define ASIO_DETAIL_POSIX_TSS_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_PTHREADS) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Helper function to create thread-specific storage. ASIO_DECL void posix_tss_ptr_create(pthread_key_t& key); template class posix_tss_ptr : private noncopyable { public: // Constructor. posix_tss_ptr() { posix_tss_ptr_create(tss_key_); } // Destructor. ~posix_tss_ptr() { ::pthread_key_delete(tss_key_); } // Get the value. operator T*() const { return static_cast(::pthread_getspecific(tss_key_)); } // Set the value. void operator=(T* value) { ::pthread_setspecific(tss_key_, value); } private: // Thread-specific storage to allow unlocked access to determine whether a // thread is a member of the pool. pthread_key_t tss_key_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/posix_tss_ptr.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_PTHREADS) #endif // ASIO_DETAIL_POSIX_TSS_PTR_HPP ================================================ FILE: src/third_party/asio/detail/push_options.hpp ================================================ // // detail/push_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // No header guard #if defined(__COMO__) // Comeau C++ #elif defined(__DMC__) // Digital Mars C++ #elif defined(__INTEL_COMPILER) || defined(__ICL) \ || defined(__ICC) || defined(__ECC) // Intel C++ # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # if !defined(ASIO_DISABLE_VISIBILITY) # pragma GCC visibility push (default) # endif // !defined(ASIO_DISABLE_VISIBILITY) # endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) #elif defined(__clang__) // Clang # if defined(__OBJC__) # if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) # if !defined(ASIO_DISABLE_OBJC_WORKAROUND) # if !defined(Protocol) && !defined(id) # define Protocol cpp_Protocol # define id cpp_id # define ASIO_OBJC_WORKAROUND # endif # endif # endif # endif # if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) # if !defined(ASIO_DISABLE_VISIBILITY) # pragma GCC visibility push (default) # endif // !defined(ASIO_DISABLE_VISIBILITY) # endif // !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) #elif defined(__GNUC__) // GNU C++ # if defined(__MINGW32__) || defined(__CYGWIN__) # pragma pack (push, 8) # endif # if defined(__OBJC__) # if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) # if !defined(ASIO_DISABLE_OBJC_WORKAROUND) # if !defined(Protocol) && !defined(id) # define Protocol cpp_Protocol # define id cpp_id # define ASIO_OBJC_WORKAROUND # endif # endif # endif # endif # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # if !defined(ASIO_DISABLE_VISIBILITY) # pragma GCC visibility push (default) # endif // !defined(ASIO_DISABLE_VISIBILITY) # endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # if (__GNUC__ >= 7) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wimplicit-fallthrough" # endif // (__GNUC__ >= 7) #elif defined(__KCC) // Kai C++ #elif defined(__sgi) // SGI MIPSpro C++ #elif defined(__DECCXX) // Compaq Tru64 Unix cxx #elif defined(__ghs) // Greenhills C++ #elif defined(__BORLANDC__) // Borland C++ # pragma option push -a8 -b -Ve- -Vx- -w-inl -vi- # pragma nopushoptwarn # pragma nopackwarning # if !defined(__MT__) # error Multithreaded RTL must be selected. # endif // !defined(__MT__) #elif defined(__MWERKS__) // Metrowerks CodeWarrior #elif defined(__SUNPRO_CC) // Sun Workshop Compiler C++ #elif defined(__HP_aCC) // HP aCC #elif defined(__MRC__) || defined(__SC__) // MPW MrCpp or SCpp #elif defined(__IBMCPP__) // IBM Visual Age #elif defined(_MSC_VER) // Microsoft Visual C++ // // Must remain the last #elif since some other vendors (Metrowerks, for example) // also #define _MSC_VER # pragma warning (disable:4103) # pragma warning (push) # pragma warning (disable:4127) # pragma warning (disable:4180) # pragma warning (disable:4244) # pragma warning (disable:4355) # pragma warning (disable:4510) # pragma warning (disable:4512) # pragma warning (disable:4610) # pragma warning (disable:4675) # if (_MSC_VER < 1600) // Visual Studio 2008 generates spurious warnings about unused parameters. # pragma warning (disable:4100) # endif // (_MSC_VER < 1600) # if defined(_M_IX86) && defined(_Wp64) // The /Wp64 option is broken. If you want to check 64 bit portability, use a // 64 bit compiler! # pragma warning (disable:4311) # pragma warning (disable:4312) # endif // defined(_M_IX86) && defined(_Wp64) # pragma pack (push, 8) // Note that if the /Og optimisation flag is enabled with MSVC6, the compiler // has a tendency to incorrectly optimise away some calls to member template // functions, even though those functions contain code that should not be // optimised away! Therefore we will always disable this optimisation option // for the MSVC6 compiler. # if (_MSC_VER < 1300) # pragma optimize ("g", off) # endif # if !defined(_MT) # error Multithreaded RTL must be selected. # endif // !defined(_MT) # if defined(__cplusplus_cli) || defined(__cplusplus_winrt) # if !defined(ASIO_DISABLE_CLR_WORKAROUND) # if !defined(generic) # define generic cpp_generic # define ASIO_CLR_WORKAROUND # endif # endif # endif #endif ================================================ FILE: src/third_party/asio/detail/reactive_descriptor_service.hpp ================================================ // // detail/reactive_descriptor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP #define ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) #include "asio/buffer.hpp" #include "asio/execution_context.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/descriptor_ops.hpp" #include "asio/detail/descriptor_read_op.hpp" #include "asio/detail/descriptor_write_op.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/reactive_null_buffers_op.hpp" #include "asio/detail/reactive_wait_op.hpp" #include "asio/detail/reactor.hpp" #include "asio/posix/descriptor_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class reactive_descriptor_service : public execution_context_service_base { public: // The native type of a descriptor. typedef int native_handle_type; // The implementation type of the descriptor. class implementation_type : private asio::detail::noncopyable { public: // Default constructor. implementation_type() : descriptor_(-1), state_(0) { } private: // Only this service will have access to the internal values. friend class reactive_descriptor_service; // The native descriptor representation. int descriptor_; // The current state of the descriptor. descriptor_ops::state_type state_; // Per-descriptor data used by the reactor. reactor::per_descriptor_data reactor_data_; }; // Constructor. ASIO_DECL reactive_descriptor_service(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Construct a new descriptor implementation. ASIO_DECL void construct(implementation_type& impl); // Move-construct a new descriptor implementation. ASIO_DECL void move_construct(implementation_type& impl, implementation_type& other_impl); // Move-assign from another descriptor implementation. ASIO_DECL void move_assign(implementation_type& impl, reactive_descriptor_service& other_service, implementation_type& other_impl); // Destroy a descriptor implementation. ASIO_DECL void destroy(implementation_type& impl); // Assign a native descriptor to a descriptor implementation. ASIO_DECL asio::error_code assign(implementation_type& impl, const native_handle_type& native_descriptor, asio::error_code& ec); // Determine whether the descriptor is open. bool is_open(const implementation_type& impl) const { return impl.descriptor_ != -1; } // Destroy a descriptor implementation. ASIO_DECL asio::error_code close(implementation_type& impl, asio::error_code& ec); // Get the native descriptor representation. native_handle_type native_handle(const implementation_type& impl) const { return impl.descriptor_; } // Release ownership of the native descriptor representation. ASIO_DECL native_handle_type release(implementation_type& impl); // Cancel all operations associated with the descriptor. ASIO_DECL asio::error_code cancel(implementation_type& impl, asio::error_code& ec); // Perform an IO control command on the descriptor. template asio::error_code io_control(implementation_type& impl, IO_Control_Command& command, asio::error_code& ec) { descriptor_ops::ioctl(impl.descriptor_, impl.state_, command.name(), static_cast(command.data()), ec); return ec; } // Gets the non-blocking mode of the descriptor. bool non_blocking(const implementation_type& impl) const { return (impl.state_ & descriptor_ops::user_set_non_blocking) != 0; } // Sets the non-blocking mode of the descriptor. asio::error_code non_blocking(implementation_type& impl, bool mode, asio::error_code& ec) { descriptor_ops::set_user_non_blocking( impl.descriptor_, impl.state_, mode, ec); return ec; } // Gets the non-blocking mode of the native descriptor implementation. bool native_non_blocking(const implementation_type& impl) const { return (impl.state_ & descriptor_ops::internal_non_blocking) != 0; } // Sets the non-blocking mode of the native descriptor implementation. asio::error_code native_non_blocking(implementation_type& impl, bool mode, asio::error_code& ec) { descriptor_ops::set_internal_non_blocking( impl.descriptor_, impl.state_, mode, ec); return ec; } // Wait for the descriptor to become ready to read, ready to write, or to have // pending error conditions. asio::error_code wait(implementation_type& impl, posix::descriptor_base::wait_type w, asio::error_code& ec) { switch (w) { case posix::descriptor_base::wait_read: descriptor_ops::poll_read(impl.descriptor_, impl.state_, ec); break; case posix::descriptor_base::wait_write: descriptor_ops::poll_write(impl.descriptor_, impl.state_, ec); break; case posix::descriptor_base::wait_error: descriptor_ops::poll_error(impl.descriptor_, impl.state_, ec); break; default: ec = asio::error::invalid_argument; break; } return ec; } // Asynchronously wait for the descriptor to become ready to read, ready to // write, or to have pending error conditions. template void async_wait(implementation_type& impl, posix::descriptor_base::wait_type w, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_wait_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", &impl, impl.descriptor_, "async_wait")); int op_type; switch (w) { case posix::descriptor_base::wait_read: op_type = reactor::read_op; break; case posix::descriptor_base::wait_write: op_type = reactor::write_op; break; case posix::descriptor_base::wait_error: op_type = reactor::except_op; break; default: p.p->ec_ = asio::error::invalid_argument; reactor_.post_immediate_completion(p.p, is_continuation); p.v = p.p = 0; return; } start_op(impl, op_type, p.p, is_continuation, false, false); p.v = p.p = 0; } // Write some data to the descriptor. template size_t write_some(implementation_type& impl, const ConstBufferSequence& buffers, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return descriptor_ops::sync_write(impl.descriptor_, impl.state_, bufs.buffers(), bufs.count(), bufs.all_empty(), ec); } // Wait until data can be written without blocking. size_t write_some(implementation_type& impl, const null_buffers&, asio::error_code& ec) { // Wait for descriptor to become ready. descriptor_ops::poll_write(impl.descriptor_, impl.state_, ec); return 0; } // Start an asynchronous write. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_write_some(implementation_type& impl, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef descriptor_write_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.descriptor_, buffers, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", &impl, impl.descriptor_, "async_write_some")); start_op(impl, reactor::write_op, p.p, is_continuation, true, buffer_sequence_adapter::all_empty(buffers)); p.v = p.p = 0; } // Start an asynchronous wait until data can be written without blocking. template void async_write_some(implementation_type& impl, const null_buffers&, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", &impl, impl.descriptor_, "async_write_some(null_buffers)")); start_op(impl, reactor::write_op, p.p, is_continuation, false, false); p.v = p.p = 0; } // Read some data from the stream. Returns the number of bytes read. template size_t read_some(implementation_type& impl, const MutableBufferSequence& buffers, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return descriptor_ops::sync_read(impl.descriptor_, impl.state_, bufs.buffers(), bufs.count(), bufs.all_empty(), ec); } // Wait until data can be read without blocking. size_t read_some(implementation_type& impl, const null_buffers&, asio::error_code& ec) { // Wait for descriptor to become ready. descriptor_ops::poll_read(impl.descriptor_, impl.state_, ec); return 0; } // Start an asynchronous read. The buffer for the data being read must be // valid for the lifetime of the asynchronous operation. template void async_read_some(implementation_type& impl, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef descriptor_read_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.descriptor_, buffers, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", &impl, impl.descriptor_, "async_read_some")); start_op(impl, reactor::read_op, p.p, is_continuation, true, buffer_sequence_adapter::all_empty(buffers)); p.v = p.p = 0; } // Wait until data can be read without blocking. template void async_read_some(implementation_type& impl, const null_buffers&, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor", &impl, impl.descriptor_, "async_read_some(null_buffers)")); start_op(impl, reactor::read_op, p.p, is_continuation, false, false); p.v = p.p = 0; } private: // Start the asynchronous operation. ASIO_DECL void start_op(implementation_type& impl, int op_type, reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); // The selector that performs event demultiplexing for the service. reactor& reactor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/reactive_descriptor_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) #endif // ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/reactive_null_buffers_op.hpp ================================================ // // detail/reactive_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP #define ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_null_buffers_op : public reactor_op { public: ASIO_DEFINE_HANDLER_PTR(reactive_null_buffers_op); reactive_null_buffers_op(Handler& handler, const IoExecutor& io_ex) : reactor_op(&reactive_null_buffers_op::do_perform, &reactive_null_buffers_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static status do_perform(reactor_op*) { return done; } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_null_buffers_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_serial_port_service.hpp ================================================ // // detail/reactive_serial_port_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP #define ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_SERIAL_PORT) #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #include #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/serial_port_base.hpp" #include "asio/detail/descriptor_ops.hpp" #include "asio/detail/reactive_descriptor_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Extend reactive_descriptor_service to provide serial port support. class reactive_serial_port_service : public execution_context_service_base { public: // The native type of a serial port. typedef reactive_descriptor_service::native_handle_type native_handle_type; // The implementation type of the serial port. typedef reactive_descriptor_service::implementation_type implementation_type; ASIO_DECL reactive_serial_port_service(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Construct a new serial port implementation. void construct(implementation_type& impl) { descriptor_service_.construct(impl); } // Move-construct a new serial port implementation. void move_construct(implementation_type& impl, implementation_type& other_impl) { descriptor_service_.move_construct(impl, other_impl); } // Move-assign from another serial port implementation. void move_assign(implementation_type& impl, reactive_serial_port_service& other_service, implementation_type& other_impl) { descriptor_service_.move_assign(impl, other_service.descriptor_service_, other_impl); } // Destroy a serial port implementation. void destroy(implementation_type& impl) { descriptor_service_.destroy(impl); } // Open the serial port using the specified device name. ASIO_DECL asio::error_code open(implementation_type& impl, const std::string& device, asio::error_code& ec); // Assign a native descriptor to a serial port implementation. asio::error_code assign(implementation_type& impl, const native_handle_type& native_descriptor, asio::error_code& ec) { return descriptor_service_.assign(impl, native_descriptor, ec); } // Determine whether the serial port is open. bool is_open(const implementation_type& impl) const { return descriptor_service_.is_open(impl); } // Destroy a serial port implementation. asio::error_code close(implementation_type& impl, asio::error_code& ec) { return descriptor_service_.close(impl, ec); } // Get the native serial port representation. native_handle_type native_handle(implementation_type& impl) { return descriptor_service_.native_handle(impl); } // Cancel all operations associated with the serial port. asio::error_code cancel(implementation_type& impl, asio::error_code& ec) { return descriptor_service_.cancel(impl, ec); } // Set an option on the serial port. template asio::error_code set_option(implementation_type& impl, const SettableSerialPortOption& option, asio::error_code& ec) { return do_set_option(impl, &reactive_serial_port_service::store_option, &option, ec); } // Get an option from the serial port. template asio::error_code get_option(const implementation_type& impl, GettableSerialPortOption& option, asio::error_code& ec) const { return do_get_option(impl, &reactive_serial_port_service::load_option, &option, ec); } // Send a break sequence to the serial port. asio::error_code send_break(implementation_type& impl, asio::error_code& ec) { errno = 0; descriptor_ops::error_wrapper(::tcsendbreak( descriptor_service_.native_handle(impl), 0), ec); return ec; } // Write the given data. Returns the number of bytes sent. template size_t write_some(implementation_type& impl, const ConstBufferSequence& buffers, asio::error_code& ec) { return descriptor_service_.write_some(impl, buffers, ec); } // Start an asynchronous write. The data being written must be valid for the // lifetime of the asynchronous operation. template void async_write_some(implementation_type& impl, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { descriptor_service_.async_write_some(impl, buffers, handler, io_ex); } // Read some data. Returns the number of bytes received. template size_t read_some(implementation_type& impl, const MutableBufferSequence& buffers, asio::error_code& ec) { return descriptor_service_.read_some(impl, buffers, ec); } // Start an asynchronous read. The buffer for the data being received must be // valid for the lifetime of the asynchronous operation. template void async_read_some(implementation_type& impl, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { descriptor_service_.async_read_some(impl, buffers, handler, io_ex); } private: // Function pointer type for storing a serial port option. typedef asio::error_code (*store_function_type)( const void*, termios&, asio::error_code&); // Helper function template to store a serial port option. template static asio::error_code store_option(const void* option, termios& storage, asio::error_code& ec) { static_cast(option)->store(storage, ec); return ec; } // Helper function to set a serial port option. ASIO_DECL asio::error_code do_set_option( implementation_type& impl, store_function_type store, const void* option, asio::error_code& ec); // Function pointer type for loading a serial port option. typedef asio::error_code (*load_function_type)( void*, const termios&, asio::error_code&); // Helper function template to load a serial port option. template static asio::error_code load_option(void* option, const termios& storage, asio::error_code& ec) { static_cast(option)->load(storage, ec); return ec; } // Helper function to get a serial port option. ASIO_DECL asio::error_code do_get_option( const implementation_type& impl, load_function_type load, void* option, asio::error_code& ec) const; // The implementation used for initiating asynchronous operations. reactive_descriptor_service descriptor_service_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/reactive_serial_port_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #endif // defined(ASIO_HAS_SERIAL_PORT) #endif // ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_accept_op.hpp ================================================ // // detail/reactive_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_holder.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_socket_accept_op_base : public reactor_op { public: reactive_socket_accept_op_base(socket_type socket, socket_ops::state_type state, Socket& peer, const Protocol& protocol, typename Protocol::endpoint* peer_endpoint, func_type complete_func) : reactor_op(&reactive_socket_accept_op_base::do_perform, complete_func), socket_(socket), state_(state), peer_(peer), protocol_(protocol), peer_endpoint_(peer_endpoint), addrlen_(peer_endpoint ? peer_endpoint->capacity() : 0) { } static status do_perform(reactor_op* base) { reactive_socket_accept_op_base* o( static_cast(base)); socket_type new_socket = invalid_socket; status result = socket_ops::non_blocking_accept(o->socket_, o->state_, o->peer_endpoint_ ? o->peer_endpoint_->data() : 0, o->peer_endpoint_ ? &o->addrlen_ : 0, o->ec_, new_socket) ? done : not_done; o->new_socket_.reset(new_socket); ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_accept", o->ec_)); return result; } void do_assign() { if (new_socket_.get() != invalid_socket) { if (peer_endpoint_) peer_endpoint_->resize(addrlen_); peer_.assign(protocol_, new_socket_.get(), ec_); if (!ec_) new_socket_.release(); } } private: socket_type socket_; socket_ops::state_type state_; socket_holder new_socket_; Socket& peer_; Protocol protocol_; typename Protocol::endpoint* peer_endpoint_; std::size_t addrlen_; }; template class reactive_socket_accept_op : public reactive_socket_accept_op_base { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_accept_op); reactive_socket_accept_op(socket_type socket, socket_ops::state_type state, Socket& peer, const Protocol& protocol, typename Protocol::endpoint* peer_endpoint, Handler& handler, const IoExecutor& io_ex) : reactive_socket_accept_op_base(socket, state, peer, protocol, peer_endpoint, &reactive_socket_accept_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_accept_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); // On success, assign new connection to peer socket object. if (owner) o->do_assign(); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(o->handler_, o->ec_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; #if defined(ASIO_HAS_MOVE) template class reactive_socket_move_accept_op : private Protocol::socket::template rebind_executor::other, public reactive_socket_accept_op_base< typename Protocol::socket::template rebind_executor::other, Protocol> { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_move_accept_op); reactive_socket_move_accept_op(const PeerIoExecutor& peer_io_ex, socket_type socket, socket_ops::state_type state, const Protocol& protocol, typename Protocol::endpoint* peer_endpoint, Handler& handler, const IoExecutor& io_ex) : peer_socket_type(peer_io_ex), reactive_socket_accept_op_base( socket, state, *this, protocol, peer_endpoint, &reactive_socket_move_accept_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_move_accept_op* o( static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); // On success, assign new connection to peer socket object. if (owner) o->do_assign(); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::move_binder2 handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_, ASIO_MOVE_CAST(peer_socket_type)(*o)); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: typedef typename Protocol::socket::template rebind_executor::other peer_socket_type; Handler handler_; IoExecutor io_executor_; }; #endif // defined(ASIO_HAS_MOVE) } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_connect_op.hpp ================================================ // // detail/reactive_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class reactive_socket_connect_op_base : public reactor_op { public: reactive_socket_connect_op_base(socket_type socket, func_type complete_func) : reactor_op(&reactive_socket_connect_op_base::do_perform, complete_func), socket_(socket) { } static status do_perform(reactor_op* base) { reactive_socket_connect_op_base* o( static_cast(base)); status result = socket_ops::non_blocking_connect( o->socket_, o->ec_) ? done : not_done; ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_connect", o->ec_)); return result; } private: socket_type socket_; }; template class reactive_socket_connect_op : public reactive_socket_connect_op_base { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_connect_op); reactive_socket_connect_op(socket_type socket, Handler& handler, const IoExecutor& io_ex) : reactive_socket_connect_op_base(socket, &reactive_socket_connect_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_connect_op* o (static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(o->handler_, o->ec_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_recv_op.hpp ================================================ // // detail/reactive_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_socket_recv_op_base : public reactor_op { public: reactive_socket_recv_op_base(socket_type socket, socket_ops::state_type state, const MutableBufferSequence& buffers, socket_base::message_flags flags, func_type complete_func) : reactor_op(&reactive_socket_recv_op_base::do_perform, complete_func), socket_(socket), state_(state), buffers_(buffers), flags_(flags) { } static status do_perform(reactor_op* base) { reactive_socket_recv_op_base* o( static_cast(base)); buffer_sequence_adapter bufs(o->buffers_); status result = socket_ops::non_blocking_recv(o->socket_, bufs.buffers(), bufs.count(), o->flags_, (o->state_ & socket_ops::stream_oriented) != 0, o->ec_, o->bytes_transferred_) ? done : not_done; if (result == done) if ((o->state_ & socket_ops::stream_oriented) != 0) if (o->bytes_transferred_ == 0) result = done_and_exhausted; ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", o->ec_, o->bytes_transferred_)); return result; } private: socket_type socket_; socket_ops::state_type state_; MutableBufferSequence buffers_; socket_base::message_flags flags_; }; template class reactive_socket_recv_op : public reactive_socket_recv_op_base { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op); reactive_socket_recv_op(socket_type socket, socket_ops::state_type state, const MutableBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) : reactive_socket_recv_op_base(socket, state, buffers, flags, &reactive_socket_recv_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_recv_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_recvfrom_op.hpp ================================================ // // detail/reactive_socket_recvfrom_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_socket_recvfrom_op_base : public reactor_op { public: reactive_socket_recvfrom_op_base(socket_type socket, int protocol_type, const MutableBufferSequence& buffers, Endpoint& endpoint, socket_base::message_flags flags, func_type complete_func) : reactor_op(&reactive_socket_recvfrom_op_base::do_perform, complete_func), socket_(socket), protocol_type_(protocol_type), buffers_(buffers), sender_endpoint_(endpoint), flags_(flags) { } static status do_perform(reactor_op* base) { reactive_socket_recvfrom_op_base* o( static_cast(base)); buffer_sequence_adapter bufs(o->buffers_); std::size_t addr_len = o->sender_endpoint_.capacity(); status result = socket_ops::non_blocking_recvfrom(o->socket_, bufs.buffers(), bufs.count(), o->flags_, o->sender_endpoint_.data(), &addr_len, o->ec_, o->bytes_transferred_) ? done : not_done; if (result && !o->ec_) o->sender_endpoint_.resize(addr_len); ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", o->ec_, o->bytes_transferred_)); return result; } private: socket_type socket_; int protocol_type_; MutableBufferSequence buffers_; Endpoint& sender_endpoint_; socket_base::message_flags flags_; }; template class reactive_socket_recvfrom_op : public reactive_socket_recvfrom_op_base { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op); reactive_socket_recvfrom_op(socket_type socket, int protocol_type, const MutableBufferSequence& buffers, Endpoint& endpoint, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) : reactive_socket_recvfrom_op_base( socket, protocol_type, buffers, endpoint, flags, &reactive_socket_recvfrom_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_recvfrom_op* o( static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_recvmsg_op.hpp ================================================ // // detail/reactive_socket_recvmsg_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/socket_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_socket_recvmsg_op_base : public reactor_op { public: reactive_socket_recvmsg_op_base(socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, func_type complete_func) : reactor_op(&reactive_socket_recvmsg_op_base::do_perform, complete_func), socket_(socket), buffers_(buffers), in_flags_(in_flags), out_flags_(out_flags) { } static status do_perform(reactor_op* base) { reactive_socket_recvmsg_op_base* o( static_cast(base)); buffer_sequence_adapter bufs(o->buffers_); status result = socket_ops::non_blocking_recvmsg(o->socket_, bufs.buffers(), bufs.count(), o->in_flags_, o->out_flags_, o->ec_, o->bytes_transferred_) ? done : not_done; ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", o->ec_, o->bytes_transferred_)); return result; } private: socket_type socket_; MutableBufferSequence buffers_; socket_base::message_flags in_flags_; socket_base::message_flags& out_flags_; }; template class reactive_socket_recvmsg_op : public reactive_socket_recvmsg_op_base { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op); reactive_socket_recvmsg_op(socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) : reactive_socket_recvmsg_op_base(socket, buffers, in_flags, out_flags, &reactive_socket_recvmsg_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_recvmsg_op* o( static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_send_op.hpp ================================================ // // detail/reactive_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_socket_send_op_base : public reactor_op { public: reactive_socket_send_op_base(socket_type socket, socket_ops::state_type state, const ConstBufferSequence& buffers, socket_base::message_flags flags, func_type complete_func) : reactor_op(&reactive_socket_send_op_base::do_perform, complete_func), socket_(socket), state_(state), buffers_(buffers), flags_(flags) { } static status do_perform(reactor_op* base) { reactive_socket_send_op_base* o( static_cast(base)); buffer_sequence_adapter bufs(o->buffers_); status result = socket_ops::non_blocking_send(o->socket_, bufs.buffers(), bufs.count(), o->flags_, o->ec_, o->bytes_transferred_) ? done : not_done; if (result == done) if ((o->state_ & socket_ops::stream_oriented) != 0) if (o->bytes_transferred_ < bufs.total_size()) result = done_and_exhausted; ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_send", o->ec_, o->bytes_transferred_)); return result; } private: socket_type socket_; socket_ops::state_type state_; ConstBufferSequence buffers_; socket_base::message_flags flags_; }; template class reactive_socket_send_op : public reactive_socket_send_op_base { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_send_op); reactive_socket_send_op(socket_type socket, socket_ops::state_type state, const ConstBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) : reactive_socket_send_op_base(socket, state, buffers, flags, &reactive_socket_send_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_send_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_sendto_op.hpp ================================================ // // detail/reactive_socket_sendto_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_socket_sendto_op_base : public reactor_op { public: reactive_socket_sendto_op_base(socket_type socket, const ConstBufferSequence& buffers, const Endpoint& endpoint, socket_base::message_flags flags, func_type complete_func) : reactor_op(&reactive_socket_sendto_op_base::do_perform, complete_func), socket_(socket), buffers_(buffers), destination_(endpoint), flags_(flags) { } static status do_perform(reactor_op* base) { reactive_socket_sendto_op_base* o( static_cast(base)); buffer_sequence_adapter bufs(o->buffers_); status result = socket_ops::non_blocking_sendto(o->socket_, bufs.buffers(), bufs.count(), o->flags_, o->destination_.data(), o->destination_.size(), o->ec_, o->bytes_transferred_) ? done : not_done; ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_sendto", o->ec_, o->bytes_transferred_)); return result; } private: socket_type socket_; ConstBufferSequence buffers_; Endpoint destination_; socket_base::message_flags flags_; }; template class reactive_socket_sendto_op : public reactive_socket_sendto_op_base { public: ASIO_DEFINE_HANDLER_PTR(reactive_socket_sendto_op); reactive_socket_sendto_op(socket_type socket, const ConstBufferSequence& buffers, const Endpoint& endpoint, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) : reactive_socket_sendto_op_base(socket, buffers, endpoint, flags, &reactive_socket_sendto_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_socket_sendto_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->bytes_transferred_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_service.hpp ================================================ // // detail/reactive_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_IOCP) #include "asio/buffer.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/socket_base.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/reactive_null_buffers_op.hpp" #include "asio/detail/reactive_socket_accept_op.hpp" #include "asio/detail/reactive_socket_connect_op.hpp" #include "asio/detail/reactive_socket_recvfrom_op.hpp" #include "asio/detail/reactive_socket_sendto_op.hpp" #include "asio/detail/reactive_socket_service_base.hpp" #include "asio/detail/reactor.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_holder.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_socket_service : public execution_context_service_base >, public reactive_socket_service_base { public: // The protocol type. typedef Protocol protocol_type; // The endpoint type. typedef typename Protocol::endpoint endpoint_type; // The native type of a socket. typedef socket_type native_handle_type; // The implementation type of the socket. struct implementation_type : reactive_socket_service_base::base_implementation_type { // Default constructor. implementation_type() : protocol_(endpoint_type().protocol()) { } // The protocol associated with the socket. protocol_type protocol_; }; // Constructor. reactive_socket_service(execution_context& context) : execution_context_service_base< reactive_socket_service >(context), reactive_socket_service_base(context) { } // Destroy all user-defined handler objects owned by the service. void shutdown() { this->base_shutdown(); } // Move-construct a new socket implementation. void move_construct(implementation_type& impl, implementation_type& other_impl) ASIO_NOEXCEPT { this->base_move_construct(impl, other_impl); impl.protocol_ = other_impl.protocol_; other_impl.protocol_ = endpoint_type().protocol(); } // Move-assign from another socket implementation. void move_assign(implementation_type& impl, reactive_socket_service_base& other_service, implementation_type& other_impl) { this->base_move_assign(impl, other_service, other_impl); impl.protocol_ = other_impl.protocol_; other_impl.protocol_ = endpoint_type().protocol(); } // Move-construct a new socket implementation from another protocol type. template void converting_move_construct(implementation_type& impl, reactive_socket_service&, typename reactive_socket_service< Protocol1>::implementation_type& other_impl) { this->base_move_construct(impl, other_impl); impl.protocol_ = protocol_type(other_impl.protocol_); other_impl.protocol_ = typename Protocol1::endpoint().protocol(); } // Open a new socket implementation. asio::error_code open(implementation_type& impl, const protocol_type& protocol, asio::error_code& ec) { if (!do_open(impl, protocol.family(), protocol.type(), protocol.protocol(), ec)) impl.protocol_ = protocol; return ec; } // Assign a native socket to a socket implementation. asio::error_code assign(implementation_type& impl, const protocol_type& protocol, const native_handle_type& native_socket, asio::error_code& ec) { if (!do_assign(impl, protocol.type(), native_socket, ec)) impl.protocol_ = protocol; return ec; } // Get the native socket representation. native_handle_type native_handle(implementation_type& impl) { return impl.socket_; } // Bind the socket to the specified local endpoint. asio::error_code bind(implementation_type& impl, const endpoint_type& endpoint, asio::error_code& ec) { socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); return ec; } // Set a socket option. template asio::error_code set_option(implementation_type& impl, const Option& option, asio::error_code& ec) { socket_ops::setsockopt(impl.socket_, impl.state_, option.level(impl.protocol_), option.name(impl.protocol_), option.data(impl.protocol_), option.size(impl.protocol_), ec); return ec; } // Set a socket option. template asio::error_code get_option(const implementation_type& impl, Option& option, asio::error_code& ec) const { std::size_t size = option.size(impl.protocol_); socket_ops::getsockopt(impl.socket_, impl.state_, option.level(impl.protocol_), option.name(impl.protocol_), option.data(impl.protocol_), &size, ec); if (!ec) option.resize(impl.protocol_, size); return ec; } // Get the local endpoint. endpoint_type local_endpoint(const implementation_type& impl, asio::error_code& ec) const { endpoint_type endpoint; std::size_t addr_len = endpoint.capacity(); if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) return endpoint_type(); endpoint.resize(addr_len); return endpoint; } // Get the remote endpoint. endpoint_type remote_endpoint(const implementation_type& impl, asio::error_code& ec) const { endpoint_type endpoint; std::size_t addr_len = endpoint.capacity(); if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, false, ec)) return endpoint_type(); endpoint.resize(addr_len); return endpoint; } // Disable sends or receives on the socket. asio::error_code shutdown(base_implementation_type& impl, socket_base::shutdown_type what, asio::error_code& ec) { socket_ops::shutdown(impl.socket_, what, ec); return ec; } // Send a datagram to the specified endpoint. Returns the number of bytes // sent. template size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_sendto(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, destination.data(), destination.size(), ec); } // Wait until data can be sent without blocking. size_t send_to(implementation_type& impl, const null_buffers&, const endpoint_type&, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); return 0; } // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_send_to(implementation_type& impl, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_sendto_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_send_to")); start_op(impl, reactor::write_op, p.p, is_continuation, true, false); p.v = p.p = 0; } // Start an asynchronous wait until data can be sent without blocking. template void async_send_to(implementation_type& impl, const null_buffers&, const endpoint_type&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_send_to(null_buffers)")); start_op(impl, reactor::write_op, p.p, is_continuation, false, false); p.v = p.p = 0; } // Receive a datagram with the endpoint of the sender. Returns the number of // bytes received. template size_t receive_from(implementation_type& impl, const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); std::size_t addr_len = sender_endpoint.capacity(); std::size_t bytes_recvd = socket_ops::sync_recvfrom( impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, sender_endpoint.data(), &addr_len, ec); if (!ec) sender_endpoint.resize(addr_len); return bytes_recvd; } // Wait until data can be received without blocking. size_t receive_from(implementation_type& impl, const null_buffers&, endpoint_type& sender_endpoint, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); return 0; } // Start an asynchronous receive. The buffer for the data being received and // the sender_endpoint object must both be valid for the lifetime of the // asynchronous operation. template void async_receive_from(implementation_type& impl, const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_recvfrom_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; int protocol = impl.protocol_.type(); p.p = new (p.v) op(impl.socket_, protocol, buffers, sender_endpoint, flags, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_receive_from")); start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, p.p, is_continuation, true, false); p.v = p.p = 0; } // Wait until data can be received without blocking. template void async_receive_from(implementation_type& impl, const null_buffers&, endpoint_type& sender_endpoint, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_receive_from(null_buffers)")); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, p.p, is_continuation, false, false); p.v = p.p = 0; } // Accept a new connection. template asio::error_code accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, asio::error_code& ec) { // We cannot accept a socket that is already open. if (peer.is_open()) { ec = asio::error::already_open; return ec; } std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; socket_holder new_socket(socket_ops::sync_accept(impl.socket_, impl.state_, peer_endpoint ? peer_endpoint->data() : 0, peer_endpoint ? &addr_len : 0, ec)); // On success, assign new connection to peer socket object. if (new_socket.get() != invalid_socket) { if (peer_endpoint) peer_endpoint->resize(addr_len); peer.assign(impl.protocol_, new_socket.get(), ec); if (!ec) new_socket.release(); } return ec; } // Start an asynchronous accept. The peer and peer_endpoint objects must be // valid until the accept's handler is invoked. template void async_accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_accept_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, impl.state_, peer, impl.protocol_, peer_endpoint, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_accept")); start_accept_op(impl, p.p, is_continuation, peer.is_open()); p.v = p.p = 0; } #if defined(ASIO_HAS_MOVE) // Start an asynchronous accept. The peer_endpoint object must be valid until // the accept's handler is invoked. template void async_move_accept(implementation_type& impl, const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_move_accept_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(peer_io_ex, impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_accept")); start_accept_op(impl, p.p, is_continuation, false); p.v = p.p = 0; } #endif // defined(ASIO_HAS_MOVE) // Connect the socket to the specified endpoint. asio::error_code connect(implementation_type& impl, const endpoint_type& peer_endpoint, asio::error_code& ec) { socket_ops::sync_connect(impl.socket_, peer_endpoint.data(), peer_endpoint.size(), ec); return ec; } // Start an asynchronous connect. template void async_connect(implementation_type& impl, const endpoint_type& peer_endpoint, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_connect_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_connect")); start_connect_op(impl, p.p, is_continuation, peer_endpoint.data(), peer_endpoint.size()); p.v = p.p = 0; } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/reactive_socket_service_base.hpp ================================================ // // detail/reactive_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP #define ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_IOCP) \ && !defined(ASIO_WINDOWS_RUNTIME) #include "asio/buffer.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/socket_base.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactive_null_buffers_op.hpp" #include "asio/detail/reactive_socket_recv_op.hpp" #include "asio/detail/reactive_socket_recvmsg_op.hpp" #include "asio/detail/reactive_socket_send_op.hpp" #include "asio/detail/reactive_wait_op.hpp" #include "asio/detail/reactor.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_holder.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class reactive_socket_service_base { public: // The native type of a socket. typedef socket_type native_handle_type; // The implementation type of the socket. struct base_implementation_type { // The native socket representation. socket_type socket_; // The current state of the socket. socket_ops::state_type state_; // Per-descriptor data used by the reactor. reactor::per_descriptor_data reactor_data_; }; // Constructor. ASIO_DECL reactive_socket_service_base(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void base_shutdown(); // Construct a new socket implementation. ASIO_DECL void construct(base_implementation_type& impl); // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl, base_implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl, reactive_socket_service_base& other_service, base_implementation_type& other_impl); // Destroy a socket implementation. ASIO_DECL void destroy(base_implementation_type& impl); // Determine whether the socket is open. bool is_open(const base_implementation_type& impl) const { return impl.socket_ != invalid_socket; } // Destroy a socket implementation. ASIO_DECL asio::error_code close( base_implementation_type& impl, asio::error_code& ec); // Release ownership of the socket. ASIO_DECL socket_type release( base_implementation_type& impl, asio::error_code& ec); // Get the native socket representation. native_handle_type native_handle(base_implementation_type& impl) { return impl.socket_; } // Cancel all operations associated with the socket. ASIO_DECL asio::error_code cancel( base_implementation_type& impl, asio::error_code& ec); // Determine whether the socket is at the out-of-band data mark. bool at_mark(const base_implementation_type& impl, asio::error_code& ec) const { return socket_ops::sockatmark(impl.socket_, ec); } // Determine the number of bytes available for reading. std::size_t available(const base_implementation_type& impl, asio::error_code& ec) const { return socket_ops::available(impl.socket_, ec); } // Place the socket into the state where it will listen for new connections. asio::error_code listen(base_implementation_type& impl, int backlog, asio::error_code& ec) { socket_ops::listen(impl.socket_, backlog, ec); return ec; } // Perform an IO control command on the socket. template asio::error_code io_control(base_implementation_type& impl, IO_Control_Command& command, asio::error_code& ec) { socket_ops::ioctl(impl.socket_, impl.state_, command.name(), static_cast(command.data()), ec); return ec; } // Gets the non-blocking mode of the socket. bool non_blocking(const base_implementation_type& impl) const { return (impl.state_ & socket_ops::user_set_non_blocking) != 0; } // Sets the non-blocking mode of the socket. asio::error_code non_blocking(base_implementation_type& impl, bool mode, asio::error_code& ec) { socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); return ec; } // Gets the non-blocking mode of the native socket implementation. bool native_non_blocking(const base_implementation_type& impl) const { return (impl.state_ & socket_ops::internal_non_blocking) != 0; } // Sets the non-blocking mode of the native socket implementation. asio::error_code native_non_blocking(base_implementation_type& impl, bool mode, asio::error_code& ec) { socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); return ec; } // Wait for the socket to become ready to read, ready to write, or to have // pending error conditions. asio::error_code wait(base_implementation_type& impl, socket_base::wait_type w, asio::error_code& ec) { switch (w) { case socket_base::wait_read: socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); break; case socket_base::wait_write: socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); break; case socket_base::wait_error: socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); break; default: ec = asio::error::invalid_argument; break; } return ec; } // Asynchronously wait for the socket to become ready to read, ready to // write, or to have pending error conditions. template void async_wait(base_implementation_type& impl, socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_wait_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_wait")); int op_type; switch (w) { case socket_base::wait_read: op_type = reactor::read_op; break; case socket_base::wait_write: op_type = reactor::write_op; break; case socket_base::wait_error: op_type = reactor::except_op; break; default: p.p->ec_ = asio::error::invalid_argument; reactor_.post_immediate_completion(p.p, is_continuation); p.v = p.p = 0; return; } start_op(impl, op_type, p.p, is_continuation, false, false); p.v = p.p = 0; } // Send the given data to the peer. template size_t send(base_implementation_type& impl, const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_send(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); } // Wait until data can be sent without blocking. size_t send(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); return 0; } // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_send(base_implementation_type& impl, const ConstBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_send_op< ConstBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_send")); start_op(impl, reactor::write_op, p.p, is_continuation, true, ((impl.state_ & socket_ops::stream_oriented) && buffer_sequence_adapter::all_empty(buffers))); p.v = p.p = 0; } // Start an asynchronous wait until data can be sent without blocking. template void async_send(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_send(null_buffers)")); start_op(impl, reactor::write_op, p.p, is_continuation, false, false); p.v = p.p = 0; } // Receive some data from the peer. Returns the number of bytes received. template size_t receive(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_recv(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); } // Wait until data can be received without blocking. size_t receive(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); return 0; } // Start an asynchronous receive. The buffer for the data being received // must be valid for the lifetime of the asynchronous operation. template void async_receive(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_recv_op< MutableBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_receive")); start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, p.p, is_continuation, (flags & socket_base::message_out_of_band) == 0, ((impl.state_ & socket_ops::stream_oriented) && buffer_sequence_adapter::all_empty(buffers))); p.v = p.p = 0; } // Wait until data can be received without blocking. template void async_receive(base_implementation_type& impl, const null_buffers&, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_receive(null_buffers)")); start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, p.p, is_continuation, false, false); p.v = p.p = 0; } // Receive some data with associated flags. Returns the number of bytes // received. template size_t receive_with_flags(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_recvmsg(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), in_flags, out_flags, ec); } // Wait until data can be received without blocking. size_t receive_with_flags(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, socket_base::message_flags& out_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); // Clear out_flags, since we cannot give it any other sensible value when // performing a null_buffers operation. out_flags = 0; return 0; } // Start an asynchronous receive. The buffer for the data being received // must be valid for the lifetime of the asynchronous operation. template void async_receive_with_flags(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_socket_recvmsg_op< MutableBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_receive_with_flags")); start_op(impl, (in_flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, p.p, is_continuation, (in_flags & socket_base::message_out_of_band) == 0, false); p.v = p.p = 0; } // Wait until data can be received without blocking. template void async_receive_with_flags(base_implementation_type& impl, const null_buffers&, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef reactive_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); // Clear out_flags, since we cannot give it any other sensible value when // performing a null_buffers operation. out_flags = 0; start_op(impl, (in_flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, p.p, is_continuation, false, false); p.v = p.p = 0; } protected: // Open a new socket implementation. ASIO_DECL asio::error_code do_open( base_implementation_type& impl, int af, int type, int protocol, asio::error_code& ec); // Assign a native socket to a socket implementation. ASIO_DECL asio::error_code do_assign( base_implementation_type& impl, int type, const native_handle_type& native_socket, asio::error_code& ec); // Start the asynchronous read or write operation. ASIO_DECL void start_op(base_implementation_type& impl, int op_type, reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); // Start the asynchronous accept operation. ASIO_DECL void start_accept_op(base_implementation_type& impl, reactor_op* op, bool is_continuation, bool peer_is_open); // Start the asynchronous connect operation. ASIO_DECL void start_connect_op(base_implementation_type& impl, reactor_op* op, bool is_continuation, const socket_addr_type* addr, size_t addrlen); // The selector that performs event demultiplexing for the service. reactor& reactor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/reactive_socket_service_base.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // !defined(ASIO_HAS_IOCP) // && !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP ================================================ FILE: src/third_party/asio/detail/reactive_wait_op.hpp ================================================ // // detail/reactive_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTIVE_WAIT_OP_HPP #define ASIO_DETAIL_REACTIVE_WAIT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactive_wait_op : public reactor_op { public: ASIO_DEFINE_HANDLER_PTR(reactive_wait_op); reactive_wait_op(Handler& handler, const IoExecutor& io_ex) : reactor_op(&reactive_wait_op::do_perform, &reactive_wait_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static status do_perform(reactor_op*) { return done; } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. reactive_wait_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(o->handler_, o->ec_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTIVE_WAIT_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactor.hpp ================================================ // // detail/reactor.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTOR_HPP #define ASIO_DETAIL_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/reactor_fwd.hpp" #if defined(ASIO_HAS_EPOLL) # include "asio/detail/epoll_reactor.hpp" #elif defined(ASIO_HAS_KQUEUE) # include "asio/detail/kqueue_reactor.hpp" #elif defined(ASIO_HAS_DEV_POLL) # include "asio/detail/dev_poll_reactor.hpp" #elif defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/null_reactor.hpp" #else # include "asio/detail/select_reactor.hpp" #endif #endif // ASIO_DETAIL_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/reactor_fwd.hpp ================================================ // // detail/reactor_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTOR_FWD_HPP #define ASIO_DETAIL_REACTOR_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" namespace asio { namespace detail { #if defined(ASIO_HAS_IOCP) || defined(ASIO_WINDOWS_RUNTIME) typedef class null_reactor reactor; #elif defined(ASIO_HAS_IOCP) typedef class select_reactor reactor; #elif defined(ASIO_HAS_EPOLL) typedef class epoll_reactor reactor; #elif defined(ASIO_HAS_KQUEUE) typedef class kqueue_reactor reactor; #elif defined(ASIO_HAS_DEV_POLL) typedef class dev_poll_reactor reactor; #else typedef class select_reactor reactor; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_REACTOR_FWD_HPP ================================================ FILE: src/third_party/asio/detail/reactor_op.hpp ================================================ // // detail/reactor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTOR_OP_HPP #define ASIO_DETAIL_REACTOR_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class reactor_op : public operation { public: // The error code to be passed to the completion handler. asio::error_code ec_; // The number of bytes transferred, to be passed to the completion handler. std::size_t bytes_transferred_; // Status returned by perform function. May be used to decide whether it is // worth performing more operations on the descriptor immediately. enum status { not_done, done, done_and_exhausted }; // Perform the operation. Returns true if it is finished. status perform() { return perform_func_(this); } protected: typedef status (*perform_func_type)(reactor_op*); reactor_op(perform_func_type perform_func, func_type complete_func) : operation(complete_func), bytes_transferred_(0), perform_func_(perform_func) { } private: perform_func_type perform_func_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTOR_OP_HPP ================================================ FILE: src/third_party/asio/detail/reactor_op_queue.hpp ================================================ // // detail/reactor_op_queue.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REACTOR_OP_QUEUE_HPP #define ASIO_DETAIL_REACTOR_OP_QUEUE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/hash_map.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class reactor_op_queue : private noncopyable { public: typedef Descriptor key_type; struct mapped_type : op_queue { mapped_type() {} mapped_type(const mapped_type&) {} void operator=(const mapped_type&) {} }; typedef typename hash_map::value_type value_type; typedef typename hash_map::iterator iterator; // Constructor. reactor_op_queue() : operations_() { } // Obtain iterators to all registered descriptors. iterator begin() { return operations_.begin(); } iterator end() { return operations_.end(); } // Add a new operation to the queue. Returns true if this is the only // operation for the given descriptor, in which case the reactor's event // demultiplexing function call may need to be interrupted and restarted. bool enqueue_operation(Descriptor descriptor, reactor_op* op) { std::pair entry = operations_.insert(value_type(descriptor, mapped_type())); entry.first->second.push(op); return entry.second; } // Cancel all operations associated with the descriptor identified by the // supplied iterator. Any operations pending for the descriptor will be // cancelled. Returns true if any operations were cancelled, in which case // the reactor's event demultiplexing function may need to be interrupted and // restarted. bool cancel_operations(iterator i, op_queue& ops, const asio::error_code& ec = asio::error::operation_aborted) { if (i != operations_.end()) { while (reactor_op* op = i->second.front()) { op->ec_ = ec; i->second.pop(); ops.push(op); } operations_.erase(i); return true; } return false; } // Cancel all operations associated with the descriptor. Any operations // pending for the descriptor will be cancelled. Returns true if any // operations were cancelled, in which case the reactor's event // demultiplexing function may need to be interrupted and restarted. bool cancel_operations(Descriptor descriptor, op_queue& ops, const asio::error_code& ec = asio::error::operation_aborted) { return this->cancel_operations(operations_.find(descriptor), ops, ec); } // Whether there are no operations in the queue. bool empty() const { return operations_.empty(); } // Determine whether there are any operations associated with the descriptor. bool has_operation(Descriptor descriptor) const { return operations_.find(descriptor) != operations_.end(); } // Perform the operations corresponding to the descriptor identified by the // supplied iterator. Returns true if there are still unfinished operations // queued for the descriptor. bool perform_operations(iterator i, op_queue& ops) { if (i != operations_.end()) { while (reactor_op* op = i->second.front()) { if (op->perform()) { i->second.pop(); ops.push(op); } else { return true; } } operations_.erase(i); } return false; } // Perform the operations corresponding to the descriptor. Returns true if // there are still unfinished operations queued for the descriptor. bool perform_operations(Descriptor descriptor, op_queue& ops) { return this->perform_operations(operations_.find(descriptor), ops); } // Get all operations owned by the queue. void get_all_operations(op_queue& ops) { iterator i = operations_.begin(); while (i != operations_.end()) { iterator op_iter = i++; ops.push(op_iter->second); operations_.erase(op_iter); } } private: // The operations that are currently executing asynchronously. hash_map operations_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_REACTOR_OP_QUEUE_HPP ================================================ FILE: src/third_party/asio/detail/recycling_allocator.hpp ================================================ // // detail/recycling_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_RECYCLING_ALLOCATOR_HPP #define ASIO_DETAIL_RECYCLING_ALLOCATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/thread_context.hpp" #include "asio/detail/thread_info_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class recycling_allocator { public: typedef T value_type; template struct rebind { typedef recycling_allocator other; }; recycling_allocator() { } template recycling_allocator(const recycling_allocator&) { } T* allocate(std::size_t n) { typedef thread_context::thread_call_stack call_stack; void* p = thread_info_base::allocate(Purpose(), call_stack::top(), sizeof(T) * n); return static_cast(p); } void deallocate(T* p, std::size_t n) { typedef thread_context::thread_call_stack call_stack; thread_info_base::deallocate(Purpose(), call_stack::top(), p, sizeof(T) * n); } }; template class recycling_allocator { public: typedef void value_type; template struct rebind { typedef recycling_allocator other; }; recycling_allocator() { } template recycling_allocator(const recycling_allocator&) { } }; template struct get_recycling_allocator { typedef Allocator type; static type get(const Allocator& a) { return a; } }; template struct get_recycling_allocator, Purpose> { typedef recycling_allocator type; static type get(const std::allocator&) { return type(); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_RECYCLING_ALLOCATOR_HPP ================================================ FILE: src/third_party/asio/detail/regex_fwd.hpp ================================================ // // detail/regex_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_REGEX_FWD_HPP #define ASIO_DETAIL_REGEX_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if defined(ASIO_HAS_BOOST_REGEX) #include #include namespace boost { template struct sub_match; template class match_results; } // namespace boost #endif // defined(ASIO_HAS_BOOST_REGEX) #endif // ASIO_DETAIL_REGEX_FWD_HPP ================================================ FILE: src/third_party/asio/detail/resolve_endpoint_op.hpp ================================================ // // detail/resolve_endpoint_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP #define ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error.hpp" #include "asio/ip/basic_resolver_results.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_op.hpp" #include "asio/detail/socket_ops.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class resolve_endpoint_op : public resolve_op { public: ASIO_DEFINE_HANDLER_PTR(resolve_endpoint_op); typedef typename Protocol::endpoint endpoint_type; typedef asio::ip::basic_resolver_results results_type; #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif resolve_endpoint_op(socket_ops::weak_cancel_token_type cancel_token, const endpoint_type& endpoint, scheduler_impl& sched, Handler& handler, const IoExecutor& io_ex) : resolve_op(&resolve_endpoint_op::do_complete), cancel_token_(cancel_token), endpoint_(endpoint), scheduler_(sched), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the operation object. resolve_endpoint_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); if (owner && owner != &o->scheduler_) { // The operation is being run on the worker io_context. Time to perform // the resolver operation. // Perform the blocking endpoint resolution operation. char host_name[NI_MAXHOST]; char service_name[NI_MAXSERV]; socket_ops::background_getnameinfo(o->cancel_token_, o->endpoint_.data(), o->endpoint_.size(), host_name, NI_MAXHOST, service_name, NI_MAXSERV, o->endpoint_.protocol().type(), o->ec_); o->results_ = results_type::create(o->endpoint_, host_name, service_name); // Pass operation back to main io_context for completion. o->scheduler_.post_deferred_completion(o); p.v = p.p = 0; } else { // The operation has been returned to the main io_context. The completion // handler is ready to be delivered. ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated // before the upcall is made. Even if we're not about to make an upcall, // a sub-object of the handler may be the true owner of the memory // associated with the handler. Consequently, a local copy of the handler // is required to ensure that any owning sub-object remains valid until // after we have deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->results_); p.h = asio::detail::addressof(handler.handler_); p.reset(); if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } } private: socket_ops::weak_cancel_token_type cancel_token_; endpoint_type endpoint_; scheduler_impl& scheduler_; Handler handler_; IoExecutor io_executor_; results_type results_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP ================================================ FILE: src/third_party/asio/detail/resolve_op.hpp ================================================ // // detail/resolve_op.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_RESOLVE_OP_HPP #define ASIO_DETAIL_RESOLVE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class resolve_op : public operation { public: // The error code to be passed to the completion handler. asio::error_code ec_; protected: resolve_op(func_type complete_func) : operation(complete_func) { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_RESOLVE_OP_HPP ================================================ FILE: src/third_party/asio/detail/resolve_query_op.hpp ================================================ // // detail/resolve_query_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_RESOLVE_QUERY_OP_HPP #define ASIO_DETAIL_RESOLVE_QUERY_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error.hpp" #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/basic_resolver_results.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_op.hpp" #include "asio/detail/socket_ops.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class resolve_query_op : public resolve_op { public: ASIO_DEFINE_HANDLER_PTR(resolve_query_op); typedef asio::ip::basic_resolver_query query_type; typedef asio::ip::basic_resolver_results results_type; #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif resolve_query_op(socket_ops::weak_cancel_token_type cancel_token, const query_type& query, scheduler_impl& sched, Handler& handler, const IoExecutor& io_ex) : resolve_op(&resolve_query_op::do_complete), cancel_token_(cancel_token), query_(query), scheduler_(sched), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex), addrinfo_(0) { handler_work::start(handler_, io_executor_); } ~resolve_query_op() { if (addrinfo_) socket_ops::freeaddrinfo(addrinfo_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the operation object. resolve_query_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; if (owner && owner != &o->scheduler_) { // The operation is being run on the worker io_context. Time to perform // the resolver operation. // Perform the blocking host resolution operation. socket_ops::background_getaddrinfo(o->cancel_token_, o->query_.host_name().c_str(), o->query_.service_name().c_str(), o->query_.hints(), &o->addrinfo_, o->ec_); // Pass operation back to main io_context for completion. o->scheduler_.post_deferred_completion(o); p.v = p.p = 0; } else { // The operation has been returned to the main io_context. The completion // handler is ready to be delivered. // Take ownership of the operation's outstanding work. handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated // before the upcall is made. Even if we're not about to make an upcall, // a sub-object of the handler may be the true owner of the memory // associated with the handler. Consequently, a local copy of the handler // is required to ensure that any owning sub-object remains valid until // after we have deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, results_type()); p.h = asio::detail::addressof(handler.handler_); if (o->addrinfo_) { handler.arg2_ = results_type::create(o->addrinfo_, o->query_.host_name(), o->query_.service_name()); } p.reset(); if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } } private: socket_ops::weak_cancel_token_type cancel_token_; query_type query_; scheduler_impl& scheduler_; Handler handler_; IoExecutor io_executor_; asio::detail::addrinfo_type* addrinfo_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_RESOLVE_QUERY_OP_HPP ================================================ FILE: src/third_party/asio/detail/resolver_service.hpp ================================================ // // detail/resolver_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_RESOLVER_SERVICE_HPP #define ASIO_DETAIL_RESOLVER_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS_RUNTIME) #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/basic_resolver_results.hpp" #include "asio/detail/concurrency_hint.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_endpoint_op.hpp" #include "asio/detail/resolve_query_op.hpp" #include "asio/detail/resolver_service_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class resolver_service : public execution_context_service_base >, public resolver_service_base { public: // The implementation type of the resolver. A cancellation token is used to // indicate to the background thread that the operation has been cancelled. typedef socket_ops::shared_cancel_token_type implementation_type; // The endpoint type. typedef typename Protocol::endpoint endpoint_type; // The query type. typedef asio::ip::basic_resolver_query query_type; // The results type. typedef asio::ip::basic_resolver_results results_type; // Constructor. resolver_service(execution_context& context) : execution_context_service_base >(context), resolver_service_base(context) { } // Destroy all user-defined handler objects owned by the service. void shutdown() { this->base_shutdown(); } // Perform any fork-related housekeeping. void notify_fork(execution_context::fork_event fork_ev) { this->base_notify_fork(fork_ev); } // Resolve a query to a list of entries. results_type resolve(implementation_type&, const query_type& query, asio::error_code& ec) { asio::detail::addrinfo_type* address_info = 0; socket_ops::getaddrinfo(query.host_name().c_str(), query.service_name().c_str(), query.hints(), &address_info, ec); auto_addrinfo auto_address_info(address_info); return ec ? results_type() : results_type::create( address_info, query.host_name(), query.service_name()); } // Asynchronously resolve a query to a list of entries. template void async_resolve(implementation_type& impl, const query_type& query, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef resolve_query_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl, query, scheduler_, handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "resolver", &impl, 0, "async_resolve")); start_resolve_op(p.p); p.v = p.p = 0; } // Resolve an endpoint to a list of entries. results_type resolve(implementation_type&, const endpoint_type& endpoint, asio::error_code& ec) { char host_name[NI_MAXHOST]; char service_name[NI_MAXSERV]; socket_ops::sync_getnameinfo(endpoint.data(), endpoint.size(), host_name, NI_MAXHOST, service_name, NI_MAXSERV, endpoint.protocol().type(), ec); return ec ? results_type() : results_type::create( endpoint, host_name, service_name); } // Asynchronously resolve an endpoint to a list of entries. template void async_resolve(implementation_type& impl, const endpoint_type& endpoint, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef resolve_endpoint_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl, endpoint, scheduler_, handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "resolver", &impl, 0, "async_resolve")); start_resolve_op(p.p); p.v = p.p = 0; } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_RESOLVER_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/resolver_service_base.hpp ================================================ // // detail/resolver_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP #define ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/resolve_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/thread.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class resolver_service_base { public: // The implementation type of the resolver. A cancellation token is used to // indicate to the background thread that the operation has been cancelled. typedef socket_ops::shared_cancel_token_type implementation_type; // Constructor. ASIO_DECL resolver_service_base(execution_context& context); // Destructor. ASIO_DECL ~resolver_service_base(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void base_shutdown(); // Perform any fork-related housekeeping. ASIO_DECL void base_notify_fork( execution_context::fork_event fork_ev); // Construct a new resolver implementation. ASIO_DECL void construct(implementation_type& impl); // Destroy a resolver implementation. ASIO_DECL void destroy(implementation_type&); // Move-construct a new resolver implementation. ASIO_DECL void move_construct(implementation_type& impl, implementation_type& other_impl); // Move-assign from another resolver implementation. ASIO_DECL void move_assign(implementation_type& impl, resolver_service_base& other_service, implementation_type& other_impl); // Cancel pending asynchronous operations. ASIO_DECL void cancel(implementation_type& impl); protected: // Helper function to start an asynchronous resolve operation. ASIO_DECL void start_resolve_op(resolve_op* op); #if !defined(ASIO_WINDOWS_RUNTIME) // Helper class to perform exception-safe cleanup of addrinfo objects. class auto_addrinfo : private asio::detail::noncopyable { public: explicit auto_addrinfo(asio::detail::addrinfo_type* ai) : ai_(ai) { } ~auto_addrinfo() { if (ai_) socket_ops::freeaddrinfo(ai_); } operator asio::detail::addrinfo_type*() { return ai_; } private: asio::detail::addrinfo_type* ai_; }; #endif // !defined(ASIO_WINDOWS_RUNTIME) // Helper class to run the work scheduler in a thread. class work_scheduler_runner; // Start the work scheduler if it's not already running. ASIO_DECL void start_work_thread(); // The scheduler implementation used to post completions. #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif scheduler_impl& scheduler_; private: // Mutex to protect access to internal data. asio::detail::mutex mutex_; // Private scheduler used for performing asynchronous host resolution. asio::detail::scoped_ptr work_scheduler_; // Thread used for running the work io_context's run loop. asio::detail::scoped_ptr work_thread_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/resolver_service_base.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP ================================================ FILE: src/third_party/asio/detail/scheduler.hpp ================================================ // // detail/scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SCHEDULER_HPP #define ASIO_DETAIL_SCHEDULER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error_code.hpp" #include "asio/execution_context.hpp" #include "asio/detail/atomic_count.hpp" #include "asio/detail/conditionally_enabled_event.hpp" #include "asio/detail/conditionally_enabled_mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/reactor_fwd.hpp" #include "asio/detail/scheduler_operation.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/thread_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct scheduler_thread_info; class scheduler : public execution_context_service_base, public thread_context { public: typedef scheduler_operation operation; // Constructor. Specifies the number of concurrent threads that are likely to // run the scheduler. If set to 1 certain optimisation are performed. ASIO_DECL scheduler(asio::execution_context& ctx, int concurrency_hint = 0, bool own_thread = true); // Destructor. ASIO_DECL ~scheduler(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Initialise the task, if required. ASIO_DECL void init_task(); // Run the event loop until interrupted or no more work. ASIO_DECL std::size_t run(asio::error_code& ec); // Run until interrupted or one operation is performed. ASIO_DECL std::size_t run_one(asio::error_code& ec); // Run until timeout, interrupted, or one operation is performed. ASIO_DECL std::size_t wait_one( long usec, asio::error_code& ec); // Poll for operations without blocking. ASIO_DECL std::size_t poll(asio::error_code& ec); // Poll for one operation without blocking. ASIO_DECL std::size_t poll_one(asio::error_code& ec); // Interrupt the event processing loop. ASIO_DECL void stop(); // Determine whether the scheduler is stopped. ASIO_DECL bool stopped() const; // Restart in preparation for a subsequent run invocation. ASIO_DECL void restart(); // Notify that some work has started. void work_started() { ++outstanding_work_; } // Used to compensate for a forthcoming work_finished call. Must be called // from within a scheduler-owned thread. ASIO_DECL void compensating_work_started(); // Notify that some work has finished. void work_finished() { if (--outstanding_work_ == 0) stop(); } // Return whether a handler can be dispatched immediately. bool can_dispatch() { return thread_call_stack::contains(this) != 0; } // Request invocation of the given operation and return immediately. Assumes // that work_started() has not yet been called for the operation. ASIO_DECL void post_immediate_completion( operation* op, bool is_continuation); // Request invocation of the given operation and return immediately. Assumes // that work_started() was previously called for the operation. ASIO_DECL void post_deferred_completion(operation* op); // Request invocation of the given operations and return immediately. Assumes // that work_started() was previously called for each operation. ASIO_DECL void post_deferred_completions(op_queue& ops); // Enqueue the given operation following a failed attempt to dispatch the // operation for immediate invocation. ASIO_DECL void do_dispatch(operation* op); // Process unfinished operations as part of a shutdownoperation. Assumes that // work_started() was previously called for the operations. ASIO_DECL void abandon_operations(op_queue& ops); // Get the concurrency hint that was used to initialise the scheduler. int concurrency_hint() const { return concurrency_hint_; } private: // The mutex type used by this scheduler. typedef conditionally_enabled_mutex mutex; // The event type used by this scheduler. typedef conditionally_enabled_event event; // Structure containing thread-specific data. typedef scheduler_thread_info thread_info; // Run at most one operation. May block. ASIO_DECL std::size_t do_run_one(mutex::scoped_lock& lock, thread_info& this_thread, const asio::error_code& ec); // Run at most one operation with a timeout. May block. ASIO_DECL std::size_t do_wait_one(mutex::scoped_lock& lock, thread_info& this_thread, long usec, const asio::error_code& ec); // Poll for at most one operation. ASIO_DECL std::size_t do_poll_one(mutex::scoped_lock& lock, thread_info& this_thread, const asio::error_code& ec); // Stop the task and all idle threads. ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock); // Wake a single idle thread, or the task, and always unlock the mutex. ASIO_DECL void wake_one_thread_and_unlock( mutex::scoped_lock& lock); // Helper class to run the scheduler in its own thread. class thread_function; friend class thread_function; // Helper class to perform task-related operations on block exit. struct task_cleanup; friend struct task_cleanup; // Helper class to call work-related operations on block exit. struct work_cleanup; friend struct work_cleanup; // Whether to optimise for single-threaded use cases. const bool one_thread_; // Mutex to protect access to internal data. mutable mutex mutex_; // Event to wake up blocked threads. event wakeup_event_; // The task to be run by this service. reactor* task_; // Operation object to represent the position of the task in the queue. struct task_operation : operation { task_operation() : operation(0) {} } task_operation_; // Whether the task has been interrupted. bool task_interrupted_; // The count of unfinished work. atomic_count outstanding_work_; // The queue of handlers that are ready to be delivered. op_queue op_queue_; // Flag to indicate that the dispatcher has been stopped. bool stopped_; // Flag to indicate that the dispatcher has been shut down. bool shutdown_; // The concurrency hint used to initialise the scheduler. const int concurrency_hint_; // The thread that is running the scheduler. asio::detail::thread* thread_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/scheduler.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_SCHEDULER_HPP ================================================ FILE: src/third_party/asio/detail/scheduler_operation.hpp ================================================ // // detail/scheduler_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SCHEDULER_OPERATION_HPP #define ASIO_DETAIL_SCHEDULER_OPERATION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/error_code.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class scheduler; // Base class for all operations. A function pointer is used instead of virtual // functions to avoid the associated overhead. class scheduler_operation ASIO_INHERIT_TRACKED_HANDLER { public: typedef scheduler_operation operation_type; void complete(void* owner, const asio::error_code& ec, std::size_t bytes_transferred) { func_(owner, this, ec, bytes_transferred); } void destroy() { func_(0, this, asio::error_code(), 0); } protected: typedef void (*func_type)(void*, scheduler_operation*, const asio::error_code&, std::size_t); scheduler_operation(func_type func) : next_(0), func_(func), task_result_(0) { } // Prevents deletion through this type. ~scheduler_operation() { } private: friend class op_queue_access; scheduler_operation* next_; func_type func_; protected: friend class scheduler; unsigned int task_result_; // Passed into bytes transferred. }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SCHEDULER_OPERATION_HPP ================================================ FILE: src/third_party/asio/detail/scheduler_thread_info.hpp ================================================ // // detail/scheduler_thread_info.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SCHEDULER_THREAD_INFO_HPP #define ASIO_DETAIL_SCHEDULER_THREAD_INFO_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/op_queue.hpp" #include "asio/detail/thread_info_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class scheduler; class scheduler_operation; struct scheduler_thread_info : public thread_info_base { op_queue private_op_queue; long private_outstanding_work; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SCHEDULER_THREAD_INFO_HPP ================================================ FILE: src/third_party/asio/detail/scoped_lock.hpp ================================================ // // detail/scoped_lock.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SCOPED_LOCK_HPP #define ASIO_DETAIL_SCOPED_LOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Helper class to lock and unlock a mutex automatically. template class scoped_lock : private noncopyable { public: // Tag type used to distinguish constructors. enum adopt_lock_t { adopt_lock }; // Constructor adopts a lock that is already held. scoped_lock(Mutex& m, adopt_lock_t) : mutex_(m), locked_(true) { } // Constructor acquires the lock. explicit scoped_lock(Mutex& m) : mutex_(m) { mutex_.lock(); locked_ = true; } // Destructor releases the lock. ~scoped_lock() { if (locked_) mutex_.unlock(); } // Explicitly acquire the lock. void lock() { if (!locked_) { mutex_.lock(); locked_ = true; } } // Explicitly release the lock. void unlock() { if (locked_) { mutex_.unlock(); locked_ = false; } } // Test whether the lock is held. bool locked() const { return locked_; } // Get the underlying mutex. Mutex& mutex() { return mutex_; } private: // The underlying mutex. Mutex& mutex_; // Whether the mutex is currently locked or unlocked. bool locked_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SCOPED_LOCK_HPP ================================================ FILE: src/third_party/asio/detail/scoped_ptr.hpp ================================================ // // detail/scoped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SCOPED_PTR_HPP #define ASIO_DETAIL_SCOPED_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class scoped_ptr { public: // Constructor. explicit scoped_ptr(T* p = 0) : p_(p) { } // Destructor. ~scoped_ptr() { delete p_; } // Access. T* get() { return p_; } // Access. T* operator->() { return p_; } // Dereference. T& operator*() { return *p_; } // Reset pointer. void reset(T* p = 0) { delete p_; p_ = p; } // Release ownership of the pointer. T* release() { T* tmp = p_; p_ = 0; return tmp; } private: // Disallow copying and assignment. scoped_ptr(const scoped_ptr&); scoped_ptr& operator=(const scoped_ptr&); T* p_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SCOPED_PTR_HPP ================================================ FILE: src/third_party/asio/detail/select_interrupter.hpp ================================================ // // detail/select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SELECT_INTERRUPTER_HPP #define ASIO_DETAIL_SELECT_INTERRUPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS_RUNTIME) #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) # include "asio/detail/socket_select_interrupter.hpp" #elif defined(ASIO_HAS_EVENTFD) # include "asio/detail/eventfd_select_interrupter.hpp" #else # include "asio/detail/pipe_select_interrupter.hpp" #endif namespace asio { namespace detail { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) typedef socket_select_interrupter select_interrupter; #elif defined(ASIO_HAS_EVENTFD) typedef eventfd_select_interrupter select_interrupter; #else typedef pipe_select_interrupter select_interrupter; #endif } // namespace detail } // namespace asio #endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_SELECT_INTERRUPTER_HPP ================================================ FILE: src/third_party/asio/detail/select_reactor.hpp ================================================ // // detail/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SELECT_REACTOR_HPP #define ASIO_DETAIL_SELECT_REACTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) \ || (!defined(ASIO_HAS_DEV_POLL) \ && !defined(ASIO_HAS_EPOLL) \ && !defined(ASIO_HAS_KQUEUE) \ && !defined(ASIO_WINDOWS_RUNTIME)) #include #include "asio/detail/fd_set_adapter.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/reactor_op_queue.hpp" #include "asio/detail/select_interrupter.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/timer_queue_set.hpp" #include "asio/detail/wait_op.hpp" #include "asio/execution_context.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/thread.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class select_reactor : public execution_context_service_base { public: #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) enum op_types { read_op = 0, write_op = 1, except_op = 2, max_select_ops = 3, connect_op = 3, max_ops = 4 }; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) enum op_types { read_op = 0, write_op = 1, except_op = 2, max_select_ops = 3, connect_op = 1, max_ops = 3 }; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // Per-descriptor data. struct per_descriptor_data { }; // Constructor. ASIO_DECL select_reactor(asio::execution_context& ctx); // Destructor. ASIO_DECL ~select_reactor(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Recreate internal descriptors following a fork. ASIO_DECL void notify_fork( asio::execution_context::fork_event fork_ev); // Initialise the task, but only if the reactor is not in its own thread. ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&); // Register a descriptor with an associated single operation. Returns 0 on // success, system error code on failure. ASIO_DECL int register_internal_descriptor( int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, reactor_op* op); // Post a reactor operation for immediate completion. void post_immediate_completion(reactor_op* op, bool is_continuation) { scheduler_.post_immediate_completion(op, is_continuation); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. ASIO_DECL void start_op(int op_type, socket_type descriptor, per_descriptor_data&, reactor_op* op, bool is_continuation, bool); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. The reactor resources associated with // the descriptor must be released by calling cleanup_descriptor_data. ASIO_DECL void deregister_descriptor(socket_type descriptor, per_descriptor_data&, bool closing); // Remove the descriptor's registration from the reactor. The reactor // resources associated with the descriptor must be released by calling // cleanup_descriptor_data. ASIO_DECL void deregister_internal_descriptor( socket_type descriptor, per_descriptor_data&); // Perform any post-deregistration cleanup tasks associated with the // descriptor data. ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&); // Move descriptor registration from one descriptor_data object to another. ASIO_DECL void move_descriptor(socket_type descriptor, per_descriptor_data& target_descriptor_data, per_descriptor_data& source_descriptor_data); // Add a new timer queue to the reactor. template void add_timer_queue(timer_queue& queue); // Remove a timer queue from the reactor. template void remove_timer_queue(timer_queue& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template void schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template std::size_t cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits::max)()); // Move the timer operations associated with the given timer. template void move_timer(timer_queue& queue, typename timer_queue::per_timer_data& target, typename timer_queue::per_timer_data& source); // Run select once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue& ops); // Interrupt the select loop. ASIO_DECL void interrupt(); private: #if defined(ASIO_HAS_IOCP) // Run the select loop in the thread. ASIO_DECL void run_thread(); #endif // defined(ASIO_HAS_IOCP) // Helper function to add a new timer queue. ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); // Helper function to remove a timer queue. ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Get the timeout value for the select call. ASIO_DECL timeval* get_timeout(long usec, timeval& tv); // Cancel all operations associated with the given descriptor. This function // does not acquire the select_reactor's mutex. ASIO_DECL void cancel_ops_unlocked(socket_type descriptor, const asio::error_code& ec); // The scheduler implementation used to post completions. # if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_type; # else // defined(ASIO_HAS_IOCP) typedef class scheduler scheduler_type; # endif // defined(ASIO_HAS_IOCP) scheduler_type& scheduler_; // Mutex to protect access to internal data. asio::detail::mutex mutex_; // The interrupter is used to break a blocking select call. select_interrupter interrupter_; // The queues of read, write and except operations. reactor_op_queue op_queue_[max_ops]; // The file descriptor sets to be passed to the select system call. fd_set_adapter fd_sets_[max_select_ops]; // The timer queues. timer_queue_set timer_queues_; #if defined(ASIO_HAS_IOCP) // Helper class to run the reactor loop in a thread. class thread_function; friend class thread_function; // Does the reactor loop thread need to stop. bool stop_thread_; // The thread that is running the reactor loop. asio::detail::thread* thread_; #endif // defined(ASIO_HAS_IOCP) // Whether the service has been shut down. bool shutdown_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/select_reactor.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/select_reactor.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_IOCP) // || (!defined(ASIO_HAS_DEV_POLL) // && !defined(ASIO_HAS_EPOLL) // && !defined(ASIO_HAS_KQUEUE) // && !defined(ASIO_WINDOWS_RUNTIME)) #endif // ASIO_DETAIL_SELECT_REACTOR_HPP ================================================ FILE: src/third_party/asio/detail/service_registry.hpp ================================================ // // detail/service_registry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SERVICE_REGISTRY_HPP #define ASIO_DETAIL_SERVICE_REGISTRY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/mutex.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { class io_context; namespace detail { template class typeid_wrapper {}; class service_registry : private noncopyable { public: // Constructor. ASIO_DECL service_registry(execution_context& owner); // Destructor. ASIO_DECL ~service_registry(); // Shutdown all services. ASIO_DECL void shutdown_services(); // Destroy all services. ASIO_DECL void destroy_services(); // Notify all services of a fork event. ASIO_DECL void notify_fork(execution_context::fork_event fork_ev); // Get the service object corresponding to the specified service type. Will // create a new service object automatically if no such object already // exists. Ownership of the service object is not transferred to the caller. template Service& use_service(); // Get the service object corresponding to the specified service type. Will // create a new service object automatically if no such object already // exists. Ownership of the service object is not transferred to the caller. // This overload is used for backwards compatibility with services that // inherit from io_context::service. template Service& use_service(io_context& owner); // Add a service object. Throws on error, in which case ownership of the // object is retained by the caller. template void add_service(Service* new_service); // Check whether a service object of the specified type already exists. template bool has_service() const; private: // Initalise a service's key when the key_type typedef is not available. template static void init_key(execution_context::service::key& key, ...); #if !defined(ASIO_NO_TYPEID) // Initalise a service's key when the key_type typedef is available. template static void init_key(execution_context::service::key& key, typename enable_if< is_base_of::value>::type*); #endif // !defined(ASIO_NO_TYPEID) // Initialise a service's key based on its id. ASIO_DECL static void init_key_from_id( execution_context::service::key& key, const execution_context::id& id); #if !defined(ASIO_NO_TYPEID) // Initialise a service's key based on its id. template static void init_key_from_id(execution_context::service::key& key, const service_id& /*id*/); #endif // !defined(ASIO_NO_TYPEID) // Check if a service matches the given id. ASIO_DECL static bool keys_match( const execution_context::service::key& key1, const execution_context::service::key& key2); // The type of a factory function used for creating a service instance. typedef execution_context::service*(*factory_type)(void*); // Factory function for creating a service instance. template static execution_context::service* create(void* owner); // Destroy a service instance. ASIO_DECL static void destroy(execution_context::service* service); // Helper class to manage service pointers. struct auto_service_ptr; friend struct auto_service_ptr; struct auto_service_ptr { execution_context::service* ptr_; ~auto_service_ptr() { destroy(ptr_); } }; // Get the service object corresponding to the specified service key. Will // create a new service object automatically if no such object already // exists. Ownership of the service object is not transferred to the caller. ASIO_DECL execution_context::service* do_use_service( const execution_context::service::key& key, factory_type factory, void* owner); // Add a service object. Throws on error, in which case ownership of the // object is retained by the caller. ASIO_DECL void do_add_service( const execution_context::service::key& key, execution_context::service* new_service); // Check whether a service object with the specified key already exists. ASIO_DECL bool do_has_service( const execution_context::service::key& key) const; // Mutex to protect access to internal data. mutable asio::detail::mutex mutex_; // The owner of this service registry and the services it contains. execution_context& owner_; // The first service in the list of contained services. execution_context::service* first_service_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/service_registry.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/service_registry.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_SERVICE_REGISTRY_HPP ================================================ FILE: src/third_party/asio/detail/signal_blocker.hpp ================================================ // // detail/signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SIGNAL_BLOCKER_HPP #define ASIO_DETAIL_SIGNAL_BLOCKER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) || defined(ASIO_WINDOWS) \ || defined(ASIO_WINDOWS_RUNTIME) \ || defined(__CYGWIN__) || defined(__SYMBIAN32__) # include "asio/detail/null_signal_blocker.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_signal_blocker.hpp" #else # error Only Windows and POSIX are supported! #endif namespace asio { namespace detail { #if !defined(ASIO_HAS_THREADS) || defined(ASIO_WINDOWS) \ || defined(ASIO_WINDOWS_RUNTIME) \ || defined(__CYGWIN__) || defined(__SYMBIAN32__) typedef null_signal_blocker signal_blocker; #elif defined(ASIO_HAS_PTHREADS) typedef posix_signal_blocker signal_blocker; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_SIGNAL_BLOCKER_HPP ================================================ FILE: src/third_party/asio/detail/signal_handler.hpp ================================================ // // detail/signal_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SIGNAL_HANDLER_HPP #define ASIO_DETAIL_SIGNAL_HANDLER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/signal_op.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class signal_handler : public signal_op { public: ASIO_DEFINE_HANDLER_PTR(signal_handler); signal_handler(Handler& h, const IoExecutor& io_ex) : signal_op(&signal_handler::do_complete), handler_(ASIO_MOVE_CAST(Handler)(h)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. signal_handler* h(static_cast(base)); ptr p = { asio::detail::addressof(h->handler_), h, h }; handler_work w(h->handler_, h->io_executor_); ASIO_HANDLER_COMPLETION((*h)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(h->handler_, h->ec_, h->signal_number_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SIGNAL_HANDLER_HPP ================================================ FILE: src/third_party/asio/detail/signal_init.hpp ================================================ // // detail/signal_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SIGNAL_INIT_HPP #define ASIO_DETAIL_SIGNAL_INIT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #include #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class signal_init { public: // Constructor. signal_init() { std::signal(Signal, SIG_IGN); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #endif // ASIO_DETAIL_SIGNAL_INIT_HPP ================================================ FILE: src/third_party/asio/detail/signal_op.hpp ================================================ // // detail/signal_op.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SIGNAL_OP_HPP #define ASIO_DETAIL_SIGNAL_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class signal_op : public operation { public: // The error code to be passed to the completion handler. asio::error_code ec_; // The signal number to be passed to the completion handler. int signal_number_; protected: signal_op(func_type func) : operation(func), signal_number_(0) { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SIGNAL_OP_HPP ================================================ FILE: src/third_party/asio/detail/signal_set_service.hpp ================================================ // // detail/signal_set_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP #define ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/signal_handler.hpp" #include "asio/detail/signal_op.hpp" #include "asio/detail/socket_types.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) # include "asio/detail/reactor.hpp" #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { #if defined(NSIG) && (NSIG > 0) enum { max_signal_number = NSIG }; #else enum { max_signal_number = 128 }; #endif extern ASIO_DECL struct signal_state* get_signal_state(); extern "C" ASIO_DECL void asio_signal_handler(int signal_number); class signal_set_service : public execution_context_service_base { public: // Type used for tracking an individual signal registration. class registration { public: // Default constructor. registration() : signal_number_(0), queue_(0), undelivered_(0), next_in_table_(0), prev_in_table_(0), next_in_set_(0) { } private: // Only this service will have access to the internal values. friend class signal_set_service; // The signal number that is registered. int signal_number_; // The waiting signal handlers. op_queue* queue_; // The number of undelivered signals. std::size_t undelivered_; // Pointers to adjacent registrations in the registrations_ table. registration* next_in_table_; registration* prev_in_table_; // Link to next registration in the signal set. registration* next_in_set_; }; // The implementation type of the signal_set. class implementation_type { public: // Default constructor. implementation_type() : signals_(0) { } private: // Only this service will have access to the internal values. friend class signal_set_service; // The pending signal handlers. op_queue queue_; // Linked list of registered signals. registration* signals_; }; // Constructor. ASIO_DECL signal_set_service(execution_context& context); // Destructor. ASIO_DECL ~signal_set_service(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Perform fork-related housekeeping. ASIO_DECL void notify_fork( asio::execution_context::fork_event fork_ev); // Construct a new signal_set implementation. ASIO_DECL void construct(implementation_type& impl); // Destroy a signal_set implementation. ASIO_DECL void destroy(implementation_type& impl); // Add a signal to a signal_set. ASIO_DECL asio::error_code add(implementation_type& impl, int signal_number, asio::error_code& ec); // Remove a signal to a signal_set. ASIO_DECL asio::error_code remove(implementation_type& impl, int signal_number, asio::error_code& ec); // Remove all signals from a signal_set. ASIO_DECL asio::error_code clear(implementation_type& impl, asio::error_code& ec); // Cancel all operations associated with the signal set. ASIO_DECL asio::error_code cancel(implementation_type& impl, asio::error_code& ec); // Start an asynchronous operation to wait for a signal to be delivered. template void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef signal_handler op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "signal_set", &impl, 0, "async_wait")); start_wait_op(impl, p.p); p.v = p.p = 0; } // Deliver notification that a particular signal occurred. ASIO_DECL static void deliver_signal(int signal_number); private: // Helper function to add a service to the global signal state. ASIO_DECL static void add_service(signal_set_service* service); // Helper function to remove a service from the global signal state. ASIO_DECL static void remove_service(signal_set_service* service); // Helper function to create the pipe descriptors. ASIO_DECL static void open_descriptors(); // Helper function to close the pipe descriptors. ASIO_DECL static void close_descriptors(); // Helper function to start a wait operation. ASIO_DECL void start_wait_op(implementation_type& impl, signal_op* op); // The scheduler used for dispatching handlers. #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif scheduler_impl& scheduler_; #if !defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_RUNTIME) \ && !defined(__CYGWIN__) // The type used for registering for pipe reactor notifications. class pipe_read_op; // The reactor used for waiting for pipe readiness. reactor& reactor_; // The per-descriptor reactor data used for the pipe. reactor::per_descriptor_data reactor_data_; #endif // !defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_RUNTIME) // && !defined(__CYGWIN__) // A mapping from signal number to the registered signal sets. registration* registrations_[max_signal_number]; // Pointers to adjacent services in linked list. signal_set_service* next_; signal_set_service* prev_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/signal_set_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/socket_holder.hpp ================================================ // // detail/socket_holder.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SOCKET_HOLDER_HPP #define ASIO_DETAIL_SOCKET_HOLDER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Implement the resource acquisition is initialisation idiom for sockets. class socket_holder : private noncopyable { public: // Construct as an uninitialised socket. socket_holder() : socket_(invalid_socket) { } // Construct to take ownership of the specified socket. explicit socket_holder(socket_type s) : socket_(s) { } // Destructor. ~socket_holder() { if (socket_ != invalid_socket) { asio::error_code ec; socket_ops::state_type state = 0; socket_ops::close(socket_, state, true, ec); } } // Get the underlying socket. socket_type get() const { return socket_; } // Reset to an uninitialised socket. void reset() { if (socket_ != invalid_socket) { asio::error_code ec; socket_ops::state_type state = 0; socket_ops::close(socket_, state, true, ec); socket_ = invalid_socket; } } // Reset to take ownership of the specified socket. void reset(socket_type s) { reset(); socket_ = s; } // Release ownership of the socket. socket_type release() { socket_type tmp = socket_; socket_ = invalid_socket; return tmp; } private: // The underlying socket. socket_type socket_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SOCKET_HOLDER_HPP ================================================ FILE: src/third_party/asio/detail/socket_ops.hpp ================================================ // // detail/socket_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SOCKET_OPS_HPP #define ASIO_DETAIL_SOCKET_OPS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error_code.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { namespace socket_ops { // Socket state bits. enum { // The user wants a non-blocking socket. user_set_non_blocking = 1, // The socket has been set non-blocking. internal_non_blocking = 2, // Helper "state" used to determine whether the socket is non-blocking. non_blocking = user_set_non_blocking | internal_non_blocking, // User wants connection_aborted errors, which are disabled by default. enable_connection_aborted = 4, // The user set the linger option. Needs to be checked when closing. user_set_linger = 8, // The socket is stream-oriented. stream_oriented = 16, // The socket is datagram-oriented. datagram_oriented = 32, // The socket may have been dup()-ed. possible_dup = 64 }; typedef unsigned char state_type; struct noop_deleter { void operator()(void*) {} }; typedef shared_ptr shared_cancel_token_type; typedef weak_ptr weak_cancel_token_type; #if !defined(ASIO_WINDOWS_RUNTIME) ASIO_DECL socket_type accept(socket_type s, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec); ASIO_DECL socket_type sync_accept(socket_type s, state_type state, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec); #if defined(ASIO_HAS_IOCP) ASIO_DECL void complete_iocp_accept(socket_type s, void* output_buffer, DWORD address_length, socket_addr_type* addr, std::size_t* addrlen, socket_type new_socket, asio::error_code& ec); #else // defined(ASIO_HAS_IOCP) ASIO_DECL bool non_blocking_accept(socket_type s, state_type state, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec, socket_type& new_socket); #endif // defined(ASIO_HAS_IOCP) ASIO_DECL int bind(socket_type s, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec); ASIO_DECL int close(socket_type s, state_type& state, bool destruction, asio::error_code& ec); ASIO_DECL bool set_user_non_blocking(socket_type s, state_type& state, bool value, asio::error_code& ec); ASIO_DECL bool set_internal_non_blocking(socket_type s, state_type& state, bool value, asio::error_code& ec); ASIO_DECL int shutdown(socket_type s, int what, asio::error_code& ec); ASIO_DECL int connect(socket_type s, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec); ASIO_DECL void sync_connect(socket_type s, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec); #if defined(ASIO_HAS_IOCP) ASIO_DECL void complete_iocp_connect(socket_type s, asio::error_code& ec); #endif // defined(ASIO_HAS_IOCP) ASIO_DECL bool non_blocking_connect(socket_type s, asio::error_code& ec); ASIO_DECL int socketpair(int af, int type, int protocol, socket_type sv[2], asio::error_code& ec); ASIO_DECL bool sockatmark(socket_type s, asio::error_code& ec); ASIO_DECL size_t available(socket_type s, asio::error_code& ec); ASIO_DECL int listen(socket_type s, int backlog, asio::error_code& ec); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) typedef WSABUF buf; #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) typedef iovec buf; #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) ASIO_DECL void init_buf(buf& b, void* data, size_t size); ASIO_DECL void init_buf(buf& b, const void* data, size_t size); ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, size_t count, int flags, asio::error_code& ec); ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, size_t count, int flags, bool all_empty, asio::error_code& ec); #if defined(ASIO_HAS_IOCP) ASIO_DECL void complete_iocp_recv(state_type state, const weak_cancel_token_type& cancel_token, bool all_empty, asio::error_code& ec, size_t bytes_transferred); #else // defined(ASIO_HAS_IOCP) ASIO_DECL bool non_blocking_recv(socket_type s, buf* bufs, size_t count, int flags, bool is_stream, asio::error_code& ec, size_t& bytes_transferred); #endif // defined(ASIO_HAS_IOCP) ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec); ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec); #if defined(ASIO_HAS_IOCP) ASIO_DECL void complete_iocp_recvfrom( const weak_cancel_token_type& cancel_token, asio::error_code& ec); #else // defined(ASIO_HAS_IOCP) ASIO_DECL bool non_blocking_recvfrom(socket_type s, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec, size_t& bytes_transferred); #endif // defined(ASIO_HAS_IOCP) ASIO_DECL signed_size_type recvmsg(socket_type s, buf* bufs, size_t count, int in_flags, int& out_flags, asio::error_code& ec); ASIO_DECL size_t sync_recvmsg(socket_type s, state_type state, buf* bufs, size_t count, int in_flags, int& out_flags, asio::error_code& ec); #if defined(ASIO_HAS_IOCP) ASIO_DECL void complete_iocp_recvmsg( const weak_cancel_token_type& cancel_token, asio::error_code& ec); #else // defined(ASIO_HAS_IOCP) ASIO_DECL bool non_blocking_recvmsg(socket_type s, buf* bufs, size_t count, int in_flags, int& out_flags, asio::error_code& ec, size_t& bytes_transferred); #endif // defined(ASIO_HAS_IOCP) ASIO_DECL signed_size_type send(socket_type s, const buf* bufs, size_t count, int flags, asio::error_code& ec); ASIO_DECL size_t sync_send(socket_type s, state_type state, const buf* bufs, size_t count, int flags, bool all_empty, asio::error_code& ec); #if defined(ASIO_HAS_IOCP) ASIO_DECL void complete_iocp_send( const weak_cancel_token_type& cancel_token, asio::error_code& ec); #else // defined(ASIO_HAS_IOCP) ASIO_DECL bool non_blocking_send(socket_type s, const buf* bufs, size_t count, int flags, asio::error_code& ec, size_t& bytes_transferred); #endif // defined(ASIO_HAS_IOCP) ASIO_DECL signed_size_type sendto(socket_type s, const buf* bufs, size_t count, int flags, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec); ASIO_DECL size_t sync_sendto(socket_type s, state_type state, const buf* bufs, size_t count, int flags, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec); #if !defined(ASIO_HAS_IOCP) ASIO_DECL bool non_blocking_sendto(socket_type s, const buf* bufs, size_t count, int flags, const socket_addr_type* addr, std::size_t addrlen, asio::error_code& ec, size_t& bytes_transferred); #endif // !defined(ASIO_HAS_IOCP) ASIO_DECL socket_type socket(int af, int type, int protocol, asio::error_code& ec); ASIO_DECL int setsockopt(socket_type s, state_type& state, int level, int optname, const void* optval, std::size_t optlen, asio::error_code& ec); ASIO_DECL int getsockopt(socket_type s, state_type state, int level, int optname, void* optval, size_t* optlen, asio::error_code& ec); ASIO_DECL int getpeername(socket_type s, socket_addr_type* addr, std::size_t* addrlen, bool cached, asio::error_code& ec); ASIO_DECL int getsockname(socket_type s, socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec); ASIO_DECL int ioctl(socket_type s, state_type& state, int cmd, ioctl_arg_type* arg, asio::error_code& ec); ASIO_DECL int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout, asio::error_code& ec); ASIO_DECL int poll_read(socket_type s, state_type state, int msec, asio::error_code& ec); ASIO_DECL int poll_write(socket_type s, state_type state, int msec, asio::error_code& ec); ASIO_DECL int poll_error(socket_type s, state_type state, int msec, asio::error_code& ec); ASIO_DECL int poll_connect(socket_type s, int msec, asio::error_code& ec); #endif // !defined(ASIO_WINDOWS_RUNTIME) ASIO_DECL const char* inet_ntop(int af, const void* src, char* dest, size_t length, unsigned long scope_id, asio::error_code& ec); ASIO_DECL int inet_pton(int af, const char* src, void* dest, unsigned long* scope_id, asio::error_code& ec); ASIO_DECL int gethostname(char* name, int namelen, asio::error_code& ec); #if !defined(ASIO_WINDOWS_RUNTIME) ASIO_DECL asio::error_code getaddrinfo(const char* host, const char* service, const addrinfo_type& hints, addrinfo_type** result, asio::error_code& ec); ASIO_DECL asio::error_code background_getaddrinfo( const weak_cancel_token_type& cancel_token, const char* host, const char* service, const addrinfo_type& hints, addrinfo_type** result, asio::error_code& ec); ASIO_DECL void freeaddrinfo(addrinfo_type* ai); ASIO_DECL asio::error_code getnameinfo( const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int flags, asio::error_code& ec); ASIO_DECL asio::error_code sync_getnameinfo( const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int sock_type, asio::error_code& ec); ASIO_DECL asio::error_code background_getnameinfo( const weak_cancel_token_type& cancel_token, const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int sock_type, asio::error_code& ec); #endif // !defined(ASIO_WINDOWS_RUNTIME) ASIO_DECL u_long_type network_to_host_long(u_long_type value); ASIO_DECL u_long_type host_to_network_long(u_long_type value); ASIO_DECL u_short_type network_to_host_short(u_short_type value); ASIO_DECL u_short_type host_to_network_short(u_short_type value); } // namespace socket_ops } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/socket_ops.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_SOCKET_OPS_HPP ================================================ FILE: src/third_party/asio/detail/socket_option.hpp ================================================ // // detail/socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SOCKET_OPTION_HPP #define ASIO_DETAIL_SOCKET_OPTION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { namespace socket_option { // Helper template for implementing boolean-based options. template class boolean { public: // Default constructor. boolean() : value_(0) { } // Construct with a specific option value. explicit boolean(bool v) : value_(v ? 1 : 0) { } // Set the current value of the boolean. boolean& operator=(bool v) { value_ = v ? 1 : 0; return *this; } // Get the current value of the boolean. bool value() const { return !!value_; } // Convert to bool. operator bool() const { return !!value_; } // Test for false. bool operator!() const { return !value_; } // Get the level of the socket option. template int level(const Protocol&) const { return Level; } // Get the name of the socket option. template int name(const Protocol&) const { return Name; } // Get the address of the boolean data. template int* data(const Protocol&) { return &value_; } // Get the address of the boolean data. template const int* data(const Protocol&) const { return &value_; } // Get the size of the boolean data. template std::size_t size(const Protocol&) const { return sizeof(value_); } // Set the size of the boolean data. template void resize(const Protocol&, std::size_t s) { // On some platforms (e.g. Windows Vista), the getsockopt function will // return the size of a boolean socket option as one byte, even though a // four byte integer was passed in. switch (s) { case sizeof(char): value_ = *reinterpret_cast(&value_) ? 1 : 0; break; case sizeof(value_): break; default: { std::length_error ex("boolean socket option resize"); asio::detail::throw_exception(ex); } } } private: int value_; }; // Helper template for implementing integer options. template class integer { public: // Default constructor. integer() : value_(0) { } // Construct with a specific option value. explicit integer(int v) : value_(v) { } // Set the value of the int option. integer& operator=(int v) { value_ = v; return *this; } // Get the current value of the int option. int value() const { return value_; } // Get the level of the socket option. template int level(const Protocol&) const { return Level; } // Get the name of the socket option. template int name(const Protocol&) const { return Name; } // Get the address of the int data. template int* data(const Protocol&) { return &value_; } // Get the address of the int data. template const int* data(const Protocol&) const { return &value_; } // Get the size of the int data. template std::size_t size(const Protocol&) const { return sizeof(value_); } // Set the size of the int data. template void resize(const Protocol&, std::size_t s) { if (s != sizeof(value_)) { std::length_error ex("integer socket option resize"); asio::detail::throw_exception(ex); } } private: int value_; }; // Helper template for implementing linger options. template class linger { public: // Default constructor. linger() { value_.l_onoff = 0; value_.l_linger = 0; } // Construct with specific option values. linger(bool e, int t) { enabled(e); timeout ASIO_PREVENT_MACRO_SUBSTITUTION(t); } // Set the value for whether linger is enabled. void enabled(bool value) { value_.l_onoff = value ? 1 : 0; } // Get the value for whether linger is enabled. bool enabled() const { return value_.l_onoff != 0; } // Set the value for the linger timeout. void timeout ASIO_PREVENT_MACRO_SUBSTITUTION(int value) { #if defined(WIN32) value_.l_linger = static_cast(value); #else value_.l_linger = value; #endif } // Get the value for the linger timeout. int timeout ASIO_PREVENT_MACRO_SUBSTITUTION() const { return static_cast(value_.l_linger); } // Get the level of the socket option. template int level(const Protocol&) const { return Level; } // Get the name of the socket option. template int name(const Protocol&) const { return Name; } // Get the address of the linger data. template detail::linger_type* data(const Protocol&) { return &value_; } // Get the address of the linger data. template const detail::linger_type* data(const Protocol&) const { return &value_; } // Get the size of the linger data. template std::size_t size(const Protocol&) const { return sizeof(value_); } // Set the size of the int data. template void resize(const Protocol&, std::size_t s) { if (s != sizeof(value_)) { std::length_error ex("linger socket option resize"); asio::detail::throw_exception(ex); } } private: detail::linger_type value_; }; } // namespace socket_option } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SOCKET_OPTION_HPP ================================================ FILE: src/third_party/asio/detail/socket_select_interrupter.hpp ================================================ // // detail/socket_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP #define ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_WINDOWS_RUNTIME) #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class socket_select_interrupter { public: // Constructor. ASIO_DECL socket_select_interrupter(); // Destructor. ASIO_DECL ~socket_select_interrupter(); // Recreate the interrupter's descriptors. Used after a fork. ASIO_DECL void recreate(); // Interrupt the select call. ASIO_DECL void interrupt(); // Reset the select interrupt. Returns true if the call was interrupted. ASIO_DECL bool reset(); // Get the read descriptor to be passed to select. socket_type read_descriptor() const { return read_descriptor_; } private: // Open the descriptors. Throws on error. ASIO_DECL void open_descriptors(); // Close the descriptors. ASIO_DECL void close_descriptors(); // The read end of a connection used to interrupt the select call. This file // descriptor is passed to select such that when it is time to stop, a single // byte will be written on the other end of the connection and this // descriptor will become readable. socket_type read_descriptor_; // The write end of a connection used to interrupt the select call. A single // byte may be written to this to wake up the select which is waiting for the // other end to become readable. socket_type write_descriptor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/socket_select_interrupter.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) #endif // !defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP ================================================ FILE: src/third_party/asio/detail/socket_types.hpp ================================================ // // detail/socket_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SOCKET_TYPES_HPP #define ASIO_DETAIL_SOCKET_TYPES_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) // Empty. #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) # error WinSock.h has already been included # endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) # if defined(__BORLANDC__) # include // Needed for __errno # if !defined(_WSPIAPI_H_) # define _WSPIAPI_H_ # define ASIO_WSPIAPI_H_DEFINED # endif // !defined(_WSPIAPI_H_) # endif // defined(__BORLANDC__) # include # include # if defined(WINAPI_FAMILY) # if ((WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP) != 0) # include # endif // ((WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP) != 0) # endif // defined(WINAPI_FAMILY) # if !defined(ASIO_WINDOWS_APP) # include # endif // !defined(ASIO_WINDOWS_APP) # if defined(ASIO_WSPIAPI_H_DEFINED) # undef _WSPIAPI_H_ # undef ASIO_WSPIAPI_H_DEFINED # endif // defined(ASIO_WSPIAPI_H_DEFINED) # if !defined(ASIO_NO_DEFAULT_LINKED_LIBS) # if defined(UNDER_CE) # pragma comment(lib, "ws2.lib") # elif defined(_MSC_VER) || defined(__BORLANDC__) # pragma comment(lib, "ws2_32.lib") # if !defined(ASIO_WINDOWS_APP) # pragma comment(lib, "mswsock.lib") # endif // !defined(ASIO_WINDOWS_APP) # endif // defined(_MSC_VER) || defined(__BORLANDC__) # endif // !defined(ASIO_NO_DEFAULT_LINKED_LIBS) # include "asio/detail/old_win_sdk_compat.hpp" #else # include # if (defined(__MACH__) && defined(__APPLE__)) \ || defined(__FreeBSD__) || defined(__NetBSD__) \ || defined(__OpenBSD__) || defined(__linux__) \ || defined(__EMSCRIPTEN__) # include # elif !defined(__SYMBIAN32__) # include # endif # include # include # include # if defined(__hpux) # include # endif # if !defined(__hpux) || defined(__SELECT) # include # endif # include # include # include # include # if !defined(__SYMBIAN32__) # include # endif # include # include # include # include # if defined(__sun) # include # include # endif #endif #include "asio/detail/push_options.hpp" namespace asio { namespace detail { #if defined(ASIO_WINDOWS_RUNTIME) const int max_addr_v4_str_len = 256; const int max_addr_v6_str_len = 256; typedef unsigned __int32 u_long_type; typedef unsigned __int16 u_short_type; struct in4_addr_type { u_long_type s_addr; }; struct in4_mreq_type { in4_addr_type imr_multiaddr, imr_interface; }; struct in6_addr_type { unsigned char s6_addr[16]; }; struct in6_mreq_type { in6_addr_type ipv6mr_multiaddr; unsigned long ipv6mr_interface; }; struct socket_addr_type { int sa_family; }; struct sockaddr_in4_type { int sin_family; in4_addr_type sin_addr; u_short_type sin_port; }; struct sockaddr_in6_type { int sin6_family; in6_addr_type sin6_addr; u_short_type sin6_port; u_long_type sin6_flowinfo; u_long_type sin6_scope_id; }; struct sockaddr_storage_type { int ss_family; unsigned char ss_bytes[128 - sizeof(int)]; }; struct addrinfo_type { int ai_flags; int ai_family, ai_socktype, ai_protocol; int ai_addrlen; const void* ai_addr; const char* ai_canonname; addrinfo_type* ai_next; }; struct linger_type { u_short_type l_onoff, l_linger; }; typedef u_long_type ioctl_arg_type; typedef int signed_size_type; # define ASIO_OS_DEF(c) ASIO_OS_DEF_##c # define ASIO_OS_DEF_AF_UNSPEC 0 # define ASIO_OS_DEF_AF_INET 2 # define ASIO_OS_DEF_AF_INET6 23 # define ASIO_OS_DEF_SOCK_STREAM 1 # define ASIO_OS_DEF_SOCK_DGRAM 2 # define ASIO_OS_DEF_SOCK_RAW 3 # define ASIO_OS_DEF_SOCK_SEQPACKET 5 # define ASIO_OS_DEF_IPPROTO_IP 0 # define ASIO_OS_DEF_IPPROTO_IPV6 41 # define ASIO_OS_DEF_IPPROTO_TCP 6 # define ASIO_OS_DEF_IPPROTO_UDP 17 # define ASIO_OS_DEF_IPPROTO_ICMP 1 # define ASIO_OS_DEF_IPPROTO_ICMPV6 58 # define ASIO_OS_DEF_FIONBIO 1 # define ASIO_OS_DEF_FIONREAD 2 # define ASIO_OS_DEF_INADDR_ANY 0 # define ASIO_OS_DEF_MSG_OOB 0x1 # define ASIO_OS_DEF_MSG_PEEK 0x2 # define ASIO_OS_DEF_MSG_DONTROUTE 0x4 # define ASIO_OS_DEF_MSG_EOR 0 // Not supported. # define ASIO_OS_DEF_SHUT_RD 0x0 # define ASIO_OS_DEF_SHUT_WR 0x1 # define ASIO_OS_DEF_SHUT_RDWR 0x2 # define ASIO_OS_DEF_SOMAXCONN 0x7fffffff # define ASIO_OS_DEF_SOL_SOCKET 0xffff # define ASIO_OS_DEF_SO_BROADCAST 0x20 # define ASIO_OS_DEF_SO_DEBUG 0x1 # define ASIO_OS_DEF_SO_DONTROUTE 0x10 # define ASIO_OS_DEF_SO_KEEPALIVE 0x8 # define ASIO_OS_DEF_SO_LINGER 0x80 # define ASIO_OS_DEF_SO_OOBINLINE 0x100 # define ASIO_OS_DEF_SO_SNDBUF 0x1001 # define ASIO_OS_DEF_SO_RCVBUF 0x1002 # define ASIO_OS_DEF_SO_SNDLOWAT 0x1003 # define ASIO_OS_DEF_SO_RCVLOWAT 0x1004 # define ASIO_OS_DEF_SO_REUSEADDR 0x4 # define ASIO_OS_DEF_TCP_NODELAY 0x1 # define ASIO_OS_DEF_IP_MULTICAST_IF 2 # define ASIO_OS_DEF_IP_MULTICAST_TTL 3 # define ASIO_OS_DEF_IP_MULTICAST_LOOP 4 # define ASIO_OS_DEF_IP_ADD_MEMBERSHIP 5 # define ASIO_OS_DEF_IP_DROP_MEMBERSHIP 6 # define ASIO_OS_DEF_IP_TTL 7 # define ASIO_OS_DEF_IPV6_UNICAST_HOPS 4 # define ASIO_OS_DEF_IPV6_MULTICAST_IF 9 # define ASIO_OS_DEF_IPV6_MULTICAST_HOPS 10 # define ASIO_OS_DEF_IPV6_MULTICAST_LOOP 11 # define ASIO_OS_DEF_IPV6_JOIN_GROUP 12 # define ASIO_OS_DEF_IPV6_LEAVE_GROUP 13 # define ASIO_OS_DEF_AI_CANONNAME 0x2 # define ASIO_OS_DEF_AI_PASSIVE 0x1 # define ASIO_OS_DEF_AI_NUMERICHOST 0x4 # define ASIO_OS_DEF_AI_NUMERICSERV 0x8 # define ASIO_OS_DEF_AI_V4MAPPED 0x800 # define ASIO_OS_DEF_AI_ALL 0x100 # define ASIO_OS_DEF_AI_ADDRCONFIG 0x400 #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) typedef SOCKET socket_type; const SOCKET invalid_socket = INVALID_SOCKET; const int socket_error_retval = SOCKET_ERROR; const int max_addr_v4_str_len = 256; const int max_addr_v6_str_len = 256; typedef sockaddr socket_addr_type; typedef in_addr in4_addr_type; typedef ip_mreq in4_mreq_type; typedef sockaddr_in sockaddr_in4_type; # if defined(ASIO_HAS_OLD_WIN_SDK) typedef in6_addr_emulation in6_addr_type; typedef ipv6_mreq_emulation in6_mreq_type; typedef sockaddr_in6_emulation sockaddr_in6_type; typedef sockaddr_storage_emulation sockaddr_storage_type; typedef addrinfo_emulation addrinfo_type; # else typedef in6_addr in6_addr_type; typedef ipv6_mreq in6_mreq_type; typedef sockaddr_in6 sockaddr_in6_type; typedef sockaddr_storage sockaddr_storage_type; typedef addrinfo addrinfo_type; # endif typedef ::linger linger_type; typedef unsigned long ioctl_arg_type; typedef u_long u_long_type; typedef u_short u_short_type; typedef int signed_size_type; # define ASIO_OS_DEF(c) ASIO_OS_DEF_##c # define ASIO_OS_DEF_AF_UNSPEC AF_UNSPEC # define ASIO_OS_DEF_AF_INET AF_INET # define ASIO_OS_DEF_AF_INET6 AF_INET6 # define ASIO_OS_DEF_SOCK_STREAM SOCK_STREAM # define ASIO_OS_DEF_SOCK_DGRAM SOCK_DGRAM # define ASIO_OS_DEF_SOCK_RAW SOCK_RAW # define ASIO_OS_DEF_SOCK_SEQPACKET SOCK_SEQPACKET # define ASIO_OS_DEF_IPPROTO_IP IPPROTO_IP # define ASIO_OS_DEF_IPPROTO_IPV6 IPPROTO_IPV6 # define ASIO_OS_DEF_IPPROTO_TCP IPPROTO_TCP # define ASIO_OS_DEF_IPPROTO_UDP IPPROTO_UDP # define ASIO_OS_DEF_IPPROTO_ICMP IPPROTO_ICMP # define ASIO_OS_DEF_IPPROTO_ICMPV6 IPPROTO_ICMPV6 # define ASIO_OS_DEF_FIONBIO FIONBIO # define ASIO_OS_DEF_FIONREAD FIONREAD # define ASIO_OS_DEF_INADDR_ANY INADDR_ANY # define ASIO_OS_DEF_MSG_OOB MSG_OOB # define ASIO_OS_DEF_MSG_PEEK MSG_PEEK # define ASIO_OS_DEF_MSG_DONTROUTE MSG_DONTROUTE # define ASIO_OS_DEF_MSG_EOR 0 // Not supported on Windows. # define ASIO_OS_DEF_SHUT_RD SD_RECEIVE # define ASIO_OS_DEF_SHUT_WR SD_SEND # define ASIO_OS_DEF_SHUT_RDWR SD_BOTH # define ASIO_OS_DEF_SOMAXCONN SOMAXCONN # define ASIO_OS_DEF_SOL_SOCKET SOL_SOCKET # define ASIO_OS_DEF_SO_BROADCAST SO_BROADCAST # define ASIO_OS_DEF_SO_DEBUG SO_DEBUG # define ASIO_OS_DEF_SO_DONTROUTE SO_DONTROUTE # define ASIO_OS_DEF_SO_KEEPALIVE SO_KEEPALIVE # define ASIO_OS_DEF_SO_LINGER SO_LINGER # define ASIO_OS_DEF_SO_OOBINLINE SO_OOBINLINE # define ASIO_OS_DEF_SO_SNDBUF SO_SNDBUF # define ASIO_OS_DEF_SO_RCVBUF SO_RCVBUF # define ASIO_OS_DEF_SO_SNDLOWAT SO_SNDLOWAT # define ASIO_OS_DEF_SO_RCVLOWAT SO_RCVLOWAT # define ASIO_OS_DEF_SO_REUSEADDR SO_REUSEADDR # define ASIO_OS_DEF_TCP_NODELAY TCP_NODELAY # define ASIO_OS_DEF_IP_MULTICAST_IF IP_MULTICAST_IF # define ASIO_OS_DEF_IP_MULTICAST_TTL IP_MULTICAST_TTL # define ASIO_OS_DEF_IP_MULTICAST_LOOP IP_MULTICAST_LOOP # define ASIO_OS_DEF_IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP # define ASIO_OS_DEF_IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP # define ASIO_OS_DEF_IP_TTL IP_TTL # define ASIO_OS_DEF_IPV6_UNICAST_HOPS IPV6_UNICAST_HOPS # define ASIO_OS_DEF_IPV6_MULTICAST_IF IPV6_MULTICAST_IF # define ASIO_OS_DEF_IPV6_MULTICAST_HOPS IPV6_MULTICAST_HOPS # define ASIO_OS_DEF_IPV6_MULTICAST_LOOP IPV6_MULTICAST_LOOP # define ASIO_OS_DEF_IPV6_JOIN_GROUP IPV6_JOIN_GROUP # define ASIO_OS_DEF_IPV6_LEAVE_GROUP IPV6_LEAVE_GROUP # define ASIO_OS_DEF_AI_CANONNAME AI_CANONNAME # define ASIO_OS_DEF_AI_PASSIVE AI_PASSIVE # define ASIO_OS_DEF_AI_NUMERICHOST AI_NUMERICHOST # if defined(AI_NUMERICSERV) # define ASIO_OS_DEF_AI_NUMERICSERV AI_NUMERICSERV # else # define ASIO_OS_DEF_AI_NUMERICSERV 0 # endif # if defined(AI_V4MAPPED) # define ASIO_OS_DEF_AI_V4MAPPED AI_V4MAPPED # else # define ASIO_OS_DEF_AI_V4MAPPED 0 # endif # if defined(AI_ALL) # define ASIO_OS_DEF_AI_ALL AI_ALL # else # define ASIO_OS_DEF_AI_ALL 0 # endif # if defined(AI_ADDRCONFIG) # define ASIO_OS_DEF_AI_ADDRCONFIG AI_ADDRCONFIG # else # define ASIO_OS_DEF_AI_ADDRCONFIG 0 # endif # if defined (_WIN32_WINNT) const int max_iov_len = 64; # else const int max_iov_len = 16; # endif #else typedef int socket_type; const int invalid_socket = -1; const int socket_error_retval = -1; const int max_addr_v4_str_len = INET_ADDRSTRLEN; #if defined(INET6_ADDRSTRLEN) const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE; #else // defined(INET6_ADDRSTRLEN) const int max_addr_v6_str_len = 256; #endif // defined(INET6_ADDRSTRLEN) typedef sockaddr socket_addr_type; typedef in_addr in4_addr_type; # if defined(__hpux) // HP-UX doesn't provide ip_mreq when _XOPEN_SOURCE_EXTENDED is defined. struct in4_mreq_type { struct in_addr imr_multiaddr; struct in_addr imr_interface; }; # else typedef ip_mreq in4_mreq_type; # endif typedef sockaddr_in sockaddr_in4_type; typedef in6_addr in6_addr_type; typedef ipv6_mreq in6_mreq_type; typedef sockaddr_in6 sockaddr_in6_type; typedef sockaddr_storage sockaddr_storage_type; typedef sockaddr_un sockaddr_un_type; typedef addrinfo addrinfo_type; typedef ::linger linger_type; typedef int ioctl_arg_type; typedef uint32_t u_long_type; typedef uint16_t u_short_type; #if defined(ASIO_HAS_SSIZE_T) typedef ssize_t signed_size_type; #else // defined(ASIO_HAS_SSIZE_T) typedef int signed_size_type; #endif // defined(ASIO_HAS_SSIZE_T) # define ASIO_OS_DEF(c) ASIO_OS_DEF_##c # define ASIO_OS_DEF_AF_UNSPEC AF_UNSPEC # define ASIO_OS_DEF_AF_INET AF_INET # define ASIO_OS_DEF_AF_INET6 AF_INET6 # define ASIO_OS_DEF_SOCK_STREAM SOCK_STREAM # define ASIO_OS_DEF_SOCK_DGRAM SOCK_DGRAM # define ASIO_OS_DEF_SOCK_RAW SOCK_RAW # define ASIO_OS_DEF_SOCK_SEQPACKET SOCK_SEQPACKET # define ASIO_OS_DEF_IPPROTO_IP IPPROTO_IP # define ASIO_OS_DEF_IPPROTO_IPV6 IPPROTO_IPV6 # define ASIO_OS_DEF_IPPROTO_TCP IPPROTO_TCP # define ASIO_OS_DEF_IPPROTO_UDP IPPROTO_UDP # define ASIO_OS_DEF_IPPROTO_ICMP IPPROTO_ICMP # define ASIO_OS_DEF_IPPROTO_ICMPV6 IPPROTO_ICMPV6 # define ASIO_OS_DEF_FIONBIO FIONBIO # define ASIO_OS_DEF_FIONREAD FIONREAD # define ASIO_OS_DEF_INADDR_ANY INADDR_ANY # define ASIO_OS_DEF_MSG_OOB MSG_OOB # define ASIO_OS_DEF_MSG_PEEK MSG_PEEK # define ASIO_OS_DEF_MSG_DONTROUTE MSG_DONTROUTE # define ASIO_OS_DEF_MSG_EOR MSG_EOR # define ASIO_OS_DEF_SHUT_RD SHUT_RD # define ASIO_OS_DEF_SHUT_WR SHUT_WR # define ASIO_OS_DEF_SHUT_RDWR SHUT_RDWR # define ASIO_OS_DEF_SOMAXCONN SOMAXCONN # define ASIO_OS_DEF_SOL_SOCKET SOL_SOCKET # define ASIO_OS_DEF_SO_BROADCAST SO_BROADCAST # define ASIO_OS_DEF_SO_DEBUG SO_DEBUG # define ASIO_OS_DEF_SO_DONTROUTE SO_DONTROUTE # define ASIO_OS_DEF_SO_KEEPALIVE SO_KEEPALIVE # define ASIO_OS_DEF_SO_LINGER SO_LINGER # define ASIO_OS_DEF_SO_OOBINLINE SO_OOBINLINE # define ASIO_OS_DEF_SO_SNDBUF SO_SNDBUF # define ASIO_OS_DEF_SO_RCVBUF SO_RCVBUF # define ASIO_OS_DEF_SO_SNDLOWAT SO_SNDLOWAT # define ASIO_OS_DEF_SO_RCVLOWAT SO_RCVLOWAT # define ASIO_OS_DEF_SO_REUSEADDR SO_REUSEADDR # define ASIO_OS_DEF_TCP_NODELAY TCP_NODELAY # define ASIO_OS_DEF_IP_MULTICAST_IF IP_MULTICAST_IF # define ASIO_OS_DEF_IP_MULTICAST_TTL IP_MULTICAST_TTL # define ASIO_OS_DEF_IP_MULTICAST_LOOP IP_MULTICAST_LOOP # define ASIO_OS_DEF_IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP # define ASIO_OS_DEF_IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP # define ASIO_OS_DEF_IP_TTL IP_TTL # define ASIO_OS_DEF_IPV6_UNICAST_HOPS IPV6_UNICAST_HOPS # define ASIO_OS_DEF_IPV6_MULTICAST_IF IPV6_MULTICAST_IF # define ASIO_OS_DEF_IPV6_MULTICAST_HOPS IPV6_MULTICAST_HOPS # define ASIO_OS_DEF_IPV6_MULTICAST_LOOP IPV6_MULTICAST_LOOP # define ASIO_OS_DEF_IPV6_JOIN_GROUP IPV6_JOIN_GROUP # define ASIO_OS_DEF_IPV6_LEAVE_GROUP IPV6_LEAVE_GROUP # define ASIO_OS_DEF_AI_CANONNAME AI_CANONNAME # define ASIO_OS_DEF_AI_PASSIVE AI_PASSIVE # define ASIO_OS_DEF_AI_NUMERICHOST AI_NUMERICHOST # if defined(AI_NUMERICSERV) # define ASIO_OS_DEF_AI_NUMERICSERV AI_NUMERICSERV # else # define ASIO_OS_DEF_AI_NUMERICSERV 0 # endif // Note: QNX Neutrino 6.3 defines AI_V4MAPPED, AI_ALL and AI_ADDRCONFIG but // does not implement them. Therefore they are specifically excluded here. # if defined(AI_V4MAPPED) && !defined(__QNXNTO__) # define ASIO_OS_DEF_AI_V4MAPPED AI_V4MAPPED # else # define ASIO_OS_DEF_AI_V4MAPPED 0 # endif # if defined(AI_ALL) && !defined(__QNXNTO__) # define ASIO_OS_DEF_AI_ALL AI_ALL # else # define ASIO_OS_DEF_AI_ALL 0 # endif # if defined(AI_ADDRCONFIG) && !defined(__QNXNTO__) # define ASIO_OS_DEF_AI_ADDRCONFIG AI_ADDRCONFIG # else # define ASIO_OS_DEF_AI_ADDRCONFIG 0 # endif # if defined(IOV_MAX) const int max_iov_len = IOV_MAX; # else // POSIX platforms are not required to define IOV_MAX. const int max_iov_len = 16; # endif #endif const int custom_socket_option_level = 0xA5100000; const int enable_connection_aborted_option = 1; const int always_fail_option = 2; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_SOCKET_TYPES_HPP ================================================ FILE: src/third_party/asio/detail/solaris_fenced_block.hpp ================================================ // // detail/solaris_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP #define ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(__sun) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class solaris_fenced_block : private noncopyable { public: enum half_t { half }; enum full_t { full }; // Constructor for a half fenced block. explicit solaris_fenced_block(half_t) { } // Constructor for a full fenced block. explicit solaris_fenced_block(full_t) { membar_consumer(); } // Destructor. ~solaris_fenced_block() { membar_producer(); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(__sun) #endif // ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/static_mutex.hpp ================================================ // // detail/static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STATIC_MUTEX_HPP #define ASIO_DETAIL_STATIC_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) # include "asio/detail/null_static_mutex.hpp" #elif defined(ASIO_WINDOWS) # include "asio/detail/win_static_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_static_mutex.hpp" #elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_static_mutex.hpp" #else # error Only Windows and POSIX are supported! #endif namespace asio { namespace detail { #if !defined(ASIO_HAS_THREADS) typedef null_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_NULL_STATIC_MUTEX_INIT #elif defined(ASIO_WINDOWS) typedef win_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_WIN_STATIC_MUTEX_INIT #elif defined(ASIO_HAS_PTHREADS) typedef posix_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_POSIX_STATIC_MUTEX_INIT #elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_STD_STATIC_MUTEX_INIT #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_STATIC_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/std_event.hpp ================================================ // // detail/std_event.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STD_EVENT_HPP #define ASIO_DETAIL_STD_EVENT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #include #include #include "asio/detail/assert.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class std_event : private noncopyable { public: // Constructor. std_event() : state_(0) { } // Destructor. ~std_event() { } // Signal the event. (Retained for backward compatibility.) template void signal(Lock& lock) { this->signal_all(lock); } // Signal all waiters. template void signal_all(Lock& lock) { ASIO_ASSERT(lock.locked()); (void)lock; state_ |= 1; cond_.notify_all(); } // Unlock the mutex and signal one waiter. template void unlock_and_signal_one(Lock& lock) { ASIO_ASSERT(lock.locked()); state_ |= 1; bool have_waiters = (state_ > 1); lock.unlock(); if (have_waiters) cond_.notify_one(); } // If there's a waiter, unlock the mutex and signal it. template bool maybe_unlock_and_signal_one(Lock& lock) { ASIO_ASSERT(lock.locked()); state_ |= 1; if (state_ > 1) { lock.unlock(); cond_.notify_one(); return true; } return false; } // Reset the event. template void clear(Lock& lock) { ASIO_ASSERT(lock.locked()); (void)lock; state_ &= ~std::size_t(1); } // Wait for the event to become signalled. template void wait(Lock& lock) { ASIO_ASSERT(lock.locked()); unique_lock_adapter u_lock(lock); while ((state_ & 1) == 0) { waiter w(state_); cond_.wait(u_lock.unique_lock_); } } // Timed wait for the event to become signalled. template bool wait_for_usec(Lock& lock, long usec) { ASIO_ASSERT(lock.locked()); unique_lock_adapter u_lock(lock); if ((state_ & 1) == 0) { waiter w(state_); cond_.wait_for(u_lock.unique_lock_, std::chrono::microseconds(usec)); } return (state_ & 1) != 0; } private: // Helper class to temporarily adapt a scoped_lock into a unique_lock so that // it can be passed to std::condition_variable::wait(). struct unique_lock_adapter { template explicit unique_lock_adapter(Lock& lock) : unique_lock_(lock.mutex().mutex_, std::adopt_lock) { } ~unique_lock_adapter() { unique_lock_.release(); } std::unique_lock unique_lock_; }; // Helper to increment and decrement the state to track outstanding waiters. class waiter { public: explicit waiter(std::size_t& state) : state_(state) { state_ += 2; } ~waiter() { state_ -= 2; } private: std::size_t& state_; }; std::condition_variable cond_; std::size_t state_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #endif // ASIO_DETAIL_STD_EVENT_HPP ================================================ FILE: src/third_party/asio/detail/std_fenced_block.hpp ================================================ // // detail/std_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STD_FENCED_BLOCK_HPP #define ASIO_DETAIL_STD_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_ATOMIC) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class std_fenced_block : private noncopyable { public: enum half_t { half }; enum full_t { full }; // Constructor for a half fenced block. explicit std_fenced_block(half_t) { } // Constructor for a full fenced block. explicit std_fenced_block(full_t) { std::atomic_thread_fence(std::memory_order_acquire); } // Destructor. ~std_fenced_block() { std::atomic_thread_fence(std::memory_order_release); } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_STD_ATOMIC) #endif // ASIO_DETAIL_STD_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/std_global.hpp ================================================ // // detail/std_global.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STD_GLOBAL_HPP #define ASIO_DETAIL_STD_GLOBAL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_CALL_ONCE) #include #include #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct std_global_impl { // Helper function to perform initialisation. static void do_init() { instance_.ptr_ = new T; } // Destructor automatically cleans up the global. ~std_global_impl() { delete ptr_; } static std::once_flag init_once_; static std_global_impl instance_; T* ptr_; }; template std::once_flag std_global_impl::init_once_; template std_global_impl std_global_impl::instance_; template T& std_global() { std::call_once(std_global_impl::init_once_, &std_global_impl::do_init); return *std_global_impl::instance_.ptr_; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_STD_CALL_ONCE) #endif // ASIO_DETAIL_STD_GLOBAL_HPP ================================================ FILE: src/third_party/asio/detail/std_mutex.hpp ================================================ // // detail/std_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STD_MUTEX_HPP #define ASIO_DETAIL_STD_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class std_event; class std_mutex : private noncopyable { public: typedef asio::detail::scoped_lock scoped_lock; // Constructor. std_mutex() { } // Destructor. ~std_mutex() { } // Lock the mutex. void lock() { mutex_.lock(); } // Unlock the mutex. void unlock() { mutex_.unlock(); } private: friend class std_event; std::mutex mutex_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #endif // ASIO_DETAIL_STD_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/std_static_mutex.hpp ================================================ // // detail/std_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STD_STATIC_MUTEX_HPP #define ASIO_DETAIL_STD_STATIC_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class std_event; class std_static_mutex : private noncopyable { public: typedef asio::detail::scoped_lock scoped_lock; // Constructor. std_static_mutex(int) { } // Destructor. ~std_static_mutex() { } // Initialise the mutex. void init() { // Nothing to do. } // Lock the mutex. void lock() { mutex_.lock(); } // Unlock the mutex. void unlock() { mutex_.unlock(); } private: friend class std_event; std::mutex mutex_; }; #define ASIO_STD_STATIC_MUTEX_INIT 0 } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #endif // ASIO_DETAIL_STD_STATIC_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/std_thread.hpp ================================================ // // detail/std_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STD_THREAD_HPP #define ASIO_DETAIL_STD_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_THREAD) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class std_thread : private noncopyable { public: // Constructor. template std_thread(Function f, unsigned int = 0) : thread_(f) { } // Destructor. ~std_thread() { join(); } // Wait for the thread to exit. void join() { if (thread_.joinable()) thread_.join(); } // Get number of CPUs. static std::size_t hardware_concurrency() { return std::thread::hardware_concurrency(); } private: std::thread thread_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_STD_THREAD) #endif // ASIO_DETAIL_STD_THREAD_HPP ================================================ FILE: src/third_party/asio/detail/strand_executor_service.hpp ================================================ // // detail/strand_executor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STRAND_EXECUTOR_SERVICE_HPP #define ASIO_DETAIL_STRAND_EXECUTOR_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/atomic_count.hpp" #include "asio/detail/executor_op.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/scheduler_operation.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Default service implementation for a strand. class strand_executor_service : public execution_context_service_base { public: // The underlying implementation of a strand. class strand_impl { public: ASIO_DECL ~strand_impl(); private: friend class strand_executor_service; // Mutex to protect access to internal data. mutex* mutex_; // Indicates whether the strand is currently "locked" by a handler. This // means that there is a handler upcall in progress, or that the strand // itself has been scheduled in order to invoke some pending handlers. bool locked_; // Indicates that the strand has been shut down and will accept no further // handlers. bool shutdown_; // The handlers that are waiting on the strand but should not be run until // after the next time the strand is scheduled. This queue must only be // modified while the mutex is locked. op_queue waiting_queue_; // The handlers that are ready to be run. Logically speaking, these are the // handlers that hold the strand's lock. The ready queue is only modified // from within the strand and so may be accessed without locking the mutex. op_queue ready_queue_; // Pointers to adjacent handle implementations in linked list. strand_impl* next_; strand_impl* prev_; // The strand service in where the implementation is held. strand_executor_service* service_; }; typedef shared_ptr implementation_type; // Construct a new strand service for the specified context. ASIO_DECL explicit strand_executor_service(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Create a new strand_executor implementation. ASIO_DECL implementation_type create_implementation(); // Request invocation of the given function. template static void dispatch(const implementation_type& impl, Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a); // Request invocation of the given function and return immediately. template static void post(const implementation_type& impl, Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a); // Request invocation of the given function and return immediately. template static void defer(const implementation_type& impl, Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a); // Determine whether the strand is running in the current thread. ASIO_DECL static bool running_in_this_thread( const implementation_type& impl); private: friend class strand_impl; template class invoker; // Adds a function to the strand. Returns true if it acquires the lock. ASIO_DECL static bool enqueue(const implementation_type& impl, scheduler_operation* op); // Mutex to protect access to the service-wide state. mutex mutex_; // Number of mutexes shared between all strand objects. enum { num_mutexes = 193 }; // Pool of mutexes. scoped_ptr mutexes_[num_mutexes]; // Extra value used when hashing to prevent recycled memory locations from // getting the same mutex. std::size_t salt_; // The head of a linked list of all implementations. strand_impl* impl_list_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/strand_executor_service.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/strand_executor_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_STRAND_EXECUTOR_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/strand_service.hpp ================================================ // // detail/strand_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STRAND_SERVICE_HPP #define ASIO_DETAIL_STRAND_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/io_context.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Default service implementation for a strand. class strand_service : public asio::detail::service_base { private: // Helper class to re-post the strand on exit. struct on_do_complete_exit; // Helper class to re-post the strand on exit. struct on_dispatch_exit; public: // The underlying implementation of a strand. class strand_impl : public operation { public: strand_impl(); private: // Only this service will have access to the internal values. friend class strand_service; friend struct on_do_complete_exit; friend struct on_dispatch_exit; // Mutex to protect access to internal data. asio::detail::mutex mutex_; // Indicates whether the strand is currently "locked" by a handler. This // means that there is a handler upcall in progress, or that the strand // itself has been scheduled in order to invoke some pending handlers. bool locked_; // The handlers that are waiting on the strand but should not be run until // after the next time the strand is scheduled. This queue must only be // modified while the mutex is locked. op_queue waiting_queue_; // The handlers that are ready to be run. Logically speaking, these are the // handlers that hold the strand's lock. The ready queue is only modified // from within the strand and so may be accessed without locking the mutex. op_queue ready_queue_; }; typedef strand_impl* implementation_type; // Construct a new strand service for the specified io_context. ASIO_DECL explicit strand_service(asio::io_context& io_context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Construct a new strand implementation. ASIO_DECL void construct(implementation_type& impl); // Request the io_context to invoke the given handler. template void dispatch(implementation_type& impl, Handler& handler); // Request the io_context to invoke the given handler and return immediately. template void post(implementation_type& impl, Handler& handler); // Determine whether the strand is running in the current thread. ASIO_DECL bool running_in_this_thread( const implementation_type& impl) const; private: // Helper function to dispatch a handler. Returns true if the handler should // be dispatched immediately. ASIO_DECL bool do_dispatch(implementation_type& impl, operation* op); // Helper fiunction to post a handler. ASIO_DECL void do_post(implementation_type& impl, operation* op, bool is_continuation); ASIO_DECL static void do_complete(void* owner, operation* base, const asio::error_code& ec, std::size_t bytes_transferred); // The io_context implementation used to post completions. io_context_impl& io_context_; // Mutex to protect access to the array of implementations. asio::detail::mutex mutex_; // Number of implementations shared between all strand objects. #if defined(ASIO_STRAND_IMPLEMENTATIONS) enum { num_implementations = ASIO_STRAND_IMPLEMENTATIONS }; #else // defined(ASIO_STRAND_IMPLEMENTATIONS) enum { num_implementations = 193 }; #endif // defined(ASIO_STRAND_IMPLEMENTATIONS) // Pool of implementations. scoped_ptr implementations_[num_implementations]; // Extra value used when hashing to prevent recycled memory locations from // getting the same strand implementation. std::size_t salt_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/strand_service.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/strand_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_STRAND_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/string_view.hpp ================================================ // // detail/string_view.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_STRING_VIEW_HPP #define ASIO_DETAIL_STRING_VIEW_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STRING_VIEW) #if defined(ASIO_HAS_STD_STRING_VIEW) # include #elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) # include #else // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) # error ASIO_HAS_STRING_VIEW is set but no string_view is available #endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) namespace asio { #if defined(ASIO_HAS_STD_STRING_VIEW) using std::basic_string_view; using std::string_view; #elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) using std::experimental::basic_string_view; using std::experimental::string_view; #endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) } // namespace asio # define ASIO_STRING_VIEW_PARAM asio::string_view #else // defined(ASIO_HAS_STRING_VIEW) # define ASIO_STRING_VIEW_PARAM const std::string& #endif // defined(ASIO_HAS_STRING_VIEW) #endif // ASIO_DETAIL_STRING_VIEW_HPP ================================================ FILE: src/third_party/asio/detail/thread.hpp ================================================ // // detail/thread.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_THREAD_HPP #define ASIO_DETAIL_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) # include "asio/detail/null_thread.hpp" #elif defined(ASIO_WINDOWS) # if defined(UNDER_CE) # include "asio/detail/wince_thread.hpp" # elif defined(ASIO_WINDOWS_APP) # include "asio/detail/winapp_thread.hpp" # else # include "asio/detail/win_thread.hpp" # endif #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_thread.hpp" #elif defined(ASIO_HAS_STD_THREAD) # include "asio/detail/std_thread.hpp" #else # error Only Windows, POSIX and std::thread are supported! #endif namespace asio { namespace detail { #if !defined(ASIO_HAS_THREADS) typedef null_thread thread; #elif defined(ASIO_WINDOWS) # if defined(UNDER_CE) typedef wince_thread thread; # elif defined(ASIO_WINDOWS_APP) typedef winapp_thread thread; # else typedef win_thread thread; # endif #elif defined(ASIO_HAS_PTHREADS) typedef posix_thread thread; #elif defined(ASIO_HAS_STD_THREAD) typedef std_thread thread; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_THREAD_HPP ================================================ FILE: src/third_party/asio/detail/thread_context.hpp ================================================ // // detail/thread_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_THREAD_CONTEXT_HPP #define ASIO_DETAIL_THREAD_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include "asio/detail/call_stack.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class thread_info_base; // Base class for things that manage threads (scheduler, win_iocp_io_context). class thread_context { public: // Per-thread call stack to track the state of each thread in the context. typedef call_stack thread_call_stack; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_THREAD_CONTEXT_HPP ================================================ FILE: src/third_party/asio/detail/thread_group.hpp ================================================ // // detail/thread_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_THREAD_GROUP_HPP #define ASIO_DETAIL_THREAD_GROUP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/thread.hpp" namespace asio { namespace detail { class thread_group { public: // Constructor initialises an empty thread group. thread_group() : first_(0) { } // Destructor joins any remaining threads in the group. ~thread_group() { join(); } // Create a new thread in the group. template void create_thread(Function f) { first_ = new item(f, first_); } // Create new threads in the group. template void create_threads(Function f, std::size_t num_threads) { for (std::size_t i = 0; i < num_threads; ++i) create_thread(f); } // Wait for all threads in the group to exit. void join() { while (first_) { first_->thread_.join(); item* tmp = first_; first_ = first_->next_; delete tmp; } } // Test whether the group is empty. bool empty() const { return first_ == 0; } private: // Structure used to track a single thread in the group. struct item { template explicit item(Function f, item* next) : thread_(f), next_(next) { } asio::detail::thread thread_; item* next_; }; // The first thread in the group. item* first_; }; } // namespace detail } // namespace asio #endif // ASIO_DETAIL_THREAD_GROUP_HPP ================================================ FILE: src/third_party/asio/detail/thread_info_base.hpp ================================================ // // detail/thread_info_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_THREAD_INFO_BASE_HPP #define ASIO_DETAIL_THREAD_INFO_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class thread_info_base : private noncopyable { public: struct default_tag { enum { mem_index = 0 }; }; struct awaitable_frame_tag { enum { mem_index = 1 }; }; struct executor_function_tag { enum { mem_index = 2 }; }; thread_info_base() { for (int i = 0; i < max_mem_index; ++i) reusable_memory_[i] = 0; } ~thread_info_base() { for (int i = 0; i < max_mem_index; ++i) if (reusable_memory_[i]) ::operator delete(reusable_memory_[i]); } static void* allocate(thread_info_base* this_thread, std::size_t size) { return allocate(default_tag(), this_thread, size); } static void deallocate(thread_info_base* this_thread, void* pointer, std::size_t size) { deallocate(default_tag(), this_thread, pointer, size); } template static void* allocate(Purpose, thread_info_base* this_thread, std::size_t size) { std::size_t chunks = (size + chunk_size - 1) / chunk_size; if (this_thread && this_thread->reusable_memory_[Purpose::mem_index]) { void* const pointer = this_thread->reusable_memory_[Purpose::mem_index]; this_thread->reusable_memory_[Purpose::mem_index] = 0; unsigned char* const mem = static_cast(pointer); if (static_cast(mem[0]) >= chunks) { mem[size] = mem[0]; return pointer; } ::operator delete(pointer); } void* const pointer = ::operator new(chunks * chunk_size + 1); unsigned char* const mem = static_cast(pointer); mem[size] = (chunks <= UCHAR_MAX) ? static_cast(chunks) : 0; return pointer; } template static void deallocate(Purpose, thread_info_base* this_thread, void* pointer, std::size_t size) { if (size <= chunk_size * UCHAR_MAX) { if (this_thread && this_thread->reusable_memory_[Purpose::mem_index] == 0) { unsigned char* const mem = static_cast(pointer); mem[0] = mem[size]; this_thread->reusable_memory_[Purpose::mem_index] = pointer; return; } } ::operator delete(pointer); } private: enum { chunk_size = 4 }; enum { max_mem_index = 3 }; void* reusable_memory_[max_mem_index]; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_THREAD_INFO_BASE_HPP ================================================ FILE: src/third_party/asio/detail/throw_error.hpp ================================================ // // detail/throw_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_THROW_ERROR_HPP #define ASIO_DETAIL_THROW_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error_code.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { ASIO_DECL void do_throw_error(const asio::error_code& err); ASIO_DECL void do_throw_error(const asio::error_code& err, const char* location); inline void throw_error(const asio::error_code& err) { if (err) do_throw_error(err); } inline void throw_error(const asio::error_code& err, const char* location) { if (err) do_throw_error(err, location); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/throw_error.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_THROW_ERROR_HPP ================================================ FILE: src/third_party/asio/detail/throw_exception.hpp ================================================ // // detail/throw_exception.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_THROW_EXCEPTION_HPP #define ASIO_DETAIL_THROW_EXCEPTION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_THROW_EXCEPTION) # include #endif // defined(ASIO_BOOST_THROW_EXCEPTION) namespace asio { namespace detail { #if defined(ASIO_HAS_BOOST_THROW_EXCEPTION) using boost::throw_exception; #else // defined(ASIO_HAS_BOOST_THROW_EXCEPTION) // Declare the throw_exception function for all targets. template void throw_exception(const Exception& e); // Only define the throw_exception function when exceptions are enabled. // Otherwise, it is up to the application to provide a definition of this // function. # if !defined(ASIO_NO_EXCEPTIONS) template void throw_exception(const Exception& e) { throw e; } # endif // !defined(ASIO_NO_EXCEPTIONS) #endif // defined(ASIO_HAS_BOOST_THROW_EXCEPTION) } // namespace detail } // namespace asio #endif // ASIO_DETAIL_THROW_EXCEPTION_HPP ================================================ FILE: src/third_party/asio/detail/timer_queue.hpp ================================================ // // detail/timer_queue.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TIMER_QUEUE_HPP #define ASIO_DETAIL_TIMER_QUEUE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/detail/cstdint.hpp" #include "asio/detail/date_time_fwd.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/wait_op.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class timer_queue : public timer_queue_base { public: // The time type. typedef typename Time_Traits::time_type time_type; // The duration type. typedef typename Time_Traits::duration_type duration_type; // Per-timer data. class per_timer_data { public: per_timer_data() : heap_index_((std::numeric_limits::max)()), next_(0), prev_(0) { } private: friend class timer_queue; // The operations waiting on the timer. op_queue op_queue_; // The index of the timer in the heap. std::size_t heap_index_; // Pointers to adjacent timers in a linked list. per_timer_data* next_; per_timer_data* prev_; }; // Constructor. timer_queue() : timers_(), heap_() { } // Add a new timer to the queue. Returns true if this is the timer that is // earliest in the queue, in which case the reactor's event demultiplexing // function call may need to be interrupted and restarted. bool enqueue_timer(const time_type& time, per_timer_data& timer, wait_op* op) { // Enqueue the timer object. if (timer.prev_ == 0 && &timer != timers_) { if (this->is_positive_infinity(time)) { // No heap entry is required for timers that never expire. timer.heap_index_ = (std::numeric_limits::max)(); } else { // Put the new timer at the correct position in the heap. This is done // first since push_back() can throw due to allocation failure. timer.heap_index_ = heap_.size(); heap_entry entry = { time, &timer }; heap_.push_back(entry); up_heap(heap_.size() - 1); } // Insert the new timer into the linked list of active timers. timer.next_ = timers_; timer.prev_ = 0; if (timers_) timers_->prev_ = &timer; timers_ = &timer; } // Enqueue the individual timer operation. timer.op_queue_.push(op); // Interrupt reactor only if newly added timer is first to expire. return timer.heap_index_ == 0 && timer.op_queue_.front() == op; } // Whether there are no timers in the queue. virtual bool empty() const { return timers_ == 0; } // Get the time for the timer that is earliest in the queue. virtual long wait_duration_msec(long max_duration) const { if (heap_.empty()) return max_duration; return this->to_msec( Time_Traits::to_posix_duration( Time_Traits::subtract(heap_[0].time_, Time_Traits::now())), max_duration); } // Get the time for the timer that is earliest in the queue. virtual long wait_duration_usec(long max_duration) const { if (heap_.empty()) return max_duration; return this->to_usec( Time_Traits::to_posix_duration( Time_Traits::subtract(heap_[0].time_, Time_Traits::now())), max_duration); } // Dequeue all timers not later than the current time. virtual void get_ready_timers(op_queue& ops) { if (!heap_.empty()) { const time_type now = Time_Traits::now(); while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_)) { per_timer_data* timer = heap_[0].timer_; ops.push(timer->op_queue_); remove_timer(*timer); } } } // Dequeue all timers. virtual void get_all_timers(op_queue& ops) { while (timers_) { per_timer_data* timer = timers_; timers_ = timers_->next_; ops.push(timer->op_queue_); timer->next_ = 0; timer->prev_ = 0; } heap_.clear(); } // Cancel and dequeue operations for the given timer. std::size_t cancel_timer(per_timer_data& timer, op_queue& ops, std::size_t max_cancelled = (std::numeric_limits::max)()) { std::size_t num_cancelled = 0; if (timer.prev_ != 0 || &timer == timers_) { while (wait_op* op = (num_cancelled != max_cancelled) ? timer.op_queue_.front() : 0) { op->ec_ = asio::error::operation_aborted; timer.op_queue_.pop(); ops.push(op); ++num_cancelled; } if (timer.op_queue_.empty()) remove_timer(timer); } return num_cancelled; } // Move operations from one timer to another, empty timer. void move_timer(per_timer_data& target, per_timer_data& source) { target.op_queue_.push(source.op_queue_); target.heap_index_ = source.heap_index_; source.heap_index_ = (std::numeric_limits::max)(); if (target.heap_index_ < heap_.size()) heap_[target.heap_index_].timer_ = ⌖ if (timers_ == &source) timers_ = ⌖ if (source.prev_) source.prev_->next_ = ⌖ if (source.next_) source.next_->prev_= ⌖ target.next_ = source.next_; target.prev_ = source.prev_; source.next_ = 0; source.prev_ = 0; } private: // Move the item at the given index up the heap to its correct position. void up_heap(std::size_t index) { while (index > 0) { std::size_t parent = (index - 1) / 2; if (!Time_Traits::less_than(heap_[index].time_, heap_[parent].time_)) break; swap_heap(index, parent); index = parent; } } // Move the item at the given index down the heap to its correct position. void down_heap(std::size_t index) { std::size_t child = index * 2 + 1; while (child < heap_.size()) { std::size_t min_child = (child + 1 == heap_.size() || Time_Traits::less_than( heap_[child].time_, heap_[child + 1].time_)) ? child : child + 1; if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_)) break; swap_heap(index, min_child); index = min_child; child = index * 2 + 1; } } // Swap two entries in the heap. void swap_heap(std::size_t index1, std::size_t index2) { heap_entry tmp = heap_[index1]; heap_[index1] = heap_[index2]; heap_[index2] = tmp; heap_[index1].timer_->heap_index_ = index1; heap_[index2].timer_->heap_index_ = index2; } // Remove a timer from the heap and list of timers. void remove_timer(per_timer_data& timer) { // Remove the timer from the heap. std::size_t index = timer.heap_index_; if (!heap_.empty() && index < heap_.size()) { if (index == heap_.size() - 1) { timer.heap_index_ = (std::numeric_limits::max)(); heap_.pop_back(); } else { swap_heap(index, heap_.size() - 1); timer.heap_index_ = (std::numeric_limits::max)(); heap_.pop_back(); if (index > 0 && Time_Traits::less_than( heap_[index].time_, heap_[(index - 1) / 2].time_)) up_heap(index); else down_heap(index); } } // Remove the timer from the linked list of active timers. if (timers_ == &timer) timers_ = timer.next_; if (timer.prev_) timer.prev_->next_ = timer.next_; if (timer.next_) timer.next_->prev_= timer.prev_; timer.next_ = 0; timer.prev_ = 0; } // Determine if the specified absolute time is positive infinity. template static bool is_positive_infinity(const Time_Type&) { return false; } // Determine if the specified absolute time is positive infinity. template static bool is_positive_infinity( const boost::date_time::base_time& time) { return time.is_pos_infinity(); } // Helper function to convert a duration into milliseconds. template long to_msec(const Duration& d, long max_duration) const { if (d.ticks() <= 0) return 0; int64_t msec = d.total_milliseconds(); if (msec == 0) return 1; if (msec > max_duration) return max_duration; return static_cast(msec); } // Helper function to convert a duration into microseconds. template long to_usec(const Duration& d, long max_duration) const { if (d.ticks() <= 0) return 0; int64_t usec = d.total_microseconds(); if (usec == 0) return 1; if (usec > max_duration) return max_duration; return static_cast(usec); } // The head of a linked list of all active timers. per_timer_data* timers_; struct heap_entry { // The time when the timer should fire. time_type time_; // The associated timer with enqueued operations. per_timer_data* timer_; }; // The heap of timers, with the earliest timer at the front. std::vector heap_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_TIMER_QUEUE_HPP ================================================ FILE: src/third_party/asio/detail/timer_queue_base.hpp ================================================ // // detail/timer_queue_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TIMER_QUEUE_BASE_HPP #define ASIO_DETAIL_TIMER_QUEUE_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class timer_queue_base : private noncopyable { public: // Constructor. timer_queue_base() : next_(0) {} // Destructor. virtual ~timer_queue_base() {} // Whether there are no timers in the queue. virtual bool empty() const = 0; // Get the time to wait until the next timer. virtual long wait_duration_msec(long max_duration) const = 0; // Get the time to wait until the next timer. virtual long wait_duration_usec(long max_duration) const = 0; // Dequeue all ready timers. virtual void get_ready_timers(op_queue& ops) = 0; // Dequeue all timers. virtual void get_all_timers(op_queue& ops) = 0; private: friend class timer_queue_set; // Next timer queue in the set. timer_queue_base* next_; }; template class timer_queue; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_TIMER_QUEUE_BASE_HPP ================================================ FILE: src/third_party/asio/detail/timer_queue_ptime.hpp ================================================ // // detail/timer_queue_ptime.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP #define ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) #include "asio/time_traits.hpp" #include "asio/detail/timer_queue.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct forwarding_posix_time_traits : time_traits {}; // Template specialisation for the commonly used instantation. template <> class timer_queue > : public timer_queue_base { public: // The time type. typedef boost::posix_time::ptime time_type; // The duration type. typedef boost::posix_time::time_duration duration_type; // Per-timer data. typedef timer_queue::per_timer_data per_timer_data; // Constructor. ASIO_DECL timer_queue(); // Destructor. ASIO_DECL virtual ~timer_queue(); // Add a new timer to the queue. Returns true if this is the timer that is // earliest in the queue, in which case the reactor's event demultiplexing // function call may need to be interrupted and restarted. ASIO_DECL bool enqueue_timer(const time_type& time, per_timer_data& timer, wait_op* op); // Whether there are no timers in the queue. ASIO_DECL virtual bool empty() const; // Get the time for the timer that is earliest in the queue. ASIO_DECL virtual long wait_duration_msec(long max_duration) const; // Get the time for the timer that is earliest in the queue. ASIO_DECL virtual long wait_duration_usec(long max_duration) const; // Dequeue all timers not later than the current time. ASIO_DECL virtual void get_ready_timers(op_queue& ops); // Dequeue all timers. ASIO_DECL virtual void get_all_timers(op_queue& ops); // Cancel and dequeue operations for the given timer. ASIO_DECL std::size_t cancel_timer( per_timer_data& timer, op_queue& ops, std::size_t max_cancelled = (std::numeric_limits::max)()); // Move operations from one timer to another, empty timer. ASIO_DECL void move_timer(per_timer_data& target, per_timer_data& source); private: timer_queue impl_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/timer_queue_ptime.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_BOOST_DATE_TIME) #endif // ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP ================================================ FILE: src/third_party/asio/detail/timer_queue_set.hpp ================================================ // // detail/timer_queue_set.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TIMER_QUEUE_SET_HPP #define ASIO_DETAIL_TIMER_QUEUE_SET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class timer_queue_set { public: // Constructor. ASIO_DECL timer_queue_set(); // Add a timer queue to the set. ASIO_DECL void insert(timer_queue_base* q); // Remove a timer queue from the set. ASIO_DECL void erase(timer_queue_base* q); // Determine whether all queues are empty. ASIO_DECL bool all_empty() const; // Get the wait duration in milliseconds. ASIO_DECL long wait_duration_msec(long max_duration) const; // Get the wait duration in microseconds. ASIO_DECL long wait_duration_usec(long max_duration) const; // Dequeue all ready timers. ASIO_DECL void get_ready_timers(op_queue& ops); // Dequeue all timers. ASIO_DECL void get_all_timers(op_queue& ops); private: timer_queue_base* first_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/timer_queue_set.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_DETAIL_TIMER_QUEUE_SET_HPP ================================================ FILE: src/third_party/asio/detail/timer_scheduler.hpp ================================================ // // detail/timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TIMER_SCHEDULER_HPP #define ASIO_DETAIL_TIMER_SCHEDULER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/timer_scheduler_fwd.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/winrt_timer_scheduler.hpp" #elif defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #elif defined(ASIO_HAS_EPOLL) # include "asio/detail/epoll_reactor.hpp" #elif defined(ASIO_HAS_KQUEUE) # include "asio/detail/kqueue_reactor.hpp" #elif defined(ASIO_HAS_DEV_POLL) # include "asio/detail/dev_poll_reactor.hpp" #else # include "asio/detail/select_reactor.hpp" #endif #endif // ASIO_DETAIL_TIMER_SCHEDULER_HPP ================================================ FILE: src/third_party/asio/detail/timer_scheduler_fwd.hpp ================================================ // // detail/timer_scheduler_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP #define ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" namespace asio { namespace detail { #if defined(ASIO_WINDOWS_RUNTIME) typedef class winrt_timer_scheduler timer_scheduler; #elif defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context timer_scheduler; #elif defined(ASIO_HAS_EPOLL) typedef class epoll_reactor timer_scheduler; #elif defined(ASIO_HAS_KQUEUE) typedef class kqueue_reactor timer_scheduler; #elif defined(ASIO_HAS_DEV_POLL) typedef class dev_poll_reactor timer_scheduler; #else typedef class select_reactor timer_scheduler; #endif } // namespace detail } // namespace asio #endif // ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP ================================================ FILE: src/third_party/asio/detail/tss_ptr.hpp ================================================ // // detail/tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TSS_PTR_HPP #define ASIO_DETAIL_TSS_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_THREADS) # include "asio/detail/null_tss_ptr.hpp" #elif defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) # include "asio/detail/keyword_tss_ptr.hpp" #elif defined(ASIO_WINDOWS) # include "asio/detail/win_tss_ptr.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_tss_ptr.hpp" #else # error Only Windows and POSIX are supported! #endif #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class tss_ptr #if !defined(ASIO_HAS_THREADS) : public null_tss_ptr #elif defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) : public keyword_tss_ptr #elif defined(ASIO_WINDOWS) : public win_tss_ptr #elif defined(ASIO_HAS_PTHREADS) : public posix_tss_ptr #endif { public: void operator=(T* value) { #if !defined(ASIO_HAS_THREADS) null_tss_ptr::operator=(value); #elif defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION) keyword_tss_ptr::operator=(value); #elif defined(ASIO_WINDOWS) win_tss_ptr::operator=(value); #elif defined(ASIO_HAS_PTHREADS) posix_tss_ptr::operator=(value); #endif } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_TSS_PTR_HPP ================================================ FILE: src/third_party/asio/detail/type_traits.hpp ================================================ // // detail/type_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_TYPE_TRAITS_HPP #define ASIO_DETAIL_TYPE_TRAITS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_TYPE_TRAITS) # include #else // defined(ASIO_HAS_TYPE_TRAITS) # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include #endif // defined(ASIO_HAS_TYPE_TRAITS) namespace asio { #if defined(ASIO_HAS_STD_TYPE_TRAITS) using std::add_const; using std::conditional; using std::decay; using std::declval; using std::enable_if; using std::false_type; using std::integral_constant; using std::is_base_of; using std::is_class; using std::is_const; using std::is_convertible; using std::is_function; using std::is_same; using std::remove_pointer; using std::remove_reference; #if defined(ASIO_HAS_STD_INVOKE_RESULT) template struct result_of; template struct result_of : std::invoke_result {}; #else // defined(ASIO_HAS_STD_INVOKE_RESULT) using std::result_of; #endif // defined(ASIO_HAS_STD_INVOKE_RESULT) using std::true_type; #else // defined(ASIO_HAS_STD_TYPE_TRAITS) using boost::add_const; template struct enable_if : boost::enable_if_c {}; using boost::conditional; using boost::decay; using boost::declval; using boost::false_type; using boost::integral_constant; using boost::is_base_of; using boost::is_class; using boost::is_const; using boost::is_convertible; using boost::is_function; using boost::is_same; using boost::remove_pointer; using boost::remove_reference; using boost::result_of; using boost::true_type; #endif // defined(ASIO_HAS_STD_TYPE_TRAITS) } // namespace asio #endif // ASIO_DETAIL_TYPE_TRAITS_HPP ================================================ FILE: src/third_party/asio/detail/variadic_templates.hpp ================================================ // // detail/variadic_templates.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_VARIADIC_TEMPLATES_HPP #define ASIO_DETAIL_VARIADIC_TEMPLATES_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) # define ASIO_VARIADIC_TPARAMS(n) ASIO_VARIADIC_TPARAMS_##n # define ASIO_VARIADIC_TPARAMS_1 \ typename T1 # define ASIO_VARIADIC_TPARAMS_2 \ typename T1, typename T2 # define ASIO_VARIADIC_TPARAMS_3 \ typename T1, typename T2, typename T3 # define ASIO_VARIADIC_TPARAMS_4 \ typename T1, typename T2, typename T3, typename T4 # define ASIO_VARIADIC_TPARAMS_5 \ typename T1, typename T2, typename T3, typename T4, typename T5 # define ASIO_VARIADIC_TARGS(n) ASIO_VARIADIC_TARGS_##n # define ASIO_VARIADIC_TARGS_1 T1 # define ASIO_VARIADIC_TARGS_2 T1, T2 # define ASIO_VARIADIC_TARGS_3 T1, T2, T3 # define ASIO_VARIADIC_TARGS_4 T1, T2, T3, T4 # define ASIO_VARIADIC_TARGS_5 T1, T2, T3, T4, T5 # define ASIO_VARIADIC_BYVAL_PARAMS(n) \ ASIO_VARIADIC_BYVAL_PARAMS_##n # define ASIO_VARIADIC_BYVAL_PARAMS_1 T1 x1 # define ASIO_VARIADIC_BYVAL_PARAMS_2 T1 x1, T2 x2 # define ASIO_VARIADIC_BYVAL_PARAMS_3 T1 x1, T2 x2, T3 x3 # define ASIO_VARIADIC_BYVAL_PARAMS_4 T1 x1, T2 x2, T3 x3, T4 x4 # define ASIO_VARIADIC_BYVAL_PARAMS_5 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5 # define ASIO_VARIADIC_BYVAL_ARGS(n) \ ASIO_VARIADIC_BYVAL_ARGS_##n # define ASIO_VARIADIC_BYVAL_ARGS_1 x1 # define ASIO_VARIADIC_BYVAL_ARGS_2 x1, x2 # define ASIO_VARIADIC_BYVAL_ARGS_3 x1, x2, x3 # define ASIO_VARIADIC_BYVAL_ARGS_4 x1, x2, x3, x4 # define ASIO_VARIADIC_BYVAL_ARGS_5 x1, x2, x3, x4, x5 # define ASIO_VARIADIC_CONSTREF_PARAMS(n) \ ASIO_VARIADIC_CONSTREF_PARAMS_##n # define ASIO_VARIADIC_CONSTREF_PARAMS_1 \ const T1& x1 # define ASIO_VARIADIC_CONSTREF_PARAMS_2 \ const T1& x1, const T2& x2 # define ASIO_VARIADIC_CONSTREF_PARAMS_3 \ const T1& x1, const T2& x2, const T3& x3 # define ASIO_VARIADIC_CONSTREF_PARAMS_4 \ const T1& x1, const T2& x2, const T3& x3, const T4& x4 # define ASIO_VARIADIC_CONSTREF_PARAMS_5 \ const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5 # define ASIO_VARIADIC_MOVE_PARAMS(n) \ ASIO_VARIADIC_MOVE_PARAMS_##n # define ASIO_VARIADIC_MOVE_PARAMS_1 \ ASIO_MOVE_ARG(T1) x1 # define ASIO_VARIADIC_MOVE_PARAMS_2 \ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2 # define ASIO_VARIADIC_MOVE_PARAMS_3 \ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \ ASIO_MOVE_ARG(T3) x3 # define ASIO_VARIADIC_MOVE_PARAMS_4 \ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \ ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4 # define ASIO_VARIADIC_MOVE_PARAMS_5 \ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \ ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \ ASIO_MOVE_ARG(T5) x5 # define ASIO_VARIADIC_MOVE_ARGS(n) \ ASIO_VARIADIC_MOVE_ARGS_##n # define ASIO_VARIADIC_MOVE_ARGS_1 \ ASIO_MOVE_CAST(T1)(x1) # define ASIO_VARIADIC_MOVE_ARGS_2 \ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2) # define ASIO_VARIADIC_MOVE_ARGS_3 \ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \ ASIO_MOVE_CAST(T3)(x3) # define ASIO_VARIADIC_MOVE_ARGS_4 \ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \ ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4) # define ASIO_VARIADIC_MOVE_ARGS_5 \ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \ ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \ ASIO_MOVE_CAST(T5)(x5) # define ASIO_VARIADIC_MOVE_DECLVAL(n) \ ASIO_VARIADIC_MOVE_DECLVAL_##n # define ASIO_VARIADIC_MOVE_DECLVAL_1 \ declval() # define ASIO_VARIADIC_MOVE_DECLVAL_2 \ declval(), declval() # define ASIO_VARIADIC_MOVE_DECLVAL_3 \ declval(), declval(), \ declval() # define ASIO_VARIADIC_MOVE_DECLVAL_4 \ declval(), declval(), \ declval(), declval() # define ASIO_VARIADIC_MOVE_DECLVAL_5 \ declval(), declval(), \ declval(), declval(), \ declval() # define ASIO_VARIADIC_DECAY(n) \ ASIO_VARIADIC_DECAY_##n # define ASIO_VARIADIC_DECAY_1 \ typename decay::type # define ASIO_VARIADIC_DECAY_2 \ typename decay::type, typename decay::type # define ASIO_VARIADIC_DECAY_3 \ typename decay::type, typename decay::type, \ typename decay::type # define ASIO_VARIADIC_DECAY_4 \ typename decay::type, typename decay::type, \ typename decay::type, typename decay::type # define ASIO_VARIADIC_DECAY_5 \ typename decay::type, typename decay::type, \ typename decay::type, typename decay::type, \ typename decay::type # define ASIO_VARIADIC_GENERATE(m) m(1) m(2) m(3) m(4) m(5) #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // ASIO_DETAIL_VARIADIC_TEMPLATES_HPP ================================================ FILE: src/third_party/asio/detail/wait_handler.hpp ================================================ // // detail/wait_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WAIT_HANDLER_HPP #define ASIO_DETAIL_WAIT_HANDLER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/wait_op.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class wait_handler : public wait_op { public: ASIO_DEFINE_HANDLER_PTR(wait_handler); wait_handler(Handler& h, const IoExecutor& ex) : wait_op(&wait_handler::do_complete), handler_(ASIO_MOVE_CAST(Handler)(h)), io_executor_(ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& /*ec*/, std::size_t /*bytes_transferred*/) { // Take ownership of the handler object. wait_handler* h(static_cast(base)); ptr p = { asio::detail::addressof(h->handler_), h, h }; handler_work w(h->handler_, h->io_executor_); ASIO_HANDLER_COMPLETION((*h)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(h->handler_, h->ec_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_WAIT_HANDLER_HPP ================================================ FILE: src/third_party/asio/detail/wait_op.hpp ================================================ // // detail/wait_op.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WAIT_OP_HPP #define ASIO_DETAIL_WAIT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class wait_op : public operation { public: // The error code to be passed to the completion handler. asio::error_code ec_; protected: wait_op(func_type func) : operation(func) { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_WAIT_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_event.hpp ================================================ // // detail/win_event.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_EVENT_HPP #define ASIO_DETAIL_WIN_EVENT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include "asio/detail/assert.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_event : private noncopyable { public: // Constructor. ASIO_DECL win_event(); // Destructor. ASIO_DECL ~win_event(); // Signal the event. (Retained for backward compatibility.) template void signal(Lock& lock) { this->signal_all(lock); } // Signal all waiters. template void signal_all(Lock& lock) { ASIO_ASSERT(lock.locked()); (void)lock; state_ |= 1; ::SetEvent(events_[0]); } // Unlock the mutex and signal one waiter. template void unlock_and_signal_one(Lock& lock) { ASIO_ASSERT(lock.locked()); state_ |= 1; bool have_waiters = (state_ > 1); lock.unlock(); if (have_waiters) ::SetEvent(events_[1]); } // If there's a waiter, unlock the mutex and signal it. template bool maybe_unlock_and_signal_one(Lock& lock) { ASIO_ASSERT(lock.locked()); state_ |= 1; if (state_ > 1) { lock.unlock(); ::SetEvent(events_[1]); return true; } return false; } // Reset the event. template void clear(Lock& lock) { ASIO_ASSERT(lock.locked()); (void)lock; ::ResetEvent(events_[0]); state_ &= ~std::size_t(1); } // Wait for the event to become signalled. template void wait(Lock& lock) { ASIO_ASSERT(lock.locked()); while ((state_ & 1) == 0) { state_ += 2; lock.unlock(); #if defined(ASIO_WINDOWS_APP) ::WaitForMultipleObjectsEx(2, events_, false, INFINITE, false); #else // defined(ASIO_WINDOWS_APP) ::WaitForMultipleObjects(2, events_, false, INFINITE); #endif // defined(ASIO_WINDOWS_APP) lock.lock(); state_ -= 2; } } // Timed wait for the event to become signalled. template bool wait_for_usec(Lock& lock, long usec) { ASIO_ASSERT(lock.locked()); if ((state_ & 1) == 0) { state_ += 2; lock.unlock(); DWORD msec = usec > 0 ? (usec < 1000 ? 1 : usec / 1000) : 0; #if defined(ASIO_WINDOWS_APP) ::WaitForMultipleObjectsEx(2, events_, false, msec, false); #else // defined(ASIO_WINDOWS_APP) ::WaitForMultipleObjects(2, events_, false, msec); #endif // defined(ASIO_WINDOWS_APP) lock.lock(); state_ -= 2; } return (state_ & 1) != 0; } private: HANDLE events_[2]; std::size_t state_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_event.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_WIN_EVENT_HPP ================================================ FILE: src/third_party/asio/detail/win_fd_set_adapter.hpp ================================================ // // detail/win_fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP #define ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) #include "asio/detail/noncopyable.hpp" #include "asio/detail/reactor_op_queue.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. class win_fd_set_adapter : noncopyable { public: enum { default_fd_set_size = 1024 }; win_fd_set_adapter() : capacity_(default_fd_set_size), max_descriptor_(invalid_socket) { fd_set_ = static_cast(::operator new( sizeof(win_fd_set) - sizeof(SOCKET) + sizeof(SOCKET) * (capacity_))); fd_set_->fd_count = 0; } ~win_fd_set_adapter() { ::operator delete(fd_set_); } void reset() { fd_set_->fd_count = 0; max_descriptor_ = invalid_socket; } bool set(socket_type descriptor) { for (u_int i = 0; i < fd_set_->fd_count; ++i) if (fd_set_->fd_array[i] == descriptor) return true; reserve(fd_set_->fd_count + 1); fd_set_->fd_array[fd_set_->fd_count++] = descriptor; return true; } void set(reactor_op_queue& operations, op_queue&) { reactor_op_queue::iterator i = operations.begin(); while (i != operations.end()) { reactor_op_queue::iterator op_iter = i++; reserve(fd_set_->fd_count + 1); fd_set_->fd_array[fd_set_->fd_count++] = op_iter->first; } } bool is_set(socket_type descriptor) const { return !!__WSAFDIsSet(descriptor, const_cast(reinterpret_cast(fd_set_))); } operator fd_set*() { return reinterpret_cast(fd_set_); } socket_type max_descriptor() const { return max_descriptor_; } void perform(reactor_op_queue& operations, op_queue& ops) const { for (u_int i = 0; i < fd_set_->fd_count; ++i) operations.perform_operations(fd_set_->fd_array[i], ops); } private: // This structure is defined to be compatible with the Windows API fd_set // structure, but without being dependent on the value of FD_SETSIZE. We use // the "struct hack" to allow the number of descriptors to be varied at // runtime. struct win_fd_set { u_int fd_count; SOCKET fd_array[1]; }; // Increase the fd_set_ capacity to at least the specified number of elements. void reserve(u_int n) { if (n <= capacity_) return; u_int new_capacity = capacity_ + capacity_ / 2; if (new_capacity < n) new_capacity = n; win_fd_set* new_fd_set = static_cast(::operator new( sizeof(win_fd_set) - sizeof(SOCKET) + sizeof(SOCKET) * (new_capacity))); new_fd_set->fd_count = fd_set_->fd_count; for (u_int i = 0; i < fd_set_->fd_count; ++i) new_fd_set->fd_array[i] = fd_set_->fd_array[i]; ::operator delete(fd_set_); fd_set_ = new_fd_set; capacity_ = new_capacity; } win_fd_set* fd_set_; u_int capacity_; socket_type max_descriptor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #endif // ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP ================================================ FILE: src/third_party/asio/detail/win_fenced_block.hpp ================================================ // // detail/win_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_FENCED_BLOCK_HPP #define ASIO_DETAIL_WIN_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) && !defined(UNDER_CE) #include "asio/detail/socket_types.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_fenced_block : private noncopyable { public: enum half_t { half }; enum full_t { full }; // Constructor for a half fenced block. explicit win_fenced_block(half_t) { } // Constructor for a full fenced block. explicit win_fenced_block(full_t) { #if defined(__BORLANDC__) LONG barrier = 0; ::InterlockedExchange(&barrier, 1); #elif defined(ASIO_MSVC) \ && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier)) # if defined(_M_IX86) # pragma warning(push) # pragma warning(disable:4793) LONG barrier; __asm { xchg barrier, eax } # pragma warning(pop) # endif // defined(_M_IX86) #else MemoryBarrier(); #endif } // Destructor. ~win_fenced_block() { #if defined(__BORLANDC__) LONG barrier = 0; ::InterlockedExchange(&barrier, 1); #elif defined(ASIO_MSVC) \ && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier)) # if defined(_M_IX86) # pragma warning(push) # pragma warning(disable:4793) LONG barrier; __asm { xchg barrier, eax } # pragma warning(pop) # endif // defined(_M_IX86) #else MemoryBarrier(); #endif } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) && !defined(UNDER_CE) #endif // ASIO_DETAIL_WIN_FENCED_BLOCK_HPP ================================================ FILE: src/third_party/asio/detail/win_global.hpp ================================================ // // detail/win_global.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_GLOBAL_HPP #define ASIO_DETAIL_WIN_GLOBAL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/static_mutex.hpp" #include "asio/detail/tss_ptr.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct win_global_impl { // Destructor automatically cleans up the global. ~win_global_impl() { delete ptr_; } static win_global_impl instance_; static static_mutex mutex_; T* ptr_; static tss_ptr tss_ptr_; }; template win_global_impl win_global_impl::instance_ = { 0 }; template static_mutex win_global_impl::mutex_ = ASIO_STATIC_MUTEX_INIT; template tss_ptr win_global_impl::tss_ptr_; template T& win_global() { if (static_cast(win_global_impl::tss_ptr_) == 0) { win_global_impl::mutex_.init(); static_mutex::scoped_lock lock(win_global_impl::mutex_); if (win_global_impl::instance_.ptr_ == 0) win_global_impl::instance_.ptr_ = new T; win_global_impl::tss_ptr_ = win_global_impl::instance_.ptr_; } return *win_global_impl::tss_ptr_; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_WIN_GLOBAL_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_handle_read_op.hpp ================================================ // // detail/win_iocp_handle_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP #define ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/error.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_handle_read_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_read_op); win_iocp_handle_read_op(const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_handle_read_op::do_complete), buffers_(buffers), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t bytes_transferred) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_handle_read_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) if (owner) { // Check whether buffers are still valid. buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_HANDLE_EOF) ec = asio::error::eof; // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: MutableBufferSequence buffers_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_handle_service.hpp ================================================ // // detail/win_iocp_handle_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP #define ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/cstdint.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/win_iocp_handle_read_op.hpp" #include "asio/detail/win_iocp_handle_write_op.hpp" #include "asio/detail/win_iocp_io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_iocp_handle_service : public execution_context_service_base { public: // The native type of a stream handle. typedef HANDLE native_handle_type; // The implementation type of the stream handle. class implementation_type { public: // Default constructor. implementation_type() : handle_(INVALID_HANDLE_VALUE), safe_cancellation_thread_id_(0), next_(0), prev_(0) { } private: // Only this service will have access to the internal values. friend class win_iocp_handle_service; // The native stream handle representation. native_handle_type handle_; // The ID of the thread from which it is safe to cancel asynchronous // operations. 0 means no asynchronous operations have been started yet. // ~0 means asynchronous operations have been started from more than one // thread, and cancellation is not supported for the handle. DWORD safe_cancellation_thread_id_; // Pointers to adjacent handle implementations in linked list. implementation_type* next_; implementation_type* prev_; }; ASIO_DECL win_iocp_handle_service(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Construct a new handle implementation. ASIO_DECL void construct(implementation_type& impl); // Move-construct a new handle implementation. ASIO_DECL void move_construct(implementation_type& impl, implementation_type& other_impl); // Move-assign from another handle implementation. ASIO_DECL void move_assign(implementation_type& impl, win_iocp_handle_service& other_service, implementation_type& other_impl); // Destroy a handle implementation. ASIO_DECL void destroy(implementation_type& impl); // Assign a native handle to a handle implementation. ASIO_DECL asio::error_code assign(implementation_type& impl, const native_handle_type& handle, asio::error_code& ec); // Determine whether the handle is open. bool is_open(const implementation_type& impl) const { return impl.handle_ != INVALID_HANDLE_VALUE; } // Destroy a handle implementation. ASIO_DECL asio::error_code close(implementation_type& impl, asio::error_code& ec); // Get the native handle representation. native_handle_type native_handle(const implementation_type& impl) const { return impl.handle_; } // Cancel all operations associated with the handle. ASIO_DECL asio::error_code cancel(implementation_type& impl, asio::error_code& ec); // Write the given data. Returns the number of bytes written. template size_t write_some(implementation_type& impl, const ConstBufferSequence& buffers, asio::error_code& ec) { return write_some_at(impl, 0, buffers, ec); } // Write the given data at the specified offset. Returns the number of bytes // written. template size_t write_some_at(implementation_type& impl, uint64_t offset, const ConstBufferSequence& buffers, asio::error_code& ec) { asio::const_buffer buffer = buffer_sequence_adapter::first(buffers); return do_write(impl, offset, buffer, ec); } // Start an asynchronous write. The data being written must be valid for the // lifetime of the asynchronous operation. template void async_write_some(implementation_type& impl, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_handle_write_op< ConstBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(buffers, handler, io_ex); ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, reinterpret_cast(impl.handle_), "async_write_some")); start_write_op(impl, 0, buffer_sequence_adapter::first(buffers), p.p); p.v = p.p = 0; } // Start an asynchronous write at a specified offset. The data being written // must be valid for the lifetime of the asynchronous operation. template void async_write_some_at(implementation_type& impl, uint64_t offset, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_handle_write_op< ConstBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(buffers, handler, io_ex); ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, reinterpret_cast(impl.handle_), "async_write_some_at")); start_write_op(impl, offset, buffer_sequence_adapter::first(buffers), p.p); p.v = p.p = 0; } // Read some data. Returns the number of bytes received. template size_t read_some(implementation_type& impl, const MutableBufferSequence& buffers, asio::error_code& ec) { return read_some_at(impl, 0, buffers, ec); } // Read some data at a specified offset. Returns the number of bytes received. template size_t read_some_at(implementation_type& impl, uint64_t offset, const MutableBufferSequence& buffers, asio::error_code& ec) { asio::mutable_buffer buffer = buffer_sequence_adapter::first(buffers); return do_read(impl, offset, buffer, ec); } // Start an asynchronous read. The buffer for the data being received must be // valid for the lifetime of the asynchronous operation. template void async_read_some(implementation_type& impl, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_handle_read_op< MutableBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(buffers, handler, io_ex); ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, reinterpret_cast(impl.handle_), "async_read_some")); start_read_op(impl, 0, buffer_sequence_adapter::first(buffers), p.p); p.v = p.p = 0; } // Start an asynchronous read at a specified offset. The buffer for the data // being received must be valid for the lifetime of the asynchronous // operation. template void async_read_some_at(implementation_type& impl, uint64_t offset, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_handle_read_op< MutableBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(buffers, handler, io_ex); ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl, reinterpret_cast(impl.handle_), "async_read_some_at")); start_read_op(impl, offset, buffer_sequence_adapter::first(buffers), p.p); p.v = p.p = 0; } private: // Prevent the use of the null_buffers type with this service. size_t write_some(implementation_type& impl, const null_buffers& buffers, asio::error_code& ec); size_t write_some_at(implementation_type& impl, uint64_t offset, const null_buffers& buffers, asio::error_code& ec); template void async_write_some(implementation_type& impl, const null_buffers& buffers, Handler& handler, const IoExecutor& io_ex); template void async_write_some_at(implementation_type& impl, uint64_t offset, const null_buffers& buffers, Handler& handler, const IoExecutor& io_ex); size_t read_some(implementation_type& impl, const null_buffers& buffers, asio::error_code& ec); size_t read_some_at(implementation_type& impl, uint64_t offset, const null_buffers& buffers, asio::error_code& ec); template void async_read_some(implementation_type& impl, const null_buffers& buffers, Handler& handler, const IoExecutor& io_ex); template void async_read_some_at(implementation_type& impl, uint64_t offset, const null_buffers& buffers, Handler& handler, const IoExecutor& io_ex); // Helper class for waiting for synchronous operations to complete. class overlapped_wrapper; // Helper function to perform a synchronous write operation. ASIO_DECL size_t do_write(implementation_type& impl, uint64_t offset, const asio::const_buffer& buffer, asio::error_code& ec); // Helper function to start a write operation. ASIO_DECL void start_write_op(implementation_type& impl, uint64_t offset, const asio::const_buffer& buffer, operation* op); // Helper function to perform a synchronous write operation. ASIO_DECL size_t do_read(implementation_type& impl, uint64_t offset, const asio::mutable_buffer& buffer, asio::error_code& ec); // Helper function to start a read operation. ASIO_DECL void start_read_op(implementation_type& impl, uint64_t offset, const asio::mutable_buffer& buffer, operation* op); // Update the ID of the thread from which cancellation is safe. ASIO_DECL void update_cancellation_thread_id(implementation_type& impl); // Helper function to close a handle when the associated object is being // destroyed. ASIO_DECL void close_for_destruction(implementation_type& impl); // The IOCP service used for running asynchronous operations and dispatching // handlers. win_iocp_io_context& iocp_service_; // Mutex to protect access to the linked list of implementations. mutex mutex_; // The head of a linked list of all implementations. implementation_type* impl_list_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_iocp_handle_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_handle_write_op.hpp ================================================ // // detail/win_iocp_handle_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP #define ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/error.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_handle_write_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_write_op); win_iocp_handle_write_op(const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_handle_write_op::do_complete), buffers_(buffers), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& ec, std::size_t bytes_transferred) { // Take ownership of the operation object. win_iocp_handle_write_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) if (owner) { // Check whether buffers are still valid. buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: ConstBufferSequence buffers_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_io_context.hpp ================================================ // // detail/win_iocp_io_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_HPP #define ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/limits.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/thread_context.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/timer_queue_set.hpp" #include "asio/detail/wait_op.hpp" #include "asio/detail/win_iocp_operation.hpp" #include "asio/detail/win_iocp_thread_info.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class wait_op; class win_iocp_io_context : public execution_context_service_base, public thread_context { public: // Constructor. Specifies a concurrency hint that is passed through to the // underlying I/O completion port. ASIO_DECL win_iocp_io_context(asio::execution_context& ctx, int concurrency_hint = -1, bool own_thread = true); // Destructor. ASIO_DECL ~win_iocp_io_context(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Initialise the task. Nothing to do here. void init_task() { } // Register a handle with the IO completion port. ASIO_DECL asio::error_code register_handle( HANDLE handle, asio::error_code& ec); // Run the event loop until stopped or no more work. ASIO_DECL size_t run(asio::error_code& ec); // Run until stopped or one operation is performed. ASIO_DECL size_t run_one(asio::error_code& ec); // Run until timeout, interrupted, or one operation is performed. ASIO_DECL size_t wait_one(long usec, asio::error_code& ec); // Poll for operations without blocking. ASIO_DECL size_t poll(asio::error_code& ec); // Poll for one operation without blocking. ASIO_DECL size_t poll_one(asio::error_code& ec); // Stop the event processing loop. ASIO_DECL void stop(); // Determine whether the io_context is stopped. bool stopped() const { return ::InterlockedExchangeAdd(&stopped_, 0) != 0; } // Restart in preparation for a subsequent run invocation. void restart() { ::InterlockedExchange(&stopped_, 0); } // Notify that some work has started. void work_started() { ::InterlockedIncrement(&outstanding_work_); } // Notify that some work has finished. void work_finished() { if (::InterlockedDecrement(&outstanding_work_) == 0) stop(); } // Return whether a handler can be dispatched immediately. bool can_dispatch() { return thread_call_stack::contains(this) != 0; } // Request invocation of the given operation and return immediately. Assumes // that work_started() has not yet been called for the operation. void post_immediate_completion(win_iocp_operation* op, bool) { work_started(); post_deferred_completion(op); } // Request invocation of the given operation and return immediately. Assumes // that work_started() was previously called for the operation. ASIO_DECL void post_deferred_completion(win_iocp_operation* op); // Request invocation of the given operation and return immediately. Assumes // that work_started() was previously called for the operations. ASIO_DECL void post_deferred_completions( op_queue& ops); // Request invocation of the given operation using the thread-private queue // and return immediately. Assumes that work_started() has not yet been // called for the operation. void post_private_immediate_completion(win_iocp_operation* op) { post_immediate_completion(op, false); } // Request invocation of the given operation using the thread-private queue // and return immediately. Assumes that work_started() was previously called // for the operation. void post_private_deferred_completion(win_iocp_operation* op) { post_deferred_completion(op); } // Enqueue the given operation following a failed attempt to dispatch the // operation for immediate invocation. void do_dispatch(operation* op) { post_immediate_completion(op, false); } // Process unfinished operations as part of a shutdown operation. Assumes // that work_started() was previously called for the operations. ASIO_DECL void abandon_operations(op_queue& ops); // Called after starting an overlapped I/O operation that did not complete // immediately. The caller must have already called work_started() prior to // starting the operation. ASIO_DECL void on_pending(win_iocp_operation* op); // Called after starting an overlapped I/O operation that completed // immediately. The caller must have already called work_started() prior to // starting the operation. ASIO_DECL void on_completion(win_iocp_operation* op, DWORD last_error = 0, DWORD bytes_transferred = 0); // Called after starting an overlapped I/O operation that completed // immediately. The caller must have already called work_started() prior to // starting the operation. ASIO_DECL void on_completion(win_iocp_operation* op, const asio::error_code& ec, DWORD bytes_transferred = 0); // Add a new timer queue to the service. template void add_timer_queue(timer_queue& timer_queue); // Remove a timer queue from the service. template void remove_timer_queue(timer_queue& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template void schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op); // Cancel the timer associated with the given token. Returns the number of // handlers that have been posted or dispatched. template std::size_t cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits::max)()); // Move the timer operations associated with the given timer. template void move_timer(timer_queue& queue, typename timer_queue::per_timer_data& to, typename timer_queue::per_timer_data& from); // Get the concurrency hint that was used to initialise the io_context. int concurrency_hint() const { return concurrency_hint_; } private: #if defined(WINVER) && (WINVER < 0x0500) typedef DWORD dword_ptr_t; typedef ULONG ulong_ptr_t; #else // defined(WINVER) && (WINVER < 0x0500) typedef DWORD_PTR dword_ptr_t; typedef ULONG_PTR ulong_ptr_t; #endif // defined(WINVER) && (WINVER < 0x0500) // Dequeues at most one operation from the I/O completion port, and then // executes it. Returns the number of operations that were dequeued (i.e. // either 0 or 1). ASIO_DECL size_t do_one(DWORD msec, asio::error_code& ec); // Helper to calculate the GetQueuedCompletionStatus timeout. ASIO_DECL static DWORD get_gqcs_timeout(); // Helper function to add a new timer queue. ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); // Helper function to remove a timer queue. ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Called to recalculate and update the timeout. ASIO_DECL void update_timeout(); // Helper class to call work_finished() on block exit. struct work_finished_on_block_exit; // Helper class for managing a HANDLE. struct auto_handle { HANDLE handle; auto_handle() : handle(0) {} ~auto_handle() { if (handle) ::CloseHandle(handle); } }; // The IO completion port used for queueing operations. auto_handle iocp_; // The count of unfinished work. long outstanding_work_; // Flag to indicate whether the event loop has been stopped. mutable long stopped_; // Flag to indicate whether there is an in-flight stop event. Every event // posted using PostQueuedCompletionStatus consumes non-paged pool, so to // avoid exhausting this resouce we limit the number of outstanding events. long stop_event_posted_; // Flag to indicate whether the service has been shut down. long shutdown_; enum { // Timeout to use with GetQueuedCompletionStatus on older versions of // Windows. Some versions of windows have a "bug" where a call to // GetQueuedCompletionStatus can appear stuck even though there are events // waiting on the queue. Using a timeout helps to work around the issue. default_gqcs_timeout = 500, // Maximum waitable timer timeout, in milliseconds. max_timeout_msec = 5 * 60 * 1000, // Maximum waitable timer timeout, in microseconds. max_timeout_usec = max_timeout_msec * 1000, // Completion key value used to wake up a thread to dispatch timers or // completed operations. wake_for_dispatch = 1, // Completion key value to indicate that an operation has posted with the // original last_error and bytes_transferred values stored in the fields of // the OVERLAPPED structure. overlapped_contains_result = 2 }; // Timeout to use with GetQueuedCompletionStatus. const DWORD gqcs_timeout_; // Helper class to run the scheduler in its own thread. struct thread_function; friend struct thread_function; // Function object for processing timeouts in a background thread. struct timer_thread_function; friend struct timer_thread_function; // Background thread used for processing timeouts. scoped_ptr timer_thread_; // A waitable timer object used for waiting for timeouts. auto_handle waitable_timer_; // Non-zero if timers or completed operations need to be dispatched. long dispatch_required_; // Mutex for protecting access to the timer queues and completed operations. mutex dispatch_mutex_; // The timer queues. timer_queue_set timer_queues_; // The operations that are ready to dispatch. op_queue completed_ops_; // The concurrency hint used to initialise the io_context. const int concurrency_hint_; // The thread that is running the io_context. scoped_ptr thread_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/win_iocp_io_context.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_iocp_io_context.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_null_buffers_op.hpp ================================================ // // detail/win_iocp_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP #define ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_null_buffers_op : public reactor_op { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_null_buffers_op); win_iocp_null_buffers_op(socket_ops::weak_cancel_token_type cancel_token, Handler& handler, const IoExecutor& io_ex) : reactor_op(&win_iocp_null_buffers_op::do_perform, &win_iocp_null_buffers_op::do_complete), cancel_token_(cancel_token), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static status do_perform(reactor_op*) { return done; } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t bytes_transferred) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_null_buffers_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // The reactor may have stored a result in the operation object. if (o->ec_) ec = o->ec_; // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_NETNAME_DELETED) { if (o->cancel_token_.expired()) ec = asio::error::operation_aborted; else ec = asio::error::connection_reset; } else if (ec.value() == ERROR_PORT_UNREACHABLE) { ec = asio::error::connection_refused; } // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: socket_ops::weak_cancel_token_type cancel_token_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_operation.hpp ================================================ // // detail/win_iocp_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_OPERATION_HPP #define ASIO_DETAIL_WIN_IOCP_OPERATION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/handler_tracking.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/socket_types.hpp" #include "asio/error_code.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_iocp_io_context; // Base class for all operations. A function pointer is used instead of virtual // functions to avoid the associated overhead. class win_iocp_operation : public OVERLAPPED ASIO_ALSO_INHERIT_TRACKED_HANDLER { public: typedef win_iocp_operation operation_type; void complete(void* owner, const asio::error_code& ec, std::size_t bytes_transferred) { func_(owner, this, ec, bytes_transferred); } void destroy() { func_(0, this, asio::error_code(), 0); } protected: typedef void (*func_type)( void*, win_iocp_operation*, const asio::error_code&, std::size_t); win_iocp_operation(func_type func) : next_(0), func_(func) { reset(); } // Prevents deletion through this type. ~win_iocp_operation() { } void reset() { Internal = 0; InternalHigh = 0; Offset = 0; OffsetHigh = 0; hEvent = 0; ready_ = 0; } private: friend class op_queue_access; friend class win_iocp_io_context; win_iocp_operation* next_; func_type func_; long ready_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_OPERATION_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_overlapped_op.hpp ================================================ // // detail/win_iocp_overlapped_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP #define ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/error.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_overlapped_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_overlapped_op); win_iocp_overlapped_op(Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_overlapped_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& ec, std::size_t bytes_transferred) { // Take ownership of the operation object. win_iocp_overlapped_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_overlapped_ptr.hpp ================================================ // // detail/win_iocp_overlapped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP #define ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/io_context.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/io_object_executor.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/win_iocp_overlapped_op.hpp" #include "asio/detail/win_iocp_io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Wraps a handler to create an OVERLAPPED object for use with overlapped I/O. class win_iocp_overlapped_ptr : private noncopyable { public: // Construct an empty win_iocp_overlapped_ptr. win_iocp_overlapped_ptr() : ptr_(0), iocp_service_(0) { } // Construct an win_iocp_overlapped_ptr to contain the specified handler. template explicit win_iocp_overlapped_ptr(const Executor& ex, ASIO_MOVE_ARG(Handler) handler) : ptr_(0), iocp_service_(0) { this->reset(ex, ASIO_MOVE_CAST(Handler)(handler)); } // Destructor automatically frees the OVERLAPPED object unless released. ~win_iocp_overlapped_ptr() { reset(); } // Reset to empty. void reset() { if (ptr_) { ptr_->destroy(); ptr_ = 0; iocp_service_->work_finished(); iocp_service_ = 0; } } // Reset to contain the specified handler, freeing any current OVERLAPPED // object. template void reset(const Executor& ex, Handler handler) { const bool native = is_same::value; win_iocp_io_context* iocp_service = this->get_iocp_service(ex); typedef win_iocp_overlapped_op > op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_object_executor(ex, native)); ASIO_HANDLER_CREATION((ex.context(), *p.p, "iocp_service", iocp_service, 0, "overlapped")); iocp_service->work_started(); reset(); ptr_ = p.p; p.v = p.p = 0; iocp_service_ = iocp_service; } // Get the contained OVERLAPPED object. OVERLAPPED* get() { return ptr_; } // Get the contained OVERLAPPED object. const OVERLAPPED* get() const { return ptr_; } // Release ownership of the OVERLAPPED object. OVERLAPPED* release() { if (ptr_) iocp_service_->on_pending(ptr_); OVERLAPPED* tmp = ptr_; ptr_ = 0; iocp_service_ = 0; return tmp; } // Post completion notification for overlapped operation. Releases ownership. void complete(const asio::error_code& ec, std::size_t bytes_transferred) { if (ptr_) { iocp_service_->on_completion(ptr_, ec, static_cast(bytes_transferred)); ptr_ = 0; iocp_service_ = 0; } } private: template static win_iocp_io_context* get_iocp_service(const Executor& ex) { return &use_service(ex.context()); } static win_iocp_io_context* get_iocp_service( const io_context::executor_type& ex) { return &ex.context().impl_; } win_iocp_operation* ptr_; win_iocp_io_context* iocp_service_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_serial_port_service.hpp ================================================ // // detail/win_iocp_serial_port_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP #define ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) && defined(ASIO_HAS_SERIAL_PORT) #include #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/win_iocp_handle_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Extend win_iocp_handle_service to provide serial port support. class win_iocp_serial_port_service : public execution_context_service_base { public: // The native type of a serial port. typedef win_iocp_handle_service::native_handle_type native_handle_type; // The implementation type of the serial port. typedef win_iocp_handle_service::implementation_type implementation_type; // Constructor. ASIO_DECL win_iocp_serial_port_service(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Construct a new serial port implementation. void construct(implementation_type& impl) { handle_service_.construct(impl); } // Move-construct a new serial port implementation. void move_construct(implementation_type& impl, implementation_type& other_impl) { handle_service_.move_construct(impl, other_impl); } // Move-assign from another serial port implementation. void move_assign(implementation_type& impl, win_iocp_serial_port_service& other_service, implementation_type& other_impl) { handle_service_.move_assign(impl, other_service.handle_service_, other_impl); } // Destroy a serial port implementation. void destroy(implementation_type& impl) { handle_service_.destroy(impl); } // Open the serial port using the specified device name. ASIO_DECL asio::error_code open(implementation_type& impl, const std::string& device, asio::error_code& ec); // Assign a native handle to a serial port implementation. asio::error_code assign(implementation_type& impl, const native_handle_type& handle, asio::error_code& ec) { return handle_service_.assign(impl, handle, ec); } // Determine whether the serial port is open. bool is_open(const implementation_type& impl) const { return handle_service_.is_open(impl); } // Destroy a serial port implementation. asio::error_code close(implementation_type& impl, asio::error_code& ec) { return handle_service_.close(impl, ec); } // Get the native serial port representation. native_handle_type native_handle(implementation_type& impl) { return handle_service_.native_handle(impl); } // Cancel all operations associated with the handle. asio::error_code cancel(implementation_type& impl, asio::error_code& ec) { return handle_service_.cancel(impl, ec); } // Set an option on the serial port. template asio::error_code set_option(implementation_type& impl, const SettableSerialPortOption& option, asio::error_code& ec) { return do_set_option(impl, &win_iocp_serial_port_service::store_option, &option, ec); } // Get an option from the serial port. template asio::error_code get_option(const implementation_type& impl, GettableSerialPortOption& option, asio::error_code& ec) const { return do_get_option(impl, &win_iocp_serial_port_service::load_option, &option, ec); } // Send a break sequence to the serial port. asio::error_code send_break(implementation_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Write the given data. Returns the number of bytes sent. template size_t write_some(implementation_type& impl, const ConstBufferSequence& buffers, asio::error_code& ec) { return handle_service_.write_some(impl, buffers, ec); } // Start an asynchronous write. The data being written must be valid for the // lifetime of the asynchronous operation. template void async_write_some(implementation_type& impl, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { handle_service_.async_write_some(impl, buffers, handler, io_ex); } // Read some data. Returns the number of bytes received. template size_t read_some(implementation_type& impl, const MutableBufferSequence& buffers, asio::error_code& ec) { return handle_service_.read_some(impl, buffers, ec); } // Start an asynchronous read. The buffer for the data being received must be // valid for the lifetime of the asynchronous operation. template void async_read_some(implementation_type& impl, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) { handle_service_.async_read_some(impl, buffers, handler, io_ex); } private: // Function pointer type for storing a serial port option. typedef asio::error_code (*store_function_type)( const void*, ::DCB&, asio::error_code&); // Helper function template to store a serial port option. template static asio::error_code store_option(const void* option, ::DCB& storage, asio::error_code& ec) { static_cast(option)->store(storage, ec); return ec; } // Helper function to set a serial port option. ASIO_DECL asio::error_code do_set_option( implementation_type& impl, store_function_type store, const void* option, asio::error_code& ec); // Function pointer type for loading a serial port option. typedef asio::error_code (*load_function_type)( void*, const ::DCB&, asio::error_code&); // Helper function template to load a serial port option. template static asio::error_code load_option(void* option, const ::DCB& storage, asio::error_code& ec) { static_cast(option)->load(storage, ec); return ec; } // Helper function to get a serial port option. ASIO_DECL asio::error_code do_get_option( const implementation_type& impl, load_function_type load, void* option, asio::error_code& ec) const; // The implementation used for initiating asynchronous operations. win_iocp_handle_service handle_service_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_iocp_serial_port_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_IOCP) && defined(ASIO_HAS_SERIAL_PORT) #endif // ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_accept_op.hpp ================================================ // // detail/win_iocp_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/win_iocp_socket_service_base.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_socket_accept_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_accept_op); win_iocp_socket_accept_op(win_iocp_socket_service_base& socket_service, socket_type socket, Socket& peer, const Protocol& protocol, typename Protocol::endpoint* peer_endpoint, bool enable_connection_aborted, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_socket_accept_op::do_complete), socket_service_(socket_service), socket_(socket), peer_(peer), protocol_(protocol), peer_endpoint_(peer_endpoint), enable_connection_aborted_(enable_connection_aborted), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } socket_holder& new_socket() { return new_socket_; } void* output_buffer() { return output_buffer_; } DWORD address_length() { return sizeof(sockaddr_storage_type) + 16; } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t /*bytes_transferred*/) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_socket_accept_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); if (owner) { typename Protocol::endpoint peer_endpoint; std::size_t addr_len = peer_endpoint.capacity(); socket_ops::complete_iocp_accept(o->socket_, o->output_buffer(), o->address_length(), peer_endpoint.data(), &addr_len, o->new_socket_.get(), ec); // Restart the accept operation if we got the connection_aborted error // and the enable_connection_aborted socket option is not set. if (ec == asio::error::connection_aborted && !o->enable_connection_aborted_) { o->reset(); o->socket_service_.restart_accept_op(o->socket_, o->new_socket_, o->protocol_.family(), o->protocol_.type(), o->protocol_.protocol(), o->output_buffer(), o->address_length(), o); p.v = p.p = 0; return; } // If the socket was successfully accepted, transfer ownership of the // socket to the peer object. if (!ec) { o->peer_.assign(o->protocol_, typename Socket::native_handle_type( o->new_socket_.get(), peer_endpoint), ec); if (!ec) o->new_socket_.release(); } // Pass endpoint back to caller. if (o->peer_endpoint_) *o->peer_endpoint_ = peer_endpoint; } ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(o->handler_, ec); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: win_iocp_socket_service_base& socket_service_; socket_type socket_; socket_holder new_socket_; Socket& peer_; Protocol protocol_; typename Protocol::endpoint* peer_endpoint_; unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; bool enable_connection_aborted_; Handler handler_; IoExecutor io_executor_; }; #if defined(ASIO_HAS_MOVE) template class win_iocp_socket_move_accept_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_move_accept_op); win_iocp_socket_move_accept_op( win_iocp_socket_service_base& socket_service, socket_type socket, const Protocol& protocol, const PeerIoExecutor& peer_io_ex, typename Protocol::endpoint* peer_endpoint, bool enable_connection_aborted, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_socket_move_accept_op::do_complete), socket_service_(socket_service), socket_(socket), peer_(peer_io_ex), protocol_(protocol), peer_endpoint_(peer_endpoint), enable_connection_aborted_(enable_connection_aborted), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } socket_holder& new_socket() { return new_socket_; } void* output_buffer() { return output_buffer_; } DWORD address_length() { return sizeof(sockaddr_storage_type) + 16; } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t /*bytes_transferred*/) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_socket_move_accept_op* o( static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); if (owner) { typename Protocol::endpoint peer_endpoint; std::size_t addr_len = peer_endpoint.capacity(); socket_ops::complete_iocp_accept(o->socket_, o->output_buffer(), o->address_length(), peer_endpoint.data(), &addr_len, o->new_socket_.get(), ec); // Restart the accept operation if we got the connection_aborted error // and the enable_connection_aborted socket option is not set. if (ec == asio::error::connection_aborted && !o->enable_connection_aborted_) { o->reset(); o->socket_service_.restart_accept_op(o->socket_, o->new_socket_, o->protocol_.family(), o->protocol_.type(), o->protocol_.protocol(), o->output_buffer(), o->address_length(), o); p.v = p.p = 0; return; } // If the socket was successfully accepted, transfer ownership of the // socket to the peer object. if (!ec) { o->peer_.assign(o->protocol_, typename Protocol::socket::native_handle_type( o->new_socket_.get(), peer_endpoint), ec); if (!ec) o->new_socket_.release(); } // Pass endpoint back to caller. if (o->peer_endpoint_) *o->peer_endpoint_ = peer_endpoint; } ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::move_binder2 handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), ec, ASIO_MOVE_CAST(peer_socket_type)(o->peer_)); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: typedef typename Protocol::socket::template rebind_executor::other peer_socket_type; win_iocp_socket_service_base& socket_service_; socket_type socket_; socket_holder new_socket_; peer_socket_type peer_; Protocol protocol_; typename Protocol::endpoint* peer_endpoint_; unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; bool enable_connection_aborted_; Handler handler_; IoExecutor io_executor_; }; #endif // defined(ASIO_HAS_MOVE) } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_connect_op.hpp ================================================ // // detail/win_iocp_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_CONNECT_OP_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_CONNECT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_iocp_socket_connect_op_base : public reactor_op { public: win_iocp_socket_connect_op_base(socket_type socket, func_type complete_func) : reactor_op(&win_iocp_socket_connect_op_base::do_perform, complete_func), socket_(socket), connect_ex_(false) { } static status do_perform(reactor_op* base) { win_iocp_socket_connect_op_base* o( static_cast(base)); return socket_ops::non_blocking_connect( o->socket_, o->ec_) ? done : not_done; } socket_type socket_; bool connect_ex_; }; template class win_iocp_socket_connect_op : public win_iocp_socket_connect_op_base { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_connect_op); win_iocp_socket_connect_op(socket_type socket, Handler& handler, const IoExecutor& io_ex) : win_iocp_socket_connect_op_base(socket, &win_iocp_socket_connect_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t /*bytes_transferred*/) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_socket_connect_op* o( static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); if (owner) { if (o->connect_ex_) socket_ops::complete_iocp_connect(o->socket_, ec); else ec = o->ec_; } ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(o->handler_, ec); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_CONNECT_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_recv_op.hpp ================================================ // // detail/win_iocp_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_socket_recv_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recv_op); win_iocp_socket_recv_op(socket_ops::state_type state, socket_ops::weak_cancel_token_type cancel_token, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_socket_recv_op::do_complete), state_(state), cancel_token_(cancel_token), buffers_(buffers), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t bytes_transferred) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_socket_recv_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. if (owner) { buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) socket_ops::complete_iocp_recv(o->state_, o->cancel_token_, buffer_sequence_adapter::all_empty(o->buffers_), ec, bytes_transferred); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: socket_ops::state_type state_; socket_ops::weak_cancel_token_type cancel_token_; MutableBufferSequence buffers_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_recvfrom_op.hpp ================================================ // // detail/win_iocp_socket_recvfrom_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_socket_recvfrom_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recvfrom_op); win_iocp_socket_recvfrom_op(Endpoint& endpoint, socket_ops::weak_cancel_token_type cancel_token, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_socket_recvfrom_op::do_complete), endpoint_(endpoint), endpoint_size_(static_cast(endpoint.capacity())), cancel_token_(cancel_token), buffers_(buffers), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } int& endpoint_size() { return endpoint_size_; } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t bytes_transferred) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_socket_recvfrom_op* o( static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. if (owner) { buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) socket_ops::complete_iocp_recvfrom(o->cancel_token_, ec); // Record the size of the endpoint returned by the operation. o->endpoint_.resize(o->endpoint_size_); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Endpoint& endpoint_; int endpoint_size_; socket_ops::weak_cancel_token_type cancel_token_; MutableBufferSequence buffers_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_recvmsg_op.hpp ================================================ // // detail/win_iocp_socket_recvmsg_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_RECVMSG_OP_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_RECVMSG_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #include "asio/socket_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_socket_recvmsg_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recvmsg_op); win_iocp_socket_recvmsg_op( socket_ops::weak_cancel_token_type cancel_token, const MutableBufferSequence& buffers, socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_socket_recvmsg_op::do_complete), cancel_token_(cancel_token), buffers_(buffers), out_flags_(out_flags), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t bytes_transferred) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_socket_recvmsg_op* o( static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. if (owner) { buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) socket_ops::complete_iocp_recvmsg(o->cancel_token_, ec); o->out_flags_ = 0; // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: socket_ops::weak_cancel_token_type cancel_token_; MutableBufferSequence buffers_; socket_base::message_flags& out_flags_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_RECVMSG_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_send_op.hpp ================================================ // // detail/win_iocp_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_socket_send_op : public operation { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_send_op); win_iocp_socket_send_op(socket_ops::weak_cancel_token_type cancel_token, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_socket_send_op::do_complete), cancel_token_(cancel_token), buffers_(buffers), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t bytes_transferred) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_socket_send_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. if (owner) { buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) socket_ops::complete_iocp_send(o->cancel_token_, ec); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, ec, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: socket_ops::weak_cancel_token_type cancel_token_; ConstBufferSequence buffers_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_service.hpp ================================================ // // detail/win_iocp_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/socket_base.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/select_reactor.hpp" #include "asio/detail/socket_holder.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/win_iocp_io_context.hpp" #include "asio/detail/win_iocp_null_buffers_op.hpp" #include "asio/detail/win_iocp_socket_accept_op.hpp" #include "asio/detail/win_iocp_socket_connect_op.hpp" #include "asio/detail/win_iocp_socket_recvfrom_op.hpp" #include "asio/detail/win_iocp_socket_send_op.hpp" #include "asio/detail/win_iocp_socket_service_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_socket_service : public execution_context_service_base >, public win_iocp_socket_service_base { public: // The protocol type. typedef Protocol protocol_type; // The endpoint type. typedef typename Protocol::endpoint endpoint_type; // The native type of a socket. class native_handle_type { public: native_handle_type(socket_type s) : socket_(s), have_remote_endpoint_(false) { } native_handle_type(socket_type s, const endpoint_type& ep) : socket_(s), have_remote_endpoint_(true), remote_endpoint_(ep) { } void operator=(socket_type s) { socket_ = s; have_remote_endpoint_ = false; remote_endpoint_ = endpoint_type(); } operator socket_type() const { return socket_; } bool have_remote_endpoint() const { return have_remote_endpoint_; } endpoint_type remote_endpoint() const { return remote_endpoint_; } private: socket_type socket_; bool have_remote_endpoint_; endpoint_type remote_endpoint_; }; // The implementation type of the socket. struct implementation_type : win_iocp_socket_service_base::base_implementation_type { // Default constructor. implementation_type() : protocol_(endpoint_type().protocol()), have_remote_endpoint_(false), remote_endpoint_() { } // The protocol associated with the socket. protocol_type protocol_; // Whether we have a cached remote endpoint. bool have_remote_endpoint_; // A cached remote endpoint. endpoint_type remote_endpoint_; }; // Constructor. win_iocp_socket_service(execution_context& context) : execution_context_service_base< win_iocp_socket_service >(context), win_iocp_socket_service_base(context) { } // Destroy all user-defined handler objects owned by the service. void shutdown() { this->base_shutdown(); } // Move-construct a new socket implementation. void move_construct(implementation_type& impl, implementation_type& other_impl) ASIO_NOEXCEPT { this->base_move_construct(impl, other_impl); impl.protocol_ = other_impl.protocol_; other_impl.protocol_ = endpoint_type().protocol(); impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_; other_impl.have_remote_endpoint_ = false; impl.remote_endpoint_ = other_impl.remote_endpoint_; other_impl.remote_endpoint_ = endpoint_type(); } // Move-assign from another socket implementation. void move_assign(implementation_type& impl, win_iocp_socket_service_base& other_service, implementation_type& other_impl) { this->base_move_assign(impl, other_service, other_impl); impl.protocol_ = other_impl.protocol_; other_impl.protocol_ = endpoint_type().protocol(); impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_; other_impl.have_remote_endpoint_ = false; impl.remote_endpoint_ = other_impl.remote_endpoint_; other_impl.remote_endpoint_ = endpoint_type(); } // Move-construct a new socket implementation from another protocol type. template void converting_move_construct(implementation_type& impl, win_iocp_socket_service&, typename win_iocp_socket_service< Protocol1>::implementation_type& other_impl) { this->base_move_construct(impl, other_impl); impl.protocol_ = protocol_type(other_impl.protocol_); other_impl.protocol_ = typename Protocol1::endpoint().protocol(); impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_; other_impl.have_remote_endpoint_ = false; impl.remote_endpoint_ = other_impl.remote_endpoint_; other_impl.remote_endpoint_ = typename Protocol1::endpoint(); } // Open a new socket implementation. asio::error_code open(implementation_type& impl, const protocol_type& protocol, asio::error_code& ec) { if (!do_open(impl, protocol.family(), protocol.type(), protocol.protocol(), ec)) { impl.protocol_ = protocol; impl.have_remote_endpoint_ = false; impl.remote_endpoint_ = endpoint_type(); } return ec; } // Assign a native socket to a socket implementation. asio::error_code assign(implementation_type& impl, const protocol_type& protocol, const native_handle_type& native_socket, asio::error_code& ec) { if (!do_assign(impl, protocol.type(), native_socket, ec)) { impl.protocol_ = protocol; impl.have_remote_endpoint_ = native_socket.have_remote_endpoint(); impl.remote_endpoint_ = native_socket.remote_endpoint(); } return ec; } // Get the native socket representation. native_handle_type native_handle(implementation_type& impl) { if (impl.have_remote_endpoint_) return native_handle_type(impl.socket_, impl.remote_endpoint_); return native_handle_type(impl.socket_); } // Bind the socket to the specified local endpoint. asio::error_code bind(implementation_type& impl, const endpoint_type& endpoint, asio::error_code& ec) { socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); return ec; } // Set a socket option. template asio::error_code set_option(implementation_type& impl, const Option& option, asio::error_code& ec) { socket_ops::setsockopt(impl.socket_, impl.state_, option.level(impl.protocol_), option.name(impl.protocol_), option.data(impl.protocol_), option.size(impl.protocol_), ec); return ec; } // Set a socket option. template asio::error_code get_option(const implementation_type& impl, Option& option, asio::error_code& ec) const { std::size_t size = option.size(impl.protocol_); socket_ops::getsockopt(impl.socket_, impl.state_, option.level(impl.protocol_), option.name(impl.protocol_), option.data(impl.protocol_), &size, ec); if (!ec) option.resize(impl.protocol_, size); return ec; } // Get the local endpoint. endpoint_type local_endpoint(const implementation_type& impl, asio::error_code& ec) const { endpoint_type endpoint; std::size_t addr_len = endpoint.capacity(); if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) return endpoint_type(); endpoint.resize(addr_len); return endpoint; } // Get the remote endpoint. endpoint_type remote_endpoint(const implementation_type& impl, asio::error_code& ec) const { endpoint_type endpoint = impl.remote_endpoint_; std::size_t addr_len = endpoint.capacity(); if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, impl.have_remote_endpoint_, ec)) return endpoint_type(); endpoint.resize(addr_len); return endpoint; } // Disable sends or receives on the socket. asio::error_code shutdown(base_implementation_type& impl, socket_base::shutdown_type what, asio::error_code& ec) { socket_ops::shutdown(impl.socket_, what, ec); return ec; } // Send a datagram to the specified endpoint. Returns the number of bytes // sent. template size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_sendto(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, destination.data(), destination.size(), ec); } // Wait until data can be sent without blocking. size_t send_to(implementation_type& impl, const null_buffers&, const endpoint_type&, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); return 0; } // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_send_to(implementation_type& impl, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_send_op< ConstBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, buffers, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_send_to")); buffer_sequence_adapter bufs(buffers); start_send_to_op(impl, bufs.buffers(), bufs.count(), destination.data(), static_cast(destination.size()), flags, p.p); p.v = p.p = 0; } // Start an asynchronous wait until data can be sent without blocking. template void async_send_to(implementation_type& impl, const null_buffers&, const endpoint_type&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_send_to(null_buffers)")); start_reactor_op(impl, select_reactor::write_op, p.p); p.v = p.p = 0; } // Receive a datagram with the endpoint of the sender. Returns the number of // bytes received. template size_t receive_from(implementation_type& impl, const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); std::size_t addr_len = sender_endpoint.capacity(); std::size_t bytes_recvd = socket_ops::sync_recvfrom( impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, sender_endpoint.data(), &addr_len, ec); if (!ec) sender_endpoint.resize(addr_len); return bytes_recvd; } // Wait until data can be received without blocking. size_t receive_from(implementation_type& impl, const null_buffers&, endpoint_type& sender_endpoint, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); return 0; } // Start an asynchronous receive. The buffer for the data being received and // the sender_endpoint object must both be valid for the lifetime of the // asynchronous operation. template void async_receive_from(implementation_type& impl, const MutableBufferSequence& buffers, endpoint_type& sender_endp, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_recvfrom_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(sender_endp, impl.cancel_token_, buffers, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_receive_from")); buffer_sequence_adapter bufs(buffers); start_receive_from_op(impl, bufs.buffers(), bufs.count(), sender_endp.data(), flags, &p.p->endpoint_size(), p.p); p.v = p.p = 0; } // Wait until data can be received without blocking. template void async_receive_from(implementation_type& impl, const null_buffers&, endpoint_type& sender_endpoint, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_receive_from(null_buffers)")); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); start_null_buffers_receive_op(impl, flags, p.p); p.v = p.p = 0; } // Accept a new connection. template asio::error_code accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, asio::error_code& ec) { // We cannot accept a socket that is already open. if (peer.is_open()) { ec = asio::error::already_open; return ec; } std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; socket_holder new_socket(socket_ops::sync_accept(impl.socket_, impl.state_, peer_endpoint ? peer_endpoint->data() : 0, peer_endpoint ? &addr_len : 0, ec)); // On success, assign new connection to peer socket object. if (new_socket.get() != invalid_socket) { if (peer_endpoint) peer_endpoint->resize(addr_len); peer.assign(impl.protocol_, new_socket.get(), ec); if (!ec) new_socket.release(); } return ec; } // Start an asynchronous accept. The peer and peer_endpoint objects // must be valid until the accept's handler is invoked. template void async_accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_accept_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; bool enable_connection_aborted = (impl.state_ & socket_ops::enable_connection_aborted) != 0; p.p = new (p.v) op(*this, impl.socket_, peer, impl.protocol_, peer_endpoint, enable_connection_aborted, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_accept")); start_accept_op(impl, peer.is_open(), p.p->new_socket(), impl.protocol_.family(), impl.protocol_.type(), impl.protocol_.protocol(), p.p->output_buffer(), p.p->address_length(), p.p); p.v = p.p = 0; } #if defined(ASIO_HAS_MOVE) // Start an asynchronous accept. The peer and peer_endpoint objects // must be valid until the accept's handler is invoked. template void async_move_accept(implementation_type& impl, const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_move_accept_op< protocol_type, PeerIoExecutor, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; bool enable_connection_aborted = (impl.state_ & socket_ops::enable_connection_aborted) != 0; p.p = new (p.v) op(*this, impl.socket_, impl.protocol_, peer_io_ex, peer_endpoint, enable_connection_aborted, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_accept")); start_accept_op(impl, false, p.p->new_socket(), impl.protocol_.family(), impl.protocol_.type(), impl.protocol_.protocol(), p.p->output_buffer(), p.p->address_length(), p.p); p.v = p.p = 0; } #endif // defined(ASIO_HAS_MOVE) // Connect the socket to the specified endpoint. asio::error_code connect(implementation_type& impl, const endpoint_type& peer_endpoint, asio::error_code& ec) { socket_ops::sync_connect(impl.socket_, peer_endpoint.data(), peer_endpoint.size(), ec); return ec; } // Start an asynchronous connect. template void async_connect(implementation_type& impl, const endpoint_type& peer_endpoint, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_connect_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_connect")); start_connect_op(impl, impl.protocol_.family(), impl.protocol_.type(), peer_endpoint.data(), static_cast(peer_endpoint.size()), p.p); p.v = p.p = 0; } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_socket_service_base.hpp ================================================ // // detail/win_iocp_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP #define ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/socket_base.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/select_reactor.hpp" #include "asio/detail/socket_holder.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/win_iocp_io_context.hpp" #include "asio/detail/win_iocp_null_buffers_op.hpp" #include "asio/detail/win_iocp_socket_connect_op.hpp" #include "asio/detail/win_iocp_socket_send_op.hpp" #include "asio/detail/win_iocp_socket_recv_op.hpp" #include "asio/detail/win_iocp_socket_recvmsg_op.hpp" #include "asio/detail/win_iocp_wait_op.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_iocp_socket_service_base { public: // The implementation type of the socket. struct base_implementation_type { // The native socket representation. socket_type socket_; // The current state of the socket. socket_ops::state_type state_; // We use a shared pointer as a cancellation token here to work around the // broken Windows support for cancellation. MSDN says that when you call // closesocket any outstanding WSARecv or WSASend operations will complete // with the error ERROR_OPERATION_ABORTED. In practice they complete with // ERROR_NETNAME_DELETED, which means you can't tell the difference between // a local cancellation and the socket being hard-closed by the peer. socket_ops::shared_cancel_token_type cancel_token_; // Per-descriptor data used by the reactor. select_reactor::per_descriptor_data reactor_data_; #if defined(ASIO_ENABLE_CANCELIO) // The ID of the thread from which it is safe to cancel asynchronous // operations. 0 means no asynchronous operations have been started yet. // ~0 means asynchronous operations have been started from more than one // thread, and cancellation is not supported for the socket. DWORD safe_cancellation_thread_id_; #endif // defined(ASIO_ENABLE_CANCELIO) // Pointers to adjacent socket implementations in linked list. base_implementation_type* next_; base_implementation_type* prev_; }; // Constructor. ASIO_DECL win_iocp_socket_service_base(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void base_shutdown(); // Construct a new socket implementation. ASIO_DECL void construct(base_implementation_type& impl); // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl, base_implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl, win_iocp_socket_service_base& other_service, base_implementation_type& other_impl); // Destroy a socket implementation. ASIO_DECL void destroy(base_implementation_type& impl); // Determine whether the socket is open. bool is_open(const base_implementation_type& impl) const { return impl.socket_ != invalid_socket; } // Destroy a socket implementation. ASIO_DECL asio::error_code close( base_implementation_type& impl, asio::error_code& ec); // Release ownership of the socket. ASIO_DECL socket_type release( base_implementation_type& impl, asio::error_code& ec); // Cancel all operations associated with the socket. ASIO_DECL asio::error_code cancel( base_implementation_type& impl, asio::error_code& ec); // Determine whether the socket is at the out-of-band data mark. bool at_mark(const base_implementation_type& impl, asio::error_code& ec) const { return socket_ops::sockatmark(impl.socket_, ec); } // Determine the number of bytes available for reading. std::size_t available(const base_implementation_type& impl, asio::error_code& ec) const { return socket_ops::available(impl.socket_, ec); } // Place the socket into the state where it will listen for new connections. asio::error_code listen(base_implementation_type& impl, int backlog, asio::error_code& ec) { socket_ops::listen(impl.socket_, backlog, ec); return ec; } // Perform an IO control command on the socket. template asio::error_code io_control(base_implementation_type& impl, IO_Control_Command& command, asio::error_code& ec) { socket_ops::ioctl(impl.socket_, impl.state_, command.name(), static_cast(command.data()), ec); return ec; } // Gets the non-blocking mode of the socket. bool non_blocking(const base_implementation_type& impl) const { return (impl.state_ & socket_ops::user_set_non_blocking) != 0; } // Sets the non-blocking mode of the socket. asio::error_code non_blocking(base_implementation_type& impl, bool mode, asio::error_code& ec) { socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); return ec; } // Gets the non-blocking mode of the native socket implementation. bool native_non_blocking(const base_implementation_type& impl) const { return (impl.state_ & socket_ops::internal_non_blocking) != 0; } // Sets the non-blocking mode of the native socket implementation. asio::error_code native_non_blocking(base_implementation_type& impl, bool mode, asio::error_code& ec) { socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); return ec; } // Wait for the socket to become ready to read, ready to write, or to have // pending error conditions. asio::error_code wait(base_implementation_type& impl, socket_base::wait_type w, asio::error_code& ec) { switch (w) { case socket_base::wait_read: socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); break; case socket_base::wait_write: socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); break; case socket_base::wait_error: socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); break; default: ec = asio::error::invalid_argument; break; } return ec; } // Asynchronously wait for the socket to become ready to read, ready to // write, or to have pending error conditions. template void async_wait(base_implementation_type& impl, socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef win_iocp_wait_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_wait")); switch (w) { case socket_base::wait_read: start_null_buffers_receive_op(impl, 0, p.p); break; case socket_base::wait_write: start_reactor_op(impl, select_reactor::write_op, p.p); break; case socket_base::wait_error: start_reactor_op(impl, select_reactor::except_op, p.p); break; default: p.p->ec_ = asio::error::invalid_argument; iocp_service_.post_immediate_completion(p.p, is_continuation); break; } p.v = p.p = 0; } // Send the given data to the peer. Returns the number of bytes sent. template size_t send(base_implementation_type& impl, const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_send(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); } // Wait until data can be sent without blocking. size_t send(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); return 0; } // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_send(base_implementation_type& impl, const ConstBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_send_op< ConstBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, buffers, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_send")); buffer_sequence_adapter bufs(buffers); start_send_op(impl, bufs.buffers(), bufs.count(), flags, (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(), p.p); p.v = p.p = 0; } // Start an asynchronous wait until data can be sent without blocking. template void async_send(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_send(null_buffers)")); start_reactor_op(impl, select_reactor::write_op, p.p); p.v = p.p = 0; } // Receive some data from the peer. Returns the number of bytes received. template size_t receive(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_recv(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); } // Wait until data can be received without blocking. size_t receive(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); return 0; } // Start an asynchronous receive. The buffer for the data being received // must be valid for the lifetime of the asynchronous operation. template void async_receive(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_recv_op< MutableBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.state_, impl.cancel_token_, buffers, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_receive")); buffer_sequence_adapter bufs(buffers); start_receive_op(impl, bufs.buffers(), bufs.count(), flags, (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(), p.p); p.v = p.p = 0; } // Wait until data can be received without blocking. template void async_receive(base_implementation_type& impl, const null_buffers&, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_receive(null_buffers)")); start_null_buffers_receive_op(impl, flags, p.p); p.v = p.p = 0; } // Receive some data with associated flags. Returns the number of bytes // received. template size_t receive_with_flags(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, asio::error_code& ec) { buffer_sequence_adapter bufs(buffers); return socket_ops::sync_recvmsg(impl.socket_, impl.state_, bufs.buffers(), bufs.count(), in_flags, out_flags, ec); } // Wait until data can be received without blocking. size_t receive_with_flags(base_implementation_type& impl, const null_buffers&, socket_base::message_flags, socket_base::message_flags& out_flags, asio::error_code& ec) { // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); // Clear out_flags, since we cannot give it any other sensible value when // performing a null_buffers operation. out_flags = 0; return 0; } // Start an asynchronous receive. The buffer for the data being received // must be valid for the lifetime of the asynchronous operation. template void async_receive_with_flags(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_recvmsg_op< MutableBufferSequence, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, buffers, out_flags, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_receive_with_flags")); buffer_sequence_adapter bufs(buffers); start_receive_op(impl, bufs.buffers(), bufs.count(), in_flags, false, p.p); p.v = p.p = 0; } // Wait until data can be received without blocking. template void async_receive_with_flags(base_implementation_type& impl, const null_buffers&, socket_base::message_flags in_flags, socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef win_iocp_null_buffers_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler, io_ex); ASIO_HANDLER_CREATION((context_, *p.p, "socket", &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); // Reset out_flags since it can be given no sensible value at this time. out_flags = 0; start_null_buffers_receive_op(impl, in_flags, p.p); p.v = p.p = 0; } // Helper function to restart an asynchronous accept operation. ASIO_DECL void restart_accept_op(socket_type s, socket_holder& new_socket, int family, int type, int protocol, void* output_buffer, DWORD address_length, operation* op); protected: // Open a new socket implementation. ASIO_DECL asio::error_code do_open( base_implementation_type& impl, int family, int type, int protocol, asio::error_code& ec); // Assign a native socket to a socket implementation. ASIO_DECL asio::error_code do_assign( base_implementation_type& impl, int type, socket_type native_socket, asio::error_code& ec); // Helper function to start an asynchronous send operation. ASIO_DECL void start_send_op(base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, socket_base::message_flags flags, bool noop, operation* op); // Helper function to start an asynchronous send_to operation. ASIO_DECL void start_send_to_op(base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, const socket_addr_type* addr, int addrlen, socket_base::message_flags flags, operation* op); // Helper function to start an asynchronous receive operation. ASIO_DECL void start_receive_op(base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, socket_base::message_flags flags, bool noop, operation* op); // Helper function to start an asynchronous null_buffers receive operation. ASIO_DECL void start_null_buffers_receive_op( base_implementation_type& impl, socket_base::message_flags flags, reactor_op* op); // Helper function to start an asynchronous receive_from operation. ASIO_DECL void start_receive_from_op(base_implementation_type& impl, WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr, socket_base::message_flags flags, int* addrlen, operation* op); // Helper function to start an asynchronous accept operation. ASIO_DECL void start_accept_op(base_implementation_type& impl, bool peer_is_open, socket_holder& new_socket, int family, int type, int protocol, void* output_buffer, DWORD address_length, operation* op); // Start an asynchronous read or write operation using the reactor. ASIO_DECL void start_reactor_op(base_implementation_type& impl, int op_type, reactor_op* op); // Start the asynchronous connect operation using the reactor. ASIO_DECL void start_connect_op(base_implementation_type& impl, int family, int type, const socket_addr_type* remote_addr, std::size_t remote_addrlen, win_iocp_socket_connect_op_base* op); // Helper function to close a socket when the associated object is being // destroyed. ASIO_DECL void close_for_destruction(base_implementation_type& impl); // Update the ID of the thread from which cancellation is safe. ASIO_DECL void update_cancellation_thread_id( base_implementation_type& impl); // Helper function to get the reactor. If no reactor has been created yet, a // new one is obtained from the execution context and a pointer to it is // cached in this service. ASIO_DECL select_reactor& get_reactor(); // The type of a ConnectEx function pointer, as old SDKs may not provide it. typedef BOOL (PASCAL *connect_ex_fn)(SOCKET, const socket_addr_type*, int, void*, DWORD, DWORD*, OVERLAPPED*); // Helper function to get the ConnectEx pointer. If no ConnectEx pointer has // been obtained yet, one is obtained using WSAIoctl and the pointer is // cached. Returns a null pointer if ConnectEx is not available. ASIO_DECL connect_ex_fn get_connect_ex( base_implementation_type& impl, int type); // The type of a NtSetInformationFile function pointer. typedef LONG (NTAPI *nt_set_info_fn)(HANDLE, ULONG_PTR*, void*, ULONG, ULONG); // Helper function to get the NtSetInformationFile function pointer. If no // NtSetInformationFile pointer has been obtained yet, one is obtained using // GetProcAddress and the pointer is cached. Returns a null pointer if // NtSetInformationFile is not available. ASIO_DECL nt_set_info_fn get_nt_set_info(); // Helper function to emulate InterlockedCompareExchangePointer functionality // for: // - very old Platform SDKs; and // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. ASIO_DECL void* interlocked_compare_exchange_pointer( void** dest, void* exch, void* cmp); // Helper function to emulate InterlockedExchangePointer functionality for: // - very old Platform SDKs; and // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. ASIO_DECL void* interlocked_exchange_pointer(void** dest, void* val); // The execution context used to obtain the reactor, if required. execution_context& context_; // The IOCP service used for running asynchronous operations and dispatching // handlers. win_iocp_io_context& iocp_service_; // The reactor used for performing connect operations. This object is created // only if needed. select_reactor* reactor_; // Pointer to ConnectEx implementation. void* connect_ex_; // Pointer to NtSetInformationFile implementation. void* nt_set_info_; // Mutex to protect access to the linked list of implementations. asio::detail::mutex mutex_; // The head of a linked list of all implementations. base_implementation_type* impl_list_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_iocp_socket_service_base.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_thread_info.hpp ================================================ // // detail/win_iocp_thread_info.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_THREAD_INFO_HPP #define ASIO_DETAIL_WIN_IOCP_THREAD_INFO_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/thread_info_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct win_iocp_thread_info : public thread_info_base { }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_WIN_IOCP_THREAD_INFO_HPP ================================================ FILE: src/third_party/asio/detail/win_iocp_wait_op.hpp ================================================ // // detail/win_iocp_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_IOCP_WAIT_OP_HPP #define ASIO_DETAIL_WIN_IOCP_WAIT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_IOCP) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class win_iocp_wait_op : public reactor_op { public: ASIO_DEFINE_HANDLER_PTR(win_iocp_wait_op); win_iocp_wait_op(socket_ops::weak_cancel_token_type cancel_token, Handler& handler, const IoExecutor& io_ex) : reactor_op(&win_iocp_wait_op::do_perform, &win_iocp_wait_op::do_complete), cancel_token_(cancel_token), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static status do_perform(reactor_op*) { return done; } static void do_complete(void* owner, operation* base, const asio::error_code& result_ec, std::size_t /*bytes_transferred*/) { asio::error_code ec(result_ec); // Take ownership of the operation object. win_iocp_wait_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // The reactor may have stored a result in the operation object. if (o->ec_) ec = o->ec_; // Map non-portable errors to their portable counterparts. if (ec.value() == ERROR_NETNAME_DELETED) { if (o->cancel_token_.expired()) ec = asio::error::operation_aborted; else ec = asio::error::connection_reset; } else if (ec.value() == ERROR_PORT_UNREACHABLE) { ec = asio::error::connection_refused; } // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(o->handler_, ec); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: socket_ops::weak_cancel_token_type cancel_token_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_IOCP) #endif // ASIO_DETAIL_WIN_IOCP_WAIT_OP_HPP ================================================ FILE: src/third_party/asio/detail/win_mutex.hpp ================================================ // // detail/win_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_MUTEX_HPP #define ASIO_DETAIL_WIN_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_mutex : private noncopyable { public: typedef asio::detail::scoped_lock scoped_lock; // Constructor. ASIO_DECL win_mutex(); // Destructor. ~win_mutex() { ::DeleteCriticalSection(&crit_section_); } // Lock the mutex. void lock() { ::EnterCriticalSection(&crit_section_); } // Unlock the mutex. void unlock() { ::LeaveCriticalSection(&crit_section_); } private: // Initialisation must be performed in a separate function to the constructor // since the compiler does not support the use of structured exceptions and // C++ exceptions in the same function. ASIO_DECL int do_init(); ::CRITICAL_SECTION crit_section_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_mutex.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_WIN_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/win_object_handle_service.hpp ================================================ // // detail/win_object_handle_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP #define ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/wait_handler.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class win_object_handle_service : public execution_context_service_base { public: // The native type of an object handle. typedef HANDLE native_handle_type; // The implementation type of the object handle. class implementation_type { public: // Default constructor. implementation_type() : handle_(INVALID_HANDLE_VALUE), wait_handle_(INVALID_HANDLE_VALUE), owner_(0), next_(0), prev_(0) { } private: // Only this service will have access to the internal values. friend class win_object_handle_service; // The native object handle representation. May be accessed or modified // without locking the mutex. native_handle_type handle_; // The handle used to unregister the wait operation. The mutex must be // locked when accessing or modifying this member. HANDLE wait_handle_; // The operations waiting on the object handle. If there is a registered // wait then the mutex must be locked when accessing or modifying this // member op_queue op_queue_; // The service instance that owns the object handle implementation. win_object_handle_service* owner_; // Pointers to adjacent handle implementations in linked list. The mutex // must be locked when accessing or modifying these members. implementation_type* next_; implementation_type* prev_; }; // Constructor. ASIO_DECL win_object_handle_service(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Construct a new handle implementation. ASIO_DECL void construct(implementation_type& impl); // Move-construct a new handle implementation. ASIO_DECL void move_construct(implementation_type& impl, implementation_type& other_impl); // Move-assign from another handle implementation. ASIO_DECL void move_assign(implementation_type& impl, win_object_handle_service& other_service, implementation_type& other_impl); // Destroy a handle implementation. ASIO_DECL void destroy(implementation_type& impl); // Assign a native handle to a handle implementation. ASIO_DECL asio::error_code assign(implementation_type& impl, const native_handle_type& handle, asio::error_code& ec); // Determine whether the handle is open. bool is_open(const implementation_type& impl) const { return impl.handle_ != INVALID_HANDLE_VALUE && impl.handle_ != 0; } // Destroy a handle implementation. ASIO_DECL asio::error_code close(implementation_type& impl, asio::error_code& ec); // Get the native handle representation. native_handle_type native_handle(const implementation_type& impl) const { return impl.handle_; } // Cancel all operations associated with the handle. ASIO_DECL asio::error_code cancel(implementation_type& impl, asio::error_code& ec); // Perform a synchronous wait for the object to enter a signalled state. ASIO_DECL void wait(implementation_type& impl, asio::error_code& ec); /// Start an asynchronous wait. template void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex) { // Allocate and construct an operation to wrap the handler. typedef wait_handler op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "object_handle", &impl, reinterpret_cast(impl.wait_handle_), "async_wait")); start_wait_op(impl, p.p); p.v = p.p = 0; } private: // Helper function to start an asynchronous wait operation. ASIO_DECL void start_wait_op(implementation_type& impl, wait_op* op); // Helper function to register a wait operation. ASIO_DECL void register_wait_callback( implementation_type& impl, mutex::scoped_lock& lock); // Callback function invoked when the registered wait completes. static ASIO_DECL VOID CALLBACK wait_callback( PVOID param, BOOLEAN timeout); // The scheduler used to post completions. #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif scheduler_impl& scheduler_; // Mutex to protect access to internal state. mutex mutex_; // The head of a linked list of all implementations. implementation_type* impl_list_; // Flag to indicate that the dispatcher has been shut down. bool shutdown_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_object_handle_service.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) #endif // ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/win_static_mutex.hpp ================================================ // // detail/win_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_STATIC_MUTEX_HPP #define ASIO_DETAIL_WIN_STATIC_MUTEX_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include "asio/detail/scoped_lock.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct win_static_mutex { typedef asio::detail::scoped_lock scoped_lock; // Initialise the mutex. ASIO_DECL void init(); // Initialisation must be performed in a separate function to the "public" // init() function since the compiler does not support the use of structured // exceptions and C++ exceptions in the same function. ASIO_DECL int do_init(); // Lock the mutex. void lock() { ::EnterCriticalSection(&crit_section_); } // Unlock the mutex. void unlock() { ::LeaveCriticalSection(&crit_section_); } bool initialised_; ::CRITICAL_SECTION crit_section_; }; #if defined(UNDER_CE) # define ASIO_WIN_STATIC_MUTEX_INIT { false, { 0, 0, 0, 0, 0 } } #else // defined(UNDER_CE) # define ASIO_WIN_STATIC_MUTEX_INIT { false, { 0, 0, 0, 0, 0, 0 } } #endif // defined(UNDER_CE) } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_static_mutex.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_WIN_STATIC_MUTEX_HPP ================================================ FILE: src/third_party/asio/detail/win_thread.hpp ================================================ // // detail/win_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_THREAD_HPP #define ASIO_DETAIL_WIN_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) \ && !defined(ASIO_WINDOWS_APP) \ && !defined(UNDER_CE) #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); #if defined(WINVER) && (WINVER < 0x0500) ASIO_DECL void __stdcall apc_function(ULONG data); #else ASIO_DECL void __stdcall apc_function(ULONG_PTR data); #endif template class win_thread_base { public: static bool terminate_threads() { return ::InterlockedExchangeAdd(&terminate_threads_, 0) != 0; } static void set_terminate_threads(bool b) { ::InterlockedExchange(&terminate_threads_, b ? 1 : 0); } private: static long terminate_threads_; }; template long win_thread_base::terminate_threads_ = 0; class win_thread : private noncopyable, public win_thread_base { public: // Constructor. template win_thread(Function f, unsigned int stack_size = 0) : thread_(0), exit_event_(0) { start_thread(new func(f), stack_size); } // Destructor. ASIO_DECL ~win_thread(); // Wait for the thread to exit. ASIO_DECL void join(); // Get number of CPUs. ASIO_DECL static std::size_t hardware_concurrency(); private: friend ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); #if defined(WINVER) && (WINVER < 0x0500) friend ASIO_DECL void __stdcall apc_function(ULONG); #else friend ASIO_DECL void __stdcall apc_function(ULONG_PTR); #endif class func_base { public: virtual ~func_base() {} virtual void run() = 0; ::HANDLE entry_event_; ::HANDLE exit_event_; }; struct auto_func_base_ptr { func_base* ptr; ~auto_func_base_ptr() { delete ptr; } }; template class func : public func_base { public: func(Function f) : f_(f) { } virtual void run() { f_(); } private: Function f_; }; ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); ::HANDLE thread_; ::HANDLE exit_event_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_thread.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS) // && !defined(ASIO_WINDOWS_APP) // && !defined(UNDER_CE) #endif // ASIO_DETAIL_WIN_THREAD_HPP ================================================ FILE: src/third_party/asio/detail/win_tss_ptr.hpp ================================================ // // detail/win_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WIN_TSS_PTR_HPP #define ASIO_DETAIL_WIN_TSS_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) #include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Helper function to create thread-specific storage. ASIO_DECL DWORD win_tss_ptr_create(); template class win_tss_ptr : private noncopyable { public: // Constructor. win_tss_ptr() : tss_key_(win_tss_ptr_create()) { } // Destructor. ~win_tss_ptr() { ::TlsFree(tss_key_); } // Get the value. operator T*() const { return static_cast(::TlsGetValue(tss_key_)); } // Set the value. void operator=(T* value) { ::TlsSetValue(tss_key_, value); } private: // Thread-specific storage to allow unlocked access to determine whether a // thread is a member of the pool. DWORD tss_key_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/win_tss_ptr.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS) #endif // ASIO_DETAIL_WIN_TSS_PTR_HPP ================================================ FILE: src/third_party/asio/detail/winapp_thread.hpp ================================================ // // detail/winapp_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINAPP_THREAD_HPP #define ASIO_DETAIL_WINAPP_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { DWORD WINAPI winapp_thread_function(LPVOID arg); class winapp_thread : private noncopyable { public: // Constructor. template winapp_thread(Function f, unsigned int = 0) { scoped_ptr arg(new func(f)); DWORD thread_id = 0; thread_ = ::CreateThread(0, 0, winapp_thread_function, arg.get(), 0, &thread_id); if (!thread_) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread"); } arg.release(); } // Destructor. ~winapp_thread() { ::CloseHandle(thread_); } // Wait for the thread to exit. void join() { ::WaitForSingleObjectEx(thread_, INFINITE, false); } // Get number of CPUs. static std::size_t hardware_concurrency() { SYSTEM_INFO system_info; ::GetNativeSystemInfo(&system_info); return system_info.dwNumberOfProcessors; } private: friend DWORD WINAPI winapp_thread_function(LPVOID arg); class func_base { public: virtual ~func_base() {} virtual void run() = 0; }; template class func : public func_base { public: func(Function f) : f_(f) { } virtual void run() { f_(); } private: Function f_; }; ::HANDLE thread_; }; inline DWORD WINAPI winapp_thread_function(LPVOID arg) { scoped_ptr func( static_cast(arg)); func->run(); return 0; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) #endif // ASIO_DETAIL_WINAPP_THREAD_HPP ================================================ FILE: src/third_party/asio/detail/wince_thread.hpp ================================================ // // detail/wince_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINCE_THREAD_HPP #define ASIO_DETAIL_WINCE_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) && defined(UNDER_CE) #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { DWORD WINAPI wince_thread_function(LPVOID arg); class wince_thread : private noncopyable { public: // Constructor. template wince_thread(Function f, unsigned int = 0) { scoped_ptr arg(new func(f)); DWORD thread_id = 0; thread_ = ::CreateThread(0, 0, wince_thread_function, arg.get(), 0, &thread_id); if (!thread_) { DWORD last_error = ::GetLastError(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread"); } arg.release(); } // Destructor. ~wince_thread() { ::CloseHandle(thread_); } // Wait for the thread to exit. void join() { ::WaitForSingleObject(thread_, INFINITE); } // Get number of CPUs. static std::size_t hardware_concurrency() { SYSTEM_INFO system_info; ::GetSystemInfo(&system_info); return system_info.dwNumberOfProcessors; } private: friend DWORD WINAPI wince_thread_function(LPVOID arg); class func_base { public: virtual ~func_base() {} virtual void run() = 0; }; template class func : public func_base { public: func(Function f) : f_(f) { } virtual void run() { f_(); } private: Function f_; }; ::HANDLE thread_; }; inline DWORD WINAPI wince_thread_function(LPVOID arg) { scoped_ptr func( static_cast(arg)); func->run(); return 0; } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS) && defined(UNDER_CE) #endif // ASIO_DETAIL_WINCE_THREAD_HPP ================================================ FILE: src/third_party/asio/detail/winrt_async_manager.hpp ================================================ // // detail/winrt_async_manager.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP #define ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include #include "asio/detail/atomic_count.hpp" #include "asio/detail/winrt_async_op.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class winrt_async_manager : public execution_context_service_base { public: // Constructor. winrt_async_manager(execution_context& context) : execution_context_service_base(context), scheduler_(use_service(context)), outstanding_ops_(1) { } // Destructor. ~winrt_async_manager() { } // Destroy all user-defined handler objects owned by the service. void shutdown() { if (--outstanding_ops_ > 0) { // Block until last operation is complete. std::future f = promise_.get_future(); f.wait(); } } void sync(Windows::Foundation::IAsyncAction^ action, asio::error_code& ec) { using namespace Windows::Foundation; using Windows::Foundation::AsyncStatus; auto promise = std::make_shared>(); auto future = promise->get_future(); action->Completed = ref new AsyncActionCompletedHandler( [promise](IAsyncAction^ action, AsyncStatus status) { switch (status) { case AsyncStatus::Canceled: promise->set_value(asio::error::operation_aborted); break; case AsyncStatus::Error: case AsyncStatus::Completed: default: asio::error_code ec( action->ErrorCode.Value, asio::system_category()); promise->set_value(ec); break; } }); ec = future.get(); } template TResult sync(Windows::Foundation::IAsyncOperation^ operation, asio::error_code& ec) { using namespace Windows::Foundation; using Windows::Foundation::AsyncStatus; auto promise = std::make_shared>(); auto future = promise->get_future(); operation->Completed = ref new AsyncOperationCompletedHandler( [promise](IAsyncOperation^ operation, AsyncStatus status) { switch (status) { case AsyncStatus::Canceled: promise->set_value(asio::error::operation_aborted); break; case AsyncStatus::Error: case AsyncStatus::Completed: default: asio::error_code ec( operation->ErrorCode.Value, asio::system_category()); promise->set_value(ec); break; } }); ec = future.get(); return operation->GetResults(); } template TResult sync( Windows::Foundation::IAsyncOperationWithProgress< TResult, TProgress>^ operation, asio::error_code& ec) { using namespace Windows::Foundation; using Windows::Foundation::AsyncStatus; auto promise = std::make_shared>(); auto future = promise->get_future(); operation->Completed = ref new AsyncOperationWithProgressCompletedHandler( [promise](IAsyncOperationWithProgress^ operation, AsyncStatus status) { switch (status) { case AsyncStatus::Canceled: promise->set_value(asio::error::operation_aborted); break; case AsyncStatus::Started: break; case AsyncStatus::Error: case AsyncStatus::Completed: default: asio::error_code ec( operation->ErrorCode.Value, asio::system_category()); promise->set_value(ec); break; } }); ec = future.get(); return operation->GetResults(); } void async(Windows::Foundation::IAsyncAction^ action, winrt_async_op* handler) { using namespace Windows::Foundation; using Windows::Foundation::AsyncStatus; auto on_completed = ref new AsyncActionCompletedHandler( [this, handler](IAsyncAction^ action, AsyncStatus status) { switch (status) { case AsyncStatus::Canceled: handler->ec_ = asio::error::operation_aborted; break; case AsyncStatus::Started: return; case AsyncStatus::Completed: case AsyncStatus::Error: default: handler->ec_ = asio::error_code( action->ErrorCode.Value, asio::system_category()); break; } scheduler_.post_deferred_completion(handler); if (--outstanding_ops_ == 0) promise_.set_value(); }); scheduler_.work_started(); ++outstanding_ops_; action->Completed = on_completed; } template void async(Windows::Foundation::IAsyncOperation^ operation, winrt_async_op* handler) { using namespace Windows::Foundation; using Windows::Foundation::AsyncStatus; auto on_completed = ref new AsyncOperationCompletedHandler( [this, handler](IAsyncOperation^ operation, AsyncStatus status) { switch (status) { case AsyncStatus::Canceled: handler->ec_ = asio::error::operation_aborted; break; case AsyncStatus::Started: return; case AsyncStatus::Completed: handler->result_ = operation->GetResults(); // Fall through. case AsyncStatus::Error: default: handler->ec_ = asio::error_code( operation->ErrorCode.Value, asio::system_category()); break; } scheduler_.post_deferred_completion(handler); if (--outstanding_ops_ == 0) promise_.set_value(); }); scheduler_.work_started(); ++outstanding_ops_; operation->Completed = on_completed; } template void async( Windows::Foundation::IAsyncOperationWithProgress< TResult, TProgress>^ operation, winrt_async_op* handler) { using namespace Windows::Foundation; using Windows::Foundation::AsyncStatus; auto on_completed = ref new AsyncOperationWithProgressCompletedHandler( [this, handler](IAsyncOperationWithProgress< TResult, TProgress>^ operation, AsyncStatus status) { switch (status) { case AsyncStatus::Canceled: handler->ec_ = asio::error::operation_aborted; break; case AsyncStatus::Started: return; case AsyncStatus::Completed: handler->result_ = operation->GetResults(); // Fall through. case AsyncStatus::Error: default: handler->ec_ = asio::error_code( operation->ErrorCode.Value, asio::system_category()); break; } scheduler_.post_deferred_completion(handler); if (--outstanding_ops_ == 0) promise_.set_value(); }); scheduler_.work_started(); ++outstanding_ops_; operation->Completed = on_completed; } private: // The scheduler implementation used to post completed handlers. #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif scheduler_impl& scheduler_; // Count of outstanding operations. atomic_count outstanding_ops_; // Used to keep wait for outstanding operations to complete. std::promise promise_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP ================================================ FILE: src/third_party/asio/detail/winrt_async_op.hpp ================================================ // // detail/winrt_async_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_ASYNC_OP_HPP #define ASIO_DETAIL_WINRT_ASYNC_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/operation.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class winrt_async_op : public operation { public: // The error code to be passed to the completion handler. asio::error_code ec_; // The result of the operation, to be passed to the completion handler. TResult result_; protected: winrt_async_op(func_type complete_func) : operation(complete_func), result_() { } }; template <> class winrt_async_op : public operation { public: // The error code to be passed to the completion handler. asio::error_code ec_; protected: winrt_async_op(func_type complete_func) : operation(complete_func) { } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_WINRT_ASYNC_OP_HPP ================================================ FILE: src/third_party/asio/detail/winrt_resolve_op.hpp ================================================ // // detail/winrt_resolve_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_RESOLVE_OP_HPP #define ASIO_DETAIL_WINRT_RESOLVE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp" #include "asio/ip/basic_resolver_results.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class winrt_resolve_op : public winrt_async_op< Windows::Foundation::Collections::IVectorView< Windows::Networking::EndpointPair^>^> { public: ASIO_DEFINE_HANDLER_PTR(winrt_resolve_op); typedef typename Protocol::endpoint endpoint_type; typedef asio::ip::basic_resolver_query query_type; typedef asio::ip::basic_resolver_results results_type; winrt_resolve_op(const query_type& query, Handler& handler, const IoExecutor& io_ex) : winrt_async_op< Windows::Foundation::Collections::IVectorView< Windows::Networking::EndpointPair^>^>( &winrt_resolve_op::do_complete), query_(query), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code&, std::size_t) { // Take ownership of the operation object. winrt_resolve_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); results_type results = results_type(); if (!o->ec_) { try { results = results_type::create(o->result_, o->query_.hints(), o->query_.host_name(), o->query_.service_name()); } catch (Platform::Exception^ e) { o->ec_ = asio::error_code(e->HResult, asio::system_category()); } } // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, results); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: query_type query_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_RESOLVE_OP_HPP ================================================ FILE: src/third_party/asio/detail/winrt_resolver_service.hpp ================================================ // // detail/winrt_resolver_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP #define ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/basic_resolver_results.hpp" #include "asio/post.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/winrt_async_manager.hpp" #include "asio/detail/winrt_resolve_op.hpp" #include "asio/detail/winrt_utils.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class winrt_resolver_service : public execution_context_service_base > { public: // The implementation type of the resolver. A cancellation token is used to // indicate to the asynchronous operation that the operation has been // cancelled. typedef socket_ops::shared_cancel_token_type implementation_type; // The endpoint type. typedef typename Protocol::endpoint endpoint_type; // The query type. typedef asio::ip::basic_resolver_query query_type; // The results type. typedef asio::ip::basic_resolver_results results_type; // Constructor. winrt_resolver_service(execution_context& context) : execution_context_service_base< winrt_resolver_service >(context), scheduler_(use_service(context)), async_manager_(use_service(context)) { } // Destructor. ~winrt_resolver_service() { } // Destroy all user-defined handler objects owned by the service. void shutdown() { } // Perform any fork-related housekeeping. void notify_fork(execution_context::fork_event) { } // Construct a new resolver implementation. void construct(implementation_type&) { } // Move-construct a new resolver implementation. void move_construct(implementation_type&, implementation_type&) { } // Move-assign from another resolver implementation. void move_assign(implementation_type&, winrt_resolver_service&, implementation_type&) { } // Destroy a resolver implementation. void destroy(implementation_type&) { } // Cancel pending asynchronous operations. void cancel(implementation_type&) { } // Resolve a query to a list of entries. results_type resolve(implementation_type&, const query_type& query, asio::error_code& ec) { try { using namespace Windows::Networking::Sockets; auto endpoint_pairs = async_manager_.sync( DatagramSocket::GetEndpointPairsAsync( winrt_utils::host_name(query.host_name()), winrt_utils::string(query.service_name())), ec); if (ec) return results_type(); return results_type::create( endpoint_pairs, query.hints(), query.host_name(), query.service_name()); } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); return results_type(); } } // Asynchronously resolve a query to a list of entries. template void async_resolve(implementation_type& impl, const query_type& query, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef winrt_resolve_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(query, handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "resolver", &impl, 0, "async_resolve")); (void)impl; try { using namespace Windows::Networking::Sockets; async_manager_.async(DatagramSocket::GetEndpointPairsAsync( winrt_utils::host_name(query.host_name()), winrt_utils::string(query.service_name())), p.p); p.v = p.p = 0; } catch (Platform::Exception^ e) { p.p->ec_ = asio::error_code( e->HResult, asio::system_category()); scheduler_.post_immediate_completion(p.p, is_continuation); p.v = p.p = 0; } } // Resolve an endpoint to a list of entries. results_type resolve(implementation_type&, const endpoint_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return results_type(); } // Asynchronously resolve an endpoint to a list of entries. template void async_resolve(implementation_type&, const endpoint_type&, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const results_type results; asio::post(io_ex, detail::bind_handler(handler, ec, results)); } private: // The scheduler implementation used for delivering completions. #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif scheduler_impl& scheduler_; winrt_async_manager& async_manager_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/winrt_socket_connect_op.hpp ================================================ // // detail/winrt_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_SOCKET_CONNECT_OP_HPP #define ASIO_DETAIL_WINRT_SOCKET_CONNECT_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class winrt_socket_connect_op : public winrt_async_op { public: ASIO_DEFINE_HANDLER_PTR(winrt_socket_connect_op); winrt_socket_connect_op(Handler& handler, const IoExecutor& io_ex) : winrt_async_op(&winrt_socket_connect_op::do_complete), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code&, std::size_t) { // Take ownership of the operation object. winrt_socket_connect_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder1 handler(o->handler_, o->ec_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_SOCKET_CONNECT_OP_HPP ================================================ FILE: src/third_party/asio/detail/winrt_socket_recv_op.hpp ================================================ // // detail/winrt_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_SOCKET_RECV_OP_HPP #define ASIO_DETAIL_WINRT_SOCKET_RECV_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class winrt_socket_recv_op : public winrt_async_op { public: ASIO_DEFINE_HANDLER_PTR(winrt_socket_recv_op); winrt_socket_recv_op(const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : winrt_async_op( &winrt_socket_recv_op::do_complete), buffers_(buffers), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code&, std::size_t) { // Take ownership of the operation object. winrt_socket_recv_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. if (owner) { buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) std::size_t bytes_transferred = o->result_ ? o->result_->Length : 0; if (bytes_transferred == 0 && !o->ec_ && !buffer_sequence_adapter::all_empty(o->buffers_)) { o->ec_ = asio::error::eof; } // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, bytes_transferred); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: MutableBufferSequence buffers_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_SOCKET_RECV_OP_HPP ================================================ FILE: src/third_party/asio/detail/winrt_socket_send_op.hpp ================================================ // // detail/winrt_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_SOCKET_SEND_OP_HPP #define ASIO_DETAIL_WINRT_SOCKET_SEND_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/bind_handler.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class winrt_socket_send_op : public winrt_async_op { public: ASIO_DEFINE_HANDLER_PTR(winrt_socket_send_op); winrt_socket_send_op(const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) : winrt_async_op(&winrt_socket_send_op::do_complete), buffers_(buffers), handler_(ASIO_MOVE_CAST(Handler)(handler)), io_executor_(io_ex) { handler_work::start(handler_, io_executor_); } static void do_complete(void* owner, operation* base, const asio::error_code&, std::size_t) { // Take ownership of the operation object. winrt_socket_send_op* o(static_cast(base)); ptr p = { asio::detail::addressof(o->handler_), o, o }; handler_work w(o->handler_, o->io_executor_); ASIO_HANDLER_COMPLETION((*o)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. if (owner) { buffer_sequence_adapter::validate(o->buffers_); } #endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) // Make a copy of the handler so that the memory can be deallocated before // the upcall is made. Even if we're not about to make an upcall, a // sub-object of the handler may be the true owner of the memory associated // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here. detail::binder2 handler(o->handler_, o->ec_, o->result_); p.h = asio::detail::addressof(handler.handler_); p.reset(); // Make the upcall if required. if (owner) { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } } private: ConstBufferSequence buffers_; Handler handler_; IoExecutor io_executor_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_SOCKET_SEND_OP_HPP ================================================ FILE: src/third_party/asio/detail/winrt_ssocket_service.hpp ================================================ // // detail/winrt_ssocket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP #define ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_socket_connect_op.hpp" #include "asio/detail/winrt_ssocket_service_base.hpp" #include "asio/detail/winrt_utils.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class winrt_ssocket_service : public execution_context_service_base >, public winrt_ssocket_service_base { public: // The protocol type. typedef Protocol protocol_type; // The endpoint type. typedef typename Protocol::endpoint endpoint_type; // The native type of a socket. typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type; // The implementation type of the socket. struct implementation_type : base_implementation_type { // Default constructor. implementation_type() : base_implementation_type(), protocol_(endpoint_type().protocol()) { } // The protocol associated with the socket. protocol_type protocol_; }; // Constructor. winrt_ssocket_service(execution_context& context) : execution_context_service_base >(context), winrt_ssocket_service_base(context) { } // Destroy all user-defined handler objects owned by the service. void shutdown() { this->base_shutdown(); } // Move-construct a new socket implementation. void move_construct(implementation_type& impl, implementation_type& other_impl) ASIO_NOEXCEPT { this->base_move_construct(impl, other_impl); impl.protocol_ = other_impl.protocol_; other_impl.protocol_ = endpoint_type().protocol(); } // Move-assign from another socket implementation. void move_assign(implementation_type& impl, winrt_ssocket_service& other_service, implementation_type& other_impl) { this->base_move_assign(impl, other_service, other_impl); impl.protocol_ = other_impl.protocol_; other_impl.protocol_ = endpoint_type().protocol(); } // Move-construct a new socket implementation from another protocol type. template void converting_move_construct(implementation_type& impl, winrt_ssocket_service&, typename winrt_ssocket_service< Protocol1>::implementation_type& other_impl) { this->base_move_construct(impl, other_impl); impl.protocol_ = protocol_type(other_impl.protocol_); other_impl.protocol_ = typename Protocol1::endpoint().protocol(); } // Open a new socket implementation. asio::error_code open(implementation_type& impl, const protocol_type& protocol, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } try { impl.socket_ = ref new Windows::Networking::Sockets::StreamSocket; impl.protocol_ = protocol; ec = asio::error_code(); } catch (Platform::Exception^ e) { ec = asio::error_code(e->HResult, asio::system_category()); } return ec; } // Assign a native socket to a socket implementation. asio::error_code assign(implementation_type& impl, const protocol_type& protocol, const native_handle_type& native_socket, asio::error_code& ec) { if (is_open(impl)) { ec = asio::error::already_open; return ec; } impl.socket_ = native_socket; impl.protocol_ = protocol; ec = asio::error_code(); return ec; } // Bind the socket to the specified local endpoint. asio::error_code bind(implementation_type&, const endpoint_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Get the local endpoint. endpoint_type local_endpoint(const implementation_type& impl, asio::error_code& ec) const { endpoint_type endpoint; endpoint.resize(do_get_endpoint(impl, true, endpoint.data(), endpoint.size(), ec)); return endpoint; } // Get the remote endpoint. endpoint_type remote_endpoint(const implementation_type& impl, asio::error_code& ec) const { endpoint_type endpoint; endpoint.resize(do_get_endpoint(impl, false, endpoint.data(), endpoint.size(), ec)); return endpoint; } // Disable sends or receives on the socket. asio::error_code shutdown(implementation_type&, socket_base::shutdown_type, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Set a socket option. template asio::error_code set_option(implementation_type& impl, const Option& option, asio::error_code& ec) { return do_set_option(impl, option.level(impl.protocol_), option.name(impl.protocol_), option.data(impl.protocol_), option.size(impl.protocol_), ec); } // Get a socket option. template asio::error_code get_option(const implementation_type& impl, Option& option, asio::error_code& ec) const { std::size_t size = option.size(impl.protocol_); do_get_option(impl, option.level(impl.protocol_), option.name(impl.protocol_), option.data(impl.protocol_), &size, ec); if (!ec) option.resize(impl.protocol_, size); return ec; } // Connect the socket to the specified endpoint. asio::error_code connect(implementation_type& impl, const endpoint_type& peer_endpoint, asio::error_code& ec) { return do_connect(impl, peer_endpoint.data(), ec); } // Start an asynchronous connect. template void async_connect(implementation_type& impl, const endpoint_type& peer_endpoint, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef winrt_socket_connect_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "socket", &impl, 0, "async_connect")); start_connect_op(impl, peer_endpoint.data(), p.p, is_continuation); p.v = p.p = 0; } }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP ================================================ FILE: src/third_party/asio/detail/winrt_ssocket_service_base.hpp ================================================ // // detail/winrt_ssocket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP #define ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include "asio/buffer.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/socket_base.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/winrt_async_manager.hpp" #include "asio/detail/winrt_socket_recv_op.hpp" #include "asio/detail/winrt_socket_send_op.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class winrt_ssocket_service_base { public: // The native type of a socket. typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type; // The implementation type of the socket. struct base_implementation_type { // Default constructor. base_implementation_type() : socket_(nullptr), next_(0), prev_(0) { } // The underlying native socket. native_handle_type socket_; // Pointers to adjacent socket implementations in linked list. base_implementation_type* next_; base_implementation_type* prev_; }; // Constructor. ASIO_DECL winrt_ssocket_service_base(execution_context& context); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void base_shutdown(); // Construct a new socket implementation. ASIO_DECL void construct(base_implementation_type&); // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl, base_implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl, winrt_ssocket_service_base& other_service, base_implementation_type& other_impl); // Destroy a socket implementation. ASIO_DECL void destroy(base_implementation_type& impl); // Determine whether the socket is open. bool is_open(const base_implementation_type& impl) const { return impl.socket_ != nullptr; } // Destroy a socket implementation. ASIO_DECL asio::error_code close( base_implementation_type& impl, asio::error_code& ec); // Release ownership of the socket. ASIO_DECL native_handle_type release( base_implementation_type& impl, asio::error_code& ec); // Get the native socket representation. native_handle_type native_handle(base_implementation_type& impl) { return impl.socket_; } // Cancel all operations associated with the socket. asio::error_code cancel(base_implementation_type&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Determine whether the socket is at the out-of-band data mark. bool at_mark(const base_implementation_type&, asio::error_code& ec) const { ec = asio::error::operation_not_supported; return false; } // Determine the number of bytes available for reading. std::size_t available(const base_implementation_type&, asio::error_code& ec) const { ec = asio::error::operation_not_supported; return 0; } // Perform an IO control command on the socket. template asio::error_code io_control(base_implementation_type&, IO_Control_Command&, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Gets the non-blocking mode of the socket. bool non_blocking(const base_implementation_type&) const { return false; } // Sets the non-blocking mode of the socket. asio::error_code non_blocking(base_implementation_type&, bool, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Gets the non-blocking mode of the native socket implementation. bool native_non_blocking(const base_implementation_type&) const { return false; } // Sets the non-blocking mode of the native socket implementation. asio::error_code native_non_blocking(base_implementation_type&, bool, asio::error_code& ec) { ec = asio::error::operation_not_supported; return ec; } // Send the given data to the peer. template std::size_t send(base_implementation_type& impl, const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return do_send(impl, buffer_sequence_adapter::first(buffers), flags, ec); } // Wait until data can be sent without blocking. std::size_t send(base_implementation_type&, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template void async_send(base_implementation_type& impl, const ConstBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef winrt_socket_send_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(buffers, handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "socket", &impl, 0, "async_send")); start_send_op(impl, buffer_sequence_adapter::first(buffers), flags, p.p, is_continuation); p.v = p.p = 0; } // Start an asynchronous wait until data can be sent without blocking. template void async_send(base_implementation_type&, const null_buffers&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler(handler, ec, bytes_transferred)); } // Receive some data from the peer. Returns the number of bytes received. template std::size_t receive(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::error_code& ec) { return do_receive(impl, buffer_sequence_adapter::first(buffers), flags, ec); } // Wait until data can be received without blocking. std::size_t receive(base_implementation_type&, const null_buffers&, socket_base::message_flags, asio::error_code& ec) { ec = asio::error::operation_not_supported; return 0; } // Start an asynchronous receive. The buffer for the data being received // must be valid for the lifetime of the asynchronous operation. template void async_receive(base_implementation_type& impl, const MutableBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) { bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); // Allocate and construct an operation to wrap the handler. typedef winrt_socket_recv_op op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(buffers, handler, io_ex); ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "socket", &impl, 0, "async_receive")); start_receive_op(impl, buffer_sequence_adapter::first(buffers), flags, p.p, is_continuation); p.v = p.p = 0; } // Wait until data can be received without blocking. template void async_receive(base_implementation_type&, const null_buffers&, socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) { asio::error_code ec = asio::error::operation_not_supported; const std::size_t bytes_transferred = 0; asio::post(io_ex, detail::bind_handler(handler, ec, bytes_transferred)); } protected: // Helper function to obtain endpoints associated with the connection. ASIO_DECL std::size_t do_get_endpoint( const base_implementation_type& impl, bool local, void* addr, std::size_t addr_len, asio::error_code& ec) const; // Helper function to set a socket option. ASIO_DECL asio::error_code do_set_option( base_implementation_type& impl, int level, int optname, const void* optval, std::size_t optlen, asio::error_code& ec); // Helper function to get a socket option. ASIO_DECL void do_get_option( const base_implementation_type& impl, int level, int optname, void* optval, std::size_t* optlen, asio::error_code& ec) const; // Helper function to perform a synchronous connect. ASIO_DECL asio::error_code do_connect( base_implementation_type& impl, const void* addr, asio::error_code& ec); // Helper function to start an asynchronous connect. ASIO_DECL void start_connect_op( base_implementation_type& impl, const void* addr, winrt_async_op* op, bool is_continuation); // Helper function to perform a synchronous send. ASIO_DECL std::size_t do_send( base_implementation_type& impl, const asio::const_buffer& data, socket_base::message_flags flags, asio::error_code& ec); // Helper function to start an asynchronous send. ASIO_DECL void start_send_op(base_implementation_type& impl, const asio::const_buffer& data, socket_base::message_flags flags, winrt_async_op* op, bool is_continuation); // Helper function to perform a synchronous receive. ASIO_DECL std::size_t do_receive( base_implementation_type& impl, const asio::mutable_buffer& data, socket_base::message_flags flags, asio::error_code& ec); // Helper function to start an asynchronous receive. ASIO_DECL void start_receive_op(base_implementation_type& impl, const asio::mutable_buffer& data, socket_base::message_flags flags, winrt_async_op* op, bool is_continuation); // The scheduler implementation used for delivering completions. #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif scheduler_impl& scheduler_; // The manager that keeps track of outstanding operations. winrt_async_manager& async_manager_; // Mutex to protect access to the linked list of implementations. asio::detail::mutex mutex_; // The head of a linked list of all implementations. base_implementation_type* impl_list_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/winrt_ssocket_service_base.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP ================================================ FILE: src/third_party/asio/detail/winrt_timer_scheduler.hpp ================================================ // // detail/winrt_timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_TIMER_SCHEDULER_HPP #define ASIO_DETAIL_WINRT_TIMER_SCHEDULER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include #include "asio/detail/event.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/timer_queue_base.hpp" #include "asio/detail/timer_queue_set.hpp" #include "asio/detail/wait_op.hpp" #include "asio/execution_context.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else // defined(ASIO_HAS_IOCP) # include "asio/detail/scheduler.hpp" #endif // defined(ASIO_HAS_IOCP) #if defined(ASIO_HAS_IOCP) # include "asio/detail/thread.hpp" #endif // defined(ASIO_HAS_IOCP) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class winrt_timer_scheduler : public execution_context_service_base { public: // Constructor. ASIO_DECL winrt_timer_scheduler(execution_context& context); // Destructor. ASIO_DECL ~winrt_timer_scheduler(); // Destroy all user-defined handler objects owned by the service. ASIO_DECL void shutdown(); // Recreate internal descriptors following a fork. ASIO_DECL void notify_fork(execution_context::fork_event fork_ev); // Initialise the task. No effect as this class uses its own thread. ASIO_DECL void init_task(); // Add a new timer queue to the reactor. template void add_timer_queue(timer_queue& queue); // Remove a timer queue from the reactor. template void remove_timer_queue(timer_queue& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template void schedule_timer(timer_queue& queue, const typename Time_Traits::time_type& time, typename timer_queue::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template std::size_t cancel_timer(timer_queue& queue, typename timer_queue::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits::max)()); // Move the timer operations associated with the given timer. template void move_timer(timer_queue& queue, typename timer_queue::per_timer_data& to, typename timer_queue::per_timer_data& from); private: // Run the select loop in the thread. ASIO_DECL void run_thread(); // Entry point for the select loop thread. ASIO_DECL static void call_run_thread(winrt_timer_scheduler* reactor); // Helper function to add a new timer queue. ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); // Helper function to remove a timer queue. ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // The scheduler implementation used to post completions. #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context scheduler_impl; #else typedef class scheduler scheduler_impl; #endif scheduler_impl& scheduler_; // Mutex used to protect internal variables. asio::detail::mutex mutex_; // Event used to wake up background thread. asio::detail::event event_; // The timer queues. timer_queue_set timer_queues_; // The background thread that is waiting for timers to expire. asio::detail::thread* thread_; // Does the background thread need to stop. bool stop_thread_; // Whether the service has been shut down. bool shutdown_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/detail/impl/winrt_timer_scheduler.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/winrt_timer_scheduler.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_TIMER_SCHEDULER_HPP ================================================ FILE: src/third_party/asio/detail/winrt_utils.hpp ================================================ // // detail/winrt_utils.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINRT_UTILS_HPP #define ASIO_DETAIL_WINRT_UTILS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS_RUNTIME) #include #include #include #include #include #include #include #include "asio/buffer.hpp" #include "asio/error_code.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { namespace winrt_utils { inline Platform::String^ string(const char* from) { std::wstring tmp(from, from + std::strlen(from)); return ref new Platform::String(tmp.c_str()); } inline Platform::String^ string(const std::string& from) { std::wstring tmp(from.begin(), from.end()); return ref new Platform::String(tmp.c_str()); } inline std::string string(Platform::String^ from) { std::wstring_convert> converter; return converter.to_bytes(from->Data()); } inline Platform::String^ string(unsigned short from) { return string(std::to_string(from)); } template inline Platform::String^ string(const T& from) { return string(from.to_string()); } inline int integer(Platform::String^ from) { return _wtoi(from->Data()); } template inline Windows::Networking::HostName^ host_name(const T& from) { return ref new Windows::Networking::HostName((string)(from)); } template inline Windows::Storage::Streams::IBuffer^ buffer_dup( const ConstBufferSequence& buffers) { using Microsoft::WRL::ComPtr; using asio::buffer_size; std::size_t size = buffer_size(buffers); auto b = ref new Windows::Storage::Streams::Buffer(size); ComPtr insp = reinterpret_cast(b); ComPtr bacc; insp.As(&bacc); byte* bytes = nullptr; bacc->Buffer(&bytes); asio::buffer_copy(asio::buffer(bytes, size), buffers); b->Length = size; return b; } } // namespace winrt_utils } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #endif // ASIO_DETAIL_WINRT_UTILS_HPP ================================================ FILE: src/third_party/asio/detail/winsock_init.hpp ================================================ // // detail/winsock_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WINSOCK_INIT_HPP #define ASIO_DETAIL_WINSOCK_INIT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class winsock_init_base { protected: // Structure to track result of initialisation and number of uses. POD is used // to ensure that the values are zero-initialised prior to any code being run. struct data { long init_count_; long result_; }; ASIO_DECL static void startup(data& d, unsigned char major, unsigned char minor); ASIO_DECL static void manual_startup(data& d); ASIO_DECL static void cleanup(data& d); ASIO_DECL static void manual_cleanup(data& d); ASIO_DECL static void throw_on_error(data& d); }; template class winsock_init : private winsock_init_base { public: winsock_init(bool allow_throw = true) { startup(data_, Major, Minor); if (allow_throw) throw_on_error(data_); } winsock_init(const winsock_init&) { startup(data_, Major, Minor); throw_on_error(data_); } ~winsock_init() { cleanup(data_); } // This class may be used to indicate that user code will manage Winsock // initialisation and cleanup. This may be required in the case of a DLL, for // example, where it is not safe to initialise Winsock from global object // constructors. // // To prevent asio from initialising Winsock, the object must be constructed // before any Asio's own global objects. With MSVC, this may be accomplished // by adding the following code to the DLL: // // #pragma warning(push) // #pragma warning(disable:4073) // #pragma init_seg(lib) // asio::detail::winsock_init<>::manual manual_winsock_init; // #pragma warning(pop) class manual { public: manual() { manual_startup(data_); } manual(const manual&) { manual_startup(data_); } ~manual() { manual_cleanup(data_); } }; private: friend class manual; static data data_; }; template winsock_init_base::data winsock_init::data_; // Static variable to ensure that winsock is initialised before main, and // therefore before any other threads can get started. static const winsock_init<>& winsock_init_instance = winsock_init<>(false); } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/detail/impl/winsock_init.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) #endif // ASIO_DETAIL_WINSOCK_INIT_HPP ================================================ FILE: src/third_party/asio/detail/work_dispatcher.hpp ================================================ // // detail/work_dispatcher.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WORK_DISPATCHER_HPP #define ASIO_DETAIL_WORK_DISPATCHER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_executor.hpp" #include "asio/associated_allocator.hpp" #include "asio/executor_work_guard.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class work_dispatcher { public: template explicit work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler) : work_((get_associated_executor)(handler)), handler_(ASIO_MOVE_CAST(CompletionHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) work_dispatcher(const work_dispatcher& other) : work_(other.work_), handler_(other.handler_) { } work_dispatcher(work_dispatcher&& other) : work_(ASIO_MOVE_CAST(executor_work_guard< typename associated_executor::type>)(other.work_)), handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { typename associated_allocator::type alloc( (get_associated_allocator)(handler_)); work_.get_executor().dispatch( ASIO_MOVE_CAST(Handler)(handler_), alloc); work_.reset(); } private: executor_work_guard::type> work_; Handler handler_; }; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_WORK_DISPATCHER_HPP ================================================ FILE: src/third_party/asio/detail/wrapped_handler.hpp ================================================ // // detail/wrapped_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DETAIL_WRAPPED_HANDLER_HPP #define ASIO_DETAIL_WRAPPED_HANDLER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/bind_handler.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct is_continuation_delegated { template bool operator()(Dispatcher&, Handler& handler) const { return asio_handler_cont_helpers::is_continuation(handler); } }; struct is_continuation_if_running { template bool operator()(Dispatcher& dispatcher, Handler&) const { return dispatcher.running_in_this_thread(); } }; template class wrapped_handler { public: typedef void result_type; wrapped_handler(Dispatcher dispatcher, Handler& handler) : dispatcher_(dispatcher), handler_(ASIO_MOVE_CAST(Handler)(handler)) { } #if defined(ASIO_HAS_MOVE) wrapped_handler(const wrapped_handler& other) : dispatcher_(other.dispatcher_), handler_(other.handler_) { } wrapped_handler(wrapped_handler&& other) : dispatcher_(other.dispatcher_), handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { dispatcher_.dispatch(ASIO_MOVE_CAST(Handler)(handler_)); } void operator()() const { dispatcher_.dispatch(handler_); } template void operator()(const Arg1& arg1) { dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); } template void operator()(const Arg1& arg1) const { dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); } template void operator()(const Arg1& arg1, const Arg2& arg2) { dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); } template void operator()(const Arg1& arg1, const Arg2& arg2) const { dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); } template void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); } template void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const { dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); } template void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { dispatcher_.dispatch( detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); } template void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) const { dispatcher_.dispatch( detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); } template void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) { dispatcher_.dispatch( detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); } template void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) const { dispatcher_.dispatch( detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); } //private: Dispatcher dispatcher_; Handler handler_; }; template class rewrapped_handler { public: explicit rewrapped_handler(Handler& handler, const Context& context) : context_(context), handler_(ASIO_MOVE_CAST(Handler)(handler)) { } explicit rewrapped_handler(const Handler& handler, const Context& context) : context_(context), handler_(handler) { } #if defined(ASIO_HAS_MOVE) rewrapped_handler(const rewrapped_handler& other) : context_(other.context_), handler_(other.handler_) { } rewrapped_handler(rewrapped_handler&& other) : context_(ASIO_MOVE_CAST(Context)(other.context_)), handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()() { handler_(); } void operator()() const { handler_(); } //private: Context context_; Handler handler_; }; template inline void* asio_handler_allocate(std::size_t size, wrapped_handler* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, wrapped_handler* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( wrapped_handler* this_handler) { return IsContinuation()(this_handler->dispatcher_, this_handler->handler_); } template inline void asio_handler_invoke(Function& function, wrapped_handler* this_handler) { this_handler->dispatcher_.dispatch( rewrapped_handler( function, this_handler->handler_)); } template inline void asio_handler_invoke(const Function& function, wrapped_handler* this_handler) { this_handler->dispatcher_.dispatch( rewrapped_handler( function, this_handler->handler_)); } template inline void* asio_handler_allocate(std::size_t size, rewrapped_handler* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->context_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, rewrapped_handler* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->context_); } template inline bool asio_handler_is_continuation( rewrapped_handler* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->context_); } template inline void asio_handler_invoke(Function& function, rewrapped_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->context_); } template inline void asio_handler_invoke(const Function& function, rewrapped_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->context_); } } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_DETAIL_WRAPPED_HANDLER_HPP ================================================ FILE: src/third_party/asio/dispatch.hpp ================================================ // // dispatch.hpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_DISPATCH_HPP #define ASIO_DISPATCH_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Submits a completion token or function object for execution. /** * This function submits an object for execution using the object's associated * executor. The function object may be called from the current thread prior to * returning from dispatch(). Otherwise, it is queued for execution. * * This function has the following effects: * * @li Constructs a function object handler of type @c Handler, initialized * with handler(forward(token)). * * @li Constructs an object @c result of type async_result, * initializing the object as result(handler). * * @li Obtains the handler's associated executor object @c ex by performing * get_associated_executor(handler). * * @li Obtains the handler's associated allocator object @c alloc by performing * get_associated_allocator(handler). * * @li Performs ex.dispatch(std::move(handler), alloc). * * @li Returns result.get(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( ASIO_MOVE_ARG(CompletionToken) token); /// Submits a completion token or function object for execution. /** * This function submits an object for execution using the specified executor. * The function object may be called from the current thread prior to returning * from dispatch(). Otherwise, it is queued for execution. * * This function has the following effects: * * @li Constructs a function object handler of type @c Handler, initialized * with handler(forward(token)). * * @li Constructs an object @c result of type async_result, * initializing the object as result(handler). * * @li Obtains the handler's associated executor object @c ex1 by performing * get_associated_executor(handler). * * @li Creates a work object @c w by performing make_work(ex1). * * @li Obtains the handler's associated allocator object @c alloc by performing * get_associated_allocator(handler). * * @li Constructs a function object @c f with a function call operator that * performs ex1.dispatch(std::move(handler), alloc) followed by * w.reset(). * * @li Performs Executor(ex).dispatch(std::move(f), alloc). * * @li Returns result.get(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if::value>::type* = 0); /// Submits a completion token or function object for execution. /** * @returns dispatch(ctx.get_executor(), * forward(token)). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type), typename enable_if::value>::type* = 0); } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/dispatch.hpp" #endif // ASIO_DISPATCH_HPP ================================================ FILE: src/third_party/asio/error.hpp ================================================ // // error.hpp // ~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_ERROR_HPP #define ASIO_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error_code.hpp" #include "asio/system_error.hpp" #if defined(ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(ASIO_WINDOWS_RUNTIME) # include #else # include # include #endif #if defined(GENERATING_DOCUMENTATION) /// INTERNAL ONLY. # define ASIO_NATIVE_ERROR(e) implementation_defined /// INTERNAL ONLY. # define ASIO_SOCKET_ERROR(e) implementation_defined /// INTERNAL ONLY. # define ASIO_NETDB_ERROR(e) implementation_defined /// INTERNAL ONLY. # define ASIO_GETADDRINFO_ERROR(e) implementation_defined /// INTERNAL ONLY. # define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined #elif defined(ASIO_WINDOWS_RUNTIME) # define ASIO_NATIVE_ERROR(e) __HRESULT_FROM_WIN32(e) # define ASIO_SOCKET_ERROR(e) __HRESULT_FROM_WIN32(WSA ## e) # define ASIO_NETDB_ERROR(e) __HRESULT_FROM_WIN32(WSA ## e) # define ASIO_GETADDRINFO_ERROR(e) __HRESULT_FROM_WIN32(WSA ## e) # define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) # define ASIO_NATIVE_ERROR(e) e # define ASIO_SOCKET_ERROR(e) WSA ## e # define ASIO_NETDB_ERROR(e) WSA ## e # define ASIO_GETADDRINFO_ERROR(e) WSA ## e # define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win #else # define ASIO_NATIVE_ERROR(e) e # define ASIO_SOCKET_ERROR(e) e # define ASIO_NETDB_ERROR(e) e # define ASIO_GETADDRINFO_ERROR(e) e # define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix #endif #include "asio/detail/push_options.hpp" namespace asio { namespace error { enum basic_errors { /// Permission denied. access_denied = ASIO_SOCKET_ERROR(EACCES), /// Address family not supported by protocol. address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT), /// Address already in use. address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE), /// Transport endpoint is already connected. already_connected = ASIO_SOCKET_ERROR(EISCONN), /// Operation already in progress. already_started = ASIO_SOCKET_ERROR(EALREADY), /// Broken pipe. broken_pipe = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(ERROR_BROKEN_PIPE), ASIO_NATIVE_ERROR(EPIPE)), /// A connection has been aborted. connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED), /// Connection refused. connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED), /// Connection reset by peer. connection_reset = ASIO_SOCKET_ERROR(ECONNRESET), /// Bad file descriptor. bad_descriptor = ASIO_SOCKET_ERROR(EBADF), /// Bad address. fault = ASIO_SOCKET_ERROR(EFAULT), /// No route to host. host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH), /// Operation now in progress. in_progress = ASIO_SOCKET_ERROR(EINPROGRESS), /// Interrupted system call. interrupted = ASIO_SOCKET_ERROR(EINTR), /// Invalid argument. invalid_argument = ASIO_SOCKET_ERROR(EINVAL), /// Message too long. message_size = ASIO_SOCKET_ERROR(EMSGSIZE), /// The name was too long. name_too_long = ASIO_SOCKET_ERROR(ENAMETOOLONG), /// Network is down. network_down = ASIO_SOCKET_ERROR(ENETDOWN), /// Network dropped connection on reset. network_reset = ASIO_SOCKET_ERROR(ENETRESET), /// Network is unreachable. network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH), /// Too many open files. no_descriptors = ASIO_SOCKET_ERROR(EMFILE), /// No buffer space available. no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS), /// Cannot allocate memory. no_memory = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY), ASIO_NATIVE_ERROR(ENOMEM)), /// Operation not permitted. no_permission = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED), ASIO_NATIVE_ERROR(EPERM)), /// Protocol not available. no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT), /// No such device. no_such_device = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(ERROR_BAD_UNIT), ASIO_NATIVE_ERROR(ENODEV)), /// Transport endpoint is not connected. not_connected = ASIO_SOCKET_ERROR(ENOTCONN), /// Socket operation on non-socket. not_socket = ASIO_SOCKET_ERROR(ENOTSOCK), /// Operation cancelled. operation_aborted = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED), ASIO_NATIVE_ERROR(ECANCELED)), /// Operation not supported. operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP), /// Cannot send after transport endpoint shutdown. shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN), /// Connection timed out. timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT), /// Resource temporarily unavailable. try_again = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(ERROR_RETRY), ASIO_NATIVE_ERROR(EAGAIN)), /// The socket is marked non-blocking and the requested operation would block. would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK) }; enum netdb_errors { /// Host not found (authoritative). host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND), /// Host not found (non-authoritative). host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN), /// The query is valid but does not have associated address data. no_data = ASIO_NETDB_ERROR(NO_DATA), /// A non-recoverable error occurred. no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY) }; enum addrinfo_errors { /// The service is not supported for the given socket type. service_not_found = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND), ASIO_GETADDRINFO_ERROR(EAI_SERVICE)), /// The socket type is not supported. socket_type_not_supported = ASIO_WIN_OR_POSIX( ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT), ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE)) }; enum misc_errors { /// Already open. already_open = 1, /// End of file or stream. eof, /// Element not found. not_found, /// The descriptor cannot fit into the select system call's fd_set. fd_set_failure }; inline const asio::error_category& get_system_category() { return asio::system_category(); } #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) extern ASIO_DECL const asio::error_category& get_netdb_category(); extern ASIO_DECL const asio::error_category& get_addrinfo_category(); #else // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) inline const asio::error_category& get_netdb_category() { return get_system_category(); } inline const asio::error_category& get_addrinfo_category() { return get_system_category(); } #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) extern ASIO_DECL const asio::error_category& get_misc_category(); static const asio::error_category& system_category ASIO_UNUSED_VARIABLE = asio::error::get_system_category(); static const asio::error_category& netdb_category ASIO_UNUSED_VARIABLE = asio::error::get_netdb_category(); static const asio::error_category& addrinfo_category ASIO_UNUSED_VARIABLE = asio::error::get_addrinfo_category(); static const asio::error_category& misc_category ASIO_UNUSED_VARIABLE = asio::error::get_misc_category(); } // namespace error } // namespace asio #if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum { static const bool value = true; }; template<> struct is_error_code_enum { static const bool value = true; }; template<> struct is_error_code_enum { static const bool value = true; }; template<> struct is_error_code_enum { static const bool value = true; }; } // namespace std #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace asio { namespace error { inline asio::error_code make_error_code(basic_errors e) { return asio::error_code( static_cast(e), get_system_category()); } inline asio::error_code make_error_code(netdb_errors e) { return asio::error_code( static_cast(e), get_netdb_category()); } inline asio::error_code make_error_code(addrinfo_errors e) { return asio::error_code( static_cast(e), get_addrinfo_category()); } inline asio::error_code make_error_code(misc_errors e) { return asio::error_code( static_cast(e), get_misc_category()); } } // namespace error namespace stream_errc { // Simulates the proposed stream_errc scoped enum. using error::eof; using error::not_found; } // namespace stream_errc namespace socket_errc { // Simulates the proposed socket_errc scoped enum. using error::already_open; using error::not_found; } // namespace socket_errc namespace resolver_errc { // Simulates the proposed resolver_errc scoped enum. using error::host_not_found; const error::netdb_errors try_again = error::host_not_found_try_again; using error::service_not_found; } // namespace resolver_errc } // namespace asio #include "asio/detail/pop_options.hpp" #undef ASIO_NATIVE_ERROR #undef ASIO_SOCKET_ERROR #undef ASIO_NETDB_ERROR #undef ASIO_GETADDRINFO_ERROR #undef ASIO_WIN_OR_POSIX #if defined(ASIO_HEADER_ONLY) # include "asio/impl/error.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_ERROR_HPP ================================================ FILE: src/third_party/asio/error_code.hpp ================================================ // // error_code.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_ERROR_CODE_HPP #define ASIO_ERROR_CODE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_SYSTEM_ERROR) # include #else // defined(ASIO_HAS_STD_SYSTEM_ERROR) # include # include "asio/detail/noncopyable.hpp" # if !defined(ASIO_NO_IOSTREAM) # include # endif // !defined(ASIO_NO_IOSTREAM) #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) #include "asio/detail/push_options.hpp" namespace asio { #if defined(ASIO_HAS_STD_SYSTEM_ERROR) typedef std::error_category error_category; #else // defined(ASIO_HAS_STD_SYSTEM_ERROR) /// Base class for all error categories. class error_category : private noncopyable { public: /// Destructor. virtual ~error_category() { } /// Returns a string naming the error gategory. virtual const char* name() const = 0; /// Returns a string describing the error denoted by @c value. virtual std::string message(int value) const = 0; /// Equality operator to compare two error categories. bool operator==(const error_category& rhs) const { return this == &rhs; } /// Inequality operator to compare two error categories. bool operator!=(const error_category& rhs) const { return !(*this == rhs); } }; #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) /// Returns the error category used for the system errors produced by asio. extern ASIO_DECL const error_category& system_category(); #if defined(ASIO_HAS_STD_SYSTEM_ERROR) typedef std::error_code error_code; #else // defined(ASIO_HAS_STD_SYSTEM_ERROR) /// Class to represent an error code value. class error_code { public: /// Default constructor. error_code() : value_(0), category_(&system_category()) { } /// Construct with specific error code and category. error_code(int v, const error_category& c) : value_(v), category_(&c) { } /// Construct from an error code enum. template error_code(ErrorEnum e) { *this = make_error_code(e); } /// Clear the error value to the default. void clear() { value_ = 0; category_ = &system_category(); } /// Assign a new error value. void assign(int v, const error_category& c) { value_ = v; category_ = &c; } /// Get the error value. int value() const { return value_; } /// Get the error category. const error_category& category() const { return *category_; } /// Get the message associated with the error. std::string message() const { return category_->message(value_); } struct unspecified_bool_type_t { }; typedef void (*unspecified_bool_type)(unspecified_bool_type_t); static void unspecified_bool_true(unspecified_bool_type_t) {} /// Operator returns non-null if there is a non-success error code. operator unspecified_bool_type() const { if (value_ == 0) return 0; else return &error_code::unspecified_bool_true; } /// Operator to test if the error represents success. bool operator!() const { return value_ == 0; } /// Equality operator to compare two error objects. friend bool operator==(const error_code& e1, const error_code& e2) { return e1.value_ == e2.value_ && e1.category_ == e2.category_; } /// Inequality operator to compare two error objects. friend bool operator!=(const error_code& e1, const error_code& e2) { return e1.value_ != e2.value_ || e1.category_ != e2.category_; } private: // The value associated with the error code. int value_; // The category associated with the error code. const error_category* category_; }; # if !defined(ASIO_NO_IOSTREAM) /// Output an error code. template std::basic_ostream& operator<<( std::basic_ostream& os, const error_code& ec) { os << ec.category().name() << ':' << ec.value(); return os; } # endif // !defined(ASIO_NO_IOSTREAM) #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/error_code.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_ERROR_CODE_HPP ================================================ FILE: src/third_party/asio/execution_context.hpp ================================================ // // execution_context.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_EXECUTION_CONTEXT_HPP #define ASIO_EXECUTION_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include "asio/detail/noncopyable.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio { class execution_context; class io_context; #if !defined(GENERATING_DOCUMENTATION) template Service& use_service(execution_context&); template Service& use_service(io_context&); template void add_service(execution_context&, Service*); template bool has_service(execution_context&); #endif // !defined(GENERATING_DOCUMENTATION) namespace detail { class service_registry; } /// A context for function object execution. /** * An execution context represents a place where function objects will be * executed. An @c io_context is an example of an execution context. * * @par The execution_context class and services * * Class execution_context implements an extensible, type-safe, polymorphic set * of services, indexed by service type. * * Services exist to manage the resources that are shared across an execution * context. For example, timers may be implemented in terms of a single timer * queue, and this queue would be stored in a service. * * Access to the services of an execution_context is via three function * templates, use_service(), add_service() and has_service(). * * In a call to @c use_service(), the type argument chooses a service, * making available all members of the named type. If @c Service is not present * in an execution_context, an object of type @c Service is created and added * to the execution_context. A C++ program can check if an execution_context * implements a particular service with the function template @c * has_service(). * * Service objects may be explicitly added to an execution_context using the * function template @c add_service(). If the @c Service is already * present, the service_already_exists exception is thrown. If the owner of the * service is not the same object as the execution_context parameter, the * invalid_service_owner exception is thrown. * * Once a service reference is obtained from an execution_context object by * calling use_service(), that reference remains usable as long as the owning * execution_context object exists. * * All service implementations have execution_context::service as a public base * class. Custom services may be implemented by deriving from this class and * then added to an execution_context using the facilities described above. * * @par The execution_context as a base class * * Class execution_context may be used only as a base class for concrete * execution context types. The @c io_context is an example of such a derived * type. * * On destruction, a class that is derived from execution_context must perform * execution_context::shutdown() followed by * execution_context::destroy(). * * This destruction sequence permits programs to simplify their resource * management by using @c shared_ptr<>. Where an object's lifetime is tied to * the lifetime of a connection (or some other sequence of asynchronous * operations), a @c shared_ptr to the object would be bound into the handlers * for all asynchronous operations associated with it. This works as follows: * * @li When a single connection ends, all associated asynchronous operations * complete. The corresponding handler objects are destroyed, and all @c * shared_ptr references to the objects are destroyed. * * @li To shut down the whole program, the io_context function stop() is called * to terminate any run() calls as soon as possible. The io_context destructor * calls @c shutdown() and @c destroy() to destroy all pending handlers, * causing all @c shared_ptr references to all connection objects to be * destroyed. */ class execution_context : private noncopyable { public: class id; class service; public: /// Constructor. ASIO_DECL execution_context(); /// Destructor. ASIO_DECL ~execution_context(); protected: /// Shuts down all services in the context. /** * This function is implemented as follows: * * @li For each service object @c svc in the execution_context set, in * reverse order of the beginning of service object lifetime, performs @c * svc->shutdown(). */ ASIO_DECL void shutdown(); /// Destroys all services in the context. /** * This function is implemented as follows: * * @li For each service object @c svc in the execution_context set, in * reverse order * of the beginning of service object lifetime, performs * delete static_cast(svc). */ ASIO_DECL void destroy(); public: /// Fork-related event notifications. enum fork_event { /// Notify the context that the process is about to fork. fork_prepare, /// Notify the context that the process has forked and is the parent. fork_parent, /// Notify the context that the process has forked and is the child. fork_child }; /// Notify the execution_context of a fork-related event. /** * This function is used to inform the execution_context that the process is * about to fork, or has just forked. This allows the execution_context, and * the services it contains, to perform any necessary housekeeping to ensure * correct operation following a fork. * * This function must not be called while any other execution_context * function, or any function associated with the execution_context's derived * class, is being called in another thread. It is, however, safe to call * this function from within a completion handler, provided no other thread * is accessing the execution_context or its derived class. * * @param event A fork-related event. * * @throws asio::system_error Thrown on failure. If the notification * fails the execution_context object should no longer be used and should be * destroyed. * * @par Example * The following code illustrates how to incorporate the notify_fork() * function: * @code my_execution_context.notify_fork(execution_context::fork_prepare); * if (fork() == 0) * { * // This is the child process. * my_execution_context.notify_fork(execution_context::fork_child); * } * else * { * // This is the parent process. * my_execution_context.notify_fork(execution_context::fork_parent); * } @endcode * * @note For each service object @c svc in the execution_context set, * performs svc->notify_fork();. When processing the fork_prepare * event, services are visited in reverse order of the beginning of service * object lifetime. Otherwise, services are visited in order of the beginning * of service object lifetime. */ ASIO_DECL void notify_fork(fork_event event); /// Obtain the service object corresponding to the given type. /** * This function is used to locate a service object that corresponds to the * given service type. If there is no existing implementation of the service, * then the execution_context will create a new instance of the service. * * @param e The execution_context object that owns the service. * * @return The service interface implementing the specified service type. * Ownership of the service interface is not transferred to the caller. */ template friend Service& use_service(execution_context& e); /// Obtain the service object corresponding to the given type. /** * This function is used to locate a service object that corresponds to the * given service type. If there is no existing implementation of the service, * then the io_context will create a new instance of the service. * * @param ioc The io_context object that owns the service. * * @return The service interface implementing the specified service type. * Ownership of the service interface is not transferred to the caller. * * @note This overload is preserved for backwards compatibility with services * that inherit from io_context::service. */ template friend Service& use_service(io_context& ioc); #if defined(GENERATING_DOCUMENTATION) /// Creates a service object and adds it to the execution_context. /** * This function is used to add a service to the execution_context. * * @param e The execution_context object that owns the service. * * @param args Zero or more arguments to be passed to the service * constructor. * * @throws asio::service_already_exists Thrown if a service of the * given type is already present in the execution_context. */ template friend Service& make_service(execution_context& e, Args&&... args); #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template friend Service& make_service(execution_context& e, ASIO_MOVE_ARG(Args)... args); #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template friend Service& make_service(execution_context& e); #define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \ template \ friend Service& make_service(execution_context& e, \ ASIO_VARIADIC_MOVE_PARAMS(n)); \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF) #undef ASIO_PRIVATE_MAKE_SERVICE_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) /// (Deprecated: Use make_service().) Add a service object to the /// execution_context. /** * This function is used to add a service to the execution_context. * * @param e The execution_context object that owns the service. * * @param svc The service object. On success, ownership of the service object * is transferred to the execution_context. When the execution_context object * is destroyed, it will destroy the service object by performing: @code * delete static_cast(svc) @endcode * * @throws asio::service_already_exists Thrown if a service of the * given type is already present in the execution_context. * * @throws asio::invalid_service_owner Thrown if the service's owning * execution_context is not the execution_context object specified by the * @c e parameter. */ template friend void add_service(execution_context& e, Service* svc); /// Determine if an execution_context contains a specified service type. /** * This function is used to determine whether the execution_context contains a * service object corresponding to the given service type. * * @param e The execution_context object that owns the service. * * @return A boolean indicating whether the execution_context contains the * service. */ template friend bool has_service(execution_context& e); private: // The service registry. asio::detail::service_registry* service_registry_; }; /// Class used to uniquely identify a service. class execution_context::id : private noncopyable { public: /// Constructor. id() {} }; /// Base class for all io_context services. class execution_context::service : private noncopyable { public: /// Get the context object that owns the service. execution_context& context(); protected: /// Constructor. /** * @param owner The execution_context object that owns the service. */ ASIO_DECL service(execution_context& owner); /// Destructor. ASIO_DECL virtual ~service(); private: /// Destroy all user-defined handler objects owned by the service. virtual void shutdown() = 0; /// Handle notification of a fork-related event to perform any necessary /// housekeeping. /** * This function is not a pure virtual so that services only have to * implement it if necessary. The default implementation does nothing. */ ASIO_DECL virtual void notify_fork( execution_context::fork_event event); friend class asio::detail::service_registry; struct key { key() : type_info_(0), id_(0) {} const std::type_info* type_info_; const execution_context::id* id_; } key_; execution_context& owner_; service* next_; }; /// Exception thrown when trying to add a duplicate service to an /// execution_context. class service_already_exists : public std::logic_error { public: ASIO_DECL service_already_exists(); }; /// Exception thrown when trying to add a service object to an /// execution_context where the service has a different owner. class invalid_service_owner : public std::logic_error { public: ASIO_DECL invalid_service_owner(); }; namespace detail { // Special derived service id type to keep classes header-file only. template class service_id : public execution_context::id { }; // Special service base class to keep classes header-file only. template class execution_context_service_base : public execution_context::service { public: static service_id id; // Constructor. execution_context_service_base(execution_context& e) : execution_context::service(e) { } }; template service_id execution_context_service_base::id; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/execution_context.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/execution_context.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_EXECUTION_CONTEXT_HPP ================================================ FILE: src/third_party/asio/executor.hpp ================================================ // // executor.hpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_EXECUTOR_HPP #define ASIO_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/cstddef.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Exception thrown when trying to access an empty polymorphic executor. class bad_executor : public std::exception { public: /// Constructor. ASIO_DECL bad_executor() ASIO_NOEXCEPT; /// Obtain message associated with exception. ASIO_DECL virtual const char* what() const ASIO_NOEXCEPT_OR_NOTHROW; }; /// Polymorphic wrapper for executors. class executor { public: /// Default constructor. executor() ASIO_NOEXCEPT : impl_(0) { } /// Construct from nullptr. executor(nullptr_t) ASIO_NOEXCEPT : impl_(0) { } /// Copy constructor. executor(const executor& other) ASIO_NOEXCEPT : impl_(other.clone()) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. executor(executor&& other) ASIO_NOEXCEPT : impl_(other.impl_) { other.impl_ = 0; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a polymorphic wrapper for the specified executor. template executor(Executor e); /// Allocator-aware constructor to create a polymorphic wrapper for the /// specified executor. template executor(allocator_arg_t, const Allocator& a, Executor e); /// Destructor. ~executor() { destroy(); } /// Assignment operator. executor& operator=(const executor& other) ASIO_NOEXCEPT { destroy(); impl_ = other.clone(); return *this; } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) // Move assignment operator. executor& operator=(executor&& other) ASIO_NOEXCEPT { destroy(); impl_ = other.impl_; other.impl_ = 0; return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator for nullptr_t. executor& operator=(nullptr_t) ASIO_NOEXCEPT { destroy(); impl_ = 0; return *this; } /// Assignment operator to create a polymorphic wrapper for the specified /// executor. template executor& operator=(ASIO_MOVE_ARG(Executor) e) ASIO_NOEXCEPT { executor tmp(ASIO_MOVE_CAST(Executor)(e)); destroy(); impl_ = tmp.impl_; tmp.impl_ = 0; return *this; } /// Obtain the underlying execution context. execution_context& context() const ASIO_NOEXCEPT { return get_impl()->context(); } /// Inform the executor that it has some outstanding work to do. void on_work_started() const ASIO_NOEXCEPT { get_impl()->on_work_started(); } /// Inform the executor that some work is no longer outstanding. void on_work_finished() const ASIO_NOEXCEPT { get_impl()->on_work_finished(); } /// Request the executor to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object is executed according to the rules of the * target executor object. * * @param f The function object to be called. The executor will make a copy * of the handler object as required. The function signature of the function * object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the executor to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object is executed according to the rules of the * target executor object. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the executor to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object is executed according to the rules of the * target executor object. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; struct unspecified_bool_type_t {}; typedef void (*unspecified_bool_type)(unspecified_bool_type_t); static void unspecified_bool_true(unspecified_bool_type_t) {} /// Operator to test if the executor contains a valid target. operator unspecified_bool_type() const ASIO_NOEXCEPT { return impl_ ? &executor::unspecified_bool_true : 0; } /// Obtain type information for the target executor object. /** * @returns If @c *this has a target type of type @c T, typeid(T); * otherwise, typeid(void). */ #if !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION) const std::type_info& target_type() const ASIO_NOEXCEPT { return impl_ ? impl_->target_type() : typeid(void); } #else // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION) const void* target_type() const ASIO_NOEXCEPT { return impl_ ? impl_->target_type() : 0; } #endif // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION) /// Obtain a pointer to the target executor object. /** * @returns If target_type() == typeid(T), a pointer to the stored * executor target; otherwise, a null pointer. */ template Executor* target() ASIO_NOEXCEPT; /// Obtain a pointer to the target executor object. /** * @returns If target_type() == typeid(T), a pointer to the stored * executor target; otherwise, a null pointer. */ template const Executor* target() const ASIO_NOEXCEPT; /// Compare two executors for equality. friend bool operator==(const executor& a, const executor& b) ASIO_NOEXCEPT { if (a.impl_ == b.impl_) return true; if (!a.impl_ || !b.impl_) return false; return a.impl_->equals(b.impl_); } /// Compare two executors for inequality. friend bool operator!=(const executor& a, const executor& b) ASIO_NOEXCEPT { return !(a == b); } private: #if !defined(GENERATING_DOCUMENTATION) class function; template class impl; #if !defined(ASIO_NO_TYPEID) typedef const std::type_info& type_id_result_type; #else // !defined(ASIO_NO_TYPEID) typedef const void* type_id_result_type; #endif // !defined(ASIO_NO_TYPEID) template static type_id_result_type type_id() { #if !defined(ASIO_NO_TYPEID) return typeid(T); #else // !defined(ASIO_NO_TYPEID) static int unique_id; return &unique_id; #endif // !defined(ASIO_NO_TYPEID) } // Base class for all polymorphic executor implementations. class impl_base { public: virtual impl_base* clone() const ASIO_NOEXCEPT = 0; virtual void destroy() ASIO_NOEXCEPT = 0; virtual execution_context& context() ASIO_NOEXCEPT = 0; virtual void on_work_started() ASIO_NOEXCEPT = 0; virtual void on_work_finished() ASIO_NOEXCEPT = 0; virtual void dispatch(ASIO_MOVE_ARG(function)) = 0; virtual void post(ASIO_MOVE_ARG(function)) = 0; virtual void defer(ASIO_MOVE_ARG(function)) = 0; virtual type_id_result_type target_type() const ASIO_NOEXCEPT = 0; virtual void* target() ASIO_NOEXCEPT = 0; virtual const void* target() const ASIO_NOEXCEPT = 0; virtual bool equals(const impl_base* e) const ASIO_NOEXCEPT = 0; protected: impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {} virtual ~impl_base() {} private: friend class executor; const bool fast_dispatch_; }; // Helper function to check and return the implementation pointer. impl_base* get_impl() const { if (!impl_) { bad_executor ex; asio::detail::throw_exception(ex); } return impl_; } // Helper function to clone another implementation. impl_base* clone() const ASIO_NOEXCEPT { return impl_ ? impl_->clone() : 0; } // Helper function to destroy an implementation. void destroy() ASIO_NOEXCEPT { if (impl_) impl_->destroy(); } impl_base* impl_; #endif // !defined(GENERATING_DOCUMENTATION) }; } // namespace asio ASIO_USES_ALLOCATOR(asio::executor) #include "asio/detail/pop_options.hpp" #include "asio/impl/executor.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/executor.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/executor_work_guard.hpp ================================================ // // executor_work_guard.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_EXECUTOR_WORK_GUARD_HPP #define ASIO_EXECUTOR_WORK_GUARD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/type_traits.hpp" #include "asio/is_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// An object of type @c executor_work_guard controls ownership of executor work /// within a scope. template class executor_work_guard { public: /// The underlying executor type. typedef Executor executor_type; /// Constructs a @c executor_work_guard object for the specified executor. /** * Stores a copy of @c e and calls on_work_started() on it. */ explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT : executor_(e), owns_(true) { executor_.on_work_started(); } /// Copy constructor. executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT : executor_(other.executor_), owns_(other.owns_) { if (owns_) executor_.on_work_started(); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), owns_(other.owns_) { other.owns_ = false; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. /** * Unless the object has already been reset, or is in a moved-from state, * calls on_work_finished() on the stored executor. */ ~executor_work_guard() { if (owns_) executor_.on_work_finished(); } /// Obtain the associated executor. executor_type get_executor() const ASIO_NOEXCEPT { return executor_; } /// Whether the executor_work_guard object owns some outstanding work. bool owns_work() const ASIO_NOEXCEPT { return owns_; } /// Indicate that the work is no longer outstanding. /* * Unless the object has already been reset, or is in a moved-from state, * calls on_work_finished() on the stored executor. */ void reset() ASIO_NOEXCEPT { if (owns_) { executor_.on_work_finished(); owns_ = false; } } private: // Disallow assignment. executor_work_guard& operator=(const executor_work_guard&); executor_type executor_; bool owns_; }; /// Create an @ref executor_work_guard object. template inline executor_work_guard make_work_guard(const Executor& ex, typename enable_if::value>::type* = 0) { return executor_work_guard(ex); } /// Create an @ref executor_work_guard object. template inline executor_work_guard make_work_guard(ExecutionContext& ctx, typename enable_if< is_convertible::value>::type* = 0) { return executor_work_guard( ctx.get_executor()); } /// Create an @ref executor_work_guard object. template inline executor_work_guard::type> make_work_guard(const T& t, typename enable_if::value && !is_convertible::value>::type* = 0) { return executor_work_guard::type>( associated_executor::get(t)); } /// Create an @ref executor_work_guard object. template inline executor_work_guard::type> make_work_guard(const T& t, const Executor& ex, typename enable_if::value>::type* = 0) { return executor_work_guard::type>( associated_executor::get(t, ex)); } /// Create an @ref executor_work_guard object. template inline executor_work_guard::type> make_work_guard(const T& t, ExecutionContext& ctx, typename enable_if::value && !is_convertible::value && is_convertible::value>::type* = 0) { return executor_work_guard::type>( associated_executor::get( t, ctx.get_executor())); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_EXECUTOR_WORK_GUARD_HPP ================================================ FILE: src/third_party/asio/generic/basic_endpoint.hpp ================================================ // // generic/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_GENERIC_BASIC_ENDPOINT_HPP #define ASIO_GENERIC_BASIC_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/generic/detail/endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace generic { /// Describes an endpoint for any socket type. /** * The asio::generic::basic_endpoint class template describes an endpoint * that may be associated with any socket type. * * @note The socket types sockaddr type must be able to fit into a * @c sockaddr_storage structure. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * Endpoint. */ template class basic_endpoint { public: /// The protocol type associated with the endpoint. typedef Protocol protocol_type; /// The type of the endpoint structure. This type is dependent on the /// underlying implementation of the socket layer. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined data_type; #else typedef asio::detail::socket_addr_type data_type; #endif /// Default constructor. basic_endpoint() ASIO_NOEXCEPT { } /// Construct an endpoint from the specified socket address. basic_endpoint(const void* socket_address, std::size_t socket_address_size, int socket_protocol = 0) : impl_(socket_address, socket_address_size, socket_protocol) { } /// Construct an endpoint from the specific endpoint type. template basic_endpoint(const Endpoint& endpoint) : impl_(endpoint.data(), endpoint.size(), endpoint.protocol().protocol()) { } /// Copy constructor. basic_endpoint(const basic_endpoint& other) : impl_(other.impl_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. basic_endpoint(basic_endpoint&& other) : impl_(other.impl_) { } #endif // defined(ASIO_HAS_MOVE) /// Assign from another endpoint. basic_endpoint& operator=(const basic_endpoint& other) { impl_ = other.impl_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move-assign from another endpoint. basic_endpoint& operator=(basic_endpoint&& other) { impl_ = other.impl_; return *this; } #endif // defined(ASIO_HAS_MOVE) /// The protocol associated with the endpoint. protocol_type protocol() const { return protocol_type(impl_.family(), impl_.protocol()); } /// Get the underlying endpoint in the native type. data_type* data() { return impl_.data(); } /// Get the underlying endpoint in the native type. const data_type* data() const { return impl_.data(); } /// Get the underlying size of the endpoint in the native type. std::size_t size() const { return impl_.size(); } /// Set the underlying size of the endpoint in the native type. void resize(std::size_t new_size) { impl_.resize(new_size); } /// Get the capacity of the endpoint in the native type. std::size_t capacity() const { return impl_.capacity(); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint& e1, const basic_endpoint& e2) { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint& e1, const basic_endpoint& e2) { return !(e1.impl_ == e2.impl_); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint& e1, const basic_endpoint& e2) { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint& e1, const basic_endpoint& e2) { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint& e1, const basic_endpoint& e2) { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint& e1, const basic_endpoint& e2) { return !(e1 < e2); } private: // The underlying generic endpoint. asio::generic::detail::endpoint impl_; }; } // namespace generic } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_GENERIC_BASIC_ENDPOINT_HPP ================================================ FILE: src/third_party/asio/generic/datagram_protocol.hpp ================================================ // // generic/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP #define ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/basic_datagram_socket.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/generic/basic_endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace generic { /// Encapsulates the flags needed for a generic datagram-oriented socket. /** * The asio::generic::datagram_protocol class contains flags necessary * for datagram-oriented sockets of any address family and protocol. * * @par Examples * Constructing using a native address family and socket protocol: * @code datagram_protocol p(AF_INET, IPPROTO_UDP); @endcode * Constructing from a specific protocol type: * @code datagram_protocol p(asio::ip::udp::v4()); @endcode * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class datagram_protocol { public: /// Construct a protocol object for a specific address family and protocol. datagram_protocol(int address_family, int socket_protocol) : family_(address_family), protocol_(socket_protocol) { } /// Construct a generic protocol object from a specific protocol. /** * @throws @c bad_cast Thrown if the source protocol is not datagram-oriented. */ template datagram_protocol(const Protocol& source_protocol) : family_(source_protocol.family()), protocol_(source_protocol.protocol()) { if (source_protocol.type() != type()) { std::bad_cast ex; asio::detail::throw_exception(ex); } } /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_DGRAM); } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return family_; } /// Compare two protocols for equality. friend bool operator==(const datagram_protocol& p1, const datagram_protocol& p2) { return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; } /// Compare two protocols for inequality. friend bool operator!=(const datagram_protocol& p1, const datagram_protocol& p2) { return !(p1 == p2); } /// The type of an endpoint. typedef basic_endpoint endpoint; /// The generic socket type. typedef basic_datagram_socket socket; private: int family_; int protocol_; }; } // namespace generic } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP ================================================ FILE: src/third_party/asio/generic/detail/endpoint.hpp ================================================ // // generic/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_GENERIC_DETAIL_ENDPOINT_HPP #define ASIO_GENERIC_DETAIL_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace generic { namespace detail { // Helper class for implementing a generic socket endpoint. class endpoint { public: // Default constructor. ASIO_DECL endpoint(); // Construct an endpoint from the specified raw bytes. ASIO_DECL endpoint(const void* sock_addr, std::size_t sock_addr_size, int sock_protocol); // Copy constructor. endpoint(const endpoint& other) : data_(other.data_), size_(other.size_), protocol_(other.protocol_) { } // Assign from another endpoint. endpoint& operator=(const endpoint& other) { data_ = other.data_; size_ = other.size_; protocol_ = other.protocol_; return *this; } // Get the address family associated with the endpoint. int family() const { return data_.base.sa_family; } // Get the socket protocol associated with the endpoint. int protocol() const { return protocol_; } // Get the underlying endpoint in the native type. asio::detail::socket_addr_type* data() { return &data_.base; } // Get the underlying endpoint in the native type. const asio::detail::socket_addr_type* data() const { return &data_.base; } // Get the underlying size of the endpoint in the native type. std::size_t size() const { return size_; } // Set the underlying size of the endpoint in the native type. ASIO_DECL void resize(std::size_t size); // Get the capacity of the endpoint in the native type. std::size_t capacity() const { return sizeof(asio::detail::sockaddr_storage_type); } // Compare two endpoints for equality. ASIO_DECL friend bool operator==( const endpoint& e1, const endpoint& e2); // Compare endpoints for ordering. ASIO_DECL friend bool operator<( const endpoint& e1, const endpoint& e2); private: // The underlying socket address. union data_union { asio::detail::socket_addr_type base; asio::detail::sockaddr_storage_type generic; } data_; // The length of the socket address stored in the endpoint. std::size_t size_; // The socket protocol associated with the endpoint. int protocol_; // Initialise with a specified memory. ASIO_DECL void init(const void* sock_addr, std::size_t sock_addr_size, int sock_protocol); }; } // namespace detail } // namespace generic } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/generic/detail/impl/endpoint.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_GENERIC_DETAIL_ENDPOINT_HPP ================================================ FILE: src/third_party/asio/generic/detail/impl/endpoint.ipp ================================================ // // generic/detail/impl/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP #define ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/detail/socket_ops.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/error.hpp" #include "asio/generic/detail/endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace generic { namespace detail { endpoint::endpoint() { init(0, 0, 0); } endpoint::endpoint(const void* sock_addr, std::size_t sock_addr_size, int sock_protocol) { init(sock_addr, sock_addr_size, sock_protocol); } void endpoint::resize(std::size_t new_size) { if (new_size > sizeof(asio::detail::sockaddr_storage_type)) { asio::error_code ec(asio::error::invalid_argument); asio::detail::throw_error(ec); } else { size_ = new_size; protocol_ = 0; } } bool operator==(const endpoint& e1, const endpoint& e2) { using namespace std; // For memcmp. return e1.size() == e2.size() && memcmp(e1.data(), e2.data(), e1.size()) == 0; } bool operator<(const endpoint& e1, const endpoint& e2) { if (e1.protocol() < e2.protocol()) return true; if (e1.protocol() > e2.protocol()) return false; using namespace std; // For memcmp. std::size_t compare_size = e1.size() < e2.size() ? e1.size() : e2.size(); int compare_result = memcmp(e1.data(), e2.data(), compare_size); if (compare_result < 0) return true; if (compare_result > 0) return false; return e1.size() < e2.size(); } void endpoint::init(const void* sock_addr, std::size_t sock_addr_size, int sock_protocol) { if (sock_addr_size > sizeof(asio::detail::sockaddr_storage_type)) { asio::error_code ec(asio::error::invalid_argument); asio::detail::throw_error(ec); } using namespace std; // For memset and memcpy. memset(&data_.generic, 0, sizeof(asio::detail::sockaddr_storage_type)); if (sock_addr_size > 0) memcpy(&data_.generic, sock_addr, sock_addr_size); size_ = sock_addr_size; protocol_ = sock_protocol; } } // namespace detail } // namespace generic } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP ================================================ FILE: src/third_party/asio/generic/raw_protocol.hpp ================================================ // // generic/raw_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_GENERIC_RAW_PROTOCOL_HPP #define ASIO_GENERIC_RAW_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/basic_raw_socket.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/generic/basic_endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace generic { /// Encapsulates the flags needed for a generic raw socket. /** * The asio::generic::raw_protocol class contains flags necessary for * raw sockets of any address family and protocol. * * @par Examples * Constructing using a native address family and socket protocol: * @code raw_protocol p(AF_INET, IPPROTO_ICMP); @endcode * Constructing from a specific protocol type: * @code raw_protocol p(asio::ip::icmp::v4()); @endcode * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class raw_protocol { public: /// Construct a protocol object for a specific address family and protocol. raw_protocol(int address_family, int socket_protocol) : family_(address_family), protocol_(socket_protocol) { } /// Construct a generic protocol object from a specific protocol. /** * @throws @c bad_cast Thrown if the source protocol is not raw-oriented. */ template raw_protocol(const Protocol& source_protocol) : family_(source_protocol.family()), protocol_(source_protocol.protocol()) { if (source_protocol.type() != type()) { std::bad_cast ex; asio::detail::throw_exception(ex); } } /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_RAW); } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return family_; } /// Compare two protocols for equality. friend bool operator==(const raw_protocol& p1, const raw_protocol& p2) { return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; } /// Compare two protocols for inequality. friend bool operator!=(const raw_protocol& p1, const raw_protocol& p2) { return !(p1 == p2); } /// The type of an endpoint. typedef basic_endpoint endpoint; /// The generic socket type. typedef basic_raw_socket socket; private: int family_; int protocol_; }; } // namespace generic } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_GENERIC_RAW_PROTOCOL_HPP ================================================ FILE: src/third_party/asio/generic/seq_packet_protocol.hpp ================================================ // // generic/seq_packet_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP #define ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/basic_seq_packet_socket.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/generic/basic_endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace generic { /// Encapsulates the flags needed for a generic sequenced packet socket. /** * The asio::generic::seq_packet_protocol class contains flags necessary * for seq_packet-oriented sockets of any address family and protocol. * * @par Examples * Constructing using a native address family and socket protocol: * @code seq_packet_protocol p(AF_INET, IPPROTO_SCTP); @endcode * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class seq_packet_protocol { public: /// Construct a protocol object for a specific address family and protocol. seq_packet_protocol(int address_family, int socket_protocol) : family_(address_family), protocol_(socket_protocol) { } /// Construct a generic protocol object from a specific protocol. /** * @throws @c bad_cast Thrown if the source protocol is not based around * sequenced packets. */ template seq_packet_protocol(const Protocol& source_protocol) : family_(source_protocol.family()), protocol_(source_protocol.protocol()) { if (source_protocol.type() != type()) { std::bad_cast ex; asio::detail::throw_exception(ex); } } /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_SEQPACKET); } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return family_; } /// Compare two protocols for equality. friend bool operator==(const seq_packet_protocol& p1, const seq_packet_protocol& p2) { return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; } /// Compare two protocols for inequality. friend bool operator!=(const seq_packet_protocol& p1, const seq_packet_protocol& p2) { return !(p1 == p2); } /// The type of an endpoint. typedef basic_endpoint endpoint; /// The generic socket type. typedef basic_seq_packet_socket socket; private: int family_; int protocol_; }; } // namespace generic } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP ================================================ FILE: src/third_party/asio/generic/stream_protocol.hpp ================================================ // // generic/stream_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_GENERIC_STREAM_PROTOCOL_HPP #define ASIO_GENERIC_STREAM_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/basic_socket_iostream.hpp" #include "asio/basic_stream_socket.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/generic/basic_endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace generic { /// Encapsulates the flags needed for a generic stream-oriented socket. /** * The asio::generic::stream_protocol class contains flags necessary for * stream-oriented sockets of any address family and protocol. * * @par Examples * Constructing using a native address family and socket protocol: * @code stream_protocol p(AF_INET, IPPROTO_TCP); @endcode * Constructing from a specific protocol type: * @code stream_protocol p(asio::ip::tcp::v4()); @endcode * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class stream_protocol { public: /// Construct a protocol object for a specific address family and protocol. stream_protocol(int address_family, int socket_protocol) : family_(address_family), protocol_(socket_protocol) { } /// Construct a generic protocol object from a specific protocol. /** * @throws @c bad_cast Thrown if the source protocol is not stream-oriented. */ template stream_protocol(const Protocol& source_protocol) : family_(source_protocol.family()), protocol_(source_protocol.protocol()) { if (source_protocol.type() != type()) { std::bad_cast ex; asio::detail::throw_exception(ex); } } /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_STREAM); } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return family_; } /// Compare two protocols for equality. friend bool operator==(const stream_protocol& p1, const stream_protocol& p2) { return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; } /// Compare two protocols for inequality. friend bool operator!=(const stream_protocol& p1, const stream_protocol& p2) { return !(p1 == p2); } /// The type of an endpoint. typedef basic_endpoint endpoint; /// The generic socket type. typedef basic_stream_socket socket; #if !defined(ASIO_NO_IOSTREAM) /// The generic socket iostream type. typedef basic_socket_iostream iostream; #endif // !defined(ASIO_NO_IOSTREAM) private: int family_; int protocol_; }; } // namespace generic } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_GENERIC_STREAM_PROTOCOL_HPP ================================================ FILE: src/third_party/asio/handler_alloc_hook.hpp ================================================ // // handler_alloc_hook.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_HANDLER_ALLOC_HOOK_HPP #define ASIO_HANDLER_ALLOC_HOOK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/push_options.hpp" namespace asio { /// Default allocation function for handlers. /** * Asynchronous operations may need to allocate temporary objects. Since * asynchronous operations have a handler function object, these temporary * objects can be said to be associated with the handler. * * Implement asio_handler_allocate and asio_handler_deallocate for your own * handlers to provide custom allocation for these temporary objects. * * The default implementation of these allocation hooks uses ::operator * new and ::operator delete. * * @note All temporary objects associated with a handler will be deallocated * before the upcall to the handler is performed. This allows the same memory to * be reused for a subsequent asynchronous operation initiated by the handler. * * @par Example * @code * class my_handler; * * void* asio_handler_allocate(std::size_t size, my_handler* context) * { * return ::operator new(size); * } * * void asio_handler_deallocate(void* pointer, std::size_t size, * my_handler* context) * { * ::operator delete(pointer); * } * @endcode */ ASIO_DECL void* asio_handler_allocate( std::size_t size, ...); /// Default deallocation function for handlers. /** * Implement asio_handler_allocate and asio_handler_deallocate for your own * handlers to provide custom allocation for the associated temporary objects. * * The default implementation of these allocation hooks uses ::operator * new and ::operator delete. * * @sa asio_handler_allocate. */ ASIO_DECL void asio_handler_deallocate( void* pointer, std::size_t size, ...); } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/handler_alloc_hook.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_HANDLER_ALLOC_HOOK_HPP ================================================ FILE: src/third_party/asio/handler_continuation_hook.hpp ================================================ // // handler_continuation_hook.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_HANDLER_CONTINUATION_HOOK_HPP #define ASIO_HANDLER_CONTINUATION_HOOK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Default continuation function for handlers. /** * Asynchronous operations may represent a continuation of the asynchronous * control flow associated with the current handler. The implementation can use * this knowledge to optimise scheduling of the handler. * * Implement asio_handler_is_continuation for your own handlers to indicate * when a handler represents a continuation. * * The default implementation of the continuation hook returns false. * * @par Example * @code * class my_handler; * * bool asio_handler_is_continuation(my_handler* context) * { * return true; * } * @endcode */ inline bool asio_handler_is_continuation(...) { return false; } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_HANDLER_CONTINUATION_HOOK_HPP ================================================ FILE: src/third_party/asio/handler_invoke_hook.hpp ================================================ // // handler_invoke_hook.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_HANDLER_INVOKE_HOOK_HPP #define ASIO_HANDLER_INVOKE_HOOK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { /** @defgroup asio_handler_invoke asio::asio_handler_invoke * * @brief Default invoke function for handlers. * * Completion handlers for asynchronous operations are invoked by the * io_context associated with the corresponding object (e.g. a socket or * deadline_timer). Certain guarantees are made on when the handler may be * invoked, in particular that a handler can only be invoked from a thread that * is currently calling @c run() on the corresponding io_context object. * Handlers may subsequently be invoked through other objects (such as * io_context::strand objects) that provide additional guarantees. * * When asynchronous operations are composed from other asynchronous * operations, all intermediate handlers should be invoked using the same * method as the final handler. This is required to ensure that user-defined * objects are not accessed in a way that may violate the guarantees. This * hooking function ensures that the invoked method used for the final handler * is accessible at each intermediate step. * * Implement asio_handler_invoke for your own handlers to specify a custom * invocation strategy. * * This default implementation invokes the function object like so: * @code function(); @endcode * If necessary, the default implementation makes a copy of the function object * so that the non-const operator() can be used. * * @par Example * @code * class my_handler; * * template * void asio_handler_invoke(Function function, my_handler* context) * { * context->strand_.dispatch(function); * } * @endcode */ /*@{*/ /// Default handler invocation hook used for non-const function objects. template inline void asio_handler_invoke(Function& function, ...) { function(); } /// Default handler invocation hook used for const function objects. template inline void asio_handler_invoke(const Function& function, ...) { Function tmp(function); tmp(); } /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_HANDLER_INVOKE_HOOK_HPP ================================================ FILE: src/third_party/asio/high_resolution_timer.hpp ================================================ // // high_resolution_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_HIGH_RESOLUTION_TIMER_HPP #define ASIO_HIGH_RESOLUTION_TIMER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" namespace asio { /// Typedef for a timer based on the high resolution clock. /** * This typedef uses the C++11 @c <chrono> standard library facility, if * available. Otherwise, it may use the Boost.Chrono library. To explicitly * utilise Boost.Chrono, use the basic_waitable_timer template directly: * @code * typedef basic_waitable_timer timer; * @endcode */ typedef basic_waitable_timer< chrono::high_resolution_clock> high_resolution_timer; } // namespace asio #endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_HIGH_RESOLUTION_TIMER_HPP ================================================ FILE: src/third_party/asio/impl/awaitable.hpp ================================================ // // impl/awaitable.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_AWAITABLE_HPP #define ASIO_IMPL_AWAITABLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include #include "asio/detail/thread_context.hpp" #include "asio/detail/thread_info_base.hpp" #include "asio/detail/type_traits.hpp" #include "asio/post.hpp" #include "asio/system_error.hpp" #include "asio/this_coro.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // An awaitable_thread represents a thread-of-execution that is composed of one // or more "stack frames", with each frame represented by an awaitable_frame. // All execution occurs in the context of the awaitable_thread's executor. An // awaitable_thread continues to "pump" the stack frames by repeatedly resuming // the top stack frame until the stack is empty, or until ownership of the // stack is transferred to another awaitable_thread object. // // +------------------------------------+ // | top_of_stack_ | // | V // +--------------+---+ +-----------------+ // | | | | // | awaitable_thread |<---------------------------+ awaitable_frame | // | | attached_thread_ | | // +--------------+---+ (Set only when +---+-------------+ // | frames are being | // | actively pumped | caller_ // | by a thread, and | // | then only for V // | the top frame.) +-----------------+ // | | | // | | awaitable_frame | // | | | // | +---+-------------+ // | | // | | caller_ // | : // | : // | | // | V // | +-----------------+ // | bottom_of_stack_ | | // +------------------------------->| awaitable_frame | // | | // +-----------------+ template class awaitable_frame_base { public: #if !defined(ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING) void* operator new(std::size_t size) { return asio::detail::thread_info_base::allocate( asio::detail::thread_info_base::awaitable_frame_tag(), asio::detail::thread_context::thread_call_stack::top(), size); } void operator delete(void* pointer, std::size_t size) { asio::detail::thread_info_base::deallocate( asio::detail::thread_info_base::awaitable_frame_tag(), asio::detail::thread_context::thread_call_stack::top(), pointer, size); } #endif // !defined(ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING) // The frame starts in a suspended state until the awaitable_thread object // pumps the stack. auto initial_suspend() noexcept { return suspend_always(); } // On final suspension the frame is popped from the top of the stack. auto final_suspend() noexcept { struct result { awaitable_frame_base* this_; bool await_ready() const noexcept { return false; } void await_suspend(coroutine_handle) noexcept { this_->pop_frame(); } void await_resume() const noexcept { } }; return result{this}; } void set_except(std::exception_ptr e) noexcept { pending_exception_ = e; } void set_error(const asio::error_code& ec) { this->set_except(std::make_exception_ptr(asio::system_error(ec))); } void unhandled_exception() { set_except(std::current_exception()); } void rethrow_exception() { if (pending_exception_) { std::exception_ptr ex = std::exchange(pending_exception_, nullptr); std::rethrow_exception(ex); } } template auto await_transform(awaitable a) const { return a; } // This await transformation obtains the associated executor of the thread of // execution. auto await_transform(this_coro::executor_t) noexcept { struct result { awaitable_frame_base* this_; bool await_ready() const noexcept { return true; } void await_suspend(coroutine_handle) noexcept { } auto await_resume() const noexcept { return this_->attached_thread_->get_executor(); } }; return result{this}; } // This await transformation is used to run an async operation's initiation // function object after the coroutine has been suspended. This ensures that // immediate resumption of the coroutine in another thread does not cause a // race condition. template auto await_transform(Function f, typename enable_if< is_convertible< typename result_of::type, awaitable_thread* >::value >::type* = 0) { struct result { Function function_; awaitable_frame_base* this_; bool await_ready() const noexcept { return false; } void await_suspend(coroutine_handle) noexcept { function_(this_); } void await_resume() const noexcept { } }; return result{std::move(f), this}; } void attach_thread(awaitable_thread* handler) noexcept { attached_thread_ = handler; } awaitable_thread* detach_thread() noexcept { return std::exchange(attached_thread_, nullptr); } void push_frame(awaitable_frame_base* caller) noexcept { caller_ = caller; attached_thread_ = caller_->attached_thread_; attached_thread_->top_of_stack_ = this; caller_->attached_thread_ = nullptr; } void pop_frame() noexcept { if (caller_) caller_->attached_thread_ = attached_thread_; attached_thread_->top_of_stack_ = caller_; attached_thread_ = nullptr; caller_ = nullptr; } void resume() { coro_.resume(); } void destroy() { coro_.destroy(); } protected: coroutine_handle coro_ = nullptr; awaitable_thread* attached_thread_ = nullptr; awaitable_frame_base* caller_ = nullptr; std::exception_ptr pending_exception_ = nullptr; }; template class awaitable_frame : public awaitable_frame_base { public: awaitable_frame() noexcept { } awaitable_frame(awaitable_frame&& other) noexcept : awaitable_frame_base(std::move(other)) { } ~awaitable_frame() { if (has_result_) static_cast(static_cast(result_))->~T(); } awaitable get_return_object() noexcept { this->coro_ = coroutine_handle::from_promise(*this); return awaitable(this); }; template void return_value(U&& u) { new (&result_) T(std::forward(u)); has_result_ = true; } template void return_values(Us&&... us) { this->return_value(std::forward_as_tuple(std::forward(us)...)); } T get() { this->caller_ = nullptr; this->rethrow_exception(); return std::move(*static_cast(static_cast(result_))); } private: alignas(T) unsigned char result_[sizeof(T)]; bool has_result_ = false; }; template class awaitable_frame : public awaitable_frame_base { public: awaitable get_return_object() { this->coro_ = coroutine_handle::from_promise(*this); return awaitable(this); }; void return_void() { } void get() { this->caller_ = nullptr; this->rethrow_exception(); } }; template class awaitable_thread { public: typedef Executor executor_type; // Construct from the entry point of a new thread of execution. awaitable_thread(awaitable p, const Executor& ex) : bottom_of_stack_(std::move(p)), top_of_stack_(bottom_of_stack_.frame_), executor_(ex) { } // Transfer ownership from another awaitable_thread. awaitable_thread(awaitable_thread&& other) noexcept : bottom_of_stack_(std::move(other.bottom_of_stack_)), top_of_stack_(std::exchange(other.top_of_stack_, nullptr)), executor_(std::move(other.executor_)) { } // Clean up with a last ditch effort to ensure the thread is unwound within // the context of the executor. ~awaitable_thread() { if (bottom_of_stack_.valid()) { // Coroutine "stack unwinding" must be performed through the executor. (post)(executor_, [a = std::move(bottom_of_stack_)]() mutable { awaitable(std::move(a)); }); } } executor_type get_executor() const noexcept { return executor_; } // Launch a new thread of execution. void launch() { top_of_stack_->attach_thread(this); pump(); } protected: template friend class awaitable_frame_base; // Repeatedly resume the top stack frame until the stack is empty or until it // has been transferred to another resumable_thread object. void pump() { do top_of_stack_->resume(); while (top_of_stack_); if (bottom_of_stack_.valid()) { awaitable a(std::move(bottom_of_stack_)); a.frame_->rethrow_exception(); } } awaitable bottom_of_stack_; awaitable_frame_base* top_of_stack_; executor_type executor_; }; } // namespace detail } // namespace asio #if !defined(GENERATING_DOCUMENTATION) namespace std { namespace experimental { template struct coroutine_traits, Args...> { typedef asio::detail::awaitable_frame promise_type; }; }} // namespace std::experimental #endif // !defined(GENERATING_DOCUMENTATION) #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_AWAITABLE_HPP ================================================ FILE: src/third_party/asio/impl/buffered_read_stream.hpp ================================================ // // impl/buffered_read_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_BUFFERED_READ_STREAM_HPP #define ASIO_IMPL_BUFFERED_READ_STREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { template std::size_t buffered_read_stream::fill() { detail::buffer_resize_guard resize_guard(storage_); std::size_t previous_size = storage_.size(); storage_.resize(storage_.capacity()); storage_.resize(previous_size + next_layer_.read_some(buffer( storage_.data() + previous_size, storage_.size() - previous_size))); resize_guard.commit(); return storage_.size() - previous_size; } template std::size_t buffered_read_stream::fill(asio::error_code& ec) { detail::buffer_resize_guard resize_guard(storage_); std::size_t previous_size = storage_.size(); storage_.resize(storage_.capacity()); storage_.resize(previous_size + next_layer_.read_some(buffer( storage_.data() + previous_size, storage_.size() - previous_size), ec)); resize_guard.commit(); return storage_.size() - previous_size; } namespace detail { template class buffered_fill_handler { public: buffered_fill_handler(detail::buffered_stream_storage& storage, std::size_t previous_size, ReadHandler& handler) : storage_(storage), previous_size_(previous_size), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) buffered_fill_handler(const buffered_fill_handler& other) : storage_(other.storage_), previous_size_(other.previous_size_), handler_(other.handler_) { } buffered_fill_handler(buffered_fill_handler&& other) : storage_(other.storage_), previous_size_(other.previous_size_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, const std::size_t bytes_transferred) { storage_.resize(previous_size_ + bytes_transferred); handler_(ec, bytes_transferred); } //private: detail::buffered_stream_storage& storage_; std::size_t previous_size_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, buffered_fill_handler* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, buffered_fill_handler* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( buffered_fill_handler* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, buffered_fill_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, buffered_fill_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_buffered_fill { public: typedef typename remove_reference< Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_fill(Stream& next_layer) : next_layer_(next_layer) { } executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, buffered_stream_storage* storage) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); std::size_t previous_size = storage->size(); storage->resize(storage->capacity()); next_layer_.async_read_some( buffer( storage->data() + previous_size, storage->size() - previous_size), buffered_fill_handler::type>( *storage, previous_size, handler2.value)); } private: Stream& next_layer_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::buffered_fill_handler, Allocator> { typedef typename associated_allocator::type type; static type get(const detail::buffered_fill_handler& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::buffered_fill_handler, Executor> { typedef typename associated_executor::type type; static type get(const detail::buffered_fill_handler& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadHandler> ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) buffered_read_stream::async_fill( ASIO_MOVE_ARG(ReadHandler) handler) { return async_initiate( detail::initiate_async_buffered_fill(next_layer_), handler, &storage_); } template template std::size_t buffered_read_stream::read_some( const MutableBufferSequence& buffers) { using asio::buffer_size; if (buffer_size(buffers) == 0) return 0; if (storage_.empty()) this->fill(); return this->copy(buffers); } template template std::size_t buffered_read_stream::read_some( const MutableBufferSequence& buffers, asio::error_code& ec) { ec = asio::error_code(); using asio::buffer_size; if (buffer_size(buffers) == 0) return 0; if (storage_.empty() && !this->fill(ec)) return 0; return this->copy(buffers); } namespace detail { template class buffered_read_some_handler { public: buffered_read_some_handler(detail::buffered_stream_storage& storage, const MutableBufferSequence& buffers, ReadHandler& handler) : storage_(storage), buffers_(buffers), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) buffered_read_some_handler(const buffered_read_some_handler& other) : storage_(other.storage_), buffers_(other.buffers_), handler_(other.handler_) { } buffered_read_some_handler(buffered_read_some_handler&& other) : storage_(other.storage_), buffers_(other.buffers_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t) { if (ec || storage_.empty()) { const std::size_t length = 0; handler_(ec, length); } else { const std::size_t bytes_copied = asio::buffer_copy( buffers_, storage_.data(), storage_.size()); storage_.consume(bytes_copied); handler_(ec, bytes_copied); } } //private: detail::buffered_stream_storage& storage_; MutableBufferSequence buffers_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, buffered_read_some_handler< MutableBufferSequence, ReadHandler>* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, buffered_read_some_handler< MutableBufferSequence, ReadHandler>* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( buffered_read_some_handler< MutableBufferSequence, ReadHandler>* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, buffered_read_some_handler< MutableBufferSequence, ReadHandler>* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, buffered_read_some_handler< MutableBufferSequence, ReadHandler>* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_buffered_read_some { public: typedef typename remove_reference< Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_read_some(Stream& next_layer) : next_layer_(next_layer) { } executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, buffered_stream_storage* storage, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; using asio::buffer_size; non_const_lvalue handler2(handler); if (buffer_size(buffers) == 0 || !storage->empty()) { next_layer_.async_read_some(ASIO_MUTABLE_BUFFER(0, 0), buffered_read_some_handler::type>( *storage, buffers, handler2.value)); } else { initiate_async_buffered_fill(this->next_layer_)( buffered_read_some_handler::type>( *storage, buffers, handler2.value), storage); } } private: Stream& next_layer_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::buffered_read_some_handler, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::buffered_read_some_handler< MutableBufferSequence, ReadHandler>& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::buffered_read_some_handler, Executor> { typedef typename associated_executor::type type; static type get( const detail::buffered_read_some_handler< MutableBufferSequence, ReadHandler>& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) buffered_read_stream::async_read_some( const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler) { return async_initiate( detail::initiate_async_buffered_read_some(next_layer_), handler, &storage_, buffers); } template template std::size_t buffered_read_stream::peek( const MutableBufferSequence& buffers) { if (storage_.empty()) this->fill(); return this->peek_copy(buffers); } template template std::size_t buffered_read_stream::peek( const MutableBufferSequence& buffers, asio::error_code& ec) { ec = asio::error_code(); if (storage_.empty() && !this->fill(ec)) return 0; return this->peek_copy(buffers); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_BUFFERED_READ_STREAM_HPP ================================================ FILE: src/third_party/asio/impl/buffered_write_stream.hpp ================================================ // // impl/buffered_write_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP #define ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/push_options.hpp" namespace asio { template std::size_t buffered_write_stream::flush() { std::size_t bytes_written = write(next_layer_, buffer(storage_.data(), storage_.size())); storage_.consume(bytes_written); return bytes_written; } template std::size_t buffered_write_stream::flush(asio::error_code& ec) { std::size_t bytes_written = write(next_layer_, buffer(storage_.data(), storage_.size()), transfer_all(), ec); storage_.consume(bytes_written); return bytes_written; } namespace detail { template class buffered_flush_handler { public: buffered_flush_handler(detail::buffered_stream_storage& storage, WriteHandler& handler) : storage_(storage), handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) buffered_flush_handler(const buffered_flush_handler& other) : storage_(other.storage_), handler_(other.handler_) { } buffered_flush_handler(buffered_flush_handler&& other) : storage_(other.storage_), handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, const std::size_t bytes_written) { storage_.consume(bytes_written); handler_(ec, bytes_written); } //private: detail::buffered_stream_storage& storage_; WriteHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, buffered_flush_handler* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, buffered_flush_handler* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( buffered_flush_handler* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, buffered_flush_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, buffered_flush_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_buffered_flush { public: typedef typename remove_reference< Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_flush(Stream& next_layer) : next_layer_(next_layer) { } executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, buffered_stream_storage* storage) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; non_const_lvalue handler2(handler); async_write(next_layer_, buffer(storage->data(), storage->size()), buffered_flush_handler::type>( *storage, handler2.value)); } private: Stream& next_layer_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::buffered_flush_handler, Allocator> { typedef typename associated_allocator::type type; static type get(const detail::buffered_flush_handler& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::buffered_flush_handler, Executor> { typedef typename associated_executor::type type; static type get(const detail::buffered_flush_handler& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteHandler> ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) buffered_write_stream::async_flush( ASIO_MOVE_ARG(WriteHandler) handler) { return async_initiate( detail::initiate_async_buffered_flush(next_layer_), handler, &storage_); } template template std::size_t buffered_write_stream::write_some( const ConstBufferSequence& buffers) { using asio::buffer_size; if (buffer_size(buffers) == 0) return 0; if (storage_.size() == storage_.capacity()) this->flush(); return this->copy(buffers); } template template std::size_t buffered_write_stream::write_some( const ConstBufferSequence& buffers, asio::error_code& ec) { ec = asio::error_code(); using asio::buffer_size; if (buffer_size(buffers) == 0) return 0; if (storage_.size() == storage_.capacity() && !flush(ec)) return 0; return this->copy(buffers); } namespace detail { template class buffered_write_some_handler { public: buffered_write_some_handler(detail::buffered_stream_storage& storage, const ConstBufferSequence& buffers, WriteHandler& handler) : storage_(storage), buffers_(buffers), handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) buffered_write_some_handler(const buffered_write_some_handler& other) : storage_(other.storage_), buffers_(other.buffers_), handler_(other.handler_) { } buffered_write_some_handler(buffered_write_some_handler&& other) : storage_(other.storage_), buffers_(other.buffers_), handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t) { if (ec) { const std::size_t length = 0; handler_(ec, length); } else { using asio::buffer_size; std::size_t orig_size = storage_.size(); std::size_t space_avail = storage_.capacity() - orig_size; std::size_t bytes_avail = buffer_size(buffers_); std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail; storage_.resize(orig_size + length); const std::size_t bytes_copied = asio::buffer_copy( storage_.data() + orig_size, buffers_, length); handler_(ec, bytes_copied); } } //private: detail::buffered_stream_storage& storage_; ConstBufferSequence buffers_; WriteHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, buffered_write_some_handler< ConstBufferSequence, WriteHandler>* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, buffered_write_some_handler< ConstBufferSequence, WriteHandler>* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( buffered_write_some_handler< ConstBufferSequence, WriteHandler>* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, buffered_write_some_handler< ConstBufferSequence, WriteHandler>* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, buffered_write_some_handler< ConstBufferSequence, WriteHandler>* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_buffered_write_some { public: typedef typename remove_reference< Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_write_some(Stream& next_layer) : next_layer_(next_layer) { } executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, buffered_stream_storage* storage, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; using asio::buffer_size; non_const_lvalue handler2(handler); if (buffer_size(buffers) == 0 || storage->size() < storage->capacity()) { next_layer_.async_write_some(ASIO_CONST_BUFFER(0, 0), buffered_write_some_handler::type>( *storage, buffers, handler2.value)); } else { initiate_async_buffered_flush(this->next_layer_)( buffered_write_some_handler::type>( *storage, buffers, handler2.value), storage); } } private: Stream& next_layer_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::buffered_write_some_handler, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::buffered_write_some_handler< ConstBufferSequence, WriteHandler>& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::buffered_write_some_handler, Executor> { typedef typename associated_executor::type type; static type get( const detail::buffered_write_some_handler< ConstBufferSequence, WriteHandler>& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) buffered_write_stream::async_write_some( const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler) { return async_initiate( detail::initiate_async_buffered_write_some(next_layer_), handler, &storage_, buffers); } template template std::size_t buffered_write_stream::copy( const ConstBufferSequence& buffers) { using asio::buffer_size; std::size_t orig_size = storage_.size(); std::size_t space_avail = storage_.capacity() - orig_size; std::size_t bytes_avail = buffer_size(buffers); std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail; storage_.resize(orig_size + length); return asio::buffer_copy( storage_.data() + orig_size, buffers, length); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP ================================================ FILE: src/third_party/asio/impl/co_spawn.hpp ================================================ // // impl/co_spawn.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_CO_SPAWN_HPP #define ASIO_IMPL_CO_SPAWN_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/awaitable.hpp" #include "asio/dispatch.hpp" #include "asio/post.hpp" #include "asio/use_awaitable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template awaitable co_spawn_entry_point( awaitable*, Executor ex, F f, Handler handler) { auto spawn_work = make_work_guard(ex); auto handler_work = make_work_guard(handler, ex); (void) co_await (post)(spawn_work.get_executor(), use_awaitable_t{}); bool done = false; try { T t = co_await f(); done = true; (dispatch)(handler_work.get_executor(), [handler = std::move(handler), t = std::move(t)]() mutable { handler(std::exception_ptr(), std::move(t)); }); } catch (...) { if (done) throw; (dispatch)(handler_work.get_executor(), [handler = std::move(handler), e = std::current_exception()]() mutable { handler(e, T()); }); } } template awaitable co_spawn_entry_point( awaitable*, Executor ex, F f, Handler handler) { auto spawn_work = make_work_guard(ex); auto handler_work = make_work_guard(handler, ex); (void) co_await (post)(spawn_work.get_executor(), use_awaitable_t{}); std::exception_ptr e = nullptr; try { co_await f(); } catch (...) { e = std::current_exception(); } (dispatch)(handler_work.get_executor(), [handler = std::move(handler), e]() mutable { handler(e); }); } template class initiate_co_spawn { public: typedef Executor executor_type; template explicit initiate_co_spawn(const OtherExecutor& ex) : ex_(ex) { } executor_type get_executor() const ASIO_NOEXCEPT { return ex_; } template void operator()(Handler&& handler, F&& f) const { typedef typename result_of::type awaitable_type; auto a = (co_spawn_entry_point)(static_cast(nullptr), ex_, std::forward(f), std::forward(handler)); awaitable_handler(std::move(a), ex_).launch(); } private: Executor ex_; }; } // namespace detail template ::type>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, typename detail::awaitable_signature::type>::type) co_spawn(const Executor& ex, F&& f, CompletionToken&& token, typename enable_if< is_executor::value >::type*) { return async_initiate::type>>( detail::initiate_co_spawn< typename result_of::type::executor_type>(ex), token, std::forward(f)); } template ::type>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, typename detail::awaitable_signature::type>::type) co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token, typename enable_if< is_convertible::value >::type*) { return (co_spawn)(ctx.get_executor(), std::forward(f), std::forward(token)); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_CO_SPAWN_HPP ================================================ FILE: src/third_party/asio/impl/compose.hpp ================================================ // // impl/compose.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_COMPOSE_HPP #define ASIO_IMPL_COMPOSE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/executor_work_guard.hpp" #include "asio/is_executor.hpp" #include "asio/system_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template struct composed_io_executors; template <> struct composed_io_executors { composed_io_executors() ASIO_NOEXCEPT : head_(system_executor()) { } typedef system_executor head_type; system_executor head_; }; inline composed_io_executors make_composed_io_executors() { return composed_io_executors(); } template struct composed_io_executors { explicit composed_io_executors(const Head& ex) ASIO_NOEXCEPT : head_(ex) { } typedef Head head_type; Head head_; }; template inline composed_io_executors make_composed_io_executors(const Head& head) { return composed_io_executors(head); } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template struct composed_io_executors { explicit composed_io_executors(const Head& head, const Tail&... tail) ASIO_NOEXCEPT : head_(head), tail_(tail...) { } void reset() { head_.reset(); tail_.reset(); } typedef Head head_type; Head head_; composed_io_executors tail_; }; template inline composed_io_executors make_composed_io_executors(const Head& head, const Tail&... tail) { return composed_io_executors(head, tail...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) #define ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF(n) \ template \ struct composed_io_executors \ { \ explicit composed_io_executors(const Head& head, \ ASIO_VARIADIC_CONSTREF_PARAMS(n)) ASIO_NOEXCEPT \ : head_(head), \ tail_(ASIO_VARIADIC_BYVAL_ARGS(n)) \ { \ } \ \ void reset() \ { \ head_.reset(); \ tail_.reset(); \ } \ \ typedef Head head_type; \ Head head_; \ composed_io_executors tail_; \ }; \ \ template \ inline composed_io_executors \ make_composed_io_executors(const Head& head, \ ASIO_VARIADIC_CONSTREF_PARAMS(n)) \ { \ return composed_io_executors< \ void(Head, ASIO_VARIADIC_TARGS(n))>( \ head, ASIO_VARIADIC_BYVAL_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF) #undef ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) template struct composed_work; template <> struct composed_work { typedef composed_io_executors executors_type; composed_work(const executors_type&) ASIO_NOEXCEPT : head_(system_executor()) { } void reset() { head_.reset(); } typedef system_executor head_type; executor_work_guard head_; }; template struct composed_work { typedef composed_io_executors executors_type; explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT : head_(ex.head_) { } void reset() { head_.reset(); } typedef Head head_type; executor_work_guard head_; }; #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template struct composed_work { typedef composed_io_executors executors_type; explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT : head_(ex.head_), tail_(ex.tail_) { } void reset() { head_.reset(); tail_.reset(); } typedef Head head_type; executor_work_guard head_; composed_work tail_; }; #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) #define ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \ template \ struct composed_work \ { \ typedef composed_io_executors executors_type; \ \ explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT \ : head_(ex.head_), \ tail_(ex.tail_) \ { \ } \ \ void reset() \ { \ head_.reset(); \ tail_.reset(); \ } \ \ typedef Head head_type; \ executor_work_guard head_; \ composed_work tail_; \ }; \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_WORK_DEF) #undef ASIO_PRIVATE_COMPOSED_WORK_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template class composed_op; template class composed_op #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template class composed_op #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) { public: composed_op(ASIO_MOVE_ARG(Impl) impl, ASIO_MOVE_ARG(Work) work, ASIO_MOVE_ARG(Handler) handler) : impl_(ASIO_MOVE_CAST(Impl)(impl)), work_(ASIO_MOVE_CAST(Work)(work)), handler_(ASIO_MOVE_CAST(Handler)(handler)), invocations_(0) { } #if defined(ASIO_HAS_MOVE) composed_op(composed_op&& other) : impl_(ASIO_MOVE_CAST(Impl)(other.impl_)), work_(ASIO_MOVE_CAST(Work)(other.work_)), handler_(ASIO_MOVE_CAST(Handler)(other.handler_)), invocations_(other.invocations_) { } #endif // defined(ASIO_HAS_MOVE) typedef typename associated_executor::type executor_type; executor_type get_executor() const ASIO_NOEXCEPT { return (get_associated_executor)(handler_, work_.head_.get_executor()); } typedef typename associated_allocator >::type allocator_type; allocator_type get_allocator() const ASIO_NOEXCEPT { return (get_associated_allocator)(handler_, std::allocator()); } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()(ASIO_MOVE_ARG(T)... t) { if (invocations_ < ~unsigned(0)) ++invocations_; impl_(*this, ASIO_MOVE_CAST(T)(t)...); } void complete(Args... args) { this->work_.reset(); this->handler_(ASIO_MOVE_CAST(Args)(args)...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) void operator()() { if (invocations_ < ~unsigned(0)) ++invocations_; impl_(*this); } void complete() { this->work_.reset(); this->handler_(); } #define ASIO_PRIVATE_COMPOSED_OP_DEF(n) \ template \ void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ if (invocations_ < ~unsigned(0)) \ ++invocations_; \ impl_(*this, ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template \ void complete(ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ this->work_.reset(); \ this->handler_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_OP_DEF) #undef ASIO_PRIVATE_COMPOSED_OP_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) //private: Impl impl_; Work work_; Handler handler_; unsigned invocations_; }; template inline void* asio_handler_allocate(std::size_t size, composed_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, composed_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( composed_op* this_handler) { return this_handler->invocations_ > 1 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, composed_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, composed_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_composed_op { public: typedef typename composed_io_executors::head_type executor_type; template explicit initiate_composed_op(ASIO_MOVE_ARG(T) executors) : executors_(ASIO_MOVE_CAST(T)(executors)) { } executor_type get_executor() const ASIO_NOEXCEPT { return executors_.head_; } template void operator()(ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Impl) impl) const { composed_op::type, composed_work, typename decay::type, Signature>( ASIO_MOVE_CAST(Impl)(impl), composed_work(executors_), ASIO_MOVE_CAST(Handler)(handler))(); } private: composed_io_executors executors_; }; template inline initiate_composed_op make_initiate_composed_op( ASIO_MOVE_ARG(composed_io_executors) executors) { return initiate_composed_op( ASIO_MOVE_CAST(composed_io_executors)(executors)); } template inline typename IoObject::executor_type get_composed_io_executor(IoObject& io_object) { return io_object.get_executor(); } template inline const Executor& get_composed_io_executor(const Executor& ex, typename enable_if::value>::type* = 0) { return ex; } } // namespace detail #if !defined(GENERATING_DOCUMENTATION) #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) async_compose(ASIO_MOVE_ARG(Implementation) implementation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors) { return async_initiate( detail::make_initiate_composed_op( detail::make_composed_io_executors( detail::get_composed_io_executor( ASIO_MOVE_CAST(IoObjectsOrExecutors)( io_objects_or_executors))...)), token, ASIO_MOVE_CAST(Implementation)(implementation)); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) async_compose(ASIO_MOVE_ARG(Implementation) implementation, ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) { return async_initiate( detail::make_initiate_composed_op( detail::make_composed_io_executors()), token, ASIO_MOVE_CAST(Implementation)(implementation)); } # define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \ ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_##n # define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)) # define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)) # define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)) # define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)) # define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \ detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5)) #define ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \ template \ ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) \ async_compose(ASIO_MOVE_ARG(Implementation) implementation, \ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ return async_initiate( \ detail::make_initiate_composed_op( \ detail::make_composed_io_executors( \ ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \ token, ASIO_MOVE_CAST(Implementation)(implementation)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_COMPOSE_DEF) #undef ASIO_PRIVATE_ASYNC_COMPOSE_DEF #undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR #undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 #undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 #undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 #undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 #undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_COMPOSE_HPP ================================================ FILE: src/third_party/asio/impl/connect.hpp ================================================ // // impl/connect.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_CONNECT_HPP #define ASIO_IMPL_CONNECT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/post.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { struct default_connect_condition { template bool operator()(const asio::error_code&, const Endpoint&) { return true; } }; template inline typename Protocol::endpoint deref_connect_result( Iterator iter, asio::error_code& ec) { return ec ? typename Protocol::endpoint() : *iter; } template struct legacy_connect_condition_helper : T { typedef char (*fallback_func_type)(...); operator fallback_func_type() const; }; template struct legacy_connect_condition_helper { R operator()(Arg1, Arg2) const; char operator()(...) const; }; template struct is_legacy_connect_condition { static char asio_connect_condition_check(char); static char (&asio_connect_condition_check(Iterator))[2]; static const bool value = sizeof(asio_connect_condition_check( (*static_cast*>(0))( *static_cast(0), *static_cast(0)))) != 1; }; template inline Iterator call_connect_condition(ConnectCondition& connect_condition, const asio::error_code& ec, Iterator next, Iterator end, typename enable_if::value>::type* = 0) { if (next != end) return connect_condition(ec, next); return end; } template inline Iterator call_connect_condition(ConnectCondition& connect_condition, const asio::error_code& ec, Iterator next, Iterator end, typename enable_if::value>::type* = 0) { for (;next != end; ++next) if (connect_condition(ec, *next)) return next; return end; } } template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, typename enable_if::value>::type*) { asio::error_code ec; typename Protocol::endpoint result = connect(s, endpoints, ec); asio::detail::throw_error(ec, "connect"); return result; } template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, asio::error_code& ec, typename enable_if::value>::type*) { return detail::deref_connect_result( connect(s, endpoints.begin(), endpoints.end(), detail::default_connect_condition(), ec), ec); } #if !defined(ASIO_NO_DEPRECATED) template Iterator connect(basic_socket& s, Iterator begin, typename enable_if::value>::type*) { asio::error_code ec; Iterator result = connect(s, begin, ec); asio::detail::throw_error(ec, "connect"); return result; } template inline Iterator connect(basic_socket& s, Iterator begin, asio::error_code& ec, typename enable_if::value>::type*) { return connect(s, begin, Iterator(), detail::default_connect_condition(), ec); } #endif // !defined(ASIO_NO_DEPRECATED) template Iterator connect(basic_socket& s, Iterator begin, Iterator end) { asio::error_code ec; Iterator result = connect(s, begin, end, ec); asio::detail::throw_error(ec, "connect"); return result; } template inline Iterator connect(basic_socket& s, Iterator begin, Iterator end, asio::error_code& ec) { return connect(s, begin, end, detail::default_connect_condition(), ec); } template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, typename enable_if::value>::type*) { asio::error_code ec; typename Protocol::endpoint result = connect( s, endpoints, connect_condition, ec); asio::detail::throw_error(ec, "connect"); return result; } template typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, asio::error_code& ec, typename enable_if::value>::type*) { return detail::deref_connect_result( connect(s, endpoints.begin(), endpoints.end(), connect_condition, ec), ec); } #if !defined(ASIO_NO_DEPRECATED) template Iterator connect(basic_socket& s, Iterator begin, ConnectCondition connect_condition, typename enable_if::value>::type*) { asio::error_code ec; Iterator result = connect(s, begin, connect_condition, ec); asio::detail::throw_error(ec, "connect"); return result; } template inline Iterator connect(basic_socket& s, Iterator begin, ConnectCondition connect_condition, asio::error_code& ec, typename enable_if::value>::type*) { return connect(s, begin, Iterator(), connect_condition, ec); } #endif // !defined(ASIO_NO_DEPRECATED) template Iterator connect(basic_socket& s, Iterator begin, Iterator end, ConnectCondition connect_condition) { asio::error_code ec; Iterator result = connect(s, begin, end, connect_condition, ec); asio::detail::throw_error(ec, "connect"); return result; } template Iterator connect(basic_socket& s, Iterator begin, Iterator end, ConnectCondition connect_condition, asio::error_code& ec) { ec = asio::error_code(); for (Iterator iter = begin; iter != end; ++iter) { iter = (detail::call_connect_condition(connect_condition, ec, iter, end)); if (iter != end) { s.close(ec); s.connect(*iter, ec); if (!ec) return iter; } else break; } if (!ec) ec = asio::error::not_found; return end; } namespace detail { // Enable the empty base class optimisation for the connect condition. template class base_from_connect_condition { protected: explicit base_from_connect_condition( const ConnectCondition& connect_condition) : connect_condition_(connect_condition) { } template void check_condition(const asio::error_code& ec, Iterator& iter, Iterator& end) { iter = detail::call_connect_condition(connect_condition_, ec, iter, end); } private: ConnectCondition connect_condition_; }; // The default_connect_condition implementation is essentially a no-op. This // template specialisation lets us eliminate all costs associated with it. template <> class base_from_connect_condition { protected: explicit base_from_connect_condition(const default_connect_condition&) { } template void check_condition(const asio::error_code&, Iterator&, Iterator&) { } }; template class range_connect_op : base_from_connect_condition { public: range_connect_op(basic_socket& sock, const EndpointSequence& endpoints, const ConnectCondition& connect_condition, RangeConnectHandler& handler) : base_from_connect_condition(connect_condition), socket_(sock), endpoints_(endpoints), index_(0), start_(0), handler_(ASIO_MOVE_CAST(RangeConnectHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) range_connect_op(const range_connect_op& other) : base_from_connect_condition(other), socket_(other.socket_), endpoints_(other.endpoints_), index_(other.index_), start_(other.start_), handler_(other.handler_) { } range_connect_op(range_connect_op&& other) : base_from_connect_condition(other), socket_(other.socket_), endpoints_(other.endpoints_), index_(other.index_), start_(other.start_), handler_(ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, int start = 0) { this->process(ec, start, const_cast(endpoints_).begin(), const_cast(endpoints_).end()); } //private: template void process(asio::error_code ec, int start, Iterator begin, Iterator end) { Iterator iter = begin; std::advance(iter, index_); switch (start_ = start) { case 1: for (;;) { this->check_condition(ec, iter, end); index_ = std::distance(begin, iter); if (iter != end) { socket_.close(ec); socket_.async_connect(*iter, ASIO_MOVE_CAST(range_connect_op)(*this)); return; } if (start) { ec = asio::error::not_found; asio::post(socket_.get_executor(), detail::bind_handler( ASIO_MOVE_CAST(range_connect_op)(*this), ec)); return; } /* fall-through */ default: if (iter == end) break; if (!socket_.is_open()) { ec = asio::error::operation_aborted; break; } if (!ec) break; ++iter; ++index_; } handler_(static_cast(ec), static_cast( ec || iter == end ? typename Protocol::endpoint() : *iter)); } } basic_socket& socket_; EndpointSequence endpoints_; std::size_t index_; int start_; RangeConnectHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, range_connect_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, range_connect_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( range_connect_op* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, range_connect_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, range_connect_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_range_connect { public: typedef Executor executor_type; explicit initiate_async_range_connect(basic_socket& s) : socket_(s) { } executor_type get_executor() const ASIO_NOEXCEPT { return socket_.get_executor(); } template void operator()(ASIO_MOVE_ARG(RangeConnectHandler) handler, const EndpointSequence& endpoints, const ConnectCondition& connect_condition) const { // If you get an error on the following line it means that your // handler does not meet the documented type requirements for an // RangeConnectHandler. ASIO_RANGE_CONNECT_HANDLER_CHECK(RangeConnectHandler, handler, typename Protocol::endpoint) type_check; non_const_lvalue handler2(handler); range_connect_op::type>(socket_, endpoints, connect_condition, handler2.value)(asio::error_code(), 1); } private: basic_socket& socket_; }; template class iterator_connect_op : base_from_connect_condition { public: iterator_connect_op(basic_socket& sock, const Iterator& begin, const Iterator& end, const ConnectCondition& connect_condition, IteratorConnectHandler& handler) : base_from_connect_condition(connect_condition), socket_(sock), iter_(begin), end_(end), start_(0), handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) iterator_connect_op(const iterator_connect_op& other) : base_from_connect_condition(other), socket_(other.socket_), iter_(other.iter_), end_(other.end_), start_(other.start_), handler_(other.handler_) { } iterator_connect_op(iterator_connect_op&& other) : base_from_connect_condition(other), socket_(other.socket_), iter_(other.iter_), end_(other.end_), start_(other.start_), handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, int start = 0) { switch (start_ = start) { case 1: for (;;) { this->check_condition(ec, iter_, end_); if (iter_ != end_) { socket_.close(ec); socket_.async_connect(*iter_, ASIO_MOVE_CAST(iterator_connect_op)(*this)); return; } if (start) { ec = asio::error::not_found; asio::post(socket_.get_executor(), detail::bind_handler( ASIO_MOVE_CAST(iterator_connect_op)(*this), ec)); return; } /* fall-through */ default: if (iter_ == end_) break; if (!socket_.is_open()) { ec = asio::error::operation_aborted; break; } if (!ec) break; ++iter_; } handler_(static_cast(ec), static_cast(iter_)); } } //private: basic_socket& socket_; Iterator iter_; Iterator end_; int start_; IteratorConnectHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, iterator_connect_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, iterator_connect_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( iterator_connect_op* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, iterator_connect_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, iterator_connect_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_iterator_connect { public: typedef Executor executor_type; explicit initiate_async_iterator_connect( basic_socket& s) : socket_(s) { } executor_type get_executor() const ASIO_NOEXCEPT { return socket_.get_executor(); } template void operator()(ASIO_MOVE_ARG(IteratorConnectHandler) handler, Iterator begin, Iterator end, const ConnectCondition& connect_condition) const { // If you get an error on the following line it means that your // handler does not meet the documented type requirements for an // IteratorConnectHandler. ASIO_ITERATOR_CONNECT_HANDLER_CHECK( IteratorConnectHandler, handler, Iterator) type_check; non_const_lvalue handler2(handler); iterator_connect_op::type>(socket_, begin, end, connect_condition, handler2.value)(asio::error_code(), 1); } private: basic_socket& socket_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::range_connect_op, Allocator> { typedef typename associated_allocator< RangeConnectHandler, Allocator>::type type; static type get( const detail::range_connect_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::range_connect_op, Executor1> { typedef typename associated_executor< RangeConnectHandler, Executor1>::type type; static type get( const detail::range_connect_op& h, const Executor1& ex = Executor1()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; template struct associated_allocator< detail::iterator_connect_op, Allocator> { typedef typename associated_allocator< IteratorConnectHandler, Allocator>::type type; static type get( const detail::iterator_connect_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::iterator_connect_op, Executor1> { typedef typename associated_executor< IteratorConnectHandler, Executor1>::type type; static type get( const detail::iterator_connect_op& h, const Executor1& ex = Executor1()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler, void (asio::error_code, typename Protocol::endpoint)) async_connect(basic_socket& s, const EndpointSequence& endpoints, ASIO_MOVE_ARG(RangeConnectHandler) handler, typename enable_if::value>::type*) { return async_initiate( detail::initiate_async_range_connect(s), handler, endpoints, detail::default_connect_condition()); } #if !defined(ASIO_NO_DEPRECATED) template inline ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, ASIO_MOVE_ARG(IteratorConnectHandler) handler, typename enable_if::value>::type*) { return async_initiate( detail::initiate_async_iterator_connect(s), handler, begin, Iterator(), detail::default_connect_condition()); } #endif // !defined(ASIO_NO_DEPRECATED) template inline ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, Iterator end, ASIO_MOVE_ARG(IteratorConnectHandler) handler) { return async_initiate( detail::initiate_async_iterator_connect(s), handler, begin, end, detail::default_connect_condition()); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler, void (asio::error_code, typename Protocol::endpoint)) async_connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, ASIO_MOVE_ARG(RangeConnectHandler) handler, typename enable_if::value>::type*) { return async_initiate( detail::initiate_async_range_connect(s), handler, endpoints, connect_condition); } #if !defined(ASIO_NO_DEPRECATED) template inline ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, ConnectCondition connect_condition, ASIO_MOVE_ARG(IteratorConnectHandler) handler, typename enable_if::value>::type*) { return async_initiate( detail::initiate_async_iterator_connect(s), handler, begin, Iterator(), connect_condition); } #endif // !defined(ASIO_NO_DEPRECATED) template inline ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler, void (asio::error_code, Iterator)) async_connect(basic_socket& s, Iterator begin, Iterator end, ConnectCondition connect_condition, ASIO_MOVE_ARG(IteratorConnectHandler) handler) { return async_initiate( detail::initiate_async_iterator_connect(s), handler, begin, end, connect_condition); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_CONNECT_HPP ================================================ FILE: src/third_party/asio/impl/defer.hpp ================================================ // // impl/defer.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_DEFER_HPP #define ASIO_IMPL_DEFER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/work_dispatcher.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class initiate_defer { public: template void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const { typedef typename decay::type DecayedHandler; typename associated_executor::type ex( (get_associated_executor)(handler)); typename associated_allocator::type alloc( (get_associated_allocator)(handler)); ex.defer(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); } }; template class initiate_defer_with_executor { public: typedef Executor executor_type; explicit initiate_defer_with_executor(const Executor& ex) : ex_(ex) { } executor_type get_executor() const ASIO_NOEXCEPT { return ex_; } template void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const { typedef typename decay::type DecayedHandler; typename associated_allocator::type alloc( (get_associated_allocator)(handler)); ex_.defer(detail::work_dispatcher( ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } private: Executor ex_; }; } // namespace detail template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer( ASIO_MOVE_ARG(CompletionToken) token) { return async_initiate( detail::initiate_defer(), token); } template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer( const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, typename enable_if::value>::type*) { return async_initiate( detail::initiate_defer_with_executor(ex), token); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer( ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, typename enable_if::value>::type*) { return (defer)(ctx.get_executor(), ASIO_MOVE_CAST(CompletionToken)(token)); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_DEFER_HPP ================================================ FILE: src/third_party/asio/impl/detached.hpp ================================================ // // impl/detached.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_DETACHED_HPP #define ASIO_IMPL_DETACHED_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Class to adapt a detached_t as a completion handler. class detached_handler { public: typedef void result_type; detached_handler(detached_t) { } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()(Args...) { } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) void operator()() { } #define ASIO_PRIVATE_DETACHED_DEF(n) \ template \ void operator()(ASIO_VARIADIC_TARGS(n)) \ { \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_DETACHED_DEF) #undef ASIO_PRIVATE_DETACHED_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct async_result { typedef asio::detail::detached_handler completion_handler_type; typedef void return_type; explicit async_result(completion_handler_type&) { } void get() { } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template static return_type initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken), ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_CAST(Initiation)(initiation)( detail::detached_handler(detached_t()), ASIO_MOVE_CAST(Args)(args)...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template static return_type initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken)) { ASIO_MOVE_CAST(Initiation)(initiation)( detail::detached_handler(detached_t())); } #define ASIO_PRIVATE_INITIATE_DEF(n) \ template \ static return_type initiate( \ ASIO_MOVE_ARG(Initiation) initiation, \ ASIO_MOVE_ARG(RawCompletionToken), \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ ASIO_MOVE_CAST(Initiation)(initiation)( \ detail::detached_handler(detached_t()), \ ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF) #undef ASIO_PRIVATE_INITIATE_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_DETACHED_HPP ================================================ FILE: src/third_party/asio/impl/dispatch.hpp ================================================ // // impl/dispatch.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_DISPATCH_HPP #define ASIO_IMPL_DISPATCH_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/work_dispatcher.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class initiate_dispatch { public: template void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const { typedef typename decay::type DecayedHandler; typename associated_executor::type ex( (get_associated_executor)(handler)); typename associated_allocator::type alloc( (get_associated_allocator)(handler)); ex.dispatch(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); } }; template class initiate_dispatch_with_executor { public: typedef Executor executor_type; explicit initiate_dispatch_with_executor(const Executor& ex) : ex_(ex) { } executor_type get_executor() const ASIO_NOEXCEPT { return ex_; } template void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const { typedef typename decay::type DecayedHandler; typename associated_allocator::type alloc( (get_associated_allocator)(handler)); ex_.dispatch(detail::work_dispatcher( ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } private: Executor ex_; }; } // namespace detail template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( ASIO_MOVE_ARG(CompletionToken) token) { return async_initiate( detail::initiate_dispatch(), token); } template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, typename enable_if::value>::type*) { return async_initiate( detail::initiate_dispatch_with_executor(ex), token); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, typename enable_if::value>::type*) { return (dispatch)(ctx.get_executor(), ASIO_MOVE_CAST(CompletionToken)(token)); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_DISPATCH_HPP ================================================ FILE: src/third_party/asio/impl/error.ipp ================================================ // // impl/error.ipp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_ERROR_IPP #define ASIO_IMPL_ERROR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace error { #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) namespace detail { class netdb_category : public asio::error_category { public: const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.netdb"; } std::string message(int value) const { if (value == error::host_not_found) return "Host not found (authoritative)"; if (value == error::host_not_found_try_again) return "Host not found (non-authoritative), try again later"; if (value == error::no_data) return "The query is valid, but it does not have associated data"; if (value == error::no_recovery) return "A non-recoverable error occurred during database lookup"; return "asio.netdb error"; } }; } // namespace detail const asio::error_category& get_netdb_category() { static detail::netdb_category instance; return instance; } namespace detail { class addrinfo_category : public asio::error_category { public: const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.addrinfo"; } std::string message(int value) const { if (value == error::service_not_found) return "Service not found"; if (value == error::socket_type_not_supported) return "Socket type not supported"; return "asio.addrinfo error"; } }; } // namespace detail const asio::error_category& get_addrinfo_category() { static detail::addrinfo_category instance; return instance; } #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) namespace detail { class misc_category : public asio::error_category { public: const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.misc"; } std::string message(int value) const { if (value == error::already_open) return "Already open"; if (value == error::eof) return "End of file"; if (value == error::not_found) return "Element not found"; if (value == error::fd_set_failure) return "The descriptor does not fit into the select call's fd_set"; return "asio.misc error"; } }; } // namespace detail const asio::error_category& get_misc_category() { static detail::misc_category instance; return instance; } } // namespace error } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_ERROR_IPP ================================================ FILE: src/third_party/asio/impl/error_code.ipp ================================================ // // impl/error_code.ipp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_ERROR_CODE_IPP #define ASIO_IMPL_ERROR_CODE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # include #elif defined(ASIO_WINDOWS_RUNTIME) # include #else # include # include # include #endif #include "asio/detail/local_free_on_block_exit.hpp" #include "asio/detail/socket_types.hpp" #include "asio/error_code.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class system_category : public error_category { public: const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.system"; } std::string message(int value) const { #if defined(ASIO_WINDOWS_RUNTIME) || defined(ASIO_WINDOWS_APP) std::wstring wmsg(128, wchar_t()); for (;;) { DWORD wlength = ::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, value, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wmsg[0], static_cast(wmsg.size()), 0); if (wlength == 0 && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { wmsg.resize(wmsg.size() + wmsg.size() / 2); continue; } if (wlength && wmsg[wlength - 1] == '\n') --wlength; if (wlength && wmsg[wlength - 1] == '\r') --wlength; if (wlength) { std::string msg(wlength * 2, char()); int length = ::WideCharToMultiByte(CP_ACP, 0, wmsg.c_str(), static_cast(wlength), &msg[0], static_cast(wlength * 2), 0, 0); if (length <= 0) return "asio.system error"; msg.resize(static_cast(length)); return msg; } else return "asio.system error"; } #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) char* msg = 0; DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, value, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); detail::local_free_on_block_exit local_free_obj(msg); if (length && msg[length - 1] == '\n') msg[--length] = '\0'; if (length && msg[length - 1] == '\r') msg[--length] = '\0'; if (length) return msg; else return "asio.system error"; #else // defined(ASIO_WINDOWS_DESKTOP) || defined(__CYGWIN__) #if !defined(__sun) if (value == ECANCELED) return "Operation aborted."; #endif // !defined(__sun) #if defined(__sun) || defined(__QNX__) || defined(__SYMBIAN32__) using namespace std; return strerror(value); #else char buf[256] = ""; using namespace std; return strerror_result(strerror_r(value, buf, sizeof(buf)), buf); #endif #endif // defined(ASIO_WINDOWS_DESKTOP) || defined(__CYGWIN__) } #if defined(ASIO_HAS_STD_ERROR_CODE) std::error_condition default_error_condition( int ev) const ASIO_ERROR_CATEGORY_NOEXCEPT { switch (ev) { case access_denied: return std::errc::permission_denied; case address_family_not_supported: return std::errc::address_family_not_supported; case address_in_use: return std::errc::address_in_use; case already_connected: return std::errc::already_connected; case already_started: return std::errc::connection_already_in_progress; case broken_pipe: return std::errc::broken_pipe; case connection_aborted: return std::errc::connection_aborted; case connection_refused: return std::errc::connection_refused; case connection_reset: return std::errc::connection_reset; case bad_descriptor: return std::errc::bad_file_descriptor; case fault: return std::errc::bad_address; case host_unreachable: return std::errc::host_unreachable; case in_progress: return std::errc::operation_in_progress; case interrupted: return std::errc::interrupted; case invalid_argument: return std::errc::invalid_argument; case message_size: return std::errc::message_size; case name_too_long: return std::errc::filename_too_long; case network_down: return std::errc::network_down; case network_reset: return std::errc::network_reset; case network_unreachable: return std::errc::network_unreachable; case no_descriptors: return std::errc::too_many_files_open; case no_buffer_space: return std::errc::no_buffer_space; case no_memory: return std::errc::not_enough_memory; case no_permission: return std::errc::operation_not_permitted; case no_protocol_option: return std::errc::no_protocol_option; case no_such_device: return std::errc::no_such_device; case not_connected: return std::errc::not_connected; case not_socket: return std::errc::not_a_socket; case operation_aborted: return std::errc::operation_canceled; case operation_not_supported: return std::errc::operation_not_supported; case shut_down: return std::make_error_condition(ev, *this); case timed_out: return std::errc::timed_out; case try_again: return std::errc::resource_unavailable_try_again; case would_block: return std::errc::operation_would_block; default: return std::make_error_condition(ev, *this); } #endif // defined(ASIO_HAS_STD_ERROR_CODE) private: // Helper function to adapt the result from glibc's variant of strerror_r. static const char* strerror_result(int, const char* s) { return s; } static const char* strerror_result(const char* s, const char*) { return s; } }; } // namespace detail const error_category& system_category() { static detail::system_category instance; return instance; } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_ERROR_CODE_IPP ================================================ FILE: src/third_party/asio/impl/execution_context.hpp ================================================ // // impl/execution_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_EXECUTION_CONTEXT_HPP #define ASIO_IMPL_EXECUTION_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/service_registry.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if !defined(GENERATING_DOCUMENTATION) template inline Service& use_service(execution_context& e) { // Check that Service meets the necessary type requirements. (void)static_cast(static_cast(0)); return e.service_registry_->template use_service(); } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template Service& make_service(execution_context& e, ASIO_MOVE_ARG(Args)... args) { detail::scoped_ptr svc( new Service(e, ASIO_MOVE_CAST(Args)(args)...)); e.service_registry_->template add_service(svc.get()); Service& result = *svc; svc.release(); return result; } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template Service& make_service(execution_context& e) { detail::scoped_ptr svc(new Service(e)); e.service_registry_->template add_service(svc.get()); Service& result = *svc; svc.release(); return result; } #define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \ template \ Service& make_service(execution_context& e, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ detail::scoped_ptr svc( \ new Service(e, ASIO_VARIADIC_MOVE_ARGS(n))); \ e.service_registry_->template add_service(svc.get()); \ Service& result = *svc; \ svc.release(); \ return result; \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF) #undef ASIO_PRIVATE_MAKE_SERVICE_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) template inline void add_service(execution_context& e, Service* svc) { // Check that Service meets the necessary type requirements. (void)static_cast(static_cast(0)); e.service_registry_->template add_service(svc); } template inline bool has_service(execution_context& e) { // Check that Service meets the necessary type requirements. (void)static_cast(static_cast(0)); return e.service_registry_->template has_service(); } #endif // !defined(GENERATING_DOCUMENTATION) inline execution_context& execution_context::service::context() { return owner_; } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_EXECUTION_CONTEXT_HPP ================================================ FILE: src/third_party/asio/impl/execution_context.ipp ================================================ // // impl/execution_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_EXECUTION_CONTEXT_IPP #define ASIO_IMPL_EXECUTION_CONTEXT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/execution_context.hpp" #include "asio/detail/service_registry.hpp" #include "asio/detail/push_options.hpp" namespace asio { execution_context::execution_context() : service_registry_(new asio::detail::service_registry(*this)) { } execution_context::~execution_context() { shutdown(); destroy(); delete service_registry_; } void execution_context::shutdown() { service_registry_->shutdown_services(); } void execution_context::destroy() { service_registry_->destroy_services(); } void execution_context::notify_fork( asio::execution_context::fork_event event) { service_registry_->notify_fork(event); } execution_context::service::service(execution_context& owner) : owner_(owner), next_(0) { } execution_context::service::~service() { } void execution_context::service::notify_fork(execution_context::fork_event) { } service_already_exists::service_already_exists() : std::logic_error("Service already exists.") { } invalid_service_owner::invalid_service_owner() : std::logic_error("Invalid service owner.") { } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_EXECUTION_CONTEXT_IPP ================================================ FILE: src/third_party/asio/impl/executor.hpp ================================================ // // impl/executor.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_EXECUTOR_HPP #define ASIO_IMPL_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/atomic_count.hpp" #include "asio/detail/executor_function.hpp" #include "asio/detail/global.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/executor.hpp" #include "asio/system_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if !defined(GENERATING_DOCUMENTATION) #if defined(ASIO_HAS_MOVE) // Lightweight, move-only function object wrapper. class executor::function { public: template explicit function(F f, const Alloc& a) { // Allocate and construct an operation to wrap the function. typedef detail::executor_function func_type; typename func_type::ptr p = { detail::addressof(a), func_type::ptr::allocate(a), 0 }; func_ = new (p.v) func_type(ASIO_MOVE_CAST(F)(f), a); p.v = 0; } function(function&& other) ASIO_NOEXCEPT : func_(other.func_) { other.func_ = 0; } ~function() { if (func_) func_->destroy(); } void operator()() { if (func_) { detail::executor_function_base* func = func_; func_ = 0; func->complete(); } } private: detail::executor_function_base* func_; }; #else // defined(ASIO_HAS_MOVE) // Not so lightweight, copyable function object wrapper. class executor::function { public: template explicit function(const F& f, const Alloc&) : impl_(new impl(f)) { } void operator()() { impl_->invoke_(impl_.get()); } private: // Base class for polymorphic function implementations. struct impl_base { void (*invoke_)(impl_base*); }; // Polymorphic function implementation. template struct impl : impl_base { impl(const F& f) : function_(f) { invoke_ = &function::invoke; } F function_; }; // Helper to invoke a function. template static void invoke(impl_base* i) { static_cast*>(i)->function_(); } detail::shared_ptr impl_; }; #endif // defined(ASIO_HAS_MOVE) // Default polymorphic allocator implementation. template class executor::impl : public executor::impl_base { public: typedef ASIO_REBIND_ALLOC(Allocator, impl) allocator_type; static impl_base* create(const Executor& e, Allocator a = Allocator()) { raw_mem mem(a); impl* p = new (mem.ptr_) impl(e, a); mem.ptr_ = 0; return p; } impl(const Executor& e, const Allocator& a) ASIO_NOEXCEPT : impl_base(false), ref_count_(1), executor_(e), allocator_(a) { } impl_base* clone() const ASIO_NOEXCEPT { ++ref_count_; return const_cast(static_cast(this)); } void destroy() ASIO_NOEXCEPT { if (--ref_count_ == 0) { allocator_type alloc(allocator_); impl* p = this; p->~impl(); alloc.deallocate(p, 1); } } void on_work_started() ASIO_NOEXCEPT { executor_.on_work_started(); } void on_work_finished() ASIO_NOEXCEPT { executor_.on_work_finished(); } execution_context& context() ASIO_NOEXCEPT { return executor_.context(); } void dispatch(ASIO_MOVE_ARG(function) f) { executor_.dispatch(ASIO_MOVE_CAST(function)(f), allocator_); } void post(ASIO_MOVE_ARG(function) f) { executor_.post(ASIO_MOVE_CAST(function)(f), allocator_); } void defer(ASIO_MOVE_ARG(function) f) { executor_.defer(ASIO_MOVE_CAST(function)(f), allocator_); } type_id_result_type target_type() const ASIO_NOEXCEPT { return type_id(); } void* target() ASIO_NOEXCEPT { return &executor_; } const void* target() const ASIO_NOEXCEPT { return &executor_; } bool equals(const impl_base* e) const ASIO_NOEXCEPT { if (this == e) return true; if (target_type() != e->target_type()) return false; return executor_ == *static_cast(e->target()); } private: mutable detail::atomic_count ref_count_; Executor executor_; Allocator allocator_; struct raw_mem { allocator_type allocator_; impl* ptr_; explicit raw_mem(const Allocator& a) : allocator_(a), ptr_(allocator_.allocate(1)) { } ~raw_mem() { if (ptr_) allocator_.deallocate(ptr_, 1); } private: // Disallow copying and assignment. raw_mem(const raw_mem&); raw_mem operator=(const raw_mem&); }; }; // Polymorphic allocator specialisation for system_executor. template class executor::impl : public executor::impl_base { public: static impl_base* create(const system_executor&, const Allocator& = Allocator()) { return &detail::global > >(); } impl() : impl_base(true) { } impl_base* clone() const ASIO_NOEXCEPT { return const_cast(static_cast(this)); } void destroy() ASIO_NOEXCEPT { } void on_work_started() ASIO_NOEXCEPT { executor_.on_work_started(); } void on_work_finished() ASIO_NOEXCEPT { executor_.on_work_finished(); } execution_context& context() ASIO_NOEXCEPT { return executor_.context(); } void dispatch(ASIO_MOVE_ARG(function) f) { executor_.dispatch(ASIO_MOVE_CAST(function)(f), allocator_); } void post(ASIO_MOVE_ARG(function) f) { executor_.post(ASIO_MOVE_CAST(function)(f), allocator_); } void defer(ASIO_MOVE_ARG(function) f) { executor_.defer(ASIO_MOVE_CAST(function)(f), allocator_); } type_id_result_type target_type() const ASIO_NOEXCEPT { return type_id(); } void* target() ASIO_NOEXCEPT { return &executor_; } const void* target() const ASIO_NOEXCEPT { return &executor_; } bool equals(const impl_base* e) const ASIO_NOEXCEPT { return this == e; } private: system_executor executor_; Allocator allocator_; }; template executor::executor(Executor e) : impl_(impl >::create(e)) { } template executor::executor(allocator_arg_t, const Allocator& a, Executor e) : impl_(impl::create(e, a)) { } template void executor::dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { impl_base* i = get_impl(); if (i->fast_dispatch_) system_executor().dispatch(ASIO_MOVE_CAST(Function)(f), a); else i->dispatch(function(ASIO_MOVE_CAST(Function)(f), a)); } template void executor::post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { get_impl()->post(function(ASIO_MOVE_CAST(Function)(f), a)); } template void executor::defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { get_impl()->defer(function(ASIO_MOVE_CAST(Function)(f), a)); } template Executor* executor::target() ASIO_NOEXCEPT { return impl_ && impl_->target_type() == type_id() ? static_cast(impl_->target()) : 0; } template const Executor* executor::target() const ASIO_NOEXCEPT { return impl_ && impl_->target_type() == type_id() ? static_cast(impl_->target()) : 0; } #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/impl/executor.ipp ================================================ // // impl/executor.ipp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_EXECUTOR_IPP #define ASIO_IMPL_EXECUTOR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { bad_executor::bad_executor() ASIO_NOEXCEPT { } const char* bad_executor::what() const ASIO_NOEXCEPT_OR_NOTHROW { return "bad executor"; } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_EXECUTOR_IPP ================================================ FILE: src/third_party/asio/impl/handler_alloc_hook.ipp ================================================ // // impl/handler_alloc_hook.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP #define ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/thread_context.hpp" #include "asio/detail/thread_info_base.hpp" #include "asio/handler_alloc_hook.hpp" #include "asio/detail/push_options.hpp" namespace asio { void* asio_handler_allocate(std::size_t size, ...) { #if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) return detail::thread_info_base::allocate( detail::thread_context::thread_call_stack::top(), size); #else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) return ::operator new(size); #endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) } void asio_handler_deallocate(void* pointer, std::size_t size, ...) { #if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) detail::thread_info_base::deallocate( detail::thread_context::thread_call_stack::top(), pointer, size); #else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) (void)size; ::operator delete(pointer); #endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP ================================================ FILE: src/third_party/asio/impl/io_context.hpp ================================================ // // impl/io_context.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_IO_CONTEXT_HPP #define ASIO_IMPL_IO_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/completion_handler.hpp" #include "asio/detail/executor_op.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/detail/service_registry.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" #if !defined(GENERATING_DOCUMENTATION) namespace asio { template inline Service& use_service(io_context& ioc) { // Check that Service meets the necessary type requirements. (void)static_cast(static_cast(0)); (void)static_cast(&Service::id); return ioc.service_registry_->template use_service(ioc); } template <> inline detail::io_context_impl& use_service( io_context& ioc) { return ioc.impl_; } } // namespace asio #endif // !defined(GENERATING_DOCUMENTATION) #include "asio/detail/pop_options.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else # include "asio/detail/scheduler.hpp" #endif #include "asio/detail/push_options.hpp" namespace asio { inline io_context::executor_type io_context::get_executor() ASIO_NOEXCEPT { return executor_type(*this); } #if defined(ASIO_HAS_CHRONO) template std::size_t io_context::run_for( const chrono::duration& rel_time) { return this->run_until(chrono::steady_clock::now() + rel_time); } template std::size_t io_context::run_until( const chrono::time_point& abs_time) { std::size_t n = 0; while (this->run_one_until(abs_time)) if (n != (std::numeric_limits::max)()) ++n; return n; } template std::size_t io_context::run_one_for( const chrono::duration& rel_time) { return this->run_one_until(chrono::steady_clock::now() + rel_time); } template std::size_t io_context::run_one_until( const chrono::time_point& abs_time) { typename Clock::time_point now = Clock::now(); while (now < abs_time) { typename Clock::duration rel_time = abs_time - now; if (rel_time > chrono::seconds(1)) rel_time = chrono::seconds(1); asio::error_code ec; std::size_t s = impl_.wait_one( static_cast(chrono::duration_cast< chrono::microseconds>(rel_time).count()), ec); asio::detail::throw_error(ec); if (s || impl_.stopped()) return s; now = Clock::now(); } return 0; } #endif // defined(ASIO_HAS_CHRONO) #if !defined(ASIO_NO_DEPRECATED) inline void io_context::reset() { restart(); } struct io_context::initiate_dispatch { template void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler, io_context* self) const { // If you get an error on the following line it means that your handler does // not meet the documented type requirements for a LegacyCompletionHandler. ASIO_LEGACY_COMPLETION_HANDLER_CHECK( LegacyCompletionHandler, handler) type_check; detail::non_const_lvalue handler2(handler); if (self->impl_.can_dispatch()) { detail::fenced_block b(detail::fenced_block::full); asio_handler_invoke_helpers::invoke( handler2.value, handler2.value); } else { // Allocate and construct an operation to wrap the handler. typedef detail::completion_handler< typename decay::type> op; typename op::ptr p = { detail::addressof(handler2.value), op::ptr::allocate(handler2.value), 0 }; p.p = new (p.v) op(handler2.value); ASIO_HANDLER_CREATION((*self, *p.p, "io_context", self, 0, "dispatch")); self->impl_.do_dispatch(p.p); p.v = p.p = 0; } } }; template ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) io_context::dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) { return async_initiate( initiate_dispatch(), handler, this); } struct io_context::initiate_post { template void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler, io_context* self) const { // If you get an error on the following line it means that your handler does // not meet the documented type requirements for a LegacyCompletionHandler. ASIO_LEGACY_COMPLETION_HANDLER_CHECK( LegacyCompletionHandler, handler) type_check; detail::non_const_lvalue handler2(handler); bool is_continuation = asio_handler_cont_helpers::is_continuation(handler2.value); // Allocate and construct an operation to wrap the handler. typedef detail::completion_handler< typename decay::type> op; typename op::ptr p = { detail::addressof(handler2.value), op::ptr::allocate(handler2.value), 0 }; p.p = new (p.v) op(handler2.value); ASIO_HANDLER_CREATION((*self, *p.p, "io_context", self, 0, "post")); self->impl_.post_immediate_completion(p.p, is_continuation); p.v = p.p = 0; } }; template ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) io_context::post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) { return async_initiate( initiate_post(), handler, this); } template #if defined(GENERATING_DOCUMENTATION) unspecified #else inline detail::wrapped_handler #endif io_context::wrap(Handler handler) { return detail::wrapped_handler(*this, handler); } #endif // !defined(ASIO_NO_DEPRECATED) inline io_context& io_context::executor_type::context() const ASIO_NOEXCEPT { return io_context_; } inline void io_context::executor_type::on_work_started() const ASIO_NOEXCEPT { io_context_.impl_.work_started(); } inline void io_context::executor_type::on_work_finished() const ASIO_NOEXCEPT { io_context_.impl_.work_finished(); } template void io_context::executor_type::dispatch( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; // Invoke immediately if we are already inside the thread pool. if (io_context_.impl_.can_dispatch()) { // Make a local, non-const copy of the function. function_type tmp(ASIO_MOVE_CAST(Function)(f)); detail::fenced_block b(detail::fenced_block::full); asio_handler_invoke_helpers::invoke(tmp, tmp); return; } // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((this->context(), *p.p, "io_context", &this->context(), 0, "dispatch")); io_context_.impl_.post_immediate_completion(p.p, false); p.v = p.p = 0; } template void io_context::executor_type::post( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((this->context(), *p.p, "io_context", &this->context(), 0, "post")); io_context_.impl_.post_immediate_completion(p.p, false); p.v = p.p = 0; } template void io_context::executor_type::defer( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((this->context(), *p.p, "io_context", &this->context(), 0, "defer")); io_context_.impl_.post_immediate_completion(p.p, true); p.v = p.p = 0; } inline bool io_context::executor_type::running_in_this_thread() const ASIO_NOEXCEPT { return io_context_.impl_.can_dispatch(); } #if !defined(ASIO_NO_DEPRECATED) inline io_context::work::work(asio::io_context& io_context) : io_context_impl_(io_context.impl_) { io_context_impl_.work_started(); } inline io_context::work::work(const work& other) : io_context_impl_(other.io_context_impl_) { io_context_impl_.work_started(); } inline io_context::work::~work() { io_context_impl_.work_finished(); } inline asio::io_context& io_context::work::get_io_context() { return static_cast(io_context_impl_.context()); } #endif // !defined(ASIO_NO_DEPRECATED) inline asio::io_context& io_context::service::get_io_context() { return static_cast(context()); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_IO_CONTEXT_HPP ================================================ FILE: src/third_party/asio/impl/io_context.ipp ================================================ // // impl/io_context.ipp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_IO_CONTEXT_IPP #define ASIO_IMPL_IO_CONTEXT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/io_context.hpp" #include "asio/detail/concurrency_hint.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/scoped_ptr.hpp" #include "asio/detail/service_registry.hpp" #include "asio/detail/throw_error.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp" #else # include "asio/detail/scheduler.hpp" #endif #include "asio/detail/push_options.hpp" namespace asio { io_context::io_context() : impl_(add_impl(new impl_type(*this, ASIO_CONCURRENCY_HINT_DEFAULT, false))) { } io_context::io_context(int concurrency_hint) : impl_(add_impl(new impl_type(*this, concurrency_hint == 1 ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint, false))) { } io_context::impl_type& io_context::add_impl(io_context::impl_type* impl) { asio::detail::scoped_ptr scoped_impl(impl); asio::add_service(*this, scoped_impl.get()); return *scoped_impl.release(); } io_context::~io_context() { } io_context::count_type io_context::run() { asio::error_code ec; count_type s = impl_.run(ec); asio::detail::throw_error(ec); return s; } #if !defined(ASIO_NO_DEPRECATED) io_context::count_type io_context::run(asio::error_code& ec) { return impl_.run(ec); } #endif // !defined(ASIO_NO_DEPRECATED) io_context::count_type io_context::run_one() { asio::error_code ec; count_type s = impl_.run_one(ec); asio::detail::throw_error(ec); return s; } #if !defined(ASIO_NO_DEPRECATED) io_context::count_type io_context::run_one(asio::error_code& ec) { return impl_.run_one(ec); } #endif // !defined(ASIO_NO_DEPRECATED) io_context::count_type io_context::poll() { asio::error_code ec; count_type s = impl_.poll(ec); asio::detail::throw_error(ec); return s; } #if !defined(ASIO_NO_DEPRECATED) io_context::count_type io_context::poll(asio::error_code& ec) { return impl_.poll(ec); } #endif // !defined(ASIO_NO_DEPRECATED) io_context::count_type io_context::poll_one() { asio::error_code ec; count_type s = impl_.poll_one(ec); asio::detail::throw_error(ec); return s; } #if !defined(ASIO_NO_DEPRECATED) io_context::count_type io_context::poll_one(asio::error_code& ec) { return impl_.poll_one(ec); } #endif // !defined(ASIO_NO_DEPRECATED) void io_context::stop() { impl_.stop(); } bool io_context::stopped() const { return impl_.stopped(); } void io_context::restart() { impl_.restart(); } io_context::service::service(asio::io_context& owner) : execution_context::service(owner) { } io_context::service::~service() { } void io_context::service::shutdown() { #if !defined(ASIO_NO_DEPRECATED) shutdown_service(); #endif // !defined(ASIO_NO_DEPRECATED) } #if !defined(ASIO_NO_DEPRECATED) void io_context::service::shutdown_service() { } #endif // !defined(ASIO_NO_DEPRECATED) void io_context::service::notify_fork(io_context::fork_event ev) { #if !defined(ASIO_NO_DEPRECATED) fork_service(ev); #else // !defined(ASIO_NO_DEPRECATED) (void)ev; #endif // !defined(ASIO_NO_DEPRECATED) } #if !defined(ASIO_NO_DEPRECATED) void io_context::service::fork_service(io_context::fork_event) { } #endif // !defined(ASIO_NO_DEPRECATED) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_IO_CONTEXT_IPP ================================================ FILE: src/third_party/asio/impl/post.hpp ================================================ // // impl/post.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_POST_HPP #define ASIO_IMPL_POST_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/detail/work_dispatcher.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { class initiate_post { public: template void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const { typedef typename decay::type DecayedHandler; typename associated_executor::type ex( (get_associated_executor)(handler)); typename associated_allocator::type alloc( (get_associated_allocator)(handler)); ex.post(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); } }; template class initiate_post_with_executor { public: typedef Executor executor_type; explicit initiate_post_with_executor(const Executor& ex) : ex_(ex) { } executor_type get_executor() const ASIO_NOEXCEPT { return ex_; } template void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const { typedef typename decay::type DecayedHandler; typename associated_allocator::type alloc( (get_associated_allocator)(handler)); ex_.post(detail::work_dispatcher( ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } private: Executor ex_; }; } // namespace detail template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post( ASIO_MOVE_ARG(CompletionToken) token) { return async_initiate( detail::initiate_post(), token); } template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post( const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token, typename enable_if::value>::type*) { return async_initiate( detail::initiate_post_with_executor(ex), token); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post( ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token, typename enable_if::value>::type*) { return (post)(ctx.get_executor(), ASIO_MOVE_CAST(CompletionToken)(token)); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_POST_HPP ================================================ FILE: src/third_party/asio/impl/read.hpp ================================================ // // impl/read.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_READ_HPP #define ASIO_IMPL_READ_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/buffer.hpp" #include "asio/completion_condition.hpp" #include "asio/detail/array_fwd.hpp" #include "asio/detail/base_from_completion_cond.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template std::size_t read_buffer_sequence(SyncReadStream& s, const MutableBufferSequence& buffers, const MutableBufferIterator&, CompletionCondition completion_condition, asio::error_code& ec) { ec = asio::error_code(); asio::detail::consuming_buffers tmp(buffers); while (!tmp.empty()) { if (std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, tmp.total_consumed()))) tmp.consume(s.read_some(tmp.prepare(max_size), ec)); else break; } return tmp.total_consumed();; } } // namespace detail template std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_mutable_buffer_sequence::value >::type*) { return detail::read_buffer_sequence(s, buffers, asio::buffer_sequence_begin(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, typename enable_if< is_mutable_buffer_sequence::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; } template inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, asio::error_code& ec, typename enable_if< is_mutable_buffer_sequence::value >::type*) { return read(s, buffers, transfer_all(), ec); } template inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, typename enable_if< is_mutable_buffer_sequence::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read(s, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) template std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { typename decay::type b( ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); ec = asio::error_code(); std::size_t total_transferred = 0; std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); std::size_t bytes_available = std::min( std::max(512, b.capacity() - b.size()), std::min(max_size, b.max_size() - b.size())); while (bytes_available > 0) { std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec); b.commit(bytes_transferred); total_transferred += bytes_transferred; max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); bytes_available = std::min( std::max(512, b.capacity() - b.size()), std::min(max_size, b.max_size() - b.size())); } return total_transferred; } template inline std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; } template inline std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return read(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); } template inline std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) template inline std::size_t read(SyncReadStream& s, asio::basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec) { return read(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template inline std::size_t read(SyncReadStream& s, asio::basic_streambuf& b) { return read(s, basic_streambuf_ref(b)); } template inline std::size_t read(SyncReadStream& s, asio::basic_streambuf& b, asio::error_code& ec) { return read(s, basic_streambuf_ref(b), ec); } template inline std::size_t read(SyncReadStream& s, asio::basic_streambuf& b, CompletionCondition completion_condition) { return read(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) template std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type*) { DynamicBuffer_v2& b = buffers; ec = asio::error_code(); std::size_t total_transferred = 0; std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); std::size_t bytes_available = std::min( std::max(512, b.capacity() - b.size()), std::min(max_size, b.max_size() - b.size())); while (bytes_available > 0) { std::size_t pos = b.size(); b.grow(bytes_available); std::size_t bytes_transferred = s.read_some( b.data(pos, bytes_available), ec); b.shrink(bytes_available - bytes_transferred); total_transferred += bytes_transferred; max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); bytes_available = std::min( std::max(512, b.capacity() - b.size()), std::min(max_size, b.max_size() - b.size())); } return total_transferred; } template inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, typename enable_if< is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; } template inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return read(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); } template inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; } namespace detail { template class read_op : detail::base_from_completion_cond { public: read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers, CompletionCondition& completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffers_(buffers), start_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_op(const read_op& other) : detail::base_from_completion_cond(other), stream_(other.stream_), buffers_(other.buffers_), start_(other.start_), handler_(other.handler_) { } read_op(read_op&& other) : detail::base_from_completion_cond( ASIO_MOVE_CAST(detail::base_from_completion_cond< CompletionCondition>)(other)), stream_(other.stream_), buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { std::size_t max_size; switch (start_ = start) { case 1: max_size = this->check_for_completion(ec, buffers_.total_consumed()); do { stream_.async_read_some(buffers_.prepare(max_size), ASIO_MOVE_CAST(read_op)(*this)); return; default: buffers_.consume(bytes_transferred); if ((!ec && bytes_transferred == 0) || buffers_.empty()) break; max_size = this->check_for_completion(ec, buffers_.total_consumed()); } while (max_size > 0); handler_(ec, buffers_.total_consumed()); } } //private: typedef asio::detail::consuming_buffers buffers_type; AsyncReadStream& stream_; buffers_type buffers_; int start_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void start_read_buffer_sequence_op(AsyncReadStream& stream, const MutableBufferSequence& buffers, const MutableBufferIterator&, CompletionCondition& completion_condition, ReadHandler& handler) { detail::read_op( stream, buffers, completion_condition, handler)( asio::error_code(), 0, 1); } template class initiate_async_read_buffer_sequence { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_buffer_sequence(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); start_read_buffer_sequence_op(stream_, buffers, asio::buffer_sequence_begin(buffers), completion_cond2.value, handler2.value); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_mutable_buffer_sequence::value >::type*) { return async_initiate( detail::initiate_async_read_buffer_sequence(s), handler, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_mutable_buffer_sequence::value >::type*) { return async_initiate( detail::initiate_async_read_buffer_sequence(s), handler, buffers, transfer_all()); } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail { template class read_dynbuf_v1_op : detail::base_from_completion_cond { public: template read_dynbuf_v1_op(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), start_(0), total_transferred_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_dynbuf_v1_op(const read_dynbuf_v1_op& other) : detail::base_from_completion_cond(other), stream_(other.stream_), buffers_(other.buffers_), start_(other.start_), total_transferred_(other.total_transferred_), handler_(other.handler_) { } read_dynbuf_v1_op(read_dynbuf_v1_op&& other) : detail::base_from_completion_cond( ASIO_MOVE_CAST(detail::base_from_completion_cond< CompletionCondition>)(other)), stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), start_(other.start_), total_transferred_(other.total_transferred_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { std::size_t max_size, bytes_available; switch (start_ = start) { case 1: max_size = this->check_for_completion(ec, total_transferred_); bytes_available = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(max_size, buffers_.max_size() - buffers_.size())); for (;;) { stream_.async_read_some(buffers_.prepare(bytes_available), ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this)); return; default: total_transferred_ += bytes_transferred; buffers_.commit(bytes_transferred); max_size = this->check_for_completion(ec, total_transferred_); bytes_available = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(max_size, buffers_.max_size() - buffers_.size())); if ((!ec && bytes_transferred == 0) || bytes_available == 0) break; } handler_(ec, static_cast(total_transferred_)); } } //private: AsyncReadStream& stream_; DynamicBuffer_v1 buffers_; int start_; std::size_t total_transferred_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_dynbuf_v1_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_dynbuf_v1_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_dynbuf_v1_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_dynbuf_v1_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_dynbuf_v1_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_dynbuf_v1 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_dynbuf_v1(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); read_dynbuf_v1_op::type, CompletionCondition, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_dynbuf_v1_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_dynbuf_v1_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_dynbuf_v1_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_dynbuf_v1_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return async_read(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ASIO_MOVE_CAST(ReadHandler)(handler)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { // If you get an error on the following line it means that your handler does // not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; return async_initiate( detail::initiate_async_read_dynbuf_v1(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, basic_streambuf& b, ASIO_MOVE_ARG(ReadHandler) handler) { return async_read(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(ReadHandler)(handler)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler) { return async_read(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ASIO_MOVE_CAST(ReadHandler)(handler)); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail { template class read_dynbuf_v2_op : detail::base_from_completion_cond { public: template read_dynbuf_v2_op(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), start_(0), total_transferred_(0), bytes_available_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_dynbuf_v2_op(const read_dynbuf_v2_op& other) : detail::base_from_completion_cond(other), stream_(other.stream_), buffers_(other.buffers_), start_(other.start_), total_transferred_(other.total_transferred_), bytes_available_(other.bytes_available_), handler_(other.handler_) { } read_dynbuf_v2_op(read_dynbuf_v2_op&& other) : detail::base_from_completion_cond( ASIO_MOVE_CAST(detail::base_from_completion_cond< CompletionCondition>)(other)), stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), start_(other.start_), total_transferred_(other.total_transferred_), bytes_available_(other.bytes_available_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { std::size_t max_size, pos; switch (start_ = start) { case 1: max_size = this->check_for_completion(ec, total_transferred_); bytes_available_ = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(max_size, buffers_.max_size() - buffers_.size())); for (;;) { pos = buffers_.size(); buffers_.grow(bytes_available_); stream_.async_read_some(buffers_.data(pos, bytes_available_), ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this)); return; default: total_transferred_ += bytes_transferred; buffers_.shrink(bytes_available_ - bytes_transferred); max_size = this->check_for_completion(ec, total_transferred_); bytes_available_ = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(max_size, buffers_.max_size() - buffers_.size())); if ((!ec && bytes_transferred == 0) || bytes_available_ == 0) break; } handler_(ec, static_cast(total_transferred_)); } } //private: AsyncReadStream& stream_; DynamicBuffer_v2 buffers_; int start_; std::size_t total_transferred_; std::size_t bytes_available_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_dynbuf_v2_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_dynbuf_v2_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_dynbuf_v2_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_dynbuf_v2_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_dynbuf_v2_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_dynbuf_v2 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_dynbuf_v2(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); read_dynbuf_v2_op::type, CompletionCondition, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_dynbuf_v2_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_dynbuf_v2_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_dynbuf_v2_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_dynbuf_v2_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return async_read(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ASIO_MOVE_CAST(ReadHandler)(handler)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v2::value >::type*) { // If you get an error on the following line it means that your handler does // not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; return async_initiate( detail::initiate_async_read_dynbuf_v2(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_READ_HPP ================================================ FILE: src/third_party/asio/impl/read_at.hpp ================================================ // // impl/read_at.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_READ_AT_HPP #define ASIO_IMPL_READ_AT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/buffer.hpp" #include "asio/completion_condition.hpp" #include "asio/detail/array_fwd.hpp" #include "asio/detail/base_from_completion_cond.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template std::size_t read_at_buffer_sequence(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, const MutableBufferIterator&, CompletionCondition completion_condition, asio::error_code& ec) { ec = asio::error_code(); asio::detail::consuming_buffers tmp(buffers); while (!tmp.empty()) { if (std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, tmp.total_consumed()))) { tmp.consume(d.read_some_at(offset + tmp.total_consumed(), tmp.prepare(max_size), ec)); } else break; } return tmp.total_consumed();; } } // namespace detail template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec) { return detail::read_at_buffer_sequence(d, offset, buffers, asio::buffer_sequence_begin(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t bytes_transferred = read_at( d, offset, buffers, transfer_all(), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } template inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, asio::error_code& ec) { return read_at(d, offset, buffers, transfer_all(), ec); } template inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = read_at(d, offset, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec) { ec = asio::error_code(); std::size_t total_transferred = 0; std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); std::size_t bytes_available = read_size_helper(b, max_size); while (bytes_available > 0) { std::size_t bytes_transferred = d.read_some_at( offset + total_transferred, b.prepare(bytes_available), ec); b.commit(bytes_transferred); total_transferred += bytes_transferred; max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); bytes_available = read_size_helper(b, max_size); } return total_transferred; } template inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf& b) { asio::error_code ec; std::size_t bytes_transferred = read_at( d, offset, b, transfer_all(), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } template inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf& b, asio::error_code& ec) { return read_at(d, offset, b, transfer_all(), ec); } template inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf& b, CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = read_at(d, offset, b, ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) namespace detail { template class read_at_op : detail::base_from_completion_cond { public: read_at_op(AsyncRandomAccessReadDevice& device, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition& completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), buffers_(buffers), start_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_at_op(const read_at_op& other) : detail::base_from_completion_cond(other), device_(other.device_), offset_(other.offset_), buffers_(other.buffers_), start_(other.start_), handler_(other.handler_) { } read_at_op(read_at_op&& other) : detail::base_from_completion_cond( ASIO_MOVE_CAST(detail::base_from_completion_cond< CompletionCondition>)(other)), device_(other.device_), offset_(other.offset_), buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { std::size_t max_size; switch (start_ = start) { case 1: max_size = this->check_for_completion(ec, buffers_.total_consumed()); do { device_.async_read_some_at( offset_ + buffers_.total_consumed(), buffers_.prepare(max_size), ASIO_MOVE_CAST(read_at_op)(*this)); return; default: buffers_.consume(bytes_transferred); if ((!ec && bytes_transferred == 0) || buffers_.empty()) break; max_size = this->check_for_completion(ec, buffers_.total_consumed()); } while (max_size > 0); handler_(ec, buffers_.total_consumed()); } } //private: typedef asio::detail::consuming_buffers buffers_type; AsyncRandomAccessReadDevice& device_; uint64_t offset_; buffers_type buffers_; int start_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_at_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_at_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_at_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_at_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_at_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void start_read_at_buffer_sequence_op(AsyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, const MutableBufferIterator&, CompletionCondition& completion_condition, ReadHandler& handler) { detail::read_at_op( d, offset, buffers, completion_condition, handler)( asio::error_code(), 0, 1); } template class initiate_async_read_at_buffer_sequence { public: typedef typename AsyncRandomAccessReadDevice::executor_type executor_type; explicit initiate_async_read_at_buffer_sequence( AsyncRandomAccessReadDevice& device) : device_(device) { } executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, uint64_t offset, const MutableBufferSequence& buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); start_read_at_buffer_sequence_op(device_, offset, buffers, asio::buffer_sequence_begin(buffers), completion_cond2.value, handler2.value); } private: AsyncRandomAccessReadDevice& device_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_at_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_at_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_at_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_at_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler) { return async_initiate( detail::initiate_async_read_at_buffer_sequence< AsyncRandomAccessReadDevice>(d), handler, offset, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler) { return async_initiate( detail::initiate_async_read_at_buffer_sequence< AsyncRandomAccessReadDevice>(d), handler, offset, buffers, transfer_all()); } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) namespace detail { template class read_at_streambuf_op : detail::base_from_completion_cond { public: read_at_streambuf_op(AsyncRandomAccessReadDevice& device, uint64_t offset, basic_streambuf& streambuf, CompletionCondition& completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), streambuf_(streambuf), start_(0), total_transferred_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_at_streambuf_op(const read_at_streambuf_op& other) : detail::base_from_completion_cond(other), device_(other.device_), offset_(other.offset_), streambuf_(other.streambuf_), start_(other.start_), total_transferred_(other.total_transferred_), handler_(other.handler_) { } read_at_streambuf_op(read_at_streambuf_op&& other) : detail::base_from_completion_cond( ASIO_MOVE_CAST(detail::base_from_completion_cond< CompletionCondition>)(other)), device_(other.device_), offset_(other.offset_), streambuf_(other.streambuf_), start_(other.start_), total_transferred_(other.total_transferred_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { std::size_t max_size, bytes_available; switch (start_ = start) { case 1: max_size = this->check_for_completion(ec, total_transferred_); bytes_available = read_size_helper(streambuf_, max_size); for (;;) { device_.async_read_some_at(offset_ + total_transferred_, streambuf_.prepare(bytes_available), ASIO_MOVE_CAST(read_at_streambuf_op)(*this)); return; default: total_transferred_ += bytes_transferred; streambuf_.commit(bytes_transferred); max_size = this->check_for_completion(ec, total_transferred_); bytes_available = read_size_helper(streambuf_, max_size); if ((!ec && bytes_transferred == 0) || bytes_available == 0) break; } handler_(ec, static_cast(total_transferred_)); } } //private: AsyncRandomAccessReadDevice& device_; uint64_t offset_; asio::basic_streambuf& streambuf_; int start_; std::size_t total_transferred_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_at_streambuf_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_at_streambuf_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_at_streambuf_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_at_streambuf_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_at_streambuf_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_at_streambuf { public: typedef typename AsyncRandomAccessReadDevice::executor_type executor_type; explicit initiate_async_read_at_streambuf( AsyncRandomAccessReadDevice& device) : device_(device) { } executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, uint64_t offset, basic_streambuf* b, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); read_at_streambuf_op::type>( device_, offset, *b, completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); } private: AsyncRandomAccessReadDevice& device_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_at_streambuf_op, Allocator1> { typedef typename associated_allocator::type type; static type get( const detail::read_at_streambuf_op& h, const Allocator1& a = Allocator1()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_at_streambuf_op, Executor1> { typedef typename associated_executor::type type; static type get( const detail::read_at_streambuf_op& h, const Executor1& ex = Executor1()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler) { return async_initiate( detail::initiate_async_read_at_streambuf(d), handler, offset, &b, ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf& b, ASIO_MOVE_ARG(ReadHandler) handler) { return async_initiate( detail::initiate_async_read_at_streambuf(d), handler, offset, &b, transfer_all()); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_READ_AT_HPP ================================================ FILE: src/third_party/asio/impl/read_until.hpp ================================================ // // impl/read_until.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_READ_UNTIL_HPP #define ASIO_IMPL_READ_UNTIL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include #include #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/buffer.hpp" #include "asio/buffers_iterator.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Algorithm that finds a subsequence of equal values in a sequence. Returns // (iterator,true) if a full match was found, in which case the iterator // points to the beginning of the match. Returns (iterator,false) if a // partial match was found at the end of the first sequence, in which case // the iterator points to the beginning of the partial match. Returns // (last1,false) if no full or partial match was found. template std::pair partial_search( Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) { for (Iterator1 iter1 = first1; iter1 != last1; ++iter1) { Iterator1 test_iter1 = iter1; Iterator2 test_iter2 = first2; for (;; ++test_iter1, ++test_iter2) { if (test_iter2 == last2) return std::make_pair(iter1, true); if (test_iter1 == last1) { if (test_iter2 != first2) return std::make_pair(iter1, false); else break; } if (*test_iter1 != *test_iter2) break; } } return std::make_pair(last1, false); } } // namespace detail #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) template inline std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { typename decay::type b( ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = b.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. iterator iter = std::find(start_pos, end, delim); if (iter != end) { // Found a match. We're done. ec = asio::error_code(); return iter - begin + 1; } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); b.commit(s.read_some(b.prepare(bytes_to_read), ec)); if (ec) return 0; } } template inline std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { typename decay::type b( ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = b.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = detail::partial_search( start_pos, end, delim.begin(), delim.end()); if (result.first != end) { if (result.second) { // Full match. We're done. ec = asio::error_code(); return result.first - begin + delim.length(); } else { // Partial match. Next search needs to start from beginning of match. search_position = result.first - begin; } } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); b.commit(s.read_some(b.prepare(bytes_to_read), ec)); if (ec) return 0; } } #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) template inline std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const boost::regex& expr, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const boost::regex& expr, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { typename decay::type b( ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = b.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. boost::match_results >::allocator_type> match_results; if (regex_search(start_pos, end, match_results, expr, boost::match_default | boost::match_partial)) { if (match_results[0].matched) { // Full match. We're done. ec = asio::error_code(); return match_results[0].second - begin; } else { // Partial match. Next search needs to start from beginning of match. search_position = match_results[0].first - begin; } } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); b.commit(s.read_some(b.prepare(bytes_to_read), ec)); if (ec) return 0; } } #endif // defined(ASIO_HAS_BOOST_REGEX) template inline std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition, typename enable_if< is_match_condition::value && is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition, asio::error_code& ec, typename enable_if< is_match_condition::value && is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { typename decay::type b( ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = b.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = match_condition(start_pos, end); if (result.second) { // Full match. We're done. ec = asio::error_code(); return result.first - begin; } else if (result.first != end) { // Partial match. Next search needs to start from beginning of match. search_position = result.first - begin; } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); b.commit(s.read_some(b.prepare(bytes_to_read), ec)); if (ec) return 0; } } #if !defined(ASIO_NO_IOSTREAM) template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, char delim) { return read_until(s, basic_streambuf_ref(b), delim); } template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, char delim, asio::error_code& ec) { return read_until(s, basic_streambuf_ref(b), delim, ec); } template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, ASIO_STRING_VIEW_PARAM delim) { return read_until(s, basic_streambuf_ref(b), delim); } template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec) { return read_until(s, basic_streambuf_ref(b), delim, ec); } #if defined(ASIO_HAS_BOOST_REGEX) template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, const boost::regex& expr) { return read_until(s, basic_streambuf_ref(b), expr); } template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, const boost::regex& expr, asio::error_code& ec) { return read_until(s, basic_streambuf_ref(b), expr, ec); } #endif // defined(ASIO_HAS_BOOST_REGEX) template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, MatchCondition match_condition, typename enable_if::value>::type*) { return read_until(s, basic_streambuf_ref(b), match_condition); } template inline std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, MatchCondition match_condition, asio::error_code& ec, typename enable_if::value>::type*) { return read_until(s, basic_streambuf_ref(b), match_condition, ec); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) template inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim, typename enable_if< is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type*) { DynamicBuffer_v2& b = buffers; std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(b).data(0, b.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. iterator iter = std::find(start_pos, end, delim); if (iter != end) { // Found a match. We're done. ec = asio::error_code(); return iter - begin + 1; } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); std::size_t pos = b.size(); b.grow(bytes_to_read); std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec); b.shrink(bytes_to_read - bytes_transferred); if (ec) return 0; } } template inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim, typename enable_if< is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type*) { DynamicBuffer_v2& b = buffers; std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(b).data(0, b.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = detail::partial_search( start_pos, end, delim.begin(), delim.end()); if (result.first != end) { if (result.second) { // Full match. We're done. ec = asio::error_code(); return result.first - begin + delim.length(); } else { // Partial match. Next search needs to start from beginning of match. search_position = result.first - begin; } } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); std::size_t pos = b.size(); b.grow(bytes_to_read); std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec); b.shrink(bytes_to_read - bytes_transferred); if (ec) return 0; } } #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) template inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, const boost::regex& expr, typename enable_if< is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, const boost::regex& expr, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type*) { DynamicBuffer_v2& b = buffers; std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(b).data(0, b.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. boost::match_results >::allocator_type> match_results; if (regex_search(start_pos, end, match_results, expr, boost::match_default | boost::match_partial)) { if (match_results[0].matched) { // Full match. We're done. ec = asio::error_code(); return match_results[0].second - begin; } else { // Partial match. Next search needs to start from beginning of match. search_position = match_results[0].first - begin; } } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); std::size_t pos = b.size(); b.grow(bytes_to_read); std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec); b.shrink(bytes_to_read - bytes_transferred); if (ec) return 0; } } #endif // defined(ASIO_HAS_BOOST_REGEX) template inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, typename enable_if< is_match_condition::value && is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = read_until(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition, ec); asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, asio::error_code& ec, typename enable_if< is_match_condition::value && is_dynamic_buffer_v2::value >::type*) { DynamicBuffer_v2& b = buffers; std::size_t search_position = 0; for (;;) { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(b).data(0, b.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = match_condition(start_pos, end); if (result.second) { // Full match. We're done. ec = asio::error_code(); return result.first - begin; } else if (result.first != end) { // Partial match. Next search needs to start from beginning of match. search_position = result.first - begin; } else { // No match. Next search can start with the new data. search_position = end - begin; } // Check if buffer is full. if (b.size() == b.max_size()) { ec = error::not_found; return 0; } // Need more data. std::size_t bytes_to_read = std::min( std::max(512, b.capacity() - b.size()), std::min(65536, b.max_size() - b.size())); std::size_t pos = b.size(); b.grow(bytes_to_read); std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec); b.shrink(bytes_to_read - bytes_transferred); if (ec) return 0; } } #endif // !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail { template class read_until_delim_op_v1 { public: template read_until_delim_op_v1(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, char delim, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), delim_(delim), start_(0), search_position_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_delim_op_v1(const read_until_delim_op_v1& other) : stream_(other.stream_), buffers_(other.buffers_), delim_(other.delim_), start_(other.start_), search_position_(other.search_position_), handler_(other.handler_) { } read_until_delim_op_v1(read_until_delim_op_v1&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), delim_(other.delim_), start_(other.start_), search_position_(other.search_position_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t bytes_to_read; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = buffers_.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. iterator iter = std::find(start_pos, end, delim_); if (iter != end) { // Found a match. We're done. search_position_ = iter - begin + 1; bytes_to_read = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read = 0; } // Need to read some more data. else { // Next search can start with the new data. search_position_ = end - begin; bytes_to_read = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read == 0) break; // Start a new asynchronous read op_v1eration to obtain more data. stream_.async_read_some(buffers_.prepare(bytes_to_read), ASIO_MOVE_CAST(read_until_delim_op_v1)(*this)); return; default: buffers_.commit(bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v1 buffers_; char delim_; int start_; std::size_t search_position_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_delim_op_v1* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_delim_op_v1* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_delim_op_v1* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_delim_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_delim_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_delim_v1 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_delim_v1(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_delim_op_v1::type, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_delim_op_v1, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_delim_op_v1& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_delim_op_v1, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_delim_op_v1& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return async_initiate( detail::initiate_async_read_until_delim_v1(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim); } namespace detail { template class read_until_delim_string_op_v1 { public: template read_until_delim_string_op_v1(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, const std::string& delim, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), delim_(delim), start_(0), search_position_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_delim_string_op_v1(const read_until_delim_string_op_v1& other) : stream_(other.stream_), buffers_(other.buffers_), delim_(other.delim_), start_(other.start_), search_position_(other.search_position_), handler_(other.handler_) { } read_until_delim_string_op_v1(read_until_delim_string_op_v1&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), delim_(ASIO_MOVE_CAST(std::string)(other.delim_)), start_(other.start_), search_position_(other.search_position_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t bytes_to_read; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = buffers_.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = detail::partial_search( start_pos, end, delim_.begin(), delim_.end()); if (result.first != end && result.second) { // Full match. We're done. search_position_ = result.first - begin + delim_.length(); bytes_to_read = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read = 0; } // Need to read some more data. else { if (result.first != end) { // Partial match. Next search needs to start from beginning of // match. search_position_ = result.first - begin; } else { // Next search can start with the new data. search_position_ = end - begin; } bytes_to_read = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read == 0) break; // Start a new asynchronous read op_v1eration to obtain more data. stream_.async_read_some(buffers_.prepare(bytes_to_read), ASIO_MOVE_CAST(read_until_delim_string_op_v1)(*this)); return; default: buffers_.commit(bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v1 buffers_; std::string delim_; int start_; std::size_t search_position_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_delim_string_op_v1* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_delim_string_op_v1* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_delim_string_op_v1* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_delim_string_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_delim_string_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_delim_string_v1 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_delim_string_v1(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const std::string& delim) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_delim_string_op_v1::type, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_delim_string_op_v1, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_delim_string_op_v1& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_delim_string_op_v1, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_delim_string_op_v1& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return async_initiate( detail::initiate_async_read_until_delim_string_v1(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), static_cast(delim)); } #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) namespace detail { template class read_until_expr_op_v1 { public: template read_until_expr_op_v1(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, const boost::regex& expr, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), expr_(expr), start_(0), search_position_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_expr_op_v1(const read_until_expr_op_v1& other) : stream_(other.stream_), buffers_(other.buffers_), expr_(other.expr_), start_(other.start_), search_position_(other.search_position_), handler_(other.handler_) { } read_until_expr_op_v1(read_until_expr_op_v1&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), expr_(other.expr_), start_(other.start_), search_position_(other.search_position_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t bytes_to_read; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = buffers_.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. boost::match_results >::allocator_type> match_results; bool match = regex_search(start_pos, end, match_results, expr_, boost::match_default | boost::match_partial); if (match && match_results[0].matched) { // Full match. We're done. search_position_ = match_results[0].second - begin; bytes_to_read = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read = 0; } // Need to read some more data. else { if (match) { // Partial match. Next search needs to start from beginning of // match. search_position_ = match_results[0].first - begin; } else { // Next search can start with the new data. search_position_ = end - begin; } bytes_to_read = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read == 0) break; // Start a new asynchronous read op_v1eration to obtain more data. stream_.async_read_some(buffers_.prepare(bytes_to_read), ASIO_MOVE_CAST(read_until_expr_op_v1)(*this)); return; default: buffers_.commit(bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v1 buffers_; RegEx expr_; int start_; std::size_t search_position_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_expr_op_v1* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_expr_op_v1* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_expr_op_v1* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_expr_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_expr_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_expr_v1 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_expr_v1(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const RegEx& expr) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_expr_op_v1::type, RegEx, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_expr_op_v1, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_expr_op_v1& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_expr_op_v1, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_expr_op_v1& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const boost::regex& expr, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return async_initiate( detail::initiate_async_read_until_expr_v1(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr); } #endif // defined(ASIO_HAS_BOOST_REGEX) namespace detail { template class read_until_match_op_v1 { public: template read_until_match_op_v1(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, MatchCondition match_condition, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), match_condition_(match_condition), start_(0), search_position_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_match_op_v1(const read_until_match_op_v1& other) : stream_(other.stream_), buffers_(other.buffers_), match_condition_(other.match_condition_), start_(other.start_), search_position_(other.search_position_), handler_(other.handler_) { } read_until_match_op_v1(read_until_match_op_v1&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), match_condition_(other.match_condition_), start_(other.start_), search_position_(other.search_position_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t bytes_to_read; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v1::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = buffers_.data(); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = match_condition_(start_pos, end); if (result.second) { // Full match. We're done. search_position_ = result.first - begin; bytes_to_read = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read = 0; } // Need to read some more data. else { if (result.first != end) { // Partial match. Next search needs to start from beginning of // match. search_position_ = result.first - begin; } else { // Next search can start with the new data. search_position_ = end - begin; } bytes_to_read = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read == 0) break; // Start a new asynchronous read op_v1eration to obtain more data. stream_.async_read_some(buffers_.prepare(bytes_to_read), ASIO_MOVE_CAST(read_until_match_op_v1)(*this)); return; default: buffers_.commit(bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v1 buffers_; MatchCondition match_condition_; int start_; std::size_t search_position_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_match_op_v1* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_match_op_v1* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_match_op_v1* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_match_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_match_op_v1* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_match_v1 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_match_v1(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_match_op_v1::type, MatchCondition, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_match_op_v1, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_match_op_v1& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_match_op_v1, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_match_op_v1& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_match_condition::value && is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return async_initiate( detail::initiate_async_read_until_match_v1(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition); } #if !defined(ASIO_NO_IOSTREAM) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, char delim, ASIO_MOVE_ARG(ReadHandler) handler) { return async_read_until(s, basic_streambuf_ref(b), delim, ASIO_MOVE_CAST(ReadHandler)(handler)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, ASIO_STRING_VIEW_PARAM delim, ASIO_MOVE_ARG(ReadHandler) handler) { return async_read_until(s, basic_streambuf_ref(b), delim, ASIO_MOVE_CAST(ReadHandler)(handler)); } #if defined(ASIO_HAS_BOOST_REGEX) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, const boost::regex& expr, ASIO_MOVE_ARG(ReadHandler) handler) { return async_read_until(s, basic_streambuf_ref(b), expr, ASIO_MOVE_CAST(ReadHandler)(handler)); } #endif // defined(ASIO_HAS_BOOST_REGEX) template inline ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if::value>::type*) { return async_read_until(s, basic_streambuf_ref(b), match_condition, ASIO_MOVE_CAST(ReadHandler)(handler)); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail { template class read_until_delim_op_v2 { public: template read_until_delim_op_v2(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, char delim, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), delim_(delim), start_(0), search_position_(0), bytes_to_read_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_delim_op_v2(const read_until_delim_op_v2& other) : stream_(other.stream_), buffers_(other.buffers_), delim_(other.delim_), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(other.handler_) { } read_until_delim_op_v2(read_until_delim_op_v2&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), delim_(other.delim_), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t pos; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(buffers_).data( 0, buffers_.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. iterator iter = std::find(start_pos, end, delim_); if (iter != end) { // Found a match. We're done. search_position_ = iter - begin + 1; bytes_to_read_ = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read_ = 0; } // Need to read some more data. else { // Next search can start with the new data. search_position_ = end - begin; bytes_to_read_ = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read_ == 0) break; // Start a new asynchronous read op_v2eration to obtain more data. pos = buffers_.size(); buffers_.grow(bytes_to_read_); stream_.async_read_some(buffers_.data(pos, bytes_to_read_), ASIO_MOVE_CAST(read_until_delim_op_v2)(*this)); return; default: buffers_.shrink(bytes_to_read_ - bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v2 buffers_; char delim_; int start_; std::size_t search_position_; std::size_t bytes_to_read_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_delim_op_v2* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_delim_op_v2* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_delim_op_v2* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_delim_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_delim_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_delim_v2 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_delim_v2(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, char delim) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_delim_op_v2::type, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_delim_op_v2, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_delim_op_v2& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_delim_op_v2, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_delim_op_v2& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, char delim, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return async_initiate( detail::initiate_async_read_until_delim_v2(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim); } namespace detail { template class read_until_delim_string_op_v2 { public: template read_until_delim_string_op_v2(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, const std::string& delim, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), delim_(delim), start_(0), search_position_(0), bytes_to_read_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_delim_string_op_v2(const read_until_delim_string_op_v2& other) : stream_(other.stream_), buffers_(other.buffers_), delim_(other.delim_), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(other.handler_) { } read_until_delim_string_op_v2(read_until_delim_string_op_v2&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), delim_(ASIO_MOVE_CAST(std::string)(other.delim_)), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t pos; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(buffers_).data( 0, buffers_.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = detail::partial_search( start_pos, end, delim_.begin(), delim_.end()); if (result.first != end && result.second) { // Full match. We're done. search_position_ = result.first - begin + delim_.length(); bytes_to_read_ = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read_ = 0; } // Need to read some more data. else { if (result.first != end) { // Partial match. Next search needs to start from beginning of // match. search_position_ = result.first - begin; } else { // Next search can start with the new data. search_position_ = end - begin; } bytes_to_read_ = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read_ == 0) break; // Start a new asynchronous read op_v2eration to obtain more data. pos = buffers_.size(); buffers_.grow(bytes_to_read_); stream_.async_read_some(buffers_.data(pos, bytes_to_read_), ASIO_MOVE_CAST(read_until_delim_string_op_v2)(*this)); return; default: buffers_.shrink(bytes_to_read_ - bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v2 buffers_; std::string delim_; int start_; std::size_t search_position_; std::size_t bytes_to_read_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_delim_string_op_v2* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_delim_string_op_v2* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_delim_string_op_v2* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_delim_string_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_delim_string_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_delim_string_v2 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_delim_string_v2(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, const std::string& delim) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_delim_string_op_v2::type, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_delim_string_op_v2, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_delim_string_op_v2& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_delim_string_op_v2, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_delim_string_op_v2& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return async_initiate( detail::initiate_async_read_until_delim_string_v2(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), static_cast(delim)); } #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) namespace detail { template class read_until_expr_op_v2 { public: template read_until_expr_op_v2(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, const boost::regex& expr, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), expr_(expr), start_(0), search_position_(0), bytes_to_read_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_expr_op_v2(const read_until_expr_op_v2& other) : stream_(other.stream_), buffers_(other.buffers_), expr_(other.expr_), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(other.handler_) { } read_until_expr_op_v2(read_until_expr_op_v2&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), expr_(other.expr_), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t pos; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(buffers_).data( 0, buffers_.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. boost::match_results >::allocator_type> match_results; bool match = regex_search(start_pos, end, match_results, expr_, boost::match_default | boost::match_partial); if (match && match_results[0].matched) { // Full match. We're done. search_position_ = match_results[0].second - begin; bytes_to_read_ = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read_ = 0; } // Need to read some more data. else { if (match) { // Partial match. Next search needs to start from beginning of // match. search_position_ = match_results[0].first - begin; } else { // Next search can start with the new data. search_position_ = end - begin; } bytes_to_read_ = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read_ == 0) break; // Start a new asynchronous read op_v2eration to obtain more data. pos = buffers_.size(); buffers_.grow(bytes_to_read_); stream_.async_read_some(buffers_.data(pos, bytes_to_read_), ASIO_MOVE_CAST(read_until_expr_op_v2)(*this)); return; default: buffers_.shrink(bytes_to_read_ - bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v2 buffers_; RegEx expr_; int start_; std::size_t search_position_; std::size_t bytes_to_read_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_expr_op_v2* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_expr_op_v2* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_expr_op_v2* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_expr_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_expr_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_expr_v2 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_expr_v2(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, const RegEx& expr) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_expr_op_v2::type, RegEx, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_expr_op_v2, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_expr_op_v2& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_expr_op_v2, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_expr_op_v2& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, const boost::regex& expr, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return async_initiate( detail::initiate_async_read_until_expr_v2(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr); } #endif // defined(ASIO_HAS_BOOST_REGEX) namespace detail { template class read_until_match_op_v2 { public: template read_until_match_op_v2(AsyncReadStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, MatchCondition match_condition, ReadHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), match_condition_(match_condition), start_(0), search_position_(0), bytes_to_read_(0), handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) read_until_match_op_v2(const read_until_match_op_v2& other) : stream_(other.stream_), buffers_(other.buffers_), match_condition_(other.match_condition_), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(other.handler_) { } read_until_match_op_v2(read_until_match_op_v2&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), match_condition_(other.match_condition_), start_(other.start_), search_position_(other.search_position_), bytes_to_read_(other.bytes_to_read_), handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { const std::size_t not_found = (std::numeric_limits::max)(); std::size_t pos; switch (start_ = start) { case 1: for (;;) { { // Determine the range of the data to be searched. typedef typename DynamicBuffer_v2::const_buffers_type buffers_type; typedef buffers_iterator iterator; buffers_type data_buffers = const_cast(buffers_).data( 0, buffers_.size()); iterator begin = iterator::begin(data_buffers); iterator start_pos = begin + search_position_; iterator end = iterator::end(data_buffers); // Look for a match. std::pair result = match_condition_(start_pos, end); if (result.second) { // Full match. We're done. search_position_ = result.first - begin; bytes_to_read_ = 0; } // No match yet. Check if buffer is full. else if (buffers_.size() == buffers_.max_size()) { search_position_ = not_found; bytes_to_read_ = 0; } // Need to read some more data. else { if (result.first != end) { // Partial match. Next search needs to start from beginning of // match. search_position_ = result.first - begin; } else { // Next search can start with the new data. search_position_ = end - begin; } bytes_to_read_ = std::min( std::max(512, buffers_.capacity() - buffers_.size()), std::min(65536, buffers_.max_size() - buffers_.size())); } } // Check if we're done. if (!start && bytes_to_read_ == 0) break; // Start a new asynchronous read op_v2eration to obtain more data. pos = buffers_.size(); buffers_.grow(bytes_to_read_); stream_.async_read_some(buffers_.data(pos, bytes_to_read_), ASIO_MOVE_CAST(read_until_match_op_v2)(*this)); return; default: buffers_.shrink(bytes_to_read_ - bytes_transferred); if (ec || bytes_transferred == 0) break; } const asio::error_code result_ec = (search_position_ == not_found) ? error::not_found : ec; const std::size_t result_n = (ec || search_position_ == not_found) ? 0 : search_position_; handler_(result_ec, result_n); } } //private: AsyncReadStream& stream_; DynamicBuffer_v2 buffers_; MatchCondition match_condition_; int start_; std::size_t search_position_; std::size_t bytes_to_read_; ReadHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, read_until_match_op_v2* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, read_until_match_op_v2* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( read_until_match_op_v2* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, read_until_match_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, read_until_match_op_v2* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_read_until_match_v2 { public: typedef typename AsyncReadStream::executor_type executor_type; explicit initiate_async_read_until_match_v2(AsyncReadStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, MatchCondition match_condition) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; non_const_lvalue handler2(handler); read_until_match_op_v2::type, MatchCondition, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition, handler2.value)(asio::error_code(), 0, 1); } private: AsyncReadStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::read_until_match_op_v2, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::read_until_match_op_v2& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::read_until_match_op_v2, Executor> { typedef typename associated_executor::type type; static type get( const detail::read_until_match_op_v2& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler, typename enable_if< is_match_condition::value && is_dynamic_buffer_v2::value >::type*) { return async_initiate( detail::initiate_async_read_until_match_v2(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition); } #endif // !defined(ASIO_NO_EXTENSIONS) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_READ_UNTIL_HPP ================================================ FILE: src/third_party/asio/impl/redirect_error.hpp ================================================ // impl/redirect_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_REDIRECT_ERROR_HPP #define ASIO_IMPL_REDIRECT_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_executor.hpp" #include "asio/associated_allocator.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/system_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Class to adapt a redirect_error_t as a completion handler. template class redirect_error_handler { public: typedef void result_type; template redirect_error_handler(redirect_error_t e) : ec_(e.ec_), handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_)) { } template redirect_error_handler(asio::error_code& ec, ASIO_MOVE_ARG(RedirectedHandler) h) : ec_(ec), handler_(ASIO_MOVE_CAST(RedirectedHandler)(h)) { } void operator()() { handler_(); } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template typename enable_if< !is_same::type, asio::error_code>::value >::type operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_MOVE_ARG(Args)... args) { handler_(ASIO_MOVE_CAST(Arg)(arg), ASIO_MOVE_CAST(Args)(args)...); } template void operator()(const asio::error_code& ec, ASIO_MOVE_ARG(Args)... args) { ec_ = ec; handler_(ASIO_MOVE_CAST(Args)(args)...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template typename enable_if< !is_same::type, asio::error_code>::value >::type operator()(ASIO_MOVE_ARG(Arg) arg) { handler_(ASIO_MOVE_CAST(Arg)(arg)); } void operator()(const asio::error_code& ec) { ec_ = ec; handler_(); } #define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \ template \ typename enable_if< \ !is_same::type, asio::error_code>::value \ >::type \ operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ handler_(ASIO_MOVE_CAST(Arg)(arg), \ ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template \ void operator()(const asio::error_code& ec, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ ec_ = ec; \ handler_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF) #undef ASIO_PRIVATE_REDIRECT_ERROR_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) //private: asio::error_code& ec_; Handler handler_; }; template inline void* asio_handler_allocate(std::size_t size, redirect_error_handler* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, redirect_error_handler* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( redirect_error_handler* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, redirect_error_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, redirect_error_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template struct redirect_error_signature { typedef Signature type; }; #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template struct redirect_error_signature { typedef R type(Args...); }; template struct redirect_error_signature { typedef R type(Args...); }; #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template struct redirect_error_signature { typedef R type(); }; template struct redirect_error_signature { typedef R type(); }; #define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \ template \ struct redirect_error_signature< \ R(asio::error_code, ASIO_VARIADIC_TARGS(n))> \ { \ typedef R type(ASIO_VARIADIC_TARGS(n)); \ }; \ \ template \ struct redirect_error_signature< \ R(const asio::error_code&, ASIO_VARIADIC_TARGS(n))> \ { \ typedef R type(ASIO_VARIADIC_TARGS(n)); \ }; \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF) #undef ASIO_PRIVATE_REDIRECT_ERROR_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct async_result, Signature> { typedef typename async_result::type> ::return_type return_type; template struct init_wrapper { template init_wrapper(asio::error_code& ec, ASIO_MOVE_ARG(Init) init) : ec_(ec), initiation_(ASIO_MOVE_CAST(Init)(init)) { } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()( ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_CAST(Initiation)(initiation_)( detail::redirect_error_handler< typename decay::type>( ec_, ASIO_MOVE_CAST(Handler)(handler)), ASIO_MOVE_CAST(Args)(args)...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()( ASIO_MOVE_ARG(Handler) handler) { ASIO_MOVE_CAST(Initiation)(initiation_)( detail::redirect_error_handler< typename decay::type>( ec_, ASIO_MOVE_CAST(Handler)(handler))); } #define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \ template \ void operator()( \ ASIO_MOVE_ARG(Handler) handler, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ ASIO_MOVE_CAST(Initiation)(initiation_)( \ detail::redirect_error_handler< \ typename decay::type>( \ ec_, ASIO_MOVE_CAST(Handler)(handler)), \ ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF) #undef ASIO_PRIVATE_INIT_WRAPPER_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) asio::error_code& ec_; Initiation initiation_; }; #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template static return_type initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token, ASIO_MOVE_ARG(Args)... args) { return async_initiate::type>( init_wrapper::type>( token.ec_, ASIO_MOVE_CAST(Initiation)(initiation)), token.token_, ASIO_MOVE_CAST(Args)(args)...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template static return_type initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token) { return async_initiate::type>( init_wrapper::type>( token.ec_, ASIO_MOVE_CAST(Initiation)(initiation)), token.token_); } #define ASIO_PRIVATE_INITIATE_DEF(n) \ template \ static return_type initiate( \ ASIO_MOVE_ARG(Initiation) initiation, \ ASIO_MOVE_ARG(RawCompletionToken) token, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ return async_initiate::type>( \ init_wrapper::type>( \ token.ec_, ASIO_MOVE_CAST(Initiation)(initiation)), \ token.token_, ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF) #undef ASIO_PRIVATE_INITIATE_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; template struct associated_executor, Executor> { typedef typename associated_executor::type type; static type get( const detail::redirect_error_handler& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; template struct associated_allocator, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::redirect_error_handler& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_REDIRECT_ERROR_HPP ================================================ FILE: src/third_party/asio/impl/serial_port_base.hpp ================================================ // // impl/serial_port_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_SERIAL_PORT_BASE_HPP #define ASIO_IMPL_SERIAL_PORT_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/push_options.hpp" namespace asio { inline serial_port_base::baud_rate::baud_rate(unsigned int rate) : value_(rate) { } inline unsigned int serial_port_base::baud_rate::value() const { return value_; } inline serial_port_base::flow_control::type serial_port_base::flow_control::value() const { return value_; } inline serial_port_base::parity::type serial_port_base::parity::value() const { return value_; } inline serial_port_base::stop_bits::type serial_port_base::stop_bits::value() const { return value_; } inline unsigned int serial_port_base::character_size::value() const { return value_; } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_SERIAL_PORT_BASE_HPP ================================================ FILE: src/third_party/asio/impl/serial_port_base.ipp ================================================ // // impl/serial_port_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_SERIAL_PORT_BASE_IPP #define ASIO_IMPL_SERIAL_PORT_BASE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_SERIAL_PORT) #include #include "asio/error.hpp" #include "asio/serial_port_base.hpp" #include "asio/detail/throw_exception.hpp" #if defined(GENERATING_DOCUMENTATION) # define ASIO_OPTION_STORAGE implementation_defined #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) # define ASIO_OPTION_STORAGE DCB #else # define ASIO_OPTION_STORAGE termios #endif #include "asio/detail/push_options.hpp" namespace asio { ASIO_SYNC_OP_VOID serial_port_base::baud_rate::store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) storage.BaudRate = value_; #else speed_t baud; switch (value_) { // Do POSIX-specified rates first. case 0: baud = B0; break; case 50: baud = B50; break; case 75: baud = B75; break; case 110: baud = B110; break; case 134: baud = B134; break; case 150: baud = B150; break; case 200: baud = B200; break; case 300: baud = B300; break; case 600: baud = B600; break; case 1200: baud = B1200; break; case 1800: baud = B1800; break; case 2400: baud = B2400; break; case 4800: baud = B4800; break; case 9600: baud = B9600; break; case 19200: baud = B19200; break; case 38400: baud = B38400; break; // And now the extended ones conditionally. # ifdef B7200 case 7200: baud = B7200; break; # endif # ifdef B14400 case 14400: baud = B14400; break; # endif # ifdef B57600 case 57600: baud = B57600; break; # endif # ifdef B115200 case 115200: baud = B115200; break; # endif # ifdef B230400 case 230400: baud = B230400; break; # endif # ifdef B460800 case 460800: baud = B460800; break; # endif # ifdef B500000 case 500000: baud = B500000; break; # endif # ifdef B576000 case 576000: baud = B576000; break; # endif # ifdef B921600 case 921600: baud = B921600; break; # endif # ifdef B1000000 case 1000000: baud = B1000000; break; # endif # ifdef B1152000 case 1152000: baud = B1152000; break; # endif # ifdef B2000000 case 2000000: baud = B2000000; break; # endif # ifdef B3000000 case 3000000: baud = B3000000; break; # endif # ifdef B3500000 case 3500000: baud = B3500000; break; # endif # ifdef B4000000 case 4000000: baud = B4000000; break; # endif default: ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE) ::cfsetspeed(&storage, baud); # else ::cfsetispeed(&storage, baud); ::cfsetospeed(&storage, baud); # endif #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID serial_port_base::baud_rate::load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) value_ = storage.BaudRate; #else speed_t baud = ::cfgetospeed(&storage); switch (baud) { // First do those specified by POSIX. case B0: value_ = 0; break; case B50: value_ = 50; break; case B75: value_ = 75; break; case B110: value_ = 110; break; case B134: value_ = 134; break; case B150: value_ = 150; break; case B200: value_ = 200; break; case B300: value_ = 300; break; case B600: value_ = 600; break; case B1200: value_ = 1200; break; case B1800: value_ = 1800; break; case B2400: value_ = 2400; break; case B4800: value_ = 4800; break; case B9600: value_ = 9600; break; case B19200: value_ = 19200; break; case B38400: value_ = 38400; break; // Now conditionally handle a bunch of extended rates. # ifdef B7200 case B7200: value_ = 7200; break; # endif # ifdef B14400 case B14400: value_ = 14400; break; # endif # ifdef B57600 case B57600: value_ = 57600; break; # endif # ifdef B115200 case B115200: value_ = 115200; break; # endif # ifdef B230400 case B230400: value_ = 230400; break; # endif # ifdef B460800 case B460800: value_ = 460800; break; # endif # ifdef B500000 case B500000: value_ = 500000; break; # endif # ifdef B576000 case B576000: value_ = 576000; break; # endif # ifdef B921600 case B921600: value_ = 921600; break; # endif # ifdef B1000000 case B1000000: value_ = 1000000; break; # endif # ifdef B1152000 case B1152000: value_ = 1152000; break; # endif # ifdef B2000000 case B2000000: value_ = 2000000; break; # endif # ifdef B3000000 case B3000000: value_ = 3000000; break; # endif # ifdef B3500000 case B3500000: value_ = 3500000; break; # endif # ifdef B4000000 case B4000000: value_ = 4000000; break; # endif default: value_ = 0; ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } serial_port_base::flow_control::flow_control( serial_port_base::flow_control::type t) : value_(t) { if (t != none && t != software && t != hardware) { std::out_of_range ex("invalid flow_control value"); asio::detail::throw_exception(ex); } } ASIO_SYNC_OP_VOID serial_port_base::flow_control::store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) storage.fOutxCtsFlow = FALSE; storage.fOutxDsrFlow = FALSE; storage.fTXContinueOnXoff = TRUE; storage.fDtrControl = DTR_CONTROL_ENABLE; storage.fDsrSensitivity = FALSE; storage.fOutX = FALSE; storage.fInX = FALSE; storage.fRtsControl = RTS_CONTROL_ENABLE; switch (value_) { case none: break; case software: storage.fOutX = TRUE; storage.fInX = TRUE; break; case hardware: storage.fOutxCtsFlow = TRUE; storage.fRtsControl = RTS_CONTROL_HANDSHAKE; break; default: break; } #else switch (value_) { case none: storage.c_iflag &= ~(IXOFF | IXON); # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE) storage.c_cflag &= ~CRTSCTS; # elif defined(__QNXNTO__) storage.c_cflag &= ~(IHFLOW | OHFLOW); # endif break; case software: storage.c_iflag |= IXOFF | IXON; # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE) storage.c_cflag &= ~CRTSCTS; # elif defined(__QNXNTO__) storage.c_cflag &= ~(IHFLOW | OHFLOW); # endif break; case hardware: # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE) storage.c_iflag &= ~(IXOFF | IXON); storage.c_cflag |= CRTSCTS; break; # elif defined(__QNXNTO__) storage.c_iflag &= ~(IXOFF | IXON); storage.c_cflag |= (IHFLOW | OHFLOW); break; # else ec = asio::error::operation_not_supported; ASIO_SYNC_OP_VOID_RETURN(ec); # endif default: break; } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID serial_port_base::flow_control::load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) if (storage.fOutX && storage.fInX) { value_ = software; } else if (storage.fOutxCtsFlow && storage.fRtsControl == RTS_CONTROL_HANDSHAKE) { value_ = hardware; } else { value_ = none; } #else if (storage.c_iflag & (IXOFF | IXON)) { value_ = software; } # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE) else if (storage.c_cflag & CRTSCTS) { value_ = hardware; } # elif defined(__QNXNTO__) else if (storage.c_cflag & IHFLOW && storage.c_cflag & OHFLOW) { value_ = hardware; } # endif else { value_ = none; } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } serial_port_base::parity::parity(serial_port_base::parity::type t) : value_(t) { if (t != none && t != odd && t != even) { std::out_of_range ex("invalid parity value"); asio::detail::throw_exception(ex); } } ASIO_SYNC_OP_VOID serial_port_base::parity::store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) switch (value_) { case none: storage.fParity = FALSE; storage.Parity = NOPARITY; break; case odd: storage.fParity = TRUE; storage.Parity = ODDPARITY; break; case even: storage.fParity = TRUE; storage.Parity = EVENPARITY; break; default: break; } #else switch (value_) { case none: storage.c_iflag |= IGNPAR; storage.c_cflag &= ~(PARENB | PARODD); break; case even: storage.c_iflag &= ~(IGNPAR | PARMRK); storage.c_iflag |= INPCK; storage.c_cflag |= PARENB; storage.c_cflag &= ~PARODD; break; case odd: storage.c_iflag &= ~(IGNPAR | PARMRK); storage.c_iflag |= INPCK; storage.c_cflag |= (PARENB | PARODD); break; default: break; } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID serial_port_base::parity::load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) if (storage.Parity == EVENPARITY) { value_ = even; } else if (storage.Parity == ODDPARITY) { value_ = odd; } else { value_ = none; } #else if (storage.c_cflag & PARENB) { if (storage.c_cflag & PARODD) { value_ = odd; } else { value_ = even; } } else { value_ = none; } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } serial_port_base::stop_bits::stop_bits( serial_port_base::stop_bits::type t) : value_(t) { if (t != one && t != onepointfive && t != two) { std::out_of_range ex("invalid stop_bits value"); asio::detail::throw_exception(ex); } } ASIO_SYNC_OP_VOID serial_port_base::stop_bits::store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) switch (value_) { case one: storage.StopBits = ONESTOPBIT; break; case onepointfive: storage.StopBits = ONE5STOPBITS; break; case two: storage.StopBits = TWOSTOPBITS; break; default: break; } #else switch (value_) { case one: storage.c_cflag &= ~CSTOPB; break; case two: storage.c_cflag |= CSTOPB; break; default: ec = asio::error::operation_not_supported; ASIO_SYNC_OP_VOID_RETURN(ec); } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID serial_port_base::stop_bits::load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) if (storage.StopBits == ONESTOPBIT) { value_ = one; } else if (storage.StopBits == ONE5STOPBITS) { value_ = onepointfive; } else if (storage.StopBits == TWOSTOPBITS) { value_ = two; } else { value_ = one; } #else value_ = (storage.c_cflag & CSTOPB) ? two : one; #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } serial_port_base::character_size::character_size(unsigned int t) : value_(t) { if (t < 5 || t > 8) { std::out_of_range ex("invalid character_size value"); asio::detail::throw_exception(ex); } } ASIO_SYNC_OP_VOID serial_port_base::character_size::store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) storage.ByteSize = value_; #else storage.c_cflag &= ~CSIZE; switch (value_) { case 5: storage.c_cflag |= CS5; break; case 6: storage.c_cflag |= CS6; break; case 7: storage.c_cflag |= CS7; break; case 8: storage.c_cflag |= CS8; break; default: break; } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID serial_port_base::character_size::load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) value_ = storage.ByteSize; #else if ((storage.c_cflag & CSIZE) == CS5) { value_ = 5; } else if ((storage.c_cflag & CSIZE) == CS6) { value_ = 6; } else if ((storage.c_cflag & CSIZE) == CS7) { value_ = 7; } else if ((storage.c_cflag & CSIZE) == CS8) { value_ = 8; } else { // Hmmm, use 8 for now. value_ = 8; } #endif ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } } // namespace asio #include "asio/detail/pop_options.hpp" #undef ASIO_OPTION_STORAGE #endif // defined(ASIO_HAS_SERIAL_PORT) #endif // ASIO_IMPL_SERIAL_PORT_BASE_IPP ================================================ FILE: src/third_party/asio/impl/spawn.hpp ================================================ // // impl/spawn.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_SPAWN_HPP #define ASIO_IMPL_SPAWN_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/async_result.hpp" #include "asio/bind_executor.hpp" #include "asio/detail/atomic_count.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/type_traits.hpp" #include "asio/system_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class coro_handler { public: coro_handler(basic_yield_context ctx) : coro_(ctx.coro_.lock()), ca_(ctx.ca_), handler_(ctx.handler_), ready_(0), ec_(ctx.ec_), value_(0) { } void operator()(T value) { *ec_ = asio::error_code(); *value_ = ASIO_MOVE_CAST(T)(value); if (--*ready_ == 0) (*coro_)(); } void operator()(asio::error_code ec, T value) { *ec_ = ec; *value_ = ASIO_MOVE_CAST(T)(value); if (--*ready_ == 0) (*coro_)(); } //private: shared_ptr::callee_type> coro_; typename basic_yield_context::caller_type& ca_; Handler handler_; atomic_count* ready_; asio::error_code* ec_; T* value_; }; template class coro_handler { public: coro_handler(basic_yield_context ctx) : coro_(ctx.coro_.lock()), ca_(ctx.ca_), handler_(ctx.handler_), ready_(0), ec_(ctx.ec_) { } void operator()() { *ec_ = asio::error_code(); if (--*ready_ == 0) (*coro_)(); } void operator()(asio::error_code ec) { *ec_ = ec; if (--*ready_ == 0) (*coro_)(); } //private: shared_ptr::callee_type> coro_; typename basic_yield_context::caller_type& ca_; Handler handler_; atomic_count* ready_; asio::error_code* ec_; }; template inline void* asio_handler_allocate(std::size_t size, coro_handler* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, coro_handler* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation(coro_handler*) { return true; } template inline void asio_handler_invoke(Function& function, coro_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, coro_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class coro_async_result { public: typedef coro_handler completion_handler_type; typedef T return_type; explicit coro_async_result(completion_handler_type& h) : handler_(h), ca_(h.ca_), ready_(2) { h.ready_ = &ready_; out_ec_ = h.ec_; if (!out_ec_) h.ec_ = &ec_; h.value_ = &value_; } return_type get() { // Must not hold shared_ptr to coro while suspended. handler_.coro_.reset(); if (--ready_ != 0) ca_(); if (!out_ec_ && ec_) throw asio::system_error(ec_); return ASIO_MOVE_CAST(return_type)(value_); } private: completion_handler_type& handler_; typename basic_yield_context::caller_type& ca_; atomic_count ready_; asio::error_code* out_ec_; asio::error_code ec_; return_type value_; }; template class coro_async_result { public: typedef coro_handler completion_handler_type; typedef void return_type; explicit coro_async_result(completion_handler_type& h) : handler_(h), ca_(h.ca_), ready_(2) { h.ready_ = &ready_; out_ec_ = h.ec_; if (!out_ec_) h.ec_ = &ec_; } void get() { // Must not hold shared_ptr to coro while suspended. handler_.coro_.reset(); if (--ready_ != 0) ca_(); if (!out_ec_ && ec_) throw asio::system_error(ec_); } private: completion_handler_type& handler_; typename basic_yield_context::caller_type& ca_; atomic_count ready_; asio::error_code* out_ec_; asio::error_code ec_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template class async_result, ReturnType()> : public detail::coro_async_result { public: explicit async_result( typename detail::coro_async_result::completion_handler_type& h) : detail::coro_async_result(h) { } }; template class async_result, ReturnType(Arg1)> : public detail::coro_async_result::type> { public: explicit async_result( typename detail::coro_async_result::type>::completion_handler_type& h) : detail::coro_async_result::type>(h) { } }; template class async_result, ReturnType(asio::error_code)> : public detail::coro_async_result { public: explicit async_result( typename detail::coro_async_result::completion_handler_type& h) : detail::coro_async_result(h) { } }; template class async_result, ReturnType(asio::error_code, Arg2)> : public detail::coro_async_result::type> { public: explicit async_result( typename detail::coro_async_result::type>::completion_handler_type& h) : detail::coro_async_result::type>(h) { } }; template struct associated_allocator, Allocator> { typedef typename associated_allocator::type type; static type get(const detail::coro_handler& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor, Executor> { typedef typename associated_executor::type type; static type get(const detail::coro_handler& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; namespace detail { template struct spawn_data : private noncopyable { template spawn_data(ASIO_MOVE_ARG(Hand) handler, bool call_handler, ASIO_MOVE_ARG(Func) function) : handler_(ASIO_MOVE_CAST(Hand)(handler)), call_handler_(call_handler), function_(ASIO_MOVE_CAST(Func)(function)) { } weak_ptr::callee_type> coro_; Handler handler_; bool call_handler_; Function function_; }; template struct coro_entry_point { void operator()(typename basic_yield_context::caller_type& ca) { shared_ptr > data(data_); #if !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2) ca(); // Yield until coroutine pointer has been initialised. #endif // !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2) const basic_yield_context yield( data->coro_, ca, data->handler_); (data->function_)(yield); if (data->call_handler_) (data->handler_)(); } shared_ptr > data_; }; template struct spawn_helper { void operator()() { typedef typename basic_yield_context::callee_type callee_type; coro_entry_point entry_point = { data_ }; shared_ptr coro(new callee_type(entry_point, attributes_)); data_->coro_ = coro; (*coro)(); } shared_ptr > data_; boost::coroutines::attributes attributes_; }; template inline void asio_handler_invoke(Function& function, spawn_helper* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->data_->handler_); } template inline void asio_handler_invoke(const Function& function, spawn_helper* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->data_->handler_); } inline void default_spawn_handler() {} } // namespace detail template inline void spawn(ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes) { typedef typename decay::type function_type; typename associated_executor::type ex( (get_associated_executor)(function)); asio::spawn(ex, ASIO_MOVE_CAST(Function)(function), attributes); } template void spawn(ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes, typename enable_if::type>::value && !is_convertible::value>::type*) { typedef typename decay::type handler_type; typedef typename decay::type function_type; typename associated_executor::type ex( (get_associated_executor)(handler)); typename associated_allocator::type a( (get_associated_allocator)(handler)); detail::spawn_helper helper; helper.data_.reset( new detail::spawn_data( ASIO_MOVE_CAST(Handler)(handler), true, ASIO_MOVE_CAST(Function)(function))); helper.attributes_ = attributes; ex.dispatch(helper, a); } template void spawn(basic_yield_context ctx, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes) { typedef typename decay::type function_type; Handler handler(ctx.handler_); // Explicit copy that might be moved from. typename associated_executor::type ex( (get_associated_executor)(handler)); typename associated_allocator::type a( (get_associated_allocator)(handler)); detail::spawn_helper helper; helper.data_.reset( new detail::spawn_data( ASIO_MOVE_CAST(Handler)(handler), false, ASIO_MOVE_CAST(Function)(function))); helper.attributes_ = attributes; ex.dispatch(helper, a); } template inline void spawn(const Executor& ex, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes, typename enable_if::value>::type*) { asio::spawn(asio::strand(ex), ASIO_MOVE_CAST(Function)(function), attributes); } template inline void spawn(const strand& ex, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes) { asio::spawn(asio::bind_executor( ex, &detail::default_spawn_handler), ASIO_MOVE_CAST(Function)(function), attributes); } template inline void spawn(const asio::io_context::strand& s, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes) { asio::spawn(asio::bind_executor( s, &detail::default_spawn_handler), ASIO_MOVE_CAST(Function)(function), attributes); } template inline void spawn(ExecutionContext& ctx, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes, typename enable_if::value>::type*) { asio::spawn(ctx.get_executor(), ASIO_MOVE_CAST(Function)(function), attributes); } #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_SPAWN_HPP ================================================ FILE: src/third_party/asio/impl/src.cpp ================================================ // // impl/src.cpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #if defined(_MSC_VER) \ || defined(__BORLANDC__) \ || defined(__DMC__) # pragma message ( \ "This file is deprecated. " \ "Please #include instead.") #elif defined(__GNUC__) \ || defined(__HP_aCC) \ || defined(__SUNPRO_CC) \ || defined(__IBMCPP__) # warning "This file is deprecated." # warning "Please #include instead." #endif #include "asio/impl/src.hpp" ================================================ FILE: src/third_party/asio/impl/src.hpp ================================================ // // impl/src.hpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_SRC_HPP #define ASIO_IMPL_SRC_HPP #define ASIO_SOURCE #include "asio/detail/config.hpp" #if defined(ASIO_HEADER_ONLY) # error Do not compile Asio library source with ASIO_HEADER_ONLY defined #endif #include "asio/impl/error.ipp" #include "asio/impl/error_code.ipp" #include "asio/impl/execution_context.ipp" #include "asio/impl/executor.ipp" #include "asio/impl/handler_alloc_hook.ipp" #include "asio/impl/io_context.ipp" #include "asio/impl/serial_port_base.ipp" #include "asio/impl/system_context.ipp" #include "asio/impl/thread_pool.ipp" #include "asio/detail/impl/buffer_sequence_adapter.ipp" #include "asio/detail/impl/descriptor_ops.ipp" #include "asio/detail/impl/dev_poll_reactor.ipp" #include "asio/detail/impl/epoll_reactor.ipp" #include "asio/detail/impl/eventfd_select_interrupter.ipp" #include "asio/detail/impl/handler_tracking.ipp" #include "asio/detail/impl/kqueue_reactor.ipp" #include "asio/detail/impl/null_event.ipp" #include "asio/detail/impl/pipe_select_interrupter.ipp" #include "asio/detail/impl/posix_event.ipp" #include "asio/detail/impl/posix_mutex.ipp" #include "asio/detail/impl/posix_thread.ipp" #include "asio/detail/impl/posix_tss_ptr.ipp" #include "asio/detail/impl/reactive_descriptor_service.ipp" #include "asio/detail/impl/reactive_serial_port_service.ipp" #include "asio/detail/impl/reactive_socket_service_base.ipp" #include "asio/detail/impl/resolver_service_base.ipp" #include "asio/detail/impl/scheduler.ipp" #include "asio/detail/impl/select_reactor.ipp" #include "asio/detail/impl/service_registry.ipp" #include "asio/detail/impl/signal_set_service.ipp" #include "asio/detail/impl/socket_ops.ipp" #include "asio/detail/impl/socket_select_interrupter.ipp" #include "asio/detail/impl/strand_executor_service.ipp" #include "asio/detail/impl/strand_service.ipp" #include "asio/detail/impl/throw_error.ipp" #include "asio/detail/impl/timer_queue_ptime.ipp" #include "asio/detail/impl/timer_queue_set.ipp" #include "asio/detail/impl/win_iocp_handle_service.ipp" #include "asio/detail/impl/win_iocp_io_context.ipp" #include "asio/detail/impl/win_iocp_serial_port_service.ipp" #include "asio/detail/impl/win_iocp_socket_service_base.ipp" #include "asio/detail/impl/win_event.ipp" #include "asio/detail/impl/win_mutex.ipp" #include "asio/detail/impl/win_object_handle_service.ipp" #include "asio/detail/impl/win_static_mutex.ipp" #include "asio/detail/impl/win_thread.ipp" #include "asio/detail/impl/win_tss_ptr.ipp" #include "asio/detail/impl/winrt_ssocket_service_base.ipp" #include "asio/detail/impl/winrt_timer_scheduler.ipp" #include "asio/detail/impl/winsock_init.ipp" #include "asio/generic/detail/impl/endpoint.ipp" #include "asio/ip/impl/address.ipp" #include "asio/ip/impl/address_v4.ipp" #include "asio/ip/impl/address_v6.ipp" #include "asio/ip/impl/host_name.ipp" #include "asio/ip/impl/network_v4.ipp" #include "asio/ip/impl/network_v6.ipp" #include "asio/ip/detail/impl/endpoint.ipp" #include "asio/local/detail/impl/endpoint.ipp" #endif // ASIO_IMPL_SRC_HPP ================================================ FILE: src/third_party/asio/impl/system_context.hpp ================================================ // // impl/system_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_SYSTEM_CONTEXT_HPP #define ASIO_IMPL_SYSTEM_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/system_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { inline system_context::executor_type system_context::get_executor() ASIO_NOEXCEPT { return system_executor(); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_SYSTEM_CONTEXT_HPP ================================================ FILE: src/third_party/asio/impl/system_context.ipp ================================================ // // impl/system_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_SYSTEM_CONTEXT_IPP #define ASIO_IMPL_SYSTEM_CONTEXT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/system_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { struct system_context::thread_function { detail::scheduler* scheduler_; void operator()() { asio::error_code ec; scheduler_->run(ec); } }; system_context::system_context() : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false))) { scheduler_.work_started(); thread_function f = { &scheduler_ }; std::size_t num_threads = detail::thread::hardware_concurrency() * 2; threads_.create_threads(f, num_threads ? num_threads : 2); } system_context::~system_context() { scheduler_.work_finished(); scheduler_.stop(); threads_.join(); } void system_context::stop() { scheduler_.stop(); } bool system_context::stopped() const ASIO_NOEXCEPT { return scheduler_.stopped(); } void system_context::join() { scheduler_.work_finished(); threads_.join(); } detail::scheduler& system_context::add_scheduler(detail::scheduler* s) { detail::scoped_ptr scoped_impl(s); asio::add_service(*this, scoped_impl.get()); return *scoped_impl.release(); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_SYSTEM_CONTEXT_IPP ================================================ FILE: src/third_party/asio/impl/system_executor.hpp ================================================ // // impl/system_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_SYSTEM_EXECUTOR_HPP #define ASIO_IMPL_SYSTEM_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/executor_op.hpp" #include "asio/detail/global.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/detail/type_traits.hpp" #include "asio/system_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { inline system_context& system_executor::context() const ASIO_NOEXCEPT { return detail::global(); } template void system_executor::dispatch( ASIO_MOVE_ARG(Function) f, const Allocator&) const { typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); asio_handler_invoke_helpers::invoke(tmp, tmp); } template void system_executor::post( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; system_context& ctx = detail::global(); // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((ctx, *p.p, "system_executor", &this->context(), 0, "post")); ctx.scheduler_.post_immediate_completion(p.p, false); p.v = p.p = 0; } template void system_executor::defer( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; system_context& ctx = detail::global(); // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((ctx, *p.p, "system_executor", &this->context(), 0, "defer")); ctx.scheduler_.post_immediate_completion(p.p, true); p.v = p.p = 0; } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_SYSTEM_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/impl/thread_pool.hpp ================================================ // // impl/thread_pool.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_THREAD_POOL_HPP #define ASIO_IMPL_THREAD_POOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/executor_op.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { inline thread_pool::executor_type thread_pool::get_executor() ASIO_NOEXCEPT { return executor_type(*this); } inline thread_pool& thread_pool::executor_type::context() const ASIO_NOEXCEPT { return pool_; } inline void thread_pool::executor_type::on_work_started() const ASIO_NOEXCEPT { pool_.scheduler_.work_started(); } inline void thread_pool::executor_type::on_work_finished() const ASIO_NOEXCEPT { pool_.scheduler_.work_finished(); } template void thread_pool::executor_type::dispatch( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; // Invoke immediately if we are already inside the thread pool. if (pool_.scheduler_.can_dispatch()) { // Make a local, non-const copy of the function. function_type tmp(ASIO_MOVE_CAST(Function)(f)); detail::fenced_block b(detail::fenced_block::full); asio_handler_invoke_helpers::invoke(tmp, tmp); return; } // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((pool_, *p.p, "thread_pool", &this->context(), 0, "dispatch")); pool_.scheduler_.post_immediate_completion(p.p, false); p.v = p.p = 0; } template void thread_pool::executor_type::post( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((pool_, *p.p, "thread_pool", &this->context(), 0, "post")); pool_.scheduler_.post_immediate_completion(p.p, false); p.v = p.p = 0; } template void thread_pool::executor_type::defer( ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typedef typename decay::type function_type; // Allocate and construct an operation to wrap the function. typedef detail::executor_op op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 }; p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((pool_, *p.p, "thread_pool", &this->context(), 0, "defer")); pool_.scheduler_.post_immediate_completion(p.p, true); p.v = p.p = 0; } inline bool thread_pool::executor_type::running_in_this_thread() const ASIO_NOEXCEPT { return pool_.scheduler_.can_dispatch(); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_THREAD_POOL_HPP ================================================ FILE: src/third_party/asio/impl/thread_pool.ipp ================================================ // // impl/thread_pool.ipp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_THREAD_POOL_IPP #define ASIO_IMPL_THREAD_POOL_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/thread_pool.hpp" #include "asio/detail/push_options.hpp" namespace asio { struct thread_pool::thread_function { detail::scheduler* scheduler_; void operator()() { asio::error_code ec; scheduler_->run(ec); } }; thread_pool::thread_pool() : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false))) { scheduler_.work_started(); thread_function f = { &scheduler_ }; std::size_t num_threads = detail::thread::hardware_concurrency() * 2; threads_.create_threads(f, num_threads ? num_threads : 2); } thread_pool::thread_pool(std::size_t num_threads) : scheduler_(add_scheduler(new detail::scheduler( *this, num_threads == 1 ? 1 : 0, false))) { scheduler_.work_started(); thread_function f = { &scheduler_ }; threads_.create_threads(f, num_threads); } thread_pool::~thread_pool() { stop(); join(); } void thread_pool::stop() { scheduler_.stop(); } void thread_pool::join() { if (!threads_.empty()) { scheduler_.work_finished(); threads_.join(); } } detail::scheduler& thread_pool::add_scheduler(detail::scheduler* s) { detail::scoped_ptr scoped_impl(s); asio::add_service(*this, scoped_impl.get()); return *scoped_impl.release(); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_THREAD_POOL_IPP ================================================ FILE: src/third_party/asio/impl/use_awaitable.hpp ================================================ // // impl/use_awaitable.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_USE_AWAITABLE_HPP #define ASIO_IMPL_USE_AWAITABLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class awaitable_handler_base : public awaitable_thread { public: typedef void result_type; typedef awaitable awaitable_type; // Construct from the entry point of a new thread of execution. awaitable_handler_base(awaitable a, const Executor& ex) : awaitable_thread(std::move(a), ex) { } // Transfer ownership from another awaitable_thread. explicit awaitable_handler_base(awaitable_thread* h) : awaitable_thread(std::move(*h)) { } protected: awaitable_frame* frame() noexcept { return static_cast*>(this->top_of_stack_); } }; template class awaitable_handler; template class awaitable_handler : public awaitable_handler_base { public: using awaitable_handler_base::awaitable_handler_base; void operator()() { this->frame()->attach_thread(this); this->frame()->return_void(); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base { public: using awaitable_handler_base::awaitable_handler_base; void operator()(const asio::error_code& ec) { this->frame()->attach_thread(this); if (ec) this->frame()->set_error(ec); else this->frame()->return_void(); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base { public: using awaitable_handler_base::awaitable_handler_base; void operator()(std::exception_ptr ex) { this->frame()->attach_thread(this); if (ex) this->frame()->set_except(ex); else this->frame()->return_void(); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base { public: using awaitable_handler_base::awaitable_handler_base; template void operator()(Arg&& arg) { this->frame()->attach_thread(this); this->frame()->return_value(std::forward(arg)); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base { public: using awaitable_handler_base::awaitable_handler_base; template void operator()(const asio::error_code& ec, Arg&& arg) { this->frame()->attach_thread(this); if (ec) this->frame()->set_error(ec); else this->frame()->return_value(std::forward(arg)); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base { public: using awaitable_handler_base::awaitable_handler_base; template void operator()(std::exception_ptr ex, Arg&& arg) { this->frame()->attach_thread(this); if (ex) this->frame()->set_except(ex); else this->frame()->return_value(std::forward(arg)); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base> { public: using awaitable_handler_base>::awaitable_handler_base; template void operator()(Args&&... args) { this->frame()->attach_thread(this); this->frame()->return_values(std::forward(args)...); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base> { public: using awaitable_handler_base>::awaitable_handler_base; template void operator()(const asio::error_code& ec, Args&&... args) { this->frame()->attach_thread(this); if (ec) this->frame()->set_error(ec); else this->frame()->return_values(std::forward(args)...); this->frame()->pop_frame(); this->pump(); } }; template class awaitable_handler : public awaitable_handler_base> { public: using awaitable_handler_base>::awaitable_handler_base; template void operator()(std::exception_ptr ex, Args&&... args) { this->frame()->attach_thread(this); if (ex) this->frame()->set_except(ex); else this->frame()->return_values(std::forward(args)...); this->frame()->pop_frame(); this->pump(); } }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template class async_result, R(Args...)> { public: typedef typename detail::awaitable_handler< Executor, typename decay::type...> handler_type; typedef typename handler_type::awaitable_type return_type; #if defined(_MSC_VER) template static T dummy_return() { return std::move(*static_cast(nullptr)); } template <> static void dummy_return() { } #endif // defined(_MSC_VER) template static return_type initiate(Initiation initiation, use_awaitable_t, InitArgs... args) { co_await [&](auto* frame) { handler_type handler(frame->detach_thread()); std::move(initiation)(std::move(handler), std::move(args)...); return static_cast(nullptr); }; for (;;) {} // Never reached. #if defined(_MSC_VER) co_return dummy_return(); #endif // defined(_MSC_VER) } }; #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_USE_AWAITABLE_HPP ================================================ FILE: src/third_party/asio/impl/use_future.hpp ================================================ // // impl/use_future.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_USE_FUTURE_HPP #define ASIO_IMPL_USE_FUTURE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/detail/memory.hpp" #include "asio/error_code.hpp" #include "asio/packaged_task.hpp" #include "asio/system_error.hpp" #include "asio/system_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template inline void promise_invoke_and_set(std::promise& p, F& f, ASIO_MOVE_ARG(Args)... args) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) { p.set_value(f(ASIO_MOVE_CAST(Args)(args)...)); } #if !defined(ASIO_NO_EXCEPTIONS) catch (...) { p.set_exception(std::current_exception()); } #endif // !defined(ASIO_NO_EXCEPTIONS) } template inline void promise_invoke_and_set(std::promise& p, F& f, ASIO_MOVE_ARG(Args)... args) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) { f(ASIO_MOVE_CAST(Args)(args)...); p.set_value(); } #if !defined(ASIO_NO_EXCEPTIONS) catch (...) { p.set_exception(std::current_exception()); } #endif // !defined(ASIO_NO_EXCEPTIONS) } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template inline void promise_invoke_and_set(std::promise& p, F& f) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) { p.set_value(f()); } #if !defined(ASIO_NO_EXCEPTIONS) catch (...) { p.set_exception(std::current_exception()); } #endif // !defined(ASIO_NO_EXCEPTIONS) } template inline void promise_invoke_and_set(std::promise& p, F& f) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) { f(); p.set_value(); #if !defined(ASIO_NO_EXCEPTIONS) } catch (...) { p.set_exception(std::current_exception()); } #endif // !defined(ASIO_NO_EXCEPTIONS) } #if defined(ASIO_NO_EXCEPTIONS) #define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \ template \ inline void promise_invoke_and_set(std::promise& p, \ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \ } \ \ template \ inline void promise_invoke_and_set(std::promise& p, \ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ f(ASIO_VARIADIC_MOVE_ARGS(n)); \ p.set_value(); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF) #undef ASIO_PRIVATE_PROMISE_INVOKE_DEF #else // defined(ASIO_NO_EXCEPTIONS) #define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \ template \ inline void promise_invoke_and_set(std::promise& p, \ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ try \ { \ p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \ } \ catch (...) \ { \ p.set_exception(std::current_exception()); \ } \ } \ \ template \ inline void promise_invoke_and_set(std::promise& p, \ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ try \ { \ f(ASIO_VARIADIC_MOVE_ARGS(n)); \ p.set_value(); \ } \ catch (...) \ { \ p.set_exception(std::current_exception()); \ } \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF) #undef ASIO_PRIVATE_PROMISE_INVOKE_DEF #endif // defined(ASIO_NO_EXCEPTIONS) #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) // A function object adapter to invoke a nullary function object and capture // any exception thrown into a promise. template class promise_invoker { public: promise_invoker(const shared_ptr >& p, ASIO_MOVE_ARG(F) f) : p_(p), f_(ASIO_MOVE_CAST(F)(f)) { } void operator()() { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) { f_(); } #if !defined(ASIO_NO_EXCEPTIONS) catch (...) { p_->set_exception(std::current_exception()); } #endif // !defined(ASIO_NO_EXCEPTIONS) } private: shared_ptr > p_; typename decay::type f_; }; // An executor that adapts the system_executor to capture any exeption thrown // by a submitted function object and save it into a promise. template class promise_executor { public: explicit promise_executor(const shared_ptr >& p) : p_(p) { } execution_context& context() const ASIO_NOEXCEPT { return system_executor().context(); } void on_work_started() const ASIO_NOEXCEPT {} void on_work_finished() const ASIO_NOEXCEPT {} template void dispatch(ASIO_MOVE_ARG(F) f, const A&) const { promise_invoker(p_, ASIO_MOVE_CAST(F)(f))(); } template void post(ASIO_MOVE_ARG(F) f, const A& a) const { system_executor().post( promise_invoker(p_, ASIO_MOVE_CAST(F)(f)), a); } template void defer(ASIO_MOVE_ARG(F) f, const A& a) const { system_executor().defer( promise_invoker(p_, ASIO_MOVE_CAST(F)(f)), a); } friend bool operator==(const promise_executor& a, const promise_executor& b) ASIO_NOEXCEPT { return a.p_ == b.p_; } friend bool operator!=(const promise_executor& a, const promise_executor& b) ASIO_NOEXCEPT { return a.p_ != b.p_; } private: shared_ptr > p_; }; // The base class for all completion handlers that create promises. template class promise_creator { public: typedef promise_executor executor_type; executor_type get_executor() const ASIO_NOEXCEPT { return executor_type(p_); } typedef std::future future_type; future_type get_future() { return p_->get_future(); } protected: template void create_promise(const Allocator& a) { ASIO_REBIND_ALLOC(Allocator, char) b(a); p_ = std::allocate_shared>(b, std::allocator_arg, b); } shared_ptr > p_; }; // For completion signature void(). class promise_handler_0 : public promise_creator { public: void operator()() { this->p_->set_value(); } }; // For completion signature void(error_code). class promise_handler_ec_0 : public promise_creator { public: void operator()(const asio::error_code& ec) { if (ec) { this->p_->set_exception( std::make_exception_ptr( asio::system_error(ec))); } else { this->p_->set_value(); } } }; // For completion signature void(exception_ptr). class promise_handler_ex_0 : public promise_creator { public: void operator()(const std::exception_ptr& ex) { if (ex) { this->p_->set_exception(ex); } else { this->p_->set_value(); } } }; // For completion signature void(T). template class promise_handler_1 : public promise_creator { public: template void operator()(ASIO_MOVE_ARG(Arg) arg) { this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); } }; // For completion signature void(error_code, T). template class promise_handler_ec_1 : public promise_creator { public: template void operator()(const asio::error_code& ec, ASIO_MOVE_ARG(Arg) arg) { if (ec) { this->p_->set_exception( std::make_exception_ptr( asio::system_error(ec))); } else this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); } }; // For completion signature void(exception_ptr, T). template class promise_handler_ex_1 : public promise_creator { public: template void operator()(const std::exception_ptr& ex, ASIO_MOVE_ARG(Arg) arg) { if (ex) this->p_->set_exception(ex); else this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); } }; // For completion signature void(T1, ..., Tn); template class promise_handler_n : public promise_creator { public: #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()(ASIO_MOVE_ARG(Args)... args) { this->p_->set_value( std::forward_as_tuple( ASIO_MOVE_CAST(Args)(args)...)); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) #define ASIO_PRIVATE_CALL_OP_DEF(n) \ template \ void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \ {\ this->p_->set_value( \ std::forward_as_tuple( \ ASIO_VARIADIC_MOVE_ARGS(n))); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) #undef ASIO_PRIVATE_CALL_OP_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; // For completion signature void(error_code, T1, ..., Tn); template class promise_handler_ec_n : public promise_creator { public: #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()(const asio::error_code& ec, ASIO_MOVE_ARG(Args)... args) { if (ec) { this->p_->set_exception( std::make_exception_ptr( asio::system_error(ec))); } else { this->p_->set_value( std::forward_as_tuple( ASIO_MOVE_CAST(Args)(args)...)); } } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) #define ASIO_PRIVATE_CALL_OP_DEF(n) \ template \ void operator()(const asio::error_code& ec, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ {\ if (ec) \ { \ this->p_->set_exception( \ std::make_exception_ptr( \ asio::system_error(ec))); \ } \ else \ { \ this->p_->set_value( \ std::forward_as_tuple( \ ASIO_VARIADIC_MOVE_ARGS(n))); \ } \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) #undef ASIO_PRIVATE_CALL_OP_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; // For completion signature void(exception_ptr, T1, ..., Tn); template class promise_handler_ex_n : public promise_creator { public: #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()(const std::exception_ptr& ex, ASIO_MOVE_ARG(Args)... args) { if (ex) this->p_->set_exception(ex); else { this->p_->set_value( std::forward_as_tuple( ASIO_MOVE_CAST(Args)(args)...)); } } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) #define ASIO_PRIVATE_CALL_OP_DEF(n) \ template \ void operator()(const std::exception_ptr& ex, \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ {\ if (ex) \ this->p_->set_exception(ex); \ else \ { \ this->p_->set_value( \ std::forward_as_tuple( \ ASIO_VARIADIC_MOVE_ARGS(n))); \ } \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) #undef ASIO_PRIVATE_CALL_OP_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; // Helper template to choose the appropriate concrete promise handler // implementation based on the supplied completion signature. template class promise_handler_selector; template <> class promise_handler_selector : public promise_handler_0 {}; template <> class promise_handler_selector : public promise_handler_ec_0 {}; template <> class promise_handler_selector : public promise_handler_ex_0 {}; template class promise_handler_selector : public promise_handler_1 {}; template class promise_handler_selector : public promise_handler_ec_1 {}; template class promise_handler_selector : public promise_handler_ex_1 {}; #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template class promise_handler_selector : public promise_handler_n > {}; template class promise_handler_selector : public promise_handler_ec_n > {}; template class promise_handler_selector : public promise_handler_ex_n > {}; #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) #define ASIO_PRIVATE_PROMISE_SELECTOR_DEF(n) \ template \ class promise_handler_selector< \ void(Arg, ASIO_VARIADIC_TARGS(n))> \ : public promise_handler_n< \ std::tuple > {}; \ \ template \ class promise_handler_selector< \ void(asio::error_code, Arg, ASIO_VARIADIC_TARGS(n))> \ : public promise_handler_ec_n< \ std::tuple > {}; \ \ template \ class promise_handler_selector< \ void(std::exception_ptr, Arg, ASIO_VARIADIC_TARGS(n))> \ : public promise_handler_ex_n< \ std::tuple > {}; \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_SELECTOR_DEF) #undef ASIO_PRIVATE_PROMISE_SELECTOR_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) // Completion handlers produced from the use_future completion token, when not // using use_future::operator(). template class promise_handler : public promise_handler_selector { public: typedef Allocator allocator_type; typedef void result_type; promise_handler(use_future_t u) : allocator_(u.get_allocator()) { this->create_promise(allocator_); } allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_; } private: Allocator allocator_; }; template inline void asio_handler_invoke(Function& f, promise_handler* h) { typename promise_handler::executor_type ex(h->get_executor()); ex.dispatch(ASIO_MOVE_CAST(Function)(f), std::allocator()); } template inline void asio_handler_invoke(const Function& f, promise_handler* h) { typename promise_handler::executor_type ex(h->get_executor()); ex.dispatch(f, std::allocator()); } // Helper base class for async_result specialisation. template class promise_async_result { public: typedef promise_handler completion_handler_type; typedef typename completion_handler_type::future_type return_type; explicit promise_async_result(completion_handler_type& h) : future_(h.get_future()) { } return_type get() { return ASIO_MOVE_CAST(return_type)(future_); } private: return_type future_; }; // Return value from use_future::operator(). template class packaged_token { public: packaged_token(Function f, const Allocator& a) : function_(ASIO_MOVE_CAST(Function)(f)), allocator_(a) { } //private: Function function_; Allocator allocator_; }; // Completion handlers produced from the use_future completion token, when // using use_future::operator(). template class packaged_handler : public promise_creator { public: typedef Allocator allocator_type; typedef void result_type; packaged_handler(packaged_token t) : function_(ASIO_MOVE_CAST(Function)(t.function_)), allocator_(t.allocator_) { this->create_promise(allocator_); } allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_; } #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template void operator()(ASIO_MOVE_ARG(Args)... args) { (promise_invoke_and_set)(*this->p_, function_, ASIO_MOVE_CAST(Args)(args)...); } #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) void operator()() { (promise_invoke_and_set)(*this->p_, function_); } #define ASIO_PRIVATE_CALL_OP_DEF(n) \ template \ void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \ {\ (promise_invoke_and_set)(*this->p_, \ function_, ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) #undef ASIO_PRIVATE_CALL_OP_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) private: Function function_; Allocator allocator_; }; template inline void asio_handler_invoke(Function& f, packaged_handler* h) { typename packaged_handler::executor_type ex(h->get_executor()); ex.dispatch(ASIO_MOVE_CAST(Function)(f), std::allocator()); } template inline void asio_handler_invoke(const Function& f, packaged_handler* h) { typename packaged_handler::executor_type ex(h->get_executor()); ex.dispatch(f, std::allocator()); } // Helper base class for async_result specialisation. template class packaged_async_result { public: typedef packaged_handler completion_handler_type; typedef typename completion_handler_type::future_type return_type; explicit packaged_async_result(completion_handler_type& h) : future_(h.get_future()) { } return_type get() { return ASIO_MOVE_CAST(return_type)(future_); } private: return_type future_; }; } // namespace detail template template inline detail::packaged_token::type, Allocator> use_future_t::operator()(ASIO_MOVE_ARG(Function) f) const { return detail::packaged_token::type, Allocator>( ASIO_MOVE_CAST(Function)(f), allocator_); } #if !defined(GENERATING_DOCUMENTATION) #if defined(ASIO_HAS_VARIADIC_TEMPLATES) template class async_result, Result(Args...)> : public detail::promise_async_result< void(typename decay::type...), Allocator> { public: explicit async_result( typename detail::promise_async_result::type...), Allocator>::completion_handler_type& h) : detail::promise_async_result< void(typename decay::type...), Allocator>(h) { } }; template class async_result, Result(Args...)> : public detail::packaged_async_result::type> { public: explicit async_result( typename detail::packaged_async_result::type>::completion_handler_type& h) : detail::packaged_async_result::type>(h) { } }; #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) template class async_result, Result()> : public detail::promise_async_result { public: explicit async_result( typename detail::promise_async_result< void(), Allocator>::completion_handler_type& h) : detail::promise_async_result(h) { } }; template class async_result, Result()> : public detail::packaged_async_result::type> { public: explicit async_result( typename detail::packaged_async_result::type>::completion_handler_type& h) : detail::packaged_async_result::type>(h) { } }; #define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \ template \ class async_result, \ Result(ASIO_VARIADIC_TARGS(n))> \ : public detail::promise_async_result< \ void(ASIO_VARIADIC_DECAY(n)), Allocator> \ { \ public: \ explicit async_result( \ typename detail::promise_async_result< \ void(ASIO_VARIADIC_DECAY(n)), \ Allocator>::completion_handler_type& h) \ : detail::promise_async_result< \ void(ASIO_VARIADIC_DECAY(n)), Allocator>(h) \ { \ } \ }; \ \ template \ class async_result, \ Result(ASIO_VARIADIC_TARGS(n))> \ : public detail::packaged_async_result::type> \ { \ public: \ explicit async_result( \ typename detail::packaged_async_result::type \ >::completion_handler_type& h) \ : detail::packaged_async_result::type>(h) \ { \ } \ }; \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF) #undef ASIO_PRIVATE_ASYNC_RESULT_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_USE_FUTURE_HPP ================================================ FILE: src/third_party/asio/impl/write.hpp ================================================ // // impl/write.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_WRITE_HPP #define ASIO_IMPL_WRITE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/buffer.hpp" #include "asio/completion_condition.hpp" #include "asio/detail/array_fwd.hpp" #include "asio/detail/base_from_completion_cond.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template std::size_t write_buffer_sequence(SyncWriteStream& s, const ConstBufferSequence& buffers, const ConstBufferIterator&, CompletionCondition completion_condition, asio::error_code& ec) { ec = asio::error_code(); asio::detail::consuming_buffers tmp(buffers); while (!tmp.empty()) { if (std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, tmp.total_consumed()))) tmp.consume(s.write_some(tmp.prepare(max_size), ec)); else break; } return tmp.total_consumed();; } } // namespace detail template inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_const_buffer_sequence::value >::type*) { return detail::write_buffer_sequence(s, buffers, asio::buffer_sequence_begin(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, typename enable_if< is_const_buffer_sequence::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; } template inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, asio::error_code& ec, typename enable_if< is_const_buffer_sequence::value >::type*) { return write(s, buffers, transfer_all(), ec); } template inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, typename enable_if< is_const_buffer_sequence::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = write(s, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) template std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { typename decay::type b( ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); std::size_t bytes_transferred = write(s, b.data(), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); b.consume(bytes_transferred); return bytes_transferred; } template inline std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = write(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; } template inline std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return write(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); } template inline std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = write(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) template inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec) { return write(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf& b) { return write(s, basic_streambuf_ref(b)); } template inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf& b, asio::error_code& ec) { return write(s, basic_streambuf_ref(b), ec); } template inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf& b, CompletionCondition completion_condition) { return write(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) template std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type*) { std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); buffers.consume(bytes_transferred); return bytes_transferred; } template inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, typename enable_if< is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = write(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; } template inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return write(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); } template inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v2::value >::type*) { asio::error_code ec; std::size_t bytes_transferred = write(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; } namespace detail { template class write_op : detail::base_from_completion_cond { public: write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers, CompletionCondition& completion_condition, WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffers_(buffers), start_(0), handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) write_op(const write_op& other) : detail::base_from_completion_cond(other), stream_(other.stream_), buffers_(other.buffers_), start_(other.start_), handler_(other.handler_) { } write_op(write_op&& other) : detail::base_from_completion_cond( ASIO_MOVE_CAST(detail::base_from_completion_cond< CompletionCondition>)(other)), stream_(other.stream_), buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_), handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { std::size_t max_size; switch (start_ = start) { case 1: max_size = this->check_for_completion(ec, buffers_.total_consumed()); do { stream_.async_write_some(buffers_.prepare(max_size), ASIO_MOVE_CAST(write_op)(*this)); return; default: buffers_.consume(bytes_transferred); if ((!ec && bytes_transferred == 0) || buffers_.empty()) break; max_size = this->check_for_completion(ec, buffers_.total_consumed()); } while (max_size > 0); handler_(ec, buffers_.total_consumed()); } } //private: typedef asio::detail::consuming_buffers buffers_type; AsyncWriteStream& stream_; buffers_type buffers_; int start_; WriteHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, write_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, write_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( write_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, write_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, write_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void start_write_buffer_sequence_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers, const ConstBufferIterator&, CompletionCondition& completion_condition, WriteHandler& handler) { detail::write_op( stream, buffers, completion_condition, handler)( asio::error_code(), 0, 1); } template class initiate_async_write_buffer_sequence { public: typedef typename AsyncWriteStream::executor_type executor_type; explicit initiate_async_write_buffer_sequence(AsyncWriteStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); start_write_buffer_sequence_op(stream_, buffers, asio::buffer_sequence_begin(buffers), completion_cond2.value, handler2.value); } private: AsyncWriteStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::write_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::write_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::write_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::write_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler, typename enable_if< is_const_buffer_sequence::value >::type*) { return async_initiate( detail::initiate_async_write_buffer_sequence(s), handler, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler, typename enable_if< is_const_buffer_sequence::value >::type*) { return async_initiate( detail::initiate_async_write_buffer_sequence(s), handler, buffers, transfer_all()); } #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail { template class write_dynbuf_v1_op { public: template write_dynbuf_v1_op(AsyncWriteStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, WriteHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), completion_condition_( ASIO_MOVE_CAST(CompletionCondition)(completion_condition)), handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) write_dynbuf_v1_op(const write_dynbuf_v1_op& other) : stream_(other.stream_), buffers_(other.buffers_), completion_condition_(other.completion_condition_), handler_(other.handler_) { } write_dynbuf_v1_op(write_dynbuf_v1_op&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), completion_condition_( ASIO_MOVE_CAST(CompletionCondition)( other.completion_condition_)), handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { switch (start) { case 1: async_write(stream_, buffers_.data(), ASIO_MOVE_CAST(CompletionCondition)(completion_condition_), ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this)); return; default: buffers_.consume(bytes_transferred); handler_(ec, static_cast(bytes_transferred)); } } //private: AsyncWriteStream& stream_; DynamicBuffer_v1 buffers_; CompletionCondition completion_condition_; WriteHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, write_dynbuf_v1_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, write_dynbuf_v1_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( write_dynbuf_v1_op* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, write_dynbuf_v1_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, write_dynbuf_v1_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_write_dynbuf_v1 { public: typedef typename AsyncWriteStream::executor_type executor_type; explicit initiate_async_write_dynbuf_v1(AsyncWriteStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); write_dynbuf_v1_op::type, CompletionCondition, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); } private: AsyncWriteStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::write_dynbuf_v1_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::write_dynbuf_v1_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::write_dynbuf_v1_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::write_dynbuf_v1_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_MOVE_ARG(WriteHandler) handler, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return async_write(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ASIO_MOVE_CAST(WriteHandler)(handler)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type*) { return async_initiate( detail::initiate_async_write_dynbuf_v1(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, asio::basic_streambuf& b, ASIO_MOVE_ARG(WriteHandler) handler) { return async_write(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(WriteHandler)(handler)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, asio::basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler) { return async_write(s, basic_streambuf_ref(b), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ASIO_MOVE_CAST(WriteHandler)(handler)); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail { template class write_dynbuf_v2_op { public: template write_dynbuf_v2_op(AsyncWriteStream& stream, ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, WriteHandler& handler) : stream_(stream), buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), completion_condition_( ASIO_MOVE_CAST(CompletionCondition)(completion_condition)), handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) write_dynbuf_v2_op(const write_dynbuf_v2_op& other) : stream_(other.stream_), buffers_(other.buffers_), completion_condition_(other.completion_condition_), handler_(other.handler_) { } write_dynbuf_v2_op(write_dynbuf_v2_op&& other) : stream_(other.stream_), buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), completion_condition_( ASIO_MOVE_CAST(CompletionCondition)( other.completion_condition_)), handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { switch (start) { case 1: async_write(stream_, buffers_.data(0, buffers_.size()), ASIO_MOVE_CAST(CompletionCondition)(completion_condition_), ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this)); return; default: buffers_.consume(bytes_transferred); handler_(ec, static_cast(bytes_transferred)); } } //private: AsyncWriteStream& stream_; DynamicBuffer_v2 buffers_; CompletionCondition completion_condition_; WriteHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, write_dynbuf_v2_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, write_dynbuf_v2_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( write_dynbuf_v2_op* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, write_dynbuf_v2_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, write_dynbuf_v2_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_write_dynbuf_v2 { public: typedef typename AsyncWriteStream::executor_type executor_type; explicit initiate_async_write_dynbuf_v2(AsyncWriteStream& stream) : stream_(stream) { } executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); write_dynbuf_v2_op::type, CompletionCondition, typename decay::type>( stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); } private: AsyncWriteStream& stream_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::write_dynbuf_v2_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::write_dynbuf_v2_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::write_dynbuf_v2_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::write_dynbuf_v2_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, ASIO_MOVE_ARG(WriteHandler) handler, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return async_write(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ASIO_MOVE_CAST(WriteHandler)(handler)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler, typename enable_if< is_dynamic_buffer_v2::value >::type*) { return async_initiate( detail::initiate_async_write_dynbuf_v2(s), handler, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_WRITE_HPP ================================================ FILE: src/third_party/asio/impl/write_at.hpp ================================================ // // impl/write_at.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IMPL_WRITE_AT_HPP #define ASIO_IMPL_WRITE_AT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/buffer.hpp" #include "asio/completion_condition.hpp" #include "asio/detail/array_fwd.hpp" #include "asio/detail/base_from_completion_cond.hpp" #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template std::size_t write_at_buffer_sequence(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, const ConstBufferIterator&, CompletionCondition completion_condition, asio::error_code& ec) { ec = asio::error_code(); asio::detail::consuming_buffers tmp(buffers); while (!tmp.empty()) { if (std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, tmp.total_consumed()))) { tmp.consume(d.write_some_at(offset + tmp.total_consumed(), tmp.prepare(max_size), ec)); } else break; } return tmp.total_consumed();; } } // namespace detail template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec) { return detail::write_at_buffer_sequence(d, offset, buffers, asio::buffer_sequence_begin(buffers), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t bytes_transferred = write_at( d, offset, buffers, transfer_all(), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } template inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, asio::error_code& ec) { return write_at(d, offset, buffers, transfer_all(), ec); } template inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = write_at(d, offset, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec) { std::size_t bytes_transferred = write_at(d, offset, b.data(), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); b.consume(bytes_transferred); return bytes_transferred; } template inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf& b) { asio::error_code ec; std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } template inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf& b, asio::error_code& ec) { return write_at(d, offset, b, transfer_all(), ec); } template inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf& b, CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = write_at(d, offset, b, ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) namespace detail { template class write_at_op : detail::base_from_completion_cond { public: write_at_op(AsyncRandomAccessWriteDevice& device, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition& completion_condition, WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), buffers_(buffers), start_(0), handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) write_at_op(const write_at_op& other) : detail::base_from_completion_cond(other), device_(other.device_), offset_(other.offset_), buffers_(other.buffers_), start_(other.start_), handler_(other.handler_) { } write_at_op(write_at_op&& other) : detail::base_from_completion_cond( ASIO_MOVE_CAST(detail::base_from_completion_cond< CompletionCondition>)(other)), device_(other.device_), offset_(other.offset_), buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_), handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0) { std::size_t max_size; switch (start_ = start) { case 1: max_size = this->check_for_completion(ec, buffers_.total_consumed()); do { device_.async_write_some_at( offset_ + buffers_.total_consumed(), buffers_.prepare(max_size), ASIO_MOVE_CAST(write_at_op)(*this)); return; default: buffers_.consume(bytes_transferred); if ((!ec && bytes_transferred == 0) || buffers_.empty()) break; max_size = this->check_for_completion(ec, buffers_.total_consumed()); } while (max_size > 0); handler_(ec, buffers_.total_consumed()); } } //private: typedef asio::detail::consuming_buffers buffers_type; AsyncRandomAccessWriteDevice& device_; uint64_t offset_; buffers_type buffers_; int start_; WriteHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, write_at_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, write_at_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( write_at_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, write_at_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, write_at_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void start_write_at_buffer_sequence_op(AsyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, const ConstBufferIterator&, CompletionCondition& completion_condition, WriteHandler& handler) { detail::write_at_op( d, offset, buffers, completion_condition, handler)( asio::error_code(), 0, 1); } template class initiate_async_write_at_buffer_sequence { public: typedef typename AsyncRandomAccessWriteDevice::executor_type executor_type; explicit initiate_async_write_at_buffer_sequence( AsyncRandomAccessWriteDevice& device) : device_(device) { } executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, uint64_t offset, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; non_const_lvalue handler2(handler); non_const_lvalue completion_cond2(completion_cond); start_write_at_buffer_sequence_op(device_, offset, buffers, asio::buffer_sequence_begin(buffers), completion_cond2.value, handler2.value); } private: AsyncRandomAccessWriteDevice& device_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::write_at_op, Allocator> { typedef typename associated_allocator::type type; static type get( const detail::write_at_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::write_at_op, Executor> { typedef typename associated_executor::type type; static type get( const detail::write_at_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler) { return async_initiate( detail::initiate_async_write_at_buffer_sequence< AsyncRandomAccessWriteDevice>(d), handler, offset, buffers, ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler) { return async_initiate( detail::initiate_async_write_at_buffer_sequence< AsyncRandomAccessWriteDevice>(d), handler, offset, buffers, transfer_all()); } #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) namespace detail { template class write_at_streambuf_op { public: write_at_streambuf_op( asio::basic_streambuf& streambuf, WriteHandler& handler) : streambuf_(streambuf), handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } #if defined(ASIO_HAS_MOVE) write_at_streambuf_op(const write_at_streambuf_op& other) : streambuf_(other.streambuf_), handler_(other.handler_) { } write_at_streambuf_op(write_at_streambuf_op&& other) : streambuf_(other.streambuf_), handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, const std::size_t bytes_transferred) { streambuf_.consume(bytes_transferred); handler_(ec, bytes_transferred); } //private: asio::basic_streambuf& streambuf_; WriteHandler handler_; }; template inline void* asio_handler_allocate(std::size_t size, write_at_streambuf_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, write_at_streambuf_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( write_at_streambuf_op* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline void asio_handler_invoke(Function& function, write_at_streambuf_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, write_at_streambuf_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template class initiate_async_write_at_streambuf { public: typedef typename AsyncRandomAccessWriteDevice::executor_type executor_type; explicit initiate_async_write_at_streambuf( AsyncRandomAccessWriteDevice& device) : device_(device) { } executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, uint64_t offset, basic_streambuf* b, ASIO_MOVE_ARG(CompletionCondition) completion_condition) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; non_const_lvalue handler2(handler); async_write_at(device_, offset, b->data(), ASIO_MOVE_CAST(CompletionCondition)(completion_condition), write_at_streambuf_op::type>( *b, handler2.value)); } private: AsyncRandomAccessWriteDevice& device_; }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct associated_allocator< detail::write_at_streambuf_op, Allocator1> { typedef typename associated_allocator::type type; static type get( const detail::write_at_streambuf_op& h, const Allocator1& a = Allocator1()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< detail::write_at_streambuf_op, Executor1> { typedef typename associated_executor::type type; static type get( const detail::write_at_streambuf_op& h, const Executor1& ex = Executor1()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; #endif // !defined(GENERATING_DOCUMENTATION) template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler) { return async_initiate( detail::initiate_async_write_at_streambuf< AsyncRandomAccessWriteDevice>(d), handler, offset, &b, ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } template inline ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf& b, ASIO_MOVE_ARG(WriteHandler) handler) { return async_initiate( detail::initiate_async_write_at_streambuf< AsyncRandomAccessWriteDevice>(d), handler, offset, &b, transfer_all()); } #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_WRITE_AT_HPP ================================================ FILE: src/third_party/asio/io_context.hpp ================================================ // // io_context.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IO_CONTEXT_HPP #define ASIO_IO_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include "asio/async_result.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/wrapped_handler.hpp" #include "asio/error_code.hpp" #include "asio/execution_context.hpp" #if defined(ASIO_HAS_CHRONO) # include "asio/detail/chrono.hpp" #endif // defined(ASIO_HAS_CHRONO) #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # include "asio/detail/winsock_init.hpp" #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ || defined(__osf__) # include "asio/detail/signal_init.hpp" #endif #include "asio/detail/push_options.hpp" namespace asio { namespace detail { #if defined(ASIO_HAS_IOCP) typedef class win_iocp_io_context io_context_impl; class win_iocp_overlapped_ptr; #else typedef class scheduler io_context_impl; #endif } // namespace detail /// Provides core I/O functionality. /** * The io_context class provides the core I/O functionality for users of the * asynchronous I/O objects, including: * * @li asio::ip::tcp::socket * @li asio::ip::tcp::acceptor * @li asio::ip::udp::socket * @li asio::deadline_timer. * * The io_context class also includes facilities intended for developers of * custom asynchronous services. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe, with the specific exceptions of the restart() * and notify_fork() functions. Calling restart() while there are unfinished * run(), run_one(), run_for(), run_until(), poll() or poll_one() calls results * in undefined behaviour. The notify_fork() function should not be called * while any io_context function, or any function on an I/O object that is * associated with the io_context, is being called in another thread. * * @par Concepts: * Dispatcher. * * @par Synchronous and asynchronous operations * * Synchronous operations on I/O objects implicitly run the io_context object * for an individual operation. The io_context functions run(), run_one(), * run_for(), run_until(), poll() or poll_one() must be called for the * io_context to perform asynchronous operations on behalf of a C++ program. * Notification that an asynchronous operation has completed is delivered by * invocation of the associated handler. Handlers are invoked only by a thread * that is currently calling any overload of run(), run_one(), run_for(), * run_until(), poll() or poll_one() for the io_context. * * @par Effect of exceptions thrown from handlers * * If an exception is thrown from a handler, the exception is allowed to * propagate through the throwing thread's invocation of run(), run_one(), * run_for(), run_until(), poll() or poll_one(). No other threads that are * calling any of these functions are affected. It is then the responsibility * of the application to catch the exception. * * After the exception has been caught, the run(), run_one(), run_for(), * run_until(), poll() or poll_one() call may be restarted @em without the need * for an intervening call to restart(). This allows the thread to rejoin the * io_context object's thread pool without impacting any other threads in the * pool. * * For example: * * @code * asio::io_context io_context; * ... * for (;;) * { * try * { * io_context.run(); * break; // run() exited normally * } * catch (my_exception& e) * { * // Deal with exception as appropriate. * } * } * @endcode * * @par Submitting arbitrary tasks to the io_context * * To submit functions to the io_context, use the @ref asio::dispatch, * @ref asio::post or @ref asio::defer free functions. * * For example: * * @code void my_task() * { * ... * } * * ... * * asio::io_context io_context; * * // Submit a function to the io_context. * asio::post(io_context, my_task); * * // Submit a lambda object to the io_context. * asio::post(io_context, * []() * { * ... * }); * * // Run the io_context until it runs out of work. * io_context.run(); @endcode * * @par Stopping the io_context from running out of work * * Some applications may need to prevent an io_context object's run() call from * returning when there is no more work to do. For example, the io_context may * be being run in a background thread that is launched prior to the * application's asynchronous operations. The run() call may be kept running by * creating an object of type * asio::executor_work_guard: * * @code asio::io_context io_context; * asio::executor_work_guard * = asio::make_work_guard(io_context); * ... @endcode * * To effect a shutdown, the application will then need to call the io_context * object's stop() member function. This will cause the io_context run() call * to return as soon as possible, abandoning unfinished operations and without * permitting ready handlers to be dispatched. * * Alternatively, if the application requires that all operations and handlers * be allowed to finish normally, the work object may be explicitly reset. * * @code asio::io_context io_context; * asio::executor_work_guard * = asio::make_work_guard(io_context); * ... * work.reset(); // Allow run() to exit. @endcode */ class io_context : public execution_context { private: typedef detail::io_context_impl impl_type; #if defined(ASIO_HAS_IOCP) friend class detail::win_iocp_overlapped_ptr; #endif public: class executor_type; friend class executor_type; #if !defined(ASIO_NO_DEPRECATED) class work; friend class work; #endif // !defined(ASIO_NO_DEPRECATED) class service; #if !defined(ASIO_NO_EXTENSIONS) class strand; #endif // !defined(ASIO_NO_EXTENSIONS) /// The type used to count the number of handlers executed by the context. typedef std::size_t count_type; /// Constructor. ASIO_DECL io_context(); /// Constructor. /** * Construct with a hint about the required level of concurrency. * * @param concurrency_hint A suggestion to the implementation on how many * threads it should allow to run simultaneously. */ ASIO_DECL explicit io_context(int concurrency_hint); /// Destructor. /** * On destruction, the io_context performs the following sequence of * operations: * * @li For each service object @c svc in the io_context set, in reverse order * of the beginning of service object lifetime, performs * @c svc->shutdown(). * * @li Uninvoked handler objects that were scheduled for deferred invocation * on the io_context, or any associated strand, are destroyed. * * @li For each service object @c svc in the io_context set, in reverse order * of the beginning of service object lifetime, performs * delete static_cast(svc). * * @note The destruction sequence described above permits programs to * simplify their resource management by using @c shared_ptr<>. Where an * object's lifetime is tied to the lifetime of a connection (or some other * sequence of asynchronous operations), a @c shared_ptr to the object would * be bound into the handlers for all asynchronous operations associated with * it. This works as follows: * * @li When a single connection ends, all associated asynchronous operations * complete. The corresponding handler objects are destroyed, and all * @c shared_ptr references to the objects are destroyed. * * @li To shut down the whole program, the io_context function stop() is * called to terminate any run() calls as soon as possible. The io_context * destructor defined above destroys all handlers, causing all @c shared_ptr * references to all connection objects to be destroyed. */ ASIO_DECL ~io_context(); /// Obtains the executor associated with the io_context. executor_type get_executor() ASIO_NOEXCEPT; /// Run the io_context object's event processing loop. /** * The run() function blocks until all work has finished and there are no * more handlers to be dispatched, or until the io_context has been stopped. * * Multiple threads may call the run() function to set up a pool of threads * from which the io_context may execute handlers. All threads that are * waiting in the pool are equivalent and the io_context may choose any one * of them to invoke a handler. * * A normal exit from the run() function implies that the io_context object * is stopped (the stopped() function returns @c true). Subsequent calls to * run(), run_one(), poll() or poll_one() will return immediately unless there * is a prior call to restart(). * * @return The number of handlers that were executed. * * @note Calling the run() function from a thread that is currently calling * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on * the same io_context object may introduce the potential for deadlock. It is * the caller's reponsibility to avoid this. * * The poll() function may also be used to dispatch ready handlers, but * without blocking. */ ASIO_DECL count_type run(); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use non-error_code overload.) Run the io_context object's /// event processing loop. /** * The run() function blocks until all work has finished and there are no * more handlers to be dispatched, or until the io_context has been stopped. * * Multiple threads may call the run() function to set up a pool of threads * from which the io_context may execute handlers. All threads that are * waiting in the pool are equivalent and the io_context may choose any one * of them to invoke a handler. * * A normal exit from the run() function implies that the io_context object * is stopped (the stopped() function returns @c true). Subsequent calls to * run(), run_one(), poll() or poll_one() will return immediately unless there * is a prior call to restart(). * * @param ec Set to indicate what error occurred, if any. * * @return The number of handlers that were executed. * * @note Calling the run() function from a thread that is currently calling * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on * the same io_context object may introduce the potential for deadlock. It is * the caller's reponsibility to avoid this. * * The poll() function may also be used to dispatch ready handlers, but * without blocking. */ ASIO_DECL count_type run(asio::error_code& ec); #endif // !defined(ASIO_NO_DEPRECATED) #if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop for a specified /// duration. /** * The run_for() function blocks until all work has finished and there are no * more handlers to be dispatched, until the io_context has been stopped, or * until the specified duration has elapsed. * * @param rel_time The duration for which the call may block. * * @return The number of handlers that were executed. */ template std::size_t run_for(const chrono::duration& rel_time); /// Run the io_context object's event processing loop until a specified time. /** * The run_until() function blocks until all work has finished and there are * no more handlers to be dispatched, until the io_context has been stopped, * or until the specified time has been reached. * * @param abs_time The time point until which the call may block. * * @return The number of handlers that were executed. */ template std::size_t run_until(const chrono::time_point& abs_time); #endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop to execute at most one /// handler. /** * The run_one() function blocks until one handler has been dispatched, or * until the io_context has been stopped. * * @return The number of handlers that were executed. A zero return value * implies that the io_context object is stopped (the stopped() function * returns @c true). Subsequent calls to run(), run_one(), poll() or * poll_one() will return immediately unless there is a prior call to * restart(). * * @note Calling the run_one() function from a thread that is currently * calling one of run(), run_one(), run_for(), run_until(), poll() or * poll_one() on the same io_context object may introduce the potential for * deadlock. It is the caller's reponsibility to avoid this. */ ASIO_DECL count_type run_one(); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use non-error_code overlaod.) Run the io_context object's /// event processing loop to execute at most one handler. /** * The run_one() function blocks until one handler has been dispatched, or * until the io_context has been stopped. * * @return The number of handlers that were executed. A zero return value * implies that the io_context object is stopped (the stopped() function * returns @c true). Subsequent calls to run(), run_one(), poll() or * poll_one() will return immediately unless there is a prior call to * restart(). * * @return The number of handlers that were executed. * * @note Calling the run_one() function from a thread that is currently * calling one of run(), run_one(), run_for(), run_until(), poll() or * poll_one() on the same io_context object may introduce the potential for * deadlock. It is the caller's reponsibility to avoid this. */ ASIO_DECL count_type run_one(asio::error_code& ec); #endif // !defined(ASIO_NO_DEPRECATED) #if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop for a specified duration /// to execute at most one handler. /** * The run_one_for() function blocks until one handler has been dispatched, * until the io_context has been stopped, or until the specified duration has * elapsed. * * @param rel_time The duration for which the call may block. * * @return The number of handlers that were executed. */ template std::size_t run_one_for(const chrono::duration& rel_time); /// Run the io_context object's event processing loop until a specified time /// to execute at most one handler. /** * The run_one_until() function blocks until one handler has been dispatched, * until the io_context has been stopped, or until the specified time has * been reached. * * @param abs_time The time point until which the call may block. * * @return The number of handlers that were executed. */ template std::size_t run_one_until( const chrono::time_point& abs_time); #endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop to execute ready /// handlers. /** * The poll() function runs handlers that are ready to run, without blocking, * until the io_context has been stopped or there are no more ready handlers. * * @return The number of handlers that were executed. */ ASIO_DECL count_type poll(); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use non-error_code overload.) Run the io_context object's /// event processing loop to execute ready handlers. /** * The poll() function runs handlers that are ready to run, without blocking, * until the io_context has been stopped or there are no more ready handlers. * * @param ec Set to indicate what error occurred, if any. * * @return The number of handlers that were executed. */ ASIO_DECL count_type poll(asio::error_code& ec); #endif // !defined(ASIO_NO_DEPRECATED) /// Run the io_context object's event processing loop to execute one ready /// handler. /** * The poll_one() function runs at most one handler that is ready to run, * without blocking. * * @return The number of handlers that were executed. */ ASIO_DECL count_type poll_one(); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use non-error_code overload.) Run the io_context object's /// event processing loop to execute one ready handler. /** * The poll_one() function runs at most one handler that is ready to run, * without blocking. * * @param ec Set to indicate what error occurred, if any. * * @return The number of handlers that were executed. */ ASIO_DECL count_type poll_one(asio::error_code& ec); #endif // !defined(ASIO_NO_DEPRECATED) /// Stop the io_context object's event processing loop. /** * This function does not block, but instead simply signals the io_context to * stop. All invocations of its run() or run_one() member functions should * return as soon as possible. Subsequent calls to run(), run_one(), poll() * or poll_one() will return immediately until restart() is called. */ ASIO_DECL void stop(); /// Determine whether the io_context object has been stopped. /** * This function is used to determine whether an io_context object has been * stopped, either through an explicit call to stop(), or due to running out * of work. When an io_context object is stopped, calls to run(), run_one(), * poll() or poll_one() will return immediately without invoking any * handlers. * * @return @c true if the io_context object is stopped, otherwise @c false. */ ASIO_DECL bool stopped() const; /// Restart the io_context in preparation for a subsequent run() invocation. /** * This function must be called prior to any second or later set of * invocations of the run(), run_one(), poll() or poll_one() functions when a * previous invocation of these functions returned due to the io_context * being stopped or running out of work. After a call to restart(), the * io_context object's stopped() function will return @c false. * * This function must not be called while there are any unfinished calls to * the run(), run_one(), poll() or poll_one() functions. */ ASIO_DECL void restart(); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use restart().) Reset the io_context in preparation for a /// subsequent run() invocation. /** * This function must be called prior to any second or later set of * invocations of the run(), run_one(), poll() or poll_one() functions when a * previous invocation of these functions returned due to the io_context * being stopped or running out of work. After a call to restart(), the * io_context object's stopped() function will return @c false. * * This function must not be called while there are any unfinished calls to * the run(), run_one(), poll() or poll_one() functions. */ void reset(); /// (Deprecated: Use asio::dispatch().) Request the io_context to /// invoke the given handler. /** * This function is used to ask the io_context to execute the given handler. * * The io_context guarantees that the handler will only be called in a thread * in which the run(), run_one(), poll() or poll_one() member functions is * currently being invoked. The handler may be executed inside this function * if the guarantee can be met. * * @param handler The handler to be called. The io_context will make * a copy of the handler object as required. The function signature of the * handler must be: @code void handler(); @endcode * * @note This function throws an exception only if: * * @li the handler's @c asio_handler_allocate function; or * * @li the handler's copy constructor * * throws an exception. */ template ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler); /// (Deprecated: Use asio::post().) Request the io_context to invoke /// the given handler and return immediately. /** * This function is used to ask the io_context to execute the given handler, * but without allowing the io_context to call the handler from inside this * function. * * The io_context guarantees that the handler will only be called in a thread * in which the run(), run_one(), poll() or poll_one() member functions is * currently being invoked. * * @param handler The handler to be called. The io_context will make * a copy of the handler object as required. The function signature of the * handler must be: @code void handler(); @endcode * * @note This function throws an exception only if: * * @li the handler's @c asio_handler_allocate function; or * * @li the handler's copy constructor * * throws an exception. */ template ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler); /// (Deprecated: Use asio::bind_executor().) Create a new handler that /// automatically dispatches the wrapped handler on the io_context. /** * This function is used to create a new handler function object that, when * invoked, will automatically pass the wrapped handler to the io_context * object's dispatch function. * * @param handler The handler to be wrapped. The io_context will make a copy * of the handler object as required. The function signature of the handler * must be: @code void handler(A1 a1, ... An an); @endcode * * @return A function object that, when invoked, passes the wrapped handler to * the io_context object's dispatch function. Given a function object with the * signature: * @code R f(A1 a1, ... An an); @endcode * If this function object is passed to the wrap function like so: * @code io_context.wrap(f); @endcode * then the return value is a function object with the signature * @code void g(A1 a1, ... An an); @endcode * that, when invoked, executes code equivalent to: * @code io_context.dispatch(boost::bind(f, a1, ... an)); @endcode */ template #if defined(GENERATING_DOCUMENTATION) unspecified #else detail::wrapped_handler #endif wrap(Handler handler); #endif // !defined(ASIO_NO_DEPRECATED) private: #if !defined(ASIO_NO_DEPRECATED) struct initiate_dispatch; struct initiate_post; #endif // !defined(ASIO_NO_DEPRECATED) // Helper function to add the implementation. ASIO_DECL impl_type& add_impl(impl_type* impl); // Backwards compatible overload for use with services derived from // io_context::service. template friend Service& use_service(io_context& ioc); #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) detail::winsock_init<> init_; #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ || defined(__osf__) detail::signal_init<> init_; #endif // The implementation. impl_type& impl_; }; /// Executor used to submit functions to an io_context. class io_context::executor_type { public: /// Obtain the underlying execution context. io_context& context() const ASIO_NOEXCEPT; /// Inform the io_context that it has some outstanding work to do. /** * This function is used to inform the io_context that some work has begun. * This ensures that the io_context's run() and run_one() functions do not * exit while the work is underway. */ void on_work_started() const ASIO_NOEXCEPT; /// Inform the io_context that some work is no longer outstanding. /** * This function is used to inform the io_context that some work has * finished. Once the count of unfinished work reaches zero, the io_context * is stopped and the run() and run_one() functions may exit. */ void on_work_finished() const ASIO_NOEXCEPT; /// Request the io_context to invoke the given function object. /** * This function is used to ask the io_context to execute the given function * object. If the current thread is running the io_context, @c dispatch() * executes the function before returning. Otherwise, the function will be * scheduled to run on the io_context. * * @param f The function object to be called. The executor will make a copy * of the handler object as required. The function signature of the function * object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the io_context to invoke the given function object. /** * This function is used to ask the io_context to execute the given function * object. The function object will never be executed inside @c post(). * Instead, it will be scheduled to run on the io_context. * * @param f The function object to be called. The executor will make a copy * of the handler object as required. The function signature of the function * object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the io_context to invoke the given function object. /** * This function is used to ask the io_context to execute the given function * object. The function object will never be executed inside @c defer(). * Instead, it will be scheduled to run on the io_context. * * If the current thread belongs to the io_context, @c defer() will delay * scheduling the function object until the current thread returns control to * the pool. * * @param f The function object to be called. The executor will make a copy * of the handler object as required. The function signature of the function * object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Determine whether the io_context is running in the current thread. /** * @return @c true if the current thread is running the io_context. Otherwise * returns @c false. */ bool running_in_this_thread() const ASIO_NOEXCEPT; /// Compare two executors for equality. /** * Two executors are equal if they refer to the same underlying io_context. */ friend bool operator==(const executor_type& a, const executor_type& b) ASIO_NOEXCEPT { return &a.io_context_ == &b.io_context_; } /// Compare two executors for inequality. /** * Two executors are equal if they refer to the same underlying io_context. */ friend bool operator!=(const executor_type& a, const executor_type& b) ASIO_NOEXCEPT { return &a.io_context_ != &b.io_context_; } private: friend class io_context; // Constructor. explicit executor_type(io_context& i) : io_context_(i) {} // The underlying io_context. io_context& io_context_; }; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use executor_work_guard.) Class to inform the io_context when /// it has work to do. /** * The work class is used to inform the io_context when work starts and * finishes. This ensures that the io_context object's run() function will not * exit while work is underway, and that it does exit when there is no * unfinished work remaining. * * The work class is copy-constructible so that it may be used as a data member * in a handler class. It is not assignable. */ class io_context::work { public: /// Constructor notifies the io_context that work is starting. /** * The constructor is used to inform the io_context that some work has begun. * This ensures that the io_context object's run() function will not exit * while the work is underway. */ explicit work(asio::io_context& io_context); /// Copy constructor notifies the io_context that work is starting. /** * The constructor is used to inform the io_context that some work has begun. * This ensures that the io_context object's run() function will not exit * while the work is underway. */ work(const work& other); /// Destructor notifies the io_context that the work is complete. /** * The destructor is used to inform the io_context that some work has * finished. Once the count of unfinished work reaches zero, the io_context * object's run() function is permitted to exit. */ ~work(); /// Get the io_context associated with the work. asio::io_context& get_io_context(); private: // Prevent assignment. void operator=(const work& other); // The io_context implementation. detail::io_context_impl& io_context_impl_; }; #endif // !defined(ASIO_NO_DEPRECATED) /// Base class for all io_context services. class io_context::service : public execution_context::service { public: /// Get the io_context object that owns the service. asio::io_context& get_io_context(); private: /// Destroy all user-defined handler objects owned by the service. ASIO_DECL virtual void shutdown(); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use shutdown().) Destroy all user-defined handler objects /// owned by the service. ASIO_DECL virtual void shutdown_service(); #endif // !defined(ASIO_NO_DEPRECATED) /// Handle notification of a fork-related event to perform any necessary /// housekeeping. /** * This function is not a pure virtual so that services only have to * implement it if necessary. The default implementation does nothing. */ ASIO_DECL virtual void notify_fork( execution_context::fork_event event); #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use notify_fork().) Handle notification of a fork-related /// event to perform any necessary housekeeping. /** * This function is not a pure virtual so that services only have to * implement it if necessary. The default implementation does nothing. */ ASIO_DECL virtual void fork_service( execution_context::fork_event event); #endif // !defined(ASIO_NO_DEPRECATED) protected: /// Constructor. /** * @param owner The io_context object that owns the service. */ ASIO_DECL service(asio::io_context& owner); /// Destructor. ASIO_DECL virtual ~service(); }; namespace detail { // Special service base class to keep classes header-file only. template class service_base : public asio::io_context::service { public: static asio::detail::service_id id; // Constructor. service_base(asio::io_context& io_context) : asio::io_context::service(io_context) { } }; template asio::detail::service_id service_base::id; } // namespace detail } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/io_context.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/io_context.ipp" #endif // defined(ASIO_HEADER_ONLY) // If both io_context.hpp and strand.hpp have been included, automatically // include the header file needed for the io_context::strand class. #if !defined(ASIO_NO_EXTENSIONS) # if defined(ASIO_STRAND_HPP) # include "asio/io_context_strand.hpp" # endif // defined(ASIO_STRAND_HPP) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // ASIO_IO_CONTEXT_HPP ================================================ FILE: src/third_party/asio/io_context_strand.hpp ================================================ // // io_context_strand.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IO_CONTEXT_STRAND_HPP #define ASIO_IO_CONTEXT_STRAND_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_NO_EXTENSIONS) #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/strand_service.hpp" #include "asio/detail/wrapped_handler.hpp" #include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Provides serialised handler execution. /** * The io_context::strand class provides the ability to post and dispatch * handlers with the guarantee that none of those handlers will execute * concurrently. * * @par Order of handler invocation * Given: * * @li a strand object @c s * * @li an object @c a meeting completion handler requirements * * @li an object @c a1 which is an arbitrary copy of @c a made by the * implementation * * @li an object @c b meeting completion handler requirements * * @li an object @c b1 which is an arbitrary copy of @c b made by the * implementation * * if any of the following conditions are true: * * @li @c s.post(a) happens-before @c s.post(b) * * @li @c s.post(a) happens-before @c s.dispatch(b), where the latter is * performed outside the strand * * @li @c s.dispatch(a) happens-before @c s.post(b), where the former is * performed outside the strand * * @li @c s.dispatch(a) happens-before @c s.dispatch(b), where both are * performed outside the strand * * then @c asio_handler_invoke(a1, &a1) happens-before * @c asio_handler_invoke(b1, &b1). * * Note that in the following case: * @code async_op_1(..., s.wrap(a)); * async_op_2(..., s.wrap(b)); @endcode * the completion of the first async operation will perform @c s.dispatch(a), * and the second will perform @c s.dispatch(b), but the order in which those * are performed is unspecified. That is, you cannot state whether one * happens-before the other. Therefore none of the above conditions are met and * no ordering guarantee is made. * * @note The implementation makes no guarantee that handlers posted or * dispatched through different @c strand objects will be invoked concurrently. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Dispatcher. */ class io_context::strand { public: /// Constructor. /** * Constructs the strand. * * @param io_context The io_context object that the strand will use to * dispatch handlers that are ready to be run. */ explicit strand(asio::io_context& io_context) : service_(asio::use_service< asio::detail::strand_service>(io_context)) { service_.construct(impl_); } /// Destructor. /** * Destroys a strand. * * Handlers posted through the strand that have not yet been invoked will * still be dispatched in a way that meets the guarantee of non-concurrency. */ ~strand() { } /// Obtain the underlying execution context. asio::io_context& context() const ASIO_NOEXCEPT { return service_.get_io_context(); } /// Inform the strand that it has some outstanding work to do. /** * The strand delegates this call to its underlying io_context. */ void on_work_started() const ASIO_NOEXCEPT { context().get_executor().on_work_started(); } /// Inform the strand that some work is no longer outstanding. /** * The strand delegates this call to its underlying io_context. */ void on_work_finished() const ASIO_NOEXCEPT { context().get_executor().on_work_finished(); } /// Request the strand to invoke the given function object. /** * This function is used to ask the strand to execute the given function * object on its underlying io_context. The function object will be executed * inside this function if the strand is not otherwise busy and if the * underlying io_context's executor's @c dispatch() function is also able to * execute the function before returning. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); service_.dispatch(impl_, tmp); (void)a; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use asio::dispatch().) Request the strand to invoke /// the given handler. /** * This function is used to ask the strand to execute the given handler. * * The strand object guarantees that handlers posted or dispatched through * the strand will not be executed concurrently. The handler may be executed * inside this function if the guarantee can be met. If this function is * called from within a handler that was posted or dispatched through the same * strand, then the new handler will be executed immediately. * * The strand's guarantee is in addition to the guarantee provided by the * underlying io_context. The io_context guarantees that the handler will only * be called in a thread in which the io_context's run member function is * currently being invoked. * * @param handler The handler to be called. The strand will make a copy of the * handler object as required. The function signature of the handler must be: * @code void handler(); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) { return async_initiate( initiate_dispatch(), handler, this); } #endif // !defined(ASIO_NO_DEPRECATED) /// Request the strand to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object will never be executed inside this function. * Instead, it will be scheduled to run by the underlying io_context. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); service_.post(impl_, tmp); (void)a; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use asio::post().) Request the strand to invoke the /// given handler and return immediately. /** * This function is used to ask the strand to execute the given handler, but * without allowing the strand to call the handler from inside this function. * * The strand object guarantees that handlers posted or dispatched through * the strand will not be executed concurrently. The strand's guarantee is in * addition to the guarantee provided by the underlying io_context. The * io_context guarantees that the handler will only be called in a thread in * which the io_context's run member function is currently being invoked. * * @param handler The handler to be called. The strand will make a copy of the * handler object as required. The function signature of the handler must be: * @code void handler(); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler) { return async_initiate( initiate_post(), handler, this); } #endif // !defined(ASIO_NO_DEPRECATED) /// Request the strand to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object will never be executed inside this function. * Instead, it will be scheduled to run by the underlying io_context. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { typename decay::type tmp(ASIO_MOVE_CAST(Function)(f)); service_.post(impl_, tmp); (void)a; } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use asio::bind_executor().) Create a new handler that /// automatically dispatches the wrapped handler on the strand. /** * This function is used to create a new handler function object that, when * invoked, will automatically pass the wrapped handler to the strand's * dispatch function. * * @param handler The handler to be wrapped. The strand will make a copy of * the handler object as required. The function signature of the handler must * be: @code void handler(A1 a1, ... An an); @endcode * * @return A function object that, when invoked, passes the wrapped handler to * the strand's dispatch function. Given a function object with the signature: * @code R f(A1 a1, ... An an); @endcode * If this function object is passed to the wrap function like so: * @code strand.wrap(f); @endcode * then the return value is a function object with the signature * @code void g(A1 a1, ... An an); @endcode * that, when invoked, executes code equivalent to: * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode */ template #if defined(GENERATING_DOCUMENTATION) unspecified #else detail::wrapped_handler #endif wrap(Handler handler) { return detail::wrapped_handler(*this, handler); } #endif // !defined(ASIO_NO_DEPRECATED) /// Determine whether the strand is running in the current thread. /** * @return @c true if the current thread is executing a handler that was * submitted to the strand using post(), dispatch() or wrap(). Otherwise * returns @c false. */ bool running_in_this_thread() const ASIO_NOEXCEPT { return service_.running_in_this_thread(impl_); } /// Compare two strands for equality. /** * Two strands are equal if they refer to the same ordered, non-concurrent * state. */ friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ == b.impl_; } /// Compare two strands for inequality. /** * Two strands are equal if they refer to the same ordered, non-concurrent * state. */ friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ != b.impl_; } private: #if !defined(ASIO_NO_DEPRECATED) struct initiate_dispatch { template void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler, strand* self) const { // If you get an error on the following line it means that your // handler does not meet the documented type requirements for a // LegacyCompletionHandler. ASIO_LEGACY_COMPLETION_HANDLER_CHECK( LegacyCompletionHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self->service_.dispatch(self->impl_, handler2.value); } }; struct initiate_post { template void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler, strand* self) const { // If you get an error on the following line it means that your // handler does not meet the documented type requirements for a // LegacyCompletionHandler. ASIO_LEGACY_COMPLETION_HANDLER_CHECK( LegacyCompletionHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self->service_.post(self->impl_, handler2.value); } }; #endif // !defined(ASIO_NO_DEPRECATED) asio::detail::strand_service& service_; mutable asio::detail::strand_service::implementation_type impl_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_EXTENSIONS) #endif // ASIO_IO_CONTEXT_STRAND_HPP ================================================ FILE: src/third_party/asio/io_service.hpp ================================================ // // io_service.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IO_SERVICE_HPP #define ASIO_IO_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if !defined(ASIO_NO_DEPRECATED) /// Typedef for backwards compatibility. typedef io_context io_service; #endif // !defined(ASIO_NO_DEPRECATED) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IO_SERVICE_HPP ================================================ FILE: src/third_party/asio/io_service_strand.hpp ================================================ // // io_service_strand.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IO_SERVICE_STRAND_HPP #define ASIO_IO_SERVICE_STRAND_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/io_context_strand.hpp" #endif // ASIO_IO_SERVICE_STRAND_HPP ================================================ FILE: src/third_party/asio/ip/address.hpp ================================================ // // ip/address.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ADDRESS_HPP #define ASIO_IP_ADDRESS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/throw_exception.hpp" #include "asio/detail/string_view.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error_code.hpp" #include "asio/ip/address_v4.hpp" #include "asio/ip/address_v6.hpp" #include "asio/ip/bad_address_cast.hpp" #if !defined(ASIO_NO_IOSTREAM) # include #endif // !defined(ASIO_NO_IOSTREAM) #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Implements version-independent IP addresses. /** * The asio::ip::address class provides the ability to use either IP * version 4 or version 6 addresses. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ class address { public: /// Default constructor. ASIO_DECL address() ASIO_NOEXCEPT; /// Construct an address from an IPv4 address. ASIO_DECL address( const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT; /// Construct an address from an IPv6 address. ASIO_DECL address( const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT; /// Copy constructor. ASIO_DECL address(const address& other) ASIO_NOEXCEPT; #if defined(ASIO_HAS_MOVE) /// Move constructor. ASIO_DECL address(address&& other) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_MOVE) /// Assign from another address. ASIO_DECL address& operator=(const address& other) ASIO_NOEXCEPT; #if defined(ASIO_HAS_MOVE) /// Move-assign from another address. ASIO_DECL address& operator=(address&& other) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_MOVE) /// Assign from an IPv4 address. ASIO_DECL address& operator=( const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT; /// Assign from an IPv6 address. ASIO_DECL address& operator=( const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT; /// Get whether the address is an IP version 4 address. bool is_v4() const ASIO_NOEXCEPT { return type_ == ipv4; } /// Get whether the address is an IP version 6 address. bool is_v6() const ASIO_NOEXCEPT { return type_ == ipv6; } /// Get the address as an IP version 4 address. ASIO_DECL asio::ip::address_v4 to_v4() const; /// Get the address as an IP version 6 address. ASIO_DECL asio::ip::address_v6 to_v6() const; /// Get the address as a string. ASIO_DECL std::string to_string() const; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use other overload.) Get the address as a string. ASIO_DECL std::string to_string(asio::error_code& ec) const; /// (Deprecated: Use make_address().) Create an address from an IPv4 address /// string in dotted decimal form, or from an IPv6 address in hexadecimal /// notation. static address from_string(const char* str); /// (Deprecated: Use make_address().) Create an address from an IPv4 address /// string in dotted decimal form, or from an IPv6 address in hexadecimal /// notation. static address from_string(const char* str, asio::error_code& ec); /// (Deprecated: Use make_address().) Create an address from an IPv4 address /// string in dotted decimal form, or from an IPv6 address in hexadecimal /// notation. static address from_string(const std::string& str); /// (Deprecated: Use make_address().) Create an address from an IPv4 address /// string in dotted decimal form, or from an IPv6 address in hexadecimal /// notation. static address from_string( const std::string& str, asio::error_code& ec); #endif // !defined(ASIO_NO_DEPRECATED) /// Determine whether the address is a loopback address. ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT; /// Determine whether the address is unspecified. ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT; /// Determine whether the address is a multicast address. ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT; /// Compare two addresses for equality. ASIO_DECL friend bool operator==(const address& a1, const address& a2) ASIO_NOEXCEPT; /// Compare two addresses for inequality. friend bool operator!=(const address& a1, const address& a2) ASIO_NOEXCEPT { return !(a1 == a2); } /// Compare addresses for ordering. ASIO_DECL friend bool operator<(const address& a1, const address& a2) ASIO_NOEXCEPT; /// Compare addresses for ordering. friend bool operator>(const address& a1, const address& a2) ASIO_NOEXCEPT { return a2 < a1; } /// Compare addresses for ordering. friend bool operator<=(const address& a1, const address& a2) ASIO_NOEXCEPT { return !(a2 < a1); } /// Compare addresses for ordering. friend bool operator>=(const address& a1, const address& a2) ASIO_NOEXCEPT { return !(a1 < a2); } private: // The type of the address. enum { ipv4, ipv6 } type_; // The underlying IPv4 address. asio::ip::address_v4 ipv4_address_; // The underlying IPv6 address. asio::ip::address_v6 ipv6_address_; }; /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. /** * @relates address */ ASIO_DECL address make_address(const char* str); /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. /** * @relates address */ ASIO_DECL address make_address(const char* str, asio::error_code& ec) ASIO_NOEXCEPT; /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. /** * @relates address */ ASIO_DECL address make_address(const std::string& str); /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. /** * @relates address */ ASIO_DECL address make_address(const std::string& str, asio::error_code& ec) ASIO_NOEXCEPT; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION) /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. /** * @relates address */ ASIO_DECL address make_address(string_view str); /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. /** * @relates address */ ASIO_DECL address make_address(string_view str, asio::error_code& ec) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION) #if !defined(ASIO_NO_IOSTREAM) /// Output an address as a string. /** * Used to output a human-readable string for a specified address. * * @param os The output stream to which the string will be written. * * @param addr The address to be written. * * @return The output stream. * * @relates asio::ip::address */ template std::basic_ostream& operator<<( std::basic_ostream& os, const address& addr); #endif // !defined(ASIO_NO_IOSTREAM) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/ip/impl/address.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ip/impl/address.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_IP_ADDRESS_HPP ================================================ FILE: src/third_party/asio/ip/address_v4.hpp ================================================ // // ip/address_v4.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ADDRESS_V4_HPP #define ASIO_IP_ADDRESS_V4_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/array.hpp" #include "asio/detail/cstdint.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/string_view.hpp" #include "asio/detail/winsock_init.hpp" #include "asio/error_code.hpp" #if !defined(ASIO_NO_IOSTREAM) # include #endif // !defined(ASIO_NO_IOSTREAM) #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Implements IP version 4 style addresses. /** * The asio::ip::address_v4 class provides the ability to use and * manipulate IP version 4 addresses. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ class address_v4 { public: /// The type used to represent an address as an unsigned integer. typedef uint_least32_t uint_type; /// The type used to represent an address as an array of bytes. /** * @note This type is defined in terms of the C++0x template @c std::array * when it is available. Otherwise, it uses @c boost:array. */ #if defined(GENERATING_DOCUMENTATION) typedef array bytes_type; #else typedef asio::detail::array bytes_type; #endif /// Default constructor. address_v4() ASIO_NOEXCEPT { addr_.s_addr = 0; } /// Construct an address from raw bytes. ASIO_DECL explicit address_v4(const bytes_type& bytes); /// Construct an address from an unsigned integer in host byte order. ASIO_DECL explicit address_v4(uint_type addr); /// Copy constructor. address_v4(const address_v4& other) ASIO_NOEXCEPT : addr_(other.addr_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. address_v4(address_v4&& other) ASIO_NOEXCEPT : addr_(other.addr_) { } #endif // defined(ASIO_HAS_MOVE) /// Assign from another address. address_v4& operator=(const address_v4& other) ASIO_NOEXCEPT { addr_ = other.addr_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move-assign from another address. address_v4& operator=(address_v4&& other) ASIO_NOEXCEPT { addr_ = other.addr_; return *this; } #endif // defined(ASIO_HAS_MOVE) /// Get the address in bytes, in network byte order. ASIO_DECL bytes_type to_bytes() const ASIO_NOEXCEPT; /// Get the address as an unsigned integer in host byte order ASIO_DECL uint_type to_uint() const ASIO_NOEXCEPT; #if !defined(ASIO_NO_DEPRECATED) /// Get the address as an unsigned long in host byte order ASIO_DECL unsigned long to_ulong() const; #endif // !defined(ASIO_NO_DEPRECATED) /// Get the address as a string in dotted decimal format. ASIO_DECL std::string to_string() const; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use other overload.) Get the address as a string in dotted /// decimal format. ASIO_DECL std::string to_string(asio::error_code& ec) const; /// (Deprecated: Use make_address_v4().) Create an address from an IP address /// string in dotted decimal form. static address_v4 from_string(const char* str); /// (Deprecated: Use make_address_v4().) Create an address from an IP address /// string in dotted decimal form. static address_v4 from_string( const char* str, asio::error_code& ec); /// (Deprecated: Use make_address_v4().) Create an address from an IP address /// string in dotted decimal form. static address_v4 from_string(const std::string& str); /// (Deprecated: Use make_address_v4().) Create an address from an IP address /// string in dotted decimal form. static address_v4 from_string( const std::string& str, asio::error_code& ec); #endif // !defined(ASIO_NO_DEPRECATED) /// Determine whether the address is a loopback address. ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT; /// Determine whether the address is unspecified. ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use network_v4 class.) Determine whether the address is a /// class A address. ASIO_DECL bool is_class_a() const; /// (Deprecated: Use network_v4 class.) Determine whether the address is a /// class B address. ASIO_DECL bool is_class_b() const; /// (Deprecated: Use network_v4 class.) Determine whether the address is a /// class C address. ASIO_DECL bool is_class_c() const; #endif // !defined(ASIO_NO_DEPRECATED) /// Determine whether the address is a multicast address. ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT; /// Compare two addresses for equality. friend bool operator==(const address_v4& a1, const address_v4& a2) ASIO_NOEXCEPT { return a1.addr_.s_addr == a2.addr_.s_addr; } /// Compare two addresses for inequality. friend bool operator!=(const address_v4& a1, const address_v4& a2) ASIO_NOEXCEPT { return a1.addr_.s_addr != a2.addr_.s_addr; } /// Compare addresses for ordering. friend bool operator<(const address_v4& a1, const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() < a2.to_uint(); } /// Compare addresses for ordering. friend bool operator>(const address_v4& a1, const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() > a2.to_uint(); } /// Compare addresses for ordering. friend bool operator<=(const address_v4& a1, const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() <= a2.to_uint(); } /// Compare addresses for ordering. friend bool operator>=(const address_v4& a1, const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() >= a2.to_uint(); } /// Obtain an address object that represents any address. static address_v4 any() ASIO_NOEXCEPT { return address_v4(); } /// Obtain an address object that represents the loopback address. static address_v4 loopback() ASIO_NOEXCEPT { return address_v4(0x7F000001); } /// Obtain an address object that represents the broadcast address. static address_v4 broadcast() ASIO_NOEXCEPT { return address_v4(0xFFFFFFFF); } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use network_v4 class.) Obtain an address object that /// represents the broadcast address that corresponds to the specified /// address and netmask. ASIO_DECL static address_v4 broadcast( const address_v4& addr, const address_v4& mask); /// (Deprecated: Use network_v4 class.) Obtain the netmask that corresponds /// to the address, based on its address class. ASIO_DECL static address_v4 netmask(const address_v4& addr); #endif // !defined(ASIO_NO_DEPRECATED) private: // The underlying IPv4 address. asio::detail::in4_addr_type addr_; }; /// Create an IPv4 address from raw bytes in network order. /** * @relates address_v4 */ inline address_v4 make_address_v4(const address_v4::bytes_type& bytes) { return address_v4(bytes); } /// Create an IPv4 address from an unsigned integer in host byte order. /** * @relates address_v4 */ inline address_v4 make_address_v4(address_v4::uint_type addr) { return address_v4(addr); } /// Create an IPv4 address from an IP address string in dotted decimal form. /** * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const char* str); /// Create an IPv4 address from an IP address string in dotted decimal form. /** * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const char* str, asio::error_code& ec) ASIO_NOEXCEPT; /// Create an IPv4 address from an IP address string in dotted decimal form. /** * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const std::string& str); /// Create an IPv4 address from an IP address string in dotted decimal form. /** * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const std::string& str, asio::error_code& ec) ASIO_NOEXCEPT; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION) /// Create an IPv4 address from an IP address string in dotted decimal form. /** * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(string_view str); /// Create an IPv4 address from an IP address string in dotted decimal form. /** * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(string_view str, asio::error_code& ec) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION) #if !defined(ASIO_NO_IOSTREAM) /// Output an address as a string. /** * Used to output a human-readable string for a specified address. * * @param os The output stream to which the string will be written. * * @param addr The address to be written. * * @return The output stream. * * @relates asio::ip::address_v4 */ template std::basic_ostream& operator<<( std::basic_ostream& os, const address_v4& addr); #endif // !defined(ASIO_NO_IOSTREAM) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/ip/impl/address_v4.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ip/impl/address_v4.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_IP_ADDRESS_V4_HPP ================================================ FILE: src/third_party/asio/ip/address_v4_iterator.hpp ================================================ // // ip/address_v4_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ADDRESS_V4_ITERATOR_HPP #define ASIO_IP_ADDRESS_V4_ITERATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ip/address_v4.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template class basic_address_iterator; /// An input iterator that can be used for traversing IPv4 addresses. /** * In addition to satisfying the input iterator requirements, this iterator * also supports decrement. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template <> class basic_address_iterator { public: /// The type of the elements pointed to by the iterator. typedef address_v4 value_type; /// Distance between two iterators. typedef std::ptrdiff_t difference_type; /// The type of a pointer to an element pointed to by the iterator. typedef const address_v4* pointer; /// The type of a reference to an element pointed to by the iterator. typedef const address_v4& reference; /// Denotes that the iterator satisfies the input iterator requirements. typedef std::input_iterator_tag iterator_category; /// Construct an iterator that points to the specified address. basic_address_iterator(const address_v4& addr) ASIO_NOEXCEPT : address_(addr) { } /// Copy constructor. basic_address_iterator( const basic_address_iterator& other) ASIO_NOEXCEPT : address_(other.address_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT : address_(ASIO_MOVE_CAST(address_v4)(other.address_)) { } #endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_iterator& operator=( const basic_address_iterator& other) ASIO_NOEXCEPT { address_ = other.address_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move assignment operator. basic_address_iterator& operator=( basic_address_iterator&& other) ASIO_NOEXCEPT { address_ = ASIO_MOVE_CAST(address_v4)(other.address_); return *this; } #endif // defined(ASIO_HAS_MOVE) /// Dereference the iterator. const address_v4& operator*() const ASIO_NOEXCEPT { return address_; } /// Dereference the iterator. const address_v4* operator->() const ASIO_NOEXCEPT { return &address_; } /// Pre-increment operator. basic_address_iterator& operator++() ASIO_NOEXCEPT { address_ = address_v4((address_.to_uint() + 1) & 0xFFFFFFFF); return *this; } /// Post-increment operator. basic_address_iterator operator++(int) ASIO_NOEXCEPT { basic_address_iterator tmp(*this); ++*this; return tmp; } /// Pre-decrement operator. basic_address_iterator& operator--() ASIO_NOEXCEPT { address_ = address_v4((address_.to_uint() - 1) & 0xFFFFFFFF); return *this; } /// Post-decrement operator. basic_address_iterator operator--(int) { basic_address_iterator tmp(*this); --*this; return tmp; } /// Compare two addresses for equality. friend bool operator==(const basic_address_iterator& a, const basic_address_iterator& b) { return a.address_ == b.address_; } /// Compare two addresses for inequality. friend bool operator!=(const basic_address_iterator& a, const basic_address_iterator& b) { return a.address_ != b.address_; } private: address_v4 address_; }; /// An input iterator that can be used for traversing IPv4 addresses. typedef basic_address_iterator address_v4_iterator; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_ADDRESS_V4_ITERATOR_HPP ================================================ FILE: src/third_party/asio/ip/address_v4_range.hpp ================================================ // // ip/address_v4_range.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ADDRESS_V4_RANGE_HPP #define ASIO_IP_ADDRESS_V4_RANGE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ip/address_v4_iterator.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template class basic_address_range; /// Represents a range of IPv4 addresses. /** * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template <> class basic_address_range { public: /// The type of an iterator that points into the range. typedef basic_address_iterator iterator; /// Construct an empty range. basic_address_range() ASIO_NOEXCEPT : begin_(address_v4()), end_(address_v4()) { } /// Construct an range that represents the given range of addresses. explicit basic_address_range(const iterator& first, const iterator& last) ASIO_NOEXCEPT : begin_(first), end_(last) { } /// Copy constructor. basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT : begin_(other.begin_), end_(other.end_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)), end_(ASIO_MOVE_CAST(iterator)(other.end_)) { } #endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_range& operator=( const basic_address_range& other) ASIO_NOEXCEPT { begin_ = other.begin_; end_ = other.end_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move assignment operator. basic_address_range& operator=( basic_address_range&& other) ASIO_NOEXCEPT { begin_ = ASIO_MOVE_CAST(iterator)(other.begin_); end_ = ASIO_MOVE_CAST(iterator)(other.end_); return *this; } #endif // defined(ASIO_HAS_MOVE) /// Obtain an iterator that points to the start of the range. iterator begin() const ASIO_NOEXCEPT { return begin_; } /// Obtain an iterator that points to the end of the range. iterator end() const ASIO_NOEXCEPT { return end_; } /// Determine whether the range is empty. bool empty() const ASIO_NOEXCEPT { return size() == 0; } /// Return the size of the range. std::size_t size() const ASIO_NOEXCEPT { return end_->to_uint() - begin_->to_uint(); } /// Find an address in the range. iterator find(const address_v4& addr) const ASIO_NOEXCEPT { return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; } private: iterator begin_; iterator end_; }; /// Represents a range of IPv4 addresses. typedef basic_address_range address_v4_range; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_ADDRESS_V4_RANGE_HPP ================================================ FILE: src/third_party/asio/ip/address_v6.hpp ================================================ // // ip/address_v6.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ADDRESS_V6_HPP #define ASIO_IP_ADDRESS_V6_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/array.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/string_view.hpp" #include "asio/detail/winsock_init.hpp" #include "asio/error_code.hpp" #include "asio/ip/address_v4.hpp" #if !defined(ASIO_NO_IOSTREAM) # include #endif // !defined(ASIO_NO_IOSTREAM) #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template class basic_address_iterator; /// Implements IP version 6 style addresses. /** * The asio::ip::address_v6 class provides the ability to use and * manipulate IP version 6 addresses. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ class address_v6 { public: /// The type used to represent an address as an array of bytes. /** * @note This type is defined in terms of the C++0x template @c std::array * when it is available. Otherwise, it uses @c boost:array. */ #if defined(GENERATING_DOCUMENTATION) typedef array bytes_type; #else typedef asio::detail::array bytes_type; #endif /// Default constructor. ASIO_DECL address_v6() ASIO_NOEXCEPT; /// Construct an address from raw bytes and scope ID. ASIO_DECL explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0); /// Copy constructor. ASIO_DECL address_v6(const address_v6& other) ASIO_NOEXCEPT; #if defined(ASIO_HAS_MOVE) /// Move constructor. ASIO_DECL address_v6(address_v6&& other) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_MOVE) /// Assign from another address. ASIO_DECL address_v6& operator=( const address_v6& other) ASIO_NOEXCEPT; #if defined(ASIO_HAS_MOVE) /// Move-assign from another address. ASIO_DECL address_v6& operator=(address_v6&& other) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_MOVE) /// The scope ID of the address. /** * Returns the scope ID associated with the IPv6 address. */ unsigned long scope_id() const ASIO_NOEXCEPT { return scope_id_; } /// The scope ID of the address. /** * Modifies the scope ID associated with the IPv6 address. */ void scope_id(unsigned long id) ASIO_NOEXCEPT { scope_id_ = id; } /// Get the address in bytes, in network byte order. ASIO_DECL bytes_type to_bytes() const ASIO_NOEXCEPT; /// Get the address as a string. ASIO_DECL std::string to_string() const; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use other overload.) Get the address as a string. ASIO_DECL std::string to_string(asio::error_code& ec) const; /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP /// address string. static address_v6 from_string(const char* str); /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP /// address string. static address_v6 from_string( const char* str, asio::error_code& ec); /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP /// address string. static address_v6 from_string(const std::string& str); /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP /// address string. static address_v6 from_string( const std::string& str, asio::error_code& ec); /// (Deprecated: Use make_address_v4().) Converts an IPv4-mapped or /// IPv4-compatible address to an IPv4 address. ASIO_DECL address_v4 to_v4() const; #endif // !defined(ASIO_NO_DEPRECATED) /// Determine whether the address is a loopback address. ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT; /// Determine whether the address is unspecified. ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT; /// Determine whether the address is link local. ASIO_DECL bool is_link_local() const ASIO_NOEXCEPT; /// Determine whether the address is site local. ASIO_DECL bool is_site_local() const ASIO_NOEXCEPT; /// Determine whether the address is a mapped IPv4 address. ASIO_DECL bool is_v4_mapped() const ASIO_NOEXCEPT; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: No replacement.) Determine whether the address is an /// IPv4-compatible address. ASIO_DECL bool is_v4_compatible() const; #endif // !defined(ASIO_NO_DEPRECATED) /// Determine whether the address is a multicast address. ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT; /// Determine whether the address is a global multicast address. ASIO_DECL bool is_multicast_global() const ASIO_NOEXCEPT; /// Determine whether the address is a link-local multicast address. ASIO_DECL bool is_multicast_link_local() const ASIO_NOEXCEPT; /// Determine whether the address is a node-local multicast address. ASIO_DECL bool is_multicast_node_local() const ASIO_NOEXCEPT; /// Determine whether the address is a org-local multicast address. ASIO_DECL bool is_multicast_org_local() const ASIO_NOEXCEPT; /// Determine whether the address is a site-local multicast address. ASIO_DECL bool is_multicast_site_local() const ASIO_NOEXCEPT; /// Compare two addresses for equality. ASIO_DECL friend bool operator==(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT; /// Compare two addresses for inequality. friend bool operator!=(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { return !(a1 == a2); } /// Compare addresses for ordering. ASIO_DECL friend bool operator<(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT; /// Compare addresses for ordering. friend bool operator>(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { return a2 < a1; } /// Compare addresses for ordering. friend bool operator<=(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { return !(a2 < a1); } /// Compare addresses for ordering. friend bool operator>=(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { return !(a1 < a2); } /// Obtain an address object that represents any address. static address_v6 any() ASIO_NOEXCEPT { return address_v6(); } /// Obtain an address object that represents the loopback address. ASIO_DECL static address_v6 loopback() ASIO_NOEXCEPT; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. ASIO_DECL static address_v6 v4_mapped(const address_v4& addr); /// (Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. ASIO_DECL static address_v6 v4_compatible(const address_v4& addr); #endif // !defined(ASIO_NO_DEPRECATED) private: friend class basic_address_iterator; // The underlying IPv6 address. asio::detail::in6_addr_type addr_; // The scope ID associated with the address. unsigned long scope_id_; }; /// Create an IPv6 address from raw bytes and scope ID. /** * @relates address_v6 */ inline address_v6 make_address_v6(const address_v6::bytes_type& bytes, unsigned long scope_id = 0) { return address_v6(bytes, scope_id); } /// Create an IPv6 address from an IP address string. /** * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const char* str); /// Create an IPv6 address from an IP address string. /** * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const char* str, asio::error_code& ec) ASIO_NOEXCEPT; /// Createan IPv6 address from an IP address string. /** * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const std::string& str); /// Create an IPv6 address from an IP address string. /** * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const std::string& str, asio::error_code& ec) ASIO_NOEXCEPT; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION) /// Create an IPv6 address from an IP address string. /** * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(string_view str); /// Create an IPv6 address from an IP address string. /** * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(string_view str, asio::error_code& ec) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION) /// Tag type used for distinguishing overloads that deal in IPv4-mapped IPv6 /// addresses. enum v4_mapped_t { v4_mapped }; /// Create an IPv4 address from a IPv4-mapped IPv6 address. /** * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4( v4_mapped_t, const address_v6& v6_addr); /// Create an IPv4-mapped IPv6 address from an IPv4 address. /** * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6( v4_mapped_t, const address_v4& v4_addr); #if !defined(ASIO_NO_IOSTREAM) /// Output an address as a string. /** * Used to output a human-readable string for a specified address. * * @param os The output stream to which the string will be written. * * @param addr The address to be written. * * @return The output stream. * * @relates asio::ip::address_v6 */ template std::basic_ostream& operator<<( std::basic_ostream& os, const address_v6& addr); #endif // !defined(ASIO_NO_IOSTREAM) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/ip/impl/address_v6.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ip/impl/address_v6.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_IP_ADDRESS_V6_HPP ================================================ FILE: src/third_party/asio/ip/address_v6_iterator.hpp ================================================ // // ip/address_v6_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ADDRESS_V6_ITERATOR_HPP #define ASIO_IP_ADDRESS_V6_ITERATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ip/address_v6.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template class basic_address_iterator; /// An input iterator that can be used for traversing IPv6 addresses. /** * In addition to satisfying the input iterator requirements, this iterator * also supports decrement. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template <> class basic_address_iterator { public: /// The type of the elements pointed to by the iterator. typedef address_v6 value_type; /// Distance between two iterators. typedef std::ptrdiff_t difference_type; /// The type of a pointer to an element pointed to by the iterator. typedef const address_v6* pointer; /// The type of a reference to an element pointed to by the iterator. typedef const address_v6& reference; /// Denotes that the iterator satisfies the input iterator requirements. typedef std::input_iterator_tag iterator_category; /// Construct an iterator that points to the specified address. basic_address_iterator(const address_v6& addr) ASIO_NOEXCEPT : address_(addr) { } /// Copy constructor. basic_address_iterator( const basic_address_iterator& other) ASIO_NOEXCEPT : address_(other.address_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT : address_(ASIO_MOVE_CAST(address_v6)(other.address_)) { } #endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_iterator& operator=( const basic_address_iterator& other) ASIO_NOEXCEPT { address_ = other.address_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move assignment operator. basic_address_iterator& operator=( basic_address_iterator&& other) ASIO_NOEXCEPT { address_ = ASIO_MOVE_CAST(address_v6)(other.address_); return *this; } #endif // defined(ASIO_HAS_MOVE) /// Dereference the iterator. const address_v6& operator*() const ASIO_NOEXCEPT { return address_; } /// Dereference the iterator. const address_v6* operator->() const ASIO_NOEXCEPT { return &address_; } /// Pre-increment operator. basic_address_iterator& operator++() ASIO_NOEXCEPT { for (int i = 15; i >= 0; --i) { if (address_.addr_.s6_addr[i] < 0xFF) { ++address_.addr_.s6_addr[i]; break; } address_.addr_.s6_addr[i] = 0; } return *this; } /// Post-increment operator. basic_address_iterator operator++(int) ASIO_NOEXCEPT { basic_address_iterator tmp(*this); ++*this; return tmp; } /// Pre-decrement operator. basic_address_iterator& operator--() ASIO_NOEXCEPT { for (int i = 15; i >= 0; --i) { if (address_.addr_.s6_addr[i] > 0) { --address_.addr_.s6_addr[i]; break; } address_.addr_.s6_addr[i] = 0xFF; } return *this; } /// Post-decrement operator. basic_address_iterator operator--(int) { basic_address_iterator tmp(*this); --*this; return tmp; } /// Compare two addresses for equality. friend bool operator==(const basic_address_iterator& a, const basic_address_iterator& b) { return a.address_ == b.address_; } /// Compare two addresses for inequality. friend bool operator!=(const basic_address_iterator& a, const basic_address_iterator& b) { return a.address_ != b.address_; } private: address_v6 address_; }; /// An input iterator that can be used for traversing IPv6 addresses. typedef basic_address_iterator address_v6_iterator; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_ADDRESS_V6_ITERATOR_HPP ================================================ FILE: src/third_party/asio/ip/address_v6_range.hpp ================================================ // // ip/address_v6_range.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ADDRESS_V6_RANGE_HPP #define ASIO_IP_ADDRESS_V6_RANGE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ip/address_v6_iterator.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template class basic_address_range; /// Represents a range of IPv6 addresses. /** * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template <> class basic_address_range { public: /// The type of an iterator that points into the range. typedef basic_address_iterator iterator; /// Construct an empty range. basic_address_range() ASIO_NOEXCEPT : begin_(address_v6()), end_(address_v6()) { } /// Construct an range that represents the given range of addresses. explicit basic_address_range(const iterator& first, const iterator& last) ASIO_NOEXCEPT : begin_(first), end_(last) { } /// Copy constructor. basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT : begin_(other.begin_), end_(other.end_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)), end_(ASIO_MOVE_CAST(iterator)(other.end_)) { } #endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_range& operator=( const basic_address_range& other) ASIO_NOEXCEPT { begin_ = other.begin_; end_ = other.end_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move assignment operator. basic_address_range& operator=( basic_address_range&& other) ASIO_NOEXCEPT { begin_ = ASIO_MOVE_CAST(iterator)(other.begin_); end_ = ASIO_MOVE_CAST(iterator)(other.end_); return *this; } #endif // defined(ASIO_HAS_MOVE) /// Obtain an iterator that points to the start of the range. iterator begin() const ASIO_NOEXCEPT { return begin_; } /// Obtain an iterator that points to the end of the range. iterator end() const ASIO_NOEXCEPT { return end_; } /// Determine whether the range is empty. bool empty() const ASIO_NOEXCEPT { return begin_ == end_; } /// Find an address in the range. iterator find(const address_v6& addr) const ASIO_NOEXCEPT { return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; } private: iterator begin_; iterator end_; }; /// Represents a range of IPv6 addresses. typedef basic_address_range address_v6_range; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_ADDRESS_V6_RANGE_HPP ================================================ FILE: src/third_party/asio/ip/bad_address_cast.hpp ================================================ // // ip/bad_address_cast.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_BAD_ADDRESS_CAST_HPP #define ASIO_IP_BAD_ADDRESS_CAST_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Thrown to indicate a failed address conversion. class bad_address_cast : #if defined(ASIO_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS public std::exception #else public std::bad_cast #endif { public: /// Default constructor. bad_address_cast() {} /// Destructor. virtual ~bad_address_cast() ASIO_NOEXCEPT_OR_NOTHROW {} /// Get the message associated with the exception. virtual const char* what() const ASIO_NOEXCEPT_OR_NOTHROW { return "bad address cast"; } }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_ADDRESS_HPP ================================================ FILE: src/third_party/asio/ip/basic_endpoint.hpp ================================================ // // ip/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_BASIC_ENDPOINT_HPP #define ASIO_IP_BASIC_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ip/address.hpp" #include "asio/ip/detail/endpoint.hpp" #if !defined(ASIO_NO_IOSTREAM) # include #endif // !defined(ASIO_NO_IOSTREAM) #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Describes an endpoint for a version-independent IP socket. /** * The asio::ip::basic_endpoint class template describes an endpoint that * may be associated with a particular socket. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * Endpoint. */ template class basic_endpoint { public: /// The protocol type associated with the endpoint. typedef InternetProtocol protocol_type; /// The type of the endpoint structure. This type is dependent on the /// underlying implementation of the socket layer. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined data_type; #else typedef asio::detail::socket_addr_type data_type; #endif /// Default constructor. basic_endpoint() ASIO_NOEXCEPT : impl_() { } /// Construct an endpoint using a port number, specified in the host's byte /// order. The IP address will be the any address (i.e. INADDR_ANY or /// in6addr_any). This constructor would typically be used for accepting new /// connections. /** * @par Examples * To initialise an IPv4 TCP endpoint for port 1234, use: * @code * asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), 1234); * @endcode * * To specify an IPv6 UDP endpoint for port 9876, use: * @code * asio::ip::udp::endpoint ep(asio::ip::udp::v6(), 9876); * @endcode */ basic_endpoint(const InternetProtocol& internet_protocol, unsigned short port_num) ASIO_NOEXCEPT : impl_(internet_protocol.family(), port_num) { } /// Construct an endpoint using a port number and an IP address. This /// constructor may be used for accepting connections on a specific interface /// or for making a connection to a remote endpoint. basic_endpoint(const asio::ip::address& addr, unsigned short port_num) ASIO_NOEXCEPT : impl_(addr, port_num) { } /// Copy constructor. basic_endpoint(const basic_endpoint& other) ASIO_NOEXCEPT : impl_(other.impl_) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. basic_endpoint(basic_endpoint&& other) ASIO_NOEXCEPT : impl_(other.impl_) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assign from another endpoint. basic_endpoint& operator=(const basic_endpoint& other) ASIO_NOEXCEPT { impl_ = other.impl_; return *this; } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-assign from another endpoint. basic_endpoint& operator=(basic_endpoint&& other) ASIO_NOEXCEPT { impl_ = other.impl_; return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// The protocol associated with the endpoint. protocol_type protocol() const ASIO_NOEXCEPT { if (impl_.is_v4()) return InternetProtocol::v4(); return InternetProtocol::v6(); } /// Get the underlying endpoint in the native type. data_type* data() ASIO_NOEXCEPT { return impl_.data(); } /// Get the underlying endpoint in the native type. const data_type* data() const ASIO_NOEXCEPT { return impl_.data(); } /// Get the underlying size of the endpoint in the native type. std::size_t size() const ASIO_NOEXCEPT { return impl_.size(); } /// Set the underlying size of the endpoint in the native type. void resize(std::size_t new_size) { impl_.resize(new_size); } /// Get the capacity of the endpoint in the native type. std::size_t capacity() const ASIO_NOEXCEPT { return impl_.capacity(); } /// Get the port associated with the endpoint. The port number is always in /// the host's byte order. unsigned short port() const ASIO_NOEXCEPT { return impl_.port(); } /// Set the port associated with the endpoint. The port number is always in /// the host's byte order. void port(unsigned short port_num) ASIO_NOEXCEPT { impl_.port(port_num); } /// Get the IP address associated with the endpoint. asio::ip::address address() const ASIO_NOEXCEPT { return impl_.address(); } /// Set the IP address associated with the endpoint. void address(const asio::ip::address& addr) ASIO_NOEXCEPT { impl_.address(addr); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint& e1, const basic_endpoint& e2) ASIO_NOEXCEPT { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint& e1, const basic_endpoint& e2) ASIO_NOEXCEPT { return !(e1 == e2); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint& e1, const basic_endpoint& e2) ASIO_NOEXCEPT { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint& e1, const basic_endpoint& e2) ASIO_NOEXCEPT { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint& e1, const basic_endpoint& e2) ASIO_NOEXCEPT { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint& e1, const basic_endpoint& e2) ASIO_NOEXCEPT { return !(e1 < e2); } private: // The underlying IP endpoint. asio::ip::detail::endpoint impl_; }; #if !defined(ASIO_NO_IOSTREAM) /// Output an endpoint as a string. /** * Used to output a human-readable string for a specified endpoint. * * @param os The output stream to which the string will be written. * * @param endpoint The endpoint to be written. * * @return The output stream. * * @relates asio::ip::basic_endpoint */ template std::basic_ostream& operator<<( std::basic_ostream& os, const basic_endpoint& endpoint); #endif // !defined(ASIO_NO_IOSTREAM) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/ip/impl/basic_endpoint.hpp" #endif // ASIO_IP_BASIC_ENDPOINT_HPP ================================================ FILE: src/third_party/asio/ip/basic_resolver.hpp ================================================ // // ip/basic_resolver.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_BASIC_RESOLVER_HPP #define ASIO_IP_BASIC_RESOLVER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/string_view.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/ip/basic_resolver_iterator.hpp" #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/basic_resolver_results.hpp" #include "asio/ip/resolver_base.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/winrt_resolver_service.hpp" #else # include "asio/detail/resolver_service.hpp" #endif #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { namespace ip { #if !defined(ASIO_IP_BASIC_RESOLVER_FWD_DECL) #define ASIO_IP_BASIC_RESOLVER_FWD_DECL // Forward declaration with defaulted arguments. template class basic_resolver; #endif // !defined(ASIO_IP_BASIC_RESOLVER_FWD_DECL) /// Provides endpoint resolution functionality. /** * The basic_resolver class template provides the ability to resolve a query * to a list of endpoints. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_resolver : public resolver_base { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the resolver type to another executor. template struct rebind_executor { /// The resolver type when rebound to the specified executor. typedef basic_resolver other; }; /// The protocol type. typedef InternetProtocol protocol_type; /// The endpoint type. typedef typename InternetProtocol::endpoint endpoint_type; #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated.) The query type. typedef basic_resolver_query query; /// (Deprecated.) The iterator type. typedef basic_resolver_iterator iterator; #endif // !defined(ASIO_NO_DEPRECATED) /// The results type. typedef basic_resolver_results results_type; /// Construct with executor. /** * This constructor creates a basic_resolver. * * @param ex The I/O executor that the resolver will use, by default, to * dispatch handlers for any asynchronous operations performed on the * resolver. */ explicit basic_resolver(const executor_type& ex) : impl_(ex) { } /// Construct with execution context. /** * This constructor creates a basic_resolver. * * @param context An execution context which provides the I/O executor that * the resolver will use, by default, to dispatch handlers for any * asynchronous operations performed on the resolver. */ template explicit basic_resolver(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_resolver from another. /** * This constructor moves a resolver from one object to another. * * @param other The other basic_resolver object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_resolver(const executor_type&) constructor. */ basic_resolver(basic_resolver&& other) : impl_(std::move(other.impl_)) { } /// Move-assign a basic_resolver from another. /** * This assignment operator moves a resolver from one object to another. * Cancels any outstanding asynchronous operations associated with the target * object. * * @param other The other basic_resolver object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_resolver(const executor_type&) constructor. */ basic_resolver& operator=(basic_resolver&& other) { impl_ = std::move(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the resolver. /** * This function destroys the resolver, cancelling any outstanding * asynchronous wait operations associated with the resolver as if by calling * @c cancel. */ ~basic_resolver() { } /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Cancel any asynchronous operations that are waiting on the resolver. /** * This function forces the completion of any pending asynchronous * operations on the host resolver. The handler for each cancelled operation * will be invoked with the asio::error::operation_aborted error code. */ void cancel() { return impl_.get_service().cancel(impl_.get_implementation()); } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use overload with separate host and service parameters.) /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve a query into a list of endpoint entries. * * @param q A query object that determines what endpoints will be returned. * * @returns A range object representing the list of endpoint entries. A * successful call to this function is guaranteed to return a non-empty * range. * * @throws asio::system_error Thrown on failure. */ results_type resolve(const query& q) { asio::error_code ec; results_type r = impl_.get_service().resolve( impl_.get_implementation(), q, ec); asio::detail::throw_error(ec, "resolve"); return r; } /// (Deprecated: Use overload with separate host and service parameters.) /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve a query into a list of endpoint entries. * * @param q A query object that determines what endpoints will be returned. * * @param ec Set to indicate what error occurred, if any. * * @returns A range object representing the list of endpoint entries. An * empty range is returned if an error occurs. A successful call to this * function is guaranteed to return a non-empty range. */ results_type resolve(const query& q, asio::error_code& ec) { return impl_.get_service().resolve(impl_.get_implementation(), q, ec); } #endif // !defined(ASIO_NO_DEPRECATED) /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @returns A range object representing the list of endpoint entries. A * successful call to this function is guaranteed to return a non-empty * range. * * @throws asio::system_error Thrown on failure. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service) { return resolve(host, service, resolver_base::flags()); } /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param ec Set to indicate what error occurred, if any. * * @returns A range object representing the list of endpoint entries. An * empty range is returned if an error occurs. A successful call to this * function is guaranteed to return a non-empty range. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, asio::error_code& ec) { return resolve(host, service, resolver_base::flags(), ec); } /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. See the @ref resolver_base documentation for the set of * available flags. * * @returns A range object representing the list of endpoint entries. A * successful call to this function is guaranteed to return a non-empty * range. * * @throws asio::system_error Thrown on failure. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags) { asio::error_code ec; basic_resolver_query q(static_cast(host), static_cast(service), resolve_flags); results_type r = impl_.get_service().resolve( impl_.get_implementation(), q, ec); asio::detail::throw_error(ec, "resolve"); return r; } /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. See the @ref resolver_base documentation for the set of * available flags. * * @param ec Set to indicate what error occurred, if any. * * @returns A range object representing the list of endpoint entries. An * empty range is returned if an error occurs. A successful call to this * function is guaranteed to return a non-empty range. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags, asio::error_code& ec) { basic_resolver_query q(static_cast(host), static_cast(service), resolve_flags); return impl_.get_service().resolve(impl_.get_implementation(), q, ec); } /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @returns A range object representing the list of endpoint entries. A * successful call to this function is guaranteed to return a non-empty * range. * * @throws asio::system_error Thrown on failure. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service) { return resolve(protocol, host, service, resolver_base::flags()); } /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param ec Set to indicate what error occurred, if any. * * @returns A range object representing the list of endpoint entries. An * empty range is returned if an error occurs. A successful call to this * function is guaranteed to return a non-empty range. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, asio::error_code& ec) { return resolve(protocol, host, service, resolver_base::flags(), ec); } /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. See the @ref resolver_base documentation for the set of * available flags. * * @returns A range object representing the list of endpoint entries. A * successful call to this function is guaranteed to return a non-empty * range. * * @throws asio::system_error Thrown on failure. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags) { asio::error_code ec; basic_resolver_query q( protocol, static_cast(host), static_cast(service), resolve_flags); results_type r = impl_.get_service().resolve( impl_.get_implementation(), q, ec); asio::detail::throw_error(ec, "resolve"); return r; } /// Perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. See the @ref resolver_base documentation for the set of * available flags. * * @param ec Set to indicate what error occurred, if any. * * @returns A range object representing the list of endpoint entries. An * empty range is returned if an error occurs. A successful call to this * function is guaranteed to return a non-empty range. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ results_type resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags, asio::error_code& ec) { basic_resolver_query q( protocol, static_cast(host), static_cast(service), resolve_flags); return impl_.get_service().resolve(impl_.get_implementation(), q, ec); } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use overload with separate host and service parameters.) /// Asynchronously perform forward resolution of a query to a list of entries. /** * This function is used to asynchronously resolve a query into a list of * endpoint entries. * * @param q A query object that determines what endpoints will be returned. * * @param handler The handler to be called when the resolve operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * resolver::results_type results // Resolved endpoints as a range. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler. */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, results_type)) ResolveHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler, void (asio::error_code, results_type)) async_resolve(const query& q, ASIO_MOVE_ARG(ResolveHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return asio::async_initiate( initiate_async_resolve(this), handler, q); } #endif // !defined(ASIO_NO_DEPRECATED) /// Asynchronously perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param handler The handler to be called when the resolve operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * resolver::results_type results // Resolved endpoints as a range. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, results_type)) ResolveHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler, void (asio::error_code, results_type)) async_resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, ASIO_MOVE_ARG(ResolveHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_resolve(host, service, resolver_base::flags(), ASIO_MOVE_CAST(ResolveHandler)(handler)); } /// Asynchronously perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. See the @ref resolver_base documentation for the set of * available flags. * * @param handler The handler to be called when the resolve operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * resolver::results_type results // Resolved endpoints as a range. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, results_type)) ResolveHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler, void (asio::error_code, results_type)) async_resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags, ASIO_MOVE_ARG(ResolveHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { basic_resolver_query q(static_cast(host), static_cast(service), resolve_flags); return asio::async_initiate( initiate_async_resolve(this), handler, q); } /// Asynchronously perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param handler The handler to be called when the resolve operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * resolver::results_type results // Resolved endpoints as a range. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, results_type)) ResolveHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler, void (asio::error_code, results_type)) async_resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, ASIO_MOVE_ARG(ResolveHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_resolve(protocol, host, service, resolver_base::flags(), ASIO_MOVE_CAST(ResolveHandler)(handler)); } /// Asynchronously perform forward resolution of a query to a list of entries. /** * This function is used to resolve host and service names into a list of * endpoint entries. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. See the @ref resolver_base documentation for the set of * available flags. * * @param handler The handler to be called when the resolve operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * resolver::results_type results // Resolved endpoints as a range. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, results_type)) ResolveHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler, void (asio::error_code, results_type)) async_resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags, ASIO_MOVE_ARG(ResolveHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { basic_resolver_query q( protocol, static_cast(host), static_cast(service), resolve_flags); return asio::async_initiate( initiate_async_resolve(this), handler, q); } /// Perform reverse resolution of an endpoint to a list of entries. /** * This function is used to resolve an endpoint into a list of endpoint * entries. * * @param e An endpoint object that determines what endpoints will be * returned. * * @returns A range object representing the list of endpoint entries. A * successful call to this function is guaranteed to return a non-empty * range. * * @throws asio::system_error Thrown on failure. */ results_type resolve(const endpoint_type& e) { asio::error_code ec; results_type i = impl_.get_service().resolve( impl_.get_implementation(), e, ec); asio::detail::throw_error(ec, "resolve"); return i; } /// Perform reverse resolution of an endpoint to a list of entries. /** * This function is used to resolve an endpoint into a list of endpoint * entries. * * @param e An endpoint object that determines what endpoints will be * returned. * * @param ec Set to indicate what error occurred, if any. * * @returns A range object representing the list of endpoint entries. An * empty range is returned if an error occurs. A successful call to this * function is guaranteed to return a non-empty range. */ results_type resolve(const endpoint_type& e, asio::error_code& ec) { return impl_.get_service().resolve(impl_.get_implementation(), e, ec); } /// Asynchronously perform reverse resolution of an endpoint to a list of /// entries. /** * This function is used to asynchronously resolve an endpoint into a list of * endpoint entries. * * @param e An endpoint object that determines what endpoints will be * returned. * * @param handler The handler to be called when the resolve operation * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * resolver::results_type results // Resolved endpoints as a range. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler. */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, results_type)) ResolveHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler, void (asio::error_code, results_type)) async_resolve(const endpoint_type& e, ASIO_MOVE_ARG(ResolveHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return asio::async_initiate( initiate_async_resolve(this), handler, e); } private: // Disallow copying and assignment. basic_resolver(const basic_resolver&) ASIO_DELETED; basic_resolver& operator=(const basic_resolver&) ASIO_DELETED; class initiate_async_resolve { public: typedef Executor executor_type; explicit initiate_async_resolve(basic_resolver* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ResolveHandler) handler, const Query& q) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ResolveHandler. ASIO_RESOLVE_HANDLER_CHECK( ResolveHandler, handler, results_type) type_check; asio::detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_resolve( self_->impl_.get_implementation(), q, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_resolver* self_; }; # if defined(ASIO_WINDOWS_RUNTIME) asio::detail::io_object_impl< asio::detail::winrt_resolver_service, Executor> impl_; # else asio::detail::io_object_impl< asio::detail::resolver_service, Executor> impl_; # endif }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_BASIC_RESOLVER_HPP ================================================ FILE: src/third_party/asio/ip/basic_resolver_entry.hpp ================================================ // // ip/basic_resolver_entry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_BASIC_RESOLVER_ENTRY_HPP #define ASIO_IP_BASIC_RESOLVER_ENTRY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/string_view.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// An entry produced by a resolver. /** * The asio::ip::basic_resolver_entry class template describes an entry * as returned by a resolver. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_resolver_entry { public: /// The protocol type associated with the endpoint entry. typedef InternetProtocol protocol_type; /// The endpoint type associated with the endpoint entry. typedef typename InternetProtocol::endpoint endpoint_type; /// Default constructor. basic_resolver_entry() { } /// Construct with specified endpoint, host name and service name. basic_resolver_entry(const endpoint_type& ep, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service) : endpoint_(ep), host_name_(static_cast(host)), service_name_(static_cast(service)) { } /// Get the endpoint associated with the entry. endpoint_type endpoint() const { return endpoint_; } /// Convert to the endpoint associated with the entry. operator endpoint_type() const { return endpoint_; } /// Get the host name associated with the entry. std::string host_name() const { return host_name_; } /// Get the host name associated with the entry. template std::basic_string, Allocator> host_name( const Allocator& alloc = Allocator()) const { return std::basic_string, Allocator>( host_name_.c_str(), alloc); } /// Get the service name associated with the entry. std::string service_name() const { return service_name_; } /// Get the service name associated with the entry. template std::basic_string, Allocator> service_name( const Allocator& alloc = Allocator()) const { return std::basic_string, Allocator>( service_name_.c_str(), alloc); } private: endpoint_type endpoint_; std::string host_name_; std::string service_name_; }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_BASIC_RESOLVER_ENTRY_HPP ================================================ FILE: src/third_party/asio/ip/basic_resolver_iterator.hpp ================================================ // // ip/basic_resolver_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP #define ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include #include #include "asio/detail/memory.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/ip/basic_resolver_entry.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/winrt_utils.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// An iterator over the entries produced by a resolver. /** * The asio::ip::basic_resolver_iterator class template is used to define * iterators over the results returned by a resolver. * * The iterator's value_type, obtained when the iterator is dereferenced, is: * @code const basic_resolver_entry @endcode * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_resolver_iterator { public: /// The type used for the distance between two iterators. typedef std::ptrdiff_t difference_type; /// The type of the value pointed to by the iterator. typedef basic_resolver_entry value_type; /// The type of the result of applying operator->() to the iterator. typedef const basic_resolver_entry* pointer; /// The type of the result of applying operator*() to the iterator. typedef const basic_resolver_entry& reference; /// The iterator category. typedef std::forward_iterator_tag iterator_category; /// Default constructor creates an end iterator. basic_resolver_iterator() : index_(0) { } /// Copy constructor. basic_resolver_iterator(const basic_resolver_iterator& other) : values_(other.values_), index_(other.index_) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. basic_resolver_iterator(basic_resolver_iterator&& other) : values_(ASIO_MOVE_CAST(values_ptr_type)(other.values_)), index_(other.index_) { other.index_ = 0; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator. basic_resolver_iterator& operator=(const basic_resolver_iterator& other) { values_ = other.values_; index_ = other.index_; return *this; } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-assignment operator. basic_resolver_iterator& operator=(basic_resolver_iterator&& other) { if (this != &other) { values_ = ASIO_MOVE_CAST(values_ptr_type)(other.values_); index_ = other.index_; other.index_ = 0; } return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Dereference an iterator. const basic_resolver_entry& operator*() const { return dereference(); } /// Dereference an iterator. const basic_resolver_entry* operator->() const { return &dereference(); } /// Increment operator (prefix). basic_resolver_iterator& operator++() { increment(); return *this; } /// Increment operator (postfix). basic_resolver_iterator operator++(int) { basic_resolver_iterator tmp(*this); ++*this; return tmp; } /// Test two iterators for equality. friend bool operator==(const basic_resolver_iterator& a, const basic_resolver_iterator& b) { return a.equal(b); } /// Test two iterators for inequality. friend bool operator!=(const basic_resolver_iterator& a, const basic_resolver_iterator& b) { return !a.equal(b); } protected: void increment() { if (++index_ == values_->size()) { // Reset state to match a default constructed end iterator. values_.reset(); index_ = 0; } } bool equal(const basic_resolver_iterator& other) const { if (!values_ && !other.values_) return true; if (values_ != other.values_) return false; return index_ == other.index_; } const basic_resolver_entry& dereference() const { return (*values_)[index_]; } typedef std::vector > values_type; typedef asio::detail::shared_ptr values_ptr_type; values_ptr_type values_; std::size_t index_; }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP ================================================ FILE: src/third_party/asio/ip/basic_resolver_query.hpp ================================================ // // ip/basic_resolver_query.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_BASIC_RESOLVER_QUERY_HPP #define ASIO_IP_BASIC_RESOLVER_QUERY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/socket_ops.hpp" #include "asio/ip/resolver_query_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// An query to be passed to a resolver. /** * The asio::ip::basic_resolver_query class template describes a query * that can be passed to a resolver. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_resolver_query : public resolver_query_base { public: /// The protocol type associated with the endpoint query. typedef InternetProtocol protocol_type; /// Construct with specified service name for any protocol. /** * This constructor is typically used to perform name resolution for local * service binding. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for local service * binding. * * @note On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ basic_resolver_query(const std::string& service, resolver_query_base::flags resolve_flags = passive | address_configured) : hints_(), host_name_(), service_name_(service) { typename InternetProtocol::endpoint endpoint; hints_.ai_flags = static_cast(resolve_flags); hints_.ai_family = PF_UNSPEC; hints_.ai_socktype = endpoint.protocol().type(); hints_.ai_protocol = endpoint.protocol().protocol(); hints_.ai_addrlen = 0; hints_.ai_canonname = 0; hints_.ai_addr = 0; hints_.ai_next = 0; } /// Construct with specified service name for a given protocol. /** * This constructor is typically used to perform name resolution for local * service binding with a specific protocol version. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for local service * binding. * * @note On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ basic_resolver_query(const protocol_type& protocol, const std::string& service, resolver_query_base::flags resolve_flags = passive | address_configured) : hints_(), host_name_(), service_name_(service) { hints_.ai_flags = static_cast(resolve_flags); hints_.ai_family = protocol.family(); hints_.ai_socktype = protocol.type(); hints_.ai_protocol = protocol.protocol(); hints_.ai_addrlen = 0; hints_.ai_canonname = 0; hints_.ai_addr = 0; hints_.ai_next = 0; } /// Construct with specified host name and service name for any protocol. /** * This constructor is typically used to perform name resolution for * communication with remote hosts. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ basic_resolver_query(const std::string& host, const std::string& service, resolver_query_base::flags resolve_flags = address_configured) : hints_(), host_name_(host), service_name_(service) { typename InternetProtocol::endpoint endpoint; hints_.ai_flags = static_cast(resolve_flags); hints_.ai_family = ASIO_OS_DEF(AF_UNSPEC); hints_.ai_socktype = endpoint.protocol().type(); hints_.ai_protocol = endpoint.protocol().protocol(); hints_.ai_addrlen = 0; hints_.ai_canonname = 0; hints_.ai_addr = 0; hints_.ai_next = 0; } /// Construct with specified host name and service name for a given protocol. /** * This constructor is typically used to perform name resolution for * communication with remote hosts. * * @param protocol A protocol object, normally representing either the IPv4 or * IPv6 version of an internet protocol. * * @param host A string identifying a location. May be a descriptive name or * a numeric address string. If an empty string and the passive flag has been * specified, the resolved endpoints are suitable for local service binding. * If an empty string and passive is not specified, the resolved endpoints * will use the loopback address. * * @param service A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. May * be an empty string, in which case all resolved endpoints will have a port * number of 0. * * @param resolve_flags A set of flags that determine how name resolution * should be performed. The default flags are suitable for communication with * remote hosts. * * @note On POSIX systems, host names may be locally defined in the file * /etc/hosts. On Windows, host names may be defined in the file * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name * resolution is performed using DNS. Operating systems may use additional * locations when resolving host names (such as NETBIOS names on Windows). * * On POSIX systems, service names are typically defined in the file * /etc/services. On Windows, service names may be found in the file * c:\\windows\\system32\\drivers\\etc\\services. Operating systems * may use additional locations when resolving service names. */ basic_resolver_query(const protocol_type& protocol, const std::string& host, const std::string& service, resolver_query_base::flags resolve_flags = address_configured) : hints_(), host_name_(host), service_name_(service) { hints_.ai_flags = static_cast(resolve_flags); hints_.ai_family = protocol.family(); hints_.ai_socktype = protocol.type(); hints_.ai_protocol = protocol.protocol(); hints_.ai_addrlen = 0; hints_.ai_canonname = 0; hints_.ai_addr = 0; hints_.ai_next = 0; } /// Get the hints associated with the query. const asio::detail::addrinfo_type& hints() const { return hints_; } /// Get the host name associated with the query. std::string host_name() const { return host_name_; } /// Get the service name associated with the query. std::string service_name() const { return service_name_; } private: asio::detail::addrinfo_type hints_; std::string host_name_; std::string service_name_; }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_BASIC_RESOLVER_QUERY_HPP ================================================ FILE: src/third_party/asio/ip/basic_resolver_results.hpp ================================================ // // ip/basic_resolver_results.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_BASIC_RESOLVER_RESULTS_HPP #define ASIO_IP_BASIC_RESOLVER_RESULTS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/ip/basic_resolver_iterator.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/winrt_utils.hpp" #endif // defined(ASIO_WINDOWS_RUNTIME) #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// A range of entries produced by a resolver. /** * The asio::ip::basic_resolver_results class template is used to define * a range over the results returned by a resolver. * * The iterator's value_type, obtained when a results iterator is dereferenced, * is: @code const basic_resolver_entry @endcode * * @note For backward compatibility, basic_resolver_results is derived from * basic_resolver_iterator. This derivation is deprecated. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_resolver_results #if !defined(ASIO_NO_DEPRECATED) : public basic_resolver_iterator #else // !defined(ASIO_NO_DEPRECATED) : private basic_resolver_iterator #endif // !defined(ASIO_NO_DEPRECATED) { public: /// The protocol type associated with the results. typedef InternetProtocol protocol_type; /// The endpoint type associated with the results. typedef typename protocol_type::endpoint endpoint_type; /// The type of a value in the results range. typedef basic_resolver_entry value_type; /// The type of a const reference to a value in the range. typedef const value_type& const_reference; /// The type of a non-const reference to a value in the range. typedef value_type& reference; /// The type of an iterator into the range. typedef basic_resolver_iterator const_iterator; /// The type of an iterator into the range. typedef const_iterator iterator; /// Type used to represent the distance between two iterators in the range. typedef std::ptrdiff_t difference_type; /// Type used to represent a count of the elements in the range. typedef std::size_t size_type; /// Default constructor creates an empty range. basic_resolver_results() { } /// Copy constructor. basic_resolver_results(const basic_resolver_results& other) : basic_resolver_iterator(other) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. basic_resolver_results(basic_resolver_results&& other) : basic_resolver_iterator( ASIO_MOVE_CAST(basic_resolver_results)(other)) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator. basic_resolver_results& operator=(const basic_resolver_results& other) { basic_resolver_iterator::operator=(other); return *this; } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-assignment operator. basic_resolver_results& operator=(basic_resolver_results&& other) { basic_resolver_iterator::operator=( ASIO_MOVE_CAST(basic_resolver_results)(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #if !defined(GENERATING_DOCUMENTATION) // Create results from an addrinfo list returned by getaddrinfo. static basic_resolver_results create( asio::detail::addrinfo_type* address_info, const std::string& host_name, const std::string& service_name) { basic_resolver_results results; if (!address_info) return results; std::string actual_host_name = host_name; if (address_info->ai_canonname) actual_host_name = address_info->ai_canonname; results.values_.reset(new values_type); while (address_info) { if (address_info->ai_family == ASIO_OS_DEF(AF_INET) || address_info->ai_family == ASIO_OS_DEF(AF_INET6)) { using namespace std; // For memcpy. typename InternetProtocol::endpoint endpoint; endpoint.resize(static_cast(address_info->ai_addrlen)); memcpy(endpoint.data(), address_info->ai_addr, address_info->ai_addrlen); results.values_->push_back( basic_resolver_entry(endpoint, actual_host_name, service_name)); } address_info = address_info->ai_next; } return results; } // Create results from an endpoint, host name and service name. static basic_resolver_results create(const endpoint_type& endpoint, const std::string& host_name, const std::string& service_name) { basic_resolver_results results; results.values_.reset(new values_type); results.values_->push_back( basic_resolver_entry( endpoint, host_name, service_name)); return results; } // Create results from a sequence of endpoints, host and service name. template static basic_resolver_results create( EndpointIterator begin, EndpointIterator end, const std::string& host_name, const std::string& service_name) { basic_resolver_results results; if (begin != end) { results.values_.reset(new values_type); for (EndpointIterator ep_iter = begin; ep_iter != end; ++ep_iter) { results.values_->push_back( basic_resolver_entry( *ep_iter, host_name, service_name)); } } return results; } # if defined(ASIO_WINDOWS_RUNTIME) // Create results from a Windows Runtime list of EndpointPair objects. static basic_resolver_results create( Windows::Foundation::Collections::IVectorView< Windows::Networking::EndpointPair^>^ endpoints, const asio::detail::addrinfo_type& hints, const std::string& host_name, const std::string& service_name) { basic_resolver_results results; if (endpoints->Size) { results.values_.reset(new values_type); for (unsigned int i = 0; i < endpoints->Size; ++i) { auto pair = endpoints->GetAt(i); if (hints.ai_family == ASIO_OS_DEF(AF_INET) && pair->RemoteHostName->Type != Windows::Networking::HostNameType::Ipv4) continue; if (hints.ai_family == ASIO_OS_DEF(AF_INET6) && pair->RemoteHostName->Type != Windows::Networking::HostNameType::Ipv6) continue; results.values_->push_back( basic_resolver_entry( typename InternetProtocol::endpoint( ip::make_address( asio::detail::winrt_utils::string( pair->RemoteHostName->CanonicalName)), asio::detail::winrt_utils::integer( pair->RemoteServiceName)), host_name, service_name)); } } return results; } # endif // defined(ASIO_WINDOWS_RUNTIME) #endif // !defined(GENERATING_DOCUMENTATION) /// Get the number of entries in the results range. size_type size() const ASIO_NOEXCEPT { return this->values_ ? this->values_->size() : 0; } /// Get the maximum number of entries permitted in a results range. size_type max_size() const ASIO_NOEXCEPT { return this->values_ ? this->values_->max_size() : values_type().max_size(); } /// Determine whether the results range is empty. bool empty() const ASIO_NOEXCEPT { return this->values_ ? this->values_->empty() : true; } /// Obtain a begin iterator for the results range. const_iterator begin() const { basic_resolver_results tmp(*this); tmp.index_ = 0; return ASIO_MOVE_CAST(basic_resolver_results)(tmp); } /// Obtain an end iterator for the results range. const_iterator end() const { return const_iterator(); } /// Obtain a begin iterator for the results range. const_iterator cbegin() const { return begin(); } /// Obtain an end iterator for the results range. const_iterator cend() const { return end(); } /// Swap the results range with another. void swap(basic_resolver_results& that) ASIO_NOEXCEPT { if (this != &that) { this->values_.swap(that.values_); std::size_t index = this->index_; this->index_ = that.index_; that.index_ = index; } } /// Test two iterators for equality. friend bool operator==(const basic_resolver_results& a, const basic_resolver_results& b) { return a.equal(b); } /// Test two iterators for inequality. friend bool operator!=(const basic_resolver_results& a, const basic_resolver_results& b) { return !a.equal(b); } private: typedef std::vector > values_type; }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_BASIC_RESOLVER_RESULTS_HPP ================================================ FILE: src/third_party/asio/ip/detail/endpoint.hpp ================================================ // // ip/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_DETAIL_ENDPOINT_HPP #define ASIO_IP_DETAIL_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/socket_types.hpp" #include "asio/detail/winsock_init.hpp" #include "asio/error_code.hpp" #include "asio/ip/address.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { namespace detail { // Helper class for implementating an IP endpoint. class endpoint { public: // Default constructor. ASIO_DECL endpoint() ASIO_NOEXCEPT; // Construct an endpoint using a family and port number. ASIO_DECL endpoint(int family, unsigned short port_num) ASIO_NOEXCEPT; // Construct an endpoint using an address and port number. ASIO_DECL endpoint(const asio::ip::address& addr, unsigned short port_num) ASIO_NOEXCEPT; // Copy constructor. endpoint(const endpoint& other) ASIO_NOEXCEPT : data_(other.data_) { } // Assign from another endpoint. endpoint& operator=(const endpoint& other) ASIO_NOEXCEPT { data_ = other.data_; return *this; } // Get the underlying endpoint in the native type. asio::detail::socket_addr_type* data() ASIO_NOEXCEPT { return &data_.base; } // Get the underlying endpoint in the native type. const asio::detail::socket_addr_type* data() const ASIO_NOEXCEPT { return &data_.base; } // Get the underlying size of the endpoint in the native type. std::size_t size() const ASIO_NOEXCEPT { if (is_v4()) return sizeof(asio::detail::sockaddr_in4_type); else return sizeof(asio::detail::sockaddr_in6_type); } // Set the underlying size of the endpoint in the native type. ASIO_DECL void resize(std::size_t new_size); // Get the capacity of the endpoint in the native type. std::size_t capacity() const ASIO_NOEXCEPT { return sizeof(data_); } // Get the port associated with the endpoint. ASIO_DECL unsigned short port() const ASIO_NOEXCEPT; // Set the port associated with the endpoint. ASIO_DECL void port(unsigned short port_num) ASIO_NOEXCEPT; // Get the IP address associated with the endpoint. ASIO_DECL asio::ip::address address() const ASIO_NOEXCEPT; // Set the IP address associated with the endpoint. ASIO_DECL void address( const asio::ip::address& addr) ASIO_NOEXCEPT; // Compare two endpoints for equality. ASIO_DECL friend bool operator==(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT; // Compare endpoints for ordering. ASIO_DECL friend bool operator<(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT; // Determine whether the endpoint is IPv4. bool is_v4() const ASIO_NOEXCEPT { return data_.base.sa_family == ASIO_OS_DEF(AF_INET); } #if !defined(ASIO_NO_IOSTREAM) // Convert to a string. ASIO_DECL std::string to_string() const; #endif // !defined(ASIO_NO_IOSTREAM) private: // The underlying IP socket address. union data_union { asio::detail::socket_addr_type base; asio::detail::sockaddr_in4_type v4; asio::detail::sockaddr_in6_type v6; } data_; }; } // namespace detail } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ip/detail/impl/endpoint.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_IP_DETAIL_ENDPOINT_HPP ================================================ FILE: src/third_party/asio/ip/detail/impl/endpoint.ipp ================================================ // // ip/detail/impl/endpoint.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP #define ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #if !defined(ASIO_NO_IOSTREAM) # include #endif // !defined(ASIO_NO_IOSTREAM) #include "asio/detail/socket_ops.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/ip/detail/endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { namespace detail { endpoint::endpoint() ASIO_NOEXCEPT : data_() { data_.v4.sin_family = ASIO_OS_DEF(AF_INET); data_.v4.sin_port = 0; data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); } endpoint::endpoint(int family, unsigned short port_num) ASIO_NOEXCEPT : data_() { using namespace std; // For memcpy. if (family == ASIO_OS_DEF(AF_INET)) { data_.v4.sin_family = ASIO_OS_DEF(AF_INET); data_.v4.sin_port = asio::detail::socket_ops::host_to_network_short(port_num); data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); } else { data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6); data_.v6.sin6_port = asio::detail::socket_ops::host_to_network_short(port_num); data_.v6.sin6_flowinfo = 0; data_.v6.sin6_addr.s6_addr[0] = 0; data_.v6.sin6_addr.s6_addr[1] = 0; data_.v6.sin6_addr.s6_addr[2] = 0; data_.v6.sin6_addr.s6_addr[3] = 0; data_.v6.sin6_addr.s6_addr[4] = 0; data_.v6.sin6_addr.s6_addr[5] = 0; data_.v6.sin6_addr.s6_addr[6] = 0; data_.v6.sin6_addr.s6_addr[7] = 0; data_.v6.sin6_addr.s6_addr[8] = 0; data_.v6.sin6_addr.s6_addr[9] = 0; data_.v6.sin6_addr.s6_addr[10] = 0; data_.v6.sin6_addr.s6_addr[11] = 0; data_.v6.sin6_addr.s6_addr[12] = 0; data_.v6.sin6_addr.s6_addr[13] = 0; data_.v6.sin6_addr.s6_addr[14] = 0; data_.v6.sin6_addr.s6_addr[15] = 0; data_.v6.sin6_scope_id = 0; } } endpoint::endpoint(const asio::ip::address& addr, unsigned short port_num) ASIO_NOEXCEPT : data_() { using namespace std; // For memcpy. if (addr.is_v4()) { data_.v4.sin_family = ASIO_OS_DEF(AF_INET); data_.v4.sin_port = asio::detail::socket_ops::host_to_network_short(port_num); data_.v4.sin_addr.s_addr = asio::detail::socket_ops::host_to_network_long( addr.to_v4().to_uint()); } else { data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6); data_.v6.sin6_port = asio::detail::socket_ops::host_to_network_short(port_num); data_.v6.sin6_flowinfo = 0; asio::ip::address_v6 v6_addr = addr.to_v6(); asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); memcpy(data_.v6.sin6_addr.s6_addr, bytes.data(), 16); data_.v6.sin6_scope_id = static_cast( v6_addr.scope_id()); } } void endpoint::resize(std::size_t new_size) { if (new_size > sizeof(asio::detail::sockaddr_storage_type)) { asio::error_code ec(asio::error::invalid_argument); asio::detail::throw_error(ec); } } unsigned short endpoint::port() const ASIO_NOEXCEPT { if (is_v4()) { return asio::detail::socket_ops::network_to_host_short( data_.v4.sin_port); } else { return asio::detail::socket_ops::network_to_host_short( data_.v6.sin6_port); } } void endpoint::port(unsigned short port_num) ASIO_NOEXCEPT { if (is_v4()) { data_.v4.sin_port = asio::detail::socket_ops::host_to_network_short(port_num); } else { data_.v6.sin6_port = asio::detail::socket_ops::host_to_network_short(port_num); } } asio::ip::address endpoint::address() const ASIO_NOEXCEPT { using namespace std; // For memcpy. if (is_v4()) { return asio::ip::address_v4( asio::detail::socket_ops::network_to_host_long( data_.v4.sin_addr.s_addr)); } else { asio::ip::address_v6::bytes_type bytes; #if defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.data(), data_.v6.sin6_addr.s6_addr, 16); #else // defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16); #endif // defined(ASIO_HAS_STD_ARRAY) return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); } } void endpoint::address(const asio::ip::address& addr) ASIO_NOEXCEPT { endpoint tmp_endpoint(addr, port()); data_ = tmp_endpoint.data_; } bool operator==(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT { return e1.address() == e2.address() && e1.port() == e2.port(); } bool operator<(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT { if (e1.address() < e2.address()) return true; if (e1.address() != e2.address()) return false; return e1.port() < e2.port(); } #if !defined(ASIO_NO_IOSTREAM) std::string endpoint::to_string() const { std::ostringstream tmp_os; tmp_os.imbue(std::locale::classic()); if (is_v4()) tmp_os << address(); else tmp_os << '[' << address() << ']'; tmp_os << ':' << port(); return tmp_os.str(); } #endif // !defined(ASIO_NO_IOSTREAM) } // namespace detail } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP ================================================ FILE: src/third_party/asio/ip/detail/socket_option.hpp ================================================ // // detail/socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_DETAIL_SOCKET_OPTION_HPP #define ASIO_IP_DETAIL_SOCKET_OPTION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/ip/address.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { namespace detail { namespace socket_option { // Helper template for implementing multicast enable loopback options. template class multicast_enable_loopback { public: #if defined(__sun) || defined(__osf__) typedef unsigned char ipv4_value_type; typedef unsigned char ipv6_value_type; #elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__) typedef unsigned char ipv4_value_type; typedef unsigned int ipv6_value_type; #else typedef int ipv4_value_type; typedef int ipv6_value_type; #endif // Default constructor. multicast_enable_loopback() : ipv4_value_(0), ipv6_value_(0) { } // Construct with a specific option value. explicit multicast_enable_loopback(bool v) : ipv4_value_(v ? 1 : 0), ipv6_value_(v ? 1 : 0) { } // Set the value of the boolean. multicast_enable_loopback& operator=(bool v) { ipv4_value_ = v ? 1 : 0; ipv6_value_ = v ? 1 : 0; return *this; } // Get the current value of the boolean. bool value() const { return !!ipv4_value_; } // Convert to bool. operator bool() const { return !!ipv4_value_; } // Test for false. bool operator!() const { return !ipv4_value_; } // Get the level of the socket option. template int level(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Level; return IPv4_Level; } // Get the name of the socket option. template int name(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Name; return IPv4_Name; } // Get the address of the boolean data. template void* data(const Protocol& protocol) { if (protocol.family() == PF_INET6) return &ipv6_value_; return &ipv4_value_; } // Get the address of the boolean data. template const void* data(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return &ipv6_value_; return &ipv4_value_; } // Get the size of the boolean data. template std::size_t size(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return sizeof(ipv6_value_); return sizeof(ipv4_value_); } // Set the size of the boolean data. template void resize(const Protocol& protocol, std::size_t s) { if (protocol.family() == PF_INET6) { if (s != sizeof(ipv6_value_)) { std::length_error ex("multicast_enable_loopback socket option resize"); asio::detail::throw_exception(ex); } ipv4_value_ = ipv6_value_ ? 1 : 0; } else { if (s != sizeof(ipv4_value_)) { std::length_error ex("multicast_enable_loopback socket option resize"); asio::detail::throw_exception(ex); } ipv6_value_ = ipv4_value_ ? 1 : 0; } } private: ipv4_value_type ipv4_value_; ipv6_value_type ipv6_value_; }; // Helper template for implementing unicast hops options. template class unicast_hops { public: // Default constructor. unicast_hops() : value_(0) { } // Construct with a specific option value. explicit unicast_hops(int v) : value_(v) { } // Set the value of the option. unicast_hops& operator=(int v) { value_ = v; return *this; } // Get the current value of the option. int value() const { return value_; } // Get the level of the socket option. template int level(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Level; return IPv4_Level; } // Get the name of the socket option. template int name(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Name; return IPv4_Name; } // Get the address of the data. template int* data(const Protocol&) { return &value_; } // Get the address of the data. template const int* data(const Protocol&) const { return &value_; } // Get the size of the data. template std::size_t size(const Protocol&) const { return sizeof(value_); } // Set the size of the data. template void resize(const Protocol&, std::size_t s) { if (s != sizeof(value_)) { std::length_error ex("unicast hops socket option resize"); asio::detail::throw_exception(ex); } #if defined(__hpux) if (value_ < 0) value_ = value_ & 0xFF; #endif } private: int value_; }; // Helper template for implementing multicast hops options. template class multicast_hops { public: #if defined(ASIO_WINDOWS) && defined(UNDER_CE) typedef int ipv4_value_type; #else typedef unsigned char ipv4_value_type; #endif typedef int ipv6_value_type; // Default constructor. multicast_hops() : ipv4_value_(0), ipv6_value_(0) { } // Construct with a specific option value. explicit multicast_hops(int v) { if (v < 0 || v > 255) { std::out_of_range ex("multicast hops value out of range"); asio::detail::throw_exception(ex); } ipv4_value_ = (ipv4_value_type)v; ipv6_value_ = v; } // Set the value of the option. multicast_hops& operator=(int v) { if (v < 0 || v > 255) { std::out_of_range ex("multicast hops value out of range"); asio::detail::throw_exception(ex); } ipv4_value_ = (ipv4_value_type)v; ipv6_value_ = v; return *this; } // Get the current value of the option. int value() const { return ipv6_value_; } // Get the level of the socket option. template int level(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Level; return IPv4_Level; } // Get the name of the socket option. template int name(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Name; return IPv4_Name; } // Get the address of the data. template void* data(const Protocol& protocol) { if (protocol.family() == PF_INET6) return &ipv6_value_; return &ipv4_value_; } // Get the address of the data. template const void* data(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return &ipv6_value_; return &ipv4_value_; } // Get the size of the data. template std::size_t size(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return sizeof(ipv6_value_); return sizeof(ipv4_value_); } // Set the size of the data. template void resize(const Protocol& protocol, std::size_t s) { if (protocol.family() == PF_INET6) { if (s != sizeof(ipv6_value_)) { std::length_error ex("multicast hops socket option resize"); asio::detail::throw_exception(ex); } if (ipv6_value_ < 0) ipv4_value_ = 0; else if (ipv6_value_ > 255) ipv4_value_ = 255; else ipv4_value_ = (ipv4_value_type)ipv6_value_; } else { if (s != sizeof(ipv4_value_)) { std::length_error ex("multicast hops socket option resize"); asio::detail::throw_exception(ex); } ipv6_value_ = ipv4_value_; } } private: ipv4_value_type ipv4_value_; ipv6_value_type ipv6_value_; }; // Helper template for implementing ip_mreq-based options. template class multicast_request { public: // Default constructor. multicast_request() : ipv4_value_(), // Zero-initialisation gives the "any" address. ipv6_value_() // Zero-initialisation gives the "any" address. { } // Construct with multicast address only. explicit multicast_request(const address& multicast_address) : ipv4_value_(), // Zero-initialisation gives the "any" address. ipv6_value_() // Zero-initialisation gives the "any" address. { if (multicast_address.is_v6()) { using namespace std; // For memcpy. address_v6 ipv6_address = multicast_address.to_v6(); address_v6::bytes_type bytes = ipv6_address.to_bytes(); memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.data(), 16); ipv6_value_.ipv6mr_interface = ipv6_address.scope_id(); } else { ipv4_value_.imr_multiaddr.s_addr = asio::detail::socket_ops::host_to_network_long( multicast_address.to_v4().to_uint()); ipv4_value_.imr_interface.s_addr = asio::detail::socket_ops::host_to_network_long( address_v4::any().to_uint()); } } // Construct with multicast address and IPv4 address specifying an interface. explicit multicast_request(const address_v4& multicast_address, const address_v4& network_interface = address_v4::any()) : ipv6_value_() // Zero-initialisation gives the "any" address. { ipv4_value_.imr_multiaddr.s_addr = asio::detail::socket_ops::host_to_network_long( multicast_address.to_uint()); ipv4_value_.imr_interface.s_addr = asio::detail::socket_ops::host_to_network_long( network_interface.to_uint()); } // Construct with multicast address and IPv6 network interface index. explicit multicast_request( const address_v6& multicast_address, unsigned long network_interface = 0) : ipv4_value_() // Zero-initialisation gives the "any" address. { using namespace std; // For memcpy. address_v6::bytes_type bytes = multicast_address.to_bytes(); memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.data(), 16); if (network_interface) ipv6_value_.ipv6mr_interface = network_interface; else ipv6_value_.ipv6mr_interface = multicast_address.scope_id(); } // Get the level of the socket option. template int level(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Level; return IPv4_Level; } // Get the name of the socket option. template int name(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Name; return IPv4_Name; } // Get the address of the option data. template const void* data(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return &ipv6_value_; return &ipv4_value_; } // Get the size of the option data. template std::size_t size(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return sizeof(ipv6_value_); return sizeof(ipv4_value_); } private: asio::detail::in4_mreq_type ipv4_value_; asio::detail::in6_mreq_type ipv6_value_; }; // Helper template for implementing options that specify a network interface. template class network_interface { public: // Default constructor. network_interface() { ipv4_value_.s_addr = asio::detail::socket_ops::host_to_network_long( address_v4::any().to_uint()); ipv6_value_ = 0; } // Construct with IPv4 interface. explicit network_interface(const address_v4& ipv4_interface) { ipv4_value_.s_addr = asio::detail::socket_ops::host_to_network_long( ipv4_interface.to_uint()); ipv6_value_ = 0; } // Construct with IPv6 interface. explicit network_interface(unsigned int ipv6_interface) { ipv4_value_.s_addr = asio::detail::socket_ops::host_to_network_long( address_v4::any().to_uint()); ipv6_value_ = ipv6_interface; } // Get the level of the socket option. template int level(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Level; return IPv4_Level; } // Get the name of the socket option. template int name(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return IPv6_Name; return IPv4_Name; } // Get the address of the option data. template const void* data(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return &ipv6_value_; return &ipv4_value_; } // Get the size of the option data. template std::size_t size(const Protocol& protocol) const { if (protocol.family() == PF_INET6) return sizeof(ipv6_value_); return sizeof(ipv4_value_); } private: asio::detail::in4_addr_type ipv4_value_; unsigned int ipv6_value_; }; } // namespace socket_option } // namespace detail } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_DETAIL_SOCKET_OPTION_HPP ================================================ FILE: src/third_party/asio/ip/host_name.hpp ================================================ // // ip/host_name.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_HOST_NAME_HPP #define ASIO_IP_HOST_NAME_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/error_code.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Get the current host name. ASIO_DECL std::string host_name(); /// Get the current host name. ASIO_DECL std::string host_name(asio::error_code& ec); } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ip/impl/host_name.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_IP_HOST_NAME_HPP ================================================ FILE: src/third_party/asio/ip/icmp.hpp ================================================ // // ip/icmp.hpp // ~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_ICMP_HPP #define ASIO_IP_ICMP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/socket_types.hpp" #include "asio/basic_raw_socket.hpp" #include "asio/ip/basic_endpoint.hpp" #include "asio/ip/basic_resolver.hpp" #include "asio/ip/basic_resolver_iterator.hpp" #include "asio/ip/basic_resolver_query.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Encapsulates the flags needed for ICMP. /** * The asio::ip::icmp class contains flags necessary for ICMP sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol, InternetProtocol. */ class icmp { public: /// The type of a ICMP endpoint. typedef basic_endpoint endpoint; /// Construct to represent the IPv4 ICMP protocol. static icmp v4() ASIO_NOEXCEPT { return icmp(ASIO_OS_DEF(IPPROTO_ICMP), ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 ICMP protocol. static icmp v6() ASIO_NOEXCEPT { return icmp(ASIO_OS_DEF(IPPROTO_ICMPV6), ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_RAW); } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return family_; } /// The ICMP socket type. typedef basic_raw_socket socket; /// The ICMP resolver type. typedef basic_resolver resolver; /// Compare two protocols for equality. friend bool operator==(const icmp& p1, const icmp& p2) { return p1.protocol_ == p2.protocol_ && p1.family_ == p2.family_; } /// Compare two protocols for inequality. friend bool operator!=(const icmp& p1, const icmp& p2) { return p1.protocol_ != p2.protocol_ || p1.family_ != p2.family_; } private: // Construct with a specific family. explicit icmp(int protocol_id, int protocol_family) ASIO_NOEXCEPT : protocol_(protocol_id), family_(protocol_family) { } int protocol_; int family_; }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_ICMP_HPP ================================================ FILE: src/third_party/asio/ip/impl/address.hpp ================================================ // // ip/impl/address.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_ADDRESS_HPP #define ASIO_IP_IMPL_ADDRESS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if !defined(ASIO_NO_IOSTREAM) #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { #if !defined(ASIO_NO_DEPRECATED) inline address address::from_string(const char* str) { return asio::ip::make_address(str); } inline address address::from_string( const char* str, asio::error_code& ec) { return asio::ip::make_address(str, ec); } inline address address::from_string(const std::string& str) { return asio::ip::make_address(str); } inline address address::from_string( const std::string& str, asio::error_code& ec) { return asio::ip::make_address(str, ec); } #endif // !defined(ASIO_NO_DEPRECATED) template std::basic_ostream& operator<<( std::basic_ostream& os, const address& addr) { return os << addr.to_string().c_str(); } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_IP_IMPL_ADDRESS_HPP ================================================ FILE: src/third_party/asio/ip/impl/address.ipp ================================================ // // ip/impl/address.ipp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_ADDRESS_IPP #define ASIO_IP_IMPL_ADDRESS_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/throw_error.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/error.hpp" #include "asio/ip/address.hpp" #include "asio/ip/bad_address_cast.hpp" #include "asio/system_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { address::address() ASIO_NOEXCEPT : type_(ipv4), ipv4_address_(), ipv6_address_() { } address::address( const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT : type_(ipv4), ipv4_address_(ipv4_address), ipv6_address_() { } address::address( const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT : type_(ipv6), ipv4_address_(), ipv6_address_(ipv6_address) { } address::address(const address& other) ASIO_NOEXCEPT : type_(other.type_), ipv4_address_(other.ipv4_address_), ipv6_address_(other.ipv6_address_) { } #if defined(ASIO_HAS_MOVE) address::address(address&& other) ASIO_NOEXCEPT : type_(other.type_), ipv4_address_(other.ipv4_address_), ipv6_address_(other.ipv6_address_) { } #endif // defined(ASIO_HAS_MOVE) address& address::operator=(const address& other) ASIO_NOEXCEPT { type_ = other.type_; ipv4_address_ = other.ipv4_address_; ipv6_address_ = other.ipv6_address_; return *this; } #if defined(ASIO_HAS_MOVE) address& address::operator=(address&& other) ASIO_NOEXCEPT { type_ = other.type_; ipv4_address_ = other.ipv4_address_; ipv6_address_ = other.ipv6_address_; return *this; } #endif // defined(ASIO_HAS_MOVE) address& address::operator=( const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT { type_ = ipv4; ipv4_address_ = ipv4_address; ipv6_address_ = asio::ip::address_v6(); return *this; } address& address::operator=( const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT { type_ = ipv6; ipv4_address_ = asio::ip::address_v4(); ipv6_address_ = ipv6_address; return *this; } address make_address(const char* str) { asio::error_code ec; address addr = make_address(str, ec); asio::detail::throw_error(ec); return addr; } address make_address(const char* str, asio::error_code& ec) ASIO_NOEXCEPT { asio::ip::address_v6 ipv6_address = asio::ip::make_address_v6(str, ec); if (!ec) return address(ipv6_address); asio::ip::address_v4 ipv4_address = asio::ip::make_address_v4(str, ec); if (!ec) return address(ipv4_address); return address(); } address make_address(const std::string& str) { return make_address(str.c_str()); } address make_address(const std::string& str, asio::error_code& ec) ASIO_NOEXCEPT { return make_address(str.c_str(), ec); } #if defined(ASIO_HAS_STRING_VIEW) address make_address(string_view str) { return make_address(static_cast(str)); } address make_address(string_view str, asio::error_code& ec) ASIO_NOEXCEPT { return make_address(static_cast(str), ec); } #endif // defined(ASIO_HAS_STRING_VIEW) asio::ip::address_v4 address::to_v4() const { if (type_ != ipv4) { bad_address_cast ex; asio::detail::throw_exception(ex); } return ipv4_address_; } asio::ip::address_v6 address::to_v6() const { if (type_ != ipv6) { bad_address_cast ex; asio::detail::throw_exception(ex); } return ipv6_address_; } std::string address::to_string() const { if (type_ == ipv6) return ipv6_address_.to_string(); return ipv4_address_.to_string(); } #if !defined(ASIO_NO_DEPRECATED) std::string address::to_string(asio::error_code& ec) const { if (type_ == ipv6) return ipv6_address_.to_string(ec); return ipv4_address_.to_string(ec); } #endif // !defined(ASIO_NO_DEPRECATED) bool address::is_loopback() const ASIO_NOEXCEPT { return (type_ == ipv4) ? ipv4_address_.is_loopback() : ipv6_address_.is_loopback(); } bool address::is_unspecified() const ASIO_NOEXCEPT { return (type_ == ipv4) ? ipv4_address_.is_unspecified() : ipv6_address_.is_unspecified(); } bool address::is_multicast() const ASIO_NOEXCEPT { return (type_ == ipv4) ? ipv4_address_.is_multicast() : ipv6_address_.is_multicast(); } bool operator==(const address& a1, const address& a2) ASIO_NOEXCEPT { if (a1.type_ != a2.type_) return false; if (a1.type_ == address::ipv6) return a1.ipv6_address_ == a2.ipv6_address_; return a1.ipv4_address_ == a2.ipv4_address_; } bool operator<(const address& a1, const address& a2) ASIO_NOEXCEPT { if (a1.type_ < a2.type_) return true; if (a1.type_ > a2.type_) return false; if (a1.type_ == address::ipv6) return a1.ipv6_address_ < a2.ipv6_address_; return a1.ipv4_address_ < a2.ipv4_address_; } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_IMPL_ADDRESS_IPP ================================================ FILE: src/third_party/asio/ip/impl/address_v4.hpp ================================================ // // ip/impl/address_v4.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_ADDRESS_V4_HPP #define ASIO_IP_IMPL_ADDRESS_V4_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if !defined(ASIO_NO_IOSTREAM) #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { #if !defined(ASIO_NO_DEPRECATED) inline address_v4 address_v4::from_string(const char* str) { return asio::ip::make_address_v4(str); } inline address_v4 address_v4::from_string( const char* str, asio::error_code& ec) { return asio::ip::make_address_v4(str, ec); } inline address_v4 address_v4::from_string(const std::string& str) { return asio::ip::make_address_v4(str); } inline address_v4 address_v4::from_string( const std::string& str, asio::error_code& ec) { return asio::ip::make_address_v4(str, ec); } #endif // !defined(ASIO_NO_DEPRECATED) template std::basic_ostream& operator<<( std::basic_ostream& os, const address_v4& addr) { return os << addr.to_string().c_str(); } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_IP_IMPL_ADDRESS_V4_HPP ================================================ FILE: src/third_party/asio/ip/impl/address_v4.ipp ================================================ // // ip/impl/address_v4.ipp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_ADDRESS_V4_IPP #define ASIO_IP_IMPL_ADDRESS_V4_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include "asio/error.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/ip/address_v4.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { address_v4::address_v4(const address_v4::bytes_type& bytes) { #if UCHAR_MAX > 0xFF if (bytes[0] > 0xFF || bytes[1] > 0xFF || bytes[2] > 0xFF || bytes[3] > 0xFF) { std::out_of_range ex("address_v4 from bytes_type"); asio::detail::throw_exception(ex); } #endif // UCHAR_MAX > 0xFF using namespace std; // For memcpy. memcpy(&addr_.s_addr, bytes.data(), 4); } address_v4::address_v4(address_v4::uint_type addr) { if ((std::numeric_limits::max)() > 0xFFFFFFFF) { std::out_of_range ex("address_v4 from unsigned integer"); asio::detail::throw_exception(ex); } addr_.s_addr = asio::detail::socket_ops::host_to_network_long( static_cast(addr)); } address_v4::bytes_type address_v4::to_bytes() const ASIO_NOEXCEPT { using namespace std; // For memcpy. bytes_type bytes; #if defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.data(), &addr_.s_addr, 4); #else // defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.elems, &addr_.s_addr, 4); #endif // defined(ASIO_HAS_STD_ARRAY) return bytes; } address_v4::uint_type address_v4::to_uint() const ASIO_NOEXCEPT { return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); } #if !defined(ASIO_NO_DEPRECATED) unsigned long address_v4::to_ulong() const { return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); } #endif // !defined(ASIO_NO_DEPRECATED) std::string address_v4::to_string() const { asio::error_code ec; char addr_str[asio::detail::max_addr_v4_str_len]; const char* addr = asio::detail::socket_ops::inet_ntop( ASIO_OS_DEF(AF_INET), &addr_, addr_str, asio::detail::max_addr_v4_str_len, 0, ec); if (addr == 0) asio::detail::throw_error(ec); return addr; } #if !defined(ASIO_NO_DEPRECATED) std::string address_v4::to_string(asio::error_code& ec) const { char addr_str[asio::detail::max_addr_v4_str_len]; const char* addr = asio::detail::socket_ops::inet_ntop( ASIO_OS_DEF(AF_INET), &addr_, addr_str, asio::detail::max_addr_v4_str_len, 0, ec); if (addr == 0) return std::string(); return addr; } #endif // !defined(ASIO_NO_DEPRECATED) bool address_v4::is_loopback() const ASIO_NOEXCEPT { return (to_uint() & 0xFF000000) == 0x7F000000; } bool address_v4::is_unspecified() const ASIO_NOEXCEPT { return to_uint() == 0; } #if !defined(ASIO_NO_DEPRECATED) bool address_v4::is_class_a() const { return (to_uint() & 0x80000000) == 0; } bool address_v4::is_class_b() const { return (to_uint() & 0xC0000000) == 0x80000000; } bool address_v4::is_class_c() const { return (to_uint() & 0xE0000000) == 0xC0000000; } #endif // !defined(ASIO_NO_DEPRECATED) bool address_v4::is_multicast() const ASIO_NOEXCEPT { return (to_uint() & 0xF0000000) == 0xE0000000; } #if !defined(ASIO_NO_DEPRECATED) address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask) { return address_v4(addr.to_uint() | (mask.to_uint() ^ 0xFFFFFFFF)); } address_v4 address_v4::netmask(const address_v4& addr) { if (addr.is_class_a()) return address_v4(0xFF000000); if (addr.is_class_b()) return address_v4(0xFFFF0000); if (addr.is_class_c()) return address_v4(0xFFFFFF00); return address_v4(0xFFFFFFFF); } #endif // !defined(ASIO_NO_DEPRECATED) address_v4 make_address_v4(const char* str) { asio::error_code ec; address_v4 addr = make_address_v4(str, ec); asio::detail::throw_error(ec); return addr; } address_v4 make_address_v4(const char* str, asio::error_code& ec) ASIO_NOEXCEPT { address_v4::bytes_type bytes; if (asio::detail::socket_ops::inet_pton( ASIO_OS_DEF(AF_INET), str, &bytes, 0, ec) <= 0) return address_v4(); return address_v4(bytes); } address_v4 make_address_v4(const std::string& str) { return make_address_v4(str.c_str()); } address_v4 make_address_v4(const std::string& str, asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v4(str.c_str(), ec); } #if defined(ASIO_HAS_STRING_VIEW) address_v4 make_address_v4(string_view str) { return make_address_v4(static_cast(str)); } address_v4 make_address_v4(string_view str, asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v4(static_cast(str), ec); } #endif // defined(ASIO_HAS_STRING_VIEW) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_IMPL_ADDRESS_V4_IPP ================================================ FILE: src/third_party/asio/ip/impl/address_v6.hpp ================================================ // // ip/impl/address_v6.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_ADDRESS_V6_HPP #define ASIO_IP_IMPL_ADDRESS_V6_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if !defined(ASIO_NO_IOSTREAM) #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { #if !defined(ASIO_NO_DEPRECATED) inline address_v6 address_v6::from_string(const char* str) { return asio::ip::make_address_v6(str); } inline address_v6 address_v6::from_string( const char* str, asio::error_code& ec) { return asio::ip::make_address_v6(str, ec); } inline address_v6 address_v6::from_string(const std::string& str) { return asio::ip::make_address_v6(str); } inline address_v6 address_v6::from_string( const std::string& str, asio::error_code& ec) { return asio::ip::make_address_v6(str, ec); } #endif // !defined(ASIO_NO_DEPRECATED) template std::basic_ostream& operator<<( std::basic_ostream& os, const address_v6& addr) { return os << addr.to_string().c_str(); } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_IP_IMPL_ADDRESS_V6_HPP ================================================ FILE: src/third_party/asio/ip/impl/address_v6.ipp ================================================ // // ip/impl/address_v6.ipp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_ADDRESS_V6_IPP #define ASIO_IP_IMPL_ADDRESS_V6_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include "asio/detail/socket_ops.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/error.hpp" #include "asio/ip/address_v6.hpp" #include "asio/ip/bad_address_cast.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { address_v6::address_v6() ASIO_NOEXCEPT : addr_(), scope_id_(0) { } address_v6::address_v6(const address_v6::bytes_type& bytes, unsigned long scope) : scope_id_(scope) { #if UCHAR_MAX > 0xFF for (std::size_t i = 0; i < bytes.size(); ++i) { if (bytes[i] > 0xFF) { std::out_of_range ex("address_v6 from bytes_type"); asio::detail::throw_exception(ex); } } #endif // UCHAR_MAX > 0xFF using namespace std; // For memcpy. memcpy(addr_.s6_addr, bytes.data(), 16); } address_v6::address_v6(const address_v6& other) ASIO_NOEXCEPT : addr_(other.addr_), scope_id_(other.scope_id_) { } #if defined(ASIO_HAS_MOVE) address_v6::address_v6(address_v6&& other) ASIO_NOEXCEPT : addr_(other.addr_), scope_id_(other.scope_id_) { } #endif // defined(ASIO_HAS_MOVE) address_v6& address_v6::operator=(const address_v6& other) ASIO_NOEXCEPT { addr_ = other.addr_; scope_id_ = other.scope_id_; return *this; } #if defined(ASIO_HAS_MOVE) address_v6& address_v6::operator=(address_v6&& other) ASIO_NOEXCEPT { addr_ = other.addr_; scope_id_ = other.scope_id_; return *this; } #endif // defined(ASIO_HAS_MOVE) address_v6::bytes_type address_v6::to_bytes() const ASIO_NOEXCEPT { using namespace std; // For memcpy. bytes_type bytes; #if defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.data(), addr_.s6_addr, 16); #else // defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.elems, addr_.s6_addr, 16); #endif // defined(ASIO_HAS_STD_ARRAY) return bytes; } std::string address_v6::to_string() const { asio::error_code ec; char addr_str[asio::detail::max_addr_v6_str_len]; const char* addr = asio::detail::socket_ops::inet_ntop( ASIO_OS_DEF(AF_INET6), &addr_, addr_str, asio::detail::max_addr_v6_str_len, scope_id_, ec); if (addr == 0) asio::detail::throw_error(ec); return addr; } #if !defined(ASIO_NO_DEPRECATED) std::string address_v6::to_string(asio::error_code& ec) const { char addr_str[asio::detail::max_addr_v6_str_len]; const char* addr = asio::detail::socket_ops::inet_ntop( ASIO_OS_DEF(AF_INET6), &addr_, addr_str, asio::detail::max_addr_v6_str_len, scope_id_, ec); if (addr == 0) return std::string(); return addr; } address_v4 address_v6::to_v4() const { if (!is_v4_mapped() && !is_v4_compatible()) { bad_address_cast ex; asio::detail::throw_exception(ex); } address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12], addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } }; return address_v4(v4_bytes); } #endif // !defined(ASIO_NO_DEPRECATED) bool address_v6::is_loopback() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); } bool address_v6::is_unspecified() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); } bool address_v6::is_link_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80)); } bool address_v6::is_site_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0)); } bool address_v6::is_v4_mapped() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) && (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff)); } #if !defined(ASIO_NO_DEPRECATED) bool address_v6::is_v4_compatible() const { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) && !((addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) && (addr_.s6_addr[14] == 0) && ((addr_.s6_addr[15] == 0) || (addr_.s6_addr[15] == 1)))); } #endif // !defined(ASIO_NO_DEPRECATED) bool address_v6::is_multicast() const ASIO_NOEXCEPT { return (addr_.s6_addr[0] == 0xff); } bool address_v6::is_multicast_global() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e)); } bool address_v6::is_multicast_link_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02)); } bool address_v6::is_multicast_node_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01)); } bool address_v6::is_multicast_org_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08)); } bool address_v6::is_multicast_site_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05)); } bool operator==(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { using namespace std; // For memcmp. return memcmp(&a1.addr_, &a2.addr_, sizeof(asio::detail::in6_addr_type)) == 0 && a1.scope_id_ == a2.scope_id_; } bool operator<(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { using namespace std; // For memcmp. int memcmp_result = memcmp(&a1.addr_, &a2.addr_, sizeof(asio::detail::in6_addr_type)); if (memcmp_result < 0) return true; if (memcmp_result > 0) return false; return a1.scope_id_ < a2.scope_id_; } address_v6 address_v6::loopback() ASIO_NOEXCEPT { address_v6 tmp; tmp.addr_.s6_addr[15] = 1; return tmp; } #if !defined(ASIO_NO_DEPRECATED) address_v6 address_v6::v4_mapped(const address_v4& addr) { address_v4::bytes_type v4_bytes = addr.to_bytes(); bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; return address_v6(v6_bytes); } address_v6 address_v6::v4_compatible(const address_v4& addr) { address_v4::bytes_type v4_bytes = addr.to_bytes(); bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; return address_v6(v6_bytes); } #endif // !defined(ASIO_NO_DEPRECATED) address_v6 make_address_v6(const char* str) { asio::error_code ec; address_v6 addr = make_address_v6(str, ec); asio::detail::throw_error(ec); return addr; } address_v6 make_address_v6(const char* str, asio::error_code& ec) ASIO_NOEXCEPT { address_v6::bytes_type bytes; unsigned long scope_id = 0; if (asio::detail::socket_ops::inet_pton( ASIO_OS_DEF(AF_INET6), str, &bytes[0], &scope_id, ec) <= 0) return address_v6(); return address_v6(bytes, scope_id); } address_v6 make_address_v6(const std::string& str) { return make_address_v6(str.c_str()); } address_v6 make_address_v6(const std::string& str, asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v6(str.c_str(), ec); } #if defined(ASIO_HAS_STRING_VIEW) address_v6 make_address_v6(string_view str) { return make_address_v6(static_cast(str)); } address_v6 make_address_v6(string_view str, asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v6(static_cast(str), ec); } #endif // defined(ASIO_HAS_STRING_VIEW) address_v4 make_address_v4( v4_mapped_t, const address_v6& v6_addr) { if (!v6_addr.is_v4_mapped()) { bad_address_cast ex; asio::detail::throw_exception(ex); } address_v6::bytes_type v6_bytes = v6_addr.to_bytes(); address_v4::bytes_type v4_bytes = { { v6_bytes[12], v6_bytes[13], v6_bytes[14], v6_bytes[15] } }; return address_v4(v4_bytes); } address_v6 make_address_v6( v4_mapped_t, const address_v4& v4_addr) { address_v4::bytes_type v4_bytes = v4_addr.to_bytes(); address_v6::bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; return address_v6(v6_bytes); } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_IMPL_ADDRESS_V6_IPP ================================================ FILE: src/third_party/asio/ip/impl/basic_endpoint.hpp ================================================ // // ip/impl/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_BASIC_ENDPOINT_HPP #define ASIO_IP_IMPL_BASIC_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if !defined(ASIO_NO_IOSTREAM) #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template std::basic_ostream& operator<<( std::basic_ostream& os, const basic_endpoint& endpoint) { asio::ip::detail::endpoint tmp_ep(endpoint.address(), endpoint.port()); return os << tmp_ep.to_string().c_str(); } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_IP_IMPL_BASIC_ENDPOINT_HPP ================================================ FILE: src/third_party/asio/ip/impl/host_name.ipp ================================================ // // ip/impl/host_name.ipp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_HOST_NAME_IPP #define ASIO_IP_IMPL_HOST_NAME_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/winsock_init.hpp" #include "asio/ip/host_name.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { std::string host_name() { char name[1024]; asio::error_code ec; if (asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) { asio::detail::throw_error(ec); return std::string(); } return std::string(name); } std::string host_name(asio::error_code& ec) { char name[1024]; if (asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) return std::string(); return std::string(name); } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_IMPL_HOST_NAME_IPP ================================================ FILE: src/third_party/asio/ip/impl/network_v4.hpp ================================================ // // ip/impl/network_v4.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_NETWORK_V4_HPP #define ASIO_IP_IMPL_NETWORK_V4_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if !defined(ASIO_NO_IOSTREAM) #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template std::basic_ostream& operator<<( std::basic_ostream& os, const network_v4& addr) { asio::error_code ec; std::string s = addr.to_string(ec); if (ec) { if (os.exceptions() & std::basic_ostream::failbit) asio::detail::throw_error(ec); else os.setstate(std::basic_ostream::failbit); } else for (std::string::iterator i = s.begin(); i != s.end(); ++i) os << os.widen(*i); return os; } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_IP_IMPL_NETWORK_V4_HPP ================================================ FILE: src/third_party/asio/ip/impl/network_v4.ipp ================================================ // // ip/impl/network_v4.ipp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_NETWORK_V4_IPP #define ASIO_IP_IMPL_NETWORK_V4_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include #include "asio/error.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/ip/network_v4.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { network_v4::network_v4(const address_v4& addr, unsigned short prefix_len) : address_(addr), prefix_length_(prefix_len) { if (prefix_len > 32) { std::out_of_range ex("prefix length too large"); asio::detail::throw_exception(ex); } } network_v4::network_v4(const address_v4& addr, const address_v4& mask) : address_(addr), prefix_length_(0) { address_v4::bytes_type mask_bytes = mask.to_bytes(); bool finished = false; for (std::size_t i = 0; i < mask_bytes.size(); ++i) { if (finished) { if (mask_bytes[i]) { std::invalid_argument ex("non-contiguous netmask"); asio::detail::throw_exception(ex); } continue; } else { switch (mask_bytes[i]) { case 255: prefix_length_ += 8; break; case 254: // prefix_length_ += 7 prefix_length_ += 1; case 252: // prefix_length_ += 6 prefix_length_ += 1; case 248: // prefix_length_ += 5 prefix_length_ += 1; case 240: // prefix_length_ += 4 prefix_length_ += 1; case 224: // prefix_length_ += 3 prefix_length_ += 1; case 192: // prefix_length_ += 2 prefix_length_ += 1; case 128: // prefix_length_ += 1 prefix_length_ += 1; case 0: // nbits += 0 finished = true; break; default: std::out_of_range ex("non-contiguous netmask"); asio::detail::throw_exception(ex); } } } } address_v4 network_v4::netmask() const ASIO_NOEXCEPT { uint32_t nmbits = 0xffffffff; if (prefix_length_ == 0) nmbits = 0; else nmbits = nmbits << (32 - prefix_length_); return address_v4(nmbits); } address_v4_range network_v4::hosts() const ASIO_NOEXCEPT { return is_host() ? address_v4_range(address_, address_v4(address_.to_uint() + 1)) : address_v4_range(address_v4(network().to_uint() + 1), broadcast()); } bool network_v4::is_subnet_of(const network_v4& other) const { if (other.prefix_length_ >= prefix_length_) return false; // Only real subsets are allowed. const network_v4 me(address_, other.prefix_length_); return other.canonical() == me.canonical(); } std::string network_v4::to_string() const { asio::error_code ec; std::string addr = to_string(ec); asio::detail::throw_error(ec); return addr; } std::string network_v4::to_string(asio::error_code& ec) const { using namespace std; // For sprintf. ec = asio::error_code(); char prefix_len[16]; #if defined(ASIO_HAS_SECURE_RTL) sprintf_s(prefix_len, sizeof(prefix_len), "/%u", prefix_length_); #else // defined(ASIO_HAS_SECURE_RTL) sprintf(prefix_len, "/%u", prefix_length_); #endif // defined(ASIO_HAS_SECURE_RTL) return address_.to_string() + prefix_len; } network_v4 make_network_v4(const char* str) { return make_network_v4(std::string(str)); } network_v4 make_network_v4(const char* str, asio::error_code& ec) { return make_network_v4(std::string(str), ec); } network_v4 make_network_v4(const std::string& str) { asio::error_code ec; network_v4 net = make_network_v4(str, ec); asio::detail::throw_error(ec); return net; } network_v4 make_network_v4(const std::string& str, asio::error_code& ec) { std::string::size_type pos = str.find_first_of("/"); if (pos == std::string::npos) { ec = asio::error::invalid_argument; return network_v4(); } if (pos == str.size() - 1) { ec = asio::error::invalid_argument; return network_v4(); } std::string::size_type end = str.find_first_not_of("0123456789", pos + 1); if (end != std::string::npos) { ec = asio::error::invalid_argument; return network_v4(); } const address_v4 addr = make_address_v4(str.substr(0, pos), ec); if (ec) return network_v4(); const int prefix_len = std::atoi(str.substr(pos + 1).c_str()); if (prefix_len < 0 || prefix_len > 32) { ec = asio::error::invalid_argument; return network_v4(); } return network_v4(addr, static_cast(prefix_len)); } #if defined(ASIO_HAS_STRING_VIEW) network_v4 make_network_v4(string_view str) { return make_network_v4(static_cast(str)); } network_v4 make_network_v4(string_view str, asio::error_code& ec) { return make_network_v4(static_cast(str), ec); } #endif // defined(ASIO_HAS_STRING_VIEW) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_IMPL_NETWORK_V4_IPP ================================================ FILE: src/third_party/asio/ip/impl/network_v6.hpp ================================================ // // ip/impl/network_v6.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_NETWORK_V6_HPP #define ASIO_IP_IMPL_NETWORK_V6_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if !defined(ASIO_NO_IOSTREAM) #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { template std::basic_ostream& operator<<( std::basic_ostream& os, const network_v6& addr) { asio::error_code ec; std::string s = addr.to_string(ec); if (ec) { if (os.exceptions() & std::basic_ostream::failbit) asio::detail::throw_error(ec); else os.setstate(std::basic_ostream::failbit); } else for (std::string::iterator i = s.begin(); i != s.end(); ++i) os << os.widen(*i); return os; } } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_IP_IMPL_NETWORK_V6_HPP ================================================ FILE: src/third_party/asio/ip/impl/network_v6.ipp ================================================ // // ip/impl/network_v6.ipp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_IMPL_NETWORK_V6_IPP #define ASIO_IP_IMPL_NETWORK_V6_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include #include #include "asio/error.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/throw_exception.hpp" #include "asio/ip/network_v6.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { network_v6::network_v6(const address_v6& addr, unsigned short prefix_len) : address_(addr), prefix_length_(prefix_len) { if (prefix_len > 128) { std::out_of_range ex("prefix length too large"); asio::detail::throw_exception(ex); } } ASIO_DECL address_v6 network_v6::network() const ASIO_NOEXCEPT { address_v6::bytes_type bytes(address_.to_bytes()); for (std::size_t i = 0; i < 16; ++i) { if (prefix_length_ <= i * 8) bytes[i] = 0; else if (prefix_length_ < (i + 1) * 8) bytes[i] &= 0xFF00 >> (prefix_length_ % 8); } return address_v6(bytes, address_.scope_id()); } address_v6_range network_v6::hosts() const ASIO_NOEXCEPT { address_v6::bytes_type begin_bytes(address_.to_bytes()); address_v6::bytes_type end_bytes(address_.to_bytes()); for (std::size_t i = 0; i < 16; ++i) { if (prefix_length_ <= i * 8) { begin_bytes[i] = 0; end_bytes[i] = 0xFF; } else if (prefix_length_ < (i + 1) * 8) { begin_bytes[i] &= 0xFF00 >> (prefix_length_ % 8); end_bytes[i] |= 0xFF >> (prefix_length_ % 8); } } return address_v6_range( address_v6_iterator(address_v6(begin_bytes, address_.scope_id())), ++address_v6_iterator(address_v6(end_bytes, address_.scope_id()))); } bool network_v6::is_subnet_of(const network_v6& other) const { if (other.prefix_length_ >= prefix_length_) return false; // Only real subsets are allowed. const network_v6 me(address_, other.prefix_length_); return other.canonical() == me.canonical(); } std::string network_v6::to_string() const { asio::error_code ec; std::string addr = to_string(ec); asio::detail::throw_error(ec); return addr; } std::string network_v6::to_string(asio::error_code& ec) const { using namespace std; // For sprintf. ec = asio::error_code(); char prefix_len[16]; #if defined(ASIO_HAS_SECURE_RTL) sprintf_s(prefix_len, sizeof(prefix_len), "/%u", prefix_length_); #else // defined(ASIO_HAS_SECURE_RTL) sprintf(prefix_len, "/%u", prefix_length_); #endif // defined(ASIO_HAS_SECURE_RTL) return address_.to_string() + prefix_len; } network_v6 make_network_v6(const char* str) { return make_network_v6(std::string(str)); } network_v6 make_network_v6(const char* str, asio::error_code& ec) { return make_network_v6(std::string(str), ec); } network_v6 make_network_v6(const std::string& str) { asio::error_code ec; network_v6 net = make_network_v6(str, ec); asio::detail::throw_error(ec); return net; } network_v6 make_network_v6(const std::string& str, asio::error_code& ec) { std::string::size_type pos = str.find_first_of("/"); if (pos == std::string::npos) { ec = asio::error::invalid_argument; return network_v6(); } if (pos == str.size() - 1) { ec = asio::error::invalid_argument; return network_v6(); } std::string::size_type end = str.find_first_not_of("0123456789", pos + 1); if (end != std::string::npos) { ec = asio::error::invalid_argument; return network_v6(); } const address_v6 addr = make_address_v6(str.substr(0, pos), ec); if (ec) return network_v6(); const int prefix_len = std::atoi(str.substr(pos + 1).c_str()); if (prefix_len < 0 || prefix_len > 128) { ec = asio::error::invalid_argument; return network_v6(); } return network_v6(addr, static_cast(prefix_len)); } #if defined(ASIO_HAS_STRING_VIEW) network_v6 make_network_v6(string_view str) { return make_network_v6(static_cast(str)); } network_v6 make_network_v6(string_view str, asio::error_code& ec) { return make_network_v6(static_cast(str), ec); } #endif // defined(ASIO_HAS_STRING_VIEW) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_IMPL_NETWORK_V6_IPP ================================================ FILE: src/third_party/asio/ip/multicast.hpp ================================================ // // ip/multicast.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_MULTICAST_HPP #define ASIO_IP_MULTICAST_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/ip/detail/socket_option.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { namespace multicast { /// Socket option to join a multicast group on a specified interface. /** * Implements the IPPROTO_IP/IP_ADD_MEMBERSHIP socket option. * * @par Examples * Setting the option to join a multicast group: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::address multicast_address = * asio::ip::address::from_string("225.0.0.1"); * asio::ip::multicast::join_group option(multicast_address); * socket.set_option(option); * @endcode * * @par Concepts: * SettableSocketOption. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined join_group; #else typedef asio::ip::detail::socket_option::multicast_request< ASIO_OS_DEF(IPPROTO_IP), ASIO_OS_DEF(IP_ADD_MEMBERSHIP), ASIO_OS_DEF(IPPROTO_IPV6), ASIO_OS_DEF(IPV6_JOIN_GROUP)> join_group; #endif /// Socket option to leave a multicast group on a specified interface. /** * Implements the IPPROTO_IP/IP_DROP_MEMBERSHIP socket option. * * @par Examples * Setting the option to leave a multicast group: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::address multicast_address = * asio::ip::address::from_string("225.0.0.1"); * asio::ip::multicast::leave_group option(multicast_address); * socket.set_option(option); * @endcode * * @par Concepts: * SettableSocketOption. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined leave_group; #else typedef asio::ip::detail::socket_option::multicast_request< ASIO_OS_DEF(IPPROTO_IP), ASIO_OS_DEF(IP_DROP_MEMBERSHIP), ASIO_OS_DEF(IPPROTO_IPV6), ASIO_OS_DEF(IPV6_LEAVE_GROUP)> leave_group; #endif /// Socket option for local interface to use for outgoing multicast packets. /** * Implements the IPPROTO_IP/IP_MULTICAST_IF socket option. * * @par Examples * Setting the option: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::address_v4 local_interface = * asio::ip::address_v4::from_string("1.2.3.4"); * asio::ip::multicast::outbound_interface option(local_interface); * socket.set_option(option); * @endcode * * @par Concepts: * SettableSocketOption. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined outbound_interface; #else typedef asio::ip::detail::socket_option::network_interface< ASIO_OS_DEF(IPPROTO_IP), ASIO_OS_DEF(IP_MULTICAST_IF), ASIO_OS_DEF(IPPROTO_IPV6), ASIO_OS_DEF(IPV6_MULTICAST_IF)> outbound_interface; #endif /// Socket option for time-to-live associated with outgoing multicast packets. /** * Implements the IPPROTO_IP/IP_MULTICAST_TTL socket option. * * @par Examples * Setting the option: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::multicast::hops option(4); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::multicast::hops option; * socket.get_option(option); * int ttl = option.value(); * @endcode * * @par Concepts: * GettableSocketOption, SettableSocketOption. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined hops; #else typedef asio::ip::detail::socket_option::multicast_hops< ASIO_OS_DEF(IPPROTO_IP), ASIO_OS_DEF(IP_MULTICAST_TTL), ASIO_OS_DEF(IPPROTO_IPV6), ASIO_OS_DEF(IPV6_MULTICAST_HOPS)> hops; #endif /// Socket option determining whether outgoing multicast packets will be /// received on the same socket if it is a member of the multicast group. /** * Implements the IPPROTO_IP/IP_MULTICAST_LOOP socket option. * * @par Examples * Setting the option: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::multicast::enable_loopback option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::multicast::enable_loopback option; * socket.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * GettableSocketOption, SettableSocketOption. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined enable_loopback; #else typedef asio::ip::detail::socket_option::multicast_enable_loopback< ASIO_OS_DEF(IPPROTO_IP), ASIO_OS_DEF(IP_MULTICAST_LOOP), ASIO_OS_DEF(IPPROTO_IPV6), ASIO_OS_DEF(IPV6_MULTICAST_LOOP)> enable_loopback; #endif } // namespace multicast } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_MULTICAST_HPP ================================================ FILE: src/third_party/asio/ip/network_v4.hpp ================================================ // // ip/network_v4.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_NETWORK_V4_HPP #define ASIO_IP_NETWORK_V4_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/string_view.hpp" #include "asio/error_code.hpp" #include "asio/ip/address_v4_range.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Represents an IPv4 network. /** * The asio::ip::network_v4 class provides the ability to use and * manipulate IP version 4 networks. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ class network_v4 { public: /// Default constructor. network_v4() ASIO_NOEXCEPT : address_(), prefix_length_(0) { } /// Construct a network based on the specified address and prefix length. ASIO_DECL network_v4(const address_v4& addr, unsigned short prefix_len); /// Construct network based on the specified address and netmask. ASIO_DECL network_v4(const address_v4& addr, const address_v4& mask); /// Copy constructor. network_v4(const network_v4& other) ASIO_NOEXCEPT : address_(other.address_), prefix_length_(other.prefix_length_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. network_v4(network_v4&& other) ASIO_NOEXCEPT : address_(ASIO_MOVE_CAST(address_v4)(other.address_)), prefix_length_(other.prefix_length_) { } #endif // defined(ASIO_HAS_MOVE) /// Assign from another network. network_v4& operator=(const network_v4& other) ASIO_NOEXCEPT { address_ = other.address_; prefix_length_ = other.prefix_length_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move-assign from another network. network_v4& operator=(network_v4&& other) ASIO_NOEXCEPT { address_ = ASIO_MOVE_CAST(address_v4)(other.address_); prefix_length_ = other.prefix_length_; return *this; } #endif // defined(ASIO_HAS_MOVE) /// Obtain the address object specified when the network object was created. address_v4 address() const ASIO_NOEXCEPT { return address_; } /// Obtain the prefix length that was specified when the network object was /// created. unsigned short prefix_length() const ASIO_NOEXCEPT { return prefix_length_; } /// Obtain the netmask that was specified when the network object was created. ASIO_DECL address_v4 netmask() const ASIO_NOEXCEPT; /// Obtain an address object that represents the network address. address_v4 network() const ASIO_NOEXCEPT { return address_v4(address_.to_uint() & netmask().to_uint()); } /// Obtain an address object that represents the network's broadcast address. address_v4 broadcast() const ASIO_NOEXCEPT { return address_v4(network().to_uint() | (netmask().to_uint() ^ 0xFFFFFFFF)); } /// Obtain an address range corresponding to the hosts in the network. ASIO_DECL address_v4_range hosts() const ASIO_NOEXCEPT; /// Obtain the true network address, omitting any host bits. network_v4 canonical() const ASIO_NOEXCEPT { return network_v4(network(), netmask()); } /// Test if network is a valid host address. bool is_host() const ASIO_NOEXCEPT { return prefix_length_ == 32; } /// Test if a network is a real subnet of another network. ASIO_DECL bool is_subnet_of(const network_v4& other) const; /// Get the network as an address in dotted decimal format. ASIO_DECL std::string to_string() const; /// Get the network as an address in dotted decimal format. ASIO_DECL std::string to_string(asio::error_code& ec) const; /// Compare two networks for equality. friend bool operator==(const network_v4& a, const network_v4& b) { return a.address_ == b.address_ && a.prefix_length_ == b.prefix_length_; } /// Compare two networks for inequality. friend bool operator!=(const network_v4& a, const network_v4& b) { return !(a == b); } private: address_v4 address_; unsigned short prefix_length_; }; /// Create an IPv4 network from an address and prefix length. /** * @relates address_v4 */ inline network_v4 make_network_v4( const address_v4& addr, unsigned short prefix_len) { return network_v4(addr, prefix_len); } /// Create an IPv4 network from an address and netmask. /** * @relates address_v4 */ inline network_v4 make_network_v4( const address_v4& addr, const address_v4& mask) { return network_v4(addr, mask); } /// Create an IPv4 network from a string containing IP address and prefix /// length. /** * @relates network_v4 */ ASIO_DECL network_v4 make_network_v4(const char* str); /// Create an IPv4 network from a string containing IP address and prefix /// length. /** * @relates network_v4 */ ASIO_DECL network_v4 make_network_v4( const char* str, asio::error_code& ec); /// Create an IPv4 network from a string containing IP address and prefix /// length. /** * @relates network_v4 */ ASIO_DECL network_v4 make_network_v4(const std::string& str); /// Create an IPv4 network from a string containing IP address and prefix /// length. /** * @relates network_v4 */ ASIO_DECL network_v4 make_network_v4( const std::string& str, asio::error_code& ec); #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION) /// Create an IPv4 network from a string containing IP address and prefix /// length. /** * @relates network_v4 */ ASIO_DECL network_v4 make_network_v4(string_view str); /// Create an IPv4 network from a string containing IP address and prefix /// length. /** * @relates network_v4 */ ASIO_DECL network_v4 make_network_v4( string_view str, asio::error_code& ec); #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION) #if !defined(ASIO_NO_IOSTREAM) /// Output a network as a string. /** * Used to output a human-readable string for a specified network. * * @param os The output stream to which the string will be written. * * @param net The network to be written. * * @return The output stream. * * @relates asio::ip::address_v4 */ template std::basic_ostream& operator<<( std::basic_ostream& os, const network_v4& net); #endif // !defined(ASIO_NO_IOSTREAM) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/ip/impl/network_v4.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ip/impl/network_v4.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_IP_NETWORK_V4_HPP ================================================ FILE: src/third_party/asio/ip/network_v6.hpp ================================================ // // ip/network_v6.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_NETWORK_V6_HPP #define ASIO_IP_NETWORK_V6_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/string_view.hpp" #include "asio/error_code.hpp" #include "asio/ip/address_v6_range.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Represents an IPv6 network. /** * The asio::ip::network_v6 class provides the ability to use and * manipulate IP version 6 networks. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ class network_v6 { public: /// Default constructor. network_v6() ASIO_NOEXCEPT : address_(), prefix_length_(0) { } /// Construct a network based on the specified address and prefix length. ASIO_DECL network_v6(const address_v6& addr, unsigned short prefix_len); /// Copy constructor. network_v6(const network_v6& other) ASIO_NOEXCEPT : address_(other.address_), prefix_length_(other.prefix_length_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. network_v6(network_v6&& other) ASIO_NOEXCEPT : address_(ASIO_MOVE_CAST(address_v6)(other.address_)), prefix_length_(other.prefix_length_) { } #endif // defined(ASIO_HAS_MOVE) /// Assign from another network. network_v6& operator=(const network_v6& other) ASIO_NOEXCEPT { address_ = other.address_; prefix_length_ = other.prefix_length_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move-assign from another network. network_v6& operator=(network_v6&& other) ASIO_NOEXCEPT { address_ = ASIO_MOVE_CAST(address_v6)(other.address_); prefix_length_ = other.prefix_length_; return *this; } #endif // defined(ASIO_HAS_MOVE) /// Obtain the address object specified when the network object was created. address_v6 address() const ASIO_NOEXCEPT { return address_; } /// Obtain the prefix length that was specified when the network object was /// created. unsigned short prefix_length() const ASIO_NOEXCEPT { return prefix_length_; } /// Obtain an address object that represents the network address. ASIO_DECL address_v6 network() const ASIO_NOEXCEPT; /// Obtain an address range corresponding to the hosts in the network. ASIO_DECL address_v6_range hosts() const ASIO_NOEXCEPT; /// Obtain the true network address, omitting any host bits. network_v6 canonical() const ASIO_NOEXCEPT { return network_v6(network(), prefix_length()); } /// Test if network is a valid host address. bool is_host() const ASIO_NOEXCEPT { return prefix_length_ == 128; } /// Test if a network is a real subnet of another network. ASIO_DECL bool is_subnet_of(const network_v6& other) const; /// Get the network as an address in dotted decimal format. ASIO_DECL std::string to_string() const; /// Get the network as an address in dotted decimal format. ASIO_DECL std::string to_string(asio::error_code& ec) const; /// Compare two networks for equality. friend bool operator==(const network_v6& a, const network_v6& b) { return a.address_ == b.address_ && a.prefix_length_ == b.prefix_length_; } /// Compare two networks for inequality. friend bool operator!=(const network_v6& a, const network_v6& b) { return !(a == b); } private: address_v6 address_; unsigned short prefix_length_; }; /// Create an IPv6 network from an address and prefix length. /** * @relates address_v6 */ inline network_v6 make_network_v6( const address_v6& addr, unsigned short prefix_len) { return network_v6(addr, prefix_len); } /// Create an IPv6 network from a string containing IP address and prefix /// length. /** * @relates network_v6 */ ASIO_DECL network_v6 make_network_v6(const char* str); /// Create an IPv6 network from a string containing IP address and prefix /// length. /** * @relates network_v6 */ ASIO_DECL network_v6 make_network_v6( const char* str, asio::error_code& ec); /// Create an IPv6 network from a string containing IP address and prefix /// length. /** * @relates network_v6 */ ASIO_DECL network_v6 make_network_v6(const std::string& str); /// Create an IPv6 network from a string containing IP address and prefix /// length. /** * @relates network_v6 */ ASIO_DECL network_v6 make_network_v6( const std::string& str, asio::error_code& ec); #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION) /// Create an IPv6 network from a string containing IP address and prefix /// length. /** * @relates network_v6 */ ASIO_DECL network_v6 make_network_v6(string_view str); /// Create an IPv6 network from a string containing IP address and prefix /// length. /** * @relates network_v6 */ ASIO_DECL network_v6 make_network_v6( string_view str, asio::error_code& ec); #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION) #if !defined(ASIO_NO_IOSTREAM) /// Output a network as a string. /** * Used to output a human-readable string for a specified network. * * @param os The output stream to which the string will be written. * * @param net The network to be written. * * @return The output stream. * * @relates asio::ip::address_v6 */ template std::basic_ostream& operator<<( std::basic_ostream& os, const network_v6& net); #endif // !defined(ASIO_NO_IOSTREAM) } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/ip/impl/network_v6.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ip/impl/network_v6.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_IP_NETWORK_V6_HPP ================================================ FILE: src/third_party/asio/ip/resolver_base.hpp ================================================ // // ip/resolver_base.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_RESOLVER_BASE_HPP #define ASIO_IP_RESOLVER_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// The resolver_base class is used as a base for the basic_resolver class /// templates to provide a common place to define the flag constants. class resolver_base { public: #if defined(GENERATING_DOCUMENTATION) /// A bitmask type (C++ Std [lib.bitmask.types]). typedef unspecified flags; /// Determine the canonical name of the host specified in the query. static const flags canonical_name = implementation_defined; /// Indicate that returned endpoint is intended for use as a locally bound /// socket endpoint. static const flags passive = implementation_defined; /// Host name should be treated as a numeric string defining an IPv4 or IPv6 /// address and no name resolution should be attempted. static const flags numeric_host = implementation_defined; /// Service name should be treated as a numeric string defining a port number /// and no name resolution should be attempted. static const flags numeric_service = implementation_defined; /// If the query protocol family is specified as IPv6, return IPv4-mapped /// IPv6 addresses on finding no IPv6 addresses. static const flags v4_mapped = implementation_defined; /// If used with v4_mapped, return all matching IPv6 and IPv4 addresses. static const flags all_matching = implementation_defined; /// Only return IPv4 addresses if a non-loopback IPv4 address is configured /// for the system. Only return IPv6 addresses if a non-loopback IPv6 address /// is configured for the system. static const flags address_configured = implementation_defined; #else enum flags { canonical_name = ASIO_OS_DEF(AI_CANONNAME), passive = ASIO_OS_DEF(AI_PASSIVE), numeric_host = ASIO_OS_DEF(AI_NUMERICHOST), numeric_service = ASIO_OS_DEF(AI_NUMERICSERV), v4_mapped = ASIO_OS_DEF(AI_V4MAPPED), all_matching = ASIO_OS_DEF(AI_ALL), address_configured = ASIO_OS_DEF(AI_ADDRCONFIG) }; // Implement bitmask operations as shown in C++ Std [lib.bitmask.types]. friend flags operator&(flags x, flags y) { return static_cast( static_cast(x) & static_cast(y)); } friend flags operator|(flags x, flags y) { return static_cast( static_cast(x) | static_cast(y)); } friend flags operator^(flags x, flags y) { return static_cast( static_cast(x) ^ static_cast(y)); } friend flags operator~(flags x) { return static_cast(~static_cast(x)); } friend flags& operator&=(flags& x, flags y) { x = x & y; return x; } friend flags& operator|=(flags& x, flags y) { x = x | y; return x; } friend flags& operator^=(flags& x, flags y) { x = x ^ y; return x; } #endif protected: /// Protected destructor to prevent deletion through this type. ~resolver_base() { } }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_RESOLVER_BASE_HPP ================================================ FILE: src/third_party/asio/ip/resolver_query_base.hpp ================================================ // // ip/resolver_query_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_RESOLVER_QUERY_BASE_HPP #define ASIO_IP_RESOLVER_QUERY_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ip/resolver_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// The resolver_query_base class is used as a base for the /// basic_resolver_query class templates to provide a common place to define /// the flag constants. class resolver_query_base : public resolver_base { protected: /// Protected destructor to prevent deletion through this type. ~resolver_query_base() { } }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_RESOLVER_QUERY_BASE_HPP ================================================ FILE: src/third_party/asio/ip/tcp.hpp ================================================ // // ip/tcp.hpp // ~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_TCP_HPP #define ASIO_IP_TCP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/basic_socket_acceptor.hpp" #include "asio/basic_socket_iostream.hpp" #include "asio/basic_stream_socket.hpp" #include "asio/detail/socket_option.hpp" #include "asio/detail/socket_types.hpp" #include "asio/ip/basic_endpoint.hpp" #include "asio/ip/basic_resolver.hpp" #include "asio/ip/basic_resolver_iterator.hpp" #include "asio/ip/basic_resolver_query.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Encapsulates the flags needed for TCP. /** * The asio::ip::tcp class contains flags necessary for TCP sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol, InternetProtocol. */ class tcp { public: /// The type of a TCP endpoint. typedef basic_endpoint endpoint; /// Construct to represent the IPv4 TCP protocol. static tcp v4() ASIO_NOEXCEPT { return tcp(ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 TCP protocol. static tcp v6() ASIO_NOEXCEPT { return tcp(ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_STREAM); } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return ASIO_OS_DEF(IPPROTO_TCP); } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return family_; } /// The TCP socket type. typedef basic_stream_socket socket; /// The TCP acceptor type. typedef basic_socket_acceptor acceptor; /// The TCP resolver type. typedef basic_resolver resolver; #if !defined(ASIO_NO_IOSTREAM) /// The TCP iostream type. typedef basic_socket_iostream iostream; #endif // !defined(ASIO_NO_IOSTREAM) /// Socket option for disabling the Nagle algorithm. /** * Implements the IPPROTO_TCP/TCP_NODELAY socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::no_delay option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::no_delay option; * socket.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined no_delay; #else typedef asio::detail::socket_option::boolean< ASIO_OS_DEF(IPPROTO_TCP), ASIO_OS_DEF(TCP_NODELAY)> no_delay; #endif /// Compare two protocols for equality. friend bool operator==(const tcp& p1, const tcp& p2) { return p1.family_ == p2.family_; } /// Compare two protocols for inequality. friend bool operator!=(const tcp& p1, const tcp& p2) { return p1.family_ != p2.family_; } private: // Construct with a specific family. explicit tcp(int protocol_family) ASIO_NOEXCEPT : family_(protocol_family) { } int family_; }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_TCP_HPP ================================================ FILE: src/third_party/asio/ip/udp.hpp ================================================ // // ip/udp.hpp // ~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_UDP_HPP #define ASIO_IP_UDP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/basic_datagram_socket.hpp" #include "asio/detail/socket_types.hpp" #include "asio/ip/basic_endpoint.hpp" #include "asio/ip/basic_resolver.hpp" #include "asio/ip/basic_resolver_iterator.hpp" #include "asio/ip/basic_resolver_query.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Encapsulates the flags needed for UDP. /** * The asio::ip::udp class contains flags necessary for UDP sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol, InternetProtocol. */ class udp { public: /// The type of a UDP endpoint. typedef basic_endpoint endpoint; /// Construct to represent the IPv4 UDP protocol. static udp v4() ASIO_NOEXCEPT { return udp(ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 UDP protocol. static udp v6() ASIO_NOEXCEPT { return udp(ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_DGRAM); } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return ASIO_OS_DEF(IPPROTO_UDP); } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return family_; } /// The UDP socket type. typedef basic_datagram_socket socket; /// The UDP resolver type. typedef basic_resolver resolver; /// Compare two protocols for equality. friend bool operator==(const udp& p1, const udp& p2) { return p1.family_ == p2.family_; } /// Compare two protocols for inequality. friend bool operator!=(const udp& p1, const udp& p2) { return p1.family_ != p2.family_; } private: // Construct with a specific family. explicit udp(int protocol_family) ASIO_NOEXCEPT : family_(protocol_family) { } int family_; }; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_UDP_HPP ================================================ FILE: src/third_party/asio/ip/unicast.hpp ================================================ // // ip/unicast.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_UNICAST_HPP #define ASIO_IP_UNICAST_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/ip/detail/socket_option.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { namespace unicast { /// Socket option for time-to-live associated with outgoing unicast packets. /** * Implements the IPPROTO_IP/IP_UNICAST_TTL socket option. * * @par Examples * Setting the option: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::unicast::hops option(4); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::ip::unicast::hops option; * socket.get_option(option); * int ttl = option.value(); * @endcode * * @par Concepts: * GettableSocketOption, SettableSocketOption. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined hops; #else typedef asio::ip::detail::socket_option::unicast_hops< ASIO_OS_DEF(IPPROTO_IP), ASIO_OS_DEF(IP_TTL), ASIO_OS_DEF(IPPROTO_IPV6), ASIO_OS_DEF(IPV6_UNICAST_HOPS)> hops; #endif } // namespace unicast } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_UNICAST_HPP ================================================ FILE: src/third_party/asio/ip/v6_only.hpp ================================================ // // ip/v6_only.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IP_V6_ONLY_HPP #define ASIO_IP_V6_ONLY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/socket_option.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ip { /// Socket option for determining whether an IPv6 socket supports IPv6 /// communication only. /** * Implements the IPPROTO_IPV6/IP_V6ONLY socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::v6_only option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::v6_only option; * socket.get_option(option); * bool v6_only = option.value(); * @endcode * * @par Concepts: * GettableSocketOption, SettableSocketOption. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined v6_only; #elif defined(IPV6_V6ONLY) typedef asio::detail::socket_option::boolean< IPPROTO_IPV6, IPV6_V6ONLY> v6_only; #else typedef asio::detail::socket_option::boolean< asio::detail::custom_socket_option_level, asio::detail::always_fail_option> v6_only; #endif } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IP_V6_ONLY_HPP ================================================ FILE: src/third_party/asio/is_executor.hpp ================================================ // // is_executor.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IS_EXECUTOR_HPP #define ASIO_IS_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/is_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// The is_executor trait detects whether a type T meets the Executor type /// requirements. /** * Class template @c is_executor is a UnaryTypeTrait that is derived from @c * true_type if the type @c T meets the syntactic requirements for Executor, * otherwise @c false_type. */ template struct is_executor #if defined(GENERATING_DOCUMENTATION) : integral_constant #else // defined(GENERATING_DOCUMENTATION) : asio::detail::is_executor #endif // defined(GENERATING_DOCUMENTATION) { }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IS_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/is_read_buffered.hpp ================================================ // // is_read_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IS_READ_BUFFERED_HPP #define ASIO_IS_READ_BUFFERED_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/buffered_read_stream_fwd.hpp" #include "asio/buffered_stream_fwd.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template char is_read_buffered_helper(buffered_stream* s); template char is_read_buffered_helper(buffered_read_stream* s); struct is_read_buffered_big_type { char data[10]; }; is_read_buffered_big_type is_read_buffered_helper(...); } // namespace detail /// The is_read_buffered class is a traits class that may be used to determine /// whether a stream type supports buffering of read data. template class is_read_buffered { public: #if defined(GENERATING_DOCUMENTATION) /// The value member is true only if the Stream type supports buffering of /// read data. static const bool value; #else ASIO_STATIC_CONSTANT(bool, value = sizeof(detail::is_read_buffered_helper((Stream*)0)) == 1); #endif }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IS_READ_BUFFERED_HPP ================================================ FILE: src/third_party/asio/is_write_buffered.hpp ================================================ // // is_write_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_IS_WRITE_BUFFERED_HPP #define ASIO_IS_WRITE_BUFFERED_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/buffered_stream_fwd.hpp" #include "asio/buffered_write_stream_fwd.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template char is_write_buffered_helper(buffered_stream* s); template char is_write_buffered_helper(buffered_write_stream* s); struct is_write_buffered_big_type { char data[10]; }; is_write_buffered_big_type is_write_buffered_helper(...); } // namespace detail /// The is_write_buffered class is a traits class that may be used to determine /// whether a stream type supports buffering of written data. template class is_write_buffered { public: #if defined(GENERATING_DOCUMENTATION) /// The value member is true only if the Stream type supports buffering of /// written data. static const bool value; #else ASIO_STATIC_CONSTANT(bool, value = sizeof(detail::is_write_buffered_helper((Stream*)0)) == 1); #endif }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IS_WRITE_BUFFERED_HPP ================================================ FILE: src/third_party/asio/local/basic_endpoint.hpp ================================================ // // local/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_LOCAL_BASIC_ENDPOINT_HPP #define ASIO_LOCAL_BASIC_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include "asio/local/detail/endpoint.hpp" #if !defined(ASIO_NO_IOSTREAM) # include #endif // !defined(ASIO_NO_IOSTREAM) #include "asio/detail/push_options.hpp" namespace asio { namespace local { /// Describes an endpoint for a UNIX socket. /** * The asio::local::basic_endpoint class template describes an endpoint * that may be associated with a particular UNIX socket. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * Endpoint. */ template class basic_endpoint { public: /// The protocol type associated with the endpoint. typedef Protocol protocol_type; /// The type of the endpoint structure. This type is dependent on the /// underlying implementation of the socket layer. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined data_type; #else typedef asio::detail::socket_addr_type data_type; #endif /// Default constructor. basic_endpoint() ASIO_NOEXCEPT { } /// Construct an endpoint using the specified path name. basic_endpoint(const char* path_name) : impl_(path_name) { } /// Construct an endpoint using the specified path name. basic_endpoint(const std::string& path_name) : impl_(path_name) { } #if defined(ASIO_HAS_STRING_VIEW) /// Construct an endpoint using the specified path name. basic_endpoint(string_view path_name) : impl_(path_name) { } #endif // defined(ASIO_HAS_STRING_VIEW) /// Copy constructor. basic_endpoint(const basic_endpoint& other) : impl_(other.impl_) { } #if defined(ASIO_HAS_MOVE) /// Move constructor. basic_endpoint(basic_endpoint&& other) : impl_(other.impl_) { } #endif // defined(ASIO_HAS_MOVE) /// Assign from another endpoint. basic_endpoint& operator=(const basic_endpoint& other) { impl_ = other.impl_; return *this; } #if defined(ASIO_HAS_MOVE) /// Move-assign from another endpoint. basic_endpoint& operator=(basic_endpoint&& other) { impl_ = other.impl_; return *this; } #endif // defined(ASIO_HAS_MOVE) /// The protocol associated with the endpoint. protocol_type protocol() const { return protocol_type(); } /// Get the underlying endpoint in the native type. data_type* data() { return impl_.data(); } /// Get the underlying endpoint in the native type. const data_type* data() const { return impl_.data(); } /// Get the underlying size of the endpoint in the native type. std::size_t size() const { return impl_.size(); } /// Set the underlying size of the endpoint in the native type. void resize(std::size_t new_size) { impl_.resize(new_size); } /// Get the capacity of the endpoint in the native type. std::size_t capacity() const { return impl_.capacity(); } /// Get the path associated with the endpoint. std::string path() const { return impl_.path(); } /// Set the path associated with the endpoint. void path(const char* p) { impl_.path(p); } /// Set the path associated with the endpoint. void path(const std::string& p) { impl_.path(p); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint& e1, const basic_endpoint& e2) { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint& e1, const basic_endpoint& e2) { return !(e1.impl_ == e2.impl_); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint& e1, const basic_endpoint& e2) { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint& e1, const basic_endpoint& e2) { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint& e1, const basic_endpoint& e2) { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint& e1, const basic_endpoint& e2) { return !(e1 < e2); } private: // The underlying UNIX domain endpoint. asio::local::detail::endpoint impl_; }; /// Output an endpoint as a string. /** * Used to output a human-readable string for a specified endpoint. * * @param os The output stream to which the string will be written. * * @param endpoint The endpoint to be written. * * @return The output stream. * * @relates asio::local::basic_endpoint */ template std::basic_ostream& operator<<( std::basic_ostream& os, const basic_endpoint& endpoint) { os << endpoint.path(); return os; } } // namespace local } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_LOCAL_BASIC_ENDPOINT_HPP ================================================ FILE: src/third_party/asio/local/connect_pair.hpp ================================================ // // local/connect_pair.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_LOCAL_CONNECT_PAIR_HPP #define ASIO_LOCAL_CONNECT_PAIR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include "asio/basic_socket.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/local/basic_endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace local { /// Create a pair of connected sockets. template void connect_pair(basic_socket& socket1, basic_socket& socket2); /// Create a pair of connected sockets. template ASIO_SYNC_OP_VOID connect_pair(basic_socket& socket1, basic_socket& socket2, asio::error_code& ec); template inline void connect_pair(basic_socket& socket1, basic_socket& socket2) { asio::error_code ec; connect_pair(socket1, socket2, ec); asio::detail::throw_error(ec, "connect_pair"); } template inline ASIO_SYNC_OP_VOID connect_pair( basic_socket& socket1, basic_socket& socket2, asio::error_code& ec) { // Check that this function is only being used with a UNIX domain socket. asio::local::basic_endpoint* tmp = static_cast(0); (void)tmp; Protocol protocol; asio::detail::socket_type sv[2]; if (asio::detail::socket_ops::socketpair(protocol.family(), protocol.type(), protocol.protocol(), sv, ec) == asio::detail::socket_error_retval) ASIO_SYNC_OP_VOID_RETURN(ec); socket1.assign(protocol, sv[0], ec); if (ec) { asio::error_code temp_ec; asio::detail::socket_ops::state_type state[2] = { 0, 0 }; asio::detail::socket_ops::close(sv[0], state[0], true, temp_ec); asio::detail::socket_ops::close(sv[1], state[1], true, temp_ec); ASIO_SYNC_OP_VOID_RETURN(ec); } socket2.assign(protocol, sv[1], ec); if (ec) { asio::error_code temp_ec; socket1.close(temp_ec); asio::detail::socket_ops::state_type state = 0; asio::detail::socket_ops::close(sv[1], state, true, temp_ec); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID_RETURN(ec); } } // namespace local } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_LOCAL_CONNECT_PAIR_HPP ================================================ FILE: src/third_party/asio/local/datagram_protocol.hpp ================================================ // // local/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP #define ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include "asio/basic_datagram_socket.hpp" #include "asio/detail/socket_types.hpp" #include "asio/local/basic_endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace local { /// Encapsulates the flags needed for datagram-oriented UNIX sockets. /** * The asio::local::datagram_protocol class contains flags necessary for * datagram-oriented UNIX domain sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class datagram_protocol { public: /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return SOCK_DGRAM; } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return 0; } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return AF_UNIX; } /// The type of a UNIX domain endpoint. typedef basic_endpoint endpoint; /// The UNIX domain socket type. typedef basic_datagram_socket socket; }; } // namespace local } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP ================================================ FILE: src/third_party/asio/local/detail/endpoint.hpp ================================================ // // local/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_LOCAL_DETAIL_ENDPOINT_HPP #define ASIO_LOCAL_DETAIL_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_LOCAL_SOCKETS) #include #include #include "asio/detail/socket_types.hpp" #include "asio/detail/string_view.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace local { namespace detail { // Helper class for implementing a UNIX domain endpoint. class endpoint { public: // Default constructor. ASIO_DECL endpoint(); // Construct an endpoint using the specified path name. ASIO_DECL endpoint(const char* path_name); // Construct an endpoint using the specified path name. ASIO_DECL endpoint(const std::string& path_name); #if defined(ASIO_HAS_STRING_VIEW) // Construct an endpoint using the specified path name. ASIO_DECL endpoint(string_view path_name); #endif // defined(ASIO_HAS_STRING_VIEW) // Copy constructor. endpoint(const endpoint& other) : data_(other.data_), path_length_(other.path_length_) { } // Assign from another endpoint. endpoint& operator=(const endpoint& other) { data_ = other.data_; path_length_ = other.path_length_; return *this; } // Get the underlying endpoint in the native type. asio::detail::socket_addr_type* data() { return &data_.base; } // Get the underlying endpoint in the native type. const asio::detail::socket_addr_type* data() const { return &data_.base; } // Get the underlying size of the endpoint in the native type. std::size_t size() const { return path_length_ + offsetof(asio::detail::sockaddr_un_type, sun_path); } // Set the underlying size of the endpoint in the native type. ASIO_DECL void resize(std::size_t size); // Get the capacity of the endpoint in the native type. std::size_t capacity() const { return sizeof(asio::detail::sockaddr_un_type); } // Get the path associated with the endpoint. ASIO_DECL std::string path() const; // Set the path associated with the endpoint. ASIO_DECL void path(const char* p); // Set the path associated with the endpoint. ASIO_DECL void path(const std::string& p); // Compare two endpoints for equality. ASIO_DECL friend bool operator==( const endpoint& e1, const endpoint& e2); // Compare endpoints for ordering. ASIO_DECL friend bool operator<( const endpoint& e1, const endpoint& e2); private: // The underlying UNIX socket address. union data_union { asio::detail::socket_addr_type base; asio::detail::sockaddr_un_type local; } data_; // The length of the path associated with the endpoint. std::size_t path_length_; // Initialise with a specified path. ASIO_DECL void init(const char* path, std::size_t path_length); }; } // namespace detail } // namespace local } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/local/detail/impl/endpoint.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_LOCAL_SOCKETS) #endif // ASIO_LOCAL_DETAIL_ENDPOINT_HPP ================================================ FILE: src/third_party/asio/local/detail/impl/endpoint.ipp ================================================ // // local/detail/impl/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP #define ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_LOCAL_SOCKETS) #include #include "asio/detail/socket_ops.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/local/detail/endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace local { namespace detail { endpoint::endpoint() { init("", 0); } endpoint::endpoint(const char* path_name) { using namespace std; // For strlen. init(path_name, strlen(path_name)); } endpoint::endpoint(const std::string& path_name) { init(path_name.data(), path_name.length()); } #if defined(ASIO_HAS_STRING_VIEW) endpoint::endpoint(string_view path_name) { init(path_name.data(), path_name.length()); } #endif // defined(ASIO_HAS_STRING_VIEW) void endpoint::resize(std::size_t new_size) { if (new_size > sizeof(asio::detail::sockaddr_un_type)) { asio::error_code ec(asio::error::invalid_argument); asio::detail::throw_error(ec); } else if (new_size == 0) { path_length_ = 0; } else { path_length_ = new_size - offsetof(asio::detail::sockaddr_un_type, sun_path); // The path returned by the operating system may be NUL-terminated. if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0) --path_length_; } } std::string endpoint::path() const { return std::string(data_.local.sun_path, path_length_); } void endpoint::path(const char* p) { using namespace std; // For strlen. init(p, strlen(p)); } void endpoint::path(const std::string& p) { init(p.data(), p.length()); } bool operator==(const endpoint& e1, const endpoint& e2) { return e1.path() == e2.path(); } bool operator<(const endpoint& e1, const endpoint& e2) { return e1.path() < e2.path(); } void endpoint::init(const char* path_name, std::size_t path_length) { if (path_length > sizeof(data_.local.sun_path) - 1) { // The buffer is not large enough to store this address. asio::error_code ec(asio::error::name_too_long); asio::detail::throw_error(ec); } using namespace std; // For memcpy. data_.local = asio::detail::sockaddr_un_type(); data_.local.sun_family = AF_UNIX; if (path_length > 0) memcpy(data_.local.sun_path, path_name, path_length); path_length_ = path_length; // NUL-terminate normal path names. Names that start with a NUL are in the // UNIX domain protocol's "abstract namespace" and are not NUL-terminated. if (path_length > 0 && data_.local.sun_path[0] == 0) data_.local.sun_path[path_length] = 0; } } // namespace detail } // namespace local } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_LOCAL_SOCKETS) #endif // ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP ================================================ FILE: src/third_party/asio/local/stream_protocol.hpp ================================================ // // local/stream_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_LOCAL_STREAM_PROTOCOL_HPP #define ASIO_LOCAL_STREAM_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include "asio/basic_socket_acceptor.hpp" #include "asio/basic_socket_iostream.hpp" #include "asio/basic_stream_socket.hpp" #include "asio/detail/socket_types.hpp" #include "asio/local/basic_endpoint.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace local { /// Encapsulates the flags needed for stream-oriented UNIX sockets. /** * The asio::local::stream_protocol class contains flags necessary for * stream-oriented UNIX domain sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class stream_protocol { public: /// Obtain an identifier for the type of the protocol. int type() const ASIO_NOEXCEPT { return SOCK_STREAM; } /// Obtain an identifier for the protocol. int protocol() const ASIO_NOEXCEPT { return 0; } /// Obtain an identifier for the protocol family. int family() const ASIO_NOEXCEPT { return AF_UNIX; } /// The type of a UNIX domain endpoint. typedef basic_endpoint endpoint; /// The UNIX domain socket type. typedef basic_stream_socket socket; /// The UNIX domain acceptor type. typedef basic_socket_acceptor acceptor; #if !defined(ASIO_NO_IOSTREAM) /// The UNIX domain iostream type. typedef basic_socket_iostream iostream; #endif // !defined(ASIO_NO_IOSTREAM) }; } // namespace local } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_LOCAL_STREAM_PROTOCOL_HPP ================================================ FILE: src/third_party/asio/packaged_task.hpp ================================================ // // packaged_task.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_PACKAGED_TASK_HPP #define ASIO_PACKAGED_TASK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/future.hpp" #if defined(ASIO_HAS_STD_FUTURE_CLASS) \ || defined(GENERATING_DOCUMENTATION) #include "asio/async_result.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio { #if defined(ASIO_HAS_VARIADIC_TEMPLATES) \ || defined(GENERATING_DOCUMENTATION) /// Partial specialisation of @c async_result for @c std::packaged_task. template class async_result, Signature> { public: /// The packaged task is the concrete completion handler type. typedef std::packaged_task completion_handler_type; /// The return type of the initiating function is the future obtained from /// the packaged task. typedef std::future return_type; /// The constructor extracts the future from the packaged task. explicit async_result(completion_handler_type& h) : future_(h.get_future()) { } /// Returns the packaged task's future. return_type get() { return std::move(future_); } private: return_type future_; }; #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) template struct async_result, Signature> { typedef std::packaged_task completion_handler_type; typedef std::future return_type; explicit async_result(completion_handler_type& h) : future_(h.get_future()) { } return_type get() { return std::move(future_); } private: return_type future_; }; #define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \ template \ class async_result< \ std::packaged_task, Signature> \ { \ public: \ typedef std::packaged_task< \ Result(ASIO_VARIADIC_TARGS(n))> \ completion_handler_type; \ \ typedef std::future return_type; \ \ explicit async_result(completion_handler_type& h) \ : future_(h.get_future()) \ { \ } \ \ return_type get() \ { \ return std::move(future_); \ } \ \ private: \ return_type future_; \ }; \ /**/ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF) #undef ASIO_PRIVATE_ASYNC_RESULT_DEF #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_STD_FUTURE_CLASS) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_PACKAGED_TASK_HPP ================================================ FILE: src/third_party/asio/placeholders.hpp ================================================ // // placeholders.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_PLACEHOLDERS_HPP #define ASIO_PLACEHOLDERS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_BIND) # include #endif // defined(ASIO_HAS_BOOST_BIND) #include "asio/detail/push_options.hpp" namespace asio { namespace placeholders { #if defined(GENERATING_DOCUMENTATION) /// An argument placeholder, for use with boost::bind(), that corresponds to /// the error argument of a handler for any of the asynchronous functions. unspecified error; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the bytes_transferred argument of a handler for asynchronous functions such /// as asio::basic_stream_socket::async_write_some or /// asio::async_write. unspecified bytes_transferred; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the iterator argument of a handler for asynchronous functions such as /// asio::async_connect. unspecified iterator; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the results argument of a handler for asynchronous functions such as /// asio::basic_resolver::async_resolve. unspecified results; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the results argument of a handler for asynchronous functions such as /// asio::async_connect. unspecified endpoint; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the signal_number argument of a handler for asynchronous functions such as /// asio::signal_set::async_wait. unspecified signal_number; #elif defined(ASIO_HAS_BOOST_BIND) # if defined(__BORLANDC__) || defined(__GNUC__) inline boost::arg<1> error() { return boost::arg<1>(); } inline boost::arg<2> bytes_transferred() { return boost::arg<2>(); } inline boost::arg<2> iterator() { return boost::arg<2>(); } inline boost::arg<2> results() { return boost::arg<2>(); } inline boost::arg<2> endpoint() { return boost::arg<2>(); } inline boost::arg<2> signal_number() { return boost::arg<2>(); } # else namespace detail { template struct placeholder { static boost::arg& get() { static boost::arg result; return result; } }; } # if defined(ASIO_MSVC) && (ASIO_MSVC < 1400) static boost::arg<1>& error = asio::placeholders::detail::placeholder<1>::get(); static boost::arg<2>& bytes_transferred = asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& iterator = asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& results = asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& endpoint = asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& signal_number = asio::placeholders::detail::placeholder<2>::get(); # else namespace { boost::arg<1>& error = asio::placeholders::detail::placeholder<1>::get(); boost::arg<2>& bytes_transferred = asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& iterator = asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& results = asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& endpoint = asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& signal_number = asio::placeholders::detail::placeholder<2>::get(); } // namespace # endif # endif #endif } // namespace placeholders } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_PLACEHOLDERS_HPP ================================================ FILE: src/third_party/asio/posix/basic_descriptor.hpp ================================================ // // posix/basic_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_POSIX_BASIC_DESCRIPTOR_HPP #define ASIO_POSIX_BASIC_DESCRIPTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/reactive_descriptor_service.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/posix/descriptor_base.hpp" #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { namespace posix { /// Provides POSIX descriptor functionality. /** * The posix::basic_descriptor class template provides the ability to wrap a * POSIX descriptor. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_descriptor : public descriptor_base { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the descriptor type to another executor. template struct rebind_executor { /// The descriptor type when rebound to the specified executor. typedef basic_descriptor other; }; /// The native representation of a descriptor. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef detail::reactive_descriptor_service::native_handle_type native_handle_type; #endif /// A descriptor is always the lowest layer. typedef basic_descriptor lowest_layer_type; /// Construct a descriptor without opening it. /** * This constructor creates a descriptor without opening it. * * @param ex The I/O executor that the descriptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * descriptor. */ explicit basic_descriptor(const executor_type& ex) : impl_(ex) { } /// Construct a descriptor without opening it. /** * This constructor creates a descriptor without opening it. * * @param context An execution context which provides the I/O executor that * the descriptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the descriptor. */ template explicit basic_descriptor(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { } /// Construct a descriptor on an existing native descriptor. /** * This constructor creates a descriptor object to hold an existing native * descriptor. * * @param ex The I/O executor that the descriptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * descriptor. * * @param native_descriptor A native descriptor. * * @throws asio::system_error Thrown on failure. */ basic_descriptor(const executor_type& ex, const native_handle_type& native_descriptor) : impl_(ex) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_descriptor, ec); asio::detail::throw_error(ec, "assign"); } /// Construct a descriptor on an existing native descriptor. /** * This constructor creates a descriptor object to hold an existing native * descriptor. * * @param context An execution context which provides the I/O executor that * the descriptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the descriptor. * * @param native_descriptor A native descriptor. * * @throws asio::system_error Thrown on failure. */ template basic_descriptor(ExecutionContext& context, const native_handle_type& native_descriptor, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_descriptor, ec); asio::detail::throw_error(ec, "assign"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a descriptor from another. /** * This constructor moves a descriptor from one object to another. * * @param other The other descriptor object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_descriptor(const executor_type&) * constructor. */ basic_descriptor(basic_descriptor&& other) : impl_(std::move(other.impl_)) { } /// Move-assign a descriptor from another. /** * This assignment operator moves a descriptor from one object to another. * * @param other The other descriptor object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_descriptor(const executor_type&) * constructor. */ basic_descriptor& operator=(basic_descriptor&& other) { impl_ = std::move(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of * layers. Since a descriptor cannot contain any further layers, it * simply returns a reference to itself. * * @return A reference to the lowest layer in the stack of layers. Ownership * is not transferred to the caller. */ lowest_layer_type& lowest_layer() { return *this; } /// Get a const reference to the lowest layer. /** * This function returns a const reference to the lowest layer in a stack of * layers. Since a descriptor cannot contain any further layers, it * simply returns a reference to itself. * * @return A const reference to the lowest layer in the stack of layers. * Ownership is not transferred to the caller. */ const lowest_layer_type& lowest_layer() const { return *this; } /// Assign an existing native descriptor to the descriptor. /* * This function opens the descriptor to hold an existing native descriptor. * * @param native_descriptor A native descriptor. * * @throws asio::system_error Thrown on failure. */ void assign(const native_handle_type& native_descriptor) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_descriptor, ec); asio::detail::throw_error(ec, "assign"); } /// Assign an existing native descriptor to the descriptor. /* * This function opens the descriptor to hold an existing native descriptor. * * @param native_descriptor A native descriptor. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID assign(const native_handle_type& native_descriptor, asio::error_code& ec) { impl_.get_service().assign( impl_.get_implementation(), native_descriptor, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the descriptor is open. bool is_open() const { return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the descriptor. /** * This function is used to close the descriptor. Any asynchronous read or * write operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. Note that, even if * the function indicates an error, the underlying descriptor is closed. */ void close() { asio::error_code ec; impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } /// Close the descriptor. /** * This function is used to close the descriptor. Any asynchronous read or * write operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. Note that, even if * the function indicates an error, the underlying descriptor is closed. */ ASIO_SYNC_OP_VOID close(asio::error_code& ec) { impl_.get_service().close(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the native descriptor representation. /** * This function may be used to obtain the underlying representation of the * descriptor. This is intended to allow access to native descriptor * functionality that is not otherwise provided. */ native_handle_type native_handle() { return impl_.get_service().native_handle(impl_.get_implementation()); } /// Release ownership of the native descriptor implementation. /** * This function may be used to obtain the underlying representation of the * descriptor. After calling this function, @c is_open() returns false. The * caller is responsible for closing the descriptor. * * All outstanding asynchronous read or write operations will finish * immediately, and the handlers for cancelled operations will be passed the * asio::error::operation_aborted error. */ native_handle_type release() { return impl_.get_service().release(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the descriptor. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void cancel() { asio::error_code ec; impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } /// Cancel all asynchronous operations associated with the descriptor. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { impl_.get_service().cancel(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform an IO control command on the descriptor. /** * This function is used to execute an IO control command on the descriptor. * * @param command The IO control command to be performed on the descriptor. * * @throws asio::system_error Thrown on failure. * * @sa IoControlCommand @n * asio::posix::descriptor_base::bytes_readable @n * asio::posix::descriptor_base::non_blocking_io * * @par Example * Getting the number of bytes ready to read: * @code * asio::posix::stream_descriptor descriptor(my_context); * ... * asio::posix::stream_descriptor::bytes_readable command; * descriptor.io_control(command); * std::size_t bytes_readable = command.get(); * @endcode */ template void io_control(IoControlCommand& command) { asio::error_code ec; impl_.get_service().io_control(impl_.get_implementation(), command, ec); asio::detail::throw_error(ec, "io_control"); } /// Perform an IO control command on the descriptor. /** * This function is used to execute an IO control command on the descriptor. * * @param command The IO control command to be performed on the descriptor. * * @param ec Set to indicate what error occurred, if any. * * @sa IoControlCommand @n * asio::posix::descriptor_base::bytes_readable @n * asio::posix::descriptor_base::non_blocking_io * * @par Example * Getting the number of bytes ready to read: * @code * asio::posix::stream_descriptor descriptor(my_context); * ... * asio::posix::stream_descriptor::bytes_readable command; * asio::error_code ec; * descriptor.io_control(command, ec); * if (ec) * { * // An error occurred. * } * std::size_t bytes_readable = command.get(); * @endcode */ template ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, asio::error_code& ec) { impl_.get_service().io_control(impl_.get_implementation(), command, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the descriptor. /** * @returns @c true if the descriptor's synchronous operations will fail with * asio::error::would_block if they are unable to perform the requested * operation immediately. If @c false, synchronous operations will block * until complete. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ bool non_blocking() const { return impl_.get_service().non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the descriptor. /** * @param mode If @c true, the descriptor's synchronous operations will fail * with asio::error::would_block if they are unable to perform the * requested operation immediately. If @c false, synchronous operations will * block until complete. * * @throws asio::system_error Thrown on failure. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ void non_blocking(bool mode) { asio::error_code ec; impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "non_blocking"); } /// Sets the non-blocking mode of the descriptor. /** * @param mode If @c true, the descriptor's synchronous operations will fail * with asio::error::would_block if they are unable to perform the * requested operation immediately. If @c false, synchronous operations will * block until complete. * * @param ec Set to indicate what error occurred, if any. * * @note The non-blocking mode has no effect on the behaviour of asynchronous * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ ASIO_SYNC_OP_VOID non_blocking( bool mode, asio::error_code& ec) { impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the native descriptor implementation. /** * This function is used to retrieve the non-blocking mode of the underlying * native descriptor. This mode has no effect on the behaviour of the * descriptor object's synchronous operations. * * @returns @c true if the underlying descriptor is in non-blocking mode and * direct system calls may fail with asio::error::would_block (or the * equivalent system error). * * @note The current non-blocking mode is cached by the descriptor object. * Consequently, the return value may be incorrect if the non-blocking mode * was set directly on the native descriptor. */ bool native_non_blocking() const { return impl_.get_service().native_non_blocking( impl_.get_implementation()); } /// Sets the non-blocking mode of the native descriptor implementation. /** * This function is used to modify the non-blocking mode of the underlying * native descriptor. It has no effect on the behaviour of the descriptor * object's synchronous operations. * * @param mode If @c true, the underlying descriptor is put into non-blocking * mode and direct system calls may fail with asio::error::would_block * (or the equivalent system error). * * @throws asio::system_error Thrown on failure. If the @c mode is * @c false, but the current value of @c non_blocking() is @c true, this * function fails with asio::error::invalid_argument, as the * combination does not make sense. */ void native_non_blocking(bool mode) { asio::error_code ec; impl_.get_service().native_non_blocking( impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "native_non_blocking"); } /// Sets the non-blocking mode of the native descriptor implementation. /** * This function is used to modify the non-blocking mode of the underlying * native descriptor. It has no effect on the behaviour of the descriptor * object's synchronous operations. * * @param mode If @c true, the underlying descriptor is put into non-blocking * mode and direct system calls may fail with asio::error::would_block * (or the equivalent system error). * * @param ec Set to indicate what error occurred, if any. If the @c mode is * @c false, but the current value of @c non_blocking() is @c true, this * function fails with asio::error::invalid_argument, as the * combination does not make sense. */ ASIO_SYNC_OP_VOID native_non_blocking( bool mode, asio::error_code& ec) { impl_.get_service().native_non_blocking( impl_.get_implementation(), mode, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Wait for the descriptor to become ready to read, ready to write, or to /// have pending error conditions. /** * This function is used to perform a blocking wait for a descriptor to enter * a ready to read, write or error condition state. * * @param w Specifies the desired descriptor state. * * @par Example * Waiting for a descriptor to become readable. * @code * asio::posix::stream_descriptor descriptor(my_context); * ... * descriptor.wait(asio::posix::stream_descriptor::wait_read); * @endcode */ void wait(wait_type w) { asio::error_code ec; impl_.get_service().wait(impl_.get_implementation(), w, ec); asio::detail::throw_error(ec, "wait"); } /// Wait for the descriptor to become ready to read, ready to write, or to /// have pending error conditions. /** * This function is used to perform a blocking wait for a descriptor to enter * a ready to read, write or error condition state. * * @param w Specifies the desired descriptor state. * * @param ec Set to indicate what error occurred, if any. * * @par Example * Waiting for a descriptor to become readable. * @code * asio::posix::stream_descriptor descriptor(my_context); * ... * asio::error_code ec; * descriptor.wait(asio::posix::stream_descriptor::wait_read, ec); * @endcode */ ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) { impl_.get_service().wait(impl_.get_implementation(), w, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Asynchronously wait for the descriptor to become ready to read, ready to /// write, or to have pending error conditions. /** * This function is used to perform an asynchronous wait for a descriptor to * enter a ready to read, write or error condition state. * * @param w Specifies the desired descriptor state. * * @param handler The handler to be called when the wait operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error // Result of operation * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * @code * void wait_handler(const asio::error_code& error) * { * if (!error) * { * // Wait succeeded. * } * } * * ... * * asio::posix::stream_descriptor descriptor(my_context); * ... * descriptor.async_wait( * asio::posix::stream_descriptor::wait_read, * wait_handler); * @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (asio::error_code)) async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_wait(this), handler, w); } protected: /// Protected destructor to prevent deletion through this type. /** * This function destroys the descriptor, cancelling any outstanding * asynchronous wait operations associated with the descriptor as if by * calling @c cancel. */ ~basic_descriptor() { } detail::io_object_impl impl_; private: // Disallow copying and assignment. basic_descriptor(const basic_descriptor&) ASIO_DELETED; basic_descriptor& operator=(const basic_descriptor&) ASIO_DELETED; class initiate_async_wait { public: typedef Executor executor_type; explicit initiate_async_wait(basic_descriptor* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler. ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_wait( self_->impl_.get_implementation(), w, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_descriptor* self_; }; }; } // namespace posix } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_POSIX_BASIC_DESCRIPTOR_HPP ================================================ FILE: src/third_party/asio/posix/basic_stream_descriptor.hpp ================================================ // // posix/basic_stream_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP #define ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/posix/descriptor.hpp" #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) namespace asio { namespace posix { /// Provides stream-oriented descriptor functionality. /** * The posix::basic_stream_descriptor class template provides asynchronous and * blocking stream-oriented descriptor functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template class basic_stream_descriptor : public basic_descriptor { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the descriptor type to another executor. template struct rebind_executor { /// The descriptor type when rebound to the specified executor. typedef basic_stream_descriptor other; }; /// The native representation of a descriptor. typedef typename basic_descriptor::native_handle_type native_handle_type; /// Construct a stream descriptor without opening it. /** * This constructor creates a stream descriptor without opening it. The * descriptor needs to be opened and then connected or accepted before data * can be sent or received on it. * * @param ex The I/O executor that the descriptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * descriptor. */ explicit basic_stream_descriptor(const executor_type& ex) : basic_descriptor(ex) { } /// Construct a stream descriptor without opening it. /** * This constructor creates a stream descriptor without opening it. The * descriptor needs to be opened and then connected or accepted before data * can be sent or received on it. * * @param context An execution context which provides the I/O executor that * the descriptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the descriptor. */ template explicit basic_stream_descriptor(ExecutionContext& context, typename enable_if< is_convertible::value >::type* = 0) : basic_descriptor(context) { } /// Construct a stream descriptor on an existing native descriptor. /** * This constructor creates a stream descriptor object to hold an existing * native descriptor. * * @param ex The I/O executor that the descriptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * descriptor. * * @param native_descriptor The new underlying descriptor implementation. * * @throws asio::system_error Thrown on failure. */ basic_stream_descriptor(const executor_type& ex, const native_handle_type& native_descriptor) : basic_descriptor(ex, native_descriptor) { } /// Construct a stream descriptor on an existing native descriptor. /** * This constructor creates a stream descriptor object to hold an existing * native descriptor. * * @param context An execution context which provides the I/O executor that * the descriptor will use, by default, to dispatch handlers for any * asynchronous operations performed on the descriptor. * * @param native_descriptor The new underlying descriptor implementation. * * @throws asio::system_error Thrown on failure. */ template basic_stream_descriptor(ExecutionContext& context, const native_handle_type& native_descriptor, typename enable_if< is_convertible::value >::type* = 0) : basic_descriptor(context, native_descriptor) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a stream descriptor from another. /** * This constructor moves a stream descriptor from one object to another. * * @param other The other stream descriptor object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_descriptor(const executor_type&) * constructor. */ basic_stream_descriptor(basic_stream_descriptor&& other) : descriptor(std::move(other)) { } /// Move-assign a stream descriptor from another. /** * This assignment operator moves a stream descriptor from one object to * another. * * @param other The other stream descriptor object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_descriptor(const executor_type&) * constructor. */ basic_stream_descriptor& operator=(basic_stream_descriptor&& other) { descriptor::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Write some data to the descriptor. /** * This function is used to write data to the stream descriptor. The function * call will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the descriptor. * * @returns The number of bytes written. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * descriptor.write_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t write_some(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().write_some( this->impl_.get_implementation(), buffers, ec); asio::detail::throw_error(ec, "write_some"); return s; } /// Write some data to the descriptor. /** * This function is used to write data to the stream descriptor. The function * call will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the descriptor. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. */ template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().write_some( this->impl_.get_implementation(), buffers, ec); } /// Start an asynchronous write. /** * This function is used to asynchronously write data to the stream * descriptor. The function call always returns immediately. * * @param buffers One or more data buffers to be written to the descriptor. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The write operation may not transmit all of the data to the peer. * Consider using the @ref async_write function if you need to ensure that all * data is written before the asynchronous operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * descriptor.async_write_some(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_write_some(this), handler, buffers); } /// Read some data from the descriptor. /** * This function is used to read data from the stream descriptor. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @returns The number of bytes read. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * descriptor.read_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t read_some(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().read_some( this->impl_.get_implementation(), buffers, ec); asio::detail::throw_error(ec, "read_some"); return s; } /// Read some data from the descriptor. /** * This function is used to read data from the stream descriptor. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. */ template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().read_some( this->impl_.get_implementation(), buffers, ec); } /// Start an asynchronous read. /** * This function is used to asynchronously read data from the stream * descriptor. The function call always returns immediately. * * @param buffers One or more buffers into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The read operation may not read all of the requested number of bytes. * Consider using the @ref async_read function if you need to ensure that the * requested amount of data is read before the asynchronous operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * descriptor.async_read_some(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_read_some(this), handler, buffers); } private: class initiate_async_write_some { public: typedef Executor executor_type; explicit initiate_async_write_some(basic_stream_descriptor* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_write_some( self_->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_stream_descriptor* self_; }; class initiate_async_read_some { public: typedef Executor executor_type; explicit initiate_async_read_some(basic_stream_descriptor* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_read_some( self_->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_stream_descriptor* self_; }; }; } // namespace posix } // namespace asio #endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP ================================================ FILE: src/third_party/asio/posix/descriptor.hpp ================================================ // // posix/descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_POSIX_DESCRIPTOR_HPP #define ASIO_POSIX_DESCRIPTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) #include "asio/posix/basic_descriptor.hpp" namespace asio { namespace posix { /// Typedef for the typical usage of basic_descriptor. typedef basic_descriptor<> descriptor; } // namespace posix } // namespace asio #endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_POSIX_DESCRIPTOR_HPP ================================================ FILE: src/third_party/asio/posix/descriptor_base.hpp ================================================ // // posix/descriptor_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_POSIX_DESCRIPTOR_BASE_HPP #define ASIO_POSIX_DESCRIPTOR_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) #include "asio/detail/io_control.hpp" #include "asio/detail/socket_option.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace posix { /// The descriptor_base class is used as a base for the descriptor class as a /// place to define the associated IO control commands. class descriptor_base { public: /// Wait types. /** * For use with descriptor::wait() and descriptor::async_wait(). */ enum wait_type { /// Wait for a descriptor to become ready to read. wait_read, /// Wait for a descriptor to become ready to write. wait_write, /// Wait for a descriptor to have error conditions pending. wait_error }; /// IO control command to get the amount of data that can be read without /// blocking. /** * Implements the FIONREAD IO control command. * * @par Example * @code * asio::posix::stream_descriptor descriptor(my_context); * ... * asio::descriptor_base::bytes_readable command(true); * descriptor.io_control(command); * std::size_t bytes_readable = command.get(); * @endcode * * @par Concepts: * IoControlCommand. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined bytes_readable; #else typedef asio::detail::io_control::bytes_readable bytes_readable; #endif protected: /// Protected destructor to prevent deletion through this type. ~descriptor_base() { } }; } // namespace posix } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_POSIX_DESCRIPTOR_BASE_HPP ================================================ FILE: src/third_party/asio/posix/stream_descriptor.hpp ================================================ // // posix/stream_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_POSIX_STREAM_DESCRIPTOR_HPP #define ASIO_POSIX_STREAM_DESCRIPTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) #include "asio/posix/basic_stream_descriptor.hpp" namespace asio { namespace posix { /// Typedef for the typical usage of a stream-oriented descriptor. typedef basic_stream_descriptor<> stream_descriptor; } // namespace posix } // namespace asio #endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_POSIX_STREAM_DESCRIPTOR_HPP ================================================ FILE: src/third_party/asio/post.hpp ================================================ // // post.hpp // ~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_POST_HPP #define ASIO_POST_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Submits a completion token or function object for execution. /** * This function submits an object for execution using the object's associated * executor. The function object is queued for execution, and is never called * from the current thread prior to returning from post(). * * The use of @c post(), rather than @ref defer(), indicates the caller's * preference that the function object be eagerly queued for execution. * * This function has the following effects: * * @li Constructs a function object handler of type @c Handler, initialized * with handler(forward(token)). * * @li Constructs an object @c result of type async_result, * initializing the object as result(handler). * * @li Obtains the handler's associated executor object @c ex by performing * get_associated_executor(handler). * * @li Obtains the handler's associated allocator object @c alloc by performing * get_associated_allocator(handler). * * @li Performs ex.post(std::move(handler), alloc). * * @li Returns result.get(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post( ASIO_MOVE_ARG(CompletionToken) token); /// Submits a completion token or function object for execution. /** * This function submits an object for execution using the specified executor. * The function object is queued for execution, and is never called from the * current thread prior to returning from post(). * * The use of @c post(), rather than @ref defer(), indicates the caller's * preference that the function object be eagerly queued for execution. * * This function has the following effects: * * @li Constructs a function object handler of type @c Handler, initialized * with handler(forward(token)). * * @li Constructs an object @c result of type async_result, * initializing the object as result(handler). * * @li Obtains the handler's associated executor object @c ex1 by performing * get_associated_executor(handler). * * @li Creates a work object @c w by performing make_work(ex1). * * @li Obtains the handler's associated allocator object @c alloc by performing * get_associated_allocator(handler). * * @li Constructs a function object @c f with a function call operator that * performs ex1.dispatch(std::move(handler), alloc) followed by * w.reset(). * * @li Performs Executor(ex).post(std::move(f), alloc). * * @li Returns result.get(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post( const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN(Executor), typename enable_if::value>::type* = 0); /// Submits a completion token or function object for execution. /** * @returns post(ctx.get_executor(), forward(token)). */ template ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post( ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type), typename enable_if::value>::type* = 0); } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/post.hpp" #endif // ASIO_POST_HPP ================================================ FILE: src/third_party/asio/read.hpp ================================================ // // read.hpp // ~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_READ_HPP #define ASIO_READ_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/buffer.hpp" #include "asio/error.hpp" #if !defined(ASIO_NO_EXTENSIONS) # include "asio/basic_streambuf_fwd.hpp" #endif // !defined(ASIO_NO_EXTENSIONS) #include "asio/detail/push_options.hpp" namespace asio { /** * @defgroup read asio::read * * @brief The @c read function is a composed operation that reads a certain * amount of data from a stream before returning. */ /*@{*/ /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * stream. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::read(s, asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::read( * s, buffers, * asio::transfer_all()); @endcode */ template std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, typename enable_if< is_mutable_buffer_sequence::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * stream. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::read(s, asio::buffer(data, size), ec); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::read( * s, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, asio::error_code& ec, typename enable_if< is_mutable_buffer_sequence::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * stream. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::read(s, asio::buffer(data, size), * asio::transfer_at_least(32)); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, typename enable_if< is_mutable_buffer_sequence::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * stream. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_mutable_buffer_sequence::value >::type* = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::read( * s, buffers, * asio::transfer_all()); @endcode */ template std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::read( * s, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t read(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b The basic_streambuf object into which the data will be read. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::read( * s, b, * asio::transfer_all()); @endcode */ template std::size_t read(SyncReadStream& s, basic_streambuf& b); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b The basic_streambuf object into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::read( * s, b, * asio::transfer_all(), ec); @endcode */ template std::size_t read(SyncReadStream& s, basic_streambuf& b, asio::error_code& ec); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b The basic_streambuf object into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t read(SyncReadStream& s, basic_streambuf& b, CompletionCondition completion_condition); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b The basic_streambuf object into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t read(SyncReadStream& s, basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::read( * s, buffers, * asio::transfer_all()); @endcode */ template std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::read( * s, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Attempt to read a certain amount of data from a stream before returning. /** * This function is used to read a certain number of bytes of data from a * stream. The call will block until one of the following conditions is true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's read_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /*@}*/ /** * @defgroup async_read asio::async_read * * @brief The @c async_read function is a composed asynchronous operation that * reads a certain amount of data from a stream before completion. */ /*@{*/ /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. The * program must ensure that the stream performs no other read operations (such * as async_read, the stream's async_read_some function, or any other composed * operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * stream. Although the buffers object may be copied as necessary, ownership of * the underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * asio::async_read(s, asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::async_read( * s, buffers, * asio::transfer_all(), * handler); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_mutable_buffer_sequence::value >::type* = 0); /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * stream. Although the buffers object may be copied as necessary, ownership of * the underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's async_read_some function. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::async_read(s, * asio::buffer(data, size), * asio::transfer_at_least(32), * handler); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_mutable_buffer_sequence::value >::type* = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. The * program must ensure that the stream performs no other read operations (such * as async_read, the stream's async_read_some function, or any other composed * operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note This overload is equivalent to calling: * @code asio::async_read( * s, buffers, * asio::transfer_all(), * handler); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. The * program must ensure that the stream performs no other read operations (such * as async_read, the stream's async_read_some function, or any other composed * operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's async_read_some function. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. The * program must ensure that the stream performs no other read operations (such * as async_read, the stream's async_read_some function, or any other composed * operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param b A basic_streambuf object into which the data will be read. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note This overload is equivalent to calling: * @code asio::async_read( * s, b, * asio::transfer_all(), * handler); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, basic_streambuf& b, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type)); /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The supplied buffer is full (that is, it has reached maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. The * program must ensure that the stream performs no other read operations (such * as async_read, the stream's async_read_some function, or any other composed * operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param b A basic_streambuf object into which the data will be read. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's async_read_some function. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type)); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. The * program must ensure that the stream performs no other read operations (such * as async_read, the stream's async_read_some function, or any other composed * operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note This overload is equivalent to calling: * @code asio::async_read( * s, buffers, * asio::transfer_all(), * handler); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Start an asynchronous operation to read a certain amount of data from a /// stream. /** * This function is used to asynchronously read a certain number of bytes of * data from a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions is * true: * * @li The specified dynamic buffer sequence is full (that is, it has reached * maximum size). * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. The * program must ensure that the stream performs no other read operations (such * as async_read, the stream's async_read_some function, or any other composed * operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_read_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the stream's async_read_some function. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes copied into the * // buffers. If an error occurred, * // this will be the number of * // bytes successfully transferred * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/read.hpp" #endif // ASIO_READ_HPP ================================================ FILE: src/third_party/asio/read_at.hpp ================================================ // // read_at.hpp // ~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_READ_AT_HPP #define ASIO_READ_AT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/detail/cstdint.hpp" #include "asio/error.hpp" #if !defined(ASIO_NO_EXTENSIONS) # include "asio/basic_streambuf_fwd.hpp" #endif // !defined(ASIO_NO_EXTENSIONS) #include "asio/detail/push_options.hpp" namespace asio { /** * @defgroup read_at asio::read_at * * @brief The @c read_at function is a composed operation that reads a certain * amount of data at the specified offset before returning. */ /*@{*/ /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * device. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::read_at(d, 42, asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::read_at( * d, 42, buffers, * asio::transfer_all()); @endcode */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers); /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * device. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::read_at(d, 42, * asio::buffer(data, size), ec); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::read_at( * d, 42, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, asio::error_code& ec); /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * device. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the device's read_some_at function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::read_at(d, 42, asio::buffer(data, size), * asio::transfer_at_least(32)); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition); /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * device. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the device's read_some_at function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param b The basic_streambuf object into which the data will be read. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::read_at( * d, 42, b, * asio::transfer_all()); @endcode */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf& b); /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param b The basic_streambuf object into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::read_at( * d, 42, b, * asio::transfer_all(), ec); @endcode */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf& b, asio::error_code& ec); /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param b The basic_streambuf object into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the device's read_some_at function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf& b, CompletionCondition completion_condition); /// Attempt to read a certain amount of data at the specified offset before /// returning. /** * This function is used to read a certain number of bytes of data from a * random access device at the specified offset. The call will block until one * of the following conditions is true: * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * read_some_at function. * * @param d The device from which the data is to be read. The type must support * the SyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param b The basic_streambuf object into which the data will be read. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest read_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the device's read_some_at function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) /*@}*/ /** * @defgroup async_read_at asio::async_read_at * * @brief The @c async_read_at function is a composed asynchronous operation * that reads a certain amount of data at the specified offset. */ /*@{*/ /// Start an asynchronous operation to read a certain amount of data at the /// specified offset. /** * This function is used to asynchronously read a certain number of bytes of * data from a random access device at the specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * async_read_some_at function. * * @param d The device from which the data is to be read. The type must support * the AsyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * device. Although the buffers object may be copied as necessary, ownership of * the underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes copied into the buffers. If an error * // occurred, this will be the number of bytes successfully * // transferred prior to the error. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * asio::async_read_at(d, 42, asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::async_read_at( * d, 42, buffers, * asio::transfer_all(), * handler); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessReadDevice::executor_type)); /// Start an asynchronous operation to read a certain amount of data at the /// specified offset. /** * This function is used to asynchronously read a certain number of bytes of * data from a random access device at the specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li The supplied buffers are full. That is, the bytes transferred is equal to * the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * @param d The device from which the data is to be read. The type must support * the AsyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. The sum * of the buffer sizes indicates the maximum number of bytes to read from the * device. Although the buffers object may be copied as necessary, ownership of * the underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_read_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the device's async_read_some_at function. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes copied into the buffers. If an error * // occurred, this will be the number of bytes successfully * // transferred prior to the error. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code asio::async_read_at(d, 42, * asio::buffer(data, size), * asio::transfer_at_least(32), * handler); @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessReadDevice::executor_type)); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Start an asynchronous operation to read a certain amount of data at the /// specified offset. /** * This function is used to asynchronously read a certain number of bytes of * data from a random access device at the specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * async_read_some_at function. * * @param d The device from which the data is to be read. The type must support * the AsyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param b A basic_streambuf object into which the data will be read. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes copied into the buffers. If an error * // occurred, this will be the number of bytes successfully * // transferred prior to the error. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note This overload is equivalent to calling: * @code asio::async_read_at( * d, 42, b, * asio::transfer_all(), * handler); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf& b, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessReadDevice::executor_type)); /// Start an asynchronous operation to read a certain amount of data at the /// specified offset. /** * This function is used to asynchronously read a certain number of bytes of * data from a random access device at the specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * async_read_some_at function. * * @param d The device from which the data is to be read. The type must support * the AsyncRandomAccessReadDevice concept. * * @param offset The offset at which the data will be read. * * @param b A basic_streambuf object into which the data will be read. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the read operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_read_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the read operation is complete. A non-zero * return value indicates the maximum number of bytes to be read on the next * call to the device's async_read_some_at function. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes copied into the buffers. If an error * // occurred, this will be the number of bytes successfully * // transferred prior to the error. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessReadDevice::executor_type)); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/read_at.hpp" #endif // ASIO_READ_AT_HPP ================================================ FILE: src/third_party/asio/read_until.hpp ================================================ // // read_until.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_READ_UNTIL_HPP #define ASIO_READ_UNTIL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/async_result.hpp" #include "asio/buffer.hpp" #include "asio/detail/regex_fwd.hpp" #include "asio/detail/string_view.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #if !defined(ASIO_NO_EXTENSIONS) # include "asio/basic_streambuf_fwd.hpp" #endif // !defined(ASIO_NO_EXTENSIONS) #include "asio/detail/push_options.hpp" namespace asio { namespace detail { char (&has_result_type_helper(...))[2]; template char has_result_type_helper(T*, typename T::result_type* = 0); template struct has_result_type { enum { value = (sizeof((has_result_type_helper)((T*)(0))) == 1) }; }; } // namespace detail /// Type trait used to determine whether a type can be used as a match condition /// function with read_until and async_read_until. template struct is_match_condition { #if defined(GENERATING_DOCUMENTATION) /// The value member is true if the type may be used as a match condition. static const bool value; #else enum { value = asio::is_function< typename asio::remove_pointer::type>::value || detail::has_result_type::value }; #endif }; /** * @defgroup read_until asio::read_until * * @brief The @c read_until function is a composed operation that reads data * into a dynamic buffer sequence, or into a streambuf, until it contains a * delimiter, matches a regular expression, or a function object indicates a * match. */ /*@{*/ #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter character. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. * * @par Example * To read data into a @c std::string until a newline is encountered: * @code std::string data; * std::string n = asio::read_until(s, * asio::dynamic_buffer(data), '\n'); * std::string line = data.substr(0, n); * data.erase(0, n); @endcode * After the @c read_until operation completes successfully, the string @c data * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c b as * follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter character. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. Returns 0 if an error occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter string. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. * * @par Example * To read data into a @c std::string until a CR-LF sequence is encountered: * @code std::string data; * std::string n = asio::read_until(s, * asio::dynamic_buffer(data), "\r\n"); * std::string line = data.substr(0, n); * data.erase(0, n); @endcode * After the @c read_until operation completes successfully, the string @c data * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c b as * follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter string. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. Returns 0 if an error occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION) /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains some data * that matches a regular expression. The call will block until one of the * following conditions is true: * * @li A substring of the dynamic buffer sequence's get area matches the * regular expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains data that matches the regular expression, the function returns * immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param expr The regular expression. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the substring that matches the regular expression. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the regular * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent read_until operation to examine. * * @par Example * To read data into a @c std::string until a CR-LF sequence is encountered: * @code std::string data; * std::string n = asio::read_until(s, * asio::dynamic_buffer(data), boost::regex("\r\n")); * std::string line = data.substr(0, n); * data.erase(0, n); @endcode * After the @c read_until operation completes successfully, the string @c data * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c b as * follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const boost::regex& expr, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains some data * that matches a regular expression. The call will block until one of the * following conditions is true: * * @li A substring of the dynamic buffer sequence's get area matches the * regular expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains data that matches the regular expression, the function returns * immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param expr The regular expression. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the substring that matches the regular expression. Returns 0 * if an error occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the regular * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const boost::regex& expr, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION) /// Read data into a dynamic buffer sequence until a function object indicates a /// match. /** * This function is used to read data into the specified dynamic buffer * sequence until a user-defined match condition function object, when applied * to the data contained in the dynamic buffer sequence, indicates a successful * match. The call will block until one of the following conditions is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the match condition function object already indicates * a match, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @returns The number of bytes in the dynamic_buffer's get area that * have been fully consumed by the match function. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the function object. * An application will typically leave that data in the dynamic buffer sequence * for a subsequent read_until operation to examine. * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. * * @par Examples * To read data into a dynamic buffer sequence until whitespace is encountered: * @code typedef asio::buffers_iterator< * asio::const_buffers_1> iterator; * * std::pair * match_whitespace(iterator begin, iterator end) * { * iterator i = begin; * while (i != end) * if (std::isspace(*i++)) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * ... * std::string data; * asio::read_until(s, data, match_whitespace); * @endcode * * To read data into a @c std::string until a matching character is found: * @code class match_char * { * public: * explicit match_char(char c) : c_(c) {} * * template * std::pair operator()( * Iterator begin, Iterator end) const * { * Iterator i = begin; * while (i != end) * if (c_ == *i++) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * * private: * char c_; * }; * * namespace asio { * template <> struct is_match_condition * : public boost::true_type {}; * } // namespace asio * ... * std::string data; * asio::read_until(s, data, match_char('a')); * @endcode */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition, typename enable_if< is_match_condition::value && is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Read data into a dynamic buffer sequence until a function object indicates a /// match. /** * This function is used to read data into the specified dynamic buffer * sequence until a user-defined match condition function object, when applied * to the data contained in the dynamic buffer sequence, indicates a successful * match. The call will block until one of the following conditions is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the match condition function object already indicates * a match, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area that * have been fully consumed by the match function. Returns 0 if an error * occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the function object. * An application will typically leave that data in the dynamic buffer sequence * for a subsequent read_until operation to examine. * * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. */ template std::size_t read_until(SyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition, asio::error_code& ec, typename enable_if< is_match_condition::value && is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_IOSTREAM) /// Read data into a streambuf until it contains a specified delimiter. /** * This function is used to read data into the specified streambuf until the * streambuf's get area contains the specified delimiter. The call will block * until one of the following conditions is true: * * @li The get area of the streambuf contains the specified delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the streambuf's get area already contains the * delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param delim The delimiter character. * * @returns The number of bytes in the streambuf's get area up to and including * the delimiter. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond the delimiter. An application will typically leave * that data in the streambuf for a subsequent read_until operation to examine. * * @par Example * To read data into a streambuf until a newline is encountered: * @code asio::streambuf b; * asio::read_until(s, b, '\n'); * std::istream is(&b); * std::string line; * std::getline(is, line); @endcode * After the @c read_until operation completes successfully, the buffer @c b * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode * The call to @c std::getline then extracts the data up to and including the * newline (which is discarded), so that the string @c line contains: * @code { 'a', 'b', ..., 'c' } @endcode * The remaining data is left in the buffer @c b as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, char delim); /// Read data into a streambuf until it contains a specified delimiter. /** * This function is used to read data into the specified streambuf until the * streambuf's get area contains the specified delimiter. The call will block * until one of the following conditions is true: * * @li The get area of the streambuf contains the specified delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the streambuf's get area already contains the * delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param delim The delimiter character. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the streambuf's get area up to and including * the delimiter. Returns 0 if an error occurred. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond the delimiter. An application will typically leave * that data in the streambuf for a subsequent read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, char delim, asio::error_code& ec); /// Read data into a streambuf until it contains a specified delimiter. /** * This function is used to read data into the specified streambuf until the * streambuf's get area contains the specified delimiter. The call will block * until one of the following conditions is true: * * @li The get area of the streambuf contains the specified delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the streambuf's get area already contains the * delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param delim The delimiter string. * * @returns The number of bytes in the streambuf's get area up to and including * the delimiter. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond the delimiter. An application will typically leave * that data in the streambuf for a subsequent read_until operation to examine. * * @par Example * To read data into a streambuf until a newline is encountered: * @code asio::streambuf b; * asio::read_until(s, b, "\r\n"); * std::istream is(&b); * std::string line; * std::getline(is, line); @endcode * After the @c read_until operation completes successfully, the buffer @c b * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c std::getline then extracts the data up to and including the * newline (which is discarded), so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r' } @endcode * The remaining data is left in the buffer @c b as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, ASIO_STRING_VIEW_PARAM delim); /// Read data into a streambuf until it contains a specified delimiter. /** * This function is used to read data into the specified streambuf until the * streambuf's get area contains the specified delimiter. The call will block * until one of the following conditions is true: * * @li The get area of the streambuf contains the specified delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the streambuf's get area already contains the * delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param delim The delimiter string. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the streambuf's get area up to and including * the delimiter. Returns 0 if an error occurred. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond the delimiter. An application will typically leave * that data in the streambuf for a subsequent read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec); #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION) /// Read data into a streambuf until some part of the data it contains matches /// a regular expression. /** * This function is used to read data into the specified streambuf until the * streambuf's get area contains some data that matches a regular expression. * The call will block until one of the following conditions is true: * * @li A substring of the streambuf's get area matches the regular expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the streambuf's get area already contains data that * matches the regular expression, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param expr The regular expression. * * @returns The number of bytes in the streambuf's get area up to and including * the substring that matches the regular expression. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond that which matched the regular expression. An * application will typically leave that data in the streambuf for a subsequent * read_until operation to examine. * * @par Example * To read data into a streambuf until a CR-LF sequence is encountered: * @code asio::streambuf b; * asio::read_until(s, b, boost::regex("\r\n")); * std::istream is(&b); * std::string line; * std::getline(is, line); @endcode * After the @c read_until operation completes successfully, the buffer @c b * contains the data which matched the regular expression: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c std::getline then extracts the data up to and including the * newline (which is discarded), so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r' } @endcode * The remaining data is left in the buffer @c b as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, const boost::regex& expr); /// Read data into a streambuf until some part of the data it contains matches /// a regular expression. /** * This function is used to read data into the specified streambuf until the * streambuf's get area contains some data that matches a regular expression. * The call will block until one of the following conditions is true: * * @li A substring of the streambuf's get area matches the regular expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the streambuf's get area already contains data that * matches the regular expression, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param expr The regular expression. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the streambuf's get area up to and including * the substring that matches the regular expression. Returns 0 if an error * occurred. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond that which matched the regular expression. An * application will typically leave that data in the streambuf for a subsequent * read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, const boost::regex& expr, asio::error_code& ec); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION) /// Read data into a streambuf until a function object indicates a match. /** * This function is used to read data into the specified streambuf until a * user-defined match condition function object, when applied to the data * contained in the streambuf, indicates a successful match. The call will * block until one of the following conditions is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the match condition function object already indicates * a match, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator::const_buffers_type> * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @returns The number of bytes in the streambuf's get area that have been fully * consumed by the match function. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond that which matched the function object. An application * will typically leave that data in the streambuf for a subsequent read_until * operation to examine. * * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. * * @par Examples * To read data into a streambuf until whitespace is encountered: * @code typedef asio::buffers_iterator< * asio::streambuf::const_buffers_type> iterator; * * std::pair * match_whitespace(iterator begin, iterator end) * { * iterator i = begin; * while (i != end) * if (std::isspace(*i++)) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * ... * asio::streambuf b; * asio::read_until(s, b, match_whitespace); * @endcode * * To read data into a streambuf until a matching character is found: * @code class match_char * { * public: * explicit match_char(char c) : c_(c) {} * * template * std::pair operator()( * Iterator begin, Iterator end) const * { * Iterator i = begin; * while (i != end) * if (c_ == *i++) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * * private: * char c_; * }; * * namespace asio { * template <> struct is_match_condition * : public boost::true_type {}; * } // namespace asio * ... * asio::streambuf b; * asio::read_until(s, b, match_char('a')); * @endcode */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, MatchCondition match_condition, typename enable_if::value>::type* = 0); /// Read data into a streambuf until a function object indicates a match. /** * This function is used to read data into the specified streambuf until a * user-defined match condition function object, when applied to the data * contained in the streambuf, indicates a successful match. The call will * block until one of the following conditions is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the match condition function object already indicates * a match, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator::const_buffers_type> * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the streambuf's get area that have been fully * consumed by the match function. Returns 0 if an error occurred. * * @note After a successful read_until operation, the streambuf may contain * additional data beyond that which matched the function object. An application * will typically leave that data in the streambuf for a subsequent read_until * operation to examine. * * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. */ template std::size_t read_until(SyncReadStream& s, asio::basic_streambuf& b, MatchCondition match_condition, asio::error_code& ec, typename enable_if::value>::type* = 0); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter character. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. * * @par Example * To read data into a @c std::string until a newline is encountered: * @code std::string data; * std::string n = asio::read_until(s, * asio::dynamic_buffer(data), '\n'); * std::string line = data.substr(0, n); * data.erase(0, n); @endcode * After the @c read_until operation completes successfully, the string @c data * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c b as * follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter character. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. Returns 0 if an error occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter string. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. * * @par Example * To read data into a @c std::string until a CR-LF sequence is encountered: * @code std::string data; * std::string n = asio::read_until(s, * asio::dynamic_buffer(data), "\r\n"); * std::string line = data.substr(0, n); * data.erase(0, n); @endcode * After the @c read_until operation completes successfully, the string @c data * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c b as * follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains the specified * delimiter. The call will block until one of the following conditions is * true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains the delimiter, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * * @param delim The delimiter string. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the delimiter. Returns 0 if an error occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond the delimiter. An application will * typically leave that data in the dynamic buffer sequence for a subsequent * read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION) /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains some data * that matches a regular expression. The call will block until one of the * following conditions is true: * * @li A substring of the dynamic buffer sequence's get area matches the * regular expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains data that matches the regular expression, the function returns * immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param expr The regular expression. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the substring that matches the regular expression. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the regular * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent read_until operation to examine. * * @par Example * To read data into a @c std::string until a CR-LF sequence is encountered: * @code std::string data; * std::string n = asio::read_until(s, * asio::dynamic_buffer(data), boost::regex("\r\n")); * std::string line = data.substr(0, n); * data.erase(0, n); @endcode * After the @c read_until operation completes successfully, the string @c data * contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c b as * follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, const boost::regex& expr, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression. /** * This function is used to read data into the specified dynamic buffer * sequence until the dynamic buffer sequence's get area contains some data * that matches a regular expression. The call will block until one of the * following conditions is true: * * @li A substring of the dynamic buffer sequence's get area matches the * regular expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the dynamic buffer sequence's get area already * contains data that matches the regular expression, the function returns * immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param expr The regular expression. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area up to * and including the substring that matches the regular expression. Returns 0 * if an error occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the regular * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent read_until operation to examine. */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, const boost::regex& expr, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION) /// Read data into a dynamic buffer sequence until a function object indicates a /// match. /** * This function is used to read data into the specified dynamic buffer * sequence until a user-defined match condition function object, when applied * to the data contained in the dynamic buffer sequence, indicates a successful * match. The call will block until one of the following conditions is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the match condition function object already indicates * a match, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @returns The number of bytes in the dynamic_buffer's get area that * have been fully consumed by the match function. * * @throws asio::system_error Thrown on failure. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the function object. * An application will typically leave that data in the dynamic buffer sequence * for a subsequent read_until operation to examine. * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. * * @par Examples * To read data into a dynamic buffer sequence until whitespace is encountered: * @code typedef asio::buffers_iterator< * asio::const_buffers_1> iterator; * * std::pair * match_whitespace(iterator begin, iterator end) * { * iterator i = begin; * while (i != end) * if (std::isspace(*i++)) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * ... * std::string data; * asio::read_until(s, data, match_whitespace); * @endcode * * To read data into a @c std::string until a matching character is found: * @code class match_char * { * public: * explicit match_char(char c) : c_(c) {} * * template * std::pair operator()( * Iterator begin, Iterator end) const * { * Iterator i = begin; * while (i != end) * if (c_ == *i++) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * * private: * char c_; * }; * * namespace asio { * template <> struct is_match_condition * : public boost::true_type {}; * } // namespace asio * ... * std::string data; * asio::read_until(s, data, match_char('a')); * @endcode */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, typename enable_if< is_match_condition::value && is_dynamic_buffer_v2::value >::type* = 0); /// Read data into a dynamic buffer sequence until a function object indicates a /// match. /** * This function is used to read data into the specified dynamic buffer * sequence until a user-defined match condition function object, when applied * to the data contained in the dynamic buffer sequence, indicates a successful * match. The call will block until one of the following conditions is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * read_some function. If the match condition function object already indicates * a match, the function returns immediately. * * @param s The stream from which the data is to be read. The type must support * the SyncReadStream concept. * * @param buffers A dynamic buffer sequence into which the data will be read. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the dynamic buffer sequence's get area that * have been fully consumed by the match function. Returns 0 if an error * occurred. * * @note After a successful read_until operation, the dynamic buffer sequence * may contain additional data beyond that which matched the function object. * An application will typically leave that data in the dynamic buffer sequence * for a subsequent read_until operation to examine. * * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. */ template std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, asio::error_code& ec, typename enable_if< is_match_condition::value && is_dynamic_buffer_v2::value >::type* = 0); #endif // !defined(ASIO_NO_EXTENSIONS) /*@}*/ /** * @defgroup async_read_until asio::async_read_until * * @brief The @c async_read_until function is a composed asynchronous operation * that reads data into a dynamic buffer sequence, or into a streambuf, until * it contains a delimiter, matches a regular expression, or a function object * indicates a match. */ /*@{*/ #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until the dynamic buffer sequence's get area contains the * specified delimiter. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the dynamic buffer sequence's get area already contains the delimiter, this * asynchronous operation completes immediately. The program must ensure that * the stream performs no other read operations (such as async_read, * async_read_until, the stream's async_read_some function, or any other * composed operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param delim The delimiter character. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer sequence's * // get area up to and including the delimiter. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond the delimiter. An application * will typically leave that data in the dynamic buffer sequence for a * subsequent async_read_until operation to examine. * * @par Example * To asynchronously read data into a @c std::string until a newline is * encountered: * @code std::string data; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::string line = data.substr(0, n); * data.erase(0, n); * ... * } * } * ... * asio::async_read_until(s, data, '\n', handler); @endcode * After the @c async_read_until operation completes successfully, the buffer * @c data contains the delimiter: * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c data * as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until the dynamic buffer sequence's get area contains the * specified delimiter. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the dynamic buffer sequence's get area already contains the delimiter, this * asynchronous operation completes immediately. The program must ensure that * the stream performs no other read operations (such as async_read, * async_read_until, the stream's async_read_some function, or any other * composed operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param delim The delimiter string. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer sequence's * // get area up to and including the delimiter. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond the delimiter. An application * will typically leave that data in the dynamic buffer sequence for a * subsequent async_read_until operation to examine. * * @par Example * To asynchronously read data into a @c std::string until a CR-LF sequence is * encountered: * @code std::string data; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::string line = data.substr(0, n); * data.erase(0, n); * ... * } * } * ... * asio::async_read_until(s, data, "\r\n", handler); @endcode * After the @c async_read_until operation completes successfully, the string * @c data contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the string @c data * as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION) /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until some part of its data matches a regular expression. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until the dynamic buffer sequence's get area contains some * data that matches a regular expression. The function call always returns * immediately. The asynchronous operation will continue until one of the * following conditions is true: * * @li A substring of the dynamic buffer sequence's get area matches the regular * expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the dynamic buffer sequence's get area already contains data that matches * the regular expression, this asynchronous operation completes immediately. * The program must ensure that the stream performs no other read operations * (such as async_read, async_read_until, the stream's async_read_some * function, or any other composed operations that perform reads) until this * operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param expr The regular expression. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer * // sequence's get area up to and including the * // substring that matches the regular expression. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the regular * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent async_read_until operation to examine. * * @par Example * To asynchronously read data into a @c std::string until a CR-LF sequence is * encountered: * @code std::string data; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::string line = data.substr(0, n); * data.erase(0, n); * ... * } * } * ... * asio::async_read_until(s, data, * boost::regex("\r\n"), handler); @endcode * After the @c async_read_until operation completes successfully, the string * @c data contains the data which matched the regular expression: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the match, * so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the string @c data * as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const boost::regex& expr, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION) /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until a function object indicates a match. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until a user-defined match condition function object, when * applied to the data contained in the dynamic buffer sequence, indicates a * successful match. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the match condition function object already indicates a match, this * asynchronous operation completes immediately. The program must ensure that * the stream performs no other read operations (such as async_read, * async_read_until, the stream's async_read_some function, or any other * composed operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer sequence's * // get area that have been fully consumed by the match * // function. O if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the function * object. An application will typically leave that data in the dynamic buffer * sequence for a subsequent async_read_until operation to examine. * * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. * * @par Examples * To asynchronously read data into a @c std::string until whitespace is * encountered: * @code typedef asio::buffers_iterator< * asio::const_buffers_1> iterator; * * std::pair * match_whitespace(iterator begin, iterator end) * { * iterator i = begin; * while (i != end) * if (std::isspace(*i++)) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * ... * void handler(const asio::error_code& e, std::size_t size); * ... * std::string data; * asio::async_read_until(s, data, match_whitespace, handler); * @endcode * * To asynchronously read data into a @c std::string until a matching character * is found: * @code class match_char * { * public: * explicit match_char(char c) : c_(c) {} * * template * std::pair operator()( * Iterator begin, Iterator end) const * { * Iterator i = begin; * while (i != end) * if (c_ == *i++) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * * private: * char c_; * }; * * namespace asio { * template <> struct is_match_condition * : public boost::true_type {}; * } // namespace asio * ... * void handler(const asio::error_code& e, std::size_t size); * ... * std::string data; * asio::async_read_until(s, data, match_char('a'), handler); * @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_match_condition::value && is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_IOSTREAM) /// Start an asynchronous operation to read data into a streambuf until it /// contains a specified delimiter. /** * This function is used to asynchronously read data into the specified * streambuf until the streambuf's get area contains the specified delimiter. * The function call always returns immediately. The asynchronous operation * will continue until one of the following conditions is true: * * @li The get area of the streambuf contains the specified delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the streambuf's get area already contains the delimiter, this asynchronous * operation completes immediately. The program must ensure that the stream * performs no other read operations (such as async_read, async_read_until, the * stream's async_read_some function, or any other composed operations that * perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param b A streambuf object into which the data will be read. Ownership of * the streambuf is retained by the caller, which must guarantee that it remains * valid until the handler is called. * * @param delim The delimiter character. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the streambuf's get * // area up to and including the delimiter. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the streambuf may * contain additional data beyond the delimiter. An application will typically * leave that data in the streambuf for a subsequent async_read_until operation * to examine. * * @par Example * To asynchronously read data into a streambuf until a newline is encountered: * @code asio::streambuf b; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::istream is(&b); * std::string line; * std::getline(is, line); * ... * } * } * ... * asio::async_read_until(s, b, '\n', handler); @endcode * After the @c async_read_until operation completes successfully, the buffer * @c b contains the delimiter: * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode * The call to @c std::getline then extracts the data up to and including the * newline (which is discarded), so that the string @c line contains: * @code { 'a', 'b', ..., 'c' } @endcode * The remaining data is left in the buffer @c b as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, char delim, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type)); /// Start an asynchronous operation to read data into a streambuf until it /// contains a specified delimiter. /** * This function is used to asynchronously read data into the specified * streambuf until the streambuf's get area contains the specified delimiter. * The function call always returns immediately. The asynchronous operation * will continue until one of the following conditions is true: * * @li The get area of the streambuf contains the specified delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the streambuf's get area already contains the delimiter, this asynchronous * operation completes immediately. The program must ensure that the stream * performs no other read operations (such as async_read, async_read_until, the * stream's async_read_some function, or any other composed operations that * perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param b A streambuf object into which the data will be read. Ownership of * the streambuf is retained by the caller, which must guarantee that it remains * valid until the handler is called. * * @param delim The delimiter string. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the streambuf's get * // area up to and including the delimiter. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the streambuf may * contain additional data beyond the delimiter. An application will typically * leave that data in the streambuf for a subsequent async_read_until operation * to examine. * * @par Example * To asynchronously read data into a streambuf until a newline is encountered: * @code asio::streambuf b; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::istream is(&b); * std::string line; * std::getline(is, line); * ... * } * } * ... * asio::async_read_until(s, b, "\r\n", handler); @endcode * After the @c async_read_until operation completes successfully, the buffer * @c b contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c std::getline then extracts the data up to and including the * newline (which is discarded), so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r' } @endcode * The remaining data is left in the buffer @c b as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, ASIO_STRING_VIEW_PARAM delim, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type)); #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION) /// Start an asynchronous operation to read data into a streambuf until some /// part of its data matches a regular expression. /** * This function is used to asynchronously read data into the specified * streambuf until the streambuf's get area contains some data that matches a * regular expression. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li A substring of the streambuf's get area matches the regular expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the streambuf's get area already contains data that matches the regular * expression, this asynchronous operation completes immediately. The program * must ensure that the stream performs no other read operations (such as * async_read, async_read_until, the stream's async_read_some function, or any * other composed operations that perform reads) until this operation * completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param b A streambuf object into which the data will be read. Ownership of * the streambuf is retained by the caller, which must guarantee that it remains * valid until the handler is called. * * @param expr The regular expression. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the streambuf's get * // area up to and including the substring * // that matches the regular. expression. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the streambuf may * contain additional data beyond that which matched the regular expression. An * application will typically leave that data in the streambuf for a subsequent * async_read_until operation to examine. * * @par Example * To asynchronously read data into a streambuf until a CR-LF sequence is * encountered: * @code asio::streambuf b; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::istream is(&b); * std::string line; * std::getline(is, line); * ... * } * } * ... * asio::async_read_until(s, b, boost::regex("\r\n"), handler); @endcode * After the @c async_read_until operation completes successfully, the buffer * @c b contains the data which matched the regular expression: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c std::getline then extracts the data up to and including the * newline (which is discarded), so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r' } @endcode * The remaining data is left in the buffer @c b as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, const boost::regex& expr, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type)); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION) /// Start an asynchronous operation to read data into a streambuf until a /// function object indicates a match. /** * This function is used to asynchronously read data into the specified * streambuf until a user-defined match condition function object, when applied * to the data contained in the streambuf, indicates a successful match. The * function call always returns immediately. The asynchronous operation will * continue until one of the following conditions is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the match condition function object already indicates a match, this * asynchronous operation completes immediately. The program must ensure that * the stream performs no other read operations (such as async_read, * async_read_until, the stream's async_read_some function, or any other * composed operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param b A streambuf object into which the data will be read. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator::const_buffers_type> * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the streambuf's get * // area that have been fully consumed by the * // match function. O if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the streambuf may * contain additional data beyond that which matched the function object. An * application will typically leave that data in the streambuf for a subsequent * async_read_until operation to examine. * * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. * * @par Examples * To asynchronously read data into a streambuf until whitespace is encountered: * @code typedef asio::buffers_iterator< * asio::streambuf::const_buffers_type> iterator; * * std::pair * match_whitespace(iterator begin, iterator end) * { * iterator i = begin; * while (i != end) * if (std::isspace(*i++)) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * ... * void handler(const asio::error_code& e, std::size_t size); * ... * asio::streambuf b; * asio::async_read_until(s, b, match_whitespace, handler); * @endcode * * To asynchronously read data into a streambuf until a matching character is * found: * @code class match_char * { * public: * explicit match_char(char c) : c_(c) {} * * template * std::pair operator()( * Iterator begin, Iterator end) const * { * Iterator i = begin; * while (i != end) * if (c_ == *i++) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * * private: * char c_; * }; * * namespace asio { * template <> struct is_match_condition * : public boost::true_type {}; * } // namespace asio * ... * void handler(const asio::error_code& e, std::size_t size); * ... * asio::streambuf b; * asio::async_read_until(s, b, match_char('a'), handler); * @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, asio::basic_streambuf& b, MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if::value>::type* = 0); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until the dynamic buffer sequence's get area contains the * specified delimiter. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the dynamic buffer sequence's get area already contains the delimiter, this * asynchronous operation completes immediately. The program must ensure that * the stream performs no other read operations (such as async_read, * async_read_until, the stream's async_read_some function, or any other * composed operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param delim The delimiter character. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer sequence's * // get area up to and including the delimiter. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond the delimiter. An application * will typically leave that data in the dynamic buffer sequence for a * subsequent async_read_until operation to examine. * * @par Example * To asynchronously read data into a @c std::string until a newline is * encountered: * @code std::string data; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::string line = data.substr(0, n); * data.erase(0, n); * ... * } * } * ... * asio::async_read_until(s, data, '\n', handler); @endcode * After the @c async_read_until operation completes successfully, the buffer * @c data contains the delimiter: * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\n' } @endcode * After the call to @c erase, the remaining data is left in the buffer @c data * as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, char delim, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until the dynamic buffer sequence's get area contains the * specified delimiter. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li The get area of the dynamic buffer sequence contains the specified * delimiter. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the dynamic buffer sequence's get area already contains the delimiter, this * asynchronous operation completes immediately. The program must ensure that * the stream performs no other read operations (such as async_read, * async_read_until, the stream's async_read_some function, or any other * composed operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param delim The delimiter string. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer sequence's * // get area up to and including the delimiter. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond the delimiter. An application * will typically leave that data in the dynamic buffer sequence for a * subsequent async_read_until operation to examine. * * @par Example * To asynchronously read data into a @c std::string until a CR-LF sequence is * encountered: * @code std::string data; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::string line = data.substr(0, n); * data.erase(0, n); * ... * } * } * ... * asio::async_read_until(s, data, "\r\n", handler); @endcode * After the @c async_read_until operation completes successfully, the string * @c data contains the delimiter: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the * delimiter, so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the string @c data * as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION) /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until some part of its data matches a regular expression. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until the dynamic buffer sequence's get area contains some * data that matches a regular expression. The function call always returns * immediately. The asynchronous operation will continue until one of the * following conditions is true: * * @li A substring of the dynamic buffer sequence's get area matches the regular * expression. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the dynamic buffer sequence's get area already contains data that matches * the regular expression, this asynchronous operation completes immediately. * The program must ensure that the stream performs no other read operations * (such as async_read, async_read_until, the stream's async_read_some * function, or any other composed operations that perform reads) until this * operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param expr The regular expression. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer * // sequence's get area up to and including the * // substring that matches the regular expression. * // 0 if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the regular * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent async_read_until operation to examine. * * @par Example * To asynchronously read data into a @c std::string until a CR-LF sequence is * encountered: * @code std::string data; * ... * void handler(const asio::error_code& e, std::size_t size) * { * if (!e) * { * std::string line = data.substr(0, n); * data.erase(0, n); * ... * } * } * ... * asio::async_read_until(s, data, * boost::regex("\r\n"), handler); @endcode * After the @c async_read_until operation completes successfully, the string * @c data contains the data which matched the regular expression: * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode * The call to @c substr then extracts the data up to and including the match, * so that the string @c line contains: * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode * After the call to @c erase, the remaining data is left in the string @c data * as follows: * @code { 'd', 'e', ... } @endcode * This data may be the start of a new line, to be extracted by a subsequent * @c async_read_until operation. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, const boost::regex& expr, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION) /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until a function object indicates a match. /** * This function is used to asynchronously read data into the specified dynamic * buffer sequence until a user-defined match condition function object, when * applied to the data contained in the dynamic buffer sequence, indicates a * successful match. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li The match condition function object returns a std::pair where the second * element evaluates to true. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_read_some function, and is known as a composed operation. If * the match condition function object already indicates a match, this * asynchronous operation completes immediately. The program must ensure that * the stream performs no other read operations (such as async_read, * async_read_until, the stream's async_read_some function, or any other * composed operations that perform reads) until this operation completes. * * @param s The stream from which the data is to be read. The type must support * the AsyncReadStream concept. * * @param buffers The dynamic buffer sequence into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param match_condition The function object to be called to determine whether * a match exists. The signature of the function object must be: * @code pair match_condition(iterator begin, iterator end); * @endcode * where @c iterator represents the type: * @code buffers_iterator * @endcode * The iterator parameters @c begin and @c end define the range of bytes to be * scanned to determine whether there is a match. The @c first member of the * return value is an iterator marking one-past-the-end of the bytes that have * been consumed by the match function. This iterator is used to calculate the * @c begin parameter for any subsequent invocation of the match condition. The * @c second member of the return value is true if a match has been found, false * otherwise. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // The number of bytes in the dynamic buffer sequence's * // get area that have been fully consumed by the match * // function. O if an error occurred. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the function * object. An application will typically leave that data in the dynamic buffer * sequence for a subsequent async_read_until operation to examine. * * @note The default implementation of the @c is_match_condition type trait * evaluates to true for function pointers and function objects with a * @c result_type typedef. It must be specialised for other user-defined * function objects. * * @par Examples * To asynchronously read data into a @c std::string until whitespace is * encountered: * @code typedef asio::buffers_iterator< * asio::const_buffers_1> iterator; * * std::pair * match_whitespace(iterator begin, iterator end) * { * iterator i = begin; * while (i != end) * if (std::isspace(*i++)) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * ... * void handler(const asio::error_code& e, std::size_t size); * ... * std::string data; * asio::async_read_until(s, data, match_whitespace, handler); * @endcode * * To asynchronously read data into a @c std::string until a matching character * is found: * @code class match_char * { * public: * explicit match_char(char c) : c_(c) {} * * template * std::pair operator()( * Iterator begin, Iterator end) const * { * Iterator i = begin; * while (i != end) * if (c_ == *i++) * return std::make_pair(i, true); * return std::make_pair(i, false); * } * * private: * char c_; * }; * * namespace asio { * template <> struct is_match_condition * : public boost::true_type {}; * } // namespace asio * ... * void handler(const asio::error_code& e, std::size_t size); * ... * std::string data; * asio::async_read_until(s, data, match_char('a'), handler); * @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncReadStream::executor_type), typename enable_if< is_match_condition::value && is_dynamic_buffer_v2::value >::type* = 0); #endif // !defined(ASIO_NO_EXTENSIONS) /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/read_until.hpp" #endif // ASIO_READ_UNTIL_HPP ================================================ FILE: src/third_party/asio/redirect_error.hpp ================================================ // // redirect_error.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_REDIRECT_ERROR_HPP #define ASIO_REDIRECT_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error_code.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Completion token type used to specify that an error produced by an /// asynchronous operation is captured to an error_code variable. /** * The redirect_error_t class is used to indicate that any error_code produced * by an asynchronous operation is captured to a specified variable. */ template class redirect_error_t { public: /// Constructor. template redirect_error_t(ASIO_MOVE_ARG(T) completion_token, asio::error_code& ec) : token_(ASIO_MOVE_CAST(T)(completion_token)), ec_(ec) { } //private: CompletionToken token_; asio::error_code& ec_; }; /// Create a completion token to capture error_code values to a variable. template inline redirect_error_t::type> redirect_error( ASIO_MOVE_ARG(CompletionToken) completion_token, asio::error_code& ec) { return redirect_error_t::type>( ASIO_MOVE_CAST(CompletionToken)(completion_token), ec); } } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/redirect_error.hpp" #endif // ASIO_REDIRECT_ERROR_HPP ================================================ FILE: src/third_party/asio/serial_port.hpp ================================================ // // serial_port.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SERIAL_PORT_HPP #define ASIO_SERIAL_PORT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_SERIAL_PORT) \ || defined(GENERATING_DOCUMENTATION) #include "asio/basic_serial_port.hpp" namespace asio { /// Typedef for the typical usage of a serial port. typedef basic_serial_port<> serial_port; } // namespace asio #endif // defined(ASIO_HAS_SERIAL_PORT) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_SERIAL_PORT_HPP ================================================ FILE: src/third_party/asio/serial_port_base.hpp ================================================ // // serial_port_base.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SERIAL_PORT_BASE_HPP #define ASIO_SERIAL_PORT_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_SERIAL_PORT) \ || defined(GENERATING_DOCUMENTATION) #if !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) # include #endif // !defined(ASIO_WINDOWS) && !defined(__CYGWIN__) #include "asio/detail/socket_types.hpp" #include "asio/error_code.hpp" #if defined(GENERATING_DOCUMENTATION) # define ASIO_OPTION_STORAGE implementation_defined #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__) # define ASIO_OPTION_STORAGE DCB #else # define ASIO_OPTION_STORAGE termios #endif #include "asio/detail/push_options.hpp" namespace asio { /// The serial_port_base class is used as a base for the basic_serial_port class /// template so that we have a common place to define the serial port options. class serial_port_base { public: /// Serial port option to permit changing the baud rate. /** * Implements changing the baud rate for a given serial port. */ class baud_rate { public: explicit baud_rate(unsigned int rate = 0); unsigned int value() const; ASIO_DECL ASIO_SYNC_OP_VOID store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const; ASIO_DECL ASIO_SYNC_OP_VOID load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec); private: unsigned int value_; }; /// Serial port option to permit changing the flow control. /** * Implements changing the flow control for a given serial port. */ class flow_control { public: enum type { none, software, hardware }; ASIO_DECL explicit flow_control(type t = none); type value() const; ASIO_DECL ASIO_SYNC_OP_VOID store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const; ASIO_DECL ASIO_SYNC_OP_VOID load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec); private: type value_; }; /// Serial port option to permit changing the parity. /** * Implements changing the parity for a given serial port. */ class parity { public: enum type { none, odd, even }; ASIO_DECL explicit parity(type t = none); type value() const; ASIO_DECL ASIO_SYNC_OP_VOID store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const; ASIO_DECL ASIO_SYNC_OP_VOID load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec); private: type value_; }; /// Serial port option to permit changing the number of stop bits. /** * Implements changing the number of stop bits for a given serial port. */ class stop_bits { public: enum type { one, onepointfive, two }; ASIO_DECL explicit stop_bits(type t = one); type value() const; ASIO_DECL ASIO_SYNC_OP_VOID store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const; ASIO_DECL ASIO_SYNC_OP_VOID load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec); private: type value_; }; /// Serial port option to permit changing the character size. /** * Implements changing the character size for a given serial port. */ class character_size { public: ASIO_DECL explicit character_size(unsigned int t = 8); unsigned int value() const; ASIO_DECL ASIO_SYNC_OP_VOID store( ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const; ASIO_DECL ASIO_SYNC_OP_VOID load( const ASIO_OPTION_STORAGE& storage, asio::error_code& ec); private: unsigned int value_; }; protected: /// Protected destructor to prevent deletion through this type. ~serial_port_base() { } }; } // namespace asio #include "asio/detail/pop_options.hpp" #undef ASIO_OPTION_STORAGE #include "asio/impl/serial_port_base.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/serial_port_base.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_SERIAL_PORT) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_SERIAL_PORT_BASE_HPP ================================================ FILE: src/third_party/asio/signal_set.hpp ================================================ // // signal_set.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SIGNAL_SET_HPP #define ASIO_SIGNAL_SET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/basic_signal_set.hpp" namespace asio { /// Typedef for the typical usage of a signal set. typedef basic_signal_set<> signal_set; } // namespace asio #endif // ASIO_SIGNAL_SET_HPP ================================================ FILE: src/third_party/asio/socket_base.hpp ================================================ // // socket_base.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SOCKET_BASE_HPP #define ASIO_SOCKET_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/io_control.hpp" #include "asio/detail/socket_option.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// The socket_base class is used as a base for the basic_stream_socket and /// basic_datagram_socket class templates so that we have a common place to /// define the shutdown_type and enum. class socket_base { public: /// Different ways a socket may be shutdown. enum shutdown_type { #if defined(GENERATING_DOCUMENTATION) /// Shutdown the receive side of the socket. shutdown_receive = implementation_defined, /// Shutdown the send side of the socket. shutdown_send = implementation_defined, /// Shutdown both send and receive on the socket. shutdown_both = implementation_defined #else shutdown_receive = ASIO_OS_DEF(SHUT_RD), shutdown_send = ASIO_OS_DEF(SHUT_WR), shutdown_both = ASIO_OS_DEF(SHUT_RDWR) #endif }; /// Bitmask type for flags that can be passed to send and receive operations. typedef int message_flags; #if defined(GENERATING_DOCUMENTATION) /// Peek at incoming data without removing it from the input queue. static const int message_peek = implementation_defined; /// Process out-of-band data. static const int message_out_of_band = implementation_defined; /// Specify that the data should not be subject to routing. static const int message_do_not_route = implementation_defined; /// Specifies that the data marks the end of a record. static const int message_end_of_record = implementation_defined; #else ASIO_STATIC_CONSTANT(int, message_peek = ASIO_OS_DEF(MSG_PEEK)); ASIO_STATIC_CONSTANT(int, message_out_of_band = ASIO_OS_DEF(MSG_OOB)); ASIO_STATIC_CONSTANT(int, message_do_not_route = ASIO_OS_DEF(MSG_DONTROUTE)); ASIO_STATIC_CONSTANT(int, message_end_of_record = ASIO_OS_DEF(MSG_EOR)); #endif /// Wait types. /** * For use with basic_socket::wait() and basic_socket::async_wait(). */ enum wait_type { /// Wait for a socket to become ready to read. wait_read, /// Wait for a socket to become ready to write. wait_write, /// Wait for a socket to have error conditions pending. wait_error }; /// Socket option to permit sending of broadcast messages. /** * Implements the SOL_SOCKET/SO_BROADCAST socket option. * * @par Examples * Setting the option: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::socket_base::broadcast option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::socket_base::broadcast option; * socket.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined broadcast; #else typedef asio::detail::socket_option::boolean< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_BROADCAST)> broadcast; #endif /// Socket option to enable socket-level debugging. /** * Implements the SOL_SOCKET/SO_DEBUG socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::debug option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::debug option; * socket.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined debug; #else typedef asio::detail::socket_option::boolean< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_DEBUG)> debug; #endif /// Socket option to prevent routing, use local interfaces only. /** * Implements the SOL_SOCKET/SO_DONTROUTE socket option. * * @par Examples * Setting the option: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::socket_base::do_not_route option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::udp::socket socket(my_context); * ... * asio::socket_base::do_not_route option; * socket.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined do_not_route; #else typedef asio::detail::socket_option::boolean< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_DONTROUTE)> do_not_route; #endif /// Socket option to send keep-alives. /** * Implements the SOL_SOCKET/SO_KEEPALIVE socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::keep_alive option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::keep_alive option; * socket.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined keep_alive; #else typedef asio::detail::socket_option::boolean< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_KEEPALIVE)> keep_alive; #endif /// Socket option for the send buffer size of a socket. /** * Implements the SOL_SOCKET/SO_SNDBUF socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::send_buffer_size option(8192); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::send_buffer_size option; * socket.get_option(option); * int size = option.value(); * @endcode * * @par Concepts: * Socket_Option, Integer_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined send_buffer_size; #else typedef asio::detail::socket_option::integer< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_SNDBUF)> send_buffer_size; #endif /// Socket option for the send low watermark. /** * Implements the SOL_SOCKET/SO_SNDLOWAT socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::send_low_watermark option(1024); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::send_low_watermark option; * socket.get_option(option); * int size = option.value(); * @endcode * * @par Concepts: * Socket_Option, Integer_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined send_low_watermark; #else typedef asio::detail::socket_option::integer< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_SNDLOWAT)> send_low_watermark; #endif /// Socket option for the receive buffer size of a socket. /** * Implements the SOL_SOCKET/SO_RCVBUF socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::receive_buffer_size option(8192); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::receive_buffer_size option; * socket.get_option(option); * int size = option.value(); * @endcode * * @par Concepts: * Socket_Option, Integer_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined receive_buffer_size; #else typedef asio::detail::socket_option::integer< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_RCVBUF)> receive_buffer_size; #endif /// Socket option for the receive low watermark. /** * Implements the SOL_SOCKET/SO_RCVLOWAT socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::receive_low_watermark option(1024); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::receive_low_watermark option; * socket.get_option(option); * int size = option.value(); * @endcode * * @par Concepts: * Socket_Option, Integer_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined receive_low_watermark; #else typedef asio::detail::socket_option::integer< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_RCVLOWAT)> receive_low_watermark; #endif /// Socket option to allow the socket to be bound to an address that is /// already in use. /** * Implements the SOL_SOCKET/SO_REUSEADDR socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::socket_base::reuse_address option(true); * acceptor.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::socket_base::reuse_address option; * acceptor.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined reuse_address; #else typedef asio::detail::socket_option::boolean< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_REUSEADDR)> reuse_address; #endif /// Socket option to specify whether the socket lingers on close if unsent /// data is present. /** * Implements the SOL_SOCKET/SO_LINGER socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::linger option(true, 30); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::linger option; * socket.get_option(option); * bool is_set = option.enabled(); * unsigned short timeout = option.timeout(); * @endcode * * @par Concepts: * Socket_Option, Linger_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined linger; #else typedef asio::detail::socket_option::linger< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_LINGER)> linger; #endif /// Socket option for putting received out-of-band data inline. /** * Implements the SOL_SOCKET/SO_OOBINLINE socket option. * * @par Examples * Setting the option: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::out_of_band_inline option(true); * socket.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::out_of_band_inline option; * socket.get_option(option); * bool value = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined out_of_band_inline; #else typedef asio::detail::socket_option::boolean< ASIO_OS_DEF(SOL_SOCKET), ASIO_OS_DEF(SO_OOBINLINE)> out_of_band_inline; #endif /// Socket option to report aborted connections on accept. /** * Implements a custom socket option that determines whether or not an accept * operation is permitted to fail with asio::error::connection_aborted. * By default the option is false. * * @par Examples * Setting the option: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::socket_base::enable_connection_aborted option(true); * acceptor.set_option(option); * @endcode * * @par * Getting the current option value: * @code * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::socket_base::enable_connection_aborted option; * acceptor.get_option(option); * bool is_set = option.value(); * @endcode * * @par Concepts: * Socket_Option, Boolean_Socket_Option. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined enable_connection_aborted; #else typedef asio::detail::socket_option::boolean< asio::detail::custom_socket_option_level, asio::detail::enable_connection_aborted_option> enable_connection_aborted; #endif /// IO control command to get the amount of data that can be read without /// blocking. /** * Implements the FIONREAD IO control command. * * @par Example * @code * asio::ip::tcp::socket socket(my_context); * ... * asio::socket_base::bytes_readable command(true); * socket.io_control(command); * std::size_t bytes_readable = command.get(); * @endcode * * @par Concepts: * IO_Control_Command, Size_IO_Control_Command. */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined bytes_readable; #else typedef asio::detail::io_control::bytes_readable bytes_readable; #endif /// The maximum length of the queue of pending incoming connections. #if defined(GENERATING_DOCUMENTATION) static const int max_listen_connections = implementation_defined; #else ASIO_STATIC_CONSTANT(int, max_listen_connections = ASIO_OS_DEF(SOMAXCONN)); #endif #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use max_listen_connections.) The maximum length of the queue /// of pending incoming connections. #if defined(GENERATING_DOCUMENTATION) static const int max_connections = implementation_defined; #else ASIO_STATIC_CONSTANT(int, max_connections = ASIO_OS_DEF(SOMAXCONN)); #endif #endif // !defined(ASIO_NO_DEPRECATED) protected: /// Protected destructor to prevent deletion through this type. ~socket_base() { } }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SOCKET_BASE_HPP ================================================ FILE: src/third_party/asio/spawn.hpp ================================================ // // spawn.hpp // ~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SPAWN_HPP #define ASIO_SPAWN_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/bind_executor.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/wrapped_handler.hpp" #include "asio/executor.hpp" #include "asio/io_context.hpp" #include "asio/is_executor.hpp" #include "asio/strand.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Context object the represents the currently executing coroutine. /** * The basic_yield_context class is used to represent the currently executing * stackful coroutine. A basic_yield_context may be passed as a handler to an * asynchronous operation. For example: * * @code template * void my_coroutine(basic_yield_context yield) * { * ... * std::size_t n = my_socket.async_read_some(buffer, yield); * ... * } @endcode * * The initiating function (async_read_some in the above example) suspends the * current coroutine. The coroutine is resumed when the asynchronous operation * completes, and the result of the operation is returned. */ template class basic_yield_context { public: /// The coroutine callee type, used by the implementation. /** * When using Boost.Coroutine v1, this type is: * @code typename coroutine @endcode * When using Boost.Coroutine v2 (unidirectional coroutines), this type is: * @code push_coroutine @endcode */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined callee_type; #elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2) typedef boost::coroutines::push_coroutine callee_type; #else typedef boost::coroutines::coroutine callee_type; #endif /// The coroutine caller type, used by the implementation. /** * When using Boost.Coroutine v1, this type is: * @code typename coroutine::caller_type @endcode * When using Boost.Coroutine v2 (unidirectional coroutines), this type is: * @code pull_coroutine @endcode */ #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined caller_type; #elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2) typedef boost::coroutines::pull_coroutine caller_type; #else typedef boost::coroutines::coroutine::caller_type caller_type; #endif /// Construct a yield context to represent the specified coroutine. /** * Most applications do not need to use this constructor. Instead, the * spawn() function passes a yield context as an argument to the coroutine * function. */ basic_yield_context( const detail::weak_ptr& coro, caller_type& ca, Handler& handler) : coro_(coro), ca_(ca), handler_(handler), ec_(0) { } /// Construct a yield context from another yield context type. /** * Requires that OtherHandler be convertible to Handler. */ template basic_yield_context(const basic_yield_context& other) : coro_(other.coro_), ca_(other.ca_), handler_(other.handler_), ec_(other.ec_) { } /// Return a yield context that sets the specified error_code. /** * By default, when a yield context is used with an asynchronous operation, a * non-success error_code is converted to system_error and thrown. This * operator may be used to specify an error_code object that should instead be * set with the asynchronous operation's result. For example: * * @code template * void my_coroutine(basic_yield_context yield) * { * ... * std::size_t n = my_socket.async_read_some(buffer, yield[ec]); * if (ec) * { * // An error occurred. * } * ... * } @endcode */ basic_yield_context operator[](asio::error_code& ec) const { basic_yield_context tmp(*this); tmp.ec_ = &ec; return tmp; } #if defined(GENERATING_DOCUMENTATION) private: #endif // defined(GENERATING_DOCUMENTATION) detail::weak_ptr coro_; caller_type& ca_; Handler handler_; asio::error_code* ec_; }; #if defined(GENERATING_DOCUMENTATION) /// Context object that represents the currently executing coroutine. typedef basic_yield_context yield_context; #else // defined(GENERATING_DOCUMENTATION) typedef basic_yield_context< executor_binder > yield_context; #endif // defined(GENERATING_DOCUMENTATION) /** * @defgroup spawn asio::spawn * * @brief Start a new stackful coroutine. * * The spawn() function is a high-level wrapper over the Boost.Coroutine * library. This function enables programs to implement asynchronous logic in a * synchronous manner, as illustrated by the following example: * * @code asio::spawn(my_strand, do_echo); * * // ... * * void do_echo(asio::yield_context yield) * { * try * { * char data[128]; * for (;;) * { * std::size_t length = * my_socket.async_read_some( * asio::buffer(data), yield); * * asio::async_write(my_socket, * asio::buffer(data, length), yield); * } * } * catch (std::exception& e) * { * // ... * } * } @endcode */ /*@{*/ /// Start a new stackful coroutine, calling the specified handler when it /// completes. /** * This function is used to launch a new coroutine. * * @param function The coroutine function. The function must have the signature: * @code void function(basic_yield_context yield); @endcode * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ template void spawn(ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); /// Start a new stackful coroutine, calling the specified handler when it /// completes. /** * This function is used to launch a new coroutine. * * @param handler A handler to be called when the coroutine exits. More * importantly, the handler provides an execution context (via the the handler * invocation hook) for the coroutine. The handler must have the signature: * @code void handler(); @endcode * * @param function The coroutine function. The function must have the signature: * @code void function(basic_yield_context yield); @endcode * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ template void spawn(ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes(), typename enable_if::type>::value && !is_convertible::value>::type* = 0); /// Start a new stackful coroutine, inheriting the execution context of another. /** * This function is used to launch a new coroutine. * * @param ctx Identifies the current coroutine as a parent of the new * coroutine. This specifies that the new coroutine should inherit the * execution context of the parent. For example, if the parent coroutine is * executing in a particular strand, then the new coroutine will execute in the * same strand. * * @param function The coroutine function. The function must have the signature: * @code void function(basic_yield_context yield); @endcode * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ template void spawn(basic_yield_context ctx, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); /// Start a new stackful coroutine that executes on a given executor. /** * This function is used to launch a new coroutine. * * @param ex Identifies the executor that will run the coroutine. The new * coroutine is implicitly given its own strand within this executor. * * @param function The coroutine function. The function must have the signature: * @code void function(yield_context yield); @endcode * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ template void spawn(const Executor& ex, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes(), typename enable_if::value>::type* = 0); /// Start a new stackful coroutine that executes on a given strand. /** * This function is used to launch a new coroutine. * * @param ex Identifies the strand that will run the coroutine. * * @param function The coroutine function. The function must have the signature: * @code void function(yield_context yield); @endcode * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ template void spawn(const strand& ex, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); /// Start a new stackful coroutine that executes in the context of a strand. /** * This function is used to launch a new coroutine. * * @param s Identifies a strand. By starting multiple coroutines on the same * strand, the implementation ensures that none of those coroutines can execute * simultaneously. * * @param function The coroutine function. The function must have the signature: * @code void function(yield_context yield); @endcode * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ template void spawn(const asio::io_context::strand& s, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes()); /// Start a new stackful coroutine that executes on a given execution context. /** * This function is used to launch a new coroutine. * * @param ctx Identifies the execution context that will run the coroutine. The * new coroutine is implicitly given its own strand within this execution * context. * * @param function The coroutine function. The function must have the signature: * @code void function(yield_context yield); @endcode * * @param attributes Boost.Coroutine attributes used to customise the coroutine. */ template void spawn(ExecutionContext& ctx, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes = boost::coroutines::attributes(), typename enable_if::value>::type* = 0); /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/spawn.hpp" #endif // ASIO_SPAWN_HPP ================================================ FILE: src/third_party/asio/ssl/context.hpp ================================================ // // ssl/context.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_CONTEXT_HPP #define ASIO_SSL_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/buffer.hpp" #include "asio/io_context.hpp" #include "asio/ssl/context_base.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/ssl/detail/openssl_init.hpp" #include "asio/ssl/detail/password_callback.hpp" #include "asio/ssl/detail/verify_callback.hpp" #include "asio/ssl/verify_mode.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { class context : public context_base, private noncopyable { public: /// The native handle type of the SSL context. typedef SSL_CTX* native_handle_type; /// Constructor. ASIO_DECL explicit context(method m); #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a context from another. /** * This constructor moves an SSL context from one object to another. * * @param other The other context object from which the move will occur. * * @note Following the move, the following operations only are valid for the * moved-from object: * @li Destruction. * @li As a target for move-assignment. */ ASIO_DECL context(context&& other); /// Move-assign a context from another. /** * This assignment operator moves an SSL context from one object to another. * * @param other The other context object from which the move will occur. * * @note Following the move, the following operations only are valid for the * moved-from object: * @li Destruction. * @li As a target for move-assignment. */ ASIO_DECL context& operator=(context&& other); #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ASIO_DECL ~context(); /// Get the underlying implementation in the native type. /** * This function may be used to obtain the underlying implementation of the * context. This is intended to allow access to context functionality that is * not otherwise provided. */ ASIO_DECL native_handle_type native_handle(); /// Clear options on the context. /** * This function may be used to configure the SSL options used by the context. * * @param o A bitmask of options. The available option values are defined in * the context_base class. The specified options, if currently enabled on the * context, are cleared. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_clear_options. */ ASIO_DECL void clear_options(options o); /// Clear options on the context. /** * This function may be used to configure the SSL options used by the context. * * @param o A bitmask of options. The available option values are defined in * the context_base class. The specified options, if currently enabled on the * context, are cleared. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_clear_options. */ ASIO_DECL ASIO_SYNC_OP_VOID clear_options(options o, asio::error_code& ec); /// Set options on the context. /** * This function may be used to configure the SSL options used by the context. * * @param o A bitmask of options. The available option values are defined in * the context_base class. The options are bitwise-ored with any existing * value for the options. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_options. */ ASIO_DECL void set_options(options o); /// Set options on the context. /** * This function may be used to configure the SSL options used by the context. * * @param o A bitmask of options. The available option values are defined in * the context_base class. The options are bitwise-ored with any existing * value for the options. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_options. */ ASIO_DECL ASIO_SYNC_OP_VOID set_options(options o, asio::error_code& ec); /// Set the peer verification mode. /** * This function may be used to configure the peer verification mode used by * the context. * * @param v A bitmask of peer verification modes. See @ref verify_mode for * available values. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_verify. */ ASIO_DECL void set_verify_mode(verify_mode v); /// Set the peer verification mode. /** * This function may be used to configure the peer verification mode used by * the context. * * @param v A bitmask of peer verification modes. See @ref verify_mode for * available values. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_verify. */ ASIO_DECL ASIO_SYNC_OP_VOID set_verify_mode( verify_mode v, asio::error_code& ec); /// Set the peer verification depth. /** * This function may be used to configure the maximum verification depth * allowed by the context. * * @param depth Maximum depth for the certificate chain verification that * shall be allowed. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_verify_depth. */ ASIO_DECL void set_verify_depth(int depth); /// Set the peer verification depth. /** * This function may be used to configure the maximum verification depth * allowed by the context. * * @param depth Maximum depth for the certificate chain verification that * shall be allowed. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_verify_depth. */ ASIO_DECL ASIO_SYNC_OP_VOID set_verify_depth( int depth, asio::error_code& ec); /// Set the callback used to verify peer certificates. /** * This function is used to specify a callback function that will be called * by the implementation when it needs to verify a peer certificate. * * @param callback The function object to be used for verifying a certificate. * The function signature of the handler must be: * @code bool verify_callback( * bool preverified, // True if the certificate passed pre-verification. * verify_context& ctx // The peer certificate and other context. * ); @endcode * The return value of the callback is true if the certificate has passed * verification, false otherwise. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_verify. */ template void set_verify_callback(VerifyCallback callback); /// Set the callback used to verify peer certificates. /** * This function is used to specify a callback function that will be called * by the implementation when it needs to verify a peer certificate. * * @param callback The function object to be used for verifying a certificate. * The function signature of the handler must be: * @code bool verify_callback( * bool preverified, // True if the certificate passed pre-verification. * verify_context& ctx // The peer certificate and other context. * ); @endcode * The return value of the callback is true if the certificate has passed * verification, false otherwise. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_verify. */ template ASIO_SYNC_OP_VOID set_verify_callback(VerifyCallback callback, asio::error_code& ec); /// Load a certification authority file for performing verification. /** * This function is used to load one or more trusted certification authorities * from a file. * * @param filename The name of a file containing certification authority * certificates in PEM format. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_load_verify_locations. */ ASIO_DECL void load_verify_file(const std::string& filename); /// Load a certification authority file for performing verification. /** * This function is used to load the certificates for one or more trusted * certification authorities from a file. * * @param filename The name of a file containing certification authority * certificates in PEM format. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_load_verify_locations. */ ASIO_DECL ASIO_SYNC_OP_VOID load_verify_file( const std::string& filename, asio::error_code& ec); /// Add certification authority for performing verification. /** * This function is used to add one trusted certification authority * from a memory buffer. * * @param ca The buffer containing the certification authority certificate. * The certificate must use the PEM format. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_get_cert_store and @c X509_STORE_add_cert. */ ASIO_DECL void add_certificate_authority(const const_buffer& ca); /// Add certification authority for performing verification. /** * This function is used to add one trusted certification authority * from a memory buffer. * * @param ca The buffer containing the certification authority certificate. * The certificate must use the PEM format. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_get_cert_store and @c X509_STORE_add_cert. */ ASIO_DECL ASIO_SYNC_OP_VOID add_certificate_authority( const const_buffer& ca, asio::error_code& ec); /// Configures the context to use the default directories for finding /// certification authority certificates. /** * This function specifies that the context should use the default, * system-dependent directories for locating certification authority * certificates. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_default_verify_paths. */ ASIO_DECL void set_default_verify_paths(); /// Configures the context to use the default directories for finding /// certification authority certificates. /** * This function specifies that the context should use the default, * system-dependent directories for locating certification authority * certificates. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_default_verify_paths. */ ASIO_DECL ASIO_SYNC_OP_VOID set_default_verify_paths( asio::error_code& ec); /// Add a directory containing certificate authority files to be used for /// performing verification. /** * This function is used to specify the name of a directory containing * certification authority certificates. Each file in the directory must * contain a single certificate. The files must be named using the subject * name's hash and an extension of ".0". * * @param path The name of a directory containing the certificates. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_load_verify_locations. */ ASIO_DECL void add_verify_path(const std::string& path); /// Add a directory containing certificate authority files to be used for /// performing verification. /** * This function is used to specify the name of a directory containing * certification authority certificates. Each file in the directory must * contain a single certificate. The files must be named using the subject * name's hash and an extension of ".0". * * @param path The name of a directory containing the certificates. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_load_verify_locations. */ ASIO_DECL ASIO_SYNC_OP_VOID add_verify_path( const std::string& path, asio::error_code& ec); /// Use a certificate from a memory buffer. /** * This function is used to load a certificate into the context from a buffer. * * @param certificate The buffer containing the certificate. * * @param format The certificate format (ASN.1 or PEM). * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_certificate or SSL_CTX_use_certificate_ASN1. */ ASIO_DECL void use_certificate( const const_buffer& certificate, file_format format); /// Use a certificate from a memory buffer. /** * This function is used to load a certificate into the context from a buffer. * * @param certificate The buffer containing the certificate. * * @param format The certificate format (ASN.1 or PEM). * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_certificate or SSL_CTX_use_certificate_ASN1. */ ASIO_DECL ASIO_SYNC_OP_VOID use_certificate( const const_buffer& certificate, file_format format, asio::error_code& ec); /// Use a certificate from a file. /** * This function is used to load a certificate into the context from a file. * * @param filename The name of the file containing the certificate. * * @param format The file format (ASN.1 or PEM). * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_certificate_file. */ ASIO_DECL void use_certificate_file( const std::string& filename, file_format format); /// Use a certificate from a file. /** * This function is used to load a certificate into the context from a file. * * @param filename The name of the file containing the certificate. * * @param format The file format (ASN.1 or PEM). * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_certificate_file. */ ASIO_DECL ASIO_SYNC_OP_VOID use_certificate_file( const std::string& filename, file_format format, asio::error_code& ec); /// Use a certificate chain from a memory buffer. /** * This function is used to load a certificate chain into the context from a * buffer. * * @param chain The buffer containing the certificate chain. The certificate * chain must use the PEM format. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_certificate and SSL_CTX_add_extra_chain_cert. */ ASIO_DECL void use_certificate_chain(const const_buffer& chain); /// Use a certificate chain from a memory buffer. /** * This function is used to load a certificate chain into the context from a * buffer. * * @param chain The buffer containing the certificate chain. The certificate * chain must use the PEM format. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_certificate and SSL_CTX_add_extra_chain_cert. */ ASIO_DECL ASIO_SYNC_OP_VOID use_certificate_chain( const const_buffer& chain, asio::error_code& ec); /// Use a certificate chain from a file. /** * This function is used to load a certificate chain into the context from a * file. * * @param filename The name of the file containing the certificate. The file * must use the PEM format. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_certificate_chain_file. */ ASIO_DECL void use_certificate_chain_file(const std::string& filename); /// Use a certificate chain from a file. /** * This function is used to load a certificate chain into the context from a * file. * * @param filename The name of the file containing the certificate. The file * must use the PEM format. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_certificate_chain_file. */ ASIO_DECL ASIO_SYNC_OP_VOID use_certificate_chain_file( const std::string& filename, asio::error_code& ec); /// Use a private key from a memory buffer. /** * This function is used to load a private key into the context from a buffer. * * @param private_key The buffer containing the private key. * * @param format The private key format (ASN.1 or PEM). * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_PrivateKey or SSL_CTX_use_PrivateKey_ASN1. */ ASIO_DECL void use_private_key( const const_buffer& private_key, file_format format); /// Use a private key from a memory buffer. /** * This function is used to load a private key into the context from a buffer. * * @param private_key The buffer containing the private key. * * @param format The private key format (ASN.1 or PEM). * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_PrivateKey or SSL_CTX_use_PrivateKey_ASN1. */ ASIO_DECL ASIO_SYNC_OP_VOID use_private_key( const const_buffer& private_key, file_format format, asio::error_code& ec); /// Use a private key from a file. /** * This function is used to load a private key into the context from a file. * * @param filename The name of the file containing the private key. * * @param format The file format (ASN.1 or PEM). * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_PrivateKey_file. */ ASIO_DECL void use_private_key_file( const std::string& filename, file_format format); /// Use a private key from a file. /** * This function is used to load a private key into the context from a file. * * @param filename The name of the file containing the private key. * * @param format The file format (ASN.1 or PEM). * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_PrivateKey_file. */ ASIO_DECL ASIO_SYNC_OP_VOID use_private_key_file( const std::string& filename, file_format format, asio::error_code& ec); /// Use an RSA private key from a memory buffer. /** * This function is used to load an RSA private key into the context from a * buffer. * * @param private_key The buffer containing the RSA private key. * * @param format The private key format (ASN.1 or PEM). * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_RSAPrivateKey or SSL_CTX_use_RSAPrivateKey_ASN1. */ ASIO_DECL void use_rsa_private_key( const const_buffer& private_key, file_format format); /// Use an RSA private key from a memory buffer. /** * This function is used to load an RSA private key into the context from a * buffer. * * @param private_key The buffer containing the RSA private key. * * @param format The private key format (ASN.1 or PEM). * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_RSAPrivateKey or SSL_CTX_use_RSAPrivateKey_ASN1. */ ASIO_DECL ASIO_SYNC_OP_VOID use_rsa_private_key( const const_buffer& private_key, file_format format, asio::error_code& ec); /// Use an RSA private key from a file. /** * This function is used to load an RSA private key into the context from a * file. * * @param filename The name of the file containing the RSA private key. * * @param format The file format (ASN.1 or PEM). * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_use_RSAPrivateKey_file. */ ASIO_DECL void use_rsa_private_key_file( const std::string& filename, file_format format); /// Use an RSA private key from a file. /** * This function is used to load an RSA private key into the context from a * file. * * @param filename The name of the file containing the RSA private key. * * @param format The file format (ASN.1 or PEM). * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_use_RSAPrivateKey_file. */ ASIO_DECL ASIO_SYNC_OP_VOID use_rsa_private_key_file( const std::string& filename, file_format format, asio::error_code& ec); /// Use the specified memory buffer to obtain the temporary Diffie-Hellman /// parameters. /** * This function is used to load Diffie-Hellman parameters into the context * from a buffer. * * @param dh The memory buffer containing the Diffie-Hellman parameters. The * buffer must use the PEM format. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_tmp_dh. */ ASIO_DECL void use_tmp_dh(const const_buffer& dh); /// Use the specified memory buffer to obtain the temporary Diffie-Hellman /// parameters. /** * This function is used to load Diffie-Hellman parameters into the context * from a buffer. * * @param dh The memory buffer containing the Diffie-Hellman parameters. The * buffer must use the PEM format. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_tmp_dh. */ ASIO_DECL ASIO_SYNC_OP_VOID use_tmp_dh( const const_buffer& dh, asio::error_code& ec); /// Use the specified file to obtain the temporary Diffie-Hellman parameters. /** * This function is used to load Diffie-Hellman parameters into the context * from a file. * * @param filename The name of the file containing the Diffie-Hellman * parameters. The file must use the PEM format. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_tmp_dh. */ ASIO_DECL void use_tmp_dh_file(const std::string& filename); /// Use the specified file to obtain the temporary Diffie-Hellman parameters. /** * This function is used to load Diffie-Hellman parameters into the context * from a file. * * @param filename The name of the file containing the Diffie-Hellman * parameters. The file must use the PEM format. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_tmp_dh. */ ASIO_DECL ASIO_SYNC_OP_VOID use_tmp_dh_file( const std::string& filename, asio::error_code& ec); /// Set the password callback. /** * This function is used to specify a callback function to obtain password * information about an encrypted key in PEM format. * * @param callback The function object to be used for obtaining the password. * The function signature of the handler must be: * @code std::string password_callback( * std::size_t max_length, // The maximum size for a password. * password_purpose purpose // Whether password is for reading or writing. * ); @endcode * The return value of the callback is a string containing the password. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_CTX_set_default_passwd_cb. */ template void set_password_callback(PasswordCallback callback); /// Set the password callback. /** * This function is used to specify a callback function to obtain password * information about an encrypted key in PEM format. * * @param callback The function object to be used for obtaining the password. * The function signature of the handler must be: * @code std::string password_callback( * std::size_t max_length, // The maximum size for a password. * password_purpose purpose // Whether password is for reading or writing. * ); @endcode * The return value of the callback is a string containing the password. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_CTX_set_default_passwd_cb. */ template ASIO_SYNC_OP_VOID set_password_callback(PasswordCallback callback, asio::error_code& ec); private: struct bio_cleanup; struct x509_cleanup; struct evp_pkey_cleanup; struct rsa_cleanup; struct dh_cleanup; // Helper function used to set a peer certificate verification callback. ASIO_DECL ASIO_SYNC_OP_VOID do_set_verify_callback( detail::verify_callback_base* callback, asio::error_code& ec); // Callback used when the SSL implementation wants to verify a certificate. ASIO_DECL static int verify_callback_function( int preverified, X509_STORE_CTX* ctx); // Helper function used to set a password callback. ASIO_DECL ASIO_SYNC_OP_VOID do_set_password_callback( detail::password_callback_base* callback, asio::error_code& ec); // Callback used when the SSL implementation wants a password. ASIO_DECL static int password_callback_function( char* buf, int size, int purpose, void* data); // Helper function to set the temporary Diffie-Hellman parameters from a BIO. ASIO_DECL ASIO_SYNC_OP_VOID do_use_tmp_dh( BIO* bio, asio::error_code& ec); // Helper function to make a BIO from a memory buffer. ASIO_DECL BIO* make_buffer_bio(const const_buffer& b); // The underlying native implementation. native_handle_type handle_; // Ensure openssl is initialised. asio::ssl::detail::openssl_init<> init_; }; } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/ssl/impl/context.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ssl/impl/context.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_SSL_CONTEXT_HPP ================================================ FILE: src/third_party/asio/ssl/context_base.hpp ================================================ // // ssl/context_base.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_CONTEXT_BASE_HPP #define ASIO_SSL_CONTEXT_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { /// The context_base class is used as a base for the basic_context class /// template so that we have a common place to define various enums. class context_base { public: /// Different methods supported by a context. enum method { /// Generic SSL version 2. sslv2, /// SSL version 2 client. sslv2_client, /// SSL version 2 server. sslv2_server, /// Generic SSL version 3. sslv3, /// SSL version 3 client. sslv3_client, /// SSL version 3 server. sslv3_server, /// Generic TLS version 1. tlsv1, /// TLS version 1 client. tlsv1_client, /// TLS version 1 server. tlsv1_server, /// Generic SSL/TLS. sslv23, /// SSL/TLS client. sslv23_client, /// SSL/TLS server. sslv23_server, /// Generic TLS version 1.1. tlsv11, /// TLS version 1.1 client. tlsv11_client, /// TLS version 1.1 server. tlsv11_server, /// Generic TLS version 1.2. tlsv12, /// TLS version 1.2 client. tlsv12_client, /// TLS version 1.2 server. tlsv12_server, /// Generic TLS version 1.3. tlsv13, /// TLS version 1.3 client. tlsv13_client, /// TLS version 1.3 server. tlsv13_server, /// Generic TLS. tls, /// TLS client. tls_client, /// TLS server. tls_server }; /// Bitmask type for SSL options. typedef long options; #if defined(GENERATING_DOCUMENTATION) /// Implement various bug workarounds. static const long default_workarounds = implementation_defined; /// Always create a new key when using tmp_dh parameters. static const long single_dh_use = implementation_defined; /// Disable SSL v2. static const long no_sslv2 = implementation_defined; /// Disable SSL v3. static const long no_sslv3 = implementation_defined; /// Disable TLS v1. static const long no_tlsv1 = implementation_defined; /// Disable TLS v1.1. static const long no_tlsv1_1 = implementation_defined; /// Disable TLS v1.2. static const long no_tlsv1_2 = implementation_defined; /// Disable TLS v1.3. static const long no_tlsv1_3 = implementation_defined; /// Disable compression. Compression is disabled by default. static const long no_compression = implementation_defined; #else ASIO_STATIC_CONSTANT(long, default_workarounds = SSL_OP_ALL); ASIO_STATIC_CONSTANT(long, single_dh_use = SSL_OP_SINGLE_DH_USE); ASIO_STATIC_CONSTANT(long, no_sslv2 = SSL_OP_NO_SSLv2); ASIO_STATIC_CONSTANT(long, no_sslv3 = SSL_OP_NO_SSLv3); ASIO_STATIC_CONSTANT(long, no_tlsv1 = SSL_OP_NO_TLSv1); # if defined(SSL_OP_NO_TLSv1_1) ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = SSL_OP_NO_TLSv1_1); # else // defined(SSL_OP_NO_TLSv1_1) ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = 0x10000000L); # endif // defined(SSL_OP_NO_TLSv1_1) # if defined(SSL_OP_NO_TLSv1_2) ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = SSL_OP_NO_TLSv1_2); # else // defined(SSL_OP_NO_TLSv1_2) ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = 0x08000000L); # endif // defined(SSL_OP_NO_TLSv1_2) # if defined(SSL_OP_NO_TLSv1_3) ASIO_STATIC_CONSTANT(long, no_tlsv1_3 = SSL_OP_NO_TLSv1_3); # else // defined(SSL_OP_NO_TLSv1_3) ASIO_STATIC_CONSTANT(long, no_tlsv1_3 = 0x20000000L); # endif // defined(SSL_OP_NO_TLSv1_3) # if defined(SSL_OP_NO_COMPRESSION) ASIO_STATIC_CONSTANT(long, no_compression = SSL_OP_NO_COMPRESSION); # else // defined(SSL_OP_NO_COMPRESSION) ASIO_STATIC_CONSTANT(long, no_compression = 0x20000L); # endif // defined(SSL_OP_NO_COMPRESSION) #endif /// File format types. enum file_format { /// ASN.1 file. asn1, /// PEM file. pem }; #if !defined(GENERATING_DOCUMENTATION) // The following types and constants are preserved for backward compatibility. // New programs should use the equivalents of the same names that are defined // in the asio::ssl namespace. typedef int verify_mode; ASIO_STATIC_CONSTANT(int, verify_none = SSL_VERIFY_NONE); ASIO_STATIC_CONSTANT(int, verify_peer = SSL_VERIFY_PEER); ASIO_STATIC_CONSTANT(int, verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT); ASIO_STATIC_CONSTANT(int, verify_client_once = SSL_VERIFY_CLIENT_ONCE); #endif /// Purpose of PEM password. enum password_purpose { /// The password is needed for reading/decryption. for_reading, /// The password is needed for writing/encryption. for_writing }; protected: /// Protected destructor to prevent deletion through this type. ~context_base() { } }; } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_CONTEXT_BASE_HPP ================================================ FILE: src/third_party/asio/ssl/detail/buffered_handshake_op.hpp ================================================ // // ssl/detail/buffered_handshake_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP #define ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/detail/engine.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { template class buffered_handshake_op { public: buffered_handshake_op(stream_base::handshake_type type, const ConstBufferSequence& buffers) : type_(type), buffers_(buffers), total_buffer_size_(asio::buffer_size(buffers_)) { } engine::want operator()(engine& eng, asio::error_code& ec, std::size_t& bytes_transferred) const { return this->process(eng, ec, bytes_transferred, asio::buffer_sequence_begin(buffers_), asio::buffer_sequence_end(buffers_)); } template void call_handler(Handler& handler, const asio::error_code& ec, const std::size_t& bytes_transferred) const { handler(ec, bytes_transferred); } private: template engine::want process(engine& eng, asio::error_code& ec, std::size_t& bytes_transferred, Iterator begin, Iterator end) const { Iterator iter = begin; std::size_t accumulated_size = 0; for (;;) { engine::want want = eng.handshake(type_, ec); if (want != engine::want_input_and_retry || bytes_transferred == total_buffer_size_) return want; // Find the next buffer piece to be fed to the engine. while (iter != end) { const_buffer buffer(*iter); // Skip over any buffers which have already been consumed by the engine. if (bytes_transferred >= accumulated_size + buffer.size()) { accumulated_size += buffer.size(); ++iter; continue; } // The current buffer may have been partially consumed by the engine on // a previous iteration. If so, adjust the buffer to point to the // unused portion. if (bytes_transferred > accumulated_size) buffer = buffer + (bytes_transferred - accumulated_size); // Pass the buffer to the engine, and update the bytes transferred to // reflect the total number of bytes consumed so far. bytes_transferred += buffer.size(); buffer = eng.put_input(buffer); bytes_transferred -= buffer.size(); break; } } } stream_base::handshake_type type_; ConstBufferSequence buffers_; std::size_t total_buffer_size_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP ================================================ FILE: src/third_party/asio/ssl/detail/engine.hpp ================================================ // // ssl/detail/engine.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_ENGINE_HPP #define ASIO_SSL_DETAIL_ENGINE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/buffer.hpp" #include "asio/detail/static_mutex.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/ssl/detail/verify_callback.hpp" #include "asio/ssl/stream_base.hpp" #include "asio/ssl/verify_mode.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { class engine { public: enum want { // Returned by functions to indicate that the engine wants input. The input // buffer should be updated to point to the data. The engine then needs to // be called again to retry the operation. want_input_and_retry = -2, // Returned by functions to indicate that the engine wants to write output. // The output buffer points to the data to be written. The engine then // needs to be called again to retry the operation. want_output_and_retry = -1, // Returned by functions to indicate that the engine doesn't need input or // output. want_nothing = 0, // Returned by functions to indicate that the engine wants to write output. // The output buffer points to the data to be written. After that the // operation is complete, and the engine does not need to be called again. want_output = 1 }; // Construct a new engine for the specified context. ASIO_DECL explicit engine(SSL_CTX* context); // Destructor. ASIO_DECL ~engine(); // Get the underlying implementation in the native type. ASIO_DECL SSL* native_handle(); // Set the peer verification mode. ASIO_DECL asio::error_code set_verify_mode( verify_mode v, asio::error_code& ec); // Set the peer verification depth. ASIO_DECL asio::error_code set_verify_depth( int depth, asio::error_code& ec); // Set a peer certificate verification callback. ASIO_DECL asio::error_code set_verify_callback( verify_callback_base* callback, asio::error_code& ec); // Perform an SSL handshake using either SSL_connect (client-side) or // SSL_accept (server-side). ASIO_DECL want handshake( stream_base::handshake_type type, asio::error_code& ec); // Perform a graceful shutdown of the SSL session. ASIO_DECL want shutdown(asio::error_code& ec); // Write bytes to the SSL session. ASIO_DECL want write(const asio::const_buffer& data, asio::error_code& ec, std::size_t& bytes_transferred); // Read bytes from the SSL session. ASIO_DECL want read(const asio::mutable_buffer& data, asio::error_code& ec, std::size_t& bytes_transferred); // Get output data to be written to the transport. ASIO_DECL asio::mutable_buffer get_output( const asio::mutable_buffer& data); // Put input data that was read from the transport. ASIO_DECL asio::const_buffer put_input( const asio::const_buffer& data); // Map an error::eof code returned by the underlying transport according to // the type and state of the SSL session. Returns a const reference to the // error code object, suitable for passing to a completion handler. ASIO_DECL const asio::error_code& map_error_code( asio::error_code& ec) const; private: // Disallow copying and assignment. engine(const engine&); engine& operator=(const engine&); // Callback used when the SSL implementation wants to verify a certificate. ASIO_DECL static int verify_callback_function( int preverified, X509_STORE_CTX* ctx); #if (OPENSSL_VERSION_NUMBER < 0x10000000L) // The SSL_accept function may not be thread safe. This mutex is used to // protect all calls to the SSL_accept function. ASIO_DECL static asio::detail::static_mutex& accept_mutex(); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) // Perform one operation. Returns >= 0 on success or error, want_read if the // operation needs more input, or want_write if it needs to write some output // before the operation can complete. ASIO_DECL want perform(int (engine::* op)(void*, std::size_t), void* data, std::size_t length, asio::error_code& ec, std::size_t* bytes_transferred); // Adapt the SSL_accept function to the signature needed for perform(). ASIO_DECL int do_accept(void*, std::size_t); // Adapt the SSL_connect function to the signature needed for perform(). ASIO_DECL int do_connect(void*, std::size_t); // Adapt the SSL_shutdown function to the signature needed for perform(). ASIO_DECL int do_shutdown(void*, std::size_t); // Adapt the SSL_read function to the signature needed for perform(). ASIO_DECL int do_read(void* data, std::size_t length); // Adapt the SSL_write function to the signature needed for perform(). ASIO_DECL int do_write(void* data, std::size_t length); SSL* ssl_; BIO* ext_bio_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ssl/detail/impl/engine.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_SSL_DETAIL_ENGINE_HPP ================================================ FILE: src/third_party/asio/ssl/detail/handshake_op.hpp ================================================ // // ssl/detail/handshake_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP #define ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/detail/engine.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { class handshake_op { public: handshake_op(stream_base::handshake_type type) : type_(type) { } engine::want operator()(engine& eng, asio::error_code& ec, std::size_t& bytes_transferred) const { bytes_transferred = 0; return eng.handshake(type_, ec); } template void call_handler(Handler& handler, const asio::error_code& ec, const std::size_t&) const { handler(ec); } private: stream_base::handshake_type type_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP ================================================ FILE: src/third_party/asio/ssl/detail/impl/engine.ipp ================================================ // // ssl/detail/impl/engine.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_IMPL_ENGINE_IPP #define ASIO_SSL_DETAIL_IMPL_ENGINE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/ssl/detail/engine.hpp" #include "asio/ssl/error.hpp" #include "asio/ssl/verify_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { engine::engine(SSL_CTX* context) : ssl_(::SSL_new(context)) { if (!ssl_) { asio::error_code ec( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); asio::detail::throw_error(ec, "engine"); } #if (OPENSSL_VERSION_NUMBER < 0x10000000L) accept_mutex().init(); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) ::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE); ::SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); #if defined(SSL_MODE_RELEASE_BUFFERS) ::SSL_set_mode(ssl_, SSL_MODE_RELEASE_BUFFERS); #endif // defined(SSL_MODE_RELEASE_BUFFERS) ::BIO* int_bio = 0; ::BIO_new_bio_pair(&int_bio, 0, &ext_bio_, 0); ::SSL_set_bio(ssl_, int_bio, int_bio); } engine::~engine() { if (SSL_get_app_data(ssl_)) { delete static_cast(SSL_get_app_data(ssl_)); SSL_set_app_data(ssl_, 0); } ::BIO_free(ext_bio_); ::SSL_free(ssl_); } SSL* engine::native_handle() { return ssl_; } asio::error_code engine::set_verify_mode( verify_mode v, asio::error_code& ec) { ::SSL_set_verify(ssl_, v, ::SSL_get_verify_callback(ssl_)); ec = asio::error_code(); return ec; } asio::error_code engine::set_verify_depth( int depth, asio::error_code& ec) { ::SSL_set_verify_depth(ssl_, depth); ec = asio::error_code(); return ec; } asio::error_code engine::set_verify_callback( verify_callback_base* callback, asio::error_code& ec) { if (SSL_get_app_data(ssl_)) delete static_cast(SSL_get_app_data(ssl_)); SSL_set_app_data(ssl_, callback); ::SSL_set_verify(ssl_, ::SSL_get_verify_mode(ssl_), &engine::verify_callback_function); ec = asio::error_code(); return ec; } int engine::verify_callback_function(int preverified, X509_STORE_CTX* ctx) { if (ctx) { if (SSL* ssl = static_cast( ::X509_STORE_CTX_get_ex_data( ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx()))) { if (SSL_get_app_data(ssl)) { verify_callback_base* callback = static_cast( SSL_get_app_data(ssl)); verify_context verify_ctx(ctx); return callback->call(preverified != 0, verify_ctx) ? 1 : 0; } } } return 0; } engine::want engine::handshake( stream_base::handshake_type type, asio::error_code& ec) { return perform((type == asio::ssl::stream_base::client) ? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0); } engine::want engine::shutdown(asio::error_code& ec) { return perform(&engine::do_shutdown, 0, 0, ec, 0); } engine::want engine::write(const asio::const_buffer& data, asio::error_code& ec, std::size_t& bytes_transferred) { if (data.size() == 0) { ec = asio::error_code(); return engine::want_nothing; } return perform(&engine::do_write, const_cast(data.data()), data.size(), ec, &bytes_transferred); } engine::want engine::read(const asio::mutable_buffer& data, asio::error_code& ec, std::size_t& bytes_transferred) { if (data.size() == 0) { ec = asio::error_code(); return engine::want_nothing; } return perform(&engine::do_read, data.data(), data.size(), ec, &bytes_transferred); } asio::mutable_buffer engine::get_output( const asio::mutable_buffer& data) { int length = ::BIO_read(ext_bio_, data.data(), static_cast(data.size())); return asio::buffer(data, length > 0 ? static_cast(length) : 0); } asio::const_buffer engine::put_input( const asio::const_buffer& data) { int length = ::BIO_write(ext_bio_, data.data(), static_cast(data.size())); return asio::buffer(data + (length > 0 ? static_cast(length) : 0)); } const asio::error_code& engine::map_error_code( asio::error_code& ec) const { // We only want to map the error::eof code. if (ec != asio::error::eof) return ec; // If there's data yet to be read, it's an error. if (BIO_wpending(ext_bio_)) { ec = asio::ssl::error::stream_truncated; return ec; } // SSL v2 doesn't provide a protocol-level shutdown, so an eof on the // underlying transport is passed through. #if (OPENSSL_VERSION_NUMBER < 0x10100000L) if (SSL_version(ssl_) == SSL2_VERSION) return ec; #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) // Otherwise, the peer should have negotiated a proper shutdown. if ((::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) == 0) { ec = asio::ssl::error::stream_truncated; } return ec; } #if (OPENSSL_VERSION_NUMBER < 0x10000000L) asio::detail::static_mutex& engine::accept_mutex() { static asio::detail::static_mutex mutex = ASIO_STATIC_MUTEX_INIT; return mutex; } #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) engine::want engine::perform(int (engine::* op)(void*, std::size_t), void* data, std::size_t length, asio::error_code& ec, std::size_t* bytes_transferred) { std::size_t pending_output_before = ::BIO_ctrl_pending(ext_bio_); ::ERR_clear_error(); int result = (this->*op)(data, length); int ssl_error = ::SSL_get_error(ssl_, result); int sys_error = static_cast(::ERR_get_error()); std::size_t pending_output_after = ::BIO_ctrl_pending(ext_bio_); if (ssl_error == SSL_ERROR_SSL) { ec = asio::error_code(sys_error, asio::error::get_ssl_category()); return pending_output_after > pending_output_before ? want_output : want_nothing; } if (ssl_error == SSL_ERROR_SYSCALL) { if (sys_error == 0) { ec = asio::ssl::error::unspecified_system_error; } else { ec = asio::error_code(sys_error, asio::error::get_ssl_category()); } return pending_output_after > pending_output_before ? want_output : want_nothing; } if (result > 0 && bytes_transferred) *bytes_transferred = static_cast(result); if (ssl_error == SSL_ERROR_WANT_WRITE) { ec = asio::error_code(); return want_output_and_retry; } else if (pending_output_after > pending_output_before) { ec = asio::error_code(); return result > 0 ? want_output : want_output_and_retry; } else if (ssl_error == SSL_ERROR_WANT_READ) { ec = asio::error_code(); return want_input_and_retry; } else if (ssl_error == SSL_ERROR_ZERO_RETURN) { ec = asio::error::eof; return want_nothing; } else if (ssl_error == SSL_ERROR_NONE) { ec = asio::error_code(); return want_nothing; } else { ec = asio::ssl::error::unexpected_result; return want_nothing; } } int engine::do_accept(void*, std::size_t) { #if (OPENSSL_VERSION_NUMBER < 0x10000000L) asio::detail::static_mutex::scoped_lock lock(accept_mutex()); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) return ::SSL_accept(ssl_); } int engine::do_connect(void*, std::size_t) { return ::SSL_connect(ssl_); } int engine::do_shutdown(void*, std::size_t) { int result = ::SSL_shutdown(ssl_); if (result == 0) result = ::SSL_shutdown(ssl_); return result; } int engine::do_read(void* data, std::size_t length) { return ::SSL_read(ssl_, data, length < INT_MAX ? static_cast(length) : INT_MAX); } int engine::do_write(void* data, std::size_t length) { return ::SSL_write(ssl_, data, length < INT_MAX ? static_cast(length) : INT_MAX); } } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_IMPL_ENGINE_IPP ================================================ FILE: src/third_party/asio/ssl/detail/impl/openssl_init.ipp ================================================ // // ssl/detail/impl/openssl_init.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com // Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP #define ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/assert.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/tss_ptr.hpp" #include "asio/ssl/detail/openssl_init.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { class openssl_init_base::do_init { public: do_init() { #if (OPENSSL_VERSION_NUMBER < 0x10100000L) ::SSL_library_init(); ::SSL_load_error_strings(); ::OpenSSL_add_all_algorithms(); mutexes_.resize(::CRYPTO_num_locks()); for (size_t i = 0; i < mutexes_.size(); ++i) mutexes_[i].reset(new asio::detail::mutex); ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func); #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) #if (OPENSSL_VERSION_NUMBER < 0x10000000L) ::CRYPTO_set_id_callback(&do_init::openssl_id_func); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) #if !defined(SSL_OP_NO_COMPRESSION) \ && (OPENSSL_VERSION_NUMBER >= 0x00908000L) null_compression_methods_ = sk_SSL_COMP_new_null(); #endif // !defined(SSL_OP_NO_COMPRESSION) // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) } ~do_init() { #if !defined(SSL_OP_NO_COMPRESSION) \ && (OPENSSL_VERSION_NUMBER >= 0x00908000L) sk_SSL_COMP_free(null_compression_methods_); #endif // !defined(SSL_OP_NO_COMPRESSION) // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) #if (OPENSSL_VERSION_NUMBER < 0x10000000L) ::CRYPTO_set_id_callback(0); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) ::CRYPTO_set_locking_callback(0); ::ERR_free_strings(); ::EVP_cleanup(); ::CRYPTO_cleanup_all_ex_data(); #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) #if (OPENSSL_VERSION_NUMBER < 0x10000000L) ::ERR_remove_state(0); #elif (OPENSSL_VERSION_NUMBER < 0x10100000L) ::ERR_remove_thread_state(NULL); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) #if (OPENSSL_VERSION_NUMBER >= 0x10002000L) \ && (OPENSSL_VERSION_NUMBER < 0x10100000L) \ && !defined(SSL_OP_NO_COMPRESSION) ::SSL_COMP_free_compression_methods(); #endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L) // && (OPENSSL_VERSION_NUMBER < 0x10100000L) // && !defined(SSL_OP_NO_COMPRESSION) #if !defined(OPENSSL_IS_BORINGSSL) && !defined(ASIO_USE_WOLFSSL) ::CONF_modules_unload(1); #endif // !defined(OPENSSL_IS_BORINGSSL) && !defined(ASIO_USE_WOLFSSL) #if !defined(OPENSSL_NO_ENGINE) \ && (OPENSSL_VERSION_NUMBER < 0x10100000L) ::ENGINE_cleanup(); #endif // !defined(OPENSSL_NO_ENGINE) // && (OPENSSL_VERSION_NUMBER < 0x10100000L) } #if !defined(SSL_OP_NO_COMPRESSION) \ && (OPENSSL_VERSION_NUMBER >= 0x00908000L) STACK_OF(SSL_COMP)* get_null_compression_methods() const { return null_compression_methods_; } #endif // !defined(SSL_OP_NO_COMPRESSION) // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) private: #if (OPENSSL_VERSION_NUMBER < 0x10000000L) static unsigned long openssl_id_func() { #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) return ::GetCurrentThreadId(); #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__) void* id = &errno; ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*)); return reinterpret_cast(id); #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) } #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) static void openssl_locking_func(int mode, int n, const char* /*file*/, int /*line*/) { if (mode & CRYPTO_LOCK) instance()->mutexes_[n]->lock(); else instance()->mutexes_[n]->unlock(); } // Mutexes to be used in locking callbacks. std::vector > mutexes_; #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) #if !defined(SSL_OP_NO_COMPRESSION) \ && (OPENSSL_VERSION_NUMBER >= 0x00908000L) STACK_OF(SSL_COMP)* null_compression_methods_; #endif // !defined(SSL_OP_NO_COMPRESSION) // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) }; asio::detail::shared_ptr openssl_init_base::instance() { static asio::detail::shared_ptr init(new do_init); return init; } #if !defined(SSL_OP_NO_COMPRESSION) \ && (OPENSSL_VERSION_NUMBER >= 0x00908000L) STACK_OF(SSL_COMP)* openssl_init_base::get_null_compression_methods() { return instance()->get_null_compression_methods(); } #endif // !defined(SSL_OP_NO_COMPRESSION) // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP ================================================ FILE: src/third_party/asio/ssl/detail/io.hpp ================================================ // // ssl/detail/io.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_IO_HPP #define ASIO_SSL_DETAIL_IO_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/detail/engine.hpp" #include "asio/ssl/detail/stream_core.hpp" #include "asio/write.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { template std::size_t io(Stream& next_layer, stream_core& core, const Operation& op, asio::error_code& ec) { asio::error_code io_ec; std::size_t bytes_transferred = 0; do switch (op(core.engine_, ec, bytes_transferred)) { case engine::want_input_and_retry: // If the input buffer is empty then we need to read some more data from // the underlying transport. if (core.input_.size() == 0) { core.input_ = asio::buffer(core.input_buffer_, next_layer.read_some(core.input_buffer_, io_ec)); if (!ec) ec = io_ec; } // Pass the new input data to the engine. core.input_ = core.engine_.put_input(core.input_); // Try the operation again. continue; case engine::want_output_and_retry: // Get output data from the engine and write it to the underlying // transport. asio::write(next_layer, core.engine_.get_output(core.output_buffer_), io_ec); if (!ec) ec = io_ec; // Try the operation again. continue; case engine::want_output: // Get output data from the engine and write it to the underlying // transport. asio::write(next_layer, core.engine_.get_output(core.output_buffer_), io_ec); if (!ec) ec = io_ec; // Operation is complete. Return result to caller. core.engine_.map_error_code(ec); return bytes_transferred; default: // Operation is complete. Return result to caller. core.engine_.map_error_code(ec); return bytes_transferred; } while (!ec); // Operation failed. Return result to caller. core.engine_.map_error_code(ec); return 0; } template class io_op { public: io_op(Stream& next_layer, stream_core& core, const Operation& op, Handler& handler) : next_layer_(next_layer), core_(core), op_(op), start_(0), want_(engine::want_nothing), bytes_transferred_(0), handler_(ASIO_MOVE_CAST(Handler)(handler)) { } #if defined(ASIO_HAS_MOVE) io_op(const io_op& other) : next_layer_(other.next_layer_), core_(other.core_), op_(other.op_), start_(other.start_), want_(other.want_), ec_(other.ec_), bytes_transferred_(other.bytes_transferred_), handler_(other.handler_) { } io_op(io_op&& other) : next_layer_(other.next_layer_), core_(other.core_), op_(ASIO_MOVE_CAST(Operation)(other.op_)), start_(other.start_), want_(other.want_), ec_(other.ec_), bytes_transferred_(other.bytes_transferred_), handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { } #endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred = ~std::size_t(0), int start = 0) { switch (start_ = start) { case 1: // Called after at least one async operation. do { switch (want_ = op_(core_.engine_, ec_, bytes_transferred_)) { case engine::want_input_and_retry: // If the input buffer already has data in it we can pass it to the // engine and then retry the operation immediately. if (core_.input_.size() != 0) { core_.input_ = core_.engine_.put_input(core_.input_); continue; } // The engine wants more data to be read from input. However, we // cannot allow more than one read operation at a time on the // underlying transport. The pending_read_ timer's expiry is set to // pos_infin if a read is in progress, and neg_infin otherwise. if (core_.expiry(core_.pending_read_) == core_.neg_infin()) { // Prevent other read operations from being started. core_.pending_read_.expires_at(core_.pos_infin()); // Start reading some data from the underlying transport. next_layer_.async_read_some( asio::buffer(core_.input_buffer_), ASIO_MOVE_CAST(io_op)(*this)); } else { // Wait until the current read operation completes. core_.pending_read_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); } // Yield control until asynchronous operation completes. Control // resumes at the "default:" label below. return; case engine::want_output_and_retry: case engine::want_output: // The engine wants some data to be written to the output. However, we // cannot allow more than one write operation at a time on the // underlying transport. The pending_write_ timer's expiry is set to // pos_infin if a write is in progress, and neg_infin otherwise. if (core_.expiry(core_.pending_write_) == core_.neg_infin()) { // Prevent other write operations from being started. core_.pending_write_.expires_at(core_.pos_infin()); // Start writing all the data to the underlying transport. asio::async_write(next_layer_, core_.engine_.get_output(core_.output_buffer_), ASIO_MOVE_CAST(io_op)(*this)); } else { // Wait until the current write operation completes. core_.pending_write_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); } // Yield control until asynchronous operation completes. Control // resumes at the "default:" label below. return; default: // The SSL operation is done and we can invoke the handler, but we // have to keep in mind that this function might be being called from // the async operation's initiating function. In this case we're not // allowed to call the handler directly. Instead, issue a zero-sized // read so the handler runs "as-if" posted using io_context::post(). if (start) { next_layer_.async_read_some( asio::buffer(core_.input_buffer_, 0), ASIO_MOVE_CAST(io_op)(*this)); // Yield control until asynchronous operation completes. Control // resumes at the "default:" label below. return; } else { // Continue on to run handler directly. break; } } default: if (bytes_transferred == ~std::size_t(0)) bytes_transferred = 0; // Timer cancellation, no data transferred. else if (!ec_) ec_ = ec; switch (want_) { case engine::want_input_and_retry: // Add received data to the engine's input. core_.input_ = asio::buffer( core_.input_buffer_, bytes_transferred); core_.input_ = core_.engine_.put_input(core_.input_); // Release any waiting read operations. core_.pending_read_.expires_at(core_.neg_infin()); // Try the operation again. continue; case engine::want_output_and_retry: // Release any waiting write operations. core_.pending_write_.expires_at(core_.neg_infin()); // Try the operation again. continue; case engine::want_output: // Release any waiting write operations. core_.pending_write_.expires_at(core_.neg_infin()); // Fall through to call handler. default: // Pass the result to the handler. op_.call_handler(handler_, core_.engine_.map_error_code(ec_), ec_ ? 0 : bytes_transferred_); // Our work here is done. return; } } while (!ec_); // Operation failed. Pass the result to the handler. op_.call_handler(handler_, core_.engine_.map_error_code(ec_), 0); } } //private: Stream& next_layer_; stream_core& core_; Operation op_; int start_; engine::want want_; asio::error_code ec_; std::size_t bytes_transferred_; Handler handler_; }; template inline void* asio_handler_allocate(std::size_t size, io_op* this_handler) { return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } template inline void asio_handler_deallocate(void* pointer, std::size_t size, io_op* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } template inline bool asio_handler_is_continuation( io_op* this_handler) { return this_handler->start_ == 0 ? true : asio_handler_cont_helpers::is_continuation(this_handler->handler_); } template inline void asio_handler_invoke(Function& function, io_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void asio_handler_invoke(const Function& function, io_op* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } template inline void async_io(Stream& next_layer, stream_core& core, const Operation& op, Handler& handler) { io_op( next_layer, core, op, handler)( asio::error_code(), 0, 1); } } // namespace detail } // namespace ssl template struct associated_allocator< ssl::detail::io_op, Allocator> { typedef typename associated_allocator::type type; static type get(const ssl::detail::io_op& h, const Allocator& a = Allocator()) ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; template struct associated_executor< ssl::detail::io_op, Executor> { typedef typename associated_executor::type type; static type get(const ssl::detail::io_op& h, const Executor& ex = Executor()) ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_IO_HPP ================================================ FILE: src/third_party/asio/ssl/detail/openssl_init.hpp ================================================ // // ssl/detail/openssl_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_OPENSSL_INIT_HPP #define ASIO_SSL_DETAIL_OPENSSL_INIT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { class openssl_init_base : private noncopyable { protected: // Class that performs the actual initialisation. class do_init; // Helper function to manage a do_init singleton. The static instance of the // openssl_init object ensures that this function is always called before // main, and therefore before any other threads can get started. The do_init // instance must be static in this function to ensure that it gets // initialised before any other global objects try to use it. ASIO_DECL static asio::detail::shared_ptr instance(); #if !defined(SSL_OP_NO_COMPRESSION) \ && (OPENSSL_VERSION_NUMBER >= 0x00908000L) // Get an empty stack of compression methods, to be used when disabling // compression. ASIO_DECL static STACK_OF(SSL_COMP)* get_null_compression_methods(); #endif // !defined(SSL_OP_NO_COMPRESSION) // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) }; template class openssl_init : private openssl_init_base { public: // Constructor. openssl_init() : ref_(instance()) { using namespace std; // For memmove. // Ensure openssl_init::instance_ is linked in. openssl_init* tmp = &instance_; memmove(&tmp, &tmp, sizeof(openssl_init*)); } // Destructor. ~openssl_init() { } #if !defined(SSL_OP_NO_COMPRESSION) \ && (OPENSSL_VERSION_NUMBER >= 0x00908000L) using openssl_init_base::get_null_compression_methods; #endif // !defined(SSL_OP_NO_COMPRESSION) // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) private: // Instance to force initialisation of openssl at global scope. static openssl_init instance_; // Reference to singleton do_init object to ensure that openssl does not get // cleaned up until the last user has finished with it. asio::detail::shared_ptr ref_; }; template openssl_init openssl_init::instance_; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ssl/detail/impl/openssl_init.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_SSL_DETAIL_OPENSSL_INIT_HPP ================================================ FILE: src/third_party/asio/ssl/detail/openssl_types.hpp ================================================ // // ssl/detail/openssl_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP #define ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/socket_types.hpp" #if defined(ASIO_USE_WOLFSSL) # include #endif // defined(ASIO_USE_WOLFSSL) #include #include #if !defined(OPENSSL_NO_ENGINE) # include #endif // !defined(OPENSSL_NO_ENGINE) #include #include #include #include #endif // ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP ================================================ FILE: src/third_party/asio/ssl/detail/password_callback.hpp ================================================ // // ssl/detail/password_callback.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP #define ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/ssl/context_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { class password_callback_base { public: virtual ~password_callback_base() { } virtual std::string call(std::size_t size, context_base::password_purpose purpose) = 0; }; template class password_callback : public password_callback_base { public: explicit password_callback(PasswordCallback callback) : callback_(callback) { } virtual std::string call(std::size_t size, context_base::password_purpose purpose) { return callback_(size, purpose); } private: PasswordCallback callback_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_PASSWORD_CALLBACK_HPP ================================================ FILE: src/third_party/asio/ssl/detail/read_op.hpp ================================================ // // ssl/detail/read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_READ_OP_HPP #define ASIO_SSL_DETAIL_READ_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/ssl/detail/engine.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { template class read_op { public: read_op(const MutableBufferSequence& buffers) : buffers_(buffers) { } engine::want operator()(engine& eng, asio::error_code& ec, std::size_t& bytes_transferred) const { asio::mutable_buffer buffer = asio::detail::buffer_sequence_adapter::first(buffers_); return eng.read(buffer, ec, bytes_transferred); } template void call_handler(Handler& handler, const asio::error_code& ec, const std::size_t& bytes_transferred) const { handler(ec, bytes_transferred); } private: MutableBufferSequence buffers_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_READ_OP_HPP ================================================ FILE: src/third_party/asio/ssl/detail/shutdown_op.hpp ================================================ // // ssl/detail/shutdown_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP #define ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/detail/engine.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { class shutdown_op { public: engine::want operator()(engine& eng, asio::error_code& ec, std::size_t& bytes_transferred) const { bytes_transferred = 0; return eng.shutdown(ec); } template void call_handler(Handler& handler, const asio::error_code& ec, const std::size_t&) const { if (ec == asio::error::eof) { // The engine only generates an eof when the shutdown notification has // been received from the peer. This indicates that the shutdown has // completed successfully, and thus need not be passed on to the handler. handler(asio::error_code()); } else { handler(ec); } } }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP ================================================ FILE: src/third_party/asio/ssl/detail/stream_core.hpp ================================================ // // ssl/detail/stream_core.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_STREAM_CORE_HPP #define ASIO_SSL_DETAIL_STREAM_CORE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) # include "asio/deadline_timer.hpp" #else // defined(ASIO_HAS_BOOST_DATE_TIME) # include "asio/steady_timer.hpp" #endif // defined(ASIO_HAS_BOOST_DATE_TIME) #include "asio/ssl/detail/engine.hpp" #include "asio/buffer.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { struct stream_core { // According to the OpenSSL documentation, this is the buffer size that is // sufficient to hold the largest possible TLS record. enum { max_tls_record_size = 17 * 1024 }; template stream_core(SSL_CTX* context, const Executor& ex) : engine_(context), pending_read_(ex), pending_write_(ex), output_buffer_space_(max_tls_record_size), output_buffer_(asio::buffer(output_buffer_space_)), input_buffer_space_(max_tls_record_size), input_buffer_(asio::buffer(input_buffer_space_)) { pending_read_.expires_at(neg_infin()); pending_write_.expires_at(neg_infin()); } ~stream_core() { } // The SSL engine. engine engine_; #if defined(ASIO_HAS_BOOST_DATE_TIME) // Timer used for storing queued read operations. asio::deadline_timer pending_read_; // Timer used for storing queued write operations. asio::deadline_timer pending_write_; // Helper function for obtaining a time value that always fires. static asio::deadline_timer::time_type neg_infin() { return boost::posix_time::neg_infin; } // Helper function for obtaining a time value that never fires. static asio::deadline_timer::time_type pos_infin() { return boost::posix_time::pos_infin; } // Helper function to get a timer's expiry time. static asio::deadline_timer::time_type expiry( const asio::deadline_timer& timer) { return timer.expires_at(); } #else // defined(ASIO_HAS_BOOST_DATE_TIME) // Timer used for storing queued read operations. asio::steady_timer pending_read_; // Timer used for storing queued write operations. asio::steady_timer pending_write_; // Helper function for obtaining a time value that always fires. static asio::steady_timer::time_point neg_infin() { return (asio::steady_timer::time_point::min)(); } // Helper function for obtaining a time value that never fires. static asio::steady_timer::time_point pos_infin() { return (asio::steady_timer::time_point::max)(); } // Helper function to get a timer's expiry time. static asio::steady_timer::time_point expiry( const asio::steady_timer& timer) { return timer.expiry(); } #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // Buffer space used to prepare output intended for the transport. std::vector output_buffer_space_; // A buffer that may be used to prepare output intended for the transport. const asio::mutable_buffer output_buffer_; // Buffer space used to read input intended for the engine. std::vector input_buffer_space_; // A buffer that may be used to read input intended for the engine. const asio::mutable_buffer input_buffer_; // The buffer pointing to the engine's unconsumed input. asio::const_buffer input_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_STREAM_CORE_HPP ================================================ FILE: src/third_party/asio/ssl/detail/verify_callback.hpp ================================================ // // ssl/detail/verify_callback.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP #define ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/verify_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { class verify_callback_base { public: virtual ~verify_callback_base() { } virtual bool call(bool preverified, verify_context& ctx) = 0; }; template class verify_callback : public verify_callback_base { public: explicit verify_callback(VerifyCallback callback) : callback_(callback) { } virtual bool call(bool preverified, verify_context& ctx) { return callback_(preverified, ctx); } private: VerifyCallback callback_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP ================================================ FILE: src/third_party/asio/ssl/detail/write_op.hpp ================================================ // // ssl/detail/write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_DETAIL_WRITE_OP_HPP #define ASIO_SSL_DETAIL_WRITE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/ssl/detail/engine.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { namespace detail { template class write_op { public: write_op(const ConstBufferSequence& buffers) : buffers_(buffers) { } engine::want operator()(engine& eng, asio::error_code& ec, std::size_t& bytes_transferred) const { asio::const_buffer buffer = asio::detail::buffer_sequence_adapter::first(buffers_); return eng.write(buffer, ec, bytes_transferred); } template void call_handler(Handler& handler, const asio::error_code& ec, const std::size_t& bytes_transferred) const { handler(ec, bytes_transferred); } private: ConstBufferSequence buffers_; }; } // namespace detail } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_DETAIL_WRITE_OP_HPP ================================================ FILE: src/third_party/asio/ssl/error.hpp ================================================ // // ssl/error.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_ERROR_HPP #define ASIO_SSL_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error_code.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace error { enum ssl_errors { // Error numbers are those produced by openssl. }; extern ASIO_DECL const asio::error_category& get_ssl_category(); static const asio::error_category& ssl_category ASIO_UNUSED_VARIABLE = asio::error::get_ssl_category(); } // namespace error namespace ssl { namespace error { enum stream_errors { #if defined(GENERATING_DOCUMENTATION) /// The underlying stream closed before the ssl stream gracefully shut down. stream_truncated, /// The underlying SSL library returned a system error without providing /// further information. unspecified_system_error, /// The underlying SSL library generated an unexpected result from a function /// call. unexpected_result #else // defined(GENERATING_DOCUMENTATION) # if (OPENSSL_VERSION_NUMBER < 0x10100000L) \ && !defined(OPENSSL_IS_BORINGSSL) \ && !defined(ASIO_USE_WOLFSSL) stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ), # else stream_truncated = 1, # endif unspecified_system_error = 2, unexpected_result = 3 #endif // defined(GENERATING_DOCUMENTATION) }; extern ASIO_DECL const asio::error_category& get_stream_category(); static const asio::error_category& stream_category ASIO_UNUSED_VARIABLE = asio::ssl::error::get_stream_category(); } // namespace error } // namespace ssl } // namespace asio #if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum { static const bool value = true; }; template<> struct is_error_code_enum { static const bool value = true; }; } // namespace std #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace asio { namespace error { inline asio::error_code make_error_code(ssl_errors e) { return asio::error_code( static_cast(e), get_ssl_category()); } } // namespace error namespace ssl { namespace error { inline asio::error_code make_error_code(stream_errors e) { return asio::error_code( static_cast(e), get_stream_category()); } } // namespace error } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ssl/impl/error.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_SSL_ERROR_HPP ================================================ FILE: src/third_party/asio/ssl/impl/context.hpp ================================================ // // ssl/impl/context.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com // Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_IMPL_CONTEXT_HPP #define ASIO_SSL_IMPL_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { template void context::set_verify_callback(VerifyCallback callback) { asio::error_code ec; this->set_verify_callback(callback, ec); asio::detail::throw_error(ec, "set_verify_callback"); } template ASIO_SYNC_OP_VOID context::set_verify_callback( VerifyCallback callback, asio::error_code& ec) { do_set_verify_callback( new detail::verify_callback(callback), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } template void context::set_password_callback(PasswordCallback callback) { asio::error_code ec; this->set_password_callback(callback, ec); asio::detail::throw_error(ec, "set_password_callback"); } template ASIO_SYNC_OP_VOID context::set_password_callback( PasswordCallback callback, asio::error_code& ec) { do_set_password_callback( new detail::password_callback(callback), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_IMPL_CONTEXT_HPP ================================================ FILE: src/third_party/asio/ssl/impl/context.ipp ================================================ // // ssl/impl/context.ipp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com // Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_IMPL_CONTEXT_IPP #define ASIO_SSL_IMPL_CONTEXT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "asio/ssl/context.hpp" #include "asio/ssl/error.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { struct context::bio_cleanup { BIO* p; ~bio_cleanup() { if (p) ::BIO_free(p); } }; struct context::x509_cleanup { X509* p; ~x509_cleanup() { if (p) ::X509_free(p); } }; struct context::evp_pkey_cleanup { EVP_PKEY* p; ~evp_pkey_cleanup() { if (p) ::EVP_PKEY_free(p); } }; struct context::rsa_cleanup { RSA* p; ~rsa_cleanup() { if (p) ::RSA_free(p); } }; struct context::dh_cleanup { DH* p; ~dh_cleanup() { if (p) ::DH_free(p); } }; context::context(context::method m) : handle_(0) { ::ERR_clear_error(); switch (m) { // SSL v2. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) case context::sslv2: case context::sslv2_client: case context::sslv2_server: asio::detail::throw_error( asio::error::invalid_argument, "context"); break; #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) case context::sslv2: handle_ = ::SSL_CTX_new(::SSLv2_method()); break; case context::sslv2_client: handle_ = ::SSL_CTX_new(::SSLv2_client_method()); break; case context::sslv2_server: handle_ = ::SSL_CTX_new(::SSLv2_server_method()); break; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) // SSL v3. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) case context::sslv3: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); } break; case context::sslv3_client: handle_ = ::SSL_CTX_new(::TLS_client_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); } break; case context::sslv3_server: handle_ = ::SSL_CTX_new(::TLS_server_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); } break; #elif defined(OPENSSL_NO_SSL3) case context::sslv3: case context::sslv3_client: case context::sslv3_server: asio::detail::throw_error( asio::error::invalid_argument, "context"); break; #else // defined(OPENSSL_NO_SSL3) case context::sslv3: handle_ = ::SSL_CTX_new(::SSLv3_method()); break; case context::sslv3_client: handle_ = ::SSL_CTX_new(::SSLv3_client_method()); break; case context::sslv3_server: handle_ = ::SSL_CTX_new(::SSLv3_server_method()); break; #endif // defined(OPENSSL_NO_SSL3) // TLS v1.0. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) case context::tlsv1: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); } break; case context::tlsv1_client: handle_ = ::SSL_CTX_new(::TLS_client_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); } break; case context::tlsv1_server: handle_ = ::SSL_CTX_new(::TLS_server_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); } break; #elif defined(SSL_TXT_TLSV1) case context::tlsv1: handle_ = ::SSL_CTX_new(::TLSv1_method()); break; case context::tlsv1_client: handle_ = ::SSL_CTX_new(::TLSv1_client_method()); break; case context::tlsv1_server: handle_ = ::SSL_CTX_new(::TLSv1_server_method()); break; #else // defined(SSL_TXT_TLSV1) case context::tlsv1: case context::tlsv1_client: case context::tlsv1_server: asio::detail::throw_error( asio::error::invalid_argument, "context"); break; #endif // defined(SSL_TXT_TLSV1) // TLS v1.1. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) case context::tlsv11: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); } break; case context::tlsv11_client: handle_ = ::SSL_CTX_new(::TLS_client_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); } break; case context::tlsv11_server: handle_ = ::SSL_CTX_new(::TLS_server_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); } break; #elif defined(SSL_TXT_TLSV1_1) case context::tlsv11: handle_ = ::SSL_CTX_new(::TLSv1_1_method()); break; case context::tlsv11_client: handle_ = ::SSL_CTX_new(::TLSv1_1_client_method()); break; case context::tlsv11_server: handle_ = ::SSL_CTX_new(::TLSv1_1_server_method()); break; #else // defined(SSL_TXT_TLSV1_1) case context::tlsv11: case context::tlsv11_client: case context::tlsv11_server: asio::detail::throw_error( asio::error::invalid_argument, "context"); break; #endif // defined(SSL_TXT_TLSV1_1) // TLS v1.2. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) case context::tlsv12: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); } break; case context::tlsv12_client: handle_ = ::SSL_CTX_new(::TLS_client_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); } break; case context::tlsv12_server: handle_ = ::SSL_CTX_new(::TLS_server_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); } break; #elif defined(SSL_TXT_TLSV1_2) case context::tlsv12: handle_ = ::SSL_CTX_new(::TLSv1_2_method()); break; case context::tlsv12_client: handle_ = ::SSL_CTX_new(::TLSv1_2_client_method()); break; case context::tlsv12_server: handle_ = ::SSL_CTX_new(::TLSv1_2_server_method()); break; #else // defined(SSL_TXT_TLSV1_2) case context::tlsv12: case context::tlsv12_client: case context::tlsv12_server: asio::detail::throw_error( asio::error::invalid_argument, "context"); break; #endif // defined(SSL_TXT_TLSV1_2) // TLS v1.3. #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) \ && !defined(LIBRESSL_VERSION_NUMBER) case context::tlsv13: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION); } break; case context::tlsv13_client: handle_ = ::SSL_CTX_new(::TLS_client_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION); } break; case context::tlsv13_server: handle_ = ::SSL_CTX_new(::TLS_server_method()); if (handle_) { SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION); SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION); } break; #else // (OPENSSL_VERSION_NUMBER >= 0x10101000L) // && !defined(LIBRESSL_VERSION_NUMBER) case context::tlsv13: case context::tlsv13_client: case context::tlsv13_server: asio::detail::throw_error( asio::error::invalid_argument, "context"); break; #endif // (OPENSSL_VERSION_NUMBER >= 0x10101000L) // && !defined(LIBRESSL_VERSION_NUMBER) // Any supported SSL/TLS version. case context::sslv23: handle_ = ::SSL_CTX_new(::SSLv23_method()); break; case context::sslv23_client: handle_ = ::SSL_CTX_new(::SSLv23_client_method()); break; case context::sslv23_server: handle_ = ::SSL_CTX_new(::SSLv23_server_method()); break; // Any supported TLS version. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) case context::tls: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_) SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); break; case context::tls_client: handle_ = ::SSL_CTX_new(::TLS_client_method()); if (handle_) SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); break; case context::tls_server: handle_ = ::SSL_CTX_new(::TLS_server_method()); if (handle_) SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); break; #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) case context::tls: handle_ = ::SSL_CTX_new(::SSLv23_method()); if (handle_) SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); break; case context::tls_client: handle_ = ::SSL_CTX_new(::SSLv23_client_method()); if (handle_) SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); break; case context::tls_server: handle_ = ::SSL_CTX_new(::SSLv23_server_method()); if (handle_) SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); break; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) default: handle_ = ::SSL_CTX_new(0); break; } if (handle_ == 0) { asio::error_code ec( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); asio::detail::throw_error(ec, "context"); } set_options(no_compression); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) context::context(context&& other) { handle_ = other.handle_; other.handle_ = 0; } context& context::operator=(context&& other) { context tmp(ASIO_MOVE_CAST(context)(*this)); handle_ = other.handle_; other.handle_ = 0; return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) context::~context() { if (handle_) { #if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \ && !defined(LIBRESSL_VERSION_NUMBER)) \ || defined(ASIO_USE_WOLFSSL) void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_); #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) void* cb_userdata = handle_->default_passwd_callback_userdata; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) if (cb_userdata) { detail::password_callback_base* callback = static_cast( cb_userdata); delete callback; #if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \ && !defined(LIBRESSL_VERSION_NUMBER)) \ || defined(ASIO_USE_WOLFSSL) ::SSL_CTX_set_default_passwd_cb_userdata(handle_, 0); #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) handle_->default_passwd_callback_userdata = 0; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) } if (SSL_CTX_get_app_data(handle_)) { detail::verify_callback_base* callback = static_cast( SSL_CTX_get_app_data(handle_)); delete callback; SSL_CTX_set_app_data(handle_, 0); } ::SSL_CTX_free(handle_); } } context::native_handle_type context::native_handle() { return handle_; } void context::clear_options(context::options o) { asio::error_code ec; clear_options(o, ec); asio::detail::throw_error(ec, "clear_options"); } ASIO_SYNC_OP_VOID context::clear_options( context::options o, asio::error_code& ec) { #if (OPENSSL_VERSION_NUMBER >= 0x009080DFL) \ && (OPENSSL_VERSION_NUMBER != 0x00909000L) # if !defined(SSL_OP_NO_COMPRESSION) if ((o & context::no_compression) != 0) { # if (OPENSSL_VERSION_NUMBER >= 0x00908000L) handle_->comp_methods = SSL_COMP_get_compression_methods(); # endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L) o ^= context::no_compression; } # endif // !defined(SSL_OP_NO_COMPRESSION) ::SSL_CTX_clear_options(handle_, o); ec = asio::error_code(); #else // (OPENSSL_VERSION_NUMBER >= 0x009080DFL) // && (OPENSSL_VERSION_NUMBER != 0x00909000L) (void)o; ec = asio::error::operation_not_supported; #endif // (OPENSSL_VERSION_NUMBER >= 0x009080DFL) // && (OPENSSL_VERSION_NUMBER != 0x00909000L) ASIO_SYNC_OP_VOID_RETURN(ec); } void context::set_options(context::options o) { asio::error_code ec; set_options(o, ec); asio::detail::throw_error(ec, "set_options"); } ASIO_SYNC_OP_VOID context::set_options( context::options o, asio::error_code& ec) { #if !defined(SSL_OP_NO_COMPRESSION) if ((o & context::no_compression) != 0) { #if (OPENSSL_VERSION_NUMBER >= 0x00908000L) handle_->comp_methods = asio::ssl::detail::openssl_init<>::get_null_compression_methods(); #endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L) o ^= context::no_compression; } #endif // !defined(SSL_OP_NO_COMPRESSION) ::SSL_CTX_set_options(handle_, o); ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::set_verify_mode(verify_mode v) { asio::error_code ec; set_verify_mode(v, ec); asio::detail::throw_error(ec, "set_verify_mode"); } ASIO_SYNC_OP_VOID context::set_verify_mode( verify_mode v, asio::error_code& ec) { ::SSL_CTX_set_verify(handle_, v, ::SSL_CTX_get_verify_callback(handle_)); ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::set_verify_depth(int depth) { asio::error_code ec; set_verify_depth(depth, ec); asio::detail::throw_error(ec, "set_verify_depth"); } ASIO_SYNC_OP_VOID context::set_verify_depth( int depth, asio::error_code& ec) { ::SSL_CTX_set_verify_depth(handle_, depth); ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::load_verify_file(const std::string& filename) { asio::error_code ec; load_verify_file(filename, ec); asio::detail::throw_error(ec, "load_verify_file"); } ASIO_SYNC_OP_VOID context::load_verify_file( const std::string& filename, asio::error_code& ec) { ::ERR_clear_error(); if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::add_certificate_authority(const const_buffer& ca) { asio::error_code ec; add_certificate_authority(ca, ec); asio::detail::throw_error(ec, "add_certificate_authority"); } ASIO_SYNC_OP_VOID context::add_certificate_authority( const const_buffer& ca, asio::error_code& ec) { ::ERR_clear_error(); bio_cleanup bio = { make_buffer_bio(ca) }; if (bio.p) { if (X509_STORE* store = ::SSL_CTX_get_cert_store(handle_)) { for (;;) { x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) }; if (!cert.p) break; if (::X509_STORE_add_cert(store, cert.p) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } } } } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::set_default_verify_paths() { asio::error_code ec; set_default_verify_paths(ec); asio::detail::throw_error(ec, "set_default_verify_paths"); } ASIO_SYNC_OP_VOID context::set_default_verify_paths( asio::error_code& ec) { ::ERR_clear_error(); if (::SSL_CTX_set_default_verify_paths(handle_) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::add_verify_path(const std::string& path) { asio::error_code ec; add_verify_path(path, ec); asio::detail::throw_error(ec, "add_verify_path"); } ASIO_SYNC_OP_VOID context::add_verify_path( const std::string& path, asio::error_code& ec) { ::ERR_clear_error(); if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_certificate( const const_buffer& certificate, file_format format) { asio::error_code ec; use_certificate(certificate, format, ec); asio::detail::throw_error(ec, "use_certificate"); } ASIO_SYNC_OP_VOID context::use_certificate( const const_buffer& certificate, file_format format, asio::error_code& ec) { ::ERR_clear_error(); if (format == context_base::asn1) { if (::SSL_CTX_use_certificate_ASN1(handle_, static_cast(certificate.size()), static_cast(certificate.data())) == 1) { ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } } else if (format == context_base::pem) { bio_cleanup bio = { make_buffer_bio(certificate) }; if (bio.p) { x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) }; if (cert.p) { if (::SSL_CTX_use_certificate(handle_, cert.p) == 1) { ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } } } } else { ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_certificate_file( const std::string& filename, file_format format) { asio::error_code ec; use_certificate_file(filename, format, ec); asio::detail::throw_error(ec, "use_certificate_file"); } ASIO_SYNC_OP_VOID context::use_certificate_file( const std::string& filename, file_format format, asio::error_code& ec) { int file_type; switch (format) { case context_base::asn1: file_type = SSL_FILETYPE_ASN1; break; case context_base::pem: file_type = SSL_FILETYPE_PEM; break; default: { ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } } ::ERR_clear_error(); if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_certificate_chain(const const_buffer& chain) { asio::error_code ec; use_certificate_chain(chain, ec); asio::detail::throw_error(ec, "use_certificate_chain"); } ASIO_SYNC_OP_VOID context::use_certificate_chain( const const_buffer& chain, asio::error_code& ec) { ::ERR_clear_error(); bio_cleanup bio = { make_buffer_bio(chain) }; if (bio.p) { #if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \ && !defined(LIBRESSL_VERSION_NUMBER)) \ || defined(ASIO_USE_WOLFSSL) pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_); void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_); #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) pem_password_cb* callback = handle_->default_passwd_callback; void* cb_userdata = handle_->default_passwd_callback_userdata; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) x509_cleanup cert = { ::PEM_read_bio_X509_AUX(bio.p, 0, callback, cb_userdata) }; if (!cert.p) { ec = asio::error_code(ERR_R_PEM_LIB, asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } int result = ::SSL_CTX_use_certificate(handle_, cert.p); if (result == 0 || ::ERR_peek_error() != 0) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } #if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) \ && !defined(LIBRESSL_VERSION_NUMBER)) \ || defined(ASIO_USE_WOLFSSL) ::SSL_CTX_clear_chain_certs(handle_); #else if (handle_->extra_certs) { ::sk_X509_pop_free(handle_->extra_certs, X509_free); handle_->extra_certs = 0; } #endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L) while (X509* cacert = ::PEM_read_bio_X509(bio.p, 0, callback, cb_userdata)) { if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert)) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } } result = ::ERR_peek_last_error(); if ((ERR_GET_LIB(result) == ERR_LIB_PEM) && (ERR_GET_REASON(result) == PEM_R_NO_START_LINE)) { ::ERR_clear_error(); ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } } ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_certificate_chain_file(const std::string& filename) { asio::error_code ec; use_certificate_chain_file(filename, ec); asio::detail::throw_error(ec, "use_certificate_chain_file"); } ASIO_SYNC_OP_VOID context::use_certificate_chain_file( const std::string& filename, asio::error_code& ec) { ::ERR_clear_error(); if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_private_key( const const_buffer& private_key, context::file_format format) { asio::error_code ec; use_private_key(private_key, format, ec); asio::detail::throw_error(ec, "use_private_key"); } ASIO_SYNC_OP_VOID context::use_private_key( const const_buffer& private_key, context::file_format format, asio::error_code& ec) { ::ERR_clear_error(); #if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \ && !defined(LIBRESSL_VERSION_NUMBER)) \ || defined(ASIO_USE_WOLFSSL) pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_); void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_); #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) pem_password_cb* callback = handle_->default_passwd_callback; void* cb_userdata = handle_->default_passwd_callback_userdata; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) bio_cleanup bio = { make_buffer_bio(private_key) }; if (bio.p) { evp_pkey_cleanup evp_private_key = { 0 }; switch (format) { case context_base::asn1: evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0); break; case context_base::pem: evp_private_key.p = ::PEM_read_bio_PrivateKey( bio.p, 0, callback, cb_userdata); break; default: { ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } } if (evp_private_key.p) { if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1) { ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } } } ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_private_key_file( const std::string& filename, context::file_format format) { asio::error_code ec; use_private_key_file(filename, format, ec); asio::detail::throw_error(ec, "use_private_key_file"); } void context::use_rsa_private_key( const const_buffer& private_key, context::file_format format) { asio::error_code ec; use_rsa_private_key(private_key, format, ec); asio::detail::throw_error(ec, "use_rsa_private_key"); } ASIO_SYNC_OP_VOID context::use_rsa_private_key( const const_buffer& private_key, context::file_format format, asio::error_code& ec) { ::ERR_clear_error(); #if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \ && !defined(LIBRESSL_VERSION_NUMBER)) \ || defined(ASIO_USE_WOLFSSL) pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_); void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_); #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) pem_password_cb* callback = handle_->default_passwd_callback; void* cb_userdata = handle_->default_passwd_callback_userdata; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) bio_cleanup bio = { make_buffer_bio(private_key) }; if (bio.p) { rsa_cleanup rsa_private_key = { 0 }; switch (format) { case context_base::asn1: rsa_private_key.p = ::d2i_RSAPrivateKey_bio(bio.p, 0); break; case context_base::pem: rsa_private_key.p = ::PEM_read_bio_RSAPrivateKey( bio.p, 0, callback, cb_userdata); break; default: { ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } } if (rsa_private_key.p) { if (::SSL_CTX_use_RSAPrivateKey(handle_, rsa_private_key.p) == 1) { ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } } } ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID context::use_private_key_file( const std::string& filename, context::file_format format, asio::error_code& ec) { int file_type; switch (format) { case context_base::asn1: file_type = SSL_FILETYPE_ASN1; break; case context_base::pem: file_type = SSL_FILETYPE_PEM; break; default: { ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } } ::ERR_clear_error(); if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_rsa_private_key_file( const std::string& filename, context::file_format format) { asio::error_code ec; use_rsa_private_key_file(filename, format, ec); asio::detail::throw_error(ec, "use_rsa_private_key_file"); } ASIO_SYNC_OP_VOID context::use_rsa_private_key_file( const std::string& filename, context::file_format format, asio::error_code& ec) { int file_type; switch (format) { case context_base::asn1: file_type = SSL_FILETYPE_ASN1; break; case context_base::pem: file_type = SSL_FILETYPE_PEM; break; default: { ec = asio::error::invalid_argument; ASIO_SYNC_OP_VOID_RETURN(ec); } } ::ERR_clear_error(); if (::SSL_CTX_use_RSAPrivateKey_file( handle_, filename.c_str(), file_type) != 1) { ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_tmp_dh(const const_buffer& dh) { asio::error_code ec; use_tmp_dh(dh, ec); asio::detail::throw_error(ec, "use_tmp_dh"); } ASIO_SYNC_OP_VOID context::use_tmp_dh( const const_buffer& dh, asio::error_code& ec) { ::ERR_clear_error(); bio_cleanup bio = { make_buffer_bio(dh) }; if (bio.p) { return do_use_tmp_dh(bio.p, ec); } ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } void context::use_tmp_dh_file(const std::string& filename) { asio::error_code ec; use_tmp_dh_file(filename, ec); asio::detail::throw_error(ec, "use_tmp_dh_file"); } ASIO_SYNC_OP_VOID context::use_tmp_dh_file( const std::string& filename, asio::error_code& ec) { ::ERR_clear_error(); bio_cleanup bio = { ::BIO_new_file(filename.c_str(), "r") }; if (bio.p) { return do_use_tmp_dh(bio.p, ec); } ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID context::do_use_tmp_dh( BIO* bio, asio::error_code& ec) { ::ERR_clear_error(); dh_cleanup dh = { ::PEM_read_bio_DHparams(bio, 0, 0, 0) }; if (dh.p) { if (::SSL_CTX_set_tmp_dh(handle_, dh.p) == 1) { ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } } ec = asio::error_code( static_cast(::ERR_get_error()), asio::error::get_ssl_category()); ASIO_SYNC_OP_VOID_RETURN(ec); } ASIO_SYNC_OP_VOID context::do_set_verify_callback( detail::verify_callback_base* callback, asio::error_code& ec) { if (SSL_CTX_get_app_data(handle_)) { delete static_cast( SSL_CTX_get_app_data(handle_)); } SSL_CTX_set_app_data(handle_, callback); ::SSL_CTX_set_verify(handle_, ::SSL_CTX_get_verify_mode(handle_), &context::verify_callback_function); ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx) { if (ctx) { if (SSL* ssl = static_cast( ::X509_STORE_CTX_get_ex_data( ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx()))) { if (SSL_CTX* handle = ::SSL_get_SSL_CTX(ssl)) { if (SSL_CTX_get_app_data(handle)) { detail::verify_callback_base* callback = static_cast( SSL_CTX_get_app_data(handle)); verify_context verify_ctx(ctx); return callback->call(preverified != 0, verify_ctx) ? 1 : 0; } } } } return 0; } ASIO_SYNC_OP_VOID context::do_set_password_callback( detail::password_callback_base* callback, asio::error_code& ec) { #if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \ && !defined(LIBRESSL_VERSION_NUMBER)) \ || defined(ASIO_USE_WOLFSSL) void* old_callback = ::SSL_CTX_get_default_passwd_cb_userdata(handle_); ::SSL_CTX_set_default_passwd_cb_userdata(handle_, callback); #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) void* old_callback = handle_->default_passwd_callback_userdata; handle_->default_passwd_callback_userdata = callback; #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) if (old_callback) delete static_cast( old_callback); SSL_CTX_set_default_passwd_cb(handle_, &context::password_callback_function); ec = asio::error_code(); ASIO_SYNC_OP_VOID_RETURN(ec); } int context::password_callback_function( char* buf, int size, int purpose, void* data) { using namespace std; // For strncat and strlen. if (data) { detail::password_callback_base* callback = static_cast(data); std::string passwd = callback->call(static_cast(size), purpose ? context_base::for_writing : context_base::for_reading); #if defined(ASIO_HAS_SECURE_RTL) strcpy_s(buf, size, passwd.c_str()); #else // defined(ASIO_HAS_SECURE_RTL) *buf = '\0'; if (size > 0) strncat(buf, passwd.c_str(), size - 1); #endif // defined(ASIO_HAS_SECURE_RTL) return static_cast(strlen(buf)); } return 0; } BIO* context::make_buffer_bio(const const_buffer& b) { return ::BIO_new_mem_buf( const_cast(b.data()), static_cast(b.size())); } } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_IMPL_CONTEXT_IPP ================================================ FILE: src/third_party/asio/ssl/impl/error.ipp ================================================ // // ssl/impl/error.ipp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_IMPL_ERROR_IPP #define ASIO_SSL_IMPL_ERROR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/error.hpp" #include "asio/ssl/detail/openssl_init.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace error { namespace detail { class ssl_category : public asio::error_category { public: const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.ssl"; } std::string message(int value) const { const char* s = ::ERR_reason_error_string(value); return s ? s : "asio.ssl error"; } }; } // namespace detail const asio::error_category& get_ssl_category() { static detail::ssl_category instance; return instance; } } // namespace error namespace ssl { namespace error { #if (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL) const asio::error_category& get_stream_category() { return asio::error::get_ssl_category(); } #else namespace detail { class stream_category : public asio::error_category { public: const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.ssl.stream"; } std::string message(int value) const { switch (value) { case stream_truncated: return "stream truncated"; case unspecified_system_error: return "unspecified system error"; case unexpected_result: return "unexpected result"; default: return "asio.ssl.stream error"; } } }; } // namespace detail const asio::error_category& get_stream_category() { static detail::stream_category instance; return instance; } #endif } // namespace error } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_IMPL_ERROR_IPP ================================================ FILE: src/third_party/asio/ssl/impl/rfc2818_verification.ipp ================================================ // // ssl/impl/rfc2818_verification.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP #define ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include #include "asio/ip/address.hpp" #include "asio/ssl/rfc2818_verification.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { bool rfc2818_verification::operator()( bool preverified, verify_context& ctx) const { using namespace std; // For memcmp. // Don't bother looking at certificates that have failed pre-verification. if (!preverified) return false; // We're only interested in checking the certificate at the end of the chain. int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle()); if (depth > 0) return true; // Try converting the host name to an address. If it is an address then we // need to look for an IP address in the certificate rather than a host name. asio::error_code ec; ip::address address = ip::make_address(host_, ec); bool is_address = !ec; X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); // Go through the alternate names in the certificate looking for matching DNS // or IP address entries. GENERAL_NAMES* gens = static_cast( X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0)); for (int i = 0; i < sk_GENERAL_NAME_num(gens); ++i) { GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i); if (gen->type == GEN_DNS && !is_address) { ASN1_IA5STRING* domain = gen->d.dNSName; if (domain->type == V_ASN1_IA5STRING && domain->data && domain->length) { const char* pattern = reinterpret_cast(domain->data); std::size_t pattern_length = domain->length; if (match_pattern(pattern, pattern_length, host_.c_str())) { GENERAL_NAMES_free(gens); return true; } } } else if (gen->type == GEN_IPADD && is_address) { ASN1_OCTET_STRING* ip_address = gen->d.iPAddress; if (ip_address->type == V_ASN1_OCTET_STRING && ip_address->data) { if (address.is_v4() && ip_address->length == 4) { ip::address_v4::bytes_type bytes = address.to_v4().to_bytes(); if (memcmp(bytes.data(), ip_address->data, 4) == 0) { GENERAL_NAMES_free(gens); return true; } } else if (address.is_v6() && ip_address->length == 16) { ip::address_v6::bytes_type bytes = address.to_v6().to_bytes(); if (memcmp(bytes.data(), ip_address->data, 16) == 0) { GENERAL_NAMES_free(gens); return true; } } } } } GENERAL_NAMES_free(gens); // No match in the alternate names, so try the common names. We should only // use the "most specific" common name, which is the last one in the list. X509_NAME* name = X509_get_subject_name(cert); int i = -1; ASN1_STRING* common_name = 0; while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0) { X509_NAME_ENTRY* name_entry = X509_NAME_get_entry(name, i); common_name = X509_NAME_ENTRY_get_data(name_entry); } if (common_name && common_name->data && common_name->length) { const char* pattern = reinterpret_cast(common_name->data); std::size_t pattern_length = common_name->length; if (match_pattern(pattern, pattern_length, host_.c_str())) return true; } return false; } bool rfc2818_verification::match_pattern(const char* pattern, std::size_t pattern_length, const char* host) { using namespace std; // For tolower. const char* p = pattern; const char* p_end = p + pattern_length; const char* h = host; while (p != p_end && *h) { if (*p == '*') { ++p; while (*h && *h != '.') if (match_pattern(p, p_end - p, h++)) return true; } else if (tolower(*p) == tolower(*h)) { ++p; ++h; } else { return false; } } return p == p_end && !*h; } } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP ================================================ FILE: src/third_party/asio/ssl/impl/src.hpp ================================================ // // impl/ssl/src.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_IMPL_SRC_HPP #define ASIO_SSL_IMPL_SRC_HPP #define ASIO_SOURCE #include "asio/detail/config.hpp" #if defined(ASIO_HEADER_ONLY) # error Do not compile Asio library source with ASIO_HEADER_ONLY defined #endif #include "asio/ssl/impl/context.ipp" #include "asio/ssl/impl/error.ipp" #include "asio/ssl/detail/impl/engine.ipp" #include "asio/ssl/detail/impl/openssl_init.ipp" #include "asio/ssl/impl/rfc2818_verification.ipp" #endif // ASIO_SSL_IMPL_SRC_HPP ================================================ FILE: src/third_party/asio/ssl/rfc2818_verification.hpp ================================================ // // ssl/rfc2818_verification.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_RFC2818_VERIFICATION_HPP #define ASIO_SSL_RFC2818_VERIFICATION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/ssl/detail/openssl_types.hpp" #include "asio/ssl/verify_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { /// Verifies a certificate against a hostname according to the rules described /// in RFC 2818. /** * @par Example * The following example shows how to synchronously open a secure connection to * a given host name: * @code * using asio::ip::tcp; * namespace ssl = asio::ssl; * typedef ssl::stream ssl_socket; * * // Create a context that uses the default paths for finding CA certificates. * ssl::context ctx(ssl::context::sslv23); * ctx.set_default_verify_paths(); * * // Open a socket and connect it to the remote host. * asio::io_context io_context; * ssl_socket sock(io_context, ctx); * tcp::resolver resolver(io_context); * tcp::resolver::query query("host.name", "https"); * asio::connect(sock.lowest_layer(), resolver.resolve(query)); * sock.lowest_layer().set_option(tcp::no_delay(true)); * * // Perform SSL handshake and verify the remote host's certificate. * sock.set_verify_mode(ssl::verify_peer); * sock.set_verify_callback(ssl::rfc2818_verification("host.name")); * sock.handshake(ssl_socket::client); * * // ... read and write as normal ... * @endcode */ class rfc2818_verification { public: /// The type of the function object's result. typedef bool result_type; /// Constructor. explicit rfc2818_verification(const std::string& host) : host_(host) { } /// Perform certificate verification. ASIO_DECL bool operator()(bool preverified, verify_context& ctx) const; private: // Helper function to check a host name against a pattern. ASIO_DECL static bool match_pattern(const char* pattern, std::size_t pattern_length, const char* host); // Helper function to check a host name against an IPv4 address // The host name to be checked. std::string host_; }; } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/ssl/impl/rfc2818_verification.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_SSL_RFC2818_VERIFICATION_HPP ================================================ FILE: src/third_party/asio/ssl/stream.hpp ================================================ // // ssl/stream.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_STREAM_HPP #define ASIO_SSL_STREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/type_traits.hpp" #include "asio/ssl/context.hpp" #include "asio/ssl/detail/buffered_handshake_op.hpp" #include "asio/ssl/detail/handshake_op.hpp" #include "asio/ssl/detail/io.hpp" #include "asio/ssl/detail/read_op.hpp" #include "asio/ssl/detail/shutdown_op.hpp" #include "asio/ssl/detail/stream_core.hpp" #include "asio/ssl/detail/write_op.hpp" #include "asio/ssl/stream_base.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { /// Provides stream-oriented functionality using SSL. /** * The stream class template provides asynchronous and blocking stream-oriented * functionality using SSL. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. The application must also ensure that all * asynchronous operations are performed within the same implicit or explicit * strand. * * @par Example * To use the SSL stream template with an ip::tcp::socket, you would write: * @code * asio::io_context my_context; * asio::ssl::context ctx(asio::ssl::context::sslv23); * asio::ssl::stream sock(my_context, ctx); * @endcode * * @par Concepts: * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template class stream : public stream_base, private noncopyable { public: /// The native handle type of the SSL stream. typedef SSL* native_handle_type; /// Structure for use with deprecated impl_type. struct impl_struct { SSL* ssl; }; /// The type of the next layer. typedef typename remove_reference::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; /// The type of the executor associated with the object. typedef typename lowest_layer_type::executor_type executor_type; #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a stream. /** * This constructor creates a stream and initialises the underlying stream * object. * * @param arg The argument to be passed to initialise the underlying stream. * * @param ctx The SSL context to be used for the stream. */ template stream(Arg&& arg, context& ctx) : next_layer_(ASIO_MOVE_CAST(Arg)(arg)), core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor()) { } #else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template stream(Arg& arg, context& ctx) : next_layer_(arg), core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor()) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. /** * @note A @c stream object must not be destroyed while there are pending * asynchronous operations associated with it. */ ~stream() { } /// Get the executor associated with the object. /** * This function may be used to obtain the executor object that the stream * uses to dispatch handlers for asynchronous operations. * * @return A copy of the executor that stream will use to dispatch handlers. */ executor_type get_executor() ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } /// Get the underlying implementation in the native type. /** * This function may be used to obtain the underlying implementation of the * context. This is intended to allow access to context functionality that is * not otherwise provided. * * @par Example * The native_handle() function returns a pointer of type @c SSL* that is * suitable for passing to functions such as @c SSL_get_verify_result and * @c SSL_get_peer_certificate: * @code * asio::ssl::stream sock(my_context, ctx); * * // ... establish connection and perform handshake ... * * if (X509* cert = SSL_get_peer_certificate(sock.native_handle())) * { * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK) * { * // ... * } * } * @endcode */ native_handle_type native_handle() { return core_.engine_.native_handle(); } /// Get a reference to the next layer. /** * This function returns a reference to the next layer in a stack of stream * layers. * * @return A reference to the next layer in the stack of stream layers. * Ownership is not transferred to the caller. */ const next_layer_type& next_layer() const { return next_layer_; } /// Get a reference to the next layer. /** * This function returns a reference to the next layer in a stack of stream * layers. * * @return A reference to the next layer in the stack of stream layers. * Ownership is not transferred to the caller. */ next_layer_type& next_layer() { return next_layer_; } /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of * stream layers. * * @return A reference to the lowest layer in the stack of stream layers. * Ownership is not transferred to the caller. */ lowest_layer_type& lowest_layer() { return next_layer_.lowest_layer(); } /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of * stream layers. * * @return A reference to the lowest layer in the stack of stream layers. * Ownership is not transferred to the caller. */ const lowest_layer_type& lowest_layer() const { return next_layer_.lowest_layer(); } /// Set the peer verification mode. /** * This function may be used to configure the peer verification mode used by * the stream. The new mode will override the mode inherited from the context. * * @param v A bitmask of peer verification modes. See @ref verify_mode for * available values. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_set_verify. */ void set_verify_mode(verify_mode v) { asio::error_code ec; set_verify_mode(v, ec); asio::detail::throw_error(ec, "set_verify_mode"); } /// Set the peer verification mode. /** * This function may be used to configure the peer verification mode used by * the stream. The new mode will override the mode inherited from the context. * * @param v A bitmask of peer verification modes. See @ref verify_mode for * available values. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_set_verify. */ ASIO_SYNC_OP_VOID set_verify_mode( verify_mode v, asio::error_code& ec) { core_.engine_.set_verify_mode(v, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set the peer verification depth. /** * This function may be used to configure the maximum verification depth * allowed by the stream. * * @param depth Maximum depth for the certificate chain verification that * shall be allowed. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_set_verify_depth. */ void set_verify_depth(int depth) { asio::error_code ec; set_verify_depth(depth, ec); asio::detail::throw_error(ec, "set_verify_depth"); } /// Set the peer verification depth. /** * This function may be used to configure the maximum verification depth * allowed by the stream. * * @param depth Maximum depth for the certificate chain verification that * shall be allowed. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_set_verify_depth. */ ASIO_SYNC_OP_VOID set_verify_depth( int depth, asio::error_code& ec) { core_.engine_.set_verify_depth(depth, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set the callback used to verify peer certificates. /** * This function is used to specify a callback function that will be called * by the implementation when it needs to verify a peer certificate. * * @param callback The function object to be used for verifying a certificate. * The function signature of the handler must be: * @code bool verify_callback( * bool preverified, // True if the certificate passed pre-verification. * verify_context& ctx // The peer certificate and other context. * ); @endcode * The return value of the callback is true if the certificate has passed * verification, false otherwise. * * @throws asio::system_error Thrown on failure. * * @note Calls @c SSL_set_verify. */ template void set_verify_callback(VerifyCallback callback) { asio::error_code ec; this->set_verify_callback(callback, ec); asio::detail::throw_error(ec, "set_verify_callback"); } /// Set the callback used to verify peer certificates. /** * This function is used to specify a callback function that will be called * by the implementation when it needs to verify a peer certificate. * * @param callback The function object to be used for verifying a certificate. * The function signature of the handler must be: * @code bool verify_callback( * bool preverified, // True if the certificate passed pre-verification. * verify_context& ctx // The peer certificate and other context. * ); @endcode * The return value of the callback is true if the certificate has passed * verification, false otherwise. * * @param ec Set to indicate what error occurred, if any. * * @note Calls @c SSL_set_verify. */ template ASIO_SYNC_OP_VOID set_verify_callback(VerifyCallback callback, asio::error_code& ec) { core_.engine_.set_verify_callback( new detail::verify_callback(callback), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform SSL handshaking. /** * This function is used to perform SSL handshaking on the stream. The * function call will block until handshaking is complete or an error occurs. * * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * * @throws asio::system_error Thrown on failure. */ void handshake(handshake_type type) { asio::error_code ec; handshake(type, ec); asio::detail::throw_error(ec, "handshake"); } /// Perform SSL handshaking. /** * This function is used to perform SSL handshaking on the stream. The * function call will block until handshaking is complete or an error occurs. * * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID handshake(handshake_type type, asio::error_code& ec) { detail::io(next_layer_, core_, detail::handshake_op(type), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform SSL handshaking. /** * This function is used to perform SSL handshaking on the stream. The * function call will block until handshaking is complete or an error occurs. * * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * * @param buffers The buffered data to be reused for the handshake. * * @throws asio::system_error Thrown on failure. */ template void handshake(handshake_type type, const ConstBufferSequence& buffers) { asio::error_code ec; handshake(type, buffers, ec); asio::detail::throw_error(ec, "handshake"); } /// Perform SSL handshaking. /** * This function is used to perform SSL handshaking on the stream. The * function call will block until handshaking is complete or an error occurs. * * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * * @param buffers The buffered data to be reused for the handshake. * * @param ec Set to indicate what error occurred, if any. */ template ASIO_SYNC_OP_VOID handshake(handshake_type type, const ConstBufferSequence& buffers, asio::error_code& ec) { detail::io(next_layer_, core_, detail::buffered_handshake_op(type, buffers), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous SSL handshake. /** * This function is used to asynchronously perform an SSL handshake on the * stream. This function call always returns immediately. * * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * * @param handler The handler to be called when the handshake operation * completes. Copies will be made of the handler as required. The equivalent * function signature of the handler must be: * @code void handler( * const asio::error_code& error // Result of operation. * ); @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) HandshakeHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(HandshakeHandler, void (asio::error_code)) async_handshake(handshake_type type, ASIO_MOVE_ARG(HandshakeHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_handshake(this), handler, type); } /// Start an asynchronous SSL handshake. /** * This function is used to asynchronously perform an SSL handshake on the * stream. This function call always returns immediately. * * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * * @param buffers The buffered data to be reused for the handshake. Although * the buffers object may be copied as necessary, ownership of the underlying * buffers is retained by the caller, which must guarantee that they remain * valid until the handler is called. * * @param handler The handler to be called when the handshake operation * completes. Copies will be made of the handler as required. The equivalent * function signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Amount of buffers used in handshake. * ); @endcode */ template ASIO_INITFN_AUTO_RESULT_TYPE(BufferedHandshakeHandler, void (asio::error_code, std::size_t)) async_handshake(handshake_type type, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(BufferedHandshakeHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_buffered_handshake(this), handler, type, buffers); } /// Shut down SSL on the stream. /** * This function is used to shut down SSL on the stream. The function call * will block until SSL has been shut down or an error occurs. * * @throws asio::system_error Thrown on failure. */ void shutdown() { asio::error_code ec; shutdown(ec); asio::detail::throw_error(ec, "shutdown"); } /// Shut down SSL on the stream. /** * This function is used to shut down SSL on the stream. The function call * will block until SSL has been shut down or an error occurs. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID shutdown(asio::error_code& ec) { detail::io(next_layer_, core_, detail::shutdown_op(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Asynchronously shut down SSL on the stream. /** * This function is used to asynchronously shut down SSL on the stream. This * function call always returns immediately. * * @param handler The handler to be called when the handshake operation * completes. Copies will be made of the handler as required. The equivalent * function signature of the handler must be: * @code void handler( * const asio::error_code& error // Result of operation. * ); @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) ShutdownHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(ShutdownHandler, void (asio::error_code)) async_shutdown( ASIO_MOVE_ARG(ShutdownHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_shutdown(this), handler); } /// Write some data to the stream. /** * This function is used to write data on the stream. The function call will * block until one or more bytes of data has been written successfully, or * until an error occurs. * * @param buffers The data to be written. * * @returns The number of bytes written. * * @throws asio::system_error Thrown on failure. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that all * data is written before the blocking operation completes. */ template std::size_t write_some(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t n = write_some(buffers, ec); asio::detail::throw_error(ec, "write_some"); return n; } /// Write some data to the stream. /** * This function is used to write data on the stream. The function call will * block until one or more bytes of data has been written successfully, or * until an error occurs. * * @param buffers The data to be written to the stream. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that all * data is written before the blocking operation completes. */ template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { return detail::io(next_layer_, core_, detail::write_op(buffers), ec); } /// Start an asynchronous write. /** * This function is used to asynchronously write one or more bytes of data to * the stream. The function call always returns immediately. * * @param buffers The data to be written to the stream. Although the buffers * object may be copied as necessary, ownership of the underlying buffers is * retained by the caller, which must guarantee that they remain valid until * the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The equivalent function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * * @note The async_write_some operation may not transmit all of the data to * the peer. Consider using the @ref async_write function if you need to * ensure that all data is written before the asynchronous operation * completes. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_write_some(this), handler, buffers); } /// Read some data from the stream. /** * This function is used to read data from the stream. The function call will * block until one or more bytes of data has been read successfully, or until * an error occurs. * * @param buffers The buffers into which the data will be read. * * @returns The number of bytes read. * * @throws asio::system_error Thrown on failure. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. */ template std::size_t read_some(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t n = read_some(buffers, ec); asio::detail::throw_error(ec, "read_some"); return n; } /// Read some data from the stream. /** * This function is used to read data from the stream. The function call will * block until one or more bytes of data has been read successfully, or until * an error occurs. * * @param buffers The buffers into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. */ template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { return detail::io(next_layer_, core_, detail::read_op(buffers), ec); } /// Start an asynchronous read. /** * This function is used to asynchronously read one or more bytes of data from * the stream. The function call always returns immediately. * * @param buffers The buffers into which the data will be read. Although the * buffers object may be copied as necessary, ownership of the underlying * buffers is retained by the caller, which must guarantee that they remain * valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The equivalent function * signature of the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * * @note The async_read_some operation may not read all of the requested * number of bytes. Consider using the @ref async_read function if you need to * ensure that the requested amount of data is read before the asynchronous * operation completes. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_read_some(this), handler, buffers); } private: class initiate_async_handshake { public: typedef stream::executor_type executor_type; explicit initiate_async_handshake(stream* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(HandshakeHandler) handler, handshake_type type) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a HandshakeHandler. ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check; asio::detail::non_const_lvalue handler2(handler); detail::async_io(self_->next_layer_, self_->core_, detail::handshake_op(type), handler2.value); } private: stream* self_; }; class initiate_async_buffered_handshake { public: typedef stream::executor_type executor_type; explicit initiate_async_buffered_handshake(stream* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(BufferedHandshakeHandler) handler, handshake_type type, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your // handler does not meet the documented type requirements for a // BufferedHandshakeHandler. ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( BufferedHandshakeHandler, handler) type_check; asio::detail::non_const_lvalue< BufferedHandshakeHandler> handler2(handler); detail::async_io(self_->next_layer_, self_->core_, detail::buffered_handshake_op(type, buffers), handler2.value); } private: stream* self_; }; class initiate_async_shutdown { public: typedef typename stream::executor_type executor_type; explicit initiate_async_shutdown(stream* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ShutdownHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ShutdownHandler. ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check; asio::detail::non_const_lvalue handler2(handler); detail::async_io(self_->next_layer_, self_->core_, detail::shutdown_op(), handler2.value); } private: stream* self_; }; class initiate_async_write_some { public: typedef typename stream::executor_type executor_type; explicit initiate_async_write_some(stream* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; asio::detail::non_const_lvalue handler2(handler); detail::async_io(self_->next_layer_, self_->core_, detail::write_op(buffers), handler2.value); } private: stream* self_; }; class initiate_async_read_some { public: typedef typename stream::executor_type executor_type; explicit initiate_async_read_some(stream* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; asio::detail::non_const_lvalue handler2(handler); detail::async_io(self_->next_layer_, self_->core_, detail::read_op(buffers), handler2.value); } private: stream* self_; }; Stream next_layer_; detail::stream_core core_; }; } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_STREAM_HPP ================================================ FILE: src/third_party/asio/ssl/stream_base.hpp ================================================ // // ssl/stream_base.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_STREAM_BASE_HPP #define ASIO_SSL_STREAM_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { /// The stream_base class is used as a base for the asio::ssl::stream /// class template so that we have a common place to define various enums. class stream_base { public: /// Different handshake types. enum handshake_type { /// Perform handshaking as a client. client, /// Perform handshaking as a server. server }; protected: /// Protected destructor to prevent deletion through this type. ~stream_base() { } }; } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_STREAM_BASE_HPP ================================================ FILE: src/third_party/asio/ssl/verify_context.hpp ================================================ // // ssl/verify_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_VERIFY_CONTEXT_HPP #define ASIO_SSL_VERIFY_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { /// A simple wrapper around the X509_STORE_CTX type, used during verification of /// a peer certificate. /** * @note The verify_context does not own the underlying X509_STORE_CTX object. */ class verify_context : private noncopyable { public: /// The native handle type of the verification context. typedef X509_STORE_CTX* native_handle_type; /// Constructor. explicit verify_context(native_handle_type handle) : handle_(handle) { } /// Get the underlying implementation in the native type. /** * This function may be used to obtain the underlying implementation of the * context. This is intended to allow access to context functionality that is * not otherwise provided. */ native_handle_type native_handle() { return handle_; } private: // The underlying native implementation. native_handle_type handle_; }; } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_VERIFY_CONTEXT_HPP ================================================ FILE: src/third_party/asio/ssl/verify_mode.hpp ================================================ // // ssl/verify_mode.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_VERIFY_MODE_HPP #define ASIO_SSL_VERIFY_MODE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/ssl/detail/openssl_types.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { /// Bitmask type for peer verification. /** * Possible values are: * * @li @ref verify_none * @li @ref verify_peer * @li @ref verify_fail_if_no_peer_cert * @li @ref verify_client_once */ typedef int verify_mode; #if defined(GENERATING_DOCUMENTATION) /// No verification. const int verify_none = implementation_defined; /// Verify the peer. const int verify_peer = implementation_defined; /// Fail verification if the peer has no certificate. Ignored unless /// @ref verify_peer is set. const int verify_fail_if_no_peer_cert = implementation_defined; /// Do not request client certificate on renegotiation. Ignored unless /// @ref verify_peer is set. const int verify_client_once = implementation_defined; #else const int verify_none = SSL_VERIFY_NONE; const int verify_peer = SSL_VERIFY_PEER; const int verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT; const int verify_client_once = SSL_VERIFY_CLIENT_ONCE; #endif } // namespace ssl } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SSL_VERIFY_MODE_HPP ================================================ FILE: src/third_party/asio/ssl.hpp ================================================ // // ssl.hpp // ~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SSL_HPP #define ASIO_SSL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/ssl/context.hpp" #include "asio/ssl/context_base.hpp" #include "asio/ssl/error.hpp" #include "asio/ssl/rfc2818_verification.hpp" #include "asio/ssl/stream.hpp" #include "asio/ssl/stream_base.hpp" #include "asio/ssl/verify_context.hpp" #include "asio/ssl/verify_mode.hpp" #endif // ASIO_SSL_HPP ================================================ FILE: src/third_party/asio/steady_timer.hpp ================================================ // // steady_timer.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_STEADY_TIMER_HPP #define ASIO_STEADY_TIMER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" namespace asio { /// Typedef for a timer based on the steady clock. /** * This typedef uses the C++11 @c <chrono> standard library facility, if * available. Otherwise, it may use the Boost.Chrono library. To explicitly * utilise Boost.Chrono, use the basic_waitable_timer template directly: * @code * typedef basic_waitable_timer timer; * @endcode */ typedef basic_waitable_timer steady_timer; } // namespace asio #endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_STEADY_TIMER_HPP ================================================ FILE: src/third_party/asio/strand.hpp ================================================ // // strand.hpp // ~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_STRAND_HPP #define ASIO_STRAND_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/strand_executor_service.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// Provides serialised function invocation for any executor type. template class strand { public: /// The type of the underlying executor. typedef Executor inner_executor_type; /// Default constructor. /** * This constructor is only valid if the underlying executor type is default * constructible. */ strand() : executor_(), impl_(use_service( executor_.context()).create_implementation()) { } /// Construct a strand for the specified executor. explicit strand(const Executor& e) : executor_(e), impl_(use_service( executor_.context()).create_implementation()) { } /// Copy constructor. strand(const strand& other) ASIO_NOEXCEPT : executor_(other.executor_), impl_(other.impl_) { } /// Converting constructor. /** * This constructor is only valid if the @c OtherExecutor type is convertible * to @c Executor. */ template strand( const strand& other) ASIO_NOEXCEPT : executor_(other.executor_), impl_(other.impl_) { } /// Assignment operator. strand& operator=(const strand& other) ASIO_NOEXCEPT { executor_ = other.executor_; impl_ = other.impl_; return *this; } /// Converting assignment operator. /** * This assignment operator is only valid if the @c OtherExecutor type is * convertible to @c Executor. */ template strand& operator=( const strand& other) ASIO_NOEXCEPT { executor_ = other.executor_; impl_ = other.impl_; return *this; } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. strand(strand&& other) ASIO_NOEXCEPT : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)) { } /// Converting move constructor. /** * This constructor is only valid if the @c OtherExecutor type is convertible * to @c Executor. */ template strand(strand&& other) ASIO_NOEXCEPT : executor_(ASIO_MOVE_CAST(OtherExecutor)(other)), impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)) { } /// Move assignment operator. strand& operator=(strand&& other) ASIO_NOEXCEPT { executor_ = ASIO_MOVE_CAST(Executor)(other); impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_); return *this; } /// Converting move assignment operator. /** * This assignment operator is only valid if the @c OtherExecutor type is * convertible to @c Executor. */ template strand& operator=( const strand&& other) ASIO_NOEXCEPT { executor_ = ASIO_MOVE_CAST(OtherExecutor)(other); impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ~strand() { } /// Obtain the underlying executor. inner_executor_type get_inner_executor() const ASIO_NOEXCEPT { return executor_; } /// Obtain the underlying execution context. execution_context& context() const ASIO_NOEXCEPT { return executor_.context(); } /// Inform the strand that it has some outstanding work to do. /** * The strand delegates this call to its underlying executor. */ void on_work_started() const ASIO_NOEXCEPT { executor_.on_work_started(); } /// Inform the strand that some work is no longer outstanding. /** * The strand delegates this call to its underlying executor. */ void on_work_finished() const ASIO_NOEXCEPT { executor_.on_work_finished(); } /// Request the strand to invoke the given function object. /** * This function is used to ask the strand to execute the given function * object on its underlying executor. The function object will be executed * inside this function if the strand is not otherwise busy and if the * underlying executor's @c dispatch() function is also able to execute the * function before returning. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { detail::strand_executor_service::dispatch(impl_, executor_, ASIO_MOVE_CAST(Function)(f), a); } /// Request the strand to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object will never be executed inside this function. * Instead, it will be scheduled by the underlying executor's defer function. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { detail::strand_executor_service::post(impl_, executor_, ASIO_MOVE_CAST(Function)(f), a); } /// Request the strand to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object will never be executed inside this function. * Instead, it will be scheduled by the underlying executor's defer function. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { detail::strand_executor_service::defer(impl_, executor_, ASIO_MOVE_CAST(Function)(f), a); } /// Determine whether the strand is running in the current thread. /** * @return @c true if the current thread is executing a function that was * submitted to the strand using post(), dispatch() or defer(). Otherwise * returns @c false. */ bool running_in_this_thread() const ASIO_NOEXCEPT { return detail::strand_executor_service::running_in_this_thread(impl_); } /// Compare two strands for equality. /** * Two strands are equal if they refer to the same ordered, non-concurrent * state. */ friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ == b.impl_; } /// Compare two strands for inequality. /** * Two strands are equal if they refer to the same ordered, non-concurrent * state. */ friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ != b.impl_; } private: Executor executor_; typedef detail::strand_executor_service::implementation_type implementation_type; implementation_type impl_; }; /** @defgroup make_strand asio::make_strand * * @brief The asio::make_strand function creates a @ref strand object for * an executor or execution context. */ /*@{*/ /// Create a @ref strand object for an executor. template inline strand make_strand(const Executor& ex, typename enable_if::value>::type* = 0) { return strand(ex); } /// Create a @ref strand object for an execution context. template inline strand make_strand(ExecutionContext& ctx, typename enable_if< is_convertible::value>::type* = 0) { return strand(ctx.get_executor()); } /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" // If both io_context.hpp and strand.hpp have been included, automatically // include the header file needed for the io_context::strand class. #if !defined(ASIO_NO_EXTENSIONS) # if defined(ASIO_IO_CONTEXT_HPP) # include "asio/io_context_strand.hpp" # endif // defined(ASIO_IO_CONTEXT_HPP) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // ASIO_STRAND_HPP ================================================ FILE: src/third_party/asio/streambuf.hpp ================================================ // // streambuf.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_STREAMBUF_HPP #define ASIO_STREAMBUF_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if !defined(ASIO_NO_IOSTREAM) #include "asio/basic_streambuf.hpp" namespace asio { /// Typedef for the typical usage of basic_streambuf. typedef basic_streambuf<> streambuf; } // namespace asio #endif // !defined(ASIO_NO_IOSTREAM) #endif // ASIO_STREAMBUF_HPP ================================================ FILE: src/third_party/asio/system_context.hpp ================================================ // // system_context.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SYSTEM_CONTEXT_HPP #define ASIO_SYSTEM_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/thread_group.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { class system_executor; /// The executor context for the system executor. class system_context : public execution_context { public: /// The executor type associated with the context. typedef system_executor executor_type; /// Destructor shuts down all threads in the system thread pool. ASIO_DECL ~system_context(); /// Obtain an executor for the context. executor_type get_executor() ASIO_NOEXCEPT; /// Signal all threads in the system thread pool to stop. ASIO_DECL void stop(); /// Determine whether the system thread pool has been stopped. ASIO_DECL bool stopped() const ASIO_NOEXCEPT; /// Join all threads in the system thread pool. ASIO_DECL void join(); #if defined(GENERATING_DOCUMENTATION) private: #endif // defined(GENERATING_DOCUMENTATION) // Constructor creates all threads in the system thread pool. ASIO_DECL system_context(); private: friend class system_executor; struct thread_function; // Helper function to create the underlying scheduler. ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s); // The underlying scheduler. detail::scheduler& scheduler_; // The threads in the system thread pool. detail::thread_group threads_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/system_context.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/system_context.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_SYSTEM_CONTEXT_HPP ================================================ FILE: src/third_party/asio/system_error.hpp ================================================ // // system_error.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SYSTEM_ERROR_HPP #define ASIO_SYSTEM_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_STD_SYSTEM_ERROR) # include #else // defined(ASIO_HAS_STD_SYSTEM_ERROR) # include # include # include # include "asio/error_code.hpp" # include "asio/detail/scoped_ptr.hpp" #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) #include "asio/detail/push_options.hpp" namespace asio { #if defined(ASIO_HAS_STD_SYSTEM_ERROR) typedef std::system_error system_error; #else // defined(ASIO_HAS_STD_SYSTEM_ERROR) /// The system_error class is used to represent system conditions that /// prevent the library from operating correctly. class system_error : public std::exception { public: /// Construct with an error code. system_error(const error_code& ec) : code_(ec), context_() { } /// Construct with an error code and context. system_error(const error_code& ec, const std::string& context) : code_(ec), context_(context) { } /// Copy constructor. system_error(const system_error& other) : std::exception(other), code_(other.code_), context_(other.context_), what_() { } /// Destructor. virtual ~system_error() throw () { } /// Assignment operator. system_error& operator=(const system_error& e) { context_ = e.context_; code_ = e.code_; what_.reset(); return *this; } /// Get a string representation of the exception. virtual const char* what() const throw () { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) { if (!what_.get()) { std::string tmp(context_); if (tmp.length()) tmp += ": "; tmp += code_.message(); what_.reset(new std::string(tmp)); } return what_->c_str(); } #if !defined(ASIO_NO_EXCEPTIONS) catch (std::exception&) { return "system_error"; } #endif // !defined(ASIO_NO_EXCEPTIONS) } /// Get the error code associated with the exception. error_code code() const { return code_; } private: // The code associated with the error. error_code code_; // The context associated with the error. std::string context_; // The string representation of the error. mutable asio::detail::scoped_ptr what_; }; #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_SYSTEM_ERROR_HPP ================================================ FILE: src/third_party/asio/system_executor.hpp ================================================ // // system_executor.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SYSTEM_EXECUTOR_HPP #define ASIO_SYSTEM_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { class system_context; /// An executor that uses arbitrary threads. /** * The system executor represents an execution context where functions are * permitted to run on arbitrary threads. The post() and defer() functions * schedule the function to run on an unspecified system thread pool, and * dispatch() invokes the function immediately. */ class system_executor { public: /// Obtain the underlying execution context. system_context& context() const ASIO_NOEXCEPT; /// Inform the executor that it has some outstanding work to do. /** * For the system executor, this is a no-op. */ void on_work_started() const ASIO_NOEXCEPT { } /// Inform the executor that some work is no longer outstanding. /** * For the system executor, this is a no-op. */ void on_work_finished() const ASIO_NOEXCEPT { } /// Request the system executor to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object will always be executed inside this function. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the system executor to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object will never be executed inside this function. * Instead, it will be scheduled to run on an unspecified system thread pool. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the system executor to invoke the given function object. /** * This function is used to ask the executor to execute the given function * object. The function object will never be executed inside this function. * Instead, it will be scheduled to run on an unspecified system thread pool. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Compare two executors for equality. /** * System executors always compare equal. */ friend bool operator==(const system_executor&, const system_executor&) ASIO_NOEXCEPT { return true; } /// Compare two executors for inequality. /** * System executors always compare equal. */ friend bool operator!=(const system_executor&, const system_executor&) ASIO_NOEXCEPT { return false; } }; } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/system_executor.hpp" #endif // ASIO_SYSTEM_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/system_timer.hpp ================================================ // // system_timer.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_SYSTEM_TIMER_HPP #define ASIO_SYSTEM_TIMER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" namespace asio { /// Typedef for a timer based on the system clock. /** * This typedef uses the C++11 @c <chrono> standard library facility, if * available. Otherwise, it may use the Boost.Chrono library. To explicitly * utilise Boost.Chrono, use the basic_waitable_timer template directly: * @code * typedef basic_waitable_timer timer; * @endcode */ typedef basic_waitable_timer system_timer; } // namespace asio #endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_SYSTEM_TIMER_HPP ================================================ FILE: src/third_party/asio/this_coro.hpp ================================================ // // this_coro.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_THIS_CORO_HPP #define ASIO_THIS_CORO_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace this_coro { /// Awaitable type that returns the executor of the current coroutine. struct executor_t { ASIO_CONSTEXPR executor_t() { } }; /// Awaitable object that returns the executor of the current coroutine. #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr executor_t executor; #elif defined(ASIO_MSVC) __declspec(selectany) executor_t executor; #endif } // namespace this_coro } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_THIS_CORO_HPP ================================================ FILE: src/third_party/asio/thread.hpp ================================================ // // thread.hpp // ~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_THREAD_HPP #define ASIO_THREAD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// A simple abstraction for starting threads. /** * The asio::thread class implements the smallest possible subset of the * functionality of boost::thread. It is intended to be used only for starting * a thread and waiting for it to exit. If more extensive threading * capabilities are required, you are strongly advised to use something else. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Example * A typical use of asio::thread would be to launch a thread to run an * io_context's event processing loop: * * @par * @code asio::io_context io_context; * // ... * asio::thread t(boost::bind(&asio::io_context::run, &io_context)); * // ... * t.join(); @endcode */ class thread : private noncopyable { public: /// Start a new thread that executes the supplied function. /** * This constructor creates a new thread that will execute the given function * or function object. * * @param f The function or function object to be run in the thread. The * function signature must be: @code void f(); @endcode */ template explicit thread(Function f) : impl_(f) { } /// Destructor. ~thread() { } /// Wait for the thread to exit. /** * This function will block until the thread has exited. * * If this function is not called before the thread object is destroyed, the * thread itself will continue to run until completion. You will, however, * no longer have the ability to wait for it to exit. */ void join() { impl_.join(); } private: detail::thread impl_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_THREAD_HPP ================================================ FILE: src/third_party/asio/thread_pool.hpp ================================================ // // thread_pool.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_THREAD_POOL_HPP #define ASIO_THREAD_POOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/thread_group.hpp" #include "asio/execution_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// A simple fixed-size thread pool. /** * The thread pool class is an execution context where functions are permitted * to run on one of a fixed number of threads. * * @par Submitting tasks to the pool * * To submit functions to the thread_pool, use the @ref asio::dispatch, * @ref asio::post or @ref asio::defer free functions. * * For example: * * @code void my_task() * { * ... * } * * ... * * // Launch the pool with four threads. * asio::thread_pool pool(4); * * // Submit a function to the pool. * asio::post(pool, my_task); * * // Submit a lambda object to the pool. * asio::post(pool, * []() * { * ... * }); * * // Wait for all tasks in the pool to complete. * pool.join(); @endcode */ class thread_pool : public execution_context { public: class executor_type; /// Constructs a pool with an automatically determined number of threads. ASIO_DECL thread_pool(); /// Constructs a pool with a specified number of threads. ASIO_DECL thread_pool(std::size_t num_threads); /// Destructor. /** * Automatically stops and joins the pool, if not explicitly done beforehand. */ ASIO_DECL ~thread_pool(); /// Obtains the executor associated with the pool. executor_type get_executor() ASIO_NOEXCEPT; /// Stops the threads. /** * This function stops the threads as soon as possible. As a result of calling * @c stop(), pending function objects may be never be invoked. */ ASIO_DECL void stop(); /// Joins the threads. /** * This function blocks until the threads in the pool have completed. If @c * stop() is not called prior to @c join(), the @c join() call will wait * until the pool has no more outstanding work. */ ASIO_DECL void join(); private: friend class executor_type; struct thread_function; // Helper function to create the underlying scheduler. ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s); // The underlying scheduler. detail::scheduler& scheduler_; // The threads in the pool. detail::thread_group threads_; }; /// Executor used to submit functions to a thread pool. class thread_pool::executor_type { public: /// Obtain the underlying execution context. thread_pool& context() const ASIO_NOEXCEPT; /// Inform the thread pool that it has some outstanding work to do. /** * This function is used to inform the thread pool that some work has begun. * This ensures that the thread pool's join() function will not return while * the work is underway. */ void on_work_started() const ASIO_NOEXCEPT; /// Inform the thread pool that some work is no longer outstanding. /** * This function is used to inform the thread pool that some work has * finished. Once the count of unfinished work reaches zero, the thread * pool's join() function is permitted to exit. */ void on_work_finished() const ASIO_NOEXCEPT; /// Request the thread pool to invoke the given function object. /** * This function is used to ask the thread pool to execute the given function * object. If the current thread belongs to the pool, @c dispatch() executes * the function before returning. Otherwise, the function will be scheduled * to run on the thread pool. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the thread pool to invoke the given function object. /** * This function is used to ask the thread pool to execute the given function * object. The function object will never be executed inside @c post(). * Instead, it will be scheduled to run on the thread pool. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the thread pool to invoke the given function object. /** * This function is used to ask the thread pool to execute the given function * object. The function object will never be executed inside @c defer(). * Instead, it will be scheduled to run on the thread pool. * * If the current thread belongs to the thread pool, @c defer() will delay * scheduling the function object until the current thread returns control to * the pool. * * @param f The function object to be called. The executor will make * a copy of the handler object as required. The function signature of the * function object must be: @code void function(); @endcode * * @param a An allocator that may be used by the executor to allocate the * internal storage needed for function invocation. */ template void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Determine whether the thread pool is running in the current thread. /** * @return @c true if the current thread belongs to the pool. Otherwise * returns @c false. */ bool running_in_this_thread() const ASIO_NOEXCEPT; /// Compare two executors for equality. /** * Two executors are equal if they refer to the same underlying thread pool. */ friend bool operator==(const executor_type& a, const executor_type& b) ASIO_NOEXCEPT { return &a.pool_ == &b.pool_; } /// Compare two executors for inequality. /** * Two executors are equal if they refer to the same underlying thread pool. */ friend bool operator!=(const executor_type& a, const executor_type& b) ASIO_NOEXCEPT { return &a.pool_ != &b.pool_; } private: friend class thread_pool; // Constructor. explicit executor_type(thread_pool& p) : pool_(p) {} // The underlying thread pool. thread_pool& pool_; }; } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/thread_pool.hpp" #if defined(ASIO_HEADER_ONLY) # include "asio/impl/thread_pool.ipp" #endif // defined(ASIO_HEADER_ONLY) #endif // ASIO_THREAD_POOL_HPP ================================================ FILE: src/third_party/asio/time_traits.hpp ================================================ // // time_traits.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TIME_TRAITS_HPP #define ASIO_TIME_TRAITS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/socket_types.hpp" // Must come before posix_time. #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) #include #include "asio/detail/push_options.hpp" namespace asio { /// Time traits suitable for use with the deadline timer. template struct time_traits; /// Time traits specialised for posix_time. template <> struct time_traits { /// The time type. typedef boost::posix_time::ptime time_type; /// The duration type. typedef boost::posix_time::time_duration duration_type; /// Get the current time. static time_type now() { #if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) return boost::posix_time::microsec_clock::universal_time(); #else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) return boost::posix_time::second_clock::universal_time(); #endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) } /// Add a duration to a time. static time_type add(const time_type& t, const duration_type& d) { return t + d; } /// Subtract one time from another. static duration_type subtract(const time_type& t1, const time_type& t2) { return t1 - t2; } /// Test whether one time is less than another. static bool less_than(const time_type& t1, const time_type& t2) { return t1 < t2; } /// Convert to POSIX duration type. static boost::posix_time::time_duration to_posix_duration( const duration_type& d) { return d; } }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_TIME_TRAITS_HPP ================================================ FILE: src/third_party/asio/ts/buffer.hpp ================================================ // // ts/buffer.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_BUFFER_HPP #define ASIO_TS_BUFFER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/buffer.hpp" #include "asio/completion_condition.hpp" #include "asio/read.hpp" #include "asio/write.hpp" #include "asio/read_until.hpp" #endif // ASIO_TS_BUFFER_HPP ================================================ FILE: src/third_party/asio/ts/executor.hpp ================================================ // // ts/executor.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_EXECUTOR_HPP #define ASIO_TS_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/async_result.hpp" #include "asio/associated_allocator.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp" #include "asio/associated_executor.hpp" #include "asio/bind_executor.hpp" #include "asio/executor_work_guard.hpp" #include "asio/system_executor.hpp" #include "asio/executor.hpp" #include "asio/dispatch.hpp" #include "asio/post.hpp" #include "asio/defer.hpp" #include "asio/strand.hpp" #include "asio/packaged_task.hpp" #include "asio/use_future.hpp" #endif // ASIO_TS_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/ts/internet.hpp ================================================ // // ts/internet.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_INTERNET_HPP #define ASIO_TS_INTERNET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/ip/address.hpp" #include "asio/ip/address_v4.hpp" #include "asio/ip/address_v4_iterator.hpp" #include "asio/ip/address_v4_range.hpp" #include "asio/ip/address_v6.hpp" #include "asio/ip/address_v6_iterator.hpp" #include "asio/ip/address_v6_range.hpp" #include "asio/ip/bad_address_cast.hpp" #include "asio/ip/basic_endpoint.hpp" #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/basic_resolver_entry.hpp" #include "asio/ip/basic_resolver_iterator.hpp" #include "asio/ip/basic_resolver.hpp" #include "asio/ip/host_name.hpp" #include "asio/ip/network_v4.hpp" #include "asio/ip/network_v6.hpp" #include "asio/ip/tcp.hpp" #include "asio/ip/udp.hpp" #include "asio/ip/v6_only.hpp" #include "asio/ip/unicast.hpp" #include "asio/ip/multicast.hpp" #endif // ASIO_TS_INTERNET_HPP ================================================ FILE: src/third_party/asio/ts/io_context.hpp ================================================ // // ts/io_context.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_IO_CONTEXT_HPP #define ASIO_TS_IO_CONTEXT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/io_context.hpp" #endif // ASIO_TS_IO_CONTEXT_HPP ================================================ FILE: src/third_party/asio/ts/net.hpp ================================================ // // ts/net.hpp // ~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_NET_HPP #define ASIO_TS_NET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/ts/netfwd.hpp" #include "asio/ts/executor.hpp" #include "asio/ts/io_context.hpp" #include "asio/ts/timer.hpp" #include "asio/ts/buffer.hpp" #include "asio/ts/socket.hpp" #include "asio/ts/internet.hpp" #endif // ASIO_TS_NET_HPP ================================================ FILE: src/third_party/asio/ts/netfwd.hpp ================================================ // // ts/netfwd.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_NETFWD_HPP #define ASIO_TS_NETFWD_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CHRONO) # include "asio/detail/chrono.hpp" #endif // defined(ASIO_HAS_CHRONO) #if defined(ASIO_HAS_BOOST_DATE_TIME) # include "asio/detail/date_time_fwd.hpp" #endif // defined(ASIO_HAS_BOOST_DATE_TIME) #if !defined(GENERATING_DOCUMENTATION) #include "asio/detail/push_options.hpp" namespace asio { class execution_context; template class executor_binder; template class executor_work_guard; class system_executor; class executor; template class strand; class io_context; template struct wait_traits; #if defined(ASIO_HAS_BOOST_DATE_TIME) template struct time_traits; #endif // defined(ASIO_HAS_BOOST_DATE_TIME) #if !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) #define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL template , typename Executor = executor> class basic_waitable_timer; #endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) #if defined(ASIO_HAS_CHRONO) typedef basic_waitable_timer system_timer; typedef basic_waitable_timer steady_timer; typedef basic_waitable_timer high_resolution_timer; #endif // defined(ASIO_HAS_CHRONO) #if !defined(ASIO_BASIC_SOCKET_FWD_DECL) #define ASIO_BASIC_SOCKET_FWD_DECL template class basic_socket; #endif // !defined(ASIO_BASIC_SOCKET_FWD_DECL) #if !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) #define ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL template class basic_datagram_socket; #endif // !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) #if !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL) #define ASIO_BASIC_STREAM_SOCKET_FWD_DECL // Forward declaration with defaulted arguments. template class basic_stream_socket; #endif // !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL) #if !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) #define ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL template class basic_socket_acceptor; #endif // !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) #if !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) #define ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL // Forward declaration with defaulted arguments. template > #else typename Clock = chrono::steady_clock, typename WaitTraits = wait_traits > #endif class basic_socket_streambuf; #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL) #if !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) #define ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL // Forward declaration with defaulted arguments. template > #else typename Clock = chrono::steady_clock, typename WaitTraits = wait_traits > #endif class basic_socket_iostream; #endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) namespace ip { class address; class address_v4; class address_v6; template class basic_address_iterator; typedef basic_address_iterator address_v4_iterator; typedef basic_address_iterator address_v6_iterator; template class basic_address_range; typedef basic_address_range address_v4_range; typedef basic_address_range address_v6_range; class network_v4; class network_v6; template class basic_endpoint; template class basic_resolver_entry; template class basic_resolver_results; #if !defined(ASIO_IP_BASIC_RESOLVER_FWD_DECL) #define ASIO_IP_BASIC_RESOLVER_FWD_DECL template class basic_resolver; #endif // !defined(ASIO_IP_BASIC_RESOLVER_FWD_DECL) class tcp; class udp; } // namespace ip } // namespace asio #include "asio/detail/pop_options.hpp" #endif // !defined(GENERATING_DOCUMENTATION) #endif // ASIO_TS_NETFWD_HPP ================================================ FILE: src/third_party/asio/ts/socket.hpp ================================================ // // ts/socket.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_SOCKET_HPP #define ASIO_TS_SOCKET_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/socket_base.hpp" #include "asio/basic_socket.hpp" #include "asio/basic_datagram_socket.hpp" #include "asio/basic_stream_socket.hpp" #include "asio/basic_socket_acceptor.hpp" #include "asio/basic_socket_streambuf.hpp" #include "asio/basic_socket_iostream.hpp" #include "asio/connect.hpp" #endif // ASIO_TS_SOCKET_HPP ================================================ FILE: src/third_party/asio/ts/timer.hpp ================================================ // // ts/timer.hpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_TS_TIMER_HPP #define ASIO_TS_TIMER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/chrono.hpp" #include "asio/wait_traits.hpp" #include "asio/basic_waitable_timer.hpp" #include "asio/system_timer.hpp" #include "asio/steady_timer.hpp" #include "asio/high_resolution_timer.hpp" #endif // ASIO_TS_TIMER_HPP ================================================ FILE: src/third_party/asio/unyield.hpp ================================================ // // unyield.hpp // ~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifdef reenter # undef reenter #endif #ifdef yield # undef yield #endif #ifdef fork # undef fork #endif ================================================ FILE: src/third_party/asio/use_awaitable.hpp ================================================ // // use_awaitable.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_USE_AWAITABLE_HPP #define ASIO_USE_AWAITABLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) #include "asio/awaitable.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// A completion token that represents the currently executing coroutine. /** * The @c use_awaitable_t class, with its value @c use_awaitable, is used to * represent the currently executing coroutine. This completion token may be * passed as a handler to an asynchronous operation. For example: * * @code awaitable my_coroutine() * { * std::size_t n = co_await my_socket.async_read_some(buffer, use_awaitable); * ... * } @endcode * * When used with co_await, the initiating function (@c async_read_some in the * above example) suspends the current coroutine. The coroutine is resumed when * the asynchronous operation completes, and the result of the operation is * returned. */ template struct use_awaitable_t { /// Default constructor. ASIO_CONSTEXPR use_awaitable_t() { } /// Adapts an executor to add the @c use_awaitable_t completion token as the /// default. template struct executor_with_default : InnerExecutor { /// Specify @c use_awaitable_t as the default completion token type. typedef use_awaitable_t default_completion_token_type; /// Construct the adapted executor from the inner executor type. executor_with_default(const InnerExecutor& ex) ASIO_NOEXCEPT : InnerExecutor(ex) { } }; /// Type alias to adapt an I/O object to use @c use_awaitable_t as its /// default completion token type. #if defined(ASIO_HAS_ALIAS_TEMPLATES) \ || defined(GENERATING_DOCUMENTATION) template using as_default_on_t = typename T::template rebind_executor< executor_with_default >::other; #endif // defined(ASIO_HAS_ALIAS_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) /// Function helper to adapt an I/O object to use @c use_awaitable_t as its /// default completion token type. template static typename T::template rebind_executor< executor_with_default >::other as_default_on(ASIO_MOVE_ARG(T) object) { return typename as_default_on_t::type>::type( ASIO_MOVE_CAST(T)(object)); } }; /// A completion token object that represents the currently executing coroutine. /** * See the documentation for asio::use_awaitable_t for a usage example. */ #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr use_awaitable_t<> use_awaitable; #elif defined(ASIO_MSVC) __declspec(selectany) use_awaitable_t<> use_awaitable; #endif } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/use_awaitable.hpp" #endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_USE_AWAITABLE_HPP ================================================ FILE: src/third_party/asio/use_future.hpp ================================================ // // use_future.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_USE_FUTURE_HPP #define ASIO_USE_FUTURE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/future.hpp" #if defined(ASIO_HAS_STD_FUTURE_CLASS) \ || defined(GENERATING_DOCUMENTATION) #include #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class packaged_token; template class packaged_handler; } // namespace detail /// Class used to specify that an asynchronous operation should return a future. /** * The use_future_t class is used to indicate that an asynchronous operation * should return a std::future object. A use_future_t object may be passed as a * handler to an asynchronous operation, typically using the special value @c * asio::use_future. For example: * * @code std::future my_future * = my_socket.async_read_some(my_buffer, asio::use_future); @endcode * * The initiating function (async_read_some in the above example) returns a * future that will receive the result of the operation. If the operation * completes with an error_code indicating failure, it is converted into a * system_error and passed back to the caller via the future. */ template > class use_future_t { public: /// The allocator type. The allocator is used when constructing the /// @c std::promise object for a given asynchronous operation. typedef Allocator allocator_type; /// Construct using default-constructed allocator. ASIO_CONSTEXPR use_future_t() { } /// Construct using specified allocator. explicit use_future_t(const Allocator& allocator) : allocator_(allocator) { } #if !defined(ASIO_NO_DEPRECATED) /// (Deprecated: Use rebind().) Specify an alternate allocator. template use_future_t operator[](const OtherAllocator& allocator) const { return use_future_t(allocator); } #endif // !defined(ASIO_NO_DEPRECATED) /// Specify an alternate allocator. template use_future_t rebind(const OtherAllocator& allocator) const { return use_future_t(allocator); } /// Obtain allocator. allocator_type get_allocator() const { return allocator_; } /// Wrap a function object in a packaged task. /** * The @c package function is used to adapt a function object as a packaged * task. When this adapter is passed as a completion token to an asynchronous * operation, the result of the function object is retuned via a std::future. * * @par Example * * @code std::future fut = * my_socket.async_read_some(buffer, * use_future([](asio::error_code ec, std::size_t n) * { * return ec ? 0 : n; * })); * ... * std::size_t n = fut.get(); @endcode */ template #if defined(GENERATING_DOCUMENTATION) unspecified #else // defined(GENERATING_DOCUMENTATION) detail::packaged_token::type, Allocator> #endif // defined(GENERATING_DOCUMENTATION) operator()(ASIO_MOVE_ARG(Function) f) const; private: // Helper type to ensure that use_future can be constexpr default-constructed // even when std::allocator can't be. struct std_allocator_void { ASIO_CONSTEXPR std_allocator_void() { } operator std::allocator() const { return std::allocator(); } }; typename conditional< is_same, Allocator>::value, std_allocator_void, Allocator>::type allocator_; }; /// A special value, similar to std::nothrow. /** * See the documentation for asio::use_future_t for a usage example. */ #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr use_future_t<> use_future; #elif defined(ASIO_MSVC) __declspec(selectany) use_future_t<> use_future; #endif } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/use_future.hpp" #endif // defined(ASIO_HAS_STD_FUTURE_CLASS) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_USE_FUTURE_HPP ================================================ FILE: src/third_party/asio/uses_executor.hpp ================================================ // // uses_executor.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_USES_EXECUTOR_HPP #define ASIO_USES_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { /// A special type, similar to std::nothrow_t, used to disambiguate /// constructors that accept executor arguments. /** * The executor_arg_t struct is an empty structure type used as a unique type * to disambiguate constructor and function overloading. Specifically, some * types have constructors with executor_arg_t as the first argument, * immediately followed by an argument of a type that satisfies the Executor * type requirements. */ struct executor_arg_t { /// Constructor. ASIO_CONSTEXPR executor_arg_t() ASIO_NOEXCEPT { } }; /// A special value, similar to std::nothrow, used to disambiguate constructors /// that accept executor arguments. /** * See asio::executor_arg_t and asio::uses_executor * for more information. */ #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr executor_arg_t executor_arg; #elif defined(ASIO_MSVC) __declspec(selectany) executor_arg_t executor_arg; #endif /// The uses_executor trait detects whether a type T has an associated executor /// that is convertible from type Executor. /** * Meets the BinaryTypeTrait requirements. The Asio library provides a * definition that is derived from false_type. A program may specialize this * template to derive from true_type for a user-defined type T that can be * constructed with an executor, where the first argument of a constructor has * type executor_arg_t and the second argument is convertible from type * Executor. */ template struct uses_executor : false_type {}; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_USES_EXECUTOR_HPP ================================================ FILE: src/third_party/asio/version.hpp ================================================ // // version.hpp // ~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_VERSION_HPP #define ASIO_VERSION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) // ASIO_VERSION % 100 is the sub-minor version // ASIO_VERSION / 100 % 1000 is the minor version // ASIO_VERSION / 100000 is the major version #define ASIO_VERSION 101401 // 1.14.1 #endif // ASIO_VERSION_HPP ================================================ FILE: src/third_party/asio/wait_traits.hpp ================================================ // // wait_traits.hpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WAIT_TRAITS_HPP #define ASIO_WAIT_TRAITS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/push_options.hpp" namespace asio { /// Wait traits suitable for use with the basic_waitable_timer class template. template struct wait_traits { /// Convert a clock duration into a duration used for waiting. /** * @returns @c d. */ static typename Clock::duration to_wait_duration( const typename Clock::duration& d) { return d; } /// Convert a clock duration into a duration used for waiting. /** * @returns @c d. */ static typename Clock::duration to_wait_duration( const typename Clock::time_point& t) { typename Clock::time_point now = Clock::now(); if (now + (Clock::duration::max)() < t) return (Clock::duration::max)(); if (now + (Clock::duration::min)() > t) return (Clock::duration::min)(); return t - now; } }; } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_WAIT_TRAITS_HPP ================================================ FILE: src/third_party/asio/windows/basic_object_handle.hpp ================================================ // // windows/basic_object_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP #define ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include "asio/async_result.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/win_object_handle_service.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { namespace windows { /// Provides object-oriented handle functionality. /** * The windows::basic_object_handle class provides asynchronous and blocking * object-oriented handle functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_object_handle { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the handle type to another executor. template struct rebind_executor { /// The handle type when rebound to the specified executor. typedef basic_object_handle other; }; /// The native representation of a handle. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef asio::detail::win_object_handle_service::native_handle_type native_handle_type; #endif /// An object handle is always the lowest layer. typedef basic_object_handle lowest_layer_type; /// Construct an object handle without opening it. /** * This constructor creates an object handle without opening it. * * @param ex The I/O executor that the object handle will use, by default, to * dispatch handlers for any asynchronous operations performed on the * object handle. */ explicit basic_object_handle(const executor_type& ex) : impl_(ex) { } /// Construct an object handle without opening it. /** * This constructor creates an object handle without opening it. * * @param context An execution context which provides the I/O executor that * the object handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the object handle. */ template explicit basic_object_handle(ExecutionContext& context, typename enable_if< is_convertible::value, basic_object_handle >::type* = 0) : impl_(context) { } /// Construct an object handle on an existing native handle. /** * This constructor creates an object handle object to hold an existing native * handle. * * @param ex The I/O executor that the object handle will use, by default, to * dispatch handlers for any asynchronous operations performed on the * object handle. * * @param native_handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ basic_object_handle(const executor_type& ex, const native_handle_type& native_handle) : impl_(ex) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_handle, ec); asio::detail::throw_error(ec, "assign"); } /// Construct an object handle on an existing native handle. /** * This constructor creates an object handle object to hold an existing native * handle. * * @param context An execution context which provides the I/O executor that * the object handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the object handle. * * @param native_handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ template basic_object_handle(ExecutionContext& context, const native_handle_type& native_handle, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_handle, ec); asio::detail::throw_error(ec, "assign"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct an object handle from another. /** * This constructor moves an object handle from one object to another. * * @param other The other object handle object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_object_handle(const executor_type&) * constructor. */ basic_object_handle(basic_object_handle&& other) : impl_(std::move(other.impl_)) { } /// Move-assign an object handle from another. /** * This assignment operator moves an object handle from one object to another. * * @param other The other object handle object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_object_handle(const executor_type&) * constructor. */ basic_object_handle& operator=(basic_object_handle&& other) { impl_ = std::move(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of * layers. Since an object handle cannot contain any further layers, it simply * returns a reference to itself. * * @return A reference to the lowest layer in the stack of layers. Ownership * is not transferred to the caller. */ lowest_layer_type& lowest_layer() { return *this; } /// Get a const reference to the lowest layer. /** * This function returns a const reference to the lowest layer in a stack of * layers. Since an object handle cannot contain any further layers, it simply * returns a reference to itself. * * @return A const reference to the lowest layer in the stack of layers. * Ownership is not transferred to the caller. */ const lowest_layer_type& lowest_layer() const { return *this; } /// Assign an existing native handle to the handle. /* * This function opens the handle to hold an existing native handle. * * @param handle A native handle. * * @throws asio::system_error Thrown on failure. */ void assign(const native_handle_type& handle) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), handle, ec); asio::detail::throw_error(ec, "assign"); } /// Assign an existing native handle to the handle. /* * This function opens the handle to hold an existing native handle. * * @param handle A native handle. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, asio::error_code& ec) { impl_.get_service().assign(impl_.get_implementation(), handle, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the handle is open. bool is_open() const { return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the handle. /** * This function is used to close the handle. Any asynchronous read or write * operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void close() { asio::error_code ec; impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } /// Close the handle. /** * This function is used to close the handle. Any asynchronous read or write * operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID close(asio::error_code& ec) { impl_.get_service().close(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the native handle representation. /** * This function may be used to obtain the underlying representation of the * handle. This is intended to allow access to native handle functionality * that is not otherwise provided. */ native_handle_type native_handle() { return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the handle. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void cancel() { asio::error_code ec; impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } /// Cancel all asynchronous operations associated with the handle. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { impl_.get_service().cancel(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform a blocking wait on the object handle. /** * This function is used to wait for the object handle to be set to the * signalled state. This function blocks and does not return until the object * handle has been set to the signalled state. * * @throws asio::system_error Thrown on failure. */ void wait() { asio::error_code ec; impl_.get_service().wait(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "wait"); } /// Perform a blocking wait on the object handle. /** * This function is used to wait for the object handle to be set to the * signalled state. This function blocks and does not return until the object * handle has been set to the signalled state. * * @param ec Set to indicate what error occurred, if any. */ void wait(asio::error_code& ec) { impl_.get_service().wait(impl_.get_implementation(), ec); } /// Start an asynchronous wait on the object handle. /** * This function is be used to initiate an asynchronous wait against the * object handle. It always returns immediately. * * @param handler The handler to be called when the object handle is set to * the signalled state. Copies will be made of the handler as required. The * function signature of the handler must be: * @code void handler( * const asio::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (asio::error_code)) async_wait( ASIO_MOVE_ARG(WaitHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_wait(this), handler); } private: // Disallow copying and assignment. basic_object_handle(const basic_object_handle&) ASIO_DELETED; basic_object_handle& operator=(const basic_object_handle&) ASIO_DELETED; class initiate_async_wait { public: typedef Executor executor_type; explicit initiate_async_wait(basic_object_handle* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler. ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_wait( self_->impl_.get_implementation(), handler2.value, self_->impl_.get_implementation_executor()); } private: basic_object_handle* self_; }; asio::detail::io_object_impl< asio::detail::win_object_handle_service, Executor> impl_; }; } // namespace windows } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP ================================================ FILE: src/third_party/asio/windows/basic_overlapped_handle.hpp ================================================ // // windows/basic_overlapped_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP #define ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include #include "asio/async_result.hpp" #include "asio/detail/io_object_impl.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/win_iocp_handle_service.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #if defined(ASIO_HAS_MOVE) # include #endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" namespace asio { namespace windows { /// Provides Windows handle functionality for objects that support /// overlapped I/O. /** * The windows::overlapped_handle class provides the ability to wrap a Windows * handle. The underlying object referred to by the handle must support * overlapped I/O. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_overlapped_handle { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the handle type to another executor. template struct rebind_executor { /// The handle type when rebound to the specified executor. typedef basic_overlapped_handle other; }; /// The native representation of a handle. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef asio::detail::win_iocp_handle_service::native_handle_type native_handle_type; #endif /// An overlapped_handle is always the lowest layer. typedef basic_overlapped_handle lowest_layer_type; /// Construct an overlapped handle without opening it. /** * This constructor creates an overlapped handle without opening it. * * @param ex The I/O executor that the overlapped handle will use, by default, * to dispatch handlers for any asynchronous operations performed on the * overlapped handle. */ explicit basic_overlapped_handle(const executor_type& ex) : impl_(ex) { } /// Construct an overlapped handle without opening it. /** * This constructor creates an overlapped handle without opening it. * * @param context An execution context which provides the I/O executor that * the overlapped handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the overlapped handle. */ template explicit basic_overlapped_handle(ExecutionContext& context, typename enable_if< is_convertible::value, basic_overlapped_handle >::type* = 0) : impl_(context) { } /// Construct an overlapped handle on an existing native handle. /** * This constructor creates an overlapped handle object to hold an existing * native handle. * * @param ex The I/O executor that the overlapped handle will use, by default, * to dispatch handlers for any asynchronous operations performed on the * overlapped handle. * * @param native_handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ basic_overlapped_handle(const executor_type& ex, const native_handle_type& native_handle) : impl_(ex) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_handle, ec); asio::detail::throw_error(ec, "assign"); } /// Construct an overlapped handle on an existing native handle. /** * This constructor creates an overlapped handle object to hold an existing * native handle. * * @param context An execution context which provides the I/O executor that * the overlapped handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the overlapped handle. * * @param native_handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ template basic_overlapped_handle(ExecutionContext& context, const native_handle_type& native_handle, typename enable_if< is_convertible::value >::type* = 0) : impl_(context) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), native_handle, ec); asio::detail::throw_error(ec, "assign"); } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct an overlapped handle from another. /** * This constructor moves a handle from one object to another. * * @param other The other overlapped handle object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c overlapped_handle(const executor_type&) * constructor. */ basic_overlapped_handle(basic_overlapped_handle&& other) : impl_(std::move(other.impl_)) { } /// Move-assign an overlapped handle from another. /** * This assignment operator moves a handle from one object to another. * * @param other The other overlapped handle object from which the move will * occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c overlapped_handle(const executor_type&) * constructor. */ basic_overlapped_handle& operator=(basic_overlapped_handle&& other) { impl_ = std::move(other.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object. executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); } /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of * layers. Since an overlapped_handle cannot contain any further layers, it * simply returns a reference to itself. * * @return A reference to the lowest layer in the stack of layers. Ownership * is not transferred to the caller. */ lowest_layer_type& lowest_layer() { return *this; } /// Get a const reference to the lowest layer. /** * This function returns a const reference to the lowest layer in a stack of * layers. Since an overlapped_handle cannot contain any further layers, it * simply returns a reference to itself. * * @return A const reference to the lowest layer in the stack of layers. * Ownership is not transferred to the caller. */ const lowest_layer_type& lowest_layer() const { return *this; } /// Assign an existing native handle to the handle. /* * This function opens the handle to hold an existing native handle. * * @param handle A native handle. * * @throws asio::system_error Thrown on failure. */ void assign(const native_handle_type& handle) { asio::error_code ec; impl_.get_service().assign(impl_.get_implementation(), handle, ec); asio::detail::throw_error(ec, "assign"); } /// Assign an existing native handle to the handle. /* * This function opens the handle to hold an existing native handle. * * @param handle A native handle. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, asio::error_code& ec) { impl_.get_service().assign(impl_.get_implementation(), handle, ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the handle is open. bool is_open() const { return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the handle. /** * This function is used to close the handle. Any asynchronous read or write * operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void close() { asio::error_code ec; impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } /// Close the handle. /** * This function is used to close the handle. Any asynchronous read or write * operations will be cancelled immediately, and will complete with the * asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID close(asio::error_code& ec) { impl_.get_service().close(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the native handle representation. /** * This function may be used to obtain the underlying representation of the * handle. This is intended to allow access to native handle functionality * that is not otherwise provided. */ native_handle_type native_handle() { return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the handle. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @throws asio::system_error Thrown on failure. */ void cancel() { asio::error_code ec; impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } /// Cancel all asynchronous operations associated with the handle. /** * This function causes all outstanding asynchronous read or write operations * to finish immediately, and the handlers for cancelled operations will be * passed the asio::error::operation_aborted error. * * @param ec Set to indicate what error occurred, if any. */ ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { impl_.get_service().cancel(impl_.get_implementation(), ec); ASIO_SYNC_OP_VOID_RETURN(ec); } protected: /// Protected destructor to prevent deletion through this type. /** * This function destroys the handle, cancelling any outstanding asynchronous * wait operations associated with the handle as if by calling @c cancel. */ ~basic_overlapped_handle() { } asio::detail::io_object_impl< asio::detail::win_iocp_handle_service, Executor> impl_; private: // Disallow copying and assignment. basic_overlapped_handle(const basic_overlapped_handle&) ASIO_DELETED; basic_overlapped_handle& operator=( const basic_overlapped_handle&) ASIO_DELETED; }; } // namespace windows } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP ================================================ FILE: src/third_party/asio/windows/basic_random_access_handle.hpp ================================================ // // windows/basic_random_access_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP #define ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/windows/basic_overlapped_handle.hpp" #if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include "asio/detail/push_options.hpp" namespace asio { namespace windows { /// Provides random-access handle functionality. /** * The windows::basic_random_access_handle class provides asynchronous and * blocking random-access handle functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ template class basic_random_access_handle : public basic_overlapped_handle { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the handle type to another executor. template struct rebind_executor { /// The handle type when rebound to the specified executor. typedef basic_random_access_handle other; }; /// The native representation of a handle. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef asio::detail::win_iocp_handle_service::native_handle_type native_handle_type; #endif /// Construct a random-access handle without opening it. /** * This constructor creates a random-access handle without opening it. * * @param ex The I/O executor that the random-access handle will use, by * default, to dispatch handlers for any asynchronous operations performed on * the random-access handle. */ explicit basic_random_access_handle(const executor_type& ex) : basic_overlapped_handle(ex) { } /// Construct a random-access handle without opening it. /** * This constructor creates a random-access handle without opening it. The * handle needs to be opened or assigned before data can be sent or received * on it. * * @param context An execution context which provides the I/O executor that * the random-access handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the random-access handle. */ template explicit basic_random_access_handle(ExecutionContext& context, typename enable_if< is_convertible::value, basic_random_access_handle >::type* = 0) : basic_overlapped_handle(context) { } /// Construct a random-access handle on an existing native handle. /** * This constructor creates a random-access handle object to hold an existing * native handle. * * @param ex The I/O executor that the random-access handle will use, by * default, to dispatch handlers for any asynchronous operations performed on * the random-access handle. * * @param handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ basic_random_access_handle(const executor_type& ex, const native_handle_type& handle) : basic_overlapped_handle(ex, handle) { } /// Construct a random-access handle on an existing native handle. /** * This constructor creates a random-access handle object to hold an existing * native handle. * * @param context An execution context which provides the I/O executor that * the random-access handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the random-access handle. * * @param handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ template basic_random_access_handle(ExecutionContext& context, const native_handle_type& handle, typename enable_if< is_convertible::value >::type* = 0) : basic_overlapped_handle(context, handle) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a random-access handle from another. /** * This constructor moves a random-access handle from one object to another. * * @param other The other random-access handle object from which the * move will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_random_access_handle(const executor_type&) * constructor. */ basic_random_access_handle(basic_random_access_handle&& other) : basic_overlapped_handle(std::move(other)) { } /// Move-assign a random-access handle from another. /** * This assignment operator moves a random-access handle from one object to * another. * * @param other The other random-access handle object from which the * move will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_random_access_handle(const executor_type&) * constructor. */ basic_random_access_handle& operator=(basic_random_access_handle&& other) { basic_overlapped_handle::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Write some data to the handle at the specified offset. /** * This function is used to write data to the random-access handle. The * function call will block until one or more bytes of the data has been * written successfully, or until an error occurs. * * @param offset The offset at which the data will be written. * * @param buffers One or more data buffers to be written to the handle. * * @returns The number of bytes written. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The write_some_at operation may not write all of the data. Consider * using the @ref write_at function if you need to ensure that all data is * written before the blocking operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * handle.write_some_at(42, asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t write_some_at(uint64_t offset, const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().write_some_at( this->impl_.get_implementation(), offset, buffers, ec); asio::detail::throw_error(ec, "write_some_at"); return s; } /// Write some data to the handle at the specified offset. /** * This function is used to write data to the random-access handle. The * function call will block until one or more bytes of the data has been * written successfully, or until an error occurs. * * @param offset The offset at which the data will be written. * * @param buffers One or more data buffers to be written to the handle. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write_at function if you need to ensure that * all data is written before the blocking operation completes. */ template std::size_t write_some_at(uint64_t offset, const ConstBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().write_some_at( this->impl_.get_implementation(), offset, buffers, ec); } /// Start an asynchronous write at the specified offset. /** * This function is used to asynchronously write data to the random-access * handle. The function call always returns immediately. * * @param offset The offset at which the data will be written. * * @param buffers One or more data buffers to be written to the handle. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The write operation may not transmit all of the data to the peer. * Consider using the @ref async_write_at function if you need to ensure that * all data is written before the asynchronous operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * handle.async_write_some_at(42, asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some_at(uint64_t offset, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_write_some_at(this), handler, offset, buffers); } /// Read some data from the handle at the specified offset. /** * This function is used to read data from the random-access handle. The * function call will block until one or more bytes of data has been read * successfully, or until an error occurs. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. * * @returns The number of bytes read. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read_at function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * handle.read_some_at(42, asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t read_some_at(uint64_t offset, const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().read_some_at( this->impl_.get_implementation(), offset, buffers, ec); asio::detail::throw_error(ec, "read_some_at"); return s; } /// Read some data from the handle at the specified offset. /** * This function is used to read data from the random-access handle. The * function call will block until one or more bytes of data has been read * successfully, or until an error occurs. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read_at function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. */ template std::size_t read_some_at(uint64_t offset, const MutableBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().read_some_at( this->impl_.get_implementation(), offset, buffers, ec); } /// Start an asynchronous read at the specified offset. /** * This function is used to asynchronously read data from the random-access * handle. The function call always returns immediately. * * @param offset The offset at which the data will be read. * * @param buffers One or more buffers into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The read operation may not read all of the requested number of bytes. * Consider using the @ref async_read_at function if you need to ensure that * the requested amount of data is read before the asynchronous operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * handle.async_read_some_at(42, asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some_at(uint64_t offset, const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_read_some_at(this), handler, offset, buffers); } private: class initiate_async_write_some_at { public: typedef Executor executor_type; explicit initiate_async_write_some_at(basic_random_access_handle* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, uint64_t offset, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_write_some_at( self_->impl_.get_implementation(), offset, buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_random_access_handle* self_; }; class initiate_async_read_some_at { public: typedef Executor executor_type; explicit initiate_async_read_some_at(basic_random_access_handle* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, uint64_t offset, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_read_some_at( self_->impl_.get_implementation(), offset, buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_random_access_handle* self_; }; }; } // namespace windows } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP ================================================ FILE: src/third_party/asio/windows/basic_stream_handle.hpp ================================================ // // windows/basic_stream_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP #define ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/windows/basic_overlapped_handle.hpp" #if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include "asio/detail/push_options.hpp" namespace asio { namespace windows { /// Provides stream-oriented handle functionality. /** * The windows::basic_stream_handle class provides asynchronous and blocking * stream-oriented handle functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template class basic_stream_handle : public basic_overlapped_handle { public: /// The type of the executor associated with the object. typedef Executor executor_type; /// Rebinds the handle type to another executor. template struct rebind_executor { /// The handle type when rebound to the specified executor. typedef basic_stream_handle other; }; /// The native representation of a handle. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined native_handle_type; #else typedef asio::detail::win_iocp_handle_service::native_handle_type native_handle_type; #endif /// Construct a stream handle without opening it. /** * This constructor creates a stream handle without opening it. * * @param ex The I/O executor that the stream handle will use, by default, to * dispatch handlers for any asynchronous operations performed on the stream * handle. */ explicit basic_stream_handle(const executor_type& ex) : basic_overlapped_handle(ex) { } /// Construct a stream handle without opening it. /** * This constructor creates a stream handle without opening it. The handle * needs to be opened or assigned before data can be sent or received on it. * * @param context An execution context which provides the I/O executor that * the stream handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the stream handle. */ template explicit basic_stream_handle(ExecutionContext& context, typename enable_if< is_convertible::value, basic_stream_handle >::type* = 0) : basic_overlapped_handle(context) { } /// Construct a stream handle on an existing native handle. /** * This constructor creates a stream handle object to hold an existing native * handle. * * @param ex The I/O executor that the stream handle will use, by default, to * dispatch handlers for any asynchronous operations performed on the stream * handle. * * @param handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ basic_stream_handle(const executor_type& ex, const native_handle_type& handle) : basic_overlapped_handle(ex, handle) { } /// Construct a stream handle on an existing native handle. /** * This constructor creates a stream handle object to hold an existing native * handle. * * @param context An execution context which provides the I/O executor that * the stream handle will use, by default, to dispatch handlers for any * asynchronous operations performed on the stream handle. * * @param handle The new underlying handle implementation. * * @throws asio::system_error Thrown on failure. */ template basic_stream_handle(ExecutionContext& context, const native_handle_type& handle, typename enable_if< is_convertible::value >::type* = 0) : basic_overlapped_handle(context, handle) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a stream handle from another. /** * This constructor moves a stream handle from one object to another. * * @param other The other stream handle object from which the move * will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_handle(const executor_type&) * constructor. */ basic_stream_handle(basic_stream_handle&& other) : basic_overlapped_handle(std::move(other)) { } /// Move-assign a stream handle from another. /** * This assignment operator moves a stream handle from one object to * another. * * @param other The other stream handle object from which the move will occur. * * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_stream_handle(const executor_type&) * constructor. */ basic_stream_handle& operator=(basic_stream_handle&& other) { basic_overlapped_handle::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Write some data to the handle. /** * This function is used to write data to the stream handle. The function call * will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the handle. * * @returns The number of bytes written. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * handle.write_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t write_some(const ConstBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().write_some( this->impl_.get_implementation(), buffers, ec); asio::detail::throw_error(ec, "write_some"); return s; } /// Write some data to the handle. /** * This function is used to write data to the stream handle. The function call * will block until one or more bytes of the data has been written * successfully, or until an error occurs. * * @param buffers One or more data buffers to be written to the handle. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. */ template std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().write_some( this->impl_.get_implementation(), buffers, ec); } /// Start an asynchronous write. /** * This function is used to asynchronously write data to the stream handle. * The function call always returns immediately. * * @param buffers One or more data buffers to be written to the handle. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The write operation may not transmit all of the data to the peer. * Consider using the @ref async_write function if you need to ensure that all * data is written before the asynchronous operation completes. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * handle.async_write_some(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_write_some(this), handler, buffers); } /// Read some data from the handle. /** * This function is used to read data from the stream handle. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @returns The number of bytes read. * * @throws asio::system_error Thrown on failure. An error code of * asio::error::eof indicates that the connection was closed by the * peer. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * handle.read_some(asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t read_some(const MutableBufferSequence& buffers) { asio::error_code ec; std::size_t s = this->impl_.get_service().read_some( this->impl_.get_implementation(), buffers, ec); asio::detail::throw_error(ec, "read_some"); return s; } /// Read some data from the handle. /** * This function is used to read data from the stream handle. The function * call will block until one or more bytes of data has been read successfully, * or until an error occurs. * * @param buffers One or more buffers into which the data will be read. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. */ template std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { return this->impl_.get_service().read_some( this->impl_.get_implementation(), buffers, ec); } /// Start an asynchronous read. /** * This function is used to asynchronously read data from the stream handle. * The function call always returns immediately. * * @param buffers One or more buffers into which the data will be read. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the read operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @note The read operation may not read all of the requested number of bytes. * Consider using the @ref async_read function if you need to ensure that the * requested amount of data is read before the asynchronous operation * completes. * * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code * handle.async_read_some(asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, void (asio::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) { return async_initiate( initiate_async_read_some(this), handler, buffers); } private: class initiate_async_write_some { public: typedef Executor executor_type; explicit initiate_async_write_some(basic_stream_handle* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_write_some( self_->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_stream_handle* self_; }; class initiate_async_read_some { public: typedef Executor executor_type; explicit initiate_async_read_some(basic_stream_handle* self) : self_(self) { } executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; detail::non_const_lvalue handler2(handler); self_->impl_.get_service().async_read_some( self_->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation_executor()); } private: basic_stream_handle* self_; }; }; } // namespace windows } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP ================================================ FILE: src/third_party/asio/windows/object_handle.hpp ================================================ // // windows/object_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_OBJECT_HANDLE_HPP #define ASIO_WINDOWS_OBJECT_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include "asio/windows/basic_object_handle.hpp" namespace asio { namespace windows { /// Typedef for the typical usage of an object handle. typedef basic_object_handle<> object_handle; } // namespace windows } // namespace asio #endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_OBJECT_HANDLE_HPP ================================================ FILE: src/third_party/asio/windows/overlapped_handle.hpp ================================================ // // windows/overlapped_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP #define ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include "asio/windows/basic_overlapped_handle.hpp" namespace asio { namespace windows { /// Typedef for the typical usage of an overlapped handle. typedef basic_overlapped_handle<> overlapped_handle; } // namespace windows } // namespace asio #endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP ================================================ FILE: src/third_party/asio/windows/overlapped_ptr.hpp ================================================ // // windows/overlapped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_OVERLAPPED_PTR_HPP #define ASIO_WINDOWS_OVERLAPPED_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \ || defined(GENERATING_DOCUMENTATION) #include "asio/detail/noncopyable.hpp" #include "asio/detail/win_iocp_overlapped_ptr.hpp" #include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace windows { /// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O. /** * A special-purpose smart pointer used to wrap an application handler so that * it can be passed as the LPOVERLAPPED argument to overlapped I/O functions. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ class overlapped_ptr : private noncopyable { public: /// Construct an empty overlapped_ptr. overlapped_ptr() : impl_() { } /// Construct an overlapped_ptr to contain the specified handler. template explicit overlapped_ptr(ExecutionContext& context, ASIO_MOVE_ARG(Handler) handler, typename enable_if< is_convertible::value >::type* = 0) : impl_(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler)) { } /// Construct an overlapped_ptr to contain the specified handler. template explicit overlapped_ptr(const Executor& ex, ASIO_MOVE_ARG(Handler) handler, typename enable_if< is_executor::value >::type* = 0) : impl_(ex, ASIO_MOVE_CAST(Handler)(handler)) { } /// Destructor automatically frees the OVERLAPPED object unless released. ~overlapped_ptr() { } /// Reset to empty. void reset() { impl_.reset(); } /// Reset to contain the specified handler, freeing any current OVERLAPPED /// object. template void reset(ExecutionContext& context, ASIO_MOVE_ARG(Handler) handler, typename enable_if< is_convertible::value >::type* = 0) { impl_.reset(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler)); } /// Reset to contain the specified handler, freeing any current OVERLAPPED /// object. template void reset(const Executor& ex, ASIO_MOVE_ARG(Handler) handler, typename enable_if< is_executor::value >::type* = 0) { impl_.reset(ex, ASIO_MOVE_CAST(Handler)(handler)); } /// Get the contained OVERLAPPED object. OVERLAPPED* get() { return impl_.get(); } /// Get the contained OVERLAPPED object. const OVERLAPPED* get() const { return impl_.get(); } /// Release ownership of the OVERLAPPED object. OVERLAPPED* release() { return impl_.release(); } /// Post completion notification for overlapped operation. Releases ownership. void complete(const asio::error_code& ec, std::size_t bytes_transferred) { impl_.complete(ec, bytes_transferred); } private: detail::win_iocp_overlapped_ptr impl_; }; } // namespace windows } // namespace asio #include "asio/detail/pop_options.hpp" #endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_OVERLAPPED_PTR_HPP ================================================ FILE: src/third_party/asio/windows/random_access_handle.hpp ================================================ // // windows/random_access_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP #define ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include "asio/windows/basic_random_access_handle.hpp" namespace asio { namespace windows { /// Typedef for the typical usage of a random-access handle. typedef basic_random_access_handle<> random_access_handle; } // namespace windows } // namespace asio #endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP ================================================ FILE: src/third_party/asio/windows/stream_handle.hpp ================================================ // // windows/stream_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WINDOWS_STREAM_HANDLE_HPP #define ASIO_WINDOWS_STREAM_HANDLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ || defined(GENERATING_DOCUMENTATION) #include "asio/windows/basic_stream_handle.hpp" namespace asio { namespace windows { /// Typedef for the typical usage of a stream-oriented handle. typedef basic_stream_handle<> stream_handle; } // namespace windows } // namespace asio #endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_WINDOWS_STREAM_HANDLE_HPP ================================================ FILE: src/third_party/asio/write.hpp ================================================ // // write.hpp // ~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WRITE_HPP #define ASIO_WRITE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/buffer.hpp" #include "asio/error.hpp" #if !defined(ASIO_NO_EXTENSIONS) # include "asio/basic_streambuf_fwd.hpp" #endif // !defined(ASIO_NO_EXTENSIONS) #include "asio/detail/push_options.hpp" namespace asio { /** * @defgroup write asio::write * * @brief The @c write function is a composed operation that writes a certain * amount of data to a stream before returning. */ /*@{*/ /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * stream. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::write(s, asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::write( * s, buffers, * asio::transfer_all()); @endcode */ template std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, typename enable_if< is_const_buffer_sequence::value >::type* = 0); /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * stream. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::write(s, asio::buffer(data, size), ec); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::write( * s, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, asio::error_code& ec, typename enable_if< is_const_buffer_sequence::value >::type* = 0); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * stream. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::write(s, asio::buffer(data, size), * asio::transfer_at_least(32)); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, typename enable_if< is_const_buffer_sequence::value >::type* = 0); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * stream. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_const_buffer_sequence::value >::type* = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::write( * s, buffers, * asio::transfer_all()); @endcode */ template std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::write( * s, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t write(SyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param b The basic_streambuf object from which data will be written. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::write( * s, b, * asio::transfer_all()); @endcode */ template std::size_t write(SyncWriteStream& s, basic_streambuf& b); /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param b The basic_streambuf object from which data will be written. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::write( * s, b, * asio::transfer_all(), ec); @endcode */ template std::size_t write(SyncWriteStream& s, basic_streambuf& b, asio::error_code& ec); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param b The basic_streambuf object from which data will be written. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t write(SyncWriteStream& s, basic_streambuf& b, CompletionCondition completion_condition); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param b The basic_streambuf object from which data will be written. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t write(SyncWriteStream& s, basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::write( * s, buffers, * asio::transfer_all()); @endcode */ template std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Write all of the supplied data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::write( * s, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Write a certain amount of data to a stream before returning. /** * This function is used to write a certain number of bytes of data to a stream. * The call will block until one of the following conditions is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * write_some function. * * @param s The stream to which the data is to be written. The type must support * the SyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Successfully written data is automatically consumed from the buffers. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's write_some function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec, typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /*@}*/ /** * @defgroup async_write asio::async_write * * @brief The @c async_write function is a composed asynchronous operation that * writes a certain amount of data to a stream before completion. */ /*@{*/ /// Start an asynchronous operation to write all of the supplied data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param buffers One or more buffers containing the data to be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * asio::async_write(s, asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type), typename enable_if< is_const_buffer_sequence::value >::type* = 0); /// Start an asynchronous operation to write a certain amount of data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param buffers One or more buffers containing the data to be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's async_write_some function. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::async_write(s, * asio::buffer(data, size), * asio::transfer_at_least(32), * handler); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type), typename enable_if< is_const_buffer_sequence::value >::type* = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Start an asynchronous operation to write all of the supplied data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. Successfully written * data is automatically consumed from the buffers. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type), typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); /// Start an asynchronous operation to write a certain amount of data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. Successfully written * data is automatically consumed from the buffers. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's async_write_some function. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type), typename enable_if< is_dynamic_buffer_v1::type>::value && !is_dynamic_buffer_v2::type>::value >::type* = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Start an asynchronous operation to write all of the supplied data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param b A basic_streambuf object from which data will be written. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, basic_streambuf& b, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type)); /// Start an asynchronous operation to write a certain amount of data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param b A basic_streambuf object from which data will be written. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's async_write_some function. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type)); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) /// Start an asynchronous operation to write all of the supplied data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. Successfully written * data is automatically consumed from the buffers. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type), typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /// Start an asynchronous operation to write a certain amount of data to a /// stream. /** * This function is used to asynchronously write a certain number of bytes of * data to a stream. The function call always returns immediately. The * asynchronous operation will continue until one of the following conditions * is true: * * @li All of the data in the supplied dynamic buffer sequence has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the stream's * async_write_some function, and is known as a composed operation. The * program must ensure that the stream performs no other write operations (such * as async_write, the stream's async_write_some function, or any other composed * operations that perform writes) until this operation completes. * * @param s The stream to which the data is to be written. The type must support * the AsyncWriteStream concept. * * @param buffers The dynamic buffer sequence from which data will be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. Successfully written * data is automatically consumed from the buffers. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_write_some operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the stream's async_write_some function. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * const asio::error_code& error, // Result of operation. * * std::size_t bytes_transferred // Number of bytes written from the * // buffers. If an error occurred, * // this will be less than the sum * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncWriteStream::executor_type), typename enable_if< is_dynamic_buffer_v2::value >::type* = 0); /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/write.hpp" #endif // ASIO_WRITE_HPP ================================================ FILE: src/third_party/asio/write_at.hpp ================================================ // // write_at.hpp // ~~~~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_WRITE_AT_HPP #define ASIO_WRITE_AT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include #include "asio/async_result.hpp" #include "asio/detail/cstdint.hpp" #include "asio/error.hpp" #if !defined(ASIO_NO_EXTENSIONS) # include "asio/basic_streambuf_fwd.hpp" #endif // !defined(ASIO_NO_EXTENSIONS) #include "asio/detail/push_options.hpp" namespace asio { /** * @defgroup write_at asio::write_at * * @brief The @c write_at function is a composed operation that writes a * certain amount of data at a specified offset before returning. */ /*@{*/ /// Write all of the supplied data at the specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * device. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::write_at(d, 42, asio::buffer(data, size)); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::write_at( * d, offset, buffers, * asio::transfer_all()); @endcode */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers); /// Write all of the supplied data at the specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * device. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::write_at(d, 42, * asio::buffer(data, size), ec); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. * * @note This overload is equivalent to calling: * @code asio::write_at( * d, offset, buffers, * asio::transfer_all(), ec); @endcode */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, asio::error_code& ec); /// Write a certain amount of data at a specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * device. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the device's write_some_at function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::write_at(d, 42, asio::buffer(data, size), * asio::transfer_at_least(32)); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition); /// Write a certain amount of data at a specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param buffers One or more buffers containing the data to be written. The sum * of the buffer sizes indicates the maximum number of bytes to write to the * device. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the device's write_some_at function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Write all of the supplied data at the specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param b The basic_streambuf object from which data will be written. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code asio::write_at( * d, 42, b, * asio::transfer_all()); @endcode */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf& b); /// Write all of the supplied data at the specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param b The basic_streambuf object from which data will be written. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes transferred. * * @note This overload is equivalent to calling: * @code asio::write_at( * d, 42, b, * asio::transfer_all(), ec); @endcode */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf& b, asio::error_code& ec); /// Write a certain amount of data at a specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param b The basic_streambuf object from which data will be written. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the device's write_some_at function. * * @returns The number of bytes transferred. * * @throws asio::system_error Thrown on failure. */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf& b, CompletionCondition completion_condition); /// Write a certain amount of data at a specified offset before returning. /** * This function is used to write a certain number of bytes of data to a random * access device at a specified offset. The call will block until one of the * following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * write_some_at function. * * @param d The device to which the data is to be written. The type must support * the SyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param b The basic_streambuf object from which data will be written. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest write_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the device's write_some_at function. * * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes written. If an error occurs, returns the total * number of bytes successfully transferred prior to the error. */ template std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf& b, CompletionCondition completion_condition, asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) /*@}*/ /** * @defgroup async_write_at asio::async_write_at * * @brief The @c async_write_at function is a composed asynchronous operation * that writes a certain amount of data at the specified offset before * completion. */ /*@{*/ /// Start an asynchronous operation to write all of the supplied data at the /// specified offset. /** * This function is used to asynchronously write a certain number of bytes of * data to a random access device at a specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * async_write_some_at function, and is known as a composed operation. * The program must ensure that the device performs no overlapping * write operations (such as async_write_at, the device's async_write_some_at * function, or any other composed operations that perform writes) until this * operation completes. Operations are overlapping if the regions defined by * their offsets, and the numbers of bytes to write, intersect. * * @param d The device to which the data is to be written. The type must support * the AsyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param buffers One or more buffers containing the data to be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes written from the buffers. If an error * // occurred, this will be less than the sum of the buffer sizes. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code * asio::async_write_at(d, 42, asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessWriteDevice::executor_type)); /// Start an asynchronous operation to write a certain amount of data at the /// specified offset. /** * This function is used to asynchronously write a certain number of bytes of * data to a random access device at a specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li All of the data in the supplied buffers has been written. That is, the * bytes transferred is equal to the sum of the buffer sizes. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * async_write_some_at function, and is known as a composed operation. * The program must ensure that the device performs no overlapping * write operations (such as async_write_at, the device's async_write_some_at * function, or any other composed operations that perform writes) until this * operation completes. Operations are overlapping if the regions defined by * their offsets, and the numbers of bytes to write, intersect. * * @param d The device to which the data is to be written. The type must support * the AsyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param buffers One or more buffers containing the data to be written. * Although the buffers object may be copied as necessary, ownership of the * underlying memory blocks is retained by the caller, which must guarantee * that they remain valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_write_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the device's async_write_some_at function. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes written from the buffers. If an error * // occurred, this will be less than the sum of the buffer sizes. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). * * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code asio::async_write_at(d, 42, * asio::buffer(data, size), * asio::transfer_at_least(32), * handler); @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessWriteDevice::executor_type)); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) /// Start an asynchronous operation to write all of the supplied data at the /// specified offset. /** * This function is used to asynchronously write a certain number of bytes of * data to a random access device at a specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li An error occurred. * * This operation is implemented in terms of zero or more calls to the device's * async_write_some_at function, and is known as a composed operation. * The program must ensure that the device performs no overlapping * write operations (such as async_write_at, the device's async_write_some_at * function, or any other composed operations that perform writes) until this * operation completes. Operations are overlapping if the regions defined by * their offsets, and the numbers of bytes to write, intersect. * * @param d The device to which the data is to be written. The type must support * the AsyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param b A basic_streambuf object from which data will be written. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes written from the buffers. If an error * // occurred, this will be less than the sum of the buffer sizes. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf& b, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessWriteDevice::executor_type)); /// Start an asynchronous operation to write a certain amount of data at the /// specified offset. /** * This function is used to asynchronously write a certain number of bytes of * data to a random access device at a specified offset. The function call * always returns immediately. The asynchronous operation will continue until * one of the following conditions is true: * * @li All of the data in the supplied basic_streambuf has been written. * * @li The completion_condition function object returns 0. * * This operation is implemented in terms of zero or more calls to the device's * async_write_some_at function, and is known as a composed operation. * The program must ensure that the device performs no overlapping * write operations (such as async_write_at, the device's async_write_some_at * function, or any other composed operations that perform writes) until this * operation completes. Operations are overlapping if the regions defined by * their offsets, and the numbers of bytes to write, intersect. * * @param d The device to which the data is to be written. The type must support * the AsyncRandomAccessWriteDevice concept. * * @param offset The offset at which the data will be written. * * @param b A basic_streambuf object from which data will be written. Ownership * of the streambuf is retained by the caller, which must guarantee that it * remains valid until the handler is called. * * @param completion_condition The function object to be called to determine * whether the write operation is complete. The signature of the function object * must be: * @code std::size_t completion_condition( * // Result of latest async_write_some_at operation. * const asio::error_code& error, * * // Number of bytes transferred so far. * std::size_t bytes_transferred * ); @endcode * A return value of 0 indicates that the write operation is complete. A * non-zero return value indicates the maximum number of bytes to be written on * the next call to the device's async_write_some_at function. * * @param handler The handler to be called when the write operation completes. * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( * // Result of operation. * const asio::error_code& error, * * // Number of bytes written from the buffers. If an error * // occurred, this will be less than the sum of the buffer sizes. * std::size_t bytes_transferred * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. On * immediate completion, invocation of the handler will be performed in a * manner equivalent to using asio::post(). */ template ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void (asio::error_code, std::size_t)) async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf& b, CompletionCondition completion_condition, ASIO_MOVE_ARG(WriteHandler) handler ASIO_DEFAULT_COMPLETION_TOKEN( typename AsyncRandomAccessWriteDevice::executor_type)); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS) /*@}*/ } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/write_at.hpp" #endif // ASIO_WRITE_AT_HPP ================================================ FILE: src/third_party/asio/yield.hpp ================================================ // // yield.hpp // ~~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "coroutine.hpp" #ifndef reenter # define reenter(c) ASIO_CORO_REENTER(c) #endif #ifndef yield # define yield ASIO_CORO_YIELD #endif #ifndef fork # define fork ASIO_CORO_FORK #endif ================================================ FILE: src/third_party/asio.hpp ================================================ // // asio.hpp // ~~~~~~~~ // // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_HPP #define ASIO_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/async_result.hpp" #include "asio/awaitable.hpp" #include "asio/basic_datagram_socket.hpp" #include "asio/basic_deadline_timer.hpp" #include "asio/basic_io_object.hpp" #include "asio/basic_raw_socket.hpp" #include "asio/basic_seq_packet_socket.hpp" #include "asio/basic_serial_port.hpp" #include "asio/basic_signal_set.hpp" #include "asio/basic_socket.hpp" #include "asio/basic_socket_acceptor.hpp" #include "asio/basic_socket_iostream.hpp" #include "asio/basic_socket_streambuf.hpp" #include "asio/basic_stream_socket.hpp" #include "asio/basic_streambuf.hpp" #include "asio/basic_waitable_timer.hpp" #include "asio/bind_executor.hpp" #include "asio/buffer.hpp" #include "asio/buffered_read_stream_fwd.hpp" #include "asio/buffered_read_stream.hpp" #include "asio/buffered_stream_fwd.hpp" #include "asio/buffered_stream.hpp" #include "asio/buffered_write_stream_fwd.hpp" #include "asio/buffered_write_stream.hpp" #include "asio/buffers_iterator.hpp" #include "asio/co_spawn.hpp" #include "asio/completion_condition.hpp" #include "asio/compose.hpp" #include "asio/connect.hpp" #include "asio/coroutine.hpp" #include "asio/deadline_timer.hpp" #include "asio/defer.hpp" #include "asio/detached.hpp" #include "asio/dispatch.hpp" #include "asio/error.hpp" #include "asio/error_code.hpp" #include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/executor_work_guard.hpp" #include "asio/generic/basic_endpoint.hpp" #include "asio/generic/datagram_protocol.hpp" #include "asio/generic/raw_protocol.hpp" #include "asio/generic/seq_packet_protocol.hpp" #include "asio/generic/stream_protocol.hpp" #include "asio/handler_alloc_hook.hpp" #include "asio/handler_continuation_hook.hpp" #include "asio/handler_invoke_hook.hpp" #include "asio/high_resolution_timer.hpp" #include "asio/io_context.hpp" #include "asio/io_context_strand.hpp" #include "asio/io_service.hpp" #include "asio/io_service_strand.hpp" #include "asio/ip/address.hpp" #include "asio/ip/address_v4.hpp" #include "asio/ip/address_v4_iterator.hpp" #include "asio/ip/address_v4_range.hpp" #include "asio/ip/address_v6.hpp" #include "asio/ip/address_v6_iterator.hpp" #include "asio/ip/address_v6_range.hpp" #include "asio/ip/network_v4.hpp" #include "asio/ip/network_v6.hpp" #include "asio/ip/bad_address_cast.hpp" #include "asio/ip/basic_endpoint.hpp" #include "asio/ip/basic_resolver.hpp" #include "asio/ip/basic_resolver_entry.hpp" #include "asio/ip/basic_resolver_iterator.hpp" #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/host_name.hpp" #include "asio/ip/icmp.hpp" #include "asio/ip/multicast.hpp" #include "asio/ip/resolver_base.hpp" #include "asio/ip/resolver_query_base.hpp" #include "asio/ip/tcp.hpp" #include "asio/ip/udp.hpp" #include "asio/ip/unicast.hpp" #include "asio/ip/v6_only.hpp" #include "asio/is_executor.hpp" #include "asio/is_read_buffered.hpp" #include "asio/is_write_buffered.hpp" #include "asio/local/basic_endpoint.hpp" #include "asio/local/connect_pair.hpp" #include "asio/local/datagram_protocol.hpp" #include "asio/local/stream_protocol.hpp" #include "asio/packaged_task.hpp" #include "asio/placeholders.hpp" #include "asio/posix/basic_descriptor.hpp" #include "asio/posix/basic_stream_descriptor.hpp" #include "asio/posix/descriptor.hpp" #include "asio/posix/descriptor_base.hpp" #include "asio/posix/stream_descriptor.hpp" #include "asio/post.hpp" #include "asio/read.hpp" #include "asio/read_at.hpp" #include "asio/read_until.hpp" #include "asio/redirect_error.hpp" #include "asio/serial_port.hpp" #include "asio/serial_port_base.hpp" #include "asio/signal_set.hpp" #include "asio/socket_base.hpp" #include "asio/steady_timer.hpp" #include "asio/strand.hpp" #include "asio/streambuf.hpp" #include "asio/system_context.hpp" #include "asio/system_error.hpp" #include "asio/system_executor.hpp" #include "asio/system_timer.hpp" #include "asio/this_coro.hpp" #include "asio/thread.hpp" #include "asio/thread_pool.hpp" #include "asio/time_traits.hpp" #include "asio/use_awaitable.hpp" #include "asio/use_future.hpp" #include "asio/uses_executor.hpp" #include "asio/version.hpp" #include "asio/wait_traits.hpp" #include "asio/windows/basic_object_handle.hpp" #include "asio/windows/basic_overlapped_handle.hpp" #include "asio/windows/basic_random_access_handle.hpp" #include "asio/windows/basic_stream_handle.hpp" #include "asio/windows/object_handle.hpp" #include "asio/windows/overlapped_handle.hpp" #include "asio/windows/overlapped_ptr.hpp" #include "asio/windows/random_access_handle.hpp" #include "asio/windows/stream_handle.hpp" #include "asio/write.hpp" #include "asio/write_at.hpp" #endif // ASIO_HPP ================================================ FILE: src/third_party/concurrentqueue/LICENSE.md ================================================ This license file applies to everything in this repository except that which is explicitly annotated as being written by other authors, i.e. the Boost queue (included in the benchmarks for comparison), Intel's TBB library (ditto), the CDSChecker tool (used for verification), the Relacy model checker (ditto), and Jeff Preshing's semaphore implementation (used in the blocking queue) which has a zlib license (embedded in blockingconcurrentqueue.h). --- Simplified BSD License: Copyright (c) 2013-2016, Cameron Desrochers. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- I have also chosen to dual-license under the Boost Software License as an alternative to the Simplified BSD license above: Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: src/third_party/concurrentqueue/README.md ================================================ # moodycamel::ConcurrentQueue An industrial-strength lock-free queue for C++. Note: If all you need is a single-producer, single-consumer queue, I have [one of those too][spsc]. ## Features - Knock-your-socks-off [blazing fast performance][benchmarks]. - Single-header implementation. Just drop it in your project. - Fully thread-safe lock-free queue. Use concurrently from any number of threads. - C++11 implementation -- elements are moved (instead of copied) where possible. - Templated, obviating the need to deal exclusively with pointers -- memory is managed for you. - No artificial limitations on element types or maximum count. - Memory can be allocated once up-front, or dynamically as needed. - Fully portable (no assembly; all is done through standard C++11 primitives). - Supports super-fast bulk operations. - Includes a low-overhead blocking version (BlockingConcurrentQueue). - Exception safe. ## Reasons to use There are not that many full-fledged lock-free queues for C++. Boost has one, but it's limited to objects with trivial assignment operators and trivial destructors, for example. Intel's TBB queue isn't lock-free, and requires trivial constructors too. There're many academic papers that implement lock-free queues in C++, but usable source code is hard to find, and tests even more so. This queue not only has less limitations than others (for the most part), but [it's also faster][benchmarks]. It's been fairly well-tested, and offers advanced features like **bulk enqueueing/dequeueing** (which, with my new design, is much faster than one element at a time, approaching and even surpassing the speed of a non-concurrent queue even under heavy contention). In short, there was a lock-free queue shaped hole in the C++ open-source universe, and I set out to fill it with the fastest, most complete, and well-tested design and implementation I could. The result is `moodycamel::ConcurrentQueue` :-) ## Reasons *not* to use The fastest synchronization of all is the kind that never takes place. Fundamentally, concurrent data structures require some synchronization, and that takes time. Every effort was made, of course, to minimize the overhead, but if you can avoid sharing data between threads, do so! Why use concurrent data structures at all, then? Because they're gosh darn convenient! (And, indeed, sometimes sharing data concurrently is unavoidable.) My queue is **not linearizable** (see the next section on high-level design). The foundations of its design assume that producers are independent; if this is not the case, and your producers co-ordinate amongst themselves in some fashion, be aware that the elements won't necessarily come out of the queue in the same order they were put in *relative to the ordering formed by that co-ordination* (but they will still come out in the order they were put in by any *individual* producer). If this affects your use case, you may be better off with another implementation; either way, it's an important limitation to be aware of. My queue is also **not NUMA aware**, and does a lot of memory re-use internally, meaning it probably doesn't scale particularly well on NUMA architectures; however, I don't know of any other lock-free queue that *is* NUMA aware (except for [SALSA][salsa], which is very cool, but has no publicly available implementation that I know of). Finally, the queue is **not sequentially consistent**; there *is* a happens-before relationship between when an element is put in the queue and when it comes out, but other things (such as pumping the queue until it's empty) require more thought to get right in all eventualities, because explicit memory ordering may have to be done to get the desired effect. In other words, it can sometimes be difficult to use the queue correctly. This is why it's a good idea to follow the [samples][samples.md] where possible. On the other hand, the upside of this lack of sequential consistency is better performance. ## High-level design Elements are stored internally using contiguous blocks instead of linked lists for better performance. The queue is made up of a collection of sub-queues, one for each producer. When a consumer wants to dequeue an element, it checks all the sub-queues until it finds one that's not empty. All of this is largely transparent to the user of the queue, however -- it mostly just worksTM. One particular consequence of this design, however, (which seems to be non-intuitive) is that if two producers enqueue at the same time, there is no defined ordering between the elements when they're later dequeued. Normally this is fine, because even with a fully linearizable queue there'd be a race between the producer threads and so you couldn't rely on the ordering anyway. However, if for some reason you do extra explicit synchronization between the two producer threads yourself, thus defining a total order between enqueue operations, you might expect that the elements would come out in the same total order, which is a guarantee my queue does not offer. At that point, though, there semantically aren't really two separate producers, but rather one that happens to be spread across multiple threads. In this case, you can still establish a total ordering with my queue by creating a single producer token, and using that from both threads to enqueue (taking care to synchronize access to the token, of course, but there was already extra synchronization involved anyway). I've written a more detailed [overview of the internal design][blog], as well as [the full nitty-gritty details of the design][design], on my blog. Finally, the [source][source] itself is available for perusal for those interested in its implementation. ## Basic use The entire queue's implementation is contained in **one header**, [`concurrentqueue.h`][concurrentqueue.h]. Simply download and include that to use the queue. The blocking version is in a separate header, [`blockingconcurrentqueue.h`][blockingconcurrentqueue.h], that depends on the first. The implementation makes use of certain key C++11 features, so it requires a fairly recent compiler (e.g. VS2012+ or g++ 4.8; note that g++ 4.6 has a known bug with `std::atomic` and is thus not supported). The algorithm implementations themselves are platform independent. Use it like you would any other templated queue, with the exception that you can use it from many threads at once :-) Simple example: #include "concurrentqueue.h" moodycamel::ConcurrentQueue q; q.enqueue(25); int item; bool found = q.try_dequeue(item); assert(found && item == 25); Description of basic methods: - `ConcurrentQueue(size_t initialSizeEstimate)` Constructor which optionally accepts an estimate of the number of elements the queue will hold - `enqueue(T&& item)` Enqueues one item, allocating extra space if necessary - `try_enqueue(T&& item)` Enqueues one item, but only if enough memory is already allocated - `try_dequeue(T& item)` Dequeues one item, returning true if an item was found or false if the queue appeared empty Note that it is up to the user to ensure that the queue object is completely constructed before being used by any other threads (this includes making the memory effects of construction visible, possibly via a memory barrier). Similarly, it's important that all threads have finished using the queue (and the memory effects have fully propagated) before it is destructed. There's usually two versions of each method, one "explicit" version that takes a user-allocated per-producer or per-consumer token, and one "implicit" version that works without tokens. Using the explicit methods is almost always faster (though not necessarily by a huge factor). Apart from performance, the primary distinction between them is their sub-queue allocation behaviour for enqueue operations: Using the implicit enqueue methods causes an automatically-allocated thread-local producer sub-queue to be allocated (it is marked for reuse once the thread exits). Explicit producers, on the other hand, are tied directly to their tokens' lifetimes (and are also recycled as needed). Full API (pseudocode): # Allocates more memory if necessary enqueue(item) : bool enqueue(prod_token, item) : bool enqueue_bulk(item_first, count) : bool enqueue_bulk(prod_token, item_first, count) : bool # Fails if not enough memory to enqueue try_enqueue(item) : bool try_enqueue(prod_token, item) : bool try_enqueue_bulk(item_first, count) : bool try_enqueue_bulk(prod_token, item_first, count) : bool # Attempts to dequeue from the queue (never allocates) try_dequeue(item&) : bool try_dequeue(cons_token, item&) : bool try_dequeue_bulk(item_first, max) : size_t try_dequeue_bulk(cons_token, item_first, max) : size_t # If you happen to know which producer you want to dequeue from try_dequeue_from_producer(prod_token, item&) : bool try_dequeue_bulk_from_producer(prod_token, item_first, max) : size_t # A not-necessarily-accurate count of the total number of elements size_approx() : size_t ## Blocking version As mentioned above, a full blocking wrapper of the queue is provided that adds `wait_dequeue` and `wait_dequeue_bulk` methods in addition to the regular interface. This wrapper is extremely low-overhead, but slightly less fast than the non-blocking queue (due to the necessary bookkeeping involving a lightweight semaphore). There are also timed versions that allow a timeout to be specified (either in microseconds or with a `std::chrono` object). The only major caveat with the blocking version is that you must be careful not to destroy the queue while somebody is waiting on it. This generally means you need to know for certain that another element is going to come along before you call one of the blocking methods. (To be fair, the non-blocking version cannot be destroyed while in use either, but it can be easier to coordinate the cleanup.) Blocking example: #include "blockingconcurrentqueue.h" moodycamel::BlockingConcurrentQueue q; std::thread producer([&]() { for (int i = 0; i != 100; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(i % 10)); q.enqueue(i); } }); std::thread consumer([&]() { for (int i = 0; i != 100; ++i) { int item; q.wait_dequeue(item); assert(item == i); if (q.wait_dequeue_timed(item, std::chrono::milliseconds(5))) { ++i; assert(item == i); } } }); producer.join(); consumer.join(); assert(q.size_approx() == 0); ## Advanced features #### Tokens The queue can take advantage of extra per-producer and per-consumer storage if it's available to speed up its operations. This takes the form of "tokens": You can create a consumer token and/or a producer token for each thread or task (tokens themselves are not thread-safe), and use the methods that accept a token as their first parameter: moodycamel::ConcurrentQueue q; moodycamel::ProducerToken ptok(q); q.enqueue(ptok, 17); moodycamel::ConsumerToken ctok(q); int item; q.try_dequeue(ctok, item); assert(item == 17); If you happen to know which producer you want to consume from (e.g. in a single-producer, multi-consumer scenario), you can use the `try_dequeue_from_producer` methods, which accept a producer token instead of a consumer token, and cut some overhead. Note that tokens work with the blocking version of the queue too. When producing or consuming many elements, the most efficient way is to: 1. Use the bulk methods of the queue with tokens 2. Failing that, use the bulk methods without tokens 3. Failing that, use the single-item methods with tokens 4. Failing that, use the single-item methods without tokens Having said that, don't create tokens willy-nilly -- ideally there would be one token (of each kind) per thread. The queue will work with what it is given, but it performs best when used with tokens. Note that tokens aren't actually tied to any given thread; it's not technically required that they be local to the thread, only that they be used by a single producer/consumer at a time. #### Bulk operations Thanks to the [novel design][blog] of the queue, it's just as easy to enqueue/dequeue multiple items as it is to do one at a time. This means that overhead can be cut drastically for bulk operations. Example syntax: moodycamel::ConcurrentQueue q; int items[] = { 1, 2, 3, 4, 5 }; q.enqueue_bulk(items, 5); int results[5]; // Could also be any iterator size_t count = q.try_dequeue_bulk(results, 5); for (size_t i = 0; i != count; ++i) { assert(results[i] == items[i]); } #### Preallocation (correctly using `try_enqueue`) `try_enqueue`, unlike just plain `enqueue`, will never allocate memory. If there's not enough room in the queue, it simply returns false. The key to using this method properly, then, is to ensure enough space is pre-allocated for your desired maximum element count. The constructor accepts a count of the number of elements that it should reserve space for. Because the queue works with blocks of elements, however, and not individual elements themselves, the value to pass in order to obtain an effective number of pre-allocated element slots is non-obvious. First, be aware that the count passed is rounded up to the next multiple of the block size. Note that the default block size is 32 (this can be changed via the traits). Second, once a slot in a block has been enqueued to, that slot cannot be re-used until the rest of the block has completely been completely filled up and then completely emptied. This affects the number of blocks you need in order to account for the overhead of partially-filled blocks. Third, each producer (whether implicit or explicit) claims and recycles blocks in a different manner, which again affects the number of blocks you need to account for a desired number of usable slots. Suppose you want the queue to be able to hold at least `N` elements at any given time. Without delving too deep into the rather arcane implementation details, here are some simple formulas for the number of elements to request for pre-allocation in such a case. Note the division is intended to be arithmetic division and not integer division (in order for `ceil()` to work). For explicit producers (using tokens to enqueue): (ceil(N / BLOCK_SIZE) + 1) * MAX_NUM_PRODUCERS * BLOCK_SIZE For implicit producers (no tokens): (ceil(N / BLOCK_SIZE) - 1 + 2 * MAX_NUM_PRODUCERS) * BLOCK_SIZE When using mixed producer types: ((ceil(N / BLOCK_SIZE) - 1) * (MAX_EXPLICIT_PRODUCERS + 1) + 2 * (MAX_IMPLICIT_PRODUCERS + MAX_EXPLICIT_PRODUCERS)) * BLOCK_SIZE If these formulas seem rather inconvenient, you can use the constructor overload that accepts the minimum number of elements (`N`) and the maximum number of explicit and implicit producers directly, and let it do the computation for you. Finally, it's important to note that because the queue is only eventually consistent and takes advantage of weak memory ordering for speed, there's always a possibility that under contention `try_enqueue` will fail even if the queue is correctly pre-sized for the desired number of elements. (e.g. A given thread may think that the queue's full even when that's no longer the case.) So no matter what, you still need to handle the failure case (perhaps looping until it succeeds), unless you don't mind dropping elements. #### Exception safety The queue is exception safe, and will never become corrupted if used with a type that may throw exceptions. The queue itself never throws any exceptions (operations fail gracefully (return false) if memory allocation fails instead of throwing `std::bad_alloc`). It is important to note that the guarantees of exception safety only hold if the element type never throws from its destructor, and that any iterators passed into the queue (for bulk operations) never throw either. Note that in particular this means `std::back_inserter` iterators must be used with care, since the vector being inserted into may need to allocate and throw a `std::bad_alloc` exception from inside the iterator; so be sure to reserve enough capacity in the target container first if you do this. The guarantees are presently as follows: - Enqueue operations are rolled back completely if an exception is thrown from an element's constructor. For bulk enqueue operations, this means that elements are copied instead of moved (in order to avoid having only some of the objects be moved in the event of an exception). Non-bulk enqueues always use the move constructor if one is available. - If the assignment operator throws during a dequeue operation (both single and bulk), the element(s) are considered dequeued regardless. In such a case, the dequeued elements are all properly destructed before the exception is propagated, but there's no way to get the elements themselves back. - Any exception that is thrown is propagated up the call stack, at which point the queue is in a consistent state. Note: If any of your type's copy constructors/move constructors/assignment operators don't throw, be sure to annotate them with `noexcept`; this will avoid the exception-checking overhead in the queue where possible (even with zero-cost exceptions, there's still a code size impact that has to be taken into account). #### Traits The queue also supports a traits template argument which defines various types, constants, and the memory allocation and deallocation functions that are to be used by the queue. The typical pattern to providing your own traits is to create a class that inherits from the default traits and override only the values you wish to change. Example: struct MyTraits : public moodycamel::ConcurrentQueueDefaultTraits { static const size_t BLOCK_SIZE = 256; // Use bigger blocks }; moodycamel::ConcurrentQueue q; #### How to dequeue types without calling the constructor The normal way to dequeue an item is to pass in an existing object by reference, which is then assigned to internally by the queue (using the move-assignment operator if possible). This can pose a problem for types that are expensive to construct or don't have a default constructor; fortunately, there is a simple workaround: Create a wrapper class that copies the memory contents of the object when it is assigned by the queue (a poor man's move, essentially). Note that this only works if the object contains no internal pointers. Example: struct MyObjectMover { inline void operator=(MyObject&& obj) { std::memcpy(data, &obj, sizeof(MyObject)); // TODO: Cleanup obj so that when it's destructed by the queue // it doesn't corrupt the data of the object we just moved it into } inline MyObject& obj() { return *reinterpret_cast(data); } private: align(alignof(MyObject)) char data[sizeof(MyObject)]; }; A less dodgy alternative, if moves are cheap but default construction is not, is to use a wrapper that defers construction until the object is assigned, enabling use of the move constructor: struct MyObjectMover { inline void operator=(MyObject&& x) { new (data) MyObject(std::move(x)); created = true; } inline MyObject& obj() { assert(created); return *reinterpret_cast(data); } ~MyObjectMover() { if (created) obj().~MyObject(); } private: align(alignof(MyObject)) char data[sizeof(MyObject)]; bool created = false; }; ## Samples There are some more detailed samples [here][samples.md]. The source of the [unit tests][unittest-src] and [benchmarks][benchmark-src] are available for reference as well. ## Benchmarks See my blog post for some [benchmark results][benchmarks] (including versus `boost::lockfree::queue` and `tbb::concurrent_queue`), or run the benchmarks yourself (requires MinGW and certain GnuWin32 utilities to build on Windows, or a recent g++ on Linux): cd build make benchmarks bin/benchmarks The short version of the benchmarks is that it's so fast (especially the bulk methods), that if you're actually using the queue to *do* anything, the queue won't be your bottleneck. ## Tests (and bugs) I've written quite a few unit tests as well as a randomized long-running fuzz tester. I also ran the core queue algorithm through the [CDSChecker][cdschecker] C++11 memory model model checker. Some of the inner algorithms were tested separately using the [Relacy][relacy] model checker, and full integration tests were also performed with Relacy. I've tested on Linux (Fedora 19) and Windows (7), but only on x86 processors so far (Intel and AMD). The code was written to be platform-independent, however, and should work across all processors and OSes. Due to the complexity of the implementation and the difficult-to-test nature of lock-free code in general, there may still be bugs. If anyone is seeing buggy behaviour, I'd like to hear about it! (Especially if a unit test for it can be cooked up.) Just open an issue on GitHub. ## License I'm releasing the source of this repository (with the exception of third-party code, i.e. the Boost queue (used in the benchmarks for comparison), Intel's TBB library (ditto), CDSChecker, Relacy, and Jeff Preshing's cross-platform semaphore, which all have their own licenses) under a simplified BSD license. I'm also dual-licensing under the Boost Software License. See the [LICENSE.md][license] file for more details. Note that lock-free programming is a patent minefield, and this code may very well violate a pending patent (I haven't looked), though it does not to my present knowledge. I did design and implement this queue from scratch. ## Diving into the code If you're interested in the source code itself, it helps to have a rough idea of how it's laid out. This section attempts to describe that. The queue is formed of several basic parts (listed here in roughly the order they appear in the source). There's the helper functions (e.g. for rounding to a power of 2). There's the default traits of the queue, which contain the constants and malloc/free functions used by the queue. There's the producer and consumer tokens. Then there's the queue's public API itself, starting with the constructor, destructor, and swap/assignment methods. There's the public enqueue methods, which are all wrappers around a small set of private enqueue methods found later on. There's the dequeue methods, which are defined inline and are relatively straightforward. Then there's all the main internal data structures. First, there's a lock-free free list, used for recycling spent blocks (elements are enqueued to blocks internally). Then there's the block structure itself, which has two different ways of tracking whether it's fully emptied or not (remember, given two parallel consumers, there's no way to know which one will finish first) depending on where it's used. Then there's a small base class for the two types of internal SPMC producer queues (one for explicit producers that holds onto memory but attempts to be faster, and one for implicit ones which attempt to recycle more memory back into the parent but is a little slower). The explicit producer is defined first, then the implicit one. They both contain the same general four methods: One to enqueue, one to dequeue, one to enqueue in bulk, and one to dequeue in bulk. (Obviously they have constructors and destructors too, and helper methods.) The main difference between them is how the block handling is done (they both use the same blocks, but in different ways, and map indices to them in different ways). Finally, there's the miscellaneous internal methods: There's the ones that handle the initial block pool (populated when the queue is constructed), and an abstract block pool that comprises the initial pool and any blocks on the free list. There's ones that handle the producer list (a lock-free add-only linked list of all the producers in the system). There's ones that handle the implicit producer lookup table (which is really a sort of specialized TLS lookup). And then there's some helper methods for allocating and freeing objects, and the data members of the queue itself, followed lastly by the free-standing swap functions. [blog]: http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++ [design]: http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue [samples.md]: https://github.com/cameron314/concurrentqueue/blob/master/samples.md [source]: https://github.com/cameron314/concurrentqueue [concurrentqueue.h]: https://github.com/cameron314/concurrentqueue/blob/master/concurrentqueue.h [blockingconcurrentqueue.h]: https://github.com/cameron314/concurrentqueue/blob/master/blockingconcurrentqueue.h [unittest-src]: https://github.com/cameron314/concurrentqueue/tree/master/tests/unittests [benchmarks]: http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++#benchmarks [benchmark-src]: https://github.com/cameron314/concurrentqueue/tree/master/benchmarks [license]: https://github.com/cameron314/concurrentqueue/blob/master/LICENSE.md [cdschecker]: http://demsky.eecs.uci.edu/c11modelchecker.html [relacy]: http://www.1024cores.net/home/relacy-race-detector [spsc]: https://github.com/cameron314/readerwriterqueue [salsa]: http://webee.technion.ac.il/~idish/ftp/spaa049-gidron.pdf ================================================ FILE: src/third_party/concurrentqueue/benchmarks/benchmarks.cpp ================================================ // ©2013-2014 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this file). // Benchmarks for moodycamel::ConcurrentQueue. // Provides comparative timings of various operations under // highly artificial circumstances. You've been warned :-) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../blockingconcurrentqueue.h" #include "lockbasedqueue.h" #include "simplelockfree.h" #include "boostqueue.h" #include "tbbqueue.h" #include "stdqueue.h" #include "../tests/common/simplethread.h" #include "../tests/common/systemtime.h" #include "cpuid.h" using namespace moodycamel; typedef std::minstd_rand RNG_t; bool precise = false; enum benchmark_type_t { bench_balanced, bench_only_enqueue, bench_only_enqueue_prealloc, bench_only_enqueue_bulk, bench_only_enqueue_bulk_prealloc, bench_only_dequeue, bench_only_dequeue_bulk, bench_mostly_enqueue, bench_mostly_enqueue_bulk, bench_mostly_dequeue, bench_mostly_dequeue_bulk, bench_spmc, bench_spmc_preproduced, bench_mpsc, bench_empty_dequeue, bench_enqueue_dequeue_pairs, bench_heavy_concurrent, BENCHMARK_TYPE_COUNT }; const char BENCHMARK_SHORT_NAMES[BENCHMARK_TYPE_COUNT][32] = { "balanced", "only_enqueue", "only_enqueue_prealloc", "only_enqueue_bulk", "only_enqueue_bulk_prealloc", "only_dequeue", "only_dequeue_bulk", "mostly_enqueue", "mostly_enqueue_bulk", "mostly_dequeue", "mostly_dequeue_bulk", "spmc", "spmc_preproduced", "mpsc", "empty_dequeue", "enqueue_dequeue_pairs", "heavy_concurrent" }; const char BENCHMARK_NAMES[BENCHMARK_TYPE_COUNT][64] = { "balanced", "only enqueue", "only enqueue (pre-allocated)", "only enqueue bulk", "only enqueue bulk (pre-allocated)", "only dequeue", "only dequeue bulk", "mostly enqueue", "mostly enqueue bulk", "mostly dequeue", "mostly dequeue bulk", "single-producer, multi-consumer", "single-producer, multi-consumer (pre-produced)", "multi-producer, single-consumer", "dequeue from empty", "enqueue-dequeue pairs", "heavy concurrent" }; const char BENCHMARK_DESCS[BENCHMARK_TYPE_COUNT][256] = { "Measures the average operation speed with multiple symmetrical threads\n under reasonable load -- small random intervals between accesses", "Measures the average operation speed when all threads are producers", "Measures the average operation speed when all threads are producers,\n and the queue has been stretched out first", "Measures the average speed of enqueueing an item in bulk when all threads are producers", "Measures the average speed of enqueueing an item in bulk when all threads are producers,\n and the queue has been stretched out first", "Measures the average operation speed when all threads are consumers", "Measures the average speed of dequeueing an item in bulk when all threads are consumers", "Measures the average operation speed when most threads are enqueueing", "Measures the average speed of enqueueing an item in bulk under light contention", "Measures the average operation speed when most threads are dequeueing", "Measures the average speed of dequeueing an item in bulk under light contention", "Measures the average speed of dequeueing with only one producer, but multiple consumers", "Measures the average speed of dequeueing from a queue pre-filled by one thread", "Measures the average speed of dequeueing with only one consumer, but multiple producers", "Measures the average speed of attempting to dequeue from an empty queue\n (that eight separate threads had at one point enqueued to)", "Measures the average operation speed with each thread doing an enqueue\n followed by a dequeue", "Measures the average operation speed with many threads under heavy load" }; const char BENCHMARK_SINGLE_THREAD_NOTES[BENCHMARK_TYPE_COUNT][256] = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "No contention -- measures raw failed dequeue speed on empty queue", "No contention -- measures speed of immediately dequeueing the item that was just enqueued", "" }; int BENCHMARK_THREADS_MEASURED[BENCHMARK_TYPE_COUNT] = { 0, // measures nthreads 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, // nthreads - 1 0, 1, // 1 0, 0, 0, }; int BENCHMARK_THREADS[BENCHMARK_TYPE_COUNT][9] = { { 2, 3, 4, 8, 12, 16, 32, 0, 0 }, { 1, 2, 4, 8, 12, 16, 32, 48, 0 }, { 1, 2, 4, 8, 32, 0, 0, 0, 0 }, { 1, 2, 4, 8, 12, 16, 32, 48, 0 }, { 1, 2, 4, 8, 32, 0, 0, 0, 0 }, { 1, 2, 4, 8, 12, 16, 32, 48, 0 }, { 1, 2, 4, 8, 12, 16, 32, 48, 0 }, { 2, 4, 8, 32, 0, 0, 0, 0, 0 }, { 2, 4, 8, 32, 0, 0, 0, 0, 0 }, { 2, 4, 8, 0, 0, 0, 0, 0, 0 }, { 2, 4, 8, 0, 0, 0, 0, 0, 0 }, { 2, 4, 8, 16, 0, 0, 0, 0, 0 }, { 1, 3, 7, 15, 0, 0, 0, 0, 0 }, { 2, 4, 8, 16, 0, 0, 0, 0, 0 }, { 1, 2, 8, 32, 0, 0, 0, 0, 0 }, { 1, 2, 4, 8, 32, 0, 0, 0, 0 }, { 2, 3, 4, 8, 12, 16, 32, 48, 0 }, }; enum queue_id_t { queue_moodycamel_ConcurrentQueue, queue_moodycamel_BlockingConcurrentQueue, queue_boost, queue_tbb, queue_simplelockfree, queue_lockbased, queue_std, QUEUE_COUNT }; const char QUEUE_NAMES[QUEUE_COUNT][64] = { "moodycamel::ConcurrentQueue", "moodycamel::BlockingConcurrentQueue", "boost::lockfree::queue", "tbb::concurrent_queue", "SimpleLockFreeQueue", "LockBasedQueue", "std::queue", }; const char QUEUE_SUMMARY_NOTES[QUEUE_COUNT][128] = { "including bulk", "including bulk", "", "", "", "", "single thread only", }; const bool QUEUE_TOKEN_SUPPORT[QUEUE_COUNT] = { true, true, false, false, false, false, false, }; const int QUEUE_MAX_THREADS[QUEUE_COUNT] = { -1, // no limit -1, -1, -1, -1, -1, 1, }; const bool QUEUE_BENCH_SUPPORT[QUEUE_COUNT][BENCHMARK_TYPE_COUNT] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, }; struct Traits : public moodycamel::ConcurrentQueueDefaultTraits { // Use a slightly larger default block size; the default offers // a good trade off between speed and memory usage, but a bigger // block size will improve throughput (which is mostly what // we're after with these benchmarks). static const size_t BLOCK_SIZE = 64; }; typedef std::uint64_t counter_t; const counter_t BULK_BATCH_SIZE = 2300; struct BenchmarkResult { double elapsedTime; counter_t operations; inline bool operator<(BenchmarkResult const& other) const { return elapsedTime < other.elapsedTime; } }; template counter_t rampUpToMeasurableNumberOfMaxOps(TFunc const& func, counter_t startOps = 256) { counter_t ops = startOps; double time; do { time = func(ops); ops *= 2; } while (time < (precise ? 30 : 10)); #ifdef NDEBUG return ops / 2; #else return ops / 4; #endif } counter_t adjustForThreads(counter_t suggestedOps, int nthreads) { return std::max((counter_t)(suggestedOps / std::pow(2, std::sqrt((nthreads - 1) * 3))), suggestedOps / 16); } template counter_t determineMaxOpsForBenchmark(benchmark_type_t benchmark, int nthreads, bool useTokens, unsigned int randSeed) { switch (benchmark) { case bench_balanced: { return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([&](counter_t ops) { TQueue q; RNG_t rng(randSeed * 1); std::uniform_int_distribution rand(0, 20); double total = 0; SystemTime start; for (counter_t i = 0; i != ops; ++i) { start = getSystemTime(); q.enqueue(i); total += getTimeDelta(start); } return total; }), nthreads); } case bench_only_enqueue: case bench_only_enqueue_prealloc: case bench_mostly_enqueue: { return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([](counter_t ops) { TQueue q; auto start = getSystemTime(); for (counter_t i = 0; i != ops; ++i) { q.enqueue(i); } return getTimeDelta(start); }), nthreads); } case bench_only_dequeue: case bench_mostly_dequeue: case bench_spmc: case bench_spmc_preproduced: case bench_mpsc: { return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([](counter_t ops) { TQueue q; for (counter_t i = 0; i != ops; ++i) { q.enqueue(i); } int item; auto start = getSystemTime(); for (counter_t i = 0; i != ops; ++i) { q.try_dequeue(item); } return getTimeDelta(start); }), nthreads); } case bench_only_enqueue_bulk: case bench_only_enqueue_bulk_prealloc: case bench_mostly_enqueue_bulk: { std::vector data; for (counter_t i = 0; i != BULK_BATCH_SIZE; ++i) { data.push_back(i); } return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([&](counter_t ops) { TQueue q; auto start = getSystemTime(); for (counter_t i = 0; i != ops; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } return getTimeDelta(start); }), nthreads); } case bench_only_dequeue_bulk: case bench_mostly_dequeue_bulk: { return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([](counter_t ops) { TQueue q; std::vector data(BULK_BATCH_SIZE); for (counter_t i = 0; i != ops; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } auto start = getSystemTime(); for (counter_t i = 0; i != ops; ++i) { q.try_dequeue_bulk(data.begin(), data.size()); } return getTimeDelta(start); }), nthreads); return 0; } case bench_empty_dequeue: { return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([](counter_t ops) { TQueue q; int item; auto start = getSystemTime(); for (counter_t i = 0; i != ops; ++i) { q.try_dequeue(item); } return getTimeDelta(start); }), nthreads); } case bench_enqueue_dequeue_pairs: { return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([](counter_t ops) { TQueue q; int item; auto start = getSystemTime(); for (counter_t i = 0; i != ops; ++i) { q.enqueue(i); q.try_dequeue(item); } return getTimeDelta(start); }), nthreads); } case bench_heavy_concurrent: { return adjustForThreads(rampUpToMeasurableNumberOfMaxOps([](counter_t ops) { TQueue q; int item; auto start = getSystemTime(); for (counter_t i = 0; i != ops; ++i) { q.enqueue(i); q.try_dequeue(item); } return getTimeDelta(start); }), nthreads); } default: assert(false && "Every benchmark type must be handled here!"); return 0; } } // Returns time elapsed, in (fractional) milliseconds template double runBenchmark(benchmark_type_t benchmark, int nthreads, bool useTokens, unsigned int randSeed, counter_t maxOps, int maxThreads, counter_t& out_opCount) { double result = 0; volatile int forceNoOptimizeDummy; switch (benchmark) { case bench_balanced: { // Measures the average operation speed with multiple symmetrical threads under reasonable load TQueue q; std::vector threads(nthreads); std::vector ops(nthreads); std::vector times(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; int item; SystemTime start; RNG_t rng(randSeed * (id + 1)); std::uniform_int_distribution rand(0, 20); ops[id] = 0; times[id] = 0; typename TQueue::consumer_token_t consTok(q); typename TQueue::producer_token_t prodTok(q); for (counter_t i = 0; i != maxOps; ++i) { if (rand(rng) == 0) { start = getSystemTime(); if ((i & 1) == 0) { if (useTokens) { q.try_dequeue(consTok, item); } else { q.try_dequeue(item); } } else { if (useTokens) { q.enqueue(prodTok, i); } else { q.enqueue(i); } } times[id] += getTimeDelta(start); ++ops[id]; } } }, tid); } out_opCount = 0; result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); out_opCount += ops[tid]; result += times[tid]; } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_only_enqueue_prealloc: { out_opCount = maxOps * nthreads; TQueue q; { // Enqueue opcount elements first, then dequeue them; this // will "stretch out" the queue, letting implementatations // that re-use memory internally avoid having to allocate // more later during the timed enqueue operations. std::vector threads(nthreads); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } }, tid); } for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); } // Now empty the queue int item; while (q.try_dequeue(item)) continue; } if (nthreads == 1) { // No contention -- measures raw single-item enqueue speed auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } result = getTimeDelta(start); } else { std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_only_enqueue: { out_opCount = maxOps * nthreads; TQueue q; if (nthreads == 1) { // No contention -- measures raw single-item enqueue speed auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } result = getTimeDelta(start); } else { std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_spmc_preproduced: case bench_only_dequeue: { out_opCount = maxOps * nthreads; TQueue q; { // Fill up the queue first std::vector threads(benchmark == bench_spmc_preproduced ? 1 : nthreads); counter_t itemsPerThread = benchmark == bench_spmc_preproduced ? maxOps * nthreads : maxOps; for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](size_t id) { if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != itemsPerThread; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != itemsPerThread; ++i) { q.enqueue(i); } } }, tid); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); } } if (nthreads == 1) { // No contention -- measures raw single-item dequeue speed int item; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(tok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(item); } } result = getTimeDelta(start); } else { std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; int item; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(tok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(item); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_mostly_enqueue: { // Measures the average operation speed when most threads are enqueueing TQueue q; out_opCount = maxOps * nthreads; std::vector threads(nthreads); std::vector timings(nthreads); auto dequeueThreads = std::max(1, nthreads / 4); std::atomic ready(0); for (int tid = 0; tid != nthreads - dequeueThreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } timings[id] = getTimeDelta(start); }, tid); } for (int tid = nthreads - dequeueThreads; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; int item; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(tok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(item); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_mostly_dequeue: { // Measures the average operation speed when most threads are dequeueing TQueue q; out_opCount = maxOps * nthreads; std::vector threads(nthreads); std::vector timings(nthreads); auto enqueueThreads = std::max(1, nthreads / 4); { // Fill up the queue first std::vector threads(enqueueThreads); for (int tid = 0; tid != enqueueThreads; ++tid) { threads[tid] = SimpleThread([&](int id) { if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } }, tid); } for (int tid = 0; tid != enqueueThreads; ++tid) { threads[tid].join(); } } std::atomic ready(0); for (int tid = 0; tid != nthreads - enqueueThreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; int item; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(tok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(item); } } timings[id] = getTimeDelta(start); }, tid); } for (int tid = nthreads - enqueueThreads; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_only_enqueue_bulk_prealloc: { TQueue q; { // Enqueue opcount elements first, then dequeue them; this // will "stretch out" the queue, letting implementatations // that re-use memory internally avoid having to allocate // more later during the timed enqueue operations. std::vector threads(nthreads); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } }, tid); } for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); } // Now empty the queue int item; while (q.try_dequeue(item)) continue; } std::vector data; for (counter_t i = 0; i != BULK_BATCH_SIZE; ++i) { data.push_back(i); } out_opCount = maxOps * BULK_BATCH_SIZE * nthreads; if (nthreads == 1) { auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, data.cbegin(), data.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } } result = getTimeDelta(start); } else { std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, data.cbegin(), data.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_only_enqueue_bulk: { TQueue q; std::vector data; for (counter_t i = 0; i != BULK_BATCH_SIZE; ++i) { data.push_back(i); } out_opCount = maxOps * BULK_BATCH_SIZE * nthreads; if (nthreads == 1) { auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, data.cbegin(), data.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } } result = getTimeDelta(start); } else { std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, data.cbegin(), data.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_mostly_enqueue_bulk: { // Measures the average speed of enqueueing in bulk under light contention TQueue q; std::vector data; for (counter_t i = 0; i != BULK_BATCH_SIZE; ++i) { data.push_back(i); } std::vector threads(nthreads); std::vector timings(nthreads); auto dequeueThreads = std::max(1, nthreads / 4); std::vector ops(nthreads - dequeueThreads); out_opCount = maxOps * BULK_BATCH_SIZE * (nthreads - dequeueThreads); // dequeue ops added after std::atomic ready(0); for (int tid = 0; tid != nthreads - dequeueThreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, data.cbegin(), data.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } } timings[id] = getTimeDelta(start); }, tid); } for (int tid = nthreads - dequeueThreads; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id, int idBase0) { std::vector items(BULK_BATCH_SIZE); ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; counter_t totalOps = 0; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { auto actual = q.try_dequeue_bulk(tok, items.begin(), items.size()); totalOps += actual + (actual == items.size() ? 0 : 1); } } else { for (counter_t i = 0; i != maxOps; ++i) { auto actual = q.try_dequeue_bulk(items.begin(), items.size()); totalOps += actual + (actual == items.size() ? 0 : 1); } } timings[id] = getTimeDelta(start); ops[idBase0] = totalOps; }, tid, tid - (nthreads - dequeueThreads)); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; if (tid < dequeueThreads) { out_opCount += ops[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_only_dequeue_bulk: { // Measures the average speed of dequeueing in bulk when all threads are consumers TQueue q; { // Fill up the queue first std::vector data(BULK_BATCH_SIZE); for (int i = 0; i != BULK_BATCH_SIZE; ++i) { data[i] = i; } std::vector threads(nthreads); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, data.cbegin(), data.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(data.cbegin(), data.size()); } } }, tid); } for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); } } if (nthreads == 1) { out_opCount = maxOps * BULK_BATCH_SIZE; auto start = getSystemTime(); std::vector items(BULK_BATCH_SIZE); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue_bulk(tok, items.begin(), items.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue_bulk(items.begin(), items.size()); } } result = getTimeDelta(start); } else { std::vector threads(nthreads); std::vector timings(nthreads); std::vector ops(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { std::vector items(BULK_BATCH_SIZE); ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; counter_t totalOps = 0; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { auto actual = q.try_dequeue_bulk(tok, items.begin(), items.size()); totalOps += actual + (actual == items.size() ? 0 : 1); } } else { for (counter_t i = 0; i != maxOps; ++i) { auto actual = q.try_dequeue_bulk(items.begin(), items.size()); totalOps += actual + (actual == items.size() ? 0 : 1); } } timings[id] = getTimeDelta(start); ops[id] = totalOps; }, tid); } result = 0; out_opCount = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; out_opCount += ops[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_mostly_dequeue_bulk: { // Measures the average speed of dequeueing in bulk under light contention TQueue q; auto enqueueThreads = std::max(1, nthreads / 4); out_opCount = maxOps * BULK_BATCH_SIZE * enqueueThreads; std::vector threads(nthreads); std::vector timings(nthreads); std::vector ops(nthreads - enqueueThreads); std::vector enqueueData(BULK_BATCH_SIZE); for (int i = 0; i != BULK_BATCH_SIZE; ++i) { enqueueData[i] = i; } { // Fill up the queue first std::vector threads(enqueueThreads); for (int tid = 0; tid != enqueueThreads; ++tid) { threads[tid] = SimpleThread([&](int id) { if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, enqueueData.cbegin(), enqueueData.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(enqueueData.cbegin(), enqueueData.size()); } } }, tid); } for (int tid = 0; tid != enqueueThreads; ++tid) { threads[tid].join(); } } std::atomic ready(0); for (int tid = 0; tid != nthreads - enqueueThreads; ++tid) { threads[tid] = SimpleThread([&](int id) { std::vector data(BULK_BATCH_SIZE); ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; counter_t totalOps = 0; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { auto actual = q.try_dequeue_bulk(tok, data.begin(), data.size()); totalOps += actual + (actual == data.size() ? 0 : 1); } } else { for (counter_t i = 0; i != maxOps; ++i) { auto actual = q.try_dequeue_bulk(data.begin(), data.size()); totalOps += actual + (actual == data.size() ? 0 : 1); } } timings[id] = getTimeDelta(start); ops[id] = totalOps; }, tid); } for (int tid = nthreads - enqueueThreads; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(tok, enqueueData.cbegin(), enqueueData.size()); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue_bulk(enqueueData.cbegin(), enqueueData.size()); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; if (tid < nthreads - enqueueThreads) { out_opCount += ops[tid]; } } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_spmc: { counter_t elementsToDequeue = maxOps * (nthreads - 1); TQueue q; std::vector threads(nthreads - 1); std::vector timings(nthreads - 1); std::vector ops(nthreads - 1); std::atomic lynchpin(false); std::atomic totalDequeued(0); for (int tid = 0; tid != nthreads - 1; ++tid) { threads[tid] = SimpleThread([&](int id) { while (!lynchpin.load(std::memory_order_relaxed)) { continue; } int item; counter_t i = 0; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); while (true) { if (q.try_dequeue(tok, item)) { totalDequeued.fetch_add(1, std::memory_order_relaxed); } else if (totalDequeued.load(std::memory_order_relaxed) == elementsToDequeue) { break; } ++i; } } else { while (true) { if (q.try_dequeue(item)) { totalDequeued.fetch_add(1, std::memory_order_relaxed); } else if (totalDequeued.load(std::memory_order_relaxed) == elementsToDequeue) { break; } ++i; } } timings[id] = getTimeDelta(start); ops[id] = i; }, tid); } lynchpin.store(true, std::memory_order_seq_cst); for (counter_t i = 0; i != elementsToDequeue; ++i) { q.enqueue(i); } result = 0; out_opCount = 0; for (int tid = 0; tid != nthreads - 1; ++tid) { threads[tid].join(); result += timings[tid]; out_opCount += ops[tid]; } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_mpsc: { TQueue q; counter_t elementsToDequeue = maxOps * (nthreads - 1); std::vector threads(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { if (tid == 0) { // Consumer thread threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_seq_cst); while (ready.load(std::memory_order_relaxed) != nthreads) continue; int item; out_opCount = 0; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != elementsToDequeue;) { i += q.try_dequeue(tok, item) ? 1 : 0; ++out_opCount; } } else { for (counter_t i = 0; i != elementsToDequeue;) { i += q.try_dequeue(item) ? 1 : 0; ++out_opCount; } } result = getTimeDelta(start); }, tid); } else { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_seq_cst); while (ready.load(std::memory_order_relaxed) != nthreads) continue; if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } }, tid); } } for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } case bench_empty_dequeue: { // Measures the average speed of attempting to dequeue from an empty queue TQueue q; // Fill up then empty the queue first { std::vector threads(maxThreads > 0 ? maxThreads : 8); for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](size_t id) { if (useTokens) { typename TQueue::producer_token_t tok(q); for (counter_t i = 0; i != 10000; ++i) { q.enqueue(tok, i); } } else { for (counter_t i = 0; i != 10000; ++i) { q.enqueue(i); } } }, tid); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); } // Empty the queue int item; while (q.try_dequeue(item)) continue; } if (nthreads == 1) { // No contention -- measures raw failed dequeue speed on empty queue int item; out_opCount = maxOps; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(tok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(item); } } result = getTimeDelta(start); forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; } else { out_opCount = maxOps * nthreads; std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; int item; auto start = getSystemTime(); if (useTokens) { typename TQueue::consumer_token_t tok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(tok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(item); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; } break; } case bench_enqueue_dequeue_pairs: { // Measures the average speed of attempting to dequeue from an empty queue // (that eight separate threads had at one point enqueued to) out_opCount = maxOps * 2 * nthreads; TQueue q; if (nthreads == 1) { // No contention -- measures speed of immediately dequeueing the item that was just enqueued int item; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t ptok(q); typename TQueue::consumer_token_t ctok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(ptok, i); q.try_dequeue(ctok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); q.try_dequeue(item); } } result = getTimeDelta(start); forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; } else { std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; int item; auto start = getSystemTime(); if (useTokens) { typename TQueue::producer_token_t ptok(q); typename TQueue::consumer_token_t ctok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(ptok, i); q.try_dequeue(ctok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); q.try_dequeue(item); } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; } break; } case bench_heavy_concurrent: { // Measures the average operation speed with many threads under heavy load out_opCount = maxOps * nthreads; TQueue q; std::vector threads(nthreads); std::vector timings(nthreads); std::atomic ready(0); for (int tid = 0; tid != nthreads; ++tid) { threads[tid] = SimpleThread([&](int id) { ready.fetch_add(1, std::memory_order_relaxed); while (ready.load(std::memory_order_relaxed) != nthreads) continue; auto start = getSystemTime(); if (id < 2) { // Alternate int item; if (useTokens) { typename TQueue::consumer_token_t consTok(q); typename TQueue::producer_token_t prodTok(q); for (counter_t i = 0; i != maxOps / 2; ++i) { q.try_dequeue(consTok, item); q.enqueue(prodTok, i); } } else { for (counter_t i = 0; i != maxOps / 2; ++i) { q.try_dequeue(item); q.enqueue(i); } } } else { if ((id & 1) == 0) { // Enqueue if (useTokens) { typename TQueue::producer_token_t prodTok(q); for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(prodTok, i); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.enqueue(i); } } } else { // Dequeue int item; if (useTokens) { typename TQueue::consumer_token_t consTok(q); for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(consTok, item); } } else { for (counter_t i = 0; i != maxOps; ++i) { q.try_dequeue(item); } } } } timings[id] = getTimeDelta(start); }, tid); } result = 0; for (int tid = 0; tid != nthreads; ++tid) { threads[tid].join(); result += timings[tid]; } int item; forceNoOptimizeDummy = q.try_dequeue(item) ? 1 : 0; break; } default: assert(false && "Every benchmark type must be handled here!"); result = 0; out_opCount = 0; } (void)forceNoOptimizeDummy; return result; } const char* LOG_FILE = "benchmarks.log"; std::ofstream* logOut; bool logErrorReported = false; void sayf(int indent, const char* fmt, ...) { static char indentBuffer[] = " "; static char buf[2048]; indentBuffer[indent] = '\0'; va_list arglist; va_start(arglist, fmt); vsprintf(buf, fmt, arglist); va_end(arglist); if (*logOut) { (*logOut) << indentBuffer << buf; } else if (!logErrorReported) { std::printf("Note: Error writing to log file. Future output will appear only on stdout\n"); logErrorReported = true; } std::printf("%s%s", indentBuffer, buf); indentBuffer[indent] = ' '; } // Returns a formatted timestamp. // Returned buffer is only valid until the next call. // Not thread-safe. static const char* timestamp() { static char buf[32]; time_t time = std::time(NULL); strcpy(buf, std::asctime(std::localtime(&time))); buf[strlen(buf) - 1] = '\0'; // Remove trailing newline return buf; } static inline bool isvowel(char ch) { ch = std::tolower(ch); for (const char* v = "aeiou"; *v != '\0'; ++v) { if (*v == ch) { return true; } } return false; } static inline double safe_divide(double a, double b) { return b == 0 ? 0 : a / b; } // Returns a positive number formatted in a string in a human-readable way. // The string is always 7 characters or less (excluding null byte). // Returned buffer is only valid until the sixteenth next call. // Not thread safe. static const char* pretty(double num) { assert(num >= 0); #if defined(_MSC_VER) && _MSC_VER < 1800 if (!_finite(num)) { return "inf"; } if (_isnan(num)) { return "nan"; } #else if (std::isinf(num)) { return "inf"; } if (std::isnan(num)) { return "nan"; } #endif static char bufs[16][8]; static int nextBuf = 0; char* buf = bufs[nextBuf++]; nextBuf &= 15; int suffix = 0; if (num < 1) { static const char minisufs[] = "\0munpfazy"; while (num < 0.01) { ++suffix; num *= 1000; } sprintf(buf, "%1.4f%c", num, minisufs[suffix]); } else { static const char megasufs[] = "\0kMGTPEZY"; while (num >= 1000) { ++suffix; num /= 1000; } sprintf(buf, "%.2f%c", num, megasufs[suffix]); } return buf; } void printBenchmarkNames() { std::printf(" Supported benchmarks are:\n"); for (int i = 0; i != BENCHMARK_TYPE_COUNT; ++i) { std::printf(" %s\n", BENCHMARK_SHORT_NAMES[i]); } } int main(int argc, char** argv) { // Disable buffering (so that when run in, e.g., Sublime Text, the output appears as it is written) std::setvbuf(stdout, nullptr, _IONBF, 0); // Isolate the executable name std::string progName = argv[0]; auto slash = progName.find_last_of("/\\"); if (slash != std::string::npos) { progName = progName.substr(slash + 1); } std::map benchmarkMap; for (int i = 0; i != BENCHMARK_TYPE_COUNT; ++i) { benchmarkMap.insert(std::make_pair(std::string(BENCHMARK_SHORT_NAMES[i]), (benchmark_type_t)i)); } std::vector selectedBenchmarks; bool showHelp = false; bool error = false; bool printedBenchmarks = false; for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "-h") == 0 || std::strcmp(argv[i], "--help") == 0) { showHelp = true; } else if (std::strcmp(argv[i], "-p") == 0 || std::strcmp(argv[i], "--precise") == 0) { precise = true; } else if (std::strcmp(argv[i], "--run") == 0) { if (i + 1 == argc || argv[i + 1][0] == '-') { std::printf("Expected benchmark name argument for --run option.\n"); if (!printedBenchmarks) { printBenchmarkNames(); printedBenchmarks = true; } error = true; continue; } auto it = benchmarkMap.find(argv[++i]); if (it == benchmarkMap.end()) { std::printf("Unrecognized benchmark name '%s'.\n", argv[i]); if (!printedBenchmarks) { printBenchmarkNames(); printedBenchmarks = true; } error = true; continue; } selectedBenchmarks.push_back(it->second); } else { std::printf("Unrecognized option '%s'\n", argv[i]); error = true; } } if (showHelp || error) { if (error) { std::printf("\n"); } std::printf("%s\n Description: Runs benchmarks for moodycamel::ConcurrentQueue\n", progName.c_str()); std::printf(" --help Prints this help blurb\n"); std::printf(" --precise Generate more precise benchmark results (slower)\n"); std::printf(" --run benchmark Runs only the selected benchmark (can be used multiple times)\n"); return error ? 1 : 0; } bool logExists = true; { std::ifstream fin(LOG_FILE); if (!fin) { logExists = false; } } std::ofstream fout(LOG_FILE, std::ios::app); logOut = &fout; if (fout) { if (logExists) { fout << "\n\n\n"; } fout << "--- New run (" << timestamp() << ") ---\n"; } else { std::printf("Note: Error opening log file '%s'. Output will appear only on stdout.\n\n", LOG_FILE); logErrorReported = true; } const char* bitStr = ""; if (sizeof(void*) == 4 || sizeof(void*) == 8) { bitStr = sizeof(void*) == 4 ? " 32-bit" : " 64-bit"; } const char* cpuStr = getCPUString(); sayf(0, "Running%s benchmarks on a%s %s\n", bitStr, isvowel(cpuStr[0]) ? "n" : "", cpuStr); if (precise) { sayf(4, "(precise mode)\n"); } if (selectedBenchmarks.size() > 0) { sayf(4, "(selected benchmarks only)\n"); } sayf(0, "Note that these are synthetic benchmarks. Take them with a grain of salt.\n\n"); sayf(0, "Legend:\n"); sayf(4, "'Avg': Average time taken per operation, normalized to be per thread\n"); sayf(4, "'Range': The minimum and maximum times taken per operation (per thread)\n"); sayf(4, "'Ops/s': Overall operations per second\n"); sayf(4, "'Ops/s/t': Operations per second per thread (inverse of 'Avg')\n"); sayf(4, "Operations include those that fail (e.g. because the queue is empty).\n"); sayf(4, "Each logical enqueue/dequeue counts as an individual operation when in bulk.\n"); sayf(0, "\n"); #ifdef NDEBUG const int ITERATIONS = precise ? 100 : 10; #else const int ITERATIONS = precise ? 20 : 2; #endif const double FASTEST_PERCENT_CONSIDERED = precise ? 8 : 50; // Only consider the top % of runs // Make sure each run of a given benchmark has the same seed (otherwise different runs are not comparable) std::srand(std::time(NULL)); unsigned int randSeeds[BENCHMARK_TYPE_COUNT]; for (unsigned int i = 0; i != BENCHMARK_TYPE_COUNT; ++i) { randSeeds[i] = std::rand() * (i + 1) + 1; } double opsst = 0; // ops/s/thread double totalWeightedOpsst[QUEUE_COUNT]; double totalWeight[QUEUE_COUNT]; for (int i = 0; i != QUEUE_COUNT; ++i) { totalWeightedOpsst[i] = 0; totalWeight[i] = 0; } auto logicalCores = std::thread::hardware_concurrency(); if (selectedBenchmarks.size() == 0) { for (int i = 0; i != BENCHMARK_TYPE_COUNT; ++i) { selectedBenchmarks.push_back((benchmark_type_t)i); } } int indent = 0; for (auto selectedIt = selectedBenchmarks.cbegin(); selectedIt != selectedBenchmarks.cend(); ++selectedIt) { int benchmark = static_cast(*selectedIt); auto seed = randSeeds[benchmark]; bool anyQueueSupportsBenchmark = false; for (int queue = 0; queue != QUEUE_COUNT; ++queue) { if (QUEUE_BENCH_SUPPORT[queue][benchmark]) { anyQueueSupportsBenchmark = true; break; } } if (!anyQueueSupportsBenchmark) { continue; } sayf(0, "%s", BENCHMARK_NAMES[benchmark]); if (BENCHMARK_THREADS_MEASURED[benchmark] != 0) { if (BENCHMARK_THREADS_MEASURED[benchmark] < 0) { sayf(0, " (measuring all but %d %s)", -BENCHMARK_THREADS_MEASURED[benchmark], BENCHMARK_THREADS_MEASURED[benchmark] == -1 ? "thread" : "threads"); } else { sayf(0, " (measuring %d %s)", BENCHMARK_THREADS_MEASURED[benchmark], BENCHMARK_THREADS_MEASURED[benchmark] == 1 ? "thread" : "threads"); } } sayf(0, ":\n"); indent += 2; sayf(indent, "(%s)\n", BENCHMARK_DESCS[benchmark]); for (int queue = 0; queue != QUEUE_COUNT; ++queue) { sayf(indent, "> %s\n", QUEUE_NAMES[queue]); if (!QUEUE_BENCH_SUPPORT[queue][benchmark]) { sayf(indent + 3, "(skipping, benchmark not supported...)\n\n"); continue; } if (QUEUE_TOKEN_SUPPORT[queue]) { indent += 4; } for (int useTokens = 0; useTokens != 2; ++useTokens) { if (QUEUE_TOKEN_SUPPORT[queue]) { sayf(indent, "%s tokens\n", useTokens == 0 ? "Without" : "With"); } if (useTokens == 1 && !QUEUE_TOKEN_SUPPORT[queue]) { continue; } indent += 3; std::vector opssts; std::vector threadCounts; for (int nthreadIndex = 0; BENCHMARK_THREADS[benchmark][nthreadIndex] != 0; ++nthreadIndex) { int nthreads = BENCHMARK_THREADS[benchmark][nthreadIndex]; int measuredThreads = nthreads; if (BENCHMARK_THREADS_MEASURED[benchmark] != 0) { measuredThreads = BENCHMARK_THREADS_MEASURED[benchmark] < 0 ? nthreads + BENCHMARK_THREADS_MEASURED[benchmark] : BENCHMARK_THREADS_MEASURED[benchmark]; } if (logicalCores > 0 && (unsigned int)nthreads > 3 * logicalCores) { continue; } if (QUEUE_MAX_THREADS[queue] >= 0 && QUEUE_MAX_THREADS[queue] < nthreads) { continue; } counter_t maxOps; switch ((queue_id_t)queue) { case queue_moodycamel_ConcurrentQueue: maxOps = determineMaxOpsForBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed); break; case queue_moodycamel_BlockingConcurrentQueue: maxOps = determineMaxOpsForBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed); break; case queue_lockbased: maxOps = determineMaxOpsForBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed); break; case queue_simplelockfree: maxOps = determineMaxOpsForBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed); break; case queue_boost: maxOps = determineMaxOpsForBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed); break; case queue_tbb: maxOps = determineMaxOpsForBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed); break; case queue_std: maxOps = determineMaxOpsForBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed); break; default: assert(false && "There should be a case here for every queue in the benchmarks!"); } //std::printf("maxOps: %llu\n", maxOps); int maxThreads = QUEUE_MAX_THREADS[queue]; std::vector results(ITERATIONS); for (int i = 0; i < ITERATIONS; ++i) { double elapsed; counter_t ops = 0; switch ((queue_id_t)queue) { case queue_moodycamel_ConcurrentQueue: elapsed = runBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed, maxOps, maxThreads, ops); break; case queue_moodycamel_BlockingConcurrentQueue: elapsed = runBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed, maxOps, maxThreads, ops); break; case queue_lockbased: elapsed = runBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed, maxOps, maxThreads, ops); break; case queue_simplelockfree: elapsed = runBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed, maxOps, maxThreads, ops); break; case queue_boost: elapsed = runBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed, maxOps, maxThreads, ops); break; case queue_tbb: elapsed = runBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed, maxOps, maxThreads, ops); break; case queue_std: elapsed = runBenchmark>((benchmark_type_t)benchmark, nthreads, (bool)useTokens, seed, maxOps, maxThreads, ops); break; default: assert(false && "There should be a case here for every queue in the benchmarks!"); } results[i].elapsedTime = elapsed; results[i].operations = ops; } std::sort(&results[0], &results[0] + ITERATIONS); int consideredCount = std::max(2, (int)(ITERATIONS * FASTEST_PERCENT_CONSIDERED / 100)); double min = safe_divide(results[0].elapsedTime / 1000.0, (double)results[0].operations / measuredThreads); double max = safe_divide(results[0].elapsedTime / 1000.0, (double)results[0].operations / measuredThreads); double ops = 0; double time = 0; for (int i = 0; i != consideredCount; ++i) { double msPerOperation = safe_divide(results[i].elapsedTime / 1000.0, (double)results[i].operations / measuredThreads); if (msPerOperation < min) { min = msPerOperation; } else if (msPerOperation > max) { max = msPerOperation; } time += results[i].elapsedTime; ops += results[i].operations; } double avg = safe_divide(time / 1000.0, ops / measuredThreads); double opsPerSecond = safe_divide(ops, time / 1000.0); opsst = opsPerSecond / (double)measuredThreads; opssts.push_back(opsst); threadCounts.push_back(measuredThreads); sayf(indent, "%-3d %7s: Avg: %7ss Range: [%7ss, %7ss] Ops/s: %7s Ops/s/t: %7s\n", nthreads, nthreads != 1 ? "threads" : "thread", pretty(avg), pretty(min), pretty(max), pretty(opsPerSecond), pretty(opsst)); if (nthreads == 1 && BENCHMARK_SINGLE_THREAD_NOTES[benchmark][0] != '\0') { sayf(indent + 7, "^ Note: %s\n", BENCHMARK_SINGLE_THREAD_NOTES[benchmark]); } } opsst = 0; double divisor = 0; for (size_t i = 0; i != opssts.size(); ++i) { opsst += opssts[i] * std::sqrt(threadCounts[i]); totalWeightedOpsst[queue] += opssts[i] * std::sqrt(threadCounts[i]); divisor += std::sqrt(threadCounts[i]); totalWeight[queue] += std::sqrt(threadCounts[i]); } opsst /= divisor; sayf(indent, "Operations per second per thread (weighted average): %7s\n\n", opsst == 0 ? "(n/a)" : pretty(opsst)); indent -= 3; } if (QUEUE_TOKEN_SUPPORT[queue]) { indent -= 4; } } indent -= 2; } sayf(0, "Overall average operations per second per thread (where higher-concurrency runs have more weight):\n"); sayf(0, "(Take this summary with a grain of salt -- look at the individual benchmark results for a much\nbetter idea of how the queues measure up to each other):\n"); for (int queue = 0; queue != QUEUE_COUNT; ++queue) { opsst = safe_divide(totalWeightedOpsst[queue], totalWeight[queue]); if (QUEUE_SUMMARY_NOTES[queue] != nullptr && QUEUE_SUMMARY_NOTES[queue][0] != '\0') { sayf(4, "%s (%s): %7s\n", QUEUE_NAMES[queue], QUEUE_SUMMARY_NOTES[queue], opsst == 0 ? "(n/a)" : pretty(opsst)); } else { sayf(4, "%s: %7s\n", QUEUE_NAMES[queue], opsst == 0 ? "(n/a)" : pretty(opsst)); } } return 0; } ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/LICENSE_1_0.txt ================================================ Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/README.txt ================================================ This is a partial copy of Boost 1.60, specifically only the parts that boost/lockfree/queue.hpp depends on (extracted using bcp). ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/array.hpp ================================================ /* The following code declares class array, * an STL container (as wrapper) for arrays of constant size. * * See * http://www.boost.org/libs/array/ * for documentation. * * The original author site is at: http://www.josuttis.com/ * * (C) Copyright Nicolai M. Josuttis 2001. * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * 14 Apr 2012 - (mtc) Added support for boost::hash * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility. * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group. * See or Trac issue #3168 * Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow) * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow) * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. * 05 Aug 2001 - minor update (Nico Josuttis) * 20 Jan 2001 - STLport fix (Beman Dawes) * 29 Sep 2000 - Initial Revision (Nico Josuttis) * * Jan 29, 2004 */ #ifndef BOOST_ARRAY_HPP #define BOOST_ARRAY_HPP #include #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) # pragma warning(push) # pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe # pragma warning(disable:4510) // boost::array' : default constructor could not be generated # pragma warning(disable:4610) // warning C4610: class 'boost::array' can never be instantiated - user defined constructor required #endif #include #include #include #include // Handles broken standard libraries better than #include #include #include #include // FIXES for broken compilers #include namespace boost { template class array { public: T elems[N]; // fixed-size array of elements of type T public: // type definitions typedef T value_type; typedef T* iterator; typedef const T* const_iterator; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // iterator support iterator begin() { return elems; } const_iterator begin() const { return elems; } const_iterator cbegin() const { return elems; } iterator end() { return elems+N; } const_iterator end() const { return elems+N; } const_iterator cend() const { return elems+N; } // reverse iterator support #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) // workaround for broken reverse_iterator in VC7 typedef std::reverse_iterator > reverse_iterator; typedef std::reverse_iterator > const_reverse_iterator; #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #else // workaround for broken reverse_iterator implementations typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #endif reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } // operator[] reference operator[](size_type i) { BOOST_ASSERT_MSG( i < N, "out of range" ); return elems[i]; } const_reference operator[](size_type i) const { BOOST_ASSERT_MSG( i < N, "out of range" ); return elems[i]; } // at() with range check reference at(size_type i) { rangecheck(i); return elems[i]; } const_reference at(size_type i) const { rangecheck(i); return elems[i]; } // front() and back() reference front() { return elems[0]; } const_reference front() const { return elems[0]; } reference back() { return elems[N-1]; } const_reference back() const { return elems[N-1]; } // size is constant static size_type size() { return N; } static bool empty() { return false; } static size_type max_size() { return N; } enum { static_size = N }; // swap (note: linear complexity) void swap (array& y) { for (size_type i = 0; i < N; ++i) boost::swap(elems[i],y.elems[i]); } // direct access to data (read-only) const T* data() const { return elems; } T* data() { return elems; } // use array as C array (direct read/write access to data) T* c_array() { return elems; } // assignment with type conversion template array& operator= (const array& rhs) { std::copy(rhs.begin(),rhs.end(), begin()); return *this; } // assign one value to all elements void assign (const T& value) { fill ( value ); } // A synonym for fill void fill (const T& value) { std::fill_n(begin(),size(),value); } // check range (may be private because it is static) static void rangecheck (size_type i) { if (i >= size()) { std::out_of_range e("array<>: index out of range"); boost::throw_exception(e); } } }; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< class T > class array< T, 0 > { public: // type definitions typedef T value_type; typedef T* iterator; typedef const T* const_iterator; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // iterator support iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); } const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } iterator end() { return begin(); } const_iterator end() const { return begin(); } const_iterator cend() const { return cbegin(); } // reverse iterator support #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) // workaround for broken reverse_iterator in VC7 typedef std::reverse_iterator > reverse_iterator; typedef std::reverse_iterator > const_reverse_iterator; #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #else // workaround for broken reverse_iterator implementations typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #endif reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } // operator[] reference operator[](size_type /*i*/) { return failed_rangecheck(); } const_reference operator[](size_type /*i*/) const { return failed_rangecheck(); } // at() with range check reference at(size_type /*i*/) { return failed_rangecheck(); } const_reference at(size_type /*i*/) const { return failed_rangecheck(); } // front() and back() reference front() { return failed_rangecheck(); } const_reference front() const { return failed_rangecheck(); } reference back() { return failed_rangecheck(); } const_reference back() const { return failed_rangecheck(); } // size is constant static size_type size() { return 0; } static bool empty() { return true; } static size_type max_size() { return 0; } enum { static_size = 0 }; void swap (array& /*y*/) { } // direct access to data (read-only) const T* data() const { return 0; } T* data() { return 0; } // use array as C array (direct read/write access to data) T* c_array() { return 0; } // assignment with type conversion template array& operator= (const array& ) { return *this; } // assign one value to all elements void assign (const T& value) { fill ( value ); } void fill (const T& ) {} // check range (may be private because it is static) static reference failed_rangecheck () { std::out_of_range e("attempt to access element of an empty array"); boost::throw_exception(e); #if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__)) // // We need to return something here to keep // some compilers happy: however we will never // actually get here.... // static T placeholder; return placeholder; #endif } }; #endif // comparisons template bool operator== (const array& x, const array& y) { return std::equal(x.begin(), x.end(), y.begin()); } template bool operator< (const array& x, const array& y) { return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); } template bool operator!= (const array& x, const array& y) { return !(x==y); } template bool operator> (const array& x, const array& y) { return y bool operator<= (const array& x, const array& y) { return !(y bool operator>= (const array& x, const array& y) { return !(x inline void swap (array& x, array& y) { x.swap(y); } #if defined(__SUNPRO_CC) // Trac ticket #4757; the Sun Solaris compiler can't handle // syntax like 'T(&get_c_array(boost::array& arg))[N]' // // We can't just use this for all compilers, because the // borland compilers can't handle this form. namespace detail { template struct c_array { typedef T type[N]; }; } // Specific for boost::array: simply returns its elems data member. template typename detail::c_array::type& get_c_array(boost::array& arg) { return arg.elems; } // Specific for boost::array: simply returns its elems data member. template typename const detail::c_array::type& get_c_array(const boost::array& arg) { return arg.elems; } #else // Specific for boost::array: simply returns its elems data member. template T(&get_c_array(boost::array& arg))[N] { return arg.elems; } // Const version. template const T(&get_c_array(const boost::array& arg))[N] { return arg.elems; } #endif #if 0 // Overload for std::array, assuming that std::array will have // explicit conversion functions as discussed at the WG21 meeting // in Summit, March 2009. template T(&get_c_array(std::array& arg))[N] { return static_cast(arg); } // Const version. template const T(&get_c_array(const std::array& arg))[N] { return static_cast(arg); } #endif template std::size_t hash_value(const array& arr) { return boost::hash_range(arr.begin(), arr.end()); } } /* namespace boost */ #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) # pragma warning(pop) #endif #endif /*BOOST_ARRAY_HPP*/ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/assert.hpp ================================================ // // boost/assert.hpp - BOOST_ASSERT(expr) // BOOST_ASSERT_MSG(expr, msg) // BOOST_VERIFY(expr) // BOOST_VERIFY_MSG(expr, msg) // BOOST_ASSERT_IS_VOID // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2007, 2014 Peter Dimov // Copyright (c) Beman Dawes 2011 // Copyright (c) 2015 Ion Gaztanaga // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // // Note: There are no include guards. This is intentional. // // See http://www.boost.org/libs/assert/assert.html for documentation. // // // Stop inspect complaining about use of 'assert': // // boostinspect:naassert_macro // // // BOOST_ASSERT, BOOST_ASSERT_MSG, BOOST_ASSERT_IS_VOID // #undef BOOST_ASSERT #undef BOOST_ASSERT_MSG #undef BOOST_ASSERT_IS_VOID #if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ) # define BOOST_ASSERT(expr) ((void)0) # define BOOST_ASSERT_MSG(expr, msg) ((void)0) # define BOOST_ASSERT_IS_VOID #elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) ) #include // for BOOST_LIKELY #include namespace boost { void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined } // namespace boost #define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) #else # include // .h to support old libraries w/o - effect is the same # define BOOST_ASSERT(expr) assert(expr) # define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) #if defined(NDEBUG) # define BOOST_ASSERT_IS_VOID #endif #endif // // BOOST_VERIFY, BOOST_VERIFY_MSG // #undef BOOST_VERIFY #undef BOOST_VERIFY_MSG #if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) # define BOOST_VERIFY(expr) ((void)(expr)) # define BOOST_VERIFY_MSG(expr, msg) ((void)(expr)) #else # define BOOST_VERIFY(expr) BOOST_ASSERT(expr) # define BOOST_VERIFY_MSG(expr, msg) BOOST_ASSERT_MSG(expr,msg) #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/atomic.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2011 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/atomic.hpp * * This header contains definition of \c atomic template and \c atomic_flag. */ #ifndef BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ #define BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { using atomics::atomic; using atomics::atomic_char; using atomics::atomic_uchar; using atomics::atomic_schar; using atomics::atomic_uint8_t; using atomics::atomic_int8_t; using atomics::atomic_ushort; using atomics::atomic_short; using atomics::atomic_uint16_t; using atomics::atomic_int16_t; using atomics::atomic_uint; using atomics::atomic_int; using atomics::atomic_uint32_t; using atomics::atomic_int32_t; using atomics::atomic_ulong; using atomics::atomic_long; using atomics::atomic_uint64_t; using atomics::atomic_int64_t; #ifdef BOOST_HAS_LONG_LONG using atomics::atomic_ullong; using atomics::atomic_llong; #endif using atomics::atomic_address; using atomics::atomic_bool; using atomics::atomic_wchar_t; #if !defined(BOOST_NO_CXX11_CHAR16_T) using atomics::atomic_char16_t; #endif #if !defined(BOOST_NO_CXX11_CHAR32_T) using atomics::atomic_char32_t; #endif using atomics::atomic_int_least8_t; using atomics::atomic_uint_least8_t; using atomics::atomic_int_least16_t; using atomics::atomic_uint_least16_t; using atomics::atomic_int_least32_t; using atomics::atomic_uint_least32_t; using atomics::atomic_int_least64_t; using atomics::atomic_uint_least64_t; using atomics::atomic_int_fast8_t; using atomics::atomic_uint_fast8_t; using atomics::atomic_int_fast16_t; using atomics::atomic_uint_fast16_t; using atomics::atomic_int_fast32_t; using atomics::atomic_uint_fast32_t; using atomics::atomic_int_fast64_t; using atomics::atomic_uint_fast64_t; using atomics::atomic_intmax_t; using atomics::atomic_uintmax_t; using atomics::atomic_size_t; using atomics::atomic_ptrdiff_t; #if defined(BOOST_HAS_INTPTR_T) using atomics::atomic_intptr_t; using atomics::atomic_uintptr_t; #endif } // namespace boost #endif // BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/atomic_flag.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2011 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/atomic_flag.hpp * * This header contains definition of \c atomic_flag. */ #ifndef BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_ #define BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_ #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { using atomics::atomic_flag; } // namespace boost #endif // BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/capabilities.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/capabilities.hpp * * This header defines feature capabilities macros. */ #ifndef BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_ #define BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_ #include #include #include #if !defined(BOOST_ATOMIC_EMULATED) #include BOOST_ATOMIC_DETAIL_HEADER(boost/atomic/detail/caps_) #endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #ifndef BOOST_ATOMIC_INT8_LOCK_FREE #define BOOST_ATOMIC_INT8_LOCK_FREE 0 #endif #ifndef BOOST_ATOMIC_INT16_LOCK_FREE #define BOOST_ATOMIC_INT16_LOCK_FREE 0 #endif #ifndef BOOST_ATOMIC_INT32_LOCK_FREE #define BOOST_ATOMIC_INT32_LOCK_FREE 0 #endif #ifndef BOOST_ATOMIC_INT64_LOCK_FREE #define BOOST_ATOMIC_INT64_LOCK_FREE 0 #endif #ifndef BOOST_ATOMIC_INT128_LOCK_FREE #define BOOST_ATOMIC_INT128_LOCK_FREE 0 #endif #ifndef BOOST_ATOMIC_CHAR_LOCK_FREE #define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #endif #ifndef BOOST_ATOMIC_CHAR16_T_LOCK_FREE #define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #endif #ifndef BOOST_ATOMIC_CHAR32_T_LOCK_FREE #define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #endif #ifndef BOOST_ATOMIC_WCHAR_T_LOCK_FREE #if BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE #else #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0 #endif #endif #ifndef BOOST_ATOMIC_SHORT_LOCK_FREE #if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1 #define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2 #define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4 #define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8 #define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE #else #define BOOST_ATOMIC_SHORT_LOCK_FREE 0 #endif #endif #ifndef BOOST_ATOMIC_INT_LOCK_FREE #if BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1 #define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2 #define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4 #define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8 #define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE #else #define BOOST_ATOMIC_INT_LOCK_FREE 0 #endif #endif #ifndef BOOST_ATOMIC_LONG_LOCK_FREE #if BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1 #define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2 #define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4 #define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8 #define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE #else #define BOOST_ATOMIC_LONG_LOCK_FREE 0 #endif #endif #ifndef BOOST_ATOMIC_LLONG_LOCK_FREE #if BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1 #define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2 #define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4 #define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8 #define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE #else #define BOOST_ATOMIC_LLONG_LOCK_FREE 0 #endif #endif #ifndef BOOST_ATOMIC_POINTER_LOCK_FREE #if (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 8 #define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE #elif (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 4 #define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #else #define BOOST_ATOMIC_POINTER_LOCK_FREE 0 #endif #endif #define BOOST_ATOMIC_ADDRESS_LOCK_FREE BOOST_ATOMIC_POINTER_LOCK_FREE #ifndef BOOST_ATOMIC_BOOL_LOCK_FREE // We store bools in 1-byte storage in all backends #define BOOST_ATOMIC_BOOL_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #endif #ifndef BOOST_ATOMIC_FLAG_LOCK_FREE #define BOOST_ATOMIC_FLAG_LOCK_FREE BOOST_ATOMIC_BOOL_LOCK_FREE #endif #ifndef BOOST_ATOMIC_THREAD_FENCE #define BOOST_ATOMIC_THREAD_FENCE 0 #endif #ifndef BOOST_ATOMIC_SIGNAL_FENCE #define BOOST_ATOMIC_SIGNAL_FENCE 0 #endif #endif // BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/atomic_flag.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/atomic_flag.hpp * * This header contains interface definition of \c atomic_flag. */ #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_ #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif /* * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE, * see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp. */ namespace boost { namespace atomics { #if defined(BOOST_NO_CXX11_CONSTEXPR) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) #define BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT #else #define BOOST_ATOMIC_FLAG_INIT {} #endif struct atomic_flag { typedef atomics::detail::operations< 1u, false > operations; typedef operations::storage_type storage_type; operations::aligned_storage_type m_storage; BOOST_FORCEINLINE BOOST_CONSTEXPR atomic_flag() BOOST_NOEXCEPT : m_storage(0) { } BOOST_FORCEINLINE bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return operations::test_and_set(m_storage.value, order); } BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_acquire); BOOST_ASSERT(order != memory_order_acq_rel); operations::clear(m_storage.value, order); } BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&)) BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&)) }; } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/atomic_template.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2011 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/atomic_template.hpp * * This header contains interface definition of \c atomic template. */ #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_ #include #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(BOOST_MSVC) #pragma warning(push) // 'boost::atomics::atomic' : multiple assignment operators specified #pragma warning(disable: 4522) #endif /* * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE, * see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp. */ namespace boost { namespace atomics { namespace detail { BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order deduce_failure_order(memory_order order) BOOST_NOEXCEPT { return order == memory_order_acq_rel ? memory_order_acquire : (order == memory_order_release ? memory_order_relaxed : order); } BOOST_FORCEINLINE BOOST_CONSTEXPR bool cas_failure_order_must_not_be_stronger_than_success_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { // 15 == (memory_order_seq_cst | memory_order_consume), see memory_order.hpp // Given the enum values we can test the strength of memory order requirements with this single condition. return (failure_order & 15u) <= (success_order & 15u); } template< typename T, bool IsInt = boost::is_integral< T >::value > struct classify { typedef void type; }; template< typename T > struct classify< T, true > { typedef int type; }; template< typename T > struct classify< T*, false > { typedef void* type; }; template< typename T, typename Kind > class base_atomic; //! Implementation for integers template< typename T > class base_atomic< T, int > { private: typedef T value_type; typedef T difference_type; typedef atomics::detail::operations< storage_size_of< value_type >::value, boost::is_signed< T >::value > operations; protected: typedef value_type value_arg_type; public: typedef typename operations::storage_type storage_type; protected: typename operations::aligned_storage_type m_storage; public: BOOST_DEFAULTED_FUNCTION(base_atomic(), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : m_storage(v) {} BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_consume); BOOST_ASSERT(order != memory_order_acquire); BOOST_ASSERT(order != memory_order_acq_rel); operations::store(m_storage.value, static_cast< storage_type >(v), order); } BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_release); BOOST_ASSERT(order != memory_order_acq_rel); return static_cast< value_type >(operations::load(m_storage.value, order)); } BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return static_cast< value_type >(operations::fetch_add(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return static_cast< value_type >(operations::fetch_sub(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return static_cast< value_type >(operations::exchange(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = static_cast< storage_type >(expected); const bool res = operations::compare_exchange_strong(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order); expected = static_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = static_cast< storage_type >(expected); const bool res = operations::compare_exchange_weak(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order); expected = static_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return static_cast< value_type >(operations::fetch_and(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return static_cast< value_type >(operations::fetch_or(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return static_cast< value_type >(operations::fetch_xor(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT { return operations::is_lock_free(m_storage.value); } BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT { return fetch_add(1); } BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT { return fetch_add(1) + 1; } BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT { return fetch_sub(1); } BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT { return fetch_sub(1) - 1; } BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT { return fetch_add(v) + v; } BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT { return fetch_sub(v) - v; } BOOST_FORCEINLINE value_type operator&=(value_type v) volatile BOOST_NOEXCEPT { return fetch_and(v) & v; } BOOST_FORCEINLINE value_type operator|=(value_type v) volatile BOOST_NOEXCEPT { return fetch_or(v) | v; } BOOST_FORCEINLINE value_type operator^=(value_type v) volatile BOOST_NOEXCEPT { return fetch_xor(v) ^ v; } BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) }; //! Implementation for bool template< > class base_atomic< bool, int > { private: typedef bool value_type; typedef atomics::detail::operations< 1u, false > operations; protected: typedef value_type value_arg_type; public: typedef operations::storage_type storage_type; protected: operations::aligned_storage_type m_storage; public: BOOST_DEFAULTED_FUNCTION(base_atomic(), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : m_storage(v) {} BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_consume); BOOST_ASSERT(order != memory_order_acquire); BOOST_ASSERT(order != memory_order_acq_rel); operations::store(m_storage.value, static_cast< storage_type >(v), order); } BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_release); BOOST_ASSERT(order != memory_order_acq_rel); return !!operations::load(m_storage.value, order); } BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return !!operations::exchange(m_storage.value, static_cast< storage_type >(v), order); } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = static_cast< storage_type >(expected); const bool res = operations::compare_exchange_strong(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order); expected = !!old_value; return res; } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = static_cast< storage_type >(expected); const bool res = operations::compare_exchange_weak(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order); expected = !!old_value; return res; } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT { return operations::is_lock_free(m_storage.value); } BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) }; //! Implementation for user-defined types, such as structs and enums template< typename T > class base_atomic< T, void > { private: typedef T value_type; typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; protected: typedef value_type const& value_arg_type; public: typedef typename operations::storage_type storage_type; protected: typename operations::aligned_storage_type m_storage; public: BOOST_FORCEINLINE explicit base_atomic(value_type const& v = value_type()) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< storage_type >(v)) { } BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_consume); BOOST_ASSERT(order != memory_order_acquire); BOOST_ASSERT(order != memory_order_acq_rel); operations::store(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order); } BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_release); BOOST_ASSERT(order != memory_order_acq_rel); return atomics::detail::bitwise_cast< value_type >(operations::load(m_storage.value, order)); } BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return atomics::detail::bitwise_cast< value_type >(operations::exchange(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order)); } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); expected = atomics::detail::bitwise_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); expected = atomics::detail::bitwise_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT { return operations::is_lock_free(m_storage.value); } BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) }; //! Implementation for pointers template< typename T > class base_atomic< T*, void* > { private: typedef T* value_type; typedef std::ptrdiff_t difference_type; typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; protected: typedef value_type value_arg_type; public: typedef typename operations::storage_type storage_type; protected: typename operations::aligned_storage_type m_storage; public: BOOST_DEFAULTED_FUNCTION(base_atomic(), {}) BOOST_FORCEINLINE explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< storage_type >(v)) { } BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_consume); BOOST_ASSERT(order != memory_order_acquire); BOOST_ASSERT(order != memory_order_acq_rel); operations::store(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order); } BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_release); BOOST_ASSERT(order != memory_order_acq_rel); return atomics::detail::bitwise_cast< value_type >(operations::load(m_storage.value, order)); } BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return atomics::detail::bitwise_cast< value_type >(operations::fetch_add(m_storage.value, static_cast< storage_type >(v * sizeof(T)), order)); } BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return atomics::detail::bitwise_cast< value_type >(operations::fetch_sub(m_storage.value, static_cast< storage_type >(v * sizeof(T)), order)); } BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return atomics::detail::bitwise_cast< value_type >(operations::exchange(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order)); } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); expected = atomics::detail::bitwise_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); expected = atomics::detail::bitwise_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT { return operations::is_lock_free(m_storage.value); } BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT { return fetch_add(1); } BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT { return fetch_add(1) + 1; } BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT { return fetch_sub(1); } BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT { return fetch_sub(1) - 1; } BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT { return fetch_add(v) + v; } BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT { return fetch_sub(v) - v; } BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) }; //! Implementation for void pointers template< > class base_atomic< void*, void* > { private: typedef void* value_type; typedef std::ptrdiff_t difference_type; typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; protected: typedef value_type value_arg_type; public: typedef operations::storage_type storage_type; protected: operations::aligned_storage_type m_storage; public: BOOST_DEFAULTED_FUNCTION(base_atomic(), {}) BOOST_FORCEINLINE explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< storage_type >(v)) { } BOOST_FORCEINLINE void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_consume); BOOST_ASSERT(order != memory_order_acquire); BOOST_ASSERT(order != memory_order_acq_rel); operations::store(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order); } BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT { BOOST_ASSERT(order != memory_order_release); BOOST_ASSERT(order != memory_order_acq_rel); return atomics::detail::bitwise_cast< value_type >(operations::load(m_storage.value, order)); } BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return atomics::detail::bitwise_cast< value_type >(operations::fetch_add(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return atomics::detail::bitwise_cast< value_type >(operations::fetch_sub(m_storage.value, static_cast< storage_type >(v), order)); } BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return atomics::detail::bitwise_cast< value_type >(operations::exchange(m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order)); } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); expected = atomics::detail::bitwise_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { BOOST_ASSERT(failure_order != memory_order_release); BOOST_ASSERT(failure_order != memory_order_acq_rel); BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); expected = atomics::detail::bitwise_cast< value_type >(old_value); return res; } BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); } BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT { return operations::is_lock_free(m_storage.value); } BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT { return fetch_add(1); } BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT { return (char*)fetch_add(1) + 1; } BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT { return fetch_sub(1); } BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT { return (char*)fetch_sub(1) - 1; } BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT { return (char*)fetch_add(v) + v; } BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT { return (char*)fetch_sub(v) - v; } BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) }; } // namespace detail template< typename T > class atomic : public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type > { private: typedef T value_type; typedef atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type > base_type; typedef typename base_type::value_arg_type value_arg_type; public: typedef typename base_type::storage_type storage_type; public: BOOST_DEFAULTED_FUNCTION(atomic(), BOOST_NOEXCEPT {}) // NOTE: The constructor is made explicit because gcc 4.7 complains that // operator=(value_arg_type) is considered ambiguous with operator=(atomic const&) // in assignment expressions, even though conversion to atomic<> is less preferred // than conversion to value_arg_type. BOOST_FORCEINLINE explicit BOOST_CONSTEXPR atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v) {} BOOST_FORCEINLINE value_type operator= (value_arg_type v) volatile BOOST_NOEXCEPT { this->store(v); return v; } BOOST_FORCEINLINE operator value_type() volatile const BOOST_NOEXCEPT { return this->load(); } BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return this->m_storage.value; } BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return this->m_storage.value; } BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return this->m_storage.value; } BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return this->m_storage.value; } BOOST_DELETED_FUNCTION(atomic(atomic const&)) BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&)) BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&) volatile) }; typedef atomic< char > atomic_char; typedef atomic< unsigned char > atomic_uchar; typedef atomic< signed char > atomic_schar; typedef atomic< uint8_t > atomic_uint8_t; typedef atomic< int8_t > atomic_int8_t; typedef atomic< unsigned short > atomic_ushort; typedef atomic< short > atomic_short; typedef atomic< uint16_t > atomic_uint16_t; typedef atomic< int16_t > atomic_int16_t; typedef atomic< unsigned int > atomic_uint; typedef atomic< int > atomic_int; typedef atomic< uint32_t > atomic_uint32_t; typedef atomic< int32_t > atomic_int32_t; typedef atomic< unsigned long > atomic_ulong; typedef atomic< long > atomic_long; typedef atomic< uint64_t > atomic_uint64_t; typedef atomic< int64_t > atomic_int64_t; #ifdef BOOST_HAS_LONG_LONG typedef atomic< boost::ulong_long_type > atomic_ullong; typedef atomic< boost::long_long_type > atomic_llong; #endif typedef atomic< void* > atomic_address; typedef atomic< bool > atomic_bool; typedef atomic< wchar_t > atomic_wchar_t; #if !defined(BOOST_NO_CXX11_CHAR16_T) typedef atomic< char16_t > atomic_char16_t; #endif #if !defined(BOOST_NO_CXX11_CHAR32_T) typedef atomic< char32_t > atomic_char32_t; #endif typedef atomic< int_least8_t > atomic_int_least8_t; typedef atomic< uint_least8_t > atomic_uint_least8_t; typedef atomic< int_least16_t > atomic_int_least16_t; typedef atomic< uint_least16_t > atomic_uint_least16_t; typedef atomic< int_least32_t > atomic_int_least32_t; typedef atomic< uint_least32_t > atomic_uint_least32_t; typedef atomic< int_least64_t > atomic_int_least64_t; typedef atomic< uint_least64_t > atomic_uint_least64_t; typedef atomic< int_fast8_t > atomic_int_fast8_t; typedef atomic< uint_fast8_t > atomic_uint_fast8_t; typedef atomic< int_fast16_t > atomic_int_fast16_t; typedef atomic< uint_fast16_t > atomic_uint_fast16_t; typedef atomic< int_fast32_t > atomic_int_fast32_t; typedef atomic< uint_fast32_t > atomic_uint_fast32_t; typedef atomic< int_fast64_t > atomic_int_fast64_t; typedef atomic< uint_fast64_t > atomic_uint_fast64_t; typedef atomic< intmax_t > atomic_intmax_t; typedef atomic< uintmax_t > atomic_uintmax_t; typedef atomic< std::size_t > atomic_size_t; typedef atomic< std::ptrdiff_t > atomic_ptrdiff_t; #if defined(BOOST_HAS_INTPTR_T) typedef atomic< intptr_t > atomic_intptr_t; typedef atomic< uintptr_t > atomic_uintptr_t; #endif } // namespace atomics } // namespace boost #if defined(BOOST_MSVC) #pragma warning(pop) #endif #endif // BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/bitwise_cast.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2013 - 2014 Andrey Semashev */ /*! * \file atomic/detail/bitwise_cast.hpp * * This header defines \c bitwise_cast used to convert between storage and value types */ #ifndef BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_ #include #if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) #include #endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { template< typename To, typename From > BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT { struct { To to; } value = {}; BOOST_ATOMIC_DETAIL_MEMCPY ( &reinterpret_cast< char& >(value.to), &reinterpret_cast< const char& >(from), (sizeof(From) < sizeof(To) ? sizeof(From) : sizeof(To)) ); return value.to; } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_gcc_alpha.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_gcc_alpha.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_gcc_arm.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2009 Phil Endecott * Copyright (c) 2013 Tim Blechmann * ARM Code by Phil Endecott, based on other architectures. * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_gcc_arm.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)) // ARMv7 and later have dmb instruction #define BOOST_ATOMIC_DETAIL_ARM_HAS_DMB 1 #endif #if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__)) // ARMv6k and ARMv7 have 8 and 16 ldrex/strex variants #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1 #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1 #if !(((defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)) && defined(__thumb__)) || defined(__ARM_ARCH_7M__)) // ARMv6k and ARMv7 except ARMv7-M have 64-bit ldrex/strex variants. // Unfortunately, GCC (at least 4.7.3 on Ubuntu) does not allocate register pairs properly when targeting ARMv6k Thumb, // which is required for ldrexd/strexd instructions, so we disable 64-bit support. When targeting ARMv6k ARM // or ARMv7 (both ARM and Thumb 2) it works as expected. #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1 #endif #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #endif #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_gcc_atomic.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_gcc_atomic.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_ #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(__i386__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1 #endif #if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 #endif #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) #define BOOST_ATOMIC_INT128_LOCK_FREE 2 #else #define BOOST_ATOMIC_INT128_LOCK_FREE 0 #endif #if __GCC_ATOMIC_LLONG_LOCK_FREE == 2 #define BOOST_ATOMIC_LLONG_LOCK_FREE 2 #else #define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE #endif #if __GCC_ATOMIC_LONG_LOCK_FREE == 2 #define BOOST_ATOMIC_LONG_LOCK_FREE 2 #else #define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE #endif #if __GCC_ATOMIC_INT_LOCK_FREE == 2 #define BOOST_ATOMIC_INT_LOCK_FREE 2 #else #define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE #endif #if __GCC_ATOMIC_SHORT_LOCK_FREE == 2 #define BOOST_ATOMIC_SHORT_LOCK_FREE 2 #else #define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE #endif #if __GCC_ATOMIC_CHAR_LOCK_FREE == 2 #define BOOST_ATOMIC_CHAR_LOCK_FREE 2 #else #define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE #endif #if __GCC_ATOMIC_POINTER_LOCK_FREE == 2 #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #else #define BOOST_ATOMIC_POINTER_LOCK_FREE 0 #endif #define BOOST_ATOMIC_INT8_LOCK_FREE BOOST_ATOMIC_CHAR_LOCK_FREE #if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2 #define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2 #define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2 #define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2 #define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE #else #define BOOST_ATOMIC_INT16_LOCK_FREE 0 #endif #if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4 #define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4 #define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4 #define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4 #define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE #else #define BOOST_ATOMIC_INT32_LOCK_FREE 0 #endif #if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8 #define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8 #define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8 #define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8 #define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE #else #define BOOST_ATOMIC_INT64_LOCK_FREE 0 #endif #if __GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2 #elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1 #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE #else #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0 #endif #define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE #define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_gcc_ppc.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_gcc_ppc.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #if defined(__powerpc64__) || defined(__PPC64__) #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #endif #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_gcc_sparc.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2010 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_gcc_sparc.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_gcc_sync.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2011 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_gcc_sync.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(__i386__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1 #endif #if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 #endif #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #endif #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #endif #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #endif #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #endif #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_INT128_LOCK_FREE 2 #endif #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_gcc_x86.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2013 - 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_gcc_x86.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(__i386__) &&\ (\ defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\ defined(__i586__) || defined(__i686__) || defined(__pentium4__) || defined(__nocona__) || defined(__core2__) || defined(__corei7__) ||\ defined(__k6__) || defined(__athlon__) || defined(__k8__) || defined(__amdfam10__) || defined(__bdver1__) || defined(__bdver2__) || defined(__bdver3__) || defined(__btver1__) || defined(__btver2__)\ ) #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1 #endif #if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #if defined(__x86_64__) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #endif #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) #define BOOST_ATOMIC_INT128_LOCK_FREE 2 #endif #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_linux_arm.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009, 2011 Helge Bahmann * Copyright (c) 2009 Phil Endecott * Copyright (c) 2013 Tim Blechmann * Linux-specific code by Phil Endecott * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_linux_arm.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_msvc_arm.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2012 - 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_msvc_arm.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_msvc_x86.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2012 - 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_msvc_x86.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(_M_IX86) && _M_IX86 >= 500 #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1 #endif #if _MSC_VER >= 1500 && defined(_M_AMD64) && !defined(BOOST_ATOMIC_NO_CMPXCHG16B) #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #if defined(_M_AMD64) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) #define BOOST_ATOMIC_INT64_LOCK_FREE 2 #endif #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) #define BOOST_ATOMIC_INT128_LOCK_FREE 2 #endif #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/caps_windows.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2012 - 2014 Andrey Semashev */ /*! * \file atomic/detail/caps_windows.hpp * * This header defines feature capabilities macros */ #ifndef BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #define BOOST_ATOMIC_THREAD_FENCE 2 #define BOOST_ATOMIC_SIGNAL_FENCE 2 #endif // BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/config.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2012 Hartmut Kaiser * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/config.hpp * * This header defines configuraion macros for Boost.Atomic */ #ifndef BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(__has_builtin) #if __has_builtin(__builtin_memcpy) #define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY #endif #if __has_builtin(__builtin_memcmp) #define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP #endif #elif defined(BOOST_GCC) #define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY #define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP #endif #if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) #define BOOST_ATOMIC_DETAIL_MEMCPY __builtin_memcpy #else #define BOOST_ATOMIC_DETAIL_MEMCPY std::memcpy #endif #if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) #define BOOST_ATOMIC_DETAIL_MEMCMP __builtin_memcmp #else #define BOOST_ATOMIC_DETAIL_MEMCMP std::memcmp #endif #if defined(__CUDACC__) // nvcc does not support alternatives in asm statement constraints #define BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES // nvcc does not support condition code register ("cc") clobber in asm statements #define BOOST_ATOMIC_DETAIL_NO_ASM_CLOBBER_CC #endif #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CLOBBER_CC) #define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC "cc" #define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "cc", #else #define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC #define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA #endif #if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 403) // This macro indicates we're using older binutils that don't support implied zero displacements for memory opereands, // making code like this invalid: // movl 4+(%%edx), %%eax #define BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS #endif #if defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40500) // This macro indicates that the compiler does not support allocating rax:rdx register pairs ("A") in asm blocks #define BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS #endif #endif // BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/int_sizes.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/int_sizes.hpp * * This header defines macros for testing buitin integer type sizes */ #ifndef BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif // GCC and compatible compilers define internal macros with builtin type traits #if defined(__SIZEOF_SHORT__) #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT __SIZEOF_SHORT__ #endif #if defined(__SIZEOF_INT__) #define BOOST_ATOMIC_DETAIL_SIZEOF_INT __SIZEOF_INT__ #endif #if defined(__SIZEOF_LONG__) #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG __SIZEOF_LONG__ #endif #if defined(__SIZEOF_LONG_LONG__) #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG __SIZEOF_LONG_LONG__ #endif #if defined(__SIZEOF_WCHAR_T__) #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__ #endif #if defined(__SIZEOF_POINTER__) #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER __SIZEOF_POINTER__ #elif defined(_MSC_VER) #if defined(_M_AMD64) || defined(_M_IA64) #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 8 #else #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 4 #endif #endif #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\ !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG) // Try to deduce sizes from limits #include #include #if (USHRT_MAX + 0) == 0xff #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 1 #elif (USHRT_MAX + 0) == 0xffff #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 2 #elif (USHRT_MAX + 0) == 0xffffffff #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 4 #elif (USHRT_MAX + 0) == UINT64_C(0xffffffffffffffff) #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 8 #endif #if (UINT_MAX + 0) == 0xff #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 1 #elif (UINT_MAX + 0) == 0xffff #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 2 #elif (UINT_MAX + 0) == 0xffffffff #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 4 #elif (UINT_MAX + 0) == UINT64_C(0xffffffffffffffff) #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 8 #endif #if (ULONG_MAX + 0) == 0xff #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 1 #elif (ULONG_MAX + 0) == 0xffff #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 2 #elif (ULONG_MAX + 0) == 0xffffffff #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 4 #elif (ULONG_MAX + 0) == UINT64_C(0xffffffffffffffff) #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 8 #endif #if defined(__hpux) // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8 #else // The list of the non-standard macros (the ones except ULLONG_MAX) is taken from cstdint.hpp #if defined(ULLONG_MAX) #define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULLONG_MAX #elif defined(ULONG_LONG_MAX) #define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONG_LONG_MAX #elif defined(ULONGLONG_MAX) #define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONGLONG_MAX #elif defined(_LLONG_MAX) // strangely enough, this one seems to be holding the limit for the unsigned integer #define BOOST_ATOMIC_DETAIL_ULLONG_MAX _LLONG_MAX #endif #if (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xff #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 1 #elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffff #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 2 #elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffffffff #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 4 #elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == UINT64_C(0xffffffffffffffff) #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8 #endif #endif // defined(__hpux) #endif #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T) #include #include #if defined(_MSC_VER) && ( _MSC_VER <= 1310 || defined(UNDER_CE) && _MSC_VER <= 1500 ) // MSVC 7.1 and MSVC 8 (arm) define WCHAR_MAX to a value not suitable for constant expressions #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2 #elif (WCHAR_MAX + 0) == 0xff || (WCHAR_MAX + 0) == 0x7f #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 1 #elif (WCHAR_MAX + 0) == 0xffff || (WCHAR_MAX + 0) == 0x7fff #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2 #elif (WCHAR_MAX + 0) == 0xffffffff || (WCHAR_MAX + 0) == 0x7fffffff #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 4 #elif (WCHAR_MAX + 0) == UINT64_C(0xffffffffffffffff) || (WCHAR_MAX + 0) == INT64_C(0x7fffffffffffffff) #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 8 #endif #endif #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\ !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG) ||\ !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T) #error Boost.Atomic: Failed to determine builtin integer sizes, the target platform is not supported. Please, report to the developers. #endif #endif // BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/interlocked.hpp ================================================ #ifndef BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP #define BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP // Copyright (c) 2009 Helge Bahmann // Copyright (c) 2012 - 2014 Andrey Semashev // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(_WIN32_WCE) #if _WIN32_WCE >= 0x600 extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), exchange, compare) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval)) #else // _WIN32_WCE >= 0x600 extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); extern "C" long __cdecl InterlockedExchange( long*, long ); #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) InterlockedCompareExchange((long*)(dest), exchange, compare) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) InterlockedExchangeAdd((long*)(dest), (long)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) InterlockedExchange((long*)(dest), (long)(newval)) #endif // _WIN32_WCE >= 0x600 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), (long)(exchange), (long)(compare))) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE((long*)(dest), (long)(exchange))) #elif defined(_MSC_VER) && _MSC_VER >= 1310 #if _MSC_VER < 1400 extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedExchange) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), exchange, compare) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), (long)(exchange), (long)(compare))) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE((long*)(dest), (long)(exchange))) #else // _MSC_VER < 1400 #include #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedAnd) #pragma intrinsic(_InterlockedOr) #pragma intrinsic(_InterlockedXor) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval)) #define BOOST_ATOMIC_INTERLOCKED_AND(dest, arg) _InterlockedAnd((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR(dest, arg) _InterlockedXor((long*)(dest), (long)(arg)) #if (defined(_M_IX86) && _M_IX86 >= 500) || defined(_M_AMD64) || defined(_M_IA64) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchange64) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #endif #if _MSC_VER >= 1500 && defined(_M_AMD64) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchange128) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(dest, exchange, compare) _InterlockedCompareExchange128((__int64*)(dest), ((const __int64*)(&exchange))[1], ((const __int64*)(&exchange))[0], (__int64*)(compare)) #endif #if _MSC_VER >= 1600 // MSVC 2010 and later provide intrinsics for 8 and 16 bit integers. // Note that for each bit count these macros must be either all defined or all not defined. // Otherwise atomic<> operations will be implemented inconsistently. #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchange8) #pragma intrinsic(_InterlockedExchangeAdd8) #pragma intrinsic(_InterlockedExchange8) #pragma intrinsic(_InterlockedAnd8) #pragma intrinsic(_InterlockedOr8) #pragma intrinsic(_InterlockedXor8) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(dest, exchange, compare) _InterlockedCompareExchange8((char*)(dest), (char)(exchange), (char)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(dest, addend) _InterlockedExchangeAdd8((char*)(dest), (char)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(dest, newval) _InterlockedExchange8((char*)(dest), (char)(newval)) #define BOOST_ATOMIC_INTERLOCKED_AND8(dest, arg) _InterlockedAnd8((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR8(dest, arg) _InterlockedOr8((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR8(dest, arg) _InterlockedXor8((char*)(dest), (char)(arg)) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchange16) #pragma intrinsic(_InterlockedExchangeAdd16) #pragma intrinsic(_InterlockedExchange16) #pragma intrinsic(_InterlockedAnd16) #pragma intrinsic(_InterlockedOr16) #pragma intrinsic(_InterlockedXor16) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(dest, exchange, compare) _InterlockedCompareExchange16((short*)(dest), (short)(exchange), (short)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(dest, addend) _InterlockedExchangeAdd16((short*)(dest), (short)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(dest, newval) _InterlockedExchange16((short*)(dest), (short)(newval)) #define BOOST_ATOMIC_INTERLOCKED_AND16(dest, arg) _InterlockedAnd16((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR16(dest, arg) _InterlockedOr16((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR16(dest, arg) _InterlockedXor16((short*)(dest), (short)(arg)) #endif // _MSC_VER >= 1600 #if defined(_M_AMD64) || defined(_M_IA64) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchange64) #pragma intrinsic(_InterlockedAnd64) #pragma intrinsic(_InterlockedOr64) #pragma intrinsic(_InterlockedXor64) #endif #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR64(dest, arg) _InterlockedOr64((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR64(dest, arg) _InterlockedXor64((__int64*)(dest), (__int64)(arg)) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchangePointer) #pragma intrinsic(_InterlockedExchangePointer) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) _InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) _InterlockedExchangePointer((void**)(dest), (void*)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64((long*)(dest), byte_offset)) #elif defined(_M_IX86) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)_InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)_InterlockedExchange((long*)(dest), (long)(newval))) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset)) #endif #if _MSC_VER >= 1700 && defined(_M_ARM) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchange64) #pragma intrinsic(_InterlockedAnd64) #pragma intrinsic(_InterlockedOr64) #pragma intrinsic(_InterlockedXor64) #endif #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR64(dest, arg) _InterlockedOr64((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR64(dest, arg) _InterlockedXor64((__int64*)(dest), (__int64)(arg)) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedCompareExchange8_nf) #pragma intrinsic(_InterlockedCompareExchange8_acq) #pragma intrinsic(_InterlockedCompareExchange8_rel) #pragma intrinsic(_InterlockedCompareExchange16_nf) #pragma intrinsic(_InterlockedCompareExchange16_acq) #pragma intrinsic(_InterlockedCompareExchange16_rel) #pragma intrinsic(_InterlockedCompareExchange_nf) #pragma intrinsic(_InterlockedCompareExchange_acq) #pragma intrinsic(_InterlockedCompareExchange_rel) #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedCompareExchange64_nf) #pragma intrinsic(_InterlockedCompareExchange64_acq) #pragma intrinsic(_InterlockedCompareExchange64_rel) #pragma intrinsic(_InterlockedCompareExchangePointer) #pragma intrinsic(_InterlockedCompareExchangePointer_nf) #pragma intrinsic(_InterlockedCompareExchangePointer_acq) #pragma intrinsic(_InterlockedCompareExchangePointer_rel) #endif #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELAXED(dest, exchange, compare) _InterlockedCompareExchange8_nf((char*)(dest), (char)(exchange), (char)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange8_acq((char*)(dest), (char)(exchange), (char)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELEASE(dest, exchange, compare) _InterlockedCompareExchange8_rel((char*)(dest), (char)(exchange), (char)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELAXED(dest, exchange, compare) _InterlockedCompareExchange16_nf((short*)(dest), (short)(exchange), (short)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange16_acq((short*)(dest), (short)(exchange), (short)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELEASE(dest, exchange, compare) _InterlockedCompareExchange16_rel((short*)(dest), (short)(exchange), (short)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELAXED(dest, exchange, compare) _InterlockedCompareExchange_nf((long*)(dest), (long)(exchange), (long)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange_acq((long*)(dest), (long)(exchange), (long)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELEASE(dest, exchange, compare) _InterlockedCompareExchange_rel((long*)(dest), (long)(exchange), (long)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELAXED(dest, exchange, compare) _InterlockedCompareExchange64_nf((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange64_acq((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELEASE(dest, exchange, compare) _InterlockedCompareExchange64_rel((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) _InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_RELAXED(dest, exchange, compare) _InterlockedCompareExchangePointer_nf((void**)(dest), (void*)(exchange), (void*)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchangePointer_acq((void**)(dest), (void*)(exchange), (void*)(compare)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_RELEASE(dest, exchange, compare) _InterlockedCompareExchangePointer_rel((void**)(dest), (void*)(exchange), (void*)(compare)) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedExchangeAdd8_nf) #pragma intrinsic(_InterlockedExchangeAdd8_acq) #pragma intrinsic(_InterlockedExchangeAdd8_rel) #pragma intrinsic(_InterlockedExchangeAdd16_nf) #pragma intrinsic(_InterlockedExchangeAdd16_acq) #pragma intrinsic(_InterlockedExchangeAdd16_rel) #pragma intrinsic(_InterlockedExchangeAdd_nf) #pragma intrinsic(_InterlockedExchangeAdd_acq) #pragma intrinsic(_InterlockedExchangeAdd_rel) #pragma intrinsic(_InterlockedExchangeAdd64_nf) #pragma intrinsic(_InterlockedExchangeAdd64_acq) #pragma intrinsic(_InterlockedExchangeAdd64_rel) #endif #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELAXED(dest, addend) _InterlockedExchangeAdd8_nf((char*)(dest), (char)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_ACQUIRE(dest, addend) _InterlockedExchangeAdd8_acq((char*)(dest), (char)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELEASE(dest, addend) _InterlockedExchangeAdd8_rel((char*)(dest), (char)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELAXED(dest, addend) _InterlockedExchangeAdd16_nf((short*)(dest), (short)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_ACQUIRE(dest, addend) _InterlockedExchangeAdd16_acq((short*)(dest), (short)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELEASE(dest, addend) _InterlockedExchangeAdd16_rel((short*)(dest), (short)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED(dest, addend) _InterlockedExchangeAdd_nf((long*)(dest), (long)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE(dest, addend) _InterlockedExchangeAdd_acq((long*)(dest), (long)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE(dest, addend) _InterlockedExchangeAdd_rel((long*)(dest), (long)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED(dest, addend) _InterlockedExchangeAdd64_nf((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE(dest, addend) _InterlockedExchangeAdd64_acq((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE(dest, addend) _InterlockedExchangeAdd64_rel((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELAXED(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED((long*)(dest), byte_offset)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_ACQUIRE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE((long*)(dest), byte_offset)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELEASE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE((long*)(dest), byte_offset)) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedExchange8_nf) #pragma intrinsic(_InterlockedExchange8_acq) #pragma intrinsic(_InterlockedExchange16_nf) #pragma intrinsic(_InterlockedExchange16_acq) #pragma intrinsic(_InterlockedExchange_nf) #pragma intrinsic(_InterlockedExchange_acq) #pragma intrinsic(_InterlockedExchange64_nf) #pragma intrinsic(_InterlockedExchange64_acq) #pragma intrinsic(_InterlockedExchangePointer) #pragma intrinsic(_InterlockedExchangePointer_nf) #pragma intrinsic(_InterlockedExchangePointer_acq) #if _MSC_VER >= 1800 #pragma intrinsic(_InterlockedExchange8_rel) #pragma intrinsic(_InterlockedExchange16_rel) #pragma intrinsic(_InterlockedExchange_rel) #pragma intrinsic(_InterlockedExchange64_rel) #pragma intrinsic(_InterlockedExchangePointer_rel) #endif #endif #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELAXED(dest, newval) _InterlockedExchange8_nf((char*)(dest), (char)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_ACQUIRE(dest, newval) _InterlockedExchange8_acq((char*)(dest), (char)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELAXED(dest, newval) _InterlockedExchange16_nf((short*)(dest), (short)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_ACQUIRE(dest, newval) _InterlockedExchange16_acq((short*)(dest), (short)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELAXED(dest, newval) _InterlockedExchange_nf((long*)(dest), (long)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ACQUIRE(dest, newval) _InterlockedExchange_acq((long*)(dest), (long)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELAXED(dest, newval) _InterlockedExchange64_nf((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_ACQUIRE(dest, newval) _InterlockedExchange64_acq((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) _InterlockedExchangePointer((void**)(dest), (void*)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELAXED(dest, newval) _InterlockedExchangePointer_nf((void**)(dest), (void*)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_ACQUIRE(dest, newval) _InterlockedExchangePointer_acq((void**)(dest), (void*)(newval)) #if _MSC_VER >= 1800 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(dest, newval) _InterlockedExchange8_rel((char*)(dest), (char)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(dest, newval) _InterlockedExchange16_rel((short*)(dest), (short)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(dest, newval) _InterlockedExchange_rel((long*)(dest), (long)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(dest, newval) _InterlockedExchange64_rel((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELEASE(dest, newval) _InterlockedExchangePointer_rel((void**)(dest), (void*)(newval)) #else #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(dest, newval) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(dest, newval) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) #endif #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedAnd8_nf) #pragma intrinsic(_InterlockedAnd8_acq) #pragma intrinsic(_InterlockedAnd8_rel) #pragma intrinsic(_InterlockedAnd16_nf) #pragma intrinsic(_InterlockedAnd16_acq) #pragma intrinsic(_InterlockedAnd16_rel) #pragma intrinsic(_InterlockedAnd_nf) #pragma intrinsic(_InterlockedAnd_acq) #pragma intrinsic(_InterlockedAnd_rel) #pragma intrinsic(_InterlockedAnd64_nf) #pragma intrinsic(_InterlockedAnd64_acq) #pragma intrinsic(_InterlockedAnd64_rel) #endif #define BOOST_ATOMIC_INTERLOCKED_AND8_RELAXED(dest, arg) _InterlockedAnd8_nf((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND8_ACQUIRE(dest, arg) _InterlockedAnd8_acq((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND8_RELEASE(dest, arg) _InterlockedAnd8_rel((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND16_RELAXED(dest, arg) _InterlockedAnd16_nf((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND16_ACQUIRE(dest, arg) _InterlockedAnd16_acq((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND16_RELEASE(dest, arg) _InterlockedAnd16_rel((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND_RELAXED(dest, arg) _InterlockedAnd_nf((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND_ACQUIRE(dest, arg) _InterlockedAnd_acq((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND_RELEASE(dest, arg) _InterlockedAnd_rel((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND64_RELAXED(dest, arg) _InterlockedAnd64_nf((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND64_ACQUIRE(dest, arg) _InterlockedAnd64_acq((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND64_RELEASE(dest, arg) _InterlockedAnd64_rel((__int64*)(dest), (__int64)(arg)) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedOr8_nf) #pragma intrinsic(_InterlockedOr8_acq) #pragma intrinsic(_InterlockedOr8_rel) #pragma intrinsic(_InterlockedOr16_nf) #pragma intrinsic(_InterlockedOr16_acq) #pragma intrinsic(_InterlockedOr16_rel) #pragma intrinsic(_InterlockedOr_nf) #pragma intrinsic(_InterlockedOr_acq) #pragma intrinsic(_InterlockedOr_rel) #pragma intrinsic(_InterlockedOr64_nf) #pragma intrinsic(_InterlockedOr64_acq) #pragma intrinsic(_InterlockedOr64_rel) #endif #define BOOST_ATOMIC_INTERLOCKED_OR8_RELAXED(dest, arg) _InterlockedOr8_nf((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR8_ACQUIRE(dest, arg) _InterlockedOr8_acq((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR8_RELEASE(dest, arg) _InterlockedOr8_rel((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR16_RELAXED(dest, arg) _InterlockedOr16_nf((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR16_ACQUIRE(dest, arg) _InterlockedOr16_acq((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR16_RELEASE(dest, arg) _InterlockedOr16_rel((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR_RELAXED(dest, arg) _InterlockedOr_nf((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR_ACQUIRE(dest, arg) _InterlockedOr_acq((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR_RELEASE(dest, arg) _InterlockedOr_rel((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR64_RELAXED(dest, arg) _InterlockedOr64_nf((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR64_ACQUIRE(dest, arg) _InterlockedOr64_acq((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR64_RELEASE(dest, arg) _InterlockedOr64_rel((__int64*)(dest), (__int64)(arg)) #if defined(BOOST_MSVC) #pragma intrinsic(_InterlockedXor8_nf) #pragma intrinsic(_InterlockedXor8_acq) #pragma intrinsic(_InterlockedXor8_rel) #pragma intrinsic(_InterlockedXor16_nf) #pragma intrinsic(_InterlockedXor16_acq) #pragma intrinsic(_InterlockedXor16_rel) #pragma intrinsic(_InterlockedXor_nf) #pragma intrinsic(_InterlockedXor_acq) #pragma intrinsic(_InterlockedXor_rel) #pragma intrinsic(_InterlockedXor64_nf) #pragma intrinsic(_InterlockedXor64_acq) #pragma intrinsic(_InterlockedXor64_rel) #endif #define BOOST_ATOMIC_INTERLOCKED_XOR8_RELAXED(dest, arg) _InterlockedXor8_nf((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR8_ACQUIRE(dest, arg) _InterlockedXor8_acq((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR8_RELEASE(dest, arg) _InterlockedXor8_rel((char*)(dest), (char)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR16_RELAXED(dest, arg) _InterlockedXor16_nf((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR16_ACQUIRE(dest, arg) _InterlockedXor16_acq((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR16_RELEASE(dest, arg) _InterlockedXor16_rel((short*)(dest), (short)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR_RELAXED(dest, arg) _InterlockedXor_nf((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR_ACQUIRE(dest, arg) _InterlockedXor_acq((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR_RELEASE(dest, arg) _InterlockedXor_rel((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR64_RELAXED(dest, arg) _InterlockedXor64_nf((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR64_ACQUIRE(dest, arg) _InterlockedXor64_acq((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR64_RELEASE(dest, arg) _InterlockedXor64_rel((__int64*)(dest), (__int64)(arg)) #endif // _MSC_VER >= 1700 && defined(_M_ARM) #endif // _MSC_VER < 1400 #else // defined(_MSC_VER) && _MSC_VER >= 1310 #if defined(BOOST_USE_WINDOWS_H) #include #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) InterlockedExchange((long*)(dest), (long)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) InterlockedExchangeAdd((long*)(dest), (long)(addend)) #if defined(_WIN64) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) InterlockedExchange64((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) InterlockedExchangePointer((void**)(dest), (void*)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset)) #else // defined(_WIN64) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset)) #endif // defined(_WIN64) #else // defined(BOOST_USE_WINDOWS_H) #if defined(__MINGW64__) #define BOOST_ATOMIC_INTERLOCKED_IMPORT #else #define BOOST_ATOMIC_INTERLOCKED_IMPORT __declspec(dllimport) #endif namespace boost { namespace atomics { namespace detail { extern "C" { BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange(long volatile*, long, long); BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchange(long volatile*, long); BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd(long volatile*, long); #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) boost::atomics::detail::InterlockedExchange((long*)(dest), (long)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) boost::atomics::detail::InterlockedExchangeAdd((long*)(dest), (long)(addend)) #if defined(_WIN64) BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedCompareExchange64(__int64 volatile*, __int64, __int64); BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchange64(__int64 volatile*, __int64); BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchangeAdd64(__int64 volatile*, __int64); BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer(void* volatile *, void*, void*); BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer(void* volatile *, void*); #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) boost::atomics::detail::InterlockedExchange64((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) boost::atomics::detail::InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) boost::atomics::detail::InterlockedExchangePointer((void**)(dest), (void*)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset)) #else // defined(_WIN64) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset)) #endif // defined(_WIN64) } // extern "C" } // namespace detail } // namespace atomics } // namespace boost #undef BOOST_ATOMIC_INTERLOCKED_IMPORT #endif // defined(BOOST_USE_WINDOWS_H) #endif // defined(_MSC_VER) #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/link.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2012 Hartmut Kaiser * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/config.hpp * * This header defines macros for linking with compiled library of Boost.Atomic */ #ifndef BOOST_ATOMIC_DETAIL_LINK_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_LINK_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif /////////////////////////////////////////////////////////////////////////////// // Set up dll import/export options #if (defined(BOOST_ATOMIC_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \ !defined(BOOST_ATOMIC_STATIC_LINK) #if defined(BOOST_ATOMIC_SOURCE) #define BOOST_ATOMIC_DECL BOOST_SYMBOL_EXPORT #define BOOST_ATOMIC_BUILD_DLL #else #define BOOST_ATOMIC_DECL BOOST_SYMBOL_IMPORT #endif #endif // building a shared library #ifndef BOOST_ATOMIC_DECL #define BOOST_ATOMIC_DECL #endif /////////////////////////////////////////////////////////////////////////////// // Auto library naming #if !defined(BOOST_ATOMIC_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \ !defined(BOOST_ATOMIC_NO_LIB) #define BOOST_LIB_NAME boost_atomic // tell the auto-link code to select a dll when required: #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ATOMIC_DYN_LINK) #define BOOST_DYN_LINK #endif #include #endif // auto-linking disabled #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/lockpool.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2011 Helge Bahmann * Copyright (c) 2013-2014 Andrey Semashev */ /*! * \file atomic/detail/lockpool.hpp * * This header contains declaration of the lockpool used to emulate atomic ops. */ #ifndef BOOST_ATOMIC_DETAIL_LOCKPOOL_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_LOCKPOOL_HPP_INCLUDED_ #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { struct lockpool { class scoped_lock { void* m_lock; public: explicit BOOST_ATOMIC_DECL scoped_lock(const volatile void* addr) BOOST_NOEXCEPT; BOOST_ATOMIC_DECL ~scoped_lock() BOOST_NOEXCEPT; BOOST_DELETED_FUNCTION(scoped_lock(scoped_lock const&)) BOOST_DELETED_FUNCTION(scoped_lock& operator=(scoped_lock const&)) }; static BOOST_ATOMIC_DECL void thread_fence() BOOST_NOEXCEPT; static BOOST_ATOMIC_DECL void signal_fence() BOOST_NOEXCEPT; }; } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_LOCKPOOL_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/operations.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/operations.hpp * * This header defines atomic operations, including the emulated version. */ #ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_ #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #endif // BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/operations_fwd.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/operations_fwd.hpp * * This header contains forward declaration of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_ #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { template< std::size_t Size, bool Signed > struct operations; } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/operations_lockfree.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/operations_lockfree.hpp * * This header defines lockfree atomic operations. */ #ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_ #include #include #if !defined(BOOST_ATOMIC_EMULATED) #include BOOST_ATOMIC_DETAIL_HEADER(boost/atomic/detail/ops_) #else #include #endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #endif // BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_cas_based.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_cas_based.hpp * * This header contains CAS-based implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_ #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { template< typename Base > struct cas_based_exchange : public Base { typedef typename Base::storage_type storage_type; static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, v, order, memory_order_relaxed)) {} return old_val; } }; template< typename Base > struct cas_based_operations : public Base { typedef typename Base::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val + v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val - v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val & v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val | v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val ^ v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!Base::exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { Base::store(storage, (storage_type)0, order); } }; } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_emulated.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_emulated.hpp * * This header contains lockpool-based implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { template< typename T > struct emulated_operations { typedef T storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { lockpool::scoped_lock lock(&storage); const_cast< storage_type& >(storage) = v; } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT { lockpool::scoped_lock lock(&storage); return const_cast< storage_type const& >(storage); } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; s += v; return old_val; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; s -= v; return old_val; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; s = v; return old_val; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; const bool res = old_val == expected; if (res) s = desired; expected = old_val; return res; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { // Note: This function is the exact copy of compare_exchange_strong. The reason we're not just forwarding the call // is that MSVC-12 ICEs in this case. storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; const bool res = old_val == expected; if (res) s = desired; expected = old_val; return res; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; s &= v; return old_val; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; s |= v; return old_val; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type& s = const_cast< storage_type& >(storage); lockpool::scoped_lock lock(&storage); storage_type old_val = s; s ^= v; return old_val; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, (storage_type)0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return false; } }; template< std::size_t Size, bool Signed > struct operations : public emulated_operations< typename make_storage_type< Size, Signed >::type > { typedef typename make_storage_type< Size, Signed >::aligned aligned_storage_type; }; } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_extending_cas_based.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_extending_cas_based.hpp * * This header contains a boilerplate of the \c operations template implementation that requires sign/zero extension in arithmetic operations. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { template< typename Base, std::size_t Size, bool Signed > struct extending_cas_based_operations : public Base { typedef typename Base::storage_type storage_type; typedef typename make_storage_type< Size, Signed >::type emulated_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); emulated_storage_type new_val; do { new_val = static_cast< emulated_storage_type >(old_val) + static_cast< emulated_storage_type >(v); } while (!Base::compare_exchange_weak(storage, old_val, static_cast< storage_type >(new_val), order, memory_order_relaxed)); return old_val; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type old_val; atomics::detail::non_atomic_load(storage, old_val); emulated_storage_type new_val; do { new_val = static_cast< emulated_storage_type >(old_val) - static_cast< emulated_storage_type >(v); } while (!Base::compare_exchange_weak(storage, old_val, static_cast< storage_type >(new_val), order, memory_order_relaxed)); return old_val; } }; } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_alpha.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_alpha.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_ #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { /* Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html (HP OpenVMS systems documentation) and the Alpha Architecture Reference Manual. */ /* NB: The most natural thing would be to write the increment/decrement operators along the following lines: __asm__ __volatile__ ( "1: ldl_l %0,%1 \n" "addl %0,1,%0 \n" "stl_c %0,%1 \n" "beq %0,1b\n" : "=&b" (tmp) : "m" (value) : "cc" ); However according to the comments on the HP website and matching comments in the Linux kernel sources this defies branch prediction, as the cpu assumes that backward branches are always taken; so instead copy the trick from the Linux kernel, introduce a forward branch and back again. I have, however, had a hard time measuring the difference between the two versions in microbenchmarks -- I am leaving it in nevertheless as it apparently does not hurt either. */ struct gcc_alpha_operations_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) __asm__ __volatile__ ("mb" ::: "memory"); } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { if ((order & (memory_order_consume | memory_order_acquire)) != 0) __asm__ __volatile__ ("mb" ::: "memory"); } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) __asm__ __volatile__ ("mb" ::: "memory"); } }; template< bool Signed > struct operations< 4u, Signed > : public gcc_alpha_operations_base { typedef typename make_storage_type< 4u, Signed >::type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage = v; fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after(order); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n" "mov %3, %1\n" "ldl_l %0, %2\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (tmp) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); int success; storage_type current; __asm__ __volatile__ ( "1:\n" "ldl_l %2, %4\n" // current = *(&storage) "cmpeq %2, %0, %3\n" // success = current == expected "mov %2, %0\n" // expected = current "beq %3, 2f\n" // if (success == 0) goto end "stl_c %1, %4\n" // storage = desired; desired = store succeeded "mov %1, %3\n" // success = desired "2:\n" : "+&r" (expected), // %0 "+&r" (desired), // %1 "=&r" (current), // %2 "=&r" (success) // %3 : "m" (storage) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { int success; storage_type current, tmp; fence_before(success_order); __asm__ __volatile__ ( "1:\n" "mov %5, %1\n" // tmp = desired "ldl_l %2, %4\n" // current = *(&storage) "cmpeq %2, %0, %3\n" // success = current == expected "mov %2, %0\n" // expected = current "beq %3, 2f\n" // if (success == 0) goto end "stl_c %1, %4\n" // storage = tmp; tmp = store succeeded "beq %1, 3f\n" // if (tmp == 0) goto retry "mov %1, %3\n" // success = tmp "2:\n" ".subsection 2\n" "3: br 1b\n" ".previous\n" : "+&r" (expected), // %0 "=&r" (tmp), // %1 "=&r" (current), // %2 "=&r" (success) // %3 : "m" (storage), // %4 "r" (desired) // %5 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "addl %0, %3, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "subl %0, %3, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "and %0, %3, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "bis %0, %3, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "xor %0, %3, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, 0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< > struct operations< 1u, false > : public operations< 4u, false > { typedef operations< 4u, false > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "addl %0, %3, %1\n" "zapnot %1, #1, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "subl %0, %3, %1\n" "zapnot %1, #1, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 1u, true > : public operations< 4u, true > { typedef operations< 4u, true > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "addl %0, %3, %1\n" "sextb %1, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "subl %0, %3, %1\n" "sextb %1, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 2u, false > : public operations< 4u, false > { typedef operations< 4u, false > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "addl %0, %3, %1\n" "zapnot %1, #3, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "subl %0, %3, %1\n" "zapnot %1, #3, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 2u, true > : public operations< 4u, true > { typedef operations< 4u, true > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "addl %0, %3, %1\n" "sextw %1, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldl_l %0, %2\n" "subl %0, %3, %1\n" "sextw %1, %1\n" "stl_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< bool Signed > struct operations< 8u, Signed > : public gcc_alpha_operations_base { typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage = v; fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after(order); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n" "mov %3, %1\n" "ldq_l %0, %2\n" "stq_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (tmp) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); int success; storage_type current; __asm__ __volatile__ ( "1:\n" "ldq_l %2, %4\n" // current = *(&storage) "cmpeq %2, %0, %3\n" // success = current == expected "mov %2, %0\n" // expected = current "beq %3, 2f\n" // if (success == 0) goto end "stq_c %1, %4\n" // storage = desired; desired = store succeeded "mov %1, %3\n" // success = desired "2:\n" : "+&r" (expected), // %0 "+&r" (desired), // %1 "=&r" (current), // %2 "=&r" (success) // %3 : "m" (storage) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { int success; storage_type current, tmp; fence_before(success_order); __asm__ __volatile__ ( "1:\n" "mov %5, %1\n" // tmp = desired "ldq_l %2, %4\n" // current = *(&storage) "cmpeq %2, %0, %3\n" // success = current == expected "mov %2, %0\n" // expected = current "beq %3, 2f\n" // if (success == 0) goto end "stq_c %1, %4\n" // storage = tmp; tmp = store succeeded "beq %1, 3f\n" // if (tmp == 0) goto retry "mov %1, %3\n" // success = tmp "2:\n" ".subsection 2\n" "3: br 1b\n" ".previous\n" : "+&r" (expected), // %0 "=&r" (tmp), // %1 "=&r" (current), // %2 "=&r" (success) // %3 : "m" (storage), // %4 "r" (desired) // %5 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldq_l %0, %2\n" "addq %0, %3, %1\n" "stq_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldq_l %0, %2\n" "subq %0, %3, %1\n" "stq_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldq_l %0, %2\n" "and %0, %3, %1\n" "stq_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldq_l %0, %2\n" "bis %0, %3, %1\n" "stq_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, modified; fence_before(order); __asm__ __volatile__ ( "1:\n" "ldq_l %0, %2\n" "xor %0, %3, %1\n" "stq_c %1, %2\n" "beq %1, 2f\n" ".subsection 2\n" "2: br 1b\n" ".previous\n" : "=&r" (original), // %0 "=&r" (modified) // %1 : "m" (storage), // %2 "r" (v) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, 0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __asm__ __volatile__ ("mb" ::: "memory"); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __asm__ __volatile__ ("" ::: "memory"); } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_arm.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_arm.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_ #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { // From the ARM Architecture Reference Manual for architecture v6: // // LDREX{} , [] // Specifies the destination register for the memory word addressed by // Specifies the register containing the address. // // STREX{} , , [] // Specifies the destination register for the returned status value. // 0 if the operation updates memory // 1 if the operation fails to update memory // Specifies the register containing the word to be stored to memory. // Specifies the register containing the address. // Rd must not be the same register as Rm or Rn. // // ARM v7 is like ARM v6 plus: // There are half-word and byte versions of the LDREX and STREX instructions, // LDREXH, LDREXB, STREXH and STREXB. // There are also double-word versions, LDREXD and STREXD. // (Actually it looks like these are available from version 6k onwards.) // FIXME these are not yet used; should be mostly a matter of copy-and-paste. // I think you can supply an immediate offset to the address. // // A memory barrier is effected using a "co-processor 15" instruction, // though a separate assembler mnemonic is available for it in v7. // // "Thumb 1" is a subset of the ARM instruction set that uses a 16-bit encoding. It // doesn't include all instructions and in particular it doesn't include the co-processor // instruction used for the memory barrier or the load-locked/store-conditional // instructions. So, if we're compiling in "Thumb 1" mode, we need to wrap all of our // asm blocks with code to temporarily change to ARM mode. // // You can only change between ARM and Thumb modes when branching using the bx instruction. // bx takes an address specified in a register. The least significant bit of the address // indicates the mode, so 1 is added to indicate that the destination code is Thumb. // A temporary register is needed for the address and is passed as an argument to these // macros. It must be one of the "low" registers accessible to Thumb code, specified // using the "l" attribute in the asm statement. // // Architecture v7 introduces "Thumb 2", which does include (almost?) all of the ARM // instruction set. (Actually, there was an extension of v6 called v6T2 which supported // "Thumb 2" mode, but its architecture manual is no longer available, referring to v7.) // So in v7 we don't need to change to ARM mode; we can write "universal // assembler" which will assemble to Thumb 2 or ARM code as appropriate. The only thing // we need to do to make this "universal" assembler mode work is to insert "IT" instructions // to annotate the conditional instructions. These are ignored in other modes (e.g. v6), // so they can always be present. // A note about memory_order_consume. Technically, this architecture allows to avoid // unnecessary memory barrier after consume load since it supports data dependency ordering. // However, some compiler optimizations may break a seemingly valid code relying on data // dependency tracking by injecting bogus branches to aid out of order execution. // This may happen not only in Boost.Atomic code but also in user's code, which we have no // control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php. // For this reason we promote memory_order_consume to memory_order_acquire. #if defined(__thumb__) && !defined(__thumb2__) #define BOOST_ATOMIC_DETAIL_ARM_ASM_START(TMPREG) "adr " #TMPREG ", 8f\n" "bx " #TMPREG "\n" ".arm\n" ".align 4\n" "8:\n" #define BOOST_ATOMIC_DETAIL_ARM_ASM_END(TMPREG) "adr " #TMPREG ", 9f + 1\n" "bx " #TMPREG "\n" ".thumb\n" ".align 2\n" "9:\n" #define BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(var) "=&l" (var) #else // The tmpreg may be wasted in this case, which is non-optimal. #define BOOST_ATOMIC_DETAIL_ARM_ASM_START(TMPREG) #define BOOST_ATOMIC_DETAIL_ARM_ASM_END(TMPREG) #define BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(var) "=&r" (var) #endif struct gcc_arm_operations_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) hardware_full_fence(); } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { if ((order & (memory_order_consume | memory_order_acquire)) != 0) hardware_full_fence(); } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) hardware_full_fence(); } static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { #if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_DMB) // Older binutils (supposedly, older than 2.21.1) didn't support symbolic or numeric arguments of the "dmb" instruction such as "ish" or "#11". // As a workaround we have to inject encoded bytes of the instruction. There are two encodings for the instruction: ARM and Thumb. See ARM Architecture Reference Manual, A8.8.43. // Since we cannot detect binutils version at compile time, we'll have to always use this hack. __asm__ __volatile__ ( #if defined(__thumb2__) ".short 0xF3BF, 0x8F5B\n" // dmb ish #else ".word 0xF57FF05B\n" // dmb ish #endif : : : "memory" ); #else int tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "mcr\tp15, 0, r0, c7, c10, 5\n" BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : "=&l" (tmp) : : "memory" ); #endif } }; template< bool Signed > struct operations< 4u, Signed > : public gcc_arm_operations_base { typedef typename make_storage_type< 4u, Signed >::type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage = v; fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after(order); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original; fence_before(order); uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // load the original value "strex %[tmp], %[value], %[storage]\n" // store the replacement, tmp = store failed "teq %[tmp], #0\n" // check if store succeeded "bne 1b\n" BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [tmp] "=&l" (tmp), [original] "=&r" (original), [storage] "+Q" (storage) : [value] "r" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); uint32_t success; uint32_t tmp; storage_type original; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "mov %[success], #0\n" // success = 0 "ldrex %[original], %[storage]\n" // original = *(&storage) "cmp %[original], %[expected]\n" // flags = original==expected "itt eq\n" // [hint that the following 2 instructions are conditional on flags.equal] "strexeq %[success], %[desired], %[storage]\n" // if (flags.equal) *(&storage) = desired, success = store failed "eoreq %[success], %[success], #1\n" // if (flags.equal) success ^= 1 (i.e. make it 1 if store succeeded) BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [success] "=&r" (success), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [expected] "r" (expected), // %4 [desired] "r" (desired) // %5 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); if (success) fence_after(success_order); else fence_after(failure_order); expected = original; return !!success; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); uint32_t success; uint32_t tmp; storage_type original; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "mov %[success], #0\n" // success = 0 "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "cmp %[original], %[expected]\n" // flags = original==expected "bne 2f\n" // if (!flags.equal) goto end "strex %[success], %[desired], %[storage]\n" // *(&storage) = desired, success = store failed "eors %[success], %[success], #1\n" // success ^= 1 (i.e. make it 1 if store succeeded); flags.equal = success == 0 "beq 1b\n" // if (flags.equal) goto retry "2:\n" BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [success] "=&r" (success), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [expected] "r" (expected), // %4 [desired] "r" (desired) // %5 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); if (success) fence_after(success_order); else fence_after(failure_order); expected = original; return !!success; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "add %[result], %[original], %[value]\n" // result = original + value "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "sub %[result], %[original], %[value]\n" // result = original - value "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "and %[result], %[original], %[value]\n" // result = original & value "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "orr %[result], %[original], %[value]\n" // result = original | value "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "eor %[result], %[original], %[value]\n" // result = original ^ value "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, 0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< > struct operations< 1u, false > : public operations< 4u, false > { typedef operations< 4u, false > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "add %[result], %[original], %[value]\n" // result = original + value "uxtb %[result], %[result]\n" // zero extend result from 8 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "sub %[result], %[original], %[value]\n" // result = original - value "uxtb %[result], %[result]\n" // zero extend result from 8 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 1u, true > : public operations< 4u, true > { typedef operations< 4u, true > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "add %[result], %[original], %[value]\n" // result = original + value "sxtb %[result], %[result]\n" // sign extend result from 8 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "sub %[result], %[original], %[value]\n" // result = original - value "sxtb %[result], %[result]\n" // sign extend result from 8 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 2u, false > : public operations< 4u, false > { typedef operations< 4u, false > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "add %[result], %[original], %[value]\n" // result = original + value "uxth %[result], %[result]\n" // zero extend result from 16 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "sub %[result], %[original], %[value]\n" // result = original - value "uxth %[result], %[result]\n" // zero extend result from 16 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 2u, true > : public operations< 4u, true > { typedef operations< 4u, true > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "add %[result], %[original], %[value]\n" // result = original + value "sxth %[result], %[result]\n" // sign extend result from 16 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); uint32_t tmp; storage_type original, result; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) "1:\n" "ldrex %[original], %[storage]\n" // original = *(&storage) "sub %[result], %[original], %[value]\n" // result = original - value "sxth %[result], %[result]\n" // sign extend result from 16 to 32 bits "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed "teq %[tmp], #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) : [original] "=&r" (original), // %0 [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 : [value] "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; #if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) // Unlike 32-bit operations, for 64-bit loads and stores we must use ldrexd/strexd. // Any other instructions result in a non-atomic sequence of 32-bit accesses. // See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition", // Section A3.5.3 "Atomicity in the ARM architecture". // In the asm blocks below we have to use 32-bit register pairs to compose 64-bit values. // In order to pass the 64-bit operands to/from asm blocks, we use undocumented gcc feature: // the lower half (Rt) of the operand is accessible normally, via the numbered placeholder (e.g. %0), // and the upper half (Rt2) - via the same placeholder with an 'H' after the '%' sign (e.g. %H0). // See: http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/ template< bool Signed > struct operations< 8u, Signed > : public gcc_arm_operations_base { typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { exchange(storage, v, order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type original; uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "ldrexd %1, %H1, [%2]\n" BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original) // %1 : "r" (&storage) // %2 ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original; fence_before(order); uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "1:\n" "ldrexd %1, %H1, [%3]\n" // load the original value "strexd %0, %2, %H2, [%3]\n" // store the replacement, tmp = store failed "teq %0, #0\n" // check if store succeeded "bne 1b\n" BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original) // %1 : "r" (v), // %2 "r" (&storage) // %3 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); fence_after(order); return original; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); uint32_t tmp; storage_type original, old_val = expected; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "ldrexd %1, %H1, [%3]\n" // original = *(&storage) "cmp %1, %2\n" // flags = original.lo==old_val.lo "ittt eq\n" // [hint that the following 3 instructions are conditional on flags.equal] "cmpeq %H1, %H2\n" // if (flags.equal) flags = original.hi==old_val.hi "strexdeq %0, %4, %H4, [%3]\n" // if (flags.equal) *(&storage) = desired, tmp = store failed "teqeq %0, #0\n" // if (flags.equal) flags = tmp==0 "ite eq\n" // [hint that the following 2 instructions are conditional on flags.equal] "moveq %2, #1\n" // if (flags.equal) old_val.lo = 1 "movne %2, #0\n" // if (!flags.equal) old_val.lo = 0 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original), // %1 "+r" (old_val) // %2 : "r" (&storage), // %3 "r" (desired) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); const uint32_t success = (uint32_t)old_val; if (success) fence_after(success_order); else fence_after(failure_order); expected = original; return !!success; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); uint32_t tmp; storage_type original, old_val = expected; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "1:\n" "ldrexd %1, %H1, [%3]\n" // original = *(&storage) "cmp %1, %2\n" // flags = original.lo==old_val.lo "it eq\n" // [hint that the following instruction is conditional on flags.equal] "cmpeq %H1, %H2\n" // if (flags.equal) flags = original.hi==old_val.hi "bne 2f\n" // if (!flags.equal) goto end "strexd %0, %4, %H4, [%3]\n" // *(&storage) = desired, tmp = store failed "teq %0, #0\n" // flags.equal = tmp == 0 "bne 1b\n" // if (flags.equal) goto retry "2:\n" "ite eq\n" // [hint that the following 2 instructions are conditional on flags.equal] "moveq %2, #1\n" // if (flags.equal) old_val.lo = 1 "movne %2, #0\n" // if (!flags.equal) old_val.lo = 0 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original), // %1 "+r" (old_val) // %2 : "r" (&storage), // %3 "r" (desired) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); const uint32_t success = (uint32_t)old_val; if (success) fence_after(success_order); else fence_after(failure_order); expected = original; return !!success; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage_type original, result; uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "1:\n" "ldrexd %1, %H1, [%3]\n" // original = *(&storage) "adds %2, %1, %4\n" // result = original + value "adc %H2, %H1, %H4\n" "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed "teq %0, #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original), // %1 "=&r" (result) // %2 : "r" (&storage), // %3 "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage_type original, result; uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "1:\n" "ldrexd %1, %H1, [%3]\n" // original = *(&storage) "subs %2, %1, %4\n" // result = original - value "sbc %H2, %H1, %H4\n" "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed "teq %0, #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original), // %1 "=&r" (result) // %2 : "r" (&storage), // %3 "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage_type original, result; uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "1:\n" "ldrexd %1, %H1, [%3]\n" // original = *(&storage) "and %2, %1, %4\n" // result = original & value "and %H2, %H1, %H4\n" "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed "teq %0, #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original), // %1 "=&r" (result) // %2 : "r" (&storage), // %3 "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage_type original, result; uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "1:\n" "ldrexd %1, %H1, [%3]\n" // original = *(&storage) "orr %2, %1, %4\n" // result = original | value "orr %H2, %H1, %H4\n" "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed "teq %0, #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original), // %1 "=&r" (result) // %2 : "r" (&storage), // %3 "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); storage_type original, result; uint32_t tmp; __asm__ __volatile__ ( BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) "1:\n" "ldrexd %1, %H1, [%3]\n" // original = *(&storage) "eor %2, %1, %4\n" // result = original ^ value "eor %H2, %H1, %H4\n" "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed "teq %0, #0\n" // flags = tmp==0 "bne 1b\n" // if (!flags.equal) goto retry BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 "=&r" (original), // %1 "=&r" (result) // %2 : "r" (&storage), // %3 "r" (v) // %4 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); fence_after(order); return original; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, 0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; #endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) gcc_arm_operations_base::hardware_full_fence(); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __asm__ __volatile__ ("" ::: "memory"); } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_atomic.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_atomic.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_ #include #include #include #include #include #if defined(__clang__) && (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)) #include #include #endif #if __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE || __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE ||\ __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE || __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE ||\ __GCC_ATOMIC_CHAR_LOCK_FREE != BOOST_ATOMIC_CHAR_LOCK_FREE || __GCC_ATOMIC_BOOL_LOCK_FREE != BOOST_ATOMIC_BOOL_LOCK_FREE ||\ __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE // There are platforms where we need to use larger storage types #include #include #endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(__INTEL_COMPILER) // This is used to suppress warning #32013 described below for Intel Compiler. // In debug builds the compiler does not inline any functions, so basically // every atomic function call results in this warning. I don't know any other // way to selectively disable just this one warning. #pragma system_header #endif namespace boost { namespace atomics { namespace detail { /*! * The function converts \c boost::memory_order values to the compiler-specific constants. * * NOTE: The intention is that the function is optimized away by the compiler, and the * compiler-specific constants are passed to the intrinsics. I know constexpr doesn't * work in this case because the standard atomics interface require memory ordering * constants to be passed as function arguments, at which point they stop being constexpr. * However it is crucial that the compiler sees constants and not runtime values, * because otherwise it just ignores the ordering value and always uses seq_cst. * This is the case with Intel C++ Compiler 14.0.3 (Composer XE 2013 SP1, update 3) and * gcc 4.8.2. Intel Compiler issues a warning in this case: * * warning #32013: Invalid memory order specified. Defaulting to seq_cst memory order. * * while gcc acts silently. * * To mitigate the problem ALL functions, including the atomic<> members must be * declared with BOOST_FORCEINLINE. In this case the compilers are able to see that * all functions are called with constant orderings and call intrinstcts properly. * * Unfortunately, this still doesn't work in debug mode as the compiler doesn't * inline functions even when marked with BOOST_FORCEINLINE. In this case all atomic * operaions will be executed with seq_cst semantics. */ BOOST_FORCEINLINE BOOST_CONSTEXPR int convert_memory_order_to_gcc(memory_order order) BOOST_NOEXCEPT { return (order == memory_order_relaxed ? __ATOMIC_RELAXED : (order == memory_order_consume ? __ATOMIC_CONSUME : (order == memory_order_acquire ? __ATOMIC_ACQUIRE : (order == memory_order_release ? __ATOMIC_RELEASE : (order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_SEQ_CST))))); } template< typename T > struct gcc_atomic_operations { typedef T storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { __atomic_store_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { return __atomic_load_n(&storage, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { return __atomic_fetch_add(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { return __atomic_fetch_sub(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { return __atomic_exchange_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return __atomic_compare_exchange_n ( &storage, &expected, desired, false, atomics::detail::convert_memory_order_to_gcc(success_order), atomics::detail::convert_memory_order_to_gcc(failure_order) ); } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return __atomic_compare_exchange_n ( &storage, &expected, desired, true, atomics::detail::convert_memory_order_to_gcc(success_order), atomics::detail::convert_memory_order_to_gcc(failure_order) ); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { return __atomic_fetch_and(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { return __atomic_fetch_or(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { return __atomic_fetch_xor(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return __atomic_test_and_set(&storage, atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { __atomic_clear(const_cast< storage_type* >(&storage), atomics::detail::convert_memory_order_to_gcc(order)); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile& storage) BOOST_NOEXCEPT { return __atomic_is_lock_free(sizeof(storage_type), &storage); } }; #if BOOST_ATOMIC_INT128_LOCK_FREE > 0 #if defined(__clang__) && defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) // Workaround for clang bug: http://llvm.org/bugs/show_bug.cgi?id=19149 // Clang 3.4 does not implement 128-bit __atomic* intrinsics even though it defines __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 template< bool Signed > struct operations< 16u, Signed > : public cas_based_operations< gcc_dcas_x86_64< Signed > > { }; #else template< bool Signed > struct operations< 16u, Signed > : public gcc_atomic_operations< typename make_storage_type< 16u, Signed >::type > { typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; }; #endif #endif #if BOOST_ATOMIC_INT64_LOCK_FREE > 0 #if defined(__clang__) && defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) // Workaround for clang bug http://llvm.org/bugs/show_bug.cgi?id=19355 template< bool Signed > struct operations< 8u, Signed > : public cas_based_operations< gcc_dcas_x86< Signed > > { }; #elif (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) #define BOOST_ATOMIC_DETAIL_INT64_EXTENDED template< bool Signed > struct operations< 8u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 16u, Signed >::type >, 8u, Signed > { typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; }; #else template< bool Signed > struct operations< 8u, Signed > : public gcc_atomic_operations< typename make_storage_type< 8u, Signed >::type > { typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; }; #endif #endif #if BOOST_ATOMIC_INT32_LOCK_FREE > 0 #if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) #define BOOST_ATOMIC_DETAIL_INT32_EXTENDED #if !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) template< bool Signed > struct operations< 4u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 8u, Signed >::type >, 4u, Signed > { typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; }; #else // !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) template< bool Signed > struct operations< 4u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 16u, Signed >::type >, 4u, Signed > { typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; }; #endif // !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) #else template< bool Signed > struct operations< 4u, Signed > : public gcc_atomic_operations< typename make_storage_type< 4u, Signed >::type > { typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; }; #endif #endif #if BOOST_ATOMIC_INT16_LOCK_FREE > 0 #if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) #define BOOST_ATOMIC_DETAIL_INT16_EXTENDED #if !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED) template< bool Signed > struct operations< 2u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 4u, Signed >::type >, 2u, Signed > { typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; }; #elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) template< bool Signed > struct operations< 2u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 8u, Signed >::type >, 2u, Signed > { typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; }; #else template< bool Signed > struct operations< 2u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 16u, Signed >::type >, 2u, Signed > { typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; }; #endif #else template< bool Signed > struct operations< 2u, Signed > : public gcc_atomic_operations< typename make_storage_type< 2u, Signed >::type > { typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; }; #endif #endif #if BOOST_ATOMIC_INT8_LOCK_FREE > 0 #if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) ||\ (__GCC_ATOMIC_CHAR_LOCK_FREE != BOOST_ATOMIC_CHAR_LOCK_FREE) ||\ (__GCC_ATOMIC_BOOL_LOCK_FREE != BOOST_ATOMIC_BOOL_LOCK_FREE) #if !defined(BOOST_ATOMIC_DETAIL_INT16_EXTENDED) template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 2u, Signed >::type >, 1u, Signed > { typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; }; #elif !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED) template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 4u, Signed >::type >, 1u, Signed > { typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; }; #elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 8u, Signed >::type >, 1u, Signed > { typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; }; #else template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< gcc_atomic_operations< typename make_storage_type< 16u, Signed >::type >, 1u, Signed > { typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; }; #endif #else template< bool Signed > struct operations< 1u, Signed > : public gcc_atomic_operations< typename make_storage_type< 1u, Signed >::type > { typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; }; #endif #endif #undef BOOST_ATOMIC_DETAIL_INT16_EXTENDED #undef BOOST_ATOMIC_DETAIL_INT32_EXTENDED #undef BOOST_ATOMIC_DETAIL_INT64_EXTENDED BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { __atomic_thread_fence(atomics::detail::convert_memory_order_to_gcc(order)); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { __atomic_signal_fence(atomics::detail::convert_memory_order_to_gcc(order)); } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_ppc.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_ppc.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_ #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { // The implementation below uses information from this document: // http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2010.02.19a.html /* Refer to: Motorola: "Programming Environments Manual for 32-Bit Implementations of the PowerPC Architecture", Appendix E: "Synchronization Programming Examples" for an explanation of what is going on here (can be found on the web at various places by the name "MPCFPE32B.pdf", Google is your friend...) Most of the atomic operations map to instructions in a relatively straight-forward fashion, but "load"s may at first glance appear a bit strange as they map to: lwz %rX, addr cmpw %rX, %rX bne- 1f 1: That is, the CPU is forced to perform a branch that "formally" depends on the value retrieved from memory. This scheme has an overhead of about 1-2 clock cycles per load, but it allows to map "acquire" to the "isync" instruction instead of "sync" uniformly and for all type of atomic operations. Since "isync" has a cost of about 15 clock cycles, while "sync" hast a cost of about 50 clock cycles, the small penalty to atomic loads more than compensates for this. Byte- and halfword-sized atomic values are realized by encoding the value to be represented into a word, performing sign/zero extension as appropriate. This means that after add/sub operations the value needs fixing up to accurately preserve the wrap-around semantic of the smaller type. (Nothing special needs to be done for the bit-wise and the "exchange type" operators as the compiler already sees to it that values carried in registers are extended appropriately and everything falls into place naturally). The register constraint "b" instructs gcc to use any register except r0; this is sometimes required because the encoding for r0 is used to signify "constant zero" in a number of instructions, making r0 unusable in this place. For simplicity this constraint is used everywhere since I am to lazy to look this up on a per-instruction basis, and ppc has enough registers for this not to pose a problem. */ // A note about memory_order_consume. Technically, this architecture allows to avoid // unnecessary memory barrier after consume load since it supports data dependency ordering. // However, some compiler optimizations may break a seemingly valid code relying on data // dependency tracking by injecting bogus branches to aid out of order execution. // This may happen not only in Boost.Atomic code but also in user's code, which we have no // control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php. // For this reason we promote memory_order_consume to memory_order_acquire. struct gcc_ppc_operations_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { #if defined(__powerpc64__) || defined(__PPC64__) if (order == memory_order_seq_cst) __asm__ __volatile__ ("sync" ::: "memory"); else if ((order & memory_order_release) != 0) __asm__ __volatile__ ("lwsync" ::: "memory"); #else if ((order & memory_order_release) != 0) __asm__ __volatile__ ("sync" ::: "memory"); #endif } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { if ((order & (memory_order_consume | memory_order_acquire)) != 0) __asm__ __volatile__ ("isync" ::: "memory"); } }; template< bool Signed > struct operations< 4u, Signed > : public gcc_ppc_operations_base { typedef typename make_storage_type< 4u, Signed >::type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); __asm__ __volatile__ ( "stw %1, %0\n\t" : "+m" (storage) : "r" (v) ); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v; if (order == memory_order_seq_cst) __asm__ __volatile__ ("sync" ::: "memory"); if ((order & (memory_order_consume | memory_order_acquire)) != 0) { __asm__ __volatile__ ( "lwz %0, %1\n\t" "cmpw %0, %0\n\t" "bne- 1f\n\t" "1:\n\t" "isync\n\t" : "=&r" (v) : "m" (storage) : "cr0", "memory" ); } else { __asm__ __volatile__ ( "lwz %0, %1\n\t" : "=&r" (v) : "m" (storage) ); } return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y1\n\t" "stwcx. %2,%y1\n\t" "bne- 1b\n\t" : "=&b" (original), "+Z" (storage) : "b" (v) : "cr0" ); fence_after(order); return original; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { int success; fence_before(success_order); __asm__ __volatile__ ( "li %1, 0\n\t" "lwarx %0,%y2\n\t" "cmpw %0, %3\n\t" "bne- 1f\n\t" "stwcx. %4,%y2\n\t" "bne- 1f\n\t" "li %1, 1\n\t" "1:\n\t" : "=&b" (expected), "=&b" (success), "+Z" (storage) : "b" (expected), "b" (desired) : "cr0" ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { int success; fence_before(success_order); __asm__ __volatile__ ( "li %1, 0\n\t" "0: lwarx %0,%y2\n\t" "cmpw %0, %3\n\t" "bne- 1f\n\t" "stwcx. %4,%y2\n\t" "bne- 0b\n\t" "li %1, 1\n\t" "1:\n\t" : "=&b" (expected), "=&b" (success), "+Z" (storage) : "b" (expected), "b" (desired) : "cr0" ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "add %1,%0,%3\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "sub %1,%0,%3\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "and %1,%0,%3\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "or %1,%0,%3\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "xor %1,%0,%3\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, 0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< > struct operations< 1u, false > : public operations< 4u, false > { typedef operations< 4u, false > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "add %1,%0,%3\n\t" "rlwinm %1, %1, 0, 0xff\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "sub %1,%0,%3\n\t" "rlwinm %1, %1, 0, 0xff\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 1u, true > : public operations< 4u, true > { typedef operations< 4u, true > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "add %1,%0,%3\n\t" "extsb %1, %1\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "sub %1,%0,%3\n\t" "extsb %1, %1\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 2u, false > : public operations< 4u, false > { typedef operations< 4u, false > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "add %1,%0,%3\n\t" "rlwinm %1, %1, 0, 0xffff\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "sub %1,%0,%3\n\t" "rlwinm %1, %1, 0, 0xffff\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; template< > struct operations< 2u, true > : public operations< 4u, true > { typedef operations< 4u, true > base_type; typedef base_type::storage_type storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "add %1,%0,%3\n\t" "extsh %1, %1\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "lwarx %0,%y2\n\t" "sub %1,%0,%3\n\t" "extsh %1, %1\n\t" "stwcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } }; #if defined(__powerpc64__) || defined(__PPC64__) template< bool Signed > struct operations< 8u, Signed > : public gcc_ppc_operations_base { typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before(order); __asm__ __volatile__ ( "std %1, %0\n\t" : "+m" (storage) : "r" (v) ); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v; if (order == memory_order_seq_cst) __asm__ __volatile__ ("sync" ::: "memory"); if ((order & (memory_order_consume | memory_order_acquire)) != 0) { __asm__ __volatile__ ( "ld %0, %1\n\t" "cmpd %0, %0\n\t" "bne- 1f\n\t" "1:\n\t" "isync\n\t" : "=&b" (v) : "m" (storage) : "cr0", "memory" ); } else { __asm__ __volatile__ ( "ld %0, %1\n\t" : "=&b" (v) : "m" (storage) ); } return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "ldarx %0,%y1\n\t" "stdcx. %2,%y1\n\t" "bne- 1b\n\t" : "=&b" (original), "+Z" (storage) : "b" (v) : "cr0" ); fence_after(order); return original; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { int success; fence_before(success_order); __asm__ __volatile__ ( "li %1, 0\n\t" "ldarx %0,%y2\n\t" "cmpd %0, %3\n\t" "bne- 1f\n\t" "stdcx. %4,%y2\n\t" "bne- 1f\n\t" "li %1, 1\n\t" "1:" : "=&b" (expected), "=&b" (success), "+Z" (storage) : "b" (expected), "b" (desired) : "cr0" ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { int success; fence_before(success_order); __asm__ __volatile__ ( "li %1, 0\n\t" "0: ldarx %0,%y2\n\t" "cmpd %0, %3\n\t" "bne- 1f\n\t" "stdcx. %4,%y2\n\t" "bne- 0b\n\t" "li %1, 1\n\t" "1:\n\t" : "=&b" (expected), "=&b" (success), "+Z" (storage) : "b" (expected), "b" (desired) : "cr0" ); if (success) fence_after(success_order); else fence_after(failure_order); return !!success; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "ldarx %0,%y2\n\t" "add %1,%0,%3\n\t" "stdcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "ldarx %0,%y2\n\t" "sub %1,%0,%3\n\t" "stdcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "ldarx %0,%y2\n\t" "and %1,%0,%3\n\t" "stdcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "ldarx %0,%y2\n\t" "or %1,%0,%3\n\t" "stdcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type original, tmp; fence_before(order); __asm__ __volatile__ ( "1:\n\t" "ldarx %0,%y2\n\t" "xor %1,%0,%3\n\t" "stdcx. %1,%y2\n\t" "bne- 1b\n\t" : "=&b" (original), "=&b" (tmp), "+Z" (storage) : "b" (v) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ); fence_after(order); return original; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, 0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; #endif // defined(__powerpc64__) || defined(__PPC64__) BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_consume: case memory_order_acquire: case memory_order_release: case memory_order_acq_rel: #if defined(__powerpc64__) || defined(__PPC64__) __asm__ __volatile__ ("lwsync" ::: "memory"); break; #endif case memory_order_seq_cst: __asm__ __volatile__ ("sync" ::: "memory"); break; default:; } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) #if defined(__ibmxl__) || defined(__IBMCPP__) __fence(); #else __asm__ __volatile__ ("" ::: "memory"); #endif } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_sparc.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2010 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_sparc.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_ #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { struct gcc_sparc_cas_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) __asm__ __volatile__ ("membar #Sync" ::: "memory"); else if ((order & memory_order_release) != 0) __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) __asm__ __volatile__ ("membar #Sync" ::: "memory"); else if ((order & (memory_order_consume | memory_order_acquire)) != 0) __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) __asm__ __volatile__ ("membar #Sync" ::: "memory"); } }; template< bool Signed > struct gcc_sparc_cas32 : public gcc_sparc_cas_base { typedef typename make_storage_type< 4u, Signed >::type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before_store(order); storage = v; fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after(order); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); storage_type previous = expected; __asm__ __volatile__ ( "cas [%1], %2, %0" : "+r" (desired) : "r" (&storage), "r" (previous) : "memory" ); const bool success = (desired == previous); if (success) fence_after(success_order); else fence_after(failure_order); expected = desired; return success; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); __asm__ __volatile__ ( "swap [%1], %0" : "+r" (v) : "r" (&storage) : "memory" ); base_type::fence_after(order); return v; } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 4u, Signed > : public cas_based_operations< gcc_sparc_cas32< Signed > > { }; template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed > { }; template< bool Signed > struct operations< 2u, Signed > : public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed > { }; template< bool Signed > struct gcc_sparc_cas64 : public gcc_sparc_cas_base { typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before_store(order); storage = v; fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after(order); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { fence_before(success_order); storage_type previous = expected; __asm__ __volatile__ ( "casx [%1], %2, %0" : "+r" (desired) : "r" (&storage), "r" (previous) : "memory" ); const bool success = (desired == previous); if (success) fence_after(success_order); else fence_after(failure_order); expected = desired; return success; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 8u, Signed > : public cas_based_operations< cas_based_exchange< gcc_sparc_cas64< Signed > > > { }; BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_release: __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); break; case memory_order_consume: case memory_order_acquire: __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); break; case memory_order_acq_rel: __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory"); break; case memory_order_seq_cst: __asm__ __volatile__ ("membar #Sync" ::: "memory"); break; case memory_order_relaxed: default: break; } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __asm__ __volatile__ ("" ::: "memory"); } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_sync.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2011 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_sync.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_ #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { struct gcc_sync_operations_base { static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) __sync_synchronize(); } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) __sync_synchronize(); } static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT { if ((order & (memory_order_acquire | memory_order_consume)) != 0) __sync_synchronize(); } }; template< typename T > struct gcc_sync_operations : public gcc_sync_operations_base { typedef T storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before_store(order); storage = v; fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after_load(order); return v; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return __sync_fetch_and_add(&storage, v); } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return __sync_fetch_and_sub(&storage, v); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { // GCC docs mention that not all architectures may support full exchange semantics for this intrinsic. However, GCC's implementation of // std::atomic<> uses this intrinsic unconditionally. We do so as well. In case if some architectures actually don't support this, we can always // add a check here and fall back to a CAS loop. if ((order & memory_order_release) != 0) __sync_synchronize(); return __sync_lock_test_and_set(&storage, v); } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type expected2 = expected; storage_type old_val = __sync_val_compare_and_swap(&storage, expected2, desired); if (old_val == expected2) { return true; } else { expected = old_val; return false; } } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return __sync_fetch_and_and(&storage, v); } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return __sync_fetch_and_or(&storage, v); } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return __sync_fetch_and_xor(&storage, v); } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) __sync_synchronize(); return !!__sync_lock_test_and_set(&storage, 1); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { __sync_lock_release(&storage); if (order == memory_order_seq_cst) __sync_synchronize(); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; #if BOOST_ATOMIC_INT8_LOCK_FREE > 0 template< bool Signed > struct operations< 1u, Signed > : #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) public gcc_sync_operations< typename make_storage_type< 1u, Signed >::type > #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 2u, Signed >::type >, 1u, Signed > #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 4u, Signed >::type >, 1u, Signed > #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 8u, Signed >::type >, 1u, Signed > #else public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 16u, Signed >::type >, 1u, Signed > #endif { #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; #else typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; #endif }; #endif #if BOOST_ATOMIC_INT16_LOCK_FREE > 0 template< bool Signed > struct operations< 2u, Signed > : #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) public gcc_sync_operations< typename make_storage_type< 2u, Signed >::type > #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 4u, Signed >::type >, 2u, Signed > #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 8u, Signed >::type >, 2u, Signed > #else public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 16u, Signed >::type >, 2u, Signed > #endif { #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; #else typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; #endif }; #endif #if BOOST_ATOMIC_INT32_LOCK_FREE > 0 template< bool Signed > struct operations< 4u, Signed > : #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) public gcc_sync_operations< typename make_storage_type< 4u, Signed >::type > #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 8u, Signed >::type >, 4u, Signed > #else public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 16u, Signed >::type >, 4u, Signed > #endif { #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; #else typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; #endif }; #endif #if BOOST_ATOMIC_INT64_LOCK_FREE > 0 template< bool Signed > struct operations< 8u, Signed > : #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) public gcc_sync_operations< typename make_storage_type< 8u, Signed >::type > #else public extending_cas_based_operations< gcc_sync_operations< typename make_storage_type< 16u, Signed >::type >, 8u, Signed > #endif { #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; #else typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; #endif }; #endif #if BOOST_ATOMIC_INT128_LOCK_FREE > 0 template< bool Signed > struct operations< 16u, Signed > : public gcc_sync_operations< typename make_storage_type< 16u, Signed >::type > { typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; }; #endif BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __sync_synchronize(); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __asm__ __volatile__ ("" ::: "memory"); } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_x86.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_x86.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ #include #include #include #include #include #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) #include #include #endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(__x86_64__) #define BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "rdx" #else #define BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "edx" #endif namespace boost { namespace atomics { namespace detail { struct gcc_x86_operations_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) __asm__ __volatile__ ("" ::: "memory"); } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_acquire) != 0) __asm__ __volatile__ ("" ::: "memory"); } }; template< typename T, typename Derived > struct gcc_x86_operations : public gcc_x86_operations_base { typedef T storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { if (order != memory_order_seq_cst) { fence_before(order); storage = v; fence_after(order); } else { Derived::exchange(storage, v, order); } } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after(order); return v; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { return Derived::fetch_add(storage, -v, order); } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!Derived::exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, (storage_type)0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 1u, Signed > : public gcc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > { typedef gcc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "lock; xaddb %0, %1" : "+q" (v), "+m" (storage) : : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "xchgb %0, %1" : "+q" (v), "+m" (storage) : : "memory" ); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; bool success; __asm__ __volatile__ ( "lock; cmpxchgb %3, %1\n\t" "sete %2" : "+a" (previous), "+m" (storage), "=q" (success) : "q" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ __asm__ __volatile__\ (\ "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ "1: movb %[arg], %%dl\n\t"\ op " %%al, %%dl\n\t"\ "lock; cmpxchgb %%dl, %[storage]\n\t"\ "jne 1b"\ : [res] "+a" (result), [storage] "+m" (storage)\ : [arg] "q" (argument)\ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("andb", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("orb", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("xorb", v, res); return res; } #undef BOOST_ATOMIC_DETAIL_CAS_LOOP }; template< bool Signed > struct operations< 2u, Signed > : public gcc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > { typedef gcc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "lock; xaddw %0, %1" : "+q" (v), "+m" (storage) : : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "xchgw %0, %1" : "+q" (v), "+m" (storage) : : "memory" ); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; bool success; __asm__ __volatile__ ( "lock; cmpxchgw %3, %1\n\t" "sete %2" : "+a" (previous), "+m" (storage), "=q" (success) : "q" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ __asm__ __volatile__\ (\ "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ "1: movw %[arg], %%dx\n\t"\ op " %%ax, %%dx\n\t"\ "lock; cmpxchgw %%dx, %[storage]\n\t"\ "jne 1b"\ : [res] "+a" (result), [storage] "+m" (storage)\ : [arg] "q" (argument)\ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("andw", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("orw", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("xorw", v, res); return res; } #undef BOOST_ATOMIC_DETAIL_CAS_LOOP }; template< bool Signed > struct operations< 4u, Signed > : public gcc_x86_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > { typedef gcc_x86_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "lock; xaddl %0, %1" : "+r" (v), "+m" (storage) : : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "xchgl %0, %1" : "+r" (v), "+m" (storage) : : "memory" ); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; bool success; __asm__ __volatile__ ( "lock; cmpxchgl %3, %1\n\t" "sete %2" : "+a" (previous), "+m" (storage), "=q" (success) : "r" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ __asm__ __volatile__\ (\ "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ "1: movl %[arg], %%edx\n\t"\ op " %%eax, %%edx\n\t"\ "lock; cmpxchgl %%edx, %[storage]\n\t"\ "jne 1b"\ : [res] "+a" (result), [storage] "+m" (storage)\ : [arg] "r" (argument)\ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("andl", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("orl", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("xorl", v, res); return res; } #undef BOOST_ATOMIC_DETAIL_CAS_LOOP }; #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) template< bool Signed > struct operations< 8u, Signed > : public cas_based_operations< gcc_dcas_x86< Signed > > { }; #elif defined(__x86_64__) template< bool Signed > struct operations< 8u, Signed > : public gcc_x86_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > { typedef gcc_x86_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "lock; xaddq %0, %1" : "+r" (v), "+m" (storage) : : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ ( "xchgq %0, %1" : "+r" (v), "+m" (storage) : : "memory" ); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; bool success; __asm__ __volatile__ ( "lock; cmpxchgq %3, %1\n\t" "sete %2" : "+a" (previous), "+m" (storage), "=q" (success) : "r" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ __asm__ __volatile__\ (\ "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ "1: movq %[arg], %%rdx\n\t"\ op " %%rax, %%rdx\n\t"\ "lock; cmpxchgq %%rdx, %[storage]\n\t"\ "jne 1b"\ : [res] "+a" (result), [storage] "+m" (storage)\ : [arg] "r" (argument)\ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("andq", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("orq", v, res); return res; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type res = storage; BOOST_ATOMIC_DETAIL_CAS_LOOP("xorq", v, res); return res; } #undef BOOST_ATOMIC_DETAIL_CAS_LOOP }; #endif #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) template< bool Signed > struct operations< 16u, Signed > : public cas_based_operations< gcc_dcas_x86_64< Signed > > { }; #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) { __asm__ __volatile__ ( #if defined(__x86_64__) || defined(__SSE2__) "mfence\n" #else "lock; addl $0, (%%esp)\n" #endif ::: "memory" ); } else if ((order & (memory_order_acquire | memory_order_release)) != 0) { __asm__ __volatile__ ("" ::: "memory"); } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __asm__ __volatile__ ("" ::: "memory"); } } // namespace detail } // namespace atomics } // namespace boost #undef BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_gcc_x86_dcas.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_gcc_x86_dcas.hpp * * This header contains implementation of the double-width CAS primitive for x86. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_ #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) template< bool Signed > struct gcc_dcas_x86 { typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { if ((((uint32_t)&storage) & 0x00000007) == 0) { #if defined(__SSE2__) __asm__ __volatile__ ( #if defined(__AVX__) "vmovq %1, %%xmm4\n\t" "vmovq %%xmm4, %0\n\t" #else "movq %1, %%xmm4\n\t" "movq %%xmm4, %0\n\t" #endif : "=m" (storage) : "m" (v) : "memory", "xmm4" ); #else __asm__ __volatile__ ( "fildll %1\n\t" "fistpll %0\n\t" : "=m" (storage) : "m" (v) : "memory" ); #endif } else { #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) #if defined(__PIC__) uint32_t scratch; __asm__ __volatile__ ( "movl %%ebx, %[scratch]\n\t" "movl %[value_lo], %%ebx\n\t" "movl %[dest], %%eax\n\t" "movl 4+%[dest], %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b %[dest]\n\t" "jne 1b\n\t" "movl %[scratch], %%ebx\n\t" : [scratch] "=m" (scratch), [dest] "=o" (storage) : [value_lo] "a" ((uint32_t)v), "c" ((uint32_t)(v >> 32)) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory" ); #else // defined(__PIC__) __asm__ __volatile__ ( "movl %[dest], %%eax\n\t" "movl 4+%[dest], %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b %[dest]\n\t" "jne 1b\n\t" : [dest] "=o" (storage) : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory" ); #endif // defined(__PIC__) #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) #if defined(__PIC__) uint32_t scratch; __asm__ __volatile__ ( "movl %%ebx, %[scratch]\n\t" "movl %[value_lo], %%ebx\n\t" "movl 0(%[dest]), %%eax\n\t" "movl 4(%[dest]), %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b 0(%[dest])\n\t" "jne 1b\n\t" "movl %[scratch], %%ebx\n\t" #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : [scratch] "=m,m" (scratch) : [value_lo] "a,a" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage) #else : [scratch] "=m" (scratch) : [value_lo] "a" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory" ); #else // defined(__PIC__) __asm__ __volatile__ ( "movl 0(%[dest]), %%eax\n\t" "movl 4(%[dest]), %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b 0(%[dest])\n\t" "jne 1b\n\t" : #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : [value_lo] "b,b" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage) #else : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory" ); #endif // defined(__PIC__) #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) } } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT { storage_type value; if ((((uint32_t)&storage) & 0x00000007) == 0) { #if defined(__SSE2__) __asm__ __volatile__ ( #if defined(__AVX__) "vmovq %1, %%xmm4\n\t" "vmovq %%xmm4, %0\n\t" #else "movq %1, %%xmm4\n\t" "movq %%xmm4, %0\n\t" #endif : "=m" (value) : "m" (storage) : "memory", "xmm4" ); #else __asm__ __volatile__ ( "fildll %1\n\t" "fistpll %0\n\t" : "=m" (value) : "m" (storage) : "memory" ); #endif } else { #if defined(__clang__) // Clang cannot allocate eax:edx register pairs but it has sync intrinsics value = __sync_val_compare_and_swap(&storage, (storage_type)0, (storage_type)0); #else // We don't care for comparison result here; the previous value will be stored into value anyway. // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. __asm__ __volatile__ ( "movl %%ebx, %%eax\n\t" "movl %%ecx, %%edx\n\t" "lock; cmpxchg8b %[storage]\n\t" : "=&A" (value) : [storage] "m" (storage) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); #endif } return value; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { #if defined(__clang__) // Clang cannot allocate eax:edx register pairs but it has sync intrinsics storage_type old_expected = expected; expected = __sync_val_compare_and_swap(&storage, old_expected, desired); return expected == old_expected; #elif defined(__PIC__) // Make sure ebx is saved and restored properly in case // of position independent code. To make this work // setup register constraints such that ebx can not be // used by accident e.g. as base address for the variable // to be modified. Accessing "scratch" should always be okay, // as it can only be placed on the stack (and therefore // accessed through ebp or esp only). // // In theory, could push/pop ebx onto/off the stack, but movs // to a prepared stack slot turn out to be faster. uint32_t scratch; bool success; __asm__ __volatile__ ( "movl %%ebx, %[scratch]\n\t" "movl %[desired_lo], %%ebx\n\t" "lock; cmpxchg8b %[dest]\n\t" "movl %[scratch], %%ebx\n\t" "sete %[success]\n\t" #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : "+A,A,A,A,A,A" (expected), [dest] "+m,m,m,m,m,m" (storage), [scratch] "=m,m,m,m,m,m" (scratch), [success] "=q,m,q,m,q,m" (success) : [desired_lo] "S,S,D,D,m,m" ((uint32_t)desired), "c,c,c,c,c,c" ((uint32_t)(desired >> 32)) #else : "+A" (expected), [dest] "+m" (storage), [scratch] "=m" (scratch), [success] "=q" (success) : [desired_lo] "S" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return success; #else bool success; __asm__ __volatile__ ( "lock; cmpxchg8b %[dest]\n\t" "sete %[success]\n\t" #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : "+A,A" (expected), [dest] "+m,m" (storage), [success] "=q,m" (success) : "b,b" ((uint32_t)desired), "c,c" ((uint32_t)(desired >> 32)) #else : "+A" (expected), [dest] "+m" (storage), [success] "=q" (success) : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return success; #endif } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { #if defined(__clang__) // Clang cannot allocate eax:edx register pairs but it has sync intrinsics storage_type old_val = storage; while (true) { storage_type val = __sync_val_compare_and_swap(&storage, old_val, v); if (val == old_val) return val; old_val = val; } #elif !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) #if defined(__PIC__) uint32_t scratch; __asm__ __volatile__ ( "movl %%ebx, %[scratch]\n\t" "movl %%eax, %%ebx\n\t" "movl %%edx, %%ecx\n\t" "movl %[dest], %%eax\n\t" "movl 4+%[dest], %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b %[dest]\n\t" "jne 1b\n\t" "movl %[scratch], %%ebx\n\t" : "+A" (v), [scratch] "=m" (scratch), [dest] "+o" (storage) : : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "ecx", "memory" ); return v; #else // defined(__PIC__) __asm__ __volatile__ ( "movl %[dest], %%eax\n\t" "movl 4+%[dest], %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b %[dest]\n\t" "jne 1b\n\t" : "=A" (v), [dest] "+o" (storage) : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return v; #endif // defined(__PIC__) #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) #if defined(__PIC__) uint32_t scratch; __asm__ __volatile__ ( "movl %%ebx, %[scratch]\n\t" "movl %%eax, %%ebx\n\t" "movl %%edx, %%ecx\n\t" "movl 0(%[dest]), %%eax\n\t" "movl 4(%[dest]), %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b 0(%[dest])\n\t" "jne 1b\n\t" "movl %[scratch], %%ebx\n\t" #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : "+A,A" (v), [scratch] "=m,m" (scratch) : [dest] "D,S" (&storage) #else : "+A" (v), [scratch] "=m" (scratch) : [dest] "D" (&storage) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "ecx", "memory" ); return v; #else // defined(__PIC__) __asm__ __volatile__ ( "movl 0(%[dest]), %%eax\n\t" "movl 4(%[dest]), %%edx\n\t" ".align 16\n\t" "1: lock; cmpxchg8b 0(%[dest])\n\t" "jne 1b\n\t" #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : "=A,A" (v) : "b,b" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage) #else : "=A" (v) : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return v; #endif // defined(__PIC__) #endif } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) template< bool Signed > struct gcc_dcas_x86_64 { typedef typename make_storage_type< 16u, Signed >::type storage_type; typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { uint64_t const* p_value = (uint64_t const*)&v; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq %[dest], %%rax\n\t" "movq 8+%[dest], %%rdx\n\t" ".align 16\n\t" "1: lock; cmpxchg16b %[dest]\n\t" "jne 1b\n\t" : [dest] "=o" (storage) : "b" (p_value[0]), "c" (p_value[1]) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq 0(%[dest]), %%rax\n\t" "movq 8(%[dest]), %%rdx\n\t" ".align 16\n\t" "1: lock; cmpxchg16b 0(%[dest])\n\t" "jne 1b\n\t" : : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT { #if defined(__clang__) // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics storage_type value = storage_type(); return __sync_val_compare_and_swap(&storage, value, value); #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap storage_type value; // We don't care for comparison result here; the previous value will be stored into value anyway. // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq %%rbx, %%rax\n\t" "movq %%rcx, %%rdx\n\t" "lock; cmpxchg16b %[storage]\n\t" "movq %%rax, %[value]\n\t" "movq %%rdx, 8+%[value]\n\t" : [value] "=o" (value) : [storage] "m" (storage) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq %%rbx, %%rax\n\t" "movq %%rcx, %%rdx\n\t" "lock; cmpxchg16b %[storage]\n\t" "movq %%rax, 0(%[value])\n\t" "movq %%rdx, 8(%[value])\n\t" : : [storage] "m" (storage), [value] "r" (&value) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) return value; #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) storage_type value; // We don't care for comparison result here; the previous value will be stored into value anyway. // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b. __asm__ __volatile__ ( "movq %%rbx, %%rax\n\t" "movq %%rcx, %%rdx\n\t" "lock; cmpxchg16b %[storage]\n\t" : "=&A" (value) : [storage] "m" (storage) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return value; #endif } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { #if defined(__clang__) // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics storage_type old_expected = expected; expected = __sync_val_compare_and_swap(&storage, old_expected, desired); return expected == old_expected; #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap uint64_t const* p_desired = (uint64_t const*)&desired; bool success; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq %[expected], %%rax\n\t" "movq 8+%[expected], %%rdx\n\t" "lock; cmpxchg16b %[dest]\n\t" "sete %[success]\n\t" "movq %%rax, %[expected]\n\t" "movq %%rdx, 8+%[expected]\n\t" : [dest] "+m" (storage), [expected] "+o" (expected), [success] "=q" (success) : "b" (p_desired[0]), "c" (p_desired[1]) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq 0(%[expected]), %%rax\n\t" "movq 8(%[expected]), %%rdx\n\t" "lock; cmpxchg16b %[dest]\n\t" "sete %[success]\n\t" "movq %%rax, 0(%[expected])\n\t" "movq %%rdx, 8(%[expected])\n\t" : [dest] "+m" (storage), [success] "=q" (success) : "b" (p_desired[0]), "c" (p_desired[1]), [expected] "r" (&expected) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) return success; #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) uint64_t const* p_desired = (uint64_t const*)&desired; bool success; __asm__ __volatile__ ( "lock; cmpxchg16b %[dest]\n\t" "sete %[success]\n\t" #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : "+A,A" (expected), [dest] "+m,m" (storage), [success] "=q,m" (success) : "b,b" (p_desired[0]), "c,c" (p_desired[1]) #else : "+A" (expected), [dest] "+m" (storage), [success] "=q" (success) : "b" (p_desired[0]), "c" (p_desired[1]) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); return success; #endif } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { #if defined(__clang__) // Clang cannot allocate eax:edx register pairs but it has sync intrinsics storage_type old_val = storage; while (true) { storage_type val = __sync_val_compare_and_swap(&storage, old_val, v); if (val == old_val) return val; old_val = val; } #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap storage_type old_value; uint64_t const* p_value = (uint64_t const*)&v; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq %[dest], %%rax\n\t" "movq 8+%[dest], %%rdx\n\t" ".align 16\n\t" "1: lock; cmpxchg16b %[dest]\n\t" "jne 1b\n\t" "movq %%rax, %[old_value]\n\t" "movq %%rdx, 8+%[old_value]\n\t" : [dest] "+o" (storage), [old_value] "=o" (old_value) : "b" (p_value[0]), "c" (p_value[1]) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq 0(%[dest]), %%rax\n\t" "movq 8(%[dest]), %%rdx\n\t" ".align 16\n\t" "1: lock; cmpxchg16b 0(%[dest])\n\t" "jne 1b\n\t" "movq %%rax, 0(%[old_value])\n\t" "movq %%rdx, 8(%[old_value])\n\t" : : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage), [old_value] "r" (&old_value) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) return old_value; #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) uint64_t const* p_value = (uint64_t const*)&v; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq %[dest], %%rax\n\t" "movq 8+%[dest], %%rdx\n\t" ".align 16\n\t" "1: lock; cmpxchg16b %[dest]\n\t" "jne 1b\n\t" : "=&A" (v), [dest] "+o" (storage) : "b" (p_value[0]), "c" (p_value[1]) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( "movq 0(%[dest]), %%rax\n\t" "movq 8(%[dest]), %%rdx\n\t" ".align 16\n\t" "1: lock; cmpxchg16b 0(%[dest])\n\t" "jne 1b\n\t" : "=&A" (v) : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) return v; #endif } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_linux_arm.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009, 2011 Helge Bahmann * Copyright (c) 2009 Phil Endecott * Copyright (c) 2013 Tim Blechmann * Linux-specific code by Phil Endecott * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_linux_arm.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_ #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { // Different ARM processors have different atomic instructions. In particular, // architecture versions before v6 (which are still in widespread use, e.g. the // Intel/Marvell XScale chips like the one in the NSLU2) have only atomic swap. // On Linux the kernel provides some support that lets us abstract away from // these differences: it provides emulated CAS and barrier functions at special // addresses that are guaranteed not to be interrupted by the kernel. Using // this facility is slightly slower than inline assembler would be, but much // faster than a system call. // // While this emulated CAS is "strong" in the sense that it does not fail // "spuriously" (i.e.: it never fails to perform the exchange when the value // found equals the value expected), it does not return the found value on // failure. To satisfy the atomic API, compare_exchange_{weak|strong} must // return the found value on failure, and we have to manually load this value // after the emulated CAS reports failure. This in turn introduces a race // between the CAS failing (due to the "wrong" value being found) and subsequently // loading (which might turn up the "right" value). From an application's // point of view this looks like "spurious failure", and therefore the // emulated CAS is only good enough to provide compare_exchange_weak // semantics. struct linux_arm_cas_base { static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) hardware_full_fence(); } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) hardware_full_fence(); } static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT { if ((order & (memory_order_consume | memory_order_acquire)) != 0) hardware_full_fence(); } static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { typedef void (*kernel_dmb_t)(void); ((kernel_dmb_t)0xffff0fa0)(); } }; template< bool Signed > struct linux_arm_cas : public linux_arm_cas_base { typedef typename make_storage_type< 4u, Signed >::type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { fence_before_store(order); storage = v; fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after_load(order); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { while (true) { storage_type tmp = expected; if (compare_exchange_weak(storage, tmp, desired, success_order, failure_order)) return true; if (tmp != expected) { expected = tmp; return false; } } } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { typedef storage_type (*kernel_cmpxchg32_t)(storage_type oldval, storage_type newval, volatile storage_type* ptr); if (((kernel_cmpxchg32_t)0xffff0fc0)(expected, desired, &storage) == 0) { return true; } else { expected = storage; return false; } } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 1u, Signed > { }; template< bool Signed > struct operations< 2u, Signed > : public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 2u, Signed > { }; template< bool Signed > struct operations< 4u, Signed > : public cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > > { }; BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) linux_arm_cas_base::hardware_full_fence(); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) __asm__ __volatile__ ("" ::: "memory"); } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_msvc_arm.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_msvc_arm.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_ #include #include #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #define BOOST_ATOMIC_DETAIL_ARM_LOAD8(p) __iso_volatile_load8((const volatile __int8*)(p)) #define BOOST_ATOMIC_DETAIL_ARM_LOAD16(p) __iso_volatile_load16((const volatile __int16*)(p)) #define BOOST_ATOMIC_DETAIL_ARM_LOAD32(p) __iso_volatile_load32((const volatile __int32*)(p)) #define BOOST_ATOMIC_DETAIL_ARM_LOAD64(p) __iso_volatile_load64((const volatile __int64*)(p)) #define BOOST_ATOMIC_DETAIL_ARM_STORE8(p, v) __iso_volatile_store8((volatile __int8*)(p), (__int8)(v)) #define BOOST_ATOMIC_DETAIL_ARM_STORE16(p, v) __iso_volatile_store16((volatile __int16*)(p), (__int16)(v)) #define BOOST_ATOMIC_DETAIL_ARM_STORE32(p, v) __iso_volatile_store32((volatile __int32*)(p), (__int32)(v)) #define BOOST_ATOMIC_DETAIL_ARM_STORE64(p, v) __iso_volatile_store64((volatile __int64*)(p), (__int64)(v)) namespace boost { namespace atomics { namespace detail { // A note about memory_order_consume. Technically, this architecture allows to avoid // unnecessary memory barrier after consume load since it supports data dependency ordering. // However, some compiler optimizations may break a seemingly valid code relying on data // dependency tracking by injecting bogus branches to aid out of order execution. // This may happen not only in Boost.Atomic code but also in user's code, which we have no // control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php. // For this reason we promote memory_order_consume to memory_order_acquire. struct msvc_arm_operations_base { static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later } static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); if ((order & memory_order_release) != 0) hardware_full_fence(); BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); if (order == memory_order_seq_cst) hardware_full_fence(); BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); if ((order & (memory_order_consume | memory_order_acquire)) != 0) hardware_full_fence(); BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order cas_common_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { // Combine order flags together and promote memory_order_consume to memory_order_acquire return static_cast< memory_order >(((failure_order | success_order) & ~memory_order_consume) | (((failure_order | success_order) & memory_order_consume) << 1u)); } }; template< typename T, typename Derived > struct msvc_arm_operations : public msvc_arm_operations_base { typedef T storage_type; static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { typedef typename make_signed< storage_type >::type signed_storage_type; return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order); } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!Derived::exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { Derived::store(storage, (storage_type)0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 1u, Signed > : public msvc_arm_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > { typedef msvc_arm_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before_store(order); BOOST_ATOMIC_DETAIL_ARM_STORE8(&storage, v); base_type::fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD8(&storage); base_type::fence_after_load(order); return v; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&storage, v)); break; } return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { storage_type previous = expected, old_val; switch (cas_common_order(success_order, failure_order)) { case memory_order_relaxed: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELAXED(&storage, desired, previous)); break; case memory_order_consume: case memory_order_acquire: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_ACQUIRE(&storage, desired, previous)); break; case memory_order_release: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELEASE(&storage, desired, previous)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&storage, desired, previous)); break; } expected = old_val; return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8(&storage, v)); break; } return v; } }; template< bool Signed > struct operations< 2u, Signed > : public msvc_arm_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > { typedef msvc_arm_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before_store(order); BOOST_ATOMIC_DETAIL_ARM_STORE16(&storage, v); base_type::fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD16(&storage); base_type::fence_after_load(order); return v; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&storage, v)); break; } return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { storage_type previous = expected, old_val; switch (cas_common_order(success_order, failure_order)) { case memory_order_relaxed: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELAXED(&storage, desired, previous)); break; case memory_order_consume: case memory_order_acquire: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_ACQUIRE(&storage, desired, previous)); break; case memory_order_release: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELEASE(&storage, desired, previous)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&storage, desired, previous)); break; } expected = old_val; return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16(&storage, v)); break; } return v; } }; template< bool Signed > struct operations< 4u, Signed > : public msvc_arm_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > { typedef msvc_arm_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before_store(order); BOOST_ATOMIC_DETAIL_ARM_STORE32(&storage, v); base_type::fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD32(&storage); base_type::fence_after_load(order); return v; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v)); break; } return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { storage_type previous = expected, old_val; switch (cas_common_order(success_order, failure_order)) { case memory_order_relaxed: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELAXED(&storage, desired, previous)); break; case memory_order_consume: case memory_order_acquire: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_ACQUIRE(&storage, desired, previous)); break; case memory_order_release: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELEASE(&storage, desired, previous)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous)); break; } expected = old_val; return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v)); break; } return v; } }; template< bool Signed > struct operations< 8u, Signed > : public msvc_arm_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > { typedef msvc_arm_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before_store(order); BOOST_ATOMIC_DETAIL_ARM_STORE64(&storage, v); base_type::fence_after_store(order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD64(&storage); base_type::fence_after_load(order); return v; } static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(&storage, v)); break; } return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { storage_type previous = expected, old_val; switch (cas_common_order(success_order, failure_order)) { case memory_order_relaxed: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELAXED(&storage, desired, previous)); break; case memory_order_consume: case memory_order_acquire: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_ACQUIRE(&storage, desired, previous)); break; case memory_order_release: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELEASE(&storage, desired, previous)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(&storage, desired, previous)); break; } expected = old_val; return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64(&storage, v)); break; } return v; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { switch (order) { case memory_order_relaxed: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELAXED(&storage, v)); break; case memory_order_consume: case memory_order_acquire: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_ACQUIRE(&storage, v)); break; case memory_order_release: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELEASE(&storage, v)); break; case memory_order_acq_rel: case memory_order_seq_cst: default: v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64(&storage, v)); break; } return v; } }; BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); if (order != memory_order_relaxed) msvc_arm_operations_base::hardware_full_fence(); BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } } // namespace detail } // namespace atomics } // namespace boost #undef BOOST_ATOMIC_DETAIL_ARM_LOAD8 #undef BOOST_ATOMIC_DETAIL_ARM_LOAD16 #undef BOOST_ATOMIC_DETAIL_ARM_LOAD32 #undef BOOST_ATOMIC_DETAIL_ARM_LOAD64 #undef BOOST_ATOMIC_DETAIL_ARM_STORE8 #undef BOOST_ATOMIC_DETAIL_ARM_STORE16 #undef BOOST_ATOMIC_DETAIL_ARM_STORE32 #undef BOOST_ATOMIC_DETAIL_ARM_STORE64 #endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_msvc_common.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_msvc_common.hpp * * This header contains common tools for MSVC implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif // Define compiler barriers #if defined(__INTEL_COMPILER) #define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() __memory_barrier() #elif defined(_MSC_VER) && !defined(_WIN32_WCE) extern "C" void _ReadWriteBarrier(void); #pragma intrinsic(_ReadWriteBarrier) #define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() _ReadWriteBarrier() #endif #ifndef BOOST_ATOMIC_DETAIL_COMPILER_BARRIER #define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() #endif #endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_msvc_x86.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_msvc_x86.hpp * * This header contains implementation of the \c operations template. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_ #include #include #include #include #include #include #include #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) #include #include #endif #include #if !defined(_M_IX86) && !(defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8) && defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16)) #include #endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(BOOST_MSVC) #pragma warning(push) // frame pointer register 'ebx' modified by inline assembly code. See the note below. #pragma warning(disable: 4731) #endif #if defined(_MSC_VER) && (defined(_M_AMD64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) extern "C" void _mm_mfence(void); #if defined(BOOST_MSVC) #pragma intrinsic(_mm_mfence) #endif #endif namespace boost { namespace atomics { namespace detail { /* * Implementation note for asm blocks. * * http://msdn.microsoft.com/en-us/data/k1a8ss06%28v=vs.105%29 * * Some SSE types require eight-byte stack alignment, forcing the compiler to emit dynamic stack-alignment code. * To be able to access both the local variables and the function parameters after the alignment, the compiler * maintains two frame pointers. If the compiler performs frame pointer omission (FPO), it will use EBP and ESP. * If the compiler does not perform FPO, it will use EBX and EBP. To ensure code runs correctly, do not modify EBX * in asm code if the function requires dynamic stack alignment as it could modify the frame pointer. * Either move the eight-byte aligned types out of the function, or avoid using EBX. * * Since we have no way of knowing that the compiler uses FPO, we have to always save and restore ebx * whenever we have to clobber it. Additionally, we disable warning C4731 above so that the compiler * doesn't spam about ebx use. */ struct msvc_x86_operations_base { static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { #if defined(_MSC_VER) && (defined(_M_AMD64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) // Use mfence only if SSE2 is available _mm_mfence(); #else long tmp; BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&tmp, 0); #endif } static BOOST_FORCEINLINE void fence_before(memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE void fence_after(memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE void fence_after_load(memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); // On x86 and x86_64 there is no need for a hardware barrier, // even if seq_cst memory order is requested, because all // seq_cst writes are implemented with lock-prefixed operations // or xchg which has implied lock prefix. Therefore normal loads // are already ordered with seq_cst stores on these architectures. } }; template< typename T, typename Derived > struct msvc_x86_operations : public msvc_x86_operations_base { typedef T storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { if (order != memory_order_seq_cst) { fence_before(order); storage = v; fence_after(order); } else { Derived::exchange(storage, v, order); } } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; fence_after_load(order); return v; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { typedef typename make_signed< storage_type >::type signed_storage_type; return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order); } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!Derived::exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, (storage_type)0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 4u, Signed > : public msvc_x86_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > { typedef msvc_x86_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v)); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v)); } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous)); expected = old_val; return (previous == old_val); } #if defined(BOOST_ATOMIC_INTERLOCKED_AND) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v)); } #else static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type res = storage; while (!compare_exchange_strong(storage, res, res & v, order, memory_order_relaxed)) {} return res; } #endif #if defined(BOOST_ATOMIC_INTERLOCKED_OR) static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v)); } #else static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type res = storage; while (!compare_exchange_strong(storage, res, res | v, order, memory_order_relaxed)) {} return res; } #endif #if defined(BOOST_ATOMIC_INTERLOCKED_XOR) static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v)); } #else static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { storage_type res = storage; while (!compare_exchange_strong(storage, res, res ^ v, order, memory_order_relaxed)) {} return res; } #endif }; #if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8) template< bool Signed > struct operations< 1u, Signed > : public msvc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > { typedef msvc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(&storage, v)); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&storage, v)); } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&storage, desired, previous)); expected = old_val; return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8(&storage, v)); } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8(&storage, v)); } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8(&storage, v)); } }; #elif defined(_M_IX86) template< bool Signed > struct operations< 1u, Signed > : public msvc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > { typedef msvc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); __asm { mov edx, storage movzx eax, v lock xadd byte ptr [edx], al mov v, al }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); __asm { mov edx, storage movzx eax, v xchg byte ptr [edx], al mov v, al }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order) BOOST_NOEXCEPT { base_type::fence_before(success_order); bool success; __asm { mov esi, expected mov edi, storage movzx eax, byte ptr [esi] movzx edx, desired lock cmpxchg byte ptr [edi], dl mov byte ptr [esi], al sete success }; // The success and failure fences are equivalent anyway base_type::fence_after(success_order); return success; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); int backup; __asm { mov backup, ebx xor edx, edx mov edi, storage movzx ebx, v movzx eax, byte ptr [edi] align 16 again: mov dl, al and dl, bl lock cmpxchg byte ptr [edi], dl jne again mov v, al mov ebx, backup }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); int backup; __asm { mov backup, ebx xor edx, edx mov edi, storage movzx ebx, v movzx eax, byte ptr [edi] align 16 again: mov dl, al or dl, bl lock cmpxchg byte ptr [edi], dl jne again mov v, al mov ebx, backup }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); int backup; __asm { mov backup, ebx xor edx, edx mov edi, storage movzx ebx, v movzx eax, byte ptr [edi] align 16 again: mov dl, al xor dl, bl lock cmpxchg byte ptr [edi], dl jne again mov v, al mov ebx, backup }; base_type::fence_after(order); return v; } }; #else template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed > { }; #endif #if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16) template< bool Signed > struct operations< 2u, Signed > : public msvc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > { typedef msvc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(&storage, v)); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&storage, v)); } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&storage, desired, previous)); expected = old_val; return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16(&storage, v)); } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16(&storage, v)); } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16(&storage, v)); } }; #elif defined(_M_IX86) template< bool Signed > struct operations< 2u, Signed > : public msvc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > { typedef msvc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); __asm { mov edx, storage movzx eax, v lock xadd word ptr [edx], ax mov v, ax }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); __asm { mov edx, storage movzx eax, v xchg word ptr [edx], ax mov v, ax }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order) BOOST_NOEXCEPT { base_type::fence_before(success_order); bool success; __asm { mov esi, expected mov edi, storage movzx eax, word ptr [esi] movzx edx, desired lock cmpxchg word ptr [edi], dx mov word ptr [esi], ax sete success }; // The success and failure fences are equivalent anyway base_type::fence_after(success_order); return success; } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); int backup; __asm { mov backup, ebx xor edx, edx mov edi, storage movzx ebx, v movzx eax, word ptr [edi] align 16 again: mov dx, ax and dx, bx lock cmpxchg word ptr [edi], dx jne again mov v, ax mov ebx, backup }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); int backup; __asm { mov backup, ebx xor edx, edx mov edi, storage movzx ebx, v movzx eax, word ptr [edi] align 16 again: mov dx, ax or dx, bx lock cmpxchg word ptr [edi], dx jne again mov v, ax mov ebx, backup }; base_type::fence_after(order); return v; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); int backup; __asm { mov backup, ebx xor edx, edx mov edi, storage movzx ebx, v movzx eax, word ptr [edi] align 16 again: mov dx, ax xor dx, bx lock cmpxchg word ptr [edi], dx jne again mov v, ax mov ebx, backup }; base_type::fence_after(order); return v; } }; #else template< bool Signed > struct operations< 2u, Signed > : public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed > { }; #endif #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) template< bool Signed > struct msvc_dcas_x86 { typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; // Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, 8.1.1. Guaranteed Atomic Operations: // // The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically: // * Reading or writing a quadword aligned on a 64-bit boundary // // Luckily, the memory is almost always 8-byte aligned in our case because atomic<> uses 64 bit native types for storage and dynamic memory allocations // have at least 8 byte alignment. The only unfortunate case is when atomic is placed on the stack and it is not 8-byte aligned (like on 32 bit Windows). static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); storage_type volatile* p = &storage; if (((uint32_t)p & 0x00000007) == 0) { #if defined(_M_IX86_FP) && _M_IX86_FP >= 2 #if defined(__AVX__) __asm { mov edx, p vmovq xmm4, v vmovq qword ptr [edx], xmm4 }; #else __asm { mov edx, p movq xmm4, v movq qword ptr [edx], xmm4 }; #endif #else __asm { mov edx, p fild v fistp qword ptr [edx] }; #endif } else { int backup; __asm { mov backup, ebx mov edi, p mov ebx, dword ptr [v] mov ecx, dword ptr [v + 4] mov eax, dword ptr [edi] mov edx, dword ptr [edi + 4] align 16 again: lock cmpxchg8b qword ptr [edi] jne again mov ebx, backup }; } BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); storage_type const volatile* p = &storage; storage_type value; if (((uint32_t)p & 0x00000007) == 0) { #if defined(_M_IX86_FP) && _M_IX86_FP >= 2 #if defined(__AVX__) __asm { mov edx, p vmovq xmm4, qword ptr [edx] vmovq value, xmm4 }; #else __asm { mov edx, p movq xmm4, qword ptr [edx] movq value, xmm4 }; #endif #else __asm { mov edx, p fild qword ptr [edx] fistp value }; #endif } else { // We don't care for comparison result here; the previous value will be stored into value anyway. // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. __asm { mov edi, p mov eax, ebx mov edx, ecx lock cmpxchg8b qword ptr [edi] mov dword ptr [value], eax mov dword ptr [value + 4], edx }; } BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); return value; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { // MSVC-11 in 32-bit mode sometimes generates messed up code without compiler barriers, // even though the _InterlockedCompareExchange64 intrinsic already provides one. BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); storage_type volatile* p = &storage; #if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) const storage_type old_val = (storage_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(p, desired, expected); const bool result = (old_val == expected); expected = old_val; #else bool result; int backup; __asm { mov backup, ebx mov edi, p mov esi, expected mov ebx, dword ptr [desired] mov ecx, dword ptr [desired + 4] mov eax, dword ptr [esi] mov edx, dword ptr [esi + 4] lock cmpxchg8b qword ptr [edi] mov dword ptr [esi], eax mov dword ptr [esi + 4], edx mov ebx, backup sete result }; #endif BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); return result; } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); storage_type volatile* p = &storage; int backup; __asm { mov backup, ebx mov edi, p mov ebx, dword ptr [v] mov ecx, dword ptr [v + 4] mov eax, dword ptr [edi] mov edx, dword ptr [edi + 4] align 16 again: lock cmpxchg8b qword ptr [edi] jne again mov ebx, backup mov dword ptr [v], eax mov dword ptr [v + 4], edx }; BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); return v; } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 8u, Signed > : public cas_based_operations< msvc_dcas_x86< Signed > > { }; #elif defined(_M_AMD64) template< bool Signed > struct operations< 8u, Signed > : public msvc_x86_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > { typedef msvc_x86_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(&storage, v)); } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(&storage, v)); } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { storage_type previous = expected; storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(&storage, desired, previous)); expected = old_val; return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64(&storage, v)); } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64(&storage, v)); } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64(&storage, v)); } }; #endif #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) template< bool Signed > struct msvc_dcas_x86_64 { typedef typename make_storage_type< 16u, Signed >::type storage_type; typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type value = const_cast< storage_type& >(storage); while (!BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, v, &value)) {} } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT { storage_type value = storage_type(); BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, value, &value); return value; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { return !!BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, desired, &expected); } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 16u, Signed > : public cas_based_operations< cas_based_exchange< msvc_dcas_x86_64< Signed > > > { }; #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); if (order == memory_order_seq_cst) msvc_x86_operations_base::hardware_full_fence(); BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } } // namespace detail } // namespace atomics } // namespace boost #if defined(BOOST_MSVC) #pragma warning(pop) #endif #endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/ops_windows.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/ops_windows.hpp * * This header contains implementation of the \c operations template. * * This implementation is the most basic version for Windows. It should * work for any non-MSVC-like compilers as long as there are Interlocked WinAPI * functions available. This version is also used for WinCE. * * Notably, this implementation is not as efficient as other * versions based on compiler intrinsics. */ #ifndef BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_ #include #include #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { struct windows_operations_base { static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { long tmp; BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&tmp, 0); } static BOOST_FORCEINLINE void fence_before(memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE void fence_after(memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } }; template< typename T, typename Derived > struct windows_operations : public windows_operations_base { typedef T storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { Derived::exchange(storage, v, order); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { return Derived::fetch_add(const_cast< storage_type volatile& >(storage), (storage_type)0, order); } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { typedef typename make_signed< storage_type >::type signed_storage_type; return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order); } static BOOST_FORCEINLINE bool compare_exchange_weak( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { return !!Derived::exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { store(storage, (storage_type)0, order); } static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; } }; template< bool Signed > struct operations< 4u, Signed > : public windows_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > { typedef windows_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v)); base_type::fence_after(order); return v; } static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { base_type::fence_before(order); v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v)); base_type::fence_after(order); return v; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { storage_type previous = expected; base_type::fence_before(success_order); storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous)); expected = old_val; // The success and failure fences are the same anyway base_type::fence_after(success_order); return (previous == old_val); } static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { #if defined(BOOST_ATOMIC_INTERLOCKED_AND) base_type::fence_before(order); v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v)); base_type::fence_after(order); return v; #else storage_type res = storage; while (!compare_exchange_strong(storage, res, res & v, order, memory_order_relaxed)) {} return res; #endif } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { #if defined(BOOST_ATOMIC_INTERLOCKED_OR) base_type::fence_before(order); v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v)); base_type::fence_after(order); return v; #else storage_type res = storage; while (!compare_exchange_strong(storage, res, res | v, order, memory_order_relaxed)) {} return res; #endif } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { #if defined(BOOST_ATOMIC_INTERLOCKED_XOR) base_type::fence_before(order); v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v)); base_type::fence_after(order); return v; #else storage_type res = storage; while (!compare_exchange_strong(storage, res, res ^ v, order, memory_order_relaxed)) {} return res; #endif } }; template< bool Signed > struct operations< 1u, Signed > : public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed > { }; template< bool Signed > struct operations< 2u, Signed > : public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed > { }; BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); if (order == memory_order_seq_cst) windows_operations_base::hardware_full_fence(); BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { if (order != memory_order_relaxed) BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/pause.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * (C) Copyright 2013 Tim Blechmann * (C) Copyright 2013 Andrey Semashev */ #ifndef BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86)) extern "C" void _mm_pause(void); #if defined(BOOST_MSVC) #pragma intrinsic(_mm_pause) #endif #endif namespace boost { namespace atomics { namespace detail { BOOST_FORCEINLINE void pause() BOOST_NOEXCEPT { #if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86)) _mm_pause(); #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) __asm__ __volatile__("pause;"); #endif } } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/platform.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/detail/platform.hpp * * This header defines macros for the target platform detection */ #ifndef BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_ #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if !defined(BOOST_ATOMIC_FORCE_FALLBACK) // Compiler-based backends #if (defined(__ibmxl__) || defined(__IBMCPP__)) && defined(__PPC__) // IBM XL C++ Compiler has to be checked before GCC/Clang as it pretends to be one but does not support __atomic* intrinsics. // It does support GCC inline assembler though. #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_ppc #elif ((defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407)) ||\ (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302))) &&\ (\ (__GCC_ATOMIC_BOOL_LOCK_FREE + 0) == 2 ||\ (__GCC_ATOMIC_CHAR_LOCK_FREE + 0) == 2 ||\ (__GCC_ATOMIC_SHORT_LOCK_FREE + 0) == 2 ||\ (__GCC_ATOMIC_INT_LOCK_FREE + 0) == 2 ||\ (__GCC_ATOMIC_LONG_LOCK_FREE + 0) == 2 ||\ (__GCC_ATOMIC_LLONG_LOCK_FREE + 0) == 2\ ) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_atomic #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_x86 #elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__PPC__)) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_ppc // This list of ARM architecture versions comes from Apple's arm/arch.h header. // I don't know how complete it is. #elif defined(__GNUC__) &&\ (\ defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) ||\ defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) ||\ defined(__ARM_ARCH_6ZK__) ||\ defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) ||\ defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) ||\ defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)\ ) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_arm #elif defined(__GNUC__) && defined(__sparc_v9__) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_sparc #elif defined(__GNUC__) && defined(__alpha__) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_alpha #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 401) &&\ (\ defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) ||\ defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) ||\ defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) ||\ defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\ defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)\ ) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_sync #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) #define BOOST_ATOMIC_DETAIL_PLATFORM msvc_x86 #elif defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM) #define BOOST_ATOMIC_DETAIL_PLATFORM msvc_arm #endif // OS-based backends #if !defined(BOOST_ATOMIC_DETAIL_PLATFORM) #if defined(__linux__) && defined(__arm__) #define BOOST_ATOMIC_DETAIL_PLATFORM linux_arm #elif defined(BOOST_WINDOWS) || defined(_WIN32_CE) #define BOOST_ATOMIC_DETAIL_PLATFORM windows #endif #endif // !defined(BOOST_ATOMIC_DETAIL_PLATFORM) #endif // !defined(BOOST_ATOMIC_FORCE_FALLBACK) #if !defined(BOOST_ATOMIC_DETAIL_PLATFORM) #define BOOST_ATOMIC_DETAIL_PLATFORM emulated #define BOOST_ATOMIC_EMULATED #endif #define BOOST_ATOMIC_DETAIL_HEADER(prefix) #endif // BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/detail/storage_type.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2009 Helge Bahmann * Copyright (c) 2012 Tim Blechmann * Copyright (c) 2013 - 2014 Andrey Semashev */ /*! * \file atomic/detail/storage_type.hpp * * This header defines underlying types used as storage */ #ifndef BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ #include #include #include #if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) #include #endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { namespace atomics { namespace detail { template< typename T > BOOST_FORCEINLINE void non_atomic_load(T const volatile& from, T& to) BOOST_NOEXCEPT { to = from; } template< std::size_t Size > struct buffer_storage { BOOST_ALIGNMENT(16) unsigned char data[Size]; BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT { return (data[0] == 0u && BOOST_ATOMIC_DETAIL_MEMCMP(data, data + 1, Size - 1) == 0); } BOOST_FORCEINLINE bool operator== (buffer_storage const& that) const BOOST_NOEXCEPT { return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) == 0; } BOOST_FORCEINLINE bool operator!= (buffer_storage const& that) const BOOST_NOEXCEPT { return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) != 0; } }; template< std::size_t Size > BOOST_FORCEINLINE void non_atomic_load(buffer_storage< Size > const volatile& from, buffer_storage< Size >& to) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_MEMCPY(to.data, const_cast< unsigned char const* >(from.data), Size); } template< std::size_t Size, bool Signed > struct make_storage_type { typedef buffer_storage< Size > type; struct aligned { type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 1u, false > { typedef boost::uint8_t type; struct aligned { type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 1u, true > { typedef boost::int8_t type; struct aligned { type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 2u, false > { typedef boost::uint16_t type; struct aligned { BOOST_ALIGNMENT(2) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 2u, true > { typedef boost::int16_t type; struct aligned { BOOST_ALIGNMENT(2) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 4u, false > { typedef boost::uint32_t type; struct aligned { BOOST_ALIGNMENT(4) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 4u, true > { typedef boost::int32_t type; struct aligned { BOOST_ALIGNMENT(4) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 8u, false > { typedef boost::uint64_t type; struct aligned { BOOST_ALIGNMENT(8) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 8u, true > { typedef boost::int64_t type; struct aligned { BOOST_ALIGNMENT(8) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; #if defined(BOOST_HAS_INT128) template< > struct make_storage_type< 16u, false > { typedef boost::uint128_type type; struct aligned { BOOST_ALIGNMENT(16) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; template< > struct make_storage_type< 16u, true > { typedef boost::int128_type type; struct aligned { BOOST_ALIGNMENT(16) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} }; }; #elif !defined(BOOST_NO_ALIGNMENT) struct storage128_t { boost::uint64_t data[2]; BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT { return data[0] == 0 && data[1] == 0; } }; BOOST_FORCEINLINE bool operator== (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT { return left.data[0] == right.data[0] && left.data[1] == right.data[1]; } BOOST_FORCEINLINE bool operator!= (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT { return !(left == right); } BOOST_FORCEINLINE void non_atomic_load(storage128_t const volatile& from, storage128_t& to) BOOST_NOEXCEPT { to.data[0] = from.data[0]; to.data[1] = from.data[1]; } template< bool Signed > struct make_storage_type< 16u, Signed > { typedef storage128_t type; struct aligned { BOOST_ALIGNMENT(16) type value; BOOST_DEFAULTED_FUNCTION(aligned(), {}) BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} }; }; #endif template< typename T > struct storage_size_of { enum _ { size = sizeof(T), value = (size == 3 ? 4 : (size >= 5 && size <= 7 ? 8 : (size >= 9 && size <= 15 ? 16 : size))) }; }; } // namespace detail } // namespace atomics } // namespace boost #endif // BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic/fences.hpp ================================================ /* * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * Copyright (c) 2011 Helge Bahmann * Copyright (c) 2013 Tim Blechmann * Copyright (c) 2014 Andrey Semashev */ /*! * \file atomic/fences.hpp * * This header contains definition of \c atomic_thread_fence and \c atomic_signal_fence functions. */ #ifndef BOOST_ATOMIC_FENCES_HPP_INCLUDED_ #define BOOST_ATOMIC_FENCES_HPP_INCLUDED_ #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif /* * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE, * see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp. */ namespace boost { namespace atomics { #if BOOST_ATOMIC_THREAD_FENCE > 0 BOOST_FORCEINLINE void atomic_thread_fence(memory_order order) BOOST_NOEXCEPT { detail::thread_fence(order); } #else BOOST_FORCEINLINE void atomic_thread_fence(memory_order) BOOST_NOEXCEPT { detail::lockpool::thread_fence(); } #endif #if BOOST_ATOMIC_SIGNAL_FENCE > 0 BOOST_FORCEINLINE void atomic_signal_fence(memory_order order) BOOST_NOEXCEPT { detail::signal_fence(order); } #else BOOST_FORCEINLINE void atomic_signal_fence(memory_order) BOOST_NOEXCEPT { detail::lockpool::signal_fence(); } #endif } // namespace atomics using atomics::atomic_thread_fence; using atomics::atomic_signal_fence; } // namespace boost #endif // BOOST_ATOMIC_FENCES_HPP_INCLUDED_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/atomic.hpp ================================================ #ifndef BOOST_ATOMIC_HPP #define BOOST_ATOMIC_HPP // Copyright (c) 2011 Helge Bahmann // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // This header includes all Boost.Atomic public headers #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/abi/borland_prefix.hpp ================================================ // (C) Copyright John Maddock 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // for C++ Builder the following options effect the ABI: // // -b (on or off - effect emum sizes) // -Vx (on or off - empty members) // -Ve (on or off - empty base classes) // -aX (alignment - 5 options). // -pX (Calling convention - 4 options) // -VmX (member pointer size and layout - 5 options) // -VC (on or off, changes name mangling) // -Vl (on or off, changes struct layout). // In addition the following warnings are sufficiently annoying (and // unfixable) to have them turned off by default: // // 8027 - functions containing [for|while] loops are not expanded inline // 8026 - functions taking class by value arguments are not expanded inline #pragma nopushoptwarn # pragma option push -a8 -Vx- -Ve- -b- -pc -Vmv -VC- -Vl- -w-8027 -w-8026 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/abi/borland_suffix.hpp ================================================ // (C) Copyright John Maddock 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # pragma option pop #pragma nopushoptwarn ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/abi/msvc_prefix.hpp ================================================ // (C) Copyright John Maddock 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Boost binaries are built with the compiler's default ABI settings, // if the user changes their default alignment in the VS IDE then their // code will no longer be binary compatible with the bjam built binaries // unless this header is included to force Boost code into a consistent ABI. // // Note that inclusion of this header is only necessary for libraries with // separate source, header only libraries DO NOT need this as long as all // translation units are built with the same options. // #if defined(_M_X64) # pragma pack(push,16) #else # pragma pack(push,8) #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/abi/msvc_suffix.hpp ================================================ // (C) Copyright John Maddock 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #pragma pack(pop) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/abi_prefix.hpp ================================================ // abi_prefix header -------------------------------------------------------// // (c) Copyright John Maddock 2003 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). #ifndef BOOST_CONFIG_ABI_PREFIX_HPP # define BOOST_CONFIG_ABI_PREFIX_HPP #else # error double inclusion of header boost/config/abi_prefix.hpp is an error #endif #include // this must occur after all other includes and before any code appears: #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX #endif #if defined( __BORLANDC__ ) #pragma nopushoptwarn #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/abi_suffix.hpp ================================================ // abi_sufffix header -------------------------------------------------------// // (c) Copyright John Maddock 2003 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // This header should be #included AFTER code that was preceded by a #include // . #ifndef BOOST_CONFIG_ABI_PREFIX_HPP # error Header boost/config/abi_suffix.hpp must only be used after boost/config/abi_prefix.hpp #else # undef BOOST_CONFIG_ABI_PREFIX_HPP #endif // the suffix header occurs after all of our code: #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_SUFFIX #endif #if defined( __BORLANDC__ ) #pragma nopushoptwarn #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/auto_link.hpp ================================================ // (C) Copyright John Maddock 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) /* * LOCATION: see http://www.boost.org for most recent version. * FILE auto_link.hpp * VERSION see * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. */ /************************************************************************* USAGE: ~~~~~~ Before including this header you must define one or more of define the following macros: BOOST_LIB_NAME: Required: A string containing the basename of the library, for example boost_regex. BOOST_LIB_TOOLSET: Optional: the base name of the toolset. BOOST_DYN_LINK: Optional: when set link to dll rather than static library. BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name of the library selected (useful for debugging). BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, rather than a mangled-name version. BOOST_AUTO_LINK_TAGGED: Specifies that we link to libraries built with the --layout=tagged option. This is essentially the same as the default name-mangled version, but without the compiler name and version, or the Boost version. Just the build options. These macros will be undef'ed at the end of the header, further this header has no include guards - so be sure to include it only once from your library! Algorithm: ~~~~~~~~~~ Libraries for Borland and Microsoft compilers are automatically selected here, the name of the lib is selected according to the following formula: BOOST_LIB_PREFIX + BOOST_LIB_NAME + "_" + BOOST_LIB_TOOLSET + BOOST_LIB_THREAD_OPT + BOOST_LIB_RT_OPT "-" + BOOST_LIB_VERSION These are defined as: BOOST_LIB_PREFIX: "lib" for static libraries otherwise "". BOOST_LIB_NAME: The base name of the lib ( for example boost_regex). BOOST_LIB_TOOLSET: The compiler toolset name (vc6, vc7, bcb5 etc). BOOST_LIB_THREAD_OPT: "-mt" for multithread builds, otherwise nothing. BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, contains one or more of the following letters after a hyphen: s static runtime (dynamic if not present). g debug/diagnostic runtime (release if not present). y Python debug/diagnostic runtime (release if not present). d debug build (release if not present). p STLport build. n STLport build without its IOStreams. BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. ***************************************************************************/ #ifdef __cplusplus # ifndef BOOST_CONFIG_HPP # include # endif #elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__) // // C language compatability (no, honestly) // # define BOOST_MSVC _MSC_VER # define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) # define BOOST_DO_STRINGIZE(X) #X #endif // // Only include what follows for known and supported compilers: // #if defined(BOOST_MSVC) \ || defined(__BORLANDC__) \ || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) #ifndef BOOST_VERSION_HPP # include #endif #ifndef BOOST_LIB_NAME # error "Macro BOOST_LIB_NAME not set (internal error)" #endif // // error check: // #if defined(__MSVC_RUNTIME_CHECKS) && !defined(_DEBUG) # pragma message("Using the /RTC option without specifying a debug runtime will lead to linker errors") # pragma message("Hint: go to the code generation options and switch to one of the debugging runtimes") # error "Incompatible build options" #endif // // select toolset if not defined already: // #ifndef BOOST_LIB_TOOLSET # if defined(BOOST_MSVC) && (BOOST_MSVC < 1200) // Note: no compilers before 1200 are supported # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1300) # ifdef UNDER_CE // eVC4: # define BOOST_LIB_TOOLSET "evc4" # else // vc6: # define BOOST_LIB_TOOLSET "vc6" # endif # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1310) // vc7: # define BOOST_LIB_TOOLSET "vc7" # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1400) // vc71: # define BOOST_LIB_TOOLSET "vc71" # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1500) // vc80: # define BOOST_LIB_TOOLSET "vc80" # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1600) // vc90: # define BOOST_LIB_TOOLSET "vc90" # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1700) // vc10: # define BOOST_LIB_TOOLSET "vc100" # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) // vc11: # define BOOST_LIB_TOOLSET "vc110" # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900) // vc12: # define BOOST_LIB_TOOLSET "vc120" # elif defined(BOOST_MSVC) // vc14: # define BOOST_LIB_TOOLSET "vc140" # elif defined(__BORLANDC__) // CBuilder 6: # define BOOST_LIB_TOOLSET "bcb" # elif defined(__ICL) // Intel C++, no version number: # define BOOST_LIB_TOOLSET "iw" # elif defined(__MWERKS__) && (__MWERKS__ <= 0x31FF ) // Metrowerks CodeWarrior 8.x # define BOOST_LIB_TOOLSET "cw8" # elif defined(__MWERKS__) && (__MWERKS__ <= 0x32FF ) // Metrowerks CodeWarrior 9.x # define BOOST_LIB_TOOLSET "cw9" # endif #endif // BOOST_LIB_TOOLSET // // select thread opt: // #if defined(_MT) || defined(__MT__) # define BOOST_LIB_THREAD_OPT "-mt" #else # define BOOST_LIB_THREAD_OPT #endif #if defined(_MSC_VER) || defined(__MWERKS__) # ifdef _DLL # if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) # if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-gydp" # elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-gdp" # elif defined(_DEBUG)\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-gydp" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-gdp" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # else # define BOOST_LIB_RT_OPT "-p" # endif # elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) # if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-gydpn" # elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-gdpn" # elif defined(_DEBUG)\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-gydpn" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-gdpn" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # else # define BOOST_LIB_RT_OPT "-pn" # endif # else # if defined(_DEBUG) && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-gyd" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-gd" # else # define BOOST_LIB_RT_OPT # endif # endif # else # if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) # if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-sgydp" # elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-sgdp" # elif defined(_DEBUG)\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-sgydp" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-sgdp" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # else # define BOOST_LIB_RT_OPT "-sp" # endif # elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) # if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-sgydpn" # elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-sgdpn" # elif defined(_DEBUG)\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-sgydpn" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-sgdpn" # pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") # error "Build options aren't compatible with pre-built libraries" # else # define BOOST_LIB_RT_OPT "-spn" # endif # else # if defined(_DEBUG)\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-sgyd" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-sgd" # else # define BOOST_LIB_RT_OPT "-s" # endif # endif # endif #elif defined(__BORLANDC__) // // figure out whether we want the debug builds or not: // #if __BORLANDC__ > 0x561 #pragma defineonoption BOOST_BORLAND_DEBUG -v #endif // // sanity check: // #if defined(__STL_DEBUG) || defined(_STLP_DEBUG) #error "Pre-built versions of the Boost libraries are not provided in STLport-debug form" #endif # ifdef _RTLDLL # if defined(BOOST_BORLAND_DEBUG)\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-yd" # elif defined(BOOST_BORLAND_DEBUG) # define BOOST_LIB_RT_OPT "-d" # elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT -y # else # define BOOST_LIB_RT_OPT # endif # else # if defined(BOOST_BORLAND_DEBUG)\ && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-syd" # elif defined(BOOST_BORLAND_DEBUG) # define BOOST_LIB_RT_OPT "-sd" # elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-sy" # else # define BOOST_LIB_RT_OPT "-s" # endif # endif #endif // // select linkage opt: // #if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) # define BOOST_LIB_PREFIX #elif defined(BOOST_DYN_LINK) # error "Mixing a dll boost library with a static runtime is a really bad idea..." #else # define BOOST_LIB_PREFIX "lib" #endif // // now include the lib: // #if defined(BOOST_LIB_NAME) \ && defined(BOOST_LIB_PREFIX) \ && defined(BOOST_LIB_TOOLSET) \ && defined(BOOST_LIB_THREAD_OPT) \ && defined(BOOST_LIB_RT_OPT) \ && defined(BOOST_LIB_VERSION) #ifdef BOOST_AUTO_LINK_TAGGED # pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib") # ifdef BOOST_LIB_DIAGNOSTIC # pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib") # endif #elif defined(BOOST_AUTO_LINK_NOMANGLE) # pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") # ifdef BOOST_LIB_DIAGNOSTIC # pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") # endif #elif defined(BOOST_LIB_BUILDID) # pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) ".lib") # ifdef BOOST_LIB_DIAGNOSTIC # pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) ".lib") # endif #else # pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") # ifdef BOOST_LIB_DIAGNOSTIC # pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") # endif #endif #else # error "some required macros where not defined (internal logic error)." #endif #endif // _MSC_VER || __BORLANDC__ // // finally undef any macros we may have set: // #ifdef BOOST_LIB_PREFIX # undef BOOST_LIB_PREFIX #endif #if defined(BOOST_LIB_NAME) # undef BOOST_LIB_NAME #endif // Don't undef this one: it can be set by the user and should be the // same for all libraries: //#if defined(BOOST_LIB_TOOLSET) //# undef BOOST_LIB_TOOLSET //#endif #if defined(BOOST_LIB_THREAD_OPT) # undef BOOST_LIB_THREAD_OPT #endif #if defined(BOOST_LIB_RT_OPT) # undef BOOST_LIB_RT_OPT #endif #if defined(BOOST_LIB_LINK_OPT) # undef BOOST_LIB_LINK_OPT #endif #if defined(BOOST_LIB_DEBUG_OPT) # undef BOOST_LIB_DEBUG_OPT #endif #if defined(BOOST_DYN_LINK) # undef BOOST_DYN_LINK #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/borland.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright David Abrahams 2002 - 2003. // (C) Copyright Aleksey Gurtovoy 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Borland C++ compiler setup: // // versions check: // we don't support Borland prior to version 5.4: #if __BORLANDC__ < 0x540 # error "Compiler not supported or configured - please reconfigure" #endif // last known compiler version: #if (__BORLANDC__ > 0x613) //# if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" //# else //# pragma message( "Unknown compiler version - please run the configure tests and report the results") //# endif #elif (__BORLANDC__ == 0x600) # error "CBuilderX preview compiler is no longer supported" #endif // // Support macros to help with standard library detection #if (__BORLANDC__ < 0x560) || defined(_USE_OLD_RW_STL) # define BOOST_BCB_WITH_ROGUE_WAVE #elif __BORLANDC__ < 0x570 # define BOOST_BCB_WITH_STLPORT #else # define BOOST_BCB_WITH_DINKUMWARE #endif // // Version 5.0 and below: # if __BORLANDC__ <= 0x0550 // Borland C++Builder 4 and 5: # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS # if __BORLANDC__ == 0x0550 // Borland C++Builder 5, command-line compiler 5.5: # define BOOST_NO_OPERATORS_IN_NAMESPACE # endif // Variadic macros do not exist for C++ Builder versions 5 and below #define BOOST_NO_CXX11_VARIADIC_MACROS # endif // Version 5.51 and below: #if (__BORLANDC__ <= 0x551) # define BOOST_NO_CV_SPECIALIZATIONS # define BOOST_NO_CV_VOID_SPECIALIZATIONS # define BOOST_NO_DEDUCED_TYPENAME // workaround for missing WCHAR_MAX/WCHAR_MIN: #ifdef __cplusplus #include #include #else #include #include #endif // __cplusplus #ifndef WCHAR_MAX # define WCHAR_MAX 0xffff #endif #ifndef WCHAR_MIN # define WCHAR_MIN 0 #endif #endif // Borland C++ Builder 6 and below: #if (__BORLANDC__ <= 0x564) # if defined(NDEBUG) && defined(__cplusplus) // fix broken so that Boost.test works: # include # undef strcmp # endif // fix broken errno declaration: # include # ifndef errno # define errno errno # endif #endif // // new bug in 5.61: #if (__BORLANDC__ >= 0x561) && (__BORLANDC__ <= 0x580) // this seems to be needed by the command line compiler, but not the IDE: # define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS #endif // Borland C++ Builder 2006 Update 2 and below: #if (__BORLANDC__ <= 0x582) # define BOOST_NO_SFINAE # define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG # define BOOST_NO_TEMPLATE_TEMPLATES # define BOOST_NO_PRIVATE_IN_AGGREGATE # ifdef _WIN32 # define BOOST_NO_SWPRINTF # elif defined(linux) || defined(__linux__) || defined(__linux) // we should really be able to do without this // but the wcs* functions aren't imported into std:: # define BOOST_NO_STDC_NAMESPACE // _CPPUNWIND doesn't get automatically set for some reason: # pragma defineonoption BOOST_CPPUNWIND -x # endif #endif #if (__BORLANDC__ <= 0x613) // Beman has asked Alisdair for more info // we shouldn't really need this - but too many things choke // without it, this needs more investigation: # define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS # define BOOST_NO_IS_ABSTRACT # define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS # define BOOST_NO_USING_TEMPLATE # define BOOST_SP_NO_SP_CONVERTIBLE // Temporary workaround #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // Borland C++ Builder 2008 and below: # define BOOST_NO_INTEGRAL_INT64_T # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL # define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS # define BOOST_NO_TWO_PHASE_NAME_LOOKUP # define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE # define BOOST_NO_NESTED_FRIENDSHIP # define BOOST_NO_TYPENAME_WITH_CTOR #if (__BORLANDC__ < 0x600) # define BOOST_ILLEGAL_CV_REFERENCES #endif // // Positive Feature detection // // Borland C++ Builder 2008 and below: #if (__BORLANDC__ >= 0x599) # pragma defineonoption BOOST_CODEGEAR_0X_SUPPORT -Ax #endif // // C++0x Macros: // #if !defined( BOOST_CODEGEAR_0X_SUPPORT ) || (__BORLANDC__ < 0x610) # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T # define BOOST_NO_CXX11_DECLTYPE # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_EXTERN_TEMPLATE # define BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_NO_CXX11_SCOPED_ENUMS # define BOOST_NO_CXX11_STATIC_ASSERT #else # define BOOST_HAS_ALIGNOF # define BOOST_HAS_CHAR16_T # define BOOST_HAS_CHAR32_T # define BOOST_HAS_DECLTYPE # define BOOST_HAS_EXPLICIT_CONVERSION_OPS # define BOOST_HAS_REF_QUALIFIER # define BOOST_HAS_RVALUE_REFS # define BOOST_HAS_STATIC_ASSERT #endif #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS // UTF-8 still not supported #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #if __BORLANDC__ >= 0x590 # define BOOST_HAS_TR1_HASH # define BOOST_HAS_MACRO_USE_FACET #endif // // Post 0x561 we have long long and stdint.h: #if __BORLANDC__ >= 0x561 # ifndef __NO_LONG_LONG # define BOOST_HAS_LONG_LONG # else # define BOOST_NO_LONG_LONG # endif // On non-Win32 platforms let the platform config figure this out: # ifdef _WIN32 # define BOOST_HAS_STDINT_H # endif #endif // Borland C++Builder 6 defaults to using STLPort. If _USE_OLD_RW_STL is // defined, then we have 0x560 or greater with the Rogue Wave implementation // which presumably has the std::DBL_MAX bug. #if defined( BOOST_BCB_WITH_ROGUE_WAVE ) // is partly broken, some macros define symbols that are really in // namespace std, so you end up having to use illegal constructs like // std::DBL_MAX, as a fix we'll just include float.h and have done with: #include #endif // // __int64: // #if (__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__) # define BOOST_HAS_MS_INT64 #endif // // check for exception handling support: // #if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif // // all versions have a : // #ifndef __STRICT_ANSI__ # define BOOST_HAS_DIRENT_H #endif // // all versions support __declspec: // #if defined(__STRICT_ANSI__) // config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined # define BOOST_SYMBOL_EXPORT #endif // // ABI fixing headers: // #if __BORLANDC__ != 0x600 // not implemented for version 6 compiler yet #ifndef BOOST_ABI_PREFIX # define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" #endif #ifndef BOOST_ABI_SUFFIX # define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" #endif #endif // // Disable Win32 support in ANSI mode: // #if __BORLANDC__ < 0x600 # pragma defineonoption BOOST_DISABLE_WIN32 -A #elif defined(__STRICT_ANSI__) # define BOOST_DISABLE_WIN32 #endif // // MSVC compatibility mode does some nasty things: // TODO: look up if this doesn't apply to the whole 12xx range // #if defined(_MSC_VER) && (_MSC_VER <= 1200) # define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP # define BOOST_NO_VOID_RETURNS #endif // Borland did not implement value-initialization completely, as I reported // in 2007, Borland Report 51854, "Value-initialization: POD struct should be // zero-initialized", http://qc.embarcadero.com/wc/qcmain.aspx?d=51854 // See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues // (Niels Dekker, LKEB, April 2010) #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/clang.hpp ================================================ // (C) Copyright Douglas Gregor 2010 // // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Clang compiler setup. #define BOOST_HAS_PRAGMA_ONCE // Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used. #if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) # define BOOST_HAS_PRAGMA_DETECT_MISMATCH #endif // When compiling with clang before __has_extension was defined, // even if one writes 'defined(__has_extension) && __has_extension(xxx)', // clang reports a compiler error. So the only workaround found is: #ifndef __has_extension #define __has_extension __has_feature #endif #ifndef __has_attribute #define __has_attribute(x) 0 #endif #if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif #if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI) # define BOOST_NO_RTTI #endif #if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID) # define BOOST_NO_TYPEID #endif #if defined(__int64) && !defined(__GNUC__) # define BOOST_HAS_MS_INT64 #endif #define BOOST_HAS_NRVO // Branch prediction hints #if defined(__has_builtin) #if __has_builtin(__builtin_expect) #define BOOST_LIKELY(x) __builtin_expect(x, 1) #define BOOST_UNLIKELY(x) __builtin_expect(x, 0) #endif #endif // Clang supports "long long" in all compilation modes. #define BOOST_HAS_LONG_LONG // // We disable this if the compiler is really nvcc as it // doesn't actually support __int128 as of CUDA_VERSION=5000 // even though it defines __SIZEOF_INT128__. // See https://svn.boost.org/trac/boost/ticket/10418 // Only re-enable this for nvcc if you're absolutely sure // of the circumstances under which it's supported. // Similarly __SIZEOF_INT128__ is defined when targetting msvc // compatibility even though the required support functions are absent. // #if defined(__SIZEOF_INT128__) && !defined(__CUDACC__) && !defined(_MSC_VER) # define BOOST_HAS_INT128 #endif // // Dynamic shared object (DSO) and dynamic-link library (DLL) support // #if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) # define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) # define BOOST_SYMBOL_IMPORT # define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) #endif // // The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through // between switch labels. // #if __cplusplus >= 201103L && defined(__has_warning) # if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") # define BOOST_FALLTHROUGH [[clang::fallthrough]] # endif #endif #if !__has_feature(cxx_auto_type) # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #endif // // Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t // #if defined(_MSC_VER) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T #endif #if !__has_feature(cxx_constexpr) # define BOOST_NO_CXX11_CONSTEXPR #endif #if !__has_feature(cxx_decltype) # define BOOST_NO_CXX11_DECLTYPE #endif #if !__has_feature(cxx_decltype_incomplete_return_types) # define BOOST_NO_CXX11_DECLTYPE_N3276 #endif #if !__has_feature(cxx_defaulted_functions) # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #endif #if !__has_feature(cxx_deleted_functions) # define BOOST_NO_CXX11_DELETED_FUNCTIONS #endif #if !__has_feature(cxx_explicit_conversions) # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #endif #if !__has_feature(cxx_default_function_template_args) # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #endif #if !__has_feature(cxx_generalized_initializers) # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #endif #if !__has_feature(cxx_lambdas) # define BOOST_NO_CXX11_LAMBDAS #endif #if !__has_feature(cxx_local_type_template_args) # define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #endif #if !__has_feature(cxx_noexcept) # define BOOST_NO_CXX11_NOEXCEPT #endif #if !__has_feature(cxx_nullptr) # define BOOST_NO_CXX11_NULLPTR #endif #if !__has_feature(cxx_range_for) # define BOOST_NO_CXX11_RANGE_BASED_FOR #endif #if !__has_feature(cxx_raw_string_literals) # define BOOST_NO_CXX11_RAW_LITERALS #endif #if !__has_feature(cxx_reference_qualified_functions) # define BOOST_NO_CXX11_REF_QUALIFIERS #endif #if !__has_feature(cxx_generalized_initializers) # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #endif #if !__has_feature(cxx_rvalue_references) # define BOOST_NO_CXX11_RVALUE_REFERENCES #endif #if !__has_feature(cxx_strong_enums) # define BOOST_NO_CXX11_SCOPED_ENUMS #endif #if !__has_feature(cxx_static_assert) # define BOOST_NO_CXX11_STATIC_ASSERT #endif #if !__has_feature(cxx_alias_templates) # define BOOST_NO_CXX11_TEMPLATE_ALIASES #endif #if !__has_feature(cxx_unicode_literals) # define BOOST_NO_CXX11_UNICODE_LITERALS #endif #if !__has_feature(cxx_variadic_templates) # define BOOST_NO_CXX11_VARIADIC_TEMPLATES #endif #if !__has_feature(cxx_user_literals) # define BOOST_NO_CXX11_USER_DEFINED_LITERALS #endif #if !__has_feature(cxx_alignas) # define BOOST_NO_CXX11_ALIGNAS #endif #if !__has_feature(cxx_trailing_return) # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #endif #if !__has_feature(cxx_inline_namespaces) # define BOOST_NO_CXX11_INLINE_NAMESPACES #endif #if !__has_feature(cxx_override_control) # define BOOST_NO_CXX11_FINAL #endif #if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__)) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !__has_feature(__cxx_decltype_auto__) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if !__has_feature(__cxx_aggregate_nsdmi__) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !__has_feature(__cxx_init_captures__) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !__has_feature(__cxx_generic_lambdas__) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif // clang < 3.5 has a defect with dependent type, like following. // // template // constexpr typename enable_if >::type foo(T &) // { } // error: no return statement in constexpr function // // This issue also affects C++11 mode, but C++11 constexpr requires return stmt. // Therefore we don't care such case. // // Note that we can't check Clang version directly as the numbering system changes depending who's // creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873) // so instead verify that we have a feature that was introduced at the same time as working C++14 // constexpr (generic lambda's in this case): // #if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !__has_feature(__cxx_return_type_deduction__) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !__has_feature(__cxx_variable_templates__) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #if __cplusplus < 201400 // All versions with __cplusplus above this value seem to support this: # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif // // __builtin_unreachable: #if defined(__has_builtin) && __has_builtin(__builtin_unreachable) #define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); #endif // Clang has supported the 'unused' attribute since the first release. #define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) #ifndef BOOST_COMPILER # define BOOST_COMPILER "Clang version " __clang_version__ #endif // Macro used to identify the Clang compiler. #define BOOST_CLANG 1 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/codegear.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright David Abrahams 2002 - 2003. // (C) Copyright Aleksey Gurtovoy 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // CodeGear C++ compiler setup: #if !defined( BOOST_WITH_CODEGEAR_WARNINGS ) // these warnings occur frequently in optimized template code # pragma warn -8004 // var assigned value, but never used # pragma warn -8008 // condition always true/false # pragma warn -8066 // dead code can never execute # pragma warn -8104 // static members with ctors not threadsafe # pragma warn -8105 // reference member in class without ctors #endif // // versions check: // last known and checked version is 0x621 #if (__CODEGEARC__ > 0x621) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # else # pragma message( "Unknown compiler version - please run the configure tests and report the results") # endif #endif // CodeGear C++ Builder 2009 #if (__CODEGEARC__ <= 0x613) # define BOOST_NO_INTEGRAL_INT64_T # define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS # define BOOST_NO_PRIVATE_IN_AGGREGATE # define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE // we shouldn't really need this - but too many things choke // without it, this needs more investigation: # define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS # define BOOST_SP_NO_SP_CONVERTIBLE #endif // CodeGear C++ Builder 2010 #if (__CODEGEARC__ <= 0x621) # define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS # define BOOST_NO_NESTED_FRIENDSHIP // TC1 gives nested classes access rights as any other member # define BOOST_NO_USING_TEMPLATE # define BOOST_NO_TWO_PHASE_NAME_LOOKUP // Temporary hack, until specific MPL preprocessed headers are generated # define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS // CodeGear has not yet completely implemented value-initialization, for // example for array types, as I reported in 2010: Embarcadero Report 83751, // "Value-initialization: arrays should have each element value-initialized", // http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 // Last checked version: Embarcadero C++ 6.21 // See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues // (Niels Dekker, LKEB, April 2010) # define BOOST_NO_COMPLETE_VALUE_INITIALIZATION # if defined(NDEBUG) && defined(__cplusplus) // fix broken so that Boost.test works: # include # undef strcmp # endif // fix broken errno declaration: # include # ifndef errno # define errno errno # endif #endif // Reportedly, #pragma once is supported since C++ Builder 2010 #if (__CODEGEARC__ >= 0x620) # define BOOST_HAS_PRAGMA_ONCE #endif // // C++0x macros: // #if (__CODEGEARC__ <= 0x620) #define BOOST_NO_CXX11_STATIC_ASSERT #else #define BOOST_HAS_STATIC_ASSERT #endif #define BOOST_HAS_CHAR16_T #define BOOST_HAS_CHAR32_T #define BOOST_HAS_LONG_LONG // #define BOOST_HAS_ALIGNOF #define BOOST_HAS_DECLTYPE #define BOOST_HAS_EXPLICIT_CONVERSION_OPS // #define BOOST_HAS_RVALUE_REFS #define BOOST_HAS_SCOPED_ENUM // #define BOOST_HAS_STATIC_ASSERT #define BOOST_HAS_STD_TYPE_TRAITS #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif // // TR1 macros: // #define BOOST_HAS_TR1_HASH #define BOOST_HAS_TR1_TYPE_TRAITS #define BOOST_HAS_TR1_UNORDERED_MAP #define BOOST_HAS_TR1_UNORDERED_SET #define BOOST_HAS_MACRO_USE_FACET #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST // On non-Win32 platforms let the platform config figure this out: #ifdef _WIN32 # define BOOST_HAS_STDINT_H #endif // // __int64: // #if !defined(__STRICT_ANSI__) # define BOOST_HAS_MS_INT64 #endif // // check for exception handling support: // #if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif // // all versions have a : // #if !defined(__STRICT_ANSI__) # define BOOST_HAS_DIRENT_H #endif // // all versions support __declspec: // #if defined(__STRICT_ANSI__) // config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined # define BOOST_SYMBOL_EXPORT #endif // // ABI fixing headers: // #ifndef BOOST_ABI_PREFIX # define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" #endif #ifndef BOOST_ABI_SUFFIX # define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" #endif // // Disable Win32 support in ANSI mode: // # pragma defineonoption BOOST_DISABLE_WIN32 -A // // MSVC compatibility mode does some nasty things: // TODO: look up if this doesn't apply to the whole 12xx range // #if defined(_MSC_VER) && (_MSC_VER <= 1200) # define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP # define BOOST_NO_VOID_RETURNS #endif #define BOOST_COMPILER "CodeGear C++ version " BOOST_STRINGIZE(__CODEGEARC__) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/comeau.hpp ================================================ // (C) Copyright John Maddock 2001. // (C) Copyright Douglas Gregor 2001. // (C) Copyright Peter Dimov 2001. // (C) Copyright Aleksey Gurtovoy 2003. // (C) Copyright Beman Dawes 2003. // (C) Copyright Jens Maurer 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Comeau C++ compiler setup: #include "boost/config/compiler/common_edg.hpp" #if (__COMO_VERSION__ <= 4245) # if defined(_MSC_VER) && _MSC_VER <= 1300 # if _MSC_VER > 100 // only set this in non-strict mode: # define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP # endif # endif // Void returns don't work when emulating VC 6 (Peter Dimov) // TODO: look up if this doesn't apply to the whole 12xx range # if defined(_MSC_VER) && (_MSC_VER < 1300) # define BOOST_NO_VOID_RETURNS # endif #endif // version 4245 // // enable __int64 support in VC emulation mode // # if defined(_MSC_VER) && (_MSC_VER >= 1200) # define BOOST_HAS_MS_INT64 # endif #define BOOST_COMPILER "Comeau compiler version " BOOST_STRINGIZE(__COMO_VERSION__) // // versions check: // we don't know Comeau prior to version 4245: #if __COMO_VERSION__ < 4245 # error "Compiler not configured - please reconfigure" #endif // // last known and checked version is 4245: #if (__COMO_VERSION__ > 4245) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/common_edg.hpp ================================================ // (C) Copyright John Maddock 2001 - 2002. // (C) Copyright Jens Maurer 2001. // (C) Copyright David Abrahams 2002. // (C) Copyright Aleksey Gurtovoy 2002. // (C) Copyright Markus Schoepflin 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // // Options common to all edg based compilers. // // This is included from within the individual compiler mini-configs. #ifndef __EDG_VERSION__ # error This file requires that __EDG_VERSION__ be defined. #endif #if (__EDG_VERSION__ <= 238) # define BOOST_NO_INTEGRAL_INT64_T # define BOOST_NO_SFINAE #endif #if (__EDG_VERSION__ <= 240) # define BOOST_NO_VOID_RETURNS #endif #if (__EDG_VERSION__ <= 241) && !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) # define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP #endif #if (__EDG_VERSION__ <= 244) && !defined(BOOST_NO_TEMPLATE_TEMPLATES) # define BOOST_NO_TEMPLATE_TEMPLATES #endif #if (__EDG_VERSION__ < 300) && !defined(BOOST_NO_IS_ABSTRACT) # define BOOST_NO_IS_ABSTRACT #endif #if (__EDG_VERSION__ <= 303) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL #endif // See also kai.hpp which checks a Kai-specific symbol for EH # if !defined(__KCC) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS # endif # if !defined(__NO_LONG_LONG) # define BOOST_HAS_LONG_LONG # else # define BOOST_NO_LONG_LONG # endif // Not sure what version was the first to support #pragma once, but // different EDG-based compilers (e.g. Intel) supported it for ages. // Add a proper version check if it causes problems. #define BOOST_HAS_PRAGMA_ONCE // // C++0x features // // See above for BOOST_NO_LONG_LONG // #if (__EDG_VERSION__ < 310) # define BOOST_NO_CXX11_EXTERN_TEMPLATE #endif #if (__EDG_VERSION__ <= 310) // No support for initializer lists # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #endif #if (__EDG_VERSION__ < 400) # define BOOST_NO_CXX11_VARIADIC_MACROS #endif #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #ifdef c_plusplus // EDG has "long long" in non-strict mode // However, some libraries have insufficient "long long" support // #define BOOST_HAS_LONG_LONG #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/compaq_cxx.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Tru64 C++ compiler setup (now HP): #define BOOST_COMPILER "HP Tru64 C++ " BOOST_STRINGIZE(__DECCXX_VER) #include "boost/config/compiler/common_edg.hpp" // // versions check: // Nothing to do here? ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/cray.hpp ================================================ // (C) Copyright John Maddock 2011. // (C) Copyright Cray, Inc. 2013 // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Greenhills C compiler setup: #define BOOST_COMPILER "Cray C version " BOOST_STRINGIZE(_RELEASE) #if _RELEASE < 8 # error "Boost is not configured for Cray compilers prior to version 8, please try the configure script." #endif // // Check this is a recent EDG based compiler, otherwise we don't support it here: // #ifndef __EDG_VERSION__ # error "Unsupported Cray compiler, please try running the configure script." #endif #include "boost/config/compiler/common_edg.hpp" // // #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_HAS_NRVO #define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #define BOOST_HAS_NRVO #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL //#define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG #define BOOST_MATH_DISABLE_STD_FPCLASSIFY //#define BOOST_HAS_FPCLASSIFY #define BOOST_SP_USE_PTHREADS #define BOOST_AC_USE_PTHREADS /* everything that follows is working around what are thought to be * compiler shortcomings. Revist all of these regularly. */ //#define BOOST_USE_ENUM_STATIC_ASSERT //#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS //(this may be implied by the previous #define // These constants should be provided by the // compiler, at least when -hgnu is asserted on the command line. #ifndef __ATOMIC_RELAXED #define __ATOMIC_RELAXED 0 #define __ATOMIC_CONSUME 1 #define __ATOMIC_ACQUIRE 2 #define __ATOMIC_RELEASE 3 #define __ATOMIC_ACQ_REL 4 #define __ATOMIC_SEQ_CST 5 #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/digitalmars.hpp ================================================ // Copyright (C) Christof Meerwald 2003 // Copyright (C) Dan Watkins 2003 // // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // Digital Mars C++ compiler setup: #define BOOST_COMPILER __DMC_VERSION_STRING__ #define BOOST_HAS_LONG_LONG #define BOOST_HAS_PRAGMA_ONCE #if !defined(BOOST_STRICT_CONFIG) #define BOOST_NO_MEMBER_TEMPLATE_FRIENDS #define BOOST_NO_OPERATORS_IN_NAMESPACE #define BOOST_NO_UNREACHABLE_RETURN_DETECTION #define BOOST_NO_SFINAE #define BOOST_NO_USING_TEMPLATE #define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL #endif // // has macros: #define BOOST_HAS_DIRENT_H #define BOOST_HAS_STDINT_H #define BOOST_HAS_WINTHREADS #if (__DMC__ >= 0x847) #define BOOST_HAS_EXPM1 #define BOOST_HAS_LOG1P #endif // // Is this really the best way to detect whether the std lib is in namespace std? // #ifdef __cplusplus #include #endif #if !defined(__STL_IMPORT_VENDOR_CSTD) && !defined(_STLP_IMPORT_VENDOR_CSTD) # define BOOST_NO_STDC_NAMESPACE #endif // check for exception handling support: #if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif // // C++0x features // #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #if (__DMC__ <= 0x840) #error "Compiler not supported or configured - please reconfigure" #endif // // last known and checked version is ...: #if (__DMC__ > 0x848) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/gcc.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Darin Adler 2001 - 2002. // (C) Copyright Jens Maurer 2001 - 2002. // (C) Copyright Beman Dawes 2001 - 2003. // (C) Copyright Douglas Gregor 2002. // (C) Copyright David Abrahams 2002 - 2003. // (C) Copyright Synge Todo 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // GNU C++ compiler setup. // // Define BOOST_GCC so we know this is "real" GCC and not some pretender: // #define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #if !defined(__CUDACC__) #define BOOST_GCC BOOST_GCC_VERSION #endif #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) # define BOOST_GCC_CXX11 #endif #if __GNUC__ == 3 # if defined (__PATHSCALE__) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP # define BOOST_NO_IS_ABSTRACT # endif # if __GNUC_MINOR__ < 4 # define BOOST_NO_IS_ABSTRACT # endif # define BOOST_NO_CXX11_EXTERN_TEMPLATE #endif #if __GNUC__ < 4 // // All problems to gcc-3.x and earlier here: // #define BOOST_NO_TWO_PHASE_NAME_LOOKUP # ifdef __OPEN64__ # define BOOST_NO_IS_ABSTRACT # endif #endif // GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links #if BOOST_GCC_VERSION >= 30400 #define BOOST_HAS_PRAGMA_ONCE #endif #if BOOST_GCC_VERSION < 40400 // Previous versions of GCC did not completely implement value-initialization: // GCC Bug 30111, "Value-initialization of POD base class doesn't initialize // members", reported by Jonathan Wakely in 2006, // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4) // GCC Bug 33916, "Default constructor fails to initialize array members", // reported by Michael Elizabeth Chastain in 2007, // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4) // See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #endif #if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif // // Threading support: Turn this on unconditionally here (except for // those platforms where we can know for sure). It will get turned off again // later if no threading API is detected. // #if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__) # define BOOST_HAS_THREADS #endif // // gcc has "long long" // Except on Darwin with standard compliance enabled (-pedantic) // Apple gcc helpfully defines this macro we can query // #if !defined(__DARWIN_NO_LONG_LONG) # define BOOST_HAS_LONG_LONG #endif // // gcc implements the named return value optimization since version 3.1 // #define BOOST_HAS_NRVO // Branch prediction hints #define BOOST_LIKELY(x) __builtin_expect(x, 1) #define BOOST_UNLIKELY(x) __builtin_expect(x, 0) // // Dynamic shared object (DSO) and dynamic-link library (DLL) support // #if __GNUC__ >= 4 # if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(__CYGWIN__) // All Win32 development environments, including 64-bit Windows and MinGW, define // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, // so does not define _WIN32 or its variants. # define BOOST_HAS_DECLSPEC # define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) # define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) # else # define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) # define BOOST_SYMBOL_IMPORT # endif # define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) #else // config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined # define BOOST_SYMBOL_EXPORT #endif // // RTTI and typeinfo detection is possible post gcc-4.3: // #if BOOST_GCC_VERSION > 40300 # ifndef __GXX_RTTI # ifndef BOOST_NO_TYPEID # define BOOST_NO_TYPEID # endif # ifndef BOOST_NO_RTTI # define BOOST_NO_RTTI # endif # endif #endif // // Recent GCC versions have __int128 when in 64-bit mode. // // We disable this if the compiler is really nvcc as it // doesn't actually support __int128 as of CUDA_VERSION=5000 // even though it defines __SIZEOF_INT128__. // See https://svn.boost.org/trac/boost/ticket/8048 // Only re-enable this for nvcc if you're absolutely sure // of the circumstances under which it's supported: // #if defined(__SIZEOF_INT128__) && !defined(__CUDACC__) # define BOOST_HAS_INT128 #endif // // Recent GCC versions have a __float128 native type, we need to // include a std lib header to detect this - not ideal, but we'll // be including later anyway when we select the std lib. // #ifdef __cplusplus #include #else #include #endif #if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__) # define BOOST_HAS_FLOAT128 #endif // C++0x features in 4.3.n and later // #if (BOOST_GCC_VERSION >= 40300) && defined(BOOST_GCC_CXX11) // C++0x features are only enabled when -std=c++0x or -std=gnu++0x are // passed on the command line, which in turn defines // __GXX_EXPERIMENTAL_CXX0X__. # define BOOST_HAS_DECLTYPE # define BOOST_HAS_RVALUE_REFS # define BOOST_HAS_STATIC_ASSERT # define BOOST_HAS_VARIADIC_TMPL #else # define BOOST_NO_CXX11_DECLTYPE # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS # define BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_NO_CXX11_STATIC_ASSERT #endif // C++0x features in 4.4.n and later // #if (BOOST_GCC_VERSION < 40400) || !defined(BOOST_GCC_CXX11) # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES # define BOOST_NO_CXX11_INLINE_NAMESPACES # define BOOST_NO_CXX11_VARIADIC_TEMPLATES #endif #if BOOST_GCC_VERSION < 40500 # define BOOST_NO_SFINAE_EXPR #endif // GCC 4.5 forbids declaration of defaulted functions in private or protected sections #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 5) || !defined(BOOST_GCC_CXX11) # define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS #endif // C++0x features in 4.5.0 and later // #if (BOOST_GCC_VERSION < 40500) || !defined(BOOST_GCC_CXX11) # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_LAMBDAS # define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS # define BOOST_NO_CXX11_RAW_LITERALS # define BOOST_NO_CXX11_UNICODE_LITERALS #endif // C++0x features in 4.5.1 and later // #if (BOOST_GCC_VERSION < 40501) || !defined(BOOST_GCC_CXX11) // scoped enums have a serious bug in 4.4.0, so define BOOST_NO_CXX11_SCOPED_ENUMS before 4.5.1 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064 # define BOOST_NO_CXX11_SCOPED_ENUMS #endif // C++0x features in 4.6.n and later // #if (BOOST_GCC_VERSION < 40600) || !defined(BOOST_GCC_CXX11) #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #endif // C++0x features in 4.7.n and later // #if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11) # define BOOST_NO_CXX11_FINAL # define BOOST_NO_CXX11_TEMPLATE_ALIASES # define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS #endif // C++0x features in 4.8.n and later // #if (BOOST_GCC_VERSION < 40800) || !defined(BOOST_GCC_CXX11) # define BOOST_NO_CXX11_ALIGNAS #endif // C++0x features in 4.8.1 and later // #if (BOOST_GCC_VERSION < 40801) || !defined(BOOST_GCC_CXX11) # define BOOST_NO_CXX11_DECLTYPE_N3276 # define BOOST_NO_CXX11_REF_QUALIFIERS # define BOOST_NO_CXX14_BINARY_LITERALS #endif // C++14 features in 4.9.0 and later // #if (BOOST_GCC_VERSION < 40900) || (__cplusplus < 201300) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION # define BOOST_NO_CXX14_GENERIC_LAMBDAS # define BOOST_NO_CXX14_DIGIT_SEPARATORS # define BOOST_NO_CXX14_DECLTYPE_AUTO # if !((BOOST_GCC_VERSION >= 40801) && (BOOST_GCC_VERSION < 40900) && defined(BOOST_GCC_CXX11)) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES # endif #endif // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif // // Unused attribute: #if __GNUC__ >= 4 # define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) #endif // // __builtin_unreachable: #if BOOST_GCC_VERSION >= 40800 #define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); #endif #ifndef BOOST_COMPILER # define BOOST_COMPILER "GNU C++ version " __VERSION__ #endif // ConceptGCC compiler: // http://www.generic-programming.org/software/ConceptGCC/ #ifdef __GXX_CONCEPTS__ # define BOOST_HAS_CONCEPTS # define BOOST_COMPILER "ConceptGCC version " __VERSION__ #endif // versions check: // we don't know gcc prior to version 3.30: #if (BOOST_GCC_VERSION< 30300) # error "Compiler not configured - please reconfigure" #endif // // last known and checked version is 4.9: #if (BOOST_GCC_VERSION > 40900) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # else // we don't emit warnings here anymore since there are no defect macros defined for // gcc post 3.4, so any failures are gcc regressions... //# warning "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/gcc_xml.hpp ================================================ // (C) Copyright John Maddock 2006. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // GCC-XML C++ compiler setup: # if !defined(__GCCXML_GNUC__) || ((__GCCXML_GNUC__ <= 3) && (__GCCXML_GNUC_MINOR__ <= 3)) # define BOOST_NO_IS_ABSTRACT # endif // // Threading support: Turn this on unconditionally here (except for // those platforms where we can know for sure). It will get turned off again // later if no threading API is detected. // #if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(linux) && !defined(__linux) && !defined(__linux__) # define BOOST_HAS_THREADS #endif // // gcc has "long long" // #define BOOST_HAS_LONG_LONG // C++0x features: // # define BOOST_NO_CXX11_CONSTEXPR # define BOOST_NO_CXX11_NULLPTR # define BOOST_NO_CXX11_TEMPLATE_ALIASES # define BOOST_NO_CXX11_DECLTYPE # define BOOST_NO_CXX11_DECLTYPE_N3276 # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS # define BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_NO_CXX11_STATIC_ASSERT # define BOOST_NO_CXX11_VARIADIC_TEMPLATES # define BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_SCOPED_ENUMS # define BOOST_NO_SFINAE_EXPR # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_LAMBDAS # define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS # define BOOST_NO_CXX11_RANGE_BASED_FOR # define BOOST_NO_CXX11_RAW_LITERALS # define BOOST_NO_CXX11_UNICODE_LITERALS # define BOOST_NO_CXX11_NOEXCEPT # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX # define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_ALIGNAS # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES # define BOOST_NO_CXX11_INLINE_NAMESPACES # define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/greenhills.hpp ================================================ // (C) Copyright John Maddock 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Greenhills C++ compiler setup: #define BOOST_COMPILER "Greenhills C++ version " BOOST_STRINGIZE(__ghs) #include "boost/config/compiler/common_edg.hpp" // // versions check: // we don't support Greenhills prior to version 0: #if __ghs < 0 # error "Compiler not supported or configured - please reconfigure" #endif // // last known and checked version is 0: #if (__ghs > 0) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/hp_acc.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001 - 2003. // (C) Copyright Aleksey Gurtovoy 2002. // (C) Copyright David Abrahams 2002 - 2003. // (C) Copyright Toon Knapen 2003. // (C) Copyright Boris Gubenko 2006 - 2007. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // HP aCC C++ compiler setup: #if defined(__EDG__) #include "boost/config/compiler/common_edg.hpp" #endif #if (__HP_aCC <= 33100) # define BOOST_NO_INTEGRAL_INT64_T # define BOOST_NO_OPERATORS_IN_NAMESPACE # if !defined(_NAMESPACE_STD) # define BOOST_NO_STD_LOCALE # define BOOST_NO_STRINGSTREAM # endif #endif #if (__HP_aCC <= 33300) // member templates are sufficiently broken that we disable them for now # define BOOST_NO_MEMBER_TEMPLATES # define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS # define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE #endif #if (__HP_aCC <= 38000) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP #endif #if (__HP_aCC > 50000) && (__HP_aCC < 60000) # define BOOST_NO_UNREACHABLE_RETURN_DETECTION # define BOOST_NO_TEMPLATE_TEMPLATES # define BOOST_NO_SWPRINTF # define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS # define BOOST_NO_IS_ABSTRACT # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS #endif // optional features rather than defects: #if (__HP_aCC >= 33900) # define BOOST_HAS_LONG_LONG # define BOOST_HAS_PARTIAL_STD_ALLOCATOR #endif #if (__HP_aCC >= 50000 ) && (__HP_aCC <= 53800 ) || (__HP_aCC < 31300 ) # define BOOST_NO_MEMBER_TEMPLATE_KEYWORD #endif // This macro should not be defined when compiling in strict ansi // mode, but, currently, we don't have the ability to determine // what standard mode we are compiling with. Some future version // of aCC6 compiler will provide predefined macros reflecting the // compilation options, including the standard mode. #if (__HP_aCC >= 60000) || ((__HP_aCC > 38000) && defined(__hpxstd98)) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP #endif #define BOOST_COMPILER "HP aCC version " BOOST_STRINGIZE(__HP_aCC) // // versions check: // we don't support HP aCC prior to version 33000: #if __HP_aCC < 33000 # error "Compiler not supported or configured - please reconfigure" #endif // // Extended checks for supporting aCC on PA-RISC #if __HP_aCC > 30000 && __HP_aCC < 50000 # if __HP_aCC < 38000 // versions prior to version A.03.80 not supported # error "Compiler version not supported - version A.03.80 or higher is required" # elif !defined(__hpxstd98) // must compile using the option +hpxstd98 with version A.03.80 and above # error "Compiler option '+hpxstd98' is required for proper support" # endif //PA-RISC #endif // // C++0x features // // See boost\config\suffix.hpp for BOOST_NO_LONG_LONG // #if !defined(__EDG__) #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS /* See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443436 */ #if (__HP_aCC < 62500) || !defined(HP_CXX0x_SOURCE) #define BOOST_NO_CXX11_VARIADIC_MACROS #endif #endif // // last known and checked version for HP-UX/ia64 is 61300 // last known and checked version for PA-RISC is 38000 #if ((__HP_aCC > 61300) || ((__HP_aCC > 38000) && defined(__hpxstd98))) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/intel.hpp ================================================ // (C) Copyright John Maddock 2001-8. // (C) Copyright Peter Dimov 2001. // (C) Copyright Jens Maurer 2001. // (C) Copyright David Abrahams 2002 - 2003. // (C) Copyright Aleksey Gurtovoy 2002 - 2003. // (C) Copyright Guillaume Melquiond 2002 - 2003. // (C) Copyright Beman Dawes 2003. // (C) Copyright Martin Wille 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Intel compiler setup: #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) #ifdef _MSC_VER #include #undef BOOST_MSVC #undef BOOST_MSVC_FULL_VER #if (__INTEL_COMPILER >= 1500) && (_MSC_VER >= 1900) // // These appear to be supported, even though VC++ may not support them: // #define BOOST_HAS_EXPM1 #define BOOST_HAS_LOG1P #undef BOOST_NO_CXX14_BINARY_LITERALS // This one may be a little risky to enable?? #undef BOOST_NO_SFINAE_EXPR #endif #else #include #undef BOOST_GCC_VERSION #undef BOOST_GCC_CXX11 #endif #undef BOOST_COMPILER #if defined(__INTEL_COMPILER) #if __INTEL_COMPILER == 9999 # define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. #else # define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER #endif #elif defined(__ICL) # define BOOST_INTEL_CXX_VERSION __ICL #elif defined(__ICC) # define BOOST_INTEL_CXX_VERSION __ICC #elif defined(__ECC) # define BOOST_INTEL_CXX_VERSION __ECC #endif // Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' #if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) # define BOOST_INTEL_STDCXX0X #endif #if defined(_MSC_VER) && (_MSC_VER >= 1600) # define BOOST_INTEL_STDCXX0X #endif #ifdef __GNUC__ # define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif #if !defined(BOOST_COMPILER) # if defined(BOOST_INTEL_STDCXX0X) # define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) # else # define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) # endif #endif #define BOOST_INTEL BOOST_INTEL_CXX_VERSION #if defined(_WIN32) || defined(_WIN64) # define BOOST_INTEL_WIN BOOST_INTEL #else # define BOOST_INTEL_LINUX BOOST_INTEL #endif #else #include "boost/config/compiler/common_edg.hpp" #if defined(__INTEL_COMPILER) #if __INTEL_COMPILER == 9999 # define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. #else # define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER #endif #elif defined(__ICL) # define BOOST_INTEL_CXX_VERSION __ICL #elif defined(__ICC) # define BOOST_INTEL_CXX_VERSION __ICC #elif defined(__ECC) # define BOOST_INTEL_CXX_VERSION __ECC #endif // Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' #if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) # define BOOST_INTEL_STDCXX0X #endif #if defined(_MSC_VER) && (_MSC_VER >= 1600) # define BOOST_INTEL_STDCXX0X #endif #ifdef __GNUC__ # define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif #if !defined(BOOST_COMPILER) # if defined(BOOST_INTEL_STDCXX0X) # define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) # else # define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) # endif #endif #define BOOST_INTEL BOOST_INTEL_CXX_VERSION #if defined(_WIN32) || defined(_WIN64) # define BOOST_INTEL_WIN BOOST_INTEL #else # define BOOST_INTEL_LINUX BOOST_INTEL #endif #if (BOOST_INTEL_CXX_VERSION <= 600) # if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) // Boost libraries assume strong standard conformance unless otherwise // indicated by a config macro. As configured by Intel, the EDG front-end // requires certain compiler options be set to achieve that strong conformance. // Particularly /Qoption,c,--arg_dep_lookup (reported by Kirk Klobe & Thomas Witt) // and /Zc:wchar_t,forScope. See boost-root/tools/build/intel-win32-tools.jam for // details as they apply to particular versions of the compiler. When the // compiler does not predefine a macro indicating if an option has been set, // this config file simply assumes the option has been set. // Thus BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP will not be defined, even if // the compiler option is not enabled. # define BOOST_NO_SWPRINTF # endif // Void returns, 64 bit integrals don't work when emulating VC 6 (Peter Dimov) # if defined(_MSC_VER) && (_MSC_VER <= 1200) # define BOOST_NO_VOID_RETURNS # define BOOST_NO_INTEGRAL_INT64_T # endif #endif #if (BOOST_INTEL_CXX_VERSION <= 710) && defined(_WIN32) # define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS #endif // See http://aspn.activestate.com/ASPN/Mail/Message/boost/1614864 #if BOOST_INTEL_CXX_VERSION < 600 # define BOOST_NO_INTRINSIC_WCHAR_T #else // We should test the macro _WCHAR_T_DEFINED to check if the compiler // supports wchar_t natively. *BUT* there is a problem here: the standard // headers define this macro if they typedef wchar_t. Anyway, we're lucky // because they define it without a value, while Intel C++ defines it // to 1. So we can check its value to see if the macro was defined natively // or not. // Under UNIX, the situation is exactly the same, but the macro _WCHAR_T // is used instead. # if ((_WCHAR_T_DEFINED + 0) == 0) && ((_WCHAR_T + 0) == 0) # define BOOST_NO_INTRINSIC_WCHAR_T # endif #endif #if defined(__GNUC__) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) // // Figure out when Intel is emulating this gcc bug // (All Intel versions prior to 9.0.26, and versions // later than that if they are set up to emulate gcc 3.2 // or earlier): // # if ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 2)) || (BOOST_INTEL < 900) || (__INTEL_COMPILER_BUILD_DATE < 20050912) # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL # endif #endif #if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_WIN32) && (BOOST_INTEL_CXX_VERSION <= 1200)) || (BOOST_INTEL_CXX_VERSION <= 1200) // GCC or VC emulation: #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #endif // // Verify that we have actually got BOOST_NO_INTRINSIC_WCHAR_T // set correctly, if we don't do this now, we will get errors later // in type_traits code among other things, getting this correct // for the Intel compiler is actually remarkably fragile and tricky: // #ifdef __cplusplus #if defined(BOOST_NO_INTRINSIC_WCHAR_T) #include template< typename T > struct assert_no_intrinsic_wchar_t; template<> struct assert_no_intrinsic_wchar_t { typedef void type; }; // if you see an error here then you need to unset BOOST_NO_INTRINSIC_WCHAR_T // where it is defined above: typedef assert_no_intrinsic_wchar_t::type assert_no_intrinsic_wchar_t_; #else template< typename T > struct assert_intrinsic_wchar_t; template<> struct assert_intrinsic_wchar_t {}; // if you see an error here then define BOOST_NO_INTRINSIC_WCHAR_T on the command line: template<> struct assert_intrinsic_wchar_t {}; #endif #endif #if defined(_MSC_VER) && (_MSC_VER+0 >= 1000) # if _MSC_VER >= 1200 # define BOOST_HAS_MS_INT64 # endif # define BOOST_NO_SWPRINTF # define BOOST_NO_TWO_PHASE_NAME_LOOKUP #elif defined(_WIN32) # define BOOST_DISABLE_WIN32 #endif // I checked version 6.0 build 020312Z, it implements the NRVO. // Correct this as you find out which version of the compiler // implemented the NRVO first. (Daniel Frey) #if (BOOST_INTEL_CXX_VERSION >= 600) # define BOOST_HAS_NRVO #endif // Branch prediction hints // I'm not sure 8.0 was the first version to support these builtins, // update the condition if the version is not accurate. (Andrey Semashev) #if defined(__GNUC__) && BOOST_INTEL_CXX_VERSION >= 800 #define BOOST_LIKELY(x) __builtin_expect(x, 1) #define BOOST_UNLIKELY(x) __builtin_expect(x, 0) #endif // RTTI // __RTTI is the EDG macro // __INTEL_RTTI__ is the Intel macro // __GXX_RTTI is the g++ macro // _CPPRTTI is the MSVC++ macro #if !defined(__RTTI) && !defined(__INTEL_RTTI__) && !defined(__GXX_RTTI) && !defined(_CPPRTTI) #if !defined(BOOST_NO_RTTI) # define BOOST_NO_RTTI #endif // in MS mode, static typeid works even when RTTI is off #if !defined(_MSC_VER) && !defined(BOOST_NO_TYPEID) # define BOOST_NO_TYPEID #endif #endif // // versions check: // we don't support Intel prior to version 6.0: #if BOOST_INTEL_CXX_VERSION < 600 # error "Compiler not supported or configured - please reconfigure" #endif // Intel on MacOS requires #if defined(__APPLE__) && defined(__INTEL_COMPILER) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP #endif // Intel on Altix Itanium #if defined(__itanium__) && defined(__INTEL_COMPILER) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP #endif // // An attempt to value-initialize a pointer-to-member may trigger an // internal error on Intel <= 11.1 (last checked version), as was // reported by John Maddock, Intel support issue 589832, May 2010. // Moreover, according to test results from Huang-Vista-x86_32_intel, // intel-vc9-win-11.1 may leave a non-POD array uninitialized, in some // cases when it should be value-initialized. // (Niels Dekker, LKEB, May 2010) // Apparently Intel 12.1 (compiler version number 9999 !!) has the same issue (compiler regression). #if defined(__INTEL_COMPILER) # if (__INTEL_COMPILER <= 1110) || (__INTEL_COMPILER == 9999) || (defined(_WIN32) && (__INTEL_COMPILER < 1600)) # define BOOST_NO_COMPLETE_VALUE_INITIALIZATION # endif #endif // // Dynamic shared object (DSO) and dynamic-link library (DLL) support // #if defined(__GNUC__) && (__GNUC__ >= 4) # define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) # define BOOST_SYMBOL_IMPORT # define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) #endif // // C++0x features // For each feature we need to check both the Intel compiler version, // and the version of MSVC or GCC that we are emulating. // See http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler/ // for a list of which features were implemented in which Intel releases. // #if defined(BOOST_INTEL_STDCXX0X) // BOOST_NO_CXX11_CONSTEXPR: #if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && !defined(_MSC_VER) // Available in earlier Intel versions, but fail our tests: # undef BOOST_NO_CXX11_CONSTEXPR #endif // BOOST_NO_CXX11_NULLPTR: #if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) # undef BOOST_NO_CXX11_NULLPTR #endif // BOOST_NO_CXX11_TEMPLATE_ALIASES #if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_TEMPLATE_ALIASES #endif // BOOST_NO_CXX11_DECLTYPE #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) # undef BOOST_NO_CXX11_DECLTYPE #endif // BOOST_NO_CXX11_DECLTYPE_N3276 #if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_DECLTYPE_N3276 #endif // BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #endif // BOOST_NO_CXX11_RVALUE_REFERENCES #if (BOOST_INTEL_CXX_VERSION >= 1300) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) // This is available from earlier Intel versions, but breaks Filesystem and other libraries: # undef BOOST_NO_CXX11_RVALUE_REFERENCES #endif // BOOST_NO_CXX11_STATIC_ASSERT #if (BOOST_INTEL_CXX_VERSION >= 1110) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) # undef BOOST_NO_CXX11_STATIC_ASSERT #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_VARIADIC_TEMPLATES #endif // BOOST_NO_CXX11_VARIADIC_MACROS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40200)) && (!defined(_MSC_VER) || (_MSC_VER >= 1400)) # undef BOOST_NO_CXX11_VARIADIC_MACROS #endif // BOOST_NO_CXX11_AUTO_DECLARATIONS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) # undef BOOST_NO_CXX11_AUTO_DECLARATIONS #endif // BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) # undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #endif // BOOST_NO_CXX11_CHAR16_T #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) # undef BOOST_NO_CXX11_CHAR16_T #endif // BOOST_NO_CXX11_CHAR32_T #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) # undef BOOST_NO_CXX11_CHAR32_T #endif // BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #endif // BOOST_NO_CXX11_DELETED_FUNCTIONS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_DELETED_FUNCTIONS #endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) # undef BOOST_NO_CXX11_HDR_INITIALIZER_LIST #endif // BOOST_NO_CXX11_SCOPED_ENUMS #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40501)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) // This is available but broken in earlier Intel releases. # undef BOOST_NO_CXX11_SCOPED_ENUMS #endif // BOOST_NO_SFINAE_EXPR #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) # undef BOOST_NO_SFINAE_EXPR #endif // BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) // This is available in earlier Intel releases, but breaks Multiprecision: # undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #endif // BOOST_NO_CXX11_LAMBDAS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) # undef BOOST_NO_CXX11_LAMBDAS #endif // BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) # undef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #endif // BOOST_NO_CXX11_RANGE_BASED_FOR #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) # undef BOOST_NO_CXX11_RANGE_BASED_FOR #endif // BOOST_NO_CXX11_RAW_LITERALS #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_RAW_LITERALS #endif // BOOST_NO_CXX11_UNICODE_LITERALS #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) # undef BOOST_NO_CXX11_UNICODE_LITERALS #endif // BOOST_NO_CXX11_NOEXCEPT #if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) // Available in earlier Intel release, but generates errors when used with // conditional exception specifications, for example in multiprecision: # undef BOOST_NO_CXX11_NOEXCEPT #endif // BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) # undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #endif // BOOST_NO_CXX11_USER_DEFINED_LITERALS #if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) # undef BOOST_NO_CXX11_USER_DEFINED_LITERALS #endif // BOOST_NO_CXX11_ALIGNAS #if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) # undef BOOST_NO_CXX11_ALIGNAS #endif // BOOST_NO_CXX11_TRAILING_RESULT_TYPES #if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) # undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES #endif // BOOST_NO_CXX11_INLINE_NAMESPACES #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) # undef BOOST_NO_CXX11_INLINE_NAMESPACES #endif // BOOST_NO_CXX11_REF_QUALIFIERS #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) # undef BOOST_NO_CXX11_REF_QUALIFIERS #endif // BOOST_NO_CXX11_FINAL #if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) # undef BOOST_NO_CXX11_FINAL #endif #endif // // Broken in all versions up to 15: #define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS #if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION <= 1310) # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #endif #if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION == 1400) // A regression in Intel's compiler means that seems to be broken in this release as well as : # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_TUPLE #endif #if (BOOST_INTEL_CXX_VERSION < 1200) // // fenv.h appears not to work with Intel prior to 12.0: // # define BOOST_NO_FENV_H #endif // Intel 13.10 fails to access defaulted functions of a base class declared in private or protected sections, // producing the following errors: // error #453: protected function "..." (declared at ...") is not accessible through a "..." pointer or object #if (BOOST_INTEL_CXX_VERSION <= 1310) # define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS #endif #if defined(_MSC_VER) && (_MSC_VER >= 1600) # define BOOST_HAS_STDINT_H #endif #if defined(__LP64__) && defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1310) && !defined(__CUDACC__) # define BOOST_HAS_INT128 #endif #endif // // last known and checked version: #if (BOOST_INTEL_CXX_VERSION > 1500) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # elif defined(_MSC_VER) // // We don't emit this warning any more, since we have so few // defect macros set anyway (just the one). // //# pragma message("Unknown compiler version - please run the configure tests and report the results") # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/kai.hpp ================================================ // (C) Copyright John Maddock 2001. // (C) Copyright David Abrahams 2002. // (C) Copyright Aleksey Gurtovoy 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Kai C++ compiler setup: #include "boost/config/compiler/common_edg.hpp" # if (__KCC_VERSION <= 4001) || !defined(BOOST_STRICT_CONFIG) // at least on Sun, the contents of is not in namespace std # define BOOST_NO_STDC_NAMESPACE # endif // see also common_edg.hpp which needs a special check for __KCC # if !defined(_EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS # endif // // last known and checked version is 4001: #if (__KCC_VERSION > 4001) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/metrowerks.hpp ================================================ // (C) Copyright John Maddock 2001. // (C) Copyright Darin Adler 2001. // (C) Copyright Peter Dimov 2001. // (C) Copyright David Abrahams 2001 - 2002. // (C) Copyright Beman Dawes 2001 - 2003. // (C) Copyright Stefan Slapeta 2004. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Metrowerks C++ compiler setup: // locale support is disabled when linking with the dynamic runtime # ifdef _MSL_NO_LOCALE # define BOOST_NO_STD_LOCALE # endif # if __MWERKS__ <= 0x2301 // 5.3 # define BOOST_NO_FUNCTION_TEMPLATE_ORDERING # define BOOST_NO_POINTER_TO_MEMBER_CONST # define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS # define BOOST_NO_MEMBER_TEMPLATE_KEYWORD # endif # if __MWERKS__ <= 0x2401 // 6.2 //# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING # endif # if(__MWERKS__ <= 0x2407) // 7.x # define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS # define BOOST_NO_UNREACHABLE_RETURN_DETECTION # endif # if(__MWERKS__ <= 0x3003) // 8.x # define BOOST_NO_SFINAE # endif // the "|| !defined(BOOST_STRICT_CONFIG)" part should apply to the last // tested version *only*: # if(__MWERKS__ <= 0x3207) || !defined(BOOST_STRICT_CONFIG) // 9.6 # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS # define BOOST_NO_IS_ABSTRACT # endif #if !__option(wchar_type) # define BOOST_NO_INTRINSIC_WCHAR_T #endif #if !__option(exceptions) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif #if (__INTEL__ && _WIN32) || (__POWERPC__ && macintosh) # if __MWERKS__ == 0x3000 # define BOOST_COMPILER_VERSION 8.0 # elif __MWERKS__ == 0x3001 # define BOOST_COMPILER_VERSION 8.1 # elif __MWERKS__ == 0x3002 # define BOOST_COMPILER_VERSION 8.2 # elif __MWERKS__ == 0x3003 # define BOOST_COMPILER_VERSION 8.3 # elif __MWERKS__ == 0x3200 # define BOOST_COMPILER_VERSION 9.0 # elif __MWERKS__ == 0x3201 # define BOOST_COMPILER_VERSION 9.1 # elif __MWERKS__ == 0x3202 # define BOOST_COMPILER_VERSION 9.2 # elif __MWERKS__ == 0x3204 # define BOOST_COMPILER_VERSION 9.3 # elif __MWERKS__ == 0x3205 # define BOOST_COMPILER_VERSION 9.4 # elif __MWERKS__ == 0x3206 # define BOOST_COMPILER_VERSION 9.5 # elif __MWERKS__ == 0x3207 # define BOOST_COMPILER_VERSION 9.6 # else # define BOOST_COMPILER_VERSION __MWERKS__ # endif #else # define BOOST_COMPILER_VERSION __MWERKS__ #endif // // C++0x features // // See boost\config\suffix.hpp for BOOST_NO_LONG_LONG // #if __MWERKS__ > 0x3206 && __option(rvalue_refs) # define BOOST_HAS_RVALUE_REFS #else # define BOOST_NO_CXX11_RVALUE_REFERENCES #endif #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) // // versions check: // we don't support Metrowerks prior to version 5.3: #if __MWERKS__ < 0x2301 # error "Compiler not supported or configured - please reconfigure" #endif // // last known and checked version: #if (__MWERKS__ > 0x3205) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/mpw.hpp ================================================ // (C) Copyright John Maddock 2001 - 2002. // (C) Copyright Aleksey Gurtovoy 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // MPW C++ compilers setup: # if defined(__SC__) # define BOOST_COMPILER "MPW SCpp version " BOOST_STRINGIZE(__SC__) # elif defined(__MRC__) # define BOOST_COMPILER "MPW MrCpp version " BOOST_STRINGIZE(__MRC__) # else # error "Using MPW compiler configuration by mistake. Please update." # endif // // MPW 8.90: // #if (MPW_CPLUS <= 0x890) || !defined(BOOST_STRICT_CONFIG) # define BOOST_NO_CV_SPECIALIZATIONS # define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS # define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS # define BOOST_NO_INCLASS_MEMBER_INITIALIZATION # define BOOST_NO_INTRINSIC_WCHAR_T # define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # define BOOST_NO_USING_TEMPLATE # define BOOST_NO_CWCHAR # define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS # define BOOST_NO_STD_ALLOCATOR /* actually a bug with const reference overloading */ #endif // // C++0x features // // See boost\config\suffix.hpp for BOOST_NO_LONG_LONG // #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif // // versions check: // we don't support MPW prior to version 8.9: #if MPW_CPLUS < 0x890 # error "Compiler not supported or configured - please reconfigure" #endif // // last known and checked version is 0x890: #if (MPW_CPLUS > 0x890) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/nvcc.hpp ================================================ // (C) Copyright Eric Jourdanneau, Joel Falcou 2010 // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // NVIDIA CUDA C++ compiler setup #ifndef BOOST_COMPILER # define BOOST_COMPILER "NVIDIA CUDA C++ Compiler" #endif // NVIDIA Specific support // BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device #define BOOST_GPU_ENABLED __host__ __device__ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/pathscale.hpp ================================================ // (C) Copyright Bryce Lelbach 2011 // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // PathScale EKOPath C++ Compiler #ifndef BOOST_COMPILER # define BOOST_COMPILER "PathScale EKOPath C++ Compiler version " __PATHSCALE__ #endif #if __PATHCC__ >= 4 # define BOOST_MSVC6_MEMBER_TEMPLATES # define BOOST_HAS_UNISTD_H # define BOOST_HAS_STDINT_H # define BOOST_HAS_SIGACTION # define BOOST_HAS_SCHED_YIELD # define BOOST_HAS_THREADS # define BOOST_HAS_PTHREADS # define BOOST_HAS_PTHREAD_YIELD # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # define BOOST_HAS_PARTIAL_STD_ALLOCATOR # define BOOST_HAS_NRVO # define BOOST_HAS_NL_TYPES_H # define BOOST_HAS_NANOSLEEP # define BOOST_HAS_LONG_LONG # define BOOST_HAS_LOG1P # define BOOST_HAS_GETTIMEOFDAY # define BOOST_HAS_EXPM1 # define BOOST_HAS_DIRENT_H # define BOOST_HAS_CLOCK_GETTIME # define BOOST_NO_CXX11_VARIADIC_TEMPLATES # define BOOST_NO_CXX11_UNICODE_LITERALS # define BOOST_NO_CXX11_TEMPLATE_ALIASES # define BOOST_NO_CXX11_STATIC_ASSERT # define BOOST_NO_SFINAE_EXPR # define BOOST_NO_CXX11_SCOPED_ENUMS # define BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_NO_CXX11_RANGE_BASED_FOR # define BOOST_NO_CXX11_RAW_LITERALS # define BOOST_NO_CXX11_NULLPTR # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_NOEXCEPT # define BOOST_NO_CXX11_LAMBDAS # define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS # define BOOST_NO_MS_INT64_NUMERIC_LIMITS # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DECLTYPE # define BOOST_NO_CXX11_DECLTYPE_N3276 # define BOOST_NO_CXX11_CONSTEXPR # define BOOST_NO_COMPLETE_VALUE_INITIALIZATION # define BOOST_NO_CXX11_CHAR32_T # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_ALIGNAS # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES # define BOOST_NO_CXX11_INLINE_NAMESPACES # define BOOST_NO_CXX11_REF_QUALIFIERS # define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/pgi.hpp ================================================ // (C) Copyright Noel Belcourt 2007. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // PGI C++ compiler setup: #define BOOST_COMPILER_VERSION __PGIC__##__PGIC_MINOR__ #define BOOST_COMPILER "PGI compiler version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) // // Threading support: // Turn this on unconditionally here, it will get turned off again later // if no threading API is detected. // #if __PGIC__ >= 11 // options requested by configure --enable-test #define BOOST_HAS_PTHREADS #define BOOST_HAS_THREADS #define BOOST_HAS_PTHREAD_YIELD #define BOOST_HAS_NRVO #define BOOST_HAS_LONG_LONG // options --enable-test wants undefined #undef BOOST_NO_STDC_NAMESPACE #undef BOOST_NO_EXCEPTION_STD_NAMESPACE #undef BOOST_DEDUCED_TYPENAME #define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_AUTO_DECLARATIONS #elif __PGIC__ >= 10 // options requested by configure --enable-test #define BOOST_HAS_THREADS #define BOOST_HAS_NRVO #define BOOST_HAS_LONG_LONG #if defined(linux) || defined(__linux) || defined(__linux__) # define BOOST_HAS_STDINT_H #endif // options --enable-test wants undefined #undef BOOST_NO_STDC_NAMESPACE #undef BOOST_NO_EXCEPTION_STD_NAMESPACE #undef BOOST_DEDUCED_TYPENAME #elif __PGIC__ >= 7 #define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #define BOOST_NO_SWPRINTF #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_AUTO_DECLARATIONS #else # error "Pgi compiler not configured - please reconfigure" #endif // // C++0x features // // See boost\config\suffix.hpp for BOOST_NO_LONG_LONG // #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_NUMERIC_LIMITS #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_SWPRINTF #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_HDR_UNORDERED_SET #define BOOST_NO_CXX11_HDR_UNORDERED_MAP #define BOOST_NO_CXX11_HDR_TYPEINDEX #define BOOST_NO_CXX11_HDR_TYPE_TRAITS #define BOOST_NO_CXX11_HDR_TUPLE #define BOOST_NO_CXX11_HDR_THREAD #define BOOST_NO_CXX11_HDR_SYSTEM_ERROR #define BOOST_NO_CXX11_HDR_REGEX #define BOOST_NO_CXX11_HDR_RATIO #define BOOST_NO_CXX11_HDR_RANDOM #define BOOST_NO_CXX11_HDR_MUTEX #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_HDR_FUTURE #define BOOST_NO_CXX11_HDR_FORWARD_LIST #define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE #define BOOST_NO_CXX11_HDR_CODECVT #define BOOST_NO_CXX11_HDR_CHRONO #define BOOST_NO_CXX11_HDR_ARRAY #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif // // version check: // probably nothing to do here? ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/sgi_mipspro.hpp ================================================ // (C) Copyright John Maddock 2001 - 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // SGI C++ compiler setup: #define BOOST_COMPILER "SGI Irix compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) #include "boost/config/compiler/common_edg.hpp" // // Threading support: // Turn this on unconditionally here, it will get turned off again later // if no threading API is detected. // #define BOOST_HAS_THREADS #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #undef BOOST_NO_SWPRINTF #undef BOOST_DEDUCED_TYPENAME // // version check: // probably nothing to do here? ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/sunpro_cc.hpp ================================================ // (C) Copyright John Maddock 2001. // (C) Copyright Jens Maurer 2001 - 2003. // (C) Copyright Peter Dimov 2002. // (C) Copyright Aleksey Gurtovoy 2002 - 2003. // (C) Copyright David Abrahams 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Sun C++ compiler setup: # if __SUNPRO_CC <= 0x500 # define BOOST_NO_MEMBER_TEMPLATES # define BOOST_NO_FUNCTION_TEMPLATE_ORDERING # endif # if (__SUNPRO_CC <= 0x520) // // Sunpro 5.2 and earler: // // although sunpro 5.2 supports the syntax for // inline initialization it often gets the value // wrong, especially where the value is computed // from other constants (J Maddock 6th May 2001) # define BOOST_NO_INCLASS_MEMBER_INITIALIZATION // Although sunpro 5.2 supports the syntax for // partial specialization, it often seems to // bind to the wrong specialization. Better // to disable it until suppport becomes more stable // (J Maddock 6th May 2001). # define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # endif # if (__SUNPRO_CC <= 0x530) // Requesting debug info (-g) with Boost.Python results // in an internal compiler error for "static const" // initialized in-class. // >> Assertion: (../links/dbg_cstabs.cc, line 611) // while processing ../test.cpp at line 0. // (Jens Maurer according to Gottfried Ganssauge 04 Mar 2002) # define BOOST_NO_INCLASS_MEMBER_INITIALIZATION // SunPro 5.3 has better support for partial specialization, // but breaks when compiling std::less > // (Jens Maurer 4 Nov 2001). // std::less specialization fixed as reported by George // Heintzelman; partial specialization re-enabled // (Peter Dimov 17 Jan 2002) //# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // integral constant expressions with 64 bit numbers fail # define BOOST_NO_INTEGRAL_INT64_T # endif # if (__SUNPRO_CC < 0x570) # define BOOST_NO_TEMPLATE_TEMPLATES // see http://lists.boost.org/MailArchives/boost/msg47184.php // and http://lists.boost.org/MailArchives/boost/msg47220.php # define BOOST_NO_INCLASS_MEMBER_INITIALIZATION # define BOOST_NO_SFINAE # define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS # endif # if (__SUNPRO_CC <= 0x580) # define BOOST_NO_IS_ABSTRACT # endif # if (__SUNPRO_CC <= 0x5100) // Sun 5.10 may not correctly value-initialize objects of // some user defined types, as was reported in April 2010 // (CR 6947016), and confirmed by Steve Clamage. // (Niels Dekker, LKEB, May 2010). # define BOOST_NO_COMPLETE_VALUE_INITIALIZATION # endif // // Dynamic shared object (DSO) and dynamic-link library (DLL) support // #if __SUNPRO_CC > 0x500 # define BOOST_SYMBOL_EXPORT __global # define BOOST_SYMBOL_IMPORT __global # define BOOST_SYMBOL_VISIBLE __global #endif #if (__SUNPRO_CC < 0x5130) // C++03 features in 12.4: #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_ADL_BARRIER #define BOOST_NO_CXX11_VARIADIC_MACROS #endif #if (__SUNPRO_CC < 0x5130) || (__cplusplus < 201100) // C++11 only featuires in 12.4: #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_NO_CXX11_SCOPED_ENUMS #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_FINAL #endif #if (__SUNPRO_CC < 0x5140) || (__cplusplus < 201103) #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_REF_QUALIFIERS #endif #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION // // C++0x features // # define BOOST_HAS_LONG_LONG // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif // // Version // #define BOOST_COMPILER "Sun compiler version " BOOST_STRINGIZE(__SUNPRO_CC) // // versions check: // we don't support sunpro prior to version 4: #if __SUNPRO_CC < 0x400 #error "Compiler not supported or configured - please reconfigure" #endif // // last known and checked version is 0x590: #if (__SUNPRO_CC > 0x590) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/vacpp.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Toon Knapen 2001 - 2003. // (C) Copyright Lie-Quan Lee 2001. // (C) Copyright Markus Schoepflin 2002 - 2003. // (C) Copyright Beman Dawes 2002 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Visual Age (IBM) C++ compiler setup: #if __IBMCPP__ <= 501 # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS # define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS #endif #if (__IBMCPP__ <= 502) // Actually the compiler supports inclass member initialization but it // requires a definition for the class member and it doesn't recognize // it as an integral constant expression when used as a template argument. # define BOOST_NO_INCLASS_MEMBER_INITIALIZATION # define BOOST_NO_INTEGRAL_INT64_T # define BOOST_NO_MEMBER_TEMPLATE_KEYWORD #endif #if (__IBMCPP__ <= 600) || !defined(BOOST_STRICT_CONFIG) # define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS #endif #if (__IBMCPP__ <= 1110) // XL C++ V11.1 and earlier versions may not always value-initialize // a temporary object T(), when T is a non-POD aggregate class type. // Michael Wong (IBM Canada Ltd) has confirmed this issue and gave it // high priority. -- Niels Dekker (LKEB), May 2010. # define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #endif // // On AIX thread support seems to be indicated by _THREAD_SAFE: // #ifdef _THREAD_SAFE # define BOOST_HAS_THREADS #endif #define BOOST_COMPILER "IBM Visual Age version " BOOST_STRINGIZE(__IBMCPP__) // // versions check: // we don't support Visual age prior to version 5: #if __IBMCPP__ < 500 #error "Compiler not supported or configured - please reconfigure" #endif // // last known and checked version is 1210: #if (__IBMCPP__ > 1210) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # endif #endif // Some versions of the compiler have issues with default arguments on partial specializations #if __IBMCPP__ <= 1010 #define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS #endif // // C++0x features // // See boost\config\suffix.hpp for BOOST_NO_LONG_LONG // #if ! __IBMCPP_AUTO_TYPEDEDUCTION # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #endif #if ! __IBMCPP_UTF_LITERAL__ # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T #endif #if ! __IBMCPP_CONSTEXPR # define BOOST_NO_CXX11_CONSTEXPR #endif #if ! __IBMCPP_DECLTYPE # define BOOST_NO_CXX11_DECLTYPE #else # define BOOST_HAS_DECLTYPE #endif #define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #define BOOST_NO_CXX11_DELETED_FUNCTIONS #if ! __IBMCPP_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #endif #if ! __IBMCPP_EXTERN_TEMPLATE # define BOOST_NO_CXX11_EXTERN_TEMPLATE #endif #if ! __IBMCPP_VARIADIC_TEMPLATES // not enabled separately at this time # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #endif #define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #define BOOST_NO_CXX11_LAMBDAS #define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NULLPTR #define BOOST_NO_CXX11_RANGE_BASED_FOR #define BOOST_NO_CXX11_RAW_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS #if ! __IBMCPP_RVALUE_REFERENCES # define BOOST_NO_CXX11_RVALUE_REFERENCES #endif #if ! __IBMCPP_SCOPED_ENUM # define BOOST_NO_CXX11_SCOPED_ENUMS #endif #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #if ! __IBMCPP_STATIC_ASSERT # define BOOST_NO_CXX11_STATIC_ASSERT #endif #define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #if ! __IBMCPP_VARIADIC_TEMPLATES # define BOOST_NO_CXX11_VARIADIC_TEMPLATES #endif #if ! __C99_MACRO_WITH_VA_ARGS # define BOOST_NO_CXX11_VARIADIC_MACROS #endif #define BOOST_NO_CXX11_ALIGNAS #define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_NO_CXX11_REF_QUALIFIERS #define BOOST_NO_CXX11_FINAL // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if (__cplusplus < 201304) // There's no SD6 check for this.... # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif #if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/visualc.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Darin Adler 2001 - 2002. // (C) Copyright Peter Dimov 2001. // (C) Copyright Aleksey Gurtovoy 2002. // (C) Copyright David Abrahams 2002 - 2003. // (C) Copyright Beman Dawes 2002 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // // Microsoft Visual C++ compiler setup: // // We need to be careful with the checks in this file, as contrary // to popular belief there are versions with _MSC_VER with the final // digit non-zero (mainly the MIPS cross compiler). // // So we either test _MSC_VER >= XXXX or else _MSC_VER < XXXX. // No other comparisons (==, >, or <=) are safe. // #define BOOST_MSVC _MSC_VER // // Helper macro BOOST_MSVC_FULL_VER for use in Boost code: // #if _MSC_FULL_VER > 100000000 # define BOOST_MSVC_FULL_VER _MSC_FULL_VER #else # define BOOST_MSVC_FULL_VER (_MSC_FULL_VER * 10) #endif // Attempt to suppress VC6 warnings about the length of decorated names (obsolete): #pragma warning( disable : 4503 ) // warning: decorated name length exceeded #define BOOST_HAS_PRAGMA_ONCE // // versions check: // we don't support Visual C++ prior to version 7.1: #if _MSC_VER < 1310 # error "Compiler not supported or configured - please reconfigure" #endif #if _MSC_FULL_VER < 180020827 # define BOOST_NO_FENV_H #endif #if _MSC_VER < 1400 // although a conforming signature for swprint exists in VC7.1 // it appears not to actually work: # define BOOST_NO_SWPRINTF // Our extern template tests also fail for this compiler: # define BOOST_NO_CXX11_EXTERN_TEMPLATE // Variadic macros do not exist for VC7.1 and lower # define BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #endif #if _MSC_VER < 1500 // 140X == VC++ 8.0 # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS #endif #if _MSC_VER < 1600 // 150X == VC++ 9.0 // A bug in VC9: # define BOOST_NO_ADL_BARRIER #endif #ifndef _NATIVE_WCHAR_T_DEFINED # define BOOST_NO_INTRINSIC_WCHAR_T #endif // // check for exception handling support: #if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif // // __int64 support: // #define BOOST_HAS_MS_INT64 #if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400) # define BOOST_HAS_LONG_LONG #else # define BOOST_NO_LONG_LONG #endif #if (_MSC_VER >= 1400) && !defined(_DEBUG) # define BOOST_HAS_NRVO #endif #if _MSC_VER >= 1600 // 160X == VC++ 10.0 # define BOOST_HAS_PRAGMA_DETECT_MISMATCH #endif // // disable Win32 API's if compiler extensions are // turned off: // #if !defined(_MSC_EXTENSIONS) && !defined(BOOST_DISABLE_WIN32) # define BOOST_DISABLE_WIN32 #endif #if !defined(_CPPRTTI) && !defined(BOOST_NO_RTTI) # define BOOST_NO_RTTI #endif // // TR1 features: // #if _MSC_VER >= 1700 // # define BOOST_HAS_TR1_HASH // don't know if this is true yet. // # define BOOST_HAS_TR1_TYPE_TRAITS // don't know if this is true yet. # define BOOST_HAS_TR1_UNORDERED_MAP # define BOOST_HAS_TR1_UNORDERED_SET #endif // // C++0x features // // See above for BOOST_NO_LONG_LONG // C++ features supported by VC++ 10 (aka 2010) // #if _MSC_VER < 1600 # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS # define BOOST_NO_CXX11_LAMBDAS # define BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_NO_CXX11_STATIC_ASSERT # define BOOST_NO_CXX11_NULLPTR # define BOOST_NO_CXX11_DECLTYPE #endif // _MSC_VER < 1600 #if _MSC_VER >= 1600 # define BOOST_HAS_STDINT_H #endif // C++11 features supported by VC++ 11 (aka 2012) // #if _MSC_VER < 1700 # define BOOST_NO_CXX11_FINAL # define BOOST_NO_CXX11_RANGE_BASED_FOR # define BOOST_NO_CXX11_SCOPED_ENUMS #endif // _MSC_VER < 1700 // C++11 features supported by VC++ 12 (aka 2013). // #if _MSC_FULL_VER < 180020827 # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS # define BOOST_NO_CXX11_RAW_LITERALS # define BOOST_NO_CXX11_TEMPLATE_ALIASES # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES # define BOOST_NO_CXX11_VARIADIC_TEMPLATES # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX # define BOOST_NO_CXX11_DECLTYPE_N3276 #endif // C++11 features supported by VC++ 14 (aka 2015) // #if (_MSC_FULL_VER < 190023026) # define BOOST_NO_CXX11_NOEXCEPT # define BOOST_NO_CXX11_REF_QUALIFIERS # define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_ALIGNAS # define BOOST_NO_CXX11_INLINE_NAMESPACES # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T # define BOOST_NO_CXX11_UNICODE_LITERALS # define BOOST_NO_CXX14_DECLTYPE_AUTO # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION # define BOOST_NO_CXX14_BINARY_LITERALS # define BOOST_NO_CXX14_GENERIC_LAMBDAS # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif // MSVC including version 14 has not yet completely // implemented value-initialization, as is reported: // "VC++ does not value-initialize members of derived classes without // user-declared constructor", reported in 2009 by Sylvester Hesp: // https://connect.microsoft.com/VisualStudio/feedback/details/484295 // "Presence of copy constructor breaks member class initialization", // reported in 2009 by Alex Vakulenko: // https://connect.microsoft.com/VisualStudio/feedback/details/499606 // "Value-initialization in new-expression", reported in 2005 by // Pavel Kuznetsov (MetaCommunications Engineering): // https://connect.microsoft.com/VisualStudio/feedback/details/100744 // Reported again by John Maddock in 2015 for VC14: // https://connect.microsoft.com/VisualStudio/feedback/details/1582233/c-subobjects-still-not-value-initialized-correctly // See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues // (Niels Dekker, LKEB, May 2010) #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION // C++11 features not supported by any versions #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_TWO_PHASE_NAME_LOOKUP // // This is somewhat supported in VC14, but we may need to wait for // a service release before enabling: // #define BOOST_NO_CXX11_CONSTEXPR // C++ 14: #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif // // prefix and suffix headers: // #ifndef BOOST_ABI_PREFIX # define BOOST_ABI_PREFIX "boost/config/abi/msvc_prefix.hpp" #endif #ifndef BOOST_ABI_SUFFIX # define BOOST_ABI_SUFFIX "boost/config/abi/msvc_suffix.hpp" #endif #ifndef BOOST_COMPILER // TODO: // these things are mostly bogus. 1200 means version 12.0 of the compiler. The // artificial versions assigned to them only refer to the versions of some IDE // these compilers have been shipped with, and even that is not all of it. Some // were shipped with freely downloadable SDKs, others as crosscompilers in eVC. // IOW, you can't use these 'versions' in any sensible way. Sorry. # if defined(UNDER_CE) # if _MSC_VER < 1400 // Note: I'm not aware of any CE compiler with version 13xx # if defined(BOOST_ASSERT_CONFIG) # error "Unknown EVC++ compiler version - please run the configure tests and report the results" # else # pragma message("Unknown EVC++ compiler version - please run the configure tests and report the results") # endif # elif _MSC_VER < 1500 # define BOOST_COMPILER_VERSION evc8 # elif _MSC_VER < 1600 # define BOOST_COMPILER_VERSION evc9 # elif _MSC_VER < 1700 # define BOOST_COMPILER_VERSION evc10 # elif _MSC_VER < 1800 # define BOOST_COMPILER_VERSION evc11 # elif _MSC_VER < 1900 # define BOOST_COMPILER_VERSION evc12 # elif _MSC_VER < 2000 # define BOOST_COMPILER_VERSION evc14 # else # if defined(BOOST_ASSERT_CONFIG) # error "Unknown EVC++ compiler version - please run the configure tests and report the results" # else # pragma message("Unknown EVC++ compiler version - please run the configure tests and report the results") # endif # endif # else # if _MSC_VER < 1310 // Note: Versions up to 7.0 aren't supported. # define BOOST_COMPILER_VERSION 5.0 # elif _MSC_VER < 1300 # define BOOST_COMPILER_VERSION 6.0 # elif _MSC_VER < 1310 # define BOOST_COMPILER_VERSION 7.0 # elif _MSC_VER < 1400 # define BOOST_COMPILER_VERSION 7.1 # elif _MSC_VER < 1500 # define BOOST_COMPILER_VERSION 8.0 # elif _MSC_VER < 1600 # define BOOST_COMPILER_VERSION 9.0 # elif _MSC_VER < 1700 # define BOOST_COMPILER_VERSION 10.0 # elif _MSC_VER < 1800 # define BOOST_COMPILER_VERSION 11.0 # elif _MSC_VER < 1900 # define BOOST_COMPILER_VERSION 12.0 # elif _MSC_VER < 2000 # define BOOST_COMPILER_VERSION 14.0 # else # define BOOST_COMPILER_VERSION _MSC_VER # endif # endif # define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) #endif // // last known and checked version is 19.00.23026 (VC++ 2015 RTM): #if (_MSC_VER > 1900) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # else # pragma message("Unknown compiler version - please run the configure tests and report the results") # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/compiler/xlcpp.hpp ================================================ // (C) Copyright Douglas Gregor 2010 // // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // compiler setup for IBM XL C/C++ for Linux (Little Endian) based on clang. #define BOOST_HAS_PRAGMA_ONCE // Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used. #if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) # define BOOST_HAS_PRAGMA_DETECT_MISMATCH #endif // When compiling with clang before __has_extension was defined, // even if one writes 'defined(__has_extension) && __has_extension(xxx)', // clang reports a compiler error. So the only workaround found is: #ifndef __has_extension #define __has_extension __has_feature #endif #if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif #if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI) # define BOOST_NO_RTTI #endif #if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID) # define BOOST_NO_TYPEID #endif #if defined(__int64) && !defined(__GNUC__) # define BOOST_HAS_MS_INT64 #endif #define BOOST_HAS_NRVO // Branch prediction hints #if defined(__has_builtin) #if __has_builtin(__builtin_expect) #define BOOST_LIKELY(x) __builtin_expect(x, 1) #define BOOST_UNLIKELY(x) __builtin_expect(x, 0) #endif #endif // Clang supports "long long" in all compilation modes. #define BOOST_HAS_LONG_LONG // // Dynamic shared object (DSO) and dynamic-link library (DLL) support // #if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) # define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) # define BOOST_SYMBOL_IMPORT # define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) #endif // // The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through // between switch labels. // #if __cplusplus >= 201103L && defined(__has_warning) # if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") # define BOOST_FALLTHROUGH [[clang::fallthrough]] # endif #endif #if !__has_feature(cxx_auto_type) # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS #endif // // Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t // #if defined(_MSC_VER) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) # define BOOST_NO_CXX11_CHAR16_T # define BOOST_NO_CXX11_CHAR32_T #endif #if !__has_feature(cxx_constexpr) # define BOOST_NO_CXX11_CONSTEXPR #endif #if !__has_feature(cxx_decltype) # define BOOST_NO_CXX11_DECLTYPE #endif #if !__has_feature(cxx_decltype_incomplete_return_types) # define BOOST_NO_CXX11_DECLTYPE_N3276 #endif #if !__has_feature(cxx_defaulted_functions) # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS #endif #if !__has_feature(cxx_deleted_functions) # define BOOST_NO_CXX11_DELETED_FUNCTIONS #endif #if !__has_feature(cxx_explicit_conversions) # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #endif #if !__has_feature(cxx_default_function_template_args) # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS #endif #if !__has_feature(cxx_generalized_initializers) # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST #endif #if !__has_feature(cxx_lambdas) # define BOOST_NO_CXX11_LAMBDAS #endif #if !__has_feature(cxx_local_type_template_args) # define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS #endif #if !__has_feature(cxx_noexcept) # define BOOST_NO_CXX11_NOEXCEPT #endif #if !__has_feature(cxx_nullptr) # define BOOST_NO_CXX11_NULLPTR #endif #if !__has_feature(cxx_range_for) # define BOOST_NO_CXX11_RANGE_BASED_FOR #endif #if !__has_feature(cxx_raw_string_literals) # define BOOST_NO_CXX11_RAW_LITERALS #endif #if !__has_feature(cxx_reference_qualified_functions) # define BOOST_NO_CXX11_REF_QUALIFIERS #endif #if !__has_feature(cxx_generalized_initializers) # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #endif #if !__has_feature(cxx_rvalue_references) # define BOOST_NO_CXX11_RVALUE_REFERENCES #endif #if !__has_feature(cxx_strong_enums) # define BOOST_NO_CXX11_SCOPED_ENUMS #endif #if !__has_feature(cxx_static_assert) # define BOOST_NO_CXX11_STATIC_ASSERT #endif #if !__has_feature(cxx_alias_templates) # define BOOST_NO_CXX11_TEMPLATE_ALIASES #endif #if !__has_feature(cxx_unicode_literals) # define BOOST_NO_CXX11_UNICODE_LITERALS #endif #if !__has_feature(cxx_variadic_templates) # define BOOST_NO_CXX11_VARIADIC_TEMPLATES #endif #if !__has_feature(cxx_user_literals) # define BOOST_NO_CXX11_USER_DEFINED_LITERALS #endif #if !__has_feature(cxx_alignas) # define BOOST_NO_CXX11_ALIGNAS #endif #if !__has_feature(cxx_trailing_return) # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES #endif #if !__has_feature(cxx_inline_namespaces) # define BOOST_NO_CXX11_INLINE_NAMESPACES #endif #if !__has_feature(cxx_override_control) # define BOOST_NO_CXX11_FINAL #endif #if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__)) # define BOOST_NO_CXX14_BINARY_LITERALS #endif #if !__has_feature(__cxx_decltype_auto__) # define BOOST_NO_CXX14_DECLTYPE_AUTO #endif #if !__has_feature(__cxx_aggregate_nsdmi__) # define BOOST_NO_CXX14_AGGREGATE_NSDMI #endif #if !__has_feature(__cxx_init_captures__) # define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES #endif #if !__has_feature(__cxx_generic_lambdas__) # define BOOST_NO_CXX14_GENERIC_LAMBDAS #endif // clang < 3.5 has a defect with dependent type, like following. // // template // constexpr typename enable_if >::type foo(T &) // { } // error: no return statement in constexpr function // // This issue also affects C++11 mode, but C++11 constexpr requires return stmt. // Therefore we don't care such case. // // Note that we can't check Clang version directly as the numbering system changes depending who's // creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873) // so instead verify that we have a feature that was introduced at the same time as working C++14 // constexpr (generic lambda's in this case): // #if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__) # define BOOST_NO_CXX14_CONSTEXPR #endif #if !__has_feature(__cxx_return_type_deduction__) # define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION #endif #if !__has_feature(__cxx_variable_templates__) # define BOOST_NO_CXX14_VARIABLE_TEMPLATES #endif #if __cplusplus < 201400 // All versions with __cplusplus above this value seem to support this: # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif // Unused attribute: #if defined(__GNUC__) && (__GNUC__ >= 4) # define BOOST_ATTRIBUTE_UNUSED __attribute__((unused)) #endif #ifndef BOOST_COMPILER # define BOOST_COMPILER "Clang version " __clang_version__ #endif // Macro used to identify the Clang compiler. #define BOOST_CLANG 1 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/no_tr1/cmath.hpp ================================================ // (C) Copyright John Maddock 2008. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // The aim of this header is just to include but to do // so in a way that does not result in recursive inclusion of // the Boost TR1 components if boost/tr1/tr1/cmath is in the // include search path. We have to do this to avoid circular // dependencies: // #ifndef BOOST_CONFIG_CMATH # define BOOST_CONFIG_CMATH # ifndef BOOST_TR1_NO_RECURSION # define BOOST_TR1_NO_RECURSION # define BOOST_CONFIG_NO_CMATH_RECURSION # endif # include # ifdef BOOST_CONFIG_NO_CMATH_RECURSION # undef BOOST_TR1_NO_RECURSION # undef BOOST_CONFIG_NO_CMATH_RECURSION # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/no_tr1/complex.hpp ================================================ // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // The aim of this header is just to include but to do // so in a way that does not result in recursive inclusion of // the Boost TR1 components if boost/tr1/tr1/complex is in the // include search path. We have to do this to avoid circular // dependencies: // #ifndef BOOST_CONFIG_COMPLEX # define BOOST_CONFIG_COMPLEX # ifndef BOOST_TR1_NO_RECURSION # define BOOST_TR1_NO_RECURSION # define BOOST_CONFIG_NO_COMPLEX_RECURSION # endif # include # ifdef BOOST_CONFIG_NO_COMPLEX_RECURSION # undef BOOST_TR1_NO_RECURSION # undef BOOST_CONFIG_NO_COMPLEX_RECURSION # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/no_tr1/functional.hpp ================================================ // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // The aim of this header is just to include but to do // so in a way that does not result in recursive inclusion of // the Boost TR1 components if boost/tr1/tr1/functional is in the // include search path. We have to do this to avoid circular // dependencies: // #ifndef BOOST_CONFIG_FUNCTIONAL # define BOOST_CONFIG_FUNCTIONAL # ifndef BOOST_TR1_NO_RECURSION # define BOOST_TR1_NO_RECURSION # define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION # endif # include # ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION # undef BOOST_TR1_NO_RECURSION # undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/no_tr1/memory.hpp ================================================ // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // The aim of this header is just to include but to do // so in a way that does not result in recursive inclusion of // the Boost TR1 components if boost/tr1/tr1/memory is in the // include search path. We have to do this to avoid circular // dependencies: // #ifndef BOOST_CONFIG_MEMORY # define BOOST_CONFIG_MEMORY # ifndef BOOST_TR1_NO_RECURSION # define BOOST_TR1_NO_RECURSION # define BOOST_CONFIG_NO_MEMORY_RECURSION # endif # include # ifdef BOOST_CONFIG_NO_MEMORY_RECURSION # undef BOOST_TR1_NO_RECURSION # undef BOOST_CONFIG_NO_MEMORY_RECURSION # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/no_tr1/utility.hpp ================================================ // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // The aim of this header is just to include but to do // so in a way that does not result in recursive inclusion of // the Boost TR1 components if boost/tr1/tr1/utility is in the // include search path. We have to do this to avoid circular // dependencies: // #ifndef BOOST_CONFIG_UTILITY # define BOOST_CONFIG_UTILITY # ifndef BOOST_TR1_NO_RECURSION # define BOOST_TR1_NO_RECURSION # define BOOST_CONFIG_NO_UTILITY_RECURSION # endif # include # ifdef BOOST_CONFIG_NO_UTILITY_RECURSION # undef BOOST_TR1_NO_RECURSION # undef BOOST_CONFIG_NO_UTILITY_RECURSION # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/aix.hpp ================================================ // (C) Copyright John Maddock 2001 - 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // IBM/Aix specific config options: #define BOOST_PLATFORM "IBM Aix" #define BOOST_HAS_UNISTD_H #define BOOST_HAS_NL_TYPES_H #define BOOST_HAS_NANOSLEEP #define BOOST_HAS_CLOCK_GETTIME // This needs support in "boost/cstdint.hpp" exactly like FreeBSD. // This platform has header named which includes all // the things needed. #define BOOST_HAS_STDINT_H // Threading API's: #define BOOST_HAS_PTHREADS #define BOOST_HAS_PTHREAD_DELAY_NP #define BOOST_HAS_SCHED_YIELD //#define BOOST_HAS_PTHREAD_YIELD // boilerplate code: #include ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/amigaos.hpp ================================================ // (C) Copyright John Maddock 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. #define BOOST_PLATFORM "AmigaOS" #define BOOST_DISABLE_THREADS #define BOOST_NO_CWCHAR #define BOOST_NO_STD_WSTRING #define BOOST_NO_INTRINSIC_WCHAR_T ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/beos.hpp ================================================ // (C) Copyright John Maddock 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // BeOS specific config options: #define BOOST_PLATFORM "BeOS" #define BOOST_NO_CWCHAR #define BOOST_NO_CWCTYPE #define BOOST_HAS_UNISTD_H #define BOOST_HAS_BETHREADS #ifndef BOOST_DISABLE_THREADS # define BOOST_HAS_THREADS #endif // boilerplate code: #include ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/bsd.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Darin Adler 2001. // (C) Copyright Douglas Gregor 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // generic BSD config options: #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) #error "This platform is not BSD" #endif #ifdef __FreeBSD__ #define BOOST_PLATFORM "FreeBSD " BOOST_STRINGIZE(__FreeBSD__) #elif defined(__NetBSD__) #define BOOST_PLATFORM "NetBSD " BOOST_STRINGIZE(__NetBSD__) #elif defined(__OpenBSD__) #define BOOST_PLATFORM "OpenBSD " BOOST_STRINGIZE(__OpenBSD__) #elif defined(__DragonFly__) #define BOOST_PLATFORM "DragonFly " BOOST_STRINGIZE(__DragonFly__) #endif // // is this the correct version check? // FreeBSD has but does not // advertise the fact in : // #if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) || defined(__DragonFly__) # define BOOST_HAS_NL_TYPES_H #endif // // FreeBSD 3.x has pthreads support, but defines _POSIX_THREADS in // and not in // #if (defined(__FreeBSD__) && (__FreeBSD__ <= 3))\ || defined(__OpenBSD__) || defined(__DragonFly__) # define BOOST_HAS_PTHREADS #endif // // No wide character support in the BSD header files: // #if defined(__NetBSD__) #define __NetBSD_GCC__ (__GNUC__ * 1000000 \ + __GNUC_MINOR__ * 1000 \ + __GNUC_PATCHLEVEL__) // XXX - the following is required until c++config.h // defines _GLIBCXX_HAVE_SWPRINTF and friends // or the preprocessor conditionals are removed // from the cwchar header. #define _GLIBCXX_HAVE_SWPRINTF 1 #endif #if !((defined(__FreeBSD__) && (__FreeBSD__ >= 5)) \ || (defined(__NetBSD_GCC__) && (__NetBSD_GCC__ >= 2095003)) || defined(__DragonFly__)) # define BOOST_NO_CWCHAR #endif // // The BSD has macros only, no functions: // #if !defined(__OpenBSD__) || defined(__DragonFly__) # define BOOST_NO_CTYPE_FUNCTIONS #endif // // thread API's not auto detected: // #define BOOST_HAS_SCHED_YIELD #define BOOST_HAS_NANOSLEEP #define BOOST_HAS_GETTIMEOFDAY #define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE #define BOOST_HAS_SIGACTION // boilerplate code: #define BOOST_HAS_UNISTD_H #include ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/cloudabi.hpp ================================================ // Copyright Nuxi, https://nuxi.nl/ 2015. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #define BOOST_PLATFORM "CloudABI" #define BOOST_HAS_DIRENT_H #define BOOST_HAS_STDINT_H #define BOOST_HAS_UNISTD_H #define BOOST_HAS_CLOCK_GETTIME #define BOOST_HAS_EXPM1 #define BOOST_HAS_GETTIMEOFDAY #define BOOST_HAS_LOG1P #define BOOST_HAS_NANOSLEEP #define BOOST_HAS_PTHREADS #define BOOST_HAS_SCHED_YIELD ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/cray.hpp ================================================ // (C) Copyright John Maddock 2011. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // SGI Irix specific config options: #define BOOST_PLATFORM "Cray" // boilerplate code: #define BOOST_HAS_UNISTD_H #include ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/cygwin.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // cygwin specific config options: #define BOOST_PLATFORM "Cygwin" #define BOOST_HAS_DIRENT_H #define BOOST_HAS_LOG1P #define BOOST_HAS_EXPM1 // // Threading API: // See if we have POSIX threads, if we do use them, otherwise // revert to native Win threads. #define BOOST_HAS_UNISTD_H #include #if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) # define BOOST_HAS_PTHREADS # define BOOST_HAS_SCHED_YIELD # define BOOST_HAS_GETTIMEOFDAY # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # define BOOST_HAS_SIGACTION #else # if !defined(BOOST_HAS_WINTHREADS) # define BOOST_HAS_WINTHREADS # endif # define BOOST_HAS_FTIME #endif // // find out if we have a stdint.h, there should be a better way to do this: // #include #ifdef _STDINT_H #define BOOST_HAS_STDINT_H #endif /// Cygwin has no fenv.h #define BOOST_NO_FENV_H // boilerplate code: #include // // Cygwin lies about XSI conformance, there is no nl_types.h: // #ifdef BOOST_HAS_NL_TYPES_H # undef BOOST_HAS_NL_TYPES_H #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/haiku.hpp ================================================ // (C) Copyright Jessica Hamilton 2014. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Haiku specific config options: #define BOOST_PLATFORM "Haiku" #define BOOST_HAS_UNISTD_H #define BOOST_HAS_STDINT_H #ifndef BOOST_DISABLE_THREADS # define BOOST_HAS_THREADS #endif #define BOOST_NO_CXX11_HDR_TYPE_TRAITS #define BOOST_NO_CXX11_ATOMIC_SMART_PTR #define BOOST_NO_CXX11_STATIC_ASSERT #define BOOST_NO_CXX11_VARIADIC_MACROS // // thread API's not auto detected: // #define BOOST_HAS_SCHED_YIELD #define BOOST_HAS_GETTIMEOFDAY // boilerplate code: #include ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/hpux.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001 - 2003. // (C) Copyright David Abrahams 2002. // (C) Copyright Toon Knapen 2003. // (C) Copyright Boris Gubenko 2006 - 2007. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // hpux specific config options: #define BOOST_PLATFORM "HP-UX" // In principle, HP-UX has a nice under the name // However, it has the following problem: // Use of UINT32_C(0) results in "0u l" for the preprocessed source // (verifyable with gcc 2.95.3) #if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__HP_aCC) # define BOOST_HAS_STDINT_H #endif #if !(defined(__HP_aCC) || !defined(_INCLUDE__STDC_A1_SOURCE)) # define BOOST_NO_SWPRINTF #endif #if defined(__HP_aCC) && !defined(_INCLUDE__STDC_A1_SOURCE) # define BOOST_NO_CWCTYPE #endif #if defined(__GNUC__) # if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3)) // GNU C on HP-UX does not support threads (checked up to gcc 3.3) # define BOOST_DISABLE_THREADS # elif !defined(BOOST_DISABLE_THREADS) // threads supported from gcc-3.3 onwards: # define BOOST_HAS_THREADS # define BOOST_HAS_PTHREADS # endif #elif defined(__HP_aCC) && !defined(BOOST_DISABLE_THREADS) # define BOOST_HAS_PTHREADS #endif // boilerplate code: #define BOOST_HAS_UNISTD_H #include // the following are always available: #ifndef BOOST_HAS_GETTIMEOFDAY # define BOOST_HAS_GETTIMEOFDAY #endif #ifndef BOOST_HAS_SCHED_YIELD # define BOOST_HAS_SCHED_YIELD #endif #ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE #endif #ifndef BOOST_HAS_NL_TYPES_H # define BOOST_HAS_NL_TYPES_H #endif #ifndef BOOST_HAS_NANOSLEEP # define BOOST_HAS_NANOSLEEP #endif #ifndef BOOST_HAS_GETTIMEOFDAY # define BOOST_HAS_GETTIMEOFDAY #endif #ifndef BOOST_HAS_DIRENT_H # define BOOST_HAS_DIRENT_H #endif #ifndef BOOST_HAS_CLOCK_GETTIME # define BOOST_HAS_CLOCK_GETTIME #endif #ifndef BOOST_HAS_SIGACTION # define BOOST_HAS_SIGACTION #endif #ifndef BOOST_HAS_NRVO # ifndef __parisc # define BOOST_HAS_NRVO # endif #endif #ifndef BOOST_HAS_LOG1P # define BOOST_HAS_LOG1P #endif #ifndef BOOST_HAS_EXPM1 # define BOOST_HAS_EXPM1 #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/irix.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // SGI Irix specific config options: #define BOOST_PLATFORM "SGI Irix" #define BOOST_NO_SWPRINTF // // these are not auto detected by POSIX feature tests: // #define BOOST_HAS_GETTIMEOFDAY #define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE #ifdef __GNUC__ // GNU C on IRIX does not support threads (checked up to gcc 3.3) # define BOOST_DISABLE_THREADS #endif // boilerplate code: #define BOOST_HAS_UNISTD_H #include ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/linux.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // linux specific config options: #define BOOST_PLATFORM "linux" // make sure we have __GLIBC_PREREQ if available at all #ifdef __cplusplus #include #else #include #endif // // added to glibc 2.1.1 // We can only test for 2.1 though: // #if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) // defines int64_t unconditionally, but defines // int64_t only if __GNUC__. Thus, assume a fully usable // only when using GCC. # if defined __GNUC__ # define BOOST_HAS_STDINT_H # endif #endif #if defined(__LIBCOMO__) // // como on linux doesn't have std:: c functions: // NOTE: versions of libcomo prior to beta28 have octal version numbering, // e.g. version 25 is 21 (dec) // # if __LIBCOMO_VERSION__ <= 20 # define BOOST_NO_STDC_NAMESPACE # endif # if __LIBCOMO_VERSION__ <= 21 # define BOOST_NO_SWPRINTF # endif #endif // // If glibc is past version 2 then we definitely have // gettimeofday, earlier versions may or may not have it: // #if defined(__GLIBC__) && (__GLIBC__ >= 2) # define BOOST_HAS_GETTIMEOFDAY #endif #ifdef __USE_POSIX199309 # define BOOST_HAS_NANOSLEEP #endif #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) // __GLIBC_PREREQ is available since 2.1.2 // swprintf is available since glibc 2.2.0 # if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98)) # define BOOST_NO_SWPRINTF # endif #else # define BOOST_NO_SWPRINTF #endif // boilerplate code: #define BOOST_HAS_UNISTD_H #include #ifdef __USE_GNU #define BOOST_HAS_PTHREAD_YIELD #endif #ifndef __GNUC__ // // if the compiler is not gcc we still need to be able to parse // the GNU system headers, some of which (mainly ) // use GNU specific extensions: // # ifndef __extension__ # define __extension__ # endif # ifndef __const__ # define __const__ const # endif # ifndef __volatile__ # define __volatile__ volatile # endif # ifndef __signed__ # define __signed__ signed # endif # ifndef __typeof__ # define __typeof__ typeof # endif # ifndef __inline__ # define __inline__ inline # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/macos.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Darin Adler 2001 - 2002. // (C) Copyright Bill Kempf 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Mac OS specific config options: #define BOOST_PLATFORM "Mac OS" #if __MACH__ && !defined(_MSL_USING_MSL_C) // Using the Mac OS X system BSD-style C library. # ifndef BOOST_HAS_UNISTD_H # define BOOST_HAS_UNISTD_H # endif // // Begin by including our boilerplate code for POSIX // feature detection, this is safe even when using // the MSL as Metrowerks supply their own // to replace the platform-native BSD one. G++ users // should also always be able to do this on MaxOS X. // # include # ifndef BOOST_HAS_STDINT_H # define BOOST_HAS_STDINT_H # endif // // BSD runtime has pthreads, sigaction, sched_yield and gettimeofday, // of these only pthreads are advertised in , so set the // other options explicitly: // # define BOOST_HAS_SCHED_YIELD # define BOOST_HAS_GETTIMEOFDAY # define BOOST_HAS_SIGACTION # if (__GNUC__ < 3) && !defined( __APPLE_CC__) // GCC strange "ignore std" mode works better if you pretend everything // is in the std namespace, for the most part. # define BOOST_NO_STDC_NAMESPACE # endif # if (__GNUC__ >= 4) // Both gcc and intel require these. # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # define BOOST_HAS_NANOSLEEP # endif #else // Using the MSL C library. // We will eventually support threads in non-Carbon builds, but we do // not support this yet. # if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON ) # if !defined(BOOST_HAS_PTHREADS) // MPTasks support is deprecated/removed from Boost: //# define BOOST_HAS_MPTASKS # elif ( __dest_os == __mac_os_x ) // We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the // gettimeofday and no posix. # define BOOST_HAS_GETTIMEOFDAY # endif #ifdef BOOST_HAS_PTHREADS # define BOOST_HAS_THREADS #endif // The remote call manager depends on this. # define BOOST_BIND_ENABLE_PASCAL # endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/qnxnto.hpp ================================================ // (C) Copyright Jim Douglas 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // QNX specific config options: #define BOOST_PLATFORM "QNX" #define BOOST_HAS_UNISTD_H #include // QNX claims XOpen version 5 compatibility, but doesn't have an nl_types.h // or log1p and expm1: #undef BOOST_HAS_NL_TYPES_H #undef BOOST_HAS_LOG1P #undef BOOST_HAS_EXPM1 #define BOOST_HAS_PTHREADS #define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE #define BOOST_HAS_GETTIMEOFDAY #define BOOST_HAS_CLOCK_GETTIME #define BOOST_HAS_NANOSLEEP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/solaris.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // sun specific config options: #define BOOST_PLATFORM "Sun Solaris" #define BOOST_HAS_GETTIMEOFDAY // boilerplate code: #define BOOST_HAS_UNISTD_H #include // // pthreads don't actually work with gcc unless _PTHREADS is defined: // #if defined(__GNUC__) && defined(_POSIX_THREADS) && !defined(_PTHREADS) # undef BOOST_HAS_PTHREADS #endif #define BOOST_HAS_STDINT_H #define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE #define BOOST_HAS_LOG1P #define BOOST_HAS_EXPM1 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/symbian.hpp ================================================ // (C) Copyright Yuriy Krasnoschek 2009. // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // symbian specific config options: #define BOOST_PLATFORM "Symbian" #define BOOST_SYMBIAN 1 #if defined(__S60_3X__) // Open C / C++ plugin was introdused in this SDK, earlier versions don't have CRT / STL # define BOOST_S60_3rd_EDITION_FP2_OR_LATER_SDK // make sure we have __GLIBC_PREREQ if available at all #ifdef __cplusplus #include #else #include #endif// boilerplate code: # define BOOST_HAS_UNISTD_H # include // S60 SDK defines _POSIX_VERSION as POSIX.1 # ifndef BOOST_HAS_STDINT_H # define BOOST_HAS_STDINT_H # endif # ifndef BOOST_HAS_GETTIMEOFDAY # define BOOST_HAS_GETTIMEOFDAY # endif # ifndef BOOST_HAS_DIRENT_H # define BOOST_HAS_DIRENT_H # endif # ifndef BOOST_HAS_SIGACTION # define BOOST_HAS_SIGACTION # endif # ifndef BOOST_HAS_PTHREADS # define BOOST_HAS_PTHREADS # endif # ifndef BOOST_HAS_NANOSLEEP # define BOOST_HAS_NANOSLEEP # endif # ifndef BOOST_HAS_SCHED_YIELD # define BOOST_HAS_SCHED_YIELD # endif # ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # endif # ifndef BOOST_HAS_LOG1P # define BOOST_HAS_LOG1P # endif # ifndef BOOST_HAS_EXPM1 # define BOOST_HAS_EXPM1 # endif # ifndef BOOST_POSIX_API # define BOOST_POSIX_API # endif // endianess support # include // Symbian SDK provides _BYTE_ORDER instead of __BYTE_ORDER # ifndef __LITTLE_ENDIAN # ifdef _LITTLE_ENDIAN # define __LITTLE_ENDIAN _LITTLE_ENDIAN # else # define __LITTLE_ENDIAN 1234 # endif # endif # ifndef __BIG_ENDIAN # ifdef _BIG_ENDIAN # define __BIG_ENDIAN _BIG_ENDIAN # else # define __BIG_ENDIAN 4321 # endif # endif # ifndef __BYTE_ORDER # define __BYTE_ORDER __LITTLE_ENDIAN // Symbian is LE # endif // Known limitations # define BOOST_ASIO_DISABLE_SERIAL_PORT # define BOOST_DATE_TIME_NO_LOCALE # define BOOST_NO_STD_WSTRING # define BOOST_EXCEPTION_DISABLE # define BOOST_NO_EXCEPTIONS #else // TODO: More platform support e.g. UIQ # error "Unsuppoted Symbian SDK" #endif #if defined(__WINSCW__) && !defined(BOOST_DISABLE_WIN32) # define BOOST_DISABLE_WIN32 // winscw defines WIN32 macro #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/vms.hpp ================================================ // (C) Copyright Artyom Beilis 2010. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_CONFIG_PLATFORM_VMS_HPP #define BOOST_CONFIG_PLATFORM_VMS_HPP #define BOOST_PLATFORM "OpenVMS" #undef BOOST_HAS_STDINT_H #define BOOST_HAS_UNISTD_H #define BOOST_HAS_NL_TYPES_H #define BOOST_HAS_GETTIMEOFDAY #define BOOST_HAS_DIRENT_H #define BOOST_HAS_PTHREADS #define BOOST_HAS_NANOSLEEP #define BOOST_HAS_CLOCK_GETTIME #define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE #define BOOST_HAS_LOG1P #define BOOST_HAS_EXPM1 #define BOOST_HAS_THREADS #undef BOOST_HAS_SCHED_YIELD #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/vxworks.hpp ================================================ // (C) Copyright Dustin Spicuzza 2009. // Adapted to vxWorks 6.9 by Peter Brockamp 2012. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Since WRS does not yet properly support boost under vxWorks // and this file was badly outdated, but I was keen on using it, // I patched boost myself to make things work. This has been tested // and adapted by me for vxWorks 6.9 *only*, as I'm lacking access // to earlier 6.X versions! The only thing I know for sure is that // very old versions of vxWorks (namely everything below 6.x) are // absolutely unable to use boost. This is mainly due to the completely // outdated libraries and ancient compiler (GCC 2.96 or worse). Do // not even think of getting this to work, a miserable failure will // be guaranteed! // Equally, this file has been tested for RTPs (Real Time Processes) // only, not for DKMs (Downloadable Kernel Modules). These two types // of executables differ largely in the available functionality of // the C-library, STL, and so on. A DKM uses a library similar to those // of vxWorks 5.X - with all its limitations and incompatibilities // with respect to ANSI C++ and STL. So probably there might be problems // with the usage of boost from DKMs. WRS or any voluteers are free to // prove the opposite! // ==================================================================== // // Some important information regarding the usage of POSIX semaphores: // ------------------------------------------------------------------- // // VxWorks as a real time operating system handles threads somewhat // different from what "normal" OSes do, regarding their scheduling! // This could lead to a scenario called "priority inversion" when using // semaphores, see http://en.wikipedia.org/wiki/Priority_inversion. // // Now, VxWorks POSIX-semaphores for DKM's default to the usage of // priority inverting semaphores, which is fine. On the other hand, // for RTP's it defaults to using non priority inverting semaphores, // which could easily pose a serious problem for a real time process, // i.e. deadlocks! To overcome this two possibilities do exist: // // a) Patch every piece of boost that uses semaphores to instanciate // the proper type of semaphores. This is non-intrusive with respect // to the OS and could relatively easy been done by giving all // semaphores attributes deviating from the default (for in-depth // information see the POSIX functions pthread_mutexattr_init() // and pthread_mutexattr_setprotocol()). However this breaks all // too easily, as with every new version some boost library could // all in a sudden start using semaphores, resurrecting the very // same, hard to locate problem over and over again! // // b) We could change the default properties for POSIX-semaphores // that VxWorks uses for RTP's and this is being suggested here, // as it will more or less seamlessly integrate with boost. I got // the following information from WRS how to do this, compare // Wind River TSR# 1209768: // // Instructions for changing the default properties of POSIX- // semaphores for RTP's in VxWorks 6.9: // - Edit the file /vxworks-6.9/target/usr/src/posix/pthreadLib.c // in the root of your Workbench-installation. // - Around line 917 there should be the definition of the default // mutex attributes: // // LOCAL pthread_mutexattr_t defaultMutexAttr = // { // PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0, // PTHREAD_MUTEX_DEFAULT // }; // // Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. // - Around line 1236 there should be a definition for the function // pthread_mutexattr_init(). A couple of lines below you should // find a block of code like this: // // pAttr->mutexAttrStatus = PTHREAD_INITIALIZED_OBJ; // pAttr->mutexAttrProtocol = PTHREAD_PRIO_NONE; // pAttr->mutexAttrPrioceiling = 0; // pAttr->mutexAttrType = PTHREAD_MUTEX_DEFAULT; // // Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. // - Finally, rebuild your VSB. This will create a new VxWorks kernel // with the changed properties. That's it! Now, using boost should // no longer cause any problems with task deadlocks! // // And here's another useful piece of information concerning VxWorks' // POSIX-functionality in general: // VxWorks is not a genuine POSIX-OS in itself, rather it is using a // kind of compatibility layer (sort of a wrapper) to emulate the // POSIX-functionality by using its own resources and functions. // At the time a task (thread) calls it's first POSIX-function during // runtime it is being transformed by the OS into a POSIX-thread. // This transformation does include a call to malloc() to allocate the // memory required for the housekeeping of POSIX-threads. In a high // priority RTP this malloc() call may be highly undesirable, as its // timing is more or less unpredictable (depending on what your actual // heap looks like). You can circumvent this problem by calling the // function thread_self() at a well defined point in the code of the // task, e.g. shortly after the task spawns up. Thereby you are able // to define the time when the task-transformation will take place and // you could shift it to an uncritical point where a malloc() call is // tolerable. So, if this could pose a problem for your code, remember // to call thread_self() from the affected task at an early stage. // // ==================================================================== // Block out all versions before vxWorks 6.x, as these don't work: // Include header with the vxWorks version information and query them #include #if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6) # error "The vxWorks version you're using is so badly outdated,\ it doesn't work at all with boost, sorry, no chance!" #endif // Handle versions above 5.X but below 6.9 #if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9) // TODO: Starting from what version does vxWorks work with boost? // We can't reasonably insert a #warning "" as a user hint here, // as this will show up with every file including some boost header, // badly bugging the user... So for the time being we just leave it. #endif // vxWorks specific config options: // -------------------------------- #define BOOST_PLATFORM "vxWorks" // Special behaviour for DKMs: #ifdef _WRS_KERNEL // DKMs do not have the -header, // but apparently they do have an intrinsic wchar_t meanwhile! # define BOOST_NO_CWCHAR // Lots of wide-functions and -headers are unavailable for DKMs as well: # define BOOST_NO_CWCTYPE # define BOOST_NO_SWPRINTF # define BOOST_NO_STD_WSTRING # define BOOST_NO_STD_WSTREAMBUF #endif // Generally available headers: #define BOOST_HAS_UNISTD_H #define BOOST_HAS_STDINT_H #define BOOST_HAS_DIRENT_H #define BOOST_HAS_SLIST // vxWorks does not have installed an iconv-library by default, // so unfortunately no Unicode support from scratch is available! // Thus, instead it is suggested to switch to ICU, as this seems // to be the most complete and portable option... #define BOOST_LOCALE_WITH_ICU // Generally available functionality: #define BOOST_HAS_THREADS #define BOOST_HAS_NANOSLEEP #define BOOST_HAS_GETTIMEOFDAY #define BOOST_HAS_CLOCK_GETTIME #define BOOST_HAS_MACRO_USE_FACET // Generally unavailable functionality, delivered by boost's test function: //#define BOOST_NO_DEDUCED_TYPENAME // Commented this out, boost's test gives an errorneous result! #define BOOST_NO_CXX11_EXTERN_TEMPLATE #define BOOST_NO_CXX11_VARIADIC_MACROS // Generally available threading API's: #define BOOST_HAS_PTHREADS #define BOOST_HAS_SCHED_YIELD #define BOOST_HAS_SIGACTION // Functionality available for RTPs only: #ifdef __RTP__ # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # define BOOST_HAS_LOG1P # define BOOST_HAS_EXPM1 #endif // Functionality available for DKMs only: #ifdef _WRS_KERNEL // Luckily, at the moment there seems to be none! #endif // These #defines allow posix_features to work, since vxWorks doesn't // #define them itself for DKMs (for RTPs on the contrary it does): #ifdef _WRS_KERNEL # ifndef _POSIX_TIMERS # define _POSIX_TIMERS 1 # endif # ifndef _POSIX_THREADS # define _POSIX_THREADS 1 # endif #endif // vxWorks doesn't work with asio serial ports: #define BOOST_ASIO_DISABLE_SERIAL_PORT // TODO: The problem here seems to bee that vxWorks uses its own, very specific // ways to handle serial ports, incompatible with POSIX or anything... // Maybe a specific implementation would be possible, but until the // straight need arises... This implementation would presumably consist // of some vxWorks specific ioctl-calls, etc. Any voluteers? // vxWorks-around: #defines CLOCKS_PER_SEC as sysClkRateGet() but // miserably fails to #include the required to make // sysClkRateGet() available! So we manually include it here. #ifdef __RTP__ # include # include #endif // vxWorks-around: In the macros INT32_C(), UINT32_C(), INT64_C() and // UINT64_C() are defined errorneously, yielding not a signed/ // unsigned long/long long type, but a signed/unsigned int/long // type. Eventually this leads to compile errors in ratio_fwd.hpp, // when trying to define several constants which do not fit into a // long type! We correct them here by redefining. #include // Some macro-magic to do the job #define VX_JOIN(X, Y) VX_DO_JOIN(X, Y) #define VX_DO_JOIN(X, Y) VX_DO_JOIN2(X, Y) #define VX_DO_JOIN2(X, Y) X##Y // Correctly setup the macros #undef INT32_C #undef UINT32_C #undef INT64_C #undef UINT64_C #define INT32_C(x) VX_JOIN(x, L) #define UINT32_C(x) VX_JOIN(x, UL) #define INT64_C(x) VX_JOIN(x, LL) #define UINT64_C(x) VX_JOIN(x, ULL) // #include Libraries required for the following function adaption #include #include #include // Use C-linkage for the following helper functions extern "C" { // vxWorks-around: The required functions getrlimit() and getrlimit() are missing. // But we have the similar functions getprlimit() and setprlimit(), // which may serve the purpose. // Problem: The vxWorks-documentation regarding these functions // doesn't deserve its name! It isn't documented what the first two // parameters idtype and id mean, so we must fall back to an educated // guess - null, argh... :-/ // TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason. // Thus for DKMs there would have to be another implementation. #ifdef __RTP__ inline int getrlimit(int resource, struct rlimit *rlp){ return getprlimit(0, 0, resource, rlp); } inline int setrlimit(int resource, const struct rlimit *rlp){ return setprlimit(0, 0, resource, const_cast(rlp)); } #endif // vxWorks has ftruncate() only, so we do simulate truncate(): inline int truncate(const char *p, off_t l){ int fd = open(p, O_WRONLY); if (fd == -1){ errno = EACCES; return -1; } if (ftruncate(fd, l) == -1){ close(fd); errno = EACCES; return -1; } return close(fd); } // Fake symlink handling by dummy functions: inline int symlink(const char*, const char*){ // vxWorks has no symlinks -> always return an error! errno = EACCES; return -1; } inline ssize_t readlink(const char*, char*, size_t){ // vxWorks has no symlinks -> always return an error! errno = EACCES; return -1; } // vxWorks claims to implement gettimeofday in sys/time.h // but nevertheless does not provide it! See // https://support.windriver.com/olsPortal/faces/maintenance/techtipDetail_noHeader.jspx?docId=16442&contentId=WR_TECHTIP_006256 // We implement a surrogate version here via clock_gettime: inline int gettimeofday(struct timeval *tv, void * /*tzv*/) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); tv->tv_sec = ts.tv_sec; tv->tv_usec = ts.tv_nsec / 1000; return 0; } // vxWorks does provide neither struct tms nor function times()! // We implement an empty dummy-function, simply setting the user // and system time to the half of thew actual system ticks-value // and the child user and system time to 0. // Rather ugly but at least it suppresses compiler errors... // Unfortunately, this of course *does* have an severe impact on // dependant libraries, actually this is chrono only! Here it will // not be possible to correctly use user and system times! But // as vxWorks is lacking the ability to calculate user and system // process times there seems to be no other possible solution. struct tms{ clock_t tms_utime; // User CPU time clock_t tms_stime; // System CPU time clock_t tms_cutime; // User CPU time of terminated child processes clock_t tms_cstime; // System CPU time of terminated child processes }; inline clock_t times(struct tms *t){ struct timespec ts; clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); clock_t ticks(static_cast(static_cast(ts.tv_sec) * CLOCKS_PER_SEC + static_cast(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0)); t->tms_utime = ticks/2U; t->tms_stime = ticks/2U; t->tms_cutime = 0; // vxWorks is lacking the concept of a child process! t->tms_cstime = 0; // -> Set the wait times for childs to 0 return ticks; } } // extern "C" // Put the selfmade functions into the std-namespace, just in case namespace std { # ifdef __RTP__ using ::getrlimit; using ::setrlimit; # endif using ::truncate; using ::symlink; using ::readlink; using ::times; using ::gettimeofday; } // Some more macro-magic: // vxWorks-around: Some functions are not present or broken in vxWorks // but may be patched to life via helper macros... // Include signal.h which might contain a typo to be corrected here #include #define getpagesize() sysconf(_SC_PAGESIZE) // getpagesize is deprecated anyway! #ifndef S_ISSOCK # define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket? #endif #define lstat(p, b) stat(p, b) // lstat() == stat(), as vxWorks has no symlinks! #ifndef FPE_FLTINV # define FPE_FLTINV (FPE_FLTSUB+1) // vxWorks has no FPE_FLTINV, so define one as a dummy #endif #if !defined(BUS_ADRALN) && defined(BUS_ADRALNR) # define BUS_ADRALN BUS_ADRALNR // Correct a supposed typo in vxWorks' #endif //typedef int locale_t; // locale_t is a POSIX-extension, currently unpresent in vxWorks! // #include boilerplate code: #include // vxWorks lies about XSI conformance, there is no nl_types.h: #undef BOOST_HAS_NL_TYPES_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/platform/win32.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Bill Kempf 2001. // (C) Copyright Aleksey Gurtovoy 2003. // (C) Copyright Rene Rivera 2005. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Win32 specific config options: #define BOOST_PLATFORM "Win32" // Get the information about the MinGW runtime, i.e. __MINGW32_*VERSION. #if defined(__MINGW32__) # include <_mingw.h> #endif #if defined(__GNUC__) && !defined(BOOST_NO_SWPRINTF) # define BOOST_NO_SWPRINTF #endif // Default defines for BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT // If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport), // its boost/config/compiler/ file must define BOOST_SYMBOL_EXPORT and // BOOST_SYMBOL_IMPORT #ifndef BOOST_SYMBOL_EXPORT # define BOOST_HAS_DECLSPEC # define BOOST_SYMBOL_EXPORT __declspec(dllexport) # define BOOST_SYMBOL_IMPORT __declspec(dllimport) #endif #if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) # define BOOST_HAS_STDINT_H # ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS # endif # define BOOST_HAS_DIRENT_H # define BOOST_HAS_UNISTD_H #endif #if defined(__MINGW32__) && (__GNUC__ >= 4) // Mingw has these functions but there are persistent problems // with calls to these crashing, so disable for now: //# define BOOST_HAS_EXPM1 //# define BOOST_HAS_LOG1P # define BOOST_HAS_GETTIMEOFDAY #endif // // Win32 will normally be using native Win32 threads, // but there is a pthread library avaliable as an option, // we used to disable this when BOOST_DISABLE_WIN32 was // defined but no longer - this should allow some // files to be compiled in strict mode - while maintaining // a consistent setting of BOOST_HAS_THREADS across // all translation units (needed for shared_ptr etc). // #ifndef BOOST_HAS_PTHREADS # define BOOST_HAS_WINTHREADS #endif // // WinCE configuration: // #if defined(_WIN32_WCE) || defined(UNDER_CE) # define BOOST_NO_ANSI_APIS // Windows CE does not have a conforming signature for swprintf # define BOOST_NO_SWPRINTF #else # define BOOST_HAS_GETSYSTEMTIMEASFILETIME # define BOOST_HAS_THREADEX # define BOOST_HAS_GETSYSTEMTIMEASFILETIME #endif // // Windows Runtime // #if defined(WINAPI_FAMILY) && \ (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) # define BOOST_NO_ANSI_APIS #endif #ifndef BOOST_DISABLE_WIN32 // WEK: Added #define BOOST_HAS_FTIME #define BOOST_WINDOWS 1 #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/posix_features.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // All POSIX feature tests go in this file, // Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well // _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's // may be present but none-functional unless _POSIX_C_SOURCE and // _XOPEN_SOURCE have been defined to the right value (it's up // to the user to do this *before* including any header, although // in most cases the compiler will do this for you). # if defined(BOOST_HAS_UNISTD_H) # include // XOpen has , but is this the correct version check? # if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3) # define BOOST_HAS_NL_TYPES_H # endif // POSIX version 6 requires # if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100) # define BOOST_HAS_STDINT_H # endif // POSIX version 2 requires # if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L) # define BOOST_HAS_DIRENT_H # endif // POSIX version 3 requires to have sigaction: # if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) # define BOOST_HAS_SIGACTION # endif // POSIX defines _POSIX_THREADS > 0 for pthread support, // however some platforms define _POSIX_THREADS without // a value, hence the (_POSIX_THREADS+0 >= 0) check. // Strictly speaking this may catch platforms with a // non-functioning stub , but such occurrences should // occur very rarely if at all. # if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS) # define BOOST_HAS_PTHREADS # endif // BOOST_HAS_NANOSLEEP: // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME: # if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \ || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) # define BOOST_HAS_NANOSLEEP # endif // BOOST_HAS_CLOCK_GETTIME: // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME // but at least one platform - linux - defines that flag without // defining clock_gettime): # if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) # define BOOST_HAS_CLOCK_GETTIME # endif // BOOST_HAS_SCHED_YIELD: // This is predicated on _POSIX_PRIORITY_SCHEDULING or // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME. # if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\ || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\ || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) # define BOOST_HAS_SCHED_YIELD # endif // BOOST_HAS_GETTIMEOFDAY: // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE: // These are predicated on _XOPEN_VERSION, and appears to be first released // in issue 4, version 2 (_XOPEN_VERSION > 500). // Likewise for the functions log1p and expm1. # if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500) # define BOOST_HAS_GETTIMEOFDAY # if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500) # define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # endif # ifndef BOOST_HAS_LOG1P # define BOOST_HAS_LOG1P # endif # ifndef BOOST_HAS_EXPM1 # define BOOST_HAS_EXPM1 # endif # endif # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/requires_threads.hpp ================================================ // (C) Copyright John Maddock 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_CONFIG_REQUIRES_THREADS_HPP #define BOOST_CONFIG_REQUIRES_THREADS_HPP #ifndef BOOST_CONFIG_HPP # include #endif #if defined(BOOST_DISABLE_THREADS) // // special case to handle versions of gcc which don't currently support threads: // #if defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC_MINOR__ <= 3) || !defined(BOOST_STRICT_CONFIG)) // // this is checked up to gcc 3.3: // #if defined(__sgi) || defined(__hpux) # error "Multi-threaded programs are not supported by gcc on HPUX or Irix (last checked with gcc 3.3)" #endif #endif # error "Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS" #elif !defined(BOOST_HAS_THREADS) # if defined __COMO__ // Comeau C++ # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_MT (Windows) or -D_REENTRANT (Unix)" #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) // Intel #ifdef _WIN32 # error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" #else # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -openmp" #endif # elif defined __GNUC__ // GNU C++: # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" #elif defined __sgi // SGI MIPSpro C++ # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_SGI_MP_SOURCE" #elif defined __DECCXX // Compaq Tru64 Unix cxx # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread" #elif defined __BORLANDC__ // Borland # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -tWM" #elif defined __MWERKS__ // Metrowerks CodeWarrior # error "Compiler threading support is not turned on. Please set the correct command line options for threading: either -runtime sm, -runtime smd, -runtime dm, or -runtime dmd" #elif defined __SUNPRO_CC // Sun Workshop Compiler C++ # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" #elif defined __HP_aCC // HP aCC # error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" #elif defined(__IBMCPP__) // IBM Visual Age # error "Compiler threading support is not turned on. Please compile the code with the xlC_r compiler" #elif defined _MSC_VER // Microsoft Visual C++ // // Must remain the last #elif since some other vendors (Metrowerks, for // example) also #define _MSC_VER # error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" #else # error "Compiler threading support is not turned on. Please consult your compiler's documentation for the appropriate options to use" #endif // compilers #endif // BOOST_HAS_THREADS #endif // BOOST_CONFIG_REQUIRES_THREADS_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/select_compiler_config.hpp ================================================ // Boost compiler configuration selection header file // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Martin Wille 2003. // (C) Copyright Guillaume Melquiond 2003. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/ for most recent version. // locate which compiler we are using and define // BOOST_COMPILER_CONFIG as needed: #if defined __CUDACC__ // NVIDIA CUDA C++ compiler for GPU # include "boost/config/compiler/nvcc.hpp" #endif #if defined(__GCCXML__) // GCC-XML emulates other compilers, it has to appear first here! # define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" #elif defined(_CRAYC) // EDG based Cray compiler: # define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp" #elif defined __COMO__ // Comeau C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" #elif defined(__PATHSCALE__) && (__PATHCC__ >= 4) // PathScale EKOPath compiler (has to come before clang and gcc) # define BOOST_COMPILER_CONFIG "boost/config/compiler/pathscale.hpp" #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) // Intel # define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp" #elif defined __clang__ && !defined(__CUDACC__) && !defined(__ibmxl__) // when using clang and cuda at same time, you want to appear as gcc // Clang C++ emulates GCC, so it has to appear early. # define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp" #elif defined __DMC__ // Digital Mars C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" # elif defined(__GNUC__) && !defined(__ibmxl__) // GNU C++: # define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp" #elif defined __KCC // Kai C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp" #elif defined __sgi // SGI MIPSpro C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp" #elif defined __DECCXX // Compaq Tru64 Unix cxx # define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp" #elif defined __ghs // Greenhills C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp" #elif defined __CODEGEARC__ // CodeGear - must be checked for before Borland # define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp" #elif defined __BORLANDC__ // Borland # define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp" #elif defined __MWERKS__ // Metrowerks CodeWarrior # define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp" #elif defined __SUNPRO_CC // Sun Workshop Compiler C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp" #elif defined __HP_aCC // HP aCC # define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp" #elif defined(__MRC__) || defined(__SC__) // MPW MrCpp or SCpp # define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp" #elif defined(__ibmxl__) // IBM XL C/C++ for Linux (Little Endian) # define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp.hpp" #elif defined(__IBMCPP__) // IBM Visual Age or IBM XL C/C++ for Linux (Big Endian) # define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp" #elif defined(__PGI) // Portland Group Inc. # define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp" #elif defined _MSC_VER // Microsoft Visual C++ // // Must remain the last #elif since some other vendors (Metrowerks, for // example) also #define _MSC_VER # define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp" #elif defined (BOOST_ASSERT_CONFIG) // this must come last - generate an error if we don't // recognise the compiler: # error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)" #endif #if 0 // // This section allows dependency scanners to find all the headers we *might* include: // #include "boost/config/compiler/gcc_xml.hpp" #include "boost/config/compiler/cray.hpp" #include "boost/config/compiler/comeau.hpp" #include "boost/config/compiler/pathscale.hpp" #include "boost/config/compiler/intel.hpp" #include "boost/config/compiler/clang.hpp" #include "boost/config/compiler/digitalmars.hpp" #include "boost/config/compiler/gcc.hpp" #include "boost/config/compiler/kai.hpp" #include "boost/config/compiler/sgi_mipspro.hpp" #include "boost/config/compiler/compaq_cxx.hpp" #include "boost/config/compiler/greenhills.hpp" #include "boost/config/compiler/codegear.hpp" #include "boost/config/compiler/borland.hpp" #include "boost/config/compiler/metrowerks.hpp" #include "boost/config/compiler/sunpro_cc.hpp" #include "boost/config/compiler/hp_acc.hpp" #include "boost/config/compiler/mpw.hpp" #include "boost/config/compiler/vacpp.hpp" #include "boost/config/compiler/pgi.hpp" #include "boost/config/compiler/visualc.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/select_platform_config.hpp ================================================ // Boost compiler configuration selection header file // (C) Copyright John Maddock 2001 - 2002. // (C) Copyright Jens Maurer 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. // Note that we define the headers to include using "header_name" not // in order to prevent macro expansion within the header // name (for example "linux" is a macro on linux systems). #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) // linux, also other platforms (Hurd etc) that use GLIBC, should these really have their own config headers though? # define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp" #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) // BSD: # define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp" #elif defined(sun) || defined(__sun) // solaris: # define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp" #elif defined(__sgi) // SGI Irix: # define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp" #elif defined(__hpux) // hp unix: # define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp" #elif defined(__CYGWIN__) // cygwin is not win32: # define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp" #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) // win32: # define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp" #elif defined(__HAIKU__) // Haiku # define BOOST_PLATFORM_CONFIG "boost/config/platform/haiku.hpp" #elif defined(__BEOS__) // BeOS # define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp" #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) // MacOS # define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp" #elif defined(__IBMCPP__) || defined(_AIX) // IBM # define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp" #elif defined(__amigaos__) // AmigaOS # define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp" #elif defined(__QNXNTO__) // QNX: # define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp" #elif defined(__VXWORKS__) // vxWorks: # define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp" #elif defined(__SYMBIAN32__) // Symbian: # define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp" #elif defined(_CRAYC) // Cray: # define BOOST_PLATFORM_CONFIG "boost/config/platform/cray.hpp" #elif defined(__VMS) // VMS: # define BOOST_PLATFORM_CONFIG "boost/config/platform/vms.hpp" #elif defined(__CloudABI__) // Nuxi CloudABI: # define BOOST_PLATFORM_CONFIG "boost/config/platform/cloudabi.hpp" #else # if defined(unix) \ || defined(__unix) \ || defined(_XOPEN_SOURCE) \ || defined(_POSIX_SOURCE) // generic unix platform: # ifndef BOOST_HAS_UNISTD_H # define BOOST_HAS_UNISTD_H # endif # include # endif # if defined (BOOST_ASSERT_CONFIG) // this must come last - generate an error if we don't // recognise the platform: # error "Unknown platform - please configure and report the results to boost.org" # endif #endif #if 0 // // This section allows dependency scanners to find all the files we *might* include: // # include "boost/config/platform/linux.hpp" # include "boost/config/platform/bsd.hpp" # include "boost/config/platform/solaris.hpp" # include "boost/config/platform/irix.hpp" # include "boost/config/platform/hpux.hpp" # include "boost/config/platform/cygwin.hpp" # include "boost/config/platform/win32.hpp" # include "boost/config/platform/beos.hpp" # include "boost/config/platform/macos.hpp" # include "boost/config/platform/aix.hpp" # include "boost/config/platform/amigaos.hpp" # include "boost/config/platform/qnxnto.hpp" # include "boost/config/platform/vxworks.hpp" # include "boost/config/platform/symbian.hpp" # include "boost/config/platform/cray.hpp" # include "boost/config/platform/vms.hpp" # include #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/select_stdlib_config.hpp ================================================ // Boost compiler configuration selection header file // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001 - 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: // First include to determine if some version of STLport is in use as the std lib // (do not rely on this header being included since users can short-circuit this header // if they know whose std lib they are using.) #ifdef __cplusplus # include #else # include #endif #if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) // STLPort library; this _must_ come first, otherwise since // STLport typically sits on top of some other library, we // can end up detecting that first rather than STLport: # define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp" #else // If our std lib was not some version of STLport, and has not otherwise // been detected, then include as it is about // the smallest of the std lib headers that includes real C++ stuff. // Some std libs do not include their C++-related macros in // so this additional include makes sure we get those definitions. // Note: do not rely on this header being included since users can short-circuit this // #include if they know whose std lib they are using. #if !defined(__LIBCOMO__) && !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER)\ && !defined(_LIBCPP_VERSION) && !defined(__GLIBCPP__) && !defined(__GLIBCXX__)\ && !defined(__STL_CONFIG_H) && !defined(__MSL_CPP__) && !defined(__IBMCPP__)\ && !defined(MSIPL_COMPILE_H) && !defined(_YVALS) && !defined(_CPPLIB_VER) #include #endif #if defined(__LIBCOMO__) // Comeau STL: #define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp" #elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) // Rogue Wave library: # define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp" #elif defined(_LIBCPP_VERSION) // libc++ # define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcpp.hpp" #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) // GNU libstdc++ 3 # define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp" #elif defined(__STL_CONFIG_H) // generic SGI STL # define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp" #elif defined(__MSL_CPP__) // MSL standard lib: # define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp" #elif defined(__IBMCPP__) // take the default VACPP std lib # define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp" #elif defined(MSIPL_COMPILE_H) // Modena C++ standard library # define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp" #elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) // Dinkumware Library (this has to appear after any possible replacement libraries): # define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp" #elif defined (BOOST_ASSERT_CONFIG) // this must come last - generate an error if we don't // recognise the library: # error "Unknown standard library - please configure and report the results to boost.org" #endif #endif #if 0 // // This section allows dependency scanners to find all the files we *might* include: // # include "boost/config/stdlib/stlport.hpp" # include "boost/config/stdlib/libcomo.hpp" # include "boost/config/stdlib/roguewave.hpp" # include "boost/config/stdlib/libcpp.hpp" # include "boost/config/stdlib/libstdcpp3.hpp" # include "boost/config/stdlib/sgi.hpp" # include "boost/config/stdlib/msl.hpp" # include "boost/config/stdlib/vacpp.hpp" # include "boost/config/stdlib/modena.hpp" # include "boost/config/stdlib/dinkumware.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/dinkumware.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001. // (C) Copyright Peter Dimov 2001. // (C) Copyright David Abrahams 2002. // (C) Copyright Guillaume Melquiond 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Dinkumware standard library config: #if !defined(_YVALS) && !defined(_CPPLIB_VER) #include #if !defined(_YVALS) && !defined(_CPPLIB_VER) #error This is not the Dinkumware lib! #endif #endif #if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 306) // full dinkumware 3.06 and above // fully conforming provided the compiler supports it: # if !(defined(_GLOBAL_USING) && (_GLOBAL_USING+0 > 0)) && !defined(__BORLANDC__) && !defined(_STD) && !(defined(__ICC) && (__ICC >= 700)) // can be defined in yvals.h # define BOOST_NO_STDC_NAMESPACE # endif # if !(defined(_HAS_MEMBER_TEMPLATES_REBIND) && (_HAS_MEMBER_TEMPLATES_REBIND+0 > 0)) && !(defined(_MSC_VER) && (_MSC_VER > 1300)) && defined(BOOST_MSVC) # define BOOST_NO_STD_ALLOCATOR # endif # define BOOST_HAS_PARTIAL_STD_ALLOCATOR # if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) // if this lib version is set up for vc6 then there is no std::use_facet: # define BOOST_NO_STD_USE_FACET # define BOOST_HAS_TWO_ARG_USE_FACET // C lib functions aren't in namespace std either: # define BOOST_NO_STDC_NAMESPACE // and nor is # define BOOST_NO_EXCEPTION_STD_NAMESPACE # endif // There's no numeric_limits support unless _LONGLONG is defined: # if !defined(_LONGLONG) && (_CPPLIB_VER <= 310) # define BOOST_NO_MS_INT64_NUMERIC_LIMITS # endif // 3.06 appears to have (non-sgi versions of) & , // and no at all #else # define BOOST_MSVC_STD_ITERATOR 1 # define BOOST_NO_STD_ITERATOR # define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS # define BOOST_NO_STD_ALLOCATOR # define BOOST_NO_STDC_NAMESPACE # define BOOST_NO_STD_USE_FACET # define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN # define BOOST_HAS_MACRO_USE_FACET # ifndef _CPPLIB_VER // Updated Dinkum library defines this, and provides // its own min and max definitions, as does MTA version. # ifndef __MTA__ # define BOOST_NO_STD_MIN_MAX # endif # define BOOST_NO_MS_INT64_NUMERIC_LIMITS # endif #endif // // std extension namespace is stdext for vc7.1 and later, // the same applies to other compilers that sit on top // of vc7.1 (Intel and Comeau): // #if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(__BORLANDC__) # define BOOST_STD_EXTENSION_NAMESPACE stdext #endif #if (defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(__BORLANDC__)) || !defined(_CPPLIB_VER) || (_CPPLIB_VER < 306) // if we're using a dinkum lib that's // been configured for VC6/7 then there is // no iterator traits (true even for icl) # define BOOST_NO_STD_ITERATOR_TRAITS #endif #if defined(__ICL) && (__ICL < 800) && defined(_CPPLIB_VER) && (_CPPLIB_VER <= 310) // Intel C++ chokes over any non-trivial use of // this may be an overly restrictive define, but regex fails without it: # define BOOST_NO_STD_LOCALE #endif // Fix for VC++ 8.0 on up ( I do not have a previous version to test ) // or clang-cl. If exceptions are off you must manually include the // header before including the header. Admittedly // trying to use Boost libraries or the standard C++ libraries without // exception support is not suggested but currently clang-cl ( v 3.4 ) // does not support exceptions and must be compiled with exceptions off. #if !_HAS_EXCEPTIONS && ((defined(BOOST_MSVC) && BOOST_MSVC >= 1400) || (defined(__clang__) && defined(_MSC_VER))) #include #endif #include #if ( (!_HAS_EXCEPTIONS && !defined(__ghs__)) || (!_HAS_NAMESPACE && defined(__ghs__)) ) && !defined(__TI_COMPILER_VERSION__) && !defined(__VISUALDSPVERSION__) # define BOOST_NO_STD_TYPEINFO #endif // C++0x headers implemented in 520 (as shipped by Microsoft) // #if !defined(_CPPLIB_VER) || _CPPLIB_VER < 520 # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_SMART_PTR #endif #if ((!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE)) \ && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 610) # define BOOST_NO_CXX11_HDR_TUPLE #endif // C++0x headers implemented in 540 (as shipped by Microsoft) // #if !defined(_CPPLIB_VER) || _CPPLIB_VER < 540 # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_ATOMIC_SMART_PTR #endif // C++0x headers implemented in 610 (as shipped by Microsoft) // #if !defined(_CPPLIB_VER) || _CPPLIB_VER < 610 # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_ALLOCATOR // 540 has std::align but it is not a conforming implementation # define BOOST_NO_CXX11_STD_ALIGN #endif #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #elif !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #if defined(BOOST_INTEL) && (BOOST_INTEL <= 1400) // Intel's compiler can't handle this header yet: # define BOOST_NO_CXX11_HDR_ATOMIC #endif // 520..610 have std::addressof, but it doesn't support functions // #if !defined(_CPPLIB_VER) || _CPPLIB_VER < 650 # define BOOST_NO_CXX11_ADDRESSOF #endif // Bug specific to VC14, // See https://connect.microsoft.com/VisualStudio/feedback/details/1348277/link-error-when-using-std-codecvt-utf8-utf16-char16-t // and discussion here: http://blogs.msdn.com/b/vcblog/archive/2014/11/12/visual-studio-2015-preview-now-available.aspx?PageIndex=2 #if defined(_CPPLIB_VER) && (_CPPLIB_VER == 650) # define BOOST_NO_CXX11_HDR_CODECVT #endif #if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 650) // If _HAS_AUTO_PTR_ETC is defined to 0, std::auto_ptr is not available. // See https://www.visualstudio.com/en-us/news/vs2015-vs.aspx#C++ // and http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx # if defined(_HAS_AUTO_PTR_ETC) && (_HAS_AUTO_PTR_ETC == 0) # define BOOST_NO_AUTO_PTR # endif #endif #ifdef _CPPLIB_VER # define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER #else # define BOOST_DINKUMWARE_STDLIB 1 #endif #ifdef _CPPLIB_VER # define BOOST_STDLIB "Dinkumware standard library version " BOOST_STRINGIZE(_CPPLIB_VER) #else # define BOOST_STDLIB "Dinkumware standard library version 1.x" #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/libcomo.hpp ================================================ // (C) Copyright John Maddock 2002 - 2003. // (C) Copyright Jens Maurer 2002 - 2003. // (C) Copyright Beman Dawes 2002 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Comeau STL: #if !defined(__LIBCOMO__) # include # if !defined(__LIBCOMO__) # error "This is not the Comeau STL!" # endif #endif // // std::streambuf is non-standard // NOTE: versions of libcomo prior to beta28 have octal version numbering, // e.g. version 25 is 21 (dec) #if __LIBCOMO_VERSION__ <= 22 # define BOOST_NO_STD_WSTREAMBUF #endif #if (__LIBCOMO_VERSION__ <= 31) && defined(_WIN32) #define BOOST_NO_SWPRINTF #endif #if __LIBCOMO_VERSION__ >= 31 # define BOOST_HAS_HASH # define BOOST_HAS_SLIST #endif // C++0x headers not yet implemented // # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #else # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif // // Intrinsic type_traits support. // The SGI STL has it's own __type_traits class, which // has intrinsic compiler support with SGI's compilers. // Whatever map SGI style type traits to boost equivalents: // #define BOOST_HAS_SGI_TYPE_TRAITS #define BOOST_STDLIB "Comeau standard library " BOOST_STRINGIZE(__LIBCOMO_VERSION__) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/libcpp.hpp ================================================ // (C) Copyright Christopher Jefferson 2011. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // config for libc++ // Might need more in here later. #if !defined(_LIBCPP_VERSION) # include # if !defined(_LIBCPP_VERSION) # error "This is not libc++!" # endif #endif #define BOOST_STDLIB "libc++ version " BOOST_STRINGIZE(_LIBCPP_VERSION) #define BOOST_HAS_THREADS #ifdef _LIBCPP_HAS_NO_VARIADICS # define BOOST_NO_CXX11_HDR_TUPLE #endif // BOOST_NO_CXX11_ALLOCATOR should imply no support for the C++11 // allocator model. The C++11 allocator model requires a conforming // std::allocator_traits which is only possible with C++11 template // aliases since members rebind_alloc and rebind_traits require it. #if defined(_LIBCPP_HAS_NO_TEMPLATE_ALIASES) # define BOOST_NO_CXX11_ALLOCATOR #endif #if __cplusplus < 201103 # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #endif // // These appear to be unusable/incomplete so far: // # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_HDR_ATOMIC // libc++ uses a non-standard messages_base #define BOOST_NO_STD_MESSAGES #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus <= 201103 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif // --- end --- ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/libstdcpp3.hpp ================================================ // (C) Copyright John Maddock 2001. // (C) Copyright Jens Maurer 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // config for libstdc++ v3 // not much to go in here: #define BOOST_GNU_STDLIB 1 #ifdef __GLIBCXX__ #define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__) #else #define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__) #endif #if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T) # define BOOST_NO_CWCHAR # define BOOST_NO_CWCTYPE # define BOOST_NO_STD_WSTRING # define BOOST_NO_STD_WSTREAMBUF #endif #if defined(__osf__) && !defined(_REENTRANT) \ && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) ) // GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header // file is included, therefore for consistency we define it here as well. # define _REENTRANT #endif #ifdef __GLIBCXX__ // gcc 3.4 and greater: # if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \ || defined(_GLIBCXX__PTHREADS) \ || defined(_GLIBCXX_HAS_GTHREADS) \ || defined(_WIN32) \ || defined(_AIX) \ || defined(__HAIKU__) // // If the std lib has thread support turned on, then turn it on in Boost // as well. We do this because some gcc-3.4 std lib headers define _REENTANT // while others do not... // # define BOOST_HAS_THREADS # else # define BOOST_DISABLE_THREADS # endif #elif defined(__GLIBCPP__) \ && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \ && !defined(_GLIBCPP__PTHREADS) // disable thread support if the std lib was built single threaded: # define BOOST_DISABLE_THREADS #endif #if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT) // linux on arm apparently doesn't define _REENTRANT // so just turn on threading support whenever the std lib is thread safe: # define BOOST_HAS_THREADS #endif #if !defined(_GLIBCPP_USE_LONG_LONG) \ && !defined(_GLIBCXX_USE_LONG_LONG)\ && defined(BOOST_HAS_LONG_LONG) // May have been set by compiler/*.hpp, but "long long" without library // support is useless. # undef BOOST_HAS_LONG_LONG #endif // Apple doesn't seem to reliably defined a *unix* macro #if !defined(CYGWIN) && ( defined(__unix__) \ || defined(__unix) \ || defined(unix) \ || defined(__APPLE__) \ || defined(__APPLE) \ || defined(APPLE)) # include #endif #if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0 # define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx # define BOOST_HAS_SLIST # define BOOST_HAS_HASH # define BOOST_SLIST_HEADER # if !defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) # define BOOST_HASH_SET_HEADER # define BOOST_HASH_MAP_HEADER # else # define BOOST_HASH_SET_HEADER # define BOOST_HASH_MAP_HEADER # endif #endif // // Decide whether we have C++11 support turned on: // #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103) # define BOOST_LIBSTDCXX11 #endif // // Decide which version of libstdc++ we have, normally // stdlibc++ C++0x support is detected via __GNUC__, __GNUC_MINOR__, and possibly // __GNUC_PATCHLEVEL__ at the suggestion of Jonathan Wakely, one of the stdlibc++ // developers. He also commented: // // "I'm not sure how useful __GLIBCXX__ is for your purposes, for instance in // GCC 4.2.4 it is set to 20080519 but in GCC 4.3.0 it is set to 20080305. // Although 4.3.0 was released earlier than 4.2.4, it has better C++0x support // than any release in the 4.2 series." // // Another resource for understanding stdlibc++ features is: // http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#manual.intro.status.standard.200x // // However, using the GCC version number fails when the compiler is clang since this // only ever claims to emulate GCC-4.2, see https://svn.boost.org/trac/boost/ticket/7473 // for a long discussion on this issue. What we can do though is use clang's __has_include // to detect the presence of a C++11 header that was introduced with a specific GCC release. // We still have to be careful though as many such headers were buggy and/or incomplete when // first introduced, so we only check for headers that were fully featured from day 1, and then // use that to infer the underlying GCC version: // #ifdef __clang__ #if __has_include() # define BOOST_LIBSTDCXX_VERSION 50100 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40900 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40800 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40700 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40600 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40500 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40400 #elif __has_include() # define BOOST_LIBSTDCXX_VERSION 40300 #endif // // GCC 4.8 and 9 add working versions of and respectively. // However, we have no test for these as the headers were present but broken // in early GCC versions. // #endif #if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) && (__cplusplus >= 201103L) // // Oracle Solaris compiler uses it's own verison of libstdc++ but doesn't // set __GNUC__ // #define BOOST_LIBSTDCXX_VERSION 40800 #endif #if !defined(BOOST_LIBSTDCXX_VERSION) # define BOOST_LIBSTDCXX_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif // C++0x headers in GCC 4.3.0 and later // #if (BOOST_LIBSTDCXX_VERSION < 40300) || !defined(BOOST_LIBSTDCXX11) # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_HDR_FUNCTIONAL #endif // C++0x headers in GCC 4.4.0 and later // #if (BOOST_LIBSTDCXX_VERSION < 40400) || !defined(BOOST_LIBSTDCXX11) # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_SMART_PTR #else # define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG # define BOOST_HAS_TR1_COMPLEX_OVERLOADS #endif // C++0x features in GCC 4.5.0 and later // #if (BOOST_LIBSTDCXX_VERSION < 40500) || !defined(BOOST_LIBSTDCXX11) # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_RANDOM #endif // C++0x features in GCC 4.6.0 and later // #if (BOOST_LIBSTDCXX_VERSION < 40600) || !defined(BOOST_LIBSTDCXX11) # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_ADDRESSOF #endif // C++0x features in GCC 4.7.0 and later // #if (BOOST_LIBSTDCXX_VERSION < 40700) || !defined(BOOST_LIBSTDCXX11) // Note that although existed prior to 4.7, "steady_clock" is spelled "monotonic_clock" // so 4.7.0 is the first truely conforming one. # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_ALLOCATOR #endif // C++0x features in GCC 4.8.0 and later // #if (BOOST_LIBSTDCXX_VERSION < 40800) || !defined(BOOST_LIBSTDCXX11) // Note that although existed prior to gcc 4.8 it was largely unimplemented for many types: # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_HDR_THREAD #endif // C++0x features in GCC 4.9.0 and later // #if (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) // Although is present and compilable against, the actual implementation is not functional // even for the simplest patterns such as "\d" or "[0-9]". This is the case at least in gcc up to 4.8, inclusively. # define BOOST_NO_CXX11_HDR_REGEX #endif #if defined(__clang_major__) && ((__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 7))) // As of clang-3.6, libstdc++ header throws up errors with clang: # define BOOST_NO_CXX11_HDR_ATOMIC #endif // // C++0x features in GCC 5.1 and later // #if (BOOST_LIBSTDCXX_VERSION < 50100) || !defined(BOOST_LIBSTDCXX11) # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_STD_ALIGN #endif #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus <= 201103 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #elif __cplusplus < 201402 || (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif // // Headers not present on Solaris with the Oracle compiler: #if defined(__SUNPRO_CC) #define BOOST_NO_CXX11_HDR_FUTURE #define BOOST_NO_CXX11_HDR_FORWARD_LIST #define BOOST_NO_CXX11_HDR_ATOMIC // shared_ptr is present, but is not convertible to bool // which causes all kinds of problems especially in Boost.Thread // but probably elsewhere as well. #define BOOST_NO_CXX11_SMART_PTR #endif #if (!defined(_GLIBCXX_HAS_GTHREADS) || !defined(_GLIBCXX_USE_C99_STDINT_TR1)) // Headers not always available: # ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # endif # ifndef BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_MUTEX # endif # ifndef BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_THREAD # endif # ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX # define BOOST_NO_CXX14_HDR_SHARED_MUTEX # endif #endif #if (!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK) || (_GTHREAD_USE_MUTEX_TIMEDLOCK == 0)) && !defined(BOOST_NO_CXX11_HDR_MUTEX) // Timed mutexes are not always available: # define BOOST_NO_CXX11_HDR_MUTEX #endif // --- end --- ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/modena.hpp ================================================ // (C) Copyright Jens Maurer 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Modena C++ standard library (comes with KAI C++) #if !defined(MSIPL_COMPILE_H) # include # if !defined(__MSIPL_COMPILE_H) # error "This is not the Modena C++ library!" # endif #endif #ifndef MSIPL_NL_TYPES #define BOOST_NO_STD_MESSAGES #endif #ifndef MSIPL_WCHART #define BOOST_NO_STD_WSTRING #endif // C++0x headers not yet implemented // # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #else # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #define BOOST_STDLIB "Modena C++ standard library" ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/msl.hpp ================================================ // (C) Copyright John Maddock 2001. // (C) Copyright Darin Adler 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Metrowerks standard library: #ifndef __MSL_CPP__ # include # ifndef __MSL_CPP__ # error This is not the MSL standard library! # endif #endif #if __MSL_CPP__ >= 0x6000 // Pro 6 # define BOOST_HAS_HASH # define BOOST_STD_EXTENSION_NAMESPACE Metrowerks #endif #define BOOST_HAS_SLIST #if __MSL_CPP__ < 0x6209 # define BOOST_NO_STD_MESSAGES #endif // check C lib version for #include #if defined(__MSL__) && (__MSL__ >= 0x5000) # define BOOST_HAS_STDINT_H # if !defined(__PALMOS_TRAPS__) # define BOOST_HAS_UNISTD_H # endif // boilerplate code: # include #endif #if defined(_MWMT) || _MSL_THREADSAFE # define BOOST_HAS_THREADS #endif #ifdef _MSL_NO_EXPLICIT_FUNC_TEMPLATE_ARG # define BOOST_NO_STD_USE_FACET # define BOOST_HAS_TWO_ARG_USE_FACET #endif // C++0x headers not yet implemented // # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #else # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/roguewave.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Jens Maurer 2001. // (C) Copyright David Abrahams 2003. // (C) Copyright Boris Gubenko 2007. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // Rogue Wave std lib: #define BOOST_RW_STDLIB 1 #if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) # include # if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) # error This is not the Rogue Wave standard library # endif #endif // // figure out a consistent version number: // #ifndef _RWSTD_VER # define BOOST_RWSTD_VER 0x010000 #elif _RWSTD_VER < 0x010000 # define BOOST_RWSTD_VER (_RWSTD_VER << 8) #else # define BOOST_RWSTD_VER _RWSTD_VER #endif #ifndef _RWSTD_VER # define BOOST_STDLIB "Rogue Wave standard library version (Unknown version)" #elif _RWSTD_VER < 0x04010200 # define BOOST_STDLIB "Rogue Wave standard library version " BOOST_STRINGIZE(_RWSTD_VER) #else # ifdef _RWSTD_VER_STR # define BOOST_STDLIB "Apache STDCXX standard library version " _RWSTD_VER_STR # else # define BOOST_STDLIB "Apache STDCXX standard library version " BOOST_STRINGIZE(_RWSTD_VER) # endif #endif // // Prior to version 2.2.0 the primary template for std::numeric_limits // does not have compile time constants, even though specializations of that // template do: // #if BOOST_RWSTD_VER < 0x020200 # define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS #endif // Sun CC 5.5 patch 113817-07 adds long long specialization, but does not change the // library version number (http://sunsolve6.sun.com/search/document.do?assetkey=1-21-113817): #if BOOST_RWSTD_VER <= 0x020101 && (!defined(__SUNPRO_CC) || (__SUNPRO_CC < 0x550)) # define BOOST_NO_LONG_LONG_NUMERIC_LIMITS # endif // // Borland version of numeric_limits lacks __int64 specialisation: // #ifdef __BORLANDC__ # define BOOST_NO_MS_INT64_NUMERIC_LIMITS #endif // // No std::iterator if it can't figure out default template args: // #if defined(_RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || defined(RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || (BOOST_RWSTD_VER < 0x020000) # define BOOST_NO_STD_ITERATOR #endif // // No iterator traits without partial specialization: // #if defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) || defined(RWSTD_NO_CLASS_PARTIAL_SPEC) # define BOOST_NO_STD_ITERATOR_TRAITS #endif // // Prior to version 2.0, std::auto_ptr was buggy, and there were no // new-style iostreams, and no conformant std::allocator: // #if (BOOST_RWSTD_VER < 0x020000) # define BOOST_NO_AUTO_PTR # define BOOST_NO_STRINGSTREAM # define BOOST_NO_STD_ALLOCATOR # define BOOST_NO_STD_LOCALE #endif // // No template iterator constructors without member template support: // #if defined(RWSTD_NO_MEMBER_TEMPLATES) || defined(_RWSTD_NO_MEMBER_TEMPLATES) # define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #endif // // RW defines _RWSTD_ALLOCATOR if the allocator is conformant and in use // (the or _HPACC_ part is a hack - the library seems to define _RWSTD_ALLOCATOR // on HP aCC systems even though the allocator is in fact broken): // #if !defined(_RWSTD_ALLOCATOR) || (defined(__HP_aCC) && __HP_aCC <= 33100) # define BOOST_NO_STD_ALLOCATOR #endif // // If we have a std::locale, we still may not have std::use_facet: // #if defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined(BOOST_NO_STD_LOCALE) # define BOOST_NO_STD_USE_FACET # define BOOST_HAS_TWO_ARG_USE_FACET #endif // // There's no std::distance prior to version 2, or without // partial specialization support: // #if (BOOST_RWSTD_VER < 0x020000) || defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) #define BOOST_NO_STD_DISTANCE #endif // // Some versions of the rogue wave library don't have assignable // OutputIterators: // #if BOOST_RWSTD_VER < 0x020100 # define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN #endif // // Disable BOOST_HAS_LONG_LONG when the library has no support for it. // #if !defined(_RWSTD_LONG_LONG) && defined(BOOST_HAS_LONG_LONG) # undef BOOST_HAS_LONG_LONG #endif // // check that on HP-UX, the proper RW library is used // #if defined(__HP_aCC) && !defined(_HP_NAMESPACE_STD) # error "Boost requires Standard RW library. Please compile and link with -AA" #endif // // Define macros specific to RW V2.2 on HP-UX // #if defined(__HP_aCC) && (BOOST_RWSTD_VER == 0x02020100) # ifndef __HP_TC1_MAKE_PAIR # define __HP_TC1_MAKE_PAIR # endif # ifndef _HP_INSTANTIATE_STD2_VL # define _HP_INSTANTIATE_STD2_VL # endif #endif #if _RWSTD_VER < 0x05000000 # define BOOST_NO_CXX11_HDR_ARRAY #endif // type_traits header is incomplete: # define BOOST_NO_CXX11_HDR_TYPE_TRAITS // // C++0x headers not yet implemented // # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #else # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/sgi.hpp ================================================ // (C) Copyright John Maddock 2001 - 2003. // (C) Copyright Darin Adler 2001. // (C) Copyright Jens Maurer 2001 - 2003. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // generic SGI STL: #if !defined(__STL_CONFIG_H) # include # if !defined(__STL_CONFIG_H) # error "This is not the SGI STL!" # endif #endif // // No std::iterator traits without partial specialisation: // #if !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) # define BOOST_NO_STD_ITERATOR_TRAITS #endif // // No std::stringstream with gcc < 3 // #if defined(__GNUC__) && (__GNUC__ < 3) && \ ((__GNUC_MINOR__ < 95) || (__GNUC_MINOR__ == 96)) && \ !defined(__STL_USE_NEW_IOSTREAMS) || \ defined(__APPLE_CC__) // Note that we only set this for GNU C++ prior to 2.95 since the // latest patches for that release do contain a minimal // If you are running a 2.95 release prior to 2.95.3 then this will need // setting, but there is no way to detect that automatically (other // than by running the configure script). // Also, the unofficial GNU C++ 2.96 included in RedHat 7.1 doesn't // have . # define BOOST_NO_STRINGSTREAM #endif // Apple doesn't seem to reliably defined a *unix* macro #if !defined(CYGWIN) && ( defined(__unix__) \ || defined(__unix) \ || defined(unix) \ || defined(__APPLE__) \ || defined(__APPLE) \ || defined(APPLE)) # include #endif // // Assume no std::locale without own iostreams (this may be an // incorrect assumption in some cases): // #if !defined(__SGI_STL_OWN_IOSTREAMS) && !defined(__STL_USE_NEW_IOSTREAMS) # define BOOST_NO_STD_LOCALE #endif // // Original native SGI streams have non-standard std::messages facet: // #if defined(__sgi) && (_COMPILER_VERSION <= 650) && !defined(__SGI_STL_OWN_IOSTREAMS) # define BOOST_NO_STD_LOCALE #endif // // SGI's new iostreams have missing "const" in messages<>::open // #if defined(__sgi) && (_COMPILER_VERSION <= 740) && defined(__STL_USE_NEW_IOSTREAMS) # define BOOST_NO_STD_MESSAGES #endif // // No template iterator constructors, or std::allocator // without member templates: // #if !defined(__STL_MEMBER_TEMPLATES) # define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS # define BOOST_NO_STD_ALLOCATOR #endif // // We always have SGI style hash_set, hash_map, and slist: // #define BOOST_HAS_HASH #define BOOST_HAS_SLIST // // If this is GNU libstdc++2, then no and no std::wstring: // #if (defined(__GNUC__) && (__GNUC__ < 3)) # include # if defined(__BASTRING__) # define BOOST_NO_LIMITS // Note: will provide compile-time constants # undef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS # define BOOST_NO_STD_WSTRING # endif #endif // // There is no standard iterator unless we have namespace support: // #if !defined(__STL_USE_NAMESPACES) # define BOOST_NO_STD_ITERATOR #endif // // Intrinsic type_traits support. // The SGI STL has it's own __type_traits class, which // has intrinsic compiler support with SGI's compilers. // Whatever map SGI style type traits to boost equivalents: // #define BOOST_HAS_SGI_TYPE_TRAITS // C++0x headers not yet implemented // # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #else # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #define BOOST_STDLIB "SGI standard library" ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/stlport.hpp ================================================ // (C) Copyright John Maddock 2001 - 2002. // (C) Copyright Darin Adler 2001. // (C) Copyright Jens Maurer 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. // STLPort standard library config: #if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) # include # if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) # error "This is not STLPort!" # endif #endif // Apple doesn't seem to reliably defined a *unix* macro #if !defined(CYGWIN) && ( defined(__unix__) \ || defined(__unix) \ || defined(unix) \ || defined(__APPLE__) \ || defined(__APPLE) \ || defined(APPLE)) # include #endif // // __STL_STATIC_CONST_INIT_BUG implies BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS // for versions prior to 4.1(beta) // #if (defined(__STL_STATIC_CONST_INIT_BUG) || defined(_STLP_STATIC_CONST_INIT_BUG)) && (__SGI_STL_PORT <= 0x400) # define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS #endif // // If STLport thinks that there is no partial specialisation, then there is no // std::iterator traits: // #if !(defined(_STLP_CLASS_PARTIAL_SPECIALIZATION) || defined(__STL_CLASS_PARTIAL_SPECIALIZATION)) # define BOOST_NO_STD_ITERATOR_TRAITS #endif // // No new style iostreams on GCC without STLport's iostreams enabled: // #if (defined(__GNUC__) && (__GNUC__ < 3)) && !(defined(__SGI_STL_OWN_IOSTREAMS) || defined(_STLP_OWN_IOSTREAMS)) # define BOOST_NO_STRINGSTREAM #endif // // No new iostreams implies no std::locale, and no std::stringstream: // #if defined(__STL_NO_IOSTREAMS) || defined(__STL_NO_NEW_IOSTREAMS) || defined(_STLP_NO_IOSTREAMS) || defined(_STLP_NO_NEW_IOSTREAMS) # define BOOST_NO_STD_LOCALE # define BOOST_NO_STRINGSTREAM #endif // // If the streams are not native, and we have a "using ::x" compiler bug // then the io stream facets are not available in namespace std:: // #ifdef _STLPORT_VERSION # if !(_STLPORT_VERSION >= 0x500) && !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) # define BOOST_NO_STD_LOCALE # endif #else # if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) # define BOOST_NO_STD_LOCALE # endif #endif #if defined(_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x520) # define BOOST_HAS_TR1_UNORDERED_SET # define BOOST_HAS_TR1_UNORDERED_MAP #endif // // Without member template support enabled, their are no template // iterate constructors, and no std::allocator: // #if !(defined(__STL_MEMBER_TEMPLATES) || defined(_STLP_MEMBER_TEMPLATES)) # define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS # define BOOST_NO_STD_ALLOCATOR #endif // // however we always have at least a partial allocator: // #define BOOST_HAS_PARTIAL_STD_ALLOCATOR #if !defined(_STLP_MEMBER_TEMPLATE_CLASSES) || defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) # define BOOST_NO_STD_ALLOCATOR #endif #if defined(_STLP_NO_MEMBER_TEMPLATE_KEYWORD) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) # define BOOST_NO_STD_ALLOCATOR #endif // // If STLport thinks there is no wchar_t at all, then we have to disable // the support for the relevant specilazations of std:: templates. // #if !defined(_STLP_HAS_WCHAR_T) && !defined(_STLP_WCHAR_T_IS_USHORT) # ifndef BOOST_NO_STD_WSTRING # define BOOST_NO_STD_WSTRING # endif # ifndef BOOST_NO_STD_WSTREAMBUF # define BOOST_NO_STD_WSTREAMBUF # endif #endif // // We always have SGI style hash_set, hash_map, and slist: // #ifndef _STLP_NO_EXTENSIONS #define BOOST_HAS_HASH #define BOOST_HAS_SLIST #endif // // STLport does a good job of importing names into namespace std::, // but doesn't always get them all, define BOOST_NO_STDC_NAMESPACE, since our // workaround does not conflict with STLports: // // // Harold Howe says: // Borland switched to STLport in BCB6. Defining BOOST_NO_STDC_NAMESPACE with // BCB6 does cause problems. If we detect C++ Builder, then don't define // BOOST_NO_STDC_NAMESPACE // #if !defined(__BORLANDC__) && !defined(__DMC__) // // If STLport is using it's own namespace, and the real names are in // the global namespace, then we duplicate STLport's using declarations // (by defining BOOST_NO_STDC_NAMESPACE), we do this because STLport doesn't // necessarily import all the names we need into namespace std:: // # if (defined(__STL_IMPORT_VENDOR_CSTD) \ || defined(__STL_USE_OWN_NAMESPACE) \ || defined(_STLP_IMPORT_VENDOR_CSTD) \ || defined(_STLP_USE_OWN_NAMESPACE)) \ && (defined(__STL_VENDOR_GLOBAL_CSTD) || defined (_STLP_VENDOR_GLOBAL_CSTD)) # define BOOST_NO_STDC_NAMESPACE # define BOOST_NO_EXCEPTION_STD_NAMESPACE # endif #elif defined(__BORLANDC__) && __BORLANDC__ < 0x560 // STLport doesn't import std::abs correctly: #include namespace std { using ::abs; } // and strcmp/strcpy don't get imported either ('cos they are macros) #include #ifdef strcpy # undef strcpy #endif #ifdef strcmp # undef strcmp #endif #ifdef _STLP_VENDOR_CSTD namespace std{ using _STLP_VENDOR_CSTD::strcmp; using _STLP_VENDOR_CSTD::strcpy; } #endif #endif // // std::use_facet may be non-standard, uses a class instead: // #if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) || defined(_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS) # define BOOST_NO_STD_USE_FACET # define BOOST_HAS_STLP_USE_FACET #endif // // If STLport thinks there are no wide functions, etc. is not working; but // only if BOOST_NO_STDC_NAMESPACE is not defined (if it is then we do the import // into std:: ourselves). // #if defined(_STLP_NO_NATIVE_WIDE_FUNCTIONS) && !defined(BOOST_NO_STDC_NAMESPACE) # define BOOST_NO_CWCHAR # define BOOST_NO_CWCTYPE #endif // // If STLport for some reason was configured so that it thinks that wchar_t // is not an intrinsic type, then we have to disable the support for it as // well (we would be missing required specializations otherwise). // #if !defined( _STLP_HAS_WCHAR_T) || defined(_STLP_WCHAR_T_IS_USHORT) # undef BOOST_NO_INTRINSIC_WCHAR_T # define BOOST_NO_INTRINSIC_WCHAR_T #endif // // Borland ships a version of STLport with C++ Builder 6 that lacks // hashtables and the like: // #if defined(__BORLANDC__) && (__BORLANDC__ == 0x560) # undef BOOST_HAS_HASH #endif // // gcc-2.95.3/STLPort does not like the using declarations we use to get ADL with std::min/max // #if defined(__GNUC__) && (__GNUC__ < 3) # include // for std::min and std::max # define BOOST_USING_STD_MIN() ((void)0) # define BOOST_USING_STD_MAX() ((void)0) namespace boost { using std::min; using std::max; } #endif // C++0x headers not yet implemented // # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #else # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/stdlib/vacpp.hpp ================================================ // (C) Copyright John Maddock 2001 - 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for most recent version. #if __IBMCPP__ <= 501 # define BOOST_NO_STD_ALLOCATOR #endif #define BOOST_HAS_MACRO_USE_FACET #define BOOST_NO_STD_MESSAGES // Apple doesn't seem to reliably defined a *unix* macro #if !defined(CYGWIN) && ( defined(__unix__) \ || defined(__unix) \ || defined(unix) \ || defined(__APPLE__) \ || defined(__APPLE) \ || defined(APPLE)) # include #endif // C++0x headers not yet implemented // # define BOOST_NO_CXX11_HDR_ARRAY # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE # define BOOST_NO_CXX11_HDR_FORWARD_LIST # define BOOST_NO_CXX11_HDR_FUTURE # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_MUTEX # define BOOST_NO_CXX11_HDR_RANDOM # define BOOST_NO_CXX11_HDR_RATIO # define BOOST_NO_CXX11_HDR_REGEX # define BOOST_NO_CXX11_HDR_SYSTEM_ERROR # define BOOST_NO_CXX11_HDR_THREAD # define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TYPE_TRAITS # define BOOST_NO_CXX11_HDR_TYPEINDEX # define BOOST_NO_CXX11_HDR_UNORDERED_MAP # define BOOST_NO_CXX11_HDR_UNORDERED_SET # define BOOST_NO_CXX11_NUMERIC_LIMITS # define BOOST_NO_CXX11_ALLOCATOR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_HDR_FUNCTIONAL # define BOOST_NO_CXX11_HDR_ATOMIC # define BOOST_NO_CXX11_STD_ALIGN # define BOOST_NO_CXX11_ADDRESSOF #if defined(__has_include) #if !__has_include() # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #elif __cplusplus < 201402 # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #else # define BOOST_NO_CXX14_HDR_SHARED_MUTEX #endif #define BOOST_STDLIB "Visual Age default standard library" ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/suffix.hpp ================================================ // Boost config.hpp configuration header file ------------------------------// // boostinspect:ndprecated_macros -- tell the inspect tool to ignore this file // Copyright (c) 2001-2003 John Maddock // Copyright (c) 2001 Darin Adler // Copyright (c) 2001 Peter Dimov // Copyright (c) 2002 Bill Kempf // Copyright (c) 2002 Jens Maurer // Copyright (c) 2002-2003 David Abrahams // Copyright (c) 2003 Gennaro Prota // Copyright (c) 2003 Eric Friedman // Copyright (c) 2010 Eric Jourdanneau, Joel Falcou // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/ for most recent version. // Boost config.hpp policy and rationale documentation has been moved to // http://www.boost.org/libs/config/ // // This file is intended to be stable, and relatively unchanging. // It should contain boilerplate code only - no compiler specific // code unless it is unavoidable - no changes unless unavoidable. #ifndef BOOST_CONFIG_SUFFIX_HPP #define BOOST_CONFIG_SUFFIX_HPP #if defined(__GNUC__) && (__GNUC__ >= 4) // // Some GCC-4.x versions issue warnings even when __extension__ is used, // so use this as a workaround: // #pragma GCC system_header #endif // // ensure that visibility macros are always defined, thus symplifying use // #ifndef BOOST_SYMBOL_EXPORT # define BOOST_SYMBOL_EXPORT #endif #ifndef BOOST_SYMBOL_IMPORT # define BOOST_SYMBOL_IMPORT #endif #ifndef BOOST_SYMBOL_VISIBLE # define BOOST_SYMBOL_VISIBLE #endif // // look for long long by looking for the appropriate macros in . // Note that we use limits.h rather than climits for maximal portability, // remember that since these just declare a bunch of macros, there should be // no namespace issues from this. // #if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG) \ && !defined(BOOST_MSVC) && !defined(__BORLANDC__) # include # if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) # define BOOST_HAS_LONG_LONG # else # define BOOST_NO_LONG_LONG # endif #endif // GCC 3.x will clean up all of those nasty macro definitions that // BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine // it under GCC 3.x. #if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS) # undef BOOST_NO_CTYPE_FUNCTIONS #endif // // Assume any extensions are in namespace std:: unless stated otherwise: // # ifndef BOOST_STD_EXTENSION_NAMESPACE # define BOOST_STD_EXTENSION_NAMESPACE std # endif // // If cv-qualified specializations are not allowed, then neither are cv-void ones: // # if defined(BOOST_NO_CV_SPECIALIZATIONS) \ && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) # define BOOST_NO_CV_VOID_SPECIALIZATIONS # endif // // If there is no numeric_limits template, then it can't have any compile time // constants either! // # if defined(BOOST_NO_LIMITS) \ && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) # define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS # define BOOST_NO_MS_INT64_NUMERIC_LIMITS # define BOOST_NO_LONG_LONG_NUMERIC_LIMITS # endif // // if there is no long long then there is no specialisation // for numeric_limits either: // #if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS) # define BOOST_NO_LONG_LONG_NUMERIC_LIMITS #endif // // if there is no __int64 then there is no specialisation // for numeric_limits<__int64> either: // #if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS) # define BOOST_NO_MS_INT64_NUMERIC_LIMITS #endif // // if member templates are supported then so is the // VC6 subset of member templates: // # if !defined(BOOST_NO_MEMBER_TEMPLATES) \ && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) # define BOOST_MSVC6_MEMBER_TEMPLATES # endif // // Without partial specialization, can't test for partial specialisation bugs: // # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) # define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG # endif // // Without partial specialization, we can't have array-type partial specialisations: // # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) # define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS # endif // // Without partial specialization, std::iterator_traits can't work: // # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_NO_STD_ITERATOR_TRAITS) # define BOOST_NO_STD_ITERATOR_TRAITS # endif // // Without partial specialization, partial // specialization with default args won't work either: // # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) # define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS # endif // // Without member template support, we can't have template constructors // in the standard library either: // # if defined(BOOST_NO_MEMBER_TEMPLATES) \ && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) # define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS # endif // // Without member template support, we can't have a conforming // std::allocator template either: // # if defined(BOOST_NO_MEMBER_TEMPLATES) \ && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ && !defined(BOOST_NO_STD_ALLOCATOR) # define BOOST_NO_STD_ALLOCATOR # endif // // without ADL support then using declarations will break ADL as well: // #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL #endif // // Without typeid support we have no dynamic RTTI either: // #if defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI) # define BOOST_NO_RTTI #endif // // If we have a standard allocator, then we have a partial one as well: // #if !defined(BOOST_NO_STD_ALLOCATOR) # define BOOST_HAS_PARTIAL_STD_ALLOCATOR #endif // // We can't have a working std::use_facet if there is no std::locale: // # if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET) # define BOOST_NO_STD_USE_FACET # endif // // We can't have a std::messages facet if there is no std::locale: // # if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES) # define BOOST_NO_STD_MESSAGES # endif // // We can't have a working std::wstreambuf if there is no std::locale: // # if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF) # define BOOST_NO_STD_WSTREAMBUF # endif // // We can't have a if there is no : // # if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE) # define BOOST_NO_CWCTYPE # endif // // We can't have a swprintf if there is no : // # if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF) # define BOOST_NO_SWPRINTF # endif // // If Win32 support is turned off, then we must turn off // threading support also, unless there is some other // thread API enabled: // #if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \ && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS) # define BOOST_DISABLE_THREADS #endif // // Turn on threading support if the compiler thinks that it's in // multithreaded mode. We put this here because there are only a // limited number of macros that identify this (if there's any missing // from here then add to the appropriate compiler section): // #if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \ || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \ && !defined(BOOST_HAS_THREADS) # define BOOST_HAS_THREADS #endif // // Turn threading support off if BOOST_DISABLE_THREADS is defined: // #if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS) # undef BOOST_HAS_THREADS #endif // // Turn threading support off if we don't recognise the threading API: // #if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\ && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\ && !defined(BOOST_HAS_MPTASKS) # undef BOOST_HAS_THREADS #endif // // Turn threading detail macros off if we don't (want to) use threading // #ifndef BOOST_HAS_THREADS # undef BOOST_HAS_PTHREADS # undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE # undef BOOST_HAS_PTHREAD_YIELD # undef BOOST_HAS_PTHREAD_DELAY_NP # undef BOOST_HAS_WINTHREADS # undef BOOST_HAS_BETHREADS # undef BOOST_HAS_MPTASKS #endif // // If the compiler claims to be C99 conformant, then it had better // have a : // # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) # define BOOST_HAS_STDINT_H # ifndef BOOST_HAS_LOG1P # define BOOST_HAS_LOG1P # endif # ifndef BOOST_HAS_EXPM1 # define BOOST_HAS_EXPM1 # endif # endif // // Define BOOST_NO_SLIST and BOOST_NO_HASH if required. // Note that this is for backwards compatibility only. // # if !defined(BOOST_HAS_SLIST) && !defined(BOOST_NO_SLIST) # define BOOST_NO_SLIST # endif # if !defined(BOOST_HAS_HASH) && !defined(BOOST_NO_HASH) # define BOOST_NO_HASH # endif // // Set BOOST_SLIST_HEADER if not set already: // #if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER) # define BOOST_SLIST_HEADER #endif // // Set BOOST_HASH_SET_HEADER if not set already: // #if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER) # define BOOST_HASH_SET_HEADER #endif // // Set BOOST_HASH_MAP_HEADER if not set already: // #if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER) # define BOOST_HASH_MAP_HEADER #endif // BOOST_HAS_ABI_HEADERS // This macro gets set if we have headers that fix the ABI, // and prevent ODR violations when linking to external libraries: #if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS) # define BOOST_HAS_ABI_HEADERS #endif #if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS) # undef BOOST_HAS_ABI_HEADERS #endif // BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// // Because std::size_t usage is so common, even in boost headers which do not // otherwise use the C library, the workaround is included here so // that ugly workaround code need not appear in many other boost headers. // NOTE WELL: This is a workaround for non-conforming compilers; // must still be #included in the usual places so that inclusion // works as expected with standard conforming compilers. The resulting // double inclusion of is harmless. # if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus) # include namespace std { using ::ptrdiff_t; using ::size_t; } # endif // Workaround for the unfortunate min/max macros defined by some platform headers #define BOOST_PREVENT_MACRO_SUBSTITUTION #ifndef BOOST_USING_STD_MIN # define BOOST_USING_STD_MIN() using std::min #endif #ifndef BOOST_USING_STD_MAX # define BOOST_USING_STD_MAX() using std::max #endif // BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// # if defined(BOOST_NO_STD_MIN_MAX) && defined(__cplusplus) namespace std { template inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { return __b < __a ? __b : __a; } template inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { return __a < __b ? __b : __a; } } # endif // BOOST_STATIC_CONSTANT workaround --------------------------------------- // // On compilers which don't allow in-class initialization of static integral // constant members, we must use enums as a workaround if we want the constants // to be available at compile-time. This macro gives us a convenient way to // declare such constants. # ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION # define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } # else # define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment # endif // BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// // When the standard library does not have a conforming std::use_facet there // are various workarounds available, but they differ from library to library. // The same problem occurs with has_facet. // These macros provide a consistent way to access a locale's facets. // Usage: // replace // std::use_facet(loc); // with // BOOST_USE_FACET(Type, loc); // Note do not add a std:: prefix to the front of BOOST_USE_FACET! // Use for BOOST_HAS_FACET is analogous. #if defined(BOOST_NO_STD_USE_FACET) # ifdef BOOST_HAS_TWO_ARG_USE_FACET # define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast(0)) # define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast(0)) # elif defined(BOOST_HAS_MACRO_USE_FACET) # define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type) # define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type) # elif defined(BOOST_HAS_STLP_USE_FACET) # define BOOST_USE_FACET(Type, loc) (*std::_Use_facet(loc)) # define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) # endif #else # define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc) # define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) #endif // BOOST_NESTED_TEMPLATE workaround ------------------------------------------// // Member templates are supported by some compilers even though they can't use // the A::template member syntax, as a workaround replace: // // typedef typename A::template rebind binder; // // with: // // typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; #ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD # define BOOST_NESTED_TEMPLATE template #else # define BOOST_NESTED_TEMPLATE #endif // BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// // Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION // is defined, in which case it evaluates to return x; Use when you have a return // statement that can never be reached. #ifndef BOOST_UNREACHABLE_RETURN # ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION # define BOOST_UNREACHABLE_RETURN(x) return x; # else # define BOOST_UNREACHABLE_RETURN(x) # endif #endif // BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// // // Some compilers don't support the use of `typename' for dependent // types in deduced contexts, e.g. // // template void f(T, typename T::type); // ^^^^^^^^ // Replace these declarations with: // // template void f(T, BOOST_DEDUCED_TYPENAME T::type); #ifndef BOOST_NO_DEDUCED_TYPENAME # define BOOST_DEDUCED_TYPENAME typename #else # define BOOST_DEDUCED_TYPENAME #endif #ifndef BOOST_NO_TYPENAME_WITH_CTOR # define BOOST_CTOR_TYPENAME typename #else # define BOOST_CTOR_TYPENAME #endif // long long workaround ------------------------------------------// // On gcc (and maybe other compilers?) long long is alway supported // but it's use may generate either warnings (with -ansi), or errors // (with -pedantic -ansi) unless it's use is prefixed by __extension__ // #if defined(BOOST_HAS_LONG_LONG) && defined(__cplusplus) namespace boost{ # ifdef __GNUC__ __extension__ typedef long long long_long_type; __extension__ typedef unsigned long long ulong_long_type; # else typedef long long long_long_type; typedef unsigned long long ulong_long_type; # endif } #endif // same again for __int128: #if defined(BOOST_HAS_INT128) && defined(__cplusplus) namespace boost{ # ifdef __GNUC__ __extension__ typedef __int128 int128_type; __extension__ typedef unsigned __int128 uint128_type; # else typedef __int128 int128_type; typedef unsigned __int128 uint128_type; # endif } #endif // same again for __float128: #if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus) namespace boost { # ifdef __GNUC__ __extension__ typedef __float128 float128_type; # else typedef __float128 float128_type; # endif } #endif // BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// // These macros are obsolete. Port away and remove. # define BOOST_EXPLICIT_TEMPLATE_TYPE(t) # define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) # define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) # define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) # define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) # define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) # define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) # define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) // When BOOST_NO_STD_TYPEINFO is defined, we can just import // the global definition into std namespace: #if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) #include namespace std{ using ::type_info; } #endif // ---------------------------------------------------------------------------// // // Helper macro BOOST_STRINGIZE: // Converts the parameter X to a string after macro replacement // on X has been performed. // #define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) #define BOOST_DO_STRINGIZE(X) #X // // Helper macro BOOST_JOIN: // The following piece of macro magic joins the two // arguments together, even when one of the arguments is // itself a macro (see 16.3.1 in C++ standard). The key // is that macro expansion of macro arguments does not // occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. // #define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) #define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y) #define BOOST_DO_JOIN2( X, Y ) X##Y // // Set some default values for compiler/library/platform names. // These are for debugging config setup only: // # ifndef BOOST_COMPILER # define BOOST_COMPILER "Unknown ISO C++ Compiler" # endif # ifndef BOOST_STDLIB # define BOOST_STDLIB "Unknown ISO standard library" # endif # ifndef BOOST_PLATFORM # if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \ || defined(_POSIX_SOURCE) # define BOOST_PLATFORM "Generic Unix" # else # define BOOST_PLATFORM "Unknown" # endif # endif // // Set some default values GPU support // # ifndef BOOST_GPU_ENABLED # define BOOST_GPU_ENABLED # endif // BOOST_FORCEINLINE ---------------------------------------------// // Macro to use in place of 'inline' to force a function to be inline #if !defined(BOOST_FORCEINLINE) # if defined(_MSC_VER) # define BOOST_FORCEINLINE __forceinline # elif defined(__GNUC__) && __GNUC__ > 3 // Clang also defines __GNUC__ (as 4) # define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) # else # define BOOST_FORCEINLINE inline # endif #endif // BOOST_NOINLINE ---------------------------------------------// // Macro to use in place of 'inline' to prevent a function to be inlined #if !defined(BOOST_NOINLINE) # if defined(_MSC_VER) # define BOOST_NOINLINE __declspec(noinline) # elif defined(__GNUC__) && __GNUC__ > 3 // Clang also defines __GNUC__ (as 4) # if defined(__CUDACC__) // nvcc doesn't always parse __noinline__, // see: https://svn.boost.org/trac/boost/ticket/9392 # define BOOST_NOINLINE __attribute__ ((noinline)) # else # define BOOST_NOINLINE __attribute__ ((__noinline__)) # endif # else # define BOOST_NOINLINE # endif #endif // BOOST_NORETURN ---------------------------------------------// // Macro to use before a function declaration/definition to designate // the function as not returning normally (i.e. with a return statement // or by leaving the function scope, if the function return type is void). #if !defined(BOOST_NORETURN) # if defined(_MSC_VER) # define BOOST_NORETURN __declspec(noreturn) # elif defined(__GNUC__) # define BOOST_NORETURN __attribute__ ((__noreturn__)) # else # define BOOST_NO_NORETURN # define BOOST_NORETURN # endif #endif // Branch prediction hints // These macros are intended to wrap conditional expressions that yield true or false // // if (BOOST_LIKELY(var == 10)) // { // // the most probable code here // } // #if !defined(BOOST_LIKELY) # define BOOST_LIKELY(x) x #endif #if !defined(BOOST_UNLIKELY) # define BOOST_UNLIKELY(x) x #endif // Type and data alignment specification // #if !defined(BOOST_NO_CXX11_ALIGNAS) # define BOOST_ALIGNMENT(x) alignas(x) #elif defined(_MSC_VER) # define BOOST_ALIGNMENT(x) __declspec(align(x)) #elif defined(__GNUC__) # define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x))) #else # define BOOST_NO_ALIGNMENT # define BOOST_ALIGNMENT(x) #endif // Lack of non-public defaulted functions is implied by the lack of any defaulted functions #if !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) && defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) # define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS #endif // Defaulted and deleted function declaration helpers // These macros are intended to be inside a class definition. // BOOST_DEFAULTED_FUNCTION accepts the function declaration and its // body, which will be used if the compiler doesn't support defaulted functions. // BOOST_DELETED_FUNCTION only accepts the function declaration. It // will expand to a private function declaration, if the compiler doesn't support // deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION // in the end of the class definition. // // class my_class // { // public: // // Default-constructible // BOOST_DEFAULTED_FUNCTION(my_class(), {}) // // Copying prohibited // BOOST_DELETED_FUNCTION(my_class(my_class const&)) // BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&)) // }; // #if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)) # define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default; #else # define BOOST_DEFAULTED_FUNCTION(fun, body) fun body #endif #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) # define BOOST_DELETED_FUNCTION(fun) fun = delete; #else # define BOOST_DELETED_FUNCTION(fun) private: fun; #endif // // Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined // #if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) #define BOOST_NO_CXX11_DECLTYPE_N3276 BOOST_NO_CXX11_DECLTYPE #endif // -------------------- Deprecated macros for 1.50 --------------------------- // These will go away in a future release // Use BOOST_NO_CXX11_HDR_UNORDERED_SET or BOOST_NO_CXX11_HDR_UNORDERED_MAP // instead of BOOST_NO_STD_UNORDERED #if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) || defined (BOOST_NO_CXX11_HDR_UNORDERED_SET) # ifndef BOOST_NO_CXX11_STD_UNORDERED # define BOOST_NO_CXX11_STD_UNORDERED # endif #endif // Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST instead of BOOST_NO_INITIALIZER_LISTS #if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_INITIALIZER_LISTS) # define BOOST_NO_INITIALIZER_LISTS #endif // Use BOOST_NO_CXX11_HDR_ARRAY instead of BOOST_NO_0X_HDR_ARRAY #if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_NO_0X_HDR_ARRAY) # define BOOST_NO_0X_HDR_ARRAY #endif // Use BOOST_NO_CXX11_HDR_CHRONO instead of BOOST_NO_0X_HDR_CHRONO #if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_NO_0X_HDR_CHRONO) # define BOOST_NO_0X_HDR_CHRONO #endif // Use BOOST_NO_CXX11_HDR_CODECVT instead of BOOST_NO_0X_HDR_CODECVT #if defined(BOOST_NO_CXX11_HDR_CODECVT) && !defined(BOOST_NO_0X_HDR_CODECVT) # define BOOST_NO_0X_HDR_CODECVT #endif // Use BOOST_NO_CXX11_HDR_CONDITION_VARIABLE instead of BOOST_NO_0X_HDR_CONDITION_VARIABLE #if defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE) && !defined(BOOST_NO_0X_HDR_CONDITION_VARIABLE) # define BOOST_NO_0X_HDR_CONDITION_VARIABLE #endif // Use BOOST_NO_CXX11_HDR_FORWARD_LIST instead of BOOST_NO_0X_HDR_FORWARD_LIST #if defined(BOOST_NO_CXX11_HDR_FORWARD_LIST) && !defined(BOOST_NO_0X_HDR_FORWARD_LIST) # define BOOST_NO_0X_HDR_FORWARD_LIST #endif // Use BOOST_NO_CXX11_HDR_FUTURE instead of BOOST_NO_0X_HDR_FUTURE #if defined(BOOST_NO_CXX11_HDR_FUTURE) && !defined(BOOST_NO_0X_HDR_FUTURE) # define BOOST_NO_0X_HDR_FUTURE #endif // Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST // instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS #ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST # ifndef BOOST_NO_0X_HDR_INITIALIZER_LIST # define BOOST_NO_0X_HDR_INITIALIZER_LIST # endif # ifndef BOOST_NO_INITIALIZER_LISTS # define BOOST_NO_INITIALIZER_LISTS # endif #endif // Use BOOST_NO_CXX11_HDR_MUTEX instead of BOOST_NO_0X_HDR_MUTEX #if defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX) # define BOOST_NO_0X_HDR_MUTEX #endif // Use BOOST_NO_CXX11_HDR_RANDOM instead of BOOST_NO_0X_HDR_RANDOM #if defined(BOOST_NO_CXX11_HDR_RANDOM) && !defined(BOOST_NO_0X_HDR_RANDOM) # define BOOST_NO_0X_HDR_RANDOM #endif // Use BOOST_NO_CXX11_HDR_RATIO instead of BOOST_NO_0X_HDR_RATIO #if defined(BOOST_NO_CXX11_HDR_RATIO) && !defined(BOOST_NO_0X_HDR_RATIO) # define BOOST_NO_0X_HDR_RATIO #endif // Use BOOST_NO_CXX11_HDR_REGEX instead of BOOST_NO_0X_HDR_REGEX #if defined(BOOST_NO_CXX11_HDR_REGEX) && !defined(BOOST_NO_0X_HDR_REGEX) # define BOOST_NO_0X_HDR_REGEX #endif // Use BOOST_NO_CXX11_HDR_SYSTEM_ERROR instead of BOOST_NO_0X_HDR_SYSTEM_ERROR #if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_0X_HDR_SYSTEM_ERROR) # define BOOST_NO_0X_HDR_SYSTEM_ERROR #endif // Use BOOST_NO_CXX11_HDR_THREAD instead of BOOST_NO_0X_HDR_THREAD #if defined(BOOST_NO_CXX11_HDR_THREAD) && !defined(BOOST_NO_0X_HDR_THREAD) # define BOOST_NO_0X_HDR_THREAD #endif // Use BOOST_NO_CXX11_HDR_TUPLE instead of BOOST_NO_0X_HDR_TUPLE #if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_0X_HDR_TUPLE) # define BOOST_NO_0X_HDR_TUPLE #endif // Use BOOST_NO_CXX11_HDR_TYPE_TRAITS instead of BOOST_NO_0X_HDR_TYPE_TRAITS #if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_0X_HDR_TYPE_TRAITS) # define BOOST_NO_0X_HDR_TYPE_TRAITS #endif // Use BOOST_NO_CXX11_HDR_TYPEINDEX instead of BOOST_NO_0X_HDR_TYPEINDEX #if defined(BOOST_NO_CXX11_HDR_TYPEINDEX) && !defined(BOOST_NO_0X_HDR_TYPEINDEX) # define BOOST_NO_0X_HDR_TYPEINDEX #endif // Use BOOST_NO_CXX11_HDR_UNORDERED_MAP instead of BOOST_NO_0X_HDR_UNORDERED_MAP #if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) && !defined(BOOST_NO_0X_HDR_UNORDERED_MAP) # define BOOST_NO_0X_HDR_UNORDERED_MAP #endif // Use BOOST_NO_CXX11_HDR_UNORDERED_SET instead of BOOST_NO_0X_HDR_UNORDERED_SET #if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_NO_0X_HDR_UNORDERED_SET) # define BOOST_NO_0X_HDR_UNORDERED_SET #endif // ------------------ End of deprecated macros for 1.50 --------------------------- // -------------------- Deprecated macros for 1.51 --------------------------- // These will go away in a future release // Use BOOST_NO_CXX11_AUTO_DECLARATIONS instead of BOOST_NO_AUTO_DECLARATIONS #if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_AUTO_DECLARATIONS) # define BOOST_NO_AUTO_DECLARATIONS #endif // Use BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS instead of BOOST_NO_AUTO_MULTIDECLARATIONS #if defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS) && !defined(BOOST_NO_AUTO_MULTIDECLARATIONS) # define BOOST_NO_AUTO_MULTIDECLARATIONS #endif // Use BOOST_NO_CXX11_CHAR16_T instead of BOOST_NO_CHAR16_T #if defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CHAR16_T) # define BOOST_NO_CHAR16_T #endif // Use BOOST_NO_CXX11_CHAR32_T instead of BOOST_NO_CHAR32_T #if defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CHAR32_T) # define BOOST_NO_CHAR32_T #endif // Use BOOST_NO_CXX11_TEMPLATE_ALIASES instead of BOOST_NO_TEMPLATE_ALIASES #if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_TEMPLATE_ALIASES) # define BOOST_NO_TEMPLATE_ALIASES #endif // Use BOOST_NO_CXX11_CONSTEXPR instead of BOOST_NO_CONSTEXPR #if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CONSTEXPR) # define BOOST_NO_CONSTEXPR #endif // Use BOOST_NO_CXX11_DECLTYPE_N3276 instead of BOOST_NO_DECLTYPE_N3276 #if defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_DECLTYPE_N3276) # define BOOST_NO_DECLTYPE_N3276 #endif // Use BOOST_NO_CXX11_DECLTYPE instead of BOOST_NO_DECLTYPE #if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE) # define BOOST_NO_DECLTYPE #endif // Use BOOST_NO_CXX11_DEFAULTED_FUNCTIONS instead of BOOST_NO_DEFAULTED_FUNCTIONS #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_DEFAULTED_FUNCTIONS) # define BOOST_NO_DEFAULTED_FUNCTIONS #endif // Use BOOST_NO_CXX11_DELETED_FUNCTIONS instead of BOOST_NO_DELETED_FUNCTIONS #if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_DELETED_FUNCTIONS) # define BOOST_NO_DELETED_FUNCTIONS #endif // Use BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS instead of BOOST_NO_EXPLICIT_CONVERSION_OPERATORS #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS) # define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS #endif // Use BOOST_NO_CXX11_EXTERN_TEMPLATE instead of BOOST_NO_EXTERN_TEMPLATE #if defined(BOOST_NO_CXX11_EXTERN_TEMPLATE) && !defined(BOOST_NO_EXTERN_TEMPLATE) # define BOOST_NO_EXTERN_TEMPLATE #endif // Use BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS instead of BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS #if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) # define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS #endif // Use BOOST_NO_CXX11_LAMBDAS instead of BOOST_NO_LAMBDAS #if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS) # define BOOST_NO_LAMBDAS #endif // Use BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS instead of BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS #if defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS) && !defined(BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) # define BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS #endif // Use BOOST_NO_CXX11_NOEXCEPT instead of BOOST_NO_NOEXCEPT #if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_NOEXCEPT) # define BOOST_NO_NOEXCEPT #endif // Use BOOST_NO_CXX11_NULLPTR instead of BOOST_NO_NULLPTR #if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR) # define BOOST_NO_NULLPTR #endif // Use BOOST_NO_CXX11_RAW_LITERALS instead of BOOST_NO_RAW_LITERALS #if defined(BOOST_NO_CXX11_RAW_LITERALS) && !defined(BOOST_NO_RAW_LITERALS) # define BOOST_NO_RAW_LITERALS #endif // Use BOOST_NO_CXX11_RVALUE_REFERENCES instead of BOOST_NO_RVALUE_REFERENCES #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES) # define BOOST_NO_RVALUE_REFERENCES #endif // Use BOOST_NO_CXX11_SCOPED_ENUMS instead of BOOST_NO_SCOPED_ENUMS #if defined(BOOST_NO_CXX11_SCOPED_ENUMS) && !defined(BOOST_NO_SCOPED_ENUMS) # define BOOST_NO_SCOPED_ENUMS #endif // Use BOOST_NO_CXX11_STATIC_ASSERT instead of BOOST_NO_STATIC_ASSERT #if defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_NO_STATIC_ASSERT) # define BOOST_NO_STATIC_ASSERT #endif // Use BOOST_NO_CXX11_STD_UNORDERED instead of BOOST_NO_STD_UNORDERED #if defined(BOOST_NO_CXX11_STD_UNORDERED) && !defined(BOOST_NO_STD_UNORDERED) # define BOOST_NO_STD_UNORDERED #endif // Use BOOST_NO_CXX11_UNICODE_LITERALS instead of BOOST_NO_UNICODE_LITERALS #if defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(BOOST_NO_UNICODE_LITERALS) # define BOOST_NO_UNICODE_LITERALS #endif // Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead of BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX #if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX) # define BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX #endif // Use BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of BOOST_NO_VARIADIC_TEMPLATES #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_VARIADIC_TEMPLATES) # define BOOST_NO_VARIADIC_TEMPLATES #endif // Use BOOST_NO_CXX11_VARIADIC_MACROS instead of BOOST_NO_VARIADIC_MACROS #if defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS) # define BOOST_NO_VARIADIC_MACROS #endif // Use BOOST_NO_CXX11_NUMERIC_LIMITS instead of BOOST_NO_NUMERIC_LIMITS_LOWEST #if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_NO_NUMERIC_LIMITS_LOWEST) # define BOOST_NO_NUMERIC_LIMITS_LOWEST #endif // ------------------ End of deprecated macros for 1.51 --------------------------- // // Helper macros BOOST_NOEXCEPT, BOOST_NOEXCEPT_IF, BOOST_NOEXCEPT_EXPR // These aid the transition to C++11 while still supporting C++03 compilers // #ifdef BOOST_NO_CXX11_NOEXCEPT # define BOOST_NOEXCEPT # define BOOST_NOEXCEPT_OR_NOTHROW throw() # define BOOST_NOEXCEPT_IF(Predicate) # define BOOST_NOEXCEPT_EXPR(Expression) false #else # define BOOST_NOEXCEPT noexcept # define BOOST_NOEXCEPT_OR_NOTHROW noexcept # define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) # define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression)) #endif // // Helper macro BOOST_FALLTHROUGH // Fallback definition of BOOST_FALLTHROUGH macro used to mark intended // fall-through between case labels in a switch statement. We use a definition // that requires a semicolon after it to avoid at least one type of misuse even // on unsupported compilers. // #ifndef BOOST_FALLTHROUGH # define BOOST_FALLTHROUGH ((void)0) #endif // // constexpr workarounds // #if defined(BOOST_NO_CXX11_CONSTEXPR) #define BOOST_CONSTEXPR #define BOOST_CONSTEXPR_OR_CONST const #else #define BOOST_CONSTEXPR constexpr #define BOOST_CONSTEXPR_OR_CONST constexpr #endif #if defined(BOOST_NO_CXX14_CONSTEXPR) #define BOOST_CXX14_CONSTEXPR #else #define BOOST_CXX14_CONSTEXPR constexpr #endif // // Unused variable/typedef workarounds: // #ifndef BOOST_ATTRIBUTE_UNUSED # define BOOST_ATTRIBUTE_UNUSED #endif #define BOOST_STATIC_CONSTEXPR static BOOST_CONSTEXPR_OR_CONST // // Set BOOST_HAS_STATIC_ASSERT when BOOST_NO_CXX11_STATIC_ASSERT is not defined // #if !defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_HAS_STATIC_ASSERT) # define BOOST_HAS_STATIC_ASSERT #endif // // Set BOOST_HAS_RVALUE_REFS when BOOST_NO_CXX11_RVALUE_REFERENCES is not defined // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_RVALUE_REFS) #define BOOST_HAS_RVALUE_REFS #endif // // Set BOOST_HAS_VARIADIC_TMPL when BOOST_NO_CXX11_VARIADIC_TEMPLATES is not defined // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_HAS_VARIADIC_TMPL) #define BOOST_HAS_VARIADIC_TMPL #endif // // Set BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS when // BOOST_NO_CXX11_VARIADIC_TEMPLATES is set: // #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS) # define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS #endif // // Finish off with checks for macros that are depricated / no longer supported, // if any of these are set then it's very likely that much of Boost will no // longer work. So stop with a #error for now, but give the user a chance // to continue at their own risk if they really want to: // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_CONFIG_ALLOW_DEPRECATED) # error "You are using a compiler which lacks features which are now a minimum requirement in order to use Boost, define BOOST_CONFIG_ALLOW_DEPRECATED if you want to continue at your own risk!!!" #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/user.hpp ================================================ // boost/config/user.hpp ---------------------------------------------------// // (C) Copyright John Maddock 2001. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // Do not check in modified versions of this file, // This file may be customized by the end user, but not by boost. // // Use this file to define a site and compiler specific // configuration policy: // // define this to locate a compiler config file: // #define BOOST_COMPILER_CONFIG // define this to locate a stdlib config file: // #define BOOST_STDLIB_CONFIG // define this to locate a platform config file: // #define BOOST_PLATFORM_CONFIG // define this to disable compiler config, // use if your compiler config has nothing to set: // #define BOOST_NO_COMPILER_CONFIG // define this to disable stdlib config, // use if your stdlib config has nothing to set: // #define BOOST_NO_STDLIB_CONFIG // define this to disable platform config, // use if your platform config has nothing to set: // #define BOOST_NO_PLATFORM_CONFIG // define this to disable all config options, // excluding the user config. Use if your // setup is fully ISO compliant, and has no // useful extensions, or for autoconf generated // setups: // #define BOOST_NO_CONFIG // define this to make the config "optimistic" // about unknown compiler versions. Normally // unknown compiler versions are assumed to have // all the defects of the last known version, however // setting this flag, causes the config to assume // that unknown compiler versions are fully conformant // with the standard: // #define BOOST_STRICT_CONFIG // define this to cause the config to halt compilation // with an #error if it encounters anything unknown -- // either an unknown compiler version or an unknown // compiler/platform/library: // #define BOOST_ASSERT_CONFIG // define if you want to disable threading support, even // when available: // #define BOOST_DISABLE_THREADS // define when you want to disable Win32 specific features // even when available: // #define BOOST_DISABLE_WIN32 // BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any // prefix/suffix headers that normally control things like struct // packing and alignment. // #define BOOST_DISABLE_ABI_HEADERS // BOOST_ABI_PREFIX: A prefix header to include in place of whatever // boost.config would normally select, any replacement should set up // struct packing and alignment options as required. // #define BOOST_ABI_PREFIX my-header-name // BOOST_ABI_SUFFIX: A suffix header to include in place of whatever // boost.config would normally select, any replacement should undo // the effects of the prefix header. // #define BOOST_ABI_SUFFIX my-header-name // BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, // to be linked as dll's rather than static libraries on Microsoft Windows // (this macro is used to turn on __declspec(dllimport) modifiers, so that // the compiler knows which symbols to look for in a dll rather than in a // static library). Note that there may be some libraries that can only // be linked in one way (statically or dynamically), in these cases this // macro has no effect. // #define BOOST_ALL_DYN_LINK // BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll // rather than a static library on Microsoft Windows: replace the WHATEVER // part of the macro name with the name of the library that you want to // dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or // BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) // modifiers, so that the compiler knows which symbols to look for in a dll // rather than in a static library). // Note that there may be some libraries that can only // be linked in one way (statically or dynamically), // in these cases this macro is unsupported. // #define BOOST_WHATEVER_DYN_LINK // BOOST_ALL_NO_LIB: Tells the config system not to automatically select // which libraries to link against. // Normally if a compiler supports #pragma lib, then the correct library // build variant will be automatically selected and linked against, // simply by the act of including one of that library's headers. // This macro turns that feature off. // #define BOOST_ALL_NO_LIB // BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically // select which library to link against for library "whatever", // replace WHATEVER in the macro name with the name of the library; // for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. // Normally if a compiler supports #pragma lib, then the correct library // build variant will be automatically selected and linked against, simply // by the act of including one of that library's headers. This macro turns // that feature off. // #define BOOST_WHATEVER_NO_LIB // BOOST_LIB_BUILDID: Set to the same value as the value passed to Boost.Build's // --buildid command line option. For example if you built using: // // bjam address-model=64 --buildid=amd64 // // then compile your code with: // // -DBOOST_LIB_BUILDID = amd64 // // to ensure the correct libraries are selected at link time. // #define BOOST_LIB_BUILDID amd64 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config/warning_disable.hpp ================================================ // Copyright John Maddock 2008 // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // This file exists to turn off some overly-pedantic warning emitted // by certain compilers. You should include this header only in: // // * A test case, before any other headers, or, // * A library source file before any other headers. // // IT SHOULD NOT BE INCLUDED BY ANY BOOST HEADER. // // YOU SHOULD NOT INCLUDE IT IF YOU CAN REASONABLY FIX THE WARNING. // // The only warnings disabled here are those that are: // // * Quite unreasonably pedantic. // * Generally only emitted by a single compiler. // * Can't easily be fixed: for example if the vendors own std lib // code emits these warnings! // // Note that THIS HEADER MUST NOT INCLUDE ANY OTHER HEADERS: // not even std library ones! Doing so may turn the warning // off too late to be of any use. For example the VC++ C4996 // warning can be emitted from if that header is included // before or by this one :-( // #ifndef BOOST_CONFIG_WARNING_DISABLE_HPP #define BOOST_CONFIG_WARNING_DISABLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1400) // Error 'function': was declared deprecated // http://msdn2.microsoft.com/en-us/library/ttcz0bys(VS.80).aspx // This error is emitted when you use some perfectly conforming // std lib functions in a perfectly correct way, and also by // some of Microsoft's own std lib code ! # pragma warning(disable:4996) #endif #if defined(__INTEL_COMPILER) || defined(__ICL) // As above: gives warning when a "deprecated" // std library function is encountered. # pragma warning(disable:1786) #endif #endif // BOOST_CONFIG_WARNING_DISABLE_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/config.hpp ================================================ // Boost config.hpp configuration header file ------------------------------// // (C) Copyright John Maddock 2002. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/config for most recent version. // Boost config.hpp policy and rationale documentation has been moved to // http://www.boost.org/libs/config // // CAUTION: This file is intended to be completely stable - // DO NOT MODIFY THIS FILE! // #ifndef BOOST_CONFIG_HPP #define BOOST_CONFIG_HPP // if we don't have a user config, then use the default location: #if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) # define BOOST_USER_CONFIG #if 0 // For dependency trackers: # include #endif #endif // include it first: #ifdef BOOST_USER_CONFIG # include BOOST_USER_CONFIG #endif // if we don't have a compiler config set, try and find one: #if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG) # include #endif // if we have a compiler config, include it now: #ifdef BOOST_COMPILER_CONFIG # include BOOST_COMPILER_CONFIG #endif // if we don't have a std library config set, try and find one: #if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) && defined(__cplusplus) # include #endif // if we have a std library config, include it now: #ifdef BOOST_STDLIB_CONFIG # include BOOST_STDLIB_CONFIG #endif // if we don't have a platform config set, try and find one: #if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG) # include #endif // if we have a platform config, include it now: #ifdef BOOST_PLATFORM_CONFIG # include BOOST_PLATFORM_CONFIG #endif // get config suffix code: #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #endif // BOOST_CONFIG_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/core/enable_if.hpp ================================================ // Boost enable_if library // Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) #ifndef BOOST_CORE_ENABLE_IF_HPP #define BOOST_CORE_ENABLE_IF_HPP #include "boost/config.hpp" // Even the definition of enable_if causes problems on some compilers, // so it's macroed out for all compilers that do not support SFINAE #ifndef BOOST_NO_SFINAE namespace boost { template struct enable_if_has_type { typedef R type; }; template struct enable_if_c { typedef T type; }; template struct enable_if_c {}; template struct enable_if : public enable_if_c {}; template struct lazy_enable_if_c { typedef typename T::type type; }; template struct lazy_enable_if_c {}; template struct lazy_enable_if : public lazy_enable_if_c {}; template struct disable_if_c { typedef T type; }; template struct disable_if_c {}; template struct disable_if : public disable_if_c {}; template struct lazy_disable_if_c { typedef typename T::type type; }; template struct lazy_disable_if_c {}; template struct lazy_disable_if : public lazy_disable_if_c {}; } // namespace boost #else namespace boost { namespace detail { typedef void enable_if_default_T; } template struct enable_if_does_not_work_on_this_compiler; template struct enable_if_has_type : enable_if_does_not_work_on_this_compiler { }; template struct enable_if_c : enable_if_does_not_work_on_this_compiler { }; template struct disable_if_c : enable_if_does_not_work_on_this_compiler { }; template struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler { }; template struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler { }; template struct enable_if : enable_if_does_not_work_on_this_compiler { }; template struct disable_if : enable_if_does_not_work_on_this_compiler { }; template struct lazy_enable_if : enable_if_does_not_work_on_this_compiler { }; template struct lazy_disable_if : enable_if_does_not_work_on_this_compiler { }; } // namespace boost #endif // BOOST_NO_SFINAE #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/core/noncopyable.hpp ================================================ // Boost noncopyable.hpp header file --------------------------------------// // (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/utility for documentation. #ifndef BOOST_CORE_NONCOPYABLE_HPP #define BOOST_CORE_NONCOPYABLE_HPP #include namespace boost { // Private copy constructor and copy assignment ensure classes derived from // class noncopyable cannot be copied. // Contributed by Dave Abrahams namespace noncopyable_ // protection from unintended ADL { class noncopyable { protected: #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) BOOST_CONSTEXPR noncopyable() = default; ~noncopyable() = default; #else noncopyable() {} ~noncopyable() {} #endif #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) noncopyable( const noncopyable& ) = delete; noncopyable& operator=( const noncopyable& ) = delete; #else private: // emphasize the following members are private noncopyable( const noncopyable& ); noncopyable& operator=( const noncopyable& ); #endif }; } typedef noncopyable_::noncopyable noncopyable; } // namespace boost #endif // BOOST_CORE_NONCOPYABLE_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/core/swap.hpp ================================================ // Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #ifndef BOOST_CORE_SWAP_HPP #define BOOST_CORE_SWAP_HPP // Note: the implementation of this utility contains various workarounds: // - swap_impl is put outside the boost namespace, to avoid infinite // recursion (causing stack overflow) when swapping objects of a primitive // type. // - swap_impl has a using-directive, rather than a using-declaration, // because some compilers (including MSVC 7.1, Borland 5.9.3, and // Intel 8.1) don't do argument-dependent lookup when it has a // using-declaration instead. // - boost::swap has two template arguments, instead of one, to // avoid ambiguity when swapping objects of a Boost type that does // not have its own boost::swap overload. #include //for std::swap (C++11) #include //for std::swap (C++98) #include //for std::size_t #include namespace boost_swap_impl { template BOOST_GPU_ENABLED void swap_impl(T& left, T& right) { using namespace std;//use std::swap if argument dependent lookup fails swap(left,right); } template BOOST_GPU_ENABLED void swap_impl(T (& left)[N], T (& right)[N]) { for (std::size_t i = 0; i < N; ++i) { ::boost_swap_impl::swap_impl(left[i], right[i]); } } } namespace boost { template BOOST_GPU_ENABLED void swap(T1& left, T2& right) { ::boost_swap_impl::swap_impl(left, right); } } #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/cstdint.hpp ================================================ // boost cstdint.hpp header file ------------------------------------------// // (C) Copyright Beman Dawes 1999. // (C) Copyright Jens Mauer 2001 // (C) Copyright John Maddock 2001 // Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/integer for documentation. // Revision History // 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) // 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) // 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) // 12 Nov 00 Merged (Jens Maurer) // 23 Sep 00 Added INTXX_C macro support (John Maddock). // 22 Sep 00 Better 64-bit support (John Maddock) // 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost // 8 Aug 99 Initial version (Beman Dawes) #ifndef BOOST_CSTDINT_HPP #define BOOST_CSTDINT_HPP // // Since we always define the INT#_C macros as per C++0x, // define __STDC_CONSTANT_MACROS so that does the right // thing if possible, and so that the user knows that the macros // are actually defined as per C99. // #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include // // Note that GLIBC is a bit inconsistent about whether int64_t is defined or not // depending upon what headers happen to have been included first... // so we disable use of stdint.h when GLIBC does not define __GLIBC_HAVE_LONG_LONG. // See https://svn.boost.org/trac/boost/ticket/3548 and http://sources.redhat.com/bugzilla/show_bug.cgi?id=10990 // #if defined(BOOST_HAS_STDINT_H) \ && (!defined(__GLIBC__) \ || defined(__GLIBC_HAVE_LONG_LONG) \ || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 17))))) // The following #include is an implementation artifact; not part of interface. # ifdef __hpux // HP-UX has a vaguely nice in a non-standard location # include # ifdef __STDC_32_MODE__ // this is triggered with GCC, because it defines __cplusplus < 199707L # define BOOST_NO_INT64_T # endif # elif defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX) # include # else # include // There is a bug in Cygwin two _C macros # if defined(__STDC_CONSTANT_MACROS) && defined(__CYGWIN__) # undef INTMAX_C # undef UINTMAX_C # define INTMAX_C(c) c##LL # define UINTMAX_C(c) c##ULL # endif # endif #if defined(__QNX__) && defined(__EXT_QNX) // QNX (Dinkumware stdlib) defines these as non-standard names. // Reflect to the standard names. typedef ::intleast8_t int_least8_t; typedef ::intfast8_t int_fast8_t; typedef ::uintleast8_t uint_least8_t; typedef ::uintfast8_t uint_fast8_t; typedef ::intleast16_t int_least16_t; typedef ::intfast16_t int_fast16_t; typedef ::uintleast16_t uint_least16_t; typedef ::uintfast16_t uint_fast16_t; typedef ::intleast32_t int_least32_t; typedef ::intfast32_t int_fast32_t; typedef ::uintleast32_t uint_least32_t; typedef ::uintfast32_t uint_fast32_t; # ifndef BOOST_NO_INT64_T typedef ::intleast64_t int_least64_t; typedef ::intfast64_t int_fast64_t; typedef ::uintleast64_t uint_least64_t; typedef ::uintfast64_t uint_fast64_t; # endif #endif namespace boost { using ::int8_t; using ::int_least8_t; using ::int_fast8_t; using ::uint8_t; using ::uint_least8_t; using ::uint_fast8_t; using ::int16_t; using ::int_least16_t; using ::int_fast16_t; using ::uint16_t; using ::uint_least16_t; using ::uint_fast16_t; using ::int32_t; using ::int_least32_t; using ::int_fast32_t; using ::uint32_t; using ::uint_least32_t; using ::uint_fast32_t; # ifndef BOOST_NO_INT64_T using ::int64_t; using ::int_least64_t; using ::int_fast64_t; using ::uint64_t; using ::uint_least64_t; using ::uint_fast64_t; # endif using ::intmax_t; using ::uintmax_t; } // namespace boost #elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) || defined(__VMS) || defined(__SOLARIS9__) || defined(__NetBSD__) // FreeBSD and Tru64 have an that contains much of what we need. # include namespace boost { using ::int8_t; typedef int8_t int_least8_t; typedef int8_t int_fast8_t; using ::uint8_t; typedef uint8_t uint_least8_t; typedef uint8_t uint_fast8_t; using ::int16_t; typedef int16_t int_least16_t; typedef int16_t int_fast16_t; using ::uint16_t; typedef uint16_t uint_least16_t; typedef uint16_t uint_fast16_t; using ::int32_t; typedef int32_t int_least32_t; typedef int32_t int_fast32_t; using ::uint32_t; typedef uint32_t uint_least32_t; typedef uint32_t uint_fast32_t; # ifndef BOOST_NO_INT64_T using ::int64_t; typedef int64_t int_least64_t; typedef int64_t int_fast64_t; using ::uint64_t; typedef uint64_t uint_least64_t; typedef uint64_t uint_fast64_t; typedef int64_t intmax_t; typedef uint64_t uintmax_t; # else typedef int32_t intmax_t; typedef uint32_t uintmax_t; # endif } // namespace boost #else // BOOST_HAS_STDINT_H # include // implementation artifact; not part of interface # include // needed for limits macros namespace boost { // These are fairly safe guesses for some 16-bit, and most 32-bit and 64-bit // platforms. For other systems, they will have to be hand tailored. // // Because the fast types are assumed to be the same as the undecorated types, // it may be possible to hand tailor a more efficient implementation. Such // an optimization may be illusionary; on the Intel x86-family 386 on, for // example, byte arithmetic and load/stores are as fast as "int" sized ones. // 8-bit types ------------------------------------------------------------// # if UCHAR_MAX == 0xff typedef signed char int8_t; typedef signed char int_least8_t; typedef signed char int_fast8_t; typedef unsigned char uint8_t; typedef unsigned char uint_least8_t; typedef unsigned char uint_fast8_t; # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif // 16-bit types -----------------------------------------------------------// # if USHRT_MAX == 0xffff # if defined(__crayx1) // The Cray X1 has a 16-bit short, however it is not recommend // for use in performance critical code. typedef short int16_t; typedef short int_least16_t; typedef int int_fast16_t; typedef unsigned short uint16_t; typedef unsigned short uint_least16_t; typedef unsigned int uint_fast16_t; # else typedef short int16_t; typedef short int_least16_t; typedef short int_fast16_t; typedef unsigned short uint16_t; typedef unsigned short uint_least16_t; typedef unsigned short uint_fast16_t; # endif # elif (USHRT_MAX == 0xffffffff) && defined(__MTA__) // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified // MTA / XMT does support the following non-standard integer types typedef __short16 int16_t; typedef __short16 int_least16_t; typedef __short16 int_fast16_t; typedef unsigned __short16 uint16_t; typedef unsigned __short16 uint_least16_t; typedef unsigned __short16 uint_fast16_t; # elif (USHRT_MAX == 0xffffffff) && defined(CRAY) // no 16-bit types on Cray: typedef short int_least16_t; typedef short int_fast16_t; typedef unsigned short uint_least16_t; typedef unsigned short uint_fast16_t; # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif // 32-bit types -----------------------------------------------------------// # if UINT_MAX == 0xffffffff typedef int int32_t; typedef int int_least32_t; typedef int int_fast32_t; typedef unsigned int uint32_t; typedef unsigned int uint_least32_t; typedef unsigned int uint_fast32_t; # elif (USHRT_MAX == 0xffffffff) typedef short int32_t; typedef short int_least32_t; typedef short int_fast32_t; typedef unsigned short uint32_t; typedef unsigned short uint_least32_t; typedef unsigned short uint_fast32_t; # elif ULONG_MAX == 0xffffffff typedef long int32_t; typedef long int_least32_t; typedef long int_fast32_t; typedef unsigned long uint32_t; typedef unsigned long uint_least32_t; typedef unsigned long uint_fast32_t; # elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) // Integers are 64 bits on the MTA / XMT typedef __int32 int32_t; typedef __int32 int_least32_t; typedef __int32 int_fast32_t; typedef unsigned __int32 uint32_t; typedef unsigned __int32 uint_least32_t; typedef unsigned __int32 uint_fast32_t; # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif // 64-bit types + intmax_t and uintmax_t ----------------------------------// # if defined(BOOST_HAS_LONG_LONG) && \ !defined(BOOST_MSVC) && !defined(__BORLANDC__) && \ (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \ (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) # if defined(__hpux) // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions # elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) // 2**64 - 1 # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif typedef ::boost::long_long_type intmax_t; typedef ::boost::ulong_long_type uintmax_t; typedef ::boost::long_long_type int64_t; typedef ::boost::long_long_type int_least64_t; typedef ::boost::long_long_type int_fast64_t; typedef ::boost::ulong_long_type uint64_t; typedef ::boost::ulong_long_type uint_least64_t; typedef ::boost::ulong_long_type uint_fast64_t; # elif ULONG_MAX != 0xffffffff # if ULONG_MAX == 18446744073709551615 // 2**64 - 1 typedef long intmax_t; typedef unsigned long uintmax_t; typedef long int64_t; typedef long int_least64_t; typedef long int_fast64_t; typedef unsigned long uint64_t; typedef unsigned long uint_least64_t; typedef unsigned long uint_fast64_t; # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif # elif defined(__GNUC__) && defined(BOOST_HAS_LONG_LONG) __extension__ typedef long long intmax_t; __extension__ typedef unsigned long long uintmax_t; __extension__ typedef long long int64_t; __extension__ typedef long long int_least64_t; __extension__ typedef long long int_fast64_t; __extension__ typedef unsigned long long uint64_t; __extension__ typedef unsigned long long uint_least64_t; __extension__ typedef unsigned long long uint_fast64_t; # elif defined(BOOST_HAS_MS_INT64) // // we have Borland/Intel/Microsoft __int64: // typedef __int64 intmax_t; typedef unsigned __int64 uintmax_t; typedef __int64 int64_t; typedef __int64 int_least64_t; typedef __int64 int_fast64_t; typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint_least64_t; typedef unsigned __int64 uint_fast64_t; # else // assume no 64-bit integers # define BOOST_NO_INT64_T typedef int32_t intmax_t; typedef uint32_t uintmax_t; # endif } // namespace boost #endif // BOOST_HAS_STDINT_H // intptr_t/uintptr_t are defined separately because they are optional and not universally available #if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H) // Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h #include #endif // PGI seems to not support intptr_t/uintptr_t properly. BOOST_HAS_STDINT_H is not defined for this compiler by Boost.Config. #if !defined(__PGIC__) #if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \ || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \ || defined(__CYGWIN__) \ || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(sun) namespace boost { using ::intptr_t; using ::uintptr_t; } #define BOOST_HAS_INTPTR_T // Clang pretends to be GCC, so it'll match this condition #elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__) namespace boost { typedef __INTPTR_TYPE__ intptr_t; typedef __UINTPTR_TYPE__ uintptr_t; } #define BOOST_HAS_INTPTR_T #endif #endif // !defined(__PGIC__) #endif // BOOST_CSTDINT_HPP /**************************************************** Macro definition section: Added 23rd September 2000 (John Maddock). Modified 11th September 2001 to be excluded when BOOST_HAS_STDINT_H is defined (John Maddock). Modified 11th Dec 2009 to always define the INT#_C macros if they're not already defined (John Maddock). ******************************************************/ #if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \ (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C)) // // For the following code we get several warnings along the lines of: // // boost/cstdint.hpp:428:35: error: use of C99 long long integer constant // // So we declare this a system header to suppress these warnings. // #if defined(__GNUC__) && (__GNUC__ >= 4) #pragma GCC system_header #endif #include # define BOOST__STDC_CONSTANT_MACROS_DEFINED # if defined(BOOST_HAS_MS_INT64) // // Borland/Intel/Microsoft compilers have width specific suffixes: // #ifndef INT8_C # define INT8_C(value) value##i8 #endif #ifndef INT16_C # define INT16_C(value) value##i16 #endif #ifndef INT32_C # define INT32_C(value) value##i32 #endif #ifndef INT64_C # define INT64_C(value) value##i64 #endif # ifdef __BORLANDC__ // Borland bug: appending ui8 makes the type a signed char # define UINT8_C(value) static_cast(value##u) # else # define UINT8_C(value) value##ui8 # endif #ifndef UINT16_C # define UINT16_C(value) value##ui16 #endif #ifndef UINT32_C # define UINT32_C(value) value##ui32 #endif #ifndef UINT64_C # define UINT64_C(value) value##ui64 #endif #ifndef INTMAX_C # define INTMAX_C(value) value##i64 # define UINTMAX_C(value) value##ui64 #endif # else // do it the old fashioned way: // 8-bit types ------------------------------------------------------------// # if (UCHAR_MAX == 0xff) && !defined(INT8_C) # define INT8_C(value) static_cast(value) # define UINT8_C(value) static_cast(value##u) # endif // 16-bit types -----------------------------------------------------------// # if (USHRT_MAX == 0xffff) && !defined(INT16_C) # define INT16_C(value) static_cast(value) # define UINT16_C(value) static_cast(value##u) # endif // 32-bit types -----------------------------------------------------------// #ifndef INT32_C # if (UINT_MAX == 0xffffffff) # define INT32_C(value) value # define UINT32_C(value) value##u # elif ULONG_MAX == 0xffffffff # define INT32_C(value) value##L # define UINT32_C(value) value##uL # endif #endif // 64-bit types + intmax_t and uintmax_t ----------------------------------// #ifndef INT64_C # if defined(BOOST_HAS_LONG_LONG) && \ (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX) || defined(_ULLONG_MAX) || defined(_LLONG_MAX)) # if defined(__hpux) // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions # define INT64_C(value) value##LL # define UINT64_C(value) value##uLL # elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || \ (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || \ (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) || \ (defined(_ULLONG_MAX) && _ULLONG_MAX == 18446744073709551615ULL) || \ (defined(_LLONG_MAX) && _LLONG_MAX == 9223372036854775807LL) # define INT64_C(value) value##LL # define UINT64_C(value) value##uLL # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif # elif ULONG_MAX != 0xffffffff # if ULONG_MAX == 18446744073709551615U // 2**64 - 1 # define INT64_C(value) value##L # define UINT64_C(value) value##uL # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif # elif defined(BOOST_HAS_LONG_LONG) // Usual macros not defined, work things out for ourselves: # if(~0uLL == 18446744073709551615ULL) # define INT64_C(value) value##LL # define UINT64_C(value) value##uLL # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif # ifdef BOOST_NO_INT64_T # define INTMAX_C(value) INT32_C(value) # define UINTMAX_C(value) UINT32_C(value) # else # define INTMAX_C(value) INT64_C(value) # define UINTMAX_C(value) UINT64_C(value) # endif #endif # endif // Borland/Microsoft specific width suffixes #endif // INT#_C macros. ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/current_function.hpp ================================================ #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED #define BOOST_CURRENT_FUNCTION_HPP_INCLUDED // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif // // boost/current_function.hpp - BOOST_CURRENT_FUNCTION // // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // // http://www.boost.org/libs/assert/current_function.html // namespace boost { namespace detail { inline void current_function_helper() { #if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ #elif defined(__DMC__) && (__DMC__ >= 0x810) # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ #elif defined(__FUNCSIG__) # define BOOST_CURRENT_FUNCTION __FUNCSIG__ #elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) # define BOOST_CURRENT_FUNCTION __FUNCTION__ #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) # define BOOST_CURRENT_FUNCTION __FUNC__ #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) # define BOOST_CURRENT_FUNCTION __func__ #elif defined(__cplusplus) && (__cplusplus >= 201103) # define BOOST_CURRENT_FUNCTION __func__ #else # define BOOST_CURRENT_FUNCTION "(unknown)" #endif } } // namespace detail } // namespace boost #endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/detail/is_xxx.hpp ================================================ // Copyright David Abrahams 2005. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_DETAIL_IS_XXX_DWA20051011_HPP # define BOOST_DETAIL_IS_XXX_DWA20051011_HPP # include # include # include # define BOOST_DETAIL_IS_XXX_DEF(name, qualified_name, nargs) \ template \ struct is_##name : mpl::false_ \ { \ }; \ \ template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) > \ struct is_##name< \ qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) > \ > \ : mpl::true_ \ { \ }; #endif // BOOST_DETAIL_IS_XXX_DWA20051011_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/detail/iterator.hpp ================================================ // (C) Copyright David Abrahams 2002. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef ITERATOR_DWA122600_HPP_ #define ITERATOR_DWA122600_HPP_ // This header is obsolete and will be deprecated. #include namespace boost { namespace detail { using std::iterator_traits; using std::distance; } // namespace detail } // namespace boost #endif // ITERATOR_DWA122600_HPP_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/detail/workaround.hpp ================================================ // Copyright David Abrahams 2002. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef WORKAROUND_DWA2002126_HPP # define WORKAROUND_DWA2002126_HPP // Compiler/library version workaround macro // // Usage: // // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // // workaround for eVC4 and VC6 // ... // workaround code here // #endif // // When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the // first argument must be undefined or expand to a numeric // value. The above expands to: // // (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 // // When used for workarounds that apply to the latest known version // and all earlier versions of a compiler, the following convention // should be observed: // // #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) // // The version number in this case corresponds to the last version in // which the workaround was known to have been required. When // BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro // BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates // the workaround for any version of the compiler. When // BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or // error will be issued if the compiler version exceeds the argument // to BOOST_TESTED_AT(). This can be used to locate workarounds which // may be obsoleted by newer versions. # ifndef BOOST_STRICT_CONFIG #include #ifndef __BORLANDC__ #define __BORLANDC___WORKAROUND_GUARD 1 #else #define __BORLANDC___WORKAROUND_GUARD 0 #endif #ifndef __CODEGEARC__ #define __CODEGEARC___WORKAROUND_GUARD 1 #else #define __CODEGEARC___WORKAROUND_GUARD 0 #endif #ifndef _MSC_VER #define _MSC_VER_WORKAROUND_GUARD 1 #else #define _MSC_VER_WORKAROUND_GUARD 0 #endif #ifndef _MSC_FULL_VER #define _MSC_FULL_VER_WORKAROUND_GUARD 1 #else #define _MSC_FULL_VER_WORKAROUND_GUARD 0 #endif #ifndef BOOST_MSVC #define BOOST_MSVC_WORKAROUND_GUARD 1 #else #define BOOST_MSVC_WORKAROUND_GUARD 0 #endif #ifndef BOOST_MSVC_FULL_VER #define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 1 #else #define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 0 #endif #ifndef __GNUC__ #define __GNUC___WORKAROUND_GUARD 1 #else #define __GNUC___WORKAROUND_GUARD 0 #endif #ifndef __GNUC_MINOR__ #define __GNUC_MINOR___WORKAROUND_GUARD 1 #else #define __GNUC_MINOR___WORKAROUND_GUARD 0 #endif #ifndef __GNUC_PATCHLEVEL__ #define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1 #else #define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0 #endif #ifndef __IBMCPP__ #define __IBMCPP___WORKAROUND_GUARD 1 #else #define __IBMCPP___WORKAROUND_GUARD 0 #endif #ifndef __SUNPRO_CC #define __SUNPRO_CC_WORKAROUND_GUARD 1 #else #define __SUNPRO_CC_WORKAROUND_GUARD 0 #endif #ifndef __DECCXX_VER #define __DECCXX_VER_WORKAROUND_GUARD 1 #else #define __DECCXX_VER_WORKAROUND_GUARD 0 #endif #ifndef __MWERKS__ #define __MWERKS___WORKAROUND_GUARD 1 #else #define __MWERKS___WORKAROUND_GUARD 0 #endif #ifndef __EDG__ #define __EDG___WORKAROUND_GUARD 1 #else #define __EDG___WORKAROUND_GUARD 0 #endif #ifndef __EDG_VERSION__ #define __EDG_VERSION___WORKAROUND_GUARD 1 #else #define __EDG_VERSION___WORKAROUND_GUARD 0 #endif #ifndef __HP_aCC #define __HP_aCC_WORKAROUND_GUARD 1 #else #define __HP_aCC_WORKAROUND_GUARD 0 #endif #ifndef __hpxstd98 #define __hpxstd98_WORKAROUND_GUARD 1 #else #define __hpxstd98_WORKAROUND_GUARD 0 #endif #ifndef _CRAYC #define _CRAYC_WORKAROUND_GUARD 1 #else #define _CRAYC_WORKAROUND_GUARD 0 #endif #ifndef __DMC__ #define __DMC___WORKAROUND_GUARD 1 #else #define __DMC___WORKAROUND_GUARD 0 #endif #ifndef MPW_CPLUS #define MPW_CPLUS_WORKAROUND_GUARD 1 #else #define MPW_CPLUS_WORKAROUND_GUARD 0 #endif #ifndef __COMO__ #define __COMO___WORKAROUND_GUARD 1 #else #define __COMO___WORKAROUND_GUARD 0 #endif #ifndef __COMO_VERSION__ #define __COMO_VERSION___WORKAROUND_GUARD 1 #else #define __COMO_VERSION___WORKAROUND_GUARD 0 #endif #ifndef __INTEL_COMPILER #define __INTEL_COMPILER_WORKAROUND_GUARD 1 #else #define __INTEL_COMPILER_WORKAROUND_GUARD 0 #endif #ifndef __ICL #define __ICL_WORKAROUND_GUARD 1 #else #define __ICL_WORKAROUND_GUARD 0 #endif #ifndef _COMPILER_VERSION #define _COMPILER_VERSION_WORKAROUND_GUARD 1 #else #define _COMPILER_VERSION_WORKAROUND_GUARD 0 #endif #ifndef _RWSTD_VER #define _RWSTD_VER_WORKAROUND_GUARD 1 #else #define _RWSTD_VER_WORKAROUND_GUARD 0 #endif #ifndef BOOST_RWSTD_VER #define BOOST_RWSTD_VER_WORKAROUND_GUARD 1 #else #define BOOST_RWSTD_VER_WORKAROUND_GUARD 0 #endif #ifndef __GLIBCPP__ #define __GLIBCPP___WORKAROUND_GUARD 1 #else #define __GLIBCPP___WORKAROUND_GUARD 0 #endif #ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC #define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1 #else #define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0 #endif #ifndef __SGI_STL_PORT #define __SGI_STL_PORT_WORKAROUND_GUARD 1 #else #define __SGI_STL_PORT_WORKAROUND_GUARD 0 #endif #ifndef _STLPORT_VERSION #define _STLPORT_VERSION_WORKAROUND_GUARD 1 #else #define _STLPORT_VERSION_WORKAROUND_GUARD 0 #endif #ifndef __LIBCOMO_VERSION__ #define __LIBCOMO_VERSION___WORKAROUND_GUARD 1 #else #define __LIBCOMO_VERSION___WORKAROUND_GUARD 0 #endif #ifndef _CPPLIB_VER #define _CPPLIB_VER_WORKAROUND_GUARD 1 #else #define _CPPLIB_VER_WORKAROUND_GUARD 0 #endif #ifndef BOOST_INTEL_CXX_VERSION #define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1 #else #define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0 #endif #ifndef BOOST_INTEL_WIN #define BOOST_INTEL_WIN_WORKAROUND_GUARD 1 #else #define BOOST_INTEL_WIN_WORKAROUND_GUARD 0 #endif #ifndef BOOST_DINKUMWARE_STDLIB #define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1 #else #define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0 #endif #ifndef BOOST_INTEL #define BOOST_INTEL_WORKAROUND_GUARD 1 #else #define BOOST_INTEL_WORKAROUND_GUARD 0 #endif // Always define to zero, if it's used it'll be defined my MPL: #define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0 # define BOOST_WORKAROUND(symbol, test) \ ((symbol ## _WORKAROUND_GUARD + 0 == 0) && \ (symbol != 0) && (1 % (( (symbol test) ) + 1))) // ^ ^ ^ ^ // The extra level of parenthesis nesting above, along with the // BOOST_OPEN_PAREN indirection below, is required to satisfy the // broken preprocessor in MWCW 8.3 and earlier. // // The basic mechanism works as follows: // (symbol test) + 1 => if (symbol test) then 2 else 1 // 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 // // The complication with % is for cooperation with BOOST_TESTED_AT(). // When "test" is BOOST_TESTED_AT(x) and // BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, // // symbol test => if (symbol <= x) then 1 else -1 // (symbol test) + 1 => if (symbol <= x) then 2 else 0 // 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero // # ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS # define BOOST_OPEN_PAREN ( # define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1 # else # define BOOST_TESTED_AT(value) != ((value)-(value)) # endif # else # define BOOST_WORKAROUND(symbol, test) 0 # endif #endif // WORKAROUND_DWA2002126_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/exception/exception.hpp ================================================ //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. //Distributed under the Boost Software License, Version 1.0. (See accompanying //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef UUID_274DA366004E11DCB1DDFE2E56D89593 #define UUID_274DA366004E11DCB1DDFE2E56D89593 #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma warning(push,1) #endif namespace boost { namespace exception_detail { template class refcount_ptr { public: refcount_ptr(): px_(0) { } ~refcount_ptr() { release(); } refcount_ptr( refcount_ptr const & x ): px_(x.px_) { add_ref(); } refcount_ptr & operator=( refcount_ptr const & x ) { adopt(x.px_); return *this; } void adopt( T * px ) { release(); px_=px; add_ref(); } T * get() const { return px_; } private: T * px_; void add_ref() { if( px_ ) px_->add_ref(); } void release() { if( px_ && px_->release() ) px_=0; } }; } //////////////////////////////////////////////////////////////////////// template class error_info; typedef error_info throw_function; typedef error_info throw_file; typedef error_info throw_line; template <> class error_info { public: typedef char const * value_type; value_type v_; explicit error_info( value_type v ): v_(v) { } }; template <> class error_info { public: typedef char const * value_type; value_type v_; explicit error_info( value_type v ): v_(v) { } }; template <> class error_info { public: typedef int value_type; value_type v_; explicit error_info( value_type v ): v_(v) { } }; #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility push (default) # endif #endif class exception; #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility pop # endif #endif template class shared_ptr; namespace exception_detail { class error_info_base; struct type_info_; struct error_info_container { virtual char const * diagnostic_information( char const * ) const = 0; virtual shared_ptr get( type_info_ const & ) const = 0; virtual void set( shared_ptr const &, type_info_ const & ) = 0; virtual void add_ref() const = 0; virtual bool release() const = 0; virtual refcount_ptr clone() const = 0; protected: ~error_info_container() throw() { } }; template struct get_info; template <> struct get_info; template <> struct get_info; template <> struct get_info; char const * get_diagnostic_information( exception const &, char const * ); void copy_boost_exception( exception *, exception const * ); template E const & set_info( E const &, error_info const & ); template E const & set_info( E const &, throw_function const & ); template E const & set_info( E const &, throw_file const & ); template E const & set_info( E const &, throw_line const & ); } #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility push (default) # endif #endif class exception { // public: template void set( typename Tag::type const & ); template typename Tag::type const * get() const; // protected: exception(): throw_function_(0), throw_file_(0), throw_line_(-1) { } #ifdef __HP_aCC //On HP aCC, this protected copy constructor prevents throwing boost::exception. //On all other platforms, the same effect is achieved by the pure virtual destructor. exception( exception const & x ) throw(): data_(x.data_), throw_function_(x.throw_function_), throw_file_(x.throw_file_), throw_line_(x.throw_line_) { } #endif virtual ~exception() throw() #ifndef __HP_aCC = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors. #endif ; #if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310) public: #else private: template friend E const & exception_detail::set_info( E const &, throw_function const & ); template friend E const & exception_detail::set_info( E const &, throw_file const & ); template friend E const & exception_detail::set_info( E const &, throw_line const & ); template friend E const & exception_detail::set_info( E const &, error_info const & ); friend char const * exception_detail::get_diagnostic_information( exception const &, char const * ); template friend struct exception_detail::get_info; friend struct exception_detail::get_info; friend struct exception_detail::get_info; friend struct exception_detail::get_info; friend void exception_detail::copy_boost_exception( exception *, exception const * ); #endif mutable exception_detail::refcount_ptr data_; mutable char const * throw_function_; mutable char const * throw_file_; mutable int throw_line_; }; #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility pop # endif #endif inline exception:: ~exception() throw() { } namespace exception_detail { template E const & set_info( E const & x, throw_function const & y ) { x.throw_function_=y.v_; return x; } template E const & set_info( E const & x, throw_file const & y ) { x.throw_file_=y.v_; return x; } template E const & set_info( E const & x, throw_line const & y ) { x.throw_line_=y.v_; return x; } } //////////////////////////////////////////////////////////////////////// namespace exception_detail { #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility push (default) # endif #endif template struct error_info_injector: public T, public exception { explicit error_info_injector( T const & x ): T(x) { } ~error_info_injector() throw() { } }; #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility pop # endif #endif struct large_size { char c[256]; }; large_size dispatch_boost_exception( exception const * ); struct small_size { }; small_size dispatch_boost_exception( void const * ); template struct enable_error_info_helper; template struct enable_error_info_helper { typedef T type; }; template struct enable_error_info_helper { typedef error_info_injector type; }; template struct enable_error_info_return_type { typedef typename enable_error_info_helper(0)))>::type type; }; } template inline typename exception_detail::enable_error_info_return_type::type enable_error_info( T const & x ) { typedef typename exception_detail::enable_error_info_return_type::type rt; return rt(x); } //////////////////////////////////////////////////////////////////////// namespace exception_detail { #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility push (default) # endif #endif class clone_base { public: virtual clone_base const * clone() const = 0; virtual void rethrow() const = 0; virtual ~clone_base() throw() { } }; #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility pop # endif #endif inline void copy_boost_exception( exception * a, exception const * b ) { refcount_ptr data; if( error_info_container * d=b->data_.get() ) data = d->clone(); a->throw_file_ = b->throw_file_; a->throw_line_ = b->throw_line_; a->throw_function_ = b->throw_function_; a->data_ = data; } inline void copy_boost_exception( void *, void const * ) { } #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility push (default) # endif #endif template class clone_impl: public T, public virtual clone_base { struct clone_tag { }; clone_impl( clone_impl const & x, clone_tag ): T(x) { copy_boost_exception(this,&x); } public: explicit clone_impl( T const & x ): T(x) { copy_boost_exception(this,&x); } ~clone_impl() throw() { } private: clone_base const * clone() const { return new clone_impl(*this,clone_tag()); } void rethrow() const { throw*this; } }; } #if defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # pragma GCC visibility pop # endif #endif template inline exception_detail::clone_impl enable_current_exception( T const & x ) { return exception_detail::clone_impl(x); } } #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma warning(pop) #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/functional/hash/hash_fwd.hpp ================================================ // Copyright 2005-2009 Daniel James. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // Based on Peter Dimov's proposal // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf // issue 6.18. #if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) #define BOOST_FUNCTIONAL_HASH_FWD_HPP #include #if defined(BOOST_HAS_PRAGMA_ONCE) #pragma once #endif #include #include namespace boost { template struct hash; template void hash_combine(std::size_t& seed, T const& v); template std::size_t hash_range(It, It); template void hash_range(std::size_t&, It, It); #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template inline std::size_t hash_range(T*, T*); template inline void hash_range(std::size_t&, T*, T*); #endif } #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/functional/hash_fwd.hpp ================================================ // Copyright 2005-2009 Daniel James. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #if defined(BOOST_HAS_PRAGMA_ONCE) #pragma once #endif #include ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/limits.hpp ================================================ // (C) Copyright John maddock 1999. // (C) David Abrahams 2002. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // use this header as a workaround for missing // See http://www.boost.org/libs/compatibility/index.html for documentation. #ifndef BOOST_LIMITS #define BOOST_LIMITS #include #ifdef BOOST_NO_LIMITS # error "There is no std::numeric_limits suppport available." #else # include #endif #if (defined(BOOST_HAS_LONG_LONG) && defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)) \ || (defined(BOOST_HAS_MS_INT64) && defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS)) // Add missing specializations for numeric_limits: #ifdef BOOST_HAS_MS_INT64 # define BOOST_LLT __int64 # define BOOST_ULLT unsigned __int64 #else # define BOOST_LLT ::boost::long_long_type # define BOOST_ULLT ::boost::ulong_long_type #endif #include // for CHAR_BIT namespace std { template<> class numeric_limits { public: BOOST_STATIC_CONSTANT(bool, is_specialized = true); #ifdef BOOST_HAS_MS_INT64 static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x8000000000000000i64; } static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x7FFFFFFFFFFFFFFFi64; } #elif defined(LLONG_MAX) static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MIN; } static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MAX; } #elif defined(LONGLONG_MAX) static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MIN; } static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MAX; } #else static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); } static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~(min)(); } #endif BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT -1); BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT) - 1) * 301L / 1000); BOOST_STATIC_CONSTANT(bool, is_signed = true); BOOST_STATIC_CONSTANT(bool, is_integer = true); BOOST_STATIC_CONSTANT(bool, is_exact = true); BOOST_STATIC_CONSTANT(int, radix = 2); static BOOST_LLT epsilon() throw() { return 0; }; static BOOST_LLT round_error() throw() { return 0; }; BOOST_STATIC_CONSTANT(int, min_exponent = 0); BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); BOOST_STATIC_CONSTANT(int, max_exponent = 0); BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); BOOST_STATIC_CONSTANT(bool, has_infinity = false); BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); BOOST_STATIC_CONSTANT(bool, has_denorm = false); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); static BOOST_LLT infinity() throw() { return 0; }; static BOOST_LLT quiet_NaN() throw() { return 0; }; static BOOST_LLT signaling_NaN() throw() { return 0; }; static BOOST_LLT denorm_min() throw() { return 0; }; BOOST_STATIC_CONSTANT(bool, is_iec559 = false); BOOST_STATIC_CONSTANT(bool, is_bounded = true); BOOST_STATIC_CONSTANT(bool, is_modulo = true); BOOST_STATIC_CONSTANT(bool, traps = false); BOOST_STATIC_CONSTANT(bool, tinyness_before = false); BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); }; template<> class numeric_limits { public: BOOST_STATIC_CONSTANT(bool, is_specialized = true); #ifdef BOOST_HAS_MS_INT64 static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0ui64; } static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0xFFFFFFFFFFFFFFFFui64; } #elif defined(ULLONG_MAX) && defined(ULLONG_MIN) static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MIN; } static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MAX; } #elif defined(ULONGLONG_MAX) && defined(ULONGLONG_MIN) static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MIN; } static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MAX; } #else static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0uLL; } static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~0uLL; } #endif BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT); BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT)) * 301L / 1000); BOOST_STATIC_CONSTANT(bool, is_signed = false); BOOST_STATIC_CONSTANT(bool, is_integer = true); BOOST_STATIC_CONSTANT(bool, is_exact = true); BOOST_STATIC_CONSTANT(int, radix = 2); static BOOST_ULLT epsilon() throw() { return 0; }; static BOOST_ULLT round_error() throw() { return 0; }; BOOST_STATIC_CONSTANT(int, min_exponent = 0); BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); BOOST_STATIC_CONSTANT(int, max_exponent = 0); BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); BOOST_STATIC_CONSTANT(bool, has_infinity = false); BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); BOOST_STATIC_CONSTANT(bool, has_denorm = false); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); static BOOST_ULLT infinity() throw() { return 0; }; static BOOST_ULLT quiet_NaN() throw() { return 0; }; static BOOST_ULLT signaling_NaN() throw() { return 0; }; static BOOST_ULLT denorm_min() throw() { return 0; }; BOOST_STATIC_CONSTANT(bool, is_iec559 = false); BOOST_STATIC_CONSTANT(bool, is_bounded = true); BOOST_STATIC_CONSTANT(bool, is_modulo = true); BOOST_STATIC_CONSTANT(bool, traps = false); BOOST_STATIC_CONSTANT(bool, tinyness_before = false); BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); }; } #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/atomic.hpp ================================================ // Copyright (C) 2011-2013 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_DETAIL_ATOMIC_HPP #define BOOST_LOCKFREE_DETAIL_ATOMIC_HPP #include #ifndef BOOST_LOCKFREE_FORCE_STD_ATOMIC #define BOOST_LOCKFREE_NO_HDR_ATOMIC // MSVC supports atomic<> from version 2012 onwards. #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700) #undef BOOST_LOCKFREE_NO_HDR_ATOMIC #endif // GCC supports atomic<> from version 4.8 onwards. #if (BOOST_GCC >= 40800) && (__cplusplus >= 201103L) #undef BOOST_LOCKFREE_NO_HDR_ATOMIC #endif // Apple clang is 2 mayor versions ahead, but in fact 1 minor version behind #ifdef BOOST_CLANG #define BOOST_ATOMIC_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #if defined(__apple_build_version__) && (BOOST_ATOMIC_CLANG_VERSION >= 60100) && (__cplusplus >= 201103L) #undef BOOST_LOCKFREE_NO_HDR_ATOMIC #endif #if !defined(__apple_build_version__) && (BOOST_ATOMIC_CLANG_VERSION >= 30600) && (__cplusplus >= 201103L) #undef BOOST_LOCKFREE_NO_HDR_ATOMIC #endif #undef BOOST_ATOMIC_CLANG_VERSION #endif // BOOST_CLANG #endif // BOOST_LOCKFREE_FORCE_STD_ATOMIC #if defined(BOOST_LOCKFREE_NO_HDR_ATOMIC) #include #else #include #endif namespace boost { namespace lockfree { namespace detail { #if defined(BOOST_LOCKFREE_NO_HDR_ATOMIC) using boost::atomic; using boost::memory_order_acquire; using boost::memory_order_consume; using boost::memory_order_relaxed; using boost::memory_order_release; #else using std::atomic; using std::memory_order_acquire; using std::memory_order_consume; using std::memory_order_relaxed; using std::memory_order_release; #endif } using detail::atomic; using detail::memory_order_acquire; using detail::memory_order_consume; using detail::memory_order_relaxed; using detail::memory_order_release; }} #endif /* BOOST_LOCKFREE_DETAIL_ATOMIC_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/copy_payload.hpp ================================================ // boost lockfree: copy_payload helper // // Copyright (C) 2011 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_DETAIL_COPY_PAYLOAD_HPP_INCLUDED #define BOOST_LOCKFREE_DETAIL_COPY_PAYLOAD_HPP_INCLUDED #include #include #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4512) // assignment operator could not be generated #endif namespace boost { namespace lockfree { namespace detail { struct copy_convertible { template static void copy(T & t, U & u) { u = t; } }; struct copy_constructible_and_copyable { template static void copy(T & t, U & u) { u = U(t); } }; template void copy_payload(T & t, U & u) { typedef typename boost::mpl::if_::type, copy_convertible, copy_constructible_and_copyable >::type copy_type; copy_type::copy(t, u); } template struct consume_via_copy { consume_via_copy(T & out): out_(out) {} template void operator()(U & element) { copy_payload(element, out_); } T & out_; }; struct consume_noop { template void operator()(const U &) { } }; }}} #if defined(_MSC_VER) #pragma warning(pop) #endif #endif /* BOOST_LOCKFREE_DETAIL_COPY_PAYLOAD_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/freelist.hpp ================================================ // lock-free freelist // // Copyright (C) 2008-2013 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_FREELIST_HPP_INCLUDED #define BOOST_LOCKFREE_FREELIST_HPP_INCLUDED #include #include #include #include #include #include #include #include #include #include #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4100) // unreferenced formal parameter #pragma warning(disable: 4127) // conditional expression is constant #endif namespace boost { namespace lockfree { namespace detail { template > class freelist_stack: Alloc { struct freelist_node { tagged_ptr next; }; typedef tagged_ptr tagged_node_ptr; public: typedef tagged_ptr tagged_node_handle; template freelist_stack (Allocator const & alloc, std::size_t n = 0): Alloc(alloc), pool_(tagged_node_ptr(NULL)) { for (std::size_t i = 0; i != n; ++i) { T * node = Alloc::allocate(1); #ifdef BOOST_LOCKFREE_FREELIST_INIT_RUNS_DTOR destruct(node); #else deallocate(node); #endif } } template void reserve (std::size_t count) { for (std::size_t i = 0; i != count; ++i) { T * node = Alloc::allocate(1); deallocate(node); } } template T * construct (void) { T * node = allocate(); if (node) new(node) T(); return node; } template T * construct (ArgumentType const & arg) { T * node = allocate(); if (node) new(node) T(arg); return node; } template T * construct (ArgumentType1 const & arg1, ArgumentType2 const & arg2) { T * node = allocate(); if (node) new(node) T(arg1, arg2); return node; } template void destruct (tagged_node_handle tagged_ptr) { T * n = tagged_ptr.get_ptr(); n->~T(); deallocate(n); } template void destruct (T * n) { n->~T(); deallocate(n); } ~freelist_stack(void) { tagged_node_ptr current = pool_.load(); while (current) { freelist_node * current_ptr = current.get_ptr(); if (current_ptr) current = current_ptr->next; Alloc::deallocate((T*)current_ptr, 1); } } bool is_lock_free(void) const { return pool_.is_lock_free(); } T * get_handle(T * pointer) const { return pointer; } T * get_handle(tagged_node_handle const & handle) const { return get_pointer(handle); } T * get_pointer(tagged_node_handle const & tptr) const { return tptr.get_ptr(); } T * get_pointer(T * pointer) const { return pointer; } T * null_handle(void) const { return NULL; } protected: // allow use from subclasses template T * allocate (void) { if (ThreadSafe) return allocate_impl(); else return allocate_impl_unsafe(); } private: template T * allocate_impl (void) { tagged_node_ptr old_pool = pool_.load(memory_order_consume); for(;;) { if (!old_pool.get_ptr()) { if (!Bounded) return Alloc::allocate(1); else return 0; } freelist_node * new_pool_ptr = old_pool->next.get_ptr(); tagged_node_ptr new_pool (new_pool_ptr, old_pool.get_next_tag()); if (pool_.compare_exchange_weak(old_pool, new_pool)) { void * ptr = old_pool.get_ptr(); return reinterpret_cast(ptr); } } } template T * allocate_impl_unsafe (void) { tagged_node_ptr old_pool = pool_.load(memory_order_relaxed); if (!old_pool.get_ptr()) { if (!Bounded) return Alloc::allocate(1); else return 0; } freelist_node * new_pool_ptr = old_pool->next.get_ptr(); tagged_node_ptr new_pool (new_pool_ptr, old_pool.get_next_tag()); pool_.store(new_pool, memory_order_relaxed); void * ptr = old_pool.get_ptr(); return reinterpret_cast(ptr); } protected: template void deallocate (T * n) { if (ThreadSafe) deallocate_impl(n); else deallocate_impl_unsafe(n); } private: void deallocate_impl (T * n) { void * node = n; tagged_node_ptr old_pool = pool_.load(memory_order_consume); freelist_node * new_pool_ptr = reinterpret_cast(node); for(;;) { tagged_node_ptr new_pool (new_pool_ptr, old_pool.get_tag()); new_pool->next.set_ptr(old_pool.get_ptr()); if (pool_.compare_exchange_weak(old_pool, new_pool)) return; } } void deallocate_impl_unsafe (T * n) { void * node = n; tagged_node_ptr old_pool = pool_.load(memory_order_relaxed); freelist_node * new_pool_ptr = reinterpret_cast(node); tagged_node_ptr new_pool (new_pool_ptr, old_pool.get_tag()); new_pool->next.set_ptr(old_pool.get_ptr()); pool_.store(new_pool, memory_order_relaxed); } atomic pool_; }; class tagged_index { public: typedef boost::uint16_t tag_t; typedef boost::uint16_t index_t; /** uninitialized constructor */ tagged_index(void) BOOST_NOEXCEPT //: index(0), tag(0) {} /** copy constructor */ #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS tagged_index(tagged_index const & rhs): index(rhs.index), tag(rhs.tag) {} #else tagged_index(tagged_index const & rhs) = default; #endif explicit tagged_index(index_t i, tag_t t = 0): index(i), tag(t) {} /** index access */ /* @{ */ index_t get_index() const { return index; } void set_index(index_t i) { index = i; } /* @} */ /** tag access */ /* @{ */ tag_t get_tag() const { return tag; } tag_t get_next_tag() const { tag_t next = (get_tag() + 1u) & (std::numeric_limits::max)(); return next; } void set_tag(tag_t t) { tag = t; } /* @} */ bool operator==(tagged_index const & rhs) const { return (index == rhs.index) && (tag == rhs.tag); } bool operator!=(tagged_index const & rhs) const { return !operator==(rhs); } protected: index_t index; tag_t tag; }; template struct compiletime_sized_freelist_storage { // array-based freelists only support a 16bit address space. BOOST_STATIC_ASSERT(size < 65536); boost::array data; // unused ... only for API purposes template compiletime_sized_freelist_storage(Allocator const & /* alloc */, std::size_t /* count */) {} T * nodes(void) const { return reinterpret_cast(const_cast(data.data())); } std::size_t node_count(void) const { return size; } }; template > struct runtime_sized_freelist_storage: Alloc { T * nodes_; std::size_t node_count_; template runtime_sized_freelist_storage(Allocator const & alloc, std::size_t count): Alloc(alloc), node_count_(count) { if (count > 65535) boost::throw_exception(std::runtime_error("boost.lockfree: freelist size is limited to a maximum of 65535 objects")); nodes_ = Alloc::allocate(count); } ~runtime_sized_freelist_storage(void) { Alloc::deallocate(nodes_, node_count_); } T * nodes(void) const { return nodes_; } std::size_t node_count(void) const { return node_count_; } }; template > class fixed_size_freelist: NodeStorage { struct freelist_node { tagged_index next; }; typedef tagged_index::index_t index_t; void initialize(void) { T * nodes = NodeStorage::nodes(); for (std::size_t i = 0; i != NodeStorage::node_count(); ++i) { tagged_index * next_index = reinterpret_cast(nodes + i); next_index->set_index(null_handle()); #ifdef BOOST_LOCKFREE_FREELIST_INIT_RUNS_DTOR destruct(nodes + i); #else deallocate(static_cast(i)); #endif } } public: typedef tagged_index tagged_node_handle; template fixed_size_freelist (Allocator const & alloc, std::size_t count): NodeStorage(alloc, count), pool_(tagged_index(static_cast(count), 0)) { initialize(); } fixed_size_freelist (void): pool_(tagged_index(NodeStorage::node_count(), 0)) { initialize(); } template T * construct (void) { index_t node_index = allocate(); if (node_index == null_handle()) return NULL; T * node = NodeStorage::nodes() + node_index; new(node) T(); return node; } template T * construct (ArgumentType const & arg) { index_t node_index = allocate(); if (node_index == null_handle()) return NULL; T * node = NodeStorage::nodes() + node_index; new(node) T(arg); return node; } template T * construct (ArgumentType1 const & arg1, ArgumentType2 const & arg2) { index_t node_index = allocate(); if (node_index == null_handle()) return NULL; T * node = NodeStorage::nodes() + node_index; new(node) T(arg1, arg2); return node; } template void destruct (tagged_node_handle tagged_index) { index_t index = tagged_index.get_index(); T * n = NodeStorage::nodes() + index; (void)n; // silence msvc warning n->~T(); deallocate(index); } template void destruct (T * n) { n->~T(); deallocate(n - NodeStorage::nodes()); } bool is_lock_free(void) const { return pool_.is_lock_free(); } index_t null_handle(void) const { return static_cast(NodeStorage::node_count()); } index_t get_handle(T * pointer) const { if (pointer == NULL) return null_handle(); else return static_cast(pointer - NodeStorage::nodes()); } index_t get_handle(tagged_node_handle const & handle) const { return handle.get_index(); } T * get_pointer(tagged_node_handle const & tptr) const { return get_pointer(tptr.get_index()); } T * get_pointer(index_t index) const { if (index == null_handle()) return 0; else return NodeStorage::nodes() + index; } T * get_pointer(T * ptr) const { return ptr; } protected: // allow use from subclasses template index_t allocate (void) { if (ThreadSafe) return allocate_impl(); else return allocate_impl_unsafe(); } private: index_t allocate_impl (void) { tagged_index old_pool = pool_.load(memory_order_consume); for(;;) { index_t index = old_pool.get_index(); if (index == null_handle()) return index; T * old_node = NodeStorage::nodes() + index; tagged_index * next_index = reinterpret_cast(old_node); tagged_index new_pool(next_index->get_index(), old_pool.get_next_tag()); if (pool_.compare_exchange_weak(old_pool, new_pool)) return old_pool.get_index(); } } index_t allocate_impl_unsafe (void) { tagged_index old_pool = pool_.load(memory_order_consume); index_t index = old_pool.get_index(); if (index == null_handle()) return index; T * old_node = NodeStorage::nodes() + index; tagged_index * next_index = reinterpret_cast(old_node); tagged_index new_pool(next_index->get_index(), old_pool.get_next_tag()); pool_.store(new_pool, memory_order_relaxed); return old_pool.get_index(); } template void deallocate (index_t index) { if (ThreadSafe) deallocate_impl(index); else deallocate_impl_unsafe(index); } void deallocate_impl (index_t index) { freelist_node * new_pool_node = reinterpret_cast(NodeStorage::nodes() + index); tagged_index old_pool = pool_.load(memory_order_consume); for(;;) { tagged_index new_pool (index, old_pool.get_tag()); new_pool_node->next.set_index(old_pool.get_index()); if (pool_.compare_exchange_weak(old_pool, new_pool)) return; } } void deallocate_impl_unsafe (index_t index) { freelist_node * new_pool_node = reinterpret_cast(NodeStorage::nodes() + index); tagged_index old_pool = pool_.load(memory_order_consume); tagged_index new_pool (index, old_pool.get_tag()); new_pool_node->next.set_index(old_pool.get_index()); pool_.store(new_pool); } atomic pool_; }; template struct select_freelist { typedef typename mpl::if_c, runtime_sized_freelist_storage >::type fixed_sized_storage_type; typedef typename mpl::if_c, freelist_stack >::type type; }; template struct select_tagged_handle { typedef typename mpl::if_c, tagged_index >::type tagged_handle_type; typedef typename mpl::if_c::type handle_type; }; } /* namespace detail */ } /* namespace lockfree */ } /* namespace boost */ #if defined(_MSC_VER) #pragma warning(pop) #endif #endif /* BOOST_LOCKFREE_FREELIST_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/parameter.hpp ================================================ // boost lockfree // // Copyright (C) 2011 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_DETAIL_PARAMETER_HPP #define BOOST_LOCKFREE_DETAIL_PARAMETER_HPP #include namespace boost { namespace lockfree { namespace detail { namespace mpl = boost::mpl; template struct has_arg { typedef typename parameter::binding::type type; static const bool value = mpl::is_not_void_::type::value; }; template struct extract_capacity { static const bool has_capacity = has_arg::value; typedef typename mpl::if_c::type, mpl::size_t< 0 > >::type capacity_t; static const std::size_t capacity = capacity_t::value; }; template struct extract_allocator { static const bool has_allocator = has_arg::value; typedef typename mpl::if_c::type, std::allocator >::type allocator_arg; typedef typename allocator_arg::template rebind::other type; }; template struct extract_fixed_sized { static const bool has_fixed_sized = has_arg::value; typedef typename mpl::if_c::type, mpl::bool_ >::type type; static const bool value = type::value; }; } /* namespace detail */ } /* namespace lockfree */ } /* namespace boost */ #endif /* BOOST_LOCKFREE_DETAIL_PARAMETER_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/prefix.hpp ================================================ // Copyright (C) 2009 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_PREFIX_HPP_INCLUDED #define BOOST_LOCKFREE_PREFIX_HPP_INCLUDED /* this file defines the following macros: BOOST_LOCKFREE_CACHELINE_BYTES: size of a cache line BOOST_LOCKFREE_PTR_COMPRESSION: use tag/pointer compression to utilize parts of the virtual address space as tag (at least 16bit) BOOST_LOCKFREE_DCAS_ALIGNMENT: symbol used for aligning structs at cache line boundaries */ #define BOOST_LOCKFREE_CACHELINE_BYTES 64 #ifdef _MSC_VER #define BOOST_LOCKFREE_CACHELINE_ALIGNMENT __declspec(align(BOOST_LOCKFREE_CACHELINE_BYTES)) #if defined(_M_IX86) #define BOOST_LOCKFREE_DCAS_ALIGNMENT #elif defined(_M_X64) || defined(_M_IA64) #define BOOST_LOCKFREE_PTR_COMPRESSION 1 #define BOOST_LOCKFREE_DCAS_ALIGNMENT __declspec(align(16)) #endif #endif /* _MSC_VER */ #ifdef __GNUC__ #define BOOST_LOCKFREE_CACHELINE_ALIGNMENT __attribute__((aligned(BOOST_LOCKFREE_CACHELINE_BYTES))) #if defined(__i386__) || defined(__ppc__) #define BOOST_LOCKFREE_DCAS_ALIGNMENT #elif defined(__x86_64__) #define BOOST_LOCKFREE_PTR_COMPRESSION 1 #define BOOST_LOCKFREE_DCAS_ALIGNMENT __attribute__((aligned(16))) #elif defined(__alpha__) // LATER: alpha may benefit from pointer compression. but what is the maximum size of the address space? #define BOOST_LOCKFREE_DCAS_ALIGNMENT #endif #endif /* __GNUC__ */ #ifndef BOOST_LOCKFREE_DCAS_ALIGNMENT #define BOOST_LOCKFREE_DCAS_ALIGNMENT /*BOOST_LOCKFREE_DCAS_ALIGNMENT*/ #endif #ifndef BOOST_LOCKFREE_CACHELINE_ALIGNMENT #define BOOST_LOCKFREE_CACHELINE_ALIGNMENT /*BOOST_LOCKFREE_CACHELINE_ALIGNMENT*/ #endif #endif /* BOOST_LOCKFREE_PREFIX_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/tagged_ptr.hpp ================================================ // tagged pointer, for aba prevention // // Copyright (C) 2008 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_TAGGED_PTR_HPP_INCLUDED #define BOOST_LOCKFREE_TAGGED_PTR_HPP_INCLUDED #include #include #ifndef BOOST_LOCKFREE_PTR_COMPRESSION #include #else #include #endif #endif /* BOOST_LOCKFREE_TAGGED_PTR_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/tagged_ptr_dcas.hpp ================================================ // tagged pointer, for aba prevention // // Copyright (C) 2008 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED #define BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED #include /* for std::size_t */ #include namespace boost { namespace lockfree { namespace detail { template class BOOST_LOCKFREE_DCAS_ALIGNMENT tagged_ptr { public: typedef std::size_t tag_t; /** uninitialized constructor */ tagged_ptr(void) BOOST_NOEXCEPT//: ptr(0), tag(0) {} #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS tagged_ptr(tagged_ptr const & p): ptr(p.ptr), tag(p.tag) {} #else tagged_ptr(tagged_ptr const & p) = default; #endif explicit tagged_ptr(T * p, tag_t t = 0): ptr(p), tag(t) {} /** unsafe set operation */ /* @{ */ #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS tagged_ptr & operator= (tagged_ptr const & p) { set(p.ptr, p.tag); return *this; } #else tagged_ptr & operator= (tagged_ptr const & p) = default; #endif void set(T * p, tag_t t) { ptr = p; tag = t; } /* @} */ /** comparing semantics */ /* @{ */ bool operator== (volatile tagged_ptr const & p) const { return (ptr == p.ptr) && (tag == p.tag); } bool operator!= (volatile tagged_ptr const & p) const { return !operator==(p); } /* @} */ /** pointer access */ /* @{ */ T * get_ptr(void) const { return ptr; } void set_ptr(T * p) { ptr = p; } /* @} */ /** tag access */ /* @{ */ tag_t get_tag() const { return tag; } tag_t get_next_tag() const { tag_t next = (get_tag() + 1) & (std::numeric_limits::max)(); return next; } void set_tag(tag_t t) { tag = t; } /* @} */ /** smart pointer support */ /* @{ */ T & operator*() const { return *ptr; } T * operator->() const { return ptr; } operator bool(void) const { return ptr != 0; } /* @} */ protected: T * ptr; tag_t tag; }; } /* namespace detail */ } /* namespace lockfree */ } /* namespace boost */ #endif /* BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/detail/tagged_ptr_ptrcompression.hpp ================================================ // tagged pointer, for aba prevention // // Copyright (C) 2008, 2009 Tim Blechmann, based on code by Cory Nelson // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED #define BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED #include /* for std::size_t */ #include #include namespace boost { namespace lockfree { namespace detail { #if defined (__x86_64__) || defined (_M_X64) template class tagged_ptr { typedef boost::uint64_t compressed_ptr_t; public: typedef boost::uint16_t tag_t; private: union cast_unit { compressed_ptr_t value; tag_t tag[4]; }; static const int tag_index = 3; static const compressed_ptr_t ptr_mask = 0xffffffffffffUL; //(1L<<48L)-1; static T* extract_ptr(volatile compressed_ptr_t const & i) { return (T*)(i & ptr_mask); } static tag_t extract_tag(volatile compressed_ptr_t const & i) { cast_unit cu; cu.value = i; return cu.tag[tag_index]; } static compressed_ptr_t pack_ptr(T * ptr, tag_t tag) { cast_unit ret; ret.value = compressed_ptr_t(ptr); ret.tag[tag_index] = tag; return ret.value; } public: /** uninitialized constructor */ tagged_ptr(void) BOOST_NOEXCEPT//: ptr(0), tag(0) {} /** copy constructor */ #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS tagged_ptr(tagged_ptr const & p): ptr(p.ptr) {} #else tagged_ptr(tagged_ptr const & p) = default; #endif explicit tagged_ptr(T * p, tag_t t = 0): ptr(pack_ptr(p, t)) {} /** unsafe set operation */ /* @{ */ #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS tagged_ptr & operator= (tagged_ptr const & p) { ptr = p.ptr; return *this; } #else tagged_ptr & operator= (tagged_ptr const & p) = default; #endif void set(T * p, tag_t t) { ptr = pack_ptr(p, t); } /* @} */ /** comparing semantics */ /* @{ */ bool operator== (volatile tagged_ptr const & p) const { return (ptr == p.ptr); } bool operator!= (volatile tagged_ptr const & p) const { return !operator==(p); } /* @} */ /** pointer access */ /* @{ */ T * get_ptr() const { return extract_ptr(ptr); } void set_ptr(T * p) { tag_t tag = get_tag(); ptr = pack_ptr(p, tag); } /* @} */ /** tag access */ /* @{ */ tag_t get_tag() const { return extract_tag(ptr); } tag_t get_next_tag() const { tag_t next = (get_tag() + 1u) & (std::numeric_limits::max)(); return next; } void set_tag(tag_t t) { T * p = get_ptr(); ptr = pack_ptr(p, t); } /* @} */ /** smart pointer support */ /* @{ */ T & operator*() const { return *get_ptr(); } T * operator->() const { return get_ptr(); } operator bool(void) const { return get_ptr() != 0; } /* @} */ protected: compressed_ptr_t ptr; }; #else #error unsupported platform #endif } /* namespace detail */ } /* namespace lockfree */ } /* namespace boost */ #endif /* BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/policies.hpp ================================================ // boost lockfree // // Copyright (C) 2011 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_POLICIES_HPP_INCLUDED #define BOOST_LOCKFREE_POLICIES_HPP_INCLUDED #include #include #include #include namespace boost { namespace lockfree { #ifndef BOOST_DOXYGEN_INVOKED namespace tag { struct allocator ; } namespace tag { struct fixed_sized; } namespace tag { struct capacity; } #endif /** Configures a data structure as \b fixed-sized. * * The internal nodes are stored inside an array and they are addressed by array indexing. This limits the possible size of the * queue to the number of elements that can be addressed by the index type (usually 2**16-2), but on platforms that lack * double-width compare-and-exchange instructions, this is the best way to achieve lock-freedom. * This implies that a data structure is bounded. * */ template struct fixed_sized: boost::parameter::template_keyword > {}; /** Sets the \b capacity of a data structure at compile-time. * * This implies that a data structure is bounded and fixed-sized. * */ template struct capacity: boost::parameter::template_keyword > {}; /** Defines the \b allocator type of a data structure. * */ template struct allocator: boost::parameter::template_keyword {}; } } #endif /* BOOST_LOCKFREE_POLICIES_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/lockfree/queue.hpp ================================================ // lock-free queue from // Michael, M. M. and Scott, M. L., // "simple, fast and practical non-blocking and blocking concurrent queue algorithms" // // Copyright (C) 2008-2013 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_LOCKFREE_FIFO_HPP_INCLUDED #define BOOST_LOCKFREE_FIFO_HPP_INCLUDED #include #include #include #include #include // for BOOST_LIKELY #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4324) // structure was padded due to __declspec(align()) #endif namespace boost { namespace lockfree { namespace detail { typedef parameter::parameters, boost::parameter::optional > queue_signature; } /* namespace detail */ /** The queue class provides a multi-writer/multi-reader queue, pushing and popping is lock-free, * construction/destruction has to be synchronized. It uses a freelist for memory management, * freed nodes are pushed to the freelist and not returned to the OS before the queue is destroyed. * * \b Policies: * - \ref boost::lockfree::fixed_sized, defaults to \c boost::lockfree::fixed_sized \n * Can be used to completely disable dynamic memory allocations during push in order to ensure lockfree behavior. \n * If the data structure is configured as fixed-sized, the internal nodes are stored inside an array and they are addressed * by array indexing. This limits the possible size of the queue to the number of elements that can be addressed by the index * type (usually 2**16-2), but on platforms that lack double-width compare-and-exchange instructions, this is the best way * to achieve lock-freedom. * * - \ref boost::lockfree::capacity, optional \n * If this template argument is passed to the options, the size of the queue is set at compile-time.\n * It this option implies \c fixed_sized * * - \ref boost::lockfree::allocator, defaults to \c boost::lockfree::allocator> \n * Specifies the allocator that is used for the internal freelist * * \b Requirements: * - T must have a copy constructor * - T must have a trivial assignment operator * - T must have a trivial destructor * * */ #ifndef BOOST_DOXYGEN_INVOKED template #else template #endif class queue { private: #ifndef BOOST_DOXYGEN_INVOKED #ifdef BOOST_HAS_TRIVIAL_DESTRUCTOR BOOST_STATIC_ASSERT((boost::has_trivial_destructor::value)); #endif #ifdef BOOST_HAS_TRIVIAL_ASSIGN BOOST_STATIC_ASSERT((boost::has_trivial_assign::value)); #endif typedef typename detail::queue_signature::bind::type bound_args; static const bool has_capacity = detail::extract_capacity::has_capacity; static const size_t capacity = detail::extract_capacity::capacity + 1; // the queue uses one dummy node static const bool fixed_sized = detail::extract_fixed_sized::value; static const bool node_based = !(has_capacity || fixed_sized); static const bool compile_time_sized = has_capacity; struct BOOST_LOCKFREE_CACHELINE_ALIGNMENT node { typedef typename detail::select_tagged_handle::tagged_handle_type tagged_node_handle; typedef typename detail::select_tagged_handle::handle_type handle_type; node(T const & v, handle_type null_handle): data(v)//, next(tagged_node_handle(0, 0)) { /* increment tag to avoid ABA problem */ tagged_node_handle old_next = next.load(memory_order_relaxed); tagged_node_handle new_next (null_handle, old_next.get_next_tag()); next.store(new_next, memory_order_release); } node (handle_type null_handle): next(tagged_node_handle(null_handle, 0)) {} node(void) {} atomic next; T data; }; typedef typename detail::extract_allocator::type node_allocator; typedef typename detail::select_freelist::type pool_t; typedef typename pool_t::tagged_node_handle tagged_node_handle; typedef typename detail::select_tagged_handle::handle_type handle_type; void initialize(void) { node * n = pool.template construct(pool.null_handle()); tagged_node_handle dummy_node(pool.get_handle(n), 0); head_.store(dummy_node, memory_order_relaxed); tail_.store(dummy_node, memory_order_release); } struct implementation_defined { typedef node_allocator allocator; typedef std::size_t size_type; }; #endif BOOST_DELETED_FUNCTION(queue(queue const&)) BOOST_DELETED_FUNCTION(queue& operator= (queue const&)) public: typedef T value_type; typedef typename implementation_defined::allocator allocator; typedef typename implementation_defined::size_type size_type; /** * \return true, if implementation is lock-free. * * \warning It only checks, if the queue head and tail nodes and the freelist can be modified in a lock-free manner. * On most platforms, the whole implementation is lock-free, if this is true. Using c++0x-style atomics, there is * no possibility to provide a completely accurate implementation, because one would need to test every internal * node, which is impossible if further nodes will be allocated from the operating system. * */ bool is_lock_free (void) const { return head_.is_lock_free() && tail_.is_lock_free() && pool.is_lock_free(); } //! Construct queue // @{ queue(void): head_(tagged_node_handle(0, 0)), tail_(tagged_node_handle(0, 0)), pool(node_allocator(), capacity) { BOOST_ASSERT(has_capacity); initialize(); } template explicit queue(typename node_allocator::template rebind::other const & alloc): head_(tagged_node_handle(0, 0)), tail_(tagged_node_handle(0, 0)), pool(alloc, capacity) { BOOST_STATIC_ASSERT(has_capacity); initialize(); } explicit queue(allocator const & alloc): head_(tagged_node_handle(0, 0)), tail_(tagged_node_handle(0, 0)), pool(alloc, capacity) { BOOST_ASSERT(has_capacity); initialize(); } // @} //! Construct queue, allocate n nodes for the freelist. // @{ explicit queue(size_type n): head_(tagged_node_handle(0, 0)), tail_(tagged_node_handle(0, 0)), pool(node_allocator(), n + 1) { BOOST_ASSERT(!has_capacity); initialize(); } template queue(size_type n, typename node_allocator::template rebind::other const & alloc): head_(tagged_node_handle(0, 0)), tail_(tagged_node_handle(0, 0)), pool(alloc, n + 1) { BOOST_STATIC_ASSERT(!has_capacity); initialize(); } // @} /** \copydoc boost::lockfree::stack::reserve * */ void reserve(size_type n) { pool.template reserve(n); } /** \copydoc boost::lockfree::stack::reserve_unsafe * */ void reserve_unsafe(size_type n) { pool.template reserve(n); } /** Destroys queue, free all nodes from freelist. * */ ~queue(void) { T dummy; while(unsynchronized_pop(dummy)) {} pool.template destruct(head_.load(memory_order_relaxed)); } /** Check if the queue is empty * * \return true, if the queue is empty, false otherwise * \note The result is only accurate, if no other thread modifies the queue. Therefore it is rarely practical to use this * value in program logic. * */ bool empty(void) const { return pool.get_handle(head_.load()) == pool.get_handle(tail_.load()); } /** Pushes object t to the queue. * * \post object will be pushed to the queue, if internal node can be allocated * \returns true, if the push operation is successful. * * \note Thread-safe. If internal memory pool is exhausted and the memory pool is not fixed-sized, a new node will be allocated * from the OS. This may not be lock-free. * */ bool push(T const & t) { return do_push(t); } /** Pushes object t to the queue. * * \post object will be pushed to the queue, if internal node can be allocated * \returns true, if the push operation is successful. * * \note Thread-safe and non-blocking. If internal memory pool is exhausted, operation will fail * \throws if memory allocator throws * */ bool bounded_push(T const & t) { return do_push(t); } private: #ifndef BOOST_DOXYGEN_INVOKED template bool do_push(T const & t) { node * n = pool.template construct(t, pool.null_handle()); handle_type node_handle = pool.get_handle(n); if (n == NULL) return false; for (;;) { tagged_node_handle tail = tail_.load(memory_order_acquire); node * tail_node = pool.get_pointer(tail); tagged_node_handle next = tail_node->next.load(memory_order_acquire); node * next_ptr = pool.get_pointer(next); tagged_node_handle tail2 = tail_.load(memory_order_acquire); if (BOOST_LIKELY(tail == tail2)) { if (next_ptr == 0) { tagged_node_handle new_tail_next(node_handle, next.get_next_tag()); if ( tail_node->next.compare_exchange_weak(next, new_tail_next) ) { tagged_node_handle new_tail(node_handle, tail.get_next_tag()); tail_.compare_exchange_strong(tail, new_tail); return true; } } else { tagged_node_handle new_tail(pool.get_handle(next_ptr), tail.get_next_tag()); tail_.compare_exchange_strong(tail, new_tail); } } } } #endif public: /** Pushes object t to the queue. * * \post object will be pushed to the queue, if internal node can be allocated * \returns true, if the push operation is successful. * * \note Not Thread-safe. If internal memory pool is exhausted and the memory pool is not fixed-sized, a new node will be allocated * from the OS. This may not be lock-free. * \throws if memory allocator throws * */ bool unsynchronized_push(T const & t) { node * n = pool.template construct(t, pool.null_handle()); if (n == NULL) return false; for (;;) { tagged_node_handle tail = tail_.load(memory_order_relaxed); tagged_node_handle next = tail->next.load(memory_order_relaxed); node * next_ptr = next.get_ptr(); if (next_ptr == 0) { tail->next.store(tagged_node_handle(n, next.get_next_tag()), memory_order_relaxed); tail_.store(tagged_node_handle(n, tail.get_next_tag()), memory_order_relaxed); return true; } else tail_.store(tagged_node_handle(next_ptr, tail.get_next_tag()), memory_order_relaxed); } } /** Pops object from queue. * * \post if pop operation is successful, object will be copied to ret. * \returns true, if the pop operation is successful, false if queue was empty. * * \note Thread-safe and non-blocking * */ bool pop (T & ret) { return pop(ret); } /** Pops object from queue. * * \pre type U must be constructible by T and copyable, or T must be convertible to U * \post if pop operation is successful, object will be copied to ret. * \returns true, if the pop operation is successful, false if queue was empty. * * \note Thread-safe and non-blocking * */ template bool pop (U & ret) { for (;;) { tagged_node_handle head = head_.load(memory_order_acquire); node * head_ptr = pool.get_pointer(head); tagged_node_handle tail = tail_.load(memory_order_acquire); tagged_node_handle next = head_ptr->next.load(memory_order_acquire); node * next_ptr = pool.get_pointer(next); tagged_node_handle head2 = head_.load(memory_order_acquire); if (BOOST_LIKELY(head == head2)) { if (pool.get_handle(head) == pool.get_handle(tail)) { if (next_ptr == 0) return false; tagged_node_handle new_tail(pool.get_handle(next), tail.get_next_tag()); tail_.compare_exchange_strong(tail, new_tail); } else { if (next_ptr == 0) /* this check is not part of the original algorithm as published by michael and scott * * however we reuse the tagged_ptr part for the freelist and clear the next part during node * allocation. we can observe a null-pointer here. * */ continue; detail::copy_payload(next_ptr->data, ret); tagged_node_handle new_head(pool.get_handle(next), head.get_next_tag()); if (head_.compare_exchange_weak(head, new_head)) { pool.template destruct(head); return true; } } } } } /** Pops object from queue. * * \post if pop operation is successful, object will be copied to ret. * \returns true, if the pop operation is successful, false if queue was empty. * * \note Not thread-safe, but non-blocking * * */ bool unsynchronized_pop (T & ret) { return unsynchronized_pop(ret); } /** Pops object from queue. * * \pre type U must be constructible by T and copyable, or T must be convertible to U * \post if pop operation is successful, object will be copied to ret. * \returns true, if the pop operation is successful, false if queue was empty. * * \note Not thread-safe, but non-blocking * * */ template bool unsynchronized_pop (U & ret) { for (;;) { tagged_node_handle head = head_.load(memory_order_relaxed); node * head_ptr = pool.get_pointer(head); tagged_node_handle tail = tail_.load(memory_order_relaxed); tagged_node_handle next = head_ptr->next.load(memory_order_relaxed); node * next_ptr = pool.get_pointer(next); if (pool.get_handle(head) == pool.get_handle(tail)) { if (next_ptr == 0) return false; tagged_node_handle new_tail(pool.get_handle(next), tail.get_next_tag()); tail_.store(new_tail); } else { if (next_ptr == 0) /* this check is not part of the original algorithm as published by michael and scott * * however we reuse the tagged_ptr part for the freelist and clear the next part during node * allocation. we can observe a null-pointer here. * */ continue; detail::copy_payload(next_ptr->data, ret); tagged_node_handle new_head(pool.get_handle(next), head.get_next_tag()); head_.store(new_head); pool.template destruct(head); return true; } } } /** consumes one element via a functor * * pops one element from the queue and applies the functor on this object * * \returns true, if one element was consumed * * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking * */ template bool consume_one(Functor & f) { T element; bool success = pop(element); if (success) f(element); return success; } /// \copydoc boost::lockfree::queue::consume_one(Functor & rhs) template bool consume_one(Functor const & f) { T element; bool success = pop(element); if (success) f(element); return success; } /** consumes all elements via a functor * * sequentially pops all elements from the queue and applies the functor on each object * * \returns number of elements that are consumed * * \note Thread-safe and non-blocking, if functor is thread-safe and non-blocking * */ template size_t consume_all(Functor & f) { size_t element_count = 0; while (consume_one(f)) element_count += 1; return element_count; } /// \copydoc boost::lockfree::queue::consume_all(Functor & rhs) template size_t consume_all(Functor const & f) { size_t element_count = 0; while (consume_one(f)) element_count += 1; return element_count; } private: #ifndef BOOST_DOXYGEN_INVOKED atomic head_; static const int padding_size = BOOST_LOCKFREE_CACHELINE_BYTES - sizeof(tagged_node_handle); char padding1[padding_size]; atomic tail_; char padding2[padding_size]; pool_t pool; #endif }; } /* namespace lockfree */ } /* namespace boost */ #if defined(_MSC_VER) #pragma warning(pop) #endif #endif /* BOOST_LOCKFREE_FIFO_HPP_INCLUDED */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/memory_order.hpp ================================================ #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED #define BOOST_MEMORY_ORDER_HPP_INCLUDED // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif // boost/memory_order.hpp // // Defines enum boost::memory_order per the C++0x working draft // // Copyright (c) 2008, 2009 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) namespace boost { // // Enum values are chosen so that code that needs to insert // a trailing fence for acquire semantics can use a single // test such as: // // if( mo & memory_order_acquire ) { ...fence... } // // For leading fences one can use: // // if( mo & memory_order_release ) { ...fence... } // // Architectures such as Alpha that need a fence on consume // can use: // // if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... } // // The values are also in the order of increasing "strength" // of the fences so that success/failure orders can be checked // efficiently in compare_exchange methods. // enum memory_order { memory_order_relaxed = 0, memory_order_consume = 1, memory_order_acquire = 2, memory_order_release = 4, memory_order_acq_rel = 6, // acquire | release memory_order_seq_cst = 14 // acq_rel | 8 }; } // namespace boost #endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/O1_size.hpp ================================================ #ifndef BOOST_MPL_O1_SIZE_HPP_INCLUDED #define BOOST_MPL_O1_SIZE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { // returns sequence size if it's an O(1) operation; otherwise returns -1 template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct O1_size : O1_size_impl< typename sequence_tag::type > ::template apply< Sequence > { BOOST_MPL_AUX_LAMBDA_SUPPORT(1, O1_size, (Sequence)) }; BOOST_MPL_AUX_NA_SPEC(1, O1_size) }} #endif // BOOST_MPL_O1_SIZE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/O1_size_fwd.hpp ================================================ #ifndef BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED #define BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct O1_size_impl; template< typename Sequence > struct O1_size; }} #endif // BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/always.hpp ================================================ #ifndef BOOST_MPL_ALWAYS_HPP_INCLUDED #define BOOST_MPL_ALWAYS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template< typename Value > struct always { template< BOOST_MPL_PP_DEFAULT_PARAMS(BOOST_MPL_LIMIT_METAFUNCTION_ARITY, typename T, na) > struct apply { typedef Value type; }; }; BOOST_MPL_AUX_ARITY_SPEC(0, always) }} #endif // BOOST_MPL_ALWAYS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/and.hpp ================================================ #ifndef BOOST_MPL_AND_HPP_INCLUDED #define BOOST_MPL_AND_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include // agurt, 19/may/04: workaround a conflict with header's // 'or' and 'and' macros, see http://tinyurl.com/3et69; 'defined(and)' // has to be checked in a separate condition, otherwise GCC complains // about 'and' being an alternative token #if defined(_MSC_VER) && !defined(__clang__) #ifndef __GCCXML__ #if defined(and) # pragma push_macro("and") # undef and # define and(x) #endif #endif #endif # define BOOST_MPL_PREPROCESSED_HEADER and.hpp # include #if defined(_MSC_VER) && !defined(__clang__) #ifndef __GCCXML__ #if defined(and) # pragma pop_macro("and") #endif #endif #endif #else # define AUX778076_OP_NAME and_ # define AUX778076_OP_VALUE1 false # define AUX778076_OP_VALUE2 true # include #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/apply.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_APPLY_HPP_INCLUDED #define BOOST_MPL_APPLY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER apply.hpp # include #else # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include namespace boost { namespace mpl { // local macros, #undef-ined at the end of the header # define AUX778076_APPLY_PARAMS(param) \ BOOST_MPL_PP_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ ) \ /**/ # define AUX778076_APPLY_DEF_PARAMS(param, value) \ BOOST_MPL_PP_DEFAULT_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ , value \ ) \ /**/ # define AUX778076_APPLY_N_PARAMS(n, param) \ BOOST_MPL_PP_PARAMS(n, param) \ /**/ # define AUX778076_APPLY_N_COMMA_PARAMS(n, param) \ BOOST_PP_COMMA_IF(n) \ BOOST_MPL_PP_PARAMS(n, param) \ /**/ # define AUX778076_APPLY_N_PARTIAL_SPEC_PARAMS(n, param, def) \ BOOST_PP_COMMA_IF(n) \ BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(n, param, def) \ /**/ # define AUX778076_APPLY_N_SPEC_PARAMS(n, param) \ BOOST_MPL_PP_ENUM(BOOST_PP_INC(n), param) \ /**/ #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() # if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE) // real C++ version is already taken care of # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace aux { // apply_count_args #define AUX778076_COUNT_ARGS_PREFIX apply #define AUX778076_COUNT_ARGS_DEFAULT na #define AUX778076_COUNT_ARGS_ARITY BOOST_MPL_LIMIT_METAFUNCTION_ARITY #include } template< typename F, AUX778076_APPLY_DEF_PARAMS(typename T, na) > struct apply : aux::apply_chooser< aux::apply_count_args< AUX778076_APPLY_PARAMS(T) >::value >::template result_< F, AUX778076_APPLY_PARAMS(T) >::type { }; # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # endif // BOOST_MPL_CFG_NO_APPLY_TEMPLATE # undef AUX778076_APPLY_N_SPEC_PARAMS # undef AUX778076_APPLY_N_PARTIAL_SPEC_PARAMS # undef AUX778076_APPLY_N_COMMA_PARAMS # undef AUX778076_APPLY_N_PARAMS # undef AUX778076_APPLY_DEF_PARAMS # undef AUX778076_APPLY_PARAMS }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_APPLY_HPP_INCLUDED ///// iteration, depth == 1 // For gcc 4.4 compatability, we must include the // BOOST_PP_ITERATION_DEPTH test inside an #else clause. #else // BOOST_PP_IS_ITERATING #if BOOST_PP_ITERATION_DEPTH() == 1 # define i_ BOOST_PP_FRAME_ITERATION(1) template< typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T) > struct BOOST_PP_CAT(apply,i_) #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) : BOOST_PP_CAT(apply_wrap,i_)< typename lambda::type AUX778076_APPLY_N_COMMA_PARAMS(i_, T) > { #else { typedef typename BOOST_PP_CAT(apply_wrap,i_)< typename lambda::type AUX778076_APPLY_N_COMMA_PARAMS(i_, T) >::type type; #endif BOOST_MPL_AUX_LAMBDA_SUPPORT( BOOST_PP_INC(i_) , BOOST_PP_CAT(apply,i_) , (F AUX778076_APPLY_N_COMMA_PARAMS(i_,T)) ) }; #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) /// workaround for ETI bug template<> struct BOOST_PP_CAT(apply,i_) { typedef int type; }; #endif # if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE) # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) #if i_ == BOOST_MPL_LIMIT_METAFUNCTION_ARITY /// primary template (not a specialization!) template< typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T) > struct apply : BOOST_PP_CAT(apply,i_)< F AUX778076_APPLY_N_COMMA_PARAMS(i_, T) > { }; #else template< typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T) > struct apply< F AUX778076_APPLY_N_PARTIAL_SPEC_PARAMS(i_, T, na) > : BOOST_PP_CAT(apply,i_)< F AUX778076_APPLY_N_COMMA_PARAMS(i_, T) > { }; #endif # else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE) namespace aux { template<> struct apply_chooser { template< typename F, AUX778076_APPLY_PARAMS(typename T) > struct result_ { typedef BOOST_PP_CAT(apply,i_)< F AUX778076_APPLY_N_COMMA_PARAMS(i_, T) > type; }; }; } // namespace aux #endif # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # endif // BOOST_MPL_CFG_NO_APPLY_TEMPLATE # undef i_ #endif // BOOST_PP_ITERATION_DEPTH() #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/apply_fwd.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_APPLY_FWD_HPP_INCLUDED #define BOOST_MPL_APPLY_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER apply_fwd.hpp # include #else # include # include # include # include # include # include # include # include // agurt, 15/jan/02: top-level 'apply' template gives an ICE on MSVC // (for known reasons) #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) # define BOOST_MPL_CFG_NO_APPLY_TEMPLATE #endif namespace boost { namespace mpl { // local macro, #undef-ined at the end of the header # define AUX778076_APPLY_DEF_PARAMS(param, value) \ BOOST_MPL_PP_DEFAULT_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ , value \ ) \ /**/ # define AUX778076_APPLY_N_COMMA_PARAMS(n, param) \ BOOST_PP_COMMA_IF(n) \ BOOST_MPL_PP_PARAMS(n, param) \ /**/ # if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE) #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) // forward declaration template< typename F, AUX778076_APPLY_DEF_PARAMS(typename T, na) > struct apply; #else namespace aux { template< BOOST_AUX_NTTP_DECL(int, arity_) > struct apply_chooser; } #endif # endif // BOOST_MPL_CFG_NO_APPLY_TEMPLATE #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() # undef AUX778076_APPLY_N_COMMA_PARAMS # undef AUX778076_APPLY_DEF_PARAMS }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_APPLY_FWD_HPP_INCLUDED ///// iteration #else #define i_ BOOST_PP_FRAME_ITERATION(1) template< typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T) > struct BOOST_PP_CAT(apply,i_); #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/apply_wrap.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_APPLY_WRAP_HPP_INCLUDED #define BOOST_MPL_APPLY_WRAP_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER apply_wrap.hpp # include #else # include # include # include # include # include # include # include # include # include # include # include # include # include # include namespace boost { namespace mpl { // local macros, #undef-ined at the end of the header # define AUX778076_APPLY_WRAP_PARAMS(n, param) \ BOOST_MPL_PP_PARAMS(n, param) \ /**/ # define AUX778076_APPLY_WRAP_SPEC_PARAMS(n, param) \ BOOST_MPL_PP_ENUM(BOOST_PP_INC(n), param) \ /**/ #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() # undef AUX778076_APPLY_WRAP_SPEC_PARAMS # undef AUX778076_APPLY_WRAP_PARAMS }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_APPLY_WRAP_HPP_INCLUDED ///// iteration, depth == 1 // For gcc 4.4 compatability, we must include the // BOOST_PP_ITERATION_DEPTH test inside an #else clause. #else // BOOST_PP_IS_ITERATING #if BOOST_PP_ITERATION_DEPTH() == 1 # define i_ BOOST_PP_FRAME_ITERATION(1) # if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // MSVC version #define AUX778076_MSVC_DTW_NAME BOOST_PP_CAT(msvc_apply,i_) #define AUX778076_MSVC_DTW_ORIGINAL_NAME apply #define AUX778076_MSVC_DTW_ARITY i_ #include template< typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T) > struct BOOST_PP_CAT(apply_wrap,i_) { // Metafunction forwarding confuses vc6 typedef typename BOOST_PP_CAT(msvc_apply,i_)::template result_< AUX778076_APPLY_WRAP_PARAMS(i_, T) >::type type; }; # elif defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) // MWCW/Borland version template< int N, typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T) > struct BOOST_PP_CAT(apply_wrap_impl,i_); #define BOOST_PP_ITERATION_PARAMS_2 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY - i_, )) #include BOOST_PP_ITERATE() template< typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T) > struct BOOST_PP_CAT(apply_wrap,i_) : BOOST_PP_CAT(apply_wrap_impl,i_)< ::boost::mpl::aux::arity::value , F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, T) >::type { }; # else // ISO98 C++, with minor concession to vc7 template< typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T) #if i_ == 0 , typename has_apply_ = typename aux::has_apply::type #endif > struct BOOST_PP_CAT(apply_wrap,i_) // metafunction forwarding confuses MSVC 7.0 #if !BOOST_WORKAROUND(BOOST_MSVC, == 1300) : F::template apply< AUX778076_APPLY_WRAP_PARAMS(i_, T) > { #else { typedef typename F::template apply< AUX778076_APPLY_WRAP_PARAMS(i_, T) >::type type; #endif }; #if i_ == 0 && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename F > struct BOOST_PP_CAT(apply_wrap,i_) : F::apply { }; #endif # endif // workarounds #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) /// workaround for ETI bug template<> struct BOOST_PP_CAT(apply_wrap,i_) { typedef int type; }; #endif # undef i_ ///// iteration, depth == 2 #elif BOOST_PP_ITERATION_DEPTH() == 2 # define j_ BOOST_PP_FRAME_ITERATION(2) #if i_ == 0 && j_ == 0 \ && defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS) \ && !defined(BOOST_MPL_CFG_NO_HAS_APPLY) template< typename F, bool F_has_apply > struct apply_wrap_impl0_bcb { typedef typename F::template apply< na > type; }; template< typename F > struct apply_wrap_impl0_bcb< F, true > { typedef typename F::apply type; }; template< typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T) > struct BOOST_PP_CAT(apply_wrap_impl,i_)< BOOST_MPL_PP_ADD(i_, j_) , F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, T) > { typedef apply_wrap_impl0_bcb< F, aux::has_apply< F >::value >::type type; }; #else template< typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T) > struct BOOST_PP_CAT(apply_wrap_impl,i_)< BOOST_MPL_PP_ADD(i_, j_) , F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, T) > { typedef typename F::template apply< AUX778076_APPLY_WRAP_PARAMS(i_, T) #if i_ == 0 && j_ == 0 /// since the defaults are "lost", we have to pass *something* even for nullary /// metafunction classes na #else BOOST_PP_COMMA_IF(BOOST_PP_AND(i_, j_)) BOOST_MPL_PP_ENUM(j_, na) #endif > type; }; #endif # undef j_ #endif // BOOST_PP_ITERATION_DEPTH() #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/arg.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_ARG_HPP_INCLUDED #define BOOST_MPL_ARG_HPP_INCLUDED // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include #endif #include #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER arg.hpp # include #else # include # include # include # include # include # include # include # include # include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN // local macro, #undef-ined at the end of the header #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # define AUX778076_ARG_N_DEFAULT_PARAMS(param,value) \ BOOST_MPL_PP_DEFAULT_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ , value \ ) \ /**/ #else # define AUX778076_ARG_N_DEFAULT_PARAMS(param,value) \ BOOST_MPL_PP_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ ) \ /**/ #endif #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() # undef AUX778076_ARG_N_DEFAULT_PARAMS BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int,arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_ARG_HPP_INCLUDED ///// iteration #else #define i_ BOOST_PP_FRAME_ITERATION(1) #if i_ > 0 template<> struct arg { BOOST_STATIC_CONSTANT(int, value = i_); typedef arg next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< AUX778076_ARG_N_DEFAULT_PARAMS(typename U, na) > struct apply { typedef BOOST_PP_CAT(U,i_) type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; #else template<> struct arg<-1> { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< AUX778076_ARG_N_DEFAULT_PARAMS(typename U, na) > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; #endif // i_ > 0 #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/arg_fwd.hpp ================================================ #ifndef BOOST_MPL_ARG_FWD_HPP_INCLUDED #define BOOST_MPL_ARG_FWD_HPP_INCLUDED // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct arg; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(arg) #endif // BOOST_MPL_ARG_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/assert.hpp ================================================ #ifndef BOOST_MPL_ASSERT_HPP_INCLUDED #define BOOST_MPL_ASSERT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // make sure 'size_t' is placed into 'std' #include #if BOOST_WORKAROUND(BOOST_MSVC, == 1700) #include #endif #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || (BOOST_MPL_CFG_GCC != 0) \ || BOOST_WORKAROUND(__IBMCPP__, <= 600) # define BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES #endif #if BOOST_WORKAROUND(__MWERKS__, < 0x3202) \ || BOOST_WORKAROUND(__EDG_VERSION__, <= 238) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) # define BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER #endif // agurt, 10/nov/06: use enums for Borland (which cannot cope with static constants) // and GCC (which issues "unused variable" warnings when static constants are used // at a function scope) #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || (BOOST_MPL_CFG_GCC != 0) || (BOOST_MPL_CFG_GPU != 0) # define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) enum { expr } #else # define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) BOOST_STATIC_CONSTANT(T, expr) #endif BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN struct failed {}; // agurt, 24/aug/04: MSVC 7.1 workaround here and below: return/accept // 'assert' by reference; can't apply it unconditionally -- apparently it // degrades the quality of GCC diagnostics #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) # define AUX778076_ASSERT_ARG(x) x& #else # define AUX778076_ASSERT_ARG(x) x #endif template< bool C > struct assert { typedef void* type; }; template<> struct assert { typedef AUX778076_ASSERT_ARG(assert) type; }; template< bool C > int assertion_failed( typename assert::type ); template< bool C > struct assertion { static int failed( assert ); }; template<> struct assertion { static int failed( void* ); }; struct assert_ { #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) template< typename T1, typename T2 = na, typename T3 = na, typename T4 = na > struct types {}; #endif static assert_ const arg; enum relations { equal = 1, not_equal, greater, greater_equal, less, less_equal }; }; #if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES) bool operator==( failed, failed ); bool operator!=( failed, failed ); bool operator>( failed, failed ); bool operator>=( failed, failed ); bool operator<( failed, failed ); bool operator<=( failed, failed ); #if defined(__EDG_VERSION__) template< bool (*)(failed, failed), long x, long y > struct assert_relation {}; # define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation #else template< BOOST_MPL_AUX_NTTP_DECL(long, x), BOOST_MPL_AUX_NTTP_DECL(long, y), bool (*)(failed, failed) > struct assert_relation {}; # define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation #endif #else // BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES boost::mpl::aux::weighted_tag<1>::type operator==( assert_, assert_ ); boost::mpl::aux::weighted_tag<2>::type operator!=( assert_, assert_ ); boost::mpl::aux::weighted_tag<3>::type operator>( assert_, assert_ ); boost::mpl::aux::weighted_tag<4>::type operator>=( assert_, assert_ ); boost::mpl::aux::weighted_tag<5>::type operator<( assert_, assert_ ); boost::mpl::aux::weighted_tag<6>::type operator<=( assert_, assert_ ); template< assert_::relations r, long x, long y > struct assert_relation {}; #endif #if BOOST_WORKAROUND(BOOST_MSVC, == 1700) template struct extract_assert_pred; template struct extract_assert_pred { typedef Pred type; }; template struct eval_assert { typedef typename extract_assert_pred::type P; typedef typename P::type p_type; typedef typename ::boost::mpl::if_c), failed ************ P::************ >::type type; }; template struct eval_assert_not { typedef typename extract_assert_pred::type P; typedef typename P::type p_type; typedef typename ::boost::mpl::if_c), failed ************ ::boost::mpl::not_

::************ >::type type; }; template< typename T > T make_assert_arg(); #elif !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) template< bool > struct assert_arg_pred_impl { typedef int type; }; template<> struct assert_arg_pred_impl { typedef void* type; }; template< typename P > struct assert_arg_pred { typedef typename P::type p_type; typedef typename assert_arg_pred_impl< p_type::value >::type type; }; template< typename P > struct assert_arg_pred_not { typedef typename P::type p_type; BOOST_MPL_AUX_ASSERT_CONSTANT( bool, p = !p_type::value ); typedef typename assert_arg_pred_impl

::type type; }; template< typename Pred > failed ************ (Pred::************ assert_arg( void (*)(Pred), typename assert_arg_pred::type ) ); template< typename Pred > failed ************ (boost::mpl::not_::************ assert_not_arg( void (*)(Pred), typename assert_arg_pred_not::type ) ); template< typename Pred > AUX778076_ASSERT_ARG(assert) assert_arg( void (*)(Pred), typename assert_arg_pred_not::type ); template< typename Pred > AUX778076_ASSERT_ARG(assert) assert_not_arg( void (*)(Pred), typename assert_arg_pred::type ); #else // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER template< bool c, typename Pred > struct assert_arg_type_impl { typedef failed ************ Pred::* mwcw83_wknd; typedef mwcw83_wknd ************* type; }; template< typename Pred > struct assert_arg_type_impl { typedef AUX778076_ASSERT_ARG(assert) type; }; template< typename Pred > struct assert_arg_type : assert_arg_type_impl< BOOST_MPL_AUX_VALUE_WKND(BOOST_MPL_AUX_NESTED_TYPE_WKND(Pred))::value, Pred > { }; template< typename Pred > typename assert_arg_type::type assert_arg(void (*)(Pred), int); template< typename Pred > typename assert_arg_type< boost::mpl::not_ >::type assert_not_arg(void (*)(Pred), int); # if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES) template< long x, long y, bool (*r)(failed, failed) > typename assert_arg_type_impl< false,BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) >::type assert_rel_arg( BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) ); # else template< assert_::relations r, long x, long y > typename assert_arg_type_impl< false,assert_relation >::type assert_rel_arg( assert_relation ); # endif #endif // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER #undef AUX778076_ASSERT_ARG BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE #if BOOST_WORKAROUND(BOOST_MSVC, == 1700) // BOOST_MPL_ASSERT((pred)) #define BOOST_MPL_ASSERT(pred) \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion_failed( \ boost::mpl::make_assert_arg< \ typename boost::mpl::eval_assert::type \ >() \ ) \ ) \ ) \ /**/ // BOOST_MPL_ASSERT_NOT((pred)) #define BOOST_MPL_ASSERT_NOT(pred) \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion_failed( \ boost::mpl::make_assert_arg< \ typename boost::mpl::eval_assert_not::type \ >() \ ) \ ) \ ) \ /**/ #else // BOOST_MPL_ASSERT((pred)) #define BOOST_MPL_ASSERT(pred) \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion_failed( \ boost::mpl::assert_arg( (void (*) pred)0, 1 ) \ ) \ ) \ ) \ /**/ // BOOST_MPL_ASSERT_NOT((pred)) #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) # define BOOST_MPL_ASSERT_NOT(pred) \ enum { \ BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion::failed( \ boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \ ) \ ) \ }\ /**/ #else # define BOOST_MPL_ASSERT_NOT(pred) \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion_failed( \ boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \ ) \ ) \ ) \ /**/ #endif #endif // BOOST_MPL_ASSERT_RELATION(x, ==|!=|<=|<|>=|>, y) #if defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES) # if !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) // agurt, 9/nov/06: 'enum' below is a workaround for gcc 4.0.4/4.1.1 bugs #29522 and #29518 # define BOOST_MPL_ASSERT_RELATION_IMPL(counter, x, rel, y) \ enum { BOOST_PP_CAT(mpl_assert_rel_value,counter) = (x rel y) }; \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \ boost::mpl::assertion_failed( \ (boost::mpl::failed ************ ( boost::mpl::assert_relation< \ boost::mpl::assert_::relations( sizeof( \ boost::mpl::assert_::arg rel boost::mpl::assert_::arg \ ) ) \ , x \ , y \ >::************)) 0 ) \ ) \ ) \ /**/ # else # define BOOST_MPL_ASSERT_RELATION_IMPL(counter, x, rel, y) \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assert_rel,counter) = sizeof( \ boost::mpl::assert_::arg rel boost::mpl::assert_::arg \ ) \ ); \ BOOST_MPL_AUX_ASSERT_CONSTANT( bool, BOOST_PP_CAT(mpl_assert_rel_value,counter) = (x rel y) ); \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \ boost::mpl::assertion_failed( \ boost::mpl::assert_rel_arg( boost::mpl::assert_relation< \ boost::mpl::assert_::relations(BOOST_PP_CAT(mpl_assert_rel,counter)) \ , x \ , y \ >() ) \ ) \ ) \ ) \ /**/ # endif # define BOOST_MPL_ASSERT_RELATION(x, rel, y) \ BOOST_MPL_ASSERT_RELATION_IMPL(BOOST_MPL_AUX_PP_COUNTER(), x, rel, y) \ /**/ #else // !BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES # if defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) # define BOOST_MPL_ASSERT_RELATION(x, rel, y) \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion_failed<(x rel y)>( boost::mpl::assert_rel_arg( \ boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))() \ ) ) \ ) \ ) \ /**/ # else # define BOOST_MPL_ASSERT_RELATION(x, rel, y) \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion_failed<(x rel y)>( (boost::mpl::failed ************ ( \ boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))::************))0 ) \ ) \ ) \ /**/ # endif #endif // BOOST_MPL_ASSERT_MSG( (pred::value), USER_PROVIDED_MESSAGE, (types) ) #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) # define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ ) \ struct msg; \ typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \ { \ using boost::mpl::assert_::types; \ static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \ { return 0; } \ } BOOST_PP_CAT(mpl_assert_arg,counter); \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \ boost::mpl::assertion<(c)>::failed( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \ ) \ ) \ /**/ #else # define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ ) \ struct msg; \ typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \ { \ static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \ { return 0; } \ } BOOST_PP_CAT(mpl_assert_arg,counter); \ BOOST_MPL_AUX_ASSERT_CONSTANT( \ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \ boost::mpl::assertion_failed<(c)>( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \ ) \ ) \ /**/ #endif #define BOOST_MPL_ASSERT_MSG( c, msg, types_ ) \ BOOST_MPL_ASSERT_MSG_IMPL( BOOST_MPL_AUX_PP_COUNTER(), c, msg, types_ ) \ /**/ #endif // BOOST_MPL_ASSERT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/at_fwd.hpp ================================================ #ifndef BOOST_MPL_AT_FWD_HPP_INCLUDED #define BOOST_MPL_AT_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct at_impl; template< typename Sequence, typename N > struct at; }} #endif // BOOST_MPL_AT_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/O1_size_impl.hpp ================================================ #ifndef BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED #define BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include namespace boost { namespace mpl { // default implementation - returns 'Sequence::size' if sequence has a 'size' // member, and -1 otherwise; conrete sequences might override it by // specializing either the 'O1_size_impl' or the primary 'O1_size' template # if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ && !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) namespace aux { template< typename Sequence > struct O1_size_impl : Sequence::size { }; } template< typename Tag > struct O1_size_impl { template< typename Sequence > struct apply #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) : if_< aux::has_size , aux::O1_size_impl , long_<-1> >::type { #else { typedef typename if_< aux::has_size , aux::O1_size_impl , long_<-1> >::type type; BOOST_STATIC_CONSTANT(long, value = (if_< aux::has_size , aux::O1_size_impl , long_<-1> >::type::value) ); #endif }; }; # else // BOOST_MSVC template< typename Tag > struct O1_size_impl { template< typename Sequence > struct apply : long_<-1> { }; }; # endif }} #endif // BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/adl_barrier.hpp ================================================ #ifndef BOOST_MPL_AUX_ADL_BARRIER_HPP_INCLUDED #define BOOST_MPL_AUX_ADL_BARRIER_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !defined(BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE) # define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE mpl_ # define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN namespace mpl_ { # define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE } # define BOOST_MPL_AUX_ADL_BARRIER_DECL(type) \ namespace boost { namespace mpl { \ using ::BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::type; \ } } \ /**/ #if !defined(BOOST_MPL_PREPROCESSING_MODE) namespace BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE { namespace aux {} } namespace boost { namespace mpl { using namespace BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE; namespace aux { using namespace BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::aux; } }} #endif #else // BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE # define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE boost::mpl # define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN namespace boost { namespace mpl { # define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE }} # define BOOST_MPL_AUX_ADL_BARRIER_DECL(type) /**/ #endif #endif // BOOST_MPL_AUX_ADL_BARRIER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/arg_typedef.hpp ================================================ #ifndef BOOST_MPL_AUX_ARG_TYPEDEF_HPP_INCLUDED #define BOOST_MPL_AUX_ARG_TYPEDEF_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) \ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) # define BOOST_MPL_AUX_ARG_TYPEDEF(T, name) typedef T name; #else # define BOOST_MPL_AUX_ARG_TYPEDEF(T, name) /**/ #endif #endif // BOOST_MPL_AUX_ARG_TYPEDEF_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/arity.hpp ================================================ #ifndef BOOST_MPL_AUX_ARITY_HPP_INCLUDED #define BOOST_MPL_AUX_ARITY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # include # include namespace boost { namespace mpl { namespace aux { // agurt, 15/mar/02: it's possible to implement the template so that it will // "just work" and do not require any specialization, but not on the compilers // that require the arity workaround in the first place template< typename F, BOOST_MPL_AUX_NTTP_DECL(int, N) > struct arity { BOOST_STATIC_CONSTANT(int, value = N); }; }}} #endif // BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES #endif // BOOST_MPL_AUX_ARITY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/arity_spec.hpp ================================================ #ifndef BOOST_MPL_AUX_ARITY_SPEC_HPP_INCLUDED #define BOOST_MPL_AUX_ARITY_SPEC_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include #include #if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # define BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(i,type,name) \ namespace aux { \ template< BOOST_MPL_AUX_NTTP_DECL(int, N), BOOST_MPL_PP_PARAMS(i,type T) > \ struct arity< \ name< BOOST_MPL_PP_PARAMS(i,T) > \ , N \ > \ { \ BOOST_STATIC_CONSTANT(int \ , value = BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ ); \ }; \ } \ /**/ #else # define BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(i,type,name) /**/ #endif # define BOOST_MPL_AUX_ARITY_SPEC(i,name) \ BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(i,typename,name) \ /**/ #if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) \ && !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # define BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(i, name) \ namespace aux { \ template< BOOST_MPL_PP_PARAMS(i,typename T) > \ struct template_arity< name > \ : int_ \ { \ }; \ } \ /**/ #else # define BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(i, name) /**/ #endif #endif // BOOST_MPL_AUX_ARITY_SPEC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/begin_end_impl.hpp ================================================ #ifndef BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED #define BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include namespace boost { namespace mpl { namespace aux { template< typename Sequence > struct begin_type { typedef typename Sequence::begin type; }; template< typename Sequence > struct end_type { typedef typename Sequence::end type; }; } // default implementation; conrete sequences might override it by // specializing either the 'begin_impl/end_impl' or the primary // 'begin/end' templates template< typename Tag > struct begin_impl { template< typename Sequence > struct apply { typedef typename eval_if, aux::begin_type, void_>::type type; }; }; template< typename Tag > struct end_impl { template< typename Sequence > struct apply { typedef typename eval_if, aux::end_type, void_>::type type; }; }; // specialize 'begin_trait/end_trait' for two pre-defined tags # define AUX778076_IMPL_SPEC(name, tag, result) \ template<> \ struct name##_impl \ { \ template< typename Sequence > struct apply \ { \ typedef result type; \ }; \ }; \ /**/ // a sequence with nested 'begin/end' typedefs; just query them AUX778076_IMPL_SPEC(begin, nested_begin_end_tag, typename Sequence::begin) AUX778076_IMPL_SPEC(end, nested_begin_end_tag, typename Sequence::end) // if a type 'T' does not contain 'begin/end' or 'tag' members // and doesn't specialize either 'begin/end' or 'begin_impl/end_impl' // templates, then we end up here AUX778076_IMPL_SPEC(begin, non_sequence_tag, void_) AUX778076_IMPL_SPEC(end, non_sequence_tag, void_) AUX778076_IMPL_SPEC(begin, na, void_) AUX778076_IMPL_SPEC(end, na, void_) # undef AUX778076_IMPL_SPEC BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,begin_impl) BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,end_impl) }} #endif // BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/clear_impl.hpp ================================================ #ifndef BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED #define BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { // no default implementation; the definition is needed to make MSVC happy template< typename Tag > struct clear_impl { template< typename Sequence > struct apply; }; BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, clear_impl) }} #endif // BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/common_name_wknd.hpp ================================================ #ifndef BOOST_MPL_AUX_COMMON_NAME_WKND_HPP_INCLUDED #define BOOST_MPL_AUX_COMMON_NAME_WKND_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if BOOST_WORKAROUND(__BORLANDC__, < 0x561) // agurt, 12/nov/02: to suppress the bogus "Cannot have both a template class // and function named 'xxx'" diagnostic # define BOOST_MPL_AUX_COMMON_NAME_WKND(name) \ namespace name_##wknd { \ template< typename > void name(); \ } \ /**/ #else # define BOOST_MPL_AUX_COMMON_NAME_WKND(name) /**/ #endif // __BORLANDC__ #endif // BOOST_MPL_AUX_COMMON_NAME_WKND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/adl.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_ADL_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_ADL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include // agurt, 25/apr/04: technically, the ADL workaround is only needed for GCC, // but putting everything expect public, user-specializable metafunctions into // a separate global namespace has a nice side effect of reducing the length // of template instantiation symbols, so we apply the workaround on all // platforms that can handle it #if !defined(BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE) \ && ( BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) \ ) # define BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE #endif #endif // BOOST_MPL_AUX_CONFIG_ADL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/arrays.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_ARRAYS_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_ARRAYS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if !defined(BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && ( BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ ) # define BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES #endif #endif // BOOST_MPL_AUX_CONFIG_ARRAYS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/bcc.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_BCC_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_BCC_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date: 2004-09-02 10:41:37 -0500 (Thu, 02 Sep 2004) $ // $Revision: 24874 $ #include #if !defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(__BORLANDC__, >= 0x590) \ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) # define BOOST_MPL_CFG_BCC590_WORKAROUNDS #endif #endif // BOOST_MPL_AUX_CONFIG_BCC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/bind.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_BIND_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_BIND_HPP_INCLUDED // Copyright David Abrahams 2002 // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && ( BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ ) # define BOOST_MPL_CFG_NO_BIND_TEMPLATE #endif //#define BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT #endif // BOOST_MPL_AUX_CONFIG_BIND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/compiler.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_COMPILER_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_COMPILER_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_CFG_COMPILER_DIR) # include # include # include # include # include # include # if BOOST_WORKAROUND(BOOST_MSVC, < 1300) # define BOOST_MPL_CFG_COMPILER_DIR msvc60 # elif BOOST_WORKAROUND(BOOST_MSVC, == 1300) # define BOOST_MPL_CFG_COMPILER_DIR msvc70 # elif BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304)) # define BOOST_MPL_CFG_COMPILER_DIR gcc # elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) # if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # define BOOST_MPL_CFG_COMPILER_DIR bcc551 # elif BOOST_WORKAROUND(__BORLANDC__, >= 0x590) # define BOOST_MPL_CFG_COMPILER_DIR bcc # else # define BOOST_MPL_CFG_COMPILER_DIR bcc_pre590 # endif # elif BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) # define BOOST_MPL_CFG_COMPILER_DIR dmc # elif defined(__MWERKS__) # if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # define BOOST_MPL_CFG_COMPILER_DIR mwcw # else # define BOOST_MPL_CFG_COMPILER_DIR plain # endif # elif defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) # define BOOST_MPL_CFG_COMPILER_DIR no_ctps # elif defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) # define BOOST_MPL_CFG_COMPILER_DIR no_ttp # else # define BOOST_MPL_CFG_COMPILER_DIR plain # endif #endif // BOOST_MPL_CFG_COMPILER_DIR #endif // BOOST_MPL_AUX_CONFIG_COMPILER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/ctps.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_CTPS_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_CTPS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(__BORLANDC__, < 0x582) # define BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION is defined in #endif // BOOST_MPL_AUX_CONFIG_CTPS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_DMC_AMBIGUOUS_CTPS_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_DMC_AMBIGUOUS_CTPS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) # define BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS #endif #endif // BOOST_MPL_AUX_CONFIG_DMC_AMBIGUOUS_CTPS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/dtp.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_DTP_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_DTP_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include // MWCW 7.x-8.0 "losts" default template parameters of nested class // templates when their owner classes are passed as arguments to other // templates; Borland 5.5.1 "forgets" them from the very beginning (if // the owner class is a class template), and Borland 5.6 isn't even // able to compile a definition of nested class template with DTP #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(__BORLANDC__, >= 0x560) \ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) # define BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES #endif #if !defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && ( BOOST_WORKAROUND(__MWERKS__, <= 0x3001) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) \ ) # define BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES #endif #endif // BOOST_MPL_AUX_CONFIG_DTP_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/eti.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_ETI_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_ETI_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include // flags for MSVC 6.5's so-called "early template instantiation bug" #if !defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(BOOST_MSVC, < 1300) # define BOOST_MPL_CFG_MSVC_60_ETI_BUG #endif #if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(BOOST_MSVC, == 1300) # define BOOST_MPL_CFG_MSVC_70_ETI_BUG #endif #if !defined(BOOST_MPL_CFG_MSVC_ETI_BUG) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && ( defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) \ || defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) \ ) # define BOOST_MPL_CFG_MSVC_ETI_BUG #endif #endif // BOOST_MPL_AUX_CONFIG_ETI_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/forwarding.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_FORWARDING_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_FORWARDING_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) # define BOOST_MPL_CFG_NO_NESTED_FORWARDING #endif #endif // BOOST_MPL_AUX_CONFIG_FORWARDING_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/gcc.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_GCC_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_GCC_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if defined(__GNUC__) && !defined(__EDG_VERSION__) # define BOOST_MPL_CFG_GCC ((__GNUC__ << 8) | __GNUC_MINOR__) #else # define BOOST_MPL_CFG_GCC 0 #endif #endif // BOOST_MPL_AUX_CONFIG_GCC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/gpu.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_GPU_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_GPU_HPP_INCLUDED // Copyright Eric Niebler 2014 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_GPU_ENABLED) \ # define BOOST_MPL_CFG_GPU_ENABLED BOOST_GPU_ENABLED #endif #if defined __CUDACC__ # define BOOST_MPL_CFG_GPU 1 #else # define BOOST_MPL_CFG_GPU 0 #endif #endif // BOOST_MPL_AUX_CONFIG_GPU_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/has_apply.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_HAS_APPLY_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_HAS_APPLY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !defined(BOOST_MPL_CFG_NO_HAS_APPLY) \ && ( defined(BOOST_MPL_CFG_NO_HAS_XXX) \ || BOOST_WORKAROUND(__EDG_VERSION__, < 300) \ || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ ) # define BOOST_MPL_CFG_NO_HAS_APPLY #endif #endif // BOOST_MPL_AUX_CONFIG_HAS_APPLY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/has_xxx.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_HAS_XXX_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_HAS_XXX_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // Copyright David Abrahams 2002-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include // agurt, 11/jan/03: signals a stub-only 'has_xxx' implementation #if !defined(BOOST_MPL_CFG_NO_HAS_XXX) \ && ( defined(BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION) \ || BOOST_WORKAROUND(__GNUC__, <= 2) \ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \ ) # define BOOST_MPL_CFG_NO_HAS_XXX # define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE #endif #endif // BOOST_MPL_AUX_CONFIG_HAS_XXX_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/integral.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_INTEGRAL_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_INTEGRAL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if !defined(BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) # define BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS #endif #if !defined(BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && ( BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || BOOST_WORKAROUND(__EDG_VERSION__, <= 238) \ ) # define BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC #endif #endif // BOOST_MPL_AUX_CONFIG_INTEGRAL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/intel.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_INTEL_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_INTEL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ // BOOST_INTEL_CXX_VERSION is defined here: #include #endif // BOOST_MPL_AUX_CONFIG_INTEL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/lambda.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_LAMBDA_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_LAMBDA_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include // agurt, 15/jan/02: full-fledged implementation requires both // template template parameters _and_ partial specialization #if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) \ && ( defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) \ || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ ) # define BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT #endif #endif // BOOST_MPL_AUX_CONFIG_LAMBDA_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/msvc.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_MSVC_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_MSVC_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ // BOOST_MSVC is defined here: #include #endif // BOOST_MPL_AUX_CONFIG_MSVC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/msvc_typename.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_MSVC_TYPENAME_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_MSVC_TYPENAME_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) # define BOOST_MSVC_TYPENAME #else # define BOOST_MSVC_TYPENAME typename #endif #endif // BOOST_MPL_AUX_CONFIG_MSVC_TYPENAME_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/nttp.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_NTTP_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_NTTP_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include // MSVC 6.5 ICE-s on the code as simple as this (see "aux_/nttp_decl.hpp" // for a workaround): // // namespace std { // template< typename Char > struct string; // } // // void foo(std::string); // // namespace boost { namespace mpl { // template< int > struct arg; // }} #if !defined(BOOST_MPL_CFG_NTTP_BUG) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && BOOST_WORKAROUND(BOOST_MSVC, < 1300) # define BOOST_MPL_CFG_NTTP_BUG #endif #endif // BOOST_MPL_AUX_CONFIG_NTTP_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/operators.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_OPERATORS_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_OPERATORS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !defined(BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING) \ && ( BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || BOOST_WORKAROUND(__EDG_VERSION__, <= 245) \ || BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0295) \ || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ || BOOST_WORKAROUND(__NVCC__, BOOST_TESTED_AT(1)) \ ) # define BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING #endif #endif // BOOST_MPL_AUX_CONFIG_OPERATORS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/overload_resolution.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_OVERLOAD_RESOLUTION_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_OVERLOAD_RESOLUTION_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && ( BOOST_WORKAROUND(__BORLANDC__, < 0x590) \ || BOOST_WORKAROUND(__MWERKS__, < 0x3001) \ ) # define BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION #endif #endif // BOOST_MPL_AUX_CONFIG_OVERLOAD_RESOLUTION_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/pp_counter.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_PP_COUNTER_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_PP_COUNTER_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_AUX_PP_COUNTER) # include # if BOOST_WORKAROUND(BOOST_MSVC, >= 1300) # define BOOST_MPL_AUX_PP_COUNTER() __COUNTER__ # else # define BOOST_MPL_AUX_PP_COUNTER() __LINE__ # endif #endif #endif // BOOST_MPL_AUX_CONFIG_PP_COUNTER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/preprocessor.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_PREPROCESSOR_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_PREPROCESSOR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_BROKEN_PP_MACRO_EXPANSION) \ && ( BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ || BOOST_WORKAROUND(__BORLANDC__, < 0x582) \ || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(502)) \ ) # define BOOST_MPL_CFG_BROKEN_PP_MACRO_EXPANSION #endif #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # define BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES #endif #if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING) \ && BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) # define BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING #endif #endif // BOOST_MPL_AUX_CONFIG_PREPROCESSOR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/static_constant.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_STATIC_CONSTANT_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_STATIC_CONSTANT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) // BOOST_STATIC_CONSTANT is defined here: # include #else // undef the macro for the preprocessing mode # undef BOOST_STATIC_CONSTANT #endif #endif // BOOST_MPL_AUX_CONFIG_STATIC_CONSTANT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/ttp.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_TTP_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_TTP_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) \ && ( defined(BOOST_NO_TEMPLATE_TEMPLATES) \ || BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x590) ) \ ) # define BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS #endif #if !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) \ && ( BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0302)) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ ) # define BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING #endif #endif // BOOST_MPL_AUX_CONFIG_TTP_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/use_preprocessed.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_USE_PREPROCESSED_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_USE_PREPROCESSED_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ // #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AUX_CONFIG_USE_PREPROCESSED_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/config/workaround.hpp ================================================ #ifndef BOOST_MPL_AUX_CONFIG_WORKAROUND_HPP_INCLUDED #define BOOST_MPL_AUX_CONFIG_WORKAROUND_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #endif // BOOST_MPL_AUX_CONFIG_WORKAROUND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/count_args.hpp ================================================ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !defined(AUX778076_COUNT_ARGS_PARAM_NAME) # define AUX778076_COUNT_ARGS_PARAM_NAME T #endif #if !defined(AUX778076_COUNT_ARGS_TEMPLATE_PARAM) # define AUX778076_COUNT_ARGS_TEMPLATE_PARAM typename AUX778076_COUNT_ARGS_PARAM_NAME #endif // local macros, #undef-ined at the end of the header #if !defined(AUX778076_COUNT_ARGS_USE_STANDARD_PP_PRIMITIVES) # include # include # define AUX778076_COUNT_ARGS_REPEAT BOOST_MPL_PP_REPEAT # define AUX778076_COUNT_ARGS_PARAMS(param) \ BOOST_MPL_PP_PARAMS( \ AUX778076_COUNT_ARGS_ARITY \ , param \ ) \ /**/ #else # include # include # include # define AUX778076_COUNT_ARGS_REPEAT BOOST_PP_REPEAT # define AUX778076_COUNT_ARGS_PARAMS(param) \ BOOST_PP_ENUM_SHIFTED_PARAMS( \ BOOST_PP_INC(AUX778076_COUNT_ARGS_ARITY) \ , param \ ) \ /**/ #endif // AUX778076_COUNT_ARGS_USE_STANDARD_PP_PRIMITIVES #define AUX778076_IS_ARG_TEMPLATE_NAME \ BOOST_PP_CAT(is_,BOOST_PP_CAT(AUX778076_COUNT_ARGS_PREFIX,_arg)) \ /**/ #define AUX778076_COUNT_ARGS_FUNC(unused, i, param) \ BOOST_PP_EXPR_IF(i, +) \ AUX778076_IS_ARG_TEMPLATE_NAME::value \ /**/ // is__arg template< AUX778076_COUNT_ARGS_TEMPLATE_PARAM > struct AUX778076_IS_ARG_TEMPLATE_NAME { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct AUX778076_IS_ARG_TEMPLATE_NAME { BOOST_STATIC_CONSTANT(bool, value = false); }; // _count_args template< AUX778076_COUNT_ARGS_PARAMS(AUX778076_COUNT_ARGS_TEMPLATE_PARAM) > struct BOOST_PP_CAT(AUX778076_COUNT_ARGS_PREFIX,_count_args) { BOOST_STATIC_CONSTANT(int, value = AUX778076_COUNT_ARGS_REPEAT( AUX778076_COUNT_ARGS_ARITY , AUX778076_COUNT_ARGS_FUNC , AUX778076_COUNT_ARGS_PARAM_NAME )); }; #undef AUX778076_COUNT_ARGS_FUNC #undef AUX778076_IS_ARG_TEMPLATE_NAME #undef AUX778076_COUNT_ARGS_PARAMS #undef AUX778076_COUNT_ARGS_REPEAT #undef AUX778076_COUNT_ARGS_ARITY #undef AUX778076_COUNT_ARGS_DEFAULT #undef AUX778076_COUNT_ARGS_PREFIX #undef AUX778076_COUNT_ARGS_USE_STANDARD_PP_PRIMITIVES #undef AUX778076_COUNT_ARGS_TEMPLATE_PARAM #undef AUX778076_COUNT_ARGS_PARAM_NAME ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/find_if_pred.hpp ================================================ #ifndef BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED #define BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Eric Friedman 2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. #include #include namespace boost { namespace mpl { namespace aux { template< typename Predicate > struct find_if_pred { template< typename Iterator > struct apply { typedef not_< aux::iter_apply1 > type; }; }; }}} #endif // BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/fold_impl.hpp ================================================ #ifndef BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED #define BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) # include # include # endif #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER fold_impl.hpp # include #else # define AUX778076_FOLD_IMPL_OP(iter) typename deref::type # define AUX778076_FOLD_IMPL_NAME_PREFIX fold # include #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/fold_impl_body.hpp ================================================ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION #if !defined(BOOST_PP_IS_ITERATING) // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ # include # include # include # include # include # include # include # include # include // local macros, #undef-ined at the end of the header # define AUX778076_ITER_FOLD_STEP(unused, i, unused2) \ typedef typename apply2< \ ForwardOp \ , BOOST_PP_CAT(state,i) \ , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,i)) \ >::type BOOST_PP_CAT(state,BOOST_PP_INC(i)); \ typedef typename mpl::next::type \ BOOST_PP_CAT(iter,BOOST_PP_INC(i)); \ /**/ # define AUX778076_FOLD_IMPL_NAME \ BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_impl) \ /**/ # define AUX778076_FOLD_CHUNK_NAME \ BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_chunk) \ /**/ namespace boost { namespace mpl { namespace aux { /// forward declaration template< BOOST_MPL_AUX_NTTP_DECL(int, N) , typename First , typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) # if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) # include BOOST_PP_ITERATE() // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING template< BOOST_MPL_AUX_NTTP_DECL(int, N) , typename First , typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME { typedef AUX778076_FOLD_IMPL_NAME< BOOST_MPL_LIMIT_UNROLLING , First , Last , State , ForwardOp > chunk_; typedef AUX778076_FOLD_IMPL_NAME< ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; // fallback implementation for sequences of unknown size template< typename First , typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME<-1,First,Last,State,ForwardOp> : AUX778076_FOLD_IMPL_NAME< -1 , typename mpl::next::type , Last , typename apply2::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME<-1,Last,Last,State,ForwardOp> { typedef State state; typedef Last iterator; }; # else // BOOST_WORKAROUND(__BORLANDC__, < 0x600) // Borland have some serious problems with the unrolled version, so // we always use a basic implementation template< BOOST_MPL_AUX_NTTP_DECL(int, N) , typename First , typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME { typedef AUX778076_FOLD_IMPL_NAME< -1 , typename mpl::next::type , Last , typename apply2::type , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; typedef state type; }; template< BOOST_MPL_AUX_NTTP_DECL(int, N) , typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME { typedef State state; typedef Last iterator; typedef state type; }; # endif // BOOST_WORKAROUND(__BORLANDC__, < 0x600) #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct AUX778076_FOLD_CHUNK_NAME; # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) # include BOOST_PP_ITERATE() // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct AUX778076_FOLD_CHUNK_NAME { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef AUX778076_FOLD_IMPL_NAME< BOOST_MPL_LIMIT_UNROLLING , First , Last , State , ForwardOp > chunk_; typedef AUX778076_FOLD_IMPL_NAME< ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; // fallback implementation for sequences of unknown size template< typename First , typename Last , typename State , typename ForwardOp > struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step); template< typename Last , typename State > struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) { typedef Last iterator; typedef State state; }; template<> struct AUX778076_FOLD_CHUNK_NAME<-1> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef typename if_< typename is_same::type , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) /// ETI workaround template<> struct result_ { typedef int state; typedef int iterator; }; #endif }; template< typename First , typename Last , typename State , typename ForwardOp > struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) { // can't inherit here - it breaks MSVC 7.0 typedef AUX778076_FOLD_CHUNK_NAME<-1>::template result_< typename mpl::next::type , Last , typename apply2::type , ForwardOp > chunk_; typedef typename chunk_::state state; typedef typename chunk_::iterator iterator; }; template< BOOST_MPL_AUX_NTTP_DECL(int, N) , typename First , typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME : AUX778076_FOLD_CHUNK_NAME ::template result_ { }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION }}} # undef AUX778076_FOLD_IMPL_NAME # undef AUX778076_FOLD_CHUNK_NAME # undef AUX778076_ITER_FOLD_STEP #undef AUX778076_FOLD_IMPL_OP #undef AUX778076_FOLD_IMPL_NAME_PREFIX ///// iteration #else # define n_ BOOST_PP_FRAME_ITERATION(1) #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename First , typename Last , typename State , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME { typedef First iter0; typedef State state0; BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused) typedef BOOST_PP_CAT(state,n_) state; typedef BOOST_PP_CAT(iter,n_) iterator; }; #else template<> struct AUX778076_FOLD_CHUNK_NAME { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused) typedef BOOST_PP_CAT(state,n_) state; typedef BOOST_PP_CAT(iter,n_) iterator; }; #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) /// ETI workaround template<> struct result_ { typedef int state; typedef int iterator; }; #endif }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # undef n_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/full_lambda.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED #define BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include # include # include # include # include # include # if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) # include # endif #endif #include #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER full_lambda.hpp # include #else # include # include # include # include # include # include # include # include # include # include namespace boost { namespace mpl { // local macros, #undef-ined at the end of the header # define AUX778076_LAMBDA_PARAMS(i_, param) \ BOOST_MPL_PP_PARAMS(i_, param) \ /**/ # define AUX778076_BIND_PARAMS(param) \ BOOST_MPL_PP_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ ) \ /**/ # define AUX778076_BIND_N_PARAMS(i_, param) \ BOOST_PP_COMMA_IF(i_) \ BOOST_MPL_PP_PARAMS(i_, param) \ /**/ # define AUX778076_ARITY_PARAM(param) \ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param) \ /**/ #define n_ BOOST_MPL_LIMIT_METAFUNCTION_ARITY namespace aux { template< BOOST_MPL_PP_DEFAULT_PARAMS(n_,bool C,false) > struct lambda_or : true_ { }; template<> struct lambda_or< BOOST_MPL_PP_ENUM(n_,false) > : false_ { }; } // namespace aux #undef n_ template< typename T , typename Tag AUX778076_ARITY_PARAM(typename Arity) > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg,Tag AUX778076_ARITY_PARAM(int_<-1>) > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect,Tag AUX778076_ARITY_PARAM(int_<1>) > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, AUX778076_BIND_PARAMS(typename T) , typename Tag > struct lambda< bind , Tag AUX778076_ARITY_PARAM(int_) > { typedef false_ is_le; typedef bind result_; typedef result_ type; }; #if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) template< typename F , typename Tag1 , typename Tag2 , typename Arity > struct lambda< lambda , Tag2 , int_<3> > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef bind1< quote1, typename l1::result_ > arity_; typedef lambda< typename if_::type,Tag2 > l3; typedef aux::le_result3 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; #elif !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS) /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars template< typename F, typename Tag1, typename Tag2 > struct lambda< lambda< F,Tag1 > , Tag2 > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef aux::le_result2 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; #endif # undef AUX778076_ARITY_PARAM # undef AUX778076_BIND_N_PARAMS # undef AUX778076_BIND_PARAMS # undef AUX778076_LAMBDA_PARAMS #if !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) BOOST_MPL_AUX_NA_SPEC(2, lambda) #else BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda) #endif }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED ///// iteration, depth == 1 // For gcc 4.4 compatability, we must include the // BOOST_PP_ITERATION_DEPTH test inside an #else clause. #else // BOOST_PP_IS_ITERATING #if BOOST_PP_ITERATION_DEPTH() == 1 #define i_ BOOST_PP_FRAME_ITERATION(1) #if i_ > 0 namespace aux { # define AUX778076_RESULT(unused, i_, T) \ BOOST_PP_COMMA_IF(i_) \ typename BOOST_PP_CAT(T, BOOST_PP_INC(i_))::result_ \ /**/ # define AUX778076_TYPE(unused, i_, T) \ BOOST_PP_COMMA_IF(i_) \ typename BOOST_PP_CAT(T, BOOST_PP_INC(i_))::type \ /**/ template< typename IsLE, typename Tag , template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F , AUX778076_LAMBDA_PARAMS(i_, typename L) > struct BOOST_PP_CAT(le_result,i_) { typedef F< BOOST_MPL_PP_REPEAT(i_, AUX778076_TYPE, L) > result_; typedef result_ type; }; template< typename Tag , template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F , AUX778076_LAMBDA_PARAMS(i_, typename L) > struct BOOST_PP_CAT(le_result,i_)< true_,Tag,F,AUX778076_LAMBDA_PARAMS(i_, L) > { typedef BOOST_PP_CAT(bind,i_)< BOOST_PP_CAT(quote,i_) , BOOST_MPL_PP_REPEAT(i_, AUX778076_RESULT, L) > result_; typedef mpl::protect type; }; # undef AUX778076_TYPE # undef AUX778076_RESULT } // namespace aux # define AUX778076_LAMBDA_TYPEDEF(unused, i_, T) \ typedef lambda< BOOST_PP_CAT(T, BOOST_PP_INC(i_)), Tag > \ BOOST_PP_CAT(l,BOOST_PP_INC(i_)); \ /**/ # define AUX778076_IS_LE_TYPEDEF(unused, i_, unused2) \ typedef typename BOOST_PP_CAT(l,BOOST_PP_INC(i_))::is_le \ BOOST_PP_CAT(is_le,BOOST_PP_INC(i_)); \ /**/ # define AUX778076_IS_LAMBDA_EXPR(unused, i_, unused2) \ BOOST_PP_COMMA_IF(i_) \ BOOST_PP_CAT(is_le,BOOST_PP_INC(i_))::value \ /**/ template< template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F , AUX778076_LAMBDA_PARAMS(i_, typename T) , typename Tag > struct lambda< F , Tag AUX778076_ARITY_PARAM(int_) > { BOOST_MPL_PP_REPEAT(i_, AUX778076_LAMBDA_TYPEDEF, T) BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LE_TYPEDEF, unused) typedef typename aux::lambda_or< BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LAMBDA_EXPR, unused) >::type is_le; typedef aux::BOOST_PP_CAT(le_result,i_)< is_le, Tag, F, AUX778076_LAMBDA_PARAMS(i_, l) > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; # undef AUX778076_IS_LAMBDA_EXPR # undef AUX778076_IS_LE_TYPEDEF # undef AUX778076_LAMBDA_TYPEDEF #endif // i_ > 0 template< typename F AUX778076_BIND_N_PARAMS(i_, typename T) , typename Tag > struct lambda< BOOST_PP_CAT(bind,i_) , Tag AUX778076_ARITY_PARAM(int_) > { typedef false_ is_le; typedef BOOST_PP_CAT(bind,i_)< F AUX778076_BIND_N_PARAMS(i_, T) > result_; typedef result_ type; }; #undef i_ #endif // BOOST_PP_ITERATION_DEPTH() #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/has_apply.hpp ================================================ #ifndef BOOST_MPL_AUX_HAS_APPLY_HPP_INCLUDED #define BOOST_MPL_AUX_HAS_APPLY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { namespace aux { #if !defined(BOOST_MPL_CFG_NO_HAS_APPLY) BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_apply, apply, false) #else template< typename T, typename fallback_ = false_ > struct has_apply : fallback_ { }; #endif }}} #endif // BOOST_MPL_AUX_HAS_APPLY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/has_begin.hpp ================================================ #ifndef BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED #define BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include namespace boost { namespace mpl { namespace aux { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_begin, begin, true) }}} #endif // BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/has_key_impl.hpp ================================================ #ifndef BOOST_MPL_AUX_HAS_KEY_IMPL_HPP_INCLUDED #define BOOST_MPL_AUX_HAS_KEY_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // Copyright David Abrahams 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { // no default implementation; the definition is needed to make MSVC happy template< typename Tag > struct has_key_impl { template< typename AssociativeSequence, typename Key > struct apply; }; BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2,has_key_impl) }} #endif // BOOST_MPL_AUX_HAS_KEY_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/has_rebind.hpp ================================================ #ifndef BOOST_MPL_AUX_HAS_REBIND_HPP_INCLUDED #define BOOST_MPL_AUX_HAS_REBIND_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if BOOST_WORKAROUND(__EDG_VERSION__, <= 244) && !defined(BOOST_INTEL_CXX_VERSION) # include #elif BOOST_WORKAROUND(BOOST_MSVC, < 1300) # include # include # include # include #elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) # include # include # include # include # include #else # include # include # include #endif namespace boost { namespace mpl { namespace aux { #if BOOST_WORKAROUND(__EDG_VERSION__, <= 244) && !defined(BOOST_INTEL_CXX_VERSION) BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_rebind, rebind, false) #elif BOOST_WORKAROUND(BOOST_MSVC, < 1300) BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_rebind_impl, rebind, false) template< typename T > struct has_rebind : if_< msvc_is_class , has_rebind_impl , bool_ >::type { }; #else // the rest template< typename T > struct has_rebind_tag {}; no_tag operator|(has_rebind_tag, void const volatile*); # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) template< typename T > struct has_rebind { static has_rebind_tag* get(); BOOST_STATIC_CONSTANT(bool, value = sizeof(has_rebind_tag() | get()) == sizeof(yes_tag) ); }; # else // __BORLANDC__ template< typename T > struct has_rebind_impl { static T* get(); BOOST_STATIC_CONSTANT(bool, value = sizeof(has_rebind_tag() | get()) == sizeof(yes_tag) ); }; template< typename T > struct has_rebind : if_< is_class , has_rebind_impl , bool_ >::type { }; # endif // __BORLANDC__ #endif }}} #endif // BOOST_MPL_AUX_HAS_REBIND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/has_size.hpp ================================================ #ifndef BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED #define BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include namespace boost { namespace mpl { namespace aux { BOOST_MPL_HAS_XXX_TRAIT_DEF(size) }}} #endif // BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/has_tag.hpp ================================================ #ifndef BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED #define BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include namespace boost { namespace mpl { namespace aux { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_tag, tag, false) }}} #endif // BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/has_type.hpp ================================================ #ifndef BOOST_MPL_AUX_HAS_TYPE_HPP_INCLUDED #define BOOST_MPL_AUX_HAS_TYPE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include namespace boost { namespace mpl { namespace aux { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_type, type, true) }}} #endif // BOOST_MPL_AUX_HAS_TYPE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/include_preprocessed.hpp ================================================ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING) # define AUX778076_PREPROCESSED_HEADER \ BOOST_MPL_CFG_COMPILER_DIR/BOOST_MPL_PREPROCESSED_HEADER \ /**/ #else # define AUX778076_PREPROCESSED_HEADER \ BOOST_PP_CAT(BOOST_MPL_CFG_COMPILER_DIR,/)##BOOST_MPL_PREPROCESSED_HEADER \ /**/ #endif #if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(700)) # define AUX778076_INCLUDE_STRING BOOST_PP_STRINGIZE(boost/mpl/aux_/preprocessed/AUX778076_PREPROCESSED_HEADER) # include AUX778076_INCLUDE_STRING # undef AUX778076_INCLUDE_STRING #else # include BOOST_PP_STRINGIZE(boost/mpl/aux_/preprocessed/AUX778076_PREPROCESSED_HEADER) #endif # undef AUX778076_PREPROCESSED_HEADER #undef BOOST_MPL_PREPROCESSED_HEADER ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/insert_impl.hpp ================================================ #ifndef BOOST_MPL_INSERT_IMPL_HPP_INCLUDED #define BOOST_MPL_INSERT_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include namespace boost { namespace mpl { // default implementation; conrete sequences might override it by // specializing either the 'insert_impl' or the primary 'insert' template template< typename Tag > struct insert_impl { template< typename Sequence , typename Pos , typename T > struct apply { typedef iterator_range< typename begin::type , Pos > first_half_; typedef iterator_range< Pos , typename end::type > second_half_; typedef typename reverse_fold< second_half_ , typename clear::type , push_front<_,_> >::type half_sequence_; typedef typename reverse_fold< first_half_ , typename push_front::type , push_front<_,_> >::type type; }; }; BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(3,insert_impl) }} #endif // BOOST_MPL_INSERT_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/integral_wrapper.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! #include #include #include #include #include #include #if !defined(AUX_WRAPPER_NAME) # define AUX_WRAPPER_NAME BOOST_PP_CAT(AUX_WRAPPER_VALUE_TYPE,_) #endif #if !defined(AUX_WRAPPER_PARAMS) # define AUX_WRAPPER_PARAMS(N) BOOST_MPL_AUX_NTTP_DECL(AUX_WRAPPER_VALUE_TYPE, N) #endif #if !defined(AUX_WRAPPER_INST) # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) # define AUX_WRAPPER_INST(value) AUX_WRAPPER_NAME< value > # else # define AUX_WRAPPER_INST(value) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::AUX_WRAPPER_NAME< value > # endif #endif BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template< AUX_WRAPPER_PARAMS(N) > struct AUX_WRAPPER_NAME { BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, value = N); // agurt, 08/mar/03: SGI MIPSpro C++ workaround, have to #ifdef because some // other compilers (e.g. MSVC) are not particulary happy about it #if BOOST_WORKAROUND(__EDG_VERSION__, <= 238) typedef struct AUX_WRAPPER_NAME type; #else typedef AUX_WRAPPER_NAME type; #endif typedef AUX_WRAPPER_VALUE_TYPE value_type; typedef integral_c_tag tag; // have to #ifdef here: some compilers don't like the 'N + 1' form (MSVC), // while some other don't like 'value + 1' (Borland), and some don't like // either #if BOOST_WORKAROUND(__EDG_VERSION__, <= 243) private: BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, next_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1))); BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, prior_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1))); public: typedef AUX_WRAPPER_INST(next_value) next; typedef AUX_WRAPPER_INST(prior_value) prior; #elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \ || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(502)) \ || (BOOST_WORKAROUND(__HP_aCC, <= 53800) && (BOOST_WORKAROUND(__hpxstd98, != 1))) typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)) ) next; typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)) ) prior; #else typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value + 1)) ) next; typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior; #endif // enables uniform function call syntax for families of overloaded // functions that return objects of both arithmetic ('int', 'long', // 'double', etc.) and wrapped integral types (for an example, see // "mpl/example/power.cpp") BOOST_CONSTEXPR operator AUX_WRAPPER_VALUE_TYPE() const { return static_cast(this->value); } }; #if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) template< AUX_WRAPPER_PARAMS(N) > AUX_WRAPPER_VALUE_TYPE const AUX_WRAPPER_INST(N)::value; #endif BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE #undef AUX_WRAPPER_NAME #undef AUX_WRAPPER_PARAMS #undef AUX_WRAPPER_INST #undef AUX_WRAPPER_VALUE_TYPE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/is_msvc_eti_arg.hpp ================================================ #ifndef BOOST_MPL_AUX_IS_MSVC_ETI_ARG_HPP_INCLUDED #define BOOST_MPL_AUX_IS_MSVC_ETI_ARG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { namespace aux { #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) template< typename T > struct is_msvc_eti_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; #else // BOOST_MPL_CFG_MSVC_60_ETI_BUG struct eti_int_convertible { eti_int_convertible(int); }; template< typename T > struct is_msvc_eti_arg { static no_tag test(...); static yes_tag test(eti_int_convertible); static T& get(); BOOST_STATIC_CONSTANT(bool, value = sizeof(test(get())) == sizeof(yes_tag) ); }; #endif template<> struct is_msvc_eti_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif // BOOST_MPL_CFG_MSVC_ETI_BUG }}} #endif // BOOST_MPL_AUX_IS_MSVC_ETI_ARG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/iter_apply.hpp ================================================ #ifndef BOOST_MPL_ITER_APPLY_HPP_INCLUDED #define BOOST_MPL_ITER_APPLY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { namespace aux { template< typename F , typename Iterator > struct iter_apply1 : apply1< F,typename deref::type > { }; template< typename F , typename Iterator1 , typename Iterator2 > struct iter_apply2 : apply2< F , typename deref::type , typename deref::type > { }; }}} #endif // BOOST_MPL_ITER_APPLY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/iter_fold_if_impl.hpp ================================================ #ifndef BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED #define BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER iter_fold_if_impl.hpp # include #else # include # include # include # include # include # include namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; // agurt, 25/jun/02: MSVC 6.5 workaround, had to get rid of inheritance // here and in 'iter_fold_if_backward_step', because sometimes it interfered // with the "early template instantiation bug" in _really_ ugly ways template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp,mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp,identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; // local macros, #undef-ined at the end of the header # define AUX_ITER_FOLD_FORWARD_STEP(unused, i, unused2) \ typedef iter_fold_if_forward_step< \ typename BOOST_PP_CAT(forward_step,i)::iterator \ , typename BOOST_PP_CAT(forward_step,i)::state \ , ForwardOp \ , ForwardPredicate \ > BOOST_PP_CAT(forward_step, BOOST_PP_INC(i)); \ /**/ # define AUX_ITER_FOLD_BACKWARD_STEP_FUNC(i) \ typedef iter_fold_if_backward_step< \ typename BOOST_PP_CAT(forward_step,BOOST_PP_DEC(i))::iterator \ , typename BOOST_PP_CAT(backward_step,i)::state \ , BackwardOp \ , BackwardPredicate \ > BOOST_PP_CAT(backward_step,BOOST_PP_DEC(i)); \ /**/ # define AUX_ITER_FOLD_BACKWARD_STEP(unused, i, unused2) \ AUX_ITER_FOLD_BACKWARD_STEP_FUNC( \ BOOST_PP_SUB_D(1,BOOST_MPL_LIMIT_UNROLLING,i) \ ) \ /**/ # define AUX_LAST_FORWARD_STEP \ BOOST_PP_CAT(forward_step, BOOST_MPL_LIMIT_UNROLLING) \ /**/ # define AUX_LAST_BACKWARD_STEP \ BOOST_PP_CAT(backward_step, BOOST_MPL_LIMIT_UNROLLING) \ /**/ template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step forward_step0; BOOST_PP_REPEAT( BOOST_MPL_LIMIT_UNROLLING , AUX_ITER_FOLD_FORWARD_STEP , unused ) typedef typename if_< typename AUX_LAST_FORWARD_STEP::not_last , iter_fold_if_impl< typename AUX_LAST_FORWARD_STEP::iterator , typename AUX_LAST_FORWARD_STEP::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename AUX_LAST_FORWARD_STEP::iterator , typename AUX_LAST_FORWARD_STEP::state > >::type AUX_LAST_BACKWARD_STEP; BOOST_PP_REPEAT( BOOST_MPL_LIMIT_UNROLLING , AUX_ITER_FOLD_BACKWARD_STEP , unused ) public: typedef typename backward_step0::state state; typedef typename AUX_LAST_BACKWARD_STEP::iterator iterator; }; # undef AUX_LAST_BACKWARD_STEP # undef AUX_LAST_FORWARD_STEP # undef AUX_ITER_FOLD_BACKWARD_STEP # undef AUX_ITER_FOLD_BACKWARD_STEP_FUNC # undef AUX_ITER_FOLD_FORWARD_STEP }}} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/lambda_arity_param.hpp ================================================ #ifndef BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED #define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) # define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param) #else # define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param) , param #endif #endif // BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/lambda_no_ctps.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_AUX_LAMBDA_NO_CTPS_HPP_INCLUDED #define BOOST_MPL_AUX_LAMBDA_NO_CTPS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include # include # include # include # include # include # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER lambda_no_ctps.hpp # include #else # include # include # include # include # include # include # include # include # include # include # include namespace boost { namespace mpl { # define AUX778076_LAMBDA_PARAMS(i_, param) \ BOOST_MPL_PP_PARAMS(i_, param) \ /**/ namespace aux { #define n_ BOOST_MPL_LIMIT_METAFUNCTION_ARITY template< BOOST_MPL_PP_DEFAULT_PARAMS(n_,bool C,false) > struct lambda_or : true_ { }; template<> struct lambda_or< BOOST_MPL_PP_ENUM(n_,false) > : false_ { }; #undef n_ template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; # undef AUX778076_LAMBDA_PARAMS }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AUX_LAMBDA_NO_CTPS_HPP_INCLUDED ///// iteration, depth == 1 #else #define i_ BOOST_PP_FRAME_ITERATION(1) # define AUX778076_LAMBDA_TYPEDEF(unused, i_, F) \ typedef lambda< \ typename F::BOOST_PP_CAT(arg,BOOST_PP_INC(i_)) \ , Tag \ , false_ \ > BOOST_PP_CAT(l,BOOST_PP_INC(i_)); \ /**/ # define AUX778076_IS_LE_TYPEDEF(unused, i_, unused2) \ typedef typename BOOST_PP_CAT(l,BOOST_PP_INC(i_))::is_le \ BOOST_PP_CAT(is_le,BOOST_PP_INC(i_)); \ /**/ # define AUX778076_IS_LAMBDA_EXPR(unused, i_, unused2) \ BOOST_PP_COMMA_IF(i_) \ BOOST_MPL_AUX_MSVC_VALUE_WKND(BOOST_PP_CAT(is_le,BOOST_PP_INC(i_)))::value \ /**/ # define AUX778076_LAMBDA_RESULT(unused, i_, unused2) \ , typename BOOST_PP_CAT(l,BOOST_PP_INC(i_))::type \ /**/ template<> struct lambda_impl< int_ > { template< typename F, typename Tag, typename Protect > struct result_ { BOOST_MPL_PP_REPEAT(i_, AUX778076_LAMBDA_TYPEDEF, F) BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LE_TYPEDEF, unused) typedef aux::lambda_or< BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LAMBDA_EXPR, unused) > is_le; typedef BOOST_PP_CAT(bind,i_)< typename F::rebind BOOST_MPL_PP_REPEAT(i_, AUX778076_LAMBDA_RESULT, unused) > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; # undef AUX778076_LAMBDA_RESULT # undef AUX778076_IS_LAMBDA_EXPR # undef AUX778076_IS_LE_TYPEDEF # undef AUX778076_LAMBDA_TYPEDEF #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/lambda_spec.hpp ================================================ #ifndef BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED #define BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2007 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) \ template< \ BOOST_MPL_PP_PARAMS(i, typename T) \ , typename Tag \ > \ struct lambda< \ name< BOOST_MPL_PP_PARAMS(i, T) > \ , Tag \ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(int_) \ > \ { \ typedef false_ is_le; \ typedef name< BOOST_MPL_PP_PARAMS(i, T) > result_; \ typedef result_ type; \ }; \ /**/ #else # define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) /**/ #endif #endif // BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/lambda_support.hpp ================================================ #ifndef BOOST_MPL_AUX_LAMBDA_SUPPORT_HPP_INCLUDED #define BOOST_MPL_AUX_LAMBDA_SUPPORT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) /**/ # define BOOST_MPL_AUX_LAMBDA_SUPPORT(i,name,params) /**/ #else # include # include # include # include # include # include # include # include # include # include # include # define BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC(R,typedef_,i,param) \ typedef_ param BOOST_PP_CAT(arg,BOOST_PP_INC(i)); \ /**/ // agurt, 07/mar/03: restore an old revision for the sake of SGI MIPSpro C++ #if BOOST_WORKAROUND(__EDG_VERSION__, <= 238) # define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \ typedef BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::int_ arity; \ BOOST_PP_LIST_FOR_EACH_I_R( \ 1 \ , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC \ , typedef \ , BOOST_PP_TUPLE_TO_LIST(i,params) \ ) \ struct rebind \ { \ template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \ : name< BOOST_MPL_PP_PARAMS(i,U) > \ { \ }; \ }; \ /**/ # define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \ BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \ /**/ #elif BOOST_WORKAROUND(__EDG_VERSION__, <= 244) && !defined(BOOST_INTEL_CXX_VERSION) // agurt, 18/jan/03: old EDG-based compilers actually enforce 11.4 para 9 // (in strict mode), so we have to provide an alternative to the // MSVC-optimized implementation # define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \ typedef BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::int_ arity; \ BOOST_PP_LIST_FOR_EACH_I_R( \ 1 \ , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC \ , typedef \ , BOOST_PP_TUPLE_TO_LIST(i,params) \ ) \ struct rebind; \ /**/ # define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \ BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \ }; \ template< BOOST_MPL_PP_PARAMS(i,typename T) > \ struct name::rebind \ { \ template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \ : name< BOOST_MPL_PP_PARAMS(i,U) > \ { \ }; \ /**/ #else // __EDG_VERSION__ namespace boost { namespace mpl { namespace aux { template< typename T > struct has_rebind_tag; }}} # define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \ typedef BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::int_ arity; \ BOOST_PP_LIST_FOR_EACH_I_R( \ 1 \ , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC \ , typedef \ , BOOST_PP_TUPLE_TO_LIST(i,params) \ ) \ friend class BOOST_PP_CAT(name,_rebind); \ typedef BOOST_PP_CAT(name,_rebind) rebind; \ /**/ #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) # define BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \ template< BOOST_MPL_PP_PARAMS(i,typename T) > \ ::boost::mpl::aux::yes_tag operator|( \ ::boost::mpl::aux::has_rebind_tag \ , name* \ ); \ ::boost::mpl::aux::no_tag operator|( \ ::boost::mpl::aux::has_rebind_tag \ , name< BOOST_MPL_PP_ENUM(i,::boost::mpl::na) >* \ ); \ /**/ #elif !BOOST_WORKAROUND(BOOST_MSVC, < 1300) # define BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \ template< BOOST_MPL_PP_PARAMS(i,typename T) > \ ::boost::mpl::aux::yes_tag operator|( \ ::boost::mpl::aux::has_rebind_tag \ , ::boost::mpl::aux::has_rebind_tag< name >* \ ); \ /**/ #else # define BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) /**/ #endif # if !defined(__BORLANDC__) # define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \ BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \ }; \ BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \ class BOOST_PP_CAT(name,_rebind) \ { \ public: \ template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \ : name< BOOST_MPL_PP_PARAMS(i,U) > \ { \ }; \ /**/ # else # define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \ BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \ }; \ BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \ class BOOST_PP_CAT(name,_rebind) \ { \ public: \ template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \ { \ typedef typename name< BOOST_MPL_PP_PARAMS(i,U) >::type type; \ }; \ /**/ # endif // __BORLANDC__ #endif // __EDG_VERSION__ #endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT #endif // BOOST_MPL_AUX_LAMBDA_SUPPORT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/logical_op.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include #endif #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace mpl { # define AUX778076_PARAMS(param, sub) \ BOOST_MPL_PP_PARAMS( \ BOOST_MPL_PP_SUB(BOOST_MPL_LIMIT_METAFUNCTION_ARITY, sub) \ , param \ ) \ /**/ # define AUX778076_SHIFTED_PARAMS(param, sub) \ BOOST_MPL_PP_EXT_PARAMS( \ 2, BOOST_MPL_PP_SUB(BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY), sub) \ , param \ ) \ /**/ # define AUX778076_SPEC_PARAMS(param) \ BOOST_MPL_PP_ENUM( \ BOOST_PP_DEC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY) \ , param \ ) \ /**/ namespace aux { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< bool C_, AUX778076_PARAMS(typename T, 1) > struct BOOST_PP_CAT(AUX778076_OP_NAME,impl) : BOOST_PP_CAT(AUX778076_OP_VALUE1,_) { }; template< AUX778076_PARAMS(typename T, 1) > struct BOOST_PP_CAT(AUX778076_OP_NAME,impl)< AUX778076_OP_VALUE2,AUX778076_PARAMS(T, 1) > : BOOST_PP_CAT(AUX778076_OP_NAME,impl)< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , AUX778076_SHIFTED_PARAMS(T, 1) , BOOST_PP_CAT(AUX778076_OP_VALUE2,_) > { }; template<> struct BOOST_PP_CAT(AUX778076_OP_NAME,impl)< AUX778076_OP_VALUE2 , AUX778076_SPEC_PARAMS(BOOST_PP_CAT(AUX778076_OP_VALUE2,_)) > : BOOST_PP_CAT(AUX778076_OP_VALUE2,_) { }; #else template< bool C_ > struct BOOST_PP_CAT(AUX778076_OP_NAME,impl) { template< AUX778076_PARAMS(typename T, 1) > struct result_ : BOOST_PP_CAT(AUX778076_OP_VALUE1,_) { }; }; template<> struct BOOST_PP_CAT(AUX778076_OP_NAME,impl) { template< AUX778076_PARAMS(typename T, 1) > struct result_ : BOOST_PP_CAT(AUX778076_OP_NAME,impl)< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< AUX778076_SHIFTED_PARAMS(T,1),BOOST_PP_CAT(AUX778076_OP_VALUE2,_) > { }; #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) template<> struct result_ : BOOST_PP_CAT(AUX778076_OP_VALUE2,_) { }; }; #else }; template<> struct BOOST_PP_CAT(AUX778076_OP_NAME,impl) ::result_< AUX778076_SPEC_PARAMS(BOOST_PP_CAT(AUX778076_OP_VALUE2,_)) > : BOOST_PP_CAT(AUX778076_OP_VALUE2,_) { }; #endif // BOOST_MSVC == 1300 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) BOOST_MPL_PP_DEF_PARAMS_TAIL(2, typename T, BOOST_PP_CAT(AUX778076_OP_VALUE2,_)) > struct AUX778076_OP_NAME #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) : aux::BOOST_PP_CAT(AUX778076_OP_NAME,impl)< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , AUX778076_SHIFTED_PARAMS(T,0) > #else : aux::BOOST_PP_CAT(AUX778076_OP_NAME,impl)< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< AUX778076_SHIFTED_PARAMS(T,0) > #endif { BOOST_MPL_AUX_LAMBDA_SUPPORT( BOOST_MPL_LIMIT_METAFUNCTION_ARITY , AUX778076_OP_NAME , (AUX778076_PARAMS(T, 0)) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , BOOST_MPL_LIMIT_METAFUNCTION_ARITY , AUX778076_OP_NAME ) }} #undef AUX778076_SPEC_PARAMS #undef AUX778076_SHIFTED_PARAMS #undef AUX778076_PARAMS #undef AUX778076_OP_NAME #undef AUX778076_OP_VALUE1 #undef AUX778076_OP_VALUE2 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/msvc_dtw.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! #include // local macros, #undef-ined at the end of the header #define AUX778076_DTW_PARAMS(param) \ BOOST_MPL_PP_PARAMS(AUX778076_MSVC_DTW_ARITY, param) \ /**/ #define AUX778076_DTW_ORIGINAL_NAME \ AUX778076_MSVC_DTW_ORIGINAL_NAME \ /**/ // warning: not a well-formed C++ // workaround for MSVC 6.5's "dependent template typedef bug" template< typename F> struct AUX778076_MSVC_DTW_NAME { template< bool > struct f_ : F {}; template<> struct f_ { #if AUX778076_MSVC_DTW_ARITY > 0 template< AUX778076_DTW_PARAMS(typename P) > struct AUX778076_DTW_ORIGINAL_NAME { typedef int type; }; }; template< AUX778076_DTW_PARAMS(typename T) > struct result_ : f_< aux::msvc_never_true::value > ::template AUX778076_DTW_ORIGINAL_NAME< AUX778076_DTW_PARAMS(T) > { }; #else template< typename P = int > struct AUX778076_DTW_ORIGINAL_NAME { typedef int type; }; }; template< typename T = int > struct result_ : f_< aux::msvc_never_true::value > ::template AUX778076_DTW_ORIGINAL_NAME<> { }; #endif }; #undef AUX778076_DTW_ORIGINAL_NAME #undef AUX778076_DTW_PARAMS #undef AUX778076_MSVC_DTW_NAME #undef AUX778076_MSVC_DTW_ORIGINAL_NAME #undef AUX778076_MSVC_DTW_ARITY ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/msvc_eti_base.hpp ================================================ #ifndef BOOST_MPL_AUX_MSVC_ETI_BASE_HPP_INCLUDED #define BOOST_MPL_AUX_MSVC_ETI_BASE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { namespace aux { #if defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) template< bool > struct msvc_eti_base_impl { template< typename T > struct result_ : T { typedef T type; }; }; template<> struct msvc_eti_base_impl { template< typename T > struct result_ { typedef result_ type; typedef result_ first; typedef result_ second; typedef result_ tag; enum { value = 0 }; }; }; template< typename T > struct msvc_eti_base : msvc_eti_base_impl< is_msvc_eti_arg::value > ::template result_ { }; #else // !BOOST_MPL_CFG_MSVC_70_ETI_BUG template< typename T > struct msvc_eti_base : T { #if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304)) msvc_eti_base(); #endif typedef T type; }; #endif template<> struct msvc_eti_base { typedef msvc_eti_base type; typedef msvc_eti_base first; typedef msvc_eti_base second; typedef msvc_eti_base tag; enum { value = 0 }; }; }}} #endif // BOOST_MPL_AUX_MSVC_ETI_BASE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/msvc_is_class.hpp ================================================ #ifndef BOOST_MPL_AUX_MSVC_IS_CLASS_HPP_INCLUDED #define BOOST_MPL_AUX_MSVC_IS_CLASS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { namespace aux { template< typename T > struct is_class_helper { typedef int (T::* type)(); }; // MSVC 6.x-specific lightweight 'is_class' implementation; // Distinguishing feature: does not instantiate the type being tested. template< typename T > struct msvc_is_class_impl { template< typename U> static yes_tag test(type_wrapper*, /*typename*/ is_class_helper::type = 0); static no_tag test(void const volatile*, ...); enum { value = sizeof(test((type_wrapper*)0)) == sizeof(yes_tag) }; typedef bool_ type; }; // agurt, 17/sep/04: have to check for 'is_reference' upfront to avoid ICEs in // complex metaprograms template< typename T > struct msvc_is_class : if_< is_reference , false_ , msvc_is_class_impl >::type { }; }}} #endif // BOOST_MPL_AUX_MSVC_IS_CLASS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/msvc_never_true.hpp ================================================ #ifndef BOOST_MPL_AUX_MSVC_NEVER_TRUE_HPP_INCLUDED #define BOOST_MPL_AUX_MSVC_NEVER_TRUE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) namespace boost { namespace mpl { namespace aux { template< typename T > struct msvc_never_true { enum { value = false }; }; }}} #endif // BOOST_MSVC #endif // BOOST_MPL_AUX_MSVC_NEVER_TRUE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/msvc_type.hpp ================================================ #ifndef BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED #define BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { namespace aux { #if defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) template< bool > struct msvc_type_impl { template< typename T > struct result_ { typedef typename T::type type; }; }; template<> struct msvc_type_impl { template< typename T > struct result_ { typedef result_ type; }; }; template< typename T > struct msvc_type : msvc_type_impl< is_msvc_eti_arg::value > ::template result_ { }; #else // BOOST_MPL_CFG_MSVC_70_ETI_BUG template< typename T > struct msvc_type { typedef typename T::type type; }; template<> struct msvc_type { typedef int type; }; #endif }}} #endif // BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/na.hpp ================================================ #ifndef BOOST_MPL_AUX_NA_HPP_INCLUDED #define BOOST_MPL_AUX_NA_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template< typename T > struct is_na : false_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using false_::value; #endif }; template<> struct is_na : true_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using true_::value; #endif }; template< typename T > struct is_not_na : true_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using true_::value; #endif }; template<> struct is_not_na : false_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using false_::value; #endif }; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename T, typename U > struct if_na { typedef T type; }; template< typename U > struct if_na { typedef U type; }; #else template< typename T > struct if_na_impl { template< typename U > struct apply { typedef T type; }; }; template<> struct if_na_impl { template< typename U > struct apply { typedef U type; }; }; template< typename T, typename U > struct if_na : if_na_impl::template apply { }; #endif }} #endif // BOOST_MPL_AUX_NA_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/na_assert.hpp ================================================ #ifndef BOOST_MPL_AUX_NA_ASSERT_HPP_INCLUDED #define BOOST_MPL_AUX_NA_ASSERT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !BOOST_WORKAROUND(_MSC_FULL_VER, <= 140050601) \ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243) # include # define BOOST_MPL_AUX_ASSERT_NOT_NA(x) \ BOOST_MPL_ASSERT_NOT((boost::mpl::is_na)) \ /**/ #else # include # define BOOST_MPL_AUX_ASSERT_NOT_NA(x) \ BOOST_STATIC_ASSERT(!boost::mpl::is_na::value) \ /**/ #endif #endif // BOOST_MPL_AUX_NA_ASSERT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/na_fwd.hpp ================================================ #ifndef BOOST_MPL_AUX_NA_FWD_HPP_INCLUDED #define BOOST_MPL_AUX_NA_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN // n.a. == not available struct na { typedef na type; enum { value = 0 }; }; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(na) #endif // BOOST_MPL_AUX_NA_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/na_spec.hpp ================================================ #ifndef BOOST_MPL_AUX_NA_SPEC_HPP_INCLUDED #define BOOST_MPL_AUX_NA_SPEC_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include # include #endif #include #include #include #include #include #include #include #include #include #include #define BOOST_MPL_AUX_NA_PARAMS(i) \ BOOST_MPL_PP_ENUM(i, na) \ /**/ #if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # define BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) \ namespace aux { \ template< BOOST_MPL_AUX_NTTP_DECL(int, N) > \ struct arity< \ name< BOOST_MPL_AUX_NA_PARAMS(i) > \ , N \ > \ : int_< BOOST_MPL_LIMIT_METAFUNCTION_ARITY > \ { \ }; \ } \ /**/ #else # define BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) /**/ #endif #define BOOST_MPL_AUX_NA_SPEC_MAIN(i, name) \ template<> \ struct name< BOOST_MPL_AUX_NA_PARAMS(i) > \ { \ template< \ BOOST_MPL_PP_PARAMS(i, typename T) \ BOOST_MPL_PP_NESTED_DEF_PARAMS_TAIL(i, typename T, na) \ > \ struct apply \ : name< BOOST_MPL_PP_PARAMS(i, T) > \ { \ }; \ }; \ /**/ #if defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # define BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \ template<> \ struct lambda< \ name< BOOST_MPL_AUX_NA_PARAMS(i) > \ , void_ \ , true_ \ > \ { \ typedef false_ is_le; \ typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > type; \ }; \ template<> \ struct lambda< \ name< BOOST_MPL_AUX_NA_PARAMS(i) > \ , void_ \ , false_ \ > \ { \ typedef false_ is_le; \ typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > type; \ }; \ /**/ #else # define BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \ template< typename Tag > \ struct lambda< \ name< BOOST_MPL_AUX_NA_PARAMS(i) > \ , Tag \ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(int_<-1>) \ > \ { \ typedef false_ is_le; \ typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > result_; \ typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > type; \ }; \ /**/ #endif #if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) \ || defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) \ && defined(BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION) # define BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, j, name) \ namespace aux { \ template< BOOST_MPL_PP_PARAMS(j, typename T) > \ struct template_arity< \ name< BOOST_MPL_PP_PARAMS(j, T) > \ > \ : int_ \ { \ }; \ \ template<> \ struct template_arity< \ name< BOOST_MPL_PP_ENUM(i, na) > \ > \ : int_<-1> \ { \ }; \ } \ /**/ #else # define BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, j, name) /**/ #endif #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) # define BOOST_MPL_AUX_NA_SPEC_ETI(i, name) \ template<> \ struct name< BOOST_MPL_PP_ENUM(i, int) > \ { \ typedef int type; \ enum { value = 0 }; \ }; \ /**/ #else # define BOOST_MPL_AUX_NA_SPEC_ETI(i, name) /**/ #endif #define BOOST_MPL_AUX_NA_PARAM(param) param = na #define BOOST_MPL_AUX_NA_SPEC_NO_ETI(i, name) \ BOOST_MPL_AUX_NA_SPEC_MAIN(i, name) \ BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \ BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) \ BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, i, name) \ /**/ #define BOOST_MPL_AUX_NA_SPEC(i, name) \ BOOST_MPL_AUX_NA_SPEC_NO_ETI(i, name) \ BOOST_MPL_AUX_NA_SPEC_ETI(i, name) \ /**/ #define BOOST_MPL_AUX_NA_SPEC2(i, j, name) \ BOOST_MPL_AUX_NA_SPEC_MAIN(i, name) \ BOOST_MPL_AUX_NA_SPEC_ETI(i, name) \ BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \ BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) \ BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, j, name) \ /**/ #endif // BOOST_MPL_AUX_NA_SPEC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/nested_type_wknd.hpp ================================================ #ifndef BOOST_MPL_AUX_NESTED_TYPE_WKND_HPP_INCLUDED #define BOOST_MPL_AUX_NESTED_TYPE_WKND_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0302)) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \ || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x530)) \ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) namespace boost { namespace mpl { namespace aux { template< typename T > struct nested_type_wknd : T::type { }; }}} #if BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) # define BOOST_MPL_AUX_NESTED_TYPE_WKND(T) \ aux::nested_type_wknd \ /**/ #else # define BOOST_MPL_AUX_NESTED_TYPE_WKND(T) \ ::boost::mpl::aux::nested_type_wknd \ /**/ #endif #else // !BOOST_MPL_CFG_GCC et al. # define BOOST_MPL_AUX_NESTED_TYPE_WKND(T) T::type #endif #endif // BOOST_MPL_AUX_NESTED_TYPE_WKND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/nttp_decl.hpp ================================================ #ifndef BOOST_MPL_AUX_NTTP_DECL_HPP_INCLUDED #define BOOST_MPL_AUX_NTTP_DECL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if defined(BOOST_MPL_CFG_NTTP_BUG) typedef bool _mpl_nttp_bool; typedef int _mpl_nttp_int; typedef unsigned _mpl_nttp_unsigned; typedef long _mpl_nttp_long; # include # define BOOST_MPL_AUX_NTTP_DECL(T, x) BOOST_PP_CAT(_mpl_nttp_,T) x /**/ #else # define BOOST_MPL_AUX_NTTP_DECL(T, x) T x /**/ #endif #endif // BOOST_MPL_AUX_NTTP_DECL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/overload_names.hpp ================================================ #ifndef BOOST_MPL_AUX_OVERLOAD_NAMES_HPP_INCLUDED #define BOOST_MPL_AUX_OVERLOAD_NAMES_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if defined(BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING) # include # define BOOST_MPL_AUX_OVERLOAD_VALUE_BY_KEY operator/ # define BOOST_MPL_AUX_OVERLOAD_ITEM_BY_ORDER operator| # define BOOST_MPL_AUX_OVERLOAD_ORDER_BY_KEY operator|| # define BOOST_MPL_AUX_OVERLOAD_IS_MASKED operator% # define BOOST_MPL_AUX_OVERLOAD_CALL_VALUE_BY_KEY(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) / x # define BOOST_MPL_AUX_OVERLOAD_CALL_ITEM_BY_ORDER(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) | x # define BOOST_MPL_AUX_OVERLOAD_CALL_ORDER_BY_KEY(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) || x # define BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) % x #else # define BOOST_MPL_AUX_OVERLOAD_VALUE_BY_KEY value_by_key_ # define BOOST_MPL_AUX_OVERLOAD_ITEM_BY_ORDER item_by_order_ # define BOOST_MPL_AUX_OVERLOAD_ORDER_BY_KEY order_by_key_ # define BOOST_MPL_AUX_OVERLOAD_IS_MASKED is_masked_ # define BOOST_MPL_AUX_OVERLOAD_CALL_VALUE_BY_KEY(T, x) T::BOOST_MPL_AUX_OVERLOAD_VALUE_BY_KEY( BOOST_MPL_AUX_PTR_TO_REF(T), x ) # define BOOST_MPL_AUX_OVERLOAD_CALL_ITEM_BY_ORDER(T, x) T::BOOST_MPL_AUX_OVERLOAD_ITEM_BY_ORDER( BOOST_MPL_AUX_PTR_TO_REF(T), x ) # define BOOST_MPL_AUX_OVERLOAD_CALL_ORDER_BY_KEY(T, x) T::BOOST_MPL_AUX_OVERLOAD_ORDER_BY_KEY( BOOST_MPL_AUX_PTR_TO_REF(T), x ) # define BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED(T, x) T::BOOST_MPL_AUX_OVERLOAD_IS_MASKED( BOOST_MPL_AUX_PTR_TO_REF(T), x ) #endif #endif // BOOST_MPL_AUX_OVERLOAD_NAMES_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< int N, typename F > struct apply_wrap_impl0; template< typename F, bool F_has_apply > struct apply_wrap_impl0_bcb { typedef typename F::template apply type; }; template< typename F > struct apply_wrap_impl0_bcb< F,true > { typedef typename F::apply type; }; template< typename F > struct apply_wrap_impl0< 0 , F > { typedef apply_wrap_impl0_bcb< F, aux::has_apply::value >::type type; }; template< typename F > struct apply_wrap_impl0< 1 , F > { typedef typename F::template apply< na > type; }; template< typename F > struct apply_wrap_impl0< 2 , F > { typedef typename F::template apply< na, na > type; }; template< typename F > struct apply_wrap_impl0< 3 , F > { typedef typename F::template apply< na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 4 , F > { typedef typename F::template apply< na, na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 5 , F > { typedef typename F::template apply< na, na, na, na, na > type; }; template< typename F > struct apply_wrap0 : apply_wrap_impl0< ::boost::mpl::aux::arity< F,0 >::value , F >::type { }; template< int N, typename F, typename T1 > struct apply_wrap_impl1; template< typename F, typename T1 > struct apply_wrap_impl1< 1 , F , T1 > { typedef typename F::template apply< T1 > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 2 , F , T1 > { typedef typename F::template apply< T1 , na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 3 , F , T1 > { typedef typename F::template apply< T1 , na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 4 , F , T1 > { typedef typename F::template apply< T1 , na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 5 , F , T1 > { typedef typename F::template apply< T1 , na, na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap1 : apply_wrap_impl1< ::boost::mpl::aux::arity< F,1 >::value , F , T1 >::type { }; template< int N, typename F, typename T1, typename T2 > struct apply_wrap_impl2; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 2 , F , T1, T2 > { typedef typename F::template apply< T1, T2 > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 3 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 4 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 5 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : apply_wrap_impl2< ::boost::mpl::aux::arity< F,2 >::value , F , T1, T2 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 3 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 4 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 5 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na, na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : apply_wrap_impl3< ::boost::mpl::aux::arity< F,3 >::value , F , T1, T2, T3 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 4 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 5 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 , na > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : apply_wrap_impl4< ::boost::mpl::aux::arity< F,4 >::value , F , T1, T2, T3, T4 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5< 5 , F , T1, T2, T3, T4, T5 > { typedef typename F::template apply< T1, T2, T3, T4, T5 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : apply_wrap_impl5< ::boost::mpl::aux::arity< F,5 >::value , F , T1, T2, T3, T4, T5 >::type { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag , typename Arity > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg,Tag, int_< -1 > > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag , int_<1> > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag , int_<1> > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag , int_<2> > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag , int_<2> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag , int_<3> > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag , int_<3> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag , int_<4> > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag , int_<4> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag , int_<5> > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag , int_<5> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect,Tag, int_<1> > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; template< typename F , typename Tag1 , typename Tag2 , typename Arity > struct lambda< lambda< F,Tag1,Arity > , Tag2 , int_<3> > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef bind1< quote1, typename l1::result_ > arity_; typedef lambda< typename if_< is_le,arity_,Arity >::type, Tag2 > l3; typedef aux::le_result3 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1, typename T2, typename T3, typename T4, typename T5 > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "quote.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, bool has_type_ > struct quote_impl { typedef typename T::type type; }; template< typename T > struct quote_impl< T,false > { typedef T type; }; template< template< typename P1 > class F , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply { typedef typename quote_impl< F , aux::has_type< F >::value >::type type; }; }; template< template< typename P1, typename P2 > class F , typename Tag = void_ > struct quote2 { template< typename U1, typename U2 > struct apply { typedef typename quote_impl< F< U1,U2 > , aux::has_type< F< U1,U2 > >::value >::type type; }; }; template< template< typename P1, typename P2, typename P3 > class F , typename Tag = void_ > struct quote3 { template< typename U1, typename U2, typename U3 > struct apply { typedef typename quote_impl< F< U1,U2,U3 > , aux::has_type< F< U1,U2,U3 > >::value >::type type; }; }; template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename Tag = void_ > struct quote4 { template< typename U1, typename U2, typename U3, typename U4 > struct apply { typedef typename quote_impl< F< U1,U2,U3,U4 > , aux::has_type< F< U1,U2,U3,U4 > >::value >::type type; }; }; template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename Tag = void_ > struct quote5 { template< typename U1, typename U2, typename U3, typename U4 , typename U5 > struct apply { typedef typename quote_impl< F< U1,U2,U3,U4,U5 > , aux::has_type< F< U1,U2,U3,U4,U5 > >::value >::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< long N > struct reverse_fold_chunk; template<> struct reverse_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step; template< typename Last , typename State > struct reverse_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_fold_null_step< Last,State > , reverse_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step { typedef reverse_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl : reverse_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< long N > struct reverse_iter_fold_chunk; template<> struct reverse_iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_iter_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step; template< typename Last , typename State > struct reverse_iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_iter_fold_null_step< Last,State > , reverse_iter_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step { typedef reverse_iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl : reverse_iter_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_< -1 > { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply { typedef typename aux::unpack_args_impl< size::value , F , Args >::type type; }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< int N, typename F > struct apply_wrap_impl0; template< typename F > struct apply_wrap_impl0< 0 , F > { typedef typename F::template apply< /// since the defaults are "lost", we have to pass *something* even for nullary /// metafunction classes na > type; }; template< typename F > struct apply_wrap_impl0< 1 , F > { typedef typename F::template apply< na > type; }; template< typename F > struct apply_wrap_impl0< 2 , F > { typedef typename F::template apply< na, na > type; }; template< typename F > struct apply_wrap_impl0< 3 , F > { typedef typename F::template apply< na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 4 , F > { typedef typename F::template apply< na, na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 5 , F > { typedef typename F::template apply< na, na, na, na, na > type; }; template< typename F > struct apply_wrap0 : apply_wrap_impl0< ::boost::mpl::aux::arity< F,0 >::value , F >::type { }; template< int N, typename F, typename T1 > struct apply_wrap_impl1; template< typename F, typename T1 > struct apply_wrap_impl1< 1 , F , T1 > { typedef typename F::template apply< T1 > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 2 , F , T1 > { typedef typename F::template apply< T1 , na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 3 , F , T1 > { typedef typename F::template apply< T1 , na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 4 , F , T1 > { typedef typename F::template apply< T1 , na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 5 , F , T1 > { typedef typename F::template apply< T1 , na, na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap1 : apply_wrap_impl1< ::boost::mpl::aux::arity< F,1 >::value , F , T1 >::type { }; template< int N, typename F, typename T1, typename T2 > struct apply_wrap_impl2; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 2 , F , T1, T2 > { typedef typename F::template apply< T1, T2 > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 3 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 4 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 5 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : apply_wrap_impl2< ::boost::mpl::aux::arity< F,2 >::value , F , T1, T2 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 3 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 4 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 5 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na, na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : apply_wrap_impl3< ::boost::mpl::aux::arity< F,3 >::value , F , T1, T2, T3 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 4 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 5 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 , na > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : apply_wrap_impl4< ::boost::mpl::aux::arity< F,4 >::value , F , T1, T2, T3, T4 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5< 5 , F , T1, T2, T3, T4, T5 > { typedef typename F::template apply< T1, T2, T3, T4, T5 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : apply_wrap_impl5< ::boost::mpl::aux::arity< F,5 >::value , F , T1, T2, T3, T4, T5 >::type { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag , typename Arity > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg,Tag, int_< -1 > > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag , int_<1> > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag , int_<1> > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag , int_<2> > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag , int_<2> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag , int_<3> > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag , int_<3> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag , int_<4> > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag , int_<4> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag , int_<5> > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag , int_<5> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect,Tag, int_<1> > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; template< typename F , typename Tag1 , typename Tag2 , typename Arity > struct lambda< lambda< F,Tag1,Arity > , Tag2 , int_<3> > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef bind1< quote1, typename l1::result_ > arity_; typedef lambda< typename if_< is_le,arity_,Arity >::type, Tag2 > l3; typedef aux::le_result3 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< long N > struct reverse_fold_chunk; template<> struct reverse_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step; template< typename Last , typename State > struct reverse_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_fold_null_step< Last,State > , reverse_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step { typedef reverse_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl : reverse_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< long N > struct reverse_iter_fold_chunk; template<> struct reverse_iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_iter_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step; template< typename Last , typename State > struct reverse_iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_iter_fold_null_step< Last,State > , reverse_iter_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step { typedef reverse_iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl : reverse_iter_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_< -1 > { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply { typedef typename aux::unpack_args_impl< size::value , F , Args >::type type; }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc551/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< int N, typename F > struct apply_wrap_impl0; template< typename F > struct apply_wrap_impl0< 0 , F > { typedef typename F::template apply< /// since the defaults are "lost", we have to pass *something* even for nullary /// metafunction classes na > type; }; template< typename F > struct apply_wrap_impl0< 1 , F > { typedef typename F::template apply< na > type; }; template< typename F > struct apply_wrap_impl0< 2 , F > { typedef typename F::template apply< na, na > type; }; template< typename F > struct apply_wrap_impl0< 3 , F > { typedef typename F::template apply< na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 4 , F > { typedef typename F::template apply< na, na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 5 , F > { typedef typename F::template apply< na, na, na, na, na > type; }; template< typename F > struct apply_wrap0 : apply_wrap_impl0< ::boost::mpl::aux::arity< F,0 >::value , F >::type { }; template< int N, typename F, typename T1 > struct apply_wrap_impl1; template< typename F, typename T1 > struct apply_wrap_impl1< 1 , F , T1 > { typedef typename F::template apply< T1 > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 2 , F , T1 > { typedef typename F::template apply< T1 , na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 3 , F , T1 > { typedef typename F::template apply< T1 , na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 4 , F , T1 > { typedef typename F::template apply< T1 , na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 5 , F , T1 > { typedef typename F::template apply< T1 , na, na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap1 : apply_wrap_impl1< ::boost::mpl::aux::arity< F,1 >::value , F , T1 >::type { }; template< int N, typename F, typename T1, typename T2 > struct apply_wrap_impl2; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 2 , F , T1, T2 > { typedef typename F::template apply< T1, T2 > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 3 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 4 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 5 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : apply_wrap_impl2< ::boost::mpl::aux::arity< F,2 >::value , F , T1, T2 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 3 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 4 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 5 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na, na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : apply_wrap_impl3< ::boost::mpl::aux::arity< F,3 >::value , F , T1, T2, T3 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 4 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 5 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 , na > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : apply_wrap_impl4< ::boost::mpl::aux::arity< F,4 >::value , F , T1, T2, T3, T4 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5< 5 , F , T1, T2, T3, T4, T5 > { typedef typename F::template apply< T1, T2, T3, T4, T5 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : apply_wrap_impl5< ::boost::mpl::aux::arity< F,5 >::value , F , T1, T2, T3, T4, T5 >::type { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1, typename U2, typename U3, typename U4, typename U5 > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag , typename Arity > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg,Tag, int_< -1 > > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag , int_<1> > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag , int_<1> > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag , int_<2> > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag , int_<2> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag , int_<3> > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag , int_<3> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag , int_<4> > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag , int_<4> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag , int_<5> > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag , int_<5> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect,Tag, int_<1> > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; template< typename F , typename Tag1 , typename Tag2 , typename Arity > struct lambda< lambda< F,Tag1,Arity > , Tag2 , int_<3> > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef bind1< quote1, typename l1::result_ > arity_; typedef lambda< typename if_< is_le,arity_,Arity >::type, Tag2 > l3; typedef aux::le_result3 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1, typename T2, typename T3, typename T4, typename T5 > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "quote.hpp" header // -- DO NOT modify by hand! ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< long N > struct reverse_fold_chunk; template<> struct reverse_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step; template< typename Last , typename State > struct reverse_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_fold_null_step< Last,State > , reverse_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step { typedef reverse_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl : reverse_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< long N > struct reverse_iter_fold_chunk; template<> struct reverse_iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_iter_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step; template< typename Last , typename State > struct reverse_iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_iter_fold_null_step< Last,State > , reverse_iter_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step { typedef reverse_iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl : reverse_iter_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_< -1 > { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply { typedef typename aux::unpack_args_impl< size::value , F , Args >::type type; }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/bcc_pre590/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F , typename has_apply_ = typename aux::has_apply::type > struct apply_wrap0 : F::template apply< > { }; template< typename F > struct apply_wrap0< F,true_ > : F::apply { }; template< typename F, typename T1 > struct apply_wrap1 : F::template apply { }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : F::template apply< T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : F::template apply< T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : F::template apply< T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : F::template apply< T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F, int dummy_ > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, int dummy_ > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1, int dummy_ > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, int dummy_ > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2, int dummy_ > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, int dummy_ > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3, int dummy_ > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, int dummy_ > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , int dummy_ > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , int dummy_ > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, int dummy_ > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, int dummy_ > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F, int dummy_ > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, int dummy_ > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1, int dummy_ > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, int dummy_ > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2, int dummy_ > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, int dummy_ > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3, int dummy_ > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, int dummy_ > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , int dummy_ > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , int dummy_ > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, int dummy_ > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, int dummy_ > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, int dummy_ = 0 > struct bind; template< typename F, int dummy_ = 0 > struct bind0; template< typename F, typename T1, int dummy_ = 0 > struct bind1; template< typename F, typename T1, typename T2, int dummy_ = 0 > struct bind2; template< typename F, typename T1, typename T2, typename T3, int dummy_ = 0 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 , int dummy_ = 0 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, int dummy_ = 0 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg, Tag > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect, Tag > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; BOOST_MPL_AUX_NA_SPEC(2, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, bool has_type_ > struct quote_impl : T { }; template< typename T > struct quote_impl< T,false > { typedef T type; }; template< template< typename P1 > class F , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply : quote_impl< F , aux::has_type< F >::value > { }; }; template< template< typename P1, typename P2 > class F , typename Tag = void_ > struct quote2 { template< typename U1, typename U2 > struct apply : quote_impl< F< U1,U2 > , aux::has_type< F< U1,U2 > >::value > { }; }; template< template< typename P1, typename P2, typename P3 > class F , typename Tag = void_ > struct quote3 { template< typename U1, typename U2, typename U3 > struct apply : quote_impl< F< U1,U2,U3 > , aux::has_type< F< U1,U2,U3 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename Tag = void_ > struct quote4 { template< typename U1, typename U2, typename U3, typename U4 > struct apply : quote_impl< F< U1,U2,U3,U4 > , aux::has_type< F< U1,U2,U3,U4 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename Tag = void_ > struct quote5 { template< typename U1, typename U2, typename U3, typename U4 , typename U5 > struct apply : quote_impl< F< U1,U2,U3,U4,U5 > , aux::has_type< F< U1,U2,U3,U4,U5 > >::value > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value,F, Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/dmc/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F , typename has_apply_ = typename aux::has_apply::type > struct apply_wrap0 : F::template apply< > { }; template< typename F > struct apply_wrap0< F,true_ > : F::apply { }; template< typename F, typename T1 > struct apply_wrap1 : F::template apply { }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : F::template apply< T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : F::template apply< T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : F::template apply< T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : F::template apply< T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct eval_if; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< eval_if,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef typename eval_if< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct eval_if; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< eval_if,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef typename eval_if< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct bind; template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag , typename Arity > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg,Tag, int_< -1 > > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag , int_<1> > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag , int_<1> > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag , int_<2> > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag , int_<2> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag , int_<3> > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag , int_<3> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag , int_<4> > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag , int_<4> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag , int_<5> > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag , int_<5> > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect,Tag, int_<1> > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag , int_<6> > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; template< typename F , typename Tag1 , typename Tag2 , typename Arity > struct lambda< lambda< F,Tag1,Arity > , Tag2 , int_<3> > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef bind1< quote1, typename l1::result_ > arity_; typedef lambda< typename if_< is_le,arity_,Arity >::type, Tag2 > l3; typedef aux::le_result3 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, bool has_type_ > struct quote_impl { typedef typename T::type type; }; template< typename T > struct quote_impl< T,false > { typedef T type; }; template< template< typename P1 > class F , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply : quote_impl< F , aux::has_type< F >::value > { }; }; template< template< typename P1, typename P2 > class F , typename Tag = void_ > struct quote2 { template< typename U1, typename U2 > struct apply : quote_impl< F< U1,U2 > , aux::has_type< F< U1,U2 > >::value > { }; }; template< template< typename P1, typename P2, typename P3 > class F , typename Tag = void_ > struct quote3 { template< typename U1, typename U2, typename U3 > struct apply : quote_impl< F< U1,U2,U3 > , aux::has_type< F< U1,U2,U3 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename Tag = void_ > struct quote4 { template< typename U1, typename U2, typename U3, typename U4 > struct apply : quote_impl< F< U1,U2,U3,U4 > , aux::has_type< F< U1,U2,U3,U4 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename Tag = void_ > struct quote5 { template< typename U1, typename U2, typename U3, typename U4 , typename U5 > struct apply : quote_impl< F< U1,U2,U3,U4,U5 > , aux::has_type< F< U1,U2,U3,U4,U5 > >::value > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // *Preprocessed* version of the main "template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct arity_tag { typedef char (&type)[N + 1]; }; template< int C1, int C2, int C3, int C4, int C5, int C6 > struct max_arity { BOOST_STATIC_CONSTANT(int, value = ( C6 > 0 ? C6 : ( C5 > 0 ? C5 : ( C4 > 0 ? C4 : ( C3 > 0 ? C3 : ( C2 > 0 ? C2 : ( C1 > 0 ? C1 : -1 ) ) ) ) ) ) ); }; arity_tag<0>::type arity_helper(...); template< template< typename P1 > class F , typename T1 > typename arity_tag<1>::type arity_helper(type_wrapper< F >, arity_tag<1>); template< template< typename P1, typename P2 > class F , typename T1, typename T2 > typename arity_tag<2>::type arity_helper(type_wrapper< F< T1,T2 > >, arity_tag<2>); template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 > typename arity_tag<3>::type arity_helper(type_wrapper< F< T1,T2,T3 > >, arity_tag<3>); template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 > typename arity_tag<4>::type arity_helper(type_wrapper< F< T1,T2,T3,T4 > >, arity_tag<4>); template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 > typename arity_tag<5>::type arity_helper(type_wrapper< F< T1,T2,T3,T4,T5 > >, arity_tag<5>); template< template< typename P1, typename P2, typename P3, typename P4 , typename P5, typename P6 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6 > typename arity_tag<6>::type arity_helper(type_wrapper< F< T1,T2,T3,T4,T5,T6 > >, arity_tag<6>); template< typename F, int N > struct template_arity_impl { BOOST_STATIC_CONSTANT(int, value = sizeof(::boost::mpl::aux::arity_helper(type_wrapper(), arity_tag())) - 1 ); }; template< typename F > struct template_arity { BOOST_STATIC_CONSTANT(int, value = ( max_arity< template_arity_impl< F,1 >::value, template_arity_impl< F,2 >::value, template_arity_impl< F,3 >::value, template_arity_impl< F,4 >::value, template_arity_impl< F,5 >::value, template_arity_impl< F,6 >::value >::value )); typedef mpl::int_ type; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value,F, Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/gcc/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; /// ETI workaround template<> struct apply { typedef int type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_ > struct and_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : false_ { }; }; template<> struct and_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,true_ > { }; }; template<> struct and_impl ::result_< true_,true_,true_,true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 { typedef typename apply_wrap0< typename lambda::type >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; /// workaround for ETI bug template<> struct apply0 { typedef int type; }; template< typename F, typename T1 > struct apply1 { typedef typename apply_wrap1< typename lambda::type , T1 >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; /// workaround for ETI bug template<> struct apply1< int,int > { typedef int type; }; template< typename F, typename T1, typename T2 > struct apply2 { typedef typename apply_wrap2< typename lambda::type , T1, T2 >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; /// workaround for ETI bug template<> struct apply2< int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 { typedef typename apply_wrap3< typename lambda::type , T1, T2, T3 >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; /// workaround for ETI bug template<> struct apply3< int,int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 { typedef typename apply_wrap4< typename lambda::type , T1, T2, T3, T4 >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; /// workaround for ETI bug template<> struct apply4< int,int,int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 { typedef typename apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// workaround for ETI bug template<> struct apply5< int,int,int,int,int,int > { typedef int type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F> struct msvc_apply0 { template< bool > struct f_ : F {}; template<> struct f_ { template< typename P = int > struct apply { typedef int type; }; }; template< typename T = int > struct result_ : f_< aux::msvc_never_true::value > ::template apply<> { }; }; template< typename F > struct apply_wrap0 { typedef typename msvc_apply0::template result_< >::type type; }; /// workaround for ETI bug template<> struct apply_wrap0 { typedef int type; }; template< typename F> struct msvc_apply1 { template< bool > struct f_ : F {}; template<> struct f_ { template< typename P1 > struct apply { typedef int type; }; }; template< typename T1 > struct result_ : f_< aux::msvc_never_true::value > ::template apply { }; }; template< typename F, typename T1 > struct apply_wrap1 { typedef typename msvc_apply1::template result_< T1 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap1< int,int > { typedef int type; }; template< typename F> struct msvc_apply2 { template< bool > struct f_ : F {}; template<> struct f_ { template< typename P1, typename P2 > struct apply { typedef int type; }; }; template< typename T1, typename T2 > struct result_ : f_< aux::msvc_never_true::value > ::template apply< T1,T2 > { }; }; template< typename F, typename T1, typename T2 > struct apply_wrap2 { typedef typename msvc_apply2::template result_< T1, T2 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap2< int,int,int > { typedef int type; }; template< typename F> struct msvc_apply3 { template< bool > struct f_ : F {}; template<> struct f_ { template< typename P1, typename P2, typename P3 > struct apply { typedef int type; }; }; template< typename T1, typename T2, typename T3 > struct result_ : f_< aux::msvc_never_true::value > ::template apply< T1,T2,T3 > { }; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 { typedef typename msvc_apply3::template result_< T1, T2, T3 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap3< int,int,int,int > { typedef int type; }; template< typename F> struct msvc_apply4 { template< bool > struct f_ : F {}; template<> struct f_ { template< typename P1, typename P2, typename P3, typename P4 > struct apply { typedef int type; }; }; template< typename T1, typename T2, typename T3, typename T4 > struct result_ : f_< aux::msvc_never_true::value > ::template apply< T1,T2,T3,T4 > { }; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 { typedef typename msvc_apply4::template result_< T1, T2, T3, T4 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap4< int,int,int,int,int > { typedef int type; }; template< typename F> struct msvc_apply5 { template< bool > struct f_ : F {}; template<> struct f_ { template< typename P1, typename P2, typename P3, typename P4 , typename P5 > struct apply { typedef int type; }; }; template< typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ : f_< aux::msvc_never_true::value > ::template apply< T1,T2,T3,T4,T5 > { }; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 { typedef typename msvc_apply5::template result_< T1, T2, T3, T4, T5 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap5< int,int,int,int,int,int > { typedef int type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef T type; }; }; template<> struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef typename apply_wrap5< T , U1, U2, U3, U4, U5 >::type type; }; }; template< typename T > struct is_bind_template; template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg : resolve_arg_impl< is_bind_template::value > ::template result_< T,U1,U2,U3,U4,U5 > { }; template< int arity_ > struct bind_chooser; aux::no_tag is_bind_helper(...); template< typename T > aux::no_tag is_bind_helper(protect*); template< int N > aux::yes_tag is_bind_helper(arg*); template< bool is_ref_ = true > struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template<> struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_bind_helper(static_cast(0))) == sizeof(aux::yes_tag) ); }; }; template< typename T > struct is_bind_template : is_bind_template_impl< ::boost::detail::is_reference_impl::value > ::template result_ { }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F > aux::yes_tag is_bind_helper(bind0*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1 > aux::yes_tag is_bind_helper(bind1< F,T1 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2 > aux::yes_tag is_bind_helper(bind2< F,T1,T2 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3 > aux::yes_tag is_bind_helper(bind3< F,T1,T2,T3 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 > aux::yes_tag is_bind_helper(bind4< F,T1,T2,T3,T4 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind5< F,T1,T2,T3,T4,T5 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef T type; }; }; template<> struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef typename apply_wrap5< T , U1, U2, U3, U4, U5 >::type type; }; }; template< typename T > struct is_bind_template; template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg : resolve_arg_impl< is_bind_template::value > ::template result_< T,U1,U2,U3,U4,U5 > { }; template< typename T > struct replace_unnamed_arg_impl { template< typename Arg > struct result_ { typedef Arg next; typedef T type; }; }; template<> struct replace_unnamed_arg_impl< arg< -1 > > { template< typename Arg > struct result_ { typedef typename next::type next; typedef Arg type; }; }; template< typename T, typename Arg > struct replace_unnamed_arg : replace_unnamed_arg_impl::template result_ { }; template< int arity_ > struct bind_chooser; aux::no_tag is_bind_helper(...); template< typename T > aux::no_tag is_bind_helper(protect*); template< int N > aux::yes_tag is_bind_helper(arg*); template< bool is_ref_ = true > struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template<> struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_bind_helper(static_cast(0))) == sizeof(aux::yes_tag) ); }; }; template< typename T > struct is_bind_template : is_bind_template_impl< ::boost::detail::is_reference_impl::value > ::template result_ { }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F > aux::yes_tag is_bind_helper(bind0*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1 > aux::yes_tag is_bind_helper(bind1< F,T1 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2 > aux::yes_tag is_bind_helper(bind2< F,T1,T2 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3 > aux::yes_tag is_bind_helper(bind3< F,T1,T2,T3 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 > aux::yes_tag is_bind_helper(bind4< F,T1,T2,T3,T4 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind5< F,T1,T2,T3,T4,T5 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct bitand_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitand_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitand_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitand_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : if_< is_na , bitand_2< N1,N2 > , bitand_< bitand_2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitand_2 : aux::msvc_eti_base< typename apply_wrap2< bitand_impl< typename bitand_tag::type , typename bitand_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitand_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitand_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 & n2)); typedef integral_c< T,value > type; }; } template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitand_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct bitor_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitor_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitor_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitor_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : if_< is_na , bitor_2< N1,N2 > , bitor_< bitor_2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitor_2 : aux::msvc_eti_base< typename apply_wrap2< bitor_impl< typename bitor_tag::type , typename bitor_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitor_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitor_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 | n2)); typedef integral_c< T,value > type; }; } template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitor_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct bitxor_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitxor_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitxor_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitxor_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : if_< is_na , bitxor_2< N1,N2 > , bitxor_< bitxor_2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitxor_2 : aux::msvc_eti_base< typename apply_wrap2< bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitxor_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitxor_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 ^ n2)); typedef integral_c< T,value > type; }; } template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitxor_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct deque_chooser; } namespace aux { template<> struct deque_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef vector0< >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_deque_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_deque_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct deque_count_args { BOOST_STATIC_CONSTANT(int, value = is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque_impl { typedef aux::deque_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::deque_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque : aux::deque_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::deque_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct divides_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct divides_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct divides_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct divides2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : if_< is_na , divides2< N1,N2 > , divides< divides2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct divides2 : aux::msvc_eti_base< typename apply_wrap2< divides_impl< typename divides_tag::type , typename divides_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, divides2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct divides_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 / n2)); typedef integral_c< T,value > type; }; } template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::divides_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct equal_to_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct equal_to_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct equal_to_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : aux::msvc_eti_base< typename apply_wrap2< equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< int N > struct fold_chunk; template<> struct fold_chunk<0> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct fold_chunk<1> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct fold_chunk<2> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct fold_chunk<3> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct fold_chunk<4> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template< int N > struct fold_chunk { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_step; template< typename Last , typename State > struct fold_null_step { typedef Last iterator; typedef State state; }; template<> struct fold_chunk< -1 > { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , fold_null_step< Last,State > , fold_step< First,Last,State,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_step { typedef fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > chunk_; typedef typename chunk_::state state; typedef typename chunk_::iterator iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl : fold_chunk ::template result_< First,Last,State,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg, Tag > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect, Tag > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars template< typename F, typename Tag1, typename Tag2 > struct lambda< lambda< F,Tag1 > , Tag2 > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef aux::le_result2 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC(2, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct greater_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : aux::msvc_eti_base< typename apply_wrap2< greater_impl< typename greater_tag::type , typename greater_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct greater_equal_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_equal_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_equal_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : aux::msvc_eti_base< typename apply_wrap2< greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1, bool C2 > struct inherit2_impl { template< typename Derived, typename T1, typename T2 > struct result_ : T1, T2 { typedef Derived type_; }; }; template<> struct inherit2_impl< false,true > { template< typename Derived, typename T1, typename T2 > struct result_ : T1 { typedef T1 type_; }; }; template<> struct inherit2_impl< true,false > { template< typename Derived, typename T1, typename T2 > struct result_ : T2 { typedef T2 type_; }; }; template<> struct inherit2_impl< true,true > { template< typename Derived, typename T1, typename T2 > struct result_ { typedef T1 type_; }; }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : aux::inherit2_impl< is_empty_base::value , is_empty_base::value >::template result_< inherit2< T1,T2 >,T1, T2 > { typedef typename inherit2::type_ type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< int N > struct iter_fold_chunk; template<> struct iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template< int N > struct iter_fold_chunk { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_step; template< typename Last , typename State > struct iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , iter_fold_null_step< Last,State > , iter_fold_step< First,Last,State,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; /// ETI workaround template<> struct result_< int,int,int,int > { typedef int state; typedef int iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_step { typedef iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > chunk_; typedef typename chunk_::state state; typedef typename chunk_::iterator iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl : iter_fold_chunk ::template result_< First,Last,State,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct less_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : aux::msvc_eti_base< typename apply_wrap2< less_impl< typename less_tag::type , typename less_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct less_equal_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_equal_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_equal_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : aux::msvc_eti_base< typename apply_wrap2< less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct list_chooser; } namespace aux { template<> struct list_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef list0< >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_list_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_list_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct list_count_args { BOOST_STATIC_CONSTANT(int, value = is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list_impl { typedef aux::list_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::list_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list : aux::list_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::list_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct list_c_chooser; } namespace aux { template<> struct list_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list1_c< T, C0 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list2_c< T, C0, C1 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list3_c< T, C0, C1, C2 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list4_c< T, C0, C1, C2, C3 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list5_c< T, C0, C1, C2, C3, C4 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list6_c< T, C0, C1, C2, C3, C4, C5 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list7_c< T, C0, C1, C2, C3, C4, C5, C6 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list8_c< T, C0, C1, C2, C3, C4, C5, C6, C7 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list9_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list10_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list11_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list12_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list13_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_list_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_list_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct list_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c_impl { typedef aux::list_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::list_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c : aux::list_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::list_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct map_chooser; } namespace aux { template<> struct map_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef map0< >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_map_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_map_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct map_count_args { BOOST_STATIC_CONSTANT(int, value = is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map_impl { typedef aux::map_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::map_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map : aux::map_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::map_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct minus_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct minus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct minus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct minus2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : if_< is_na , minus2< N1,N2 > , minus< minus2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct minus2 : aux::msvc_eti_base< typename apply_wrap2< minus_impl< typename minus_tag::type , typename minus_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, minus2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct minus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 - n2)); typedef integral_c< T,value > type; }; } template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::minus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct modulus_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct modulus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct modulus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : aux::msvc_eti_base< typename apply_wrap2< modulus_impl< typename modulus_tag::type , typename modulus_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct modulus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 % n2)); typedef integral_c< T,value > type; }; } template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::modulus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct not_equal_to_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct not_equal_to_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct not_equal_to_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : aux::msvc_eti_base< typename apply_wrap2< not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_ > struct or_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : true_ { }; }; template<> struct or_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,false_ > { }; }; template<> struct or_impl ::result_< false_,false_,false_,false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct plus_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct plus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct plus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct plus2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : if_< is_na , plus2< N1,N2 > , plus< plus2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct plus2 : aux::msvc_eti_base< typename apply_wrap2< plus_impl< typename plus_tag::type , typename plus_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, plus2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct plus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 + n2)); typedef integral_c< T,value > type; }; } template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::plus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< long N > struct reverse_fold_chunk; template<> struct reverse_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template< long N > struct reverse_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step; template< typename Last , typename State > struct reverse_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_fold_null_step< Last,State > , reverse_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step { typedef reverse_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl : reverse_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< long N > struct reverse_iter_fold_chunk; template<> struct reverse_iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template<> struct reverse_iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template< long N > struct reverse_iter_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step; template< typename Last , typename State > struct reverse_iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_iter_fold_null_step< Last,State > , reverse_iter_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; /// ETI workaround template<> struct result_< int,int,int,int,int > { typedef int state; typedef int iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step { typedef reverse_iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl : reverse_iter_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct set_chooser; } namespace aux { template<> struct set_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef set0< >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_set_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_set_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct set_count_args { BOOST_STATIC_CONSTANT(int, value = is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set_impl { typedef aux::set_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::set_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set : aux::set_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::set_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct set_c_chooser; } namespace aux { template<> struct set_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set1_c< T, C0 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set2_c< T, C0, C1 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set3_c< T, C0, C1, C2 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set4_c< T, C0, C1, C2, C3 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set5_c< T, C0, C1, C2, C3, C4 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set6_c< T, C0, C1, C2, C3, C4, C5 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set7_c< T, C0, C1, C2, C3, C4, C5, C6 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set8_c< T, C0, C1, C2, C3, C4, C5, C6, C7 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set9_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set10_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set11_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set12_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set13_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_set_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_set_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct set_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c_impl { typedef aux::set_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::set_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c : aux::set_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::set_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct shift_left_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_left_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_left_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : aux::msvc_eti_base< typename apply_wrap2< shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { namespace aux { template< typename T, typename Shift, T n, Shift s > struct shift_left_wknd { BOOST_STATIC_CONSTANT(T, value = (n << s)); typedef integral_c< T,value > type; }; } template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : aux::shift_left_wknd< typename N::value_type , typename S::value_type , N::value , S::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct shift_right_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_right_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_right_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : aux::msvc_eti_base< typename apply_wrap2< shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { namespace aux { template< typename T, typename Shift, T n, Shift s > struct shift_right_wknd { BOOST_STATIC_CONSTANT(T, value = (n >> s)); typedef integral_c< T,value > type; }; } template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : aux::shift_right_wknd< typename N::value_type , typename S::value_type , N::value , S::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_< -1 > { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; template<> struct template_arity : mpl::int_< -1 > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct times_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct times_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct times_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct times2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : if_< is_na , times2< N1,N2 > , times< times2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct times2 : aux::msvc_eti_base< typename apply_wrap2< times_impl< typename times_tag::type , typename times_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, times2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct times_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 * n2)); typedef integral_c< T,value > type; }; } template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::times_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< BOOST_MPL_AUX_NTTP_DECL(int, size) > struct unpack_args_impl { template< typename F, typename Args > struct apply; }; template<> struct unpack_args_impl<0> { template< typename F, typename Args > struct apply : apply0< F > { }; }; template<> struct unpack_args_impl<1> { template< typename F, typename Args > struct apply : apply1< F , typename at_c< Args,0 >::type > { }; }; template<> struct unpack_args_impl<2> { template< typename F, typename Args > struct apply : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; }; template<> struct unpack_args_impl<3> { template< typename F, typename Args > struct apply : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; }; template<> struct unpack_args_impl<4> { template< typename F, typename Args > struct apply : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; }; template<> struct unpack_args_impl<5> { template< typename F, typename Args > struct apply : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value > ::template apply< F,Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct vector_chooser; } namespace aux { template<> struct vector_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef vector0< >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_vector_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_vector_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct vector_count_args { BOOST_STATIC_CONSTANT(int, value = is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector_impl { typedef aux::vector_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::vector_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector : aux::vector_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::vector_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc60/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct vector_c_chooser; } namespace aux { template<> struct vector_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector1_c< T, T(C0) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_vector_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_vector_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct vector_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c_impl { typedef aux::vector_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::vector_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c : aux::vector_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::vector_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_ > struct and_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : false_ { }; }; template<> struct and_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,true_ > { }; template<> struct result_< true_,true_,true_,true_ > : true_ { }; }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; /// workaround for ETI bug template<> struct apply0 { typedef int type; }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; /// workaround for ETI bug template<> struct apply1< int,int > { typedef int type; }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; /// workaround for ETI bug template<> struct apply2< int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; /// workaround for ETI bug template<> struct apply3< int,int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; /// workaround for ETI bug template<> struct apply4< int,int,int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// workaround for ETI bug template<> struct apply5< int,int,int,int,int,int > { typedef int type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F , typename has_apply_ = typename aux::has_apply::type > struct apply_wrap0 { typedef typename F::template apply< >::type type; }; /// workaround for ETI bug template<> struct apply_wrap0 { typedef int type; }; template< typename F, typename T1 > struct apply_wrap1 { typedef typename F::template apply< T1 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap1< int,int > { typedef int type; }; template< typename F, typename T1, typename T2 > struct apply_wrap2 { typedef typename F::template apply< T1, T2 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap2< int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 { typedef typename F::template apply< T1, T2, T3 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap3< int,int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 { typedef typename F::template apply< T1, T2, T3, T4 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap4< int,int,int,int,int > { typedef int type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 { typedef typename F::template apply< T1, T2, T3, T4, T5 >::type type; }; /// workaround for ETI bug template<> struct apply_wrap5< int,int,int,int,int,int > { typedef int type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef T type; }; }; template<> struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef typename apply_wrap5< T , U1, U2, U3, U4, U5 >::type type; }; }; template< typename T > struct is_bind_template; template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg : resolve_arg_impl< is_bind_template::value > ::template result_< T,U1,U2,U3,U4,U5 > { }; template< int arity_ > struct bind_chooser; aux::no_tag is_bind_helper(...); template< typename T > aux::no_tag is_bind_helper(protect*); template< int N > aux::yes_tag is_bind_helper(arg*); template< bool is_ref_ = true > struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template<> struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_bind_helper(static_cast(0))) == sizeof(aux::yes_tag) ); }; }; template< typename T > struct is_bind_template : is_bind_template_impl< ::boost::detail::is_reference_impl::value > ::template result_ { }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F > aux::yes_tag is_bind_helper(bind0*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1 > aux::yes_tag is_bind_helper(bind1< F,T1 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2 > aux::yes_tag is_bind_helper(bind2< F,T1,T2 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3 > aux::yes_tag is_bind_helper(bind3< F,T1,T2,T3 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 > aux::yes_tag is_bind_helper(bind4< F,T1,T2,T3,T4 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind5< F,T1,T2,T3,T4,T5 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef T type; }; }; template<> struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef typename apply_wrap5< T , U1, U2, U3, U4, U5 >::type type; }; }; template< typename T > struct is_bind_template; template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg : resolve_arg_impl< is_bind_template::value > ::template result_< T,U1,U2,U3,U4,U5 > { }; template< typename T > struct replace_unnamed_arg_impl { template< typename Arg > struct result_ { typedef Arg next; typedef T type; }; }; template<> struct replace_unnamed_arg_impl< arg< -1 > > { template< typename Arg > struct result_ { typedef typename next::type next; typedef Arg type; }; }; template< typename T, typename Arg > struct replace_unnamed_arg : replace_unnamed_arg_impl::template result_ { }; template< int arity_ > struct bind_chooser; aux::no_tag is_bind_helper(...); template< typename T > aux::no_tag is_bind_helper(protect*); template< int N > aux::yes_tag is_bind_helper(arg*); template< bool is_ref_ = true > struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template<> struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_bind_helper(static_cast(0))) == sizeof(aux::yes_tag) ); }; }; template< typename T > struct is_bind_template : is_bind_template_impl< ::boost::detail::is_reference_impl::value > ::template result_ { }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F > aux::yes_tag is_bind_helper(bind0*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1 > aux::yes_tag is_bind_helper(bind1< F,T1 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2 > aux::yes_tag is_bind_helper(bind2< F,T1,T2 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3 > aux::yes_tag is_bind_helper(bind3< F,T1,T2,T3 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 > aux::yes_tag is_bind_helper(bind4< F,T1,T2,T3,T4 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind5< F,T1,T2,T3,T4,T5 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct bitand_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitand_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitand_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag : tag< T,na > { }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitand_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : aux::msvc_eti_base< typename if_< is_na , bitand_2< N1,N2 > , bitand_< bitand_2< N1,N2 > , N3, N4, N5 > >::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitand_2 : aux::msvc_eti_base< typename apply_wrap2< bitand_impl< typename bitand_tag::type , typename bitand_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitand_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitand_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 & n2)); typedef integral_c< T,value > type; }; } template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitand_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct bitor_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitor_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitor_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag : tag< T,na > { }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitor_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : aux::msvc_eti_base< typename if_< is_na , bitor_2< N1,N2 > , bitor_< bitor_2< N1,N2 > , N3, N4, N5 > >::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitor_2 : aux::msvc_eti_base< typename apply_wrap2< bitor_impl< typename bitor_tag::type , typename bitor_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitor_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitor_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 | n2)); typedef integral_c< T,value > type; }; } template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitor_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct bitxor_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitxor_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitxor_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag : tag< T,na > { }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitxor_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : aux::msvc_eti_base< typename if_< is_na , bitxor_2< N1,N2 > , bitxor_< bitxor_2< N1,N2 > , N3, N4, N5 > >::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitxor_2 : aux::msvc_eti_base< typename apply_wrap2< bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitxor_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitxor_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 ^ n2)); typedef integral_c< T,value > type; }; } template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitxor_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct deque_chooser; } namespace aux { template<> struct deque_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef vector0< >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_deque_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_deque_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct deque_count_args { BOOST_STATIC_CONSTANT(int, value = is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque_impl { typedef aux::deque_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::deque_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque : aux::deque_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::deque_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct divides_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct divides_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct divides_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag : tag< T,na > { }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct divides2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : aux::msvc_eti_base< typename if_< is_na , divides2< N1,N2 > , divides< divides2< N1,N2 > , N3, N4, N5 > >::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct divides2 : aux::msvc_eti_base< typename apply_wrap2< divides_impl< typename divides_tag::type , typename divides_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, divides2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct divides_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 / n2)); typedef integral_c< T,value > type; }; } template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::divides_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct equal_to_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct equal_to_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct equal_to_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : aux::msvc_eti_base< typename apply_wrap2< equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< int N > struct fold_chunk; template<> struct fold_chunk<0> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; }; template<> struct fold_chunk<1> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; }; template<> struct fold_chunk<2> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; }; template<> struct fold_chunk<3> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; }; template<> struct fold_chunk<4> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; }; template< int N > struct fold_chunk { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_step; template< typename Last , typename State > struct fold_null_step { typedef Last iterator; typedef State state; }; template<> struct fold_chunk< -1 > { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , fold_null_step< Last,State > , fold_step< First,Last,State,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_step { typedef fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > chunk_; typedef typename chunk_::state state; typedef typename chunk_::iterator iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl : fold_chunk ::template result_< First,Last,State,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg, Tag > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect, Tag > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars template< typename F, typename Tag1, typename Tag2 > struct lambda< lambda< F,Tag1 > , Tag2 > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef aux::le_result2 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC(2, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct greater_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : aux::msvc_eti_base< typename apply_wrap2< greater_impl< typename greater_tag::type , typename greater_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct greater_equal_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_equal_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_equal_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : aux::msvc_eti_base< typename apply_wrap2< greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1, bool C2 > struct inherit2_impl { template< typename Derived, typename T1, typename T2 > struct result_ : T1, T2 { typedef Derived type_; }; }; template<> struct inherit2_impl< false,true > { template< typename Derived, typename T1, typename T2 > struct result_ : T1 { typedef T1 type_; }; }; template<> struct inherit2_impl< true,false > { template< typename Derived, typename T1, typename T2 > struct result_ : T2 { typedef T2 type_; }; }; template<> struct inherit2_impl< true,true > { template< typename Derived, typename T1, typename T2 > struct result_ { typedef T1 type_; }; }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : aux::inherit2_impl< is_empty_base::value , is_empty_base::value >::template result_< inherit2< T1,T2 >,T1, T2 > { typedef typename inherit2::type_ type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< int N > struct iter_fold_chunk; template<> struct iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; }; template<> struct iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; }; template<> struct iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; }; template<> struct iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; }; template<> struct iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; }; template< int N > struct iter_fold_chunk { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_step; template< typename Last , typename State > struct iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , iter_fold_null_step< Last,State > , iter_fold_step< First,Last,State,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_step { typedef iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > chunk_; typedef typename chunk_::state state; typedef typename chunk_::iterator iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl : iter_fold_chunk ::template result_< First,Last,State,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct less_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : aux::msvc_eti_base< typename apply_wrap2< less_impl< typename less_tag::type , typename less_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct less_equal_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_equal_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_equal_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : aux::msvc_eti_base< typename apply_wrap2< less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct list_chooser; } namespace aux { template<> struct list_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef list0< >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_list_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_list_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct list_count_args { BOOST_STATIC_CONSTANT(int, value = is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list_impl { typedef aux::list_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::list_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list : aux::list_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::list_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct list_c_chooser; } namespace aux { template<> struct list_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list1_c< T, C0 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list2_c< T, C0, C1 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list3_c< T, C0, C1, C2 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list4_c< T, C0, C1, C2, C3 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list5_c< T, C0, C1, C2, C3, C4 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list6_c< T, C0, C1, C2, C3, C4, C5 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list7_c< T, C0, C1, C2, C3, C4, C5, C6 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list8_c< T, C0, C1, C2, C3, C4, C5, C6, C7 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list9_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list10_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list11_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list12_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list13_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_list_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_list_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct list_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c_impl { typedef aux::list_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::list_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c : aux::list_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::list_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct map_chooser; } namespace aux { template<> struct map_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef map0< >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_map_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_map_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct map_count_args { BOOST_STATIC_CONSTANT(int, value = is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map_impl { typedef aux::map_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::map_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map : aux::map_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::map_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct minus_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct minus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct minus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag : tag< T,na > { }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct minus2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : aux::msvc_eti_base< typename if_< is_na , minus2< N1,N2 > , minus< minus2< N1,N2 > , N3, N4, N5 > >::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct minus2 : aux::msvc_eti_base< typename apply_wrap2< minus_impl< typename minus_tag::type , typename minus_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, minus2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct minus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 - n2)); typedef integral_c< T,value > type; }; } template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::minus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct modulus_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct modulus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct modulus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : aux::msvc_eti_base< typename apply_wrap2< modulus_impl< typename modulus_tag::type , typename modulus_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct modulus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 % n2)); typedef integral_c< T,value > type; }; } template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::modulus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct not_equal_to_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct not_equal_to_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct not_equal_to_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : aux::msvc_eti_base< typename apply_wrap2< not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_ > struct or_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : true_ { }; }; template<> struct or_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,false_ > { }; template<> struct result_< false_,false_,false_,false_ > : false_ { }; }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct plus_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct plus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct plus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag : tag< T,na > { }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct plus2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : aux::msvc_eti_base< typename if_< is_na , plus2< N1,N2 > , plus< plus2< N1,N2 > , N3, N4, N5 > >::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct plus2 : aux::msvc_eti_base< typename apply_wrap2< plus_impl< typename plus_tag::type , typename plus_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, plus2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct plus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 + n2)); typedef integral_c< T,value > type; }; } template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::plus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< bool > struct quote_impl { template< typename T > struct result_ : T { }; }; template<> struct quote_impl { template< typename T > struct result_ { typedef T type; }; }; template< template< typename P1 > class F , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply : quote_impl< aux::has_type< F >::value > ::template result_< F > { }; }; template< template< typename P1, typename P2 > class F , typename Tag = void_ > struct quote2 { template< typename U1, typename U2 > struct apply : quote_impl< aux::has_type< F< U1,U2 > >::value > ::template result_< F< U1,U2 > > { }; }; template< template< typename P1, typename P2, typename P3 > class F , typename Tag = void_ > struct quote3 { template< typename U1, typename U2, typename U3 > struct apply : quote_impl< aux::has_type< F< U1,U2,U3 > >::value > ::template result_< F< U1,U2,U3 > > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename Tag = void_ > struct quote4 { template< typename U1, typename U2, typename U3, typename U4 > struct apply : quote_impl< aux::has_type< F< U1,U2,U3,U4 > >::value > ::template result_< F< U1,U2,U3,U4 > > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename Tag = void_ > struct quote5 { template< typename U1, typename U2, typename U3, typename U4 , typename U5 > struct apply : quote_impl< aux::has_type< F< U1,U2,U3,U4,U5 > >::value > ::template result_< F< U1,U2,U3,U4,U5 > > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< long N > struct reverse_fold_chunk; template<> struct reverse_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step; template< typename Last , typename State > struct reverse_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_fold_null_step< Last,State > , reverse_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step { typedef reverse_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl : reverse_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< long N > struct reverse_iter_fold_chunk; template<> struct reverse_iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_iter_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step; template< typename Last , typename State > struct reverse_iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_iter_fold_null_step< Last,State > , reverse_iter_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step { typedef reverse_iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl : reverse_iter_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct set_chooser; } namespace aux { template<> struct set_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef set0< >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_set_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_set_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct set_count_args { BOOST_STATIC_CONSTANT(int, value = is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set_impl { typedef aux::set_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::set_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set : aux::set_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::set_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct set_c_chooser; } namespace aux { template<> struct set_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set1_c< T, C0 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set2_c< T, C0, C1 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set3_c< T, C0, C1, C2 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set4_c< T, C0, C1, C2, C3 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set5_c< T, C0, C1, C2, C3, C4 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set6_c< T, C0, C1, C2, C3, C4, C5 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set7_c< T, C0, C1, C2, C3, C4, C5, C6 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set8_c< T, C0, C1, C2, C3, C4, C5, C6, C7 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set9_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set10_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set11_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set12_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set13_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_set_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_set_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct set_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c_impl { typedef aux::set_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::set_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c : aux::set_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::set_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct shift_left_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_left_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_left_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : aux::msvc_eti_base< typename apply_wrap2< shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { namespace aux { template< typename T, typename Shift, T n, Shift s > struct shift_left_wknd { BOOST_STATIC_CONSTANT(T, value = (n << s)); typedef integral_c< T,value > type; }; } template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : aux::shift_left_wknd< typename N::value_type , typename S::value_type , N::value , S::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct shift_right_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_right_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_right_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag : tag< T,na > { }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : aux::msvc_eti_base< typename apply_wrap2< shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { namespace aux { template< typename T, typename Shift, T n, Shift s > struct shift_right_wknd { BOOST_STATIC_CONSTANT(T, value = (n >> s)); typedef integral_c< T,value > type; }; } template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : aux::shift_right_wknd< typename N::value_type , typename S::value_type , N::value , S::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_< -1 > { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; template<> struct template_arity : mpl::int_< -1 > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value > struct times_impl : if_c< ( tag1_ > tag2_ ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct times_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct times_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag : tag< T,na > { }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct times2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : aux::msvc_eti_base< typename if_< is_na , times2< N1,N2 > , times< times2< N1,N2 > , N3, N4, N5 > >::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct times2 : aux::msvc_eti_base< typename apply_wrap2< times_impl< typename times_tag::type , typename times_tag::type > , N1 , N2 >::type >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, times2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct times_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 * n2)); typedef integral_c< T,value > type; }; } template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::times_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< BOOST_MPL_AUX_NTTP_DECL(int, size) > struct unpack_args_impl { template< typename F, typename Args > struct apply; }; template<> struct unpack_args_impl<0> { template< typename F, typename Args > struct apply : apply0< F > { }; }; template<> struct unpack_args_impl<1> { template< typename F, typename Args > struct apply : apply1< F , typename at_c< Args,0 >::type > { }; }; template<> struct unpack_args_impl<2> { template< typename F, typename Args > struct apply : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; }; template<> struct unpack_args_impl<3> { template< typename F, typename Args > struct apply : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; }; template<> struct unpack_args_impl<4> { template< typename F, typename Args > struct apply : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; }; template<> struct unpack_args_impl<5> { template< typename F, typename Args > struct apply : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value > ::template apply< F,Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct vector_chooser; } namespace aux { template<> struct vector_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef vector0< >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_vector_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_vector_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct vector_count_args { BOOST_STATIC_CONSTANT(int, value = is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector_impl { typedef aux::vector_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::vector_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector : aux::vector_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::vector_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/msvc70/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct vector_c_chooser; } namespace aux { template<> struct vector_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector1_c< T, T(C0) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_vector_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_vector_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct vector_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c_impl { typedef aux::vector_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::vector_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c : aux::vector_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::vector_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< int N, typename F > struct apply_wrap_impl0; template< typename F > struct apply_wrap_impl0< 0 , F > { typedef typename F::template apply< /// since the defaults are "lost", we have to pass *something* even for nullary /// metafunction classes na > type; }; template< typename F > struct apply_wrap_impl0< 1 , F > { typedef typename F::template apply< na > type; }; template< typename F > struct apply_wrap_impl0< 2 , F > { typedef typename F::template apply< na, na > type; }; template< typename F > struct apply_wrap_impl0< 3 , F > { typedef typename F::template apply< na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 4 , F > { typedef typename F::template apply< na, na, na, na > type; }; template< typename F > struct apply_wrap_impl0< 5 , F > { typedef typename F::template apply< na, na, na, na, na > type; }; template< typename F > struct apply_wrap0 : apply_wrap_impl0< ::boost::mpl::aux::arity< F,0 >::value , F >::type { }; template< int N, typename F, typename T1 > struct apply_wrap_impl1; template< typename F, typename T1 > struct apply_wrap_impl1< 1 , F , T1 > { typedef typename F::template apply< T1 > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 2 , F , T1 > { typedef typename F::template apply< T1 , na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 3 , F , T1 > { typedef typename F::template apply< T1 , na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 4 , F , T1 > { typedef typename F::template apply< T1 , na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap_impl1< 5 , F , T1 > { typedef typename F::template apply< T1 , na, na, na, na > type; }; template< typename F, typename T1 > struct apply_wrap1 : apply_wrap_impl1< ::boost::mpl::aux::arity< F,1 >::value , F , T1 >::type { }; template< int N, typename F, typename T1, typename T2 > struct apply_wrap_impl2; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 2 , F , T1, T2 > { typedef typename F::template apply< T1, T2 > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 3 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 4 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap_impl2< 5 , F , T1, T2 > { typedef typename F::template apply< T1, T2 , na, na, na > type; }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : apply_wrap_impl2< ::boost::mpl::aux::arity< F,2 >::value , F , T1, T2 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 3 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 4 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap_impl3< 5 , F , T1, T2, T3 > { typedef typename F::template apply< T1, T2, T3 , na, na > type; }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : apply_wrap_impl3< ::boost::mpl::aux::arity< F,3 >::value , F , T1, T2, T3 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 4 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap_impl4< 5 , F , T1, T2, T3, T4 > { typedef typename F::template apply< T1, T2, T3, T4 , na > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : apply_wrap_impl4< ::boost::mpl::aux::arity< F,4 >::value , F , T1, T2, T3, T4 >::type { }; template< int N, typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap_impl5< 5 , F , T1, T2, T3, T4, T5 > { typedef typename F::template apply< T1, T2, T3, T4, T5 > type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : apply_wrap_impl5< ::boost::mpl::aux::arity< F,5 >::value , F , T1, T2, T3, T4, T5 >::type { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct eval_if; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< eval_if,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef typename eval_if< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct eval_if; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< eval_if,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef typename eval_if< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct bind; template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg, Tag > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect, Tag > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars template< typename F, typename Tag1, typename Tag2 > struct lambda< lambda< F,Tag1 > , Tag2 > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef aux::le_result2 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC(2, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, bool has_type_ > struct quote_impl : T { }; template< typename T > struct quote_impl< T,false > { typedef T type; }; template< template< typename P1 > class F , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply : quote_impl< F , aux::has_type< F >::value > { }; }; template< template< typename P1, typename P2 > class F , typename Tag = void_ > struct quote2 { template< typename U1, typename U2 > struct apply : quote_impl< F< U1,U2 > , aux::has_type< F< U1,U2 > >::value > { }; }; template< template< typename P1, typename P2, typename P3 > class F , typename Tag = void_ > struct quote3 { template< typename U1, typename U2, typename U3 > struct apply : quote_impl< F< U1,U2,U3 > , aux::has_type< F< U1,U2,U3 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename Tag = void_ > struct quote4 { template< typename U1, typename U2, typename U3, typename U4 > struct apply : quote_impl< F< U1,U2,U3,U4 > , aux::has_type< F< U1,U2,U3,U4 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename Tag = void_ > struct quote5 { template< typename U1, typename U2, typename U3, typename U4 , typename U5 > struct apply : quote_impl< F< U1,U2,U3,U4,U5 > , aux::has_type< F< U1,U2,U3,U4,U5 > >::value > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value,F, Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/mwcw/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_ > struct and_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : false_ { }; }; template<> struct and_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,true_ > { }; }; template<> struct and_impl ::result_< true_,true_,true_,true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; namespace aux { template<> struct apply_chooser<0> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef apply0< F > type; }; }; } // namespace aux template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; namespace aux { template<> struct apply_chooser<1> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef apply1< F, T1 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; namespace aux { template<> struct apply_chooser<2> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef apply2< F, T1, T2 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; namespace aux { template<> struct apply_chooser<3> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef apply3< F, T1, T2, T3 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; namespace aux { template<> struct apply_chooser<4> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef apply4< F, T1, T2, T3, T4 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; namespace aux { template<> struct apply_chooser<5> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef apply5< F, T1, T2, T3, T4, T5 > type; }; }; } // namespace aux namespace aux { template< typename T > struct is_apply_arg { static bool const value = true; }; template<> struct is_apply_arg { static bool const value = false; }; template< typename T1, typename T2, typename T3, typename T4, typename T5 > struct apply_count_args { static int const value = is_apply_arg::value + is_apply_arg::value + is_apply_arg::value + is_apply_arg::value + is_apply_arg::value; }; } template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply : aux::apply_chooser< aux::apply_count_args< T1,T2,T3,T4,T5 >::value >::template result_< F,T1,T2,T3,T4,T5 >::type { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< BOOST_AUX_NTTP_DECL(int, arity_) > struct apply_chooser; } template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F , typename has_apply_ = typename aux::has_apply::type > struct apply_wrap0 : F::template apply< > { }; template< typename F, typename T1 > struct apply_wrap1 : F::template apply { }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : F::template apply< T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : F::template apply< T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : F::template apply< T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : F::template apply< T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef T type; }; }; template<> struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef typename apply_wrap5< T , U1, U2, U3, U4, U5 >::type type; }; }; template< typename T > struct is_bind_template; template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg : resolve_arg_impl< is_bind_template::value > ::template result_< T,U1,U2,U3,U4,U5 > { }; template< int arity_ > struct bind_chooser; aux::no_tag is_bind_helper(...); template< typename T > aux::no_tag is_bind_helper(protect*); template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind< F,T1,T2,T3,T4,T5 >*); template< int N > aux::yes_tag is_bind_helper(arg*); template< bool is_ref_ = true > struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template<> struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_bind_helper(static_cast(0))) == sizeof(aux::yes_tag) ); }; }; template< typename T > struct is_bind_template : is_bind_template_impl< ::boost::detail::is_reference_impl::value > ::template result_ { }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F > aux::yes_tag is_bind_helper(bind0*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) namespace aux { template<> struct bind_chooser<0> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind0 type; }; }; } // namespace aux template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1 > aux::yes_tag is_bind_helper(bind1< F,T1 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) namespace aux { template<> struct bind_chooser<1> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind1< F,T1 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2 > aux::yes_tag is_bind_helper(bind2< F,T1,T2 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) namespace aux { template<> struct bind_chooser<2> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind2< F,T1,T2 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3 > aux::yes_tag is_bind_helper(bind3< F,T1,T2,T3 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) namespace aux { template<> struct bind_chooser<3> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind3< F,T1,T2,T3 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 > aux::yes_tag is_bind_helper(bind4< F,T1,T2,T3,T4 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) namespace aux { template<> struct bind_chooser<4> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind4< F,T1,T2,T3,T4 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind5< F,T1,T2,T3,T4,T5 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) namespace aux { template<> struct bind_chooser<5> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind5< F,T1,T2,T3,T4,T5 > type; }; }; } // namespace aux namespace aux { template< typename T > struct is_bind_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_bind_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 > struct bind_count_args { BOOST_STATIC_CONSTANT(int, value = is_bind_arg::value + is_bind_arg::value + is_bind_arg::value + is_bind_arg::value + is_bind_arg::value ); }; } template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : aux::bind_chooser< aux::bind_count_args< T1,T2,T3,T4,T5 >::value >::template result_< F,T1,T2,T3,T4,T5 >::type { }; BOOST_MPL_AUX_ARITY_SPEC( 6 , bind ) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC( 6 , bind ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef T type; }; }; template<> struct resolve_arg_impl { template< typename T, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct result_ { typedef typename apply_wrap5< T , U1, U2, U3, U4, U5 >::type type; }; }; template< typename T > struct is_bind_template; template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg : resolve_arg_impl< is_bind_template::value > ::template result_< T,U1,U2,U3,U4,U5 > { }; template< typename T > struct replace_unnamed_arg_impl { template< typename Arg > struct result_ { typedef Arg next; typedef T type; }; }; template<> struct replace_unnamed_arg_impl< arg< -1 > > { template< typename Arg > struct result_ { typedef typename next::type next; typedef Arg type; }; }; template< typename T, typename Arg > struct replace_unnamed_arg : replace_unnamed_arg_impl::template result_ { }; template< int arity_ > struct bind_chooser; aux::no_tag is_bind_helper(...); template< typename T > aux::no_tag is_bind_helper(protect*); template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind< F,T1,T2,T3,T4,T5 >*); template< int N > aux::yes_tag is_bind_helper(arg*); template< bool is_ref_ = true > struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template<> struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_bind_helper(static_cast(0))) == sizeof(aux::yes_tag) ); }; }; template< typename T > struct is_bind_template : is_bind_template_impl< ::boost::detail::is_reference_impl::value > ::template result_ { }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F > aux::yes_tag is_bind_helper(bind0*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) namespace aux { template<> struct bind_chooser<0> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind0 type; }; }; } // namespace aux template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1 > aux::yes_tag is_bind_helper(bind1< F,T1 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) namespace aux { template<> struct bind_chooser<1> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind1< F,T1 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2 > aux::yes_tag is_bind_helper(bind2< F,T1,T2 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) namespace aux { template<> struct bind_chooser<2> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind2< F,T1,T2 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3 > aux::yes_tag is_bind_helper(bind3< F,T1,T2,T3 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) namespace aux { template<> struct bind_chooser<3> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind3< F,T1,T2,T3 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 > aux::yes_tag is_bind_helper(bind4< F,T1,T2,T3,T4 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) namespace aux { template<> struct bind_chooser<4> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind4< F,T1,T2,T3,T4 > type; }; }; } // namespace aux template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > aux::yes_tag is_bind_helper(bind5< F,T1,T2,T3,T4,T5 >*); } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) namespace aux { template<> struct bind_chooser<5> { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct result_ { typedef bind5< F,T1,T2,T3,T4,T5 > type; }; }; } // namespace aux namespace aux { template< typename T > struct is_bind_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_bind_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 > struct bind_count_args { BOOST_STATIC_CONSTANT(int, value = is_bind_arg::value + is_bind_arg::value + is_bind_arg::value + is_bind_arg::value + is_bind_arg::value ); }; } template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : aux::bind_chooser< aux::bind_count_args< T1,T2,T3,T4,T5 >::value >::template result_< F,T1,T2,T3,T4,T5 >::type { }; BOOST_MPL_AUX_ARITY_SPEC( 6 , bind ) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC( 6 , bind ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct bind; template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitand_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitand_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitand_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : if_< is_na , bitand_2< N1,N2 > , bitand_< bitand_2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitand_2 : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitand_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitor_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitor_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitor_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : if_< is_na , bitor_2< N1,N2 > , bitor_< bitor_2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitor_2 : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitor_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitxor_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct bitxor_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct bitxor_2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : if_< is_na , bitxor_2< N1,N2 > , bitxor_< bitxor_2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct bitxor_2 : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, bitxor_2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct deque_chooser; } namespace aux { template<> struct deque_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef vector0< >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct deque_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_deque_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_deque_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct deque_count_args { BOOST_STATIC_CONSTANT(int, value = is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value + is_deque_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque_impl { typedef aux::deque_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::deque_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque : aux::deque_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::deque_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct divides_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct divides_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct divides2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : if_< is_na , divides2< N1,N2 > , divides< divides2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct divides2 : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, divides2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct equal_to_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct equal_to_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< int N > struct fold_chunk; template<> struct fold_chunk<0> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; }; template<> struct fold_chunk<1> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; }; template<> struct fold_chunk<2> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; }; template<> struct fold_chunk<3> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; }; template<> struct fold_chunk<4> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; }; template< int N > struct fold_chunk { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_step; template< typename Last , typename State > struct fold_null_step { typedef Last iterator; typedef State state; }; template<> struct fold_chunk< -1 > { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , fold_null_step< Last,State > , fold_step< First,Last,State,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_step { typedef fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > chunk_; typedef typename chunk_::state state; typedef typename chunk_::iterator iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl : fold_chunk ::template result_< First,Last,State,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg, Tag > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect, Tag > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars template< typename F, typename Tag1, typename Tag2 > struct lambda< lambda< F,Tag1 > , Tag2 > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef aux::le_result2 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC(2, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_equal_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct greater_equal_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1, bool C2 > struct inherit2_impl { template< typename Derived, typename T1, typename T2 > struct result_ : T1, T2 { typedef Derived type_; }; }; template<> struct inherit2_impl< false,true > { template< typename Derived, typename T1, typename T2 > struct result_ : T1 { typedef T1 type_; }; }; template<> struct inherit2_impl< true,false > { template< typename Derived, typename T1, typename T2 > struct result_ : T2 { typedef T2 type_; }; }; template<> struct inherit2_impl< true,true > { template< typename Derived, typename T1, typename T2 > struct result_ { typedef T1 type_; }; }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : aux::inherit2_impl< is_empty_base::value , is_empty_base::value >::template result_< inherit2< T1,T2 >,T1, T2 > { typedef typename inherit2::type_ type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< int N > struct iter_fold_chunk; template<> struct iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; }; template<> struct iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; }; template<> struct iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; }; template<> struct iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; }; template<> struct iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; }; template< int N > struct iter_fold_chunk { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_step; template< typename Last , typename State > struct iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , iter_fold_null_step< Last,State > , iter_fold_step< First,Last,State,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_step { typedef iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > chunk_; typedef typename chunk_::state state; typedef typename chunk_::iterator iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl : iter_fold_chunk ::template result_< First,Last,State,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_equal_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct less_equal_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct list_chooser; } namespace aux { template<> struct list_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef list0< >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_list_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_list_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct list_count_args { BOOST_STATIC_CONSTANT(int, value = is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value + is_list_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list_impl { typedef aux::list_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::list_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list : aux::list_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::list_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct list_c_chooser; } namespace aux { template<> struct list_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list1_c< T, C0 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list2_c< T, C0, C1 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list3_c< T, C0, C1, C2 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list4_c< T, C0, C1, C2, C3 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list5_c< T, C0, C1, C2, C3, C4 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list6_c< T, C0, C1, C2, C3, C4, C5 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list7_c< T, C0, C1, C2, C3, C4, C5, C6 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list8_c< T, C0, C1, C2, C3, C4, C5, C6, C7 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list9_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list10_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list11_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list12_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list13_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18 >::type type; }; }; } // namespace aux namespace aux { template<> struct list_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_list_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_list_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct list_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value + is_list_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c_impl { typedef aux::list_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::list_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c : aux::list_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::list_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct map_chooser; } namespace aux { template<> struct map_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef map0< >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct map_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_map_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_map_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct map_count_args { BOOST_STATIC_CONSTANT(int, value = is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value + is_map_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map_impl { typedef aux::map_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::map_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map : aux::map_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::map_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct minus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct minus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct minus2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : if_< is_na , minus2< N1,N2 > , minus< minus2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct minus2 : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, minus2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct modulus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct modulus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct not_equal_to_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct not_equal_to_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_ > struct or_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : true_ { }; }; template<> struct or_impl { template< typename T1, typename T2, typename T3, typename T4 > struct result_ : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,false_ > { }; }; template<> struct or_impl ::result_< false_,false_,false_,false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value >::template result_< T2,T3,T4,T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct plus_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct plus_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct plus2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : if_< is_na , plus2< N1,N2 > , plus< plus2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct plus2 : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, plus2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< bool > struct quote_impl { template< typename T > struct result_ : T { }; }; template<> struct quote_impl { template< typename T > struct result_ { typedef T type; }; }; template< template< typename P1 > class F , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply : quote_impl< aux::has_type< F >::value > ::template result_< F > { }; }; template< template< typename P1, typename P2 > class F , typename Tag = void_ > struct quote2 { template< typename U1, typename U2 > struct apply : quote_impl< aux::has_type< F< U1,U2 > >::value > ::template result_< F< U1,U2 > > { }; }; template< template< typename P1, typename P2, typename P3 > class F , typename Tag = void_ > struct quote3 { template< typename U1, typename U2, typename U3 > struct apply : quote_impl< aux::has_type< F< U1,U2,U3 > >::value > ::template result_< F< U1,U2,U3 > > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename Tag = void_ > struct quote4 { template< typename U1, typename U2, typename U3, typename U4 > struct apply : quote_impl< aux::has_type< F< U1,U2,U3,U4 > >::value > ::template result_< F< U1,U2,U3,U4 > > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename Tag = void_ > struct quote5 { template< typename U1, typename U2, typename U3, typename U4 , typename U5 > struct apply : quote_impl< aux::has_type< F< U1,U2,U3,U4,U5 > >::value > ::template result_< F< U1,U2,U3,U4,U5 > > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< long N > struct reverse_fold_chunk; template<> struct reverse_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step; template< typename Last , typename State > struct reverse_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_fold_null_step< Last,State > , reverse_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_step { typedef reverse_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl : reverse_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< long N > struct reverse_iter_fold_chunk; template<> struct reverse_iter_fold_chunk<0> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; }; template<> struct reverse_iter_fold_chunk<1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; }; template<> struct reverse_iter_fold_chunk<2> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; }; template<> struct reverse_iter_fold_chunk<3> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; }; template<> struct reverse_iter_fold_chunk<4> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; }; template< long N > struct reverse_iter_fold_chunk { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step; template< typename Last , typename State > struct reverse_iter_fold_null_step { typedef Last iterator; typedef State state; }; template<> struct reverse_iter_fold_chunk< -1 > { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same< First,Last >::type , reverse_iter_fold_null_step< Last,State > , reverse_iter_fold_step< First,Last,State,BackwardOp,ForwardOp > >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_step { typedef reverse_iter_fold_chunk< -1 >::template result_< typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl : reverse_iter_fold_chunk ::template result_< First,Last,State,BackwardOp,ForwardOp > { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct set_chooser; } namespace aux { template<> struct set_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef set0< >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_set_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_set_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct set_count_args { BOOST_STATIC_CONSTANT(int, value = is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value + is_set_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set_impl { typedef aux::set_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::set_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set : aux::set_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::set_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct set_c_chooser; } namespace aux { template<> struct set_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set1_c< T, C0 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set2_c< T, C0, C1 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set3_c< T, C0, C1, C2 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set4_c< T, C0, C1, C2, C3 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set5_c< T, C0, C1, C2, C3, C4 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set6_c< T, C0, C1, C2, C3, C4, C5 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set7_c< T, C0, C1, C2, C3, C4, C5, C6 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set8_c< T, C0, C1, C2, C3, C4, C5, C6, C7 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set9_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set10_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set11_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set12_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set13_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18 >::type type; }; }; } // namespace aux namespace aux { template<> struct set_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_set_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_set_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct set_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value + is_set_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c_impl { typedef aux::set_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::set_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c : aux::set_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::set_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_left_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_left_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_right_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct shift_right_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_< -1 > { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct times_impl< na,integral_c_tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template<> struct times_impl< integral_c_tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; /// forward declaration template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct times2; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : if_< is_na , times2< N1,N2 > , times< times2< N1,N2 > , N3, N4, N5 > >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1 , typename N2 > struct times2 : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, times2, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< BOOST_MPL_AUX_NTTP_DECL(int, size) > struct unpack_args_impl { template< typename F, typename Args > struct apply; }; template<> struct unpack_args_impl<0> { template< typename F, typename Args > struct apply : apply0< F > { }; }; template<> struct unpack_args_impl<1> { template< typename F, typename Args > struct apply : apply1< F , typename at_c< Args,0 >::type > { }; }; template<> struct unpack_args_impl<2> { template< typename F, typename Args > struct apply : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; }; template<> struct unpack_args_impl<3> { template< typename F, typename Args > struct apply : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; }; template<> struct unpack_args_impl<4> { template< typename F, typename Args > struct apply : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; }; template<> struct unpack_args_impl<5> { template< typename F, typename Args > struct apply : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value > ::template apply< F,Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct vector_chooser; } namespace aux { template<> struct vector_chooser<0> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef vector0< >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<1> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector1< T0 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<2> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector2< T0, T1 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<3> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector3< T0, T1, T2 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<4> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector4< T0, T1, T2, T3 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<5> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector5< T0, T1, T2, T3, T4 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<6> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector6< T0, T1, T2, T3, T4, T5 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<7> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector7< T0, T1, T2, T3, T4, T5, T6 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<8> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector8< T0, T1, T2, T3, T4, T5, T6, T7 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<9> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector9< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<10> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector10< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<11> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector11< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<12> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector12< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<13> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector13< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<14> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector14< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<15> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<16> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<17> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<18> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<19> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_chooser<20> { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct result_ { typedef typename vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }; } // namespace aux namespace aux { template< typename T > struct is_vector_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_vector_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< typename T1, typename T2, typename T3, typename T4, typename T5 , typename T6, typename T7, typename T8, typename T9, typename T10 , typename T11, typename T12, typename T13, typename T14, typename T15 , typename T16, typename T17, typename T18, typename T19, typename T20 > struct vector_count_args { BOOST_STATIC_CONSTANT(int, value = is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value + is_vector_arg::value ); }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector_impl { typedef aux::vector_count_args< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 > arg_num_; typedef typename aux::vector_chooser< arg_num_::value > ::template result_< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; } // namespace aux template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector : aux::vector_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type { typedef typename aux::vector_impl< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ctps/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int N > struct vector_c_chooser; } namespace aux { template<> struct vector_c_chooser<0> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector0_c< T >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<1> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector1_c< T, T(C0) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<2> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<3> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<4> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<5> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<6> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<7> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<8> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<9> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<10> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<11> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<12> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<13> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<14> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<15> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<16> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<17> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<18> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<19> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; }; } // namespace aux namespace aux { template<> struct vector_c_chooser<20> { template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct result_ { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }; } // namespace aux namespace aux { template< long C > struct is_vector_c_arg { BOOST_STATIC_CONSTANT(bool, value = true); }; template<> struct is_vector_c_arg { BOOST_STATIC_CONSTANT(bool, value = false); }; template< long C1, long C2, long C3, long C4, long C5, long C6, long C7, long C8 , long C9, long C10, long C11, long C12, long C13, long C14, long C15 , long C16, long C17, long C18, long C19, long C20 > struct vector_c_count_args { BOOST_STATIC_CONSTANT(int, value = is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value + is_vector_c_arg::value ); }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c_impl { typedef aux::vector_c_count_args< C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 > arg_num_; typedef typename aux::vector_c_chooser< arg_num_::value > ::template result_< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; } // namespace aux template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c : aux::vector_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type { typedef typename aux::vector_c_impl< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , and_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 1 , apply0 , (F ) ) }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 2 , apply1 , (F, T1) ) }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , apply2 , (F, T1, T2) ) }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , apply3 , (F, T1, T2, T3) ) }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , apply4 , (F, T1, T2, T3, T4) ) }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , apply5 , (F, T1, T2, T3, T4, T5) ) }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F , typename has_apply_ = typename aux::has_apply::type > struct apply_wrap0 : F::template apply< > { }; template< typename F > struct apply_wrap0< F,true_ > : F::apply { }; template< typename F, typename T1 > struct apply_wrap1 : F::template apply { }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : F::template apply< T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : F::template apply< T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : F::template apply< T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : F::template apply< T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct bind; template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitand_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitand_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 & n2)); typedef integral_c< T,value > type; }; } template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitand_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitor_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 | n2)); typedef integral_c< T,value > type; }; } template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitor_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , bitxor_ , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct bitxor_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 ^ n2)); typedef integral_c< T,value > type; }; } template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::bitxor_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , divides , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct divides_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 / n2)); typedef integral_c< T,value > type; }; } template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::divides_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg, Tag > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect, Tag > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars template< typename F, typename Tag1, typename Tag2 > struct lambda< lambda< F,Tag1 > , Tag2 > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef aux::le_result2 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC(2, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2)) }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3 , inherit3 , ( T1, T2, T3) ) }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 4 , inherit4 , ( T1, T2, T3, T4) ) }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , inherit5 , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; BOOST_MPL_AUX_LAMBDA_SUPPORT(3, lambda, (T, Tag, Protect)) }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , minus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct minus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 - n2)); typedef integral_c< T,value > type; }; } template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::minus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, modulus, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct modulus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 % n2)); typedef integral_c< T,value > type; }; } template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::modulus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply { BOOST_STATIC_CONSTANT(bool, value = ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) ); typedef bool_ type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , or_ , ( T1, T2, T3, T4, T5) ) }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , plus , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct plus_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 + n2)); typedef integral_c< T,value > type; }; } template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::plus_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_left, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { namespace aux { template< typename T, typename Shift, T n, Shift s > struct shift_left_wknd { BOOST_STATIC_CONSTANT(T, value = (n << s)); typedef integral_c< T,value > type; }; } template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : aux::shift_left_wknd< typename N::value_type , typename S::value_type , N::value , S::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(2, shift_right, (N1, N2)) }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { namespace aux { template< typename T, typename Shift, T n, Shift s > struct shift_right_wknd { BOOST_STATIC_CONSTANT(T, value = (n >> s)); typedef integral_c< T,value > type; }; } template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : aux::shift_right_wknd< typename N::value_type , typename S::value_type , N::value , S::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_< -1 > { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { BOOST_MPL_AUX_LAMBDA_SUPPORT( 5 , times , ( N1, N2, N3, N4, N5 ) ) }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { namespace aux { template< typename T, T n1, T n2 > struct times_wknd { BOOST_STATIC_CONSTANT(T, value = (n1 * n2)); typedef integral_c< T,value > type; }; } template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : aux::times_wknd< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , N1::value , N2::value >::type { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value,F, Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/no_ttp/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/advance_backward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_backward; template<> struct advance_backward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_backward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef iter1 type; }; }; template<> struct advance_backward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef iter2 type; }; }; template<> struct advance_backward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef iter3 type; }; }; template<> struct advance_backward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename prior::type iter1; typedef typename prior::type iter2; typedef typename prior::type iter3; typedef typename prior::type iter4; typedef iter4 type; }; }; template< long N > struct advance_backward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_backward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_backward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/advance_forward.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< long N > struct advance_forward; template<> struct advance_forward<0> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef iter0 type; }; }; template<> struct advance_forward<1> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef iter1 type; }; }; template<> struct advance_forward<2> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef iter2 type; }; }; template<> struct advance_forward<3> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef iter3 type; }; }; template<> struct advance_forward<4> { template< typename Iterator > struct apply { typedef Iterator iter0; typedef typename next::type iter1; typedef typename next::type iter2; typedef typename next::type iter3; typedef typename next::type iter4; typedef iter4 type; }; }; template< long N > struct advance_forward { template< typename Iterator > struct apply { typedef typename apply_wrap1< advance_forward<4> , Iterator >::type chunk_result_; typedef typename apply_wrap1< advance_forward<( (N - 4) < 0 ? 0 : N - 4 )> , chunk_result_ >::type type; }; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/and.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/and.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct and_impl : false_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct and_impl< true,T1,T2,T3,T4 > : and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , true_ > { }; template<> struct and_impl< true , true_, true_, true_, true_ > : true_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = true_, typename T4 = true_, typename T5 = true_ > struct and_ : aux::and_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , and_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/apply.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F > struct apply0 : apply_wrap0< typename lambda::type > { }; template< typename F > struct apply< F,na,na,na,na,na > : apply0 { }; template< typename F, typename T1 > struct apply1 : apply_wrap1< typename lambda::type , T1 > { }; template< typename F, typename T1 > struct apply< F,T1,na,na,na,na > : apply1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct apply2 : apply_wrap2< typename lambda::type , T1, T2 > { }; template< typename F, typename T1, typename T2 > struct apply< F,T1,T2,na,na,na > : apply2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply3 : apply_wrap3< typename lambda::type , T1, T2, T3 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply< F,T1,T2,T3,na,na > : apply3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4 : apply_wrap4< typename lambda::type , T1, T2, T3, T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply< F,T1,T2,T3,T4,na > : apply4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5 : apply_wrap5< typename lambda::type , T1, T2, T3, T4, T5 > { }; /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply : apply5< F,T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/apply_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct apply; template< typename F > struct apply0; template< typename F, typename T1 > struct apply1; template< typename F, typename T1, typename T2 > struct apply2; template< typename F, typename T1, typename T2, typename T3 > struct apply3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/apply_wrap.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/apply_wrap.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F , typename has_apply_ = typename aux::has_apply::type > struct apply_wrap0 : F::template apply< > { }; template< typename F > struct apply_wrap0< F,true_ > : F::apply { }; template< typename F, typename T1 > struct apply_wrap1 : F::template apply { }; template< typename F, typename T1, typename T2 > struct apply_wrap2 : F::template apply< T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct apply_wrap3 : F::template apply< T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct apply_wrap4 : F::template apply< T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct apply_wrap5 : F::template apply< T1,T2,T3,T4,T5 > { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/arg.hpp ================================================ // Copyright Peter Dimov 2001-2002 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/arg.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template<> struct arg< -1 > { BOOST_STATIC_CONSTANT(int, value = -1); BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<1> { BOOST_STATIC_CONSTANT(int, value = 1); typedef arg<2> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U1 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<2> { BOOST_STATIC_CONSTANT(int, value = 2); typedef arg<3> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U2 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<3> { BOOST_STATIC_CONSTANT(int, value = 3); typedef arg<4> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U3 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<4> { BOOST_STATIC_CONSTANT(int, value = 4); typedef arg<5> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U4 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; template<> struct arg<5> { BOOST_STATIC_CONSTANT(int, value = 5); typedef arg<6> next; BOOST_MPL_AUX_ARG_TYPEDEF(na, tag) BOOST_MPL_AUX_ARG_TYPEDEF(na, type) template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { typedef U5 type; BOOST_MPL_AUX_ASSERT_NOT_NA(type); }; }; BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/basic_bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/basic_bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef typename aux::resolve_bind_arg< F,U1,U2,U3,U4,U5 >::type f_; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef aux::resolve_bind_arg< T4,U1,U2,U3,U4,U5 > t4; typedef aux::resolve_bind_arg< T5,U1,U2,U3,U4,U5 > t5; public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct eval_if; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< eval_if,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::resolve_bind_arg< T1,U1,U2,U3,U4,U5 > t1; typedef aux::resolve_bind_arg< T2,U1,U2,U3,U4,U5 > t2; typedef aux::resolve_bind_arg< T3,U1,U2,U3,U4,U5 > t3; typedef typename eval_if< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/bind.hpp ================================================ // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename T, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg { typedef T type; }; template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg< -1 >, Arg > { typedef typename Arg::next next; typedef Arg type; }; template< int N, typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< arg, U1, U2, U3, U4, U5 > { typedef typename apply_wrap5, U1, U2, U3, U4, U5>::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux template< typename F > struct bind0 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// public: typedef typename apply_wrap0< f_ >::type type; }; }; namespace aux { template< typename F, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind0, U1, U2, U3, U4, U5 > { typedef bind0 f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(1, bind0) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0) template< typename F > struct bind< F,na,na,na,na,na > : bind0 { }; template< typename F, typename T1 > struct bind1 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// public: typedef typename apply_wrap1< f_ , typename t1::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename U1, typename U2, typename U3 , typename U4, typename U5 > struct resolve_bind_arg< bind1< F,T1 >, U1, U2, U3, U4, U5 > { typedef bind1< F,T1 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(2, bind1) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1) template< typename F, typename T1 > struct bind< F,T1,na,na,na,na > : bind1< F,T1 > { }; template< typename F, typename T1, typename T2 > struct bind2 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// public: typedef typename apply_wrap2< f_ , typename t1::type, typename t2::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename U1, typename U2 , typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind2< F,T1,T2 >, U1, U2, U3, U4, U5 > { typedef bind2< F,T1,T2 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(3, bind2) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2) template< typename F, typename T1, typename T2 > struct bind< F,T1,T2,na,na,na > : bind2< F,T1,T2 > { }; template< typename F, typename T1, typename T2, typename T3 > struct bind3 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// public: typedef typename apply_wrap3< f_ , typename t1::type, typename t2::type, typename t3::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename U1 , typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5 > { typedef bind3< F,T1,T2,T3 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(4, bind3) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3) template< typename F, typename T1, typename T2, typename T3 > struct bind< F,T1,T2,T3,na,na > : bind3< F,T1,T2,T3 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// public: typedef typename apply_wrap4< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename U1, typename U2, typename U3, typename U4, typename U5 > struct resolve_bind_arg< bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5 > { typedef bind4< F,T1,T2,T3,T4 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(5, bind4) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4) template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind< F,T1,T2,T3,T4,na > : bind4< F,T1,T2,T3,T4 > { }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5 { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_; /// typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef aux::replace_unnamed_arg< T4,n4 > r4; typedef typename r4::type a4; typedef typename r4::next n5; typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4; /// typedef aux::replace_unnamed_arg< T5,n5 > r5; typedef typename r5::type a5; typedef typename r5::next n6; typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5; /// public: typedef typename apply_wrap5< f_ , typename t1::type, typename t2::type, typename t3::type , typename t4::type, typename t5::type >::type type; }; }; namespace aux { template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5, typename U1, typename U2, typename U3, typename U4 , typename U5 > struct resolve_bind_arg< bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 > { typedef bind5< F,T1,T2,T3,T4,T5 > f_; typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type; }; } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(6, bind5) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5) /// primary template (not a specialization!) template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind : bind5< F,T1,T2,T3,T4,T5 > { }; /// if_/eval_if specializations template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct if_; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< if_,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef typename if_< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; template< template< typename T1, typename T2, typename T3 > class F, typename Tag > struct quote3; template< typename T1, typename T2, typename T3 > struct eval_if; template< typename Tag, typename T1, typename T2, typename T3 > struct bind3< quote3< eval_if,Tag > , T1, T2, T3 > { template< typename U1 = na, typename U2 = na, typename U3 = na , typename U4 = na, typename U5 = na > struct apply { private: typedef mpl::arg<1> n1; typedef aux::replace_unnamed_arg< T1,n1 > r1; typedef typename r1::type a1; typedef typename r1::next n2; typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1; /// typedef aux::replace_unnamed_arg< T2,n2 > r2; typedef typename r2::type a2; typedef typename r2::next n3; typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2; /// typedef aux::replace_unnamed_arg< T3,n3 > r3; typedef typename r3::type a3; typedef typename r3::next n4; typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3; /// typedef typename eval_if< typename t1::type , t2, t3 >::type f_; public: typedef typename f_::type type; }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/bind_fwd.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bind_fwd.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename F, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na > struct bind; template< typename F > struct bind0; template< typename F, typename T1 > struct bind1; template< typename F, typename T1, typename T2 > struct bind2; template< typename F, typename T1, typename T2, typename T3 > struct bind3; template< typename F, typename T1, typename T2, typename T3, typename T4 > struct bind4; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct bind5; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/bitand.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitand.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitand_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitand_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitand_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitand_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitand_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitand_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitand_ : bitand_< bitand_< bitand_< bitand_< N1,N2 >, N3>, N4>, N5> { }; template< typename N1, typename N2, typename N3, typename N4 > struct bitand_< N1,N2,N3,N4,na > : bitand_< bitand_< bitand_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitand_< N1,N2,N3,na,na > : bitand_< bitand_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitand_< N1,N2,na,na,na > : bitand_impl< typename bitand_tag::type , typename bitand_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitand_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitand_) }} namespace boost { namespace mpl { template<> struct bitand_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value & BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/bitor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitor_ : bitor_< bitor_< bitor_< bitor_< N1,N2 >, N3>, N4>, N5> { }; template< typename N1, typename N2, typename N3, typename N4 > struct bitor_< N1,N2,N3,N4,na > : bitor_< bitor_< bitor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitor_< N1,N2,N3,na,na > : bitor_< bitor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitor_< N1,N2,na,na,na > : bitor_impl< typename bitor_tag::type , typename bitor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitor_) }} namespace boost { namespace mpl { template<> struct bitor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value | BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/bitxor.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/bitxor.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct bitxor_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct bitxor_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct bitxor_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct bitxor_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct bitxor_ : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5> { }; template< typename N1, typename N2, typename N3, typename N4 > struct bitxor_< N1,N2,N3,N4,na > : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct bitxor_< N1,N2,N3,na,na > : bitxor_< bitxor_< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct bitxor_< N1,N2,na,na,na > : bitxor_impl< typename bitxor_tag::type , typename bitxor_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , bitxor_ , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_) }} namespace boost { namespace mpl { template<> struct bitxor_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/deque.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/deque.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct deque; template< > struct deque< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct deque< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct deque< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct deque< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct deque< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct deque< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct deque< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct deque< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct deque< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct deque : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/divides.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/divides.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct divides_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< divides_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< divides_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct divides_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct divides_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct divides_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct divides : divides< divides< divides< divides< N1,N2 >, N3>, N4>, N5> { }; template< typename N1, typename N2, typename N3, typename N4 > struct divides< N1,N2,N3,N4,na > : divides< divides< divides< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct divides< N1,N2,N3,na,na > : divides< divides< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct divides< N1,N2,na,na,na > : divides_impl< typename divides_tag::type , typename divides_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , divides , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, divides) }} namespace boost { namespace mpl { template<> struct divides_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value / BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct equal_to : equal_to_impl< typename equal_to_tag::type , typename equal_to_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, equal_to) }} namespace boost { namespace mpl { template<> struct equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value == BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp, state0, typename deref::type >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, state1, typename deref::type >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, state2, typename deref::type >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, state3, typename deref::type >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct fold_impl { typedef fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct fold_impl< -1,First,Last,State,ForwardOp > : fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/full_lambda.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; } // namespace aux template< typename T , typename Tag > struct lambda { typedef false_ is_le; typedef T result_; typedef T type; }; template< typename T > struct is_lambda_expression : lambda::is_le { }; template< int N, typename Tag > struct lambda< arg, Tag > { typedef true_ is_le; typedef mpl::arg result_; // qualified for the sake of MIPSpro 7.41 typedef mpl::protect type; }; template< typename F , typename Tag > struct lambda< bind0 , Tag > { typedef false_ is_le; typedef bind0< F > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1 > class F , typename L1 > struct le_result1 { typedef F< typename L1::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1 > class F , typename L1 > struct le_result1< true_,Tag,F,L1 > { typedef bind1< quote1< F,Tag > , typename L1::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1 > class F , typename T1 , typename Tag > struct lambda< F , Tag > { typedef lambda< T1,Tag > l1; typedef typename l1::is_le is_le1; typedef typename aux::lambda_or< is_le1::value >::type is_le; typedef aux::le_result1< is_le, Tag, F, l1 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1 , typename Tag > struct lambda< bind1< F,T1 > , Tag > { typedef false_ is_le; typedef bind1< F , T1 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2 { typedef F< typename L1::type, typename L2::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2 > class F , typename L1, typename L2 > struct le_result2< true_,Tag,F,L1,L2 > { typedef bind2< quote2< F,Tag > , typename L1::result_, typename L2::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2 > class F , typename T1, typename T2 , typename Tag > struct lambda< F< T1,T2 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename aux::lambda_or< is_le1::value, is_le2::value >::type is_le; typedef aux::le_result2< is_le, Tag, F, l1, l2 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2 , typename Tag > struct lambda< bind2< F,T1,T2 > , Tag > { typedef false_ is_le; typedef bind2< F , T1, T2 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3 { typedef F< typename L1::type, typename L2::type, typename L3::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3 > class F , typename L1, typename L2, typename L3 > struct le_result3< true_,Tag,F,L1,L2,L3 > { typedef bind3< quote3< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3 > class F , typename T1, typename T2, typename T3 , typename Tag > struct lambda< F< T1,T2,T3 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value >::type is_le; typedef aux::le_result3< is_le, Tag, F, l1, l2, l3 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3 , typename Tag > struct lambda< bind3< F,T1,T2,T3 > , Tag > { typedef false_ is_le; typedef bind3< F , T1, T2, T3 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4 > class F , typename L1, typename L2, typename L3, typename L4 > struct le_result4< true_,Tag,F,L1,L2,L3,L4 > { typedef bind4< quote4< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< F< T1,T2,T3,T4 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value >::type is_le; typedef aux::le_result4< is_le, Tag, F, l1, l2, l3, l4 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename Tag > struct lambda< bind4< F,T1,T2,T3,T4 > , Tag > { typedef false_ is_le; typedef bind4< F , T1, T2, T3, T4 > result_; typedef result_ type; }; namespace aux { template< typename IsLE, typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5 { typedef F< typename L1::type, typename L2::type, typename L3::type , typename L4::type, typename L5::type > result_; typedef result_ type; }; template< typename Tag , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F , typename L1, typename L2, typename L3, typename L4, typename L5 > struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 > { typedef bind5< quote5< F,Tag > , typename L1::result_, typename L2::result_, typename L3::result_ , typename L4::result_, typename L5::result_ > result_; typedef mpl::protect type; }; } // namespace aux template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename T1, typename T2, typename T3, typename T4, typename T5 , typename Tag > struct lambda< F< T1,T2,T3,T4,T5 > , Tag > { typedef lambda< T1,Tag > l1; typedef lambda< T2,Tag > l2; typedef lambda< T3,Tag > l3; typedef lambda< T4,Tag > l4; typedef lambda< T5,Tag > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef typename aux::lambda_or< is_le1::value, is_le2::value, is_le3::value, is_le4::value , is_le5::value >::type is_le; typedef aux::le_result5< is_le, Tag, F, l1, l2, l3, l4, l5 > le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind5< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind5< F , T1, T2, T3, T4, T5 > result_; typedef result_ type; }; /// special case for 'protect' template< typename T, typename Tag > struct lambda< mpl::protect, Tag > { typedef false_ is_le; typedef mpl::protect result_; typedef result_ type; }; /// specializations for the main 'bind' form template< typename F, typename T1, typename T2, typename T3, typename T4 , typename T5 , typename Tag > struct lambda< bind< F,T1,T2,T3,T4,T5 > , Tag > { typedef false_ is_le; typedef bind< F,T1,T2,T3,T4,T5 > result_; typedef result_ type; }; /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars template< typename F, typename Tag1, typename Tag2 > struct lambda< lambda< F,Tag1 > , Tag2 > { typedef lambda< F,Tag2 > l1; typedef lambda< Tag1,Tag2 > l2; typedef typename l1::is_le is_le; typedef aux::le_result2 le_result_; typedef typename le_result_::result_ result_; typedef typename le_result_::type type; }; BOOST_MPL_AUX_NA_SPEC(2, lambda) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/greater.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater : greater_impl< typename greater_tag::type , typename greater_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater) }} namespace boost { namespace mpl { template<> struct greater_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value > BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/greater_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/greater_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct greater_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct greater_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct greater_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct greater_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct greater_equal : greater_equal_impl< typename greater_equal_tag::type , typename greater_equal_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal) }} namespace boost { namespace mpl { template<> struct greater_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value >= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/inherit.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/inherit.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct inherit2 : T1, T2 { typedef inherit2 type; }; template< typename T1 > struct inherit2< T1,empty_base > { typedef T1 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base)) }; template< typename T2 > struct inherit2< empty_base,T2 > { typedef T2 type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2)) }; template<> struct inherit2< empty_base,empty_base > { typedef empty_base type; BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base)) }; BOOST_MPL_AUX_NA_SPEC(2, inherit2) template< typename T1 = na, typename T2 = na, typename T3 = na > struct inherit3 : inherit2< typename inherit2< T1, T2 >::type , T3 > { }; BOOST_MPL_AUX_NA_SPEC(3, inherit3) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na > struct inherit4 : inherit2< typename inherit3< T1, T2, T3 >::type , T4 > { }; BOOST_MPL_AUX_NA_SPEC(4, inherit4) template< typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na , typename T5 = na > struct inherit5 : inherit2< typename inherit4< T1, T2, T3, T4 >::type , T5 > { }; BOOST_MPL_AUX_NA_SPEC(5, inherit5) /// primary template template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct inherit : inherit5< T1,T2,T3,T4,T5 > { }; template<> struct inherit< na,na,na,na,na > { template< typename T1 = empty_base, typename T2 = empty_base , typename T3 = empty_base, typename T4 = empty_base , typename T5 = empty_base > struct apply : inherit< T1,T2,T3,T4,T5 > { }; }; BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit) BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< typename Iterator, typename State > struct iter_fold_if_null_step { typedef State state; typedef Iterator iterator; }; template< bool > struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef typename apply2< StateOp,State,Iterator >::type state; typedef typename IteratorOp::type iterator; }; }; template<> struct iter_fold_if_step_impl { template< typename Iterator , typename State , typename StateOp , typename IteratorOp > struct result_ { typedef State state; typedef Iterator iterator; }; }; template< typename Iterator , typename State , typename ForwardOp , typename Predicate > struct iter_fold_if_forward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,ForwardOp, mpl::next > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename BackwardOp , typename Predicate > struct iter_fold_if_backward_step { typedef typename apply2< Predicate,State,Iterator >::type not_last; typedef typename iter_fold_if_step_impl< BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value >::template result_< Iterator,State,BackwardOp, identity > impl_; typedef typename impl_::state state; typedef typename impl_::iterator iterator; }; template< typename Iterator , typename State , typename ForwardOp , typename ForwardPredicate , typename BackwardOp , typename BackwardPredicate > struct iter_fold_if_impl { private: typedef iter_fold_if_null_step< Iterator,State > forward_step0; typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1; typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2; typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3; typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4; typedef typename if_< typename forward_step4::not_last , iter_fold_if_impl< typename forward_step4::iterator , typename forward_step4::state , ForwardOp , ForwardPredicate , BackwardOp , BackwardPredicate > , iter_fold_if_null_step< typename forward_step4::iterator , typename forward_step4::state > >::type backward_step4; typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3; typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2; typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1; typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0; public: typedef typename backward_step0::state state; typedef typename backward_step4::iterator iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 0,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 1,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef state1 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 2,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef state2 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 3,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef state3 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< 4,First,Last,State,ForwardOp > { typedef First iter0; typedef State state0; typedef typename apply2< ForwardOp,state0,iter0 >::type state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,state1,iter1 >::type state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,state2,iter2 >::type state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,state3,iter3 >::type state4; typedef typename mpl::next::type iter4; typedef state4 state; typedef iter4 iterator; }; template< int N , typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl { typedef iter_fold_impl< 4 , First , Last , State , ForwardOp > chunk_; typedef iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , typename chunk_::iterator , Last , typename chunk_::state , ForwardOp > res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; template< typename First , typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,First,Last,State,ForwardOp > : iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , ForwardOp > { }; template< typename Last , typename State , typename ForwardOp > struct iter_fold_impl< -1,Last,Last,State,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/lambda_no_ctps.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/lambda_no_ctps.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false , bool C5 = false > struct lambda_or : true_ { }; template<> struct lambda_or< false,false,false,false,false > : false_ { }; template< typename Arity > struct lambda_impl { template< typename T, typename Tag, typename Protect > struct result_ { typedef T type; typedef is_placeholder is_le; }; }; template<> struct lambda_impl< int_<1> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef typename l1::is_le is_le1; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value > is_le; typedef bind1< typename F::rebind , typename l1::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<2> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value > is_le; typedef bind2< typename F::rebind , typename l1::type, typename l2::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<3> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value > is_le; typedef bind3< typename F::rebind , typename l1::type, typename l2::type, typename l3::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<4> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value > is_le; typedef bind4< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; template<> struct lambda_impl< int_<5> > { template< typename F, typename Tag, typename Protect > struct result_ { typedef lambda< typename F::arg1, Tag, false_ > l1; typedef lambda< typename F::arg2, Tag, false_ > l2; typedef lambda< typename F::arg3, Tag, false_ > l3; typedef lambda< typename F::arg4, Tag, false_ > l4; typedef lambda< typename F::arg5, Tag, false_ > l5; typedef typename l1::is_le is_le1; typedef typename l2::is_le is_le2; typedef typename l3::is_le is_le3; typedef typename l4::is_le is_le4; typedef typename l5::is_le is_le5; typedef aux::lambda_or< BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le1)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le2)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le3)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le4)::value, BOOST_MPL_AUX_MSVC_VALUE_WKND(is_le5)::value > is_le; typedef bind5< typename F::rebind , typename l1::type, typename l2::type, typename l3::type , typename l4::type, typename l5::type > bind_; typedef typename if_< is_le , if_< Protect, mpl::protect, bind_ > , identity >::type type_; typedef typename type_::type type; }; }; } // namespace aux template< typename T , typename Tag , typename Protect > struct lambda { /// Metafunction forwarding confuses MSVC 6.x typedef typename aux::template_arity::type arity_; typedef typename aux::lambda_impl ::template result_< T,Tag,Protect > l_; typedef typename l_::type type; typedef typename l_::is_le is_le; }; BOOST_MPL_AUX_NA_SPEC2(1, 3, lambda) template< typename T > struct is_lambda_expression : lambda::is_le { }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/less.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less : less_impl< typename less_tag::type , typename less_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less) }} namespace boost { namespace mpl { template<> struct less_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/less_equal.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/less_equal.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct less_equal_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct less_equal_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct less_equal_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct less_equal_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct less_equal : less_equal_impl< typename less_equal_tag::type , typename less_equal_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal) }} namespace boost { namespace mpl { template<> struct less_equal_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/list.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct list; template< > struct list< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list0< > { typedef list0< >::type type; }; template< typename T0 > struct list< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list1 { typedef typename list1::type type; }; template< typename T0, typename T1 > struct list< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list2< T0,T1 > { typedef typename list2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct list< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list3< T0,T1,T2 > { typedef typename list3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list4< T0,T1,T2,T3 > { typedef typename list4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list5< T0,T1,T2,T3,T4 > { typedef typename list5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : list6< T0,T1,T2,T3,T4,T5 > { typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : list7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : list8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : list15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : list16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : list17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : list18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : list19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list : list20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/list_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct list_c; template< typename T > struct list_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list0_c { typedef typename list0_c::type type; }; template< typename T, long C0 > struct list_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list1_c< T,C0 > { typedef typename list1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct list_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list2_c< T,C0,C1 > { typedef typename list2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct list_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list3_c< T,C0,C1,C2 > { typedef typename list3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct list_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list4_c< T,C0,C1,C2,C3 > { typedef typename list4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct list_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list5_c< T,C0,C1,C2,C3,C4 > { typedef typename list5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct list_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename list6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : list7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename list7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename list8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename list9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename list10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename list11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename list12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename list13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename list14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename list15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : list16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename list16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : list17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename list17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : list18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename list18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct list_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : list19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename list19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct list_c : list20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename list20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/map.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/map.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct map; template< > struct map< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map0< > { typedef map0< >::type type; }; template< typename T0 > struct map< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map1 { typedef typename map1::type type; }; template< typename T0, typename T1 > struct map< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map2< T0,T1 > { typedef typename map2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct map< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map3< T0,T1,T2 > { typedef typename map3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct map< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map4< T0,T1,T2,T3 > { typedef typename map4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct map< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map5< T0,T1,T2,T3,T4 > { typedef typename map5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct map< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : map6< T0,T1,T2,T3,T4,T5 > { typedef typename map6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct map< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : map7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename map7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : map8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename map8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename map9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename map10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename map11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename map12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename map13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename map14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : map15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename map15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : map16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename map16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : map17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename map17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : map18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename map18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct map< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : map19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename map19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct map : map20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename map20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/minus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/minus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct minus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct minus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct minus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct minus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct minus : minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5> { }; template< typename N1, typename N2, typename N3, typename N4 > struct minus< N1,N2,N3,N4,na > : minus< minus< minus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct minus< N1,N2,N3,na,na > : minus< minus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct minus< N1,N2,na,na,na > : minus_impl< typename minus_tag::type , typename minus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , minus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, minus) }} namespace boost { namespace mpl { template<> struct minus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value - BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/modulus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/modulus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct modulus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< modulus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< modulus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct modulus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct modulus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct modulus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct modulus : modulus_impl< typename modulus_tag::type , typename modulus_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, modulus) }} namespace boost { namespace mpl { template<> struct modulus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value % BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/not_equal_to.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/not_equal_to.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct not_equal_to_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct not_equal_to_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct not_equal_to_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct not_equal_to_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct not_equal_to : not_equal_to_impl< typename not_equal_to_tag::type , typename not_equal_to_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to) }} namespace boost { namespace mpl { template<> struct not_equal_to_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value != BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/or.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/or.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< bool C_, typename T1, typename T2, typename T3, typename T4 > struct or_impl : true_ { }; template< typename T1, typename T2, typename T3, typename T4 > struct or_impl< false,T1,T2,T3,T4 > : or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4 , false_ > { }; template<> struct or_impl< false , false_, false_, false_, false_ > : false_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename T3 = false_, typename T4 = false_, typename T5 = false_ > struct or_ : aux::or_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value , T2, T3, T4, T5 > { }; BOOST_MPL_AUX_NA_SPEC2( 2 , 5 , or_ ) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/placeholders.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/placeholders.hpp" header // -- DO NOT modify by hand! BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg< -1 > _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<1> _1; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<2> _2; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<3> _3; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<4> _4; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<5> _5; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5; } }} BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<6> _6; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6; } }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/plus.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/plus.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct plus_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< plus_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< plus_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct plus_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct plus_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct plus_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct plus : plus< plus< plus< plus< N1,N2 >, N3>, N4>, N5> { }; template< typename N1, typename N2, typename N3, typename N4 > struct plus< N1,N2,N3,N4,na > : plus< plus< plus< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct plus< N1,N2,N3,na,na > : plus< plus< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct plus< N1,N2,na,na,na > : plus_impl< typename plus_tag::type , typename plus_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , plus , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, plus) }} namespace boost { namespace mpl { template<> struct plus_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value + BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/quote.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/quote.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, bool has_type_ > struct quote_impl : T { }; template< typename T > struct quote_impl< T,false > { typedef T type; }; template< template< typename P1 > class F , typename Tag = void_ > struct quote1 { template< typename U1 > struct apply : quote_impl< F , aux::has_type< F >::value > { }; }; template< template< typename P1, typename P2 > class F , typename Tag = void_ > struct quote2 { template< typename U1, typename U2 > struct apply : quote_impl< F< U1,U2 > , aux::has_type< F< U1,U2 > >::value > { }; }; template< template< typename P1, typename P2, typename P3 > class F , typename Tag = void_ > struct quote3 { template< typename U1, typename U2, typename U3 > struct apply : quote_impl< F< U1,U2,U3 > , aux::has_type< F< U1,U2,U3 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 > class F , typename Tag = void_ > struct quote4 { template< typename U1, typename U2, typename U3, typename U4 > struct apply : quote_impl< F< U1,U2,U3,U4 > , aux::has_type< F< U1,U2,U3,U4 > >::value > { }; }; template< template< typename P1, typename P2, typename P3, typename P4 , typename P5 > class F , typename Tag = void_ > struct quote5 { template< typename U1, typename U2, typename U3, typename U4 , typename U5 > struct apply : quote_impl< F< U1,U2,U3,U4,U5 > , aux::has_type< F< U1,U2,U3,U4,U5 > >::value > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/reverse_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp, fwd_state0, typename deref::type >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp, fwd_state1, typename deref::type >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp, fwd_state2, typename deref::type >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp, fwd_state3, typename deref::type >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp, bkwd_state4, typename deref::type >::type bkwd_state3; typedef typename apply2< BackwardOp, bkwd_state3, typename deref::type >::type bkwd_state2; typedef typename apply2< BackwardOp, bkwd_state2, typename deref::type >::type bkwd_state1; typedef typename apply2< BackwardOp, bkwd_state1, typename deref::type >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_fold_impl< -1 , typename mpl::next::type , Last , typename apply2::type>::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , typename deref::type >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/reverse_iter_fold_impl.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/reverse_iter_fold_impl.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { /// forward declaration template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef fwd_state0 bkwd_state0; typedef bkwd_state0 state; typedef iter0 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef fwd_state1 bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter1 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef fwd_state2 bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter2 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef fwd_state3 bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter3 iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp > { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef fwd_state4 bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef iter4 iterator; }; template< long N , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl { typedef First iter0; typedef State fwd_state0; typedef typename apply2< ForwardOp,fwd_state0,iter0 >::type fwd_state1; typedef typename mpl::next::type iter1; typedef typename apply2< ForwardOp,fwd_state1,iter1 >::type fwd_state2; typedef typename mpl::next::type iter2; typedef typename apply2< ForwardOp,fwd_state2,iter2 >::type fwd_state3; typedef typename mpl::next::type iter3; typedef typename apply2< ForwardOp,fwd_state3,iter3 >::type fwd_state4; typedef typename mpl::next::type iter4; typedef reverse_iter_fold_impl< ( (N - 4) < 0 ? 0 : N - 4 ) , iter4 , Last , fwd_state4 , BackwardOp , ForwardOp > nested_chunk; typedef typename nested_chunk::state bkwd_state4; typedef typename apply2< BackwardOp,bkwd_state4,iter3 >::type bkwd_state3; typedef typename apply2< BackwardOp,bkwd_state3,iter2 >::type bkwd_state2; typedef typename apply2< BackwardOp,bkwd_state2,iter1 >::type bkwd_state1; typedef typename apply2< BackwardOp,bkwd_state1,iter0 >::type bkwd_state0; typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp > { typedef reverse_iter_fold_impl< -1 , typename mpl::next::type , Last , typename apply2< ForwardOp,State,First >::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , First >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct reverse_iter_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp > { typedef State state; typedef Last iterator; }; }}} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/set.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct set; template< > struct set< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set0< > { typedef set0< >::type type; }; template< typename T0 > struct set< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set1 { typedef typename set1::type type; }; template< typename T0, typename T1 > struct set< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set2< T0,T1 > { typedef typename set2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct set< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set3< T0,T1,T2 > { typedef typename set3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct set< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set4< T0,T1,T2,T3 > { typedef typename set4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct set< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set5< T0,T1,T2,T3,T4 > { typedef typename set5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct set< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : set6< T0,T1,T2,T3,T4,T5 > { typedef typename set6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct set< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : set7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename set7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : set8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename set8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename set9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename set10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename set11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename set12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename set13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename set14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : set15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename set15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : set16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename set16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : set17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename set17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : set18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename set18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct set< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : set19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename set19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct set : set20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename set20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/set_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/set_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct set_c; template< typename T > struct set_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set0_c { typedef typename set0_c::type type; }; template< typename T, long C0 > struct set_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set1_c< T,C0 > { typedef typename set1_c< T,C0 >::type type; }; template< typename T, long C0, long C1 > struct set_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set2_c< T,C0,C1 > { typedef typename set2_c< T,C0,C1 >::type type; }; template< typename T, long C0, long C1, long C2 > struct set_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set3_c< T,C0,C1,C2 > { typedef typename set3_c< T,C0,C1,C2 >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct set_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set4_c< T,C0,C1,C2,C3 > { typedef typename set4_c< T,C0,C1,C2,C3 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct set_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set5_c< T,C0,C1,C2,C3,C4 > { typedef typename set5_c< T,C0,C1,C2,C3,C4 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct set_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set6_c< T,C0,C1,C2,C3,C4,C5 > { typedef typename set6_c< T,C0,C1,C2,C3,C4,C5 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : set7_c< T,C0,C1,C2,C3,C4,C5,C6 > { typedef typename set7_c< T,C0,C1,C2,C3,C4,C5,C6 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 > { typedef typename set8_c< T,C0,C1,C2,C3,C4,C5,C6,C7 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 > { typedef typename set9_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 > { typedef typename set10_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > { typedef typename set11_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > { typedef typename set12_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > { typedef typename set13_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set14_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 > { typedef typename set14_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set15_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 > { typedef typename set15_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : set16_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15 > { typedef typename set16_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : set17_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16 > { typedef typename set17_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : set18_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17 > { typedef typename set18_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct set_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : set19_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18 > { typedef typename set19_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct set_c : set20_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, C19 > { typedef typename set20_c< T,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/shift_left.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_left.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_left_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_left_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_left_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_left_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_left_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_left_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_left : shift_left_impl< typename shift_left_tag::type , typename shift_left_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_left) }} namespace boost { namespace mpl { template<> struct shift_left_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value << BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/shift_right.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/shift_right.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct shift_right_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< shift_right_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< shift_right_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct shift_right_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct shift_right_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct shift_right_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) > struct shift_right : shift_right_impl< typename shift_right_tag::type , typename shift_right_tag::type >::template apply< N1,N2 >::type { }; BOOST_MPL_AUX_NA_SPEC2(2, 2, shift_right) }} namespace boost { namespace mpl { template<> struct shift_right_impl< integral_c_tag,integral_c_tag > { template< typename N, typename S > struct apply : integral_c< typename N::value_type , ( BOOST_MPL_AUX_VALUE_WKND(N)::value >> BOOST_MPL_AUX_VALUE_WKND(S)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/template_arity.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header // -- DO NOT modify by hand! ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/times.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/times.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename Tag1 , typename Tag2 > struct times_impl : if_c< ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ) , aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 > , aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 > >::type { }; /// for Digital Mars C++/compilers with no CTPS/TTP support template<> struct times_impl< na,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< na,Tag > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename Tag > struct times_impl< Tag,na > { template< typename U1, typename U2 > struct apply { typedef apply type; BOOST_STATIC_CONSTANT(int, value = 0); }; }; template< typename T > struct times_tag { typedef typename T::tag type; }; template< typename BOOST_MPL_AUX_NA_PARAM(N1) , typename BOOST_MPL_AUX_NA_PARAM(N2) , typename N3 = na, typename N4 = na, typename N5 = na > struct times : times< times< times< times< N1,N2 >, N3>, N4>, N5> { }; template< typename N1, typename N2, typename N3, typename N4 > struct times< N1,N2,N3,N4,na > : times< times< times< N1,N2 >, N3>, N4> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, N4, na ) ) }; template< typename N1, typename N2, typename N3 > struct times< N1,N2,N3,na,na > : times< times< N1,N2 >, N3> { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, N3, na, na ) ) }; template< typename N1, typename N2 > struct times< N1,N2,na,na,na > : times_impl< typename times_tag::type , typename times_tag::type >::template apply< N1,N2 >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC( 5 , times , ( N1, N2, na, na, na ) ) }; BOOST_MPL_AUX_NA_SPEC2(2, 5, times) }} namespace boost { namespace mpl { template<> struct times_impl< integral_c_tag,integral_c_tag > { template< typename N1, typename N2 > struct apply : integral_c< typename aux::largest_int< typename N1::value_type , typename N2::value_type >::type , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value * BOOST_MPL_AUX_VALUE_WKND(N2)::value ) > { }; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/unpack_args.hpp ================================================ // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/unpack_args.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { template< int size, typename F, typename Args > struct unpack_args_impl; template< typename F, typename Args > struct unpack_args_impl< 0,F,Args > : apply0< F > { }; template< typename F, typename Args > struct unpack_args_impl< 1,F,Args > : apply1< F , typename at_c< Args,0 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 2,F,Args > : apply2< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 3,F,Args > : apply3< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 4,F,Args > : apply4< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type > { }; template< typename F, typename Args > struct unpack_args_impl< 5,F,Args > : apply5< F , typename at_c< Args,0 >::type, typename at_c< Args,1 >::type , typename at_c< Args,2 >::type, typename at_c< Args,3 >::type , typename at_c< Args,4 >::type > { }; } template< typename F > struct unpack_args { template< typename Args > struct apply : aux::unpack_args_impl< size::value,F, Args > { }; }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, unpack_args) }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/vector.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na , typename T12 = na, typename T13 = na, typename T14 = na , typename T15 = na, typename T16 = na, typename T17 = na , typename T18 = na, typename T19 = na > struct vector; template< > struct vector< na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector0< > { typedef vector0< >::type type; }; template< typename T0 > struct vector< T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector1 { typedef typename vector1::type type; }; template< typename T0, typename T1 > struct vector< T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector2< T0,T1 > { typedef typename vector2< T0,T1 >::type type; }; template< typename T0, typename T1, typename T2 > struct vector< T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector3< T0,T1,T2 > { typedef typename vector3< T0,T1,T2 >::type type; }; template< typename T0, typename T1, typename T2, typename T3 > struct vector< T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector4< T0,T1,T2,T3 > { typedef typename vector4< T0,T1,T2,T3 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct vector< T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector5< T0,T1,T2,T3,T4 > { typedef typename vector5< T0,T1,T2,T3,T4 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct vector< T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector6< T0,T1,T2,T3,T4,T5 > { typedef typename vector6< T0,T1,T2,T3,T4,T5 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct vector< T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na , na, na, na > : vector7< T0,T1,T2,T3,T4,T5,T6 > { typedef typename vector7< T0,T1,T2,T3,T4,T5,T6 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na , na, na, na > : vector8< T0,T1,T2,T3,T4,T5,T6,T7 > { typedef typename vector8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na , na, na, na > : vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 > { typedef typename vector9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na , na, na, na > : vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 > { typedef typename vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na , na, na, na > : vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > { typedef typename vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na , na, na, na, na > : vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > { typedef typename vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na , na, na, na, na > : vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > { typedef typename vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na , na, na, na, na > : vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > { typedef typename vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na , na, na, na, na > : vector15< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 > { typedef typename vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, na, na, na, na > : vector16< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15 > { typedef typename vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, na, na, na > : vector17< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16 > { typedef typename vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, na, na > : vector18< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17 > { typedef typename vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct vector< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, na > : vector19< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18 > { typedef typename vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type; }; /// primary template (not a specialization!) template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct vector : vector20< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 , T15, T16, T17, T18, T19 > { typedef typename vector20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessed/plain/vector_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/vector_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T, long C0 = LONG_MAX, long C1 = LONG_MAX, long C2 = LONG_MAX , long C3 = LONG_MAX, long C4 = LONG_MAX, long C5 = LONG_MAX , long C6 = LONG_MAX, long C7 = LONG_MAX, long C8 = LONG_MAX , long C9 = LONG_MAX, long C10 = LONG_MAX, long C11 = LONG_MAX , long C12 = LONG_MAX, long C13 = LONG_MAX, long C14 = LONG_MAX , long C15 = LONG_MAX, long C16 = LONG_MAX, long C17 = LONG_MAX , long C18 = LONG_MAX, long C19 = LONG_MAX > struct vector_c; template< typename T > struct vector_c< T, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector0_c { typedef typename vector0_c::type type; }; template< typename T, long C0 > struct vector_c< T, C0, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector1_c< T, T(C0) > { typedef typename vector1_c< T, T(C0) >::type type; }; template< typename T, long C0, long C1 > struct vector_c< T, C0, C1, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector2_c< T, T(C0), T(C1) > { typedef typename vector2_c< T, T(C0), T(C1) >::type type; }; template< typename T, long C0, long C1, long C2 > struct vector_c< T, C0, C1, C2, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector3_c< T, T(C0), T(C1), T(C2) > { typedef typename vector3_c< T, T(C0), T(C1), T(C2) >::type type; }; template< typename T, long C0, long C1, long C2, long C3 > struct vector_c< T, C0, C1, C2, C3, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector4_c< T, T(C0), T(C1), T(C2), T(C3) > { typedef typename vector4_c< T, T(C0), T(C1), T(C2), T(C3) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4 > struct vector_c< T, C0, C1, C2, C3, C4, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) > { typedef typename vector5_c< T, T(C0), T(C1), T(C2), T(C3), T(C4) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 > struct vector_c< T, C0, C1, C2, C3, C4, C5, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) > { typedef typename vector6_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX > : vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) > { typedef typename vector7_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX > : vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) > { typedef typename vector8_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) > { typedef typename vector9_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX , LONG_MAX > : vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) > { typedef typename vector10_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, LONG_MAX, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) > { typedef typename vector11_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) > { typedef typename vector12_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, LONG_MAX , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) > { typedef typename vector13_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) > { typedef typename vector14_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) > { typedef typename vector15_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX > : vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) > { typedef typename vector16_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, LONG_MAX, LONG_MAX, LONG_MAX > : vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) > { typedef typename vector17_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, LONG_MAX, LONG_MAX > : vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) > { typedef typename vector18_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17) >::type type; }; template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18 > struct vector_c< T, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 , C15, C16, C17, C18, LONG_MAX > : vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) > { typedef typename vector19_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18) >::type type; }; /// primary template (not a specialization!) template< typename T, long C0, long C1, long C2, long C3, long C4, long C5 , long C6, long C7, long C8, long C9, long C10, long C11, long C12 , long C13, long C14, long C15, long C16, long C17, long C18, long C19 > struct vector_c : vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) > { typedef typename vector20_c< T, T(C0), T(C1), T(C2), T(C3), T(C4), T(C5), T(C6), T(C7), T(C8), T(C9), T(C10), T(C11), T(C12), T(C13), T(C14), T(C15), T(C16), T(C17), T(C18), T(C19) >::type type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/add.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_ADD_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_ADD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include #if defined(BOOST_MPL_CFG_BROKEN_PP_MACRO_EXPANSION) # include # define BOOST_MPL_PP_ADD(i,j) \ BOOST_MPL_PP_ADD_DELAY(i,j) \ /**/ # define BOOST_MPL_PP_ADD_DELAY(i,j) \ BOOST_PP_CAT(BOOST_MPL_PP_TUPLE_11_ELEM_##i,BOOST_MPL_PP_ADD_##j) \ /**/ #else # define BOOST_MPL_PP_ADD(i,j) \ BOOST_MPL_PP_ADD_DELAY(i,j) \ /**/ # define BOOST_MPL_PP_ADD_DELAY(i,j) \ BOOST_MPL_PP_TUPLE_11_ELEM_##i BOOST_MPL_PP_ADD_##j \ /**/ #endif # define BOOST_MPL_PP_ADD_0 (0,1,2,3,4,5,6,7,8,9,10) # define BOOST_MPL_PP_ADD_1 (1,2,3,4,5,6,7,8,9,10,0) # define BOOST_MPL_PP_ADD_2 (2,3,4,5,6,7,8,9,10,0,0) # define BOOST_MPL_PP_ADD_3 (3,4,5,6,7,8,9,10,0,0,0) # define BOOST_MPL_PP_ADD_4 (4,5,6,7,8,9,10,0,0,0,0) # define BOOST_MPL_PP_ADD_5 (5,6,7,8,9,10,0,0,0,0,0) # define BOOST_MPL_PP_ADD_6 (6,7,8,9,10,0,0,0,0,0,0) # define BOOST_MPL_PP_ADD_7 (7,8,9,10,0,0,0,0,0,0,0) # define BOOST_MPL_PP_ADD_8 (8,9,10,0,0,0,0,0,0,0,0) # define BOOST_MPL_PP_ADD_9 (9,10,0,0,0,0,0,0,0,0,0) # define BOOST_MPL_PP_ADD_10 (10,0,0,0,0,0,0,0,0,0,0) #else # include # define BOOST_MPL_PP_ADD(i,j) \ BOOST_PP_ADD(i,j) \ /**/ #endif #endif // BOOST_MPL_AUX_PREPROCESSOR_ADD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/def_params_tail.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_DEF_PARAMS_TAIL_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_DEF_PARAMS_TAIL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include // BOOST_MPL_PP_DEF_PARAMS_TAIL(1,T,value): , T1 = value, .., Tn = value // BOOST_MPL_PP_DEF_PARAMS_TAIL(2,T,value): , T2 = value, .., Tn = value // BOOST_MPL_PP_DEF_PARAMS_TAIL(n,T,value): #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include # include # define BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, value_func) \ BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_1( \ i \ , BOOST_MPL_PP_SUB(BOOST_MPL_LIMIT_METAFUNCTION_ARITY,i) \ , param \ , value_func \ ) \ /**/ # define BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_1(i, n, param, value_func) \ BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_2(i,n,param,value_func) \ /**/ # define BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_2(i, n, param, value_func) \ BOOST_PP_COMMA_IF(BOOST_PP_AND(i,n)) \ BOOST_MPL_PP_DEF_PARAMS_TAIL_##i(n,param,value_func) \ /**/ # define BOOST_MPL_PP_DEF_PARAMS_TAIL_0(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##1 v(),p##2 v(),p##3 v(),p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v()) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_1(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##2 v(),p##3 v(),p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_2(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##3 v(),p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_3(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2,p3) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_4(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2,p3,p4) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_5(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2,p3,p4,p5) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_6(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##7 v(),p##8 v(),p##9 v(),p1,p2,p3,p4,p5,p6) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_7(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##8 v(),p##9 v(),p1,p2,p3,p4,p5,p6,p7) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_8(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##9 v(),p1,p2,p3,p4,p5,p6,p7,p8) # define BOOST_MPL_PP_DEF_PARAMS_TAIL_9(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p1,p2,p3,p4,p5,p6,p7,p8,p9) #else # include # include # include # include # include # include # define BOOST_MPL_PP_AUX_TAIL_PARAM_FUNC(unused, i, op) \ , BOOST_PP_CAT( \ BOOST_PP_TUPLE_ELEM(3, 1, op) \ , BOOST_PP_ADD_D(1, i, BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(3, 0, op))) \ ) BOOST_PP_TUPLE_ELEM(3, 2, op)() \ /**/ # define BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, value_func) \ BOOST_PP_REPEAT( \ BOOST_PP_SUB_D(1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, i) \ , BOOST_MPL_PP_AUX_TAIL_PARAM_FUNC \ , (i, param, value_func) \ ) \ /**/ #endif // BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES #define BOOST_MPL_PP_DEF_PARAMS_TAIL(i, param, value) \ BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, BOOST_PP_IDENTITY(=value)) \ /**/ #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # define BOOST_MPL_PP_NESTED_DEF_PARAMS_TAIL(i, param, value) \ BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, BOOST_PP_IDENTITY(=value)) \ /**/ #else # define BOOST_MPL_PP_NESTED_DEF_PARAMS_TAIL(i, param, value) \ BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, BOOST_PP_EMPTY) \ /**/ #endif #endif // BOOST_MPL_AUX_PREPROCESSOR_DEF_PARAMS_TAIL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/default_params.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_DEFAULT_PARAMS_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_DEFAULT_PARAMS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include // BOOST_MPL_PP_DEFAULT_PARAMS(0,T,int): // BOOST_MPL_PP_DEFAULT_PARAMS(1,T,int): T1 = int // BOOST_MPL_PP_DEFAULT_PARAMS(2,T,int): T1 = int, T2 = int // BOOST_MPL_PP_DEFAULT_PARAMS(n,T,int): T1 = int, T2 = int, .., Tn = int #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include # define BOOST_MPL_PP_DEFAULT_PARAMS(n,p,v) \ BOOST_PP_CAT(BOOST_MPL_PP_DEFAULT_PARAMS_,n)(p,v) \ /**/ # define BOOST_MPL_PP_DEFAULT_PARAMS_0(p,v) # define BOOST_MPL_PP_DEFAULT_PARAMS_1(p,v) p##1=v # define BOOST_MPL_PP_DEFAULT_PARAMS_2(p,v) p##1=v,p##2=v # define BOOST_MPL_PP_DEFAULT_PARAMS_3(p,v) p##1=v,p##2=v,p##3=v # define BOOST_MPL_PP_DEFAULT_PARAMS_4(p,v) p##1=v,p##2=v,p##3=v,p##4=v # define BOOST_MPL_PP_DEFAULT_PARAMS_5(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v # define BOOST_MPL_PP_DEFAULT_PARAMS_6(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v # define BOOST_MPL_PP_DEFAULT_PARAMS_7(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v,p##7=v # define BOOST_MPL_PP_DEFAULT_PARAMS_8(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v,p##7=v,p##8=v # define BOOST_MPL_PP_DEFAULT_PARAMS_9(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v,p##7=v,p##8=v,p##9=v #else # include # include # include # include # include # define BOOST_MPL_PP_AUX_DEFAULT_PARAM_FUNC(unused, i, pv) \ BOOST_PP_COMMA_IF(i) \ BOOST_PP_CAT( BOOST_PP_TUPLE_ELEM(2,0,pv), BOOST_PP_INC(i) ) \ = BOOST_PP_TUPLE_ELEM(2,1,pv) \ /**/ # define BOOST_MPL_PP_DEFAULT_PARAMS(n, param, value) \ BOOST_PP_REPEAT( \ n \ , BOOST_MPL_PP_AUX_DEFAULT_PARAM_FUNC \ , (param,value) \ ) \ /**/ #endif #endif // BOOST_MPL_AUX_PREPROCESSOR_DEFAULT_PARAMS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/enum.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_ENUM_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_ENUM_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include // BOOST_MPL_PP_ENUM(0,int): // BOOST_MPL_PP_ENUM(1,int): int // BOOST_MPL_PP_ENUM(2,int): int, int // BOOST_MPL_PP_ENUM(n,int): int, int, .., int #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include # define BOOST_MPL_PP_ENUM(n, param) \ BOOST_PP_CAT(BOOST_MPL_PP_ENUM_,n)(param) \ /**/ # define BOOST_MPL_PP_ENUM_0(p) # define BOOST_MPL_PP_ENUM_1(p) p # define BOOST_MPL_PP_ENUM_2(p) p,p # define BOOST_MPL_PP_ENUM_3(p) p,p,p # define BOOST_MPL_PP_ENUM_4(p) p,p,p,p # define BOOST_MPL_PP_ENUM_5(p) p,p,p,p,p # define BOOST_MPL_PP_ENUM_6(p) p,p,p,p,p,p # define BOOST_MPL_PP_ENUM_7(p) p,p,p,p,p,p,p # define BOOST_MPL_PP_ENUM_8(p) p,p,p,p,p,p,p,p # define BOOST_MPL_PP_ENUM_9(p) p,p,p,p,p,p,p,p,p #else # include # include # define BOOST_MPL_PP_AUX_ENUM_FUNC(unused, i, param) \ BOOST_PP_COMMA_IF(i) param \ /**/ # define BOOST_MPL_PP_ENUM(n, param) \ BOOST_PP_REPEAT( \ n \ , BOOST_MPL_PP_AUX_ENUM_FUNC \ , param \ ) \ /**/ #endif #endif // BOOST_MPL_AUX_PREPROCESSOR_ENUM_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/ext_params.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_EXT_PARAMS_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_EXT_PARAMS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include // BOOST_MPL_PP_EXT_PARAMS(2,2,T): // BOOST_MPL_PP_EXT_PARAMS(2,3,T): T2 // BOOST_MPL_PP_EXT_PARAMS(2,4,T): T2, T3 // BOOST_MPL_PP_EXT_PARAMS(2,n,T): T2, T3, .., Tn-1 #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include # include # define BOOST_MPL_PP_EXT_PARAMS(i,j,p) \ BOOST_MPL_PP_EXT_PARAMS_DELAY_1(i,BOOST_MPL_PP_SUB(j,i),p) \ /**/ # define BOOST_MPL_PP_EXT_PARAMS_DELAY_1(i,n,p) \ BOOST_MPL_PP_EXT_PARAMS_DELAY_2(i,n,p) \ /**/ # define BOOST_MPL_PP_EXT_PARAMS_DELAY_2(i,n,p) \ BOOST_MPL_PP_EXT_PARAMS_##i(n,p) \ /**/ # define BOOST_MPL_PP_EXT_PARAMS_1(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##1,p##2,p##3,p##4,p##5,p##6,p##7,p##8,p##9) # define BOOST_MPL_PP_EXT_PARAMS_2(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##2,p##3,p##4,p##5,p##6,p##7,p##8,p##9,p1) # define BOOST_MPL_PP_EXT_PARAMS_3(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##3,p##4,p##5,p##6,p##7,p##8,p##9,p1,p2) # define BOOST_MPL_PP_EXT_PARAMS_4(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##4,p##5,p##6,p##7,p##8,p##9,p1,p2,p3) # define BOOST_MPL_PP_EXT_PARAMS_5(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##5,p##6,p##7,p##8,p##9,p1,p2,p3,p4) # define BOOST_MPL_PP_EXT_PARAMS_6(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##6,p##7,p##8,p##9,p1,p2,p3,p4,p5) # define BOOST_MPL_PP_EXT_PARAMS_7(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##7,p##8,p##9,p1,p2,p3,p4,p5,p6) # define BOOST_MPL_PP_EXT_PARAMS_8(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##8,p##9,p1,p2,p3,p4,p5,p6,p7) # define BOOST_MPL_PP_EXT_PARAMS_9(i,p) BOOST_MPL_PP_FILTER_PARAMS_##i(p##9,p1,p2,p3,p4,p5,p6,p7,p8) #else # include # include # include # include # include # include # define BOOST_MPL_PP_AUX_EXT_PARAM_FUNC(unused, i, op) \ BOOST_PP_COMMA_IF(i) \ BOOST_PP_CAT( \ BOOST_PP_TUPLE_ELEM(2,1,op) \ , BOOST_PP_ADD_D(1, i, BOOST_PP_TUPLE_ELEM(2,0,op)) \ ) \ /**/ # define BOOST_MPL_PP_EXT_PARAMS(i, j, param) \ BOOST_PP_REPEAT( \ BOOST_PP_SUB_D(1,j,i) \ , BOOST_MPL_PP_AUX_EXT_PARAM_FUNC \ , (i,param) \ ) \ /**/ #endif #endif // BOOST_MPL_AUX_PREPROCESSOR_EXT_PARAMS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/filter_params.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_FILTER_PARAMS_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_FILTER_PARAMS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #define BOOST_MPL_PP_FILTER_PARAMS_0(p1,p2,p3,p4,p5,p6,p7,p8,p9) #define BOOST_MPL_PP_FILTER_PARAMS_1(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1 #define BOOST_MPL_PP_FILTER_PARAMS_2(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2 #define BOOST_MPL_PP_FILTER_PARAMS_3(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2,p3 #define BOOST_MPL_PP_FILTER_PARAMS_4(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2,p3,p4 #define BOOST_MPL_PP_FILTER_PARAMS_5(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2,p3,p4,p5 #define BOOST_MPL_PP_FILTER_PARAMS_6(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2,p3,p4,p5,p6 #define BOOST_MPL_PP_FILTER_PARAMS_7(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2,p3,p4,p5,p6,p7 #define BOOST_MPL_PP_FILTER_PARAMS_8(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2,p3,p4,p5,p6,p7,p8 #define BOOST_MPL_PP_FILTER_PARAMS_9(p1,p2,p3,p4,p5,p6,p7,p8,p9) p1,p2,p3,p4,p5,p6,p7,p8,p9 #endif // BOOST_MPL_AUX_PREPROCESSOR_FILTER_PARAMS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/params.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_PARAMS_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_PARAMS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include // BOOST_MPL_PP_PARAMS(0,T): // BOOST_MPL_PP_PARAMS(1,T): T1 // BOOST_MPL_PP_PARAMS(2,T): T1, T2 // BOOST_MPL_PP_PARAMS(n,T): T1, T2, .., Tn #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include # define BOOST_MPL_PP_PARAMS(n,p) \ BOOST_PP_CAT(BOOST_MPL_PP_PARAMS_,n)(p) \ /**/ # define BOOST_MPL_PP_PARAMS_0(p) # define BOOST_MPL_PP_PARAMS_1(p) p##1 # define BOOST_MPL_PP_PARAMS_2(p) p##1,p##2 # define BOOST_MPL_PP_PARAMS_3(p) p##1,p##2,p##3 # define BOOST_MPL_PP_PARAMS_4(p) p##1,p##2,p##3,p##4 # define BOOST_MPL_PP_PARAMS_5(p) p##1,p##2,p##3,p##4,p##5 # define BOOST_MPL_PP_PARAMS_6(p) p##1,p##2,p##3,p##4,p##5,p##6 # define BOOST_MPL_PP_PARAMS_7(p) p##1,p##2,p##3,p##4,p##5,p##6,p##7 # define BOOST_MPL_PP_PARAMS_8(p) p##1,p##2,p##3,p##4,p##5,p##6,p##7,p##8 # define BOOST_MPL_PP_PARAMS_9(p) p##1,p##2,p##3,p##4,p##5,p##6,p##7,p##8,p##9 #else # include # include # include # include # define BOOST_MPL_PP_AUX_PARAM_FUNC(unused, i, param) \ BOOST_PP_COMMA_IF(i) \ BOOST_PP_CAT(param, BOOST_PP_INC(i)) \ /**/ # define BOOST_MPL_PP_PARAMS(n, param) \ BOOST_PP_REPEAT( \ n \ , BOOST_MPL_PP_AUX_PARAM_FUNC \ , param \ ) \ /**/ #endif #endif // BOOST_MPL_AUX_PREPROCESSOR_PARAMS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/partial_spec_params.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_PARTIAL_SPEC_PARAMS_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_PARTIAL_SPEC_PARAMS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #define BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(n, param, def) \ BOOST_MPL_PP_PARAMS(n, param) \ BOOST_PP_COMMA_IF(BOOST_MPL_PP_SUB(BOOST_MPL_LIMIT_METAFUNCTION_ARITY,n)) \ BOOST_MPL_PP_ENUM( \ BOOST_MPL_PP_SUB(BOOST_MPL_LIMIT_METAFUNCTION_ARITY,n) \ , def \ ) \ /**/ #endif // BOOST_MPL_AUX_PREPROCESSOR_PARTIAL_SPEC_PARAMS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/range.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_RANGE_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_RANGE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #define BOOST_MPL_PP_RANGE_ITEM(z,n,_) (n) #define BOOST_MPL_PP_RANGE(first, length) \ BOOST_PP_SEQ_SUBSEQ( \ BOOST_PP_REPEAT(BOOST_PP_ADD(first,length), BOOST_MPL_PP_RANGE_ITEM, _), \ first, length \ ) \ /**/ #endif // BOOST_MPL_AUX_PREPROCESSOR_RANGE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/repeat.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_REPEAT_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_REPEAT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include # define BOOST_MPL_PP_REPEAT(n,f,param) \ BOOST_PP_CAT(BOOST_MPL_PP_REPEAT_,n)(f,param) \ /**/ # define BOOST_MPL_PP_REPEAT_0(f,p) # define BOOST_MPL_PP_REPEAT_1(f,p) f(0,0,p) # define BOOST_MPL_PP_REPEAT_2(f,p) f(0,0,p) f(0,1,p) # define BOOST_MPL_PP_REPEAT_3(f,p) f(0,0,p) f(0,1,p) f(0,2,p) # define BOOST_MPL_PP_REPEAT_4(f,p) f(0,0,p) f(0,1,p) f(0,2,p) f(0,3,p) # define BOOST_MPL_PP_REPEAT_5(f,p) f(0,0,p) f(0,1,p) f(0,2,p) f(0,3,p) f(0,4,p) # define BOOST_MPL_PP_REPEAT_6(f,p) f(0,0,p) f(0,1,p) f(0,2,p) f(0,3,p) f(0,4,p) f(0,5,p) # define BOOST_MPL_PP_REPEAT_7(f,p) f(0,0,p) f(0,1,p) f(0,2,p) f(0,3,p) f(0,4,p) f(0,5,p) f(0,6,p) # define BOOST_MPL_PP_REPEAT_8(f,p) f(0,0,p) f(0,1,p) f(0,2,p) f(0,3,p) f(0,4,p) f(0,5,p) f(0,6,p) f(0,7,p) # define BOOST_MPL_PP_REPEAT_9(f,p) f(0,0,p) f(0,1,p) f(0,2,p) f(0,3,p) f(0,4,p) f(0,5,p) f(0,6,p) f(0,7,p) f(0,8,p) # define BOOST_MPL_PP_REPEAT_10(f,p) f(0,0,p) f(0,1,p) f(0,2,p) f(0,3,p) f(0,4,p) f(0,5,p) f(0,6,p) f(0,7,p) f(0,8,p) f(0,9,p) #else # include # define BOOST_MPL_PP_REPEAT(n,f,param) \ BOOST_PP_REPEAT(n,f,param) \ /**/ #endif #define BOOST_MPL_PP_REPEAT_IDENTITY_FUNC(unused1, unused2, x) x #endif // BOOST_MPL_AUX_PREPROCESSOR_REPEAT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/sub.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_SUB_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_SUB_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES) # include #if defined(BOOST_MPL_CFG_BROKEN_PP_MACRO_EXPANSION) # include # define BOOST_MPL_PP_SUB(i,j) \ BOOST_MPL_PP_SUB_DELAY(i,j) \ /**/ # define BOOST_MPL_PP_SUB_DELAY(i,j) \ BOOST_PP_CAT(BOOST_MPL_PP_TUPLE_11_ELEM_##i,BOOST_MPL_PP_SUB_##j) \ /**/ #else # define BOOST_MPL_PP_SUB(i,j) \ BOOST_MPL_PP_SUB_DELAY(i,j) \ /**/ # define BOOST_MPL_PP_SUB_DELAY(i,j) \ BOOST_MPL_PP_TUPLE_11_ELEM_##i BOOST_MPL_PP_SUB_##j \ /**/ #endif # define BOOST_MPL_PP_SUB_0 (0,1,2,3,4,5,6,7,8,9,10) # define BOOST_MPL_PP_SUB_1 (0,0,1,2,3,4,5,6,7,8,9) # define BOOST_MPL_PP_SUB_2 (0,0,0,1,2,3,4,5,6,7,8) # define BOOST_MPL_PP_SUB_3 (0,0,0,0,1,2,3,4,5,6,7) # define BOOST_MPL_PP_SUB_4 (0,0,0,0,0,1,2,3,4,5,6) # define BOOST_MPL_PP_SUB_5 (0,0,0,0,0,0,1,2,3,4,5) # define BOOST_MPL_PP_SUB_6 (0,0,0,0,0,0,0,1,2,3,4) # define BOOST_MPL_PP_SUB_7 (0,0,0,0,0,0,0,0,1,2,3) # define BOOST_MPL_PP_SUB_8 (0,0,0,0,0,0,0,0,0,1,2) # define BOOST_MPL_PP_SUB_9 (0,0,0,0,0,0,0,0,0,0,1) # define BOOST_MPL_PP_SUB_10 (0,0,0,0,0,0,0,0,0,0,0) #else # include # define BOOST_MPL_PP_SUB(i,j) \ BOOST_PP_SUB(i,j) \ /**/ #endif #endif // BOOST_MPL_AUX_PREPROCESSOR_SUB_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/preprocessor/tuple.hpp ================================================ #ifndef BOOST_MPL_AUX_PREPROCESSOR_TUPLE_HPP_INCLUDED #define BOOST_MPL_AUX_PREPROCESSOR_TUPLE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #define BOOST_MPL_PP_TUPLE_11_ELEM_0(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e0 #define BOOST_MPL_PP_TUPLE_11_ELEM_1(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e1 #define BOOST_MPL_PP_TUPLE_11_ELEM_2(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e2 #define BOOST_MPL_PP_TUPLE_11_ELEM_3(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e3 #define BOOST_MPL_PP_TUPLE_11_ELEM_4(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e4 #define BOOST_MPL_PP_TUPLE_11_ELEM_5(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e5 #define BOOST_MPL_PP_TUPLE_11_ELEM_6(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e6 #define BOOST_MPL_PP_TUPLE_11_ELEM_7(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e7 #define BOOST_MPL_PP_TUPLE_11_ELEM_8(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e8 #define BOOST_MPL_PP_TUPLE_11_ELEM_9(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e9 #define BOOST_MPL_PP_TUPLE_11_ELEM_10(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10) e10 #endif // BOOST_MPL_AUX_PREPROCESSOR_TUPLE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/ptr_to_ref.hpp ================================================ #ifndef BOOST_MPL_AUX_PTR_TO_REF_HPP_INCLUDED #define BOOST_MPL_AUX_PTR_TO_REF_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ || ( BOOST_WORKAROUND(__EDG_VERSION__, <= 245) \ && !(defined(__STD_STRICT_ANSI) \ || defined(__STD_STRICT_ANSI_ERRORS)) ) # define BOOST_MPL_AUX_PTR_TO_REF(X) \ *BOOST_MPL_AUX_STATIC_CAST(X*, 0) \ /**/ #else # define BOOST_MPL_AUX_PTR_TO_REF(X) \ aux::ptr_to_ref(BOOST_MPL_AUX_STATIC_CAST(X*, 0)) \ /**/ #endif namespace boost { namespace mpl { namespace aux { template< typename T > static T const& ptr_to_ref(T*); }}} #endif // BOOST_MPL_AUX_PTR_TO_REF_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/push_front_impl.hpp ================================================ #ifndef BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED #define BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include namespace boost { namespace mpl { struct has_push_front_arg {}; // agurt 05/feb/04: no default implementation; the stub definition is needed // to enable the default 'has_push_front' implementation below template< typename Tag > struct push_front_impl { template< typename Sequence, typename T > struct apply { // should be instantiated only in the context of 'has_push_front_impl'; // if you've got an assert here, you are requesting a 'push_front' // specialization that doesn't exist. BOOST_MPL_ASSERT_MSG( ( boost::is_same< T, has_push_front_arg >::value ) , REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST , ( Sequence ) ); }; }; template< typename Tag > struct has_push_front_impl { template< typename Seq > struct apply #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) : aux::has_type< push_front< Seq, has_push_front_arg > > { #else { typedef aux::has_type< push_front< Seq, has_push_front_arg > > type; BOOST_STATIC_CONSTANT(bool, value = (aux::has_type< push_front< Seq, has_push_front_arg > >::value) ); #endif }; }; BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, push_front_impl) BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, has_push_front_impl) }} #endif // BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/reverse_fold_impl.hpp ================================================ #ifndef BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED #define BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ || defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) # include # include # endif #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER reverse_fold_impl.hpp # include #else # define AUX778076_FOLD_IMPL_OP(iter) typename deref::type # define AUX778076_FOLD_IMPL_NAME_PREFIX reverse_fold # include #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/reverse_fold_impl_body.hpp ================================================ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! #if !defined(BOOST_PP_IS_ITERATING) // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ # include # include # include # include # include # include # include # include # include // local macros, #undef-ined at the end of the header # define AUX778076_ITER_FOLD_FORWARD_STEP(unused, n_, unused2) \ typedef typename apply2< \ ForwardOp \ , BOOST_PP_CAT(fwd_state,n_) \ , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,n_)) \ >::type BOOST_PP_CAT(fwd_state,BOOST_PP_INC(n_)); \ typedef typename mpl::next::type \ BOOST_PP_CAT(iter,BOOST_PP_INC(n_)); \ /**/ # define AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC(n_) \ typedef typename apply2< \ BackwardOp \ , BOOST_PP_CAT(bkwd_state,n_) \ , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,BOOST_PP_DEC(n_))) \ >::type BOOST_PP_CAT(bkwd_state,BOOST_PP_DEC(n_)); \ /**/ # define AUX778076_ITER_FOLD_BACKWARD_STEP(unused, n_, j) \ AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC( \ BOOST_PP_SUB_D(1,j,n_) \ ) \ /**/ # define AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(n_) \ typedef typename nested_chunk::state BOOST_PP_CAT(bkwd_state,n_); /**/ # define AUX778076_FOLD_IMPL_NAME \ BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_impl) \ /**/ # define AUX778076_FOLD_CHUNK_NAME \ BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_chunk) \ /**/ namespace boost { namespace mpl { namespace aux { /// forward declaration template< BOOST_MPL_AUX_NTTP_DECL(long, N) , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) # include BOOST_PP_ITERATE() // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING template< BOOST_MPL_AUX_NTTP_DECL(long, N) , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME { typedef First iter0; typedef State fwd_state0; BOOST_MPL_PP_REPEAT( BOOST_MPL_LIMIT_UNROLLING , AUX778076_ITER_FOLD_FORWARD_STEP , unused ) typedef AUX778076_FOLD_IMPL_NAME< ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) , BOOST_PP_CAT(iter,BOOST_MPL_LIMIT_UNROLLING) , Last , BOOST_PP_CAT(fwd_state,BOOST_MPL_LIMIT_UNROLLING) , BackwardOp , ForwardOp > nested_chunk; AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(BOOST_MPL_LIMIT_UNROLLING) BOOST_MPL_PP_REPEAT( BOOST_MPL_LIMIT_UNROLLING , AUX778076_ITER_FOLD_BACKWARD_STEP , BOOST_MPL_LIMIT_UNROLLING ) typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; // fallback implementation for sequences of unknown size template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME<-1,First,Last,State,BackwardOp,ForwardOp> { typedef AUX778076_FOLD_IMPL_NAME< -1 , typename mpl::next::type , Last , typename apply2::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , AUX778076_FOLD_IMPL_OP(First) >::type state; typedef typename nested_step::iterator iterator; }; template< typename Last , typename State , typename BackwardOp , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME<-1,Last,Last,State,BackwardOp,ForwardOp> { typedef State state; typedef Last iterator; }; #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct AUX778076_FOLD_CHUNK_NAME; # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) # include BOOST_PP_ITERATE() // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct AUX778076_FOLD_CHUNK_NAME { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; BOOST_MPL_PP_REPEAT( BOOST_MPL_LIMIT_UNROLLING , AUX778076_ITER_FOLD_FORWARD_STEP , unused ) typedef AUX778076_FOLD_IMPL_NAME< ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) , BOOST_PP_CAT(iter,BOOST_MPL_LIMIT_UNROLLING) , Last , BOOST_PP_CAT(fwd_state,BOOST_MPL_LIMIT_UNROLLING) , BackwardOp , ForwardOp > nested_chunk; AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(BOOST_MPL_LIMIT_UNROLLING) BOOST_MPL_PP_REPEAT( BOOST_MPL_LIMIT_UNROLLING , AUX778076_ITER_FOLD_BACKWARD_STEP , BOOST_MPL_LIMIT_UNROLLING ) typedef bkwd_state0 state; typedef typename nested_chunk::iterator iterator; }; }; // fallback implementation for sequences of unknown size template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step); template< typename Last , typename State > struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) { typedef Last iterator; typedef State state; }; template<> struct AUX778076_FOLD_CHUNK_NAME<-1> { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef typename if_< typename is_same::type , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) >::type res_; typedef typename res_::state state; typedef typename res_::iterator iterator; }; #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) /// ETI workaround template<> struct result_ { typedef int state; typedef int iterator; }; #endif }; template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) { typedef AUX778076_FOLD_CHUNK_NAME<-1>::template result_< typename mpl::next::type , Last , typename apply2::type , BackwardOp , ForwardOp > nested_step; typedef typename apply2< BackwardOp , typename nested_step::state , AUX778076_FOLD_IMPL_OP(First) >::type state; typedef typename nested_step::iterator iterator; }; template< BOOST_MPL_AUX_NTTP_DECL(long, N) , typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME : AUX778076_FOLD_CHUNK_NAME ::template result_ { }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION }}} # undef AUX778076_FIRST_BACKWARD_STATE_TYPEDEF # undef AUX778076_ITER_FOLD_BACKWARD_STEP # undef AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC # undef AUX778076_ITER_FOLD_FORWARD_STEP #undef AUX778076_FOLD_IMPL_OP #undef AUX778076_FOLD_IMPL_NAME_PREFIX ///// iteration #else # define n_ BOOST_PP_FRAME_ITERATION(1) #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct AUX778076_FOLD_IMPL_NAME { typedef First iter0; typedef State fwd_state0; BOOST_MPL_PP_REPEAT( n_ , AUX778076_ITER_FOLD_FORWARD_STEP , unused ) typedef BOOST_PP_CAT(fwd_state,n_) BOOST_PP_CAT(bkwd_state,n_); BOOST_MPL_PP_REPEAT( n_ , AUX778076_ITER_FOLD_BACKWARD_STEP , n_ ) typedef bkwd_state0 state; typedef BOOST_PP_CAT(iter,n_) iterator; }; #else template<> struct AUX778076_FOLD_CHUNK_NAME { template< typename First , typename Last , typename State , typename BackwardOp , typename ForwardOp > struct result_ { typedef First iter0; typedef State fwd_state0; BOOST_MPL_PP_REPEAT( n_ , AUX778076_ITER_FOLD_FORWARD_STEP , unused ) typedef BOOST_PP_CAT(fwd_state,n_) BOOST_PP_CAT(bkwd_state,n_); BOOST_MPL_PP_REPEAT( n_ , AUX778076_ITER_FOLD_BACKWARD_STEP , n_ ) typedef bkwd_state0 state; typedef BOOST_PP_CAT(iter,n_) iterator; }; #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) /// ETI workaround template<> struct result_ { typedef int state; typedef int iterator; }; #endif }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # undef n_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/sequence_wrapper.hpp ================================================ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION #if !defined(BOOST_PP_IS_ITERATING) ///// header body // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ # include # include # include # include # include # include # include # include # include # include # include #if defined(BOOST_MPL_PREPROCESSING_MODE) # undef LONG_MAX #endif namespace boost { namespace mpl { #if !defined(AUX778076_SEQUENCE_BASE_NAME) # define AUX778076_SEQUENCE_BASE_NAME AUX778076_SEQUENCE_NAME #endif #if !defined(AUX778076_SEQUENCE_INTEGRAL_WRAPPER) # define AUX778076_SEQUENCE_PARAM_NAME T # define AUX778076_SEQUENCE_TEMPLATE_PARAM typename T # define AUX778076_SEQUENCE_DEFAULT na # define AUX778076_SEQUENCE_NAME_N(n) \ BOOST_PP_CAT(AUX778076_SEQUENCE_BASE_NAME,n) \ /**/ # define AUX778076_SEQUENCE_PARAMS() \ BOOST_PP_ENUM_PARAMS( \ AUX778076_SEQUENCE_LIMIT \ , AUX778076_SEQUENCE_TEMPLATE_PARAM \ ) \ /**/ # define AUX778076_SEQUENCE_ARGS() \ BOOST_PP_ENUM_PARAMS( \ AUX778076_SEQUENCE_LIMIT \ , T \ ) \ /**/ # define AUX778076_SEQUENCE_DEFAULT_PARAMS() \ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ AUX778076_SEQUENCE_LIMIT \ , AUX778076_SEQUENCE_TEMPLATE_PARAM \ , AUX778076_SEQUENCE_DEFAULT \ ) \ /**/ # define AUX778076_SEQUENCE_N_PARAMS(n) \ BOOST_PP_ENUM_PARAMS(n, AUX778076_SEQUENCE_TEMPLATE_PARAM) \ /**/ # define AUX778076_SEQUENCE_N_ARGS(n) \ BOOST_PP_ENUM_PARAMS(n, T) \ /**/ # define AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS(n) \ BOOST_PP_ENUM_PARAMS(n, T) \ BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM( \ BOOST_PP_SUB_D(1,AUX778076_SEQUENCE_LIMIT,n) \ , BOOST_PP_TUPLE_ELEM_3_2 \ , AUX778076_SEQUENCE_DEFAULT \ ) \ /**/ #else // AUX778076_SEQUENCE_INTEGRAL_WRAPPER # define AUX778076_SEQUENCE_PARAM_NAME C # define AUX778076_SEQUENCE_TEMPLATE_PARAM BOOST_MPL_AUX_NTTP_DECL(long, C) # define AUX778076_SEQUENCE_DEFAULT LONG_MAX # define AUX778076_SEQUENCE_PARAMS() \ typename T, BOOST_PP_ENUM_PARAMS( \ AUX778076_SEQUENCE_LIMIT \ , AUX778076_SEQUENCE_TEMPLATE_PARAM \ ) \ /**/ # define AUX778076_SEQUENCE_ARGS() \ T, BOOST_PP_ENUM_PARAMS( \ AUX778076_SEQUENCE_LIMIT \ , C \ ) \ /**/ # define AUX778076_SEQUENCE_DEFAULT_PARAMS() \ typename T, \ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ AUX778076_SEQUENCE_LIMIT \ , AUX778076_SEQUENCE_TEMPLATE_PARAM \ , AUX778076_SEQUENCE_DEFAULT \ ) \ /**/ # define AUX778076_SEQUENCE_N_PARAMS(n) \ typename T BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM_PARAMS(n, AUX778076_SEQUENCE_TEMPLATE_PARAM) \ /**/ # if !defined(AUX778076_SEQUENCE_CONVERT_CN_TO) # define AUX778076_SEQUENCE_CONVERT_CN_TO(z,n,TARGET) BOOST_PP_CAT(C,n) # endif # define AUX778076_SEQUENCE_N_ARGS(n) \ T BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM(n,AUX778076_SEQUENCE_CONVERT_CN_TO,T) \ /**/ # define AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS(n) \ T, BOOST_PP_ENUM_PARAMS(n, C) \ BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM( \ BOOST_PP_SUB_D(1,AUX778076_SEQUENCE_LIMIT,n) \ , BOOST_PP_TUPLE_ELEM_3_2 \ , AUX778076_SEQUENCE_DEFAULT \ ) \ /**/ #endif // AUX778076_SEQUENCE_INTEGRAL_WRAPPER #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) // forward declaration template< AUX778076_SEQUENCE_DEFAULT_PARAMS() > struct AUX778076_SEQUENCE_NAME; #else namespace aux { template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_chooser); } #endif #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, AUX778076_SEQUENCE_LIMIT, )) #include BOOST_PP_ITERATE() // real C++ version is already taken care of #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace aux { // ???_count_args #define AUX778076_COUNT_ARGS_PREFIX AUX778076_SEQUENCE_NAME #define AUX778076_COUNT_ARGS_DEFAULT AUX778076_SEQUENCE_DEFAULT #define AUX778076_COUNT_ARGS_PARAM_NAME AUX778076_SEQUENCE_PARAM_NAME #define AUX778076_COUNT_ARGS_TEMPLATE_PARAM AUX778076_SEQUENCE_TEMPLATE_PARAM #define AUX778076_COUNT_ARGS_ARITY AUX778076_SEQUENCE_LIMIT #define AUX778076_COUNT_ARGS_USE_STANDARD_PP_PRIMITIVES #include template< AUX778076_SEQUENCE_PARAMS() > struct BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_impl) { typedef aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_count_args)< BOOST_PP_ENUM_PARAMS(AUX778076_SEQUENCE_LIMIT, AUX778076_SEQUENCE_PARAM_NAME) > arg_num_; typedef typename aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_chooser)< arg_num_::value > ::template result_< AUX778076_SEQUENCE_ARGS() >::type type; }; } // namespace aux template< AUX778076_SEQUENCE_DEFAULT_PARAMS() > struct AUX778076_SEQUENCE_NAME : aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_impl)< AUX778076_SEQUENCE_ARGS() >::type { typedef typename aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_impl)< AUX778076_SEQUENCE_ARGS() >::type type; }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # undef AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS # undef AUX778076_SEQUENCE_N_ARGS # undef AUX778076_SEQUENCE_CONVERT_CN_TO # undef AUX778076_SEQUENCE_N_PARAMS # undef AUX778076_SEQUENCE_DEFAULT_PARAMS # undef AUX778076_SEQUENCE_ARGS # undef AUX778076_SEQUENCE_PARAMS # undef AUX778076_SEQUENCE_NAME_N # undef AUX778076_SEQUENCE_DEFAULT # undef AUX778076_SEQUENCE_TEMPLATE_PARAM # undef AUX778076_SEQUENCE_PARAM_NAME # undef AUX778076_SEQUENCE_LIMIT # undef AUX778076_SEQUENCE_BASE_NAME # undef AUX778076_SEQUENCE_NAME # undef AUX778076_SEQUENCE_INTEGRAL_WRAPPER }} ///// iteration #else #define i_ BOOST_PP_FRAME_ITERATION(1) # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) #if i_ == AUX778076_SEQUENCE_LIMIT /// primary template (not a specialization!) template< AUX778076_SEQUENCE_N_PARAMS(i_) > struct AUX778076_SEQUENCE_NAME : AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) > { typedef typename AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; }; #else template< AUX778076_SEQUENCE_N_PARAMS(i_) > struct AUX778076_SEQUENCE_NAME< AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS(i_) > : AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) > { #if i_ > 0 || defined(AUX778076_SEQUENCE_INTEGRAL_WRAPPER) typedef typename AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; #else typedef AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; #endif }; #endif // i_ == AUX778076_SEQUENCE_LIMIT # else namespace aux { template<> struct BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_chooser) { template< AUX778076_SEQUENCE_PARAMS() > struct result_ { #if i_ > 0 || defined(AUX778076_SEQUENCE_INTEGRAL_WRAPPER) typedef typename AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; #else typedef AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; #endif }; }; } // namespace aux # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/static_cast.hpp ================================================ #ifndef BOOST_MPL_AUX_STATIC_CAST_HPP_INCLUDED #define BOOST_MPL_AUX_STATIC_CAST_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \ || BOOST_WORKAROUND(__GNUC__, < 3) \ || BOOST_WORKAROUND(__MWERKS__, <= 0x3001) # define BOOST_MPL_AUX_STATIC_CAST(T, expr) (T)(expr) #else # define BOOST_MPL_AUX_STATIC_CAST(T, expr) static_cast(expr) #endif #endif // BOOST_MPL_AUX_STATIC_CAST_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/template_arity.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED #define BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) # include # endif # else # include # endif #endif #include #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER template_arity.hpp # include #else # if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) # include # include # include # include # include # include # include # include # include # include # define AUX778076_ARITY BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY) namespace boost { namespace mpl { namespace aux { template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct arity_tag { typedef char (&type)[N + 1]; }; # define AUX778076_MAX_ARITY_OP(unused, state, i_) \ ( BOOST_PP_CAT(C,i_) > 0 ? BOOST_PP_CAT(C,i_) : state ) \ /**/ template< BOOST_MPL_PP_PARAMS(AUX778076_ARITY, BOOST_MPL_AUX_NTTP_DECL(int, C)) > struct max_arity { BOOST_STATIC_CONSTANT(int, value = BOOST_PP_SEQ_FOLD_LEFT( AUX778076_MAX_ARITY_OP , -1 , BOOST_MPL_PP_RANGE(1, AUX778076_ARITY) ) ); }; # undef AUX778076_MAX_ARITY_OP arity_tag<0>::type arity_helper(...); # define BOOST_PP_ITERATION_LIMITS (1, AUX778076_ARITY) # define BOOST_PP_FILENAME_1 # include BOOST_PP_ITERATE() template< typename F, BOOST_MPL_AUX_NTTP_DECL(int, N) > struct template_arity_impl { BOOST_STATIC_CONSTANT(int, value = sizeof(::boost::mpl::aux::arity_helper(type_wrapper(),arity_tag())) - 1 ); }; # define AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION(unused, i_, F) \ BOOST_PP_COMMA_IF(i_) template_arity_impl::value \ /**/ template< typename F > struct template_arity { BOOST_STATIC_CONSTANT(int, value = ( max_arity< BOOST_MPL_PP_REPEAT( AUX778076_ARITY , AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION , F ) >::value )); typedef mpl::int_ type; }; # undef AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION # undef AUX778076_ARITY }}} # endif // BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING # else // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT # include namespace boost { namespace mpl { namespace aux { template< bool > struct template_arity_impl { template< typename F > struct result_ : mpl::int_<-1> { }; }; template<> struct template_arity_impl { template< typename F > struct result_ : F::arity { }; }; template< typename F > struct template_arity : template_arity_impl< ::boost::mpl::aux::has_rebind::value > ::template result_ { }; #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) template<> struct template_arity : mpl::int_<-1> { }; #endif }}} # endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED ///// iteration #else #define i_ BOOST_PP_FRAME_ITERATION(1) template< template< BOOST_MPL_PP_PARAMS(i_, typename P) > class F , BOOST_MPL_PP_PARAMS(i_, typename T) > typename arity_tag::type arity_helper(type_wrapper< F >, arity_tag); #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/template_arity_fwd.hpp ================================================ #ifndef BOOST_MPL_AUX_TEMPLATE_ARITY_FWD_HPP_INCLUDED #define BOOST_MPL_AUX_TEMPLATE_ARITY_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { namespace aux { template< typename F > struct template_arity; }}} #endif // BOOST_MPL_AUX_TEMPLATE_ARITY_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/traits_lambda_spec.hpp ================================================ #ifndef BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED #define BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) /**/ #elif !defined(BOOST_MPL_CFG_MSVC_ETI_BUG) # define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \ template<> struct trait \ { \ template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \ { \ }; \ }; \ /**/ #else # define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \ template<> struct trait \ { \ template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \ { \ }; \ }; \ template<> struct trait \ { \ template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \ { \ typedef int type; \ }; \ }; \ /**/ #endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT #define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(i, trait) \ BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \ template<> struct trait {}; \ /**/ #endif // BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/type_wrapper.hpp ================================================ #ifndef BOOST_MPL_AUX_TYPE_WRAPPER_HPP_INCLUDED #define BOOST_MPL_AUX_TYPE_WRAPPER_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // Copyright Peter Dimov 2000-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include namespace boost { namespace mpl { namespace aux { template< typename T > struct type_wrapper { typedef T type; }; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) // agurt 08/may/03: a complicated way to extract the wrapped type; need it // mostly for the sake of GCC (3.2.x), which ICEs if you try to extract the // nested 'type' from 'type_wrapper' when the latter was the result of a // 'typeof' expression template< typename T > struct wrapped_type; template< typename T > struct wrapped_type< type_wrapper > { typedef T type; }; #else template< typename W > struct wrapped_type { typedef typename W::type type; }; #endif }}} #endif // BOOST_MPL_AUX_TYPE_WRAPPER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/value_wknd.hpp ================================================ #ifndef BOOST_MPL_AUX_VALUE_WKND_HPP_INCLUDED #define BOOST_MPL_AUX_VALUE_WKND_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #if defined(BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS) \ || defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) # include namespace boost { namespace mpl { namespace aux { template< typename C_ > struct value_wknd : C_ { }; #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) template<> struct value_wknd : int_<1> { using int_<1>::value; }; #endif }}} #if !defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) # define BOOST_MPL_AUX_VALUE_WKND(C) \ ::BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::aux::value_wknd< C > \ /**/ # define BOOST_MPL_AUX_MSVC_VALUE_WKND(C) BOOST_MPL_AUX_VALUE_WKND(C) #else # define BOOST_MPL_AUX_VALUE_WKND(C) C # define BOOST_MPL_AUX_MSVC_VALUE_WKND(C) \ ::boost::mpl::aux::value_wknd< C > \ /**/ #endif #else // BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS # define BOOST_MPL_AUX_VALUE_WKND(C) C # define BOOST_MPL_AUX_MSVC_VALUE_WKND(C) C #endif #if BOOST_WORKAROUND(__EDG_VERSION__, <= 238) # define BOOST_MPL_AUX_NESTED_VALUE_WKND(T, C) \ BOOST_MPL_AUX_STATIC_CAST(T, C::value) \ /**/ #else # define BOOST_MPL_AUX_NESTED_VALUE_WKND(T, C) \ BOOST_MPL_AUX_VALUE_WKND(C)::value \ /**/ #endif namespace boost { namespace mpl { namespace aux { template< typename T > struct value_type_wknd { typedef typename T::value_type type; }; #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) template<> struct value_type_wknd { typedef int type; }; #endif }}} #endif // BOOST_MPL_AUX_VALUE_WKND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/aux_/yes_no.hpp ================================================ #ifndef BOOST_MPL_AUX_YES_NO_HPP_INCLUDED #define BOOST_MPL_AUX_YES_NO_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { namespace aux { typedef char (&no_tag)[1]; typedef char (&yes_tag)[2]; template< bool C_ > struct yes_no_tag { typedef no_tag type; }; template<> struct yes_no_tag { typedef yes_tag type; }; template< BOOST_MPL_AUX_NTTP_DECL(long, n) > struct weighted_tag { #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) typedef char (&type)[n]; #else char buf[n]; typedef weighted_tag type; #endif }; #if defined(BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES) template<> struct weighted_tag<0> { typedef char (&type)[1]; }; #endif }}} #endif // BOOST_MPL_AUX_YES_NO_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/base.hpp ================================================ #ifndef BOOST_MPL_BASE_HPP_INCLUDED #define BOOST_MPL_BASE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T) > struct base { typedef typename T::base type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,base,(T)) }; BOOST_MPL_AUX_NA_SPEC(1, base) }} #endif // BOOST_MPL_BASE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/begin.hpp ================================================ #ifndef BOOST_MPL_BEGIN_HPP_INCLUDED #define BOOST_MPL_BEGIN_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #endif // BOOST_MPL_BEGIN_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/begin_end.hpp ================================================ #ifndef BOOST_MPL_BEGIN_END_HPP_INCLUDED #define BOOST_MPL_BEGIN_END_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { // agurt, 13/sep/02: switched from inheritance to typedef; MSVC is more // happy this way (less ETI-related errors), and it doesn't affect // anything else template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct begin { typedef typename sequence_tag::type tag_; typedef typename begin_impl< tag_ > ::template apply< Sequence >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,begin,(Sequence)) }; template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct end { typedef typename sequence_tag::type tag_; typedef typename end_impl< tag_ > ::template apply< Sequence >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,end,(Sequence)) }; BOOST_MPL_AUX_NA_SPEC(1, begin) BOOST_MPL_AUX_NA_SPEC(1, end) }} #endif // BOOST_MPL_BEGIN_END_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/begin_end_fwd.hpp ================================================ #ifndef BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED #define BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct begin_impl; template< typename Tag > struct end_impl; template< typename Sequence > struct begin; template< typename Sequence > struct end; }} #endif // BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/bind.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_BIND_HPP_INCLUDED #define BOOST_MPL_BIND_HPP_INCLUDED // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include # include # include # include # include # include # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) # include # endif #endif #include #include #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # if defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT) # define BOOST_MPL_PREPROCESSED_HEADER basic_bind.hpp # else # define BOOST_MPL_PREPROCESSED_HEADER bind.hpp # endif # include #else # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include namespace boost { namespace mpl { // local macros, #undef-ined at the end of the header # define AUX778076_APPLY \ BOOST_PP_CAT(apply_wrap,BOOST_MPL_LIMIT_METAFUNCTION_ARITY) \ /**/ # if defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS) # define AUX778076_DMC_PARAM() , int dummy_ # else # define AUX778076_DMC_PARAM() # endif # define AUX778076_BIND_PARAMS(param) \ BOOST_MPL_PP_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ ) \ /**/ # define AUX778076_BIND_DEFAULT_PARAMS(param, value) \ BOOST_MPL_PP_DEFAULT_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ , value \ ) \ /**/ # define AUX778076_BIND_N_PARAMS(n, param) \ BOOST_PP_COMMA_IF(n) BOOST_MPL_PP_PARAMS(n, param) \ /**/ # define AUX778076_BIND_N_SPEC_PARAMS(n, param, def) \ BOOST_PP_COMMA_IF(n) \ BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(n, param, def) \ /**/ #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) # define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \ AUX778076_BIND_DEFAULT_PARAMS(param, value) \ /**/ #else # define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \ AUX778076_BIND_PARAMS(param) \ /**/ #endif namespace aux { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename T, AUX778076_BIND_PARAMS(typename U) > struct resolve_bind_arg { typedef T type; }; # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT) template< typename T , typename Arg > struct replace_unnamed_arg { typedef Arg next; typedef T type; }; template< typename Arg > struct replace_unnamed_arg< arg<-1>,Arg > { typedef typename Arg::next next; typedef Arg type; }; # endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT template< BOOST_MPL_AUX_NTTP_DECL(int, N), AUX778076_BIND_PARAMS(typename U) > struct resolve_bind_arg< arg,AUX778076_BIND_PARAMS(U) > { typedef typename AUX778076_APPLY, AUX778076_BIND_PARAMS(U)>::type type; }; #if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE) template< typename F, AUX778076_BIND_PARAMS(typename T), AUX778076_BIND_PARAMS(typename U) > struct resolve_bind_arg< bind,AUX778076_BIND_PARAMS(U) > { typedef bind f_; typedef typename AUX778076_APPLY::type type; }; #endif #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // agurt, 15/jan/02: it's not a intended to be used as a function class, and // MSVC6.5 has problems with 'apply' name here (the code compiles, but doesn't // work), so I went with the 'result_' here, and in all other similar cases template< bool > struct resolve_arg_impl { template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_ { typedef T type; }; }; template<> struct resolve_arg_impl { template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_ { typedef typename AUX778076_APPLY< T , AUX778076_BIND_PARAMS(U) >::type type; }; }; // for 'resolve_bind_arg' template< typename T > struct is_bind_template; template< typename T, AUX778076_BIND_PARAMS(typename U) > struct resolve_bind_arg : resolve_arg_impl< is_bind_template::value > ::template result_< T,AUX778076_BIND_PARAMS(U) > { }; # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT) template< typename T > struct replace_unnamed_arg_impl { template< typename Arg > struct result_ { typedef Arg next; typedef T type; }; }; template<> struct replace_unnamed_arg_impl< arg<-1> > { template< typename Arg > struct result_ { typedef typename next::type next; typedef Arg type; }; }; template< typename T, typename Arg > struct replace_unnamed_arg : replace_unnamed_arg_impl::template result_ { }; # endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT // agurt, 10/mar/02: the forward declaration has to appear before any of // 'is_bind_helper' overloads, otherwise MSVC6.5 issues an ICE on it template< BOOST_MPL_AUX_NTTP_DECL(int, arity_) > struct bind_chooser; aux::no_tag is_bind_helper(...); template< typename T > aux::no_tag is_bind_helper(protect*); // overload for "main" form // agurt, 15/mar/02: MSVC 6.5 fails to properly resolve the overload // in case if we use 'aux::type_wrapper< bind<...> >' here, and all // 'bind' instantiations form a complete type anyway #if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE) template< typename F, AUX778076_BIND_PARAMS(typename T) > aux::yes_tag is_bind_helper(bind*); #endif template< BOOST_MPL_AUX_NTTP_DECL(int, N) > aux::yes_tag is_bind_helper(arg*); template< bool is_ref_ = true > struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template<> struct is_bind_template_impl { template< typename T > struct result_ { BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_bind_helper(static_cast(0))) == sizeof(aux::yes_tag) ); }; }; template< typename T > struct is_bind_template : is_bind_template_impl< ::boost::detail::is_reference_impl::value > ::template result_ { }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION } // namespace aux #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) /// if_/eval_if specializations # define AUX778076_SPEC_NAME if_ # define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, )) # include BOOST_PP_ITERATE() #if !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS) # define AUX778076_SPEC_NAME eval_if # define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, )) # include BOOST_PP_ITERATE() #endif #endif // real C++ version is already taken care of #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE) namespace aux { // apply_count_args #define AUX778076_COUNT_ARGS_PREFIX bind #define AUX778076_COUNT_ARGS_DEFAULT na #define AUX778076_COUNT_ARGS_ARITY BOOST_MPL_LIMIT_METAFUNCTION_ARITY #include } // bind template< typename F, AUX778076_BIND_PARAMS(typename T) AUX778076_DMC_PARAM() > struct bind : aux::bind_chooser< aux::bind_count_args::value >::template result_< F,AUX778076_BIND_PARAMS(T) >::type { }; BOOST_MPL_AUX_ARITY_SPEC( BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY) , bind ) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC( BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY) , bind ) #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # undef AUX778076_BIND_NESTED_DEFAULT_PARAMS # undef AUX778076_BIND_N_SPEC_PARAMS # undef AUX778076_BIND_N_PARAMS # undef AUX778076_BIND_DEFAULT_PARAMS # undef AUX778076_BIND_PARAMS # undef AUX778076_DMC_PARAM # undef AUX778076_APPLY }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_BIND_HPP_INCLUDED ///// iteration, depth == 1 // For gcc 4.4 compatability, we must include the // BOOST_PP_ITERATION_DEPTH test inside an #else clause. #else // BOOST_PP_IS_ITERATING #if BOOST_PP_ITERATION_DEPTH() == 1 # define i_ BOOST_PP_FRAME_ITERATION(1) #if defined(AUX778076_SPEC_NAME) // lazy metafunction specialization template< template< BOOST_MPL_PP_PARAMS(i_, typename T) > class F, typename Tag > struct BOOST_PP_CAT(quote,i_); template< BOOST_MPL_PP_PARAMS(i_, typename T) > struct AUX778076_SPEC_NAME; template< typename Tag AUX778076_BIND_N_PARAMS(i_, typename T) > struct BOOST_PP_CAT(bind,i_)< BOOST_PP_CAT(quote,i_) AUX778076_BIND_N_PARAMS(i_,T) > { template< AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na) > struct apply { private: typedef mpl::arg<1> n1; # define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, )) # include BOOST_PP_ITERATE() typedef typename AUX778076_SPEC_NAME< typename t1::type , BOOST_MPL_PP_EXT_PARAMS(2, BOOST_PP_INC(i_), t) >::type f_; public: typedef typename f_::type type; }; }; #undef AUX778076_SPEC_NAME #else // AUX778076_SPEC_NAME template< typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM() > struct BOOST_PP_CAT(bind,i_) { template< AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na) > struct apply { private: # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT) typedef aux::replace_unnamed_arg< F,mpl::arg<1> > r0; typedef typename r0::type a0; typedef typename r0::next n1; typedef typename aux::resolve_bind_arg::type f_; /// # else typedef typename aux::resolve_bind_arg::type f_; # endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT # if i_ > 0 # define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, )) # include BOOST_PP_ITERATE() # endif public: # define AUX778076_ARG(unused, i_, t) \ BOOST_PP_COMMA_IF(i_) \ typename BOOST_PP_CAT(t,BOOST_PP_INC(i_))::type \ /**/ typedef typename BOOST_PP_CAT(apply_wrap,i_)< f_ BOOST_PP_COMMA_IF(i_) BOOST_MPL_PP_REPEAT(i_, AUX778076_ARG, t) >::type type; # undef AUX778076_ARG }; }; namespace aux { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename F AUX778076_BIND_N_PARAMS(i_, typename T), AUX778076_BIND_PARAMS(typename U) > struct resolve_bind_arg< BOOST_PP_CAT(bind,i_),AUX778076_BIND_PARAMS(U) > { typedef BOOST_PP_CAT(bind,i_) f_; typedef typename AUX778076_APPLY::type type; }; #else template< typename F AUX778076_BIND_N_PARAMS(i_, typename T) > aux::yes_tag is_bind_helper(BOOST_PP_CAT(bind,i_)*); #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION } // namespace aux BOOST_MPL_AUX_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_)) BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_)) # if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE) # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) #if i_ == BOOST_MPL_LIMIT_METAFUNCTION_ARITY /// primary template (not a specialization!) template< typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM() > struct bind : BOOST_PP_CAT(bind,i_) { }; #else template< typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM() > struct bind< F AUX778076_BIND_N_SPEC_PARAMS(i_, T, na) > : BOOST_PP_CAT(bind,i_) { }; #endif # else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION namespace aux { template<> struct bind_chooser { template< typename F, AUX778076_BIND_PARAMS(typename T) > struct result_ { typedef BOOST_PP_CAT(bind,i_)< F AUX778076_BIND_N_PARAMS(i_,T) > type; }; }; } // namespace aux # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # endif // BOOST_MPL_CFG_NO_BIND_TEMPLATE #endif // AUX778076_SPEC_NAME # undef i_ ///// iteration, depth == 2 #elif BOOST_PP_ITERATION_DEPTH() == 2 # define j_ BOOST_PP_FRAME_ITERATION(2) # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT) typedef aux::replace_unnamed_arg< BOOST_PP_CAT(T,j_),BOOST_PP_CAT(n,j_) > BOOST_PP_CAT(r,j_); typedef typename BOOST_PP_CAT(r,j_)::type BOOST_PP_CAT(a,j_); typedef typename BOOST_PP_CAT(r,j_)::next BOOST_PP_CAT(n,BOOST_PP_INC(j_)); typedef aux::resolve_bind_arg BOOST_PP_CAT(t,j_); /// # else typedef aux::resolve_bind_arg< BOOST_PP_CAT(T,j_),AUX778076_BIND_PARAMS(U)> BOOST_PP_CAT(t,j_); # endif # undef j_ #endif // BOOST_PP_ITERATION_DEPTH() #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/bind_fwd.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_BIND_FWD_HPP_INCLUDED #define BOOST_MPL_BIND_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER bind_fwd.hpp # include #else # include # include # include # include # include # include # include namespace boost { namespace mpl { // local macros, #undef-ined at the end of the header # if defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS) # define AUX778076_DMC_PARAM() , int dummy_ = 0 # else # define AUX778076_DMC_PARAM() # endif # define AUX778076_BIND_DEFAULT_PARAMS(param, value) \ BOOST_MPL_PP_DEFAULT_PARAMS( \ BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ , param \ , value \ ) \ AUX778076_DMC_PARAM() \ /**/ # define AUX778076_BIND_N_PARAMS(n, param) \ BOOST_PP_COMMA_IF(n) BOOST_MPL_PP_PARAMS(n, param) \ AUX778076_DMC_PARAM() \ /**/ #if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE) template< typename F, AUX778076_BIND_DEFAULT_PARAMS(typename T, na) > struct bind; #endif #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() # undef AUX778076_BIND_N_PARAMS # undef AUX778076_BIND_DEFAULT_PARAMS # undef AUX778076_DMC_PARAM }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_BIND_FWD_HPP_INCLUDED ///// iteration #else #define i_ BOOST_PP_FRAME_ITERATION(1) template< typename F AUX778076_BIND_N_PARAMS(i_, typename T) > struct BOOST_PP_CAT(bind,i_); #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/bool.hpp ================================================ #ifndef BOOST_MPL_BOOL_HPP_INCLUDED #define BOOST_MPL_BOOL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template< bool C_ > struct bool_ { BOOST_STATIC_CONSTANT(bool, value = C_); typedef integral_c_tag tag; typedef bool_ type; typedef bool value_type; BOOST_CONSTEXPR operator bool() const { return this->value; } }; #if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) template< bool C_ > bool const bool_::value; #endif BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE #endif // BOOST_MPL_BOOL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/bool_fwd.hpp ================================================ #ifndef BOOST_MPL_BOOL_FWD_HPP_INCLUDED #define BOOST_MPL_BOOL_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template< bool C_ > struct bool_; // shorcuts typedef bool_ true_; typedef bool_ false_; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(bool_) BOOST_MPL_AUX_ADL_BARRIER_DECL(true_) BOOST_MPL_AUX_ADL_BARRIER_DECL(false_) #endif // BOOST_MPL_BOOL_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/clear.hpp ================================================ #ifndef BOOST_MPL_CLEAR_HPP_INCLUDED #define BOOST_MPL_CLEAR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct clear : clear_impl< typename sequence_tag::type > ::template apply< Sequence > { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,clear,(Sequence)) }; BOOST_MPL_AUX_NA_SPEC(1, clear) }} #endif // BOOST_MPL_CLEAR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/clear_fwd.hpp ================================================ #ifndef BOOST_MPL_CLEAR_FWD_HPP_INCLUDED #define BOOST_MPL_CLEAR_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct clear_impl; template< typename Sequence > struct clear; }} #endif // BOOST_MPL_CLEAR_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/deref.hpp ================================================ #ifndef BOOST_MPL_DEREF_HPP_INCLUDED #define BOOST_MPL_DEREF_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(Iterator) > struct deref { #if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) typedef typename Iterator::type type; #else typedef typename aux::msvc_type::type type; #endif BOOST_MPL_AUX_LAMBDA_SUPPORT(1,deref,(Iterator)) }; BOOST_MPL_AUX_NA_SPEC(1, deref) }} #endif // BOOST_MPL_DEREF_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/empty_fwd.hpp ================================================ #ifndef BOOST_MPL_EMPTY_FWD_HPP_INCLUDED #define BOOST_MPL_EMPTY_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct empty_impl; template< typename Sequence > struct empty; }} #endif // BOOST_MPL_EMPTY_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/end.hpp ================================================ #ifndef BOOST_MPL_END_HPP_INCLUDED #define BOOST_MPL_END_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #endif // BOOST_MPL_END_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/erase_fwd.hpp ================================================ #ifndef BOOST_MPL_ERASE_FWD_HPP_INCLUDED #define BOOST_MPL_ERASE_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct erase_impl; template< typename Sequence, typename First, typename Last > struct erase; }} #endif // BOOST_MPL_ERASE_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/erase_key_fwd.hpp ================================================ #ifndef BOOST_MPL_ERASE_KEY_FWD_HPP_INCLUDED #define BOOST_MPL_ERASE_KEY_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct erase_key_impl; template< typename Sequence, typename Key > struct erase_key; }} #endif // BOOST_MPL_ERASE_KEY_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/eval_if.hpp ================================================ #ifndef BOOST_MPL_EVAL_IF_HPP_INCLUDED #define BOOST_MPL_EVAL_IF_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(C) , typename BOOST_MPL_AUX_NA_PARAM(F1) , typename BOOST_MPL_AUX_NA_PARAM(F2) > struct eval_if #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || ( BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, >= 0x0300) \ && BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304)) \ ) { typedef typename if_::type f_; typedef typename f_::type type; #else : if_::type { #endif BOOST_MPL_AUX_LAMBDA_SUPPORT(3,eval_if,(C,F1,F2)) }; // (almost) copy & paste in order to save one more // recursively nested template instantiation to user template< bool C , typename F1 , typename F2 > struct eval_if_c #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || ( BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, >= 0x0300) \ && BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304)) \ ) { typedef typename if_c::type f_; typedef typename f_::type type; #else : if_c::type { #endif }; BOOST_MPL_AUX_NA_SPEC(3, eval_if) }} #endif // BOOST_MPL_EVAL_IF_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/find.hpp ================================================ #ifndef BOOST_MPL_FIND_HPP_INCLUDED #define BOOST_MPL_FIND_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(T) > struct find : find_if< Sequence,same_as > { BOOST_MPL_AUX_LAMBDA_SUPPORT(2,find,(Sequence,T)) }; BOOST_MPL_AUX_NA_SPEC(2, find) }} #endif // BOOST_MPL_FIND_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/find_if.hpp ================================================ #ifndef BOOST_MPL_FIND_IF_HPP_INCLUDED #define BOOST_MPL_FIND_IF_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include namespace boost { namespace mpl { BOOST_MPL_AUX_COMMON_NAME_WKND(find_if) template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(Predicate) > struct find_if { typedef typename iter_fold_if< Sequence , void , mpl::arg<1> // ignore , protect< aux::find_if_pred > >::type result_; typedef typename second::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2,find_if,(Sequence,Predicate)) }; BOOST_MPL_AUX_NA_SPEC(2,find_if) }} #endif // BOOST_MPL_FIND_IF_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/fold.hpp ================================================ #ifndef BOOST_MPL_FOLD_HPP_INCLUDED #define BOOST_MPL_FOLD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(State) , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp) > struct fold { typedef typename aux::fold_impl< ::boost::mpl::O1_size::value , typename begin::type , typename end::type , State , ForwardOp >::state type; BOOST_MPL_AUX_LAMBDA_SUPPORT(3,fold,(Sequence,State,ForwardOp)) }; BOOST_MPL_AUX_NA_SPEC(3, fold) }} #endif // BOOST_MPL_FOLD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/front_fwd.hpp ================================================ #ifndef BOOST_MPL_FRONT_FWD_HPP_INCLUDED #define BOOST_MPL_FRONT_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct front_impl; template< typename Sequence > struct front; }} #endif // BOOST_MPL_FRONT_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/has_key.hpp ================================================ #ifndef BOOST_MPL_HAS_KEY_HPP_INCLUDED #define BOOST_MPL_HAS_KEY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(AssociativeSequence) , typename BOOST_MPL_AUX_NA_PARAM(Key) > struct has_key : has_key_impl< typename sequence_tag::type > ::template apply { BOOST_MPL_AUX_LAMBDA_SUPPORT(2,has_key,(AssociativeSequence,Key)) }; BOOST_MPL_AUX_NA_SPEC(2, has_key) }} #endif // BOOST_MPL_HAS_KEY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/has_key_fwd.hpp ================================================ #ifndef BOOST_MPL_HAS_KEY_FWD_HPP_INCLUDED #define BOOST_MPL_HAS_KEY_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct has_key_impl; template< typename AssociativeSequence, typename Key > struct has_key; }} #endif // BOOST_MPL_HAS_KEY_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/has_xxx.hpp ================================================ #ifndef BOOST_MPL_HAS_XXX_HPP_INCLUDED #define BOOST_MPL_HAS_XXX_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2002-2006 // Copyright David Abrahams 2002-2003 // Copyright Daniel Walker 2007 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) ) # include #endif #if !defined(BOOST_MPL_CFG_NO_HAS_XXX) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // agurt, 11/sep/02: MSVC-specific version (< 7.1), based on a USENET // newsgroup's posting by John Madsen (comp.lang.c++.moderated, // 1999-11-12 19:17:06 GMT); the code is _not_ standard-conforming, but // it works way more reliably than the SFINAE-based implementation // Modified dwa 8/Oct/02 to handle reference types. # include # include namespace boost { namespace mpl { namespace aux { struct has_xxx_tag; #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) template< typename U > struct msvc_incomplete_array { typedef char (&type)[sizeof(U) + 1]; }; #endif template< typename T > struct msvc_is_incomplete { // MSVC is capable of some kinds of SFINAE. If U is an incomplete // type, it won't pick the second overload static char tester(...); #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) template< typename U > static typename msvc_incomplete_array::type tester(type_wrapper); #else template< typename U > static char (& tester(type_wrapper) )[sizeof(U)+1]; #endif BOOST_STATIC_CONSTANT(bool, value = sizeof(tester(type_wrapper())) == 1 ); }; template<> struct msvc_is_incomplete { BOOST_STATIC_CONSTANT(bool, value = false); }; }}} # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, default_) \ template< typename T, typename name = ::boost::mpl::aux::has_xxx_tag > \ struct BOOST_PP_CAT(trait,_impl) : T \ { \ static boost::mpl::aux::no_tag \ test(void(*)(::boost::mpl::aux::has_xxx_tag)); \ \ static boost::mpl::aux::yes_tag test(...); \ \ BOOST_STATIC_CONSTANT(bool, value = \ sizeof(test(static_cast(0))) \ != sizeof(boost::mpl::aux::no_tag) \ ); \ typedef boost::mpl::bool_ type; \ }; \ \ template< typename T, typename fallback_ = boost::mpl::bool_ > \ struct trait \ : boost::mpl::if_c< \ boost::mpl::aux::msvc_is_incomplete::value \ , boost::mpl::bool_ \ , BOOST_PP_CAT(trait,_impl) \ >::type \ { \ }; \ \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, void) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, bool) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, char) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed char) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned char) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed short) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned short) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed int) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned int) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed long) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned long) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, float) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, double) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, long double) \ /**/ # define BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, T) \ template<> struct trait \ { \ BOOST_STATIC_CONSTANT(bool, value = false); \ typedef boost::mpl::bool_ type; \ }; \ /**/ #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \ BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, wchar_t) \ /**/ #else # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \ /**/ #endif // SFINAE-based implementations below are derived from a USENET newsgroup's // posting by Rani Sharoni (comp.lang.c++.moderated, 2002-03-17 07:45:09 PST) # elif BOOST_WORKAROUND(BOOST_MSVC, <= 1400) \ || (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) && defined(__CUDACC__)) \ || BOOST_WORKAROUND(__IBMCPP__, <= 700) // MSVC 7.1 & MSVC 8.0 & VACPP // agurt, 15/jun/05: replace overload-based SFINAE implementation with SFINAE // applied to partial specialization to fix some apparently random failures // (thanks to Daniel Wallin for researching this!) # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ template< typename T > \ struct BOOST_PP_CAT(trait, _msvc_sfinae_helper) \ { \ typedef void type; \ };\ \ template< typename T, typename U = void > \ struct BOOST_PP_CAT(trait,_impl_) \ { \ BOOST_STATIC_CONSTANT(bool, value = false); \ typedef boost::mpl::bool_ type; \ }; \ \ template< typename T > \ struct BOOST_PP_CAT(trait,_impl_)< \ T \ , typename BOOST_PP_CAT(trait, _msvc_sfinae_helper)< typename T::name >::type \ > \ { \ BOOST_STATIC_CONSTANT(bool, value = true); \ typedef boost::mpl::bool_ type; \ }; \ \ template< typename T, typename fallback_ = boost::mpl::bool_ > \ struct trait \ : BOOST_PP_CAT(trait,_impl_) \ { \ }; \ /**/ # elif BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) ) # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF(trait, trait_tester, name, default_) \ template< typename T, bool IS_CLASS > \ struct trait_tester \ { \ BOOST_STATIC_CONSTANT( bool, value = false ); \ }; \ template< typename T > \ struct trait_tester< T, true > \ { \ struct trait_tester_impl \ { \ template < class U > \ static int resolve( boost::mpl::aux::type_wrapper const volatile * \ , boost::mpl::aux::type_wrapper* = 0 ); \ static char resolve( ... ); \ }; \ typedef boost::mpl::aux::type_wrapper t_; \ BOOST_STATIC_CONSTANT( bool, value = ( sizeof( trait_tester_impl::resolve( static_cast< t_ * >(0) ) ) == sizeof(int) ) ); \ }; \ template< typename T, typename fallback_ = boost::mpl::bool_ > \ struct trait \ { \ BOOST_STATIC_CONSTANT( bool, value = (trait_tester< T, boost::is_class< T >::value >::value) ); \ typedef boost::mpl::bool_< trait< T, fallback_ >::value > type; \ }; # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF( trait \ , BOOST_PP_CAT(trait,_tester) \ , name \ , default_ ) \ /**/ # else // other SFINAE-capable compilers # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ template< typename T, typename fallback_ = boost::mpl::bool_ > \ struct trait \ { \ struct gcc_3_2_wknd \ { \ template< typename U > \ static boost::mpl::aux::yes_tag test( \ boost::mpl::aux::type_wrapper const volatile* \ , boost::mpl::aux::type_wrapper* = 0 \ ); \ \ static boost::mpl::aux::no_tag test(...); \ }; \ \ typedef boost::mpl::aux::type_wrapper t_; \ BOOST_STATIC_CONSTANT(bool, value = \ sizeof(gcc_3_2_wknd::test(static_cast(0))) \ == sizeof(boost::mpl::aux::yes_tag) \ ); \ typedef boost::mpl::bool_ type; \ }; \ /**/ # endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1300) #else // BOOST_MPL_CFG_NO_HAS_XXX // placeholder implementation # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ template< typename T, typename fallback_ = boost::mpl::bool_ > \ struct trait \ { \ BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ typedef fallback_ type; \ }; \ /**/ #endif #define BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \ /**/ #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) // Create a boolean Metafunction to detect a nested template // member. This implementation is based on a USENET newsgroup's // posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19), // Rani Sharoni's USENET posting cited above, the non-template has_xxx // implementations above, and discussion on the Boost mailing list. # if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) # define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1 # else # define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 0 # endif # endif # if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) # if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)) # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1 # else # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 0 # endif # endif # if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1 # else # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 0 # endif # endif // NOTE: Many internal implementation macros take a Boost.Preprocessor // array argument called args which is of the following form. // ( 4, ( trait, name, max_arity, default_ ) ) # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \ /**/ # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \ /**/ # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \ BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \ /**/ // Thanks to Guillaume Melquiond for pointing out the need for the // "substitute" template as an argument to the overloaded test // functions to get SFINAE to work for member templates with the // correct name but different number of arguments. # define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \ template< \ template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename V) > class V \ > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \ }; \ /**/ # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ BOOST_PP_REPEAT( \ BOOST_PP_ARRAY_ELEM(2, args) \ , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \ , args \ ) \ /**/ # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ template< typename V > \ static boost::mpl::aux::no_tag \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ /**/ # else # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ static boost::mpl::aux::no_tag \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ /**/ # endif # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES # define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \ template< typename V > \ static boost::mpl::aux::yes_tag \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ boost::mpl::aux::type_wrapper< V > const volatile* \ , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \ V::template BOOST_PP_ARRAY_ELEM(1, args) \ >* = 0 \ ); \ /**/ # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ BOOST_PP_REPEAT( \ BOOST_PP_ARRAY_ELEM(2, args) \ , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \ , args \ ) \ /**/ # else # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ template< typename V > \ static boost::mpl::aux::yes_tag \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ V const volatile* \ , member_macro(args, V, T)* = 0 \ ); \ /**/ # endif # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION # define BOOST_MPL_HAS_MEMBER_TEST(args) \ sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \ == sizeof(boost::mpl::aux::yes_tag) \ /**/ # else # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES # define BOOST_MPL_HAS_MEMBER_TEST(args) \ sizeof( \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \ ) \ ) == sizeof(boost::mpl::aux::yes_tag) \ /**/ # else # define BOOST_MPL_HAS_MEMBER_TEST(args) \ sizeof( \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ static_cast< U* >(0) \ ) \ ) == sizeof(boost::mpl::aux::yes_tag) \ /**/ # endif # endif # define BOOST_MPL_HAS_MEMBER_INTROSPECT( \ args, substitute_macro, member_macro \ ) \ template< typename U > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \ BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ BOOST_STATIC_CONSTANT( \ bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \ ); \ typedef boost::mpl::bool_< value > type; \ }; \ /**/ # define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ args, introspect_macro, substitute_macro, member_macro \ ) \ template< \ typename T \ , typename fallback_ \ = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \ > \ class BOOST_PP_ARRAY_ELEM(0, args) { \ introspect_macro(args, substitute_macro, member_macro) \ public: \ static const bool value \ = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \ typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \ T \ >::type type; \ }; \ /**/ // BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full // implementation of the function-based metafunction. Compile with -E // to see the preprocessor output for this macro. # define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ args, substitute_macro, member_macro \ ) \ BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ args \ , BOOST_MPL_HAS_MEMBER_INTROSPECT \ , substitute_macro \ , member_macro \ ) \ /**/ # if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE # if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) # define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1 # endif # endif # if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ args, n \ ) \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ /**/ # else # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ args, n \ ) \ BOOST_PP_CAT( \ boost_mpl_has_xxx_ \ , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ ) \ /**/ # endif # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \ args \ ) \ BOOST_PP_CAT( \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ args, 0 \ ) \ , _tag \ ) \ /**/ # define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ z, n, args \ ) \ template< \ template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename U) > class U \ > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ args, n \ ) { \ typedef \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ type; \ }; \ /**/ # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ args, substitute_macro \ ) \ typedef void \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ BOOST_PP_REPEAT( \ BOOST_PP_ARRAY_ELEM(2, args) \ , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \ , args \ ) \ /**/ # define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \ args, member_macro \ ) \ template< \ typename U \ , typename V \ = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \ BOOST_STATIC_CONSTANT(bool, value = false); \ typedef boost::mpl::bool_< value > type; \ }; \ /**/ # define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \ z, n, args \ ) \ template< typename U > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ U \ , typename \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ args, n \ )< \ BOOST_MSVC_TYPENAME U::BOOST_PP_ARRAY_ELEM(1, args)< > \ >::type \ > { \ BOOST_STATIC_CONSTANT(bool, value = true); \ typedef boost::mpl::bool_< value > type; \ }; \ /**/ # define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ args, member_macro \ ) \ BOOST_PP_REPEAT( \ BOOST_PP_ARRAY_ELEM(2, args) \ , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \ , args \ ) \ /**/ # define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ args, substitute_macro, member_macro \ ) \ BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \ BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \ template< typename U > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \ }; \ /**/ // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full // implementation of the template-based metafunction. Compile with -E // to see the preprocessor output for this macro. // // Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is // defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs // to be expanded at namespace level before // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used. # define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ args, substitute_macro, member_macro \ ) \ BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ args, substitute_macro \ ) \ BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ args \ , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \ , substitute_macro \ , member_macro \ ) \ /**/ # endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE // Note: In the current implementation the parameter and access macros // are no longer expanded. # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ ) \ /**/ # else # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ ) \ /**/ # endif #else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE // placeholder implementation # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ template< typename T \ , typename fallback_ = boost::mpl::bool_< default_ > > \ struct trait { \ BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ typedef fallback_ type; \ }; \ /**/ #endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE # define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \ BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \ BOOST_PP_CAT(has_, name), name, false \ ) \ /**/ #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/identity.hpp ================================================ #ifndef BOOST_MPL_IDENTITY_HPP_INCLUDED #define BOOST_MPL_IDENTITY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T) > struct identity { typedef T type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1, identity, (T)) }; template< typename BOOST_MPL_AUX_NA_PARAM(T) > struct make_identity { typedef identity type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1, make_identity, (T)) }; BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, identity) BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, make_identity) }} #endif // BOOST_MPL_IDENTITY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/if.hpp ================================================ #ifndef BOOST_MPL_IF_HPP_INCLUDED #define BOOST_MPL_IF_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include namespace boost { namespace mpl { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< bool C , typename T1 , typename T2 > struct if_c { typedef T1 type; }; template< typename T1 , typename T2 > struct if_c { typedef T2 type; }; // agurt, 05/sep/04: nondescriptive parameter names for the sake of DigitalMars // (and possibly MWCW < 8.0); see http://article.gmane.org/gmane.comp.lib.boost.devel/108959 template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) , typename BOOST_MPL_AUX_NA_PARAM(T3) > struct if_ { private: // agurt, 02/jan/03: two-step 'type' definition for the sake of aCC typedef if_c< #if defined(BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS) BOOST_MPL_AUX_VALUE_WKND(T1)::value #else BOOST_MPL_AUX_STATIC_CAST(bool, BOOST_MPL_AUX_VALUE_WKND(T1)::value) #endif , T2 , T3 > almost_type_; public: typedef typename almost_type_::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(3,if_,(T1,T2,T3)) }; #else // no partial class template specialization namespace aux { template< bool C > struct if_impl { template< typename T1, typename T2 > struct result_ { typedef T1 type; }; }; template<> struct if_impl { template< typename T1, typename T2 > struct result_ { typedef T2 type; }; }; } // namespace aux template< bool C_ , typename T1 , typename T2 > struct if_c { typedef typename aux::if_impl< C_ > ::template result_::type type; }; // (almost) copy & paste in order to save one more // recursively nested template instantiation to user template< typename BOOST_MPL_AUX_NA_PARAM(C_) , typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct if_ { enum { msvc_wknd_ = BOOST_MPL_AUX_MSVC_VALUE_WKND(C_)::value }; typedef typename aux::if_impl< BOOST_MPL_AUX_STATIC_CAST(bool, msvc_wknd_) > ::template result_::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(3,if_,(C_,T1,T2)) }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION BOOST_MPL_AUX_NA_SPEC(3, if_) }} #endif // BOOST_MPL_IF_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/insert.hpp ================================================ #ifndef BOOST_MPL_INSERT_HPP_INCLUDED #define BOOST_MPL_INSERT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(Pos_or_T) , typename BOOST_MPL_AUX_NA_PARAM(T) > struct insert : insert_impl< typename sequence_tag::type > ::template apply< Sequence,Pos_or_T,T > { BOOST_MPL_AUX_LAMBDA_SUPPORT(3,insert,(Sequence,Pos_or_T,T)) }; BOOST_MPL_AUX_NA_SPEC(3, insert) }} #endif // BOOST_MPL_INSERT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/insert_fwd.hpp ================================================ #ifndef BOOST_MPL_INSERT_FWD_HPP_INCLUDED #define BOOST_MPL_INSERT_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct insert_impl; template< typename Sequence, typename Pos_or_T, typename T > struct insert; }} #endif // BOOST_MPL_INSERT_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/insert_range_fwd.hpp ================================================ #ifndef BOOST_MPL_INSERT_RANGE_FWD_HPP_INCLUDED #define BOOST_MPL_INSERT_RANGE_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct insert_range_impl; template< typename Sequence, typename Pos, typename Range > struct insert_range; }} #endif // BOOST_MPL_INSERT_RANGE_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/int.hpp ================================================ #ifndef BOOST_MPL_INT_HPP_INCLUDED #define BOOST_MPL_INT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #define AUX_WRAPPER_VALUE_TYPE int #include #endif // BOOST_MPL_INT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/int_fwd.hpp ================================================ #ifndef BOOST_MPL_INT_FWD_HPP_INCLUDED #define BOOST_MPL_INT_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct int_; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(int_) #endif // BOOST_MPL_INT_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/integral_c.hpp ================================================ #ifndef BOOST_MPL_INTEGRAL_C_HPP_INCLUDED #define BOOST_MPL_INTEGRAL_C_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #if BOOST_WORKAROUND(__HP_aCC, <= 53800) // the type of non-type template arguments may not depend on template arguments # define AUX_WRAPPER_PARAMS(N) typename T, long N #else # define AUX_WRAPPER_PARAMS(N) typename T, T N #endif #define AUX_WRAPPER_NAME integral_c #define AUX_WRAPPER_VALUE_TYPE T #define AUX_WRAPPER_INST(value) AUX_WRAPPER_NAME< T, value > #include #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x551) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN // 'bool' constant doesn't have 'next'/'prior' members template< bool C > struct integral_c { BOOST_STATIC_CONSTANT(bool, value = C); typedef integral_c_tag tag; typedef integral_c type; typedef bool value_type; operator bool() const { return this->value; } }; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE #endif #endif // BOOST_MPL_INTEGRAL_C_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/integral_c_fwd.hpp ================================================ #ifndef BOOST_MPL_INTEGRAL_C_FWD_HPP_INCLUDED #define BOOST_MPL_INTEGRAL_C_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN #if BOOST_WORKAROUND(__HP_aCC, <= 53800) // the type of non-type template arguments may not depend on template arguments template< typename T, long N > struct integral_c; #else template< typename T, T N > struct integral_c; #endif BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(integral_c) #endif // BOOST_MPL_INTEGRAL_C_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/integral_c_tag.hpp ================================================ #ifndef BOOST_MPL_INTEGRAL_C_TAG_HPP_INCLUDED #define BOOST_MPL_INTEGRAL_C_TAG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN struct integral_c_tag { BOOST_STATIC_CONSTANT(int, value = 0); }; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(integral_c_tag) #endif // BOOST_MPL_INTEGRAL_C_TAG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/is_placeholder.hpp ================================================ #ifndef BOOST_MPL_IS_PLACEHOLDER_HPP_INCLUDED #define BOOST_MPL_IS_PLACEHOLDER_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include namespace boost { namespace mpl { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename T > struct is_placeholder : bool_ { }; template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct is_placeholder< arg > : bool_ { }; #else namespace aux { aux::no_tag is_placeholder_helper(...); template< BOOST_MPL_AUX_NTTP_DECL(int, N) > aux::yes_tag is_placeholder_helper(aux::type_wrapper< arg >*); } // namespace aux template< typename T > struct is_placeholder { static aux::type_wrapper* get(); BOOST_STATIC_CONSTANT(bool, value = sizeof(aux::is_placeholder_helper(get())) == sizeof(aux::yes_tag) ); typedef bool_ type; }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION }} #endif // BOOST_MPL_IS_PLACEHOLDER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/iter_fold_if.hpp ================================================ #ifndef BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED #define BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright Eric Friedman 2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace mpl { namespace aux { template< typename Predicate, typename LastIterator > struct iter_fold_if_pred { template< typename State, typename Iterator > struct apply #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) : and_< not_< is_same > , apply1 > { #else { typedef and_< not_< is_same > , apply1 > type; #endif }; }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(State) , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp) , typename BOOST_MPL_AUX_NA_PARAM(ForwardPredicate) , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp) , typename BOOST_MPL_AUX_NA_PARAM(BackwardPredicate) > struct iter_fold_if { typedef typename begin::type first_; typedef typename end::type last_; typedef typename eval_if< is_na , if_< is_na, always, always > , identity >::type backward_pred_; // cwpro8 doesn't like 'cut-off' type here (use typedef instead) #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) && !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) struct result_ : #else typedef #endif aux::iter_fold_if_impl< first_ , State , ForwardOp , protect< aux::iter_fold_if_pred< ForwardPredicate,last_ > > , BackwardOp , backward_pred_ > #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) && !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) { }; #else result_; #endif public: typedef pair< typename result_::state , typename result_::iterator > type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 6 , iter_fold_if , (Sequence,State,ForwardOp,ForwardPredicate,BackwardOp,BackwardPredicate) ) }; BOOST_MPL_AUX_NA_SPEC(6, iter_fold_if) }} #endif // BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/iterator_range.hpp ================================================ #ifndef BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED #define BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { struct iterator_range_tag; template< typename BOOST_MPL_AUX_NA_PARAM(First) , typename BOOST_MPL_AUX_NA_PARAM(Last) > struct iterator_range { typedef iterator_range_tag tag; typedef iterator_range type; typedef First begin; typedef Last end; BOOST_MPL_AUX_LAMBDA_SUPPORT(2,iterator_range,(First,Last)) }; BOOST_MPL_AUX_NA_SPEC(2, iterator_range) }} #endif // BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/iterator_tags.hpp ================================================ #ifndef BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED #define BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include namespace boost { namespace mpl { struct forward_iterator_tag : int_<0> { typedef forward_iterator_tag type; }; struct bidirectional_iterator_tag : int_<1> { typedef bidirectional_iterator_tag type; }; struct random_access_iterator_tag : int_<2> { typedef random_access_iterator_tag type; }; }} #endif // BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/key_type_fwd.hpp ================================================ #ifndef BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED #define BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct key_type_impl; template< typename AssociativeSequence, typename T > struct key_type; }} #endif // BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/lambda.hpp ================================================ #ifndef BOOST_MPL_LAMBDA_HPP_INCLUDED #define BOOST_MPL_LAMBDA_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # include #else # include # include # define BOOST_MPL_CFG_NO_IMPLICIT_METAFUNCTIONS #endif #endif // BOOST_MPL_LAMBDA_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/lambda_fwd.hpp ================================================ #ifndef BOOST_MPL_LAMBDA_FWD_HPP_INCLUDED #define BOOST_MPL_LAMBDA_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) # include # include # include namespace boost { namespace mpl { template< typename T = na , typename Tag = void_ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM( typename Arity = int_< aux::template_arity::value > ) > struct lambda; }} #else // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT # include namespace boost { namespace mpl { template< typename T = na , typename Tag = void_ , typename Protect = true_ > struct lambda; }} #endif #endif // BOOST_MPL_LAMBDA_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/limits/arity.hpp ================================================ #ifndef BOOST_MPL_LIMITS_ARITY_HPP_INCLUDED #define BOOST_MPL_LIMITS_ARITY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_LIMIT_METAFUNCTION_ARITY) # define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 5 #endif #endif // BOOST_MPL_LIMITS_ARITY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/limits/list.hpp ================================================ #ifndef BOOST_MPL_LIMITS_LIST_HPP_INCLUDED #define BOOST_MPL_LIMITS_LIST_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_LIMIT_LIST_SIZE) # define BOOST_MPL_LIMIT_LIST_SIZE 20 #endif #endif // BOOST_MPL_LIMITS_LIST_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/limits/unrolling.hpp ================================================ #ifndef BOOST_MPL_LIMITS_UNROLLING_HPP_INCLUDED #define BOOST_MPL_LIMITS_UNROLLING_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_LIMIT_UNROLLING) # define BOOST_MPL_LIMIT_UNROLLING 4 #endif #endif // BOOST_MPL_LIMITS_UNROLLING_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/O1_size.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template<> struct O1_size_impl< aux::list_tag > { template< typename List > struct apply : List::size { }; }; }} #endif // BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/begin_end.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template<> struct begin_impl< aux::list_tag > { template< typename List > struct apply { typedef l_iter type; }; }; template<> struct end_impl< aux::list_tag > { template< typename > struct apply { typedef l_iter type; }; }; }} #endif // BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/clear.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template<> struct clear_impl< aux::list_tag > { template< typename List > struct apply { typedef l_end type; }; }; }} #endif // BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/empty.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template<> struct empty_impl< aux::list_tag > { template< typename List > struct apply : not_ { }; }; }} #endif // BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/front.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template<> struct front_impl< aux::list_tag > { template< typename List > struct apply { typedef typename List::item type; }; }; }} #endif // BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/include_preprocessed.hpp ================================================ // Copyright Aleksey Gurtovoy 2001-2006 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! #include #include #include # define AUX778076_HEADER \ aux_/preprocessed/plain/BOOST_MPL_PREPROCESSED_HEADER \ /**/ #if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(700)) # define AUX778076_INCLUDE_STRING BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER) # include AUX778076_INCLUDE_STRING # undef AUX778076_INCLUDE_STRING #else # include BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER) #endif # undef AUX778076_HEADER #undef BOOST_MPL_PREPROCESSED_HEADER ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/item.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template< typename Size , typename T , typename Next > struct l_item { // agurt, 17/jul/03: to facilitate the deficient 'is_sequence' implementation #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) typedef int begin; #endif typedef aux::list_tag tag; typedef l_item type; typedef Size size; typedef T item; typedef Next next; }; struct l_end { #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) typedef int begin; #endif typedef aux::list_tag tag; typedef l_end type; typedef long_<0> size; }; }} #endif // BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/iterator.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include namespace boost { namespace mpl { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename Node > struct l_iter { typedef aux::l_iter_tag tag; typedef forward_iterator_tag category; }; template< typename Node > struct deref< l_iter > { typedef typename Node::item type; }; template< typename Node > struct next< l_iter > { typedef l_iter< typename Node::next > type; }; #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template< typename Node > struct l_iter { typedef aux::l_iter_tag tag; typedef forward_iterator_tag category; typedef typename Node::item type; typedef l_iter< typename mpl::next::type > next; }; #endif template<> struct l_iter { typedef aux::l_iter_tag tag; typedef forward_iterator_tag category; #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) typedef na type; typedef l_iter next; #endif }; BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, l_iter) }} #endif // BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/numbered.hpp ================================================ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Peter Dimov 2000-2002 // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if defined(BOOST_PP_IS_ITERATING) #include #include #include #include #define i BOOST_PP_FRAME_ITERATION(1) #if i == 1 template< BOOST_PP_ENUM_PARAMS(i, typename T) > struct list1 : l_item< long_<1> , T0 , l_end > { typedef list1 type; }; #else # define MPL_AUX_LIST_TAIL(list, i, T) \ BOOST_PP_CAT(list,BOOST_PP_DEC(i))< \ BOOST_PP_ENUM_SHIFTED_PARAMS(i, T) \ > \ /**/ template< BOOST_PP_ENUM_PARAMS(i, typename T) > struct BOOST_PP_CAT(list,i) : l_item< long_ , T0 , MPL_AUX_LIST_TAIL(list,i,T) > { typedef BOOST_PP_CAT(list,i) type; }; # undef MPL_AUX_LIST_TAIL #endif // i == 1 #undef i #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/numbered_c.hpp ================================================ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if defined(BOOST_PP_IS_ITERATING) #include #include #include #include #define i BOOST_PP_FRAME_ITERATION(1) #if i == 1 template< typename T , BOOST_PP_ENUM_PARAMS(i, T C) > struct list1_c : l_item< long_<1> , integral_c , l_end > { typedef list1_c type; typedef T value_type; }; #else # define MPL_AUX_LIST_C_TAIL(list, i, C) \ BOOST_PP_CAT(BOOST_PP_CAT(list,BOOST_PP_DEC(i)),_c) \ /**/ template< typename T , BOOST_PP_ENUM_PARAMS(i, T C) > struct BOOST_PP_CAT(BOOST_PP_CAT(list,i),_c) : l_item< long_ , integral_c , MPL_AUX_LIST_C_TAIL(list,i,C) > { typedef BOOST_PP_CAT(BOOST_PP_CAT(list,i),_c) type; typedef T value_type; }; # undef MPL_AUX_LIST_C_TAIL #endif // i == 1 #undef i #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/pop_front.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template<> struct pop_front_impl< aux::list_tag > { template< typename List > struct apply { typedef typename mpl::next::type type; }; }; }} #endif // BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list10.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list10.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0 > struct list1 : l_item< long_<1> , T0 , l_end > { typedef list1 type; }; template< typename T0, typename T1 > struct list2 : l_item< long_<2> , T0 , list1 > { typedef list2 type; }; template< typename T0, typename T1, typename T2 > struct list3 : l_item< long_<3> , T0 , list2< T1,T2 > > { typedef list3 type; }; template< typename T0, typename T1, typename T2, typename T3 > struct list4 : l_item< long_<4> , T0 , list3< T1,T2,T3 > > { typedef list4 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 > struct list5 : l_item< long_<5> , T0 , list4< T1,T2,T3,T4 > > { typedef list5 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5 > struct list6 : l_item< long_<6> , T0 , list5< T1,T2,T3,T4,T5 > > { typedef list6 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 > struct list7 : l_item< long_<7> , T0 , list6< T1,T2,T3,T4,T5,T6 > > { typedef list7 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 > struct list8 : l_item< long_<8> , T0 , list7< T1,T2,T3,T4,T5,T6,T7 > > { typedef list8 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 > struct list9 : l_item< long_<9> , T0 , list8< T1,T2,T3,T4,T5,T6,T7,T8 > > { typedef list9 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 > struct list10 : l_item< long_<10> , T0 , list9< T1,T2,T3,T4,T5,T6,T7,T8,T9 > > { typedef list10 type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list10_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T , T C0 > struct list1_c : l_item< long_<1> , integral_c< T,C0 > , l_end > { typedef list1_c type; typedef T value_type; }; template< typename T , T C0, T C1 > struct list2_c : l_item< long_<2> , integral_c< T,C0 > , list1_c< T,C1 > > { typedef list2_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2 > struct list3_c : l_item< long_<3> , integral_c< T,C0 > , list2_c< T,C1,C2 > > { typedef list3_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3 > struct list4_c : l_item< long_<4> , integral_c< T,C0 > , list3_c< T,C1,C2,C3 > > { typedef list4_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4 > struct list5_c : l_item< long_<5> , integral_c< T,C0 > , list4_c< T,C1,C2,C3,C4 > > { typedef list5_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5 > struct list6_c : l_item< long_<6> , integral_c< T,C0 > , list5_c< T,C1,C2,C3,C4,C5 > > { typedef list6_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6 > struct list7_c : l_item< long_<7> , integral_c< T,C0 > , list6_c< T,C1,C2,C3,C4,C5,C6 > > { typedef list7_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7 > struct list8_c : l_item< long_<8> , integral_c< T,C0 > , list7_c< T,C1,C2,C3,C4,C5,C6,C7 > > { typedef list8_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8 > struct list9_c : l_item< long_<9> , integral_c< T,C0 > , list8_c< T,C1,C2,C3,C4,C5,C6,C7,C8 > > { typedef list9_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9 > struct list10_c : l_item< long_<10> , integral_c< T,C0 > , list9_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9 > > { typedef list10_c type; typedef T value_type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list20.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list20.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10 > struct list11 : l_item< long_<11> , T0 , list10< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > > { typedef list11 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11 > struct list12 : l_item< long_<12> , T0 , list11< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > > { typedef list12 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12 > struct list13 : l_item< long_<13> , T0 , list12< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > > { typedef list13 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13 > struct list14 : l_item< long_<14> , T0 , list13< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > > { typedef list14 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 > struct list15 : l_item< long_<15> , T0 , list14< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 > > { typedef list15 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15 > struct list16 : l_item< long_<16> , T0 , list15< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 > > { typedef list16 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16 > struct list17 : l_item< long_<17> , T0 , list16< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 > > { typedef list17 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17 > struct list18 : l_item< long_<18> , T0 , list17< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 > > { typedef list18 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18 > struct list19 : l_item< long_<19> , T0 , list18< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 > > { typedef list19 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 > struct list20 : l_item< long_<20> , T0 , list19< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 > > { typedef list20 type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list20_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 > struct list11_c : l_item< long_<11> , integral_c< T,C0 > , list10_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > > { typedef list11_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11 > struct list12_c : l_item< long_<12> , integral_c< T,C0 > , list11_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > > { typedef list12_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12 > struct list13_c : l_item< long_<13> , integral_c< T,C0 > , list12_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > > { typedef list13_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13 > struct list14_c : l_item< long_<14> , integral_c< T,C0 > , list13_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 > > { typedef list14_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14 > struct list15_c : l_item< long_<15> , integral_c< T,C0 > , list14_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 > > { typedef list15_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15 > struct list16_c : l_item< long_<16> , integral_c< T,C0 > , list15_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 > > { typedef list16_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16 > struct list17_c : l_item< long_<17> , integral_c< T,C0 > , list16_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 > > { typedef list17_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17 > struct list18_c : l_item< long_<18> , integral_c< T,C0 > , list17_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 > > { typedef list18_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18 > struct list19_c : l_item< long_<19> , integral_c< T,C0 > , list18_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 > > { typedef list19_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19 > struct list20_c : l_item< long_<20> , integral_c< T,C0 > , list19_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 > > { typedef list20_c type; typedef T value_type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list30.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list30.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20 > struct list21 : l_item< long_<21> , T0 , list20< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20 > > { typedef list21 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21 > struct list22 : l_item< long_<22> , T0 , list21< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21 > > { typedef list22 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22 > struct list23 : l_item< long_<23> , T0 , list22< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22 > > { typedef list23 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23 > struct list24 : l_item< long_<24> , T0 , list23< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23 > > { typedef list24 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 > struct list25 : l_item< long_<25> , T0 , list24< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24 > > { typedef list25 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25 > struct list26 : l_item< long_<26> , T0 , list25< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25 > > { typedef list26 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26 > struct list27 : l_item< long_<27> , T0 , list26< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26 > > { typedef list27 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27 > struct list28 : l_item< long_<28> , T0 , list27< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27 > > { typedef list28 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28 > struct list29 : l_item< long_<29> , T0 , list28< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28 > > { typedef list29 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 > struct list30 : l_item< long_<30> , T0 , list29< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29 > > { typedef list30 type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list30_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 > struct list21_c : l_item< long_<21> , integral_c< T,C0 > , list20_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20 > > { typedef list21_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21 > struct list22_c : l_item< long_<22> , integral_c< T,C0 > , list21_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21 > > { typedef list22_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22 > struct list23_c : l_item< long_<23> , integral_c< T,C0 > , list22_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22 > > { typedef list23_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23 > struct list24_c : l_item< long_<24> , integral_c< T,C0 > , list23_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23 > > { typedef list24_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24 > struct list25_c : l_item< long_<25> , integral_c< T,C0 > , list24_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24 > > { typedef list25_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25 > struct list26_c : l_item< long_<26> , integral_c< T,C0 > , list25_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25 > > { typedef list26_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26 > struct list27_c : l_item< long_<27> , integral_c< T,C0 > , list26_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26 > > { typedef list27_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27 > struct list28_c : l_item< long_<28> , integral_c< T,C0 > , list27_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27 > > { typedef list28_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28 > struct list29_c : l_item< long_<29> , integral_c< T,C0 > , list28_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28 > > { typedef list29_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29 > struct list30_c : l_item< long_<30> , integral_c< T,C0 > , list29_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29 > > { typedef list30_c type; typedef T value_type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list40.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list40.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30 > struct list31 : l_item< long_<31> , T0 , list30< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30 > > { typedef list31 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31 > struct list32 : l_item< long_<32> , T0 , list31< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31 > > { typedef list32 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32 > struct list33 : l_item< long_<33> , T0 , list32< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32 > > { typedef list33 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33 > struct list34 : l_item< long_<34> , T0 , list33< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33 > > { typedef list34 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 > struct list35 : l_item< long_<35> , T0 , list34< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34 > > { typedef list35 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35 > struct list36 : l_item< long_<36> , T0 , list35< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35 > > { typedef list36 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36 > struct list37 : l_item< long_<37> , T0 , list36< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36 > > { typedef list37 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37 > struct list38 : l_item< long_<38> , T0 , list37< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37 > > { typedef list38 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38 > struct list39 : l_item< long_<39> , T0 , list38< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38 > > { typedef list39 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 > struct list40 : l_item< long_<40> , T0 , list39< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39 > > { typedef list40 type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list40_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 > struct list31_c : l_item< long_<31> , integral_c< T,C0 > , list30_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30 > > { typedef list31_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31 > struct list32_c : l_item< long_<32> , integral_c< T,C0 > , list31_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31 > > { typedef list32_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32 > struct list33_c : l_item< long_<33> , integral_c< T,C0 > , list32_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32 > > { typedef list33_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33 > struct list34_c : l_item< long_<34> , integral_c< T,C0 > , list33_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33 > > { typedef list34_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34 > struct list35_c : l_item< long_<35> , integral_c< T,C0 > , list34_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34 > > { typedef list35_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35 > struct list36_c : l_item< long_<36> , integral_c< T,C0 > , list35_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35 > > { typedef list36_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36 > struct list37_c : l_item< long_<37> , integral_c< T,C0 > , list36_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36 > > { typedef list37_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37 > struct list38_c : l_item< long_<38> , integral_c< T,C0 > , list37_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37 > > { typedef list38_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38 > struct list39_c : l_item< long_<39> , integral_c< T,C0 > , list38_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38 > > { typedef list39_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39 > struct list40_c : l_item< long_<40> , integral_c< T,C0 > , list39_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39 > > { typedef list40_c type; typedef T value_type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list50.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list50.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40 > struct list41 : l_item< long_<41> , T0 , list40< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40 > > { typedef list41 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41 > struct list42 : l_item< long_<42> , T0 , list41< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41 > > { typedef list42 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42 > struct list43 : l_item< long_<43> , T0 , list42< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42 > > { typedef list43 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42, typename T43 > struct list44 : l_item< long_<44> , T0 , list43< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43 > > { typedef list44 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42, typename T43, typename T44 > struct list45 : l_item< long_<45> , T0 , list44< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44 > > { typedef list45 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42, typename T43, typename T44 , typename T45 > struct list46 : l_item< long_<46> , T0 , list45< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45 > > { typedef list46 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42, typename T43, typename T44 , typename T45, typename T46 > struct list47 : l_item< long_<47> , T0 , list46< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46 > > { typedef list47 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42, typename T43, typename T44 , typename T45, typename T46, typename T47 > struct list48 : l_item< long_<48> , T0 , list47< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47 > > { typedef list48 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42, typename T43, typename T44 , typename T45, typename T46, typename T47, typename T48 > struct list49 : l_item< long_<49> , T0 , list48< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,T48 > > { typedef list49 type; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 , typename T10, typename T11, typename T12, typename T13, typename T14 , typename T15, typename T16, typename T17, typename T18, typename T19 , typename T20, typename T21, typename T22, typename T23, typename T24 , typename T25, typename T26, typename T27, typename T28, typename T29 , typename T30, typename T31, typename T32, typename T33, typename T34 , typename T35, typename T36, typename T37, typename T38, typename T39 , typename T40, typename T41, typename T42, typename T43, typename T44 , typename T45, typename T46, typename T47, typename T48, typename T49 > struct list50 : l_item< long_<50> , T0 , list49< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,T48,T49 > > { typedef list50 type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp ================================================ // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Preprocessed version of "boost/mpl/list/list50_c.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 > struct list41_c : l_item< long_<41> , integral_c< T,C0 > , list40_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40 > > { typedef list41_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41 > struct list42_c : l_item< long_<42> , integral_c< T,C0 > , list41_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41 > > { typedef list42_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42 > struct list43_c : l_item< long_<43> , integral_c< T,C0 > , list42_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42 > > { typedef list43_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42, T C43 > struct list44_c : l_item< long_<44> , integral_c< T,C0 > , list43_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43 > > { typedef list44_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42, T C43, T C44 > struct list45_c : l_item< long_<45> , integral_c< T,C0 > , list44_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44 > > { typedef list45_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42, T C43, T C44, T C45 > struct list46_c : l_item< long_<46> , integral_c< T,C0 > , list45_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45 > > { typedef list46_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42, T C43, T C44, T C45, T C46 > struct list47_c : l_item< long_<47> , integral_c< T,C0 > , list46_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46 > > { typedef list47_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42, T C43, T C44, T C45, T C46, T C47 > struct list48_c : l_item< long_<48> , integral_c< T,C0 > , list47_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46,C47 > > { typedef list48_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42, T C43, T C44, T C45, T C46, T C47, T C48 > struct list49_c : l_item< long_<49> , integral_c< T,C0 > , list48_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46,C47,C48 > > { typedef list49_c type; typedef T value_type; }; template< typename T , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 , T C41, T C42, T C43, T C44, T C45, T C46, T C47, T C48, T C49 > struct list50_c : l_item< long_<50> , integral_c< T,C0 > , list49_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46,C47,C48,C49 > > { typedef list50_c type; typedef T value_type; }; }} ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/push_back.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template< typename Tag > struct has_push_back_impl; template<> struct has_push_back_impl< aux::list_tag > { template< typename Seq > struct apply : false_ { }; }; }} #endif // BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/push_front.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template<> struct push_front_impl< aux::list_tag > { template< typename List, typename T > struct apply { typedef l_item< typename next::type , T , typename List::type > type; }; }; }} #endif // BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/size.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template<> struct size_impl< aux::list_tag > { template< typename List > struct apply : List::size { }; }; }} #endif // BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/aux_/tag.hpp ================================================ #ifndef BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED #define BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { namespace aux { struct list_tag; struct l_iter_tag; }}} #endif // BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list0.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST0_HPP_INCLUDED #define BOOST_MPL_LIST_LIST0_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace mpl { template< typename Dummy = na > struct list0; template<> struct list0 : l_end { typedef l_end type; }; }} #endif // BOOST_MPL_LIST_LIST0_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list0_c.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST0_C_HPP_INCLUDED #define BOOST_MPL_LIST_LIST0_C_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template< typename T > struct list0_c : l_end { typedef l_end type; typedef T value_type; }; }} #endif // BOOST_MPL_LIST_LIST0_C_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list10.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST10_HPP_INCLUDED #define BOOST_MPL_LIST_LIST10_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list10.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(1, 10, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST10_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list10_c.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST10_C_HPP_INCLUDED #define BOOST_MPL_LIST_LIST10_C_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list10_c.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(1, 10, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST10_C_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list20.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST20_HPP_INCLUDED #define BOOST_MPL_LIST_LIST20_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list20.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(11, 20, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST20_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list20_c.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST20_C_HPP_INCLUDED #define BOOST_MPL_LIST_LIST20_C_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list20_c.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(11, 20, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST20_C_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list30.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST30_HPP_INCLUDED #define BOOST_MPL_LIST_LIST30_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list30.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(21, 30, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST30_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list30_c.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST30_C_HPP_INCLUDED #define BOOST_MPL_LIST_LIST30_C_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list30_c.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(21, 30, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST30_C_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list40.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST40_HPP_INCLUDED #define BOOST_MPL_LIST_LIST40_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list40.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(31, 40, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST40_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list40_c.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED #define BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list40_c.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(31, 40, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list50.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST50_HPP_INCLUDED #define BOOST_MPL_LIST_LIST50_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list50.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(41, 50, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST50_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list/list50_c.hpp ================================================ #ifndef BOOST_MPL_LIST_LIST50_C_HPP_INCLUDED #define BOOST_MPL_LIST_LIST50_C_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list50_c.hpp # include #else # include namespace boost { namespace mpl { # define BOOST_PP_ITERATION_PARAMS_1 \ (3,(41, 50, )) # include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_LIST50_C_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/list.hpp ================================================ #ifndef BOOST_MPL_LIST_HPP_INCLUDED #define BOOST_MPL_LIST_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include # include #if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING) # define AUX778076_LIST_HEADER \ BOOST_PP_CAT(list,BOOST_MPL_LIMIT_LIST_SIZE).hpp \ /**/ #else # define AUX778076_LIST_HEADER \ BOOST_PP_CAT(list,BOOST_MPL_LIMIT_LIST_SIZE)##.hpp \ /**/ #endif # include BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_LIST_HEADER) # undef AUX778076_LIST_HEADER #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER list.hpp # include #else # include # define AUX778076_SEQUENCE_NAME list # define AUX778076_SEQUENCE_LIMIT BOOST_MPL_LIMIT_LIST_SIZE # include #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_LIST_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/logical.hpp ================================================ #ifndef BOOST_MPL_LOGICAL_HPP_INCLUDED #define BOOST_MPL_LOGICAL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #endif // BOOST_MPL_LOGICAL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/long.hpp ================================================ #ifndef BOOST_MPL_LONG_HPP_INCLUDED #define BOOST_MPL_LONG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #define AUX_WRAPPER_VALUE_TYPE long #include #endif // BOOST_MPL_LONG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/long_fwd.hpp ================================================ #ifndef BOOST_MPL_LONG_FWD_HPP_INCLUDED #define BOOST_MPL_LONG_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct long_; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(long_) #endif // BOOST_MPL_LONG_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/next.hpp ================================================ #ifndef BOOST_MPL_NEXT_HPP_INCLUDED #define BOOST_MPL_NEXT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #endif // BOOST_MPL_NEXT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/next_prior.hpp ================================================ #ifndef BOOST_MPL_NEXT_PRIOR_HPP_INCLUDED #define BOOST_MPL_NEXT_PRIOR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { BOOST_MPL_AUX_COMMON_NAME_WKND(next) BOOST_MPL_AUX_COMMON_NAME_WKND(prior) template< typename BOOST_MPL_AUX_NA_PARAM(T) > struct next { typedef typename T::next type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,next,(T)) }; template< typename BOOST_MPL_AUX_NA_PARAM(T) > struct prior { typedef typename T::prior type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,prior,(T)) }; BOOST_MPL_AUX_NA_SPEC(1, next) BOOST_MPL_AUX_NA_SPEC(1, prior) }} #endif // BOOST_MPL_NEXT_PRIOR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/not.hpp ================================================ #ifndef BOOST_MPL_NOT_HPP_INCLUDED #define BOOST_MPL_NOT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { namespace aux { template< BOOST_MPL_AUX_NTTP_DECL(long, C_) > // 'long' is intentional here struct not_impl : bool_ { }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(T) > struct not_ : aux::not_impl< BOOST_MPL_AUX_NESTED_TYPE_WKND(T)::value > { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,not_,(T)) }; BOOST_MPL_AUX_NA_SPEC(1,not_) }} #endif // BOOST_MPL_NOT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/or.hpp ================================================ #ifndef BOOST_MPL_OR_HPP_INCLUDED #define BOOST_MPL_OR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # include # include # include // agurt, 19/may/04: workaround a conflict with header's // 'or' and 'and' macros, see http://tinyurl.com/3et69; 'defined(or)' // has to be checked in a separate condition, otherwise GCC complains // about 'or' being an alternative token #if defined(_MSC_VER) && !defined(__clang__) #ifndef __GCCXML__ #if defined(or) # pragma push_macro("or") # undef or # define or(x) #endif #endif #endif # define BOOST_MPL_PREPROCESSED_HEADER or.hpp # include #if defined(_MSC_VER) && !defined(__clang__) #ifndef __GCCXML__ #if defined(or) # pragma pop_macro("or") #endif #endif #endif #else # define AUX778076_OP_NAME or_ # define AUX778076_OP_VALUE1 true # define AUX778076_OP_VALUE2 false # include #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_OR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/pair.hpp ================================================ #ifndef BOOST_MPL_PAIR_HPP_INCLUDED #define BOOST_MPL_PAIR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T1) , typename BOOST_MPL_AUX_NA_PARAM(T2) > struct pair { typedef pair type; typedef T1 first; typedef T2 second; BOOST_MPL_AUX_LAMBDA_SUPPORT(2,pair,(T1,T2)) }; template< typename BOOST_MPL_AUX_NA_PARAM(P) > struct first { #if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) typedef typename P::first type; #else typedef typename aux::msvc_eti_base

::first type; #endif BOOST_MPL_AUX_LAMBDA_SUPPORT(1,first,(P)) }; template< typename BOOST_MPL_AUX_NA_PARAM(P) > struct second { #if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) typedef typename P::second type; #else typedef typename aux::msvc_eti_base

::second type; #endif BOOST_MPL_AUX_LAMBDA_SUPPORT(1,second,(P)) }; BOOST_MPL_AUX_NA_SPEC_NO_ETI(2, pair) BOOST_MPL_AUX_NA_SPEC(1, first) BOOST_MPL_AUX_NA_SPEC(1, second) }} #endif // BOOST_MPL_PAIR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/placeholders.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_PLACEHOLDERS_HPP_INCLUDED #define BOOST_MPL_PLACEHOLDERS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // Copyright Peter Dimov 2001-2003 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include # if !defined(BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE) # define BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(type) \ using ::BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::type; \ /**/ # else # define BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(type) /**/ # endif #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER placeholders.hpp # include #else # include # include # include # include // watch out for GNU gettext users, who #define _(x) #if !defined(_) || defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg<-1> _; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_; } }} #endif /// agurt, 17/mar/02: one more placeholder for the last 'apply#' /// specialization #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY + 1, )) #include BOOST_PP_ITERATE() #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_PLACEHOLDERS_HPP_INCLUDED ///// iteration #else #define i_ BOOST_PP_FRAME_ITERATION(1) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN typedef arg BOOST_PP_CAT(_,i_); BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(BOOST_PP_CAT(_,i_)) namespace placeholders { using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::BOOST_PP_CAT(_,i_); } }} #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/pop_front_fwd.hpp ================================================ #ifndef BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED #define BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct pop_front_impl; template< typename Sequence > struct pop_front; }} #endif // BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/prior.hpp ================================================ #ifndef BOOST_MPL_PRIOR_HPP_INCLUDED #define BOOST_MPL_PRIOR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #endif // BOOST_MPL_PRIOR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/protect.hpp ================================================ #ifndef BOOST_MPL_PROTECT_HPP_INCLUDED #define BOOST_MPL_PROTECT_HPP_INCLUDED // Copyright Peter Dimov 2001 // Copyright Aleksey Gurtovoy 2002-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(T) , int not_le_ = 0 > struct protect : T { #if BOOST_WORKAROUND(__EDG_VERSION__, == 238) typedef mpl::protect type; #else typedef protect type; #endif }; #if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) namespace aux { template< BOOST_MPL_AUX_NTTP_DECL(int, N), typename T > struct arity< protect, N > : arity { }; } // namespace aux #endif BOOST_MPL_AUX_NA_SPEC_MAIN(1, protect) #if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(1, 1, protect) #endif }} #endif // BOOST_MPL_PROTECT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/push_back_fwd.hpp ================================================ #ifndef BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED #define BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct push_back_impl; template< typename Sequence, typename T > struct push_back; }} #endif // BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/push_front.hpp ================================================ #ifndef BOOST_MPL_PUSH_FRONT_HPP_INCLUDED #define BOOST_MPL_PUSH_FRONT_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(T) > struct push_front : push_front_impl< typename sequence_tag::type > ::template apply< Sequence,T > { BOOST_MPL_AUX_LAMBDA_SUPPORT(2,push_front,(Sequence,T)) }; template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct has_push_front : has_push_front_impl< typename sequence_tag::type > ::template apply< Sequence > { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,has_push_front,(Sequence)) }; BOOST_MPL_AUX_NA_SPEC(2, push_front) BOOST_MPL_AUX_NA_SPEC(1, has_push_front) }} #endif // BOOST_MPL_PUSH_FRONT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/push_front_fwd.hpp ================================================ #ifndef BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED #define BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct push_front_impl; template< typename Sequence, typename T > struct push_front; }} #endif // BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/quote.hpp ================================================ #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_MPL_QUOTE_HPP_INCLUDED #define BOOST_MPL_QUOTE_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2008 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #if !defined(BOOST_MPL_PREPROCESSING_MODE) # include # include #endif #include #include #if defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) \ && !defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS) # define BOOST_MPL_CFG_NO_QUOTE_TEMPLATE #endif #if !defined(BOOST_MPL_CFG_NO_IMPLICIT_METAFUNCTIONS) \ && defined(BOOST_MPL_CFG_NO_HAS_XXX) # define BOOST_MPL_CFG_NO_IMPLICIT_METAFUNCTIONS #endif #include #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ && !defined(BOOST_MPL_PREPROCESSING_MODE) # define BOOST_MPL_PREPROCESSED_HEADER quote.hpp # include #else # include # include # include # include # include # include #if !defined(BOOST_MPL_CFG_NO_QUOTE_TEMPLATE) namespace boost { namespace mpl { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename T, bool has_type_ > struct quote_impl // GCC has a problem with metafunction forwarding when T is a // specialization of a template called 'type'. # if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4)) \ && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(0)) \ && BOOST_WORKAROUND(__GNUC_PATCHLEVEL__, BOOST_TESTED_AT(2)) { typedef typename T::type type; }; # else : T { }; # endif template< typename T > struct quote_impl { typedef T type; }; #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template< bool > struct quote_impl { template< typename T > struct result_ : T { }; }; template<> struct quote_impl { template< typename T > struct result_ { typedef T type; }; }; #endif #define BOOST_PP_ITERATION_PARAMS_1 \ (3,(1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, )) #include BOOST_PP_ITERATE() }} #endif // BOOST_MPL_CFG_NO_QUOTE_TEMPLATE #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #endif // BOOST_MPL_QUOTE_HPP_INCLUDED ///// iteration #else #define i_ BOOST_PP_FRAME_ITERATION(1) template< template< BOOST_MPL_PP_PARAMS(i_, typename P) > class F , typename Tag = void_ > struct BOOST_PP_CAT(quote,i_) { template< BOOST_MPL_PP_PARAMS(i_, typename U) > struct apply #if defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS) { typedef typename quote_impl< F< BOOST_MPL_PP_PARAMS(i_, U) > , aux::has_type< F< BOOST_MPL_PP_PARAMS(i_, U) > >::value >::type type; }; #elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) : quote_impl< F< BOOST_MPL_PP_PARAMS(i_, U) > , aux::has_type< F< BOOST_MPL_PP_PARAMS(i_, U) > >::value > { }; #else : quote_impl< aux::has_type< F< BOOST_MPL_PP_PARAMS(i_, U) > >::value > ::template result_< F< BOOST_MPL_PP_PARAMS(i_, U) > > { }; #endif }; #undef i_ #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/reverse_fold.hpp ================================================ #ifndef BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED #define BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // Copyright David Abrahams 2001-2002 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(State) , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp) , typename ForwardOp = arg<1> > struct reverse_fold { typedef typename aux::reverse_fold_impl< ::boost::mpl::O1_size::value , typename begin::type , typename end::type , State , BackwardOp , ForwardOp >::state type; BOOST_MPL_AUX_LAMBDA_SUPPORT(3,reverse_fold,(Sequence,State,BackwardOp)) }; BOOST_MPL_AUX_NA_SPEC(3, reverse_fold) }} #endif // BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/same_as.hpp ================================================ #ifndef BOOST_MPL_SAME_AS_HPP_INCLUDED #define BOOST_MPL_SAME_AS_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include namespace boost { namespace mpl { template< typename T1 > struct same_as { template< typename T2 > struct apply #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) : is_same { #else { typedef typename is_same::type type; #endif }; }; template< typename T1 > struct not_same_as { template< typename T2 > struct apply #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) : not_< is_same > { #else { typedef typename not_< is_same >::type type; #endif }; }; }} #endif // BOOST_MPL_SAME_AS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/sequence_tag.hpp ================================================ #ifndef BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED #define BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include namespace boost { namespace mpl { // agurt, 27/nov/02: have to use a simplistic 'sequence_tag' implementation // on MSVC to avoid dreadful "internal structure overflow" error #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ || defined(BOOST_MPL_CFG_NO_HAS_XXX) template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct sequence_tag { typedef typename Sequence::tag type; }; #elif BOOST_WORKAROUND(BOOST_MSVC, == 1300) // agurt, 07/feb/03: workaround for what seems to be MSVC 7.0-specific ETI issue namespace aux { template< bool > struct sequence_tag_impl { template< typename Sequence > struct result_ { typedef typename Sequence::tag type; }; }; template<> struct sequence_tag_impl { template< typename Sequence > struct result_ { typedef int type; }; }; } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct sequence_tag : aux::sequence_tag_impl< !aux::is_msvc_eti_arg::value > ::template result_ { }; #else namespace aux { template< bool has_tag_, bool has_begin_ > struct sequence_tag_impl { // agurt 24/nov/02: MSVC 6.5 gets confused in 'sequence_tag_impl' // specialization below, if we name it 'result_' here template< typename Sequence > struct result2_; }; # define AUX_CLASS_SEQUENCE_TAG_SPEC(has_tag, has_begin, result_type) \ template<> struct sequence_tag_impl \ { \ template< typename Sequence > struct result2_ \ { \ typedef result_type type; \ }; \ }; \ /**/ AUX_CLASS_SEQUENCE_TAG_SPEC(true, true, typename Sequence::tag) AUX_CLASS_SEQUENCE_TAG_SPEC(true, false, typename Sequence::tag) AUX_CLASS_SEQUENCE_TAG_SPEC(false, true, nested_begin_end_tag) AUX_CLASS_SEQUENCE_TAG_SPEC(false, false, non_sequence_tag) # undef AUX_CLASS_SEQUENCE_TAG_SPEC } // namespace aux template< typename BOOST_MPL_AUX_NA_PARAM(Sequence) > struct sequence_tag : aux::sequence_tag_impl< ::boost::mpl::aux::has_tag::value , ::boost::mpl::aux::has_begin::value >::template result2_ { }; #endif // BOOST_MSVC BOOST_MPL_AUX_NA_SPEC(1, sequence_tag) }} #endif // BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/sequence_tag_fwd.hpp ================================================ #ifndef BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED #define BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { struct nested_begin_end_tag; struct non_sequence_tag; template< typename Sequence > struct sequence_tag; }} #endif // BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/at_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_AT_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_AT_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template<> struct at_impl< aux::set_tag > { template< typename Set, typename T > struct apply { typedef typename if_< has_key_impl::apply , T , void_ >::type type; }; }; }} #endif // BOOST_MPL_SET_AUX_AT_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/begin_end_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_BEGIN_END_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_BEGIN_END_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2007 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template<> struct begin_impl< aux::set_tag > { template< typename Set > struct apply : s_iter_get { }; }; template<> struct end_impl< aux::set_tag > { template< typename Set > struct apply { typedef s_iter< Set,set0<> > type; }; }; }} #endif // BOOST_MPL_SET_AUX_BEGIN_END_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/clear_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_CLEAR_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_CLEAR_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template<> struct clear_impl< aux::set_tag > { template< typename Set > struct apply { typedef set0<> type; }; }; }} #endif // BOOST_MPL_SET_AUX_CLEAR_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/empty_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_EMPTY_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_EMPTY_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template<> struct empty_impl< aux::set_tag > { template< typename Set > struct apply : not_< typename Set::size > { }; }; }} #endif // BOOST_MPL_SET_AUX_EMPTY_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/erase_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_ERASE_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_ERASE_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include namespace boost { namespace mpl { template<> struct erase_impl< aux::set_tag > { template< typename Set , typename Pos , typename unused_ > struct apply : erase_key_impl ::apply { }; }; }} #endif // BOOST_MPL_SET_AUX_ERASE_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/erase_key_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_ERASE_KEY_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_ERASE_KEY_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2007 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include namespace boost { namespace mpl { template<> struct erase_key_impl< aux::set_tag > { template< typename Set , typename T > struct apply : eval_if< has_key_impl::apply , eval_if< is_same< T,typename Set::item_type_ > , base , identity< s_mask > > , identity > { }; }; }} #endif // BOOST_MPL_SET_AUX_ERASE_KEY_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/has_key_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_HAS_KEY_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_HAS_KEY_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include #include namespace boost { namespace mpl { template<> struct has_key_impl< aux::set_tag > { template< typename Set, typename T > struct apply #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ || BOOST_WORKAROUND(__EDG_VERSION__, <= 245) { BOOST_STATIC_CONSTANT(bool, value = ( sizeof( BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED( Set , BOOST_MPL_AUX_STATIC_CAST(aux::type_wrapper*, 0) ) ) == sizeof(aux::no_tag) ) ); typedef bool_ type; #else // ISO98 C++ : bool_< ( sizeof( BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED( Set , BOOST_MPL_AUX_STATIC_CAST(aux::type_wrapper*, 0) ) ) == sizeof(aux::no_tag) ) > { #endif }; }; }} #endif // BOOST_MPL_SET_AUX_HAS_KEY_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/insert_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_INSERT_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_INSERT_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2007 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include #include namespace boost { namespace mpl { namespace aux { template< typename Set, typename T > struct set_insert_impl : eval_if< has_key_impl::apply , identity , eval_if< is_same< T,typename Set::last_masked_ > , base , identity< s_item > > > { }; } template<> struct insert_impl< aux::set_tag > { template< typename Set , typename PosOrKey , typename KeyOrNA > struct apply : aux::set_insert_impl< Set , typename if_na::type > { }; }; }} #endif // BOOST_MPL_SET_AUX_INSERT_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/insert_range_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED // Copyright Bruno Dutra 2015 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include namespace boost { namespace mpl { template<> struct insert_range_impl< aux::set_tag > { template< typename Sequence , typename /*Pos*/ , typename Range > struct apply : fold > { }; }; }} #endif // BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/item.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_ITEM_HPP_INCLUDED #define BOOST_MPL_SET_AUX_ITEM_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2007 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include namespace boost { namespace mpl { template< typename T, typename Base > struct s_item : Base { typedef s_item item_; typedef void_ last_masked_; typedef T item_type_; typedef typename Base::item_ base; typedef s_item type; typedef typename next< typename Base::size >::type size; typedef typename next< typename Base::order >::type order; #if defined(BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES) typedef typename aux::weighted_tag::type order_tag_; #else typedef char (&order_tag_)[BOOST_MPL_AUX_MSVC_VALUE_WKND(order)::value]; #endif BOOST_MPL_AUX_SET_OVERLOAD( order_tag_, ORDER_BY_KEY, s_item, aux::type_wrapper* ); BOOST_MPL_AUX_SET_OVERLOAD( aux::no_tag, IS_MASKED, s_item, aux::type_wrapper* ); }; template< typename T, typename Base > struct s_mask : Base { typedef s_mask item_; typedef T last_masked_; typedef void_ item_type_; typedef typename Base::item_ base; typedef typename prior< typename Base::size >::type size; typedef s_mask type; BOOST_MPL_AUX_SET_OVERLOAD( aux::yes_tag, IS_MASKED, s_mask, aux::type_wrapper* ); }; template< typename T, typename Base > struct s_unmask : Base { typedef s_unmask item_; typedef void_ last_masked_; typedef T item_type_; typedef typename Base::item_ base; typedef typename next< typename Base::size >::type size; BOOST_MPL_AUX_SET_OVERLOAD( aux::no_tag, IS_MASKED, s_unmask, aux::type_wrapper* ); }; }} #endif // BOOST_MPL_SET_AUX_ITEM_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/iterator.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_ITERATOR_HPP_INCLUDED #define BOOST_MPL_SET_AUX_ITERATOR_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2007 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include namespace boost { namespace mpl { // used by 's_iter_get' template< typename Set, typename Tail > struct s_iter; template< typename Set, typename Tail > struct s_iter_get : eval_if< has_key< Set,typename Tail::item_type_ > , identity< s_iter > , next< s_iter > > { }; template< typename Set, typename Tail > struct s_iter_impl { typedef Tail tail_; typedef forward_iterator_tag category; typedef typename Tail::item_type_ type; #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) typedef typename s_iter_get< Set,typename Tail::base >::type next; #endif }; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< typename Set, typename Tail > struct next< s_iter > : s_iter_get< Set,typename Tail::base > { }; template< typename Set > struct next< s_iter > > { typedef s_iter > type; }; template< typename Set, typename Tail > struct s_iter : s_iter_impl { }; template< typename Set > struct s_iter > { typedef forward_iterator_tag category; }; #else template< typename Set > struct s_end_iter { typedef forward_iterator_tag category; typedef s_iter > next; }; template< typename Set, typename Tail > struct s_iter : if_< is_same< Tail,set0<> > , s_end_iter , s_iter_impl >::type { }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION }} #endif // BOOST_MPL_SET_AUX_ITERATOR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/key_type_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_KEY_TYPE_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_KEY_TYPE_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template<> struct key_type_impl< aux::set_tag > { template< typename Set, typename T > struct apply { typedef T type; }; }; }} #endif // BOOST_MPL_SET_AUX_KEY_TYPE_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/set0.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_SET0_HPP_INCLUDED #define BOOST_MPL_SET_AUX_SET0_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include #include #include #include namespace boost { namespace mpl { #if defined(BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING) # define BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T) \ friend R BOOST_PP_CAT(BOOST_MPL_AUX_OVERLOAD_,f)(X const&, T) \ /**/ # define BOOST_MPL_AUX_SET_OVERLOAD(R, f, X, T) \ BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T) \ /**/ #else # define BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T) \ static R BOOST_PP_CAT(BOOST_MPL_AUX_OVERLOAD_,f)(X const&, T) \ /**/ # define BOOST_MPL_AUX_SET_OVERLOAD(R, f, X, T) \ BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T); \ using Base::BOOST_PP_CAT(BOOST_MPL_AUX_OVERLOAD_,f) \ /**/ #endif template< typename Dummy = na > struct set0 { typedef set0<> item_; typedef item_ type; typedef aux::set_tag tag; typedef void_ last_masked_; typedef void_ item_type_; typedef long_<0> size; typedef long_<1> order; BOOST_MPL_AUX_SET0_OVERLOAD( aux::no_tag, ORDER_BY_KEY, set0<>, void const volatile* ); BOOST_MPL_AUX_SET0_OVERLOAD( aux::yes_tag, IS_MASKED, set0<>, void const volatile* ); }; }} #endif // BOOST_MPL_SET_AUX_SET0_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/size_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_SIZE_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_SIZE_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template<> struct size_impl< aux::set_tag > { template< typename Set > struct apply : Set::size { }; }; }} #endif // BOOST_MPL_SET_AUX_SIZE_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/tag.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_TAG_HPP_INCLUDED #define BOOST_MPL_SET_AUX_TAG_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { namespace aux { struct set_tag; }}} #endif // BOOST_MPL_SET_AUX_TAG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/aux_/value_type_impl.hpp ================================================ #ifndef BOOST_MPL_SET_AUX_VALUE_TYPE_IMPL_HPP_INCLUDED #define BOOST_MPL_SET_AUX_VALUE_TYPE_IMPL_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include namespace boost { namespace mpl { template<> struct value_type_impl< aux::set_tag > { template< typename Set, typename T > struct apply { typedef T type; }; }; }} #endif // BOOST_MPL_SET_AUX_VALUE_TYPE_IMPL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/set/set0.hpp ================================================ #ifndef BOOST_MPL_SET_SET0_HPP_INCLUDED #define BOOST_MPL_SET_SET0_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif // BOOST_MPL_SET_SET0_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/size_fwd.hpp ================================================ #ifndef BOOST_MPL_SIZE_FWD_HPP_INCLUDED #define BOOST_MPL_SIZE_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct size_impl; template< typename Sequence > struct size; }} #endif // BOOST_MPL_SIZE_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/size_t.hpp ================================================ #ifndef BOOST_MPL_SIZE_T_HPP_INCLUDED #define BOOST_MPL_SIZE_T_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #define AUX_WRAPPER_VALUE_TYPE std::size_t #define AUX_WRAPPER_NAME size_t #define AUX_WRAPPER_PARAMS(N) std::size_t N #include #endif // BOOST_MPL_SIZE_T_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/size_t_fwd.hpp ================================================ #ifndef BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED #define BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2000-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include // make sure 'size_t' is placed into 'std' #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN template< std::size_t N > struct size_t; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(size_t) #endif // BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/value_type_fwd.hpp ================================================ #ifndef BOOST_MPL_VALUE_TYPE_FWD_HPP_INCLUDED #define BOOST_MPL_VALUE_TYPE_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2003-2004 // Copyright David Abrahams 2003-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ namespace boost { namespace mpl { template< typename Tag > struct value_type_impl; template< typename AssociativeSequence, typename T > struct value_type; }} #endif // BOOST_MPL_VALUE_TYPE_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/void.hpp ================================================ #ifndef BOOST_MPL_VOID_HPP_INCLUDED #define BOOST_MPL_VOID_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include #include #include #include #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN // [JDG Feb-4-2003] made void_ a complete type to allow it to be // instantiated so that it can be passed in as an object that can be // used to select an overloaded function. Possible use includes signaling // a zero arity functor evaluation call. struct void_ { typedef void_ type; }; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE namespace boost { namespace mpl { template< typename T > struct is_void_ : false_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using false_::value; #endif }; template<> struct is_void_ : true_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using true_::value; #endif }; template< typename T > struct is_not_void_ : true_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using true_::value; #endif }; template<> struct is_not_void_ : false_ { #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) using false_::value; #endif }; BOOST_MPL_AUX_NA_SPEC(1, is_void_) BOOST_MPL_AUX_NA_SPEC(1, is_not_void_) }} #endif // BOOST_MPL_VOID_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/mpl/void_fwd.hpp ================================================ #ifndef BOOST_MPL_VOID_FWD_HPP_INCLUDED #define BOOST_MPL_VOID_FWD_HPP_INCLUDED // Copyright Aleksey Gurtovoy 2001-2004 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. // $Id$ // $Date$ // $Revision$ #include BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN struct void_; BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE BOOST_MPL_AUX_ADL_BARRIER_DECL(void_) #endif // BOOST_MPL_VOID_FWD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/noncopyable.hpp ================================================ /* * Copyright (c) 2014 Glen Fernandes * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_NONCOPYABLE_HPP #define BOOST_NONCOPYABLE_HPP // The header file at this path is deprecated; // use boost/core/noncopyable.hpp instead. #include #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/arg_list.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef ARG_LIST_050329_HPP #define ARG_LIST_050329_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace parameter { // Forward declaration for aux::arg_list, below. template struct keyword; namespace aux { // Tag type passed to MPL lambda. struct lambda_tag; // // Structures used to build the tuple of actual arguments. The // tuple is a nested cons-style list of arg_list specializations // terminated by an empty_arg_list. // // Each specialization of arg_list is derived from its successor in // the list type. This feature is used along with using // declarations to build member function overload sets that can // match against keywords. // // MPL sequence support struct arg_list_tag; // Terminates arg_list<> and represents an empty list. Since this // is just the terminating case you might want to look at arg_list // first, to get a feel for what's really happening here. struct empty_arg_list { empty_arg_list() {} // Constructor taking BOOST_PARAMETER_MAX_ARITY empty_arg_list // arguments; this makes initialization empty_arg_list( BOOST_PP_ENUM_PARAMS( BOOST_PARAMETER_MAX_ARITY, void_ BOOST_PP_INTERCEPT )) {} // A metafunction class that, given a keyword and a default // type, returns the appropriate result type for a keyword // lookup given that default struct binding { template struct apply { typedef Default type; }; }; // Terminator for has_key, indicating that the keyword is unique template static no_tag has_key(KW*); #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // The overload set technique doesn't work with these older // compilers, so they need some explicit handholding. // A metafunction class that, given a keyword, returns the type // of the base sublist whose get() function can produce the // value for that key struct key_owner { template struct apply { typedef empty_arg_list type; }; }; template T& get(default_ x) const { return x.value; } template typename result_of0::type get(lazy_default x) const { return x.compute_default(); } #endif // If this function is called, it means there is no argument // in the list that matches the supplied keyword. Just return // the default value. template Default& operator[](default_ x) const { return x.value; } // If this function is called, it means there is no argument // in the list that matches the supplied keyword. Just evaluate // and return the default value. template typename result_of0::type operator[]( BOOST_PARAMETER_lazy_default_fallback x) const { return x.compute_default(); } // No argument corresponding to ParameterRequirements::key_type // was found if we match this overload, so unless that parameter // has a default, we indicate that the actual arguments don't // match the function's requirements. template static typename ParameterRequirements::has_default satisfies(ParameterRequirements*, ArgPack*); // MPL sequence support typedef empty_arg_list type; // convenience typedef arg_list_tag tag; // For dispatching to sequence intrinsics }; // Forward declaration for arg_list::operator, template struct tagged_argument; template struct get_reference { typedef typename T::reference type; }; // A tuple of tagged arguments, terminated with empty_arg_list. // Every TaggedArg is an instance of tagged_argument<>. template struct arg_list : Next { typedef arg_list self; typedef typename TaggedArg::key_type key_type; typedef typename is_maybe::type holds_maybe; typedef typename mpl::eval_if< holds_maybe , get_reference , get_reference >::type reference; typedef typename mpl::if_< holds_maybe , reference , typename TaggedArg::value_type >::type value_type; TaggedArg arg; // Stores the argument // Store the arguments in successive nodes of this list template< // class A0, class A1, ... BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A) > arg_list( // A0& a0, A1& a1, ... BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, & a) ) : Next( // a1, a2, ... BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PARAMETER_MAX_ARITY, a) , void_reference() ) , arg(a0) {} // Create a new list by prepending arg to a copy of tail. Used // when incrementally building this structure with the comma // operator. arg_list(TaggedArg head, Next const& tail) : Next(tail) , arg(head) {} // A metafunction class that, given a keyword and a default // type, returns the appropriate result type for a keyword // lookup given that default struct binding { template struct apply { typedef typename mpl::eval_if< boost::is_same , mpl::if_ , mpl::apply_wrap3 >::type type; }; }; #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // Overload for key_type, so the assert below will fire if the // same keyword is used again static yes_tag has_key(key_type*); using Next::has_key; BOOST_MPL_ASSERT_MSG( sizeof(Next::has_key((key_type*)0)) == sizeof(no_tag) , duplicate_keyword, (key_type) ); #endif // // Begin implementation of indexing operators for looking up // specific arguments by name // // Helpers that handle the case when TaggedArg is // empty. template reference get_default(D const&, mpl::false_) const { return arg.value; } template reference get_default(D const& d, mpl::true_) const { return arg.value ? arg.value.get() : arg.value.construct(d.value); } #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // These older compilers don't support the overload set creation // idiom well, so we need to do all the return type calculation // for the compiler and dispatch through an outer function template // A metafunction class that, given a keyword, returns the base // sublist whose get() function can produce the value for that // key. struct key_owner { template struct apply { typedef typename mpl::eval_if< boost::is_same , mpl::identity > , mpl::apply_wrap1 >::type type; }; }; // Outer indexing operators that dispatch to the right node's // get() function. template typename mpl::apply_wrap3::type operator[](keyword const& x) const { typename mpl::apply_wrap1::type const& sublist = *this; return sublist.get(x); } template typename mpl::apply_wrap3::type operator[](default_ x) const { typename mpl::apply_wrap1::type const& sublist = *this; return sublist.get(x); } template typename mpl::apply_wrap3< binding,KW , typename result_of0::type , mpl::true_ >::type operator[](lazy_default x) const { typename mpl::apply_wrap1::type const& sublist = *this; return sublist.get(x); } // These just return the stored value; when empty_arg_list is // reached, indicating no matching argument was passed, the // default is returned, or if no default_ or lazy_default was // passed, compilation fails. reference get(keyword const&) const { BOOST_MPL_ASSERT_NOT((holds_maybe)); return arg.value; } template reference get(default_ const& d) const { return get_default(d, holds_maybe()); } template reference get(lazy_default) const { return arg.value; } #else reference operator[](keyword const&) const { BOOST_MPL_ASSERT_NOT((holds_maybe)); return arg.value; } template reference operator[](default_ const& d) const { return get_default(d, holds_maybe()); } template reference operator[](lazy_default) const { return arg.value; } // Builds an overload set including operator[]s defined in base // classes. using Next::operator[]; // // End of indexing support // // // For parameter_requirements matching this node's key_type, // return a bool constant wrapper indicating whether the // requirements are satisfied by TaggedArg. Used only for // compile-time computation and never really called, so a // declaration is enough. // template static typename mpl::apply_wrap2< typename mpl::lambda::type , value_type, ArgPack >::type satisfies( parameter_requirements* , ArgPack* ); // Builds an overload set including satisfies functions defined // in base classes. using Next::satisfies; #endif // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template arg_list, self> operator,(tagged_argument x) const { return arg_list, self>(x, *this); } // MPL sequence support typedef self type; // Convenience for users typedef Next tail_type; // For the benefit of iterators typedef arg_list_tag tag; // For dispatching to sequence intrinsics }; // MPL sequence support template struct arg_list_iterator { typedef mpl::forward_iterator_tag category; // The incremented iterator typedef arg_list_iterator next; // dereferencing yields the key type typedef typename ArgumentPack::key_type type; }; template <> struct arg_list_iterator {}; }} // namespace parameter::aux // MPL sequence support namespace mpl { template <> struct begin_impl { template struct apply { typedef parameter::aux::arg_list_iterator type; }; }; template <> struct end_impl { template struct apply { typedef parameter::aux::arg_list_iterator type; }; }; } } // namespace boost #endif // ARG_LIST_050329_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/cast.hpp ================================================ // Copyright Daniel Wallin 2006. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_CAST_060902_HPP # define BOOST_PARAMETER_CAST_060902_HPP # include # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) # include # include # endif namespace boost { namespace parameter { namespace aux { struct use_default_tag {}; # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) # define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) value # else // Handles possible implicit casts. Used by preprocessor.hpp to // normalize user input. // // cast::execute() is identity // cast::execute() is identity // cast::execute() casts to X // // preprocessor.hpp uses this like this: // // #define X(value, predicate) // cast::execute(value) // // X(something, *) // X(something, *(predicate)) // X(something, (int)) template struct cast; template struct cast { static use_default_tag execute(use_default_tag) { return use_default_tag(); } static use_default_tag remove_const(use_default_tag) { return use_default_tag(); } template static U& execute(U& value) { return value; } template static U& remove_const(U& x) { return x; } }; #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) typedef void* voidstar; template struct cast : cast { }; #else template struct cast : cast { }; #endif // This is a hack used in cast<> to turn the user supplied type, // which may or may not be a placeholder expression into one, so // that it will be properly evaluated by mpl::apply. template struct as_placeholder_expr { typedef T type; }; template struct cast { typedef typename mpl::apply2< as_placeholder_expr, Args, Args>::type type0; typedef typename boost::add_reference< typename boost::remove_const::type >::type reference; static use_default_tag execute(use_default_tag) { return use_default_tag(); } static use_default_tag remove_const(use_default_tag) { return use_default_tag(); } static type0 execute(type0 value) { return value; } template static reference remove_const(U const& x) { return const_cast(x); } }; # define BOOST_PARAMETER_FUNCTION_CAST(value, predicate, args) \ boost::parameter::aux::cast::remove_const( \ boost::parameter::aux::cast::execute(value) \ ) # endif }}} // namespace boost::parameter::aux #endif // BOOST_PARAMETER_CAST_060902_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/default.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef DEFAULT_050329_HPP # define DEFAULT_050329_HPP # include namespace boost { namespace parameter { namespace aux { // A wrapper for the default value passed by the user when resolving // the value of the parameter with the given Keyword template struct default_ { default_(Value& x) : value(x) {} Value& value; }; // // lazy_default -- // // A wrapper for the default value computation function passed by // the user when resolving the value of the parameter with the // given keyword // # if BOOST_WORKAROUND(__EDG_VERSION__, <= 300) // These compilers need a little extra help with overload // resolution; we have empty_arg_list's operator[] accept a base // class to make that overload less preferable. template struct lazy_default_base { lazy_default_base(DefaultComputer const& x) : compute_default(x) {} DefaultComputer const& compute_default; }; template struct lazy_default : lazy_default_base { lazy_default(DefaultComputer const & x) : lazy_default_base(x) {} }; # define BOOST_PARAMETER_lazy_default_fallback lazy_default_base # else template struct lazy_default { lazy_default(const DefaultComputer& x) : compute_default(x) {} DefaultComputer const& compute_default; }; # define BOOST_PARAMETER_lazy_default_fallback lazy_default # endif }}} // namespace boost::parameter::aux #endif // DEFAULT_050329_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/is_maybe.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2010. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_IS_MAYBE_050329_HPP #define BOOST_PARAMETER_IS_MAYBE_050329_HPP #include namespace boost { namespace parameter { namespace aux { struct maybe_base {}; template struct is_maybe : is_base_and_derived {}; } // namespace aux } // namespace parameter } // namespace boost #endif // BOOST_PARAMETER_IS_MAYBE_050329_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/overloads.hpp ================================================ // Copyright David Abrahams, Daniel Wallin 2003. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // This file generates overloads in this format: // // template // typename mpl::apply_wrap1< // aux::make_arg_list< // PS0,A0 // , aux::make_arg_list< // PS1,A1 // , mpl::identity // > // > // , unnamed_list // >::type // operator()(A0 const& a0, A1 const& a1) const // { // typedef typename mpl::apply_wrap1< // aux::make_arg_list< // PS0,A0 // , aux::make_arg_list< // PS1,A1 // , mpl::identity // > // > // >::type arg_tuple; // // return arg_tuple( // a0 // , a1 // , aux::void_() // ... // ); // } // #if !defined(BOOST_PP_IS_ITERATING) # error Boost.Parameters - do not include this file! #endif #define N BOOST_PP_ITERATION() #define BOOST_PARAMETER_open_list(z, n, text) \ aux::item< \ BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n) #define BOOST_PARAMETER_close_list(z, n, text) > #define BOOST_PARAMETER_arg_list(n) \ aux::make_arg_list< \ BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \ , void_ \ BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _) \ , deduced_list \ , aux::tag_keyword_arg \ > #define BOOST_PARAMETER_arg_pack_init(z, n, limit) \ BOOST_PP_CAT(a, BOOST_PP_SUB(limit,n)) template typename mpl::first< typename BOOST_PARAMETER_arg_list(N)::type >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, & a)) const { typedef typename BOOST_PARAMETER_arg_list(N)::type result; typedef typename mpl::first::type result_type; typedef typename mpl::second::type error; error(); return result_type( BOOST_PP_ENUM(N, BOOST_PARAMETER_arg_pack_init, BOOST_PP_DEC(N)) BOOST_PP_ENUM_TRAILING_PARAMS( BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, N) , aux::void_reference() BOOST_PP_INTERCEPT )); } #undef BOOST_PARAMETER_arg_list #undef BOOST_PARAMETER_open_list #undef BOOST_PARAMETER_close_list #undef N ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/parameter_requirements.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef PARAMETER_REQUIREMENTS_050331_HPP #define PARAMETER_REQUIREMENTS_050331_HPP namespace boost { namespace parameter { namespace aux { // Used to pass static information about parameter requirements // through the satisfies() overload set (below). The // matched function is never invoked, but its type indicates whether // a parameter matches at compile-time template struct parameter_requirements { typedef Keyword keyword; typedef Predicate predicate; typedef HasDefault has_default; }; }}} // namespace boost::parameter::aux #endif // PARAMETER_REQUIREMENTS_050331_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/parenthesized_type.hpp ================================================ // Copyright David Abrahams 2006. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP # define BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP # include # include namespace boost { namespace parameter { namespace aux { // A macro that takes a parenthesized C++ type name (T) and transforms // it into an un-parenthesized type expression equivalent to T. # define BOOST_PARAMETER_PARENTHESIZED_TYPE(x) \ boost::parameter::aux::unaryfunptr_arg_type< void(*)x >::type // A metafunction that transforms void(*)(T) -> T template struct unaryfunptr_arg_type; template struct unaryfunptr_arg_type { typedef Arg type; }; template <> struct unaryfunptr_arg_type { typedef void type; }; }}} // namespace boost::parameter::aux #endif // BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/preprocessor/flatten.hpp ================================================ // Copyright Daniel Wallin 2005. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_FLATTEN_051217_HPP # define BOOST_PARAMETER_FLATTEN_051217_HPP # include # include # include # include # include # include # include # include # include # include # define BOOST_PARAMETER_FLATTEN_SPLIT_required required, # define BOOST_PARAMETER_FLATTEN_SPLIT_optional optional, # define BOOST_PARAMETER_FLATTEN_SPLIT_deduced deduced, # define BOOST_PARAMETER_FLATTEN_SPLIT(sub) \ BOOST_PP_CAT(BOOST_PARAMETER_FLATTEN_SPLIT_, sub) # define BOOST_PARAMETER_FLATTEN_QUALIFIER(sub) \ BOOST_PP_SPLIT(0, BOOST_PARAMETER_FLATTEN_SPLIT(sub)) # define BOOST_PARAMETER_FLATTEN_ARGS(sub) \ BOOST_PP_SPLIT(1, BOOST_PARAMETER_FLATTEN_SPLIT(sub)) # define BOOST_PARAMETER_FLATTEN_ARITY_optional(arities) \ BOOST_PP_TUPLE_ELEM(3,0,arities) # define BOOST_PARAMETER_FLATTEN_ARITY_required(arities) \ BOOST_PP_TUPLE_ELEM(3,1,arities) # define BOOST_PARAMETER_FLATTEN_SPEC0_DUMMY_ELEM(z, n, data) ~ # define BOOST_PARAMETER_FLATTEN_SPEC0(r, n, elem, data) \ (( \ BOOST_PP_TUPLE_ELEM(3,2,data) \ , BOOST_PP_TUPLE_REM(BOOST_PP_TUPLE_ELEM(3,0,data)) elem \ BOOST_PP_ENUM_TRAILING( \ BOOST_PP_SUB( \ BOOST_PP_TUPLE_ELEM(3,1,data) \ , BOOST_PP_TUPLE_ELEM(3,0,data) \ ) \ , BOOST_PARAMETER_FLATTEN_SPEC0_DUMMY_ELEM \ , ~ \ ) \ )) # define BOOST_PARAMETER_FLATTEN_SPEC_AUX(r, arity, max_arity, spec, transform) \ BOOST_PARAMETER_FOR_EACH_R( \ r \ , arity \ , BOOST_PARAMETER_FLATTEN_ARGS(spec) \ , (arity, max_arity, transform(BOOST_PARAMETER_FLATTEN_QUALIFIER(spec))) \ , BOOST_PARAMETER_FLATTEN_SPEC0 \ ) # define BOOST_PARAMETER_FLATTEN_IDENTITY(x) x # define BOOST_PARAMETER_FLATTEN_SPEC_optional(r, arities, spec) \ BOOST_PARAMETER_FLATTEN_SPEC_AUX( \ r \ , BOOST_PP_CAT( \ BOOST_PARAMETER_FLATTEN_ARITY_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \ )(arities) \ , BOOST_PP_TUPLE_ELEM(3,2,arities) \ , spec \ , BOOST_PARAMETER_FLATTEN_IDENTITY \ ) # define BOOST_PARAMETER_FLATTEN_SPEC_required(r, arities, spec) \ BOOST_PARAMETER_FLATTEN_SPEC_optional(r, arities, spec) # define BOOST_PARAMETER_FLATTEN_SPEC_AS_DEDUCED(x) BOOST_PP_CAT(deduced_,x) # define BOOST_PARAMETER_FLATTEN_SPEC_deduced_M(r, arities, n, spec) \ BOOST_PARAMETER_FLATTEN_SPEC_AUX( \ r \ , BOOST_PP_CAT( \ BOOST_PARAMETER_FLATTEN_ARITY_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \ )(arities) \ , BOOST_PP_TUPLE_ELEM(3,2,arities) \ , spec \ , BOOST_PARAMETER_FLATTEN_SPEC_AS_DEDUCED \ ) # define BOOST_PARAMETER_FLATTEN_SPEC_deduced(r, arities, spec) \ BOOST_PP_SEQ_FOR_EACH_I_R( \ r \ , BOOST_PARAMETER_FLATTEN_SPEC_deduced_M \ , arities \ , BOOST_PARAMETER_FLATTEN_ARGS(spec) \ ) # define BOOST_PARAMETER_FLATTEN_SPEC(r, arities, spec) \ BOOST_PP_CAT( \ BOOST_PARAMETER_FLATTEN_SPEC_, BOOST_PARAMETER_FLATTEN_QUALIFIER(spec) \ )(r, arities, spec) # define BOOST_PARAMETER_FLATTEN(optional_arity, required_arity, wanted_arity, specs) \ BOOST_PP_SEQ_FOR_EACH( \ BOOST_PARAMETER_FLATTEN_SPEC \ , ( \ optional_arity, required_arity \ , wanted_arity \ ) \ , specs \ ) #endif // BOOST_PARAMETER_FLATTEN_051217_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/preprocessor/for_each.hpp ================================================ // Copyright Daniel Wallin 2005. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_FOR_EACH_051217_HPP # define BOOST_PARAMETER_FOR_EACH_051217_HPP # include # include # include # include # include # include # include # include # include # include # define BOOST_PARAMETER_FOR_EACH_head_aux2(x,y) (x,y), ~ # define BOOST_PARAMETER_FOR_EACH_head_aux3(x,y,z) (x,y,z), ~ # define BOOST_PARAMETER_FOR_EACH_head_aux4(x,y,z,u) (x,y,z,u), ~ # define BOOST_PARAMETER_FOR_EACH_head(n,x) \ BOOST_PP_SPLIT(0, BOOST_PP_CAT(BOOST_PARAMETER_FOR_EACH_head_aux,n) x) # define BOOST_PARAMETER_FOR_EACH_pred_aux_BOOST_PARAMETER_FOR_EACH_END_SENTINEL # define BOOST_PARAMETER_FOR_EACH_pred_aux_check(x) \ BOOST_PP_NOT(BOOST_PP_IS_EMPTY( \ BOOST_PP_CAT(BOOST_PARAMETER_FOR_EACH_pred_aux_, x) \ )), ~ # define BOOST_PARAMETER_FOR_EACH_pred_aux2(x,y) \ BOOST_PARAMETER_FOR_EACH_pred_aux_check(x) # define BOOST_PARAMETER_FOR_EACH_pred_aux3(x,y,z) \ BOOST_PARAMETER_FOR_EACH_pred_aux_check(x) # define BOOST_PARAMETER_FOR_EACH_pred_aux4(x,y,z,u) \ BOOST_PARAMETER_FOR_EACH_pred_aux_check(x) # define BOOST_PARAMETER_FOR_EACH_pred_aux0(n,x) \ BOOST_PP_CAT(BOOST_PARAMETER_FOR_EACH_pred_aux,n) x # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PARAMETER_FOR_EACH_pred_SPLIT_FIRST(x) \ BOOST_PP_SPLIT(0, x) # define BOOST_PARAMETER_FOR_EACH_pred(r, state) \ BOOST_PARAMETER_FOR_EACH_pred_SPLIT_FIRST( \ BOOST_PARAMETER_FOR_EACH_pred_aux0( \ BOOST_PP_TUPLE_ELEM(5,3,state) \ , BOOST_PP_TUPLE_ELEM(5,0,state) \ ) \ ) # else # define BOOST_PARAMETER_FOR_EACH_pred(r, state) \ BOOST_PP_SPLIT( \ 0 \ , BOOST_PARAMETER_FOR_EACH_pred_aux0( \ BOOST_PP_TUPLE_ELEM(5,3,state) \ , BOOST_PP_TUPLE_ELEM(5,0,state) \ ) \ ) # endif # define BOOST_PARAMETER_FOR_EACH_op(r, state) \ ( \ BOOST_PP_TUPLE_EAT(BOOST_PP_TUPLE_ELEM(5,3,state)) \ BOOST_PP_TUPLE_ELEM(5,0,state) \ , BOOST_PP_TUPLE_ELEM(5,1,state) \ , BOOST_PP_TUPLE_ELEM(5,2,state) \ , BOOST_PP_TUPLE_ELEM(5,3,state) \ , BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(5,4,state)) \ ) # define BOOST_PARAMETER_FOR_EACH_macro(r, state) \ BOOST_PP_TUPLE_ELEM(5,2,state)( \ r \ , BOOST_PP_TUPLE_ELEM(5,4,state) \ , BOOST_PARAMETER_FOR_EACH_head( \ BOOST_PP_TUPLE_ELEM(5,3,state) \ , BOOST_PP_TUPLE_ELEM(5,0,state) \ ) \ , BOOST_PP_TUPLE_ELEM(5,1,state) \ ) # define BOOST_PARAMETER_FOR_EACH_build_end_sentinel(z,n,text) \ BOOST_PP_COMMA_IF(n) BOOST_PARAMETER_FOR_EACH_END_SENTINEL # define BOOST_PARAMETER_FOR_EACH_build_end_sentinel_tuple(arity) \ ( \ BOOST_PP_REPEAT(arity, BOOST_PARAMETER_FOR_EACH_build_end_sentinel, _) \ ) # define BOOST_PARAMETER_FOR_EACH_R(r, arity, list, data, macro) \ BOOST_PP_CAT(BOOST_PP_FOR_, r)( \ (list BOOST_PARAMETER_FOR_EACH_build_end_sentinel_tuple(arity), data, macro, arity, 0) \ , BOOST_PARAMETER_FOR_EACH_pred \ , BOOST_PARAMETER_FOR_EACH_op \ , BOOST_PARAMETER_FOR_EACH_macro \ ) # define BOOST_PARAMETER_FOR_EACH(arity, list, data, macro) \ BOOST_PARAMETER_FOR_EACH_R(BOOST_PP_DEDUCE_R(), arity, list, data, macro) #endif // BOOST_PARAMETER_FOR_EACH_051217_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/result_of0.hpp ================================================ // Copyright David Abrahams 2005. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP # define BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP # include // A metafunction returning the result of invoking a nullary function // object of the given type. #ifndef BOOST_NO_RESULT_OF # include namespace boost { namespace parameter { namespace aux { template struct result_of0 : result_of {}; }}} // namespace boost::parameter::aux_ #else namespace boost { namespace parameter { namespace aux { template struct result_of0 { typedef typename F::result_type type; }; }}} // namespace boost::parameter::aux_ #endif #endif // BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/set.hpp ================================================ // Copyright Daniel Wallin 2006. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_SET_060912_HPP # define BOOST_PARAMETER_SET_060912_HPP # include # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) # include # include # include namespace boost { namespace parameter { namespace aux { typedef mpl::set0<> set0; template struct insert_ { typedef typename mpl::insert::type type; }; template struct has_key_ { typedef typename mpl::has_key::type type; }; }}} // namespace boost::parameter::aux # else # include # include # include # include # include namespace boost { namespace parameter { namespace aux { typedef mpl::list0<> set0; template struct insert_ { typedef typename mpl::push_front::type type; }; template struct has_key_ { typedef typename mpl::find::type iter; typedef mpl::not_< is_same::type> > type; }; }}} // namespace boost::parameter::aux # endif #endif // BOOST_PARAMETER_SET_060912_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/tag.hpp ================================================ // Copyright David Abrahams 2005. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP # define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP # include # include namespace boost { namespace parameter { namespace aux { template ::type #endif > struct tag { typedef tagged_argument< Keyword , typename unwrap_cv_reference::type > type; }; #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template struct tag { typedef tagged_argument< Keyword , ActualArg > type; }; #endif }}} // namespace boost::parameter::aux_ #endif // BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/tagged_argument.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP # define BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP # include # include # include # include # include # include # include # include # include # include namespace boost { namespace parameter { namespace aux { struct empty_arg_list; struct arg_list_tag; struct tagged_argument_base {}; // Holds a reference to an argument of type Arg associated with // keyword Keyword template struct tagged_argument : tagged_argument_base { typedef Keyword key_type; typedef Arg value_type; typedef Arg& reference; tagged_argument(reference x) : value(x) {} // A metafunction class that, given a keyword and a default // type, returns the appropriate result type for a keyword // lookup given that default struct binding { template struct apply { typedef typename mpl::eval_if< boost::is_same , mpl::if_ , mpl::identity >::type type; }; }; // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template arg_list< tagged_argument , arg_list > > operator,(tagged_argument x) const { return arg_list< tagged_argument , arg_list > >( *this , arg_list >(x, empty_arg_list()) ); } reference operator[](keyword const&) const { return value; } # if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template Default& get_with_default(default_ const& x, int) const { return x.value; } template reference get_with_default(default_ const&, long) const { return value; } template typename mpl::apply_wrap3::type operator[](default_ const& x) const { return get_with_default(x, 0L); } template typename result_of0::type get_with_lazy_default(lazy_default const& x, int) const { return x.compute_default(); } template reference get_with_lazy_default(lazy_default const&, long) const { return value; } template typename mpl::apply_wrap3< binding,KW , typename result_of0::type , mpl::true_ >::type operator[](lazy_default const& x) const { return get_with_lazy_default(x, 0L); } # else template reference operator[](default_ const& ) const { return value; } template reference operator[](lazy_default const& ) const { return value; } template Default& operator[](default_ const& x) const { return x.value; } template typename result_of0::type operator[](lazy_default const& x) const { return x.compute_default(); } template static typename ParameterRequirements::has_default satisfies(ParameterRequirements*); template static typename mpl::apply1::type satisfies( parameter_requirements* ); # endif reference value; # if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) // warning suppression private: void operator=(tagged_argument const&); public: # endif // MPL sequence support typedef tagged_argument type; // Convenience for users typedef empty_arg_list tail_type; // For the benefit of iterators typedef arg_list_tag tag; // For dispatching to sequence intrinsics }; // Defines a metafunction, is_tagged_argument, that identifies // tagged_argument specializations and their derived classes. template struct is_tagged_argument_aux : is_convertible {}; template struct is_tagged_argument : mpl::and_< mpl::not_ > , is_tagged_argument_aux > {}; }}} // namespace boost::parameter::aux #endif // BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/template_keyword.hpp ================================================ // Copyright Daniel Wallin 2006. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_TEMPLATE_KEYWORD_060203_HPP # define BOOST_PARAMETER_TEMPLATE_KEYWORD_060203_HPP # include # include # include # include namespace boost { namespace parameter { namespace aux { struct template_keyword_tag {}; template struct is_pointer_convertible : is_convertible {}; template struct is_template_keyword : mpl::and_< mpl::not_ > , is_pointer_convertible > {}; } // namespace aux template struct template_keyword : aux::template_keyword_tag { typedef Tag key_type; typedef T value_type; typedef value_type reference; }; }} // namespace boost::parameter #endif // BOOST_PARAMETER_TEMPLATE_KEYWORD_060203_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/unwrap_cv_reference.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef UNWRAP_CV_REFERENCE_050328_HPP #define UNWRAP_CV_REFERENCE_050328_HPP #include #include #include #include namespace boost { template class reference_wrapper; } namespace boost { namespace parameter { namespace aux { // // reference_wrapper support -- because of the forwarding problem, // when passing arguments positionally by non-const reference, we // ask users of named parameter interfaces to use ref(x) to wrap // them. // // is_cv_reference_wrapper returns mpl::true_ if T is of type // reference_wrapper cv template yes_tag is_cv_reference_wrapper_check(reference_wrapper const volatile*); no_tag is_cv_reference_wrapper_check(...); template struct is_cv_reference_wrapper { BOOST_STATIC_CONSTANT( bool, value = ( sizeof(is_cv_reference_wrapper_check((T*)0)) == sizeof(yes_tag) ) ); typedef mpl::bool_< #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) is_cv_reference_wrapper:: #endif value> type; }; // Needed for unwrap_cv_reference below. T might be const, so // eval_if might fail because of deriving from T const on EDG. template struct get_type { typedef typename T::type type; }; #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template ::type> struct unwrap_cv_reference { typedef T type; }; template struct unwrap_cv_reference { typedef T const type; }; template struct unwrap_cv_reference : T {}; #else // Produces the unwrapped type to hold a reference to in named<> // Can't use boost::unwrap_reference<> here because it // doesn't handle the case where T = reference_wrapper cv template struct unwrap_cv_reference { typedef typename mpl::eval_if< is_cv_reference_wrapper , get_type , mpl::identity >::type type; }; #endif }}} // namespace boost::parameter::aux #endif // UNWRAP_CV_REFERENCE_050328_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/void.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_VOID_050329_HPP #define BOOST_PARAMETER_VOID_050329_HPP namespace boost { namespace parameter { // A placemarker for "no argument passed." // MAINTAINER NOTE: Do not make this into a metafunction struct void_ {}; namespace aux { inline void_& void_reference() { static void_ instance; return instance; } } // namespace aux }} // namespace boost::parameter #endif // BOOST_PARAMETER_VOID_050329_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/aux_/yesno.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef YESNO_050328_HPP #define YESNO_050328_HPP #include namespace boost { namespace parameter { namespace aux { // types used with the "sizeof trick" to capture the results of // overload resolution at compile-time. typedef char yes_tag; typedef char (&no_tag)[2]; // mpl::true_ and mpl::false_ are not distinguishable by sizeof(), // so we pass them through these functions to get a type that is. yes_tag to_yesno(mpl::true_); no_tag to_yesno(mpl::false_); }}} // namespace boost::parameter::aux #endif // YESNO_050328_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/binding.hpp ================================================ // Copyright David Abrahams 2005. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_BINDING_DWA200558_HPP # define BOOST_PARAMETER_BINDING_DWA200558_HPP # include # include # include # include # include # include namespace boost { namespace parameter { // A metafunction that, given an argument pack, returns the type of // the parameter identified by the given keyword. If no such // parameter has been specified, returns Default # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template struct binding0 { typedef typename mpl::apply_wrap3< typename Parameters::binding,Keyword,Default,mpl::true_ >::type type; BOOST_MPL_ASSERT_NOT(( mpl::and_< is_same , is_same > )); }; # endif template struct binding { # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) typedef typename mpl::eval_if< mpl::is_placeholder , mpl::identity , binding0 >::type type; # else typedef typename mpl::apply_wrap3< typename Parameters::binding,Keyword,Default,mpl::true_ >::type type; BOOST_MPL_ASSERT_NOT(( mpl::and_< is_same , is_same > )); # endif BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default)) }; // A metafunction that, given an argument pack, returns the type of // the parameter identified by the given keyword. If no such // parameter has been specified, returns the type returned by invoking // DefaultFn template struct lazy_binding { typedef typename mpl::apply_wrap3< typename Parameters::binding , Keyword , typename aux::result_of0::type , mpl::true_ >::type type; }; }} // namespace boost::parameter #endif // BOOST_PARAMETER_BINDING_DWA200558_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/config.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_CONFIG_050403_HPP #define BOOST_PARAMETER_CONFIG_050403_HPP #ifndef BOOST_PARAMETER_MAX_ARITY # define BOOST_PARAMETER_MAX_ARITY 8 #endif #endif // BOOST_PARAMETER_CONFIG_050403_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/keyword.hpp ================================================ // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef KEYWORD_050328_HPP #define KEYWORD_050328_HPP #include #include #include namespace boost { namespace parameter { // Instances of unique specializations of keyword<...> serve to // associate arguments with parameter names. For example: // // struct rate_; // parameter names // struct skew_; // namespace // { // keyword rate; // keywords // keyword skew; // } // // ... // // f(rate = 1, skew = 2.4); // template struct keyword { template typename aux::tag::type const operator=(T& x) const { typedef typename aux::tag::type result; return result(x); } template aux::default_ operator|(Default& default_) const { return aux::default_(default_); } template aux::lazy_default operator||(Default& default_) const { return aux::lazy_default(default_); } template typename aux::tag::type const operator=(T const& x) const { typedef typename aux::tag::type result; return result(x); } template aux::default_ operator|(const Default& default_) const { return aux::default_(default_); } template aux::lazy_default operator||(Default const& default_) const { return aux::lazy_default(default_); } public: // Insurance against ODR violations // People will need to define these keywords in header files. To // prevent ODR violations, it's important that the keyword used in // every instantiation of a function template is the same object. // We provide a reference to a common instance of each keyword // object and prevent construction by users. static keyword const instance; // This interface is deprecated static keyword& get() { return const_cast&>(instance); } }; template keyword const keyword::instance = {}; // Reduces boilerplate required to declare and initialize keywords // without violating ODR. Declares a keyword tag type with the given // name in namespace tag_namespace, and declares and initializes a // reference in an anonymous namespace to a singleton instance of that // type. #define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \ namespace tag_namespace \ { \ struct name \ { \ static char const* keyword_name() \ { \ return #name; \ } \ }; \ } \ namespace \ { \ ::boost::parameter::keyword const& name \ = ::boost::parameter::keyword::instance;\ } }} // namespace boost::parameter #endif // KEYWORD_050328_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/macros.hpp ================================================ // Copyright David Abrahams, Daniel Wallin 2003. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_MACROS_050412_HPP #define BOOST_PARAMETER_MACROS_050412_HPP #include #include #include #include #include #include #include #include #include #include #define BOOST_PARAMETER_FUN_TEMPLATE_HEAD1(n) \ template #define BOOST_PARAMETER_FUN_TEMPLATE_HEAD0(n) #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) # define BOOST_PARAMETER_MATCH_TYPE(n, param) \ BOOST_PP_EXPR_IF(n, typename) param::match \ < \ BOOST_PP_ENUM_PARAMS(n, T) \ >::type #else # define BOOST_PARAMETER_MATCH_TYPE(n, param) param #endif #define BOOST_PARAMETER_FUN_DECL(z, n, params) \ \ BOOST_PP_CAT(BOOST_PARAMETER_FUN_TEMPLATE_HEAD, BOOST_PP_BOOL(n))(n) \ \ BOOST_PP_TUPLE_ELEM(3, 0, params) \ BOOST_PP_TUPLE_ELEM(3, 1, params)( \ BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& p) \ BOOST_PP_COMMA_IF(n) \ BOOST_PARAMETER_MATCH_TYPE(n,BOOST_PP_TUPLE_ELEM(3, 2, params)) \ kw = BOOST_PP_TUPLE_ELEM(3, 2, params)() \ ) \ { \ return BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, params), _with_named_params)( \ kw(BOOST_PP_ENUM_PARAMS(n, p)) \ ); \ } // Generates: // // template // ret name ## _with_named_params(Params const&); // // template // ret name(T0 const& p0, typename parameters::match::type kw = parameters()) // { // return name ## _with_named_params(kw(p0)); // } // // template // ret name(T0 const& p0, ..., TN const& PN // , typename parameters::match::type kw = parameters()) // { // return name ## _with_named_params(kw(p0, ..., pN)); // } // // template // ret name ## _with_named_params(Params const&) // // lo and hi determines the min and max arity of the generated functions. #define BOOST_PARAMETER_FUN(ret, name, lo, hi, parameters) \ \ template \ ret BOOST_PP_CAT(name, _with_named_params)(Params const& p); \ \ BOOST_PP_REPEAT_FROM_TO( \ lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \ \ template \ ret BOOST_PP_CAT(name, _with_named_params)(Params const& p) #define BOOST_PARAMETER_MEMFUN(ret, name, lo, hi, parameters) \ \ BOOST_PP_REPEAT_FROM_TO( \ lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \ \ template \ ret BOOST_PP_CAT(name, _with_named_params)(Params const& p) #endif // BOOST_PARAMETER_MACROS_050412_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/match.hpp ================================================ // Copyright David Abrahams 2005. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_MATCH_DWA2005714_HPP # define BOOST_PARAMETER_MATCH_DWA2005714_HPP # include # include # if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // Temporary version of BOOST_PP_SEQ_ENUM until Paul M. integrates the workaround. # define BOOST_PARAMETER_SEQ_ENUM_I(size,seq) BOOST_PP_CAT(BOOST_PP_SEQ_ENUM_, size) seq # define BOOST_PARAMETER_SEQ_ENUM(seq) BOOST_PARAMETER_SEQ_ENUM_I(BOOST_PP_SEQ_SIZE(seq), seq) # else # define BOOST_PARAMETER_SEQ_ENUM(seq) BOOST_PP_SEQ_ENUM(seq) # endif # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) # include # include # include # include # include # define BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) \ BOOST_PP_ENUM_TRAILING_PARAMS( \ BOOST_PP_SUB( \ BOOST_PARAMETER_MAX_ARITY \ , BOOST_PP_SEQ_SIZE(ArgTypes) \ ) \ , ::boost::parameter::void_ BOOST_PP_INTERCEPT \ ) # else # define BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) # endif // // Generates, e.g. // // typename dfs_params::match::type name = dfs_params() // // with workarounds for Borland compatibility. // # define BOOST_PARAMETER_MATCH(ParameterSpec, ArgTypes, name) \ typename ParameterSpec ::match< \ BOOST_PARAMETER_SEQ_ENUM(ArgTypes) \ BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) \ >::type name = ParameterSpec () #endif // BOOST_PARAMETER_MATCH_DWA2005714_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/name.hpp ================================================ // Copyright Daniel Wallin 2006. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_NAME_060806_HPP # define BOOST_PARAMETER_NAME_060806_HPP # include # include # include # include # include # include # include # include # include # if !defined(BOOST_NO_SFINAE) \ && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) # include # include namespace boost { namespace parameter { namespace aux { // Tag type passed to MPL lambda. struct lambda_tag; struct name_tag_base {}; template struct name_tag {}; template struct is_name_tag : mpl::false_ {}; }}} // namespace boost::parameter::aux namespace boost { namespace mpl { template struct lambda< T , typename boost::enable_if< parameter::aux::is_name_tag, parameter::aux::lambda_tag >::type > { typedef true_ is_le; typedef bind3< quote3, arg<2>, T, void> result_; typedef result_ type; }; }} // namespace boost::mpl # endif # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) # include // From Paul Mensonides # define BOOST_PARAMETER_IS_BINARY(x) \ BOOST_PP_SPLIT(1, BOOST_PARAMETER_IS_BINARY_C x BOOST_PP_COMMA() 0) \ /**/ # define BOOST_PARAMETER_IS_BINARY_C(x,y) \ ~, 1 BOOST_PP_RPAREN() \ BOOST_PP_TUPLE_EAT(2) BOOST_PP_LPAREN() ~ \ /**/ # else # include # define BOOST_PARAMETER_IS_BINARY(x) BOOST_PP_IS_BINARY(x) # endif # define BOOST_PARAMETER_BASIC_NAME(tag_namespace, tag, name) \ namespace tag_namespace \ { \ struct tag \ { \ static char const* keyword_name() \ { \ return BOOST_PP_STRINGIZE(tag); \ } \ \ typedef boost::parameter::value_type< \ boost::mpl::_2, tag, boost::parameter::void_ \ > _; \ \ typedef boost::parameter::value_type< \ boost::mpl::_2, tag, boost::parameter::void_ \ > _1; \ }; \ } \ namespace \ { \ ::boost::parameter::keyword const& name \ = ::boost::parameter::keyword::instance; \ } # define BOOST_PARAMETER_COMPLEX_NAME_TUPLE1(tag,namespace) \ (tag, namespace), ~ # define BOOST_PARAMETER_COMPLEX_NAME_TUPLE(name) \ BOOST_PP_TUPLE_ELEM(2, 0, (BOOST_PARAMETER_COMPLEX_NAME_TUPLE1 name)) # define BOOST_PARAMETER_COMPLEX_NAME_TAG(name) \ BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PARAMETER_COMPLEX_NAME_TUPLE(name)) # define BOOST_PARAMETER_COMPLEX_NAME_NAMESPACE(name) \ BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PARAMETER_COMPLEX_NAME_TUPLE(name)) # define BOOST_PARAMETER_COMPLEX_NAME(name) \ BOOST_PARAMETER_BASIC_NAME( \ BOOST_PARAMETER_COMPLEX_NAME_NAMESPACE(name) \ , BOOST_PP_TUPLE_EAT(2) name \ , BOOST_PARAMETER_COMPLEX_NAME_TAG(name) \ ) \ /**/ # define BOOST_PARAMETER_SIMPLE_NAME(name) \ BOOST_PARAMETER_BASIC_NAME(tag, name, BOOST_PP_CAT(_, name)) # define BOOST_PARAMETER_NAME(name) \ BOOST_PP_IIF( \ BOOST_PARAMETER_IS_BINARY(name) \ , BOOST_PARAMETER_COMPLEX_NAME \ , BOOST_PARAMETER_SIMPLE_NAME \ )(name) \ /**/ # define BOOST_PARAMETER_TEMPLATE_KEYWORD(name) \ namespace tag \ { \ struct name; \ } \ template \ struct name \ : boost::parameter::template_keyword \ {}; \ /**/ #endif // BOOST_PARAMETER_NAME_060806_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/parameters.hpp ================================================ // Copyright David Abrahams, Daniel Wallin 2003. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETERS_031014_HPP #define BOOST_PARAMETERS_031014_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace parameter_ { template struct unmatched_argument { BOOST_MPL_ASSERT((boost::is_same)); typedef int type; }; } // namespace parameter_ namespace boost { template class reference_wrapper; namespace parameter { namespace aux { struct use_default {}; } // These templates can be used to describe the treatment of particular // named parameters for the purposes of overload elimination with // SFINAE, by placing specializations in the parameters<...> list. In // order for a treated function to participate in overload resolution: // // - all keyword tags wrapped in required<...> must have a matching // actual argument // // - The actual argument type matched by every keyword tag // associated with a predicate must satisfy that predicate // // If a keyword k is specified without an optional<...> or // required<...>, wrapper, it is treated as though optional were // specified. // // If a keyword k is specified with deduced<...>, that keyword // will be automatically deduced from the argument list. // template struct required { typedef Tag key_type; typedef Predicate predicate; }; template struct optional { typedef Tag key_type; typedef Predicate predicate; }; template struct deduced { typedef Tag key_type; }; namespace aux { // Defines metafunctions, is_required and is_optional, that // identify required<...>, optional<...> and deduced<...> specializations. BOOST_DETAIL_IS_XXX_DEF(required, required, 2) BOOST_DETAIL_IS_XXX_DEF(optional, optional, 2) BOOST_DETAIL_IS_XXX_DEF(deduced_aux, deduced, 1) template struct is_deduced0 : is_deduced_aux< typename S::key_type >::type {}; template struct is_deduced : mpl::eval_if< mpl::or_< is_optional, is_required > , is_deduced0 , mpl::false_ >::type {}; // // key_type, has_default, and predicate -- // // These metafunctions accept a ParameterSpec and extract the // keyword tag, whether or not a default is supplied for the // parameter, and the predicate that the corresponding actual // argument type is required match. // // a ParameterSpec is a specialization of either keyword<...>, // required<...>, optional<...> // // helper for key_type<...>, below. template struct get_tag_type0 { typedef typename T::key_type type; }; template struct get_tag_type : mpl::eval_if< is_deduced_aux , get_tag_type0 , mpl::identity > {}; template struct tag_type : mpl::eval_if< mpl::or_< is_optional , is_required > , get_tag_type , mpl::identity > {}; template struct has_default : mpl::not_ > {}; // helper for get_predicate<...>, below template struct get_predicate_or_default { typedef T type; }; template <> struct get_predicate_or_default { typedef mpl::always type; }; // helper for predicate<...>, below template struct get_predicate { typedef typename get_predicate_or_default::type type; }; template struct predicate : mpl::eval_if< mpl::or_< is_optional , is_required > , get_predicate , mpl::identity > > { }; // Converts a ParameterSpec into a specialization of // parameter_requirements. We need to do this in order to get the // tag_type into the type in a way that can be conveniently matched // by a satisfies(...) member function in arg_list. template struct as_parameter_requirements { typedef parameter_requirements< typename tag_type::type , typename predicate::type , typename has_default::type > type; }; template struct is_named_argument : mpl::or_< is_template_keyword , is_tagged_argument > {}; // Returns mpl::true_ iff the given ParameterRequirements are // satisfied by ArgList. template struct satisfies { #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) // VC7.1 can't handle the sizeof() implementation below, // so we use this instead. typedef typename mpl::apply_wrap3< typename ArgList::binding , typename ParameterRequirements::keyword , void_ , mpl::false_ >::type bound; typedef typename mpl::eval_if< is_same , typename ParameterRequirements::has_default , mpl::apply_wrap2< typename mpl::lambda< typename ParameterRequirements::predicate, lambda_tag >::type , bound , ArgList > >::type type; #else BOOST_STATIC_CONSTANT( bool, value = ( sizeof( aux::to_yesno( ArgList::satisfies((ParameterRequirements*)0, (ArgList*)0) ) ) == sizeof(yes_tag) ) ); typedef mpl::bool_ type; #endif }; // Returns mpl::true_ if the requirements of the given ParameterSpec // are satisfied by ArgList. template struct satisfies_requirements_of : satisfies< ArgList , typename as_parameter_requirements::type > {}; // Tags a deduced argument Arg with the keyword tag of Spec using TagFn. // Returns the tagged argument and the mpl::set<> UsedArgs with the // tag of Spec inserted. template struct tag_deduced { typedef mpl::pair< typename mpl::apply_wrap2::type, Arg>::type , typename aux::insert_::type>::type > type; }; template < class Argument , class ArgumentPack , class DeducedArgs , class UsedArgs , class TagFn > struct deduce_tag; // Tag type passed to MPL lambda. struct lambda_tag; // Helper for deduce_tag<> below. template < class Argument , class ArgumentPack , class DeducedArgs , class UsedArgs , class TagFn > struct deduce_tag0 { typedef typename DeducedArgs::spec spec; typedef typename mpl::apply_wrap2< typename mpl::lambda< typename spec::predicate, lambda_tag >::type , Argument , ArgumentPack >::type condition; // Deduced parameter matches several arguments. BOOST_MPL_ASSERT(( mpl::not_::type> > > )); typedef typename mpl::eval_if< condition , tag_deduced , deduce_tag >::type type; }; // Tries to deduced a keyword tag for a given Argument. // Returns an mpl::pair<> consisting of the tagged_argument<>, // and an mpl::set<> where the new tag has been inserted. // // Argument: The argument type to be tagged. // // ArgumentPack: The ArgumentPack built so far. // // DeducedArgs: A specialization of deduced_item<> (see below). // A list containing only the deduced ParameterSpecs. // // UsedArgs: An mpl::set<> containing the keyword tags used so far. // // TagFn: A metafunction class used to tag positional or deduced // arguments with a keyword tag. template < class Argument , class ArgumentPack , class DeducedArgs , class UsedArgs , class TagFn > struct deduce_tag { typedef typename mpl::eval_if< is_same , mpl::pair , deduce_tag0 >::type type; }; template < class List , class DeducedArgs , class TagFn , class Positional , class UsedArgs , class ArgumentPack , class Error > struct make_arg_list_aux; // Inserts Tagged::key_type into the UserArgs set. // Extra indirection to lazily evaluate Tagged::key_type. template struct insert_tagged { typedef typename aux::insert_< UsedArgs, typename Tagged::key_type >::type type; }; // Borland needs the insane extra-indirection workaround below // so that it doesn't magically drop the const qualifier from // the argument type. template < class List , class DeducedArgs , class TagFn , class Positional , class UsedArgs , class ArgumentPack #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) , class argument #endif , class Error > #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) struct make_arg_list00 #else struct make_arg_list0 #endif { #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) typedef typename List::arg argument; #endif typedef typename List::spec parameter_spec; typedef typename tag_type::type tag_; typedef is_named_argument is_tagged; // If this argument is either explicitly tagged or a deduced // parameter, we turn off positional matching. typedef mpl::and_< mpl::not_< mpl::or_, is_tagged> > , Positional > positional; // If this parameter is explicitly tagged we add it to the // used-parmeters set. We only really need to add parameters // that are deduced, but we would need a way to check if // a given tag corresponds to a deduced parameter spec. typedef typename mpl::eval_if< is_tagged , insert_tagged , mpl::identity >::type used_args; // If this parameter is neither explicitly tagged, nor // positionally matched; deduce the tag from the deduced // parameter specs. typedef typename mpl::eval_if< mpl::or_ , mpl::pair , deduce_tag >::type deduced_data; // If this parameter is explicitly tagged.. typedef typename mpl::eval_if< is_tagged , mpl::identity // .. just use it , mpl::eval_if< // .. else, if positional matching is turned on.. positional , mpl::apply_wrap2 // .. tag it positionally , mpl::first // .. else, use the deduced tag > >::type tagged; // We build the arg_list incrementally as we go, prepending new // nodes. typedef typename mpl::if_< mpl::and_< is_same , is_same > , parameter_::unmatched_argument , void_ >::type error; typedef typename mpl::if_< is_same , ArgumentPack , arg_list >::type argument_pack; typedef typename make_arg_list_aux< typename List::tail , DeducedArgs , TagFn , positional , typename deduced_data::second , argument_pack , error >::type type; }; #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template < class List , class DeducedArgs , class TagFn , class Positional , class UsedArgs , class ArgumentPack , class Error > struct make_arg_list0 { typedef typename mpl::eval_if< typename List::is_arg_const , make_arg_list00< List , DeducedArgs , TagFn , Positional , UsedArgs , ArgumentPack , typename List::arg const , Error > , make_arg_list00< List , DeducedArgs , TagFn , Positional , UsedArgs , ArgumentPack , typename List::arg , Error > >::type type; }; #endif // Returns an ArgumentPack where the list of arguments has // been tagged with keyword tags. // // List: A specialization of item<> (see below). Contains // both the ordered ParameterSpecs, and the given arguments. // // DeducedArgs: A specialization of deduced_item<> (see below). // A list containing only the deduced ParameterSpecs. // // TagFn: A metafunction class used to tag positional or deduced // arguments with a keyword tag. // // Position: An mpl::bool_<> specialization indicating if positional // matching is to be performed. // // DeducedSet: An mpl::set<> containing the keyword tags used so far. // // ArgumentPack: The ArgumentPack built so far. This is initially an // empty_arg_list and is built incrementally. // template < class List , class DeducedArgs , class TagFn , class Positional , class DeducedSet , class ArgumentPack , class Error > struct make_arg_list_aux { typedef typename mpl::eval_if< is_same , mpl::identity > , make_arg_list0 >::type type; }; // VC6.5 was choking on the default parameters for make_arg_list_aux, so // this just forwards to that adding in the defaults. template < class List , class DeducedArgs , class TagFn , class EmitErrors = mpl::true_ > struct make_arg_list { typedef typename make_arg_list_aux< List, DeducedArgs, TagFn, mpl::true_, aux::set0, empty_arg_list, void_ >::type type; }; // A parameter spec item typelist. template struct item { typedef Spec spec; #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) typedef is_const is_arg_const; #endif typedef Arg arg; typedef Tail tail; }; template struct make_item { typedef item type; }; // Creates a item typelist. template struct make_items { typedef typename mpl::eval_if< is_same , mpl::identity , make_item >::type type; }; // A typelist that stored deduced parameter specs. template struct deduced_item { typedef ParameterSpec spec; typedef Tail tail; }; // Evaluate Tail and construct deduced_item list. template struct make_deduced_item { typedef deduced_item type; }; template struct make_deduced_items { typedef typename mpl::eval_if< is_same , mpl::identity , mpl::eval_if< is_deduced , make_deduced_item , Tail > >::type type; }; // Generates: // // make< // parameter_spec#0, argument_type#0 // , make< // parameter_spec#1, argument_type#1 // , ... mpl::identity // ...> // > #define BOOST_PARAMETER_make_arg_list(z, n, names) \ BOOST_PP_SEQ_ELEM(0,names)< \ BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n), \ BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n), #define BOOST_PARAMETER_right_angle(z, n, text) > #define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type) \ BOOST_PP_REPEAT( \ n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)) \ mpl::identity \ BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _) #define BOOST_PARAMETER_make_deduced_list(z, n, names) \ BOOST_PP_SEQ_ELEM(0,names)< \ BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n), #define BOOST_PARAMETER_build_deduced_list(n, make, parameter_spec) \ BOOST_PP_REPEAT( \ n, BOOST_PARAMETER_make_deduced_list, (make)(parameter_spec)) \ mpl::identity \ BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _) struct tag_keyword_arg { template struct apply : tag {}; }; struct tag_template_keyword_arg { template struct apply { typedef template_keyword type; }; }; } // namespace aux #define BOOST_PARAMETER_FORWARD_TYPEDEF(z, i, names) \ typedef BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0,names),i) BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names),i); #define BOOST_PARAMETER_FORWARD_TYPEDEFS(n, src, dest) \ BOOST_PP_REPEAT(n, BOOST_PARAMETER_FORWARD_TYPEDEF, (src)(dest)) #define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = void_ template< class PS0 , BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_TEMPLATE_ARGS, _) > struct parameters { #undef BOOST_PARAMETER_TEMPLATE_ARGS typedef typename BOOST_PARAMETER_build_deduced_list( BOOST_PARAMETER_MAX_ARITY, aux::make_deduced_items, PS )::type deduced_list; // if the elements of NamedList match the criteria of overload // resolution, returns a type which can be constructed from // parameters. Otherwise, this is not a valid metafunction (no nested // ::type). #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) // If NamedList satisfies the PS0, PS1, ..., this is a // metafunction returning parameters. Otherwise it // has no nested ::type. template struct match_base : mpl::if_< // mpl::and_< // aux::satisfies_requirements_of // , mpl::and_< // aux::satisfies_requirements_of... // ..., mpl::true_ // ...> > # define BOOST_PARAMETER_satisfies(z, n, text) \ mpl::and_< \ aux::satisfies_requirements_of< \ typename mpl::first::type \ , BOOST_PP_CAT(PS, n)> \ , mpl::and_< is_same::type, void_> , BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _) mpl::true_ BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _) > # undef BOOST_PARAMETER_satisfies , mpl::identity , void_ > {}; #endif // Specializations are to be used as an optional argument to // eliminate overloads via SFINAE template< #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // Borland simply can't handle default arguments in member // class templates. People wishing to write portable code can // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A) #else BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT ) #endif > struct match # if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) : match_base< typename aux::make_arg_list< typename BOOST_PARAMETER_build_arg_list( BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A )::type , deduced_list , aux::tag_keyword_arg , mpl::false_ // Don't emit errors when doing SFINAE >::type >::type {}; # else { typedef parameters< BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS) > type; }; # endif // Metafunction that returns an ArgumentPack. // TODO, bind has to instantiate the error type in the result // of make_arg_list. template < #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // Borland simply can't handle default arguments in member // class templates. People wishing to write portable code can // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A) #else BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT ) #endif > struct bind { typedef typename aux::make_arg_list< typename BOOST_PARAMETER_build_arg_list( BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A )::type , deduced_list , aux::tag_template_keyword_arg >::type result; typedef typename mpl::first::type type; }; BOOST_PARAMETER_FORWARD_TYPEDEFS(BOOST_PARAMETER_MAX_ARITY, PS, parameter_spec) // // The function call operator is used to build an arg_list that // labels the positional parameters and maintains whatever other // tags may have been specified by the caller. // // !!!NOTE!!! // // The make_arg_list<> produces a reversed arg_list, so // we need to pass the arguments to its constructor // reversed. // aux::empty_arg_list operator()() const { return aux::empty_arg_list(); } template typename mpl::first< typename aux::make_arg_list< aux::item< PS0,A0 > , deduced_list , aux::tag_keyword_arg >::type >::type operator()(A0& a0) const { typedef typename aux::make_arg_list< aux::item< PS0,A0 > , deduced_list , aux::tag_keyword_arg >::type result; typedef typename mpl::first::type result_type; typedef typename mpl::second::type error; error(); return result_type( a0 // , void_(), void_(), void_() ... BOOST_PP_ENUM_TRAILING_PARAMS( BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1) , aux::void_reference() BOOST_PP_INTERCEPT) ); } template typename mpl::first< typename aux::make_arg_list< aux::item< PS0,A0 , aux::item< PS1,A1 > > , deduced_list , aux::tag_keyword_arg >::type >::type operator()(A0& a0, A1& a1) const { typedef typename aux::make_arg_list< aux::item< PS0,A0 , aux::item< PS1,A1 > > , deduced_list , aux::tag_keyword_arg >::type result; typedef typename mpl::first::type result_type; typedef typename mpl::second::type error; error(); return result_type( a1,a0 // , void_(), void_() ... BOOST_PP_ENUM_TRAILING_PARAMS( BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2) , aux::void_reference() BOOST_PP_INTERCEPT) ); } // Higher arities are handled by the preprocessor #define BOOST_PP_ITERATION_PARAMS_1 (3,( \ 3,BOOST_PARAMETER_MAX_ARITY, \ )) #include BOOST_PP_ITERATE() }; } // namespace parameter } // namespace boost #endif // BOOST_PARAMETERS_031014_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/preprocessor.hpp ================================================ // Copyright Daniel Wallin 2006. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_PREPROCESSOR_060206_HPP # define BOOST_PARAMETER_PREPROCESSOR_060206_HPP # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include namespace boost { namespace parameter { namespace aux { # if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) // Given Match, which is "void x" where x is an argument matching // criterion, extract a corresponding MPL predicate. template struct unwrap_predicate; // Match anything template <> struct unwrap_predicate { typedef mpl::always type; }; #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) typedef void* voidstar; // A matching predicate is explicitly specified template struct unwrap_predicate { typedef Predicate type; }; #else // A matching predicate is explicitly specified template struct unwrap_predicate { typedef Predicate type; }; #endif // A type to which the argument is supposed to be convertible is // specified template struct unwrap_predicate { typedef is_convertible type; }; // Recast the ParameterSpec's nested match metafunction as a free metafunction template < class Parameters , BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT ) > struct match : Parameters::template match< BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, A) > {}; # endif # undef false_ template < class Parameters , BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT ) > struct argument_pack { typedef typename make_arg_list< typename BOOST_PARAMETER_build_arg_list( BOOST_PARAMETER_MAX_ARITY, make_items, typename Parameters::parameter_spec, A )::type , typename Parameters::deduced_list , tag_keyword_arg , mpl::false_ >::type result; typedef typename mpl::first::type type; }; // Works around VC6 problem where it won't accept rvalues. template T& as_lvalue(T& value, long) { return value; } template T const& as_lvalue(T const& value, int) { return value; } # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template struct apply_predicate { BOOST_MPL_ASSERT(( mpl::and_ )); typedef typename mpl::if_< typename mpl::apply2::type , char , int >::type type; }; template struct funptr_predicate { static P p; template static typename apply_predicate::type check_predicate(type, Args*, void**(*)(P0)); template static typename mpl::if_< is_convertible , char , int >::type check_predicate(type, Args*, void*(*)(P0)); template struct apply { BOOST_STATIC_CONSTANT(bool, result = sizeof(check_predicate(boost::type(), (Args*)0, &p)) == 1 ); typedef mpl::bool_::result> type; }; }; template <> struct funptr_predicate : mpl::always {}; # endif }}} // namespace boost::parameter::aux # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // From Paul Mensonides # define BOOST_PARAMETER_IS_NULLARY(x) \ BOOST_PP_SPLIT(1, BOOST_PARAMETER_IS_NULLARY_C x BOOST_PP_COMMA() 0) \ /**/ # define BOOST_PARAMETER_IS_NULLARY_C() \ ~, 1 BOOST_PP_RPAREN() \ BOOST_PP_TUPLE_EAT(2) BOOST_PP_LPAREN() ~ \ /**/ # else # define BOOST_PARAMETER_IS_NULLARY(x) BOOST_PP_IS_NULLARY(x) # endif # define BOOST_PARAMETER_MEMBER_FUNCTION_CHECK_STATIC_static () # define BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \ BOOST_PARAMETER_IS_NULLARY( \ BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_CHECK_STATIC_,name) \ ) # if !defined(BOOST_MSVC) # define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_static # define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC(name) \ BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_, name) # else // Workaround for MSVC preprocessor. // // When stripping static from "static f", msvc will produce // " f". The leading whitespace doesn't go away when pasting // the token with something else, so this thing is a hack to // strip the whitespace. # define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_static ( # define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_AUX(name) \ BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_, name)) # define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC(name) \ BOOST_PP_SEQ_HEAD( \ BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_AUX(name) \ ) # endif # define BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \ BOOST_PP_EXPR_IF( \ BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \ , static \ ) # define BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \ BOOST_PP_IF( \ BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \ , BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC \ , name BOOST_PP_TUPLE_EAT(1) \ )(name) // Calculates [begin, end) arity range. # define BOOST_PARAMETER_ARITY_RANGE_M_optional(state) state # define BOOST_PARAMETER_ARITY_RANGE_M_deduced_optional(state) state # define BOOST_PARAMETER_ARITY_RANGE_M_required(state) BOOST_PP_INC(state) # define BOOST_PARAMETER_ARITY_RANGE_M_deduced_required(state) BOOST_PP_INC(state) # define BOOST_PARAMETER_ARITY_RANGE_M(s, state, x) \ BOOST_PP_CAT( \ BOOST_PARAMETER_ARITY_RANGE_M_ \ , BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \ )(state) /**/ # define BOOST_PARAMETER_ARITY_RANGE(args) \ ( \ BOOST_PP_SEQ_FOLD_LEFT(BOOST_PARAMETER_ARITY_RANGE_M, 0, args) \ , BOOST_PP_INC(BOOST_PP_SEQ_SIZE(args)) \ ) /**/ // Accessor macros for the argument specs tuple. # define BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \ BOOST_PP_TUPLE_ELEM(4,0,x) /**/ # define BOOST_PARAMETER_FN_ARG_NAME(x) \ BOOST_PP_TUPLE_ELEM(4,1,x) /**/ # define BOOST_PARAMETER_FN_ARG_PRED(x) \ BOOST_PP_TUPLE_ELEM(4,2,x) /**/ # define BOOST_PARAMETER_FN_ARG_DEFAULT(x) \ BOOST_PP_TUPLE_ELEM(4,3,x) /**/ # define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_out(x) # define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_in_out(x) // Returns 1 if x is either "out(k)" or "in_out(k)". # define BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \ BOOST_PP_IS_EMPTY( \ BOOST_PP_CAT(BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_, x) \ ) \ /**/ # define BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_out(x) x # define BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_in_out(x) x # define BOOST_PARAMETER_FUNCTION_KEYWORD_GET(x) \ BOOST_PP_CAT(BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_, x) /**/ // Returns the keyword of x, where x is either a keyword qualifier // or a keyword. // // k => k // out(k) => k // in_out(k) => k // # define BOOST_PARAMETER_FUNCTION_KEYWORD(x) \ BOOST_PP_IF( \ BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \ , BOOST_PARAMETER_FUNCTION_KEYWORD_GET \ , x BOOST_PP_TUPLE_EAT(1) \ )(x) /**/ # define BOOST_PARAMETER_FN_ARG_KEYWORD(x) \ BOOST_PARAMETER_FUNCTION_KEYWORD( \ BOOST_PARAMETER_FN_ARG_NAME(x) \ ) // Builds forwarding functions. # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z(z, n) \ template /**/ # if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) # define BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z(z, name, parameters, n) \ , typename boost::parameter::aux::match< \ parameters, BOOST_PP_ENUM_PARAMS(n, ParameterArgumentType) \ >::type = parameters() # else # define BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z(z, name, parameters, n) # endif /**/ # define BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(base) \ BOOST_PP_CAT( \ boost_param_parameters_ \ , BOOST_PP_CAT(__LINE__, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \ ) // Produce a name for a result type metafunction for the function // named base # define BOOST_PARAMETER_FUNCTION_RESULT_NAME(base) \ BOOST_PP_CAT( \ boost_param_result_ \ , BOOST_PP_CAT(__LINE__,BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \ ) // Can't do boost_param_impl_ ## basee because base might start with an underscore // daniel: what? how is that relevant? the reason for using CAT() is to make sure // base is expanded. i'm not sure we need to here, but it's more stable to do it. # define BOOST_PARAMETER_IMPL(base) \ BOOST_PP_CAT(boost_param_impl,BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00(z, n, r, data, elem) \ BOOST_PP_IF( \ n \ , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z, BOOST_PP_TUPLE_EAT(2) \ )(z,n) \ BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(7,3,data)) \ inline \ BOOST_PP_EXPR_IF(n, typename) \ BOOST_PARAMETER_FUNCTION_RESULT_NAME(BOOST_PP_TUPLE_ELEM(7,3,data))< \ BOOST_PP_EXPR_IF(n, typename) \ boost::parameter::aux::argument_pack< \ BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(BOOST_PP_TUPLE_ELEM(7,3,data)) \ BOOST_PP_COMMA_IF(n) \ BOOST_PP_IF( \ n, BOOST_PP_SEQ_ENUM, BOOST_PP_TUPLE_EAT(1) \ )(elem) \ >::type \ >::type \ BOOST_PARAMETER_MEMBER_FUNCTION_NAME(BOOST_PP_TUPLE_ELEM(7,3,data))( \ BOOST_PP_IF( \ n \ , BOOST_PP_SEQ_FOR_EACH_I_R \ , BOOST_PP_TUPLE_EAT(4) \ )( \ r \ , BOOST_PARAMETER_FUNCTION_ARGUMENT \ , ~ \ , elem \ ) \ BOOST_PP_IF(n, BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z, BOOST_PP_TUPLE_EAT(4))( \ z \ , BOOST_PP_TUPLE_ELEM(7,3,data) \ , BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(BOOST_PP_TUPLE_ELEM(7,3,data)) \ , n \ ) \ ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(7,4,data), const) \ { \ return BOOST_PARAMETER_IMPL(BOOST_PP_TUPLE_ELEM(7,3,data))( \ BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(BOOST_PP_TUPLE_ELEM(7,3,data))()( \ BOOST_PP_ENUM_PARAMS_Z(z, n, a) \ ) \ ); \ } /**/ # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION0(r, data, elem) \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00( \ BOOST_PP_TUPLE_ELEM(7,0,data) \ , BOOST_PP_TUPLE_ELEM(7,1,data) \ , r \ , data \ , elem \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_0(z, n, data) \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00( \ z, n, BOOST_PP_DEDUCE_R() \ , (z, n, BOOST_PP_TUPLE_REM(5) data) \ , ~ \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_N(z, n, data) \ BOOST_PP_SEQ_FOR_EACH( \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTION0 \ , (z, n, BOOST_PP_TUPLE_REM(5) data) \ , BOOST_PP_SEQ_FOR_EACH_PRODUCT( \ BOOST_PARAMETER_FUNCTION_FWD_PRODUCT \ , BOOST_PP_SEQ_FIRST_N( \ n, BOOST_PP_TUPLE_ELEM(5,3,data) \ ) \ ) \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION(z, n, data) \ BOOST_PP_IF( \ n \ , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_N \ , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_0 \ )(z,n,data) \ /**/ # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS0( \ result,name,args,const_,combinations,range \ ) \ BOOST_PP_REPEAT_FROM_TO( \ BOOST_PP_TUPLE_ELEM(2,0,range), BOOST_PP_TUPLE_ELEM(2,1,range) \ , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION \ , (result,name,const_,combinations,BOOST_PP_TUPLE_ELEM(2,1,range)) \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS(result,name,args, const_, combinations) \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS0( \ result, name, args, const_, combinations, BOOST_PARAMETER_ARITY_RANGE(args) \ ) /**/ // Builds boost::parameter::parameters<> specialization # define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_optional(tag) \ optional # define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_deduced_required(tag) \ required # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) # define BOOST_PARAMETER_FUNCTION_PARAMETERS_M(r,tag_namespace,i,elem) \ BOOST_PP_COMMA_IF(i) \ boost::parameter::BOOST_PP_CAT( \ BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_ \ , BOOST_PARAMETER_FN_ARG_QUALIFIER(elem) \ )( \ tag_namespace::BOOST_PARAMETER_FUNCTION_KEYWORD( \ BOOST_PARAMETER_FN_ARG_KEYWORD(elem) \ ) \ ) \ , typename boost::parameter::aux::unwrap_predicate< \ void BOOST_PARAMETER_FN_ARG_PRED(elem) \ >::type \ > # elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) # define BOOST_PARAMETER_FUNCTION_PARAMETERS_M(r,tag_namespace,i,elem) \ BOOST_PP_COMMA_IF(i) \ boost::parameter::BOOST_PP_CAT( \ BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_ \ , BOOST_PARAMETER_FN_ARG_QUALIFIER(elem) \ )( \ tag_namespace::BOOST_PARAMETER_FUNCTION_KEYWORD( \ BOOST_PARAMETER_FN_ARG_KEYWORD(elem) \ ) \ ) \ , boost::mpl::always \ > # endif # define BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, base, args) \ template \ struct BOOST_PP_CAT( \ BOOST_PP_CAT(boost_param_params_, __LINE__) \ , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ ) : boost::parameter::parameters< \ BOOST_PP_SEQ_FOR_EACH_I( \ BOOST_PARAMETER_FUNCTION_PARAMETERS_M, tag_namespace, args \ ) \ > \ {}; \ \ typedef BOOST_PP_CAT( \ BOOST_PP_CAT(boost_param_params_, __LINE__) \ , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ ) // Defines result type metafunction # define BOOST_PARAMETER_FUNCTION_RESULT_ARG(z, _, i, x) \ BOOST_PP_COMMA_IF(i) class BOOST_PP_TUPLE_ELEM(3,1,x) /**/ # define BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args) \ template \ struct BOOST_PARAMETER_FUNCTION_RESULT_NAME(name) \ { \ typedef typename BOOST_PARAMETER_PARENTHESIZED_TYPE(result) type; \ }; // Defines implementation function # define BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) \ template \ typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)< \ Args \ >::type BOOST_PARAMETER_IMPL(name)(Args const& args) # define BOOST_PARAMETER_FUNCTION_IMPL_FWD(name) \ BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name); /**/ # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_required(state, arg) \ ( \ BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 0, state)) \ , BOOST_PP_SEQ_PUSH_BACK(BOOST_PP_TUPLE_ELEM(4, 1, state), arg) \ , BOOST_PP_TUPLE_ELEM(4, 2, state) \ , BOOST_PP_TUPLE_ELEM(4, 3, state) \ ) # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_deduced_required(state, arg) \ BOOST_PARAMETER_FUNCTION_SPLIT_ARG_required(state, arg) # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_optional(state, arg) \ ( \ BOOST_PP_TUPLE_ELEM(4, 0, state) \ , BOOST_PP_TUPLE_ELEM(4, 1, state) \ , BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 2, state)) \ , BOOST_PP_SEQ_PUSH_BACK(BOOST_PP_TUPLE_ELEM(4, 3, state), arg) \ ) # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_deduced_optional(state, arg) \ BOOST_PARAMETER_FUNCTION_SPLIT_ARG_optional(state, arg) # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG(s, state, arg) \ BOOST_PP_CAT( \ BOOST_PARAMETER_FUNCTION_SPLIT_ARG_ \ , BOOST_PARAMETER_FN_ARG_QUALIFIER(arg) \ )(state, arg) // Returns (required_count, required, optional_count, optionals) tuple # define BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args) \ BOOST_PP_SEQ_FOLD_LEFT( \ BOOST_PARAMETER_FUNCTION_SPLIT_ARG \ , (0,BOOST_PP_SEQ_NIL, 0,BOOST_PP_SEQ_NIL) \ , args \ ) # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG_NAME(keyword) \ BOOST_PP_CAT(BOOST_PP_CAT(keyword,_),type) // Helpers used as parameters to BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS. # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG(r, _, arg) \ , class BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG_NAME( \ BOOST_PARAMETER_FN_ARG_KEYWORD(arg) \ ) # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG(r, _, arg) \ , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG_NAME( \ BOOST_PARAMETER_FN_ARG_KEYWORD(arg) \ )& BOOST_PARAMETER_FN_ARG_KEYWORD(arg) # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER(r, _, arg) \ , BOOST_PARAMETER_FN_ARG_KEYWORD(arg) // Produces a name for the dispatch functions. # define BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name) \ BOOST_PP_CAT( \ boost_param_default_ \ , BOOST_PP_CAT(__LINE__, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name)) \ ) // Helper macro used below to produce lists based on the keyword argument // names. macro is applied to every element. n is the number of // optional arguments that should be included. # define BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS(macro, n, split_args) \ BOOST_PP_SEQ_FOR_EACH( \ macro \ , ~ \ , BOOST_PP_TUPLE_ELEM(4,1,split_args) \ ) \ BOOST_PP_SEQ_FOR_EACH( \ macro \ , ~ \ , BOOST_PP_SEQ_FIRST_N( \ BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(4,2,split_args), n) \ , BOOST_PP_TUPLE_ELEM(4,3,split_args) \ ) \ ) // Generates a keyword | default expression. # define BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT(arg, tag_namespace) \ boost::parameter::keyword< \ tag_namespace::BOOST_PARAMETER_FN_ARG_KEYWORD(arg) \ >::instance | boost::parameter::aux::use_default_tag() # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_GET_ARG(arg, tag_ns) \ BOOST_PARAMETER_FUNCTION_CAST( \ args[ \ BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT( \ arg, tag_ns \ ) \ ] \ , BOOST_PARAMETER_FN_ARG_PRED(arg) \ , Args \ ) # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_BODY(name, n, split_args, tag_namespace) \ { \ return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \ (ResultType(*)())0 \ , args \ , 0L \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER \ , n \ , split_args \ ) \ , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_GET_ARG( \ BOOST_PP_SEQ_ELEM( \ BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(4,2,split_args), n) \ , BOOST_PP_TUPLE_ELEM(4,3,split_args) \ ) \ , tag_namespace \ ) \ ); \ } # define BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_ACTUAL_DEFAULT(arg) \ BOOST_PARAMETER_FUNCTION_CAST( \ boost::parameter::aux::as_lvalue(BOOST_PARAMETER_FN_ARG_DEFAULT(arg), 0L) \ , BOOST_PARAMETER_FN_ARG_PRED(arg) \ , Args \ ) # define BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT_BODY(name, n, split_args, tag_ns, const_) \ template < \ class ResultType \ , class Args \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \ , BOOST_PP_INC(n) \ , split_args \ ) \ > \ BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \ ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \ ResultType(*)() \ , Args const& args \ , long \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \ , BOOST_PP_INC(n) \ , split_args \ ) \ , boost::parameter::aux::use_default_tag \ ) BOOST_PP_EXPR_IF(const_, const) \ { \ return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \ (ResultType(*)())0 \ , args \ , 0L \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER \ , BOOST_PP_INC(n) \ , split_args \ ) \ , BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_ACTUAL_DEFAULT( \ BOOST_PP_SEQ_ELEM( \ BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(4,2,split_args), BOOST_PP_INC(n)) \ , BOOST_PP_TUPLE_ELEM(4,3,split_args) \ ) \ ) \ ); \ } // Produces a forwarding layer in the default evaluation machine. // // data is a tuple: // // (name, split_args) // // Where name is the base name of the function, and split_args is a tuple: // // (required_count, required_args, optional_count, required_args) // // defines the actual function body for BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION below. # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION0(z, n, data) \ template < \ class ResultType \ , class Args \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \ , n \ , BOOST_PP_TUPLE_ELEM(5,1,data) \ ) \ > \ BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(5,0,data)) \ ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(BOOST_PP_TUPLE_ELEM(5,0,data))( \ ResultType(*)() \ , Args const& args \ , int \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \ , n \ , BOOST_PP_TUPLE_ELEM(5,1,data) \ ) \ ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(5,2,data), const) \ BOOST_PP_IF( \ n \ , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_BODY \ , ; BOOST_PP_TUPLE_EAT(4) \ )( \ BOOST_PP_TUPLE_ELEM(5,0,data) \ , n \ , BOOST_PP_TUPLE_ELEM(5,1,data) \ , BOOST_PP_TUPLE_ELEM(5,3,data) \ ) # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION(z, n, data) \ BOOST_PP_IF( \ BOOST_PP_AND( \ BOOST_PP_NOT(n) \ , BOOST_PP_TUPLE_ELEM(5,4,data) \ ) \ , BOOST_PP_TUPLE_EAT(3) \ , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION0 \ )(z, n, data) \ BOOST_PP_IF( \ BOOST_PP_EQUAL(n, BOOST_PP_TUPLE_ELEM(4,2,BOOST_PP_TUPLE_ELEM(5,1,data))) \ , BOOST_PP_TUPLE_EAT(5) \ , BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT_BODY \ )( \ BOOST_PP_TUPLE_ELEM(5,0,data) \ , n \ , BOOST_PP_TUPLE_ELEM(5,1,data) \ , BOOST_PP_TUPLE_ELEM(5,3,data) \ , BOOST_PP_TUPLE_ELEM(5,2,data) \ ) # define BOOST_PARAMETER_FUNCTION_DEFAULT_GET_ARG(r, tag_ns, arg) \ , BOOST_PARAMETER_FUNCTION_CAST( \ args[ \ boost::parameter::keyword::instance \ ] \ , BOOST_PARAMETER_FN_ARG_PRED(arg) \ , Args \ ) // Generates the function template that recives a ArgumentPack, and then // goes on to call the layers of overloads generated by // BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER. # define BOOST_PARAMETER_FUNCTION_INITIAL_DISPATCH_FUNCTION(name, split_args, const_, tag_ns) \ template \ typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)::type \ BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \ BOOST_PARAMETER_IMPL(name)(Args const& args) BOOST_PP_EXPR_IF(const_, const) \ { \ return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \ (typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)::type(*)())0 \ , args \ , 0L \ \ BOOST_PP_SEQ_FOR_EACH( \ BOOST_PARAMETER_FUNCTION_DEFAULT_GET_ARG \ , tag_ns \ , BOOST_PP_TUPLE_ELEM(4,1,split_args) \ ) \ \ ); \ } // Helper for BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER below. # define BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER_AUX( \ name, split_args, skip_fwd_decl, const_, tag_namespace \ ) \ BOOST_PP_REPEAT_FROM_TO( \ 0 \ , BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 2, split_args)) \ , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION \ , (name, split_args, const_, tag_namespace, skip_fwd_decl) \ ) \ \ BOOST_PARAMETER_FUNCTION_INITIAL_DISPATCH_FUNCTION(name, split_args, const_, tag_namespace) \ \ template < \ class ResultType \ , class Args \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \ , 0 \ , split_args \ ) \ > \ BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \ ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \ ResultType(*)() \ , Args const& \ , int \ BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \ BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \ , 0 \ , split_args \ ) \ ) BOOST_PP_EXPR_IF(const_, const) // Generates a bunch of forwarding functions that each extract // one more argument. # define BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, skip_fwd_decl, const_, tag_ns) \ BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER_AUX( \ name, BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args), skip_fwd_decl, const_, tag_ns \ ) /**/ // Defines the result metafunction and the parameters specialization. # define BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \ BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args) \ \ BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, name, args) \ BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(name); \ // Helper for BOOST_PARAMETER_FUNCTION below. # define BOOST_PARAMETER_FUNCTION_AUX(result, name, tag_namespace, args) \ BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \ BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name); \ \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \ result, name, args, 0 \ , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \ ) \ \ BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, 0, 0, tag_namespace) // Defines a Boost.Parameter enabled function with the new syntax. # define BOOST_PARAMETER_FUNCTION(result, name, tag_namespace, args) \ BOOST_PARAMETER_FUNCTION_AUX( \ result, name, tag_namespace \ , BOOST_PARAMETER_FLATTEN(3, 2, 3, args) \ ) \ /**/ // Defines a Boost.Parameter enabled function. # define BOOST_PARAMETER_BASIC_FUNCTION_AUX(result, name, tag_namespace, args) \ BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \ \ BOOST_PARAMETER_FUNCTION_IMPL_FWD(name) \ \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \ result, name, args, 0 \ , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \ ) \ \ BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) # define BOOST_PARAMETER_BASIC_FUNCTION(result, name, tag_namespace, args) \ BOOST_PARAMETER_BASIC_FUNCTION_AUX( \ result, name, tag_namespace \ , BOOST_PARAMETER_FLATTEN(2, 2, 3, args) \ ) \ /**/ // Defines a Boost.Parameter enabled member function. # define BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX(result, name, tag_namespace, args, const_) \ BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \ \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \ result, name, args, const_ \ , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \ ) \ \ BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) BOOST_PP_EXPR_IF(const_, const) \ /**/ # define BOOST_PARAMETER_BASIC_MEMBER_FUNCTION(result, name, tag_namespace, args) \ BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \ result, name, tag_namespace \ , BOOST_PARAMETER_FLATTEN(2, 2, 3, args) \ , 0 \ ) /**/ # define BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION(result, name, tag_namespace, args) \ BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \ result, name, tag_namespace \ , BOOST_PARAMETER_FLATTEN(2, 2, 3, args) \ , 1 \ ) /**/ # define BOOST_PARAMETER_MEMBER_FUNCTION_AUX(result, name, tag_namespace, const_, args) \ BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \ \ BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \ result, name, args, const_ \ , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \ ) \ \ BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, 1, const_, tag_namespace) // Defines a Boost.Parameter enabled function with the new syntax. # define BOOST_PARAMETER_MEMBER_FUNCTION(result, name, tag_namespace, args) \ BOOST_PARAMETER_MEMBER_FUNCTION_AUX( \ result, name, tag_namespace, 0 \ , BOOST_PARAMETER_FLATTEN(3, 2, 3, args) \ ) \ /**/ # define BOOST_PARAMETER_CONST_MEMBER_FUNCTION(result, name, tag_namespace, args) \ BOOST_PARAMETER_MEMBER_FUNCTION_AUX( \ result, name, tag_namespace, 1 \ , BOOST_PARAMETER_FLATTEN(3, 2, 3, args) \ ) \ /**/ // Defines a Boost.Parameter enabled constructor. # define BOOST_PARAMETER_FUNCTION_ARGUMENT(r, _, i, elem) \ BOOST_PP_COMMA_IF(i) elem& BOOST_PP_CAT(a, i) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00(z, n, r, data, elem) \ BOOST_PP_IF( \ n \ , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z, BOOST_PP_TUPLE_EAT(2) \ )(z, n) \ BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n,1), explicit) \ BOOST_PP_TUPLE_ELEM(6,2,data)( \ BOOST_PP_IF( \ n \ , BOOST_PP_SEQ_FOR_EACH_I_R \ , BOOST_PP_TUPLE_EAT(4) \ )( \ r \ , BOOST_PARAMETER_FUNCTION_ARGUMENT \ , ~ \ , elem \ ) \ BOOST_PP_IF(n, BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z, BOOST_PP_TUPLE_EAT(4))( \ z \ , BOOST_PP_TUPLE_ELEM(6,3,data) \ , BOOST_PP_CAT(constructor_parameters, __LINE__) \ , n \ ) \ ) \ : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(6,3,data)) ( \ BOOST_PP_CAT(constructor_parameters, __LINE__)()( \ BOOST_PP_ENUM_PARAMS_Z(z, n, a) \ ) \ ) \ {} /**/ # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR0(r, data, elem) \ BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00( \ BOOST_PP_TUPLE_ELEM(6,0,data) \ , BOOST_PP_TUPLE_ELEM(6,1,data) \ , r \ , data \ , elem \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_PRODUCT(r, product) \ (product) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_0(z, n, data) \ BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00( \ z, n, BOOST_PP_DEDUCE_R() \ , (z, n, BOOST_PP_TUPLE_REM(4) data) \ , ~ \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_N(z, n, data) \ BOOST_PP_SEQ_FOR_EACH( \ BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR0 \ , (z, n, BOOST_PP_TUPLE_REM(4) data) \ , BOOST_PP_SEQ_FOR_EACH_PRODUCT( \ BOOST_PARAMETER_FUNCTION_FWD_PRODUCT \ , BOOST_PP_SEQ_FIRST_N( \ n, BOOST_PP_TUPLE_ELEM(4,2,data) \ ) \ ) \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR(z, n, data) \ BOOST_PP_IF( \ n \ , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_N \ , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_0 \ )(z,n,data) \ /**/ # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS0(class_,base,args,combinations,range) \ BOOST_PP_REPEAT_FROM_TO( \ BOOST_PP_TUPLE_ELEM(2,0,range), BOOST_PP_TUPLE_ELEM(2,1,range) \ , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR \ , (class_,base,combinations,BOOST_PP_TUPLE_ELEM(2,1,range)) \ ) /**/ # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS(class_,base,args,combinations) \ BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS0( \ class_, base, args, combinations, BOOST_PARAMETER_ARITY_RANGE(args) \ ) /**/ # define BOOST_PARAMETER_CONSTRUCTOR_AUX(class_, base, tag_namespace, args) \ BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, ctor, args) \ BOOST_PP_CAT(constructor_parameters, __LINE__); \ \ BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS( \ class_, base, args \ , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \ ) \ /**/ # define BOOST_PARAMETER_CONSTRUCTOR(class_, base, tag_namespace, args) \ BOOST_PARAMETER_CONSTRUCTOR_AUX( \ class_, base, tag_namespace \ , BOOST_PARAMETER_FLATTEN(2, 2, 3, args) \ ) /**/ # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING # define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \ (BOOST_PP_IF( \ BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER( \ BOOST_PARAMETER_FN_ARG_NAME(elem) \ ) \ , (const ParameterArgumentType ## i)(ParameterArgumentType ## i) \ , (const ParameterArgumentType ## i) \ )) // No partial ordering. This feature doesn't work. # else # define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \ (BOOST_PP_IF( \ BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER( \ BOOST_PARAMETER_FN_ARG_NAME(elem) \ ) \ , (ParameterArgumentType ## i) \ , (const ParameterArgumentType ## i) \ )) # endif # define BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \ BOOST_PP_SEQ_FOR_EACH_I(BOOST_PARAMETER_FUNCTION_FWD_COMBINATION, ~, args) #endif // BOOST_PARAMETER_PREPROCESSOR_060206_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter/value_type.hpp ================================================ // Copyright Daniel Wallin 2006. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PARAMETER_VALUE_TYPE_060921_HPP # define BOOST_PARAMETER_VALUE_TYPE_060921_HPP # include # include # include # include # include # include namespace boost { namespace parameter { // A metafunction that, given an argument pack, returns the type of // the parameter identified by the given keyword. If no such // parameter has been specified, returns Default # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template struct value_type0 { typedef typename mpl::apply_wrap3< typename Parameters::binding,Keyword,Default,mpl::false_ >::type type; BOOST_MPL_ASSERT_NOT(( mpl::and_< is_same , is_same > )); }; # endif template struct value_type { # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) typedef typename mpl::eval_if< mpl::is_placeholder , mpl::identity , value_type0 >::type type; # else typedef typename mpl::apply_wrap3< typename Parameters::binding,Keyword,Default,mpl::false_ >::type type; BOOST_MPL_ASSERT_NOT(( mpl::and_< is_same , is_same > )); # endif BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default)) }; // A metafunction that, given an argument pack, returns the type of // the parameter identified by the given keyword. If no such // parameter has been specified, returns the type returned by invoking // DefaultFn template struct lazy_value_type { typedef typename mpl::apply_wrap3< typename Parameters::binding , Keyword , typename aux::result_of0::type , mpl::false_ >::type type; }; }} // namespace boost::parameter #endif // BOOST_PARAMETER_VALUE_TYPE_060921_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/parameter.hpp ================================================ // Copyright David Abrahams, Daniel Wallin 2005. Use, modification and // distribution is subject to the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See www.boost.org/libs/parameter for documentation. #ifndef BOOST_PARAMETER_050401_HPP #define BOOST_PARAMETER_050401_HPP #include #include #include #include #include #include #include #include #endif // BOOST_PARAMETER_050401_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/arithmetic/add.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ARITHMETIC_ADD_HPP # define BOOST_PREPROCESSOR_ARITHMETIC_ADD_HPP # # include # include # include # include # include # # /* BOOST_PP_ADD */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ADD(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y))) # else # define BOOST_PP_ADD(x, y) BOOST_PP_ADD_I(x, y) # define BOOST_PP_ADD_I(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y))) # endif # # define BOOST_PP_ADD_P(d, xy) BOOST_PP_TUPLE_ELEM(2, 1, xy) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_ADD_O(d, xy) BOOST_PP_ADD_O_I xy # else # define BOOST_PP_ADD_O(d, xy) BOOST_PP_ADD_O_I(BOOST_PP_TUPLE_ELEM(2, 0, xy), BOOST_PP_TUPLE_ELEM(2, 1, xy)) # endif # # define BOOST_PP_ADD_O_I(x, y) (BOOST_PP_INC(x), BOOST_PP_DEC(y)) # # /* BOOST_PP_ADD_D */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ADD_D(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y))) # else # define BOOST_PP_ADD_D(d, x, y) BOOST_PP_ADD_D_I(d, x, y) # define BOOST_PP_ADD_D_I(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y))) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/arithmetic/dec.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ARITHMETIC_DEC_HPP # define BOOST_PREPROCESSOR_ARITHMETIC_DEC_HPP # # include # # /* BOOST_PP_DEC */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_DEC(x) BOOST_PP_DEC_I(x) # else # define BOOST_PP_DEC(x) BOOST_PP_DEC_OO((x)) # define BOOST_PP_DEC_OO(par) BOOST_PP_DEC_I ## par # endif # # define BOOST_PP_DEC_I(x) BOOST_PP_DEC_ ## x # # define BOOST_PP_DEC_0 0 # define BOOST_PP_DEC_1 0 # define BOOST_PP_DEC_2 1 # define BOOST_PP_DEC_3 2 # define BOOST_PP_DEC_4 3 # define BOOST_PP_DEC_5 4 # define BOOST_PP_DEC_6 5 # define BOOST_PP_DEC_7 6 # define BOOST_PP_DEC_8 7 # define BOOST_PP_DEC_9 8 # define BOOST_PP_DEC_10 9 # define BOOST_PP_DEC_11 10 # define BOOST_PP_DEC_12 11 # define BOOST_PP_DEC_13 12 # define BOOST_PP_DEC_14 13 # define BOOST_PP_DEC_15 14 # define BOOST_PP_DEC_16 15 # define BOOST_PP_DEC_17 16 # define BOOST_PP_DEC_18 17 # define BOOST_PP_DEC_19 18 # define BOOST_PP_DEC_20 19 # define BOOST_PP_DEC_21 20 # define BOOST_PP_DEC_22 21 # define BOOST_PP_DEC_23 22 # define BOOST_PP_DEC_24 23 # define BOOST_PP_DEC_25 24 # define BOOST_PP_DEC_26 25 # define BOOST_PP_DEC_27 26 # define BOOST_PP_DEC_28 27 # define BOOST_PP_DEC_29 28 # define BOOST_PP_DEC_30 29 # define BOOST_PP_DEC_31 30 # define BOOST_PP_DEC_32 31 # define BOOST_PP_DEC_33 32 # define BOOST_PP_DEC_34 33 # define BOOST_PP_DEC_35 34 # define BOOST_PP_DEC_36 35 # define BOOST_PP_DEC_37 36 # define BOOST_PP_DEC_38 37 # define BOOST_PP_DEC_39 38 # define BOOST_PP_DEC_40 39 # define BOOST_PP_DEC_41 40 # define BOOST_PP_DEC_42 41 # define BOOST_PP_DEC_43 42 # define BOOST_PP_DEC_44 43 # define BOOST_PP_DEC_45 44 # define BOOST_PP_DEC_46 45 # define BOOST_PP_DEC_47 46 # define BOOST_PP_DEC_48 47 # define BOOST_PP_DEC_49 48 # define BOOST_PP_DEC_50 49 # define BOOST_PP_DEC_51 50 # define BOOST_PP_DEC_52 51 # define BOOST_PP_DEC_53 52 # define BOOST_PP_DEC_54 53 # define BOOST_PP_DEC_55 54 # define BOOST_PP_DEC_56 55 # define BOOST_PP_DEC_57 56 # define BOOST_PP_DEC_58 57 # define BOOST_PP_DEC_59 58 # define BOOST_PP_DEC_60 59 # define BOOST_PP_DEC_61 60 # define BOOST_PP_DEC_62 61 # define BOOST_PP_DEC_63 62 # define BOOST_PP_DEC_64 63 # define BOOST_PP_DEC_65 64 # define BOOST_PP_DEC_66 65 # define BOOST_PP_DEC_67 66 # define BOOST_PP_DEC_68 67 # define BOOST_PP_DEC_69 68 # define BOOST_PP_DEC_70 69 # define BOOST_PP_DEC_71 70 # define BOOST_PP_DEC_72 71 # define BOOST_PP_DEC_73 72 # define BOOST_PP_DEC_74 73 # define BOOST_PP_DEC_75 74 # define BOOST_PP_DEC_76 75 # define BOOST_PP_DEC_77 76 # define BOOST_PP_DEC_78 77 # define BOOST_PP_DEC_79 78 # define BOOST_PP_DEC_80 79 # define BOOST_PP_DEC_81 80 # define BOOST_PP_DEC_82 81 # define BOOST_PP_DEC_83 82 # define BOOST_PP_DEC_84 83 # define BOOST_PP_DEC_85 84 # define BOOST_PP_DEC_86 85 # define BOOST_PP_DEC_87 86 # define BOOST_PP_DEC_88 87 # define BOOST_PP_DEC_89 88 # define BOOST_PP_DEC_90 89 # define BOOST_PP_DEC_91 90 # define BOOST_PP_DEC_92 91 # define BOOST_PP_DEC_93 92 # define BOOST_PP_DEC_94 93 # define BOOST_PP_DEC_95 94 # define BOOST_PP_DEC_96 95 # define BOOST_PP_DEC_97 96 # define BOOST_PP_DEC_98 97 # define BOOST_PP_DEC_99 98 # define BOOST_PP_DEC_100 99 # define BOOST_PP_DEC_101 100 # define BOOST_PP_DEC_102 101 # define BOOST_PP_DEC_103 102 # define BOOST_PP_DEC_104 103 # define BOOST_PP_DEC_105 104 # define BOOST_PP_DEC_106 105 # define BOOST_PP_DEC_107 106 # define BOOST_PP_DEC_108 107 # define BOOST_PP_DEC_109 108 # define BOOST_PP_DEC_110 109 # define BOOST_PP_DEC_111 110 # define BOOST_PP_DEC_112 111 # define BOOST_PP_DEC_113 112 # define BOOST_PP_DEC_114 113 # define BOOST_PP_DEC_115 114 # define BOOST_PP_DEC_116 115 # define BOOST_PP_DEC_117 116 # define BOOST_PP_DEC_118 117 # define BOOST_PP_DEC_119 118 # define BOOST_PP_DEC_120 119 # define BOOST_PP_DEC_121 120 # define BOOST_PP_DEC_122 121 # define BOOST_PP_DEC_123 122 # define BOOST_PP_DEC_124 123 # define BOOST_PP_DEC_125 124 # define BOOST_PP_DEC_126 125 # define BOOST_PP_DEC_127 126 # define BOOST_PP_DEC_128 127 # define BOOST_PP_DEC_129 128 # define BOOST_PP_DEC_130 129 # define BOOST_PP_DEC_131 130 # define BOOST_PP_DEC_132 131 # define BOOST_PP_DEC_133 132 # define BOOST_PP_DEC_134 133 # define BOOST_PP_DEC_135 134 # define BOOST_PP_DEC_136 135 # define BOOST_PP_DEC_137 136 # define BOOST_PP_DEC_138 137 # define BOOST_PP_DEC_139 138 # define BOOST_PP_DEC_140 139 # define BOOST_PP_DEC_141 140 # define BOOST_PP_DEC_142 141 # define BOOST_PP_DEC_143 142 # define BOOST_PP_DEC_144 143 # define BOOST_PP_DEC_145 144 # define BOOST_PP_DEC_146 145 # define BOOST_PP_DEC_147 146 # define BOOST_PP_DEC_148 147 # define BOOST_PP_DEC_149 148 # define BOOST_PP_DEC_150 149 # define BOOST_PP_DEC_151 150 # define BOOST_PP_DEC_152 151 # define BOOST_PP_DEC_153 152 # define BOOST_PP_DEC_154 153 # define BOOST_PP_DEC_155 154 # define BOOST_PP_DEC_156 155 # define BOOST_PP_DEC_157 156 # define BOOST_PP_DEC_158 157 # define BOOST_PP_DEC_159 158 # define BOOST_PP_DEC_160 159 # define BOOST_PP_DEC_161 160 # define BOOST_PP_DEC_162 161 # define BOOST_PP_DEC_163 162 # define BOOST_PP_DEC_164 163 # define BOOST_PP_DEC_165 164 # define BOOST_PP_DEC_166 165 # define BOOST_PP_DEC_167 166 # define BOOST_PP_DEC_168 167 # define BOOST_PP_DEC_169 168 # define BOOST_PP_DEC_170 169 # define BOOST_PP_DEC_171 170 # define BOOST_PP_DEC_172 171 # define BOOST_PP_DEC_173 172 # define BOOST_PP_DEC_174 173 # define BOOST_PP_DEC_175 174 # define BOOST_PP_DEC_176 175 # define BOOST_PP_DEC_177 176 # define BOOST_PP_DEC_178 177 # define BOOST_PP_DEC_179 178 # define BOOST_PP_DEC_180 179 # define BOOST_PP_DEC_181 180 # define BOOST_PP_DEC_182 181 # define BOOST_PP_DEC_183 182 # define BOOST_PP_DEC_184 183 # define BOOST_PP_DEC_185 184 # define BOOST_PP_DEC_186 185 # define BOOST_PP_DEC_187 186 # define BOOST_PP_DEC_188 187 # define BOOST_PP_DEC_189 188 # define BOOST_PP_DEC_190 189 # define BOOST_PP_DEC_191 190 # define BOOST_PP_DEC_192 191 # define BOOST_PP_DEC_193 192 # define BOOST_PP_DEC_194 193 # define BOOST_PP_DEC_195 194 # define BOOST_PP_DEC_196 195 # define BOOST_PP_DEC_197 196 # define BOOST_PP_DEC_198 197 # define BOOST_PP_DEC_199 198 # define BOOST_PP_DEC_200 199 # define BOOST_PP_DEC_201 200 # define BOOST_PP_DEC_202 201 # define BOOST_PP_DEC_203 202 # define BOOST_PP_DEC_204 203 # define BOOST_PP_DEC_205 204 # define BOOST_PP_DEC_206 205 # define BOOST_PP_DEC_207 206 # define BOOST_PP_DEC_208 207 # define BOOST_PP_DEC_209 208 # define BOOST_PP_DEC_210 209 # define BOOST_PP_DEC_211 210 # define BOOST_PP_DEC_212 211 # define BOOST_PP_DEC_213 212 # define BOOST_PP_DEC_214 213 # define BOOST_PP_DEC_215 214 # define BOOST_PP_DEC_216 215 # define BOOST_PP_DEC_217 216 # define BOOST_PP_DEC_218 217 # define BOOST_PP_DEC_219 218 # define BOOST_PP_DEC_220 219 # define BOOST_PP_DEC_221 220 # define BOOST_PP_DEC_222 221 # define BOOST_PP_DEC_223 222 # define BOOST_PP_DEC_224 223 # define BOOST_PP_DEC_225 224 # define BOOST_PP_DEC_226 225 # define BOOST_PP_DEC_227 226 # define BOOST_PP_DEC_228 227 # define BOOST_PP_DEC_229 228 # define BOOST_PP_DEC_230 229 # define BOOST_PP_DEC_231 230 # define BOOST_PP_DEC_232 231 # define BOOST_PP_DEC_233 232 # define BOOST_PP_DEC_234 233 # define BOOST_PP_DEC_235 234 # define BOOST_PP_DEC_236 235 # define BOOST_PP_DEC_237 236 # define BOOST_PP_DEC_238 237 # define BOOST_PP_DEC_239 238 # define BOOST_PP_DEC_240 239 # define BOOST_PP_DEC_241 240 # define BOOST_PP_DEC_242 241 # define BOOST_PP_DEC_243 242 # define BOOST_PP_DEC_244 243 # define BOOST_PP_DEC_245 244 # define BOOST_PP_DEC_246 245 # define BOOST_PP_DEC_247 246 # define BOOST_PP_DEC_248 247 # define BOOST_PP_DEC_249 248 # define BOOST_PP_DEC_250 249 # define BOOST_PP_DEC_251 250 # define BOOST_PP_DEC_252 251 # define BOOST_PP_DEC_253 252 # define BOOST_PP_DEC_254 253 # define BOOST_PP_DEC_255 254 # define BOOST_PP_DEC_256 255 # define BOOST_PP_DEC_257 256 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/arithmetic/inc.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ARITHMETIC_INC_HPP # define BOOST_PREPROCESSOR_ARITHMETIC_INC_HPP # # include # # /* BOOST_PP_INC */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_INC(x) BOOST_PP_INC_I(x) # else # define BOOST_PP_INC(x) BOOST_PP_INC_OO((x)) # define BOOST_PP_INC_OO(par) BOOST_PP_INC_I ## par # endif # # define BOOST_PP_INC_I(x) BOOST_PP_INC_ ## x # # define BOOST_PP_INC_0 1 # define BOOST_PP_INC_1 2 # define BOOST_PP_INC_2 3 # define BOOST_PP_INC_3 4 # define BOOST_PP_INC_4 5 # define BOOST_PP_INC_5 6 # define BOOST_PP_INC_6 7 # define BOOST_PP_INC_7 8 # define BOOST_PP_INC_8 9 # define BOOST_PP_INC_9 10 # define BOOST_PP_INC_10 11 # define BOOST_PP_INC_11 12 # define BOOST_PP_INC_12 13 # define BOOST_PP_INC_13 14 # define BOOST_PP_INC_14 15 # define BOOST_PP_INC_15 16 # define BOOST_PP_INC_16 17 # define BOOST_PP_INC_17 18 # define BOOST_PP_INC_18 19 # define BOOST_PP_INC_19 20 # define BOOST_PP_INC_20 21 # define BOOST_PP_INC_21 22 # define BOOST_PP_INC_22 23 # define BOOST_PP_INC_23 24 # define BOOST_PP_INC_24 25 # define BOOST_PP_INC_25 26 # define BOOST_PP_INC_26 27 # define BOOST_PP_INC_27 28 # define BOOST_PP_INC_28 29 # define BOOST_PP_INC_29 30 # define BOOST_PP_INC_30 31 # define BOOST_PP_INC_31 32 # define BOOST_PP_INC_32 33 # define BOOST_PP_INC_33 34 # define BOOST_PP_INC_34 35 # define BOOST_PP_INC_35 36 # define BOOST_PP_INC_36 37 # define BOOST_PP_INC_37 38 # define BOOST_PP_INC_38 39 # define BOOST_PP_INC_39 40 # define BOOST_PP_INC_40 41 # define BOOST_PP_INC_41 42 # define BOOST_PP_INC_42 43 # define BOOST_PP_INC_43 44 # define BOOST_PP_INC_44 45 # define BOOST_PP_INC_45 46 # define BOOST_PP_INC_46 47 # define BOOST_PP_INC_47 48 # define BOOST_PP_INC_48 49 # define BOOST_PP_INC_49 50 # define BOOST_PP_INC_50 51 # define BOOST_PP_INC_51 52 # define BOOST_PP_INC_52 53 # define BOOST_PP_INC_53 54 # define BOOST_PP_INC_54 55 # define BOOST_PP_INC_55 56 # define BOOST_PP_INC_56 57 # define BOOST_PP_INC_57 58 # define BOOST_PP_INC_58 59 # define BOOST_PP_INC_59 60 # define BOOST_PP_INC_60 61 # define BOOST_PP_INC_61 62 # define BOOST_PP_INC_62 63 # define BOOST_PP_INC_63 64 # define BOOST_PP_INC_64 65 # define BOOST_PP_INC_65 66 # define BOOST_PP_INC_66 67 # define BOOST_PP_INC_67 68 # define BOOST_PP_INC_68 69 # define BOOST_PP_INC_69 70 # define BOOST_PP_INC_70 71 # define BOOST_PP_INC_71 72 # define BOOST_PP_INC_72 73 # define BOOST_PP_INC_73 74 # define BOOST_PP_INC_74 75 # define BOOST_PP_INC_75 76 # define BOOST_PP_INC_76 77 # define BOOST_PP_INC_77 78 # define BOOST_PP_INC_78 79 # define BOOST_PP_INC_79 80 # define BOOST_PP_INC_80 81 # define BOOST_PP_INC_81 82 # define BOOST_PP_INC_82 83 # define BOOST_PP_INC_83 84 # define BOOST_PP_INC_84 85 # define BOOST_PP_INC_85 86 # define BOOST_PP_INC_86 87 # define BOOST_PP_INC_87 88 # define BOOST_PP_INC_88 89 # define BOOST_PP_INC_89 90 # define BOOST_PP_INC_90 91 # define BOOST_PP_INC_91 92 # define BOOST_PP_INC_92 93 # define BOOST_PP_INC_93 94 # define BOOST_PP_INC_94 95 # define BOOST_PP_INC_95 96 # define BOOST_PP_INC_96 97 # define BOOST_PP_INC_97 98 # define BOOST_PP_INC_98 99 # define BOOST_PP_INC_99 100 # define BOOST_PP_INC_100 101 # define BOOST_PP_INC_101 102 # define BOOST_PP_INC_102 103 # define BOOST_PP_INC_103 104 # define BOOST_PP_INC_104 105 # define BOOST_PP_INC_105 106 # define BOOST_PP_INC_106 107 # define BOOST_PP_INC_107 108 # define BOOST_PP_INC_108 109 # define BOOST_PP_INC_109 110 # define BOOST_PP_INC_110 111 # define BOOST_PP_INC_111 112 # define BOOST_PP_INC_112 113 # define BOOST_PP_INC_113 114 # define BOOST_PP_INC_114 115 # define BOOST_PP_INC_115 116 # define BOOST_PP_INC_116 117 # define BOOST_PP_INC_117 118 # define BOOST_PP_INC_118 119 # define BOOST_PP_INC_119 120 # define BOOST_PP_INC_120 121 # define BOOST_PP_INC_121 122 # define BOOST_PP_INC_122 123 # define BOOST_PP_INC_123 124 # define BOOST_PP_INC_124 125 # define BOOST_PP_INC_125 126 # define BOOST_PP_INC_126 127 # define BOOST_PP_INC_127 128 # define BOOST_PP_INC_128 129 # define BOOST_PP_INC_129 130 # define BOOST_PP_INC_130 131 # define BOOST_PP_INC_131 132 # define BOOST_PP_INC_132 133 # define BOOST_PP_INC_133 134 # define BOOST_PP_INC_134 135 # define BOOST_PP_INC_135 136 # define BOOST_PP_INC_136 137 # define BOOST_PP_INC_137 138 # define BOOST_PP_INC_138 139 # define BOOST_PP_INC_139 140 # define BOOST_PP_INC_140 141 # define BOOST_PP_INC_141 142 # define BOOST_PP_INC_142 143 # define BOOST_PP_INC_143 144 # define BOOST_PP_INC_144 145 # define BOOST_PP_INC_145 146 # define BOOST_PP_INC_146 147 # define BOOST_PP_INC_147 148 # define BOOST_PP_INC_148 149 # define BOOST_PP_INC_149 150 # define BOOST_PP_INC_150 151 # define BOOST_PP_INC_151 152 # define BOOST_PP_INC_152 153 # define BOOST_PP_INC_153 154 # define BOOST_PP_INC_154 155 # define BOOST_PP_INC_155 156 # define BOOST_PP_INC_156 157 # define BOOST_PP_INC_157 158 # define BOOST_PP_INC_158 159 # define BOOST_PP_INC_159 160 # define BOOST_PP_INC_160 161 # define BOOST_PP_INC_161 162 # define BOOST_PP_INC_162 163 # define BOOST_PP_INC_163 164 # define BOOST_PP_INC_164 165 # define BOOST_PP_INC_165 166 # define BOOST_PP_INC_166 167 # define BOOST_PP_INC_167 168 # define BOOST_PP_INC_168 169 # define BOOST_PP_INC_169 170 # define BOOST_PP_INC_170 171 # define BOOST_PP_INC_171 172 # define BOOST_PP_INC_172 173 # define BOOST_PP_INC_173 174 # define BOOST_PP_INC_174 175 # define BOOST_PP_INC_175 176 # define BOOST_PP_INC_176 177 # define BOOST_PP_INC_177 178 # define BOOST_PP_INC_178 179 # define BOOST_PP_INC_179 180 # define BOOST_PP_INC_180 181 # define BOOST_PP_INC_181 182 # define BOOST_PP_INC_182 183 # define BOOST_PP_INC_183 184 # define BOOST_PP_INC_184 185 # define BOOST_PP_INC_185 186 # define BOOST_PP_INC_186 187 # define BOOST_PP_INC_187 188 # define BOOST_PP_INC_188 189 # define BOOST_PP_INC_189 190 # define BOOST_PP_INC_190 191 # define BOOST_PP_INC_191 192 # define BOOST_PP_INC_192 193 # define BOOST_PP_INC_193 194 # define BOOST_PP_INC_194 195 # define BOOST_PP_INC_195 196 # define BOOST_PP_INC_196 197 # define BOOST_PP_INC_197 198 # define BOOST_PP_INC_198 199 # define BOOST_PP_INC_199 200 # define BOOST_PP_INC_200 201 # define BOOST_PP_INC_201 202 # define BOOST_PP_INC_202 203 # define BOOST_PP_INC_203 204 # define BOOST_PP_INC_204 205 # define BOOST_PP_INC_205 206 # define BOOST_PP_INC_206 207 # define BOOST_PP_INC_207 208 # define BOOST_PP_INC_208 209 # define BOOST_PP_INC_209 210 # define BOOST_PP_INC_210 211 # define BOOST_PP_INC_211 212 # define BOOST_PP_INC_212 213 # define BOOST_PP_INC_213 214 # define BOOST_PP_INC_214 215 # define BOOST_PP_INC_215 216 # define BOOST_PP_INC_216 217 # define BOOST_PP_INC_217 218 # define BOOST_PP_INC_218 219 # define BOOST_PP_INC_219 220 # define BOOST_PP_INC_220 221 # define BOOST_PP_INC_221 222 # define BOOST_PP_INC_222 223 # define BOOST_PP_INC_223 224 # define BOOST_PP_INC_224 225 # define BOOST_PP_INC_225 226 # define BOOST_PP_INC_226 227 # define BOOST_PP_INC_227 228 # define BOOST_PP_INC_228 229 # define BOOST_PP_INC_229 230 # define BOOST_PP_INC_230 231 # define BOOST_PP_INC_231 232 # define BOOST_PP_INC_232 233 # define BOOST_PP_INC_233 234 # define BOOST_PP_INC_234 235 # define BOOST_PP_INC_235 236 # define BOOST_PP_INC_236 237 # define BOOST_PP_INC_237 238 # define BOOST_PP_INC_238 239 # define BOOST_PP_INC_239 240 # define BOOST_PP_INC_240 241 # define BOOST_PP_INC_241 242 # define BOOST_PP_INC_242 243 # define BOOST_PP_INC_243 244 # define BOOST_PP_INC_244 245 # define BOOST_PP_INC_245 246 # define BOOST_PP_INC_246 247 # define BOOST_PP_INC_247 248 # define BOOST_PP_INC_248 249 # define BOOST_PP_INC_249 250 # define BOOST_PP_INC_250 251 # define BOOST_PP_INC_251 252 # define BOOST_PP_INC_252 253 # define BOOST_PP_INC_253 254 # define BOOST_PP_INC_254 255 # define BOOST_PP_INC_255 256 # define BOOST_PP_INC_256 256 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/arithmetic/sub.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ARITHMETIC_SUB_HPP # define BOOST_PREPROCESSOR_ARITHMETIC_SUB_HPP # # include # include # include # include # # /* BOOST_PP_SUB */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SUB(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y))) # else # define BOOST_PP_SUB(x, y) BOOST_PP_SUB_I(x, y) # define BOOST_PP_SUB_I(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y))) # endif # # define BOOST_PP_SUB_P(d, xy) BOOST_PP_TUPLE_ELEM(2, 1, xy) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SUB_O(d, xy) BOOST_PP_SUB_O_I xy # else # define BOOST_PP_SUB_O(d, xy) BOOST_PP_SUB_O_I(BOOST_PP_TUPLE_ELEM(2, 0, xy), BOOST_PP_TUPLE_ELEM(2, 1, xy)) # endif # # define BOOST_PP_SUB_O_I(x, y) (BOOST_PP_DEC(x), BOOST_PP_DEC(y)) # # /* BOOST_PP_SUB_D */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SUB_D(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y))) # else # define BOOST_PP_SUB_D(d, x, y) BOOST_PP_SUB_D_I(d, x, y) # define BOOST_PP_SUB_D_I(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y))) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/array/data.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ARRAY_DATA_HPP # define BOOST_PREPROCESSOR_ARRAY_DATA_HPP # # include # include # # /* BOOST_PP_ARRAY_DATA */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ARRAY_DATA(array) BOOST_PP_TUPLE_ELEM(2, 1, array) # else # define BOOST_PP_ARRAY_DATA(array) BOOST_PP_ARRAY_DATA_I(array) # define BOOST_PP_ARRAY_DATA_I(array) BOOST_PP_ARRAY_DATA_II array # define BOOST_PP_ARRAY_DATA_II(size, data) data # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/array/elem.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ARRAY_ELEM_HPP # define BOOST_PREPROCESSOR_ARRAY_ELEM_HPP # # include # include # include # include # # /* BOOST_PP_ARRAY_ELEM */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ARRAY_ELEM(i, array) BOOST_PP_TUPLE_ELEM(BOOST_PP_ARRAY_SIZE(array), i, BOOST_PP_ARRAY_DATA(array)) # else # define BOOST_PP_ARRAY_ELEM(i, array) BOOST_PP_ARRAY_ELEM_I(i, array) # define BOOST_PP_ARRAY_ELEM_I(i, array) BOOST_PP_TUPLE_ELEM(BOOST_PP_ARRAY_SIZE(array), i, BOOST_PP_ARRAY_DATA(array)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/array/size.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ARRAY_SIZE_HPP # define BOOST_PREPROCESSOR_ARRAY_SIZE_HPP # # include # include # # /* BOOST_PP_ARRAY_SIZE */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ARRAY_SIZE(array) BOOST_PP_TUPLE_ELEM(2, 0, array) # else # define BOOST_PP_ARRAY_SIZE(array) BOOST_PP_ARRAY_SIZE_I(array) # define BOOST_PP_ARRAY_SIZE_I(array) BOOST_PP_ARRAY_SIZE_II array # define BOOST_PP_ARRAY_SIZE_II(size, data) size # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/cat.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CAT_HPP # define BOOST_PREPROCESSOR_CAT_HPP # # include # # /* BOOST_PP_CAT */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b) # else # define BOOST_PP_CAT(a, b) BOOST_PP_CAT_OO((a, b)) # define BOOST_PP_CAT_OO(par) BOOST_PP_CAT_I ## par # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_CAT_I(a, b) a ## b # else # define BOOST_PP_CAT_I(a, b) BOOST_PP_CAT_II(~, a ## b) # define BOOST_PP_CAT_II(p, res) res # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/comma_if.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_COMMA_IF_HPP # define BOOST_PREPROCESSOR_COMMA_IF_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/comparison/equal.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_COMPARISON_EQUAL_HPP # define BOOST_PREPROCESSOR_COMPARISON_EQUAL_HPP # # include # include # include # # /* BOOST_PP_EQUAL */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_EQUAL(x, y) BOOST_PP_COMPL(BOOST_PP_NOT_EQUAL(x, y)) # else # define BOOST_PP_EQUAL(x, y) BOOST_PP_EQUAL_I(x, y) # define BOOST_PP_EQUAL_I(x, y) BOOST_PP_COMPL(BOOST_PP_NOT_EQUAL(x, y)) # endif # # /* BOOST_PP_EQUAL_D */ # # define BOOST_PP_EQUAL_D(d, x, y) BOOST_PP_EQUAL(x, y) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/comparison/less_equal.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_COMPARISON_LESS_EQUAL_HPP # define BOOST_PREPROCESSOR_COMPARISON_LESS_EQUAL_HPP # # include # include # include # # /* BOOST_PP_LESS_EQUAL */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_LESS_EQUAL(x, y) BOOST_PP_NOT(BOOST_PP_SUB(x, y)) # else # define BOOST_PP_LESS_EQUAL(x, y) BOOST_PP_LESS_EQUAL_I(x, y) # define BOOST_PP_LESS_EQUAL_I(x, y) BOOST_PP_NOT(BOOST_PP_SUB(x, y)) # endif # # /* BOOST_PP_LESS_EQUAL_D */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_LESS_EQUAL_D(d, x, y) BOOST_PP_NOT(BOOST_PP_SUB_D(d, x, y)) # else # define BOOST_PP_LESS_EQUAL_D(d, x, y) BOOST_PP_LESS_EQUAL_D_I(d, x, y) # define BOOST_PP_LESS_EQUAL_D_I(d, x, y) BOOST_PP_NOT(BOOST_PP_SUB_D(d, x, y)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/comparison/not_equal.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_COMPARISON_NOT_EQUAL_HPP # define BOOST_PREPROCESSOR_COMPARISON_NOT_EQUAL_HPP # # include # include # include # # /* BOOST_PP_NOT_EQUAL */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_NOT_EQUAL(x, y) BOOST_PP_NOT_EQUAL_I(x, y) # else # define BOOST_PP_NOT_EQUAL(x, y) BOOST_PP_NOT_EQUAL_OO((x, y)) # define BOOST_PP_NOT_EQUAL_OO(par) BOOST_PP_NOT_EQUAL_I ## par # endif # # define BOOST_PP_NOT_EQUAL_I(x, y) BOOST_PP_CAT(BOOST_PP_NOT_EQUAL_CHECK_, BOOST_PP_NOT_EQUAL_ ## x(0, BOOST_PP_NOT_EQUAL_ ## y)) # # /* BOOST_PP_NOT_EQUAL_D */ # # define BOOST_PP_NOT_EQUAL_D(d, x, y) BOOST_PP_NOT_EQUAL(x, y) # # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NIL 1 # # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_0(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_1(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_2(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_3(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_4(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_5(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_6(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_7(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_8(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_9(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_10(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_11(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_12(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_13(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_14(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_15(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_16(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_17(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_18(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_19(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_20(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_21(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_22(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_23(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_24(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_25(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_26(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_27(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_28(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_29(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_30(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_31(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_32(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_33(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_34(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_35(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_36(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_37(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_38(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_39(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_40(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_41(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_42(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_43(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_44(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_45(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_46(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_47(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_48(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_49(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_50(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_51(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_52(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_53(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_54(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_55(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_56(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_57(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_58(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_59(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_60(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_61(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_62(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_63(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_64(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_65(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_66(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_67(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_68(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_69(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_70(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_71(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_72(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_73(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_74(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_75(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_76(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_77(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_78(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_79(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_80(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_81(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_82(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_83(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_84(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_85(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_86(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_87(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_88(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_89(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_90(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_91(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_92(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_93(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_94(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_95(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_96(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_97(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_98(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_99(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_100(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_101(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_102(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_103(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_104(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_105(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_106(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_107(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_108(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_109(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_110(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_111(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_112(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_113(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_114(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_115(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_116(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_117(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_118(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_119(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_120(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_121(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_122(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_123(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_124(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_125(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_126(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_127(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_128(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_129(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_130(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_131(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_132(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_133(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_134(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_135(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_136(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_137(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_138(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_139(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_140(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_141(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_142(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_143(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_144(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_145(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_146(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_147(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_148(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_149(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_150(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_151(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_152(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_153(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_154(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_155(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_156(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_157(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_158(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_159(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_160(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_161(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_162(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_163(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_164(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_165(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_166(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_167(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_168(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_169(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_170(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_171(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_172(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_173(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_174(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_175(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_176(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_177(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_178(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_179(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_180(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_181(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_182(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_183(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_184(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_185(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_186(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_187(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_188(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_189(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_190(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_191(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_192(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_193(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_194(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_195(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_196(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_197(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_198(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_199(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_200(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_201(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_202(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_203(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_204(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_205(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_206(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_207(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_208(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_209(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_210(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_211(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_212(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_213(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_214(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_215(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_216(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_217(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_218(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_219(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_220(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_221(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_222(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_223(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_224(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_225(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_226(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_227(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_228(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_229(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_230(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_231(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_232(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_233(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_234(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_235(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_236(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_237(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_238(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_239(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_240(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_241(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_242(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_243(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_244(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_245(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_246(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_247(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_248(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_249(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_250(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_251(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_252(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_253(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_254(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_255(c, y) 0 # define BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_256(c, y) 0 # #if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # define BOOST_PP_NOT_EQUAL_0(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_1(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_2(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_3(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_4(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_5(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_6(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_7(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_8(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_9(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_10(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_11(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_12(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_13(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_14(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_15(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_16(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_17(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_18(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_19(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_20(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_21(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_22(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_23(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_24(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_25(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_26(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_27(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_28(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_29(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_30(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_31(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_32(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_33(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_34(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_35(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_36(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_37(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_38(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_39(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_40(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_41(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_42(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_43(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_44(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_45(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_46(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_47(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_48(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_49(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_50(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_51(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_52(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_53(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_54(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_55(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_56(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_57(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_58(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_59(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_60(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_61(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_62(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_63(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_64(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_65(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_66(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_67(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_68(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_69(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_70(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_71(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_72(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_73(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_74(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_75(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_76(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_77(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_78(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_79(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_80(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_81(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_82(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_83(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_84(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_85(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_86(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_87(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_88(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_89(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_90(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_91(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_92(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_93(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_94(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_95(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_96(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_97(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_98(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_99(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_100(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_101(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_102(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_103(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_104(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_105(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_106(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_107(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_108(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_109(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_110(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_111(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_112(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_113(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_114(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_115(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_116(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_117(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_118(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_119(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_120(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_121(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_122(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_123(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_124(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_125(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_126(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_127(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_128(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_129(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_130(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_131(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_132(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_133(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_134(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_135(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_136(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_137(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_138(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_139(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_140(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_141(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_142(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_143(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_144(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_145(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_146(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_147(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_148(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_149(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_150(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_151(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_152(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_153(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_154(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_155(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_156(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_157(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_158(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_159(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_160(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_161(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_162(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_163(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_164(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_165(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_166(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_167(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_168(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_169(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_170(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_171(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_172(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_173(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_174(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_175(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_176(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_177(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_178(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_179(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_180(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_181(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_182(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_183(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_184(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_185(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_186(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_187(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_188(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_189(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_190(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_191(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_192(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_193(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_194(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_195(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_196(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_197(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_198(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_199(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_200(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_201(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_202(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_203(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_204(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_205(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_206(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_207(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_208(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_209(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_210(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_211(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_212(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_213(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_214(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_215(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_216(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_217(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_218(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_219(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_220(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_221(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_222(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_223(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_224(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_225(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_226(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_227(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_228(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_229(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_230(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_231(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_232(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_233(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_234(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_235(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_236(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_237(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_238(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_239(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_240(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_241(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_242(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_243(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_244(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_245(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_246(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_247(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_248(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_249(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_250(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_251(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_252(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_253(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_254(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_255(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_256(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y(1, BOOST_PP_NIL)) # else # define BOOST_PP_NOT_EQUAL_0(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_1(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_2(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_3(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_4(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_5(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_6(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_7(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_8(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_9(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_10(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_11(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_12(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_13(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_14(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_15(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_16(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_17(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_18(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_19(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_20(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_21(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_22(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_23(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_24(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_25(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_26(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_27(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_28(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_29(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_30(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_31(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_32(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_33(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_34(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_35(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_36(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_37(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_38(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_39(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_40(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_41(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_42(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_43(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_44(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_45(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_46(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_47(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_48(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_49(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_50(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_51(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_52(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_53(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_54(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_55(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_56(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_57(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_58(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_59(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_60(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_61(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_62(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_63(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_64(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_65(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_66(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_67(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_68(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_69(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_70(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_71(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_72(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_73(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_74(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_75(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_76(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_77(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_78(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_79(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_80(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_81(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_82(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_83(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_84(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_85(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_86(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_87(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_88(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_89(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_90(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_91(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_92(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_93(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_94(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_95(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_96(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_97(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_98(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_99(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_100(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_101(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_102(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_103(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_104(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_105(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_106(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_107(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_108(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_109(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_110(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_111(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_112(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_113(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_114(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_115(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_116(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_117(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_118(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_119(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_120(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_121(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_122(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_123(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_124(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_125(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_126(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_127(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_128(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_129(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_130(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_131(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_132(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_133(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_134(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_135(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_136(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_137(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_138(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_139(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_140(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_141(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_142(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_143(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_144(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_145(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_146(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_147(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_148(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_149(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_150(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_151(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_152(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_153(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_154(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_155(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_156(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_157(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_158(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_159(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_160(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_161(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_162(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_163(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_164(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_165(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_166(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_167(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_168(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_169(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_170(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_171(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_172(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_173(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_174(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_175(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_176(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_177(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_178(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_179(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_180(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_181(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_182(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_183(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_184(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_185(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_186(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_187(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_188(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_189(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_190(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_191(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_192(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_193(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_194(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_195(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_196(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_197(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_198(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_199(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_200(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_201(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_202(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_203(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_204(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_205(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_206(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_207(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_208(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_209(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_210(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_211(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_212(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_213(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_214(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_215(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_216(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_217(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_218(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_219(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_220(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_221(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_222(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_223(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_224(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_225(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_226(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_227(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_228(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_229(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_230(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_231(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_232(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_233(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_234(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_235(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_236(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_237(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_238(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_239(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_240(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_241(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_242(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_243(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_244(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_245(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_246(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_247(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_248(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_249(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_250(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_251(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_252(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_253(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_254(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_255(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # define BOOST_PP_NOT_EQUAL_256(c, y) BOOST_PP_IIF(c, BOOST_PP_NIL, y##(1, BOOST_PP_NIL)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/config/config.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002-2011. * # * (C) Copyright Edward Diener 2011. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP # define BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP # # /* BOOST_PP_CONFIG_FLAGS */ # # define BOOST_PP_CONFIG_STRICT() 0x0001 # define BOOST_PP_CONFIG_IDEAL() 0x0002 # # define BOOST_PP_CONFIG_MSVC() 0x0004 # define BOOST_PP_CONFIG_MWCC() 0x0008 # define BOOST_PP_CONFIG_BCC() 0x0010 # define BOOST_PP_CONFIG_EDG() 0x0020 # define BOOST_PP_CONFIG_DMC() 0x0040 # # ifndef BOOST_PP_CONFIG_FLAGS # if defined(__GCCXML__) # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT()) # elif defined(__WAVE__) # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT()) # elif defined(__MWERKS__) && __MWERKS__ >= 0x3200 # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT()) # elif defined(__EDG__) || defined(__EDG_VERSION__) # if defined(_MSC_VER) && (defined(__INTELLISENSE__) || __EDG_VERSION__ >= 308) # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC()) # else # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_EDG() | BOOST_PP_CONFIG_STRICT()) # endif # elif defined(__MWERKS__) # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MWCC()) # elif defined(__DMC__) # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_DMC()) # elif defined(__BORLANDC__) && __BORLANDC__ >= 0x581 # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT()) # elif defined(__BORLANDC__) || defined(__IBMC__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_BCC()) # elif defined(_MSC_VER) && !defined(__clang__) # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC()) # else # define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT()) # endif # endif # # /* BOOST_PP_CONFIG_EXTENDED_LINE_INFO */ # # ifndef BOOST_PP_CONFIG_EXTENDED_LINE_INFO # define BOOST_PP_CONFIG_EXTENDED_LINE_INFO 0 # endif # # /* BOOST_PP_CONFIG_ERRORS */ # # ifndef BOOST_PP_CONFIG_ERRORS # ifdef NDEBUG # define BOOST_PP_CONFIG_ERRORS 0 # else # define BOOST_PP_CONFIG_ERRORS 1 # endif # endif # # /* BOOST_PP_VARIADICS */ # # define BOOST_PP_VARIADICS_MSVC 0 # if !defined BOOST_PP_VARIADICS # /* variadic support explicitly disabled for all untested compilers */ # if defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || ( defined __SUNPRO_CC && __SUNPRO_CC < 0x5130 ) || defined __HP_aCC && !defined __EDG__ || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI # define BOOST_PP_VARIADICS 0 # /* VC++ (C/C++) */ # elif defined _MSC_VER && _MSC_VER >= 1400 && (!defined __EDG__ || defined(__INTELLISENSE__)) && !defined __clang__ # define BOOST_PP_VARIADICS 1 # undef BOOST_PP_VARIADICS_MSVC # define BOOST_PP_VARIADICS_MSVC 1 # /* Wave (C/C++), GCC (C++) */ # elif defined __WAVE__ && __WAVE_HAS_VARIADICS__ || defined __GNUC__ && defined __GXX_EXPERIMENTAL_CXX0X__ && __GXX_EXPERIMENTAL_CXX0X__ # define BOOST_PP_VARIADICS 1 # /* EDG-based (C/C++), GCC (C), and unknown (C/C++) */ # elif !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L # define BOOST_PP_VARIADICS 1 # else # define BOOST_PP_VARIADICS 0 # endif # elif !BOOST_PP_VARIADICS + 1 < 2 # undef BOOST_PP_VARIADICS # define BOOST_PP_VARIADICS 1 # if defined _MSC_VER && _MSC_VER >= 1400 && (defined(__INTELLISENSE__) || !(defined __EDG__ || defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI)) # undef BOOST_PP_VARIADICS_MSVC # define BOOST_PP_VARIADICS_MSVC 1 # endif # else # undef BOOST_PP_VARIADICS # define BOOST_PP_VARIADICS 0 # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/detail/dmc/while.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_DETAIL_WHILE_HPP # define BOOST_PREPROCESSOR_CONTROL_DETAIL_WHILE_HPP # # include # include # include # # define BOOST_PP_WHILE_1(p, o, s) BOOST_PP_WHILE_1_C(BOOST_PP_BOOL(p##(2, s)), p, o, s) # define BOOST_PP_WHILE_2(p, o, s) BOOST_PP_WHILE_2_C(BOOST_PP_BOOL(p##(3, s)), p, o, s) # define BOOST_PP_WHILE_3(p, o, s) BOOST_PP_WHILE_3_C(BOOST_PP_BOOL(p##(4, s)), p, o, s) # define BOOST_PP_WHILE_4(p, o, s) BOOST_PP_WHILE_4_C(BOOST_PP_BOOL(p##(5, s)), p, o, s) # define BOOST_PP_WHILE_5(p, o, s) BOOST_PP_WHILE_5_C(BOOST_PP_BOOL(p##(6, s)), p, o, s) # define BOOST_PP_WHILE_6(p, o, s) BOOST_PP_WHILE_6_C(BOOST_PP_BOOL(p##(7, s)), p, o, s) # define BOOST_PP_WHILE_7(p, o, s) BOOST_PP_WHILE_7_C(BOOST_PP_BOOL(p##(8, s)), p, o, s) # define BOOST_PP_WHILE_8(p, o, s) BOOST_PP_WHILE_8_C(BOOST_PP_BOOL(p##(9, s)), p, o, s) # define BOOST_PP_WHILE_9(p, o, s) BOOST_PP_WHILE_9_C(BOOST_PP_BOOL(p##(10, s)), p, o, s) # define BOOST_PP_WHILE_10(p, o, s) BOOST_PP_WHILE_10_C(BOOST_PP_BOOL(p##(11, s)), p, o, s) # define BOOST_PP_WHILE_11(p, o, s) BOOST_PP_WHILE_11_C(BOOST_PP_BOOL(p##(12, s)), p, o, s) # define BOOST_PP_WHILE_12(p, o, s) BOOST_PP_WHILE_12_C(BOOST_PP_BOOL(p##(13, s)), p, o, s) # define BOOST_PP_WHILE_13(p, o, s) BOOST_PP_WHILE_13_C(BOOST_PP_BOOL(p##(14, s)), p, o, s) # define BOOST_PP_WHILE_14(p, o, s) BOOST_PP_WHILE_14_C(BOOST_PP_BOOL(p##(15, s)), p, o, s) # define BOOST_PP_WHILE_15(p, o, s) BOOST_PP_WHILE_15_C(BOOST_PP_BOOL(p##(16, s)), p, o, s) # define BOOST_PP_WHILE_16(p, o, s) BOOST_PP_WHILE_16_C(BOOST_PP_BOOL(p##(17, s)), p, o, s) # define BOOST_PP_WHILE_17(p, o, s) BOOST_PP_WHILE_17_C(BOOST_PP_BOOL(p##(18, s)), p, o, s) # define BOOST_PP_WHILE_18(p, o, s) BOOST_PP_WHILE_18_C(BOOST_PP_BOOL(p##(19, s)), p, o, s) # define BOOST_PP_WHILE_19(p, o, s) BOOST_PP_WHILE_19_C(BOOST_PP_BOOL(p##(20, s)), p, o, s) # define BOOST_PP_WHILE_20(p, o, s) BOOST_PP_WHILE_20_C(BOOST_PP_BOOL(p##(21, s)), p, o, s) # define BOOST_PP_WHILE_21(p, o, s) BOOST_PP_WHILE_21_C(BOOST_PP_BOOL(p##(22, s)), p, o, s) # define BOOST_PP_WHILE_22(p, o, s) BOOST_PP_WHILE_22_C(BOOST_PP_BOOL(p##(23, s)), p, o, s) # define BOOST_PP_WHILE_23(p, o, s) BOOST_PP_WHILE_23_C(BOOST_PP_BOOL(p##(24, s)), p, o, s) # define BOOST_PP_WHILE_24(p, o, s) BOOST_PP_WHILE_24_C(BOOST_PP_BOOL(p##(25, s)), p, o, s) # define BOOST_PP_WHILE_25(p, o, s) BOOST_PP_WHILE_25_C(BOOST_PP_BOOL(p##(26, s)), p, o, s) # define BOOST_PP_WHILE_26(p, o, s) BOOST_PP_WHILE_26_C(BOOST_PP_BOOL(p##(27, s)), p, o, s) # define BOOST_PP_WHILE_27(p, o, s) BOOST_PP_WHILE_27_C(BOOST_PP_BOOL(p##(28, s)), p, o, s) # define BOOST_PP_WHILE_28(p, o, s) BOOST_PP_WHILE_28_C(BOOST_PP_BOOL(p##(29, s)), p, o, s) # define BOOST_PP_WHILE_29(p, o, s) BOOST_PP_WHILE_29_C(BOOST_PP_BOOL(p##(30, s)), p, o, s) # define BOOST_PP_WHILE_30(p, o, s) BOOST_PP_WHILE_30_C(BOOST_PP_BOOL(p##(31, s)), p, o, s) # define BOOST_PP_WHILE_31(p, o, s) BOOST_PP_WHILE_31_C(BOOST_PP_BOOL(p##(32, s)), p, o, s) # define BOOST_PP_WHILE_32(p, o, s) BOOST_PP_WHILE_32_C(BOOST_PP_BOOL(p##(33, s)), p, o, s) # define BOOST_PP_WHILE_33(p, o, s) BOOST_PP_WHILE_33_C(BOOST_PP_BOOL(p##(34, s)), p, o, s) # define BOOST_PP_WHILE_34(p, o, s) BOOST_PP_WHILE_34_C(BOOST_PP_BOOL(p##(35, s)), p, o, s) # define BOOST_PP_WHILE_35(p, o, s) BOOST_PP_WHILE_35_C(BOOST_PP_BOOL(p##(36, s)), p, o, s) # define BOOST_PP_WHILE_36(p, o, s) BOOST_PP_WHILE_36_C(BOOST_PP_BOOL(p##(37, s)), p, o, s) # define BOOST_PP_WHILE_37(p, o, s) BOOST_PP_WHILE_37_C(BOOST_PP_BOOL(p##(38, s)), p, o, s) # define BOOST_PP_WHILE_38(p, o, s) BOOST_PP_WHILE_38_C(BOOST_PP_BOOL(p##(39, s)), p, o, s) # define BOOST_PP_WHILE_39(p, o, s) BOOST_PP_WHILE_39_C(BOOST_PP_BOOL(p##(40, s)), p, o, s) # define BOOST_PP_WHILE_40(p, o, s) BOOST_PP_WHILE_40_C(BOOST_PP_BOOL(p##(41, s)), p, o, s) # define BOOST_PP_WHILE_41(p, o, s) BOOST_PP_WHILE_41_C(BOOST_PP_BOOL(p##(42, s)), p, o, s) # define BOOST_PP_WHILE_42(p, o, s) BOOST_PP_WHILE_42_C(BOOST_PP_BOOL(p##(43, s)), p, o, s) # define BOOST_PP_WHILE_43(p, o, s) BOOST_PP_WHILE_43_C(BOOST_PP_BOOL(p##(44, s)), p, o, s) # define BOOST_PP_WHILE_44(p, o, s) BOOST_PP_WHILE_44_C(BOOST_PP_BOOL(p##(45, s)), p, o, s) # define BOOST_PP_WHILE_45(p, o, s) BOOST_PP_WHILE_45_C(BOOST_PP_BOOL(p##(46, s)), p, o, s) # define BOOST_PP_WHILE_46(p, o, s) BOOST_PP_WHILE_46_C(BOOST_PP_BOOL(p##(47, s)), p, o, s) # define BOOST_PP_WHILE_47(p, o, s) BOOST_PP_WHILE_47_C(BOOST_PP_BOOL(p##(48, s)), p, o, s) # define BOOST_PP_WHILE_48(p, o, s) BOOST_PP_WHILE_48_C(BOOST_PP_BOOL(p##(49, s)), p, o, s) # define BOOST_PP_WHILE_49(p, o, s) BOOST_PP_WHILE_49_C(BOOST_PP_BOOL(p##(50, s)), p, o, s) # define BOOST_PP_WHILE_50(p, o, s) BOOST_PP_WHILE_50_C(BOOST_PP_BOOL(p##(51, s)), p, o, s) # define BOOST_PP_WHILE_51(p, o, s) BOOST_PP_WHILE_51_C(BOOST_PP_BOOL(p##(52, s)), p, o, s) # define BOOST_PP_WHILE_52(p, o, s) BOOST_PP_WHILE_52_C(BOOST_PP_BOOL(p##(53, s)), p, o, s) # define BOOST_PP_WHILE_53(p, o, s) BOOST_PP_WHILE_53_C(BOOST_PP_BOOL(p##(54, s)), p, o, s) # define BOOST_PP_WHILE_54(p, o, s) BOOST_PP_WHILE_54_C(BOOST_PP_BOOL(p##(55, s)), p, o, s) # define BOOST_PP_WHILE_55(p, o, s) BOOST_PP_WHILE_55_C(BOOST_PP_BOOL(p##(56, s)), p, o, s) # define BOOST_PP_WHILE_56(p, o, s) BOOST_PP_WHILE_56_C(BOOST_PP_BOOL(p##(57, s)), p, o, s) # define BOOST_PP_WHILE_57(p, o, s) BOOST_PP_WHILE_57_C(BOOST_PP_BOOL(p##(58, s)), p, o, s) # define BOOST_PP_WHILE_58(p, o, s) BOOST_PP_WHILE_58_C(BOOST_PP_BOOL(p##(59, s)), p, o, s) # define BOOST_PP_WHILE_59(p, o, s) BOOST_PP_WHILE_59_C(BOOST_PP_BOOL(p##(60, s)), p, o, s) # define BOOST_PP_WHILE_60(p, o, s) BOOST_PP_WHILE_60_C(BOOST_PP_BOOL(p##(61, s)), p, o, s) # define BOOST_PP_WHILE_61(p, o, s) BOOST_PP_WHILE_61_C(BOOST_PP_BOOL(p##(62, s)), p, o, s) # define BOOST_PP_WHILE_62(p, o, s) BOOST_PP_WHILE_62_C(BOOST_PP_BOOL(p##(63, s)), p, o, s) # define BOOST_PP_WHILE_63(p, o, s) BOOST_PP_WHILE_63_C(BOOST_PP_BOOL(p##(64, s)), p, o, s) # define BOOST_PP_WHILE_64(p, o, s) BOOST_PP_WHILE_64_C(BOOST_PP_BOOL(p##(65, s)), p, o, s) # define BOOST_PP_WHILE_65(p, o, s) BOOST_PP_WHILE_65_C(BOOST_PP_BOOL(p##(66, s)), p, o, s) # define BOOST_PP_WHILE_66(p, o, s) BOOST_PP_WHILE_66_C(BOOST_PP_BOOL(p##(67, s)), p, o, s) # define BOOST_PP_WHILE_67(p, o, s) BOOST_PP_WHILE_67_C(BOOST_PP_BOOL(p##(68, s)), p, o, s) # define BOOST_PP_WHILE_68(p, o, s) BOOST_PP_WHILE_68_C(BOOST_PP_BOOL(p##(69, s)), p, o, s) # define BOOST_PP_WHILE_69(p, o, s) BOOST_PP_WHILE_69_C(BOOST_PP_BOOL(p##(70, s)), p, o, s) # define BOOST_PP_WHILE_70(p, o, s) BOOST_PP_WHILE_70_C(BOOST_PP_BOOL(p##(71, s)), p, o, s) # define BOOST_PP_WHILE_71(p, o, s) BOOST_PP_WHILE_71_C(BOOST_PP_BOOL(p##(72, s)), p, o, s) # define BOOST_PP_WHILE_72(p, o, s) BOOST_PP_WHILE_72_C(BOOST_PP_BOOL(p##(73, s)), p, o, s) # define BOOST_PP_WHILE_73(p, o, s) BOOST_PP_WHILE_73_C(BOOST_PP_BOOL(p##(74, s)), p, o, s) # define BOOST_PP_WHILE_74(p, o, s) BOOST_PP_WHILE_74_C(BOOST_PP_BOOL(p##(75, s)), p, o, s) # define BOOST_PP_WHILE_75(p, o, s) BOOST_PP_WHILE_75_C(BOOST_PP_BOOL(p##(76, s)), p, o, s) # define BOOST_PP_WHILE_76(p, o, s) BOOST_PP_WHILE_76_C(BOOST_PP_BOOL(p##(77, s)), p, o, s) # define BOOST_PP_WHILE_77(p, o, s) BOOST_PP_WHILE_77_C(BOOST_PP_BOOL(p##(78, s)), p, o, s) # define BOOST_PP_WHILE_78(p, o, s) BOOST_PP_WHILE_78_C(BOOST_PP_BOOL(p##(79, s)), p, o, s) # define BOOST_PP_WHILE_79(p, o, s) BOOST_PP_WHILE_79_C(BOOST_PP_BOOL(p##(80, s)), p, o, s) # define BOOST_PP_WHILE_80(p, o, s) BOOST_PP_WHILE_80_C(BOOST_PP_BOOL(p##(81, s)), p, o, s) # define BOOST_PP_WHILE_81(p, o, s) BOOST_PP_WHILE_81_C(BOOST_PP_BOOL(p##(82, s)), p, o, s) # define BOOST_PP_WHILE_82(p, o, s) BOOST_PP_WHILE_82_C(BOOST_PP_BOOL(p##(83, s)), p, o, s) # define BOOST_PP_WHILE_83(p, o, s) BOOST_PP_WHILE_83_C(BOOST_PP_BOOL(p##(84, s)), p, o, s) # define BOOST_PP_WHILE_84(p, o, s) BOOST_PP_WHILE_84_C(BOOST_PP_BOOL(p##(85, s)), p, o, s) # define BOOST_PP_WHILE_85(p, o, s) BOOST_PP_WHILE_85_C(BOOST_PP_BOOL(p##(86, s)), p, o, s) # define BOOST_PP_WHILE_86(p, o, s) BOOST_PP_WHILE_86_C(BOOST_PP_BOOL(p##(87, s)), p, o, s) # define BOOST_PP_WHILE_87(p, o, s) BOOST_PP_WHILE_87_C(BOOST_PP_BOOL(p##(88, s)), p, o, s) # define BOOST_PP_WHILE_88(p, o, s) BOOST_PP_WHILE_88_C(BOOST_PP_BOOL(p##(89, s)), p, o, s) # define BOOST_PP_WHILE_89(p, o, s) BOOST_PP_WHILE_89_C(BOOST_PP_BOOL(p##(90, s)), p, o, s) # define BOOST_PP_WHILE_90(p, o, s) BOOST_PP_WHILE_90_C(BOOST_PP_BOOL(p##(91, s)), p, o, s) # define BOOST_PP_WHILE_91(p, o, s) BOOST_PP_WHILE_91_C(BOOST_PP_BOOL(p##(92, s)), p, o, s) # define BOOST_PP_WHILE_92(p, o, s) BOOST_PP_WHILE_92_C(BOOST_PP_BOOL(p##(93, s)), p, o, s) # define BOOST_PP_WHILE_93(p, o, s) BOOST_PP_WHILE_93_C(BOOST_PP_BOOL(p##(94, s)), p, o, s) # define BOOST_PP_WHILE_94(p, o, s) BOOST_PP_WHILE_94_C(BOOST_PP_BOOL(p##(95, s)), p, o, s) # define BOOST_PP_WHILE_95(p, o, s) BOOST_PP_WHILE_95_C(BOOST_PP_BOOL(p##(96, s)), p, o, s) # define BOOST_PP_WHILE_96(p, o, s) BOOST_PP_WHILE_96_C(BOOST_PP_BOOL(p##(97, s)), p, o, s) # define BOOST_PP_WHILE_97(p, o, s) BOOST_PP_WHILE_97_C(BOOST_PP_BOOL(p##(98, s)), p, o, s) # define BOOST_PP_WHILE_98(p, o, s) BOOST_PP_WHILE_98_C(BOOST_PP_BOOL(p##(99, s)), p, o, s) # define BOOST_PP_WHILE_99(p, o, s) BOOST_PP_WHILE_99_C(BOOST_PP_BOOL(p##(100, s)), p, o, s) # define BOOST_PP_WHILE_100(p, o, s) BOOST_PP_WHILE_100_C(BOOST_PP_BOOL(p##(101, s)), p, o, s) # define BOOST_PP_WHILE_101(p, o, s) BOOST_PP_WHILE_101_C(BOOST_PP_BOOL(p##(102, s)), p, o, s) # define BOOST_PP_WHILE_102(p, o, s) BOOST_PP_WHILE_102_C(BOOST_PP_BOOL(p##(103, s)), p, o, s) # define BOOST_PP_WHILE_103(p, o, s) BOOST_PP_WHILE_103_C(BOOST_PP_BOOL(p##(104, s)), p, o, s) # define BOOST_PP_WHILE_104(p, o, s) BOOST_PP_WHILE_104_C(BOOST_PP_BOOL(p##(105, s)), p, o, s) # define BOOST_PP_WHILE_105(p, o, s) BOOST_PP_WHILE_105_C(BOOST_PP_BOOL(p##(106, s)), p, o, s) # define BOOST_PP_WHILE_106(p, o, s) BOOST_PP_WHILE_106_C(BOOST_PP_BOOL(p##(107, s)), p, o, s) # define BOOST_PP_WHILE_107(p, o, s) BOOST_PP_WHILE_107_C(BOOST_PP_BOOL(p##(108, s)), p, o, s) # define BOOST_PP_WHILE_108(p, o, s) BOOST_PP_WHILE_108_C(BOOST_PP_BOOL(p##(109, s)), p, o, s) # define BOOST_PP_WHILE_109(p, o, s) BOOST_PP_WHILE_109_C(BOOST_PP_BOOL(p##(110, s)), p, o, s) # define BOOST_PP_WHILE_110(p, o, s) BOOST_PP_WHILE_110_C(BOOST_PP_BOOL(p##(111, s)), p, o, s) # define BOOST_PP_WHILE_111(p, o, s) BOOST_PP_WHILE_111_C(BOOST_PP_BOOL(p##(112, s)), p, o, s) # define BOOST_PP_WHILE_112(p, o, s) BOOST_PP_WHILE_112_C(BOOST_PP_BOOL(p##(113, s)), p, o, s) # define BOOST_PP_WHILE_113(p, o, s) BOOST_PP_WHILE_113_C(BOOST_PP_BOOL(p##(114, s)), p, o, s) # define BOOST_PP_WHILE_114(p, o, s) BOOST_PP_WHILE_114_C(BOOST_PP_BOOL(p##(115, s)), p, o, s) # define BOOST_PP_WHILE_115(p, o, s) BOOST_PP_WHILE_115_C(BOOST_PP_BOOL(p##(116, s)), p, o, s) # define BOOST_PP_WHILE_116(p, o, s) BOOST_PP_WHILE_116_C(BOOST_PP_BOOL(p##(117, s)), p, o, s) # define BOOST_PP_WHILE_117(p, o, s) BOOST_PP_WHILE_117_C(BOOST_PP_BOOL(p##(118, s)), p, o, s) # define BOOST_PP_WHILE_118(p, o, s) BOOST_PP_WHILE_118_C(BOOST_PP_BOOL(p##(119, s)), p, o, s) # define BOOST_PP_WHILE_119(p, o, s) BOOST_PP_WHILE_119_C(BOOST_PP_BOOL(p##(120, s)), p, o, s) # define BOOST_PP_WHILE_120(p, o, s) BOOST_PP_WHILE_120_C(BOOST_PP_BOOL(p##(121, s)), p, o, s) # define BOOST_PP_WHILE_121(p, o, s) BOOST_PP_WHILE_121_C(BOOST_PP_BOOL(p##(122, s)), p, o, s) # define BOOST_PP_WHILE_122(p, o, s) BOOST_PP_WHILE_122_C(BOOST_PP_BOOL(p##(123, s)), p, o, s) # define BOOST_PP_WHILE_123(p, o, s) BOOST_PP_WHILE_123_C(BOOST_PP_BOOL(p##(124, s)), p, o, s) # define BOOST_PP_WHILE_124(p, o, s) BOOST_PP_WHILE_124_C(BOOST_PP_BOOL(p##(125, s)), p, o, s) # define BOOST_PP_WHILE_125(p, o, s) BOOST_PP_WHILE_125_C(BOOST_PP_BOOL(p##(126, s)), p, o, s) # define BOOST_PP_WHILE_126(p, o, s) BOOST_PP_WHILE_126_C(BOOST_PP_BOOL(p##(127, s)), p, o, s) # define BOOST_PP_WHILE_127(p, o, s) BOOST_PP_WHILE_127_C(BOOST_PP_BOOL(p##(128, s)), p, o, s) # define BOOST_PP_WHILE_128(p, o, s) BOOST_PP_WHILE_128_C(BOOST_PP_BOOL(p##(129, s)), p, o, s) # define BOOST_PP_WHILE_129(p, o, s) BOOST_PP_WHILE_129_C(BOOST_PP_BOOL(p##(130, s)), p, o, s) # define BOOST_PP_WHILE_130(p, o, s) BOOST_PP_WHILE_130_C(BOOST_PP_BOOL(p##(131, s)), p, o, s) # define BOOST_PP_WHILE_131(p, o, s) BOOST_PP_WHILE_131_C(BOOST_PP_BOOL(p##(132, s)), p, o, s) # define BOOST_PP_WHILE_132(p, o, s) BOOST_PP_WHILE_132_C(BOOST_PP_BOOL(p##(133, s)), p, o, s) # define BOOST_PP_WHILE_133(p, o, s) BOOST_PP_WHILE_133_C(BOOST_PP_BOOL(p##(134, s)), p, o, s) # define BOOST_PP_WHILE_134(p, o, s) BOOST_PP_WHILE_134_C(BOOST_PP_BOOL(p##(135, s)), p, o, s) # define BOOST_PP_WHILE_135(p, o, s) BOOST_PP_WHILE_135_C(BOOST_PP_BOOL(p##(136, s)), p, o, s) # define BOOST_PP_WHILE_136(p, o, s) BOOST_PP_WHILE_136_C(BOOST_PP_BOOL(p##(137, s)), p, o, s) # define BOOST_PP_WHILE_137(p, o, s) BOOST_PP_WHILE_137_C(BOOST_PP_BOOL(p##(138, s)), p, o, s) # define BOOST_PP_WHILE_138(p, o, s) BOOST_PP_WHILE_138_C(BOOST_PP_BOOL(p##(139, s)), p, o, s) # define BOOST_PP_WHILE_139(p, o, s) BOOST_PP_WHILE_139_C(BOOST_PP_BOOL(p##(140, s)), p, o, s) # define BOOST_PP_WHILE_140(p, o, s) BOOST_PP_WHILE_140_C(BOOST_PP_BOOL(p##(141, s)), p, o, s) # define BOOST_PP_WHILE_141(p, o, s) BOOST_PP_WHILE_141_C(BOOST_PP_BOOL(p##(142, s)), p, o, s) # define BOOST_PP_WHILE_142(p, o, s) BOOST_PP_WHILE_142_C(BOOST_PP_BOOL(p##(143, s)), p, o, s) # define BOOST_PP_WHILE_143(p, o, s) BOOST_PP_WHILE_143_C(BOOST_PP_BOOL(p##(144, s)), p, o, s) # define BOOST_PP_WHILE_144(p, o, s) BOOST_PP_WHILE_144_C(BOOST_PP_BOOL(p##(145, s)), p, o, s) # define BOOST_PP_WHILE_145(p, o, s) BOOST_PP_WHILE_145_C(BOOST_PP_BOOL(p##(146, s)), p, o, s) # define BOOST_PP_WHILE_146(p, o, s) BOOST_PP_WHILE_146_C(BOOST_PP_BOOL(p##(147, s)), p, o, s) # define BOOST_PP_WHILE_147(p, o, s) BOOST_PP_WHILE_147_C(BOOST_PP_BOOL(p##(148, s)), p, o, s) # define BOOST_PP_WHILE_148(p, o, s) BOOST_PP_WHILE_148_C(BOOST_PP_BOOL(p##(149, s)), p, o, s) # define BOOST_PP_WHILE_149(p, o, s) BOOST_PP_WHILE_149_C(BOOST_PP_BOOL(p##(150, s)), p, o, s) # define BOOST_PP_WHILE_150(p, o, s) BOOST_PP_WHILE_150_C(BOOST_PP_BOOL(p##(151, s)), p, o, s) # define BOOST_PP_WHILE_151(p, o, s) BOOST_PP_WHILE_151_C(BOOST_PP_BOOL(p##(152, s)), p, o, s) # define BOOST_PP_WHILE_152(p, o, s) BOOST_PP_WHILE_152_C(BOOST_PP_BOOL(p##(153, s)), p, o, s) # define BOOST_PP_WHILE_153(p, o, s) BOOST_PP_WHILE_153_C(BOOST_PP_BOOL(p##(154, s)), p, o, s) # define BOOST_PP_WHILE_154(p, o, s) BOOST_PP_WHILE_154_C(BOOST_PP_BOOL(p##(155, s)), p, o, s) # define BOOST_PP_WHILE_155(p, o, s) BOOST_PP_WHILE_155_C(BOOST_PP_BOOL(p##(156, s)), p, o, s) # define BOOST_PP_WHILE_156(p, o, s) BOOST_PP_WHILE_156_C(BOOST_PP_BOOL(p##(157, s)), p, o, s) # define BOOST_PP_WHILE_157(p, o, s) BOOST_PP_WHILE_157_C(BOOST_PP_BOOL(p##(158, s)), p, o, s) # define BOOST_PP_WHILE_158(p, o, s) BOOST_PP_WHILE_158_C(BOOST_PP_BOOL(p##(159, s)), p, o, s) # define BOOST_PP_WHILE_159(p, o, s) BOOST_PP_WHILE_159_C(BOOST_PP_BOOL(p##(160, s)), p, o, s) # define BOOST_PP_WHILE_160(p, o, s) BOOST_PP_WHILE_160_C(BOOST_PP_BOOL(p##(161, s)), p, o, s) # define BOOST_PP_WHILE_161(p, o, s) BOOST_PP_WHILE_161_C(BOOST_PP_BOOL(p##(162, s)), p, o, s) # define BOOST_PP_WHILE_162(p, o, s) BOOST_PP_WHILE_162_C(BOOST_PP_BOOL(p##(163, s)), p, o, s) # define BOOST_PP_WHILE_163(p, o, s) BOOST_PP_WHILE_163_C(BOOST_PP_BOOL(p##(164, s)), p, o, s) # define BOOST_PP_WHILE_164(p, o, s) BOOST_PP_WHILE_164_C(BOOST_PP_BOOL(p##(165, s)), p, o, s) # define BOOST_PP_WHILE_165(p, o, s) BOOST_PP_WHILE_165_C(BOOST_PP_BOOL(p##(166, s)), p, o, s) # define BOOST_PP_WHILE_166(p, o, s) BOOST_PP_WHILE_166_C(BOOST_PP_BOOL(p##(167, s)), p, o, s) # define BOOST_PP_WHILE_167(p, o, s) BOOST_PP_WHILE_167_C(BOOST_PP_BOOL(p##(168, s)), p, o, s) # define BOOST_PP_WHILE_168(p, o, s) BOOST_PP_WHILE_168_C(BOOST_PP_BOOL(p##(169, s)), p, o, s) # define BOOST_PP_WHILE_169(p, o, s) BOOST_PP_WHILE_169_C(BOOST_PP_BOOL(p##(170, s)), p, o, s) # define BOOST_PP_WHILE_170(p, o, s) BOOST_PP_WHILE_170_C(BOOST_PP_BOOL(p##(171, s)), p, o, s) # define BOOST_PP_WHILE_171(p, o, s) BOOST_PP_WHILE_171_C(BOOST_PP_BOOL(p##(172, s)), p, o, s) # define BOOST_PP_WHILE_172(p, o, s) BOOST_PP_WHILE_172_C(BOOST_PP_BOOL(p##(173, s)), p, o, s) # define BOOST_PP_WHILE_173(p, o, s) BOOST_PP_WHILE_173_C(BOOST_PP_BOOL(p##(174, s)), p, o, s) # define BOOST_PP_WHILE_174(p, o, s) BOOST_PP_WHILE_174_C(BOOST_PP_BOOL(p##(175, s)), p, o, s) # define BOOST_PP_WHILE_175(p, o, s) BOOST_PP_WHILE_175_C(BOOST_PP_BOOL(p##(176, s)), p, o, s) # define BOOST_PP_WHILE_176(p, o, s) BOOST_PP_WHILE_176_C(BOOST_PP_BOOL(p##(177, s)), p, o, s) # define BOOST_PP_WHILE_177(p, o, s) BOOST_PP_WHILE_177_C(BOOST_PP_BOOL(p##(178, s)), p, o, s) # define BOOST_PP_WHILE_178(p, o, s) BOOST_PP_WHILE_178_C(BOOST_PP_BOOL(p##(179, s)), p, o, s) # define BOOST_PP_WHILE_179(p, o, s) BOOST_PP_WHILE_179_C(BOOST_PP_BOOL(p##(180, s)), p, o, s) # define BOOST_PP_WHILE_180(p, o, s) BOOST_PP_WHILE_180_C(BOOST_PP_BOOL(p##(181, s)), p, o, s) # define BOOST_PP_WHILE_181(p, o, s) BOOST_PP_WHILE_181_C(BOOST_PP_BOOL(p##(182, s)), p, o, s) # define BOOST_PP_WHILE_182(p, o, s) BOOST_PP_WHILE_182_C(BOOST_PP_BOOL(p##(183, s)), p, o, s) # define BOOST_PP_WHILE_183(p, o, s) BOOST_PP_WHILE_183_C(BOOST_PP_BOOL(p##(184, s)), p, o, s) # define BOOST_PP_WHILE_184(p, o, s) BOOST_PP_WHILE_184_C(BOOST_PP_BOOL(p##(185, s)), p, o, s) # define BOOST_PP_WHILE_185(p, o, s) BOOST_PP_WHILE_185_C(BOOST_PP_BOOL(p##(186, s)), p, o, s) # define BOOST_PP_WHILE_186(p, o, s) BOOST_PP_WHILE_186_C(BOOST_PP_BOOL(p##(187, s)), p, o, s) # define BOOST_PP_WHILE_187(p, o, s) BOOST_PP_WHILE_187_C(BOOST_PP_BOOL(p##(188, s)), p, o, s) # define BOOST_PP_WHILE_188(p, o, s) BOOST_PP_WHILE_188_C(BOOST_PP_BOOL(p##(189, s)), p, o, s) # define BOOST_PP_WHILE_189(p, o, s) BOOST_PP_WHILE_189_C(BOOST_PP_BOOL(p##(190, s)), p, o, s) # define BOOST_PP_WHILE_190(p, o, s) BOOST_PP_WHILE_190_C(BOOST_PP_BOOL(p##(191, s)), p, o, s) # define BOOST_PP_WHILE_191(p, o, s) BOOST_PP_WHILE_191_C(BOOST_PP_BOOL(p##(192, s)), p, o, s) # define BOOST_PP_WHILE_192(p, o, s) BOOST_PP_WHILE_192_C(BOOST_PP_BOOL(p##(193, s)), p, o, s) # define BOOST_PP_WHILE_193(p, o, s) BOOST_PP_WHILE_193_C(BOOST_PP_BOOL(p##(194, s)), p, o, s) # define BOOST_PP_WHILE_194(p, o, s) BOOST_PP_WHILE_194_C(BOOST_PP_BOOL(p##(195, s)), p, o, s) # define BOOST_PP_WHILE_195(p, o, s) BOOST_PP_WHILE_195_C(BOOST_PP_BOOL(p##(196, s)), p, o, s) # define BOOST_PP_WHILE_196(p, o, s) BOOST_PP_WHILE_196_C(BOOST_PP_BOOL(p##(197, s)), p, o, s) # define BOOST_PP_WHILE_197(p, o, s) BOOST_PP_WHILE_197_C(BOOST_PP_BOOL(p##(198, s)), p, o, s) # define BOOST_PP_WHILE_198(p, o, s) BOOST_PP_WHILE_198_C(BOOST_PP_BOOL(p##(199, s)), p, o, s) # define BOOST_PP_WHILE_199(p, o, s) BOOST_PP_WHILE_199_C(BOOST_PP_BOOL(p##(200, s)), p, o, s) # define BOOST_PP_WHILE_200(p, o, s) BOOST_PP_WHILE_200_C(BOOST_PP_BOOL(p##(201, s)), p, o, s) # define BOOST_PP_WHILE_201(p, o, s) BOOST_PP_WHILE_201_C(BOOST_PP_BOOL(p##(202, s)), p, o, s) # define BOOST_PP_WHILE_202(p, o, s) BOOST_PP_WHILE_202_C(BOOST_PP_BOOL(p##(203, s)), p, o, s) # define BOOST_PP_WHILE_203(p, o, s) BOOST_PP_WHILE_203_C(BOOST_PP_BOOL(p##(204, s)), p, o, s) # define BOOST_PP_WHILE_204(p, o, s) BOOST_PP_WHILE_204_C(BOOST_PP_BOOL(p##(205, s)), p, o, s) # define BOOST_PP_WHILE_205(p, o, s) BOOST_PP_WHILE_205_C(BOOST_PP_BOOL(p##(206, s)), p, o, s) # define BOOST_PP_WHILE_206(p, o, s) BOOST_PP_WHILE_206_C(BOOST_PP_BOOL(p##(207, s)), p, o, s) # define BOOST_PP_WHILE_207(p, o, s) BOOST_PP_WHILE_207_C(BOOST_PP_BOOL(p##(208, s)), p, o, s) # define BOOST_PP_WHILE_208(p, o, s) BOOST_PP_WHILE_208_C(BOOST_PP_BOOL(p##(209, s)), p, o, s) # define BOOST_PP_WHILE_209(p, o, s) BOOST_PP_WHILE_209_C(BOOST_PP_BOOL(p##(210, s)), p, o, s) # define BOOST_PP_WHILE_210(p, o, s) BOOST_PP_WHILE_210_C(BOOST_PP_BOOL(p##(211, s)), p, o, s) # define BOOST_PP_WHILE_211(p, o, s) BOOST_PP_WHILE_211_C(BOOST_PP_BOOL(p##(212, s)), p, o, s) # define BOOST_PP_WHILE_212(p, o, s) BOOST_PP_WHILE_212_C(BOOST_PP_BOOL(p##(213, s)), p, o, s) # define BOOST_PP_WHILE_213(p, o, s) BOOST_PP_WHILE_213_C(BOOST_PP_BOOL(p##(214, s)), p, o, s) # define BOOST_PP_WHILE_214(p, o, s) BOOST_PP_WHILE_214_C(BOOST_PP_BOOL(p##(215, s)), p, o, s) # define BOOST_PP_WHILE_215(p, o, s) BOOST_PP_WHILE_215_C(BOOST_PP_BOOL(p##(216, s)), p, o, s) # define BOOST_PP_WHILE_216(p, o, s) BOOST_PP_WHILE_216_C(BOOST_PP_BOOL(p##(217, s)), p, o, s) # define BOOST_PP_WHILE_217(p, o, s) BOOST_PP_WHILE_217_C(BOOST_PP_BOOL(p##(218, s)), p, o, s) # define BOOST_PP_WHILE_218(p, o, s) BOOST_PP_WHILE_218_C(BOOST_PP_BOOL(p##(219, s)), p, o, s) # define BOOST_PP_WHILE_219(p, o, s) BOOST_PP_WHILE_219_C(BOOST_PP_BOOL(p##(220, s)), p, o, s) # define BOOST_PP_WHILE_220(p, o, s) BOOST_PP_WHILE_220_C(BOOST_PP_BOOL(p##(221, s)), p, o, s) # define BOOST_PP_WHILE_221(p, o, s) BOOST_PP_WHILE_221_C(BOOST_PP_BOOL(p##(222, s)), p, o, s) # define BOOST_PP_WHILE_222(p, o, s) BOOST_PP_WHILE_222_C(BOOST_PP_BOOL(p##(223, s)), p, o, s) # define BOOST_PP_WHILE_223(p, o, s) BOOST_PP_WHILE_223_C(BOOST_PP_BOOL(p##(224, s)), p, o, s) # define BOOST_PP_WHILE_224(p, o, s) BOOST_PP_WHILE_224_C(BOOST_PP_BOOL(p##(225, s)), p, o, s) # define BOOST_PP_WHILE_225(p, o, s) BOOST_PP_WHILE_225_C(BOOST_PP_BOOL(p##(226, s)), p, o, s) # define BOOST_PP_WHILE_226(p, o, s) BOOST_PP_WHILE_226_C(BOOST_PP_BOOL(p##(227, s)), p, o, s) # define BOOST_PP_WHILE_227(p, o, s) BOOST_PP_WHILE_227_C(BOOST_PP_BOOL(p##(228, s)), p, o, s) # define BOOST_PP_WHILE_228(p, o, s) BOOST_PP_WHILE_228_C(BOOST_PP_BOOL(p##(229, s)), p, o, s) # define BOOST_PP_WHILE_229(p, o, s) BOOST_PP_WHILE_229_C(BOOST_PP_BOOL(p##(230, s)), p, o, s) # define BOOST_PP_WHILE_230(p, o, s) BOOST_PP_WHILE_230_C(BOOST_PP_BOOL(p##(231, s)), p, o, s) # define BOOST_PP_WHILE_231(p, o, s) BOOST_PP_WHILE_231_C(BOOST_PP_BOOL(p##(232, s)), p, o, s) # define BOOST_PP_WHILE_232(p, o, s) BOOST_PP_WHILE_232_C(BOOST_PP_BOOL(p##(233, s)), p, o, s) # define BOOST_PP_WHILE_233(p, o, s) BOOST_PP_WHILE_233_C(BOOST_PP_BOOL(p##(234, s)), p, o, s) # define BOOST_PP_WHILE_234(p, o, s) BOOST_PP_WHILE_234_C(BOOST_PP_BOOL(p##(235, s)), p, o, s) # define BOOST_PP_WHILE_235(p, o, s) BOOST_PP_WHILE_235_C(BOOST_PP_BOOL(p##(236, s)), p, o, s) # define BOOST_PP_WHILE_236(p, o, s) BOOST_PP_WHILE_236_C(BOOST_PP_BOOL(p##(237, s)), p, o, s) # define BOOST_PP_WHILE_237(p, o, s) BOOST_PP_WHILE_237_C(BOOST_PP_BOOL(p##(238, s)), p, o, s) # define BOOST_PP_WHILE_238(p, o, s) BOOST_PP_WHILE_238_C(BOOST_PP_BOOL(p##(239, s)), p, o, s) # define BOOST_PP_WHILE_239(p, o, s) BOOST_PP_WHILE_239_C(BOOST_PP_BOOL(p##(240, s)), p, o, s) # define BOOST_PP_WHILE_240(p, o, s) BOOST_PP_WHILE_240_C(BOOST_PP_BOOL(p##(241, s)), p, o, s) # define BOOST_PP_WHILE_241(p, o, s) BOOST_PP_WHILE_241_C(BOOST_PP_BOOL(p##(242, s)), p, o, s) # define BOOST_PP_WHILE_242(p, o, s) BOOST_PP_WHILE_242_C(BOOST_PP_BOOL(p##(243, s)), p, o, s) # define BOOST_PP_WHILE_243(p, o, s) BOOST_PP_WHILE_243_C(BOOST_PP_BOOL(p##(244, s)), p, o, s) # define BOOST_PP_WHILE_244(p, o, s) BOOST_PP_WHILE_244_C(BOOST_PP_BOOL(p##(245, s)), p, o, s) # define BOOST_PP_WHILE_245(p, o, s) BOOST_PP_WHILE_245_C(BOOST_PP_BOOL(p##(246, s)), p, o, s) # define BOOST_PP_WHILE_246(p, o, s) BOOST_PP_WHILE_246_C(BOOST_PP_BOOL(p##(247, s)), p, o, s) # define BOOST_PP_WHILE_247(p, o, s) BOOST_PP_WHILE_247_C(BOOST_PP_BOOL(p##(248, s)), p, o, s) # define BOOST_PP_WHILE_248(p, o, s) BOOST_PP_WHILE_248_C(BOOST_PP_BOOL(p##(249, s)), p, o, s) # define BOOST_PP_WHILE_249(p, o, s) BOOST_PP_WHILE_249_C(BOOST_PP_BOOL(p##(250, s)), p, o, s) # define BOOST_PP_WHILE_250(p, o, s) BOOST_PP_WHILE_250_C(BOOST_PP_BOOL(p##(251, s)), p, o, s) # define BOOST_PP_WHILE_251(p, o, s) BOOST_PP_WHILE_251_C(BOOST_PP_BOOL(p##(252, s)), p, o, s) # define BOOST_PP_WHILE_252(p, o, s) BOOST_PP_WHILE_252_C(BOOST_PP_BOOL(p##(253, s)), p, o, s) # define BOOST_PP_WHILE_253(p, o, s) BOOST_PP_WHILE_253_C(BOOST_PP_BOOL(p##(254, s)), p, o, s) # define BOOST_PP_WHILE_254(p, o, s) BOOST_PP_WHILE_254_C(BOOST_PP_BOOL(p##(255, s)), p, o, s) # define BOOST_PP_WHILE_255(p, o, s) BOOST_PP_WHILE_255_C(BOOST_PP_BOOL(p##(256, s)), p, o, s) # define BOOST_PP_WHILE_256(p, o, s) BOOST_PP_WHILE_256_C(BOOST_PP_BOOL(p##(257, s)), p, o, s) # # define BOOST_PP_WHILE_1_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_2, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(2, s)) # define BOOST_PP_WHILE_2_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_3, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(3, s)) # define BOOST_PP_WHILE_3_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_4, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(4, s)) # define BOOST_PP_WHILE_4_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_5, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(5, s)) # define BOOST_PP_WHILE_5_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_6, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(6, s)) # define BOOST_PP_WHILE_6_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_7, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(7, s)) # define BOOST_PP_WHILE_7_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_8, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(8, s)) # define BOOST_PP_WHILE_8_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_9, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(9, s)) # define BOOST_PP_WHILE_9_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_10, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(10, s)) # define BOOST_PP_WHILE_10_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_11, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(11, s)) # define BOOST_PP_WHILE_11_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_12, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(12, s)) # define BOOST_PP_WHILE_12_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_13, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(13, s)) # define BOOST_PP_WHILE_13_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_14, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(14, s)) # define BOOST_PP_WHILE_14_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_15, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(15, s)) # define BOOST_PP_WHILE_15_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_16, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(16, s)) # define BOOST_PP_WHILE_16_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_17, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(17, s)) # define BOOST_PP_WHILE_17_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_18, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(18, s)) # define BOOST_PP_WHILE_18_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_19, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(19, s)) # define BOOST_PP_WHILE_19_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_20, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(20, s)) # define BOOST_PP_WHILE_20_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_21, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(21, s)) # define BOOST_PP_WHILE_21_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_22, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(22, s)) # define BOOST_PP_WHILE_22_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_23, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(23, s)) # define BOOST_PP_WHILE_23_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_24, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(24, s)) # define BOOST_PP_WHILE_24_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_25, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(25, s)) # define BOOST_PP_WHILE_25_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_26, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(26, s)) # define BOOST_PP_WHILE_26_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_27, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(27, s)) # define BOOST_PP_WHILE_27_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_28, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(28, s)) # define BOOST_PP_WHILE_28_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_29, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(29, s)) # define BOOST_PP_WHILE_29_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_30, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(30, s)) # define BOOST_PP_WHILE_30_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_31, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(31, s)) # define BOOST_PP_WHILE_31_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_32, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(32, s)) # define BOOST_PP_WHILE_32_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_33, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(33, s)) # define BOOST_PP_WHILE_33_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_34, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(34, s)) # define BOOST_PP_WHILE_34_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_35, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(35, s)) # define BOOST_PP_WHILE_35_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_36, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(36, s)) # define BOOST_PP_WHILE_36_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_37, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(37, s)) # define BOOST_PP_WHILE_37_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_38, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(38, s)) # define BOOST_PP_WHILE_38_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_39, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(39, s)) # define BOOST_PP_WHILE_39_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_40, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(40, s)) # define BOOST_PP_WHILE_40_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_41, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(41, s)) # define BOOST_PP_WHILE_41_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_42, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(42, s)) # define BOOST_PP_WHILE_42_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_43, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(43, s)) # define BOOST_PP_WHILE_43_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_44, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(44, s)) # define BOOST_PP_WHILE_44_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_45, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(45, s)) # define BOOST_PP_WHILE_45_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_46, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(46, s)) # define BOOST_PP_WHILE_46_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_47, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(47, s)) # define BOOST_PP_WHILE_47_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_48, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(48, s)) # define BOOST_PP_WHILE_48_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_49, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(49, s)) # define BOOST_PP_WHILE_49_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_50, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(50, s)) # define BOOST_PP_WHILE_50_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_51, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(51, s)) # define BOOST_PP_WHILE_51_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_52, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(52, s)) # define BOOST_PP_WHILE_52_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_53, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(53, s)) # define BOOST_PP_WHILE_53_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_54, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(54, s)) # define BOOST_PP_WHILE_54_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_55, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(55, s)) # define BOOST_PP_WHILE_55_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_56, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(56, s)) # define BOOST_PP_WHILE_56_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_57, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(57, s)) # define BOOST_PP_WHILE_57_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_58, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(58, s)) # define BOOST_PP_WHILE_58_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_59, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(59, s)) # define BOOST_PP_WHILE_59_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_60, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(60, s)) # define BOOST_PP_WHILE_60_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_61, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(61, s)) # define BOOST_PP_WHILE_61_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_62, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(62, s)) # define BOOST_PP_WHILE_62_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_63, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(63, s)) # define BOOST_PP_WHILE_63_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_64, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(64, s)) # define BOOST_PP_WHILE_64_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_65, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(65, s)) # define BOOST_PP_WHILE_65_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_66, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(66, s)) # define BOOST_PP_WHILE_66_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_67, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(67, s)) # define BOOST_PP_WHILE_67_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_68, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(68, s)) # define BOOST_PP_WHILE_68_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_69, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(69, s)) # define BOOST_PP_WHILE_69_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_70, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(70, s)) # define BOOST_PP_WHILE_70_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_71, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(71, s)) # define BOOST_PP_WHILE_71_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_72, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(72, s)) # define BOOST_PP_WHILE_72_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_73, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(73, s)) # define BOOST_PP_WHILE_73_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_74, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(74, s)) # define BOOST_PP_WHILE_74_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_75, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(75, s)) # define BOOST_PP_WHILE_75_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_76, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(76, s)) # define BOOST_PP_WHILE_76_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_77, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(77, s)) # define BOOST_PP_WHILE_77_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_78, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(78, s)) # define BOOST_PP_WHILE_78_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_79, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(79, s)) # define BOOST_PP_WHILE_79_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_80, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(80, s)) # define BOOST_PP_WHILE_80_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_81, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(81, s)) # define BOOST_PP_WHILE_81_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_82, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(82, s)) # define BOOST_PP_WHILE_82_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_83, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(83, s)) # define BOOST_PP_WHILE_83_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_84, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(84, s)) # define BOOST_PP_WHILE_84_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_85, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(85, s)) # define BOOST_PP_WHILE_85_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_86, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(86, s)) # define BOOST_PP_WHILE_86_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_87, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(87, s)) # define BOOST_PP_WHILE_87_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_88, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(88, s)) # define BOOST_PP_WHILE_88_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_89, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(89, s)) # define BOOST_PP_WHILE_89_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_90, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(90, s)) # define BOOST_PP_WHILE_90_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_91, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(91, s)) # define BOOST_PP_WHILE_91_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_92, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(92, s)) # define BOOST_PP_WHILE_92_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_93, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(93, s)) # define BOOST_PP_WHILE_93_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_94, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(94, s)) # define BOOST_PP_WHILE_94_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_95, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(95, s)) # define BOOST_PP_WHILE_95_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_96, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(96, s)) # define BOOST_PP_WHILE_96_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_97, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(97, s)) # define BOOST_PP_WHILE_97_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_98, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(98, s)) # define BOOST_PP_WHILE_98_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_99, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(99, s)) # define BOOST_PP_WHILE_99_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_100, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(100, s)) # define BOOST_PP_WHILE_100_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_101, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(101, s)) # define BOOST_PP_WHILE_101_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_102, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(102, s)) # define BOOST_PP_WHILE_102_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_103, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(103, s)) # define BOOST_PP_WHILE_103_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_104, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(104, s)) # define BOOST_PP_WHILE_104_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_105, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(105, s)) # define BOOST_PP_WHILE_105_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_106, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(106, s)) # define BOOST_PP_WHILE_106_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_107, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(107, s)) # define BOOST_PP_WHILE_107_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_108, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(108, s)) # define BOOST_PP_WHILE_108_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_109, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(109, s)) # define BOOST_PP_WHILE_109_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_110, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(110, s)) # define BOOST_PP_WHILE_110_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_111, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(111, s)) # define BOOST_PP_WHILE_111_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_112, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(112, s)) # define BOOST_PP_WHILE_112_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_113, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(113, s)) # define BOOST_PP_WHILE_113_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_114, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(114, s)) # define BOOST_PP_WHILE_114_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_115, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(115, s)) # define BOOST_PP_WHILE_115_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_116, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(116, s)) # define BOOST_PP_WHILE_116_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_117, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(117, s)) # define BOOST_PP_WHILE_117_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_118, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(118, s)) # define BOOST_PP_WHILE_118_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_119, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(119, s)) # define BOOST_PP_WHILE_119_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_120, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(120, s)) # define BOOST_PP_WHILE_120_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_121, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(121, s)) # define BOOST_PP_WHILE_121_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_122, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(122, s)) # define BOOST_PP_WHILE_122_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_123, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(123, s)) # define BOOST_PP_WHILE_123_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_124, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(124, s)) # define BOOST_PP_WHILE_124_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_125, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(125, s)) # define BOOST_PP_WHILE_125_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_126, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(126, s)) # define BOOST_PP_WHILE_126_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_127, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(127, s)) # define BOOST_PP_WHILE_127_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_128, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(128, s)) # define BOOST_PP_WHILE_128_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_129, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(129, s)) # define BOOST_PP_WHILE_129_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_130, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(130, s)) # define BOOST_PP_WHILE_130_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_131, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(131, s)) # define BOOST_PP_WHILE_131_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_132, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(132, s)) # define BOOST_PP_WHILE_132_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_133, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(133, s)) # define BOOST_PP_WHILE_133_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_134, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(134, s)) # define BOOST_PP_WHILE_134_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_135, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(135, s)) # define BOOST_PP_WHILE_135_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_136, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(136, s)) # define BOOST_PP_WHILE_136_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_137, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(137, s)) # define BOOST_PP_WHILE_137_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_138, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(138, s)) # define BOOST_PP_WHILE_138_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_139, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(139, s)) # define BOOST_PP_WHILE_139_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_140, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(140, s)) # define BOOST_PP_WHILE_140_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_141, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(141, s)) # define BOOST_PP_WHILE_141_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_142, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(142, s)) # define BOOST_PP_WHILE_142_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_143, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(143, s)) # define BOOST_PP_WHILE_143_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_144, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(144, s)) # define BOOST_PP_WHILE_144_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_145, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(145, s)) # define BOOST_PP_WHILE_145_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_146, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(146, s)) # define BOOST_PP_WHILE_146_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_147, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(147, s)) # define BOOST_PP_WHILE_147_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_148, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(148, s)) # define BOOST_PP_WHILE_148_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_149, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(149, s)) # define BOOST_PP_WHILE_149_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_150, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(150, s)) # define BOOST_PP_WHILE_150_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_151, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(151, s)) # define BOOST_PP_WHILE_151_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_152, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(152, s)) # define BOOST_PP_WHILE_152_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_153, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(153, s)) # define BOOST_PP_WHILE_153_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_154, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(154, s)) # define BOOST_PP_WHILE_154_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_155, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(155, s)) # define BOOST_PP_WHILE_155_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_156, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(156, s)) # define BOOST_PP_WHILE_156_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_157, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(157, s)) # define BOOST_PP_WHILE_157_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_158, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(158, s)) # define BOOST_PP_WHILE_158_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_159, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(159, s)) # define BOOST_PP_WHILE_159_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_160, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(160, s)) # define BOOST_PP_WHILE_160_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_161, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(161, s)) # define BOOST_PP_WHILE_161_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_162, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(162, s)) # define BOOST_PP_WHILE_162_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_163, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(163, s)) # define BOOST_PP_WHILE_163_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_164, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(164, s)) # define BOOST_PP_WHILE_164_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_165, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(165, s)) # define BOOST_PP_WHILE_165_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_166, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(166, s)) # define BOOST_PP_WHILE_166_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_167, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(167, s)) # define BOOST_PP_WHILE_167_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_168, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(168, s)) # define BOOST_PP_WHILE_168_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_169, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(169, s)) # define BOOST_PP_WHILE_169_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_170, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(170, s)) # define BOOST_PP_WHILE_170_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_171, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(171, s)) # define BOOST_PP_WHILE_171_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_172, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(172, s)) # define BOOST_PP_WHILE_172_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_173, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(173, s)) # define BOOST_PP_WHILE_173_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_174, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(174, s)) # define BOOST_PP_WHILE_174_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_175, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(175, s)) # define BOOST_PP_WHILE_175_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_176, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(176, s)) # define BOOST_PP_WHILE_176_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_177, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(177, s)) # define BOOST_PP_WHILE_177_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_178, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(178, s)) # define BOOST_PP_WHILE_178_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_179, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(179, s)) # define BOOST_PP_WHILE_179_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_180, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(180, s)) # define BOOST_PP_WHILE_180_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_181, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(181, s)) # define BOOST_PP_WHILE_181_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_182, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(182, s)) # define BOOST_PP_WHILE_182_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_183, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(183, s)) # define BOOST_PP_WHILE_183_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_184, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(184, s)) # define BOOST_PP_WHILE_184_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_185, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(185, s)) # define BOOST_PP_WHILE_185_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_186, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(186, s)) # define BOOST_PP_WHILE_186_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_187, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(187, s)) # define BOOST_PP_WHILE_187_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_188, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(188, s)) # define BOOST_PP_WHILE_188_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_189, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(189, s)) # define BOOST_PP_WHILE_189_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_190, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(190, s)) # define BOOST_PP_WHILE_190_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_191, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(191, s)) # define BOOST_PP_WHILE_191_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_192, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(192, s)) # define BOOST_PP_WHILE_192_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_193, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(193, s)) # define BOOST_PP_WHILE_193_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_194, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(194, s)) # define BOOST_PP_WHILE_194_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_195, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(195, s)) # define BOOST_PP_WHILE_195_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_196, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(196, s)) # define BOOST_PP_WHILE_196_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_197, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(197, s)) # define BOOST_PP_WHILE_197_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_198, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(198, s)) # define BOOST_PP_WHILE_198_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_199, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(199, s)) # define BOOST_PP_WHILE_199_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_200, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(200, s)) # define BOOST_PP_WHILE_200_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_201, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(201, s)) # define BOOST_PP_WHILE_201_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_202, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(202, s)) # define BOOST_PP_WHILE_202_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_203, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(203, s)) # define BOOST_PP_WHILE_203_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_204, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(204, s)) # define BOOST_PP_WHILE_204_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_205, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(205, s)) # define BOOST_PP_WHILE_205_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_206, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(206, s)) # define BOOST_PP_WHILE_206_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_207, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(207, s)) # define BOOST_PP_WHILE_207_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_208, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(208, s)) # define BOOST_PP_WHILE_208_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_209, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(209, s)) # define BOOST_PP_WHILE_209_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_210, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(210, s)) # define BOOST_PP_WHILE_210_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_211, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(211, s)) # define BOOST_PP_WHILE_211_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_212, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(212, s)) # define BOOST_PP_WHILE_212_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_213, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(213, s)) # define BOOST_PP_WHILE_213_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_214, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(214, s)) # define BOOST_PP_WHILE_214_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_215, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(215, s)) # define BOOST_PP_WHILE_215_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_216, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(216, s)) # define BOOST_PP_WHILE_216_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_217, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(217, s)) # define BOOST_PP_WHILE_217_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_218, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(218, s)) # define BOOST_PP_WHILE_218_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_219, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(219, s)) # define BOOST_PP_WHILE_219_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_220, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(220, s)) # define BOOST_PP_WHILE_220_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_221, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(221, s)) # define BOOST_PP_WHILE_221_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_222, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(222, s)) # define BOOST_PP_WHILE_222_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_223, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(223, s)) # define BOOST_PP_WHILE_223_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_224, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(224, s)) # define BOOST_PP_WHILE_224_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_225, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(225, s)) # define BOOST_PP_WHILE_225_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_226, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(226, s)) # define BOOST_PP_WHILE_226_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_227, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(227, s)) # define BOOST_PP_WHILE_227_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_228, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(228, s)) # define BOOST_PP_WHILE_228_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_229, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(229, s)) # define BOOST_PP_WHILE_229_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_230, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(230, s)) # define BOOST_PP_WHILE_230_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_231, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(231, s)) # define BOOST_PP_WHILE_231_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_232, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(232, s)) # define BOOST_PP_WHILE_232_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_233, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(233, s)) # define BOOST_PP_WHILE_233_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_234, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(234, s)) # define BOOST_PP_WHILE_234_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_235, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(235, s)) # define BOOST_PP_WHILE_235_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_236, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(236, s)) # define BOOST_PP_WHILE_236_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_237, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(237, s)) # define BOOST_PP_WHILE_237_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_238, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(238, s)) # define BOOST_PP_WHILE_238_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_239, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(239, s)) # define BOOST_PP_WHILE_239_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_240, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(240, s)) # define BOOST_PP_WHILE_240_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_241, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(241, s)) # define BOOST_PP_WHILE_241_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_242, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(242, s)) # define BOOST_PP_WHILE_242_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_243, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(243, s)) # define BOOST_PP_WHILE_243_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_244, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(244, s)) # define BOOST_PP_WHILE_244_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_245, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(245, s)) # define BOOST_PP_WHILE_245_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_246, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(246, s)) # define BOOST_PP_WHILE_246_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_247, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(247, s)) # define BOOST_PP_WHILE_247_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_248, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(248, s)) # define BOOST_PP_WHILE_248_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_249, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(249, s)) # define BOOST_PP_WHILE_249_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_250, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(250, s)) # define BOOST_PP_WHILE_250_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_251, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(251, s)) # define BOOST_PP_WHILE_251_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_252, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(252, s)) # define BOOST_PP_WHILE_252_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_253, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(253, s)) # define BOOST_PP_WHILE_253_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_254, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(254, s)) # define BOOST_PP_WHILE_254_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_255, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(255, s)) # define BOOST_PP_WHILE_255_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_256, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(256, s)) # define BOOST_PP_WHILE_256_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_257, BOOST_PP_TUPLE_ELEM_3_2)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_TUPLE_ELEM_2_1)(257, s)) # # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/detail/edg/while.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_DETAIL_EDG_WHILE_HPP # define BOOST_PREPROCESSOR_CONTROL_DETAIL_EDG_WHILE_HPP # # include # include # # define BOOST_PP_WHILE_1(p, o, s) BOOST_PP_WHILE_1_I(p, o, s) # define BOOST_PP_WHILE_2(p, o, s) BOOST_PP_WHILE_2_I(p, o, s) # define BOOST_PP_WHILE_3(p, o, s) BOOST_PP_WHILE_3_I(p, o, s) # define BOOST_PP_WHILE_4(p, o, s) BOOST_PP_WHILE_4_I(p, o, s) # define BOOST_PP_WHILE_5(p, o, s) BOOST_PP_WHILE_5_I(p, o, s) # define BOOST_PP_WHILE_6(p, o, s) BOOST_PP_WHILE_6_I(p, o, s) # define BOOST_PP_WHILE_7(p, o, s) BOOST_PP_WHILE_7_I(p, o, s) # define BOOST_PP_WHILE_8(p, o, s) BOOST_PP_WHILE_8_I(p, o, s) # define BOOST_PP_WHILE_9(p, o, s) BOOST_PP_WHILE_9_I(p, o, s) # define BOOST_PP_WHILE_10(p, o, s) BOOST_PP_WHILE_10_I(p, o, s) # define BOOST_PP_WHILE_11(p, o, s) BOOST_PP_WHILE_11_I(p, o, s) # define BOOST_PP_WHILE_12(p, o, s) BOOST_PP_WHILE_12_I(p, o, s) # define BOOST_PP_WHILE_13(p, o, s) BOOST_PP_WHILE_13_I(p, o, s) # define BOOST_PP_WHILE_14(p, o, s) BOOST_PP_WHILE_14_I(p, o, s) # define BOOST_PP_WHILE_15(p, o, s) BOOST_PP_WHILE_15_I(p, o, s) # define BOOST_PP_WHILE_16(p, o, s) BOOST_PP_WHILE_16_I(p, o, s) # define BOOST_PP_WHILE_17(p, o, s) BOOST_PP_WHILE_17_I(p, o, s) # define BOOST_PP_WHILE_18(p, o, s) BOOST_PP_WHILE_18_I(p, o, s) # define BOOST_PP_WHILE_19(p, o, s) BOOST_PP_WHILE_19_I(p, o, s) # define BOOST_PP_WHILE_20(p, o, s) BOOST_PP_WHILE_20_I(p, o, s) # define BOOST_PP_WHILE_21(p, o, s) BOOST_PP_WHILE_21_I(p, o, s) # define BOOST_PP_WHILE_22(p, o, s) BOOST_PP_WHILE_22_I(p, o, s) # define BOOST_PP_WHILE_23(p, o, s) BOOST_PP_WHILE_23_I(p, o, s) # define BOOST_PP_WHILE_24(p, o, s) BOOST_PP_WHILE_24_I(p, o, s) # define BOOST_PP_WHILE_25(p, o, s) BOOST_PP_WHILE_25_I(p, o, s) # define BOOST_PP_WHILE_26(p, o, s) BOOST_PP_WHILE_26_I(p, o, s) # define BOOST_PP_WHILE_27(p, o, s) BOOST_PP_WHILE_27_I(p, o, s) # define BOOST_PP_WHILE_28(p, o, s) BOOST_PP_WHILE_28_I(p, o, s) # define BOOST_PP_WHILE_29(p, o, s) BOOST_PP_WHILE_29_I(p, o, s) # define BOOST_PP_WHILE_30(p, o, s) BOOST_PP_WHILE_30_I(p, o, s) # define BOOST_PP_WHILE_31(p, o, s) BOOST_PP_WHILE_31_I(p, o, s) # define BOOST_PP_WHILE_32(p, o, s) BOOST_PP_WHILE_32_I(p, o, s) # define BOOST_PP_WHILE_33(p, o, s) BOOST_PP_WHILE_33_I(p, o, s) # define BOOST_PP_WHILE_34(p, o, s) BOOST_PP_WHILE_34_I(p, o, s) # define BOOST_PP_WHILE_35(p, o, s) BOOST_PP_WHILE_35_I(p, o, s) # define BOOST_PP_WHILE_36(p, o, s) BOOST_PP_WHILE_36_I(p, o, s) # define BOOST_PP_WHILE_37(p, o, s) BOOST_PP_WHILE_37_I(p, o, s) # define BOOST_PP_WHILE_38(p, o, s) BOOST_PP_WHILE_38_I(p, o, s) # define BOOST_PP_WHILE_39(p, o, s) BOOST_PP_WHILE_39_I(p, o, s) # define BOOST_PP_WHILE_40(p, o, s) BOOST_PP_WHILE_40_I(p, o, s) # define BOOST_PP_WHILE_41(p, o, s) BOOST_PP_WHILE_41_I(p, o, s) # define BOOST_PP_WHILE_42(p, o, s) BOOST_PP_WHILE_42_I(p, o, s) # define BOOST_PP_WHILE_43(p, o, s) BOOST_PP_WHILE_43_I(p, o, s) # define BOOST_PP_WHILE_44(p, o, s) BOOST_PP_WHILE_44_I(p, o, s) # define BOOST_PP_WHILE_45(p, o, s) BOOST_PP_WHILE_45_I(p, o, s) # define BOOST_PP_WHILE_46(p, o, s) BOOST_PP_WHILE_46_I(p, o, s) # define BOOST_PP_WHILE_47(p, o, s) BOOST_PP_WHILE_47_I(p, o, s) # define BOOST_PP_WHILE_48(p, o, s) BOOST_PP_WHILE_48_I(p, o, s) # define BOOST_PP_WHILE_49(p, o, s) BOOST_PP_WHILE_49_I(p, o, s) # define BOOST_PP_WHILE_50(p, o, s) BOOST_PP_WHILE_50_I(p, o, s) # define BOOST_PP_WHILE_51(p, o, s) BOOST_PP_WHILE_51_I(p, o, s) # define BOOST_PP_WHILE_52(p, o, s) BOOST_PP_WHILE_52_I(p, o, s) # define BOOST_PP_WHILE_53(p, o, s) BOOST_PP_WHILE_53_I(p, o, s) # define BOOST_PP_WHILE_54(p, o, s) BOOST_PP_WHILE_54_I(p, o, s) # define BOOST_PP_WHILE_55(p, o, s) BOOST_PP_WHILE_55_I(p, o, s) # define BOOST_PP_WHILE_56(p, o, s) BOOST_PP_WHILE_56_I(p, o, s) # define BOOST_PP_WHILE_57(p, o, s) BOOST_PP_WHILE_57_I(p, o, s) # define BOOST_PP_WHILE_58(p, o, s) BOOST_PP_WHILE_58_I(p, o, s) # define BOOST_PP_WHILE_59(p, o, s) BOOST_PP_WHILE_59_I(p, o, s) # define BOOST_PP_WHILE_60(p, o, s) BOOST_PP_WHILE_60_I(p, o, s) # define BOOST_PP_WHILE_61(p, o, s) BOOST_PP_WHILE_61_I(p, o, s) # define BOOST_PP_WHILE_62(p, o, s) BOOST_PP_WHILE_62_I(p, o, s) # define BOOST_PP_WHILE_63(p, o, s) BOOST_PP_WHILE_63_I(p, o, s) # define BOOST_PP_WHILE_64(p, o, s) BOOST_PP_WHILE_64_I(p, o, s) # define BOOST_PP_WHILE_65(p, o, s) BOOST_PP_WHILE_65_I(p, o, s) # define BOOST_PP_WHILE_66(p, o, s) BOOST_PP_WHILE_66_I(p, o, s) # define BOOST_PP_WHILE_67(p, o, s) BOOST_PP_WHILE_67_I(p, o, s) # define BOOST_PP_WHILE_68(p, o, s) BOOST_PP_WHILE_68_I(p, o, s) # define BOOST_PP_WHILE_69(p, o, s) BOOST_PP_WHILE_69_I(p, o, s) # define BOOST_PP_WHILE_70(p, o, s) BOOST_PP_WHILE_70_I(p, o, s) # define BOOST_PP_WHILE_71(p, o, s) BOOST_PP_WHILE_71_I(p, o, s) # define BOOST_PP_WHILE_72(p, o, s) BOOST_PP_WHILE_72_I(p, o, s) # define BOOST_PP_WHILE_73(p, o, s) BOOST_PP_WHILE_73_I(p, o, s) # define BOOST_PP_WHILE_74(p, o, s) BOOST_PP_WHILE_74_I(p, o, s) # define BOOST_PP_WHILE_75(p, o, s) BOOST_PP_WHILE_75_I(p, o, s) # define BOOST_PP_WHILE_76(p, o, s) BOOST_PP_WHILE_76_I(p, o, s) # define BOOST_PP_WHILE_77(p, o, s) BOOST_PP_WHILE_77_I(p, o, s) # define BOOST_PP_WHILE_78(p, o, s) BOOST_PP_WHILE_78_I(p, o, s) # define BOOST_PP_WHILE_79(p, o, s) BOOST_PP_WHILE_79_I(p, o, s) # define BOOST_PP_WHILE_80(p, o, s) BOOST_PP_WHILE_80_I(p, o, s) # define BOOST_PP_WHILE_81(p, o, s) BOOST_PP_WHILE_81_I(p, o, s) # define BOOST_PP_WHILE_82(p, o, s) BOOST_PP_WHILE_82_I(p, o, s) # define BOOST_PP_WHILE_83(p, o, s) BOOST_PP_WHILE_83_I(p, o, s) # define BOOST_PP_WHILE_84(p, o, s) BOOST_PP_WHILE_84_I(p, o, s) # define BOOST_PP_WHILE_85(p, o, s) BOOST_PP_WHILE_85_I(p, o, s) # define BOOST_PP_WHILE_86(p, o, s) BOOST_PP_WHILE_86_I(p, o, s) # define BOOST_PP_WHILE_87(p, o, s) BOOST_PP_WHILE_87_I(p, o, s) # define BOOST_PP_WHILE_88(p, o, s) BOOST_PP_WHILE_88_I(p, o, s) # define BOOST_PP_WHILE_89(p, o, s) BOOST_PP_WHILE_89_I(p, o, s) # define BOOST_PP_WHILE_90(p, o, s) BOOST_PP_WHILE_90_I(p, o, s) # define BOOST_PP_WHILE_91(p, o, s) BOOST_PP_WHILE_91_I(p, o, s) # define BOOST_PP_WHILE_92(p, o, s) BOOST_PP_WHILE_92_I(p, o, s) # define BOOST_PP_WHILE_93(p, o, s) BOOST_PP_WHILE_93_I(p, o, s) # define BOOST_PP_WHILE_94(p, o, s) BOOST_PP_WHILE_94_I(p, o, s) # define BOOST_PP_WHILE_95(p, o, s) BOOST_PP_WHILE_95_I(p, o, s) # define BOOST_PP_WHILE_96(p, o, s) BOOST_PP_WHILE_96_I(p, o, s) # define BOOST_PP_WHILE_97(p, o, s) BOOST_PP_WHILE_97_I(p, o, s) # define BOOST_PP_WHILE_98(p, o, s) BOOST_PP_WHILE_98_I(p, o, s) # define BOOST_PP_WHILE_99(p, o, s) BOOST_PP_WHILE_99_I(p, o, s) # define BOOST_PP_WHILE_100(p, o, s) BOOST_PP_WHILE_100_I(p, o, s) # define BOOST_PP_WHILE_101(p, o, s) BOOST_PP_WHILE_101_I(p, o, s) # define BOOST_PP_WHILE_102(p, o, s) BOOST_PP_WHILE_102_I(p, o, s) # define BOOST_PP_WHILE_103(p, o, s) BOOST_PP_WHILE_103_I(p, o, s) # define BOOST_PP_WHILE_104(p, o, s) BOOST_PP_WHILE_104_I(p, o, s) # define BOOST_PP_WHILE_105(p, o, s) BOOST_PP_WHILE_105_I(p, o, s) # define BOOST_PP_WHILE_106(p, o, s) BOOST_PP_WHILE_106_I(p, o, s) # define BOOST_PP_WHILE_107(p, o, s) BOOST_PP_WHILE_107_I(p, o, s) # define BOOST_PP_WHILE_108(p, o, s) BOOST_PP_WHILE_108_I(p, o, s) # define BOOST_PP_WHILE_109(p, o, s) BOOST_PP_WHILE_109_I(p, o, s) # define BOOST_PP_WHILE_110(p, o, s) BOOST_PP_WHILE_110_I(p, o, s) # define BOOST_PP_WHILE_111(p, o, s) BOOST_PP_WHILE_111_I(p, o, s) # define BOOST_PP_WHILE_112(p, o, s) BOOST_PP_WHILE_112_I(p, o, s) # define BOOST_PP_WHILE_113(p, o, s) BOOST_PP_WHILE_113_I(p, o, s) # define BOOST_PP_WHILE_114(p, o, s) BOOST_PP_WHILE_114_I(p, o, s) # define BOOST_PP_WHILE_115(p, o, s) BOOST_PP_WHILE_115_I(p, o, s) # define BOOST_PP_WHILE_116(p, o, s) BOOST_PP_WHILE_116_I(p, o, s) # define BOOST_PP_WHILE_117(p, o, s) BOOST_PP_WHILE_117_I(p, o, s) # define BOOST_PP_WHILE_118(p, o, s) BOOST_PP_WHILE_118_I(p, o, s) # define BOOST_PP_WHILE_119(p, o, s) BOOST_PP_WHILE_119_I(p, o, s) # define BOOST_PP_WHILE_120(p, o, s) BOOST_PP_WHILE_120_I(p, o, s) # define BOOST_PP_WHILE_121(p, o, s) BOOST_PP_WHILE_121_I(p, o, s) # define BOOST_PP_WHILE_122(p, o, s) BOOST_PP_WHILE_122_I(p, o, s) # define BOOST_PP_WHILE_123(p, o, s) BOOST_PP_WHILE_123_I(p, o, s) # define BOOST_PP_WHILE_124(p, o, s) BOOST_PP_WHILE_124_I(p, o, s) # define BOOST_PP_WHILE_125(p, o, s) BOOST_PP_WHILE_125_I(p, o, s) # define BOOST_PP_WHILE_126(p, o, s) BOOST_PP_WHILE_126_I(p, o, s) # define BOOST_PP_WHILE_127(p, o, s) BOOST_PP_WHILE_127_I(p, o, s) # define BOOST_PP_WHILE_128(p, o, s) BOOST_PP_WHILE_128_I(p, o, s) # define BOOST_PP_WHILE_129(p, o, s) BOOST_PP_WHILE_129_I(p, o, s) # define BOOST_PP_WHILE_130(p, o, s) BOOST_PP_WHILE_130_I(p, o, s) # define BOOST_PP_WHILE_131(p, o, s) BOOST_PP_WHILE_131_I(p, o, s) # define BOOST_PP_WHILE_132(p, o, s) BOOST_PP_WHILE_132_I(p, o, s) # define BOOST_PP_WHILE_133(p, o, s) BOOST_PP_WHILE_133_I(p, o, s) # define BOOST_PP_WHILE_134(p, o, s) BOOST_PP_WHILE_134_I(p, o, s) # define BOOST_PP_WHILE_135(p, o, s) BOOST_PP_WHILE_135_I(p, o, s) # define BOOST_PP_WHILE_136(p, o, s) BOOST_PP_WHILE_136_I(p, o, s) # define BOOST_PP_WHILE_137(p, o, s) BOOST_PP_WHILE_137_I(p, o, s) # define BOOST_PP_WHILE_138(p, o, s) BOOST_PP_WHILE_138_I(p, o, s) # define BOOST_PP_WHILE_139(p, o, s) BOOST_PP_WHILE_139_I(p, o, s) # define BOOST_PP_WHILE_140(p, o, s) BOOST_PP_WHILE_140_I(p, o, s) # define BOOST_PP_WHILE_141(p, o, s) BOOST_PP_WHILE_141_I(p, o, s) # define BOOST_PP_WHILE_142(p, o, s) BOOST_PP_WHILE_142_I(p, o, s) # define BOOST_PP_WHILE_143(p, o, s) BOOST_PP_WHILE_143_I(p, o, s) # define BOOST_PP_WHILE_144(p, o, s) BOOST_PP_WHILE_144_I(p, o, s) # define BOOST_PP_WHILE_145(p, o, s) BOOST_PP_WHILE_145_I(p, o, s) # define BOOST_PP_WHILE_146(p, o, s) BOOST_PP_WHILE_146_I(p, o, s) # define BOOST_PP_WHILE_147(p, o, s) BOOST_PP_WHILE_147_I(p, o, s) # define BOOST_PP_WHILE_148(p, o, s) BOOST_PP_WHILE_148_I(p, o, s) # define BOOST_PP_WHILE_149(p, o, s) BOOST_PP_WHILE_149_I(p, o, s) # define BOOST_PP_WHILE_150(p, o, s) BOOST_PP_WHILE_150_I(p, o, s) # define BOOST_PP_WHILE_151(p, o, s) BOOST_PP_WHILE_151_I(p, o, s) # define BOOST_PP_WHILE_152(p, o, s) BOOST_PP_WHILE_152_I(p, o, s) # define BOOST_PP_WHILE_153(p, o, s) BOOST_PP_WHILE_153_I(p, o, s) # define BOOST_PP_WHILE_154(p, o, s) BOOST_PP_WHILE_154_I(p, o, s) # define BOOST_PP_WHILE_155(p, o, s) BOOST_PP_WHILE_155_I(p, o, s) # define BOOST_PP_WHILE_156(p, o, s) BOOST_PP_WHILE_156_I(p, o, s) # define BOOST_PP_WHILE_157(p, o, s) BOOST_PP_WHILE_157_I(p, o, s) # define BOOST_PP_WHILE_158(p, o, s) BOOST_PP_WHILE_158_I(p, o, s) # define BOOST_PP_WHILE_159(p, o, s) BOOST_PP_WHILE_159_I(p, o, s) # define BOOST_PP_WHILE_160(p, o, s) BOOST_PP_WHILE_160_I(p, o, s) # define BOOST_PP_WHILE_161(p, o, s) BOOST_PP_WHILE_161_I(p, o, s) # define BOOST_PP_WHILE_162(p, o, s) BOOST_PP_WHILE_162_I(p, o, s) # define BOOST_PP_WHILE_163(p, o, s) BOOST_PP_WHILE_163_I(p, o, s) # define BOOST_PP_WHILE_164(p, o, s) BOOST_PP_WHILE_164_I(p, o, s) # define BOOST_PP_WHILE_165(p, o, s) BOOST_PP_WHILE_165_I(p, o, s) # define BOOST_PP_WHILE_166(p, o, s) BOOST_PP_WHILE_166_I(p, o, s) # define BOOST_PP_WHILE_167(p, o, s) BOOST_PP_WHILE_167_I(p, o, s) # define BOOST_PP_WHILE_168(p, o, s) BOOST_PP_WHILE_168_I(p, o, s) # define BOOST_PP_WHILE_169(p, o, s) BOOST_PP_WHILE_169_I(p, o, s) # define BOOST_PP_WHILE_170(p, o, s) BOOST_PP_WHILE_170_I(p, o, s) # define BOOST_PP_WHILE_171(p, o, s) BOOST_PP_WHILE_171_I(p, o, s) # define BOOST_PP_WHILE_172(p, o, s) BOOST_PP_WHILE_172_I(p, o, s) # define BOOST_PP_WHILE_173(p, o, s) BOOST_PP_WHILE_173_I(p, o, s) # define BOOST_PP_WHILE_174(p, o, s) BOOST_PP_WHILE_174_I(p, o, s) # define BOOST_PP_WHILE_175(p, o, s) BOOST_PP_WHILE_175_I(p, o, s) # define BOOST_PP_WHILE_176(p, o, s) BOOST_PP_WHILE_176_I(p, o, s) # define BOOST_PP_WHILE_177(p, o, s) BOOST_PP_WHILE_177_I(p, o, s) # define BOOST_PP_WHILE_178(p, o, s) BOOST_PP_WHILE_178_I(p, o, s) # define BOOST_PP_WHILE_179(p, o, s) BOOST_PP_WHILE_179_I(p, o, s) # define BOOST_PP_WHILE_180(p, o, s) BOOST_PP_WHILE_180_I(p, o, s) # define BOOST_PP_WHILE_181(p, o, s) BOOST_PP_WHILE_181_I(p, o, s) # define BOOST_PP_WHILE_182(p, o, s) BOOST_PP_WHILE_182_I(p, o, s) # define BOOST_PP_WHILE_183(p, o, s) BOOST_PP_WHILE_183_I(p, o, s) # define BOOST_PP_WHILE_184(p, o, s) BOOST_PP_WHILE_184_I(p, o, s) # define BOOST_PP_WHILE_185(p, o, s) BOOST_PP_WHILE_185_I(p, o, s) # define BOOST_PP_WHILE_186(p, o, s) BOOST_PP_WHILE_186_I(p, o, s) # define BOOST_PP_WHILE_187(p, o, s) BOOST_PP_WHILE_187_I(p, o, s) # define BOOST_PP_WHILE_188(p, o, s) BOOST_PP_WHILE_188_I(p, o, s) # define BOOST_PP_WHILE_189(p, o, s) BOOST_PP_WHILE_189_I(p, o, s) # define BOOST_PP_WHILE_190(p, o, s) BOOST_PP_WHILE_190_I(p, o, s) # define BOOST_PP_WHILE_191(p, o, s) BOOST_PP_WHILE_191_I(p, o, s) # define BOOST_PP_WHILE_192(p, o, s) BOOST_PP_WHILE_192_I(p, o, s) # define BOOST_PP_WHILE_193(p, o, s) BOOST_PP_WHILE_193_I(p, o, s) # define BOOST_PP_WHILE_194(p, o, s) BOOST_PP_WHILE_194_I(p, o, s) # define BOOST_PP_WHILE_195(p, o, s) BOOST_PP_WHILE_195_I(p, o, s) # define BOOST_PP_WHILE_196(p, o, s) BOOST_PP_WHILE_196_I(p, o, s) # define BOOST_PP_WHILE_197(p, o, s) BOOST_PP_WHILE_197_I(p, o, s) # define BOOST_PP_WHILE_198(p, o, s) BOOST_PP_WHILE_198_I(p, o, s) # define BOOST_PP_WHILE_199(p, o, s) BOOST_PP_WHILE_199_I(p, o, s) # define BOOST_PP_WHILE_200(p, o, s) BOOST_PP_WHILE_200_I(p, o, s) # define BOOST_PP_WHILE_201(p, o, s) BOOST_PP_WHILE_201_I(p, o, s) # define BOOST_PP_WHILE_202(p, o, s) BOOST_PP_WHILE_202_I(p, o, s) # define BOOST_PP_WHILE_203(p, o, s) BOOST_PP_WHILE_203_I(p, o, s) # define BOOST_PP_WHILE_204(p, o, s) BOOST_PP_WHILE_204_I(p, o, s) # define BOOST_PP_WHILE_205(p, o, s) BOOST_PP_WHILE_205_I(p, o, s) # define BOOST_PP_WHILE_206(p, o, s) BOOST_PP_WHILE_206_I(p, o, s) # define BOOST_PP_WHILE_207(p, o, s) BOOST_PP_WHILE_207_I(p, o, s) # define BOOST_PP_WHILE_208(p, o, s) BOOST_PP_WHILE_208_I(p, o, s) # define BOOST_PP_WHILE_209(p, o, s) BOOST_PP_WHILE_209_I(p, o, s) # define BOOST_PP_WHILE_210(p, o, s) BOOST_PP_WHILE_210_I(p, o, s) # define BOOST_PP_WHILE_211(p, o, s) BOOST_PP_WHILE_211_I(p, o, s) # define BOOST_PP_WHILE_212(p, o, s) BOOST_PP_WHILE_212_I(p, o, s) # define BOOST_PP_WHILE_213(p, o, s) BOOST_PP_WHILE_213_I(p, o, s) # define BOOST_PP_WHILE_214(p, o, s) BOOST_PP_WHILE_214_I(p, o, s) # define BOOST_PP_WHILE_215(p, o, s) BOOST_PP_WHILE_215_I(p, o, s) # define BOOST_PP_WHILE_216(p, o, s) BOOST_PP_WHILE_216_I(p, o, s) # define BOOST_PP_WHILE_217(p, o, s) BOOST_PP_WHILE_217_I(p, o, s) # define BOOST_PP_WHILE_218(p, o, s) BOOST_PP_WHILE_218_I(p, o, s) # define BOOST_PP_WHILE_219(p, o, s) BOOST_PP_WHILE_219_I(p, o, s) # define BOOST_PP_WHILE_220(p, o, s) BOOST_PP_WHILE_220_I(p, o, s) # define BOOST_PP_WHILE_221(p, o, s) BOOST_PP_WHILE_221_I(p, o, s) # define BOOST_PP_WHILE_222(p, o, s) BOOST_PP_WHILE_222_I(p, o, s) # define BOOST_PP_WHILE_223(p, o, s) BOOST_PP_WHILE_223_I(p, o, s) # define BOOST_PP_WHILE_224(p, o, s) BOOST_PP_WHILE_224_I(p, o, s) # define BOOST_PP_WHILE_225(p, o, s) BOOST_PP_WHILE_225_I(p, o, s) # define BOOST_PP_WHILE_226(p, o, s) BOOST_PP_WHILE_226_I(p, o, s) # define BOOST_PP_WHILE_227(p, o, s) BOOST_PP_WHILE_227_I(p, o, s) # define BOOST_PP_WHILE_228(p, o, s) BOOST_PP_WHILE_228_I(p, o, s) # define BOOST_PP_WHILE_229(p, o, s) BOOST_PP_WHILE_229_I(p, o, s) # define BOOST_PP_WHILE_230(p, o, s) BOOST_PP_WHILE_230_I(p, o, s) # define BOOST_PP_WHILE_231(p, o, s) BOOST_PP_WHILE_231_I(p, o, s) # define BOOST_PP_WHILE_232(p, o, s) BOOST_PP_WHILE_232_I(p, o, s) # define BOOST_PP_WHILE_233(p, o, s) BOOST_PP_WHILE_233_I(p, o, s) # define BOOST_PP_WHILE_234(p, o, s) BOOST_PP_WHILE_234_I(p, o, s) # define BOOST_PP_WHILE_235(p, o, s) BOOST_PP_WHILE_235_I(p, o, s) # define BOOST_PP_WHILE_236(p, o, s) BOOST_PP_WHILE_236_I(p, o, s) # define BOOST_PP_WHILE_237(p, o, s) BOOST_PP_WHILE_237_I(p, o, s) # define BOOST_PP_WHILE_238(p, o, s) BOOST_PP_WHILE_238_I(p, o, s) # define BOOST_PP_WHILE_239(p, o, s) BOOST_PP_WHILE_239_I(p, o, s) # define BOOST_PP_WHILE_240(p, o, s) BOOST_PP_WHILE_240_I(p, o, s) # define BOOST_PP_WHILE_241(p, o, s) BOOST_PP_WHILE_241_I(p, o, s) # define BOOST_PP_WHILE_242(p, o, s) BOOST_PP_WHILE_242_I(p, o, s) # define BOOST_PP_WHILE_243(p, o, s) BOOST_PP_WHILE_243_I(p, o, s) # define BOOST_PP_WHILE_244(p, o, s) BOOST_PP_WHILE_244_I(p, o, s) # define BOOST_PP_WHILE_245(p, o, s) BOOST_PP_WHILE_245_I(p, o, s) # define BOOST_PP_WHILE_246(p, o, s) BOOST_PP_WHILE_246_I(p, o, s) # define BOOST_PP_WHILE_247(p, o, s) BOOST_PP_WHILE_247_I(p, o, s) # define BOOST_PP_WHILE_248(p, o, s) BOOST_PP_WHILE_248_I(p, o, s) # define BOOST_PP_WHILE_249(p, o, s) BOOST_PP_WHILE_249_I(p, o, s) # define BOOST_PP_WHILE_250(p, o, s) BOOST_PP_WHILE_250_I(p, o, s) # define BOOST_PP_WHILE_251(p, o, s) BOOST_PP_WHILE_251_I(p, o, s) # define BOOST_PP_WHILE_252(p, o, s) BOOST_PP_WHILE_252_I(p, o, s) # define BOOST_PP_WHILE_253(p, o, s) BOOST_PP_WHILE_253_I(p, o, s) # define BOOST_PP_WHILE_254(p, o, s) BOOST_PP_WHILE_254_I(p, o, s) # define BOOST_PP_WHILE_255(p, o, s) BOOST_PP_WHILE_255_I(p, o, s) # define BOOST_PP_WHILE_256(p, o, s) BOOST_PP_WHILE_256_I(p, o, s) # # define BOOST_PP_WHILE_1_I(p, o, s) BOOST_PP_IF(p(2, s), BOOST_PP_WHILE_2, s BOOST_PP_TUPLE_EAT_3)(p, o, o(2, s)) # define BOOST_PP_WHILE_2_I(p, o, s) BOOST_PP_IF(p(3, s), BOOST_PP_WHILE_3, s BOOST_PP_TUPLE_EAT_3)(p, o, o(3, s)) # define BOOST_PP_WHILE_3_I(p, o, s) BOOST_PP_IF(p(4, s), BOOST_PP_WHILE_4, s BOOST_PP_TUPLE_EAT_3)(p, o, o(4, s)) # define BOOST_PP_WHILE_4_I(p, o, s) BOOST_PP_IF(p(5, s), BOOST_PP_WHILE_5, s BOOST_PP_TUPLE_EAT_3)(p, o, o(5, s)) # define BOOST_PP_WHILE_5_I(p, o, s) BOOST_PP_IF(p(6, s), BOOST_PP_WHILE_6, s BOOST_PP_TUPLE_EAT_3)(p, o, o(6, s)) # define BOOST_PP_WHILE_6_I(p, o, s) BOOST_PP_IF(p(7, s), BOOST_PP_WHILE_7, s BOOST_PP_TUPLE_EAT_3)(p, o, o(7, s)) # define BOOST_PP_WHILE_7_I(p, o, s) BOOST_PP_IF(p(8, s), BOOST_PP_WHILE_8, s BOOST_PP_TUPLE_EAT_3)(p, o, o(8, s)) # define BOOST_PP_WHILE_8_I(p, o, s) BOOST_PP_IF(p(9, s), BOOST_PP_WHILE_9, s BOOST_PP_TUPLE_EAT_3)(p, o, o(9, s)) # define BOOST_PP_WHILE_9_I(p, o, s) BOOST_PP_IF(p(10, s), BOOST_PP_WHILE_10, s BOOST_PP_TUPLE_EAT_3)(p, o, o(10, s)) # define BOOST_PP_WHILE_10_I(p, o, s) BOOST_PP_IF(p(11, s), BOOST_PP_WHILE_11, s BOOST_PP_TUPLE_EAT_3)(p, o, o(11, s)) # define BOOST_PP_WHILE_11_I(p, o, s) BOOST_PP_IF(p(12, s), BOOST_PP_WHILE_12, s BOOST_PP_TUPLE_EAT_3)(p, o, o(12, s)) # define BOOST_PP_WHILE_12_I(p, o, s) BOOST_PP_IF(p(13, s), BOOST_PP_WHILE_13, s BOOST_PP_TUPLE_EAT_3)(p, o, o(13, s)) # define BOOST_PP_WHILE_13_I(p, o, s) BOOST_PP_IF(p(14, s), BOOST_PP_WHILE_14, s BOOST_PP_TUPLE_EAT_3)(p, o, o(14, s)) # define BOOST_PP_WHILE_14_I(p, o, s) BOOST_PP_IF(p(15, s), BOOST_PP_WHILE_15, s BOOST_PP_TUPLE_EAT_3)(p, o, o(15, s)) # define BOOST_PP_WHILE_15_I(p, o, s) BOOST_PP_IF(p(16, s), BOOST_PP_WHILE_16, s BOOST_PP_TUPLE_EAT_3)(p, o, o(16, s)) # define BOOST_PP_WHILE_16_I(p, o, s) BOOST_PP_IF(p(17, s), BOOST_PP_WHILE_17, s BOOST_PP_TUPLE_EAT_3)(p, o, o(17, s)) # define BOOST_PP_WHILE_17_I(p, o, s) BOOST_PP_IF(p(18, s), BOOST_PP_WHILE_18, s BOOST_PP_TUPLE_EAT_3)(p, o, o(18, s)) # define BOOST_PP_WHILE_18_I(p, o, s) BOOST_PP_IF(p(19, s), BOOST_PP_WHILE_19, s BOOST_PP_TUPLE_EAT_3)(p, o, o(19, s)) # define BOOST_PP_WHILE_19_I(p, o, s) BOOST_PP_IF(p(20, s), BOOST_PP_WHILE_20, s BOOST_PP_TUPLE_EAT_3)(p, o, o(20, s)) # define BOOST_PP_WHILE_20_I(p, o, s) BOOST_PP_IF(p(21, s), BOOST_PP_WHILE_21, s BOOST_PP_TUPLE_EAT_3)(p, o, o(21, s)) # define BOOST_PP_WHILE_21_I(p, o, s) BOOST_PP_IF(p(22, s), BOOST_PP_WHILE_22, s BOOST_PP_TUPLE_EAT_3)(p, o, o(22, s)) # define BOOST_PP_WHILE_22_I(p, o, s) BOOST_PP_IF(p(23, s), BOOST_PP_WHILE_23, s BOOST_PP_TUPLE_EAT_3)(p, o, o(23, s)) # define BOOST_PP_WHILE_23_I(p, o, s) BOOST_PP_IF(p(24, s), BOOST_PP_WHILE_24, s BOOST_PP_TUPLE_EAT_3)(p, o, o(24, s)) # define BOOST_PP_WHILE_24_I(p, o, s) BOOST_PP_IF(p(25, s), BOOST_PP_WHILE_25, s BOOST_PP_TUPLE_EAT_3)(p, o, o(25, s)) # define BOOST_PP_WHILE_25_I(p, o, s) BOOST_PP_IF(p(26, s), BOOST_PP_WHILE_26, s BOOST_PP_TUPLE_EAT_3)(p, o, o(26, s)) # define BOOST_PP_WHILE_26_I(p, o, s) BOOST_PP_IF(p(27, s), BOOST_PP_WHILE_27, s BOOST_PP_TUPLE_EAT_3)(p, o, o(27, s)) # define BOOST_PP_WHILE_27_I(p, o, s) BOOST_PP_IF(p(28, s), BOOST_PP_WHILE_28, s BOOST_PP_TUPLE_EAT_3)(p, o, o(28, s)) # define BOOST_PP_WHILE_28_I(p, o, s) BOOST_PP_IF(p(29, s), BOOST_PP_WHILE_29, s BOOST_PP_TUPLE_EAT_3)(p, o, o(29, s)) # define BOOST_PP_WHILE_29_I(p, o, s) BOOST_PP_IF(p(30, s), BOOST_PP_WHILE_30, s BOOST_PP_TUPLE_EAT_3)(p, o, o(30, s)) # define BOOST_PP_WHILE_30_I(p, o, s) BOOST_PP_IF(p(31, s), BOOST_PP_WHILE_31, s BOOST_PP_TUPLE_EAT_3)(p, o, o(31, s)) # define BOOST_PP_WHILE_31_I(p, o, s) BOOST_PP_IF(p(32, s), BOOST_PP_WHILE_32, s BOOST_PP_TUPLE_EAT_3)(p, o, o(32, s)) # define BOOST_PP_WHILE_32_I(p, o, s) BOOST_PP_IF(p(33, s), BOOST_PP_WHILE_33, s BOOST_PP_TUPLE_EAT_3)(p, o, o(33, s)) # define BOOST_PP_WHILE_33_I(p, o, s) BOOST_PP_IF(p(34, s), BOOST_PP_WHILE_34, s BOOST_PP_TUPLE_EAT_3)(p, o, o(34, s)) # define BOOST_PP_WHILE_34_I(p, o, s) BOOST_PP_IF(p(35, s), BOOST_PP_WHILE_35, s BOOST_PP_TUPLE_EAT_3)(p, o, o(35, s)) # define BOOST_PP_WHILE_35_I(p, o, s) BOOST_PP_IF(p(36, s), BOOST_PP_WHILE_36, s BOOST_PP_TUPLE_EAT_3)(p, o, o(36, s)) # define BOOST_PP_WHILE_36_I(p, o, s) BOOST_PP_IF(p(37, s), BOOST_PP_WHILE_37, s BOOST_PP_TUPLE_EAT_3)(p, o, o(37, s)) # define BOOST_PP_WHILE_37_I(p, o, s) BOOST_PP_IF(p(38, s), BOOST_PP_WHILE_38, s BOOST_PP_TUPLE_EAT_3)(p, o, o(38, s)) # define BOOST_PP_WHILE_38_I(p, o, s) BOOST_PP_IF(p(39, s), BOOST_PP_WHILE_39, s BOOST_PP_TUPLE_EAT_3)(p, o, o(39, s)) # define BOOST_PP_WHILE_39_I(p, o, s) BOOST_PP_IF(p(40, s), BOOST_PP_WHILE_40, s BOOST_PP_TUPLE_EAT_3)(p, o, o(40, s)) # define BOOST_PP_WHILE_40_I(p, o, s) BOOST_PP_IF(p(41, s), BOOST_PP_WHILE_41, s BOOST_PP_TUPLE_EAT_3)(p, o, o(41, s)) # define BOOST_PP_WHILE_41_I(p, o, s) BOOST_PP_IF(p(42, s), BOOST_PP_WHILE_42, s BOOST_PP_TUPLE_EAT_3)(p, o, o(42, s)) # define BOOST_PP_WHILE_42_I(p, o, s) BOOST_PP_IF(p(43, s), BOOST_PP_WHILE_43, s BOOST_PP_TUPLE_EAT_3)(p, o, o(43, s)) # define BOOST_PP_WHILE_43_I(p, o, s) BOOST_PP_IF(p(44, s), BOOST_PP_WHILE_44, s BOOST_PP_TUPLE_EAT_3)(p, o, o(44, s)) # define BOOST_PP_WHILE_44_I(p, o, s) BOOST_PP_IF(p(45, s), BOOST_PP_WHILE_45, s BOOST_PP_TUPLE_EAT_3)(p, o, o(45, s)) # define BOOST_PP_WHILE_45_I(p, o, s) BOOST_PP_IF(p(46, s), BOOST_PP_WHILE_46, s BOOST_PP_TUPLE_EAT_3)(p, o, o(46, s)) # define BOOST_PP_WHILE_46_I(p, o, s) BOOST_PP_IF(p(47, s), BOOST_PP_WHILE_47, s BOOST_PP_TUPLE_EAT_3)(p, o, o(47, s)) # define BOOST_PP_WHILE_47_I(p, o, s) BOOST_PP_IF(p(48, s), BOOST_PP_WHILE_48, s BOOST_PP_TUPLE_EAT_3)(p, o, o(48, s)) # define BOOST_PP_WHILE_48_I(p, o, s) BOOST_PP_IF(p(49, s), BOOST_PP_WHILE_49, s BOOST_PP_TUPLE_EAT_3)(p, o, o(49, s)) # define BOOST_PP_WHILE_49_I(p, o, s) BOOST_PP_IF(p(50, s), BOOST_PP_WHILE_50, s BOOST_PP_TUPLE_EAT_3)(p, o, o(50, s)) # define BOOST_PP_WHILE_50_I(p, o, s) BOOST_PP_IF(p(51, s), BOOST_PP_WHILE_51, s BOOST_PP_TUPLE_EAT_3)(p, o, o(51, s)) # define BOOST_PP_WHILE_51_I(p, o, s) BOOST_PP_IF(p(52, s), BOOST_PP_WHILE_52, s BOOST_PP_TUPLE_EAT_3)(p, o, o(52, s)) # define BOOST_PP_WHILE_52_I(p, o, s) BOOST_PP_IF(p(53, s), BOOST_PP_WHILE_53, s BOOST_PP_TUPLE_EAT_3)(p, o, o(53, s)) # define BOOST_PP_WHILE_53_I(p, o, s) BOOST_PP_IF(p(54, s), BOOST_PP_WHILE_54, s BOOST_PP_TUPLE_EAT_3)(p, o, o(54, s)) # define BOOST_PP_WHILE_54_I(p, o, s) BOOST_PP_IF(p(55, s), BOOST_PP_WHILE_55, s BOOST_PP_TUPLE_EAT_3)(p, o, o(55, s)) # define BOOST_PP_WHILE_55_I(p, o, s) BOOST_PP_IF(p(56, s), BOOST_PP_WHILE_56, s BOOST_PP_TUPLE_EAT_3)(p, o, o(56, s)) # define BOOST_PP_WHILE_56_I(p, o, s) BOOST_PP_IF(p(57, s), BOOST_PP_WHILE_57, s BOOST_PP_TUPLE_EAT_3)(p, o, o(57, s)) # define BOOST_PP_WHILE_57_I(p, o, s) BOOST_PP_IF(p(58, s), BOOST_PP_WHILE_58, s BOOST_PP_TUPLE_EAT_3)(p, o, o(58, s)) # define BOOST_PP_WHILE_58_I(p, o, s) BOOST_PP_IF(p(59, s), BOOST_PP_WHILE_59, s BOOST_PP_TUPLE_EAT_3)(p, o, o(59, s)) # define BOOST_PP_WHILE_59_I(p, o, s) BOOST_PP_IF(p(60, s), BOOST_PP_WHILE_60, s BOOST_PP_TUPLE_EAT_3)(p, o, o(60, s)) # define BOOST_PP_WHILE_60_I(p, o, s) BOOST_PP_IF(p(61, s), BOOST_PP_WHILE_61, s BOOST_PP_TUPLE_EAT_3)(p, o, o(61, s)) # define BOOST_PP_WHILE_61_I(p, o, s) BOOST_PP_IF(p(62, s), BOOST_PP_WHILE_62, s BOOST_PP_TUPLE_EAT_3)(p, o, o(62, s)) # define BOOST_PP_WHILE_62_I(p, o, s) BOOST_PP_IF(p(63, s), BOOST_PP_WHILE_63, s BOOST_PP_TUPLE_EAT_3)(p, o, o(63, s)) # define BOOST_PP_WHILE_63_I(p, o, s) BOOST_PP_IF(p(64, s), BOOST_PP_WHILE_64, s BOOST_PP_TUPLE_EAT_3)(p, o, o(64, s)) # define BOOST_PP_WHILE_64_I(p, o, s) BOOST_PP_IF(p(65, s), BOOST_PP_WHILE_65, s BOOST_PP_TUPLE_EAT_3)(p, o, o(65, s)) # define BOOST_PP_WHILE_65_I(p, o, s) BOOST_PP_IF(p(66, s), BOOST_PP_WHILE_66, s BOOST_PP_TUPLE_EAT_3)(p, o, o(66, s)) # define BOOST_PP_WHILE_66_I(p, o, s) BOOST_PP_IF(p(67, s), BOOST_PP_WHILE_67, s BOOST_PP_TUPLE_EAT_3)(p, o, o(67, s)) # define BOOST_PP_WHILE_67_I(p, o, s) BOOST_PP_IF(p(68, s), BOOST_PP_WHILE_68, s BOOST_PP_TUPLE_EAT_3)(p, o, o(68, s)) # define BOOST_PP_WHILE_68_I(p, o, s) BOOST_PP_IF(p(69, s), BOOST_PP_WHILE_69, s BOOST_PP_TUPLE_EAT_3)(p, o, o(69, s)) # define BOOST_PP_WHILE_69_I(p, o, s) BOOST_PP_IF(p(70, s), BOOST_PP_WHILE_70, s BOOST_PP_TUPLE_EAT_3)(p, o, o(70, s)) # define BOOST_PP_WHILE_70_I(p, o, s) BOOST_PP_IF(p(71, s), BOOST_PP_WHILE_71, s BOOST_PP_TUPLE_EAT_3)(p, o, o(71, s)) # define BOOST_PP_WHILE_71_I(p, o, s) BOOST_PP_IF(p(72, s), BOOST_PP_WHILE_72, s BOOST_PP_TUPLE_EAT_3)(p, o, o(72, s)) # define BOOST_PP_WHILE_72_I(p, o, s) BOOST_PP_IF(p(73, s), BOOST_PP_WHILE_73, s BOOST_PP_TUPLE_EAT_3)(p, o, o(73, s)) # define BOOST_PP_WHILE_73_I(p, o, s) BOOST_PP_IF(p(74, s), BOOST_PP_WHILE_74, s BOOST_PP_TUPLE_EAT_3)(p, o, o(74, s)) # define BOOST_PP_WHILE_74_I(p, o, s) BOOST_PP_IF(p(75, s), BOOST_PP_WHILE_75, s BOOST_PP_TUPLE_EAT_3)(p, o, o(75, s)) # define BOOST_PP_WHILE_75_I(p, o, s) BOOST_PP_IF(p(76, s), BOOST_PP_WHILE_76, s BOOST_PP_TUPLE_EAT_3)(p, o, o(76, s)) # define BOOST_PP_WHILE_76_I(p, o, s) BOOST_PP_IF(p(77, s), BOOST_PP_WHILE_77, s BOOST_PP_TUPLE_EAT_3)(p, o, o(77, s)) # define BOOST_PP_WHILE_77_I(p, o, s) BOOST_PP_IF(p(78, s), BOOST_PP_WHILE_78, s BOOST_PP_TUPLE_EAT_3)(p, o, o(78, s)) # define BOOST_PP_WHILE_78_I(p, o, s) BOOST_PP_IF(p(79, s), BOOST_PP_WHILE_79, s BOOST_PP_TUPLE_EAT_3)(p, o, o(79, s)) # define BOOST_PP_WHILE_79_I(p, o, s) BOOST_PP_IF(p(80, s), BOOST_PP_WHILE_80, s BOOST_PP_TUPLE_EAT_3)(p, o, o(80, s)) # define BOOST_PP_WHILE_80_I(p, o, s) BOOST_PP_IF(p(81, s), BOOST_PP_WHILE_81, s BOOST_PP_TUPLE_EAT_3)(p, o, o(81, s)) # define BOOST_PP_WHILE_81_I(p, o, s) BOOST_PP_IF(p(82, s), BOOST_PP_WHILE_82, s BOOST_PP_TUPLE_EAT_3)(p, o, o(82, s)) # define BOOST_PP_WHILE_82_I(p, o, s) BOOST_PP_IF(p(83, s), BOOST_PP_WHILE_83, s BOOST_PP_TUPLE_EAT_3)(p, o, o(83, s)) # define BOOST_PP_WHILE_83_I(p, o, s) BOOST_PP_IF(p(84, s), BOOST_PP_WHILE_84, s BOOST_PP_TUPLE_EAT_3)(p, o, o(84, s)) # define BOOST_PP_WHILE_84_I(p, o, s) BOOST_PP_IF(p(85, s), BOOST_PP_WHILE_85, s BOOST_PP_TUPLE_EAT_3)(p, o, o(85, s)) # define BOOST_PP_WHILE_85_I(p, o, s) BOOST_PP_IF(p(86, s), BOOST_PP_WHILE_86, s BOOST_PP_TUPLE_EAT_3)(p, o, o(86, s)) # define BOOST_PP_WHILE_86_I(p, o, s) BOOST_PP_IF(p(87, s), BOOST_PP_WHILE_87, s BOOST_PP_TUPLE_EAT_3)(p, o, o(87, s)) # define BOOST_PP_WHILE_87_I(p, o, s) BOOST_PP_IF(p(88, s), BOOST_PP_WHILE_88, s BOOST_PP_TUPLE_EAT_3)(p, o, o(88, s)) # define BOOST_PP_WHILE_88_I(p, o, s) BOOST_PP_IF(p(89, s), BOOST_PP_WHILE_89, s BOOST_PP_TUPLE_EAT_3)(p, o, o(89, s)) # define BOOST_PP_WHILE_89_I(p, o, s) BOOST_PP_IF(p(90, s), BOOST_PP_WHILE_90, s BOOST_PP_TUPLE_EAT_3)(p, o, o(90, s)) # define BOOST_PP_WHILE_90_I(p, o, s) BOOST_PP_IF(p(91, s), BOOST_PP_WHILE_91, s BOOST_PP_TUPLE_EAT_3)(p, o, o(91, s)) # define BOOST_PP_WHILE_91_I(p, o, s) BOOST_PP_IF(p(92, s), BOOST_PP_WHILE_92, s BOOST_PP_TUPLE_EAT_3)(p, o, o(92, s)) # define BOOST_PP_WHILE_92_I(p, o, s) BOOST_PP_IF(p(93, s), BOOST_PP_WHILE_93, s BOOST_PP_TUPLE_EAT_3)(p, o, o(93, s)) # define BOOST_PP_WHILE_93_I(p, o, s) BOOST_PP_IF(p(94, s), BOOST_PP_WHILE_94, s BOOST_PP_TUPLE_EAT_3)(p, o, o(94, s)) # define BOOST_PP_WHILE_94_I(p, o, s) BOOST_PP_IF(p(95, s), BOOST_PP_WHILE_95, s BOOST_PP_TUPLE_EAT_3)(p, o, o(95, s)) # define BOOST_PP_WHILE_95_I(p, o, s) BOOST_PP_IF(p(96, s), BOOST_PP_WHILE_96, s BOOST_PP_TUPLE_EAT_3)(p, o, o(96, s)) # define BOOST_PP_WHILE_96_I(p, o, s) BOOST_PP_IF(p(97, s), BOOST_PP_WHILE_97, s BOOST_PP_TUPLE_EAT_3)(p, o, o(97, s)) # define BOOST_PP_WHILE_97_I(p, o, s) BOOST_PP_IF(p(98, s), BOOST_PP_WHILE_98, s BOOST_PP_TUPLE_EAT_3)(p, o, o(98, s)) # define BOOST_PP_WHILE_98_I(p, o, s) BOOST_PP_IF(p(99, s), BOOST_PP_WHILE_99, s BOOST_PP_TUPLE_EAT_3)(p, o, o(99, s)) # define BOOST_PP_WHILE_99_I(p, o, s) BOOST_PP_IF(p(100, s), BOOST_PP_WHILE_100, s BOOST_PP_TUPLE_EAT_3)(p, o, o(100, s)) # define BOOST_PP_WHILE_100_I(p, o, s) BOOST_PP_IF(p(101, s), BOOST_PP_WHILE_101, s BOOST_PP_TUPLE_EAT_3)(p, o, o(101, s)) # define BOOST_PP_WHILE_101_I(p, o, s) BOOST_PP_IF(p(102, s), BOOST_PP_WHILE_102, s BOOST_PP_TUPLE_EAT_3)(p, o, o(102, s)) # define BOOST_PP_WHILE_102_I(p, o, s) BOOST_PP_IF(p(103, s), BOOST_PP_WHILE_103, s BOOST_PP_TUPLE_EAT_3)(p, o, o(103, s)) # define BOOST_PP_WHILE_103_I(p, o, s) BOOST_PP_IF(p(104, s), BOOST_PP_WHILE_104, s BOOST_PP_TUPLE_EAT_3)(p, o, o(104, s)) # define BOOST_PP_WHILE_104_I(p, o, s) BOOST_PP_IF(p(105, s), BOOST_PP_WHILE_105, s BOOST_PP_TUPLE_EAT_3)(p, o, o(105, s)) # define BOOST_PP_WHILE_105_I(p, o, s) BOOST_PP_IF(p(106, s), BOOST_PP_WHILE_106, s BOOST_PP_TUPLE_EAT_3)(p, o, o(106, s)) # define BOOST_PP_WHILE_106_I(p, o, s) BOOST_PP_IF(p(107, s), BOOST_PP_WHILE_107, s BOOST_PP_TUPLE_EAT_3)(p, o, o(107, s)) # define BOOST_PP_WHILE_107_I(p, o, s) BOOST_PP_IF(p(108, s), BOOST_PP_WHILE_108, s BOOST_PP_TUPLE_EAT_3)(p, o, o(108, s)) # define BOOST_PP_WHILE_108_I(p, o, s) BOOST_PP_IF(p(109, s), BOOST_PP_WHILE_109, s BOOST_PP_TUPLE_EAT_3)(p, o, o(109, s)) # define BOOST_PP_WHILE_109_I(p, o, s) BOOST_PP_IF(p(110, s), BOOST_PP_WHILE_110, s BOOST_PP_TUPLE_EAT_3)(p, o, o(110, s)) # define BOOST_PP_WHILE_110_I(p, o, s) BOOST_PP_IF(p(111, s), BOOST_PP_WHILE_111, s BOOST_PP_TUPLE_EAT_3)(p, o, o(111, s)) # define BOOST_PP_WHILE_111_I(p, o, s) BOOST_PP_IF(p(112, s), BOOST_PP_WHILE_112, s BOOST_PP_TUPLE_EAT_3)(p, o, o(112, s)) # define BOOST_PP_WHILE_112_I(p, o, s) BOOST_PP_IF(p(113, s), BOOST_PP_WHILE_113, s BOOST_PP_TUPLE_EAT_3)(p, o, o(113, s)) # define BOOST_PP_WHILE_113_I(p, o, s) BOOST_PP_IF(p(114, s), BOOST_PP_WHILE_114, s BOOST_PP_TUPLE_EAT_3)(p, o, o(114, s)) # define BOOST_PP_WHILE_114_I(p, o, s) BOOST_PP_IF(p(115, s), BOOST_PP_WHILE_115, s BOOST_PP_TUPLE_EAT_3)(p, o, o(115, s)) # define BOOST_PP_WHILE_115_I(p, o, s) BOOST_PP_IF(p(116, s), BOOST_PP_WHILE_116, s BOOST_PP_TUPLE_EAT_3)(p, o, o(116, s)) # define BOOST_PP_WHILE_116_I(p, o, s) BOOST_PP_IF(p(117, s), BOOST_PP_WHILE_117, s BOOST_PP_TUPLE_EAT_3)(p, o, o(117, s)) # define BOOST_PP_WHILE_117_I(p, o, s) BOOST_PP_IF(p(118, s), BOOST_PP_WHILE_118, s BOOST_PP_TUPLE_EAT_3)(p, o, o(118, s)) # define BOOST_PP_WHILE_118_I(p, o, s) BOOST_PP_IF(p(119, s), BOOST_PP_WHILE_119, s BOOST_PP_TUPLE_EAT_3)(p, o, o(119, s)) # define BOOST_PP_WHILE_119_I(p, o, s) BOOST_PP_IF(p(120, s), BOOST_PP_WHILE_120, s BOOST_PP_TUPLE_EAT_3)(p, o, o(120, s)) # define BOOST_PP_WHILE_120_I(p, o, s) BOOST_PP_IF(p(121, s), BOOST_PP_WHILE_121, s BOOST_PP_TUPLE_EAT_3)(p, o, o(121, s)) # define BOOST_PP_WHILE_121_I(p, o, s) BOOST_PP_IF(p(122, s), BOOST_PP_WHILE_122, s BOOST_PP_TUPLE_EAT_3)(p, o, o(122, s)) # define BOOST_PP_WHILE_122_I(p, o, s) BOOST_PP_IF(p(123, s), BOOST_PP_WHILE_123, s BOOST_PP_TUPLE_EAT_3)(p, o, o(123, s)) # define BOOST_PP_WHILE_123_I(p, o, s) BOOST_PP_IF(p(124, s), BOOST_PP_WHILE_124, s BOOST_PP_TUPLE_EAT_3)(p, o, o(124, s)) # define BOOST_PP_WHILE_124_I(p, o, s) BOOST_PP_IF(p(125, s), BOOST_PP_WHILE_125, s BOOST_PP_TUPLE_EAT_3)(p, o, o(125, s)) # define BOOST_PP_WHILE_125_I(p, o, s) BOOST_PP_IF(p(126, s), BOOST_PP_WHILE_126, s BOOST_PP_TUPLE_EAT_3)(p, o, o(126, s)) # define BOOST_PP_WHILE_126_I(p, o, s) BOOST_PP_IF(p(127, s), BOOST_PP_WHILE_127, s BOOST_PP_TUPLE_EAT_3)(p, o, o(127, s)) # define BOOST_PP_WHILE_127_I(p, o, s) BOOST_PP_IF(p(128, s), BOOST_PP_WHILE_128, s BOOST_PP_TUPLE_EAT_3)(p, o, o(128, s)) # define BOOST_PP_WHILE_128_I(p, o, s) BOOST_PP_IF(p(129, s), BOOST_PP_WHILE_129, s BOOST_PP_TUPLE_EAT_3)(p, o, o(129, s)) # define BOOST_PP_WHILE_129_I(p, o, s) BOOST_PP_IF(p(130, s), BOOST_PP_WHILE_130, s BOOST_PP_TUPLE_EAT_3)(p, o, o(130, s)) # define BOOST_PP_WHILE_130_I(p, o, s) BOOST_PP_IF(p(131, s), BOOST_PP_WHILE_131, s BOOST_PP_TUPLE_EAT_3)(p, o, o(131, s)) # define BOOST_PP_WHILE_131_I(p, o, s) BOOST_PP_IF(p(132, s), BOOST_PP_WHILE_132, s BOOST_PP_TUPLE_EAT_3)(p, o, o(132, s)) # define BOOST_PP_WHILE_132_I(p, o, s) BOOST_PP_IF(p(133, s), BOOST_PP_WHILE_133, s BOOST_PP_TUPLE_EAT_3)(p, o, o(133, s)) # define BOOST_PP_WHILE_133_I(p, o, s) BOOST_PP_IF(p(134, s), BOOST_PP_WHILE_134, s BOOST_PP_TUPLE_EAT_3)(p, o, o(134, s)) # define BOOST_PP_WHILE_134_I(p, o, s) BOOST_PP_IF(p(135, s), BOOST_PP_WHILE_135, s BOOST_PP_TUPLE_EAT_3)(p, o, o(135, s)) # define BOOST_PP_WHILE_135_I(p, o, s) BOOST_PP_IF(p(136, s), BOOST_PP_WHILE_136, s BOOST_PP_TUPLE_EAT_3)(p, o, o(136, s)) # define BOOST_PP_WHILE_136_I(p, o, s) BOOST_PP_IF(p(137, s), BOOST_PP_WHILE_137, s BOOST_PP_TUPLE_EAT_3)(p, o, o(137, s)) # define BOOST_PP_WHILE_137_I(p, o, s) BOOST_PP_IF(p(138, s), BOOST_PP_WHILE_138, s BOOST_PP_TUPLE_EAT_3)(p, o, o(138, s)) # define BOOST_PP_WHILE_138_I(p, o, s) BOOST_PP_IF(p(139, s), BOOST_PP_WHILE_139, s BOOST_PP_TUPLE_EAT_3)(p, o, o(139, s)) # define BOOST_PP_WHILE_139_I(p, o, s) BOOST_PP_IF(p(140, s), BOOST_PP_WHILE_140, s BOOST_PP_TUPLE_EAT_3)(p, o, o(140, s)) # define BOOST_PP_WHILE_140_I(p, o, s) BOOST_PP_IF(p(141, s), BOOST_PP_WHILE_141, s BOOST_PP_TUPLE_EAT_3)(p, o, o(141, s)) # define BOOST_PP_WHILE_141_I(p, o, s) BOOST_PP_IF(p(142, s), BOOST_PP_WHILE_142, s BOOST_PP_TUPLE_EAT_3)(p, o, o(142, s)) # define BOOST_PP_WHILE_142_I(p, o, s) BOOST_PP_IF(p(143, s), BOOST_PP_WHILE_143, s BOOST_PP_TUPLE_EAT_3)(p, o, o(143, s)) # define BOOST_PP_WHILE_143_I(p, o, s) BOOST_PP_IF(p(144, s), BOOST_PP_WHILE_144, s BOOST_PP_TUPLE_EAT_3)(p, o, o(144, s)) # define BOOST_PP_WHILE_144_I(p, o, s) BOOST_PP_IF(p(145, s), BOOST_PP_WHILE_145, s BOOST_PP_TUPLE_EAT_3)(p, o, o(145, s)) # define BOOST_PP_WHILE_145_I(p, o, s) BOOST_PP_IF(p(146, s), BOOST_PP_WHILE_146, s BOOST_PP_TUPLE_EAT_3)(p, o, o(146, s)) # define BOOST_PP_WHILE_146_I(p, o, s) BOOST_PP_IF(p(147, s), BOOST_PP_WHILE_147, s BOOST_PP_TUPLE_EAT_3)(p, o, o(147, s)) # define BOOST_PP_WHILE_147_I(p, o, s) BOOST_PP_IF(p(148, s), BOOST_PP_WHILE_148, s BOOST_PP_TUPLE_EAT_3)(p, o, o(148, s)) # define BOOST_PP_WHILE_148_I(p, o, s) BOOST_PP_IF(p(149, s), BOOST_PP_WHILE_149, s BOOST_PP_TUPLE_EAT_3)(p, o, o(149, s)) # define BOOST_PP_WHILE_149_I(p, o, s) BOOST_PP_IF(p(150, s), BOOST_PP_WHILE_150, s BOOST_PP_TUPLE_EAT_3)(p, o, o(150, s)) # define BOOST_PP_WHILE_150_I(p, o, s) BOOST_PP_IF(p(151, s), BOOST_PP_WHILE_151, s BOOST_PP_TUPLE_EAT_3)(p, o, o(151, s)) # define BOOST_PP_WHILE_151_I(p, o, s) BOOST_PP_IF(p(152, s), BOOST_PP_WHILE_152, s BOOST_PP_TUPLE_EAT_3)(p, o, o(152, s)) # define BOOST_PP_WHILE_152_I(p, o, s) BOOST_PP_IF(p(153, s), BOOST_PP_WHILE_153, s BOOST_PP_TUPLE_EAT_3)(p, o, o(153, s)) # define BOOST_PP_WHILE_153_I(p, o, s) BOOST_PP_IF(p(154, s), BOOST_PP_WHILE_154, s BOOST_PP_TUPLE_EAT_3)(p, o, o(154, s)) # define BOOST_PP_WHILE_154_I(p, o, s) BOOST_PP_IF(p(155, s), BOOST_PP_WHILE_155, s BOOST_PP_TUPLE_EAT_3)(p, o, o(155, s)) # define BOOST_PP_WHILE_155_I(p, o, s) BOOST_PP_IF(p(156, s), BOOST_PP_WHILE_156, s BOOST_PP_TUPLE_EAT_3)(p, o, o(156, s)) # define BOOST_PP_WHILE_156_I(p, o, s) BOOST_PP_IF(p(157, s), BOOST_PP_WHILE_157, s BOOST_PP_TUPLE_EAT_3)(p, o, o(157, s)) # define BOOST_PP_WHILE_157_I(p, o, s) BOOST_PP_IF(p(158, s), BOOST_PP_WHILE_158, s BOOST_PP_TUPLE_EAT_3)(p, o, o(158, s)) # define BOOST_PP_WHILE_158_I(p, o, s) BOOST_PP_IF(p(159, s), BOOST_PP_WHILE_159, s BOOST_PP_TUPLE_EAT_3)(p, o, o(159, s)) # define BOOST_PP_WHILE_159_I(p, o, s) BOOST_PP_IF(p(160, s), BOOST_PP_WHILE_160, s BOOST_PP_TUPLE_EAT_3)(p, o, o(160, s)) # define BOOST_PP_WHILE_160_I(p, o, s) BOOST_PP_IF(p(161, s), BOOST_PP_WHILE_161, s BOOST_PP_TUPLE_EAT_3)(p, o, o(161, s)) # define BOOST_PP_WHILE_161_I(p, o, s) BOOST_PP_IF(p(162, s), BOOST_PP_WHILE_162, s BOOST_PP_TUPLE_EAT_3)(p, o, o(162, s)) # define BOOST_PP_WHILE_162_I(p, o, s) BOOST_PP_IF(p(163, s), BOOST_PP_WHILE_163, s BOOST_PP_TUPLE_EAT_3)(p, o, o(163, s)) # define BOOST_PP_WHILE_163_I(p, o, s) BOOST_PP_IF(p(164, s), BOOST_PP_WHILE_164, s BOOST_PP_TUPLE_EAT_3)(p, o, o(164, s)) # define BOOST_PP_WHILE_164_I(p, o, s) BOOST_PP_IF(p(165, s), BOOST_PP_WHILE_165, s BOOST_PP_TUPLE_EAT_3)(p, o, o(165, s)) # define BOOST_PP_WHILE_165_I(p, o, s) BOOST_PP_IF(p(166, s), BOOST_PP_WHILE_166, s BOOST_PP_TUPLE_EAT_3)(p, o, o(166, s)) # define BOOST_PP_WHILE_166_I(p, o, s) BOOST_PP_IF(p(167, s), BOOST_PP_WHILE_167, s BOOST_PP_TUPLE_EAT_3)(p, o, o(167, s)) # define BOOST_PP_WHILE_167_I(p, o, s) BOOST_PP_IF(p(168, s), BOOST_PP_WHILE_168, s BOOST_PP_TUPLE_EAT_3)(p, o, o(168, s)) # define BOOST_PP_WHILE_168_I(p, o, s) BOOST_PP_IF(p(169, s), BOOST_PP_WHILE_169, s BOOST_PP_TUPLE_EAT_3)(p, o, o(169, s)) # define BOOST_PP_WHILE_169_I(p, o, s) BOOST_PP_IF(p(170, s), BOOST_PP_WHILE_170, s BOOST_PP_TUPLE_EAT_3)(p, o, o(170, s)) # define BOOST_PP_WHILE_170_I(p, o, s) BOOST_PP_IF(p(171, s), BOOST_PP_WHILE_171, s BOOST_PP_TUPLE_EAT_3)(p, o, o(171, s)) # define BOOST_PP_WHILE_171_I(p, o, s) BOOST_PP_IF(p(172, s), BOOST_PP_WHILE_172, s BOOST_PP_TUPLE_EAT_3)(p, o, o(172, s)) # define BOOST_PP_WHILE_172_I(p, o, s) BOOST_PP_IF(p(173, s), BOOST_PP_WHILE_173, s BOOST_PP_TUPLE_EAT_3)(p, o, o(173, s)) # define BOOST_PP_WHILE_173_I(p, o, s) BOOST_PP_IF(p(174, s), BOOST_PP_WHILE_174, s BOOST_PP_TUPLE_EAT_3)(p, o, o(174, s)) # define BOOST_PP_WHILE_174_I(p, o, s) BOOST_PP_IF(p(175, s), BOOST_PP_WHILE_175, s BOOST_PP_TUPLE_EAT_3)(p, o, o(175, s)) # define BOOST_PP_WHILE_175_I(p, o, s) BOOST_PP_IF(p(176, s), BOOST_PP_WHILE_176, s BOOST_PP_TUPLE_EAT_3)(p, o, o(176, s)) # define BOOST_PP_WHILE_176_I(p, o, s) BOOST_PP_IF(p(177, s), BOOST_PP_WHILE_177, s BOOST_PP_TUPLE_EAT_3)(p, o, o(177, s)) # define BOOST_PP_WHILE_177_I(p, o, s) BOOST_PP_IF(p(178, s), BOOST_PP_WHILE_178, s BOOST_PP_TUPLE_EAT_3)(p, o, o(178, s)) # define BOOST_PP_WHILE_178_I(p, o, s) BOOST_PP_IF(p(179, s), BOOST_PP_WHILE_179, s BOOST_PP_TUPLE_EAT_3)(p, o, o(179, s)) # define BOOST_PP_WHILE_179_I(p, o, s) BOOST_PP_IF(p(180, s), BOOST_PP_WHILE_180, s BOOST_PP_TUPLE_EAT_3)(p, o, o(180, s)) # define BOOST_PP_WHILE_180_I(p, o, s) BOOST_PP_IF(p(181, s), BOOST_PP_WHILE_181, s BOOST_PP_TUPLE_EAT_3)(p, o, o(181, s)) # define BOOST_PP_WHILE_181_I(p, o, s) BOOST_PP_IF(p(182, s), BOOST_PP_WHILE_182, s BOOST_PP_TUPLE_EAT_3)(p, o, o(182, s)) # define BOOST_PP_WHILE_182_I(p, o, s) BOOST_PP_IF(p(183, s), BOOST_PP_WHILE_183, s BOOST_PP_TUPLE_EAT_3)(p, o, o(183, s)) # define BOOST_PP_WHILE_183_I(p, o, s) BOOST_PP_IF(p(184, s), BOOST_PP_WHILE_184, s BOOST_PP_TUPLE_EAT_3)(p, o, o(184, s)) # define BOOST_PP_WHILE_184_I(p, o, s) BOOST_PP_IF(p(185, s), BOOST_PP_WHILE_185, s BOOST_PP_TUPLE_EAT_3)(p, o, o(185, s)) # define BOOST_PP_WHILE_185_I(p, o, s) BOOST_PP_IF(p(186, s), BOOST_PP_WHILE_186, s BOOST_PP_TUPLE_EAT_3)(p, o, o(186, s)) # define BOOST_PP_WHILE_186_I(p, o, s) BOOST_PP_IF(p(187, s), BOOST_PP_WHILE_187, s BOOST_PP_TUPLE_EAT_3)(p, o, o(187, s)) # define BOOST_PP_WHILE_187_I(p, o, s) BOOST_PP_IF(p(188, s), BOOST_PP_WHILE_188, s BOOST_PP_TUPLE_EAT_3)(p, o, o(188, s)) # define BOOST_PP_WHILE_188_I(p, o, s) BOOST_PP_IF(p(189, s), BOOST_PP_WHILE_189, s BOOST_PP_TUPLE_EAT_3)(p, o, o(189, s)) # define BOOST_PP_WHILE_189_I(p, o, s) BOOST_PP_IF(p(190, s), BOOST_PP_WHILE_190, s BOOST_PP_TUPLE_EAT_3)(p, o, o(190, s)) # define BOOST_PP_WHILE_190_I(p, o, s) BOOST_PP_IF(p(191, s), BOOST_PP_WHILE_191, s BOOST_PP_TUPLE_EAT_3)(p, o, o(191, s)) # define BOOST_PP_WHILE_191_I(p, o, s) BOOST_PP_IF(p(192, s), BOOST_PP_WHILE_192, s BOOST_PP_TUPLE_EAT_3)(p, o, o(192, s)) # define BOOST_PP_WHILE_192_I(p, o, s) BOOST_PP_IF(p(193, s), BOOST_PP_WHILE_193, s BOOST_PP_TUPLE_EAT_3)(p, o, o(193, s)) # define BOOST_PP_WHILE_193_I(p, o, s) BOOST_PP_IF(p(194, s), BOOST_PP_WHILE_194, s BOOST_PP_TUPLE_EAT_3)(p, o, o(194, s)) # define BOOST_PP_WHILE_194_I(p, o, s) BOOST_PP_IF(p(195, s), BOOST_PP_WHILE_195, s BOOST_PP_TUPLE_EAT_3)(p, o, o(195, s)) # define BOOST_PP_WHILE_195_I(p, o, s) BOOST_PP_IF(p(196, s), BOOST_PP_WHILE_196, s BOOST_PP_TUPLE_EAT_3)(p, o, o(196, s)) # define BOOST_PP_WHILE_196_I(p, o, s) BOOST_PP_IF(p(197, s), BOOST_PP_WHILE_197, s BOOST_PP_TUPLE_EAT_3)(p, o, o(197, s)) # define BOOST_PP_WHILE_197_I(p, o, s) BOOST_PP_IF(p(198, s), BOOST_PP_WHILE_198, s BOOST_PP_TUPLE_EAT_3)(p, o, o(198, s)) # define BOOST_PP_WHILE_198_I(p, o, s) BOOST_PP_IF(p(199, s), BOOST_PP_WHILE_199, s BOOST_PP_TUPLE_EAT_3)(p, o, o(199, s)) # define BOOST_PP_WHILE_199_I(p, o, s) BOOST_PP_IF(p(200, s), BOOST_PP_WHILE_200, s BOOST_PP_TUPLE_EAT_3)(p, o, o(200, s)) # define BOOST_PP_WHILE_200_I(p, o, s) BOOST_PP_IF(p(201, s), BOOST_PP_WHILE_201, s BOOST_PP_TUPLE_EAT_3)(p, o, o(201, s)) # define BOOST_PP_WHILE_201_I(p, o, s) BOOST_PP_IF(p(202, s), BOOST_PP_WHILE_202, s BOOST_PP_TUPLE_EAT_3)(p, o, o(202, s)) # define BOOST_PP_WHILE_202_I(p, o, s) BOOST_PP_IF(p(203, s), BOOST_PP_WHILE_203, s BOOST_PP_TUPLE_EAT_3)(p, o, o(203, s)) # define BOOST_PP_WHILE_203_I(p, o, s) BOOST_PP_IF(p(204, s), BOOST_PP_WHILE_204, s BOOST_PP_TUPLE_EAT_3)(p, o, o(204, s)) # define BOOST_PP_WHILE_204_I(p, o, s) BOOST_PP_IF(p(205, s), BOOST_PP_WHILE_205, s BOOST_PP_TUPLE_EAT_3)(p, o, o(205, s)) # define BOOST_PP_WHILE_205_I(p, o, s) BOOST_PP_IF(p(206, s), BOOST_PP_WHILE_206, s BOOST_PP_TUPLE_EAT_3)(p, o, o(206, s)) # define BOOST_PP_WHILE_206_I(p, o, s) BOOST_PP_IF(p(207, s), BOOST_PP_WHILE_207, s BOOST_PP_TUPLE_EAT_3)(p, o, o(207, s)) # define BOOST_PP_WHILE_207_I(p, o, s) BOOST_PP_IF(p(208, s), BOOST_PP_WHILE_208, s BOOST_PP_TUPLE_EAT_3)(p, o, o(208, s)) # define BOOST_PP_WHILE_208_I(p, o, s) BOOST_PP_IF(p(209, s), BOOST_PP_WHILE_209, s BOOST_PP_TUPLE_EAT_3)(p, o, o(209, s)) # define BOOST_PP_WHILE_209_I(p, o, s) BOOST_PP_IF(p(210, s), BOOST_PP_WHILE_210, s BOOST_PP_TUPLE_EAT_3)(p, o, o(210, s)) # define BOOST_PP_WHILE_210_I(p, o, s) BOOST_PP_IF(p(211, s), BOOST_PP_WHILE_211, s BOOST_PP_TUPLE_EAT_3)(p, o, o(211, s)) # define BOOST_PP_WHILE_211_I(p, o, s) BOOST_PP_IF(p(212, s), BOOST_PP_WHILE_212, s BOOST_PP_TUPLE_EAT_3)(p, o, o(212, s)) # define BOOST_PP_WHILE_212_I(p, o, s) BOOST_PP_IF(p(213, s), BOOST_PP_WHILE_213, s BOOST_PP_TUPLE_EAT_3)(p, o, o(213, s)) # define BOOST_PP_WHILE_213_I(p, o, s) BOOST_PP_IF(p(214, s), BOOST_PP_WHILE_214, s BOOST_PP_TUPLE_EAT_3)(p, o, o(214, s)) # define BOOST_PP_WHILE_214_I(p, o, s) BOOST_PP_IF(p(215, s), BOOST_PP_WHILE_215, s BOOST_PP_TUPLE_EAT_3)(p, o, o(215, s)) # define BOOST_PP_WHILE_215_I(p, o, s) BOOST_PP_IF(p(216, s), BOOST_PP_WHILE_216, s BOOST_PP_TUPLE_EAT_3)(p, o, o(216, s)) # define BOOST_PP_WHILE_216_I(p, o, s) BOOST_PP_IF(p(217, s), BOOST_PP_WHILE_217, s BOOST_PP_TUPLE_EAT_3)(p, o, o(217, s)) # define BOOST_PP_WHILE_217_I(p, o, s) BOOST_PP_IF(p(218, s), BOOST_PP_WHILE_218, s BOOST_PP_TUPLE_EAT_3)(p, o, o(218, s)) # define BOOST_PP_WHILE_218_I(p, o, s) BOOST_PP_IF(p(219, s), BOOST_PP_WHILE_219, s BOOST_PP_TUPLE_EAT_3)(p, o, o(219, s)) # define BOOST_PP_WHILE_219_I(p, o, s) BOOST_PP_IF(p(220, s), BOOST_PP_WHILE_220, s BOOST_PP_TUPLE_EAT_3)(p, o, o(220, s)) # define BOOST_PP_WHILE_220_I(p, o, s) BOOST_PP_IF(p(221, s), BOOST_PP_WHILE_221, s BOOST_PP_TUPLE_EAT_3)(p, o, o(221, s)) # define BOOST_PP_WHILE_221_I(p, o, s) BOOST_PP_IF(p(222, s), BOOST_PP_WHILE_222, s BOOST_PP_TUPLE_EAT_3)(p, o, o(222, s)) # define BOOST_PP_WHILE_222_I(p, o, s) BOOST_PP_IF(p(223, s), BOOST_PP_WHILE_223, s BOOST_PP_TUPLE_EAT_3)(p, o, o(223, s)) # define BOOST_PP_WHILE_223_I(p, o, s) BOOST_PP_IF(p(224, s), BOOST_PP_WHILE_224, s BOOST_PP_TUPLE_EAT_3)(p, o, o(224, s)) # define BOOST_PP_WHILE_224_I(p, o, s) BOOST_PP_IF(p(225, s), BOOST_PP_WHILE_225, s BOOST_PP_TUPLE_EAT_3)(p, o, o(225, s)) # define BOOST_PP_WHILE_225_I(p, o, s) BOOST_PP_IF(p(226, s), BOOST_PP_WHILE_226, s BOOST_PP_TUPLE_EAT_3)(p, o, o(226, s)) # define BOOST_PP_WHILE_226_I(p, o, s) BOOST_PP_IF(p(227, s), BOOST_PP_WHILE_227, s BOOST_PP_TUPLE_EAT_3)(p, o, o(227, s)) # define BOOST_PP_WHILE_227_I(p, o, s) BOOST_PP_IF(p(228, s), BOOST_PP_WHILE_228, s BOOST_PP_TUPLE_EAT_3)(p, o, o(228, s)) # define BOOST_PP_WHILE_228_I(p, o, s) BOOST_PP_IF(p(229, s), BOOST_PP_WHILE_229, s BOOST_PP_TUPLE_EAT_3)(p, o, o(229, s)) # define BOOST_PP_WHILE_229_I(p, o, s) BOOST_PP_IF(p(230, s), BOOST_PP_WHILE_230, s BOOST_PP_TUPLE_EAT_3)(p, o, o(230, s)) # define BOOST_PP_WHILE_230_I(p, o, s) BOOST_PP_IF(p(231, s), BOOST_PP_WHILE_231, s BOOST_PP_TUPLE_EAT_3)(p, o, o(231, s)) # define BOOST_PP_WHILE_231_I(p, o, s) BOOST_PP_IF(p(232, s), BOOST_PP_WHILE_232, s BOOST_PP_TUPLE_EAT_3)(p, o, o(232, s)) # define BOOST_PP_WHILE_232_I(p, o, s) BOOST_PP_IF(p(233, s), BOOST_PP_WHILE_233, s BOOST_PP_TUPLE_EAT_3)(p, o, o(233, s)) # define BOOST_PP_WHILE_233_I(p, o, s) BOOST_PP_IF(p(234, s), BOOST_PP_WHILE_234, s BOOST_PP_TUPLE_EAT_3)(p, o, o(234, s)) # define BOOST_PP_WHILE_234_I(p, o, s) BOOST_PP_IF(p(235, s), BOOST_PP_WHILE_235, s BOOST_PP_TUPLE_EAT_3)(p, o, o(235, s)) # define BOOST_PP_WHILE_235_I(p, o, s) BOOST_PP_IF(p(236, s), BOOST_PP_WHILE_236, s BOOST_PP_TUPLE_EAT_3)(p, o, o(236, s)) # define BOOST_PP_WHILE_236_I(p, o, s) BOOST_PP_IF(p(237, s), BOOST_PP_WHILE_237, s BOOST_PP_TUPLE_EAT_3)(p, o, o(237, s)) # define BOOST_PP_WHILE_237_I(p, o, s) BOOST_PP_IF(p(238, s), BOOST_PP_WHILE_238, s BOOST_PP_TUPLE_EAT_3)(p, o, o(238, s)) # define BOOST_PP_WHILE_238_I(p, o, s) BOOST_PP_IF(p(239, s), BOOST_PP_WHILE_239, s BOOST_PP_TUPLE_EAT_3)(p, o, o(239, s)) # define BOOST_PP_WHILE_239_I(p, o, s) BOOST_PP_IF(p(240, s), BOOST_PP_WHILE_240, s BOOST_PP_TUPLE_EAT_3)(p, o, o(240, s)) # define BOOST_PP_WHILE_240_I(p, o, s) BOOST_PP_IF(p(241, s), BOOST_PP_WHILE_241, s BOOST_PP_TUPLE_EAT_3)(p, o, o(241, s)) # define BOOST_PP_WHILE_241_I(p, o, s) BOOST_PP_IF(p(242, s), BOOST_PP_WHILE_242, s BOOST_PP_TUPLE_EAT_3)(p, o, o(242, s)) # define BOOST_PP_WHILE_242_I(p, o, s) BOOST_PP_IF(p(243, s), BOOST_PP_WHILE_243, s BOOST_PP_TUPLE_EAT_3)(p, o, o(243, s)) # define BOOST_PP_WHILE_243_I(p, o, s) BOOST_PP_IF(p(244, s), BOOST_PP_WHILE_244, s BOOST_PP_TUPLE_EAT_3)(p, o, o(244, s)) # define BOOST_PP_WHILE_244_I(p, o, s) BOOST_PP_IF(p(245, s), BOOST_PP_WHILE_245, s BOOST_PP_TUPLE_EAT_3)(p, o, o(245, s)) # define BOOST_PP_WHILE_245_I(p, o, s) BOOST_PP_IF(p(246, s), BOOST_PP_WHILE_246, s BOOST_PP_TUPLE_EAT_3)(p, o, o(246, s)) # define BOOST_PP_WHILE_246_I(p, o, s) BOOST_PP_IF(p(247, s), BOOST_PP_WHILE_247, s BOOST_PP_TUPLE_EAT_3)(p, o, o(247, s)) # define BOOST_PP_WHILE_247_I(p, o, s) BOOST_PP_IF(p(248, s), BOOST_PP_WHILE_248, s BOOST_PP_TUPLE_EAT_3)(p, o, o(248, s)) # define BOOST_PP_WHILE_248_I(p, o, s) BOOST_PP_IF(p(249, s), BOOST_PP_WHILE_249, s BOOST_PP_TUPLE_EAT_3)(p, o, o(249, s)) # define BOOST_PP_WHILE_249_I(p, o, s) BOOST_PP_IF(p(250, s), BOOST_PP_WHILE_250, s BOOST_PP_TUPLE_EAT_3)(p, o, o(250, s)) # define BOOST_PP_WHILE_250_I(p, o, s) BOOST_PP_IF(p(251, s), BOOST_PP_WHILE_251, s BOOST_PP_TUPLE_EAT_3)(p, o, o(251, s)) # define BOOST_PP_WHILE_251_I(p, o, s) BOOST_PP_IF(p(252, s), BOOST_PP_WHILE_252, s BOOST_PP_TUPLE_EAT_3)(p, o, o(252, s)) # define BOOST_PP_WHILE_252_I(p, o, s) BOOST_PP_IF(p(253, s), BOOST_PP_WHILE_253, s BOOST_PP_TUPLE_EAT_3)(p, o, o(253, s)) # define BOOST_PP_WHILE_253_I(p, o, s) BOOST_PP_IF(p(254, s), BOOST_PP_WHILE_254, s BOOST_PP_TUPLE_EAT_3)(p, o, o(254, s)) # define BOOST_PP_WHILE_254_I(p, o, s) BOOST_PP_IF(p(255, s), BOOST_PP_WHILE_255, s BOOST_PP_TUPLE_EAT_3)(p, o, o(255, s)) # define BOOST_PP_WHILE_255_I(p, o, s) BOOST_PP_IF(p(256, s), BOOST_PP_WHILE_256, s BOOST_PP_TUPLE_EAT_3)(p, o, o(256, s)) # define BOOST_PP_WHILE_256_I(p, o, s) BOOST_PP_IF(p(257, s), BOOST_PP_WHILE_257, s BOOST_PP_TUPLE_EAT_3)(p, o, o(257, s)) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/detail/msvc/while.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_DETAIL_MSVC_WHILE_HPP # define BOOST_PREPROCESSOR_CONTROL_DETAIL_MSVC_WHILE_HPP # # include # include # # define BOOST_PP_WHILE_1(p, o, s) BOOST_PP_IF(p(2, s), BOOST_PP_WHILE_2, s BOOST_PP_TUPLE_EAT_3)(p, o, o(2, s)) # define BOOST_PP_WHILE_2(p, o, s) BOOST_PP_IF(p(3, s), BOOST_PP_WHILE_3, s BOOST_PP_TUPLE_EAT_3)(p, o, o(3, s)) # define BOOST_PP_WHILE_3(p, o, s) BOOST_PP_IF(p(4, s), BOOST_PP_WHILE_4, s BOOST_PP_TUPLE_EAT_3)(p, o, o(4, s)) # define BOOST_PP_WHILE_4(p, o, s) BOOST_PP_IF(p(5, s), BOOST_PP_WHILE_5, s BOOST_PP_TUPLE_EAT_3)(p, o, o(5, s)) # define BOOST_PP_WHILE_5(p, o, s) BOOST_PP_IF(p(6, s), BOOST_PP_WHILE_6, s BOOST_PP_TUPLE_EAT_3)(p, o, o(6, s)) # define BOOST_PP_WHILE_6(p, o, s) BOOST_PP_IF(p(7, s), BOOST_PP_WHILE_7, s BOOST_PP_TUPLE_EAT_3)(p, o, o(7, s)) # define BOOST_PP_WHILE_7(p, o, s) BOOST_PP_IF(p(8, s), BOOST_PP_WHILE_8, s BOOST_PP_TUPLE_EAT_3)(p, o, o(8, s)) # define BOOST_PP_WHILE_8(p, o, s) BOOST_PP_IF(p(9, s), BOOST_PP_WHILE_9, s BOOST_PP_TUPLE_EAT_3)(p, o, o(9, s)) # define BOOST_PP_WHILE_9(p, o, s) BOOST_PP_IF(p(10, s), BOOST_PP_WHILE_10, s BOOST_PP_TUPLE_EAT_3)(p, o, o(10, s)) # define BOOST_PP_WHILE_10(p, o, s) BOOST_PP_IF(p(11, s), BOOST_PP_WHILE_11, s BOOST_PP_TUPLE_EAT_3)(p, o, o(11, s)) # define BOOST_PP_WHILE_11(p, o, s) BOOST_PP_IF(p(12, s), BOOST_PP_WHILE_12, s BOOST_PP_TUPLE_EAT_3)(p, o, o(12, s)) # define BOOST_PP_WHILE_12(p, o, s) BOOST_PP_IF(p(13, s), BOOST_PP_WHILE_13, s BOOST_PP_TUPLE_EAT_3)(p, o, o(13, s)) # define BOOST_PP_WHILE_13(p, o, s) BOOST_PP_IF(p(14, s), BOOST_PP_WHILE_14, s BOOST_PP_TUPLE_EAT_3)(p, o, o(14, s)) # define BOOST_PP_WHILE_14(p, o, s) BOOST_PP_IF(p(15, s), BOOST_PP_WHILE_15, s BOOST_PP_TUPLE_EAT_3)(p, o, o(15, s)) # define BOOST_PP_WHILE_15(p, o, s) BOOST_PP_IF(p(16, s), BOOST_PP_WHILE_16, s BOOST_PP_TUPLE_EAT_3)(p, o, o(16, s)) # define BOOST_PP_WHILE_16(p, o, s) BOOST_PP_IF(p(17, s), BOOST_PP_WHILE_17, s BOOST_PP_TUPLE_EAT_3)(p, o, o(17, s)) # define BOOST_PP_WHILE_17(p, o, s) BOOST_PP_IF(p(18, s), BOOST_PP_WHILE_18, s BOOST_PP_TUPLE_EAT_3)(p, o, o(18, s)) # define BOOST_PP_WHILE_18(p, o, s) BOOST_PP_IF(p(19, s), BOOST_PP_WHILE_19, s BOOST_PP_TUPLE_EAT_3)(p, o, o(19, s)) # define BOOST_PP_WHILE_19(p, o, s) BOOST_PP_IF(p(20, s), BOOST_PP_WHILE_20, s BOOST_PP_TUPLE_EAT_3)(p, o, o(20, s)) # define BOOST_PP_WHILE_20(p, o, s) BOOST_PP_IF(p(21, s), BOOST_PP_WHILE_21, s BOOST_PP_TUPLE_EAT_3)(p, o, o(21, s)) # define BOOST_PP_WHILE_21(p, o, s) BOOST_PP_IF(p(22, s), BOOST_PP_WHILE_22, s BOOST_PP_TUPLE_EAT_3)(p, o, o(22, s)) # define BOOST_PP_WHILE_22(p, o, s) BOOST_PP_IF(p(23, s), BOOST_PP_WHILE_23, s BOOST_PP_TUPLE_EAT_3)(p, o, o(23, s)) # define BOOST_PP_WHILE_23(p, o, s) BOOST_PP_IF(p(24, s), BOOST_PP_WHILE_24, s BOOST_PP_TUPLE_EAT_3)(p, o, o(24, s)) # define BOOST_PP_WHILE_24(p, o, s) BOOST_PP_IF(p(25, s), BOOST_PP_WHILE_25, s BOOST_PP_TUPLE_EAT_3)(p, o, o(25, s)) # define BOOST_PP_WHILE_25(p, o, s) BOOST_PP_IF(p(26, s), BOOST_PP_WHILE_26, s BOOST_PP_TUPLE_EAT_3)(p, o, o(26, s)) # define BOOST_PP_WHILE_26(p, o, s) BOOST_PP_IF(p(27, s), BOOST_PP_WHILE_27, s BOOST_PP_TUPLE_EAT_3)(p, o, o(27, s)) # define BOOST_PP_WHILE_27(p, o, s) BOOST_PP_IF(p(28, s), BOOST_PP_WHILE_28, s BOOST_PP_TUPLE_EAT_3)(p, o, o(28, s)) # define BOOST_PP_WHILE_28(p, o, s) BOOST_PP_IF(p(29, s), BOOST_PP_WHILE_29, s BOOST_PP_TUPLE_EAT_3)(p, o, o(29, s)) # define BOOST_PP_WHILE_29(p, o, s) BOOST_PP_IF(p(30, s), BOOST_PP_WHILE_30, s BOOST_PP_TUPLE_EAT_3)(p, o, o(30, s)) # define BOOST_PP_WHILE_30(p, o, s) BOOST_PP_IF(p(31, s), BOOST_PP_WHILE_31, s BOOST_PP_TUPLE_EAT_3)(p, o, o(31, s)) # define BOOST_PP_WHILE_31(p, o, s) BOOST_PP_IF(p(32, s), BOOST_PP_WHILE_32, s BOOST_PP_TUPLE_EAT_3)(p, o, o(32, s)) # define BOOST_PP_WHILE_32(p, o, s) BOOST_PP_IF(p(33, s), BOOST_PP_WHILE_33, s BOOST_PP_TUPLE_EAT_3)(p, o, o(33, s)) # define BOOST_PP_WHILE_33(p, o, s) BOOST_PP_IF(p(34, s), BOOST_PP_WHILE_34, s BOOST_PP_TUPLE_EAT_3)(p, o, o(34, s)) # define BOOST_PP_WHILE_34(p, o, s) BOOST_PP_IF(p(35, s), BOOST_PP_WHILE_35, s BOOST_PP_TUPLE_EAT_3)(p, o, o(35, s)) # define BOOST_PP_WHILE_35(p, o, s) BOOST_PP_IF(p(36, s), BOOST_PP_WHILE_36, s BOOST_PP_TUPLE_EAT_3)(p, o, o(36, s)) # define BOOST_PP_WHILE_36(p, o, s) BOOST_PP_IF(p(37, s), BOOST_PP_WHILE_37, s BOOST_PP_TUPLE_EAT_3)(p, o, o(37, s)) # define BOOST_PP_WHILE_37(p, o, s) BOOST_PP_IF(p(38, s), BOOST_PP_WHILE_38, s BOOST_PP_TUPLE_EAT_3)(p, o, o(38, s)) # define BOOST_PP_WHILE_38(p, o, s) BOOST_PP_IF(p(39, s), BOOST_PP_WHILE_39, s BOOST_PP_TUPLE_EAT_3)(p, o, o(39, s)) # define BOOST_PP_WHILE_39(p, o, s) BOOST_PP_IF(p(40, s), BOOST_PP_WHILE_40, s BOOST_PP_TUPLE_EAT_3)(p, o, o(40, s)) # define BOOST_PP_WHILE_40(p, o, s) BOOST_PP_IF(p(41, s), BOOST_PP_WHILE_41, s BOOST_PP_TUPLE_EAT_3)(p, o, o(41, s)) # define BOOST_PP_WHILE_41(p, o, s) BOOST_PP_IF(p(42, s), BOOST_PP_WHILE_42, s BOOST_PP_TUPLE_EAT_3)(p, o, o(42, s)) # define BOOST_PP_WHILE_42(p, o, s) BOOST_PP_IF(p(43, s), BOOST_PP_WHILE_43, s BOOST_PP_TUPLE_EAT_3)(p, o, o(43, s)) # define BOOST_PP_WHILE_43(p, o, s) BOOST_PP_IF(p(44, s), BOOST_PP_WHILE_44, s BOOST_PP_TUPLE_EAT_3)(p, o, o(44, s)) # define BOOST_PP_WHILE_44(p, o, s) BOOST_PP_IF(p(45, s), BOOST_PP_WHILE_45, s BOOST_PP_TUPLE_EAT_3)(p, o, o(45, s)) # define BOOST_PP_WHILE_45(p, o, s) BOOST_PP_IF(p(46, s), BOOST_PP_WHILE_46, s BOOST_PP_TUPLE_EAT_3)(p, o, o(46, s)) # define BOOST_PP_WHILE_46(p, o, s) BOOST_PP_IF(p(47, s), BOOST_PP_WHILE_47, s BOOST_PP_TUPLE_EAT_3)(p, o, o(47, s)) # define BOOST_PP_WHILE_47(p, o, s) BOOST_PP_IF(p(48, s), BOOST_PP_WHILE_48, s BOOST_PP_TUPLE_EAT_3)(p, o, o(48, s)) # define BOOST_PP_WHILE_48(p, o, s) BOOST_PP_IF(p(49, s), BOOST_PP_WHILE_49, s BOOST_PP_TUPLE_EAT_3)(p, o, o(49, s)) # define BOOST_PP_WHILE_49(p, o, s) BOOST_PP_IF(p(50, s), BOOST_PP_WHILE_50, s BOOST_PP_TUPLE_EAT_3)(p, o, o(50, s)) # define BOOST_PP_WHILE_50(p, o, s) BOOST_PP_IF(p(51, s), BOOST_PP_WHILE_51, s BOOST_PP_TUPLE_EAT_3)(p, o, o(51, s)) # define BOOST_PP_WHILE_51(p, o, s) BOOST_PP_IF(p(52, s), BOOST_PP_WHILE_52, s BOOST_PP_TUPLE_EAT_3)(p, o, o(52, s)) # define BOOST_PP_WHILE_52(p, o, s) BOOST_PP_IF(p(53, s), BOOST_PP_WHILE_53, s BOOST_PP_TUPLE_EAT_3)(p, o, o(53, s)) # define BOOST_PP_WHILE_53(p, o, s) BOOST_PP_IF(p(54, s), BOOST_PP_WHILE_54, s BOOST_PP_TUPLE_EAT_3)(p, o, o(54, s)) # define BOOST_PP_WHILE_54(p, o, s) BOOST_PP_IF(p(55, s), BOOST_PP_WHILE_55, s BOOST_PP_TUPLE_EAT_3)(p, o, o(55, s)) # define BOOST_PP_WHILE_55(p, o, s) BOOST_PP_IF(p(56, s), BOOST_PP_WHILE_56, s BOOST_PP_TUPLE_EAT_3)(p, o, o(56, s)) # define BOOST_PP_WHILE_56(p, o, s) BOOST_PP_IF(p(57, s), BOOST_PP_WHILE_57, s BOOST_PP_TUPLE_EAT_3)(p, o, o(57, s)) # define BOOST_PP_WHILE_57(p, o, s) BOOST_PP_IF(p(58, s), BOOST_PP_WHILE_58, s BOOST_PP_TUPLE_EAT_3)(p, o, o(58, s)) # define BOOST_PP_WHILE_58(p, o, s) BOOST_PP_IF(p(59, s), BOOST_PP_WHILE_59, s BOOST_PP_TUPLE_EAT_3)(p, o, o(59, s)) # define BOOST_PP_WHILE_59(p, o, s) BOOST_PP_IF(p(60, s), BOOST_PP_WHILE_60, s BOOST_PP_TUPLE_EAT_3)(p, o, o(60, s)) # define BOOST_PP_WHILE_60(p, o, s) BOOST_PP_IF(p(61, s), BOOST_PP_WHILE_61, s BOOST_PP_TUPLE_EAT_3)(p, o, o(61, s)) # define BOOST_PP_WHILE_61(p, o, s) BOOST_PP_IF(p(62, s), BOOST_PP_WHILE_62, s BOOST_PP_TUPLE_EAT_3)(p, o, o(62, s)) # define BOOST_PP_WHILE_62(p, o, s) BOOST_PP_IF(p(63, s), BOOST_PP_WHILE_63, s BOOST_PP_TUPLE_EAT_3)(p, o, o(63, s)) # define BOOST_PP_WHILE_63(p, o, s) BOOST_PP_IF(p(64, s), BOOST_PP_WHILE_64, s BOOST_PP_TUPLE_EAT_3)(p, o, o(64, s)) # define BOOST_PP_WHILE_64(p, o, s) BOOST_PP_IF(p(65, s), BOOST_PP_WHILE_65, s BOOST_PP_TUPLE_EAT_3)(p, o, o(65, s)) # define BOOST_PP_WHILE_65(p, o, s) BOOST_PP_IF(p(66, s), BOOST_PP_WHILE_66, s BOOST_PP_TUPLE_EAT_3)(p, o, o(66, s)) # define BOOST_PP_WHILE_66(p, o, s) BOOST_PP_IF(p(67, s), BOOST_PP_WHILE_67, s BOOST_PP_TUPLE_EAT_3)(p, o, o(67, s)) # define BOOST_PP_WHILE_67(p, o, s) BOOST_PP_IF(p(68, s), BOOST_PP_WHILE_68, s BOOST_PP_TUPLE_EAT_3)(p, o, o(68, s)) # define BOOST_PP_WHILE_68(p, o, s) BOOST_PP_IF(p(69, s), BOOST_PP_WHILE_69, s BOOST_PP_TUPLE_EAT_3)(p, o, o(69, s)) # define BOOST_PP_WHILE_69(p, o, s) BOOST_PP_IF(p(70, s), BOOST_PP_WHILE_70, s BOOST_PP_TUPLE_EAT_3)(p, o, o(70, s)) # define BOOST_PP_WHILE_70(p, o, s) BOOST_PP_IF(p(71, s), BOOST_PP_WHILE_71, s BOOST_PP_TUPLE_EAT_3)(p, o, o(71, s)) # define BOOST_PP_WHILE_71(p, o, s) BOOST_PP_IF(p(72, s), BOOST_PP_WHILE_72, s BOOST_PP_TUPLE_EAT_3)(p, o, o(72, s)) # define BOOST_PP_WHILE_72(p, o, s) BOOST_PP_IF(p(73, s), BOOST_PP_WHILE_73, s BOOST_PP_TUPLE_EAT_3)(p, o, o(73, s)) # define BOOST_PP_WHILE_73(p, o, s) BOOST_PP_IF(p(74, s), BOOST_PP_WHILE_74, s BOOST_PP_TUPLE_EAT_3)(p, o, o(74, s)) # define BOOST_PP_WHILE_74(p, o, s) BOOST_PP_IF(p(75, s), BOOST_PP_WHILE_75, s BOOST_PP_TUPLE_EAT_3)(p, o, o(75, s)) # define BOOST_PP_WHILE_75(p, o, s) BOOST_PP_IF(p(76, s), BOOST_PP_WHILE_76, s BOOST_PP_TUPLE_EAT_3)(p, o, o(76, s)) # define BOOST_PP_WHILE_76(p, o, s) BOOST_PP_IF(p(77, s), BOOST_PP_WHILE_77, s BOOST_PP_TUPLE_EAT_3)(p, o, o(77, s)) # define BOOST_PP_WHILE_77(p, o, s) BOOST_PP_IF(p(78, s), BOOST_PP_WHILE_78, s BOOST_PP_TUPLE_EAT_3)(p, o, o(78, s)) # define BOOST_PP_WHILE_78(p, o, s) BOOST_PP_IF(p(79, s), BOOST_PP_WHILE_79, s BOOST_PP_TUPLE_EAT_3)(p, o, o(79, s)) # define BOOST_PP_WHILE_79(p, o, s) BOOST_PP_IF(p(80, s), BOOST_PP_WHILE_80, s BOOST_PP_TUPLE_EAT_3)(p, o, o(80, s)) # define BOOST_PP_WHILE_80(p, o, s) BOOST_PP_IF(p(81, s), BOOST_PP_WHILE_81, s BOOST_PP_TUPLE_EAT_3)(p, o, o(81, s)) # define BOOST_PP_WHILE_81(p, o, s) BOOST_PP_IF(p(82, s), BOOST_PP_WHILE_82, s BOOST_PP_TUPLE_EAT_3)(p, o, o(82, s)) # define BOOST_PP_WHILE_82(p, o, s) BOOST_PP_IF(p(83, s), BOOST_PP_WHILE_83, s BOOST_PP_TUPLE_EAT_3)(p, o, o(83, s)) # define BOOST_PP_WHILE_83(p, o, s) BOOST_PP_IF(p(84, s), BOOST_PP_WHILE_84, s BOOST_PP_TUPLE_EAT_3)(p, o, o(84, s)) # define BOOST_PP_WHILE_84(p, o, s) BOOST_PP_IF(p(85, s), BOOST_PP_WHILE_85, s BOOST_PP_TUPLE_EAT_3)(p, o, o(85, s)) # define BOOST_PP_WHILE_85(p, o, s) BOOST_PP_IF(p(86, s), BOOST_PP_WHILE_86, s BOOST_PP_TUPLE_EAT_3)(p, o, o(86, s)) # define BOOST_PP_WHILE_86(p, o, s) BOOST_PP_IF(p(87, s), BOOST_PP_WHILE_87, s BOOST_PP_TUPLE_EAT_3)(p, o, o(87, s)) # define BOOST_PP_WHILE_87(p, o, s) BOOST_PP_IF(p(88, s), BOOST_PP_WHILE_88, s BOOST_PP_TUPLE_EAT_3)(p, o, o(88, s)) # define BOOST_PP_WHILE_88(p, o, s) BOOST_PP_IF(p(89, s), BOOST_PP_WHILE_89, s BOOST_PP_TUPLE_EAT_3)(p, o, o(89, s)) # define BOOST_PP_WHILE_89(p, o, s) BOOST_PP_IF(p(90, s), BOOST_PP_WHILE_90, s BOOST_PP_TUPLE_EAT_3)(p, o, o(90, s)) # define BOOST_PP_WHILE_90(p, o, s) BOOST_PP_IF(p(91, s), BOOST_PP_WHILE_91, s BOOST_PP_TUPLE_EAT_3)(p, o, o(91, s)) # define BOOST_PP_WHILE_91(p, o, s) BOOST_PP_IF(p(92, s), BOOST_PP_WHILE_92, s BOOST_PP_TUPLE_EAT_3)(p, o, o(92, s)) # define BOOST_PP_WHILE_92(p, o, s) BOOST_PP_IF(p(93, s), BOOST_PP_WHILE_93, s BOOST_PP_TUPLE_EAT_3)(p, o, o(93, s)) # define BOOST_PP_WHILE_93(p, o, s) BOOST_PP_IF(p(94, s), BOOST_PP_WHILE_94, s BOOST_PP_TUPLE_EAT_3)(p, o, o(94, s)) # define BOOST_PP_WHILE_94(p, o, s) BOOST_PP_IF(p(95, s), BOOST_PP_WHILE_95, s BOOST_PP_TUPLE_EAT_3)(p, o, o(95, s)) # define BOOST_PP_WHILE_95(p, o, s) BOOST_PP_IF(p(96, s), BOOST_PP_WHILE_96, s BOOST_PP_TUPLE_EAT_3)(p, o, o(96, s)) # define BOOST_PP_WHILE_96(p, o, s) BOOST_PP_IF(p(97, s), BOOST_PP_WHILE_97, s BOOST_PP_TUPLE_EAT_3)(p, o, o(97, s)) # define BOOST_PP_WHILE_97(p, o, s) BOOST_PP_IF(p(98, s), BOOST_PP_WHILE_98, s BOOST_PP_TUPLE_EAT_3)(p, o, o(98, s)) # define BOOST_PP_WHILE_98(p, o, s) BOOST_PP_IF(p(99, s), BOOST_PP_WHILE_99, s BOOST_PP_TUPLE_EAT_3)(p, o, o(99, s)) # define BOOST_PP_WHILE_99(p, o, s) BOOST_PP_IF(p(100, s), BOOST_PP_WHILE_100, s BOOST_PP_TUPLE_EAT_3)(p, o, o(100, s)) # define BOOST_PP_WHILE_100(p, o, s) BOOST_PP_IF(p(101, s), BOOST_PP_WHILE_101, s BOOST_PP_TUPLE_EAT_3)(p, o, o(101, s)) # define BOOST_PP_WHILE_101(p, o, s) BOOST_PP_IF(p(102, s), BOOST_PP_WHILE_102, s BOOST_PP_TUPLE_EAT_3)(p, o, o(102, s)) # define BOOST_PP_WHILE_102(p, o, s) BOOST_PP_IF(p(103, s), BOOST_PP_WHILE_103, s BOOST_PP_TUPLE_EAT_3)(p, o, o(103, s)) # define BOOST_PP_WHILE_103(p, o, s) BOOST_PP_IF(p(104, s), BOOST_PP_WHILE_104, s BOOST_PP_TUPLE_EAT_3)(p, o, o(104, s)) # define BOOST_PP_WHILE_104(p, o, s) BOOST_PP_IF(p(105, s), BOOST_PP_WHILE_105, s BOOST_PP_TUPLE_EAT_3)(p, o, o(105, s)) # define BOOST_PP_WHILE_105(p, o, s) BOOST_PP_IF(p(106, s), BOOST_PP_WHILE_106, s BOOST_PP_TUPLE_EAT_3)(p, o, o(106, s)) # define BOOST_PP_WHILE_106(p, o, s) BOOST_PP_IF(p(107, s), BOOST_PP_WHILE_107, s BOOST_PP_TUPLE_EAT_3)(p, o, o(107, s)) # define BOOST_PP_WHILE_107(p, o, s) BOOST_PP_IF(p(108, s), BOOST_PP_WHILE_108, s BOOST_PP_TUPLE_EAT_3)(p, o, o(108, s)) # define BOOST_PP_WHILE_108(p, o, s) BOOST_PP_IF(p(109, s), BOOST_PP_WHILE_109, s BOOST_PP_TUPLE_EAT_3)(p, o, o(109, s)) # define BOOST_PP_WHILE_109(p, o, s) BOOST_PP_IF(p(110, s), BOOST_PP_WHILE_110, s BOOST_PP_TUPLE_EAT_3)(p, o, o(110, s)) # define BOOST_PP_WHILE_110(p, o, s) BOOST_PP_IF(p(111, s), BOOST_PP_WHILE_111, s BOOST_PP_TUPLE_EAT_3)(p, o, o(111, s)) # define BOOST_PP_WHILE_111(p, o, s) BOOST_PP_IF(p(112, s), BOOST_PP_WHILE_112, s BOOST_PP_TUPLE_EAT_3)(p, o, o(112, s)) # define BOOST_PP_WHILE_112(p, o, s) BOOST_PP_IF(p(113, s), BOOST_PP_WHILE_113, s BOOST_PP_TUPLE_EAT_3)(p, o, o(113, s)) # define BOOST_PP_WHILE_113(p, o, s) BOOST_PP_IF(p(114, s), BOOST_PP_WHILE_114, s BOOST_PP_TUPLE_EAT_3)(p, o, o(114, s)) # define BOOST_PP_WHILE_114(p, o, s) BOOST_PP_IF(p(115, s), BOOST_PP_WHILE_115, s BOOST_PP_TUPLE_EAT_3)(p, o, o(115, s)) # define BOOST_PP_WHILE_115(p, o, s) BOOST_PP_IF(p(116, s), BOOST_PP_WHILE_116, s BOOST_PP_TUPLE_EAT_3)(p, o, o(116, s)) # define BOOST_PP_WHILE_116(p, o, s) BOOST_PP_IF(p(117, s), BOOST_PP_WHILE_117, s BOOST_PP_TUPLE_EAT_3)(p, o, o(117, s)) # define BOOST_PP_WHILE_117(p, o, s) BOOST_PP_IF(p(118, s), BOOST_PP_WHILE_118, s BOOST_PP_TUPLE_EAT_3)(p, o, o(118, s)) # define BOOST_PP_WHILE_118(p, o, s) BOOST_PP_IF(p(119, s), BOOST_PP_WHILE_119, s BOOST_PP_TUPLE_EAT_3)(p, o, o(119, s)) # define BOOST_PP_WHILE_119(p, o, s) BOOST_PP_IF(p(120, s), BOOST_PP_WHILE_120, s BOOST_PP_TUPLE_EAT_3)(p, o, o(120, s)) # define BOOST_PP_WHILE_120(p, o, s) BOOST_PP_IF(p(121, s), BOOST_PP_WHILE_121, s BOOST_PP_TUPLE_EAT_3)(p, o, o(121, s)) # define BOOST_PP_WHILE_121(p, o, s) BOOST_PP_IF(p(122, s), BOOST_PP_WHILE_122, s BOOST_PP_TUPLE_EAT_3)(p, o, o(122, s)) # define BOOST_PP_WHILE_122(p, o, s) BOOST_PP_IF(p(123, s), BOOST_PP_WHILE_123, s BOOST_PP_TUPLE_EAT_3)(p, o, o(123, s)) # define BOOST_PP_WHILE_123(p, o, s) BOOST_PP_IF(p(124, s), BOOST_PP_WHILE_124, s BOOST_PP_TUPLE_EAT_3)(p, o, o(124, s)) # define BOOST_PP_WHILE_124(p, o, s) BOOST_PP_IF(p(125, s), BOOST_PP_WHILE_125, s BOOST_PP_TUPLE_EAT_3)(p, o, o(125, s)) # define BOOST_PP_WHILE_125(p, o, s) BOOST_PP_IF(p(126, s), BOOST_PP_WHILE_126, s BOOST_PP_TUPLE_EAT_3)(p, o, o(126, s)) # define BOOST_PP_WHILE_126(p, o, s) BOOST_PP_IF(p(127, s), BOOST_PP_WHILE_127, s BOOST_PP_TUPLE_EAT_3)(p, o, o(127, s)) # define BOOST_PP_WHILE_127(p, o, s) BOOST_PP_IF(p(128, s), BOOST_PP_WHILE_128, s BOOST_PP_TUPLE_EAT_3)(p, o, o(128, s)) # define BOOST_PP_WHILE_128(p, o, s) BOOST_PP_IF(p(129, s), BOOST_PP_WHILE_129, s BOOST_PP_TUPLE_EAT_3)(p, o, o(129, s)) # define BOOST_PP_WHILE_129(p, o, s) BOOST_PP_IF(p(130, s), BOOST_PP_WHILE_130, s BOOST_PP_TUPLE_EAT_3)(p, o, o(130, s)) # define BOOST_PP_WHILE_130(p, o, s) BOOST_PP_IF(p(131, s), BOOST_PP_WHILE_131, s BOOST_PP_TUPLE_EAT_3)(p, o, o(131, s)) # define BOOST_PP_WHILE_131(p, o, s) BOOST_PP_IF(p(132, s), BOOST_PP_WHILE_132, s BOOST_PP_TUPLE_EAT_3)(p, o, o(132, s)) # define BOOST_PP_WHILE_132(p, o, s) BOOST_PP_IF(p(133, s), BOOST_PP_WHILE_133, s BOOST_PP_TUPLE_EAT_3)(p, o, o(133, s)) # define BOOST_PP_WHILE_133(p, o, s) BOOST_PP_IF(p(134, s), BOOST_PP_WHILE_134, s BOOST_PP_TUPLE_EAT_3)(p, o, o(134, s)) # define BOOST_PP_WHILE_134(p, o, s) BOOST_PP_IF(p(135, s), BOOST_PP_WHILE_135, s BOOST_PP_TUPLE_EAT_3)(p, o, o(135, s)) # define BOOST_PP_WHILE_135(p, o, s) BOOST_PP_IF(p(136, s), BOOST_PP_WHILE_136, s BOOST_PP_TUPLE_EAT_3)(p, o, o(136, s)) # define BOOST_PP_WHILE_136(p, o, s) BOOST_PP_IF(p(137, s), BOOST_PP_WHILE_137, s BOOST_PP_TUPLE_EAT_3)(p, o, o(137, s)) # define BOOST_PP_WHILE_137(p, o, s) BOOST_PP_IF(p(138, s), BOOST_PP_WHILE_138, s BOOST_PP_TUPLE_EAT_3)(p, o, o(138, s)) # define BOOST_PP_WHILE_138(p, o, s) BOOST_PP_IF(p(139, s), BOOST_PP_WHILE_139, s BOOST_PP_TUPLE_EAT_3)(p, o, o(139, s)) # define BOOST_PP_WHILE_139(p, o, s) BOOST_PP_IF(p(140, s), BOOST_PP_WHILE_140, s BOOST_PP_TUPLE_EAT_3)(p, o, o(140, s)) # define BOOST_PP_WHILE_140(p, o, s) BOOST_PP_IF(p(141, s), BOOST_PP_WHILE_141, s BOOST_PP_TUPLE_EAT_3)(p, o, o(141, s)) # define BOOST_PP_WHILE_141(p, o, s) BOOST_PP_IF(p(142, s), BOOST_PP_WHILE_142, s BOOST_PP_TUPLE_EAT_3)(p, o, o(142, s)) # define BOOST_PP_WHILE_142(p, o, s) BOOST_PP_IF(p(143, s), BOOST_PP_WHILE_143, s BOOST_PP_TUPLE_EAT_3)(p, o, o(143, s)) # define BOOST_PP_WHILE_143(p, o, s) BOOST_PP_IF(p(144, s), BOOST_PP_WHILE_144, s BOOST_PP_TUPLE_EAT_3)(p, o, o(144, s)) # define BOOST_PP_WHILE_144(p, o, s) BOOST_PP_IF(p(145, s), BOOST_PP_WHILE_145, s BOOST_PP_TUPLE_EAT_3)(p, o, o(145, s)) # define BOOST_PP_WHILE_145(p, o, s) BOOST_PP_IF(p(146, s), BOOST_PP_WHILE_146, s BOOST_PP_TUPLE_EAT_3)(p, o, o(146, s)) # define BOOST_PP_WHILE_146(p, o, s) BOOST_PP_IF(p(147, s), BOOST_PP_WHILE_147, s BOOST_PP_TUPLE_EAT_3)(p, o, o(147, s)) # define BOOST_PP_WHILE_147(p, o, s) BOOST_PP_IF(p(148, s), BOOST_PP_WHILE_148, s BOOST_PP_TUPLE_EAT_3)(p, o, o(148, s)) # define BOOST_PP_WHILE_148(p, o, s) BOOST_PP_IF(p(149, s), BOOST_PP_WHILE_149, s BOOST_PP_TUPLE_EAT_3)(p, o, o(149, s)) # define BOOST_PP_WHILE_149(p, o, s) BOOST_PP_IF(p(150, s), BOOST_PP_WHILE_150, s BOOST_PP_TUPLE_EAT_3)(p, o, o(150, s)) # define BOOST_PP_WHILE_150(p, o, s) BOOST_PP_IF(p(151, s), BOOST_PP_WHILE_151, s BOOST_PP_TUPLE_EAT_3)(p, o, o(151, s)) # define BOOST_PP_WHILE_151(p, o, s) BOOST_PP_IF(p(152, s), BOOST_PP_WHILE_152, s BOOST_PP_TUPLE_EAT_3)(p, o, o(152, s)) # define BOOST_PP_WHILE_152(p, o, s) BOOST_PP_IF(p(153, s), BOOST_PP_WHILE_153, s BOOST_PP_TUPLE_EAT_3)(p, o, o(153, s)) # define BOOST_PP_WHILE_153(p, o, s) BOOST_PP_IF(p(154, s), BOOST_PP_WHILE_154, s BOOST_PP_TUPLE_EAT_3)(p, o, o(154, s)) # define BOOST_PP_WHILE_154(p, o, s) BOOST_PP_IF(p(155, s), BOOST_PP_WHILE_155, s BOOST_PP_TUPLE_EAT_3)(p, o, o(155, s)) # define BOOST_PP_WHILE_155(p, o, s) BOOST_PP_IF(p(156, s), BOOST_PP_WHILE_156, s BOOST_PP_TUPLE_EAT_3)(p, o, o(156, s)) # define BOOST_PP_WHILE_156(p, o, s) BOOST_PP_IF(p(157, s), BOOST_PP_WHILE_157, s BOOST_PP_TUPLE_EAT_3)(p, o, o(157, s)) # define BOOST_PP_WHILE_157(p, o, s) BOOST_PP_IF(p(158, s), BOOST_PP_WHILE_158, s BOOST_PP_TUPLE_EAT_3)(p, o, o(158, s)) # define BOOST_PP_WHILE_158(p, o, s) BOOST_PP_IF(p(159, s), BOOST_PP_WHILE_159, s BOOST_PP_TUPLE_EAT_3)(p, o, o(159, s)) # define BOOST_PP_WHILE_159(p, o, s) BOOST_PP_IF(p(160, s), BOOST_PP_WHILE_160, s BOOST_PP_TUPLE_EAT_3)(p, o, o(160, s)) # define BOOST_PP_WHILE_160(p, o, s) BOOST_PP_IF(p(161, s), BOOST_PP_WHILE_161, s BOOST_PP_TUPLE_EAT_3)(p, o, o(161, s)) # define BOOST_PP_WHILE_161(p, o, s) BOOST_PP_IF(p(162, s), BOOST_PP_WHILE_162, s BOOST_PP_TUPLE_EAT_3)(p, o, o(162, s)) # define BOOST_PP_WHILE_162(p, o, s) BOOST_PP_IF(p(163, s), BOOST_PP_WHILE_163, s BOOST_PP_TUPLE_EAT_3)(p, o, o(163, s)) # define BOOST_PP_WHILE_163(p, o, s) BOOST_PP_IF(p(164, s), BOOST_PP_WHILE_164, s BOOST_PP_TUPLE_EAT_3)(p, o, o(164, s)) # define BOOST_PP_WHILE_164(p, o, s) BOOST_PP_IF(p(165, s), BOOST_PP_WHILE_165, s BOOST_PP_TUPLE_EAT_3)(p, o, o(165, s)) # define BOOST_PP_WHILE_165(p, o, s) BOOST_PP_IF(p(166, s), BOOST_PP_WHILE_166, s BOOST_PP_TUPLE_EAT_3)(p, o, o(166, s)) # define BOOST_PP_WHILE_166(p, o, s) BOOST_PP_IF(p(167, s), BOOST_PP_WHILE_167, s BOOST_PP_TUPLE_EAT_3)(p, o, o(167, s)) # define BOOST_PP_WHILE_167(p, o, s) BOOST_PP_IF(p(168, s), BOOST_PP_WHILE_168, s BOOST_PP_TUPLE_EAT_3)(p, o, o(168, s)) # define BOOST_PP_WHILE_168(p, o, s) BOOST_PP_IF(p(169, s), BOOST_PP_WHILE_169, s BOOST_PP_TUPLE_EAT_3)(p, o, o(169, s)) # define BOOST_PP_WHILE_169(p, o, s) BOOST_PP_IF(p(170, s), BOOST_PP_WHILE_170, s BOOST_PP_TUPLE_EAT_3)(p, o, o(170, s)) # define BOOST_PP_WHILE_170(p, o, s) BOOST_PP_IF(p(171, s), BOOST_PP_WHILE_171, s BOOST_PP_TUPLE_EAT_3)(p, o, o(171, s)) # define BOOST_PP_WHILE_171(p, o, s) BOOST_PP_IF(p(172, s), BOOST_PP_WHILE_172, s BOOST_PP_TUPLE_EAT_3)(p, o, o(172, s)) # define BOOST_PP_WHILE_172(p, o, s) BOOST_PP_IF(p(173, s), BOOST_PP_WHILE_173, s BOOST_PP_TUPLE_EAT_3)(p, o, o(173, s)) # define BOOST_PP_WHILE_173(p, o, s) BOOST_PP_IF(p(174, s), BOOST_PP_WHILE_174, s BOOST_PP_TUPLE_EAT_3)(p, o, o(174, s)) # define BOOST_PP_WHILE_174(p, o, s) BOOST_PP_IF(p(175, s), BOOST_PP_WHILE_175, s BOOST_PP_TUPLE_EAT_3)(p, o, o(175, s)) # define BOOST_PP_WHILE_175(p, o, s) BOOST_PP_IF(p(176, s), BOOST_PP_WHILE_176, s BOOST_PP_TUPLE_EAT_3)(p, o, o(176, s)) # define BOOST_PP_WHILE_176(p, o, s) BOOST_PP_IF(p(177, s), BOOST_PP_WHILE_177, s BOOST_PP_TUPLE_EAT_3)(p, o, o(177, s)) # define BOOST_PP_WHILE_177(p, o, s) BOOST_PP_IF(p(178, s), BOOST_PP_WHILE_178, s BOOST_PP_TUPLE_EAT_3)(p, o, o(178, s)) # define BOOST_PP_WHILE_178(p, o, s) BOOST_PP_IF(p(179, s), BOOST_PP_WHILE_179, s BOOST_PP_TUPLE_EAT_3)(p, o, o(179, s)) # define BOOST_PP_WHILE_179(p, o, s) BOOST_PP_IF(p(180, s), BOOST_PP_WHILE_180, s BOOST_PP_TUPLE_EAT_3)(p, o, o(180, s)) # define BOOST_PP_WHILE_180(p, o, s) BOOST_PP_IF(p(181, s), BOOST_PP_WHILE_181, s BOOST_PP_TUPLE_EAT_3)(p, o, o(181, s)) # define BOOST_PP_WHILE_181(p, o, s) BOOST_PP_IF(p(182, s), BOOST_PP_WHILE_182, s BOOST_PP_TUPLE_EAT_3)(p, o, o(182, s)) # define BOOST_PP_WHILE_182(p, o, s) BOOST_PP_IF(p(183, s), BOOST_PP_WHILE_183, s BOOST_PP_TUPLE_EAT_3)(p, o, o(183, s)) # define BOOST_PP_WHILE_183(p, o, s) BOOST_PP_IF(p(184, s), BOOST_PP_WHILE_184, s BOOST_PP_TUPLE_EAT_3)(p, o, o(184, s)) # define BOOST_PP_WHILE_184(p, o, s) BOOST_PP_IF(p(185, s), BOOST_PP_WHILE_185, s BOOST_PP_TUPLE_EAT_3)(p, o, o(185, s)) # define BOOST_PP_WHILE_185(p, o, s) BOOST_PP_IF(p(186, s), BOOST_PP_WHILE_186, s BOOST_PP_TUPLE_EAT_3)(p, o, o(186, s)) # define BOOST_PP_WHILE_186(p, o, s) BOOST_PP_IF(p(187, s), BOOST_PP_WHILE_187, s BOOST_PP_TUPLE_EAT_3)(p, o, o(187, s)) # define BOOST_PP_WHILE_187(p, o, s) BOOST_PP_IF(p(188, s), BOOST_PP_WHILE_188, s BOOST_PP_TUPLE_EAT_3)(p, o, o(188, s)) # define BOOST_PP_WHILE_188(p, o, s) BOOST_PP_IF(p(189, s), BOOST_PP_WHILE_189, s BOOST_PP_TUPLE_EAT_3)(p, o, o(189, s)) # define BOOST_PP_WHILE_189(p, o, s) BOOST_PP_IF(p(190, s), BOOST_PP_WHILE_190, s BOOST_PP_TUPLE_EAT_3)(p, o, o(190, s)) # define BOOST_PP_WHILE_190(p, o, s) BOOST_PP_IF(p(191, s), BOOST_PP_WHILE_191, s BOOST_PP_TUPLE_EAT_3)(p, o, o(191, s)) # define BOOST_PP_WHILE_191(p, o, s) BOOST_PP_IF(p(192, s), BOOST_PP_WHILE_192, s BOOST_PP_TUPLE_EAT_3)(p, o, o(192, s)) # define BOOST_PP_WHILE_192(p, o, s) BOOST_PP_IF(p(193, s), BOOST_PP_WHILE_193, s BOOST_PP_TUPLE_EAT_3)(p, o, o(193, s)) # define BOOST_PP_WHILE_193(p, o, s) BOOST_PP_IF(p(194, s), BOOST_PP_WHILE_194, s BOOST_PP_TUPLE_EAT_3)(p, o, o(194, s)) # define BOOST_PP_WHILE_194(p, o, s) BOOST_PP_IF(p(195, s), BOOST_PP_WHILE_195, s BOOST_PP_TUPLE_EAT_3)(p, o, o(195, s)) # define BOOST_PP_WHILE_195(p, o, s) BOOST_PP_IF(p(196, s), BOOST_PP_WHILE_196, s BOOST_PP_TUPLE_EAT_3)(p, o, o(196, s)) # define BOOST_PP_WHILE_196(p, o, s) BOOST_PP_IF(p(197, s), BOOST_PP_WHILE_197, s BOOST_PP_TUPLE_EAT_3)(p, o, o(197, s)) # define BOOST_PP_WHILE_197(p, o, s) BOOST_PP_IF(p(198, s), BOOST_PP_WHILE_198, s BOOST_PP_TUPLE_EAT_3)(p, o, o(198, s)) # define BOOST_PP_WHILE_198(p, o, s) BOOST_PP_IF(p(199, s), BOOST_PP_WHILE_199, s BOOST_PP_TUPLE_EAT_3)(p, o, o(199, s)) # define BOOST_PP_WHILE_199(p, o, s) BOOST_PP_IF(p(200, s), BOOST_PP_WHILE_200, s BOOST_PP_TUPLE_EAT_3)(p, o, o(200, s)) # define BOOST_PP_WHILE_200(p, o, s) BOOST_PP_IF(p(201, s), BOOST_PP_WHILE_201, s BOOST_PP_TUPLE_EAT_3)(p, o, o(201, s)) # define BOOST_PP_WHILE_201(p, o, s) BOOST_PP_IF(p(202, s), BOOST_PP_WHILE_202, s BOOST_PP_TUPLE_EAT_3)(p, o, o(202, s)) # define BOOST_PP_WHILE_202(p, o, s) BOOST_PP_IF(p(203, s), BOOST_PP_WHILE_203, s BOOST_PP_TUPLE_EAT_3)(p, o, o(203, s)) # define BOOST_PP_WHILE_203(p, o, s) BOOST_PP_IF(p(204, s), BOOST_PP_WHILE_204, s BOOST_PP_TUPLE_EAT_3)(p, o, o(204, s)) # define BOOST_PP_WHILE_204(p, o, s) BOOST_PP_IF(p(205, s), BOOST_PP_WHILE_205, s BOOST_PP_TUPLE_EAT_3)(p, o, o(205, s)) # define BOOST_PP_WHILE_205(p, o, s) BOOST_PP_IF(p(206, s), BOOST_PP_WHILE_206, s BOOST_PP_TUPLE_EAT_3)(p, o, o(206, s)) # define BOOST_PP_WHILE_206(p, o, s) BOOST_PP_IF(p(207, s), BOOST_PP_WHILE_207, s BOOST_PP_TUPLE_EAT_3)(p, o, o(207, s)) # define BOOST_PP_WHILE_207(p, o, s) BOOST_PP_IF(p(208, s), BOOST_PP_WHILE_208, s BOOST_PP_TUPLE_EAT_3)(p, o, o(208, s)) # define BOOST_PP_WHILE_208(p, o, s) BOOST_PP_IF(p(209, s), BOOST_PP_WHILE_209, s BOOST_PP_TUPLE_EAT_3)(p, o, o(209, s)) # define BOOST_PP_WHILE_209(p, o, s) BOOST_PP_IF(p(210, s), BOOST_PP_WHILE_210, s BOOST_PP_TUPLE_EAT_3)(p, o, o(210, s)) # define BOOST_PP_WHILE_210(p, o, s) BOOST_PP_IF(p(211, s), BOOST_PP_WHILE_211, s BOOST_PP_TUPLE_EAT_3)(p, o, o(211, s)) # define BOOST_PP_WHILE_211(p, o, s) BOOST_PP_IF(p(212, s), BOOST_PP_WHILE_212, s BOOST_PP_TUPLE_EAT_3)(p, o, o(212, s)) # define BOOST_PP_WHILE_212(p, o, s) BOOST_PP_IF(p(213, s), BOOST_PP_WHILE_213, s BOOST_PP_TUPLE_EAT_3)(p, o, o(213, s)) # define BOOST_PP_WHILE_213(p, o, s) BOOST_PP_IF(p(214, s), BOOST_PP_WHILE_214, s BOOST_PP_TUPLE_EAT_3)(p, o, o(214, s)) # define BOOST_PP_WHILE_214(p, o, s) BOOST_PP_IF(p(215, s), BOOST_PP_WHILE_215, s BOOST_PP_TUPLE_EAT_3)(p, o, o(215, s)) # define BOOST_PP_WHILE_215(p, o, s) BOOST_PP_IF(p(216, s), BOOST_PP_WHILE_216, s BOOST_PP_TUPLE_EAT_3)(p, o, o(216, s)) # define BOOST_PP_WHILE_216(p, o, s) BOOST_PP_IF(p(217, s), BOOST_PP_WHILE_217, s BOOST_PP_TUPLE_EAT_3)(p, o, o(217, s)) # define BOOST_PP_WHILE_217(p, o, s) BOOST_PP_IF(p(218, s), BOOST_PP_WHILE_218, s BOOST_PP_TUPLE_EAT_3)(p, o, o(218, s)) # define BOOST_PP_WHILE_218(p, o, s) BOOST_PP_IF(p(219, s), BOOST_PP_WHILE_219, s BOOST_PP_TUPLE_EAT_3)(p, o, o(219, s)) # define BOOST_PP_WHILE_219(p, o, s) BOOST_PP_IF(p(220, s), BOOST_PP_WHILE_220, s BOOST_PP_TUPLE_EAT_3)(p, o, o(220, s)) # define BOOST_PP_WHILE_220(p, o, s) BOOST_PP_IF(p(221, s), BOOST_PP_WHILE_221, s BOOST_PP_TUPLE_EAT_3)(p, o, o(221, s)) # define BOOST_PP_WHILE_221(p, o, s) BOOST_PP_IF(p(222, s), BOOST_PP_WHILE_222, s BOOST_PP_TUPLE_EAT_3)(p, o, o(222, s)) # define BOOST_PP_WHILE_222(p, o, s) BOOST_PP_IF(p(223, s), BOOST_PP_WHILE_223, s BOOST_PP_TUPLE_EAT_3)(p, o, o(223, s)) # define BOOST_PP_WHILE_223(p, o, s) BOOST_PP_IF(p(224, s), BOOST_PP_WHILE_224, s BOOST_PP_TUPLE_EAT_3)(p, o, o(224, s)) # define BOOST_PP_WHILE_224(p, o, s) BOOST_PP_IF(p(225, s), BOOST_PP_WHILE_225, s BOOST_PP_TUPLE_EAT_3)(p, o, o(225, s)) # define BOOST_PP_WHILE_225(p, o, s) BOOST_PP_IF(p(226, s), BOOST_PP_WHILE_226, s BOOST_PP_TUPLE_EAT_3)(p, o, o(226, s)) # define BOOST_PP_WHILE_226(p, o, s) BOOST_PP_IF(p(227, s), BOOST_PP_WHILE_227, s BOOST_PP_TUPLE_EAT_3)(p, o, o(227, s)) # define BOOST_PP_WHILE_227(p, o, s) BOOST_PP_IF(p(228, s), BOOST_PP_WHILE_228, s BOOST_PP_TUPLE_EAT_3)(p, o, o(228, s)) # define BOOST_PP_WHILE_228(p, o, s) BOOST_PP_IF(p(229, s), BOOST_PP_WHILE_229, s BOOST_PP_TUPLE_EAT_3)(p, o, o(229, s)) # define BOOST_PP_WHILE_229(p, o, s) BOOST_PP_IF(p(230, s), BOOST_PP_WHILE_230, s BOOST_PP_TUPLE_EAT_3)(p, o, o(230, s)) # define BOOST_PP_WHILE_230(p, o, s) BOOST_PP_IF(p(231, s), BOOST_PP_WHILE_231, s BOOST_PP_TUPLE_EAT_3)(p, o, o(231, s)) # define BOOST_PP_WHILE_231(p, o, s) BOOST_PP_IF(p(232, s), BOOST_PP_WHILE_232, s BOOST_PP_TUPLE_EAT_3)(p, o, o(232, s)) # define BOOST_PP_WHILE_232(p, o, s) BOOST_PP_IF(p(233, s), BOOST_PP_WHILE_233, s BOOST_PP_TUPLE_EAT_3)(p, o, o(233, s)) # define BOOST_PP_WHILE_233(p, o, s) BOOST_PP_IF(p(234, s), BOOST_PP_WHILE_234, s BOOST_PP_TUPLE_EAT_3)(p, o, o(234, s)) # define BOOST_PP_WHILE_234(p, o, s) BOOST_PP_IF(p(235, s), BOOST_PP_WHILE_235, s BOOST_PP_TUPLE_EAT_3)(p, o, o(235, s)) # define BOOST_PP_WHILE_235(p, o, s) BOOST_PP_IF(p(236, s), BOOST_PP_WHILE_236, s BOOST_PP_TUPLE_EAT_3)(p, o, o(236, s)) # define BOOST_PP_WHILE_236(p, o, s) BOOST_PP_IF(p(237, s), BOOST_PP_WHILE_237, s BOOST_PP_TUPLE_EAT_3)(p, o, o(237, s)) # define BOOST_PP_WHILE_237(p, o, s) BOOST_PP_IF(p(238, s), BOOST_PP_WHILE_238, s BOOST_PP_TUPLE_EAT_3)(p, o, o(238, s)) # define BOOST_PP_WHILE_238(p, o, s) BOOST_PP_IF(p(239, s), BOOST_PP_WHILE_239, s BOOST_PP_TUPLE_EAT_3)(p, o, o(239, s)) # define BOOST_PP_WHILE_239(p, o, s) BOOST_PP_IF(p(240, s), BOOST_PP_WHILE_240, s BOOST_PP_TUPLE_EAT_3)(p, o, o(240, s)) # define BOOST_PP_WHILE_240(p, o, s) BOOST_PP_IF(p(241, s), BOOST_PP_WHILE_241, s BOOST_PP_TUPLE_EAT_3)(p, o, o(241, s)) # define BOOST_PP_WHILE_241(p, o, s) BOOST_PP_IF(p(242, s), BOOST_PP_WHILE_242, s BOOST_PP_TUPLE_EAT_3)(p, o, o(242, s)) # define BOOST_PP_WHILE_242(p, o, s) BOOST_PP_IF(p(243, s), BOOST_PP_WHILE_243, s BOOST_PP_TUPLE_EAT_3)(p, o, o(243, s)) # define BOOST_PP_WHILE_243(p, o, s) BOOST_PP_IF(p(244, s), BOOST_PP_WHILE_244, s BOOST_PP_TUPLE_EAT_3)(p, o, o(244, s)) # define BOOST_PP_WHILE_244(p, o, s) BOOST_PP_IF(p(245, s), BOOST_PP_WHILE_245, s BOOST_PP_TUPLE_EAT_3)(p, o, o(245, s)) # define BOOST_PP_WHILE_245(p, o, s) BOOST_PP_IF(p(246, s), BOOST_PP_WHILE_246, s BOOST_PP_TUPLE_EAT_3)(p, o, o(246, s)) # define BOOST_PP_WHILE_246(p, o, s) BOOST_PP_IF(p(247, s), BOOST_PP_WHILE_247, s BOOST_PP_TUPLE_EAT_3)(p, o, o(247, s)) # define BOOST_PP_WHILE_247(p, o, s) BOOST_PP_IF(p(248, s), BOOST_PP_WHILE_248, s BOOST_PP_TUPLE_EAT_3)(p, o, o(248, s)) # define BOOST_PP_WHILE_248(p, o, s) BOOST_PP_IF(p(249, s), BOOST_PP_WHILE_249, s BOOST_PP_TUPLE_EAT_3)(p, o, o(249, s)) # define BOOST_PP_WHILE_249(p, o, s) BOOST_PP_IF(p(250, s), BOOST_PP_WHILE_250, s BOOST_PP_TUPLE_EAT_3)(p, o, o(250, s)) # define BOOST_PP_WHILE_250(p, o, s) BOOST_PP_IF(p(251, s), BOOST_PP_WHILE_251, s BOOST_PP_TUPLE_EAT_3)(p, o, o(251, s)) # define BOOST_PP_WHILE_251(p, o, s) BOOST_PP_IF(p(252, s), BOOST_PP_WHILE_252, s BOOST_PP_TUPLE_EAT_3)(p, o, o(252, s)) # define BOOST_PP_WHILE_252(p, o, s) BOOST_PP_IF(p(253, s), BOOST_PP_WHILE_253, s BOOST_PP_TUPLE_EAT_3)(p, o, o(253, s)) # define BOOST_PP_WHILE_253(p, o, s) BOOST_PP_IF(p(254, s), BOOST_PP_WHILE_254, s BOOST_PP_TUPLE_EAT_3)(p, o, o(254, s)) # define BOOST_PP_WHILE_254(p, o, s) BOOST_PP_IF(p(255, s), BOOST_PP_WHILE_255, s BOOST_PP_TUPLE_EAT_3)(p, o, o(255, s)) # define BOOST_PP_WHILE_255(p, o, s) BOOST_PP_IF(p(256, s), BOOST_PP_WHILE_256, s BOOST_PP_TUPLE_EAT_3)(p, o, o(256, s)) # define BOOST_PP_WHILE_256(p, o, s) BOOST_PP_IF(p(257, s), BOOST_PP_WHILE_257, s BOOST_PP_TUPLE_EAT_3)(p, o, o(257, s)) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/detail/while.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_DETAIL_WHILE_HPP # define BOOST_PREPROCESSOR_CONTROL_DETAIL_WHILE_HPP # # include # include # include # # define BOOST_PP_WHILE_1(p, o, s) BOOST_PP_WHILE_1_C(BOOST_PP_BOOL(p(2, s)), p, o, s) # define BOOST_PP_WHILE_2(p, o, s) BOOST_PP_WHILE_2_C(BOOST_PP_BOOL(p(3, s)), p, o, s) # define BOOST_PP_WHILE_3(p, o, s) BOOST_PP_WHILE_3_C(BOOST_PP_BOOL(p(4, s)), p, o, s) # define BOOST_PP_WHILE_4(p, o, s) BOOST_PP_WHILE_4_C(BOOST_PP_BOOL(p(5, s)), p, o, s) # define BOOST_PP_WHILE_5(p, o, s) BOOST_PP_WHILE_5_C(BOOST_PP_BOOL(p(6, s)), p, o, s) # define BOOST_PP_WHILE_6(p, o, s) BOOST_PP_WHILE_6_C(BOOST_PP_BOOL(p(7, s)), p, o, s) # define BOOST_PP_WHILE_7(p, o, s) BOOST_PP_WHILE_7_C(BOOST_PP_BOOL(p(8, s)), p, o, s) # define BOOST_PP_WHILE_8(p, o, s) BOOST_PP_WHILE_8_C(BOOST_PP_BOOL(p(9, s)), p, o, s) # define BOOST_PP_WHILE_9(p, o, s) BOOST_PP_WHILE_9_C(BOOST_PP_BOOL(p(10, s)), p, o, s) # define BOOST_PP_WHILE_10(p, o, s) BOOST_PP_WHILE_10_C(BOOST_PP_BOOL(p(11, s)), p, o, s) # define BOOST_PP_WHILE_11(p, o, s) BOOST_PP_WHILE_11_C(BOOST_PP_BOOL(p(12, s)), p, o, s) # define BOOST_PP_WHILE_12(p, o, s) BOOST_PP_WHILE_12_C(BOOST_PP_BOOL(p(13, s)), p, o, s) # define BOOST_PP_WHILE_13(p, o, s) BOOST_PP_WHILE_13_C(BOOST_PP_BOOL(p(14, s)), p, o, s) # define BOOST_PP_WHILE_14(p, o, s) BOOST_PP_WHILE_14_C(BOOST_PP_BOOL(p(15, s)), p, o, s) # define BOOST_PP_WHILE_15(p, o, s) BOOST_PP_WHILE_15_C(BOOST_PP_BOOL(p(16, s)), p, o, s) # define BOOST_PP_WHILE_16(p, o, s) BOOST_PP_WHILE_16_C(BOOST_PP_BOOL(p(17, s)), p, o, s) # define BOOST_PP_WHILE_17(p, o, s) BOOST_PP_WHILE_17_C(BOOST_PP_BOOL(p(18, s)), p, o, s) # define BOOST_PP_WHILE_18(p, o, s) BOOST_PP_WHILE_18_C(BOOST_PP_BOOL(p(19, s)), p, o, s) # define BOOST_PP_WHILE_19(p, o, s) BOOST_PP_WHILE_19_C(BOOST_PP_BOOL(p(20, s)), p, o, s) # define BOOST_PP_WHILE_20(p, o, s) BOOST_PP_WHILE_20_C(BOOST_PP_BOOL(p(21, s)), p, o, s) # define BOOST_PP_WHILE_21(p, o, s) BOOST_PP_WHILE_21_C(BOOST_PP_BOOL(p(22, s)), p, o, s) # define BOOST_PP_WHILE_22(p, o, s) BOOST_PP_WHILE_22_C(BOOST_PP_BOOL(p(23, s)), p, o, s) # define BOOST_PP_WHILE_23(p, o, s) BOOST_PP_WHILE_23_C(BOOST_PP_BOOL(p(24, s)), p, o, s) # define BOOST_PP_WHILE_24(p, o, s) BOOST_PP_WHILE_24_C(BOOST_PP_BOOL(p(25, s)), p, o, s) # define BOOST_PP_WHILE_25(p, o, s) BOOST_PP_WHILE_25_C(BOOST_PP_BOOL(p(26, s)), p, o, s) # define BOOST_PP_WHILE_26(p, o, s) BOOST_PP_WHILE_26_C(BOOST_PP_BOOL(p(27, s)), p, o, s) # define BOOST_PP_WHILE_27(p, o, s) BOOST_PP_WHILE_27_C(BOOST_PP_BOOL(p(28, s)), p, o, s) # define BOOST_PP_WHILE_28(p, o, s) BOOST_PP_WHILE_28_C(BOOST_PP_BOOL(p(29, s)), p, o, s) # define BOOST_PP_WHILE_29(p, o, s) BOOST_PP_WHILE_29_C(BOOST_PP_BOOL(p(30, s)), p, o, s) # define BOOST_PP_WHILE_30(p, o, s) BOOST_PP_WHILE_30_C(BOOST_PP_BOOL(p(31, s)), p, o, s) # define BOOST_PP_WHILE_31(p, o, s) BOOST_PP_WHILE_31_C(BOOST_PP_BOOL(p(32, s)), p, o, s) # define BOOST_PP_WHILE_32(p, o, s) BOOST_PP_WHILE_32_C(BOOST_PP_BOOL(p(33, s)), p, o, s) # define BOOST_PP_WHILE_33(p, o, s) BOOST_PP_WHILE_33_C(BOOST_PP_BOOL(p(34, s)), p, o, s) # define BOOST_PP_WHILE_34(p, o, s) BOOST_PP_WHILE_34_C(BOOST_PP_BOOL(p(35, s)), p, o, s) # define BOOST_PP_WHILE_35(p, o, s) BOOST_PP_WHILE_35_C(BOOST_PP_BOOL(p(36, s)), p, o, s) # define BOOST_PP_WHILE_36(p, o, s) BOOST_PP_WHILE_36_C(BOOST_PP_BOOL(p(37, s)), p, o, s) # define BOOST_PP_WHILE_37(p, o, s) BOOST_PP_WHILE_37_C(BOOST_PP_BOOL(p(38, s)), p, o, s) # define BOOST_PP_WHILE_38(p, o, s) BOOST_PP_WHILE_38_C(BOOST_PP_BOOL(p(39, s)), p, o, s) # define BOOST_PP_WHILE_39(p, o, s) BOOST_PP_WHILE_39_C(BOOST_PP_BOOL(p(40, s)), p, o, s) # define BOOST_PP_WHILE_40(p, o, s) BOOST_PP_WHILE_40_C(BOOST_PP_BOOL(p(41, s)), p, o, s) # define BOOST_PP_WHILE_41(p, o, s) BOOST_PP_WHILE_41_C(BOOST_PP_BOOL(p(42, s)), p, o, s) # define BOOST_PP_WHILE_42(p, o, s) BOOST_PP_WHILE_42_C(BOOST_PP_BOOL(p(43, s)), p, o, s) # define BOOST_PP_WHILE_43(p, o, s) BOOST_PP_WHILE_43_C(BOOST_PP_BOOL(p(44, s)), p, o, s) # define BOOST_PP_WHILE_44(p, o, s) BOOST_PP_WHILE_44_C(BOOST_PP_BOOL(p(45, s)), p, o, s) # define BOOST_PP_WHILE_45(p, o, s) BOOST_PP_WHILE_45_C(BOOST_PP_BOOL(p(46, s)), p, o, s) # define BOOST_PP_WHILE_46(p, o, s) BOOST_PP_WHILE_46_C(BOOST_PP_BOOL(p(47, s)), p, o, s) # define BOOST_PP_WHILE_47(p, o, s) BOOST_PP_WHILE_47_C(BOOST_PP_BOOL(p(48, s)), p, o, s) # define BOOST_PP_WHILE_48(p, o, s) BOOST_PP_WHILE_48_C(BOOST_PP_BOOL(p(49, s)), p, o, s) # define BOOST_PP_WHILE_49(p, o, s) BOOST_PP_WHILE_49_C(BOOST_PP_BOOL(p(50, s)), p, o, s) # define BOOST_PP_WHILE_50(p, o, s) BOOST_PP_WHILE_50_C(BOOST_PP_BOOL(p(51, s)), p, o, s) # define BOOST_PP_WHILE_51(p, o, s) BOOST_PP_WHILE_51_C(BOOST_PP_BOOL(p(52, s)), p, o, s) # define BOOST_PP_WHILE_52(p, o, s) BOOST_PP_WHILE_52_C(BOOST_PP_BOOL(p(53, s)), p, o, s) # define BOOST_PP_WHILE_53(p, o, s) BOOST_PP_WHILE_53_C(BOOST_PP_BOOL(p(54, s)), p, o, s) # define BOOST_PP_WHILE_54(p, o, s) BOOST_PP_WHILE_54_C(BOOST_PP_BOOL(p(55, s)), p, o, s) # define BOOST_PP_WHILE_55(p, o, s) BOOST_PP_WHILE_55_C(BOOST_PP_BOOL(p(56, s)), p, o, s) # define BOOST_PP_WHILE_56(p, o, s) BOOST_PP_WHILE_56_C(BOOST_PP_BOOL(p(57, s)), p, o, s) # define BOOST_PP_WHILE_57(p, o, s) BOOST_PP_WHILE_57_C(BOOST_PP_BOOL(p(58, s)), p, o, s) # define BOOST_PP_WHILE_58(p, o, s) BOOST_PP_WHILE_58_C(BOOST_PP_BOOL(p(59, s)), p, o, s) # define BOOST_PP_WHILE_59(p, o, s) BOOST_PP_WHILE_59_C(BOOST_PP_BOOL(p(60, s)), p, o, s) # define BOOST_PP_WHILE_60(p, o, s) BOOST_PP_WHILE_60_C(BOOST_PP_BOOL(p(61, s)), p, o, s) # define BOOST_PP_WHILE_61(p, o, s) BOOST_PP_WHILE_61_C(BOOST_PP_BOOL(p(62, s)), p, o, s) # define BOOST_PP_WHILE_62(p, o, s) BOOST_PP_WHILE_62_C(BOOST_PP_BOOL(p(63, s)), p, o, s) # define BOOST_PP_WHILE_63(p, o, s) BOOST_PP_WHILE_63_C(BOOST_PP_BOOL(p(64, s)), p, o, s) # define BOOST_PP_WHILE_64(p, o, s) BOOST_PP_WHILE_64_C(BOOST_PP_BOOL(p(65, s)), p, o, s) # define BOOST_PP_WHILE_65(p, o, s) BOOST_PP_WHILE_65_C(BOOST_PP_BOOL(p(66, s)), p, o, s) # define BOOST_PP_WHILE_66(p, o, s) BOOST_PP_WHILE_66_C(BOOST_PP_BOOL(p(67, s)), p, o, s) # define BOOST_PP_WHILE_67(p, o, s) BOOST_PP_WHILE_67_C(BOOST_PP_BOOL(p(68, s)), p, o, s) # define BOOST_PP_WHILE_68(p, o, s) BOOST_PP_WHILE_68_C(BOOST_PP_BOOL(p(69, s)), p, o, s) # define BOOST_PP_WHILE_69(p, o, s) BOOST_PP_WHILE_69_C(BOOST_PP_BOOL(p(70, s)), p, o, s) # define BOOST_PP_WHILE_70(p, o, s) BOOST_PP_WHILE_70_C(BOOST_PP_BOOL(p(71, s)), p, o, s) # define BOOST_PP_WHILE_71(p, o, s) BOOST_PP_WHILE_71_C(BOOST_PP_BOOL(p(72, s)), p, o, s) # define BOOST_PP_WHILE_72(p, o, s) BOOST_PP_WHILE_72_C(BOOST_PP_BOOL(p(73, s)), p, o, s) # define BOOST_PP_WHILE_73(p, o, s) BOOST_PP_WHILE_73_C(BOOST_PP_BOOL(p(74, s)), p, o, s) # define BOOST_PP_WHILE_74(p, o, s) BOOST_PP_WHILE_74_C(BOOST_PP_BOOL(p(75, s)), p, o, s) # define BOOST_PP_WHILE_75(p, o, s) BOOST_PP_WHILE_75_C(BOOST_PP_BOOL(p(76, s)), p, o, s) # define BOOST_PP_WHILE_76(p, o, s) BOOST_PP_WHILE_76_C(BOOST_PP_BOOL(p(77, s)), p, o, s) # define BOOST_PP_WHILE_77(p, o, s) BOOST_PP_WHILE_77_C(BOOST_PP_BOOL(p(78, s)), p, o, s) # define BOOST_PP_WHILE_78(p, o, s) BOOST_PP_WHILE_78_C(BOOST_PP_BOOL(p(79, s)), p, o, s) # define BOOST_PP_WHILE_79(p, o, s) BOOST_PP_WHILE_79_C(BOOST_PP_BOOL(p(80, s)), p, o, s) # define BOOST_PP_WHILE_80(p, o, s) BOOST_PP_WHILE_80_C(BOOST_PP_BOOL(p(81, s)), p, o, s) # define BOOST_PP_WHILE_81(p, o, s) BOOST_PP_WHILE_81_C(BOOST_PP_BOOL(p(82, s)), p, o, s) # define BOOST_PP_WHILE_82(p, o, s) BOOST_PP_WHILE_82_C(BOOST_PP_BOOL(p(83, s)), p, o, s) # define BOOST_PP_WHILE_83(p, o, s) BOOST_PP_WHILE_83_C(BOOST_PP_BOOL(p(84, s)), p, o, s) # define BOOST_PP_WHILE_84(p, o, s) BOOST_PP_WHILE_84_C(BOOST_PP_BOOL(p(85, s)), p, o, s) # define BOOST_PP_WHILE_85(p, o, s) BOOST_PP_WHILE_85_C(BOOST_PP_BOOL(p(86, s)), p, o, s) # define BOOST_PP_WHILE_86(p, o, s) BOOST_PP_WHILE_86_C(BOOST_PP_BOOL(p(87, s)), p, o, s) # define BOOST_PP_WHILE_87(p, o, s) BOOST_PP_WHILE_87_C(BOOST_PP_BOOL(p(88, s)), p, o, s) # define BOOST_PP_WHILE_88(p, o, s) BOOST_PP_WHILE_88_C(BOOST_PP_BOOL(p(89, s)), p, o, s) # define BOOST_PP_WHILE_89(p, o, s) BOOST_PP_WHILE_89_C(BOOST_PP_BOOL(p(90, s)), p, o, s) # define BOOST_PP_WHILE_90(p, o, s) BOOST_PP_WHILE_90_C(BOOST_PP_BOOL(p(91, s)), p, o, s) # define BOOST_PP_WHILE_91(p, o, s) BOOST_PP_WHILE_91_C(BOOST_PP_BOOL(p(92, s)), p, o, s) # define BOOST_PP_WHILE_92(p, o, s) BOOST_PP_WHILE_92_C(BOOST_PP_BOOL(p(93, s)), p, o, s) # define BOOST_PP_WHILE_93(p, o, s) BOOST_PP_WHILE_93_C(BOOST_PP_BOOL(p(94, s)), p, o, s) # define BOOST_PP_WHILE_94(p, o, s) BOOST_PP_WHILE_94_C(BOOST_PP_BOOL(p(95, s)), p, o, s) # define BOOST_PP_WHILE_95(p, o, s) BOOST_PP_WHILE_95_C(BOOST_PP_BOOL(p(96, s)), p, o, s) # define BOOST_PP_WHILE_96(p, o, s) BOOST_PP_WHILE_96_C(BOOST_PP_BOOL(p(97, s)), p, o, s) # define BOOST_PP_WHILE_97(p, o, s) BOOST_PP_WHILE_97_C(BOOST_PP_BOOL(p(98, s)), p, o, s) # define BOOST_PP_WHILE_98(p, o, s) BOOST_PP_WHILE_98_C(BOOST_PP_BOOL(p(99, s)), p, o, s) # define BOOST_PP_WHILE_99(p, o, s) BOOST_PP_WHILE_99_C(BOOST_PP_BOOL(p(100, s)), p, o, s) # define BOOST_PP_WHILE_100(p, o, s) BOOST_PP_WHILE_100_C(BOOST_PP_BOOL(p(101, s)), p, o, s) # define BOOST_PP_WHILE_101(p, o, s) BOOST_PP_WHILE_101_C(BOOST_PP_BOOL(p(102, s)), p, o, s) # define BOOST_PP_WHILE_102(p, o, s) BOOST_PP_WHILE_102_C(BOOST_PP_BOOL(p(103, s)), p, o, s) # define BOOST_PP_WHILE_103(p, o, s) BOOST_PP_WHILE_103_C(BOOST_PP_BOOL(p(104, s)), p, o, s) # define BOOST_PP_WHILE_104(p, o, s) BOOST_PP_WHILE_104_C(BOOST_PP_BOOL(p(105, s)), p, o, s) # define BOOST_PP_WHILE_105(p, o, s) BOOST_PP_WHILE_105_C(BOOST_PP_BOOL(p(106, s)), p, o, s) # define BOOST_PP_WHILE_106(p, o, s) BOOST_PP_WHILE_106_C(BOOST_PP_BOOL(p(107, s)), p, o, s) # define BOOST_PP_WHILE_107(p, o, s) BOOST_PP_WHILE_107_C(BOOST_PP_BOOL(p(108, s)), p, o, s) # define BOOST_PP_WHILE_108(p, o, s) BOOST_PP_WHILE_108_C(BOOST_PP_BOOL(p(109, s)), p, o, s) # define BOOST_PP_WHILE_109(p, o, s) BOOST_PP_WHILE_109_C(BOOST_PP_BOOL(p(110, s)), p, o, s) # define BOOST_PP_WHILE_110(p, o, s) BOOST_PP_WHILE_110_C(BOOST_PP_BOOL(p(111, s)), p, o, s) # define BOOST_PP_WHILE_111(p, o, s) BOOST_PP_WHILE_111_C(BOOST_PP_BOOL(p(112, s)), p, o, s) # define BOOST_PP_WHILE_112(p, o, s) BOOST_PP_WHILE_112_C(BOOST_PP_BOOL(p(113, s)), p, o, s) # define BOOST_PP_WHILE_113(p, o, s) BOOST_PP_WHILE_113_C(BOOST_PP_BOOL(p(114, s)), p, o, s) # define BOOST_PP_WHILE_114(p, o, s) BOOST_PP_WHILE_114_C(BOOST_PP_BOOL(p(115, s)), p, o, s) # define BOOST_PP_WHILE_115(p, o, s) BOOST_PP_WHILE_115_C(BOOST_PP_BOOL(p(116, s)), p, o, s) # define BOOST_PP_WHILE_116(p, o, s) BOOST_PP_WHILE_116_C(BOOST_PP_BOOL(p(117, s)), p, o, s) # define BOOST_PP_WHILE_117(p, o, s) BOOST_PP_WHILE_117_C(BOOST_PP_BOOL(p(118, s)), p, o, s) # define BOOST_PP_WHILE_118(p, o, s) BOOST_PP_WHILE_118_C(BOOST_PP_BOOL(p(119, s)), p, o, s) # define BOOST_PP_WHILE_119(p, o, s) BOOST_PP_WHILE_119_C(BOOST_PP_BOOL(p(120, s)), p, o, s) # define BOOST_PP_WHILE_120(p, o, s) BOOST_PP_WHILE_120_C(BOOST_PP_BOOL(p(121, s)), p, o, s) # define BOOST_PP_WHILE_121(p, o, s) BOOST_PP_WHILE_121_C(BOOST_PP_BOOL(p(122, s)), p, o, s) # define BOOST_PP_WHILE_122(p, o, s) BOOST_PP_WHILE_122_C(BOOST_PP_BOOL(p(123, s)), p, o, s) # define BOOST_PP_WHILE_123(p, o, s) BOOST_PP_WHILE_123_C(BOOST_PP_BOOL(p(124, s)), p, o, s) # define BOOST_PP_WHILE_124(p, o, s) BOOST_PP_WHILE_124_C(BOOST_PP_BOOL(p(125, s)), p, o, s) # define BOOST_PP_WHILE_125(p, o, s) BOOST_PP_WHILE_125_C(BOOST_PP_BOOL(p(126, s)), p, o, s) # define BOOST_PP_WHILE_126(p, o, s) BOOST_PP_WHILE_126_C(BOOST_PP_BOOL(p(127, s)), p, o, s) # define BOOST_PP_WHILE_127(p, o, s) BOOST_PP_WHILE_127_C(BOOST_PP_BOOL(p(128, s)), p, o, s) # define BOOST_PP_WHILE_128(p, o, s) BOOST_PP_WHILE_128_C(BOOST_PP_BOOL(p(129, s)), p, o, s) # define BOOST_PP_WHILE_129(p, o, s) BOOST_PP_WHILE_129_C(BOOST_PP_BOOL(p(130, s)), p, o, s) # define BOOST_PP_WHILE_130(p, o, s) BOOST_PP_WHILE_130_C(BOOST_PP_BOOL(p(131, s)), p, o, s) # define BOOST_PP_WHILE_131(p, o, s) BOOST_PP_WHILE_131_C(BOOST_PP_BOOL(p(132, s)), p, o, s) # define BOOST_PP_WHILE_132(p, o, s) BOOST_PP_WHILE_132_C(BOOST_PP_BOOL(p(133, s)), p, o, s) # define BOOST_PP_WHILE_133(p, o, s) BOOST_PP_WHILE_133_C(BOOST_PP_BOOL(p(134, s)), p, o, s) # define BOOST_PP_WHILE_134(p, o, s) BOOST_PP_WHILE_134_C(BOOST_PP_BOOL(p(135, s)), p, o, s) # define BOOST_PP_WHILE_135(p, o, s) BOOST_PP_WHILE_135_C(BOOST_PP_BOOL(p(136, s)), p, o, s) # define BOOST_PP_WHILE_136(p, o, s) BOOST_PP_WHILE_136_C(BOOST_PP_BOOL(p(137, s)), p, o, s) # define BOOST_PP_WHILE_137(p, o, s) BOOST_PP_WHILE_137_C(BOOST_PP_BOOL(p(138, s)), p, o, s) # define BOOST_PP_WHILE_138(p, o, s) BOOST_PP_WHILE_138_C(BOOST_PP_BOOL(p(139, s)), p, o, s) # define BOOST_PP_WHILE_139(p, o, s) BOOST_PP_WHILE_139_C(BOOST_PP_BOOL(p(140, s)), p, o, s) # define BOOST_PP_WHILE_140(p, o, s) BOOST_PP_WHILE_140_C(BOOST_PP_BOOL(p(141, s)), p, o, s) # define BOOST_PP_WHILE_141(p, o, s) BOOST_PP_WHILE_141_C(BOOST_PP_BOOL(p(142, s)), p, o, s) # define BOOST_PP_WHILE_142(p, o, s) BOOST_PP_WHILE_142_C(BOOST_PP_BOOL(p(143, s)), p, o, s) # define BOOST_PP_WHILE_143(p, o, s) BOOST_PP_WHILE_143_C(BOOST_PP_BOOL(p(144, s)), p, o, s) # define BOOST_PP_WHILE_144(p, o, s) BOOST_PP_WHILE_144_C(BOOST_PP_BOOL(p(145, s)), p, o, s) # define BOOST_PP_WHILE_145(p, o, s) BOOST_PP_WHILE_145_C(BOOST_PP_BOOL(p(146, s)), p, o, s) # define BOOST_PP_WHILE_146(p, o, s) BOOST_PP_WHILE_146_C(BOOST_PP_BOOL(p(147, s)), p, o, s) # define BOOST_PP_WHILE_147(p, o, s) BOOST_PP_WHILE_147_C(BOOST_PP_BOOL(p(148, s)), p, o, s) # define BOOST_PP_WHILE_148(p, o, s) BOOST_PP_WHILE_148_C(BOOST_PP_BOOL(p(149, s)), p, o, s) # define BOOST_PP_WHILE_149(p, o, s) BOOST_PP_WHILE_149_C(BOOST_PP_BOOL(p(150, s)), p, o, s) # define BOOST_PP_WHILE_150(p, o, s) BOOST_PP_WHILE_150_C(BOOST_PP_BOOL(p(151, s)), p, o, s) # define BOOST_PP_WHILE_151(p, o, s) BOOST_PP_WHILE_151_C(BOOST_PP_BOOL(p(152, s)), p, o, s) # define BOOST_PP_WHILE_152(p, o, s) BOOST_PP_WHILE_152_C(BOOST_PP_BOOL(p(153, s)), p, o, s) # define BOOST_PP_WHILE_153(p, o, s) BOOST_PP_WHILE_153_C(BOOST_PP_BOOL(p(154, s)), p, o, s) # define BOOST_PP_WHILE_154(p, o, s) BOOST_PP_WHILE_154_C(BOOST_PP_BOOL(p(155, s)), p, o, s) # define BOOST_PP_WHILE_155(p, o, s) BOOST_PP_WHILE_155_C(BOOST_PP_BOOL(p(156, s)), p, o, s) # define BOOST_PP_WHILE_156(p, o, s) BOOST_PP_WHILE_156_C(BOOST_PP_BOOL(p(157, s)), p, o, s) # define BOOST_PP_WHILE_157(p, o, s) BOOST_PP_WHILE_157_C(BOOST_PP_BOOL(p(158, s)), p, o, s) # define BOOST_PP_WHILE_158(p, o, s) BOOST_PP_WHILE_158_C(BOOST_PP_BOOL(p(159, s)), p, o, s) # define BOOST_PP_WHILE_159(p, o, s) BOOST_PP_WHILE_159_C(BOOST_PP_BOOL(p(160, s)), p, o, s) # define BOOST_PP_WHILE_160(p, o, s) BOOST_PP_WHILE_160_C(BOOST_PP_BOOL(p(161, s)), p, o, s) # define BOOST_PP_WHILE_161(p, o, s) BOOST_PP_WHILE_161_C(BOOST_PP_BOOL(p(162, s)), p, o, s) # define BOOST_PP_WHILE_162(p, o, s) BOOST_PP_WHILE_162_C(BOOST_PP_BOOL(p(163, s)), p, o, s) # define BOOST_PP_WHILE_163(p, o, s) BOOST_PP_WHILE_163_C(BOOST_PP_BOOL(p(164, s)), p, o, s) # define BOOST_PP_WHILE_164(p, o, s) BOOST_PP_WHILE_164_C(BOOST_PP_BOOL(p(165, s)), p, o, s) # define BOOST_PP_WHILE_165(p, o, s) BOOST_PP_WHILE_165_C(BOOST_PP_BOOL(p(166, s)), p, o, s) # define BOOST_PP_WHILE_166(p, o, s) BOOST_PP_WHILE_166_C(BOOST_PP_BOOL(p(167, s)), p, o, s) # define BOOST_PP_WHILE_167(p, o, s) BOOST_PP_WHILE_167_C(BOOST_PP_BOOL(p(168, s)), p, o, s) # define BOOST_PP_WHILE_168(p, o, s) BOOST_PP_WHILE_168_C(BOOST_PP_BOOL(p(169, s)), p, o, s) # define BOOST_PP_WHILE_169(p, o, s) BOOST_PP_WHILE_169_C(BOOST_PP_BOOL(p(170, s)), p, o, s) # define BOOST_PP_WHILE_170(p, o, s) BOOST_PP_WHILE_170_C(BOOST_PP_BOOL(p(171, s)), p, o, s) # define BOOST_PP_WHILE_171(p, o, s) BOOST_PP_WHILE_171_C(BOOST_PP_BOOL(p(172, s)), p, o, s) # define BOOST_PP_WHILE_172(p, o, s) BOOST_PP_WHILE_172_C(BOOST_PP_BOOL(p(173, s)), p, o, s) # define BOOST_PP_WHILE_173(p, o, s) BOOST_PP_WHILE_173_C(BOOST_PP_BOOL(p(174, s)), p, o, s) # define BOOST_PP_WHILE_174(p, o, s) BOOST_PP_WHILE_174_C(BOOST_PP_BOOL(p(175, s)), p, o, s) # define BOOST_PP_WHILE_175(p, o, s) BOOST_PP_WHILE_175_C(BOOST_PP_BOOL(p(176, s)), p, o, s) # define BOOST_PP_WHILE_176(p, o, s) BOOST_PP_WHILE_176_C(BOOST_PP_BOOL(p(177, s)), p, o, s) # define BOOST_PP_WHILE_177(p, o, s) BOOST_PP_WHILE_177_C(BOOST_PP_BOOL(p(178, s)), p, o, s) # define BOOST_PP_WHILE_178(p, o, s) BOOST_PP_WHILE_178_C(BOOST_PP_BOOL(p(179, s)), p, o, s) # define BOOST_PP_WHILE_179(p, o, s) BOOST_PP_WHILE_179_C(BOOST_PP_BOOL(p(180, s)), p, o, s) # define BOOST_PP_WHILE_180(p, o, s) BOOST_PP_WHILE_180_C(BOOST_PP_BOOL(p(181, s)), p, o, s) # define BOOST_PP_WHILE_181(p, o, s) BOOST_PP_WHILE_181_C(BOOST_PP_BOOL(p(182, s)), p, o, s) # define BOOST_PP_WHILE_182(p, o, s) BOOST_PP_WHILE_182_C(BOOST_PP_BOOL(p(183, s)), p, o, s) # define BOOST_PP_WHILE_183(p, o, s) BOOST_PP_WHILE_183_C(BOOST_PP_BOOL(p(184, s)), p, o, s) # define BOOST_PP_WHILE_184(p, o, s) BOOST_PP_WHILE_184_C(BOOST_PP_BOOL(p(185, s)), p, o, s) # define BOOST_PP_WHILE_185(p, o, s) BOOST_PP_WHILE_185_C(BOOST_PP_BOOL(p(186, s)), p, o, s) # define BOOST_PP_WHILE_186(p, o, s) BOOST_PP_WHILE_186_C(BOOST_PP_BOOL(p(187, s)), p, o, s) # define BOOST_PP_WHILE_187(p, o, s) BOOST_PP_WHILE_187_C(BOOST_PP_BOOL(p(188, s)), p, o, s) # define BOOST_PP_WHILE_188(p, o, s) BOOST_PP_WHILE_188_C(BOOST_PP_BOOL(p(189, s)), p, o, s) # define BOOST_PP_WHILE_189(p, o, s) BOOST_PP_WHILE_189_C(BOOST_PP_BOOL(p(190, s)), p, o, s) # define BOOST_PP_WHILE_190(p, o, s) BOOST_PP_WHILE_190_C(BOOST_PP_BOOL(p(191, s)), p, o, s) # define BOOST_PP_WHILE_191(p, o, s) BOOST_PP_WHILE_191_C(BOOST_PP_BOOL(p(192, s)), p, o, s) # define BOOST_PP_WHILE_192(p, o, s) BOOST_PP_WHILE_192_C(BOOST_PP_BOOL(p(193, s)), p, o, s) # define BOOST_PP_WHILE_193(p, o, s) BOOST_PP_WHILE_193_C(BOOST_PP_BOOL(p(194, s)), p, o, s) # define BOOST_PP_WHILE_194(p, o, s) BOOST_PP_WHILE_194_C(BOOST_PP_BOOL(p(195, s)), p, o, s) # define BOOST_PP_WHILE_195(p, o, s) BOOST_PP_WHILE_195_C(BOOST_PP_BOOL(p(196, s)), p, o, s) # define BOOST_PP_WHILE_196(p, o, s) BOOST_PP_WHILE_196_C(BOOST_PP_BOOL(p(197, s)), p, o, s) # define BOOST_PP_WHILE_197(p, o, s) BOOST_PP_WHILE_197_C(BOOST_PP_BOOL(p(198, s)), p, o, s) # define BOOST_PP_WHILE_198(p, o, s) BOOST_PP_WHILE_198_C(BOOST_PP_BOOL(p(199, s)), p, o, s) # define BOOST_PP_WHILE_199(p, o, s) BOOST_PP_WHILE_199_C(BOOST_PP_BOOL(p(200, s)), p, o, s) # define BOOST_PP_WHILE_200(p, o, s) BOOST_PP_WHILE_200_C(BOOST_PP_BOOL(p(201, s)), p, o, s) # define BOOST_PP_WHILE_201(p, o, s) BOOST_PP_WHILE_201_C(BOOST_PP_BOOL(p(202, s)), p, o, s) # define BOOST_PP_WHILE_202(p, o, s) BOOST_PP_WHILE_202_C(BOOST_PP_BOOL(p(203, s)), p, o, s) # define BOOST_PP_WHILE_203(p, o, s) BOOST_PP_WHILE_203_C(BOOST_PP_BOOL(p(204, s)), p, o, s) # define BOOST_PP_WHILE_204(p, o, s) BOOST_PP_WHILE_204_C(BOOST_PP_BOOL(p(205, s)), p, o, s) # define BOOST_PP_WHILE_205(p, o, s) BOOST_PP_WHILE_205_C(BOOST_PP_BOOL(p(206, s)), p, o, s) # define BOOST_PP_WHILE_206(p, o, s) BOOST_PP_WHILE_206_C(BOOST_PP_BOOL(p(207, s)), p, o, s) # define BOOST_PP_WHILE_207(p, o, s) BOOST_PP_WHILE_207_C(BOOST_PP_BOOL(p(208, s)), p, o, s) # define BOOST_PP_WHILE_208(p, o, s) BOOST_PP_WHILE_208_C(BOOST_PP_BOOL(p(209, s)), p, o, s) # define BOOST_PP_WHILE_209(p, o, s) BOOST_PP_WHILE_209_C(BOOST_PP_BOOL(p(210, s)), p, o, s) # define BOOST_PP_WHILE_210(p, o, s) BOOST_PP_WHILE_210_C(BOOST_PP_BOOL(p(211, s)), p, o, s) # define BOOST_PP_WHILE_211(p, o, s) BOOST_PP_WHILE_211_C(BOOST_PP_BOOL(p(212, s)), p, o, s) # define BOOST_PP_WHILE_212(p, o, s) BOOST_PP_WHILE_212_C(BOOST_PP_BOOL(p(213, s)), p, o, s) # define BOOST_PP_WHILE_213(p, o, s) BOOST_PP_WHILE_213_C(BOOST_PP_BOOL(p(214, s)), p, o, s) # define BOOST_PP_WHILE_214(p, o, s) BOOST_PP_WHILE_214_C(BOOST_PP_BOOL(p(215, s)), p, o, s) # define BOOST_PP_WHILE_215(p, o, s) BOOST_PP_WHILE_215_C(BOOST_PP_BOOL(p(216, s)), p, o, s) # define BOOST_PP_WHILE_216(p, o, s) BOOST_PP_WHILE_216_C(BOOST_PP_BOOL(p(217, s)), p, o, s) # define BOOST_PP_WHILE_217(p, o, s) BOOST_PP_WHILE_217_C(BOOST_PP_BOOL(p(218, s)), p, o, s) # define BOOST_PP_WHILE_218(p, o, s) BOOST_PP_WHILE_218_C(BOOST_PP_BOOL(p(219, s)), p, o, s) # define BOOST_PP_WHILE_219(p, o, s) BOOST_PP_WHILE_219_C(BOOST_PP_BOOL(p(220, s)), p, o, s) # define BOOST_PP_WHILE_220(p, o, s) BOOST_PP_WHILE_220_C(BOOST_PP_BOOL(p(221, s)), p, o, s) # define BOOST_PP_WHILE_221(p, o, s) BOOST_PP_WHILE_221_C(BOOST_PP_BOOL(p(222, s)), p, o, s) # define BOOST_PP_WHILE_222(p, o, s) BOOST_PP_WHILE_222_C(BOOST_PP_BOOL(p(223, s)), p, o, s) # define BOOST_PP_WHILE_223(p, o, s) BOOST_PP_WHILE_223_C(BOOST_PP_BOOL(p(224, s)), p, o, s) # define BOOST_PP_WHILE_224(p, o, s) BOOST_PP_WHILE_224_C(BOOST_PP_BOOL(p(225, s)), p, o, s) # define BOOST_PP_WHILE_225(p, o, s) BOOST_PP_WHILE_225_C(BOOST_PP_BOOL(p(226, s)), p, o, s) # define BOOST_PP_WHILE_226(p, o, s) BOOST_PP_WHILE_226_C(BOOST_PP_BOOL(p(227, s)), p, o, s) # define BOOST_PP_WHILE_227(p, o, s) BOOST_PP_WHILE_227_C(BOOST_PP_BOOL(p(228, s)), p, o, s) # define BOOST_PP_WHILE_228(p, o, s) BOOST_PP_WHILE_228_C(BOOST_PP_BOOL(p(229, s)), p, o, s) # define BOOST_PP_WHILE_229(p, o, s) BOOST_PP_WHILE_229_C(BOOST_PP_BOOL(p(230, s)), p, o, s) # define BOOST_PP_WHILE_230(p, o, s) BOOST_PP_WHILE_230_C(BOOST_PP_BOOL(p(231, s)), p, o, s) # define BOOST_PP_WHILE_231(p, o, s) BOOST_PP_WHILE_231_C(BOOST_PP_BOOL(p(232, s)), p, o, s) # define BOOST_PP_WHILE_232(p, o, s) BOOST_PP_WHILE_232_C(BOOST_PP_BOOL(p(233, s)), p, o, s) # define BOOST_PP_WHILE_233(p, o, s) BOOST_PP_WHILE_233_C(BOOST_PP_BOOL(p(234, s)), p, o, s) # define BOOST_PP_WHILE_234(p, o, s) BOOST_PP_WHILE_234_C(BOOST_PP_BOOL(p(235, s)), p, o, s) # define BOOST_PP_WHILE_235(p, o, s) BOOST_PP_WHILE_235_C(BOOST_PP_BOOL(p(236, s)), p, o, s) # define BOOST_PP_WHILE_236(p, o, s) BOOST_PP_WHILE_236_C(BOOST_PP_BOOL(p(237, s)), p, o, s) # define BOOST_PP_WHILE_237(p, o, s) BOOST_PP_WHILE_237_C(BOOST_PP_BOOL(p(238, s)), p, o, s) # define BOOST_PP_WHILE_238(p, o, s) BOOST_PP_WHILE_238_C(BOOST_PP_BOOL(p(239, s)), p, o, s) # define BOOST_PP_WHILE_239(p, o, s) BOOST_PP_WHILE_239_C(BOOST_PP_BOOL(p(240, s)), p, o, s) # define BOOST_PP_WHILE_240(p, o, s) BOOST_PP_WHILE_240_C(BOOST_PP_BOOL(p(241, s)), p, o, s) # define BOOST_PP_WHILE_241(p, o, s) BOOST_PP_WHILE_241_C(BOOST_PP_BOOL(p(242, s)), p, o, s) # define BOOST_PP_WHILE_242(p, o, s) BOOST_PP_WHILE_242_C(BOOST_PP_BOOL(p(243, s)), p, o, s) # define BOOST_PP_WHILE_243(p, o, s) BOOST_PP_WHILE_243_C(BOOST_PP_BOOL(p(244, s)), p, o, s) # define BOOST_PP_WHILE_244(p, o, s) BOOST_PP_WHILE_244_C(BOOST_PP_BOOL(p(245, s)), p, o, s) # define BOOST_PP_WHILE_245(p, o, s) BOOST_PP_WHILE_245_C(BOOST_PP_BOOL(p(246, s)), p, o, s) # define BOOST_PP_WHILE_246(p, o, s) BOOST_PP_WHILE_246_C(BOOST_PP_BOOL(p(247, s)), p, o, s) # define BOOST_PP_WHILE_247(p, o, s) BOOST_PP_WHILE_247_C(BOOST_PP_BOOL(p(248, s)), p, o, s) # define BOOST_PP_WHILE_248(p, o, s) BOOST_PP_WHILE_248_C(BOOST_PP_BOOL(p(249, s)), p, o, s) # define BOOST_PP_WHILE_249(p, o, s) BOOST_PP_WHILE_249_C(BOOST_PP_BOOL(p(250, s)), p, o, s) # define BOOST_PP_WHILE_250(p, o, s) BOOST_PP_WHILE_250_C(BOOST_PP_BOOL(p(251, s)), p, o, s) # define BOOST_PP_WHILE_251(p, o, s) BOOST_PP_WHILE_251_C(BOOST_PP_BOOL(p(252, s)), p, o, s) # define BOOST_PP_WHILE_252(p, o, s) BOOST_PP_WHILE_252_C(BOOST_PP_BOOL(p(253, s)), p, o, s) # define BOOST_PP_WHILE_253(p, o, s) BOOST_PP_WHILE_253_C(BOOST_PP_BOOL(p(254, s)), p, o, s) # define BOOST_PP_WHILE_254(p, o, s) BOOST_PP_WHILE_254_C(BOOST_PP_BOOL(p(255, s)), p, o, s) # define BOOST_PP_WHILE_255(p, o, s) BOOST_PP_WHILE_255_C(BOOST_PP_BOOL(p(256, s)), p, o, s) # define BOOST_PP_WHILE_256(p, o, s) BOOST_PP_WHILE_256_C(BOOST_PP_BOOL(p(257, s)), p, o, s) # # define BOOST_PP_WHILE_1_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_2, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(2, s)) # define BOOST_PP_WHILE_2_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_3, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(3, s)) # define BOOST_PP_WHILE_3_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_4, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(4, s)) # define BOOST_PP_WHILE_4_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_5, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(5, s)) # define BOOST_PP_WHILE_5_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_6, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(6, s)) # define BOOST_PP_WHILE_6_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_7, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(7, s)) # define BOOST_PP_WHILE_7_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_8, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(8, s)) # define BOOST_PP_WHILE_8_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_9, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(9, s)) # define BOOST_PP_WHILE_9_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_10, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(10, s)) # define BOOST_PP_WHILE_10_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_11, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(11, s)) # define BOOST_PP_WHILE_11_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_12, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(12, s)) # define BOOST_PP_WHILE_12_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_13, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(13, s)) # define BOOST_PP_WHILE_13_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_14, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(14, s)) # define BOOST_PP_WHILE_14_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_15, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(15, s)) # define BOOST_PP_WHILE_15_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_16, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(16, s)) # define BOOST_PP_WHILE_16_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_17, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(17, s)) # define BOOST_PP_WHILE_17_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_18, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(18, s)) # define BOOST_PP_WHILE_18_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_19, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(19, s)) # define BOOST_PP_WHILE_19_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_20, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(20, s)) # define BOOST_PP_WHILE_20_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_21, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(21, s)) # define BOOST_PP_WHILE_21_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_22, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(22, s)) # define BOOST_PP_WHILE_22_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_23, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(23, s)) # define BOOST_PP_WHILE_23_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_24, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(24, s)) # define BOOST_PP_WHILE_24_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_25, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(25, s)) # define BOOST_PP_WHILE_25_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_26, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(26, s)) # define BOOST_PP_WHILE_26_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_27, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(27, s)) # define BOOST_PP_WHILE_27_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_28, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(28, s)) # define BOOST_PP_WHILE_28_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_29, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(29, s)) # define BOOST_PP_WHILE_29_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_30, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(30, s)) # define BOOST_PP_WHILE_30_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_31, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(31, s)) # define BOOST_PP_WHILE_31_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_32, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(32, s)) # define BOOST_PP_WHILE_32_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_33, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(33, s)) # define BOOST_PP_WHILE_33_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_34, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(34, s)) # define BOOST_PP_WHILE_34_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_35, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(35, s)) # define BOOST_PP_WHILE_35_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_36, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(36, s)) # define BOOST_PP_WHILE_36_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_37, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(37, s)) # define BOOST_PP_WHILE_37_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_38, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(38, s)) # define BOOST_PP_WHILE_38_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_39, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(39, s)) # define BOOST_PP_WHILE_39_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_40, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(40, s)) # define BOOST_PP_WHILE_40_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_41, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(41, s)) # define BOOST_PP_WHILE_41_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_42, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(42, s)) # define BOOST_PP_WHILE_42_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_43, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(43, s)) # define BOOST_PP_WHILE_43_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_44, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(44, s)) # define BOOST_PP_WHILE_44_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_45, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(45, s)) # define BOOST_PP_WHILE_45_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_46, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(46, s)) # define BOOST_PP_WHILE_46_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_47, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(47, s)) # define BOOST_PP_WHILE_47_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_48, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(48, s)) # define BOOST_PP_WHILE_48_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_49, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(49, s)) # define BOOST_PP_WHILE_49_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_50, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(50, s)) # define BOOST_PP_WHILE_50_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_51, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(51, s)) # define BOOST_PP_WHILE_51_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_52, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(52, s)) # define BOOST_PP_WHILE_52_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_53, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(53, s)) # define BOOST_PP_WHILE_53_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_54, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(54, s)) # define BOOST_PP_WHILE_54_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_55, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(55, s)) # define BOOST_PP_WHILE_55_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_56, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(56, s)) # define BOOST_PP_WHILE_56_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_57, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(57, s)) # define BOOST_PP_WHILE_57_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_58, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(58, s)) # define BOOST_PP_WHILE_58_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_59, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(59, s)) # define BOOST_PP_WHILE_59_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_60, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(60, s)) # define BOOST_PP_WHILE_60_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_61, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(61, s)) # define BOOST_PP_WHILE_61_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_62, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(62, s)) # define BOOST_PP_WHILE_62_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_63, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(63, s)) # define BOOST_PP_WHILE_63_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_64, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(64, s)) # define BOOST_PP_WHILE_64_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_65, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(65, s)) # define BOOST_PP_WHILE_65_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_66, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(66, s)) # define BOOST_PP_WHILE_66_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_67, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(67, s)) # define BOOST_PP_WHILE_67_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_68, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(68, s)) # define BOOST_PP_WHILE_68_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_69, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(69, s)) # define BOOST_PP_WHILE_69_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_70, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(70, s)) # define BOOST_PP_WHILE_70_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_71, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(71, s)) # define BOOST_PP_WHILE_71_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_72, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(72, s)) # define BOOST_PP_WHILE_72_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_73, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(73, s)) # define BOOST_PP_WHILE_73_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_74, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(74, s)) # define BOOST_PP_WHILE_74_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_75, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(75, s)) # define BOOST_PP_WHILE_75_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_76, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(76, s)) # define BOOST_PP_WHILE_76_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_77, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(77, s)) # define BOOST_PP_WHILE_77_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_78, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(78, s)) # define BOOST_PP_WHILE_78_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_79, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(79, s)) # define BOOST_PP_WHILE_79_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_80, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(80, s)) # define BOOST_PP_WHILE_80_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_81, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(81, s)) # define BOOST_PP_WHILE_81_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_82, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(82, s)) # define BOOST_PP_WHILE_82_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_83, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(83, s)) # define BOOST_PP_WHILE_83_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_84, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(84, s)) # define BOOST_PP_WHILE_84_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_85, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(85, s)) # define BOOST_PP_WHILE_85_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_86, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(86, s)) # define BOOST_PP_WHILE_86_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_87, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(87, s)) # define BOOST_PP_WHILE_87_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_88, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(88, s)) # define BOOST_PP_WHILE_88_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_89, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(89, s)) # define BOOST_PP_WHILE_89_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_90, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(90, s)) # define BOOST_PP_WHILE_90_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_91, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(91, s)) # define BOOST_PP_WHILE_91_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_92, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(92, s)) # define BOOST_PP_WHILE_92_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_93, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(93, s)) # define BOOST_PP_WHILE_93_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_94, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(94, s)) # define BOOST_PP_WHILE_94_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_95, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(95, s)) # define BOOST_PP_WHILE_95_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_96, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(96, s)) # define BOOST_PP_WHILE_96_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_97, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(97, s)) # define BOOST_PP_WHILE_97_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_98, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(98, s)) # define BOOST_PP_WHILE_98_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_99, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(99, s)) # define BOOST_PP_WHILE_99_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_100, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(100, s)) # define BOOST_PP_WHILE_100_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_101, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(101, s)) # define BOOST_PP_WHILE_101_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_102, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(102, s)) # define BOOST_PP_WHILE_102_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_103, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(103, s)) # define BOOST_PP_WHILE_103_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_104, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(104, s)) # define BOOST_PP_WHILE_104_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_105, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(105, s)) # define BOOST_PP_WHILE_105_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_106, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(106, s)) # define BOOST_PP_WHILE_106_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_107, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(107, s)) # define BOOST_PP_WHILE_107_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_108, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(108, s)) # define BOOST_PP_WHILE_108_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_109, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(109, s)) # define BOOST_PP_WHILE_109_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_110, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(110, s)) # define BOOST_PP_WHILE_110_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_111, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(111, s)) # define BOOST_PP_WHILE_111_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_112, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(112, s)) # define BOOST_PP_WHILE_112_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_113, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(113, s)) # define BOOST_PP_WHILE_113_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_114, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(114, s)) # define BOOST_PP_WHILE_114_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_115, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(115, s)) # define BOOST_PP_WHILE_115_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_116, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(116, s)) # define BOOST_PP_WHILE_116_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_117, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(117, s)) # define BOOST_PP_WHILE_117_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_118, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(118, s)) # define BOOST_PP_WHILE_118_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_119, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(119, s)) # define BOOST_PP_WHILE_119_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_120, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(120, s)) # define BOOST_PP_WHILE_120_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_121, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(121, s)) # define BOOST_PP_WHILE_121_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_122, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(122, s)) # define BOOST_PP_WHILE_122_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_123, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(123, s)) # define BOOST_PP_WHILE_123_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_124, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(124, s)) # define BOOST_PP_WHILE_124_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_125, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(125, s)) # define BOOST_PP_WHILE_125_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_126, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(126, s)) # define BOOST_PP_WHILE_126_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_127, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(127, s)) # define BOOST_PP_WHILE_127_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_128, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(128, s)) # define BOOST_PP_WHILE_128_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_129, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(129, s)) # define BOOST_PP_WHILE_129_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_130, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(130, s)) # define BOOST_PP_WHILE_130_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_131, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(131, s)) # define BOOST_PP_WHILE_131_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_132, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(132, s)) # define BOOST_PP_WHILE_132_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_133, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(133, s)) # define BOOST_PP_WHILE_133_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_134, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(134, s)) # define BOOST_PP_WHILE_134_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_135, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(135, s)) # define BOOST_PP_WHILE_135_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_136, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(136, s)) # define BOOST_PP_WHILE_136_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_137, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(137, s)) # define BOOST_PP_WHILE_137_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_138, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(138, s)) # define BOOST_PP_WHILE_138_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_139, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(139, s)) # define BOOST_PP_WHILE_139_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_140, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(140, s)) # define BOOST_PP_WHILE_140_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_141, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(141, s)) # define BOOST_PP_WHILE_141_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_142, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(142, s)) # define BOOST_PP_WHILE_142_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_143, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(143, s)) # define BOOST_PP_WHILE_143_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_144, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(144, s)) # define BOOST_PP_WHILE_144_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_145, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(145, s)) # define BOOST_PP_WHILE_145_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_146, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(146, s)) # define BOOST_PP_WHILE_146_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_147, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(147, s)) # define BOOST_PP_WHILE_147_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_148, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(148, s)) # define BOOST_PP_WHILE_148_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_149, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(149, s)) # define BOOST_PP_WHILE_149_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_150, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(150, s)) # define BOOST_PP_WHILE_150_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_151, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(151, s)) # define BOOST_PP_WHILE_151_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_152, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(152, s)) # define BOOST_PP_WHILE_152_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_153, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(153, s)) # define BOOST_PP_WHILE_153_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_154, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(154, s)) # define BOOST_PP_WHILE_154_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_155, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(155, s)) # define BOOST_PP_WHILE_155_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_156, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(156, s)) # define BOOST_PP_WHILE_156_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_157, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(157, s)) # define BOOST_PP_WHILE_157_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_158, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(158, s)) # define BOOST_PP_WHILE_158_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_159, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(159, s)) # define BOOST_PP_WHILE_159_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_160, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(160, s)) # define BOOST_PP_WHILE_160_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_161, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(161, s)) # define BOOST_PP_WHILE_161_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_162, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(162, s)) # define BOOST_PP_WHILE_162_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_163, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(163, s)) # define BOOST_PP_WHILE_163_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_164, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(164, s)) # define BOOST_PP_WHILE_164_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_165, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(165, s)) # define BOOST_PP_WHILE_165_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_166, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(166, s)) # define BOOST_PP_WHILE_166_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_167, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(167, s)) # define BOOST_PP_WHILE_167_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_168, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(168, s)) # define BOOST_PP_WHILE_168_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_169, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(169, s)) # define BOOST_PP_WHILE_169_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_170, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(170, s)) # define BOOST_PP_WHILE_170_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_171, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(171, s)) # define BOOST_PP_WHILE_171_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_172, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(172, s)) # define BOOST_PP_WHILE_172_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_173, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(173, s)) # define BOOST_PP_WHILE_173_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_174, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(174, s)) # define BOOST_PP_WHILE_174_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_175, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(175, s)) # define BOOST_PP_WHILE_175_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_176, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(176, s)) # define BOOST_PP_WHILE_176_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_177, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(177, s)) # define BOOST_PP_WHILE_177_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_178, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(178, s)) # define BOOST_PP_WHILE_178_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_179, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(179, s)) # define BOOST_PP_WHILE_179_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_180, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(180, s)) # define BOOST_PP_WHILE_180_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_181, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(181, s)) # define BOOST_PP_WHILE_181_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_182, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(182, s)) # define BOOST_PP_WHILE_182_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_183, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(183, s)) # define BOOST_PP_WHILE_183_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_184, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(184, s)) # define BOOST_PP_WHILE_184_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_185, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(185, s)) # define BOOST_PP_WHILE_185_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_186, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(186, s)) # define BOOST_PP_WHILE_186_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_187, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(187, s)) # define BOOST_PP_WHILE_187_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_188, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(188, s)) # define BOOST_PP_WHILE_188_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_189, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(189, s)) # define BOOST_PP_WHILE_189_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_190, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(190, s)) # define BOOST_PP_WHILE_190_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_191, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(191, s)) # define BOOST_PP_WHILE_191_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_192, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(192, s)) # define BOOST_PP_WHILE_192_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_193, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(193, s)) # define BOOST_PP_WHILE_193_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_194, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(194, s)) # define BOOST_PP_WHILE_194_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_195, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(195, s)) # define BOOST_PP_WHILE_195_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_196, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(196, s)) # define BOOST_PP_WHILE_196_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_197, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(197, s)) # define BOOST_PP_WHILE_197_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_198, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(198, s)) # define BOOST_PP_WHILE_198_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_199, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(199, s)) # define BOOST_PP_WHILE_199_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_200, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(200, s)) # define BOOST_PP_WHILE_200_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_201, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(201, s)) # define BOOST_PP_WHILE_201_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_202, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(202, s)) # define BOOST_PP_WHILE_202_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_203, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(203, s)) # define BOOST_PP_WHILE_203_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_204, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(204, s)) # define BOOST_PP_WHILE_204_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_205, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(205, s)) # define BOOST_PP_WHILE_205_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_206, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(206, s)) # define BOOST_PP_WHILE_206_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_207, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(207, s)) # define BOOST_PP_WHILE_207_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_208, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(208, s)) # define BOOST_PP_WHILE_208_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_209, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(209, s)) # define BOOST_PP_WHILE_209_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_210, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(210, s)) # define BOOST_PP_WHILE_210_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_211, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(211, s)) # define BOOST_PP_WHILE_211_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_212, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(212, s)) # define BOOST_PP_WHILE_212_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_213, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(213, s)) # define BOOST_PP_WHILE_213_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_214, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(214, s)) # define BOOST_PP_WHILE_214_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_215, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(215, s)) # define BOOST_PP_WHILE_215_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_216, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(216, s)) # define BOOST_PP_WHILE_216_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_217, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(217, s)) # define BOOST_PP_WHILE_217_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_218, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(218, s)) # define BOOST_PP_WHILE_218_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_219, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(219, s)) # define BOOST_PP_WHILE_219_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_220, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(220, s)) # define BOOST_PP_WHILE_220_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_221, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(221, s)) # define BOOST_PP_WHILE_221_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_222, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(222, s)) # define BOOST_PP_WHILE_222_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_223, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(223, s)) # define BOOST_PP_WHILE_223_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_224, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(224, s)) # define BOOST_PP_WHILE_224_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_225, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(225, s)) # define BOOST_PP_WHILE_225_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_226, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(226, s)) # define BOOST_PP_WHILE_226_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_227, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(227, s)) # define BOOST_PP_WHILE_227_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_228, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(228, s)) # define BOOST_PP_WHILE_228_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_229, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(229, s)) # define BOOST_PP_WHILE_229_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_230, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(230, s)) # define BOOST_PP_WHILE_230_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_231, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(231, s)) # define BOOST_PP_WHILE_231_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_232, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(232, s)) # define BOOST_PP_WHILE_232_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_233, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(233, s)) # define BOOST_PP_WHILE_233_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_234, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(234, s)) # define BOOST_PP_WHILE_234_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_235, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(235, s)) # define BOOST_PP_WHILE_235_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_236, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(236, s)) # define BOOST_PP_WHILE_236_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_237, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(237, s)) # define BOOST_PP_WHILE_237_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_238, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(238, s)) # define BOOST_PP_WHILE_238_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_239, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(239, s)) # define BOOST_PP_WHILE_239_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_240, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(240, s)) # define BOOST_PP_WHILE_240_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_241, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(241, s)) # define BOOST_PP_WHILE_241_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_242, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(242, s)) # define BOOST_PP_WHILE_242_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_243, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(243, s)) # define BOOST_PP_WHILE_243_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_244, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(244, s)) # define BOOST_PP_WHILE_244_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_245, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(245, s)) # define BOOST_PP_WHILE_245_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_246, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(246, s)) # define BOOST_PP_WHILE_246_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_247, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(247, s)) # define BOOST_PP_WHILE_247_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_248, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(248, s)) # define BOOST_PP_WHILE_248_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_249, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(249, s)) # define BOOST_PP_WHILE_249_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_250, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(250, s)) # define BOOST_PP_WHILE_250_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_251, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(251, s)) # define BOOST_PP_WHILE_251_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_252, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(252, s)) # define BOOST_PP_WHILE_252_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_253, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(253, s)) # define BOOST_PP_WHILE_253_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_254, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(254, s)) # define BOOST_PP_WHILE_254_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_255, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(255, s)) # define BOOST_PP_WHILE_255_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_256, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(256, s)) # define BOOST_PP_WHILE_256_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_257, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(257, s)) # # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/expr_if.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_EXPR_IF_HPP # define BOOST_PREPROCESSOR_CONTROL_EXPR_IF_HPP # # include # include # include # # /* BOOST_PP_EXPR_IF */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_EXPR_IF(cond, expr) BOOST_PP_EXPR_IIF(BOOST_PP_BOOL(cond), expr) # else # define BOOST_PP_EXPR_IF(cond, expr) BOOST_PP_EXPR_IF_I(cond, expr) # define BOOST_PP_EXPR_IF_I(cond, expr) BOOST_PP_EXPR_IIF(BOOST_PP_BOOL(cond), expr) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/expr_iif.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_EXPR_IIF_HPP # define BOOST_PREPROCESSOR_CONTROL_EXPR_IIF_HPP # # include # # /* BOOST_PP_EXPR_IIF */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_EXPR_IIF(bit, expr) BOOST_PP_EXPR_IIF_I(bit, expr) # else # define BOOST_PP_EXPR_IIF(bit, expr) BOOST_PP_EXPR_IIF_OO((bit, expr)) # define BOOST_PP_EXPR_IIF_OO(par) BOOST_PP_EXPR_IIF_I ## par # endif # # define BOOST_PP_EXPR_IIF_I(bit, expr) BOOST_PP_EXPR_IIF_ ## bit(expr) # # define BOOST_PP_EXPR_IIF_0(expr) # define BOOST_PP_EXPR_IIF_1(expr) expr # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/if.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_IF_HPP # define BOOST_PREPROCESSOR_CONTROL_IF_HPP # # include # include # include # # /* BOOST_PP_IF */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_IF(cond, t, f) BOOST_PP_IIF(BOOST_PP_BOOL(cond), t, f) # else # define BOOST_PP_IF(cond, t, f) BOOST_PP_IF_I(cond, t, f) # define BOOST_PP_IF_I(cond, t, f) BOOST_PP_IIF(BOOST_PP_BOOL(cond), t, f) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/iif.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_IIF_HPP # define BOOST_PREPROCESSOR_CONTROL_IIF_HPP # # include # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_IIF(bit, t, f) BOOST_PP_IIF_I(bit, t, f) # else # define BOOST_PP_IIF(bit, t, f) BOOST_PP_IIF_OO((bit, t, f)) # define BOOST_PP_IIF_OO(par) BOOST_PP_IIF_I ## par # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_ ## bit(t, f) # else # define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_II(BOOST_PP_IIF_ ## bit(t, f)) # define BOOST_PP_IIF_II(id) id # endif # # define BOOST_PP_IIF_0(t, f) f # define BOOST_PP_IIF_1(t, f) t # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/control/while.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_CONTROL_WHILE_HPP # define BOOST_PREPROCESSOR_CONTROL_WHILE_HPP # # include # include # include # include # include # include # include # # /* BOOST_PP_WHILE */ # # if 0 # define BOOST_PP_WHILE(pred, op, state) # endif # # define BOOST_PP_WHILE BOOST_PP_CAT(BOOST_PP_WHILE_, BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256)) # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_WHILE_P(n) BOOST_PP_BITAND(BOOST_PP_CAT(BOOST_PP_WHILE_CHECK_, BOOST_PP_WHILE_ ## n(BOOST_PP_WHILE_F, BOOST_PP_NIL, BOOST_PP_NIL)), BOOST_PP_BITAND(BOOST_PP_CAT(BOOST_PP_LIST_FOLD_LEFT_CHECK_, BOOST_PP_LIST_FOLD_LEFT_ ## n(BOOST_PP_NIL, BOOST_PP_NIL, BOOST_PP_NIL)), BOOST_PP_CAT(BOOST_PP_LIST_FOLD_RIGHT_CHECK_, BOOST_PP_LIST_FOLD_RIGHT_ ## n(BOOST_PP_NIL, BOOST_PP_NIL, BOOST_PP_NIL)))) # else # define BOOST_PP_WHILE_P(n) BOOST_PP_BITAND(BOOST_PP_CAT(BOOST_PP_WHILE_CHECK_, BOOST_PP_WHILE_ ## n(BOOST_PP_WHILE_F, BOOST_PP_NIL, BOOST_PP_NIL)), BOOST_PP_CAT(BOOST_PP_LIST_FOLD_LEFT_CHECK_, BOOST_PP_LIST_FOLD_LEFT_ ## n(BOOST_PP_NIL, BOOST_PP_NIL, BOOST_PP_NIL))) # endif # # define BOOST_PP_WHILE_F(d, _) 0 # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # include # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # include # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # include # else # include # endif # # define BOOST_PP_WHILE_257(p, o, s) BOOST_PP_ERROR(0x0001) # # define BOOST_PP_WHILE_CHECK_BOOST_PP_NIL 1 # # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_1(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_2(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_3(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_4(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_5(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_6(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_7(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_8(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_9(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_10(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_11(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_12(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_13(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_14(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_15(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_16(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_17(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_18(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_19(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_20(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_21(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_22(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_23(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_24(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_25(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_26(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_27(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_28(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_29(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_30(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_31(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_32(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_33(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_34(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_35(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_36(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_37(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_38(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_39(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_40(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_41(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_42(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_43(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_44(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_45(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_46(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_47(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_48(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_49(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_50(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_51(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_52(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_53(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_54(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_55(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_56(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_57(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_58(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_59(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_60(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_61(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_62(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_63(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_64(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_65(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_66(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_67(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_68(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_69(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_70(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_71(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_72(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_73(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_74(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_75(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_76(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_77(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_78(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_79(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_80(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_81(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_82(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_83(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_84(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_85(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_86(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_87(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_88(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_89(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_90(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_91(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_92(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_93(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_94(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_95(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_96(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_97(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_98(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_99(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_100(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_101(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_102(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_103(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_104(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_105(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_106(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_107(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_108(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_109(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_110(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_111(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_112(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_113(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_114(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_115(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_116(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_117(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_118(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_119(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_120(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_121(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_122(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_123(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_124(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_125(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_126(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_127(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_128(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_129(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_130(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_131(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_132(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_133(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_134(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_135(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_136(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_137(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_138(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_139(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_140(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_141(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_142(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_143(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_144(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_145(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_146(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_147(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_148(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_149(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_150(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_151(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_152(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_153(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_154(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_155(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_156(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_157(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_158(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_159(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_160(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_161(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_162(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_163(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_164(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_165(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_166(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_167(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_168(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_169(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_170(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_171(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_172(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_173(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_174(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_175(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_176(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_177(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_178(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_179(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_180(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_181(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_182(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_183(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_184(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_185(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_186(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_187(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_188(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_189(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_190(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_191(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_192(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_193(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_194(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_195(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_196(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_197(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_198(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_199(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_200(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_201(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_202(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_203(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_204(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_205(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_206(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_207(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_208(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_209(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_210(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_211(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_212(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_213(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_214(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_215(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_216(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_217(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_218(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_219(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_220(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_221(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_222(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_223(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_224(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_225(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_226(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_227(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_228(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_229(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_230(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_231(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_232(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_233(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_234(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_235(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_236(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_237(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_238(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_239(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_240(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_241(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_242(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_243(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_244(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_245(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_246(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_247(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_248(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_249(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_250(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_251(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_252(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_253(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_254(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_255(p, o, s) 0 # define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_256(p, o, s) 0 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/debug/error.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_DEBUG_ERROR_HPP # define BOOST_PREPROCESSOR_DEBUG_ERROR_HPP # # include # include # # /* BOOST_PP_ERROR */ # # if BOOST_PP_CONFIG_ERRORS # define BOOST_PP_ERROR(code) BOOST_PP_CAT(BOOST_PP_ERROR_, code) # endif # # define BOOST_PP_ERROR_0x0000 BOOST_PP_ERROR(0x0000, BOOST_PP_INDEX_OUT_OF_BOUNDS) # define BOOST_PP_ERROR_0x0001 BOOST_PP_ERROR(0x0001, BOOST_PP_WHILE_OVERFLOW) # define BOOST_PP_ERROR_0x0002 BOOST_PP_ERROR(0x0002, BOOST_PP_FOR_OVERFLOW) # define BOOST_PP_ERROR_0x0003 BOOST_PP_ERROR(0x0003, BOOST_PP_REPEAT_OVERFLOW) # define BOOST_PP_ERROR_0x0004 BOOST_PP_ERROR(0x0004, BOOST_PP_LIST_FOLD_OVERFLOW) # define BOOST_PP_ERROR_0x0005 BOOST_PP_ERROR(0x0005, BOOST_PP_SEQ_FOLD_OVERFLOW) # define BOOST_PP_ERROR_0x0006 BOOST_PP_ERROR(0x0006, BOOST_PP_ARITHMETIC_OVERFLOW) # define BOOST_PP_ERROR_0x0007 BOOST_PP_ERROR(0x0007, BOOST_PP_DIVISION_BY_ZERO) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/dec.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_DEC_HPP # define BOOST_PREPROCESSOR_DEC_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/detail/auto_rec.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # include # else # # ifndef BOOST_PREPROCESSOR_DETAIL_AUTO_REC_HPP # define BOOST_PREPROCESSOR_DETAIL_AUTO_REC_HPP # # include # # /* BOOST_PP_AUTO_REC */ # # define BOOST_PP_AUTO_REC(pred, n) BOOST_PP_NODE_ENTRY_ ## n(pred) # # define BOOST_PP_NODE_ENTRY_256(p) BOOST_PP_NODE_128(p)(p)(p)(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_128(p) BOOST_PP_NODE_64(p)(p)(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_64(p) BOOST_PP_NODE_32(p)(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_32(p) BOOST_PP_NODE_16(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_16(p) BOOST_PP_NODE_8(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_8(p) BOOST_PP_NODE_4(p)(p)(p) # define BOOST_PP_NODE_ENTRY_4(p) BOOST_PP_NODE_2(p)(p) # define BOOST_PP_NODE_ENTRY_2(p) BOOST_PP_NODE_1(p) # # define BOOST_PP_NODE_128(p) BOOST_PP_IIF(p(128), BOOST_PP_NODE_64, BOOST_PP_NODE_192) # define BOOST_PP_NODE_64(p) BOOST_PP_IIF(p(64), BOOST_PP_NODE_32, BOOST_PP_NODE_96) # define BOOST_PP_NODE_32(p) BOOST_PP_IIF(p(32), BOOST_PP_NODE_16, BOOST_PP_NODE_48) # define BOOST_PP_NODE_16(p) BOOST_PP_IIF(p(16), BOOST_PP_NODE_8, BOOST_PP_NODE_24) # define BOOST_PP_NODE_8(p) BOOST_PP_IIF(p(8), BOOST_PP_NODE_4, BOOST_PP_NODE_12) # define BOOST_PP_NODE_4(p) BOOST_PP_IIF(p(4), BOOST_PP_NODE_2, BOOST_PP_NODE_6) # define BOOST_PP_NODE_2(p) BOOST_PP_IIF(p(2), BOOST_PP_NODE_1, BOOST_PP_NODE_3) # define BOOST_PP_NODE_1(p) BOOST_PP_IIF(p(1), 1, 2) # define BOOST_PP_NODE_3(p) BOOST_PP_IIF(p(3), 3, 4) # define BOOST_PP_NODE_6(p) BOOST_PP_IIF(p(6), BOOST_PP_NODE_5, BOOST_PP_NODE_7) # define BOOST_PP_NODE_5(p) BOOST_PP_IIF(p(5), 5, 6) # define BOOST_PP_NODE_7(p) BOOST_PP_IIF(p(7), 7, 8) # define BOOST_PP_NODE_12(p) BOOST_PP_IIF(p(12), BOOST_PP_NODE_10, BOOST_PP_NODE_14) # define BOOST_PP_NODE_10(p) BOOST_PP_IIF(p(10), BOOST_PP_NODE_9, BOOST_PP_NODE_11) # define BOOST_PP_NODE_9(p) BOOST_PP_IIF(p(9), 9, 10) # define BOOST_PP_NODE_11(p) BOOST_PP_IIF(p(11), 11, 12) # define BOOST_PP_NODE_14(p) BOOST_PP_IIF(p(14), BOOST_PP_NODE_13, BOOST_PP_NODE_15) # define BOOST_PP_NODE_13(p) BOOST_PP_IIF(p(13), 13, 14) # define BOOST_PP_NODE_15(p) BOOST_PP_IIF(p(15), 15, 16) # define BOOST_PP_NODE_24(p) BOOST_PP_IIF(p(24), BOOST_PP_NODE_20, BOOST_PP_NODE_28) # define BOOST_PP_NODE_20(p) BOOST_PP_IIF(p(20), BOOST_PP_NODE_18, BOOST_PP_NODE_22) # define BOOST_PP_NODE_18(p) BOOST_PP_IIF(p(18), BOOST_PP_NODE_17, BOOST_PP_NODE_19) # define BOOST_PP_NODE_17(p) BOOST_PP_IIF(p(17), 17, 18) # define BOOST_PP_NODE_19(p) BOOST_PP_IIF(p(19), 19, 20) # define BOOST_PP_NODE_22(p) BOOST_PP_IIF(p(22), BOOST_PP_NODE_21, BOOST_PP_NODE_23) # define BOOST_PP_NODE_21(p) BOOST_PP_IIF(p(21), 21, 22) # define BOOST_PP_NODE_23(p) BOOST_PP_IIF(p(23), 23, 24) # define BOOST_PP_NODE_28(p) BOOST_PP_IIF(p(28), BOOST_PP_NODE_26, BOOST_PP_NODE_30) # define BOOST_PP_NODE_26(p) BOOST_PP_IIF(p(26), BOOST_PP_NODE_25, BOOST_PP_NODE_27) # define BOOST_PP_NODE_25(p) BOOST_PP_IIF(p(25), 25, 26) # define BOOST_PP_NODE_27(p) BOOST_PP_IIF(p(27), 27, 28) # define BOOST_PP_NODE_30(p) BOOST_PP_IIF(p(30), BOOST_PP_NODE_29, BOOST_PP_NODE_31) # define BOOST_PP_NODE_29(p) BOOST_PP_IIF(p(29), 29, 30) # define BOOST_PP_NODE_31(p) BOOST_PP_IIF(p(31), 31, 32) # define BOOST_PP_NODE_48(p) BOOST_PP_IIF(p(48), BOOST_PP_NODE_40, BOOST_PP_NODE_56) # define BOOST_PP_NODE_40(p) BOOST_PP_IIF(p(40), BOOST_PP_NODE_36, BOOST_PP_NODE_44) # define BOOST_PP_NODE_36(p) BOOST_PP_IIF(p(36), BOOST_PP_NODE_34, BOOST_PP_NODE_38) # define BOOST_PP_NODE_34(p) BOOST_PP_IIF(p(34), BOOST_PP_NODE_33, BOOST_PP_NODE_35) # define BOOST_PP_NODE_33(p) BOOST_PP_IIF(p(33), 33, 34) # define BOOST_PP_NODE_35(p) BOOST_PP_IIF(p(35), 35, 36) # define BOOST_PP_NODE_38(p) BOOST_PP_IIF(p(38), BOOST_PP_NODE_37, BOOST_PP_NODE_39) # define BOOST_PP_NODE_37(p) BOOST_PP_IIF(p(37), 37, 38) # define BOOST_PP_NODE_39(p) BOOST_PP_IIF(p(39), 39, 40) # define BOOST_PP_NODE_44(p) BOOST_PP_IIF(p(44), BOOST_PP_NODE_42, BOOST_PP_NODE_46) # define BOOST_PP_NODE_42(p) BOOST_PP_IIF(p(42), BOOST_PP_NODE_41, BOOST_PP_NODE_43) # define BOOST_PP_NODE_41(p) BOOST_PP_IIF(p(41), 41, 42) # define BOOST_PP_NODE_43(p) BOOST_PP_IIF(p(43), 43, 44) # define BOOST_PP_NODE_46(p) BOOST_PP_IIF(p(46), BOOST_PP_NODE_45, BOOST_PP_NODE_47) # define BOOST_PP_NODE_45(p) BOOST_PP_IIF(p(45), 45, 46) # define BOOST_PP_NODE_47(p) BOOST_PP_IIF(p(47), 47, 48) # define BOOST_PP_NODE_56(p) BOOST_PP_IIF(p(56), BOOST_PP_NODE_52, BOOST_PP_NODE_60) # define BOOST_PP_NODE_52(p) BOOST_PP_IIF(p(52), BOOST_PP_NODE_50, BOOST_PP_NODE_54) # define BOOST_PP_NODE_50(p) BOOST_PP_IIF(p(50), BOOST_PP_NODE_49, BOOST_PP_NODE_51) # define BOOST_PP_NODE_49(p) BOOST_PP_IIF(p(49), 49, 50) # define BOOST_PP_NODE_51(p) BOOST_PP_IIF(p(51), 51, 52) # define BOOST_PP_NODE_54(p) BOOST_PP_IIF(p(54), BOOST_PP_NODE_53, BOOST_PP_NODE_55) # define BOOST_PP_NODE_53(p) BOOST_PP_IIF(p(53), 53, 54) # define BOOST_PP_NODE_55(p) BOOST_PP_IIF(p(55), 55, 56) # define BOOST_PP_NODE_60(p) BOOST_PP_IIF(p(60), BOOST_PP_NODE_58, BOOST_PP_NODE_62) # define BOOST_PP_NODE_58(p) BOOST_PP_IIF(p(58), BOOST_PP_NODE_57, BOOST_PP_NODE_59) # define BOOST_PP_NODE_57(p) BOOST_PP_IIF(p(57), 57, 58) # define BOOST_PP_NODE_59(p) BOOST_PP_IIF(p(59), 59, 60) # define BOOST_PP_NODE_62(p) BOOST_PP_IIF(p(62), BOOST_PP_NODE_61, BOOST_PP_NODE_63) # define BOOST_PP_NODE_61(p) BOOST_PP_IIF(p(61), 61, 62) # define BOOST_PP_NODE_63(p) BOOST_PP_IIF(p(63), 63, 64) # define BOOST_PP_NODE_96(p) BOOST_PP_IIF(p(96), BOOST_PP_NODE_80, BOOST_PP_NODE_112) # define BOOST_PP_NODE_80(p) BOOST_PP_IIF(p(80), BOOST_PP_NODE_72, BOOST_PP_NODE_88) # define BOOST_PP_NODE_72(p) BOOST_PP_IIF(p(72), BOOST_PP_NODE_68, BOOST_PP_NODE_76) # define BOOST_PP_NODE_68(p) BOOST_PP_IIF(p(68), BOOST_PP_NODE_66, BOOST_PP_NODE_70) # define BOOST_PP_NODE_66(p) BOOST_PP_IIF(p(66), BOOST_PP_NODE_65, BOOST_PP_NODE_67) # define BOOST_PP_NODE_65(p) BOOST_PP_IIF(p(65), 65, 66) # define BOOST_PP_NODE_67(p) BOOST_PP_IIF(p(67), 67, 68) # define BOOST_PP_NODE_70(p) BOOST_PP_IIF(p(70), BOOST_PP_NODE_69, BOOST_PP_NODE_71) # define BOOST_PP_NODE_69(p) BOOST_PP_IIF(p(69), 69, 70) # define BOOST_PP_NODE_71(p) BOOST_PP_IIF(p(71), 71, 72) # define BOOST_PP_NODE_76(p) BOOST_PP_IIF(p(76), BOOST_PP_NODE_74, BOOST_PP_NODE_78) # define BOOST_PP_NODE_74(p) BOOST_PP_IIF(p(74), BOOST_PP_NODE_73, BOOST_PP_NODE_75) # define BOOST_PP_NODE_73(p) BOOST_PP_IIF(p(73), 73, 74) # define BOOST_PP_NODE_75(p) BOOST_PP_IIF(p(75), 75, 76) # define BOOST_PP_NODE_78(p) BOOST_PP_IIF(p(78), BOOST_PP_NODE_77, BOOST_PP_NODE_79) # define BOOST_PP_NODE_77(p) BOOST_PP_IIF(p(77), 77, 78) # define BOOST_PP_NODE_79(p) BOOST_PP_IIF(p(79), 79, 80) # define BOOST_PP_NODE_88(p) BOOST_PP_IIF(p(88), BOOST_PP_NODE_84, BOOST_PP_NODE_92) # define BOOST_PP_NODE_84(p) BOOST_PP_IIF(p(84), BOOST_PP_NODE_82, BOOST_PP_NODE_86) # define BOOST_PP_NODE_82(p) BOOST_PP_IIF(p(82), BOOST_PP_NODE_81, BOOST_PP_NODE_83) # define BOOST_PP_NODE_81(p) BOOST_PP_IIF(p(81), 81, 82) # define BOOST_PP_NODE_83(p) BOOST_PP_IIF(p(83), 83, 84) # define BOOST_PP_NODE_86(p) BOOST_PP_IIF(p(86), BOOST_PP_NODE_85, BOOST_PP_NODE_87) # define BOOST_PP_NODE_85(p) BOOST_PP_IIF(p(85), 85, 86) # define BOOST_PP_NODE_87(p) BOOST_PP_IIF(p(87), 87, 88) # define BOOST_PP_NODE_92(p) BOOST_PP_IIF(p(92), BOOST_PP_NODE_90, BOOST_PP_NODE_94) # define BOOST_PP_NODE_90(p) BOOST_PP_IIF(p(90), BOOST_PP_NODE_89, BOOST_PP_NODE_91) # define BOOST_PP_NODE_89(p) BOOST_PP_IIF(p(89), 89, 90) # define BOOST_PP_NODE_91(p) BOOST_PP_IIF(p(91), 91, 92) # define BOOST_PP_NODE_94(p) BOOST_PP_IIF(p(94), BOOST_PP_NODE_93, BOOST_PP_NODE_95) # define BOOST_PP_NODE_93(p) BOOST_PP_IIF(p(93), 93, 94) # define BOOST_PP_NODE_95(p) BOOST_PP_IIF(p(95), 95, 96) # define BOOST_PP_NODE_112(p) BOOST_PP_IIF(p(112), BOOST_PP_NODE_104, BOOST_PP_NODE_120) # define BOOST_PP_NODE_104(p) BOOST_PP_IIF(p(104), BOOST_PP_NODE_100, BOOST_PP_NODE_108) # define BOOST_PP_NODE_100(p) BOOST_PP_IIF(p(100), BOOST_PP_NODE_98, BOOST_PP_NODE_102) # define BOOST_PP_NODE_98(p) BOOST_PP_IIF(p(98), BOOST_PP_NODE_97, BOOST_PP_NODE_99) # define BOOST_PP_NODE_97(p) BOOST_PP_IIF(p(97), 97, 98) # define BOOST_PP_NODE_99(p) BOOST_PP_IIF(p(99), 99, 100) # define BOOST_PP_NODE_102(p) BOOST_PP_IIF(p(102), BOOST_PP_NODE_101, BOOST_PP_NODE_103) # define BOOST_PP_NODE_101(p) BOOST_PP_IIF(p(101), 101, 102) # define BOOST_PP_NODE_103(p) BOOST_PP_IIF(p(103), 103, 104) # define BOOST_PP_NODE_108(p) BOOST_PP_IIF(p(108), BOOST_PP_NODE_106, BOOST_PP_NODE_110) # define BOOST_PP_NODE_106(p) BOOST_PP_IIF(p(106), BOOST_PP_NODE_105, BOOST_PP_NODE_107) # define BOOST_PP_NODE_105(p) BOOST_PP_IIF(p(105), 105, 106) # define BOOST_PP_NODE_107(p) BOOST_PP_IIF(p(107), 107, 108) # define BOOST_PP_NODE_110(p) BOOST_PP_IIF(p(110), BOOST_PP_NODE_109, BOOST_PP_NODE_111) # define BOOST_PP_NODE_109(p) BOOST_PP_IIF(p(109), 109, 110) # define BOOST_PP_NODE_111(p) BOOST_PP_IIF(p(111), 111, 112) # define BOOST_PP_NODE_120(p) BOOST_PP_IIF(p(120), BOOST_PP_NODE_116, BOOST_PP_NODE_124) # define BOOST_PP_NODE_116(p) BOOST_PP_IIF(p(116), BOOST_PP_NODE_114, BOOST_PP_NODE_118) # define BOOST_PP_NODE_114(p) BOOST_PP_IIF(p(114), BOOST_PP_NODE_113, BOOST_PP_NODE_115) # define BOOST_PP_NODE_113(p) BOOST_PP_IIF(p(113), 113, 114) # define BOOST_PP_NODE_115(p) BOOST_PP_IIF(p(115), 115, 116) # define BOOST_PP_NODE_118(p) BOOST_PP_IIF(p(118), BOOST_PP_NODE_117, BOOST_PP_NODE_119) # define BOOST_PP_NODE_117(p) BOOST_PP_IIF(p(117), 117, 118) # define BOOST_PP_NODE_119(p) BOOST_PP_IIF(p(119), 119, 120) # define BOOST_PP_NODE_124(p) BOOST_PP_IIF(p(124), BOOST_PP_NODE_122, BOOST_PP_NODE_126) # define BOOST_PP_NODE_122(p) BOOST_PP_IIF(p(122), BOOST_PP_NODE_121, BOOST_PP_NODE_123) # define BOOST_PP_NODE_121(p) BOOST_PP_IIF(p(121), 121, 122) # define BOOST_PP_NODE_123(p) BOOST_PP_IIF(p(123), 123, 124) # define BOOST_PP_NODE_126(p) BOOST_PP_IIF(p(126), BOOST_PP_NODE_125, BOOST_PP_NODE_127) # define BOOST_PP_NODE_125(p) BOOST_PP_IIF(p(125), 125, 126) # define BOOST_PP_NODE_127(p) BOOST_PP_IIF(p(127), 127, 128) # define BOOST_PP_NODE_192(p) BOOST_PP_IIF(p(192), BOOST_PP_NODE_160, BOOST_PP_NODE_224) # define BOOST_PP_NODE_160(p) BOOST_PP_IIF(p(160), BOOST_PP_NODE_144, BOOST_PP_NODE_176) # define BOOST_PP_NODE_144(p) BOOST_PP_IIF(p(144), BOOST_PP_NODE_136, BOOST_PP_NODE_152) # define BOOST_PP_NODE_136(p) BOOST_PP_IIF(p(136), BOOST_PP_NODE_132, BOOST_PP_NODE_140) # define BOOST_PP_NODE_132(p) BOOST_PP_IIF(p(132), BOOST_PP_NODE_130, BOOST_PP_NODE_134) # define BOOST_PP_NODE_130(p) BOOST_PP_IIF(p(130), BOOST_PP_NODE_129, BOOST_PP_NODE_131) # define BOOST_PP_NODE_129(p) BOOST_PP_IIF(p(129), 129, 130) # define BOOST_PP_NODE_131(p) BOOST_PP_IIF(p(131), 131, 132) # define BOOST_PP_NODE_134(p) BOOST_PP_IIF(p(134), BOOST_PP_NODE_133, BOOST_PP_NODE_135) # define BOOST_PP_NODE_133(p) BOOST_PP_IIF(p(133), 133, 134) # define BOOST_PP_NODE_135(p) BOOST_PP_IIF(p(135), 135, 136) # define BOOST_PP_NODE_140(p) BOOST_PP_IIF(p(140), BOOST_PP_NODE_138, BOOST_PP_NODE_142) # define BOOST_PP_NODE_138(p) BOOST_PP_IIF(p(138), BOOST_PP_NODE_137, BOOST_PP_NODE_139) # define BOOST_PP_NODE_137(p) BOOST_PP_IIF(p(137), 137, 138) # define BOOST_PP_NODE_139(p) BOOST_PP_IIF(p(139), 139, 140) # define BOOST_PP_NODE_142(p) BOOST_PP_IIF(p(142), BOOST_PP_NODE_141, BOOST_PP_NODE_143) # define BOOST_PP_NODE_141(p) BOOST_PP_IIF(p(141), 141, 142) # define BOOST_PP_NODE_143(p) BOOST_PP_IIF(p(143), 143, 144) # define BOOST_PP_NODE_152(p) BOOST_PP_IIF(p(152), BOOST_PP_NODE_148, BOOST_PP_NODE_156) # define BOOST_PP_NODE_148(p) BOOST_PP_IIF(p(148), BOOST_PP_NODE_146, BOOST_PP_NODE_150) # define BOOST_PP_NODE_146(p) BOOST_PP_IIF(p(146), BOOST_PP_NODE_145, BOOST_PP_NODE_147) # define BOOST_PP_NODE_145(p) BOOST_PP_IIF(p(145), 145, 146) # define BOOST_PP_NODE_147(p) BOOST_PP_IIF(p(147), 147, 148) # define BOOST_PP_NODE_150(p) BOOST_PP_IIF(p(150), BOOST_PP_NODE_149, BOOST_PP_NODE_151) # define BOOST_PP_NODE_149(p) BOOST_PP_IIF(p(149), 149, 150) # define BOOST_PP_NODE_151(p) BOOST_PP_IIF(p(151), 151, 152) # define BOOST_PP_NODE_156(p) BOOST_PP_IIF(p(156), BOOST_PP_NODE_154, BOOST_PP_NODE_158) # define BOOST_PP_NODE_154(p) BOOST_PP_IIF(p(154), BOOST_PP_NODE_153, BOOST_PP_NODE_155) # define BOOST_PP_NODE_153(p) BOOST_PP_IIF(p(153), 153, 154) # define BOOST_PP_NODE_155(p) BOOST_PP_IIF(p(155), 155, 156) # define BOOST_PP_NODE_158(p) BOOST_PP_IIF(p(158), BOOST_PP_NODE_157, BOOST_PP_NODE_159) # define BOOST_PP_NODE_157(p) BOOST_PP_IIF(p(157), 157, 158) # define BOOST_PP_NODE_159(p) BOOST_PP_IIF(p(159), 159, 160) # define BOOST_PP_NODE_176(p) BOOST_PP_IIF(p(176), BOOST_PP_NODE_168, BOOST_PP_NODE_184) # define BOOST_PP_NODE_168(p) BOOST_PP_IIF(p(168), BOOST_PP_NODE_164, BOOST_PP_NODE_172) # define BOOST_PP_NODE_164(p) BOOST_PP_IIF(p(164), BOOST_PP_NODE_162, BOOST_PP_NODE_166) # define BOOST_PP_NODE_162(p) BOOST_PP_IIF(p(162), BOOST_PP_NODE_161, BOOST_PP_NODE_163) # define BOOST_PP_NODE_161(p) BOOST_PP_IIF(p(161), 161, 162) # define BOOST_PP_NODE_163(p) BOOST_PP_IIF(p(163), 163, 164) # define BOOST_PP_NODE_166(p) BOOST_PP_IIF(p(166), BOOST_PP_NODE_165, BOOST_PP_NODE_167) # define BOOST_PP_NODE_165(p) BOOST_PP_IIF(p(165), 165, 166) # define BOOST_PP_NODE_167(p) BOOST_PP_IIF(p(167), 167, 168) # define BOOST_PP_NODE_172(p) BOOST_PP_IIF(p(172), BOOST_PP_NODE_170, BOOST_PP_NODE_174) # define BOOST_PP_NODE_170(p) BOOST_PP_IIF(p(170), BOOST_PP_NODE_169, BOOST_PP_NODE_171) # define BOOST_PP_NODE_169(p) BOOST_PP_IIF(p(169), 169, 170) # define BOOST_PP_NODE_171(p) BOOST_PP_IIF(p(171), 171, 172) # define BOOST_PP_NODE_174(p) BOOST_PP_IIF(p(174), BOOST_PP_NODE_173, BOOST_PP_NODE_175) # define BOOST_PP_NODE_173(p) BOOST_PP_IIF(p(173), 173, 174) # define BOOST_PP_NODE_175(p) BOOST_PP_IIF(p(175), 175, 176) # define BOOST_PP_NODE_184(p) BOOST_PP_IIF(p(184), BOOST_PP_NODE_180, BOOST_PP_NODE_188) # define BOOST_PP_NODE_180(p) BOOST_PP_IIF(p(180), BOOST_PP_NODE_178, BOOST_PP_NODE_182) # define BOOST_PP_NODE_178(p) BOOST_PP_IIF(p(178), BOOST_PP_NODE_177, BOOST_PP_NODE_179) # define BOOST_PP_NODE_177(p) BOOST_PP_IIF(p(177), 177, 178) # define BOOST_PP_NODE_179(p) BOOST_PP_IIF(p(179), 179, 180) # define BOOST_PP_NODE_182(p) BOOST_PP_IIF(p(182), BOOST_PP_NODE_181, BOOST_PP_NODE_183) # define BOOST_PP_NODE_181(p) BOOST_PP_IIF(p(181), 181, 182) # define BOOST_PP_NODE_183(p) BOOST_PP_IIF(p(183), 183, 184) # define BOOST_PP_NODE_188(p) BOOST_PP_IIF(p(188), BOOST_PP_NODE_186, BOOST_PP_NODE_190) # define BOOST_PP_NODE_186(p) BOOST_PP_IIF(p(186), BOOST_PP_NODE_185, BOOST_PP_NODE_187) # define BOOST_PP_NODE_185(p) BOOST_PP_IIF(p(185), 185, 186) # define BOOST_PP_NODE_187(p) BOOST_PP_IIF(p(187), 187, 188) # define BOOST_PP_NODE_190(p) BOOST_PP_IIF(p(190), BOOST_PP_NODE_189, BOOST_PP_NODE_191) # define BOOST_PP_NODE_189(p) BOOST_PP_IIF(p(189), 189, 190) # define BOOST_PP_NODE_191(p) BOOST_PP_IIF(p(191), 191, 192) # define BOOST_PP_NODE_224(p) BOOST_PP_IIF(p(224), BOOST_PP_NODE_208, BOOST_PP_NODE_240) # define BOOST_PP_NODE_208(p) BOOST_PP_IIF(p(208), BOOST_PP_NODE_200, BOOST_PP_NODE_216) # define BOOST_PP_NODE_200(p) BOOST_PP_IIF(p(200), BOOST_PP_NODE_196, BOOST_PP_NODE_204) # define BOOST_PP_NODE_196(p) BOOST_PP_IIF(p(196), BOOST_PP_NODE_194, BOOST_PP_NODE_198) # define BOOST_PP_NODE_194(p) BOOST_PP_IIF(p(194), BOOST_PP_NODE_193, BOOST_PP_NODE_195) # define BOOST_PP_NODE_193(p) BOOST_PP_IIF(p(193), 193, 194) # define BOOST_PP_NODE_195(p) BOOST_PP_IIF(p(195), 195, 196) # define BOOST_PP_NODE_198(p) BOOST_PP_IIF(p(198), BOOST_PP_NODE_197, BOOST_PP_NODE_199) # define BOOST_PP_NODE_197(p) BOOST_PP_IIF(p(197), 197, 198) # define BOOST_PP_NODE_199(p) BOOST_PP_IIF(p(199), 199, 200) # define BOOST_PP_NODE_204(p) BOOST_PP_IIF(p(204), BOOST_PP_NODE_202, BOOST_PP_NODE_206) # define BOOST_PP_NODE_202(p) BOOST_PP_IIF(p(202), BOOST_PP_NODE_201, BOOST_PP_NODE_203) # define BOOST_PP_NODE_201(p) BOOST_PP_IIF(p(201), 201, 202) # define BOOST_PP_NODE_203(p) BOOST_PP_IIF(p(203), 203, 204) # define BOOST_PP_NODE_206(p) BOOST_PP_IIF(p(206), BOOST_PP_NODE_205, BOOST_PP_NODE_207) # define BOOST_PP_NODE_205(p) BOOST_PP_IIF(p(205), 205, 206) # define BOOST_PP_NODE_207(p) BOOST_PP_IIF(p(207), 207, 208) # define BOOST_PP_NODE_216(p) BOOST_PP_IIF(p(216), BOOST_PP_NODE_212, BOOST_PP_NODE_220) # define BOOST_PP_NODE_212(p) BOOST_PP_IIF(p(212), BOOST_PP_NODE_210, BOOST_PP_NODE_214) # define BOOST_PP_NODE_210(p) BOOST_PP_IIF(p(210), BOOST_PP_NODE_209, BOOST_PP_NODE_211) # define BOOST_PP_NODE_209(p) BOOST_PP_IIF(p(209), 209, 210) # define BOOST_PP_NODE_211(p) BOOST_PP_IIF(p(211), 211, 212) # define BOOST_PP_NODE_214(p) BOOST_PP_IIF(p(214), BOOST_PP_NODE_213, BOOST_PP_NODE_215) # define BOOST_PP_NODE_213(p) BOOST_PP_IIF(p(213), 213, 214) # define BOOST_PP_NODE_215(p) BOOST_PP_IIF(p(215), 215, 216) # define BOOST_PP_NODE_220(p) BOOST_PP_IIF(p(220), BOOST_PP_NODE_218, BOOST_PP_NODE_222) # define BOOST_PP_NODE_218(p) BOOST_PP_IIF(p(218), BOOST_PP_NODE_217, BOOST_PP_NODE_219) # define BOOST_PP_NODE_217(p) BOOST_PP_IIF(p(217), 217, 218) # define BOOST_PP_NODE_219(p) BOOST_PP_IIF(p(219), 219, 220) # define BOOST_PP_NODE_222(p) BOOST_PP_IIF(p(222), BOOST_PP_NODE_221, BOOST_PP_NODE_223) # define BOOST_PP_NODE_221(p) BOOST_PP_IIF(p(221), 221, 222) # define BOOST_PP_NODE_223(p) BOOST_PP_IIF(p(223), 223, 224) # define BOOST_PP_NODE_240(p) BOOST_PP_IIF(p(240), BOOST_PP_NODE_232, BOOST_PP_NODE_248) # define BOOST_PP_NODE_232(p) BOOST_PP_IIF(p(232), BOOST_PP_NODE_228, BOOST_PP_NODE_236) # define BOOST_PP_NODE_228(p) BOOST_PP_IIF(p(228), BOOST_PP_NODE_226, BOOST_PP_NODE_230) # define BOOST_PP_NODE_226(p) BOOST_PP_IIF(p(226), BOOST_PP_NODE_225, BOOST_PP_NODE_227) # define BOOST_PP_NODE_225(p) BOOST_PP_IIF(p(225), 225, 226) # define BOOST_PP_NODE_227(p) BOOST_PP_IIF(p(227), 227, 228) # define BOOST_PP_NODE_230(p) BOOST_PP_IIF(p(230), BOOST_PP_NODE_229, BOOST_PP_NODE_231) # define BOOST_PP_NODE_229(p) BOOST_PP_IIF(p(229), 229, 230) # define BOOST_PP_NODE_231(p) BOOST_PP_IIF(p(231), 231, 232) # define BOOST_PP_NODE_236(p) BOOST_PP_IIF(p(236), BOOST_PP_NODE_234, BOOST_PP_NODE_238) # define BOOST_PP_NODE_234(p) BOOST_PP_IIF(p(234), BOOST_PP_NODE_233, BOOST_PP_NODE_235) # define BOOST_PP_NODE_233(p) BOOST_PP_IIF(p(233), 233, 234) # define BOOST_PP_NODE_235(p) BOOST_PP_IIF(p(235), 235, 236) # define BOOST_PP_NODE_238(p) BOOST_PP_IIF(p(238), BOOST_PP_NODE_237, BOOST_PP_NODE_239) # define BOOST_PP_NODE_237(p) BOOST_PP_IIF(p(237), 237, 238) # define BOOST_PP_NODE_239(p) BOOST_PP_IIF(p(239), 239, 240) # define BOOST_PP_NODE_248(p) BOOST_PP_IIF(p(248), BOOST_PP_NODE_244, BOOST_PP_NODE_252) # define BOOST_PP_NODE_244(p) BOOST_PP_IIF(p(244), BOOST_PP_NODE_242, BOOST_PP_NODE_246) # define BOOST_PP_NODE_242(p) BOOST_PP_IIF(p(242), BOOST_PP_NODE_241, BOOST_PP_NODE_243) # define BOOST_PP_NODE_241(p) BOOST_PP_IIF(p(241), 241, 242) # define BOOST_PP_NODE_243(p) BOOST_PP_IIF(p(243), 243, 244) # define BOOST_PP_NODE_246(p) BOOST_PP_IIF(p(246), BOOST_PP_NODE_245, BOOST_PP_NODE_247) # define BOOST_PP_NODE_245(p) BOOST_PP_IIF(p(245), 245, 246) # define BOOST_PP_NODE_247(p) BOOST_PP_IIF(p(247), 247, 248) # define BOOST_PP_NODE_252(p) BOOST_PP_IIF(p(252), BOOST_PP_NODE_250, BOOST_PP_NODE_254) # define BOOST_PP_NODE_250(p) BOOST_PP_IIF(p(250), BOOST_PP_NODE_249, BOOST_PP_NODE_251) # define BOOST_PP_NODE_249(p) BOOST_PP_IIF(p(249), 249, 250) # define BOOST_PP_NODE_251(p) BOOST_PP_IIF(p(251), 251, 252) # define BOOST_PP_NODE_254(p) BOOST_PP_IIF(p(254), BOOST_PP_NODE_253, BOOST_PP_NODE_255) # define BOOST_PP_NODE_253(p) BOOST_PP_IIF(p(253), 253, 254) # define BOOST_PP_NODE_255(p) BOOST_PP_IIF(p(255), 255, 256) # # endif # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/detail/check.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_DETAIL_CHECK_HPP # define BOOST_PREPROCESSOR_DETAIL_CHECK_HPP # # include # include # # /* BOOST_PP_CHECK */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_CHECK(x, type) BOOST_PP_CHECK_D(x, type) # else # define BOOST_PP_CHECK(x, type) BOOST_PP_CHECK_OO((x, type)) # define BOOST_PP_CHECK_OO(par) BOOST_PP_CHECK_D ## par # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() && ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # define BOOST_PP_CHECK_D(x, type) BOOST_PP_CHECK_1(BOOST_PP_CAT(BOOST_PP_CHECK_RESULT_, type x)) # define BOOST_PP_CHECK_1(chk) BOOST_PP_CHECK_2(chk) # define BOOST_PP_CHECK_2(res, _) res # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_CHECK_D(x, type) BOOST_PP_CHECK_1(type x) # define BOOST_PP_CHECK_1(chk) BOOST_PP_CHECK_2(chk) # define BOOST_PP_CHECK_2(chk) BOOST_PP_CHECK_3((BOOST_PP_CHECK_RESULT_ ## chk)) # define BOOST_PP_CHECK_3(im) BOOST_PP_CHECK_5(BOOST_PP_CHECK_4 im) # define BOOST_PP_CHECK_4(res, _) res # define BOOST_PP_CHECK_5(res) res # else /* DMC */ # define BOOST_PP_CHECK_D(x, type) BOOST_PP_CHECK_OO((type x)) # define BOOST_PP_CHECK_OO(par) BOOST_PP_CHECK_0 ## par # define BOOST_PP_CHECK_0(chk) BOOST_PP_CHECK_1(BOOST_PP_CAT(BOOST_PP_CHECK_RESULT_, chk)) # define BOOST_PP_CHECK_1(chk) BOOST_PP_CHECK_2(chk) # define BOOST_PP_CHECK_2(res, _) res # endif # # define BOOST_PP_CHECK_RESULT_1 1, BOOST_PP_NIL # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/detail/dmc/auto_rec.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_DETAIL_AUTO_REC_HPP # define BOOST_PREPROCESSOR_DETAIL_AUTO_REC_HPP # # include # # /* BOOST_PP_AUTO_REC */ # # define BOOST_PP_AUTO_REC(pred, n) BOOST_PP_NODE_ENTRY_ ## n(pred) # # define BOOST_PP_NODE_ENTRY_256(p) BOOST_PP_NODE_128(p)(p)(p)(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_128(p) BOOST_PP_NODE_64(p)(p)(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_64(p) BOOST_PP_NODE_32(p)(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_32(p) BOOST_PP_NODE_16(p)(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_16(p) BOOST_PP_NODE_8(p)(p)(p)(p) # define BOOST_PP_NODE_ENTRY_8(p) BOOST_PP_NODE_4(p)(p)(p) # define BOOST_PP_NODE_ENTRY_4(p) BOOST_PP_NODE_2(p)(p) # define BOOST_PP_NODE_ENTRY_2(p) BOOST_PP_NODE_1(p) # # define BOOST_PP_NODE_128(p) BOOST_PP_IIF(p##(128), BOOST_PP_NODE_64, BOOST_PP_NODE_192) # define BOOST_PP_NODE_64(p) BOOST_PP_IIF(p##(64), BOOST_PP_NODE_32, BOOST_PP_NODE_96) # define BOOST_PP_NODE_32(p) BOOST_PP_IIF(p##(32), BOOST_PP_NODE_16, BOOST_PP_NODE_48) # define BOOST_PP_NODE_16(p) BOOST_PP_IIF(p##(16), BOOST_PP_NODE_8, BOOST_PP_NODE_24) # define BOOST_PP_NODE_8(p) BOOST_PP_IIF(p##(8), BOOST_PP_NODE_4, BOOST_PP_NODE_12) # define BOOST_PP_NODE_4(p) BOOST_PP_IIF(p##(4), BOOST_PP_NODE_2, BOOST_PP_NODE_6) # define BOOST_PP_NODE_2(p) BOOST_PP_IIF(p##(2), BOOST_PP_NODE_1, BOOST_PP_NODE_3) # define BOOST_PP_NODE_1(p) BOOST_PP_IIF(p##(1), 1, 2) # define BOOST_PP_NODE_3(p) BOOST_PP_IIF(p##(3), 3, 4) # define BOOST_PP_NODE_6(p) BOOST_PP_IIF(p##(6), BOOST_PP_NODE_5, BOOST_PP_NODE_7) # define BOOST_PP_NODE_5(p) BOOST_PP_IIF(p##(5), 5, 6) # define BOOST_PP_NODE_7(p) BOOST_PP_IIF(p##(7), 7, 8) # define BOOST_PP_NODE_12(p) BOOST_PP_IIF(p##(12), BOOST_PP_NODE_10, BOOST_PP_NODE_14) # define BOOST_PP_NODE_10(p) BOOST_PP_IIF(p##(10), BOOST_PP_NODE_9, BOOST_PP_NODE_11) # define BOOST_PP_NODE_9(p) BOOST_PP_IIF(p##(9), 9, 10) # define BOOST_PP_NODE_11(p) BOOST_PP_IIF(p##(11), 11, 12) # define BOOST_PP_NODE_14(p) BOOST_PP_IIF(p##(14), BOOST_PP_NODE_13, BOOST_PP_NODE_15) # define BOOST_PP_NODE_13(p) BOOST_PP_IIF(p##(13), 13, 14) # define BOOST_PP_NODE_15(p) BOOST_PP_IIF(p##(15), 15, 16) # define BOOST_PP_NODE_24(p) BOOST_PP_IIF(p##(24), BOOST_PP_NODE_20, BOOST_PP_NODE_28) # define BOOST_PP_NODE_20(p) BOOST_PP_IIF(p##(20), BOOST_PP_NODE_18, BOOST_PP_NODE_22) # define BOOST_PP_NODE_18(p) BOOST_PP_IIF(p##(18), BOOST_PP_NODE_17, BOOST_PP_NODE_19) # define BOOST_PP_NODE_17(p) BOOST_PP_IIF(p##(17), 17, 18) # define BOOST_PP_NODE_19(p) BOOST_PP_IIF(p##(19), 19, 20) # define BOOST_PP_NODE_22(p) BOOST_PP_IIF(p##(22), BOOST_PP_NODE_21, BOOST_PP_NODE_23) # define BOOST_PP_NODE_21(p) BOOST_PP_IIF(p##(21), 21, 22) # define BOOST_PP_NODE_23(p) BOOST_PP_IIF(p##(23), 23, 24) # define BOOST_PP_NODE_28(p) BOOST_PP_IIF(p##(28), BOOST_PP_NODE_26, BOOST_PP_NODE_30) # define BOOST_PP_NODE_26(p) BOOST_PP_IIF(p##(26), BOOST_PP_NODE_25, BOOST_PP_NODE_27) # define BOOST_PP_NODE_25(p) BOOST_PP_IIF(p##(25), 25, 26) # define BOOST_PP_NODE_27(p) BOOST_PP_IIF(p##(27), 27, 28) # define BOOST_PP_NODE_30(p) BOOST_PP_IIF(p##(30), BOOST_PP_NODE_29, BOOST_PP_NODE_31) # define BOOST_PP_NODE_29(p) BOOST_PP_IIF(p##(29), 29, 30) # define BOOST_PP_NODE_31(p) BOOST_PP_IIF(p##(31), 31, 32) # define BOOST_PP_NODE_48(p) BOOST_PP_IIF(p##(48), BOOST_PP_NODE_40, BOOST_PP_NODE_56) # define BOOST_PP_NODE_40(p) BOOST_PP_IIF(p##(40), BOOST_PP_NODE_36, BOOST_PP_NODE_44) # define BOOST_PP_NODE_36(p) BOOST_PP_IIF(p##(36), BOOST_PP_NODE_34, BOOST_PP_NODE_38) # define BOOST_PP_NODE_34(p) BOOST_PP_IIF(p##(34), BOOST_PP_NODE_33, BOOST_PP_NODE_35) # define BOOST_PP_NODE_33(p) BOOST_PP_IIF(p##(33), 33, 34) # define BOOST_PP_NODE_35(p) BOOST_PP_IIF(p##(35), 35, 36) # define BOOST_PP_NODE_38(p) BOOST_PP_IIF(p##(38), BOOST_PP_NODE_37, BOOST_PP_NODE_39) # define BOOST_PP_NODE_37(p) BOOST_PP_IIF(p##(37), 37, 38) # define BOOST_PP_NODE_39(p) BOOST_PP_IIF(p##(39), 39, 40) # define BOOST_PP_NODE_44(p) BOOST_PP_IIF(p##(44), BOOST_PP_NODE_42, BOOST_PP_NODE_46) # define BOOST_PP_NODE_42(p) BOOST_PP_IIF(p##(42), BOOST_PP_NODE_41, BOOST_PP_NODE_43) # define BOOST_PP_NODE_41(p) BOOST_PP_IIF(p##(41), 41, 42) # define BOOST_PP_NODE_43(p) BOOST_PP_IIF(p##(43), 43, 44) # define BOOST_PP_NODE_46(p) BOOST_PP_IIF(p##(46), BOOST_PP_NODE_45, BOOST_PP_NODE_47) # define BOOST_PP_NODE_45(p) BOOST_PP_IIF(p##(45), 45, 46) # define BOOST_PP_NODE_47(p) BOOST_PP_IIF(p##(47), 47, 48) # define BOOST_PP_NODE_56(p) BOOST_PP_IIF(p##(56), BOOST_PP_NODE_52, BOOST_PP_NODE_60) # define BOOST_PP_NODE_52(p) BOOST_PP_IIF(p##(52), BOOST_PP_NODE_50, BOOST_PP_NODE_54) # define BOOST_PP_NODE_50(p) BOOST_PP_IIF(p##(50), BOOST_PP_NODE_49, BOOST_PP_NODE_51) # define BOOST_PP_NODE_49(p) BOOST_PP_IIF(p##(49), 49, 50) # define BOOST_PP_NODE_51(p) BOOST_PP_IIF(p##(51), 51, 52) # define BOOST_PP_NODE_54(p) BOOST_PP_IIF(p##(54), BOOST_PP_NODE_53, BOOST_PP_NODE_55) # define BOOST_PP_NODE_53(p) BOOST_PP_IIF(p##(53), 53, 54) # define BOOST_PP_NODE_55(p) BOOST_PP_IIF(p##(55), 55, 56) # define BOOST_PP_NODE_60(p) BOOST_PP_IIF(p##(60), BOOST_PP_NODE_58, BOOST_PP_NODE_62) # define BOOST_PP_NODE_58(p) BOOST_PP_IIF(p##(58), BOOST_PP_NODE_57, BOOST_PP_NODE_59) # define BOOST_PP_NODE_57(p) BOOST_PP_IIF(p##(57), 57, 58) # define BOOST_PP_NODE_59(p) BOOST_PP_IIF(p##(59), 59, 60) # define BOOST_PP_NODE_62(p) BOOST_PP_IIF(p##(62), BOOST_PP_NODE_61, BOOST_PP_NODE_63) # define BOOST_PP_NODE_61(p) BOOST_PP_IIF(p##(61), 61, 62) # define BOOST_PP_NODE_63(p) BOOST_PP_IIF(p##(63), 63, 64) # define BOOST_PP_NODE_96(p) BOOST_PP_IIF(p##(96), BOOST_PP_NODE_80, BOOST_PP_NODE_112) # define BOOST_PP_NODE_80(p) BOOST_PP_IIF(p##(80), BOOST_PP_NODE_72, BOOST_PP_NODE_88) # define BOOST_PP_NODE_72(p) BOOST_PP_IIF(p##(72), BOOST_PP_NODE_68, BOOST_PP_NODE_76) # define BOOST_PP_NODE_68(p) BOOST_PP_IIF(p##(68), BOOST_PP_NODE_66, BOOST_PP_NODE_70) # define BOOST_PP_NODE_66(p) BOOST_PP_IIF(p##(66), BOOST_PP_NODE_65, BOOST_PP_NODE_67) # define BOOST_PP_NODE_65(p) BOOST_PP_IIF(p##(65), 65, 66) # define BOOST_PP_NODE_67(p) BOOST_PP_IIF(p##(67), 67, 68) # define BOOST_PP_NODE_70(p) BOOST_PP_IIF(p##(70), BOOST_PP_NODE_69, BOOST_PP_NODE_71) # define BOOST_PP_NODE_69(p) BOOST_PP_IIF(p##(69), 69, 70) # define BOOST_PP_NODE_71(p) BOOST_PP_IIF(p##(71), 71, 72) # define BOOST_PP_NODE_76(p) BOOST_PP_IIF(p##(76), BOOST_PP_NODE_74, BOOST_PP_NODE_78) # define BOOST_PP_NODE_74(p) BOOST_PP_IIF(p##(74), BOOST_PP_NODE_73, BOOST_PP_NODE_75) # define BOOST_PP_NODE_73(p) BOOST_PP_IIF(p##(73), 73, 74) # define BOOST_PP_NODE_75(p) BOOST_PP_IIF(p##(75), 75, 76) # define BOOST_PP_NODE_78(p) BOOST_PP_IIF(p##(78), BOOST_PP_NODE_77, BOOST_PP_NODE_79) # define BOOST_PP_NODE_77(p) BOOST_PP_IIF(p##(77), 77, 78) # define BOOST_PP_NODE_79(p) BOOST_PP_IIF(p##(79), 79, 80) # define BOOST_PP_NODE_88(p) BOOST_PP_IIF(p##(88), BOOST_PP_NODE_84, BOOST_PP_NODE_92) # define BOOST_PP_NODE_84(p) BOOST_PP_IIF(p##(84), BOOST_PP_NODE_82, BOOST_PP_NODE_86) # define BOOST_PP_NODE_82(p) BOOST_PP_IIF(p##(82), BOOST_PP_NODE_81, BOOST_PP_NODE_83) # define BOOST_PP_NODE_81(p) BOOST_PP_IIF(p##(81), 81, 82) # define BOOST_PP_NODE_83(p) BOOST_PP_IIF(p##(83), 83, 84) # define BOOST_PP_NODE_86(p) BOOST_PP_IIF(p##(86), BOOST_PP_NODE_85, BOOST_PP_NODE_87) # define BOOST_PP_NODE_85(p) BOOST_PP_IIF(p##(85), 85, 86) # define BOOST_PP_NODE_87(p) BOOST_PP_IIF(p##(87), 87, 88) # define BOOST_PP_NODE_92(p) BOOST_PP_IIF(p##(92), BOOST_PP_NODE_90, BOOST_PP_NODE_94) # define BOOST_PP_NODE_90(p) BOOST_PP_IIF(p##(90), BOOST_PP_NODE_89, BOOST_PP_NODE_91) # define BOOST_PP_NODE_89(p) BOOST_PP_IIF(p##(89), 89, 90) # define BOOST_PP_NODE_91(p) BOOST_PP_IIF(p##(91), 91, 92) # define BOOST_PP_NODE_94(p) BOOST_PP_IIF(p##(94), BOOST_PP_NODE_93, BOOST_PP_NODE_95) # define BOOST_PP_NODE_93(p) BOOST_PP_IIF(p##(93), 93, 94) # define BOOST_PP_NODE_95(p) BOOST_PP_IIF(p##(95), 95, 96) # define BOOST_PP_NODE_112(p) BOOST_PP_IIF(p##(112), BOOST_PP_NODE_104, BOOST_PP_NODE_120) # define BOOST_PP_NODE_104(p) BOOST_PP_IIF(p##(104), BOOST_PP_NODE_100, BOOST_PP_NODE_108) # define BOOST_PP_NODE_100(p) BOOST_PP_IIF(p##(100), BOOST_PP_NODE_98, BOOST_PP_NODE_102) # define BOOST_PP_NODE_98(p) BOOST_PP_IIF(p##(98), BOOST_PP_NODE_97, BOOST_PP_NODE_99) # define BOOST_PP_NODE_97(p) BOOST_PP_IIF(p##(97), 97, 98) # define BOOST_PP_NODE_99(p) BOOST_PP_IIF(p##(99), 99, 100) # define BOOST_PP_NODE_102(p) BOOST_PP_IIF(p##(102), BOOST_PP_NODE_101, BOOST_PP_NODE_103) # define BOOST_PP_NODE_101(p) BOOST_PP_IIF(p##(101), 101, 102) # define BOOST_PP_NODE_103(p) BOOST_PP_IIF(p##(103), 103, 104) # define BOOST_PP_NODE_108(p) BOOST_PP_IIF(p##(108), BOOST_PP_NODE_106, BOOST_PP_NODE_110) # define BOOST_PP_NODE_106(p) BOOST_PP_IIF(p##(106), BOOST_PP_NODE_105, BOOST_PP_NODE_107) # define BOOST_PP_NODE_105(p) BOOST_PP_IIF(p##(105), 105, 106) # define BOOST_PP_NODE_107(p) BOOST_PP_IIF(p##(107), 107, 108) # define BOOST_PP_NODE_110(p) BOOST_PP_IIF(p##(110), BOOST_PP_NODE_109, BOOST_PP_NODE_111) # define BOOST_PP_NODE_109(p) BOOST_PP_IIF(p##(109), 109, 110) # define BOOST_PP_NODE_111(p) BOOST_PP_IIF(p##(111), 111, 112) # define BOOST_PP_NODE_120(p) BOOST_PP_IIF(p##(120), BOOST_PP_NODE_116, BOOST_PP_NODE_124) # define BOOST_PP_NODE_116(p) BOOST_PP_IIF(p##(116), BOOST_PP_NODE_114, BOOST_PP_NODE_118) # define BOOST_PP_NODE_114(p) BOOST_PP_IIF(p##(114), BOOST_PP_NODE_113, BOOST_PP_NODE_115) # define BOOST_PP_NODE_113(p) BOOST_PP_IIF(p##(113), 113, 114) # define BOOST_PP_NODE_115(p) BOOST_PP_IIF(p##(115), 115, 116) # define BOOST_PP_NODE_118(p) BOOST_PP_IIF(p##(118), BOOST_PP_NODE_117, BOOST_PP_NODE_119) # define BOOST_PP_NODE_117(p) BOOST_PP_IIF(p##(117), 117, 118) # define BOOST_PP_NODE_119(p) BOOST_PP_IIF(p##(119), 119, 120) # define BOOST_PP_NODE_124(p) BOOST_PP_IIF(p##(124), BOOST_PP_NODE_122, BOOST_PP_NODE_126) # define BOOST_PP_NODE_122(p) BOOST_PP_IIF(p##(122), BOOST_PP_NODE_121, BOOST_PP_NODE_123) # define BOOST_PP_NODE_121(p) BOOST_PP_IIF(p##(121), 121, 122) # define BOOST_PP_NODE_123(p) BOOST_PP_IIF(p##(123), 123, 124) # define BOOST_PP_NODE_126(p) BOOST_PP_IIF(p##(126), BOOST_PP_NODE_125, BOOST_PP_NODE_127) # define BOOST_PP_NODE_125(p) BOOST_PP_IIF(p##(125), 125, 126) # define BOOST_PP_NODE_127(p) BOOST_PP_IIF(p##(127), 127, 128) # define BOOST_PP_NODE_192(p) BOOST_PP_IIF(p##(192), BOOST_PP_NODE_160, BOOST_PP_NODE_224) # define BOOST_PP_NODE_160(p) BOOST_PP_IIF(p##(160), BOOST_PP_NODE_144, BOOST_PP_NODE_176) # define BOOST_PP_NODE_144(p) BOOST_PP_IIF(p##(144), BOOST_PP_NODE_136, BOOST_PP_NODE_152) # define BOOST_PP_NODE_136(p) BOOST_PP_IIF(p##(136), BOOST_PP_NODE_132, BOOST_PP_NODE_140) # define BOOST_PP_NODE_132(p) BOOST_PP_IIF(p##(132), BOOST_PP_NODE_130, BOOST_PP_NODE_134) # define BOOST_PP_NODE_130(p) BOOST_PP_IIF(p##(130), BOOST_PP_NODE_129, BOOST_PP_NODE_131) # define BOOST_PP_NODE_129(p) BOOST_PP_IIF(p##(129), 129, 130) # define BOOST_PP_NODE_131(p) BOOST_PP_IIF(p##(131), 131, 132) # define BOOST_PP_NODE_134(p) BOOST_PP_IIF(p##(134), BOOST_PP_NODE_133, BOOST_PP_NODE_135) # define BOOST_PP_NODE_133(p) BOOST_PP_IIF(p##(133), 133, 134) # define BOOST_PP_NODE_135(p) BOOST_PP_IIF(p##(135), 135, 136) # define BOOST_PP_NODE_140(p) BOOST_PP_IIF(p##(140), BOOST_PP_NODE_138, BOOST_PP_NODE_142) # define BOOST_PP_NODE_138(p) BOOST_PP_IIF(p##(138), BOOST_PP_NODE_137, BOOST_PP_NODE_139) # define BOOST_PP_NODE_137(p) BOOST_PP_IIF(p##(137), 137, 138) # define BOOST_PP_NODE_139(p) BOOST_PP_IIF(p##(139), 139, 140) # define BOOST_PP_NODE_142(p) BOOST_PP_IIF(p##(142), BOOST_PP_NODE_141, BOOST_PP_NODE_143) # define BOOST_PP_NODE_141(p) BOOST_PP_IIF(p##(141), 141, 142) # define BOOST_PP_NODE_143(p) BOOST_PP_IIF(p##(143), 143, 144) # define BOOST_PP_NODE_152(p) BOOST_PP_IIF(p##(152), BOOST_PP_NODE_148, BOOST_PP_NODE_156) # define BOOST_PP_NODE_148(p) BOOST_PP_IIF(p##(148), BOOST_PP_NODE_146, BOOST_PP_NODE_150) # define BOOST_PP_NODE_146(p) BOOST_PP_IIF(p##(146), BOOST_PP_NODE_145, BOOST_PP_NODE_147) # define BOOST_PP_NODE_145(p) BOOST_PP_IIF(p##(145), 145, 146) # define BOOST_PP_NODE_147(p) BOOST_PP_IIF(p##(147), 147, 148) # define BOOST_PP_NODE_150(p) BOOST_PP_IIF(p##(150), BOOST_PP_NODE_149, BOOST_PP_NODE_151) # define BOOST_PP_NODE_149(p) BOOST_PP_IIF(p##(149), 149, 150) # define BOOST_PP_NODE_151(p) BOOST_PP_IIF(p##(151), 151, 152) # define BOOST_PP_NODE_156(p) BOOST_PP_IIF(p##(156), BOOST_PP_NODE_154, BOOST_PP_NODE_158) # define BOOST_PP_NODE_154(p) BOOST_PP_IIF(p##(154), BOOST_PP_NODE_153, BOOST_PP_NODE_155) # define BOOST_PP_NODE_153(p) BOOST_PP_IIF(p##(153), 153, 154) # define BOOST_PP_NODE_155(p) BOOST_PP_IIF(p##(155), 155, 156) # define BOOST_PP_NODE_158(p) BOOST_PP_IIF(p##(158), BOOST_PP_NODE_157, BOOST_PP_NODE_159) # define BOOST_PP_NODE_157(p) BOOST_PP_IIF(p##(157), 157, 158) # define BOOST_PP_NODE_159(p) BOOST_PP_IIF(p##(159), 159, 160) # define BOOST_PP_NODE_176(p) BOOST_PP_IIF(p##(176), BOOST_PP_NODE_168, BOOST_PP_NODE_184) # define BOOST_PP_NODE_168(p) BOOST_PP_IIF(p##(168), BOOST_PP_NODE_164, BOOST_PP_NODE_172) # define BOOST_PP_NODE_164(p) BOOST_PP_IIF(p##(164), BOOST_PP_NODE_162, BOOST_PP_NODE_166) # define BOOST_PP_NODE_162(p) BOOST_PP_IIF(p##(162), BOOST_PP_NODE_161, BOOST_PP_NODE_163) # define BOOST_PP_NODE_161(p) BOOST_PP_IIF(p##(161), 161, 162) # define BOOST_PP_NODE_163(p) BOOST_PP_IIF(p##(163), 163, 164) # define BOOST_PP_NODE_166(p) BOOST_PP_IIF(p##(166), BOOST_PP_NODE_165, BOOST_PP_NODE_167) # define BOOST_PP_NODE_165(p) BOOST_PP_IIF(p##(165), 165, 166) # define BOOST_PP_NODE_167(p) BOOST_PP_IIF(p##(167), 167, 168) # define BOOST_PP_NODE_172(p) BOOST_PP_IIF(p##(172), BOOST_PP_NODE_170, BOOST_PP_NODE_174) # define BOOST_PP_NODE_170(p) BOOST_PP_IIF(p##(170), BOOST_PP_NODE_169, BOOST_PP_NODE_171) # define BOOST_PP_NODE_169(p) BOOST_PP_IIF(p##(169), 169, 170) # define BOOST_PP_NODE_171(p) BOOST_PP_IIF(p##(171), 171, 172) # define BOOST_PP_NODE_174(p) BOOST_PP_IIF(p##(174), BOOST_PP_NODE_173, BOOST_PP_NODE_175) # define BOOST_PP_NODE_173(p) BOOST_PP_IIF(p##(173), 173, 174) # define BOOST_PP_NODE_175(p) BOOST_PP_IIF(p##(175), 175, 176) # define BOOST_PP_NODE_184(p) BOOST_PP_IIF(p##(184), BOOST_PP_NODE_180, BOOST_PP_NODE_188) # define BOOST_PP_NODE_180(p) BOOST_PP_IIF(p##(180), BOOST_PP_NODE_178, BOOST_PP_NODE_182) # define BOOST_PP_NODE_178(p) BOOST_PP_IIF(p##(178), BOOST_PP_NODE_177, BOOST_PP_NODE_179) # define BOOST_PP_NODE_177(p) BOOST_PP_IIF(p##(177), 177, 178) # define BOOST_PP_NODE_179(p) BOOST_PP_IIF(p##(179), 179, 180) # define BOOST_PP_NODE_182(p) BOOST_PP_IIF(p##(182), BOOST_PP_NODE_181, BOOST_PP_NODE_183) # define BOOST_PP_NODE_181(p) BOOST_PP_IIF(p##(181), 181, 182) # define BOOST_PP_NODE_183(p) BOOST_PP_IIF(p##(183), 183, 184) # define BOOST_PP_NODE_188(p) BOOST_PP_IIF(p##(188), BOOST_PP_NODE_186, BOOST_PP_NODE_190) # define BOOST_PP_NODE_186(p) BOOST_PP_IIF(p##(186), BOOST_PP_NODE_185, BOOST_PP_NODE_187) # define BOOST_PP_NODE_185(p) BOOST_PP_IIF(p##(185), 185, 186) # define BOOST_PP_NODE_187(p) BOOST_PP_IIF(p##(187), 187, 188) # define BOOST_PP_NODE_190(p) BOOST_PP_IIF(p##(190), BOOST_PP_NODE_189, BOOST_PP_NODE_191) # define BOOST_PP_NODE_189(p) BOOST_PP_IIF(p##(189), 189, 190) # define BOOST_PP_NODE_191(p) BOOST_PP_IIF(p##(191), 191, 192) # define BOOST_PP_NODE_224(p) BOOST_PP_IIF(p##(224), BOOST_PP_NODE_208, BOOST_PP_NODE_240) # define BOOST_PP_NODE_208(p) BOOST_PP_IIF(p##(208), BOOST_PP_NODE_200, BOOST_PP_NODE_216) # define BOOST_PP_NODE_200(p) BOOST_PP_IIF(p##(200), BOOST_PP_NODE_196, BOOST_PP_NODE_204) # define BOOST_PP_NODE_196(p) BOOST_PP_IIF(p##(196), BOOST_PP_NODE_194, BOOST_PP_NODE_198) # define BOOST_PP_NODE_194(p) BOOST_PP_IIF(p##(194), BOOST_PP_NODE_193, BOOST_PP_NODE_195) # define BOOST_PP_NODE_193(p) BOOST_PP_IIF(p##(193), 193, 194) # define BOOST_PP_NODE_195(p) BOOST_PP_IIF(p##(195), 195, 196) # define BOOST_PP_NODE_198(p) BOOST_PP_IIF(p##(198), BOOST_PP_NODE_197, BOOST_PP_NODE_199) # define BOOST_PP_NODE_197(p) BOOST_PP_IIF(p##(197), 197, 198) # define BOOST_PP_NODE_199(p) BOOST_PP_IIF(p##(199), 199, 200) # define BOOST_PP_NODE_204(p) BOOST_PP_IIF(p##(204), BOOST_PP_NODE_202, BOOST_PP_NODE_206) # define BOOST_PP_NODE_202(p) BOOST_PP_IIF(p##(202), BOOST_PP_NODE_201, BOOST_PP_NODE_203) # define BOOST_PP_NODE_201(p) BOOST_PP_IIF(p##(201), 201, 202) # define BOOST_PP_NODE_203(p) BOOST_PP_IIF(p##(203), 203, 204) # define BOOST_PP_NODE_206(p) BOOST_PP_IIF(p##(206), BOOST_PP_NODE_205, BOOST_PP_NODE_207) # define BOOST_PP_NODE_205(p) BOOST_PP_IIF(p##(205), 205, 206) # define BOOST_PP_NODE_207(p) BOOST_PP_IIF(p##(207), 207, 208) # define BOOST_PP_NODE_216(p) BOOST_PP_IIF(p##(216), BOOST_PP_NODE_212, BOOST_PP_NODE_220) # define BOOST_PP_NODE_212(p) BOOST_PP_IIF(p##(212), BOOST_PP_NODE_210, BOOST_PP_NODE_214) # define BOOST_PP_NODE_210(p) BOOST_PP_IIF(p##(210), BOOST_PP_NODE_209, BOOST_PP_NODE_211) # define BOOST_PP_NODE_209(p) BOOST_PP_IIF(p##(209), 209, 210) # define BOOST_PP_NODE_211(p) BOOST_PP_IIF(p##(211), 211, 212) # define BOOST_PP_NODE_214(p) BOOST_PP_IIF(p##(214), BOOST_PP_NODE_213, BOOST_PP_NODE_215) # define BOOST_PP_NODE_213(p) BOOST_PP_IIF(p##(213), 213, 214) # define BOOST_PP_NODE_215(p) BOOST_PP_IIF(p##(215), 215, 216) # define BOOST_PP_NODE_220(p) BOOST_PP_IIF(p##(220), BOOST_PP_NODE_218, BOOST_PP_NODE_222) # define BOOST_PP_NODE_218(p) BOOST_PP_IIF(p##(218), BOOST_PP_NODE_217, BOOST_PP_NODE_219) # define BOOST_PP_NODE_217(p) BOOST_PP_IIF(p##(217), 217, 218) # define BOOST_PP_NODE_219(p) BOOST_PP_IIF(p##(219), 219, 220) # define BOOST_PP_NODE_222(p) BOOST_PP_IIF(p##(222), BOOST_PP_NODE_221, BOOST_PP_NODE_223) # define BOOST_PP_NODE_221(p) BOOST_PP_IIF(p##(221), 221, 222) # define BOOST_PP_NODE_223(p) BOOST_PP_IIF(p##(223), 223, 224) # define BOOST_PP_NODE_240(p) BOOST_PP_IIF(p##(240), BOOST_PP_NODE_232, BOOST_PP_NODE_248) # define BOOST_PP_NODE_232(p) BOOST_PP_IIF(p##(232), BOOST_PP_NODE_228, BOOST_PP_NODE_236) # define BOOST_PP_NODE_228(p) BOOST_PP_IIF(p##(228), BOOST_PP_NODE_226, BOOST_PP_NODE_230) # define BOOST_PP_NODE_226(p) BOOST_PP_IIF(p##(226), BOOST_PP_NODE_225, BOOST_PP_NODE_227) # define BOOST_PP_NODE_225(p) BOOST_PP_IIF(p##(225), 225, 226) # define BOOST_PP_NODE_227(p) BOOST_PP_IIF(p##(227), 227, 228) # define BOOST_PP_NODE_230(p) BOOST_PP_IIF(p##(230), BOOST_PP_NODE_229, BOOST_PP_NODE_231) # define BOOST_PP_NODE_229(p) BOOST_PP_IIF(p##(229), 229, 230) # define BOOST_PP_NODE_231(p) BOOST_PP_IIF(p##(231), 231, 232) # define BOOST_PP_NODE_236(p) BOOST_PP_IIF(p##(236), BOOST_PP_NODE_234, BOOST_PP_NODE_238) # define BOOST_PP_NODE_234(p) BOOST_PP_IIF(p##(234), BOOST_PP_NODE_233, BOOST_PP_NODE_235) # define BOOST_PP_NODE_233(p) BOOST_PP_IIF(p##(233), 233, 234) # define BOOST_PP_NODE_235(p) BOOST_PP_IIF(p##(235), 235, 236) # define BOOST_PP_NODE_238(p) BOOST_PP_IIF(p##(238), BOOST_PP_NODE_237, BOOST_PP_NODE_239) # define BOOST_PP_NODE_237(p) BOOST_PP_IIF(p##(237), 237, 238) # define BOOST_PP_NODE_239(p) BOOST_PP_IIF(p##(239), 239, 240) # define BOOST_PP_NODE_248(p) BOOST_PP_IIF(p##(248), BOOST_PP_NODE_244, BOOST_PP_NODE_252) # define BOOST_PP_NODE_244(p) BOOST_PP_IIF(p##(244), BOOST_PP_NODE_242, BOOST_PP_NODE_246) # define BOOST_PP_NODE_242(p) BOOST_PP_IIF(p##(242), BOOST_PP_NODE_241, BOOST_PP_NODE_243) # define BOOST_PP_NODE_241(p) BOOST_PP_IIF(p##(241), 241, 242) # define BOOST_PP_NODE_243(p) BOOST_PP_IIF(p##(243), 243, 244) # define BOOST_PP_NODE_246(p) BOOST_PP_IIF(p##(246), BOOST_PP_NODE_245, BOOST_PP_NODE_247) # define BOOST_PP_NODE_245(p) BOOST_PP_IIF(p##(245), 245, 246) # define BOOST_PP_NODE_247(p) BOOST_PP_IIF(p##(247), 247, 248) # define BOOST_PP_NODE_252(p) BOOST_PP_IIF(p##(252), BOOST_PP_NODE_250, BOOST_PP_NODE_254) # define BOOST_PP_NODE_250(p) BOOST_PP_IIF(p##(250), BOOST_PP_NODE_249, BOOST_PP_NODE_251) # define BOOST_PP_NODE_249(p) BOOST_PP_IIF(p##(249), 249, 250) # define BOOST_PP_NODE_251(p) BOOST_PP_IIF(p##(251), 251, 252) # define BOOST_PP_NODE_254(p) BOOST_PP_IIF(p##(254), BOOST_PP_NODE_253, BOOST_PP_NODE_255) # define BOOST_PP_NODE_253(p) BOOST_PP_IIF(p##(253), 253, 254) # define BOOST_PP_NODE_255(p) BOOST_PP_IIF(p##(255), 255, 256) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/detail/is_binary.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_DETAIL_IS_BINARY_HPP # define BOOST_PREPROCESSOR_DETAIL_IS_BINARY_HPP # # include # include # # /* BOOST_PP_IS_BINARY */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_IS_BINARY(x) BOOST_PP_CHECK(x, BOOST_PP_IS_BINARY_CHECK) # else # define BOOST_PP_IS_BINARY(x) BOOST_PP_IS_BINARY_I(x) # define BOOST_PP_IS_BINARY_I(x) BOOST_PP_CHECK(x, BOOST_PP_IS_BINARY_CHECK) # endif # # define BOOST_PP_IS_BINARY_CHECK(a, b) 1 # define BOOST_PP_CHECK_RESULT_BOOST_PP_IS_BINARY_CHECK 0, BOOST_PP_NIL # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/detail/is_nullary.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_DETAIL_IS_NULLARY_HPP # define BOOST_PREPROCESSOR_DETAIL_IS_NULLARY_HPP # # include # include # # /* BOOST_PP_IS_NULLARY */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_IS_NULLARY(x) BOOST_PP_CHECK(x, BOOST_PP_IS_NULLARY_CHECK) # else # define BOOST_PP_IS_NULLARY(x) BOOST_PP_IS_NULLARY_I(x) # define BOOST_PP_IS_NULLARY_I(x) BOOST_PP_CHECK(x, BOOST_PP_IS_NULLARY_CHECK) # endif # # define BOOST_PP_IS_NULLARY_CHECK() 1 # define BOOST_PP_CHECK_RESULT_BOOST_PP_IS_NULLARY_CHECK 0, BOOST_PP_NIL # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/detail/split.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # ifndef BOOST_PREPROCESSOR_DETAIL_SPLIT_HPP # define BOOST_PREPROCESSOR_DETAIL_SPLIT_HPP # # include # # /* BOOST_PP_SPLIT */ # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SPLIT(n, im) BOOST_PP_SPLIT_I((n, im)) # define BOOST_PP_SPLIT_I(par) BOOST_PP_SPLIT_II ## par # define BOOST_PP_SPLIT_II(n, a, b) BOOST_PP_SPLIT_ ## n(a, b) # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_SPLIT(n, im) BOOST_PP_SPLIT_I(n((im))) # define BOOST_PP_SPLIT_I(n) BOOST_PP_SPLIT_ID(BOOST_PP_SPLIT_II_ ## n) # define BOOST_PP_SPLIT_II_0(s) BOOST_PP_SPLIT_ID(BOOST_PP_SPLIT_0 s) # define BOOST_PP_SPLIT_II_1(s) BOOST_PP_SPLIT_ID(BOOST_PP_SPLIT_1 s) # define BOOST_PP_SPLIT_ID(id) id # else # define BOOST_PP_SPLIT(n, im) BOOST_PP_SPLIT_I(n)(im) # define BOOST_PP_SPLIT_I(n) BOOST_PP_SPLIT_ ## n # endif # # define BOOST_PP_SPLIT_0(a, b) a # define BOOST_PP_SPLIT_1(a, b) b # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/empty.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_EMPTY_HPP # define BOOST_PREPROCESSOR_EMPTY_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/enum.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ENUM_HPP # define BOOST_PREPROCESSOR_ENUM_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/enum_params.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ENUM_PARAMS_HPP # define BOOST_PREPROCESSOR_ENUM_PARAMS_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/enum_params_with_a_default.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ENUM_PARAMS_WITH_A_DEFAULT_HPP # define BOOST_PREPROCESSOR_ENUM_PARAMS_WITH_A_DEFAULT_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/enum_shifted_params.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ENUM_SHIFTED_PARAMS_HPP # define BOOST_PREPROCESSOR_ENUM_SHIFTED_PARAMS_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/expr_if.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_EXPR_IF_HPP # define BOOST_PREPROCESSOR_EXPR_IF_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/detail/is_empty.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2014. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # #ifndef BOOST_PREPROCESSOR_DETAIL_IS_EMPTY_HPP #define BOOST_PREPROCESSOR_DETAIL_IS_EMPTY_HPP #include #if BOOST_PP_VARIADICS_MSVC # pragma warning(once:4002) #define BOOST_PP_DETAIL_IS_EMPTY_IIF_0(t, b) b #define BOOST_PP_DETAIL_IS_EMPTY_IIF_1(t, b) t #else #define BOOST_PP_DETAIL_IS_EMPTY_IIF_0(t, ...) __VA_ARGS__ #define BOOST_PP_DETAIL_IS_EMPTY_IIF_1(t, ...) t #endif #if BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400 #define BOOST_PP_DETAIL_IS_EMPTY_PROCESS(param) \ BOOST_PP_IS_BEGIN_PARENS \ ( \ BOOST_PP_DETAIL_IS_EMPTY_NON_FUNCTION_C param () \ ) \ /**/ #else #define BOOST_PP_DETAIL_IS_EMPTY_PROCESS(...) \ BOOST_PP_IS_BEGIN_PARENS \ ( \ BOOST_PP_DETAIL_IS_EMPTY_NON_FUNCTION_C __VA_ARGS__ () \ ) \ /**/ #endif #define BOOST_PP_DETAIL_IS_EMPTY_PRIMITIVE_CAT(a, b) a ## b #define BOOST_PP_DETAIL_IS_EMPTY_IIF(bit) BOOST_PP_DETAIL_IS_EMPTY_PRIMITIVE_CAT(BOOST_PP_DETAIL_IS_EMPTY_IIF_,bit) #define BOOST_PP_DETAIL_IS_EMPTY_NON_FUNCTION_C(...) () #endif /* BOOST_PREPROCESSOR_DETAIL_IS_EMPTY_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/empty.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_EMPTY_HPP # define BOOST_PREPROCESSOR_FACILITIES_EMPTY_HPP # # include # # /* BOOST_PP_EMPTY */ # # define BOOST_PP_EMPTY() # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/expand.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_EXPAND_HPP # define BOOST_PREPROCESSOR_FACILITIES_EXPAND_HPP # # include # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() && ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # define BOOST_PP_EXPAND(x) BOOST_PP_EXPAND_I(x) # else # define BOOST_PP_EXPAND(x) BOOST_PP_EXPAND_OO((x)) # define BOOST_PP_EXPAND_OO(par) BOOST_PP_EXPAND_I ## par # endif # # define BOOST_PP_EXPAND_I(x) x # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/identity.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # /* Revised by Edward Diener (2015) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_IDENTITY_HPP # define BOOST_PREPROCESSOR_FACILITIES_IDENTITY_HPP # # include # include # # /* BOOST_PP_IDENTITY */ # # define BOOST_PP_IDENTITY(item) item BOOST_PP_EMPTY # # define BOOST_PP_IDENTITY_N(item,n) item BOOST_PP_TUPLE_EAT_N(n) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/intercept.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_INTERCEPT_HPP # define BOOST_PREPROCESSOR_FACILITIES_INTERCEPT_HPP # # /* BOOST_PP_INTERCEPT */ # # define BOOST_PP_INTERCEPT BOOST_PP_INTERCEPT_ # # define BOOST_PP_INTERCEPT_0 # define BOOST_PP_INTERCEPT_1 # define BOOST_PP_INTERCEPT_2 # define BOOST_PP_INTERCEPT_3 # define BOOST_PP_INTERCEPT_4 # define BOOST_PP_INTERCEPT_5 # define BOOST_PP_INTERCEPT_6 # define BOOST_PP_INTERCEPT_7 # define BOOST_PP_INTERCEPT_8 # define BOOST_PP_INTERCEPT_9 # define BOOST_PP_INTERCEPT_10 # define BOOST_PP_INTERCEPT_11 # define BOOST_PP_INTERCEPT_12 # define BOOST_PP_INTERCEPT_13 # define BOOST_PP_INTERCEPT_14 # define BOOST_PP_INTERCEPT_15 # define BOOST_PP_INTERCEPT_16 # define BOOST_PP_INTERCEPT_17 # define BOOST_PP_INTERCEPT_18 # define BOOST_PP_INTERCEPT_19 # define BOOST_PP_INTERCEPT_20 # define BOOST_PP_INTERCEPT_21 # define BOOST_PP_INTERCEPT_22 # define BOOST_PP_INTERCEPT_23 # define BOOST_PP_INTERCEPT_24 # define BOOST_PP_INTERCEPT_25 # define BOOST_PP_INTERCEPT_26 # define BOOST_PP_INTERCEPT_27 # define BOOST_PP_INTERCEPT_28 # define BOOST_PP_INTERCEPT_29 # define BOOST_PP_INTERCEPT_30 # define BOOST_PP_INTERCEPT_31 # define BOOST_PP_INTERCEPT_32 # define BOOST_PP_INTERCEPT_33 # define BOOST_PP_INTERCEPT_34 # define BOOST_PP_INTERCEPT_35 # define BOOST_PP_INTERCEPT_36 # define BOOST_PP_INTERCEPT_37 # define BOOST_PP_INTERCEPT_38 # define BOOST_PP_INTERCEPT_39 # define BOOST_PP_INTERCEPT_40 # define BOOST_PP_INTERCEPT_41 # define BOOST_PP_INTERCEPT_42 # define BOOST_PP_INTERCEPT_43 # define BOOST_PP_INTERCEPT_44 # define BOOST_PP_INTERCEPT_45 # define BOOST_PP_INTERCEPT_46 # define BOOST_PP_INTERCEPT_47 # define BOOST_PP_INTERCEPT_48 # define BOOST_PP_INTERCEPT_49 # define BOOST_PP_INTERCEPT_50 # define BOOST_PP_INTERCEPT_51 # define BOOST_PP_INTERCEPT_52 # define BOOST_PP_INTERCEPT_53 # define BOOST_PP_INTERCEPT_54 # define BOOST_PP_INTERCEPT_55 # define BOOST_PP_INTERCEPT_56 # define BOOST_PP_INTERCEPT_57 # define BOOST_PP_INTERCEPT_58 # define BOOST_PP_INTERCEPT_59 # define BOOST_PP_INTERCEPT_60 # define BOOST_PP_INTERCEPT_61 # define BOOST_PP_INTERCEPT_62 # define BOOST_PP_INTERCEPT_63 # define BOOST_PP_INTERCEPT_64 # define BOOST_PP_INTERCEPT_65 # define BOOST_PP_INTERCEPT_66 # define BOOST_PP_INTERCEPT_67 # define BOOST_PP_INTERCEPT_68 # define BOOST_PP_INTERCEPT_69 # define BOOST_PP_INTERCEPT_70 # define BOOST_PP_INTERCEPT_71 # define BOOST_PP_INTERCEPT_72 # define BOOST_PP_INTERCEPT_73 # define BOOST_PP_INTERCEPT_74 # define BOOST_PP_INTERCEPT_75 # define BOOST_PP_INTERCEPT_76 # define BOOST_PP_INTERCEPT_77 # define BOOST_PP_INTERCEPT_78 # define BOOST_PP_INTERCEPT_79 # define BOOST_PP_INTERCEPT_80 # define BOOST_PP_INTERCEPT_81 # define BOOST_PP_INTERCEPT_82 # define BOOST_PP_INTERCEPT_83 # define BOOST_PP_INTERCEPT_84 # define BOOST_PP_INTERCEPT_85 # define BOOST_PP_INTERCEPT_86 # define BOOST_PP_INTERCEPT_87 # define BOOST_PP_INTERCEPT_88 # define BOOST_PP_INTERCEPT_89 # define BOOST_PP_INTERCEPT_90 # define BOOST_PP_INTERCEPT_91 # define BOOST_PP_INTERCEPT_92 # define BOOST_PP_INTERCEPT_93 # define BOOST_PP_INTERCEPT_94 # define BOOST_PP_INTERCEPT_95 # define BOOST_PP_INTERCEPT_96 # define BOOST_PP_INTERCEPT_97 # define BOOST_PP_INTERCEPT_98 # define BOOST_PP_INTERCEPT_99 # define BOOST_PP_INTERCEPT_100 # define BOOST_PP_INTERCEPT_101 # define BOOST_PP_INTERCEPT_102 # define BOOST_PP_INTERCEPT_103 # define BOOST_PP_INTERCEPT_104 # define BOOST_PP_INTERCEPT_105 # define BOOST_PP_INTERCEPT_106 # define BOOST_PP_INTERCEPT_107 # define BOOST_PP_INTERCEPT_108 # define BOOST_PP_INTERCEPT_109 # define BOOST_PP_INTERCEPT_110 # define BOOST_PP_INTERCEPT_111 # define BOOST_PP_INTERCEPT_112 # define BOOST_PP_INTERCEPT_113 # define BOOST_PP_INTERCEPT_114 # define BOOST_PP_INTERCEPT_115 # define BOOST_PP_INTERCEPT_116 # define BOOST_PP_INTERCEPT_117 # define BOOST_PP_INTERCEPT_118 # define BOOST_PP_INTERCEPT_119 # define BOOST_PP_INTERCEPT_120 # define BOOST_PP_INTERCEPT_121 # define BOOST_PP_INTERCEPT_122 # define BOOST_PP_INTERCEPT_123 # define BOOST_PP_INTERCEPT_124 # define BOOST_PP_INTERCEPT_125 # define BOOST_PP_INTERCEPT_126 # define BOOST_PP_INTERCEPT_127 # define BOOST_PP_INTERCEPT_128 # define BOOST_PP_INTERCEPT_129 # define BOOST_PP_INTERCEPT_130 # define BOOST_PP_INTERCEPT_131 # define BOOST_PP_INTERCEPT_132 # define BOOST_PP_INTERCEPT_133 # define BOOST_PP_INTERCEPT_134 # define BOOST_PP_INTERCEPT_135 # define BOOST_PP_INTERCEPT_136 # define BOOST_PP_INTERCEPT_137 # define BOOST_PP_INTERCEPT_138 # define BOOST_PP_INTERCEPT_139 # define BOOST_PP_INTERCEPT_140 # define BOOST_PP_INTERCEPT_141 # define BOOST_PP_INTERCEPT_142 # define BOOST_PP_INTERCEPT_143 # define BOOST_PP_INTERCEPT_144 # define BOOST_PP_INTERCEPT_145 # define BOOST_PP_INTERCEPT_146 # define BOOST_PP_INTERCEPT_147 # define BOOST_PP_INTERCEPT_148 # define BOOST_PP_INTERCEPT_149 # define BOOST_PP_INTERCEPT_150 # define BOOST_PP_INTERCEPT_151 # define BOOST_PP_INTERCEPT_152 # define BOOST_PP_INTERCEPT_153 # define BOOST_PP_INTERCEPT_154 # define BOOST_PP_INTERCEPT_155 # define BOOST_PP_INTERCEPT_156 # define BOOST_PP_INTERCEPT_157 # define BOOST_PP_INTERCEPT_158 # define BOOST_PP_INTERCEPT_159 # define BOOST_PP_INTERCEPT_160 # define BOOST_PP_INTERCEPT_161 # define BOOST_PP_INTERCEPT_162 # define BOOST_PP_INTERCEPT_163 # define BOOST_PP_INTERCEPT_164 # define BOOST_PP_INTERCEPT_165 # define BOOST_PP_INTERCEPT_166 # define BOOST_PP_INTERCEPT_167 # define BOOST_PP_INTERCEPT_168 # define BOOST_PP_INTERCEPT_169 # define BOOST_PP_INTERCEPT_170 # define BOOST_PP_INTERCEPT_171 # define BOOST_PP_INTERCEPT_172 # define BOOST_PP_INTERCEPT_173 # define BOOST_PP_INTERCEPT_174 # define BOOST_PP_INTERCEPT_175 # define BOOST_PP_INTERCEPT_176 # define BOOST_PP_INTERCEPT_177 # define BOOST_PP_INTERCEPT_178 # define BOOST_PP_INTERCEPT_179 # define BOOST_PP_INTERCEPT_180 # define BOOST_PP_INTERCEPT_181 # define BOOST_PP_INTERCEPT_182 # define BOOST_PP_INTERCEPT_183 # define BOOST_PP_INTERCEPT_184 # define BOOST_PP_INTERCEPT_185 # define BOOST_PP_INTERCEPT_186 # define BOOST_PP_INTERCEPT_187 # define BOOST_PP_INTERCEPT_188 # define BOOST_PP_INTERCEPT_189 # define BOOST_PP_INTERCEPT_190 # define BOOST_PP_INTERCEPT_191 # define BOOST_PP_INTERCEPT_192 # define BOOST_PP_INTERCEPT_193 # define BOOST_PP_INTERCEPT_194 # define BOOST_PP_INTERCEPT_195 # define BOOST_PP_INTERCEPT_196 # define BOOST_PP_INTERCEPT_197 # define BOOST_PP_INTERCEPT_198 # define BOOST_PP_INTERCEPT_199 # define BOOST_PP_INTERCEPT_200 # define BOOST_PP_INTERCEPT_201 # define BOOST_PP_INTERCEPT_202 # define BOOST_PP_INTERCEPT_203 # define BOOST_PP_INTERCEPT_204 # define BOOST_PP_INTERCEPT_205 # define BOOST_PP_INTERCEPT_206 # define BOOST_PP_INTERCEPT_207 # define BOOST_PP_INTERCEPT_208 # define BOOST_PP_INTERCEPT_209 # define BOOST_PP_INTERCEPT_210 # define BOOST_PP_INTERCEPT_211 # define BOOST_PP_INTERCEPT_212 # define BOOST_PP_INTERCEPT_213 # define BOOST_PP_INTERCEPT_214 # define BOOST_PP_INTERCEPT_215 # define BOOST_PP_INTERCEPT_216 # define BOOST_PP_INTERCEPT_217 # define BOOST_PP_INTERCEPT_218 # define BOOST_PP_INTERCEPT_219 # define BOOST_PP_INTERCEPT_220 # define BOOST_PP_INTERCEPT_221 # define BOOST_PP_INTERCEPT_222 # define BOOST_PP_INTERCEPT_223 # define BOOST_PP_INTERCEPT_224 # define BOOST_PP_INTERCEPT_225 # define BOOST_PP_INTERCEPT_226 # define BOOST_PP_INTERCEPT_227 # define BOOST_PP_INTERCEPT_228 # define BOOST_PP_INTERCEPT_229 # define BOOST_PP_INTERCEPT_230 # define BOOST_PP_INTERCEPT_231 # define BOOST_PP_INTERCEPT_232 # define BOOST_PP_INTERCEPT_233 # define BOOST_PP_INTERCEPT_234 # define BOOST_PP_INTERCEPT_235 # define BOOST_PP_INTERCEPT_236 # define BOOST_PP_INTERCEPT_237 # define BOOST_PP_INTERCEPT_238 # define BOOST_PP_INTERCEPT_239 # define BOOST_PP_INTERCEPT_240 # define BOOST_PP_INTERCEPT_241 # define BOOST_PP_INTERCEPT_242 # define BOOST_PP_INTERCEPT_243 # define BOOST_PP_INTERCEPT_244 # define BOOST_PP_INTERCEPT_245 # define BOOST_PP_INTERCEPT_246 # define BOOST_PP_INTERCEPT_247 # define BOOST_PP_INTERCEPT_248 # define BOOST_PP_INTERCEPT_249 # define BOOST_PP_INTERCEPT_250 # define BOOST_PP_INTERCEPT_251 # define BOOST_PP_INTERCEPT_252 # define BOOST_PP_INTERCEPT_253 # define BOOST_PP_INTERCEPT_254 # define BOOST_PP_INTERCEPT_255 # define BOOST_PP_INTERCEPT_256 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/is_1.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2003. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_IS_1_HPP # define BOOST_PREPROCESSOR_FACILITIES_IS_1_HPP # # include # include # # /* BOOST_PP_IS_1 */ # # define BOOST_PP_IS_1(x) BOOST_PP_IS_EMPTY(BOOST_PP_CAT(BOOST_PP_IS_1_HELPER_, x)) # define BOOST_PP_IS_1_HELPER_1 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/is_empty.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2003. # * (C) Copyright Edward Diener 2014. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_IS_EMPTY_HPP # define BOOST_PREPROCESSOR_FACILITIES_IS_EMPTY_HPP # # include # # if BOOST_PP_VARIADICS # # include # # else # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() && ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # include # include # else # include # include # endif # # /* BOOST_PP_IS_EMPTY */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() && ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_IS_EMPTY(x) BOOST_PP_IS_EMPTY_I(x BOOST_PP_IS_EMPTY_HELPER) # define BOOST_PP_IS_EMPTY_I(contents) BOOST_PP_TUPLE_ELEM(2, 1, (BOOST_PP_IS_EMPTY_DEF_ ## contents())) # define BOOST_PP_IS_EMPTY_DEF_BOOST_PP_IS_EMPTY_HELPER 1, BOOST_PP_IDENTITY(1) # define BOOST_PP_IS_EMPTY_HELPER() , 0 # else # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_IS_EMPTY(x) BOOST_PP_IS_EMPTY_I(BOOST_PP_IS_EMPTY_HELPER x ()) # define BOOST_PP_IS_EMPTY_I(test) BOOST_PP_IS_EMPTY_II(BOOST_PP_SPLIT(0, BOOST_PP_CAT(BOOST_PP_IS_EMPTY_DEF_, test))) # define BOOST_PP_IS_EMPTY_II(id) id # else # define BOOST_PP_IS_EMPTY(x) BOOST_PP_IS_EMPTY_I((BOOST_PP_IS_EMPTY_HELPER x ())) # define BOOST_PP_IS_EMPTY_I(par) BOOST_PP_IS_EMPTY_II ## par # define BOOST_PP_IS_EMPTY_II(test) BOOST_PP_SPLIT(0, BOOST_PP_CAT(BOOST_PP_IS_EMPTY_DEF_, test)) # endif # define BOOST_PP_IS_EMPTY_HELPER() 1 # define BOOST_PP_IS_EMPTY_DEF_1 1, BOOST_PP_NIL # define BOOST_PP_IS_EMPTY_DEF_BOOST_PP_IS_EMPTY_HELPER 0, BOOST_PP_NIL # endif # # endif /* BOOST_PP_VARIADICS */ # # endif /* BOOST_PREPROCESSOR_FACILITIES_IS_EMPTY_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/is_empty_variadic.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2014. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_IS_EMPTY_VARIADIC_HPP # define BOOST_PREPROCESSOR_FACILITIES_IS_EMPTY_VARIADIC_HPP # # include # # if BOOST_PP_VARIADICS # # include # include # #if BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400 # #define BOOST_PP_IS_EMPTY(param) \ BOOST_PP_DETAIL_IS_EMPTY_IIF \ ( \ BOOST_PP_IS_BEGIN_PARENS \ ( \ param \ ) \ ) \ ( \ BOOST_PP_IS_EMPTY_ZERO, \ BOOST_PP_DETAIL_IS_EMPTY_PROCESS \ ) \ (param) \ /**/ #define BOOST_PP_IS_EMPTY_ZERO(param) 0 # else #define BOOST_PP_IS_EMPTY(...) \ BOOST_PP_DETAIL_IS_EMPTY_IIF \ ( \ BOOST_PP_IS_BEGIN_PARENS \ ( \ __VA_ARGS__ \ ) \ ) \ ( \ BOOST_PP_IS_EMPTY_ZERO, \ BOOST_PP_DETAIL_IS_EMPTY_PROCESS \ ) \ (__VA_ARGS__) \ /**/ #define BOOST_PP_IS_EMPTY_ZERO(...) 0 # endif /* BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400 */ # endif /* BOOST_PP_VARIADICS */ # endif /* BOOST_PREPROCESSOR_FACILITIES_IS_EMPTY_VARIADIC_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/facilities/overload.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2011. * # * (C) Copyright Edward Diener 2011. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FACILITIES_OVERLOAD_HPP # define BOOST_PREPROCESSOR_FACILITIES_OVERLOAD_HPP # # include # include # # /* BOOST_PP_OVERLOAD */ # # if BOOST_PP_VARIADICS # define BOOST_PP_OVERLOAD(prefix, ...) BOOST_PP_CAT(prefix, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/for.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_FOR_HPP # define BOOST_PREPROCESSOR_FOR_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/identity.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_IDENTITY_HPP # define BOOST_PREPROCESSOR_IDENTITY_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/inc.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_INC_HPP # define BOOST_PREPROCESSOR_INC_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iterate.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ITERATE_HPP # define BOOST_PREPROCESSOR_ITERATE_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/lower1.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_START_1 # # undef BOOST_PP_ITERATION_START_1_DIGIT_1 # undef BOOST_PP_ITERATION_START_1_DIGIT_2 # undef BOOST_PP_ITERATION_START_1_DIGIT_3 # undef BOOST_PP_ITERATION_START_1_DIGIT_4 # undef BOOST_PP_ITERATION_START_1_DIGIT_5 # undef BOOST_PP_ITERATION_START_1_DIGIT_6 # undef BOOST_PP_ITERATION_START_1_DIGIT_7 # undef BOOST_PP_ITERATION_START_1_DIGIT_8 # undef BOOST_PP_ITERATION_START_1_DIGIT_9 # undef BOOST_PP_ITERATION_START_1_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_START_1_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_START_1_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_START_1_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_START_1_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_START_1_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_START_1_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_START_1_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_START_1_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_START_1_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_START_1_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_START_1_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_START_1_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_START_1_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_START_1_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_START_1_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_START_1_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_START_1_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_START_1_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_START_1_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_START_1_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_START_1_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_START_1_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_START_1_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_START_1_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_START_1_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_START_1_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_START_1_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_START_1_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_START_1_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_START_1_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_START_1_DIGIT_3 # define BOOST_PP_ITERATION_START_1 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_START_1_DIGIT_3, BOOST_PP_ITERATION_START_1_DIGIT_2, BOOST_PP_ITERATION_START_1_DIGIT_1) # elif BOOST_PP_ITERATION_START_1_DIGIT_2 # define BOOST_PP_ITERATION_START_1 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_START_1_DIGIT_2, BOOST_PP_ITERATION_START_1_DIGIT_1) # else # define BOOST_PP_ITERATION_START_1 BOOST_PP_ITERATION_START_1_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/lower2.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_START_2 # # undef BOOST_PP_ITERATION_START_2_DIGIT_1 # undef BOOST_PP_ITERATION_START_2_DIGIT_2 # undef BOOST_PP_ITERATION_START_2_DIGIT_3 # undef BOOST_PP_ITERATION_START_2_DIGIT_4 # undef BOOST_PP_ITERATION_START_2_DIGIT_5 # undef BOOST_PP_ITERATION_START_2_DIGIT_6 # undef BOOST_PP_ITERATION_START_2_DIGIT_7 # undef BOOST_PP_ITERATION_START_2_DIGIT_8 # undef BOOST_PP_ITERATION_START_2_DIGIT_9 # undef BOOST_PP_ITERATION_START_2_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_START_2_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_START_2_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_START_2_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_START_2_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_START_2_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_START_2_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_START_2_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_START_2_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_START_2_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_START_2_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_START_2_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_START_2_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_START_2_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_START_2_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_START_2_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_START_2_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_START_2_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_START_2_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_START_2_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_START_2_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_START_2_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_START_2_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_START_2_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_START_2_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_START_2_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_START_2_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_START_2_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_START_2_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_START_2_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_START_2_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_START_2_DIGIT_3 # define BOOST_PP_ITERATION_START_2 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_START_2_DIGIT_3, BOOST_PP_ITERATION_START_2_DIGIT_2, BOOST_PP_ITERATION_START_2_DIGIT_1) # elif BOOST_PP_ITERATION_START_2_DIGIT_2 # define BOOST_PP_ITERATION_START_2 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_START_2_DIGIT_2, BOOST_PP_ITERATION_START_2_DIGIT_1) # else # define BOOST_PP_ITERATION_START_2 BOOST_PP_ITERATION_START_2_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/lower3.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_START_3 # # undef BOOST_PP_ITERATION_START_3_DIGIT_1 # undef BOOST_PP_ITERATION_START_3_DIGIT_2 # undef BOOST_PP_ITERATION_START_3_DIGIT_3 # undef BOOST_PP_ITERATION_START_3_DIGIT_4 # undef BOOST_PP_ITERATION_START_3_DIGIT_5 # undef BOOST_PP_ITERATION_START_3_DIGIT_6 # undef BOOST_PP_ITERATION_START_3_DIGIT_7 # undef BOOST_PP_ITERATION_START_3_DIGIT_8 # undef BOOST_PP_ITERATION_START_3_DIGIT_9 # undef BOOST_PP_ITERATION_START_3_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_START_3_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_START_3_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_START_3_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_START_3_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_START_3_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_START_3_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_START_3_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_START_3_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_START_3_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_START_3_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_START_3_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_START_3_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_START_3_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_START_3_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_START_3_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_START_3_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_START_3_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_START_3_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_START_3_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_START_3_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_START_3_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_START_3_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_START_3_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_START_3_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_START_3_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_START_3_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_START_3_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_START_3_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_START_3_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_START_3_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_START_3_DIGIT_3 # define BOOST_PP_ITERATION_START_3 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_START_3_DIGIT_3, BOOST_PP_ITERATION_START_3_DIGIT_2, BOOST_PP_ITERATION_START_3_DIGIT_1) # elif BOOST_PP_ITERATION_START_3_DIGIT_2 # define BOOST_PP_ITERATION_START_3 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_START_3_DIGIT_2, BOOST_PP_ITERATION_START_3_DIGIT_1) # else # define BOOST_PP_ITERATION_START_3 BOOST_PP_ITERATION_START_3_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/lower4.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_START_4 # # undef BOOST_PP_ITERATION_START_4_DIGIT_1 # undef BOOST_PP_ITERATION_START_4_DIGIT_2 # undef BOOST_PP_ITERATION_START_4_DIGIT_3 # undef BOOST_PP_ITERATION_START_4_DIGIT_4 # undef BOOST_PP_ITERATION_START_4_DIGIT_5 # undef BOOST_PP_ITERATION_START_4_DIGIT_6 # undef BOOST_PP_ITERATION_START_4_DIGIT_7 # undef BOOST_PP_ITERATION_START_4_DIGIT_8 # undef BOOST_PP_ITERATION_START_4_DIGIT_9 # undef BOOST_PP_ITERATION_START_4_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_START_4_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_START_4_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_START_4_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_START_4_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_START_4_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_START_4_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_START_4_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_START_4_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_START_4_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_START_4_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_START_4_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_START_4_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_START_4_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_START_4_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_START_4_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_START_4_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_START_4_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_START_4_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_START_4_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_START_4_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_START_4_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_START_4_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_START_4_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_START_4_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_START_4_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_START_4_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_START_4_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_START_4_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_START_4_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_START_4_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_START_4_DIGIT_3 # define BOOST_PP_ITERATION_START_4 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_START_4_DIGIT_3, BOOST_PP_ITERATION_START_4_DIGIT_2, BOOST_PP_ITERATION_START_4_DIGIT_1) # elif BOOST_PP_ITERATION_START_4_DIGIT_2 # define BOOST_PP_ITERATION_START_4 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_START_4_DIGIT_2, BOOST_PP_ITERATION_START_4_DIGIT_1) # else # define BOOST_PP_ITERATION_START_4 BOOST_PP_ITERATION_START_4_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/lower5.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_START_5 # # undef BOOST_PP_ITERATION_START_5_DIGIT_1 # undef BOOST_PP_ITERATION_START_5_DIGIT_2 # undef BOOST_PP_ITERATION_START_5_DIGIT_3 # undef BOOST_PP_ITERATION_START_5_DIGIT_4 # undef BOOST_PP_ITERATION_START_5_DIGIT_5 # undef BOOST_PP_ITERATION_START_5_DIGIT_6 # undef BOOST_PP_ITERATION_START_5_DIGIT_7 # undef BOOST_PP_ITERATION_START_5_DIGIT_8 # undef BOOST_PP_ITERATION_START_5_DIGIT_9 # undef BOOST_PP_ITERATION_START_5_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_START_5_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_START_5_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_START_5_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_START_5_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_START_5_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_START_5_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_START_5_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_START_5_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_START_5_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_START_5_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_START_5_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_START_5_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_START_5_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_START_5_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_START_5_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_START_5_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_START_5_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_START_5_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_START_5_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_START_5_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_START_5_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_START_5_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_START_5_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_START_5_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_START_5_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_START_5_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_START_5_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_START_5_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_START_5_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_START_5_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_START_5_DIGIT_3 # define BOOST_PP_ITERATION_START_5 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_START_5_DIGIT_3, BOOST_PP_ITERATION_START_5_DIGIT_2, BOOST_PP_ITERATION_START_5_DIGIT_1) # elif BOOST_PP_ITERATION_START_5_DIGIT_2 # define BOOST_PP_ITERATION_START_5 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_START_5_DIGIT_2, BOOST_PP_ITERATION_START_5_DIGIT_1) # else # define BOOST_PP_ITERATION_START_5 BOOST_PP_ITERATION_START_5_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/upper1.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_FINISH_1 # # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_1 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_2 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_3 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_4 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_5 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_6 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_7 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_8 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_9 # undef BOOST_PP_ITERATION_FINISH_1_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_FINISH_1_DIGIT_3 # define BOOST_PP_ITERATION_FINISH_1 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_FINISH_1_DIGIT_3, BOOST_PP_ITERATION_FINISH_1_DIGIT_2, BOOST_PP_ITERATION_FINISH_1_DIGIT_1) # elif BOOST_PP_ITERATION_FINISH_1_DIGIT_2 # define BOOST_PP_ITERATION_FINISH_1 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_FINISH_1_DIGIT_2, BOOST_PP_ITERATION_FINISH_1_DIGIT_1) # else # define BOOST_PP_ITERATION_FINISH_1 BOOST_PP_ITERATION_FINISH_1_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/upper2.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_FINISH_2 # # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_1 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_2 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_3 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_4 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_5 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_6 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_7 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_8 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_9 # undef BOOST_PP_ITERATION_FINISH_2_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_FINISH_2_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_FINISH_2_DIGIT_3 # define BOOST_PP_ITERATION_FINISH_2 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_FINISH_2_DIGIT_3, BOOST_PP_ITERATION_FINISH_2_DIGIT_2, BOOST_PP_ITERATION_FINISH_2_DIGIT_1) # elif BOOST_PP_ITERATION_FINISH_2_DIGIT_2 # define BOOST_PP_ITERATION_FINISH_2 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_FINISH_2_DIGIT_2, BOOST_PP_ITERATION_FINISH_2_DIGIT_1) # else # define BOOST_PP_ITERATION_FINISH_2 BOOST_PP_ITERATION_FINISH_2_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/upper3.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_FINISH_3 # # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_1 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_2 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_3 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_4 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_5 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_6 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_7 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_8 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_9 # undef BOOST_PP_ITERATION_FINISH_3_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_FINISH_3_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_FINISH_3_DIGIT_3 # define BOOST_PP_ITERATION_FINISH_3 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_FINISH_3_DIGIT_3, BOOST_PP_ITERATION_FINISH_3_DIGIT_2, BOOST_PP_ITERATION_FINISH_3_DIGIT_1) # elif BOOST_PP_ITERATION_FINISH_3_DIGIT_2 # define BOOST_PP_ITERATION_FINISH_3 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_FINISH_3_DIGIT_2, BOOST_PP_ITERATION_FINISH_3_DIGIT_1) # else # define BOOST_PP_ITERATION_FINISH_3 BOOST_PP_ITERATION_FINISH_3_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/upper4.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_FINISH_4 # # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_1 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_2 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_3 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_4 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_5 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_6 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_7 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_8 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_9 # undef BOOST_PP_ITERATION_FINISH_4_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_FINISH_4_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_FINISH_4_DIGIT_3 # define BOOST_PP_ITERATION_FINISH_4 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_FINISH_4_DIGIT_3, BOOST_PP_ITERATION_FINISH_4_DIGIT_2, BOOST_PP_ITERATION_FINISH_4_DIGIT_1) # elif BOOST_PP_ITERATION_FINISH_4_DIGIT_2 # define BOOST_PP_ITERATION_FINISH_4 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_FINISH_4_DIGIT_2, BOOST_PP_ITERATION_FINISH_4_DIGIT_1) # else # define BOOST_PP_ITERATION_FINISH_4 BOOST_PP_ITERATION_FINISH_4_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/bounds/upper5.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_ITERATION_FINISH_5 # # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_1 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_2 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_3 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_4 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_5 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_6 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_7 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_8 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_9 # undef BOOST_PP_ITERATION_FINISH_5_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_ITERATION_FINISH_5_DIGIT_1 9 # endif # # if BOOST_PP_ITERATION_FINISH_5_DIGIT_3 # define BOOST_PP_ITERATION_FINISH_5 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_FINISH_5_DIGIT_3, BOOST_PP_ITERATION_FINISH_5_DIGIT_2, BOOST_PP_ITERATION_FINISH_5_DIGIT_1) # elif BOOST_PP_ITERATION_FINISH_5_DIGIT_2 # define BOOST_PP_ITERATION_FINISH_5 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_FINISH_5_DIGIT_2, BOOST_PP_ITERATION_FINISH_5_DIGIT_1) # else # define BOOST_PP_ITERATION_FINISH_5 BOOST_PP_ITERATION_FINISH_5_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/finish.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_LOCAL_FE # # undef BOOST_PP_LOCAL_FE_DIGIT_1 # undef BOOST_PP_LOCAL_FE_DIGIT_2 # undef BOOST_PP_LOCAL_FE_DIGIT_3 # undef BOOST_PP_LOCAL_FE_DIGIT_4 # undef BOOST_PP_LOCAL_FE_DIGIT_5 # undef BOOST_PP_LOCAL_FE_DIGIT_6 # undef BOOST_PP_LOCAL_FE_DIGIT_7 # undef BOOST_PP_LOCAL_FE_DIGIT_8 # undef BOOST_PP_LOCAL_FE_DIGIT_9 # undef BOOST_PP_LOCAL_FE_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_LOCAL_FE_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_LOCAL_FE_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_LOCAL_FE_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_LOCAL_FE_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_LOCAL_FE_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_LOCAL_FE_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_LOCAL_FE_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_LOCAL_FE_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_LOCAL_FE_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_LOCAL_FE_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_LOCAL_FE_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_LOCAL_FE_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_LOCAL_FE_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_LOCAL_FE_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_LOCAL_FE_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_LOCAL_FE_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_LOCAL_FE_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_LOCAL_FE_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_LOCAL_FE_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_LOCAL_FE_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_LOCAL_FE_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_LOCAL_FE_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_LOCAL_FE_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_LOCAL_FE_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_LOCAL_FE_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_LOCAL_FE_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_LOCAL_FE_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_LOCAL_FE_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_LOCAL_FE_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_LOCAL_FE_DIGIT_1 9 # endif # # if BOOST_PP_LOCAL_FE_DIGIT_3 # define BOOST_PP_LOCAL_FE() BOOST_PP_SLOT_CC_3(BOOST_PP_LOCAL_FE_DIGIT_3, BOOST_PP_LOCAL_FE_DIGIT_2, BOOST_PP_LOCAL_FE_DIGIT_1) # elif BOOST_PP_LOCAL_FE_DIGIT_2 # define BOOST_PP_LOCAL_FE() BOOST_PP_SLOT_CC_2(BOOST_PP_LOCAL_FE_DIGIT_2, BOOST_PP_LOCAL_FE_DIGIT_1) # else # define BOOST_PP_LOCAL_FE() BOOST_PP_LOCAL_FE_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/forward1.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if defined(BOOST_PP_ITERATION_LIMITS) # if !defined(BOOST_PP_FILENAME_1) # error BOOST_PP_ERROR: depth #1 filename is not defined # endif # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_ITERATION_FLAGS_1() 0 # undef BOOST_PP_ITERATION_LIMITS # elif defined(BOOST_PP_ITERATION_PARAMS_1) # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(0, BOOST_PP_ITERATION_PARAMS_1) # include # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(1, BOOST_PP_ITERATION_PARAMS_1) # include # define BOOST_PP_FILENAME_1 BOOST_PP_ARRAY_ELEM(2, BOOST_PP_ITERATION_PARAMS_1) # if BOOST_PP_ARRAY_SIZE(BOOST_PP_ITERATION_PARAMS_1) >= 4 # define BOOST_PP_ITERATION_FLAGS_1() BOOST_PP_ARRAY_ELEM(3, BOOST_PP_ITERATION_PARAMS_1) # else # define BOOST_PP_ITERATION_FLAGS_1() 0 # endif # else # error BOOST_PP_ERROR: depth #1 iteration boundaries or filename not defined # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 1 # # define BOOST_PP_IS_ITERATING 1 # # if (BOOST_PP_ITERATION_START_1) > (BOOST_PP_ITERATION_FINISH_1) # include # else # if BOOST_PP_ITERATION_START_1 <= 0 && BOOST_PP_ITERATION_FINISH_1 >= 0 # define BOOST_PP_ITERATION_1 0 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 1 && BOOST_PP_ITERATION_FINISH_1 >= 1 # define BOOST_PP_ITERATION_1 1 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 2 && BOOST_PP_ITERATION_FINISH_1 >= 2 # define BOOST_PP_ITERATION_1 2 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 3 && BOOST_PP_ITERATION_FINISH_1 >= 3 # define BOOST_PP_ITERATION_1 3 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 4 && BOOST_PP_ITERATION_FINISH_1 >= 4 # define BOOST_PP_ITERATION_1 4 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 5 && BOOST_PP_ITERATION_FINISH_1 >= 5 # define BOOST_PP_ITERATION_1 5 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 6 && BOOST_PP_ITERATION_FINISH_1 >= 6 # define BOOST_PP_ITERATION_1 6 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 7 && BOOST_PP_ITERATION_FINISH_1 >= 7 # define BOOST_PP_ITERATION_1 7 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 8 && BOOST_PP_ITERATION_FINISH_1 >= 8 # define BOOST_PP_ITERATION_1 8 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 9 && BOOST_PP_ITERATION_FINISH_1 >= 9 # define BOOST_PP_ITERATION_1 9 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 10 && BOOST_PP_ITERATION_FINISH_1 >= 10 # define BOOST_PP_ITERATION_1 10 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 11 && BOOST_PP_ITERATION_FINISH_1 >= 11 # define BOOST_PP_ITERATION_1 11 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 12 && BOOST_PP_ITERATION_FINISH_1 >= 12 # define BOOST_PP_ITERATION_1 12 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 13 && BOOST_PP_ITERATION_FINISH_1 >= 13 # define BOOST_PP_ITERATION_1 13 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 14 && BOOST_PP_ITERATION_FINISH_1 >= 14 # define BOOST_PP_ITERATION_1 14 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 15 && BOOST_PP_ITERATION_FINISH_1 >= 15 # define BOOST_PP_ITERATION_1 15 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 16 && BOOST_PP_ITERATION_FINISH_1 >= 16 # define BOOST_PP_ITERATION_1 16 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 17 && BOOST_PP_ITERATION_FINISH_1 >= 17 # define BOOST_PP_ITERATION_1 17 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 18 && BOOST_PP_ITERATION_FINISH_1 >= 18 # define BOOST_PP_ITERATION_1 18 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 19 && BOOST_PP_ITERATION_FINISH_1 >= 19 # define BOOST_PP_ITERATION_1 19 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 20 && BOOST_PP_ITERATION_FINISH_1 >= 20 # define BOOST_PP_ITERATION_1 20 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 21 && BOOST_PP_ITERATION_FINISH_1 >= 21 # define BOOST_PP_ITERATION_1 21 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 22 && BOOST_PP_ITERATION_FINISH_1 >= 22 # define BOOST_PP_ITERATION_1 22 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 23 && BOOST_PP_ITERATION_FINISH_1 >= 23 # define BOOST_PP_ITERATION_1 23 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 24 && BOOST_PP_ITERATION_FINISH_1 >= 24 # define BOOST_PP_ITERATION_1 24 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 25 && BOOST_PP_ITERATION_FINISH_1 >= 25 # define BOOST_PP_ITERATION_1 25 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 26 && BOOST_PP_ITERATION_FINISH_1 >= 26 # define BOOST_PP_ITERATION_1 26 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 27 && BOOST_PP_ITERATION_FINISH_1 >= 27 # define BOOST_PP_ITERATION_1 27 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 28 && BOOST_PP_ITERATION_FINISH_1 >= 28 # define BOOST_PP_ITERATION_1 28 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 29 && BOOST_PP_ITERATION_FINISH_1 >= 29 # define BOOST_PP_ITERATION_1 29 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 30 && BOOST_PP_ITERATION_FINISH_1 >= 30 # define BOOST_PP_ITERATION_1 30 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 31 && BOOST_PP_ITERATION_FINISH_1 >= 31 # define BOOST_PP_ITERATION_1 31 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 32 && BOOST_PP_ITERATION_FINISH_1 >= 32 # define BOOST_PP_ITERATION_1 32 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 33 && BOOST_PP_ITERATION_FINISH_1 >= 33 # define BOOST_PP_ITERATION_1 33 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 34 && BOOST_PP_ITERATION_FINISH_1 >= 34 # define BOOST_PP_ITERATION_1 34 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 35 && BOOST_PP_ITERATION_FINISH_1 >= 35 # define BOOST_PP_ITERATION_1 35 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 36 && BOOST_PP_ITERATION_FINISH_1 >= 36 # define BOOST_PP_ITERATION_1 36 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 37 && BOOST_PP_ITERATION_FINISH_1 >= 37 # define BOOST_PP_ITERATION_1 37 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 38 && BOOST_PP_ITERATION_FINISH_1 >= 38 # define BOOST_PP_ITERATION_1 38 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 39 && BOOST_PP_ITERATION_FINISH_1 >= 39 # define BOOST_PP_ITERATION_1 39 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 40 && BOOST_PP_ITERATION_FINISH_1 >= 40 # define BOOST_PP_ITERATION_1 40 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 41 && BOOST_PP_ITERATION_FINISH_1 >= 41 # define BOOST_PP_ITERATION_1 41 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 42 && BOOST_PP_ITERATION_FINISH_1 >= 42 # define BOOST_PP_ITERATION_1 42 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 43 && BOOST_PP_ITERATION_FINISH_1 >= 43 # define BOOST_PP_ITERATION_1 43 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 44 && BOOST_PP_ITERATION_FINISH_1 >= 44 # define BOOST_PP_ITERATION_1 44 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 45 && BOOST_PP_ITERATION_FINISH_1 >= 45 # define BOOST_PP_ITERATION_1 45 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 46 && BOOST_PP_ITERATION_FINISH_1 >= 46 # define BOOST_PP_ITERATION_1 46 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 47 && BOOST_PP_ITERATION_FINISH_1 >= 47 # define BOOST_PP_ITERATION_1 47 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 48 && BOOST_PP_ITERATION_FINISH_1 >= 48 # define BOOST_PP_ITERATION_1 48 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 49 && BOOST_PP_ITERATION_FINISH_1 >= 49 # define BOOST_PP_ITERATION_1 49 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 50 && BOOST_PP_ITERATION_FINISH_1 >= 50 # define BOOST_PP_ITERATION_1 50 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 51 && BOOST_PP_ITERATION_FINISH_1 >= 51 # define BOOST_PP_ITERATION_1 51 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 52 && BOOST_PP_ITERATION_FINISH_1 >= 52 # define BOOST_PP_ITERATION_1 52 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 53 && BOOST_PP_ITERATION_FINISH_1 >= 53 # define BOOST_PP_ITERATION_1 53 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 54 && BOOST_PP_ITERATION_FINISH_1 >= 54 # define BOOST_PP_ITERATION_1 54 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 55 && BOOST_PP_ITERATION_FINISH_1 >= 55 # define BOOST_PP_ITERATION_1 55 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 56 && BOOST_PP_ITERATION_FINISH_1 >= 56 # define BOOST_PP_ITERATION_1 56 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 57 && BOOST_PP_ITERATION_FINISH_1 >= 57 # define BOOST_PP_ITERATION_1 57 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 58 && BOOST_PP_ITERATION_FINISH_1 >= 58 # define BOOST_PP_ITERATION_1 58 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 59 && BOOST_PP_ITERATION_FINISH_1 >= 59 # define BOOST_PP_ITERATION_1 59 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 60 && BOOST_PP_ITERATION_FINISH_1 >= 60 # define BOOST_PP_ITERATION_1 60 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 61 && BOOST_PP_ITERATION_FINISH_1 >= 61 # define BOOST_PP_ITERATION_1 61 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 62 && BOOST_PP_ITERATION_FINISH_1 >= 62 # define BOOST_PP_ITERATION_1 62 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 63 && BOOST_PP_ITERATION_FINISH_1 >= 63 # define BOOST_PP_ITERATION_1 63 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 64 && BOOST_PP_ITERATION_FINISH_1 >= 64 # define BOOST_PP_ITERATION_1 64 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 65 && BOOST_PP_ITERATION_FINISH_1 >= 65 # define BOOST_PP_ITERATION_1 65 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 66 && BOOST_PP_ITERATION_FINISH_1 >= 66 # define BOOST_PP_ITERATION_1 66 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 67 && BOOST_PP_ITERATION_FINISH_1 >= 67 # define BOOST_PP_ITERATION_1 67 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 68 && BOOST_PP_ITERATION_FINISH_1 >= 68 # define BOOST_PP_ITERATION_1 68 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 69 && BOOST_PP_ITERATION_FINISH_1 >= 69 # define BOOST_PP_ITERATION_1 69 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 70 && BOOST_PP_ITERATION_FINISH_1 >= 70 # define BOOST_PP_ITERATION_1 70 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 71 && BOOST_PP_ITERATION_FINISH_1 >= 71 # define BOOST_PP_ITERATION_1 71 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 72 && BOOST_PP_ITERATION_FINISH_1 >= 72 # define BOOST_PP_ITERATION_1 72 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 73 && BOOST_PP_ITERATION_FINISH_1 >= 73 # define BOOST_PP_ITERATION_1 73 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 74 && BOOST_PP_ITERATION_FINISH_1 >= 74 # define BOOST_PP_ITERATION_1 74 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 75 && BOOST_PP_ITERATION_FINISH_1 >= 75 # define BOOST_PP_ITERATION_1 75 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 76 && BOOST_PP_ITERATION_FINISH_1 >= 76 # define BOOST_PP_ITERATION_1 76 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 77 && BOOST_PP_ITERATION_FINISH_1 >= 77 # define BOOST_PP_ITERATION_1 77 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 78 && BOOST_PP_ITERATION_FINISH_1 >= 78 # define BOOST_PP_ITERATION_1 78 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 79 && BOOST_PP_ITERATION_FINISH_1 >= 79 # define BOOST_PP_ITERATION_1 79 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 80 && BOOST_PP_ITERATION_FINISH_1 >= 80 # define BOOST_PP_ITERATION_1 80 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 81 && BOOST_PP_ITERATION_FINISH_1 >= 81 # define BOOST_PP_ITERATION_1 81 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 82 && BOOST_PP_ITERATION_FINISH_1 >= 82 # define BOOST_PP_ITERATION_1 82 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 83 && BOOST_PP_ITERATION_FINISH_1 >= 83 # define BOOST_PP_ITERATION_1 83 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 84 && BOOST_PP_ITERATION_FINISH_1 >= 84 # define BOOST_PP_ITERATION_1 84 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 85 && BOOST_PP_ITERATION_FINISH_1 >= 85 # define BOOST_PP_ITERATION_1 85 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 86 && BOOST_PP_ITERATION_FINISH_1 >= 86 # define BOOST_PP_ITERATION_1 86 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 87 && BOOST_PP_ITERATION_FINISH_1 >= 87 # define BOOST_PP_ITERATION_1 87 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 88 && BOOST_PP_ITERATION_FINISH_1 >= 88 # define BOOST_PP_ITERATION_1 88 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 89 && BOOST_PP_ITERATION_FINISH_1 >= 89 # define BOOST_PP_ITERATION_1 89 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 90 && BOOST_PP_ITERATION_FINISH_1 >= 90 # define BOOST_PP_ITERATION_1 90 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 91 && BOOST_PP_ITERATION_FINISH_1 >= 91 # define BOOST_PP_ITERATION_1 91 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 92 && BOOST_PP_ITERATION_FINISH_1 >= 92 # define BOOST_PP_ITERATION_1 92 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 93 && BOOST_PP_ITERATION_FINISH_1 >= 93 # define BOOST_PP_ITERATION_1 93 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 94 && BOOST_PP_ITERATION_FINISH_1 >= 94 # define BOOST_PP_ITERATION_1 94 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 95 && BOOST_PP_ITERATION_FINISH_1 >= 95 # define BOOST_PP_ITERATION_1 95 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 96 && BOOST_PP_ITERATION_FINISH_1 >= 96 # define BOOST_PP_ITERATION_1 96 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 97 && BOOST_PP_ITERATION_FINISH_1 >= 97 # define BOOST_PP_ITERATION_1 97 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 98 && BOOST_PP_ITERATION_FINISH_1 >= 98 # define BOOST_PP_ITERATION_1 98 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 99 && BOOST_PP_ITERATION_FINISH_1 >= 99 # define BOOST_PP_ITERATION_1 99 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 100 && BOOST_PP_ITERATION_FINISH_1 >= 100 # define BOOST_PP_ITERATION_1 100 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 101 && BOOST_PP_ITERATION_FINISH_1 >= 101 # define BOOST_PP_ITERATION_1 101 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 102 && BOOST_PP_ITERATION_FINISH_1 >= 102 # define BOOST_PP_ITERATION_1 102 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 103 && BOOST_PP_ITERATION_FINISH_1 >= 103 # define BOOST_PP_ITERATION_1 103 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 104 && BOOST_PP_ITERATION_FINISH_1 >= 104 # define BOOST_PP_ITERATION_1 104 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 105 && BOOST_PP_ITERATION_FINISH_1 >= 105 # define BOOST_PP_ITERATION_1 105 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 106 && BOOST_PP_ITERATION_FINISH_1 >= 106 # define BOOST_PP_ITERATION_1 106 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 107 && BOOST_PP_ITERATION_FINISH_1 >= 107 # define BOOST_PP_ITERATION_1 107 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 108 && BOOST_PP_ITERATION_FINISH_1 >= 108 # define BOOST_PP_ITERATION_1 108 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 109 && BOOST_PP_ITERATION_FINISH_1 >= 109 # define BOOST_PP_ITERATION_1 109 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 110 && BOOST_PP_ITERATION_FINISH_1 >= 110 # define BOOST_PP_ITERATION_1 110 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 111 && BOOST_PP_ITERATION_FINISH_1 >= 111 # define BOOST_PP_ITERATION_1 111 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 112 && BOOST_PP_ITERATION_FINISH_1 >= 112 # define BOOST_PP_ITERATION_1 112 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 113 && BOOST_PP_ITERATION_FINISH_1 >= 113 # define BOOST_PP_ITERATION_1 113 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 114 && BOOST_PP_ITERATION_FINISH_1 >= 114 # define BOOST_PP_ITERATION_1 114 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 115 && BOOST_PP_ITERATION_FINISH_1 >= 115 # define BOOST_PP_ITERATION_1 115 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 116 && BOOST_PP_ITERATION_FINISH_1 >= 116 # define BOOST_PP_ITERATION_1 116 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 117 && BOOST_PP_ITERATION_FINISH_1 >= 117 # define BOOST_PP_ITERATION_1 117 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 118 && BOOST_PP_ITERATION_FINISH_1 >= 118 # define BOOST_PP_ITERATION_1 118 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 119 && BOOST_PP_ITERATION_FINISH_1 >= 119 # define BOOST_PP_ITERATION_1 119 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 120 && BOOST_PP_ITERATION_FINISH_1 >= 120 # define BOOST_PP_ITERATION_1 120 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 121 && BOOST_PP_ITERATION_FINISH_1 >= 121 # define BOOST_PP_ITERATION_1 121 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 122 && BOOST_PP_ITERATION_FINISH_1 >= 122 # define BOOST_PP_ITERATION_1 122 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 123 && BOOST_PP_ITERATION_FINISH_1 >= 123 # define BOOST_PP_ITERATION_1 123 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 124 && BOOST_PP_ITERATION_FINISH_1 >= 124 # define BOOST_PP_ITERATION_1 124 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 125 && BOOST_PP_ITERATION_FINISH_1 >= 125 # define BOOST_PP_ITERATION_1 125 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 126 && BOOST_PP_ITERATION_FINISH_1 >= 126 # define BOOST_PP_ITERATION_1 126 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 127 && BOOST_PP_ITERATION_FINISH_1 >= 127 # define BOOST_PP_ITERATION_1 127 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 128 && BOOST_PP_ITERATION_FINISH_1 >= 128 # define BOOST_PP_ITERATION_1 128 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 129 && BOOST_PP_ITERATION_FINISH_1 >= 129 # define BOOST_PP_ITERATION_1 129 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 130 && BOOST_PP_ITERATION_FINISH_1 >= 130 # define BOOST_PP_ITERATION_1 130 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 131 && BOOST_PP_ITERATION_FINISH_1 >= 131 # define BOOST_PP_ITERATION_1 131 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 132 && BOOST_PP_ITERATION_FINISH_1 >= 132 # define BOOST_PP_ITERATION_1 132 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 133 && BOOST_PP_ITERATION_FINISH_1 >= 133 # define BOOST_PP_ITERATION_1 133 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 134 && BOOST_PP_ITERATION_FINISH_1 >= 134 # define BOOST_PP_ITERATION_1 134 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 135 && BOOST_PP_ITERATION_FINISH_1 >= 135 # define BOOST_PP_ITERATION_1 135 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 136 && BOOST_PP_ITERATION_FINISH_1 >= 136 # define BOOST_PP_ITERATION_1 136 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 137 && BOOST_PP_ITERATION_FINISH_1 >= 137 # define BOOST_PP_ITERATION_1 137 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 138 && BOOST_PP_ITERATION_FINISH_1 >= 138 # define BOOST_PP_ITERATION_1 138 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 139 && BOOST_PP_ITERATION_FINISH_1 >= 139 # define BOOST_PP_ITERATION_1 139 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 140 && BOOST_PP_ITERATION_FINISH_1 >= 140 # define BOOST_PP_ITERATION_1 140 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 141 && BOOST_PP_ITERATION_FINISH_1 >= 141 # define BOOST_PP_ITERATION_1 141 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 142 && BOOST_PP_ITERATION_FINISH_1 >= 142 # define BOOST_PP_ITERATION_1 142 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 143 && BOOST_PP_ITERATION_FINISH_1 >= 143 # define BOOST_PP_ITERATION_1 143 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 144 && BOOST_PP_ITERATION_FINISH_1 >= 144 # define BOOST_PP_ITERATION_1 144 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 145 && BOOST_PP_ITERATION_FINISH_1 >= 145 # define BOOST_PP_ITERATION_1 145 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 146 && BOOST_PP_ITERATION_FINISH_1 >= 146 # define BOOST_PP_ITERATION_1 146 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 147 && BOOST_PP_ITERATION_FINISH_1 >= 147 # define BOOST_PP_ITERATION_1 147 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 148 && BOOST_PP_ITERATION_FINISH_1 >= 148 # define BOOST_PP_ITERATION_1 148 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 149 && BOOST_PP_ITERATION_FINISH_1 >= 149 # define BOOST_PP_ITERATION_1 149 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 150 && BOOST_PP_ITERATION_FINISH_1 >= 150 # define BOOST_PP_ITERATION_1 150 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 151 && BOOST_PP_ITERATION_FINISH_1 >= 151 # define BOOST_PP_ITERATION_1 151 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 152 && BOOST_PP_ITERATION_FINISH_1 >= 152 # define BOOST_PP_ITERATION_1 152 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 153 && BOOST_PP_ITERATION_FINISH_1 >= 153 # define BOOST_PP_ITERATION_1 153 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 154 && BOOST_PP_ITERATION_FINISH_1 >= 154 # define BOOST_PP_ITERATION_1 154 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 155 && BOOST_PP_ITERATION_FINISH_1 >= 155 # define BOOST_PP_ITERATION_1 155 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 156 && BOOST_PP_ITERATION_FINISH_1 >= 156 # define BOOST_PP_ITERATION_1 156 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 157 && BOOST_PP_ITERATION_FINISH_1 >= 157 # define BOOST_PP_ITERATION_1 157 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 158 && BOOST_PP_ITERATION_FINISH_1 >= 158 # define BOOST_PP_ITERATION_1 158 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 159 && BOOST_PP_ITERATION_FINISH_1 >= 159 # define BOOST_PP_ITERATION_1 159 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 160 && BOOST_PP_ITERATION_FINISH_1 >= 160 # define BOOST_PP_ITERATION_1 160 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 161 && BOOST_PP_ITERATION_FINISH_1 >= 161 # define BOOST_PP_ITERATION_1 161 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 162 && BOOST_PP_ITERATION_FINISH_1 >= 162 # define BOOST_PP_ITERATION_1 162 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 163 && BOOST_PP_ITERATION_FINISH_1 >= 163 # define BOOST_PP_ITERATION_1 163 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 164 && BOOST_PP_ITERATION_FINISH_1 >= 164 # define BOOST_PP_ITERATION_1 164 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 165 && BOOST_PP_ITERATION_FINISH_1 >= 165 # define BOOST_PP_ITERATION_1 165 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 166 && BOOST_PP_ITERATION_FINISH_1 >= 166 # define BOOST_PP_ITERATION_1 166 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 167 && BOOST_PP_ITERATION_FINISH_1 >= 167 # define BOOST_PP_ITERATION_1 167 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 168 && BOOST_PP_ITERATION_FINISH_1 >= 168 # define BOOST_PP_ITERATION_1 168 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 169 && BOOST_PP_ITERATION_FINISH_1 >= 169 # define BOOST_PP_ITERATION_1 169 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 170 && BOOST_PP_ITERATION_FINISH_1 >= 170 # define BOOST_PP_ITERATION_1 170 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 171 && BOOST_PP_ITERATION_FINISH_1 >= 171 # define BOOST_PP_ITERATION_1 171 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 172 && BOOST_PP_ITERATION_FINISH_1 >= 172 # define BOOST_PP_ITERATION_1 172 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 173 && BOOST_PP_ITERATION_FINISH_1 >= 173 # define BOOST_PP_ITERATION_1 173 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 174 && BOOST_PP_ITERATION_FINISH_1 >= 174 # define BOOST_PP_ITERATION_1 174 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 175 && BOOST_PP_ITERATION_FINISH_1 >= 175 # define BOOST_PP_ITERATION_1 175 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 176 && BOOST_PP_ITERATION_FINISH_1 >= 176 # define BOOST_PP_ITERATION_1 176 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 177 && BOOST_PP_ITERATION_FINISH_1 >= 177 # define BOOST_PP_ITERATION_1 177 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 178 && BOOST_PP_ITERATION_FINISH_1 >= 178 # define BOOST_PP_ITERATION_1 178 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 179 && BOOST_PP_ITERATION_FINISH_1 >= 179 # define BOOST_PP_ITERATION_1 179 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 180 && BOOST_PP_ITERATION_FINISH_1 >= 180 # define BOOST_PP_ITERATION_1 180 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 181 && BOOST_PP_ITERATION_FINISH_1 >= 181 # define BOOST_PP_ITERATION_1 181 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 182 && BOOST_PP_ITERATION_FINISH_1 >= 182 # define BOOST_PP_ITERATION_1 182 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 183 && BOOST_PP_ITERATION_FINISH_1 >= 183 # define BOOST_PP_ITERATION_1 183 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 184 && BOOST_PP_ITERATION_FINISH_1 >= 184 # define BOOST_PP_ITERATION_1 184 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 185 && BOOST_PP_ITERATION_FINISH_1 >= 185 # define BOOST_PP_ITERATION_1 185 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 186 && BOOST_PP_ITERATION_FINISH_1 >= 186 # define BOOST_PP_ITERATION_1 186 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 187 && BOOST_PP_ITERATION_FINISH_1 >= 187 # define BOOST_PP_ITERATION_1 187 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 188 && BOOST_PP_ITERATION_FINISH_1 >= 188 # define BOOST_PP_ITERATION_1 188 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 189 && BOOST_PP_ITERATION_FINISH_1 >= 189 # define BOOST_PP_ITERATION_1 189 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 190 && BOOST_PP_ITERATION_FINISH_1 >= 190 # define BOOST_PP_ITERATION_1 190 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 191 && BOOST_PP_ITERATION_FINISH_1 >= 191 # define BOOST_PP_ITERATION_1 191 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 192 && BOOST_PP_ITERATION_FINISH_1 >= 192 # define BOOST_PP_ITERATION_1 192 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 193 && BOOST_PP_ITERATION_FINISH_1 >= 193 # define BOOST_PP_ITERATION_1 193 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 194 && BOOST_PP_ITERATION_FINISH_1 >= 194 # define BOOST_PP_ITERATION_1 194 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 195 && BOOST_PP_ITERATION_FINISH_1 >= 195 # define BOOST_PP_ITERATION_1 195 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 196 && BOOST_PP_ITERATION_FINISH_1 >= 196 # define BOOST_PP_ITERATION_1 196 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 197 && BOOST_PP_ITERATION_FINISH_1 >= 197 # define BOOST_PP_ITERATION_1 197 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 198 && BOOST_PP_ITERATION_FINISH_1 >= 198 # define BOOST_PP_ITERATION_1 198 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 199 && BOOST_PP_ITERATION_FINISH_1 >= 199 # define BOOST_PP_ITERATION_1 199 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 200 && BOOST_PP_ITERATION_FINISH_1 >= 200 # define BOOST_PP_ITERATION_1 200 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 201 && BOOST_PP_ITERATION_FINISH_1 >= 201 # define BOOST_PP_ITERATION_1 201 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 202 && BOOST_PP_ITERATION_FINISH_1 >= 202 # define BOOST_PP_ITERATION_1 202 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 203 && BOOST_PP_ITERATION_FINISH_1 >= 203 # define BOOST_PP_ITERATION_1 203 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 204 && BOOST_PP_ITERATION_FINISH_1 >= 204 # define BOOST_PP_ITERATION_1 204 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 205 && BOOST_PP_ITERATION_FINISH_1 >= 205 # define BOOST_PP_ITERATION_1 205 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 206 && BOOST_PP_ITERATION_FINISH_1 >= 206 # define BOOST_PP_ITERATION_1 206 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 207 && BOOST_PP_ITERATION_FINISH_1 >= 207 # define BOOST_PP_ITERATION_1 207 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 208 && BOOST_PP_ITERATION_FINISH_1 >= 208 # define BOOST_PP_ITERATION_1 208 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 209 && BOOST_PP_ITERATION_FINISH_1 >= 209 # define BOOST_PP_ITERATION_1 209 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 210 && BOOST_PP_ITERATION_FINISH_1 >= 210 # define BOOST_PP_ITERATION_1 210 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 211 && BOOST_PP_ITERATION_FINISH_1 >= 211 # define BOOST_PP_ITERATION_1 211 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 212 && BOOST_PP_ITERATION_FINISH_1 >= 212 # define BOOST_PP_ITERATION_1 212 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 213 && BOOST_PP_ITERATION_FINISH_1 >= 213 # define BOOST_PP_ITERATION_1 213 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 214 && BOOST_PP_ITERATION_FINISH_1 >= 214 # define BOOST_PP_ITERATION_1 214 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 215 && BOOST_PP_ITERATION_FINISH_1 >= 215 # define BOOST_PP_ITERATION_1 215 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 216 && BOOST_PP_ITERATION_FINISH_1 >= 216 # define BOOST_PP_ITERATION_1 216 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 217 && BOOST_PP_ITERATION_FINISH_1 >= 217 # define BOOST_PP_ITERATION_1 217 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 218 && BOOST_PP_ITERATION_FINISH_1 >= 218 # define BOOST_PP_ITERATION_1 218 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 219 && BOOST_PP_ITERATION_FINISH_1 >= 219 # define BOOST_PP_ITERATION_1 219 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 220 && BOOST_PP_ITERATION_FINISH_1 >= 220 # define BOOST_PP_ITERATION_1 220 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 221 && BOOST_PP_ITERATION_FINISH_1 >= 221 # define BOOST_PP_ITERATION_1 221 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 222 && BOOST_PP_ITERATION_FINISH_1 >= 222 # define BOOST_PP_ITERATION_1 222 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 223 && BOOST_PP_ITERATION_FINISH_1 >= 223 # define BOOST_PP_ITERATION_1 223 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 224 && BOOST_PP_ITERATION_FINISH_1 >= 224 # define BOOST_PP_ITERATION_1 224 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 225 && BOOST_PP_ITERATION_FINISH_1 >= 225 # define BOOST_PP_ITERATION_1 225 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 226 && BOOST_PP_ITERATION_FINISH_1 >= 226 # define BOOST_PP_ITERATION_1 226 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 227 && BOOST_PP_ITERATION_FINISH_1 >= 227 # define BOOST_PP_ITERATION_1 227 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 228 && BOOST_PP_ITERATION_FINISH_1 >= 228 # define BOOST_PP_ITERATION_1 228 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 229 && BOOST_PP_ITERATION_FINISH_1 >= 229 # define BOOST_PP_ITERATION_1 229 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 230 && BOOST_PP_ITERATION_FINISH_1 >= 230 # define BOOST_PP_ITERATION_1 230 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 231 && BOOST_PP_ITERATION_FINISH_1 >= 231 # define BOOST_PP_ITERATION_1 231 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 232 && BOOST_PP_ITERATION_FINISH_1 >= 232 # define BOOST_PP_ITERATION_1 232 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 233 && BOOST_PP_ITERATION_FINISH_1 >= 233 # define BOOST_PP_ITERATION_1 233 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 234 && BOOST_PP_ITERATION_FINISH_1 >= 234 # define BOOST_PP_ITERATION_1 234 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 235 && BOOST_PP_ITERATION_FINISH_1 >= 235 # define BOOST_PP_ITERATION_1 235 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 236 && BOOST_PP_ITERATION_FINISH_1 >= 236 # define BOOST_PP_ITERATION_1 236 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 237 && BOOST_PP_ITERATION_FINISH_1 >= 237 # define BOOST_PP_ITERATION_1 237 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 238 && BOOST_PP_ITERATION_FINISH_1 >= 238 # define BOOST_PP_ITERATION_1 238 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 239 && BOOST_PP_ITERATION_FINISH_1 >= 239 # define BOOST_PP_ITERATION_1 239 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 240 && BOOST_PP_ITERATION_FINISH_1 >= 240 # define BOOST_PP_ITERATION_1 240 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 241 && BOOST_PP_ITERATION_FINISH_1 >= 241 # define BOOST_PP_ITERATION_1 241 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 242 && BOOST_PP_ITERATION_FINISH_1 >= 242 # define BOOST_PP_ITERATION_1 242 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 243 && BOOST_PP_ITERATION_FINISH_1 >= 243 # define BOOST_PP_ITERATION_1 243 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 244 && BOOST_PP_ITERATION_FINISH_1 >= 244 # define BOOST_PP_ITERATION_1 244 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 245 && BOOST_PP_ITERATION_FINISH_1 >= 245 # define BOOST_PP_ITERATION_1 245 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 246 && BOOST_PP_ITERATION_FINISH_1 >= 246 # define BOOST_PP_ITERATION_1 246 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 247 && BOOST_PP_ITERATION_FINISH_1 >= 247 # define BOOST_PP_ITERATION_1 247 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 248 && BOOST_PP_ITERATION_FINISH_1 >= 248 # define BOOST_PP_ITERATION_1 248 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 249 && BOOST_PP_ITERATION_FINISH_1 >= 249 # define BOOST_PP_ITERATION_1 249 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 250 && BOOST_PP_ITERATION_FINISH_1 >= 250 # define BOOST_PP_ITERATION_1 250 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 251 && BOOST_PP_ITERATION_FINISH_1 >= 251 # define BOOST_PP_ITERATION_1 251 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 252 && BOOST_PP_ITERATION_FINISH_1 >= 252 # define BOOST_PP_ITERATION_1 252 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 253 && BOOST_PP_ITERATION_FINISH_1 >= 253 # define BOOST_PP_ITERATION_1 253 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 254 && BOOST_PP_ITERATION_FINISH_1 >= 254 # define BOOST_PP_ITERATION_1 254 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 255 && BOOST_PP_ITERATION_FINISH_1 >= 255 # define BOOST_PP_ITERATION_1 255 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_START_1 <= 256 && BOOST_PP_ITERATION_FINISH_1 >= 256 # define BOOST_PP_ITERATION_1 256 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # endif # # undef BOOST_PP_IS_ITERATING # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 0 # # undef BOOST_PP_ITERATION_START_1 # undef BOOST_PP_ITERATION_FINISH_1 # undef BOOST_PP_FILENAME_1 # # undef BOOST_PP_ITERATION_FLAGS_1 # undef BOOST_PP_ITERATION_PARAMS_1 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/forward2.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if defined(BOOST_PP_ITERATION_LIMITS) # if !defined(BOOST_PP_FILENAME_2) # error BOOST_PP_ERROR: depth #2 filename is not defined # endif # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_ITERATION_FLAGS_2() 0 # undef BOOST_PP_ITERATION_LIMITS # elif defined(BOOST_PP_ITERATION_PARAMS_2) # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(0, BOOST_PP_ITERATION_PARAMS_2) # include # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(1, BOOST_PP_ITERATION_PARAMS_2) # include # define BOOST_PP_FILENAME_2 BOOST_PP_ARRAY_ELEM(2, BOOST_PP_ITERATION_PARAMS_2) # if BOOST_PP_ARRAY_SIZE(BOOST_PP_ITERATION_PARAMS_2) >= 4 # define BOOST_PP_ITERATION_FLAGS_2() BOOST_PP_ARRAY_ELEM(3, BOOST_PP_ITERATION_PARAMS_2) # else # define BOOST_PP_ITERATION_FLAGS_2() 0 # endif # else # error BOOST_PP_ERROR: depth #2 iteration boundaries or filename not defined # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 2 # # if (BOOST_PP_ITERATION_START_2) > (BOOST_PP_ITERATION_FINISH_2) # include # else # if BOOST_PP_ITERATION_START_2 <= 0 && BOOST_PP_ITERATION_FINISH_2 >= 0 # define BOOST_PP_ITERATION_2 0 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 1 && BOOST_PP_ITERATION_FINISH_2 >= 1 # define BOOST_PP_ITERATION_2 1 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 2 && BOOST_PP_ITERATION_FINISH_2 >= 2 # define BOOST_PP_ITERATION_2 2 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 3 && BOOST_PP_ITERATION_FINISH_2 >= 3 # define BOOST_PP_ITERATION_2 3 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 4 && BOOST_PP_ITERATION_FINISH_2 >= 4 # define BOOST_PP_ITERATION_2 4 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 5 && BOOST_PP_ITERATION_FINISH_2 >= 5 # define BOOST_PP_ITERATION_2 5 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 6 && BOOST_PP_ITERATION_FINISH_2 >= 6 # define BOOST_PP_ITERATION_2 6 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 7 && BOOST_PP_ITERATION_FINISH_2 >= 7 # define BOOST_PP_ITERATION_2 7 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 8 && BOOST_PP_ITERATION_FINISH_2 >= 8 # define BOOST_PP_ITERATION_2 8 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 9 && BOOST_PP_ITERATION_FINISH_2 >= 9 # define BOOST_PP_ITERATION_2 9 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 10 && BOOST_PP_ITERATION_FINISH_2 >= 10 # define BOOST_PP_ITERATION_2 10 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 11 && BOOST_PP_ITERATION_FINISH_2 >= 11 # define BOOST_PP_ITERATION_2 11 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 12 && BOOST_PP_ITERATION_FINISH_2 >= 12 # define BOOST_PP_ITERATION_2 12 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 13 && BOOST_PP_ITERATION_FINISH_2 >= 13 # define BOOST_PP_ITERATION_2 13 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 14 && BOOST_PP_ITERATION_FINISH_2 >= 14 # define BOOST_PP_ITERATION_2 14 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 15 && BOOST_PP_ITERATION_FINISH_2 >= 15 # define BOOST_PP_ITERATION_2 15 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 16 && BOOST_PP_ITERATION_FINISH_2 >= 16 # define BOOST_PP_ITERATION_2 16 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 17 && BOOST_PP_ITERATION_FINISH_2 >= 17 # define BOOST_PP_ITERATION_2 17 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 18 && BOOST_PP_ITERATION_FINISH_2 >= 18 # define BOOST_PP_ITERATION_2 18 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 19 && BOOST_PP_ITERATION_FINISH_2 >= 19 # define BOOST_PP_ITERATION_2 19 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 20 && BOOST_PP_ITERATION_FINISH_2 >= 20 # define BOOST_PP_ITERATION_2 20 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 21 && BOOST_PP_ITERATION_FINISH_2 >= 21 # define BOOST_PP_ITERATION_2 21 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 22 && BOOST_PP_ITERATION_FINISH_2 >= 22 # define BOOST_PP_ITERATION_2 22 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 23 && BOOST_PP_ITERATION_FINISH_2 >= 23 # define BOOST_PP_ITERATION_2 23 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 24 && BOOST_PP_ITERATION_FINISH_2 >= 24 # define BOOST_PP_ITERATION_2 24 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 25 && BOOST_PP_ITERATION_FINISH_2 >= 25 # define BOOST_PP_ITERATION_2 25 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 26 && BOOST_PP_ITERATION_FINISH_2 >= 26 # define BOOST_PP_ITERATION_2 26 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 27 && BOOST_PP_ITERATION_FINISH_2 >= 27 # define BOOST_PP_ITERATION_2 27 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 28 && BOOST_PP_ITERATION_FINISH_2 >= 28 # define BOOST_PP_ITERATION_2 28 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 29 && BOOST_PP_ITERATION_FINISH_2 >= 29 # define BOOST_PP_ITERATION_2 29 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 30 && BOOST_PP_ITERATION_FINISH_2 >= 30 # define BOOST_PP_ITERATION_2 30 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 31 && BOOST_PP_ITERATION_FINISH_2 >= 31 # define BOOST_PP_ITERATION_2 31 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 32 && BOOST_PP_ITERATION_FINISH_2 >= 32 # define BOOST_PP_ITERATION_2 32 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 33 && BOOST_PP_ITERATION_FINISH_2 >= 33 # define BOOST_PP_ITERATION_2 33 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 34 && BOOST_PP_ITERATION_FINISH_2 >= 34 # define BOOST_PP_ITERATION_2 34 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 35 && BOOST_PP_ITERATION_FINISH_2 >= 35 # define BOOST_PP_ITERATION_2 35 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 36 && BOOST_PP_ITERATION_FINISH_2 >= 36 # define BOOST_PP_ITERATION_2 36 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 37 && BOOST_PP_ITERATION_FINISH_2 >= 37 # define BOOST_PP_ITERATION_2 37 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 38 && BOOST_PP_ITERATION_FINISH_2 >= 38 # define BOOST_PP_ITERATION_2 38 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 39 && BOOST_PP_ITERATION_FINISH_2 >= 39 # define BOOST_PP_ITERATION_2 39 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 40 && BOOST_PP_ITERATION_FINISH_2 >= 40 # define BOOST_PP_ITERATION_2 40 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 41 && BOOST_PP_ITERATION_FINISH_2 >= 41 # define BOOST_PP_ITERATION_2 41 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 42 && BOOST_PP_ITERATION_FINISH_2 >= 42 # define BOOST_PP_ITERATION_2 42 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 43 && BOOST_PP_ITERATION_FINISH_2 >= 43 # define BOOST_PP_ITERATION_2 43 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 44 && BOOST_PP_ITERATION_FINISH_2 >= 44 # define BOOST_PP_ITERATION_2 44 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 45 && BOOST_PP_ITERATION_FINISH_2 >= 45 # define BOOST_PP_ITERATION_2 45 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 46 && BOOST_PP_ITERATION_FINISH_2 >= 46 # define BOOST_PP_ITERATION_2 46 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 47 && BOOST_PP_ITERATION_FINISH_2 >= 47 # define BOOST_PP_ITERATION_2 47 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 48 && BOOST_PP_ITERATION_FINISH_2 >= 48 # define BOOST_PP_ITERATION_2 48 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 49 && BOOST_PP_ITERATION_FINISH_2 >= 49 # define BOOST_PP_ITERATION_2 49 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 50 && BOOST_PP_ITERATION_FINISH_2 >= 50 # define BOOST_PP_ITERATION_2 50 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 51 && BOOST_PP_ITERATION_FINISH_2 >= 51 # define BOOST_PP_ITERATION_2 51 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 52 && BOOST_PP_ITERATION_FINISH_2 >= 52 # define BOOST_PP_ITERATION_2 52 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 53 && BOOST_PP_ITERATION_FINISH_2 >= 53 # define BOOST_PP_ITERATION_2 53 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 54 && BOOST_PP_ITERATION_FINISH_2 >= 54 # define BOOST_PP_ITERATION_2 54 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 55 && BOOST_PP_ITERATION_FINISH_2 >= 55 # define BOOST_PP_ITERATION_2 55 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 56 && BOOST_PP_ITERATION_FINISH_2 >= 56 # define BOOST_PP_ITERATION_2 56 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 57 && BOOST_PP_ITERATION_FINISH_2 >= 57 # define BOOST_PP_ITERATION_2 57 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 58 && BOOST_PP_ITERATION_FINISH_2 >= 58 # define BOOST_PP_ITERATION_2 58 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 59 && BOOST_PP_ITERATION_FINISH_2 >= 59 # define BOOST_PP_ITERATION_2 59 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 60 && BOOST_PP_ITERATION_FINISH_2 >= 60 # define BOOST_PP_ITERATION_2 60 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 61 && BOOST_PP_ITERATION_FINISH_2 >= 61 # define BOOST_PP_ITERATION_2 61 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 62 && BOOST_PP_ITERATION_FINISH_2 >= 62 # define BOOST_PP_ITERATION_2 62 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 63 && BOOST_PP_ITERATION_FINISH_2 >= 63 # define BOOST_PP_ITERATION_2 63 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 64 && BOOST_PP_ITERATION_FINISH_2 >= 64 # define BOOST_PP_ITERATION_2 64 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 65 && BOOST_PP_ITERATION_FINISH_2 >= 65 # define BOOST_PP_ITERATION_2 65 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 66 && BOOST_PP_ITERATION_FINISH_2 >= 66 # define BOOST_PP_ITERATION_2 66 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 67 && BOOST_PP_ITERATION_FINISH_2 >= 67 # define BOOST_PP_ITERATION_2 67 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 68 && BOOST_PP_ITERATION_FINISH_2 >= 68 # define BOOST_PP_ITERATION_2 68 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 69 && BOOST_PP_ITERATION_FINISH_2 >= 69 # define BOOST_PP_ITERATION_2 69 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 70 && BOOST_PP_ITERATION_FINISH_2 >= 70 # define BOOST_PP_ITERATION_2 70 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 71 && BOOST_PP_ITERATION_FINISH_2 >= 71 # define BOOST_PP_ITERATION_2 71 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 72 && BOOST_PP_ITERATION_FINISH_2 >= 72 # define BOOST_PP_ITERATION_2 72 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 73 && BOOST_PP_ITERATION_FINISH_2 >= 73 # define BOOST_PP_ITERATION_2 73 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 74 && BOOST_PP_ITERATION_FINISH_2 >= 74 # define BOOST_PP_ITERATION_2 74 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 75 && BOOST_PP_ITERATION_FINISH_2 >= 75 # define BOOST_PP_ITERATION_2 75 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 76 && BOOST_PP_ITERATION_FINISH_2 >= 76 # define BOOST_PP_ITERATION_2 76 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 77 && BOOST_PP_ITERATION_FINISH_2 >= 77 # define BOOST_PP_ITERATION_2 77 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 78 && BOOST_PP_ITERATION_FINISH_2 >= 78 # define BOOST_PP_ITERATION_2 78 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 79 && BOOST_PP_ITERATION_FINISH_2 >= 79 # define BOOST_PP_ITERATION_2 79 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 80 && BOOST_PP_ITERATION_FINISH_2 >= 80 # define BOOST_PP_ITERATION_2 80 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 81 && BOOST_PP_ITERATION_FINISH_2 >= 81 # define BOOST_PP_ITERATION_2 81 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 82 && BOOST_PP_ITERATION_FINISH_2 >= 82 # define BOOST_PP_ITERATION_2 82 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 83 && BOOST_PP_ITERATION_FINISH_2 >= 83 # define BOOST_PP_ITERATION_2 83 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 84 && BOOST_PP_ITERATION_FINISH_2 >= 84 # define BOOST_PP_ITERATION_2 84 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 85 && BOOST_PP_ITERATION_FINISH_2 >= 85 # define BOOST_PP_ITERATION_2 85 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 86 && BOOST_PP_ITERATION_FINISH_2 >= 86 # define BOOST_PP_ITERATION_2 86 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 87 && BOOST_PP_ITERATION_FINISH_2 >= 87 # define BOOST_PP_ITERATION_2 87 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 88 && BOOST_PP_ITERATION_FINISH_2 >= 88 # define BOOST_PP_ITERATION_2 88 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 89 && BOOST_PP_ITERATION_FINISH_2 >= 89 # define BOOST_PP_ITERATION_2 89 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 90 && BOOST_PP_ITERATION_FINISH_2 >= 90 # define BOOST_PP_ITERATION_2 90 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 91 && BOOST_PP_ITERATION_FINISH_2 >= 91 # define BOOST_PP_ITERATION_2 91 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 92 && BOOST_PP_ITERATION_FINISH_2 >= 92 # define BOOST_PP_ITERATION_2 92 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 93 && BOOST_PP_ITERATION_FINISH_2 >= 93 # define BOOST_PP_ITERATION_2 93 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 94 && BOOST_PP_ITERATION_FINISH_2 >= 94 # define BOOST_PP_ITERATION_2 94 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 95 && BOOST_PP_ITERATION_FINISH_2 >= 95 # define BOOST_PP_ITERATION_2 95 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 96 && BOOST_PP_ITERATION_FINISH_2 >= 96 # define BOOST_PP_ITERATION_2 96 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 97 && BOOST_PP_ITERATION_FINISH_2 >= 97 # define BOOST_PP_ITERATION_2 97 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 98 && BOOST_PP_ITERATION_FINISH_2 >= 98 # define BOOST_PP_ITERATION_2 98 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 99 && BOOST_PP_ITERATION_FINISH_2 >= 99 # define BOOST_PP_ITERATION_2 99 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 100 && BOOST_PP_ITERATION_FINISH_2 >= 100 # define BOOST_PP_ITERATION_2 100 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 101 && BOOST_PP_ITERATION_FINISH_2 >= 101 # define BOOST_PP_ITERATION_2 101 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 102 && BOOST_PP_ITERATION_FINISH_2 >= 102 # define BOOST_PP_ITERATION_2 102 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 103 && BOOST_PP_ITERATION_FINISH_2 >= 103 # define BOOST_PP_ITERATION_2 103 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 104 && BOOST_PP_ITERATION_FINISH_2 >= 104 # define BOOST_PP_ITERATION_2 104 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 105 && BOOST_PP_ITERATION_FINISH_2 >= 105 # define BOOST_PP_ITERATION_2 105 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 106 && BOOST_PP_ITERATION_FINISH_2 >= 106 # define BOOST_PP_ITERATION_2 106 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 107 && BOOST_PP_ITERATION_FINISH_2 >= 107 # define BOOST_PP_ITERATION_2 107 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 108 && BOOST_PP_ITERATION_FINISH_2 >= 108 # define BOOST_PP_ITERATION_2 108 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 109 && BOOST_PP_ITERATION_FINISH_2 >= 109 # define BOOST_PP_ITERATION_2 109 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 110 && BOOST_PP_ITERATION_FINISH_2 >= 110 # define BOOST_PP_ITERATION_2 110 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 111 && BOOST_PP_ITERATION_FINISH_2 >= 111 # define BOOST_PP_ITERATION_2 111 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 112 && BOOST_PP_ITERATION_FINISH_2 >= 112 # define BOOST_PP_ITERATION_2 112 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 113 && BOOST_PP_ITERATION_FINISH_2 >= 113 # define BOOST_PP_ITERATION_2 113 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 114 && BOOST_PP_ITERATION_FINISH_2 >= 114 # define BOOST_PP_ITERATION_2 114 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 115 && BOOST_PP_ITERATION_FINISH_2 >= 115 # define BOOST_PP_ITERATION_2 115 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 116 && BOOST_PP_ITERATION_FINISH_2 >= 116 # define BOOST_PP_ITERATION_2 116 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 117 && BOOST_PP_ITERATION_FINISH_2 >= 117 # define BOOST_PP_ITERATION_2 117 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 118 && BOOST_PP_ITERATION_FINISH_2 >= 118 # define BOOST_PP_ITERATION_2 118 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 119 && BOOST_PP_ITERATION_FINISH_2 >= 119 # define BOOST_PP_ITERATION_2 119 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 120 && BOOST_PP_ITERATION_FINISH_2 >= 120 # define BOOST_PP_ITERATION_2 120 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 121 && BOOST_PP_ITERATION_FINISH_2 >= 121 # define BOOST_PP_ITERATION_2 121 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 122 && BOOST_PP_ITERATION_FINISH_2 >= 122 # define BOOST_PP_ITERATION_2 122 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 123 && BOOST_PP_ITERATION_FINISH_2 >= 123 # define BOOST_PP_ITERATION_2 123 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 124 && BOOST_PP_ITERATION_FINISH_2 >= 124 # define BOOST_PP_ITERATION_2 124 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 125 && BOOST_PP_ITERATION_FINISH_2 >= 125 # define BOOST_PP_ITERATION_2 125 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 126 && BOOST_PP_ITERATION_FINISH_2 >= 126 # define BOOST_PP_ITERATION_2 126 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 127 && BOOST_PP_ITERATION_FINISH_2 >= 127 # define BOOST_PP_ITERATION_2 127 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 128 && BOOST_PP_ITERATION_FINISH_2 >= 128 # define BOOST_PP_ITERATION_2 128 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 129 && BOOST_PP_ITERATION_FINISH_2 >= 129 # define BOOST_PP_ITERATION_2 129 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 130 && BOOST_PP_ITERATION_FINISH_2 >= 130 # define BOOST_PP_ITERATION_2 130 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 131 && BOOST_PP_ITERATION_FINISH_2 >= 131 # define BOOST_PP_ITERATION_2 131 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 132 && BOOST_PP_ITERATION_FINISH_2 >= 132 # define BOOST_PP_ITERATION_2 132 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 133 && BOOST_PP_ITERATION_FINISH_2 >= 133 # define BOOST_PP_ITERATION_2 133 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 134 && BOOST_PP_ITERATION_FINISH_2 >= 134 # define BOOST_PP_ITERATION_2 134 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 135 && BOOST_PP_ITERATION_FINISH_2 >= 135 # define BOOST_PP_ITERATION_2 135 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 136 && BOOST_PP_ITERATION_FINISH_2 >= 136 # define BOOST_PP_ITERATION_2 136 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 137 && BOOST_PP_ITERATION_FINISH_2 >= 137 # define BOOST_PP_ITERATION_2 137 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 138 && BOOST_PP_ITERATION_FINISH_2 >= 138 # define BOOST_PP_ITERATION_2 138 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 139 && BOOST_PP_ITERATION_FINISH_2 >= 139 # define BOOST_PP_ITERATION_2 139 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 140 && BOOST_PP_ITERATION_FINISH_2 >= 140 # define BOOST_PP_ITERATION_2 140 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 141 && BOOST_PP_ITERATION_FINISH_2 >= 141 # define BOOST_PP_ITERATION_2 141 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 142 && BOOST_PP_ITERATION_FINISH_2 >= 142 # define BOOST_PP_ITERATION_2 142 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 143 && BOOST_PP_ITERATION_FINISH_2 >= 143 # define BOOST_PP_ITERATION_2 143 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 144 && BOOST_PP_ITERATION_FINISH_2 >= 144 # define BOOST_PP_ITERATION_2 144 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 145 && BOOST_PP_ITERATION_FINISH_2 >= 145 # define BOOST_PP_ITERATION_2 145 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 146 && BOOST_PP_ITERATION_FINISH_2 >= 146 # define BOOST_PP_ITERATION_2 146 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 147 && BOOST_PP_ITERATION_FINISH_2 >= 147 # define BOOST_PP_ITERATION_2 147 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 148 && BOOST_PP_ITERATION_FINISH_2 >= 148 # define BOOST_PP_ITERATION_2 148 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 149 && BOOST_PP_ITERATION_FINISH_2 >= 149 # define BOOST_PP_ITERATION_2 149 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 150 && BOOST_PP_ITERATION_FINISH_2 >= 150 # define BOOST_PP_ITERATION_2 150 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 151 && BOOST_PP_ITERATION_FINISH_2 >= 151 # define BOOST_PP_ITERATION_2 151 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 152 && BOOST_PP_ITERATION_FINISH_2 >= 152 # define BOOST_PP_ITERATION_2 152 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 153 && BOOST_PP_ITERATION_FINISH_2 >= 153 # define BOOST_PP_ITERATION_2 153 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 154 && BOOST_PP_ITERATION_FINISH_2 >= 154 # define BOOST_PP_ITERATION_2 154 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 155 && BOOST_PP_ITERATION_FINISH_2 >= 155 # define BOOST_PP_ITERATION_2 155 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 156 && BOOST_PP_ITERATION_FINISH_2 >= 156 # define BOOST_PP_ITERATION_2 156 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 157 && BOOST_PP_ITERATION_FINISH_2 >= 157 # define BOOST_PP_ITERATION_2 157 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 158 && BOOST_PP_ITERATION_FINISH_2 >= 158 # define BOOST_PP_ITERATION_2 158 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 159 && BOOST_PP_ITERATION_FINISH_2 >= 159 # define BOOST_PP_ITERATION_2 159 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 160 && BOOST_PP_ITERATION_FINISH_2 >= 160 # define BOOST_PP_ITERATION_2 160 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 161 && BOOST_PP_ITERATION_FINISH_2 >= 161 # define BOOST_PP_ITERATION_2 161 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 162 && BOOST_PP_ITERATION_FINISH_2 >= 162 # define BOOST_PP_ITERATION_2 162 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 163 && BOOST_PP_ITERATION_FINISH_2 >= 163 # define BOOST_PP_ITERATION_2 163 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 164 && BOOST_PP_ITERATION_FINISH_2 >= 164 # define BOOST_PP_ITERATION_2 164 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 165 && BOOST_PP_ITERATION_FINISH_2 >= 165 # define BOOST_PP_ITERATION_2 165 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 166 && BOOST_PP_ITERATION_FINISH_2 >= 166 # define BOOST_PP_ITERATION_2 166 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 167 && BOOST_PP_ITERATION_FINISH_2 >= 167 # define BOOST_PP_ITERATION_2 167 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 168 && BOOST_PP_ITERATION_FINISH_2 >= 168 # define BOOST_PP_ITERATION_2 168 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 169 && BOOST_PP_ITERATION_FINISH_2 >= 169 # define BOOST_PP_ITERATION_2 169 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 170 && BOOST_PP_ITERATION_FINISH_2 >= 170 # define BOOST_PP_ITERATION_2 170 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 171 && BOOST_PP_ITERATION_FINISH_2 >= 171 # define BOOST_PP_ITERATION_2 171 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 172 && BOOST_PP_ITERATION_FINISH_2 >= 172 # define BOOST_PP_ITERATION_2 172 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 173 && BOOST_PP_ITERATION_FINISH_2 >= 173 # define BOOST_PP_ITERATION_2 173 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 174 && BOOST_PP_ITERATION_FINISH_2 >= 174 # define BOOST_PP_ITERATION_2 174 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 175 && BOOST_PP_ITERATION_FINISH_2 >= 175 # define BOOST_PP_ITERATION_2 175 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 176 && BOOST_PP_ITERATION_FINISH_2 >= 176 # define BOOST_PP_ITERATION_2 176 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 177 && BOOST_PP_ITERATION_FINISH_2 >= 177 # define BOOST_PP_ITERATION_2 177 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 178 && BOOST_PP_ITERATION_FINISH_2 >= 178 # define BOOST_PP_ITERATION_2 178 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 179 && BOOST_PP_ITERATION_FINISH_2 >= 179 # define BOOST_PP_ITERATION_2 179 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 180 && BOOST_PP_ITERATION_FINISH_2 >= 180 # define BOOST_PP_ITERATION_2 180 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 181 && BOOST_PP_ITERATION_FINISH_2 >= 181 # define BOOST_PP_ITERATION_2 181 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 182 && BOOST_PP_ITERATION_FINISH_2 >= 182 # define BOOST_PP_ITERATION_2 182 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 183 && BOOST_PP_ITERATION_FINISH_2 >= 183 # define BOOST_PP_ITERATION_2 183 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 184 && BOOST_PP_ITERATION_FINISH_2 >= 184 # define BOOST_PP_ITERATION_2 184 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 185 && BOOST_PP_ITERATION_FINISH_2 >= 185 # define BOOST_PP_ITERATION_2 185 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 186 && BOOST_PP_ITERATION_FINISH_2 >= 186 # define BOOST_PP_ITERATION_2 186 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 187 && BOOST_PP_ITERATION_FINISH_2 >= 187 # define BOOST_PP_ITERATION_2 187 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 188 && BOOST_PP_ITERATION_FINISH_2 >= 188 # define BOOST_PP_ITERATION_2 188 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 189 && BOOST_PP_ITERATION_FINISH_2 >= 189 # define BOOST_PP_ITERATION_2 189 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 190 && BOOST_PP_ITERATION_FINISH_2 >= 190 # define BOOST_PP_ITERATION_2 190 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 191 && BOOST_PP_ITERATION_FINISH_2 >= 191 # define BOOST_PP_ITERATION_2 191 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 192 && BOOST_PP_ITERATION_FINISH_2 >= 192 # define BOOST_PP_ITERATION_2 192 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 193 && BOOST_PP_ITERATION_FINISH_2 >= 193 # define BOOST_PP_ITERATION_2 193 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 194 && BOOST_PP_ITERATION_FINISH_2 >= 194 # define BOOST_PP_ITERATION_2 194 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 195 && BOOST_PP_ITERATION_FINISH_2 >= 195 # define BOOST_PP_ITERATION_2 195 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 196 && BOOST_PP_ITERATION_FINISH_2 >= 196 # define BOOST_PP_ITERATION_2 196 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 197 && BOOST_PP_ITERATION_FINISH_2 >= 197 # define BOOST_PP_ITERATION_2 197 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 198 && BOOST_PP_ITERATION_FINISH_2 >= 198 # define BOOST_PP_ITERATION_2 198 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 199 && BOOST_PP_ITERATION_FINISH_2 >= 199 # define BOOST_PP_ITERATION_2 199 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 200 && BOOST_PP_ITERATION_FINISH_2 >= 200 # define BOOST_PP_ITERATION_2 200 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 201 && BOOST_PP_ITERATION_FINISH_2 >= 201 # define BOOST_PP_ITERATION_2 201 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 202 && BOOST_PP_ITERATION_FINISH_2 >= 202 # define BOOST_PP_ITERATION_2 202 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 203 && BOOST_PP_ITERATION_FINISH_2 >= 203 # define BOOST_PP_ITERATION_2 203 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 204 && BOOST_PP_ITERATION_FINISH_2 >= 204 # define BOOST_PP_ITERATION_2 204 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 205 && BOOST_PP_ITERATION_FINISH_2 >= 205 # define BOOST_PP_ITERATION_2 205 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 206 && BOOST_PP_ITERATION_FINISH_2 >= 206 # define BOOST_PP_ITERATION_2 206 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 207 && BOOST_PP_ITERATION_FINISH_2 >= 207 # define BOOST_PP_ITERATION_2 207 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 208 && BOOST_PP_ITERATION_FINISH_2 >= 208 # define BOOST_PP_ITERATION_2 208 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 209 && BOOST_PP_ITERATION_FINISH_2 >= 209 # define BOOST_PP_ITERATION_2 209 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 210 && BOOST_PP_ITERATION_FINISH_2 >= 210 # define BOOST_PP_ITERATION_2 210 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 211 && BOOST_PP_ITERATION_FINISH_2 >= 211 # define BOOST_PP_ITERATION_2 211 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 212 && BOOST_PP_ITERATION_FINISH_2 >= 212 # define BOOST_PP_ITERATION_2 212 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 213 && BOOST_PP_ITERATION_FINISH_2 >= 213 # define BOOST_PP_ITERATION_2 213 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 214 && BOOST_PP_ITERATION_FINISH_2 >= 214 # define BOOST_PP_ITERATION_2 214 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 215 && BOOST_PP_ITERATION_FINISH_2 >= 215 # define BOOST_PP_ITERATION_2 215 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 216 && BOOST_PP_ITERATION_FINISH_2 >= 216 # define BOOST_PP_ITERATION_2 216 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 217 && BOOST_PP_ITERATION_FINISH_2 >= 217 # define BOOST_PP_ITERATION_2 217 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 218 && BOOST_PP_ITERATION_FINISH_2 >= 218 # define BOOST_PP_ITERATION_2 218 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 219 && BOOST_PP_ITERATION_FINISH_2 >= 219 # define BOOST_PP_ITERATION_2 219 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 220 && BOOST_PP_ITERATION_FINISH_2 >= 220 # define BOOST_PP_ITERATION_2 220 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 221 && BOOST_PP_ITERATION_FINISH_2 >= 221 # define BOOST_PP_ITERATION_2 221 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 222 && BOOST_PP_ITERATION_FINISH_2 >= 222 # define BOOST_PP_ITERATION_2 222 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 223 && BOOST_PP_ITERATION_FINISH_2 >= 223 # define BOOST_PP_ITERATION_2 223 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 224 && BOOST_PP_ITERATION_FINISH_2 >= 224 # define BOOST_PP_ITERATION_2 224 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 225 && BOOST_PP_ITERATION_FINISH_2 >= 225 # define BOOST_PP_ITERATION_2 225 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 226 && BOOST_PP_ITERATION_FINISH_2 >= 226 # define BOOST_PP_ITERATION_2 226 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 227 && BOOST_PP_ITERATION_FINISH_2 >= 227 # define BOOST_PP_ITERATION_2 227 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 228 && BOOST_PP_ITERATION_FINISH_2 >= 228 # define BOOST_PP_ITERATION_2 228 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 229 && BOOST_PP_ITERATION_FINISH_2 >= 229 # define BOOST_PP_ITERATION_2 229 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 230 && BOOST_PP_ITERATION_FINISH_2 >= 230 # define BOOST_PP_ITERATION_2 230 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 231 && BOOST_PP_ITERATION_FINISH_2 >= 231 # define BOOST_PP_ITERATION_2 231 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 232 && BOOST_PP_ITERATION_FINISH_2 >= 232 # define BOOST_PP_ITERATION_2 232 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 233 && BOOST_PP_ITERATION_FINISH_2 >= 233 # define BOOST_PP_ITERATION_2 233 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 234 && BOOST_PP_ITERATION_FINISH_2 >= 234 # define BOOST_PP_ITERATION_2 234 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 235 && BOOST_PP_ITERATION_FINISH_2 >= 235 # define BOOST_PP_ITERATION_2 235 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 236 && BOOST_PP_ITERATION_FINISH_2 >= 236 # define BOOST_PP_ITERATION_2 236 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 237 && BOOST_PP_ITERATION_FINISH_2 >= 237 # define BOOST_PP_ITERATION_2 237 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 238 && BOOST_PP_ITERATION_FINISH_2 >= 238 # define BOOST_PP_ITERATION_2 238 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 239 && BOOST_PP_ITERATION_FINISH_2 >= 239 # define BOOST_PP_ITERATION_2 239 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 240 && BOOST_PP_ITERATION_FINISH_2 >= 240 # define BOOST_PP_ITERATION_2 240 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 241 && BOOST_PP_ITERATION_FINISH_2 >= 241 # define BOOST_PP_ITERATION_2 241 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 242 && BOOST_PP_ITERATION_FINISH_2 >= 242 # define BOOST_PP_ITERATION_2 242 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 243 && BOOST_PP_ITERATION_FINISH_2 >= 243 # define BOOST_PP_ITERATION_2 243 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 244 && BOOST_PP_ITERATION_FINISH_2 >= 244 # define BOOST_PP_ITERATION_2 244 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 245 && BOOST_PP_ITERATION_FINISH_2 >= 245 # define BOOST_PP_ITERATION_2 245 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 246 && BOOST_PP_ITERATION_FINISH_2 >= 246 # define BOOST_PP_ITERATION_2 246 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 247 && BOOST_PP_ITERATION_FINISH_2 >= 247 # define BOOST_PP_ITERATION_2 247 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 248 && BOOST_PP_ITERATION_FINISH_2 >= 248 # define BOOST_PP_ITERATION_2 248 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 249 && BOOST_PP_ITERATION_FINISH_2 >= 249 # define BOOST_PP_ITERATION_2 249 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 250 && BOOST_PP_ITERATION_FINISH_2 >= 250 # define BOOST_PP_ITERATION_2 250 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 251 && BOOST_PP_ITERATION_FINISH_2 >= 251 # define BOOST_PP_ITERATION_2 251 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 252 && BOOST_PP_ITERATION_FINISH_2 >= 252 # define BOOST_PP_ITERATION_2 252 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 253 && BOOST_PP_ITERATION_FINISH_2 >= 253 # define BOOST_PP_ITERATION_2 253 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 254 && BOOST_PP_ITERATION_FINISH_2 >= 254 # define BOOST_PP_ITERATION_2 254 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 255 && BOOST_PP_ITERATION_FINISH_2 >= 255 # define BOOST_PP_ITERATION_2 255 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_START_2 <= 256 && BOOST_PP_ITERATION_FINISH_2 >= 256 # define BOOST_PP_ITERATION_2 256 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 1 # # undef BOOST_PP_ITERATION_START_2 # undef BOOST_PP_ITERATION_FINISH_2 # undef BOOST_PP_FILENAME_2 # # undef BOOST_PP_ITERATION_FLAGS_2 # undef BOOST_PP_ITERATION_PARAMS_2 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/forward3.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if defined(BOOST_PP_ITERATION_LIMITS) # if !defined(BOOST_PP_FILENAME_3) # error BOOST_PP_ERROR: depth #3 filename is not defined # endif # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_ITERATION_FLAGS_3() 0 # undef BOOST_PP_ITERATION_LIMITS # elif defined(BOOST_PP_ITERATION_PARAMS_3) # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(0, BOOST_PP_ITERATION_PARAMS_3) # include # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(1, BOOST_PP_ITERATION_PARAMS_3) # include # define BOOST_PP_FILENAME_3 BOOST_PP_ARRAY_ELEM(2, BOOST_PP_ITERATION_PARAMS_3) # if BOOST_PP_ARRAY_SIZE(BOOST_PP_ITERATION_PARAMS_3) >= 4 # define BOOST_PP_ITERATION_FLAGS_3() BOOST_PP_ARRAY_ELEM(3, BOOST_PP_ITERATION_PARAMS_3) # else # define BOOST_PP_ITERATION_FLAGS_3() 0 # endif # else # error BOOST_PP_ERROR: depth #3 iteration boundaries or filename not defined # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 3 # # if (BOOST_PP_ITERATION_START_3) > (BOOST_PP_ITERATION_FINISH_3) # include # else # if BOOST_PP_ITERATION_START_3 <= 0 && BOOST_PP_ITERATION_FINISH_3 >= 0 # define BOOST_PP_ITERATION_3 0 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 1 && BOOST_PP_ITERATION_FINISH_3 >= 1 # define BOOST_PP_ITERATION_3 1 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 2 && BOOST_PP_ITERATION_FINISH_3 >= 2 # define BOOST_PP_ITERATION_3 2 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 3 && BOOST_PP_ITERATION_FINISH_3 >= 3 # define BOOST_PP_ITERATION_3 3 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 4 && BOOST_PP_ITERATION_FINISH_3 >= 4 # define BOOST_PP_ITERATION_3 4 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 5 && BOOST_PP_ITERATION_FINISH_3 >= 5 # define BOOST_PP_ITERATION_3 5 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 6 && BOOST_PP_ITERATION_FINISH_3 >= 6 # define BOOST_PP_ITERATION_3 6 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 7 && BOOST_PP_ITERATION_FINISH_3 >= 7 # define BOOST_PP_ITERATION_3 7 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 8 && BOOST_PP_ITERATION_FINISH_3 >= 8 # define BOOST_PP_ITERATION_3 8 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 9 && BOOST_PP_ITERATION_FINISH_3 >= 9 # define BOOST_PP_ITERATION_3 9 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 10 && BOOST_PP_ITERATION_FINISH_3 >= 10 # define BOOST_PP_ITERATION_3 10 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 11 && BOOST_PP_ITERATION_FINISH_3 >= 11 # define BOOST_PP_ITERATION_3 11 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 12 && BOOST_PP_ITERATION_FINISH_3 >= 12 # define BOOST_PP_ITERATION_3 12 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 13 && BOOST_PP_ITERATION_FINISH_3 >= 13 # define BOOST_PP_ITERATION_3 13 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 14 && BOOST_PP_ITERATION_FINISH_3 >= 14 # define BOOST_PP_ITERATION_3 14 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 15 && BOOST_PP_ITERATION_FINISH_3 >= 15 # define BOOST_PP_ITERATION_3 15 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 16 && BOOST_PP_ITERATION_FINISH_3 >= 16 # define BOOST_PP_ITERATION_3 16 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 17 && BOOST_PP_ITERATION_FINISH_3 >= 17 # define BOOST_PP_ITERATION_3 17 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 18 && BOOST_PP_ITERATION_FINISH_3 >= 18 # define BOOST_PP_ITERATION_3 18 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 19 && BOOST_PP_ITERATION_FINISH_3 >= 19 # define BOOST_PP_ITERATION_3 19 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 20 && BOOST_PP_ITERATION_FINISH_3 >= 20 # define BOOST_PP_ITERATION_3 20 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 21 && BOOST_PP_ITERATION_FINISH_3 >= 21 # define BOOST_PP_ITERATION_3 21 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 22 && BOOST_PP_ITERATION_FINISH_3 >= 22 # define BOOST_PP_ITERATION_3 22 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 23 && BOOST_PP_ITERATION_FINISH_3 >= 23 # define BOOST_PP_ITERATION_3 23 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 24 && BOOST_PP_ITERATION_FINISH_3 >= 24 # define BOOST_PP_ITERATION_3 24 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 25 && BOOST_PP_ITERATION_FINISH_3 >= 25 # define BOOST_PP_ITERATION_3 25 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 26 && BOOST_PP_ITERATION_FINISH_3 >= 26 # define BOOST_PP_ITERATION_3 26 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 27 && BOOST_PP_ITERATION_FINISH_3 >= 27 # define BOOST_PP_ITERATION_3 27 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 28 && BOOST_PP_ITERATION_FINISH_3 >= 28 # define BOOST_PP_ITERATION_3 28 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 29 && BOOST_PP_ITERATION_FINISH_3 >= 29 # define BOOST_PP_ITERATION_3 29 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 30 && BOOST_PP_ITERATION_FINISH_3 >= 30 # define BOOST_PP_ITERATION_3 30 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 31 && BOOST_PP_ITERATION_FINISH_3 >= 31 # define BOOST_PP_ITERATION_3 31 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 32 && BOOST_PP_ITERATION_FINISH_3 >= 32 # define BOOST_PP_ITERATION_3 32 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 33 && BOOST_PP_ITERATION_FINISH_3 >= 33 # define BOOST_PP_ITERATION_3 33 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 34 && BOOST_PP_ITERATION_FINISH_3 >= 34 # define BOOST_PP_ITERATION_3 34 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 35 && BOOST_PP_ITERATION_FINISH_3 >= 35 # define BOOST_PP_ITERATION_3 35 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 36 && BOOST_PP_ITERATION_FINISH_3 >= 36 # define BOOST_PP_ITERATION_3 36 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 37 && BOOST_PP_ITERATION_FINISH_3 >= 37 # define BOOST_PP_ITERATION_3 37 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 38 && BOOST_PP_ITERATION_FINISH_3 >= 38 # define BOOST_PP_ITERATION_3 38 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 39 && BOOST_PP_ITERATION_FINISH_3 >= 39 # define BOOST_PP_ITERATION_3 39 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 40 && BOOST_PP_ITERATION_FINISH_3 >= 40 # define BOOST_PP_ITERATION_3 40 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 41 && BOOST_PP_ITERATION_FINISH_3 >= 41 # define BOOST_PP_ITERATION_3 41 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 42 && BOOST_PP_ITERATION_FINISH_3 >= 42 # define BOOST_PP_ITERATION_3 42 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 43 && BOOST_PP_ITERATION_FINISH_3 >= 43 # define BOOST_PP_ITERATION_3 43 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 44 && BOOST_PP_ITERATION_FINISH_3 >= 44 # define BOOST_PP_ITERATION_3 44 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 45 && BOOST_PP_ITERATION_FINISH_3 >= 45 # define BOOST_PP_ITERATION_3 45 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 46 && BOOST_PP_ITERATION_FINISH_3 >= 46 # define BOOST_PP_ITERATION_3 46 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 47 && BOOST_PP_ITERATION_FINISH_3 >= 47 # define BOOST_PP_ITERATION_3 47 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 48 && BOOST_PP_ITERATION_FINISH_3 >= 48 # define BOOST_PP_ITERATION_3 48 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 49 && BOOST_PP_ITERATION_FINISH_3 >= 49 # define BOOST_PP_ITERATION_3 49 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 50 && BOOST_PP_ITERATION_FINISH_3 >= 50 # define BOOST_PP_ITERATION_3 50 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 51 && BOOST_PP_ITERATION_FINISH_3 >= 51 # define BOOST_PP_ITERATION_3 51 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 52 && BOOST_PP_ITERATION_FINISH_3 >= 52 # define BOOST_PP_ITERATION_3 52 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 53 && BOOST_PP_ITERATION_FINISH_3 >= 53 # define BOOST_PP_ITERATION_3 53 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 54 && BOOST_PP_ITERATION_FINISH_3 >= 54 # define BOOST_PP_ITERATION_3 54 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 55 && BOOST_PP_ITERATION_FINISH_3 >= 55 # define BOOST_PP_ITERATION_3 55 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 56 && BOOST_PP_ITERATION_FINISH_3 >= 56 # define BOOST_PP_ITERATION_3 56 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 57 && BOOST_PP_ITERATION_FINISH_3 >= 57 # define BOOST_PP_ITERATION_3 57 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 58 && BOOST_PP_ITERATION_FINISH_3 >= 58 # define BOOST_PP_ITERATION_3 58 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 59 && BOOST_PP_ITERATION_FINISH_3 >= 59 # define BOOST_PP_ITERATION_3 59 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 60 && BOOST_PP_ITERATION_FINISH_3 >= 60 # define BOOST_PP_ITERATION_3 60 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 61 && BOOST_PP_ITERATION_FINISH_3 >= 61 # define BOOST_PP_ITERATION_3 61 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 62 && BOOST_PP_ITERATION_FINISH_3 >= 62 # define BOOST_PP_ITERATION_3 62 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 63 && BOOST_PP_ITERATION_FINISH_3 >= 63 # define BOOST_PP_ITERATION_3 63 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 64 && BOOST_PP_ITERATION_FINISH_3 >= 64 # define BOOST_PP_ITERATION_3 64 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 65 && BOOST_PP_ITERATION_FINISH_3 >= 65 # define BOOST_PP_ITERATION_3 65 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 66 && BOOST_PP_ITERATION_FINISH_3 >= 66 # define BOOST_PP_ITERATION_3 66 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 67 && BOOST_PP_ITERATION_FINISH_3 >= 67 # define BOOST_PP_ITERATION_3 67 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 68 && BOOST_PP_ITERATION_FINISH_3 >= 68 # define BOOST_PP_ITERATION_3 68 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 69 && BOOST_PP_ITERATION_FINISH_3 >= 69 # define BOOST_PP_ITERATION_3 69 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 70 && BOOST_PP_ITERATION_FINISH_3 >= 70 # define BOOST_PP_ITERATION_3 70 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 71 && BOOST_PP_ITERATION_FINISH_3 >= 71 # define BOOST_PP_ITERATION_3 71 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 72 && BOOST_PP_ITERATION_FINISH_3 >= 72 # define BOOST_PP_ITERATION_3 72 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 73 && BOOST_PP_ITERATION_FINISH_3 >= 73 # define BOOST_PP_ITERATION_3 73 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 74 && BOOST_PP_ITERATION_FINISH_3 >= 74 # define BOOST_PP_ITERATION_3 74 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 75 && BOOST_PP_ITERATION_FINISH_3 >= 75 # define BOOST_PP_ITERATION_3 75 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 76 && BOOST_PP_ITERATION_FINISH_3 >= 76 # define BOOST_PP_ITERATION_3 76 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 77 && BOOST_PP_ITERATION_FINISH_3 >= 77 # define BOOST_PP_ITERATION_3 77 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 78 && BOOST_PP_ITERATION_FINISH_3 >= 78 # define BOOST_PP_ITERATION_3 78 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 79 && BOOST_PP_ITERATION_FINISH_3 >= 79 # define BOOST_PP_ITERATION_3 79 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 80 && BOOST_PP_ITERATION_FINISH_3 >= 80 # define BOOST_PP_ITERATION_3 80 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 81 && BOOST_PP_ITERATION_FINISH_3 >= 81 # define BOOST_PP_ITERATION_3 81 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 82 && BOOST_PP_ITERATION_FINISH_3 >= 82 # define BOOST_PP_ITERATION_3 82 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 83 && BOOST_PP_ITERATION_FINISH_3 >= 83 # define BOOST_PP_ITERATION_3 83 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 84 && BOOST_PP_ITERATION_FINISH_3 >= 84 # define BOOST_PP_ITERATION_3 84 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 85 && BOOST_PP_ITERATION_FINISH_3 >= 85 # define BOOST_PP_ITERATION_3 85 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 86 && BOOST_PP_ITERATION_FINISH_3 >= 86 # define BOOST_PP_ITERATION_3 86 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 87 && BOOST_PP_ITERATION_FINISH_3 >= 87 # define BOOST_PP_ITERATION_3 87 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 88 && BOOST_PP_ITERATION_FINISH_3 >= 88 # define BOOST_PP_ITERATION_3 88 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 89 && BOOST_PP_ITERATION_FINISH_3 >= 89 # define BOOST_PP_ITERATION_3 89 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 90 && BOOST_PP_ITERATION_FINISH_3 >= 90 # define BOOST_PP_ITERATION_3 90 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 91 && BOOST_PP_ITERATION_FINISH_3 >= 91 # define BOOST_PP_ITERATION_3 91 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 92 && BOOST_PP_ITERATION_FINISH_3 >= 92 # define BOOST_PP_ITERATION_3 92 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 93 && BOOST_PP_ITERATION_FINISH_3 >= 93 # define BOOST_PP_ITERATION_3 93 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 94 && BOOST_PP_ITERATION_FINISH_3 >= 94 # define BOOST_PP_ITERATION_3 94 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 95 && BOOST_PP_ITERATION_FINISH_3 >= 95 # define BOOST_PP_ITERATION_3 95 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 96 && BOOST_PP_ITERATION_FINISH_3 >= 96 # define BOOST_PP_ITERATION_3 96 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 97 && BOOST_PP_ITERATION_FINISH_3 >= 97 # define BOOST_PP_ITERATION_3 97 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 98 && BOOST_PP_ITERATION_FINISH_3 >= 98 # define BOOST_PP_ITERATION_3 98 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 99 && BOOST_PP_ITERATION_FINISH_3 >= 99 # define BOOST_PP_ITERATION_3 99 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 100 && BOOST_PP_ITERATION_FINISH_3 >= 100 # define BOOST_PP_ITERATION_3 100 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 101 && BOOST_PP_ITERATION_FINISH_3 >= 101 # define BOOST_PP_ITERATION_3 101 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 102 && BOOST_PP_ITERATION_FINISH_3 >= 102 # define BOOST_PP_ITERATION_3 102 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 103 && BOOST_PP_ITERATION_FINISH_3 >= 103 # define BOOST_PP_ITERATION_3 103 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 104 && BOOST_PP_ITERATION_FINISH_3 >= 104 # define BOOST_PP_ITERATION_3 104 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 105 && BOOST_PP_ITERATION_FINISH_3 >= 105 # define BOOST_PP_ITERATION_3 105 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 106 && BOOST_PP_ITERATION_FINISH_3 >= 106 # define BOOST_PP_ITERATION_3 106 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 107 && BOOST_PP_ITERATION_FINISH_3 >= 107 # define BOOST_PP_ITERATION_3 107 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 108 && BOOST_PP_ITERATION_FINISH_3 >= 108 # define BOOST_PP_ITERATION_3 108 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 109 && BOOST_PP_ITERATION_FINISH_3 >= 109 # define BOOST_PP_ITERATION_3 109 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 110 && BOOST_PP_ITERATION_FINISH_3 >= 110 # define BOOST_PP_ITERATION_3 110 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 111 && BOOST_PP_ITERATION_FINISH_3 >= 111 # define BOOST_PP_ITERATION_3 111 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 112 && BOOST_PP_ITERATION_FINISH_3 >= 112 # define BOOST_PP_ITERATION_3 112 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 113 && BOOST_PP_ITERATION_FINISH_3 >= 113 # define BOOST_PP_ITERATION_3 113 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 114 && BOOST_PP_ITERATION_FINISH_3 >= 114 # define BOOST_PP_ITERATION_3 114 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 115 && BOOST_PP_ITERATION_FINISH_3 >= 115 # define BOOST_PP_ITERATION_3 115 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 116 && BOOST_PP_ITERATION_FINISH_3 >= 116 # define BOOST_PP_ITERATION_3 116 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 117 && BOOST_PP_ITERATION_FINISH_3 >= 117 # define BOOST_PP_ITERATION_3 117 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 118 && BOOST_PP_ITERATION_FINISH_3 >= 118 # define BOOST_PP_ITERATION_3 118 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 119 && BOOST_PP_ITERATION_FINISH_3 >= 119 # define BOOST_PP_ITERATION_3 119 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 120 && BOOST_PP_ITERATION_FINISH_3 >= 120 # define BOOST_PP_ITERATION_3 120 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 121 && BOOST_PP_ITERATION_FINISH_3 >= 121 # define BOOST_PP_ITERATION_3 121 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 122 && BOOST_PP_ITERATION_FINISH_3 >= 122 # define BOOST_PP_ITERATION_3 122 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 123 && BOOST_PP_ITERATION_FINISH_3 >= 123 # define BOOST_PP_ITERATION_3 123 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 124 && BOOST_PP_ITERATION_FINISH_3 >= 124 # define BOOST_PP_ITERATION_3 124 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 125 && BOOST_PP_ITERATION_FINISH_3 >= 125 # define BOOST_PP_ITERATION_3 125 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 126 && BOOST_PP_ITERATION_FINISH_3 >= 126 # define BOOST_PP_ITERATION_3 126 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 127 && BOOST_PP_ITERATION_FINISH_3 >= 127 # define BOOST_PP_ITERATION_3 127 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 128 && BOOST_PP_ITERATION_FINISH_3 >= 128 # define BOOST_PP_ITERATION_3 128 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 129 && BOOST_PP_ITERATION_FINISH_3 >= 129 # define BOOST_PP_ITERATION_3 129 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 130 && BOOST_PP_ITERATION_FINISH_3 >= 130 # define BOOST_PP_ITERATION_3 130 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 131 && BOOST_PP_ITERATION_FINISH_3 >= 131 # define BOOST_PP_ITERATION_3 131 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 132 && BOOST_PP_ITERATION_FINISH_3 >= 132 # define BOOST_PP_ITERATION_3 132 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 133 && BOOST_PP_ITERATION_FINISH_3 >= 133 # define BOOST_PP_ITERATION_3 133 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 134 && BOOST_PP_ITERATION_FINISH_3 >= 134 # define BOOST_PP_ITERATION_3 134 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 135 && BOOST_PP_ITERATION_FINISH_3 >= 135 # define BOOST_PP_ITERATION_3 135 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 136 && BOOST_PP_ITERATION_FINISH_3 >= 136 # define BOOST_PP_ITERATION_3 136 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 137 && BOOST_PP_ITERATION_FINISH_3 >= 137 # define BOOST_PP_ITERATION_3 137 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 138 && BOOST_PP_ITERATION_FINISH_3 >= 138 # define BOOST_PP_ITERATION_3 138 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 139 && BOOST_PP_ITERATION_FINISH_3 >= 139 # define BOOST_PP_ITERATION_3 139 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 140 && BOOST_PP_ITERATION_FINISH_3 >= 140 # define BOOST_PP_ITERATION_3 140 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 141 && BOOST_PP_ITERATION_FINISH_3 >= 141 # define BOOST_PP_ITERATION_3 141 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 142 && BOOST_PP_ITERATION_FINISH_3 >= 142 # define BOOST_PP_ITERATION_3 142 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 143 && BOOST_PP_ITERATION_FINISH_3 >= 143 # define BOOST_PP_ITERATION_3 143 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 144 && BOOST_PP_ITERATION_FINISH_3 >= 144 # define BOOST_PP_ITERATION_3 144 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 145 && BOOST_PP_ITERATION_FINISH_3 >= 145 # define BOOST_PP_ITERATION_3 145 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 146 && BOOST_PP_ITERATION_FINISH_3 >= 146 # define BOOST_PP_ITERATION_3 146 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 147 && BOOST_PP_ITERATION_FINISH_3 >= 147 # define BOOST_PP_ITERATION_3 147 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 148 && BOOST_PP_ITERATION_FINISH_3 >= 148 # define BOOST_PP_ITERATION_3 148 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 149 && BOOST_PP_ITERATION_FINISH_3 >= 149 # define BOOST_PP_ITERATION_3 149 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 150 && BOOST_PP_ITERATION_FINISH_3 >= 150 # define BOOST_PP_ITERATION_3 150 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 151 && BOOST_PP_ITERATION_FINISH_3 >= 151 # define BOOST_PP_ITERATION_3 151 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 152 && BOOST_PP_ITERATION_FINISH_3 >= 152 # define BOOST_PP_ITERATION_3 152 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 153 && BOOST_PP_ITERATION_FINISH_3 >= 153 # define BOOST_PP_ITERATION_3 153 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 154 && BOOST_PP_ITERATION_FINISH_3 >= 154 # define BOOST_PP_ITERATION_3 154 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 155 && BOOST_PP_ITERATION_FINISH_3 >= 155 # define BOOST_PP_ITERATION_3 155 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 156 && BOOST_PP_ITERATION_FINISH_3 >= 156 # define BOOST_PP_ITERATION_3 156 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 157 && BOOST_PP_ITERATION_FINISH_3 >= 157 # define BOOST_PP_ITERATION_3 157 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 158 && BOOST_PP_ITERATION_FINISH_3 >= 158 # define BOOST_PP_ITERATION_3 158 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 159 && BOOST_PP_ITERATION_FINISH_3 >= 159 # define BOOST_PP_ITERATION_3 159 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 160 && BOOST_PP_ITERATION_FINISH_3 >= 160 # define BOOST_PP_ITERATION_3 160 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 161 && BOOST_PP_ITERATION_FINISH_3 >= 161 # define BOOST_PP_ITERATION_3 161 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 162 && BOOST_PP_ITERATION_FINISH_3 >= 162 # define BOOST_PP_ITERATION_3 162 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 163 && BOOST_PP_ITERATION_FINISH_3 >= 163 # define BOOST_PP_ITERATION_3 163 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 164 && BOOST_PP_ITERATION_FINISH_3 >= 164 # define BOOST_PP_ITERATION_3 164 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 165 && BOOST_PP_ITERATION_FINISH_3 >= 165 # define BOOST_PP_ITERATION_3 165 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 166 && BOOST_PP_ITERATION_FINISH_3 >= 166 # define BOOST_PP_ITERATION_3 166 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 167 && BOOST_PP_ITERATION_FINISH_3 >= 167 # define BOOST_PP_ITERATION_3 167 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 168 && BOOST_PP_ITERATION_FINISH_3 >= 168 # define BOOST_PP_ITERATION_3 168 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 169 && BOOST_PP_ITERATION_FINISH_3 >= 169 # define BOOST_PP_ITERATION_3 169 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 170 && BOOST_PP_ITERATION_FINISH_3 >= 170 # define BOOST_PP_ITERATION_3 170 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 171 && BOOST_PP_ITERATION_FINISH_3 >= 171 # define BOOST_PP_ITERATION_3 171 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 172 && BOOST_PP_ITERATION_FINISH_3 >= 172 # define BOOST_PP_ITERATION_3 172 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 173 && BOOST_PP_ITERATION_FINISH_3 >= 173 # define BOOST_PP_ITERATION_3 173 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 174 && BOOST_PP_ITERATION_FINISH_3 >= 174 # define BOOST_PP_ITERATION_3 174 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 175 && BOOST_PP_ITERATION_FINISH_3 >= 175 # define BOOST_PP_ITERATION_3 175 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 176 && BOOST_PP_ITERATION_FINISH_3 >= 176 # define BOOST_PP_ITERATION_3 176 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 177 && BOOST_PP_ITERATION_FINISH_3 >= 177 # define BOOST_PP_ITERATION_3 177 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 178 && BOOST_PP_ITERATION_FINISH_3 >= 178 # define BOOST_PP_ITERATION_3 178 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 179 && BOOST_PP_ITERATION_FINISH_3 >= 179 # define BOOST_PP_ITERATION_3 179 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 180 && BOOST_PP_ITERATION_FINISH_3 >= 180 # define BOOST_PP_ITERATION_3 180 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 181 && BOOST_PP_ITERATION_FINISH_3 >= 181 # define BOOST_PP_ITERATION_3 181 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 182 && BOOST_PP_ITERATION_FINISH_3 >= 182 # define BOOST_PP_ITERATION_3 182 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 183 && BOOST_PP_ITERATION_FINISH_3 >= 183 # define BOOST_PP_ITERATION_3 183 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 184 && BOOST_PP_ITERATION_FINISH_3 >= 184 # define BOOST_PP_ITERATION_3 184 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 185 && BOOST_PP_ITERATION_FINISH_3 >= 185 # define BOOST_PP_ITERATION_3 185 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 186 && BOOST_PP_ITERATION_FINISH_3 >= 186 # define BOOST_PP_ITERATION_3 186 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 187 && BOOST_PP_ITERATION_FINISH_3 >= 187 # define BOOST_PP_ITERATION_3 187 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 188 && BOOST_PP_ITERATION_FINISH_3 >= 188 # define BOOST_PP_ITERATION_3 188 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 189 && BOOST_PP_ITERATION_FINISH_3 >= 189 # define BOOST_PP_ITERATION_3 189 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 190 && BOOST_PP_ITERATION_FINISH_3 >= 190 # define BOOST_PP_ITERATION_3 190 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 191 && BOOST_PP_ITERATION_FINISH_3 >= 191 # define BOOST_PP_ITERATION_3 191 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 192 && BOOST_PP_ITERATION_FINISH_3 >= 192 # define BOOST_PP_ITERATION_3 192 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 193 && BOOST_PP_ITERATION_FINISH_3 >= 193 # define BOOST_PP_ITERATION_3 193 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 194 && BOOST_PP_ITERATION_FINISH_3 >= 194 # define BOOST_PP_ITERATION_3 194 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 195 && BOOST_PP_ITERATION_FINISH_3 >= 195 # define BOOST_PP_ITERATION_3 195 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 196 && BOOST_PP_ITERATION_FINISH_3 >= 196 # define BOOST_PP_ITERATION_3 196 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 197 && BOOST_PP_ITERATION_FINISH_3 >= 197 # define BOOST_PP_ITERATION_3 197 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 198 && BOOST_PP_ITERATION_FINISH_3 >= 198 # define BOOST_PP_ITERATION_3 198 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 199 && BOOST_PP_ITERATION_FINISH_3 >= 199 # define BOOST_PP_ITERATION_3 199 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 200 && BOOST_PP_ITERATION_FINISH_3 >= 200 # define BOOST_PP_ITERATION_3 200 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 201 && BOOST_PP_ITERATION_FINISH_3 >= 201 # define BOOST_PP_ITERATION_3 201 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 202 && BOOST_PP_ITERATION_FINISH_3 >= 202 # define BOOST_PP_ITERATION_3 202 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 203 && BOOST_PP_ITERATION_FINISH_3 >= 203 # define BOOST_PP_ITERATION_3 203 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 204 && BOOST_PP_ITERATION_FINISH_3 >= 204 # define BOOST_PP_ITERATION_3 204 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 205 && BOOST_PP_ITERATION_FINISH_3 >= 205 # define BOOST_PP_ITERATION_3 205 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 206 && BOOST_PP_ITERATION_FINISH_3 >= 206 # define BOOST_PP_ITERATION_3 206 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 207 && BOOST_PP_ITERATION_FINISH_3 >= 207 # define BOOST_PP_ITERATION_3 207 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 208 && BOOST_PP_ITERATION_FINISH_3 >= 208 # define BOOST_PP_ITERATION_3 208 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 209 && BOOST_PP_ITERATION_FINISH_3 >= 209 # define BOOST_PP_ITERATION_3 209 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 210 && BOOST_PP_ITERATION_FINISH_3 >= 210 # define BOOST_PP_ITERATION_3 210 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 211 && BOOST_PP_ITERATION_FINISH_3 >= 211 # define BOOST_PP_ITERATION_3 211 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 212 && BOOST_PP_ITERATION_FINISH_3 >= 212 # define BOOST_PP_ITERATION_3 212 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 213 && BOOST_PP_ITERATION_FINISH_3 >= 213 # define BOOST_PP_ITERATION_3 213 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 214 && BOOST_PP_ITERATION_FINISH_3 >= 214 # define BOOST_PP_ITERATION_3 214 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 215 && BOOST_PP_ITERATION_FINISH_3 >= 215 # define BOOST_PP_ITERATION_3 215 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 216 && BOOST_PP_ITERATION_FINISH_3 >= 216 # define BOOST_PP_ITERATION_3 216 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 217 && BOOST_PP_ITERATION_FINISH_3 >= 217 # define BOOST_PP_ITERATION_3 217 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 218 && BOOST_PP_ITERATION_FINISH_3 >= 218 # define BOOST_PP_ITERATION_3 218 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 219 && BOOST_PP_ITERATION_FINISH_3 >= 219 # define BOOST_PP_ITERATION_3 219 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 220 && BOOST_PP_ITERATION_FINISH_3 >= 220 # define BOOST_PP_ITERATION_3 220 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 221 && BOOST_PP_ITERATION_FINISH_3 >= 221 # define BOOST_PP_ITERATION_3 221 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 222 && BOOST_PP_ITERATION_FINISH_3 >= 222 # define BOOST_PP_ITERATION_3 222 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 223 && BOOST_PP_ITERATION_FINISH_3 >= 223 # define BOOST_PP_ITERATION_3 223 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 224 && BOOST_PP_ITERATION_FINISH_3 >= 224 # define BOOST_PP_ITERATION_3 224 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 225 && BOOST_PP_ITERATION_FINISH_3 >= 225 # define BOOST_PP_ITERATION_3 225 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 226 && BOOST_PP_ITERATION_FINISH_3 >= 226 # define BOOST_PP_ITERATION_3 226 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 227 && BOOST_PP_ITERATION_FINISH_3 >= 227 # define BOOST_PP_ITERATION_3 227 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 228 && BOOST_PP_ITERATION_FINISH_3 >= 228 # define BOOST_PP_ITERATION_3 228 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 229 && BOOST_PP_ITERATION_FINISH_3 >= 229 # define BOOST_PP_ITERATION_3 229 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 230 && BOOST_PP_ITERATION_FINISH_3 >= 230 # define BOOST_PP_ITERATION_3 230 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 231 && BOOST_PP_ITERATION_FINISH_3 >= 231 # define BOOST_PP_ITERATION_3 231 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 232 && BOOST_PP_ITERATION_FINISH_3 >= 232 # define BOOST_PP_ITERATION_3 232 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 233 && BOOST_PP_ITERATION_FINISH_3 >= 233 # define BOOST_PP_ITERATION_3 233 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 234 && BOOST_PP_ITERATION_FINISH_3 >= 234 # define BOOST_PP_ITERATION_3 234 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 235 && BOOST_PP_ITERATION_FINISH_3 >= 235 # define BOOST_PP_ITERATION_3 235 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 236 && BOOST_PP_ITERATION_FINISH_3 >= 236 # define BOOST_PP_ITERATION_3 236 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 237 && BOOST_PP_ITERATION_FINISH_3 >= 237 # define BOOST_PP_ITERATION_3 237 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 238 && BOOST_PP_ITERATION_FINISH_3 >= 238 # define BOOST_PP_ITERATION_3 238 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 239 && BOOST_PP_ITERATION_FINISH_3 >= 239 # define BOOST_PP_ITERATION_3 239 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 240 && BOOST_PP_ITERATION_FINISH_3 >= 240 # define BOOST_PP_ITERATION_3 240 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 241 && BOOST_PP_ITERATION_FINISH_3 >= 241 # define BOOST_PP_ITERATION_3 241 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 242 && BOOST_PP_ITERATION_FINISH_3 >= 242 # define BOOST_PP_ITERATION_3 242 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 243 && BOOST_PP_ITERATION_FINISH_3 >= 243 # define BOOST_PP_ITERATION_3 243 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 244 && BOOST_PP_ITERATION_FINISH_3 >= 244 # define BOOST_PP_ITERATION_3 244 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 245 && BOOST_PP_ITERATION_FINISH_3 >= 245 # define BOOST_PP_ITERATION_3 245 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 246 && BOOST_PP_ITERATION_FINISH_3 >= 246 # define BOOST_PP_ITERATION_3 246 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 247 && BOOST_PP_ITERATION_FINISH_3 >= 247 # define BOOST_PP_ITERATION_3 247 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 248 && BOOST_PP_ITERATION_FINISH_3 >= 248 # define BOOST_PP_ITERATION_3 248 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 249 && BOOST_PP_ITERATION_FINISH_3 >= 249 # define BOOST_PP_ITERATION_3 249 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 250 && BOOST_PP_ITERATION_FINISH_3 >= 250 # define BOOST_PP_ITERATION_3 250 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 251 && BOOST_PP_ITERATION_FINISH_3 >= 251 # define BOOST_PP_ITERATION_3 251 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 252 && BOOST_PP_ITERATION_FINISH_3 >= 252 # define BOOST_PP_ITERATION_3 252 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 253 && BOOST_PP_ITERATION_FINISH_3 >= 253 # define BOOST_PP_ITERATION_3 253 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 254 && BOOST_PP_ITERATION_FINISH_3 >= 254 # define BOOST_PP_ITERATION_3 254 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 255 && BOOST_PP_ITERATION_FINISH_3 >= 255 # define BOOST_PP_ITERATION_3 255 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_START_3 <= 256 && BOOST_PP_ITERATION_FINISH_3 >= 256 # define BOOST_PP_ITERATION_3 256 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 2 # # undef BOOST_PP_ITERATION_START_3 # undef BOOST_PP_ITERATION_FINISH_3 # undef BOOST_PP_FILENAME_3 # # undef BOOST_PP_ITERATION_FLAGS_3 # undef BOOST_PP_ITERATION_PARAMS_3 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/forward4.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if defined(BOOST_PP_ITERATION_LIMITS) # if !defined(BOOST_PP_FILENAME_4) # error BOOST_PP_ERROR: depth #4 filename is not defined # endif # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_ITERATION_FLAGS_4() 0 # undef BOOST_PP_ITERATION_LIMITS # elif defined(BOOST_PP_ITERATION_PARAMS_4) # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(0, BOOST_PP_ITERATION_PARAMS_4) # include # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(1, BOOST_PP_ITERATION_PARAMS_4) # include # define BOOST_PP_FILENAME_4 BOOST_PP_ARRAY_ELEM(2, BOOST_PP_ITERATION_PARAMS_4) # if BOOST_PP_ARRAY_SIZE(BOOST_PP_ITERATION_PARAMS_4) >= 4 # define BOOST_PP_ITERATION_FLAGS_4() BOOST_PP_ARRAY_ELEM(3, BOOST_PP_ITERATION_PARAMS_4) # else # define BOOST_PP_ITERATION_FLAGS_4() 0 # endif # else # error BOOST_PP_ERROR: depth #4 iteration boundaries or filename not defined # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 4 # # if (BOOST_PP_ITERATION_START_4) > (BOOST_PP_ITERATION_FINISH_4) # include # else # if BOOST_PP_ITERATION_START_4 <= 0 && BOOST_PP_ITERATION_FINISH_4 >= 0 # define BOOST_PP_ITERATION_4 0 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 1 && BOOST_PP_ITERATION_FINISH_4 >= 1 # define BOOST_PP_ITERATION_4 1 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 2 && BOOST_PP_ITERATION_FINISH_4 >= 2 # define BOOST_PP_ITERATION_4 2 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 3 && BOOST_PP_ITERATION_FINISH_4 >= 3 # define BOOST_PP_ITERATION_4 3 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 4 && BOOST_PP_ITERATION_FINISH_4 >= 4 # define BOOST_PP_ITERATION_4 4 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 5 && BOOST_PP_ITERATION_FINISH_4 >= 5 # define BOOST_PP_ITERATION_4 5 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 6 && BOOST_PP_ITERATION_FINISH_4 >= 6 # define BOOST_PP_ITERATION_4 6 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 7 && BOOST_PP_ITERATION_FINISH_4 >= 7 # define BOOST_PP_ITERATION_4 7 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 8 && BOOST_PP_ITERATION_FINISH_4 >= 8 # define BOOST_PP_ITERATION_4 8 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 9 && BOOST_PP_ITERATION_FINISH_4 >= 9 # define BOOST_PP_ITERATION_4 9 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 10 && BOOST_PP_ITERATION_FINISH_4 >= 10 # define BOOST_PP_ITERATION_4 10 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 11 && BOOST_PP_ITERATION_FINISH_4 >= 11 # define BOOST_PP_ITERATION_4 11 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 12 && BOOST_PP_ITERATION_FINISH_4 >= 12 # define BOOST_PP_ITERATION_4 12 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 13 && BOOST_PP_ITERATION_FINISH_4 >= 13 # define BOOST_PP_ITERATION_4 13 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 14 && BOOST_PP_ITERATION_FINISH_4 >= 14 # define BOOST_PP_ITERATION_4 14 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 15 && BOOST_PP_ITERATION_FINISH_4 >= 15 # define BOOST_PP_ITERATION_4 15 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 16 && BOOST_PP_ITERATION_FINISH_4 >= 16 # define BOOST_PP_ITERATION_4 16 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 17 && BOOST_PP_ITERATION_FINISH_4 >= 17 # define BOOST_PP_ITERATION_4 17 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 18 && BOOST_PP_ITERATION_FINISH_4 >= 18 # define BOOST_PP_ITERATION_4 18 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 19 && BOOST_PP_ITERATION_FINISH_4 >= 19 # define BOOST_PP_ITERATION_4 19 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 20 && BOOST_PP_ITERATION_FINISH_4 >= 20 # define BOOST_PP_ITERATION_4 20 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 21 && BOOST_PP_ITERATION_FINISH_4 >= 21 # define BOOST_PP_ITERATION_4 21 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 22 && BOOST_PP_ITERATION_FINISH_4 >= 22 # define BOOST_PP_ITERATION_4 22 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 23 && BOOST_PP_ITERATION_FINISH_4 >= 23 # define BOOST_PP_ITERATION_4 23 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 24 && BOOST_PP_ITERATION_FINISH_4 >= 24 # define BOOST_PP_ITERATION_4 24 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 25 && BOOST_PP_ITERATION_FINISH_4 >= 25 # define BOOST_PP_ITERATION_4 25 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 26 && BOOST_PP_ITERATION_FINISH_4 >= 26 # define BOOST_PP_ITERATION_4 26 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 27 && BOOST_PP_ITERATION_FINISH_4 >= 27 # define BOOST_PP_ITERATION_4 27 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 28 && BOOST_PP_ITERATION_FINISH_4 >= 28 # define BOOST_PP_ITERATION_4 28 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 29 && BOOST_PP_ITERATION_FINISH_4 >= 29 # define BOOST_PP_ITERATION_4 29 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 30 && BOOST_PP_ITERATION_FINISH_4 >= 30 # define BOOST_PP_ITERATION_4 30 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 31 && BOOST_PP_ITERATION_FINISH_4 >= 31 # define BOOST_PP_ITERATION_4 31 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 32 && BOOST_PP_ITERATION_FINISH_4 >= 32 # define BOOST_PP_ITERATION_4 32 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 33 && BOOST_PP_ITERATION_FINISH_4 >= 33 # define BOOST_PP_ITERATION_4 33 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 34 && BOOST_PP_ITERATION_FINISH_4 >= 34 # define BOOST_PP_ITERATION_4 34 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 35 && BOOST_PP_ITERATION_FINISH_4 >= 35 # define BOOST_PP_ITERATION_4 35 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 36 && BOOST_PP_ITERATION_FINISH_4 >= 36 # define BOOST_PP_ITERATION_4 36 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 37 && BOOST_PP_ITERATION_FINISH_4 >= 37 # define BOOST_PP_ITERATION_4 37 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 38 && BOOST_PP_ITERATION_FINISH_4 >= 38 # define BOOST_PP_ITERATION_4 38 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 39 && BOOST_PP_ITERATION_FINISH_4 >= 39 # define BOOST_PP_ITERATION_4 39 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 40 && BOOST_PP_ITERATION_FINISH_4 >= 40 # define BOOST_PP_ITERATION_4 40 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 41 && BOOST_PP_ITERATION_FINISH_4 >= 41 # define BOOST_PP_ITERATION_4 41 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 42 && BOOST_PP_ITERATION_FINISH_4 >= 42 # define BOOST_PP_ITERATION_4 42 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 43 && BOOST_PP_ITERATION_FINISH_4 >= 43 # define BOOST_PP_ITERATION_4 43 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 44 && BOOST_PP_ITERATION_FINISH_4 >= 44 # define BOOST_PP_ITERATION_4 44 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 45 && BOOST_PP_ITERATION_FINISH_4 >= 45 # define BOOST_PP_ITERATION_4 45 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 46 && BOOST_PP_ITERATION_FINISH_4 >= 46 # define BOOST_PP_ITERATION_4 46 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 47 && BOOST_PP_ITERATION_FINISH_4 >= 47 # define BOOST_PP_ITERATION_4 47 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 48 && BOOST_PP_ITERATION_FINISH_4 >= 48 # define BOOST_PP_ITERATION_4 48 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 49 && BOOST_PP_ITERATION_FINISH_4 >= 49 # define BOOST_PP_ITERATION_4 49 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 50 && BOOST_PP_ITERATION_FINISH_4 >= 50 # define BOOST_PP_ITERATION_4 50 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 51 && BOOST_PP_ITERATION_FINISH_4 >= 51 # define BOOST_PP_ITERATION_4 51 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 52 && BOOST_PP_ITERATION_FINISH_4 >= 52 # define BOOST_PP_ITERATION_4 52 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 53 && BOOST_PP_ITERATION_FINISH_4 >= 53 # define BOOST_PP_ITERATION_4 53 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 54 && BOOST_PP_ITERATION_FINISH_4 >= 54 # define BOOST_PP_ITERATION_4 54 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 55 && BOOST_PP_ITERATION_FINISH_4 >= 55 # define BOOST_PP_ITERATION_4 55 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 56 && BOOST_PP_ITERATION_FINISH_4 >= 56 # define BOOST_PP_ITERATION_4 56 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 57 && BOOST_PP_ITERATION_FINISH_4 >= 57 # define BOOST_PP_ITERATION_4 57 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 58 && BOOST_PP_ITERATION_FINISH_4 >= 58 # define BOOST_PP_ITERATION_4 58 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 59 && BOOST_PP_ITERATION_FINISH_4 >= 59 # define BOOST_PP_ITERATION_4 59 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 60 && BOOST_PP_ITERATION_FINISH_4 >= 60 # define BOOST_PP_ITERATION_4 60 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 61 && BOOST_PP_ITERATION_FINISH_4 >= 61 # define BOOST_PP_ITERATION_4 61 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 62 && BOOST_PP_ITERATION_FINISH_4 >= 62 # define BOOST_PP_ITERATION_4 62 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 63 && BOOST_PP_ITERATION_FINISH_4 >= 63 # define BOOST_PP_ITERATION_4 63 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 64 && BOOST_PP_ITERATION_FINISH_4 >= 64 # define BOOST_PP_ITERATION_4 64 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 65 && BOOST_PP_ITERATION_FINISH_4 >= 65 # define BOOST_PP_ITERATION_4 65 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 66 && BOOST_PP_ITERATION_FINISH_4 >= 66 # define BOOST_PP_ITERATION_4 66 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 67 && BOOST_PP_ITERATION_FINISH_4 >= 67 # define BOOST_PP_ITERATION_4 67 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 68 && BOOST_PP_ITERATION_FINISH_4 >= 68 # define BOOST_PP_ITERATION_4 68 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 69 && BOOST_PP_ITERATION_FINISH_4 >= 69 # define BOOST_PP_ITERATION_4 69 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 70 && BOOST_PP_ITERATION_FINISH_4 >= 70 # define BOOST_PP_ITERATION_4 70 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 71 && BOOST_PP_ITERATION_FINISH_4 >= 71 # define BOOST_PP_ITERATION_4 71 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 72 && BOOST_PP_ITERATION_FINISH_4 >= 72 # define BOOST_PP_ITERATION_4 72 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 73 && BOOST_PP_ITERATION_FINISH_4 >= 73 # define BOOST_PP_ITERATION_4 73 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 74 && BOOST_PP_ITERATION_FINISH_4 >= 74 # define BOOST_PP_ITERATION_4 74 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 75 && BOOST_PP_ITERATION_FINISH_4 >= 75 # define BOOST_PP_ITERATION_4 75 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 76 && BOOST_PP_ITERATION_FINISH_4 >= 76 # define BOOST_PP_ITERATION_4 76 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 77 && BOOST_PP_ITERATION_FINISH_4 >= 77 # define BOOST_PP_ITERATION_4 77 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 78 && BOOST_PP_ITERATION_FINISH_4 >= 78 # define BOOST_PP_ITERATION_4 78 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 79 && BOOST_PP_ITERATION_FINISH_4 >= 79 # define BOOST_PP_ITERATION_4 79 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 80 && BOOST_PP_ITERATION_FINISH_4 >= 80 # define BOOST_PP_ITERATION_4 80 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 81 && BOOST_PP_ITERATION_FINISH_4 >= 81 # define BOOST_PP_ITERATION_4 81 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 82 && BOOST_PP_ITERATION_FINISH_4 >= 82 # define BOOST_PP_ITERATION_4 82 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 83 && BOOST_PP_ITERATION_FINISH_4 >= 83 # define BOOST_PP_ITERATION_4 83 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 84 && BOOST_PP_ITERATION_FINISH_4 >= 84 # define BOOST_PP_ITERATION_4 84 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 85 && BOOST_PP_ITERATION_FINISH_4 >= 85 # define BOOST_PP_ITERATION_4 85 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 86 && BOOST_PP_ITERATION_FINISH_4 >= 86 # define BOOST_PP_ITERATION_4 86 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 87 && BOOST_PP_ITERATION_FINISH_4 >= 87 # define BOOST_PP_ITERATION_4 87 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 88 && BOOST_PP_ITERATION_FINISH_4 >= 88 # define BOOST_PP_ITERATION_4 88 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 89 && BOOST_PP_ITERATION_FINISH_4 >= 89 # define BOOST_PP_ITERATION_4 89 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 90 && BOOST_PP_ITERATION_FINISH_4 >= 90 # define BOOST_PP_ITERATION_4 90 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 91 && BOOST_PP_ITERATION_FINISH_4 >= 91 # define BOOST_PP_ITERATION_4 91 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 92 && BOOST_PP_ITERATION_FINISH_4 >= 92 # define BOOST_PP_ITERATION_4 92 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 93 && BOOST_PP_ITERATION_FINISH_4 >= 93 # define BOOST_PP_ITERATION_4 93 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 94 && BOOST_PP_ITERATION_FINISH_4 >= 94 # define BOOST_PP_ITERATION_4 94 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 95 && BOOST_PP_ITERATION_FINISH_4 >= 95 # define BOOST_PP_ITERATION_4 95 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 96 && BOOST_PP_ITERATION_FINISH_4 >= 96 # define BOOST_PP_ITERATION_4 96 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 97 && BOOST_PP_ITERATION_FINISH_4 >= 97 # define BOOST_PP_ITERATION_4 97 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 98 && BOOST_PP_ITERATION_FINISH_4 >= 98 # define BOOST_PP_ITERATION_4 98 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 99 && BOOST_PP_ITERATION_FINISH_4 >= 99 # define BOOST_PP_ITERATION_4 99 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 100 && BOOST_PP_ITERATION_FINISH_4 >= 100 # define BOOST_PP_ITERATION_4 100 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 101 && BOOST_PP_ITERATION_FINISH_4 >= 101 # define BOOST_PP_ITERATION_4 101 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 102 && BOOST_PP_ITERATION_FINISH_4 >= 102 # define BOOST_PP_ITERATION_4 102 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 103 && BOOST_PP_ITERATION_FINISH_4 >= 103 # define BOOST_PP_ITERATION_4 103 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 104 && BOOST_PP_ITERATION_FINISH_4 >= 104 # define BOOST_PP_ITERATION_4 104 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 105 && BOOST_PP_ITERATION_FINISH_4 >= 105 # define BOOST_PP_ITERATION_4 105 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 106 && BOOST_PP_ITERATION_FINISH_4 >= 106 # define BOOST_PP_ITERATION_4 106 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 107 && BOOST_PP_ITERATION_FINISH_4 >= 107 # define BOOST_PP_ITERATION_4 107 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 108 && BOOST_PP_ITERATION_FINISH_4 >= 108 # define BOOST_PP_ITERATION_4 108 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 109 && BOOST_PP_ITERATION_FINISH_4 >= 109 # define BOOST_PP_ITERATION_4 109 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 110 && BOOST_PP_ITERATION_FINISH_4 >= 110 # define BOOST_PP_ITERATION_4 110 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 111 && BOOST_PP_ITERATION_FINISH_4 >= 111 # define BOOST_PP_ITERATION_4 111 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 112 && BOOST_PP_ITERATION_FINISH_4 >= 112 # define BOOST_PP_ITERATION_4 112 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 113 && BOOST_PP_ITERATION_FINISH_4 >= 113 # define BOOST_PP_ITERATION_4 113 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 114 && BOOST_PP_ITERATION_FINISH_4 >= 114 # define BOOST_PP_ITERATION_4 114 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 115 && BOOST_PP_ITERATION_FINISH_4 >= 115 # define BOOST_PP_ITERATION_4 115 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 116 && BOOST_PP_ITERATION_FINISH_4 >= 116 # define BOOST_PP_ITERATION_4 116 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 117 && BOOST_PP_ITERATION_FINISH_4 >= 117 # define BOOST_PP_ITERATION_4 117 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 118 && BOOST_PP_ITERATION_FINISH_4 >= 118 # define BOOST_PP_ITERATION_4 118 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 119 && BOOST_PP_ITERATION_FINISH_4 >= 119 # define BOOST_PP_ITERATION_4 119 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 120 && BOOST_PP_ITERATION_FINISH_4 >= 120 # define BOOST_PP_ITERATION_4 120 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 121 && BOOST_PP_ITERATION_FINISH_4 >= 121 # define BOOST_PP_ITERATION_4 121 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 122 && BOOST_PP_ITERATION_FINISH_4 >= 122 # define BOOST_PP_ITERATION_4 122 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 123 && BOOST_PP_ITERATION_FINISH_4 >= 123 # define BOOST_PP_ITERATION_4 123 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 124 && BOOST_PP_ITERATION_FINISH_4 >= 124 # define BOOST_PP_ITERATION_4 124 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 125 && BOOST_PP_ITERATION_FINISH_4 >= 125 # define BOOST_PP_ITERATION_4 125 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 126 && BOOST_PP_ITERATION_FINISH_4 >= 126 # define BOOST_PP_ITERATION_4 126 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 127 && BOOST_PP_ITERATION_FINISH_4 >= 127 # define BOOST_PP_ITERATION_4 127 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 128 && BOOST_PP_ITERATION_FINISH_4 >= 128 # define BOOST_PP_ITERATION_4 128 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 129 && BOOST_PP_ITERATION_FINISH_4 >= 129 # define BOOST_PP_ITERATION_4 129 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 130 && BOOST_PP_ITERATION_FINISH_4 >= 130 # define BOOST_PP_ITERATION_4 130 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 131 && BOOST_PP_ITERATION_FINISH_4 >= 131 # define BOOST_PP_ITERATION_4 131 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 132 && BOOST_PP_ITERATION_FINISH_4 >= 132 # define BOOST_PP_ITERATION_4 132 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 133 && BOOST_PP_ITERATION_FINISH_4 >= 133 # define BOOST_PP_ITERATION_4 133 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 134 && BOOST_PP_ITERATION_FINISH_4 >= 134 # define BOOST_PP_ITERATION_4 134 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 135 && BOOST_PP_ITERATION_FINISH_4 >= 135 # define BOOST_PP_ITERATION_4 135 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 136 && BOOST_PP_ITERATION_FINISH_4 >= 136 # define BOOST_PP_ITERATION_4 136 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 137 && BOOST_PP_ITERATION_FINISH_4 >= 137 # define BOOST_PP_ITERATION_4 137 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 138 && BOOST_PP_ITERATION_FINISH_4 >= 138 # define BOOST_PP_ITERATION_4 138 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 139 && BOOST_PP_ITERATION_FINISH_4 >= 139 # define BOOST_PP_ITERATION_4 139 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 140 && BOOST_PP_ITERATION_FINISH_4 >= 140 # define BOOST_PP_ITERATION_4 140 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 141 && BOOST_PP_ITERATION_FINISH_4 >= 141 # define BOOST_PP_ITERATION_4 141 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 142 && BOOST_PP_ITERATION_FINISH_4 >= 142 # define BOOST_PP_ITERATION_4 142 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 143 && BOOST_PP_ITERATION_FINISH_4 >= 143 # define BOOST_PP_ITERATION_4 143 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 144 && BOOST_PP_ITERATION_FINISH_4 >= 144 # define BOOST_PP_ITERATION_4 144 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 145 && BOOST_PP_ITERATION_FINISH_4 >= 145 # define BOOST_PP_ITERATION_4 145 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 146 && BOOST_PP_ITERATION_FINISH_4 >= 146 # define BOOST_PP_ITERATION_4 146 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 147 && BOOST_PP_ITERATION_FINISH_4 >= 147 # define BOOST_PP_ITERATION_4 147 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 148 && BOOST_PP_ITERATION_FINISH_4 >= 148 # define BOOST_PP_ITERATION_4 148 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 149 && BOOST_PP_ITERATION_FINISH_4 >= 149 # define BOOST_PP_ITERATION_4 149 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 150 && BOOST_PP_ITERATION_FINISH_4 >= 150 # define BOOST_PP_ITERATION_4 150 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 151 && BOOST_PP_ITERATION_FINISH_4 >= 151 # define BOOST_PP_ITERATION_4 151 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 152 && BOOST_PP_ITERATION_FINISH_4 >= 152 # define BOOST_PP_ITERATION_4 152 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 153 && BOOST_PP_ITERATION_FINISH_4 >= 153 # define BOOST_PP_ITERATION_4 153 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 154 && BOOST_PP_ITERATION_FINISH_4 >= 154 # define BOOST_PP_ITERATION_4 154 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 155 && BOOST_PP_ITERATION_FINISH_4 >= 155 # define BOOST_PP_ITERATION_4 155 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 156 && BOOST_PP_ITERATION_FINISH_4 >= 156 # define BOOST_PP_ITERATION_4 156 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 157 && BOOST_PP_ITERATION_FINISH_4 >= 157 # define BOOST_PP_ITERATION_4 157 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 158 && BOOST_PP_ITERATION_FINISH_4 >= 158 # define BOOST_PP_ITERATION_4 158 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 159 && BOOST_PP_ITERATION_FINISH_4 >= 159 # define BOOST_PP_ITERATION_4 159 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 160 && BOOST_PP_ITERATION_FINISH_4 >= 160 # define BOOST_PP_ITERATION_4 160 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 161 && BOOST_PP_ITERATION_FINISH_4 >= 161 # define BOOST_PP_ITERATION_4 161 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 162 && BOOST_PP_ITERATION_FINISH_4 >= 162 # define BOOST_PP_ITERATION_4 162 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 163 && BOOST_PP_ITERATION_FINISH_4 >= 163 # define BOOST_PP_ITERATION_4 163 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 164 && BOOST_PP_ITERATION_FINISH_4 >= 164 # define BOOST_PP_ITERATION_4 164 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 165 && BOOST_PP_ITERATION_FINISH_4 >= 165 # define BOOST_PP_ITERATION_4 165 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 166 && BOOST_PP_ITERATION_FINISH_4 >= 166 # define BOOST_PP_ITERATION_4 166 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 167 && BOOST_PP_ITERATION_FINISH_4 >= 167 # define BOOST_PP_ITERATION_4 167 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 168 && BOOST_PP_ITERATION_FINISH_4 >= 168 # define BOOST_PP_ITERATION_4 168 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 169 && BOOST_PP_ITERATION_FINISH_4 >= 169 # define BOOST_PP_ITERATION_4 169 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 170 && BOOST_PP_ITERATION_FINISH_4 >= 170 # define BOOST_PP_ITERATION_4 170 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 171 && BOOST_PP_ITERATION_FINISH_4 >= 171 # define BOOST_PP_ITERATION_4 171 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 172 && BOOST_PP_ITERATION_FINISH_4 >= 172 # define BOOST_PP_ITERATION_4 172 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 173 && BOOST_PP_ITERATION_FINISH_4 >= 173 # define BOOST_PP_ITERATION_4 173 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 174 && BOOST_PP_ITERATION_FINISH_4 >= 174 # define BOOST_PP_ITERATION_4 174 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 175 && BOOST_PP_ITERATION_FINISH_4 >= 175 # define BOOST_PP_ITERATION_4 175 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 176 && BOOST_PP_ITERATION_FINISH_4 >= 176 # define BOOST_PP_ITERATION_4 176 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 177 && BOOST_PP_ITERATION_FINISH_4 >= 177 # define BOOST_PP_ITERATION_4 177 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 178 && BOOST_PP_ITERATION_FINISH_4 >= 178 # define BOOST_PP_ITERATION_4 178 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 179 && BOOST_PP_ITERATION_FINISH_4 >= 179 # define BOOST_PP_ITERATION_4 179 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 180 && BOOST_PP_ITERATION_FINISH_4 >= 180 # define BOOST_PP_ITERATION_4 180 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 181 && BOOST_PP_ITERATION_FINISH_4 >= 181 # define BOOST_PP_ITERATION_4 181 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 182 && BOOST_PP_ITERATION_FINISH_4 >= 182 # define BOOST_PP_ITERATION_4 182 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 183 && BOOST_PP_ITERATION_FINISH_4 >= 183 # define BOOST_PP_ITERATION_4 183 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 184 && BOOST_PP_ITERATION_FINISH_4 >= 184 # define BOOST_PP_ITERATION_4 184 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 185 && BOOST_PP_ITERATION_FINISH_4 >= 185 # define BOOST_PP_ITERATION_4 185 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 186 && BOOST_PP_ITERATION_FINISH_4 >= 186 # define BOOST_PP_ITERATION_4 186 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 187 && BOOST_PP_ITERATION_FINISH_4 >= 187 # define BOOST_PP_ITERATION_4 187 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 188 && BOOST_PP_ITERATION_FINISH_4 >= 188 # define BOOST_PP_ITERATION_4 188 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 189 && BOOST_PP_ITERATION_FINISH_4 >= 189 # define BOOST_PP_ITERATION_4 189 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 190 && BOOST_PP_ITERATION_FINISH_4 >= 190 # define BOOST_PP_ITERATION_4 190 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 191 && BOOST_PP_ITERATION_FINISH_4 >= 191 # define BOOST_PP_ITERATION_4 191 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 192 && BOOST_PP_ITERATION_FINISH_4 >= 192 # define BOOST_PP_ITERATION_4 192 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 193 && BOOST_PP_ITERATION_FINISH_4 >= 193 # define BOOST_PP_ITERATION_4 193 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 194 && BOOST_PP_ITERATION_FINISH_4 >= 194 # define BOOST_PP_ITERATION_4 194 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 195 && BOOST_PP_ITERATION_FINISH_4 >= 195 # define BOOST_PP_ITERATION_4 195 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 196 && BOOST_PP_ITERATION_FINISH_4 >= 196 # define BOOST_PP_ITERATION_4 196 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 197 && BOOST_PP_ITERATION_FINISH_4 >= 197 # define BOOST_PP_ITERATION_4 197 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 198 && BOOST_PP_ITERATION_FINISH_4 >= 198 # define BOOST_PP_ITERATION_4 198 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 199 && BOOST_PP_ITERATION_FINISH_4 >= 199 # define BOOST_PP_ITERATION_4 199 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 200 && BOOST_PP_ITERATION_FINISH_4 >= 200 # define BOOST_PP_ITERATION_4 200 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 201 && BOOST_PP_ITERATION_FINISH_4 >= 201 # define BOOST_PP_ITERATION_4 201 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 202 && BOOST_PP_ITERATION_FINISH_4 >= 202 # define BOOST_PP_ITERATION_4 202 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 203 && BOOST_PP_ITERATION_FINISH_4 >= 203 # define BOOST_PP_ITERATION_4 203 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 204 && BOOST_PP_ITERATION_FINISH_4 >= 204 # define BOOST_PP_ITERATION_4 204 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 205 && BOOST_PP_ITERATION_FINISH_4 >= 205 # define BOOST_PP_ITERATION_4 205 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 206 && BOOST_PP_ITERATION_FINISH_4 >= 206 # define BOOST_PP_ITERATION_4 206 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 207 && BOOST_PP_ITERATION_FINISH_4 >= 207 # define BOOST_PP_ITERATION_4 207 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 208 && BOOST_PP_ITERATION_FINISH_4 >= 208 # define BOOST_PP_ITERATION_4 208 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 209 && BOOST_PP_ITERATION_FINISH_4 >= 209 # define BOOST_PP_ITERATION_4 209 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 210 && BOOST_PP_ITERATION_FINISH_4 >= 210 # define BOOST_PP_ITERATION_4 210 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 211 && BOOST_PP_ITERATION_FINISH_4 >= 211 # define BOOST_PP_ITERATION_4 211 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 212 && BOOST_PP_ITERATION_FINISH_4 >= 212 # define BOOST_PP_ITERATION_4 212 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 213 && BOOST_PP_ITERATION_FINISH_4 >= 213 # define BOOST_PP_ITERATION_4 213 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 214 && BOOST_PP_ITERATION_FINISH_4 >= 214 # define BOOST_PP_ITERATION_4 214 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 215 && BOOST_PP_ITERATION_FINISH_4 >= 215 # define BOOST_PP_ITERATION_4 215 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 216 && BOOST_PP_ITERATION_FINISH_4 >= 216 # define BOOST_PP_ITERATION_4 216 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 217 && BOOST_PP_ITERATION_FINISH_4 >= 217 # define BOOST_PP_ITERATION_4 217 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 218 && BOOST_PP_ITERATION_FINISH_4 >= 218 # define BOOST_PP_ITERATION_4 218 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 219 && BOOST_PP_ITERATION_FINISH_4 >= 219 # define BOOST_PP_ITERATION_4 219 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 220 && BOOST_PP_ITERATION_FINISH_4 >= 220 # define BOOST_PP_ITERATION_4 220 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 221 && BOOST_PP_ITERATION_FINISH_4 >= 221 # define BOOST_PP_ITERATION_4 221 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 222 && BOOST_PP_ITERATION_FINISH_4 >= 222 # define BOOST_PP_ITERATION_4 222 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 223 && BOOST_PP_ITERATION_FINISH_4 >= 223 # define BOOST_PP_ITERATION_4 223 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 224 && BOOST_PP_ITERATION_FINISH_4 >= 224 # define BOOST_PP_ITERATION_4 224 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 225 && BOOST_PP_ITERATION_FINISH_4 >= 225 # define BOOST_PP_ITERATION_4 225 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 226 && BOOST_PP_ITERATION_FINISH_4 >= 226 # define BOOST_PP_ITERATION_4 226 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 227 && BOOST_PP_ITERATION_FINISH_4 >= 227 # define BOOST_PP_ITERATION_4 227 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 228 && BOOST_PP_ITERATION_FINISH_4 >= 228 # define BOOST_PP_ITERATION_4 228 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 229 && BOOST_PP_ITERATION_FINISH_4 >= 229 # define BOOST_PP_ITERATION_4 229 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 230 && BOOST_PP_ITERATION_FINISH_4 >= 230 # define BOOST_PP_ITERATION_4 230 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 231 && BOOST_PP_ITERATION_FINISH_4 >= 231 # define BOOST_PP_ITERATION_4 231 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 232 && BOOST_PP_ITERATION_FINISH_4 >= 232 # define BOOST_PP_ITERATION_4 232 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 233 && BOOST_PP_ITERATION_FINISH_4 >= 233 # define BOOST_PP_ITERATION_4 233 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 234 && BOOST_PP_ITERATION_FINISH_4 >= 234 # define BOOST_PP_ITERATION_4 234 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 235 && BOOST_PP_ITERATION_FINISH_4 >= 235 # define BOOST_PP_ITERATION_4 235 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 236 && BOOST_PP_ITERATION_FINISH_4 >= 236 # define BOOST_PP_ITERATION_4 236 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 237 && BOOST_PP_ITERATION_FINISH_4 >= 237 # define BOOST_PP_ITERATION_4 237 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 238 && BOOST_PP_ITERATION_FINISH_4 >= 238 # define BOOST_PP_ITERATION_4 238 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 239 && BOOST_PP_ITERATION_FINISH_4 >= 239 # define BOOST_PP_ITERATION_4 239 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 240 && BOOST_PP_ITERATION_FINISH_4 >= 240 # define BOOST_PP_ITERATION_4 240 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 241 && BOOST_PP_ITERATION_FINISH_4 >= 241 # define BOOST_PP_ITERATION_4 241 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 242 && BOOST_PP_ITERATION_FINISH_4 >= 242 # define BOOST_PP_ITERATION_4 242 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 243 && BOOST_PP_ITERATION_FINISH_4 >= 243 # define BOOST_PP_ITERATION_4 243 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 244 && BOOST_PP_ITERATION_FINISH_4 >= 244 # define BOOST_PP_ITERATION_4 244 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 245 && BOOST_PP_ITERATION_FINISH_4 >= 245 # define BOOST_PP_ITERATION_4 245 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 246 && BOOST_PP_ITERATION_FINISH_4 >= 246 # define BOOST_PP_ITERATION_4 246 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 247 && BOOST_PP_ITERATION_FINISH_4 >= 247 # define BOOST_PP_ITERATION_4 247 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 248 && BOOST_PP_ITERATION_FINISH_4 >= 248 # define BOOST_PP_ITERATION_4 248 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 249 && BOOST_PP_ITERATION_FINISH_4 >= 249 # define BOOST_PP_ITERATION_4 249 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 250 && BOOST_PP_ITERATION_FINISH_4 >= 250 # define BOOST_PP_ITERATION_4 250 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 251 && BOOST_PP_ITERATION_FINISH_4 >= 251 # define BOOST_PP_ITERATION_4 251 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 252 && BOOST_PP_ITERATION_FINISH_4 >= 252 # define BOOST_PP_ITERATION_4 252 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 253 && BOOST_PP_ITERATION_FINISH_4 >= 253 # define BOOST_PP_ITERATION_4 253 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 254 && BOOST_PP_ITERATION_FINISH_4 >= 254 # define BOOST_PP_ITERATION_4 254 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 255 && BOOST_PP_ITERATION_FINISH_4 >= 255 # define BOOST_PP_ITERATION_4 255 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_START_4 <= 256 && BOOST_PP_ITERATION_FINISH_4 >= 256 # define BOOST_PP_ITERATION_4 256 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 3 # # undef BOOST_PP_ITERATION_START_4 # undef BOOST_PP_ITERATION_FINISH_4 # undef BOOST_PP_FILENAME_4 # # undef BOOST_PP_ITERATION_FLAGS_4 # undef BOOST_PP_ITERATION_PARAMS_4 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/forward5.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if defined(BOOST_PP_ITERATION_LIMITS) # if !defined(BOOST_PP_FILENAME_5) # error BOOST_PP_ERROR: depth #5 filename is not defined # endif # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_ITERATION_LIMITS) # include # define BOOST_PP_ITERATION_FLAGS_5() 0 # undef BOOST_PP_ITERATION_LIMITS # elif defined(BOOST_PP_ITERATION_PARAMS_5) # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(0, BOOST_PP_ITERATION_PARAMS_5) # include # define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(1, BOOST_PP_ITERATION_PARAMS_5) # include # define BOOST_PP_FILENAME_5 BOOST_PP_ARRAY_ELEM(2, BOOST_PP_ITERATION_PARAMS_5) # if BOOST_PP_ARRAY_SIZE(BOOST_PP_ITERATION_PARAMS_5) >= 4 # define BOOST_PP_ITERATION_FLAGS_5() BOOST_PP_ARRAY_ELEM(3, BOOST_PP_ITERATION_PARAMS_5) # else # define BOOST_PP_ITERATION_FLAGS_5() 0 # endif # else # error BOOST_PP_ERROR: depth #5 iteration boundaries or filename not defined # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 5 # # if (BOOST_PP_ITERATION_START_5) > (BOOST_PP_ITERATION_FINISH_5) # include # else # if BOOST_PP_ITERATION_START_5 <= 0 && BOOST_PP_ITERATION_FINISH_5 >= 0 # define BOOST_PP_ITERATION_5 0 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 1 && BOOST_PP_ITERATION_FINISH_5 >= 1 # define BOOST_PP_ITERATION_5 1 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 2 && BOOST_PP_ITERATION_FINISH_5 >= 2 # define BOOST_PP_ITERATION_5 2 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 3 && BOOST_PP_ITERATION_FINISH_5 >= 3 # define BOOST_PP_ITERATION_5 3 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 4 && BOOST_PP_ITERATION_FINISH_5 >= 4 # define BOOST_PP_ITERATION_5 4 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 5 && BOOST_PP_ITERATION_FINISH_5 >= 5 # define BOOST_PP_ITERATION_5 5 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 6 && BOOST_PP_ITERATION_FINISH_5 >= 6 # define BOOST_PP_ITERATION_5 6 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 7 && BOOST_PP_ITERATION_FINISH_5 >= 7 # define BOOST_PP_ITERATION_5 7 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 8 && BOOST_PP_ITERATION_FINISH_5 >= 8 # define BOOST_PP_ITERATION_5 8 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 9 && BOOST_PP_ITERATION_FINISH_5 >= 9 # define BOOST_PP_ITERATION_5 9 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 10 && BOOST_PP_ITERATION_FINISH_5 >= 10 # define BOOST_PP_ITERATION_5 10 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 11 && BOOST_PP_ITERATION_FINISH_5 >= 11 # define BOOST_PP_ITERATION_5 11 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 12 && BOOST_PP_ITERATION_FINISH_5 >= 12 # define BOOST_PP_ITERATION_5 12 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 13 && BOOST_PP_ITERATION_FINISH_5 >= 13 # define BOOST_PP_ITERATION_5 13 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 14 && BOOST_PP_ITERATION_FINISH_5 >= 14 # define BOOST_PP_ITERATION_5 14 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 15 && BOOST_PP_ITERATION_FINISH_5 >= 15 # define BOOST_PP_ITERATION_5 15 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 16 && BOOST_PP_ITERATION_FINISH_5 >= 16 # define BOOST_PP_ITERATION_5 16 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 17 && BOOST_PP_ITERATION_FINISH_5 >= 17 # define BOOST_PP_ITERATION_5 17 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 18 && BOOST_PP_ITERATION_FINISH_5 >= 18 # define BOOST_PP_ITERATION_5 18 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 19 && BOOST_PP_ITERATION_FINISH_5 >= 19 # define BOOST_PP_ITERATION_5 19 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 20 && BOOST_PP_ITERATION_FINISH_5 >= 20 # define BOOST_PP_ITERATION_5 20 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 21 && BOOST_PP_ITERATION_FINISH_5 >= 21 # define BOOST_PP_ITERATION_5 21 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 22 && BOOST_PP_ITERATION_FINISH_5 >= 22 # define BOOST_PP_ITERATION_5 22 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 23 && BOOST_PP_ITERATION_FINISH_5 >= 23 # define BOOST_PP_ITERATION_5 23 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 24 && BOOST_PP_ITERATION_FINISH_5 >= 24 # define BOOST_PP_ITERATION_5 24 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 25 && BOOST_PP_ITERATION_FINISH_5 >= 25 # define BOOST_PP_ITERATION_5 25 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 26 && BOOST_PP_ITERATION_FINISH_5 >= 26 # define BOOST_PP_ITERATION_5 26 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 27 && BOOST_PP_ITERATION_FINISH_5 >= 27 # define BOOST_PP_ITERATION_5 27 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 28 && BOOST_PP_ITERATION_FINISH_5 >= 28 # define BOOST_PP_ITERATION_5 28 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 29 && BOOST_PP_ITERATION_FINISH_5 >= 29 # define BOOST_PP_ITERATION_5 29 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 30 && BOOST_PP_ITERATION_FINISH_5 >= 30 # define BOOST_PP_ITERATION_5 30 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 31 && BOOST_PP_ITERATION_FINISH_5 >= 31 # define BOOST_PP_ITERATION_5 31 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 32 && BOOST_PP_ITERATION_FINISH_5 >= 32 # define BOOST_PP_ITERATION_5 32 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 33 && BOOST_PP_ITERATION_FINISH_5 >= 33 # define BOOST_PP_ITERATION_5 33 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 34 && BOOST_PP_ITERATION_FINISH_5 >= 34 # define BOOST_PP_ITERATION_5 34 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 35 && BOOST_PP_ITERATION_FINISH_5 >= 35 # define BOOST_PP_ITERATION_5 35 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 36 && BOOST_PP_ITERATION_FINISH_5 >= 36 # define BOOST_PP_ITERATION_5 36 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 37 && BOOST_PP_ITERATION_FINISH_5 >= 37 # define BOOST_PP_ITERATION_5 37 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 38 && BOOST_PP_ITERATION_FINISH_5 >= 38 # define BOOST_PP_ITERATION_5 38 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 39 && BOOST_PP_ITERATION_FINISH_5 >= 39 # define BOOST_PP_ITERATION_5 39 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 40 && BOOST_PP_ITERATION_FINISH_5 >= 40 # define BOOST_PP_ITERATION_5 40 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 41 && BOOST_PP_ITERATION_FINISH_5 >= 41 # define BOOST_PP_ITERATION_5 41 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 42 && BOOST_PP_ITERATION_FINISH_5 >= 42 # define BOOST_PP_ITERATION_5 42 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 43 && BOOST_PP_ITERATION_FINISH_5 >= 43 # define BOOST_PP_ITERATION_5 43 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 44 && BOOST_PP_ITERATION_FINISH_5 >= 44 # define BOOST_PP_ITERATION_5 44 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 45 && BOOST_PP_ITERATION_FINISH_5 >= 45 # define BOOST_PP_ITERATION_5 45 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 46 && BOOST_PP_ITERATION_FINISH_5 >= 46 # define BOOST_PP_ITERATION_5 46 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 47 && BOOST_PP_ITERATION_FINISH_5 >= 47 # define BOOST_PP_ITERATION_5 47 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 48 && BOOST_PP_ITERATION_FINISH_5 >= 48 # define BOOST_PP_ITERATION_5 48 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 49 && BOOST_PP_ITERATION_FINISH_5 >= 49 # define BOOST_PP_ITERATION_5 49 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 50 && BOOST_PP_ITERATION_FINISH_5 >= 50 # define BOOST_PP_ITERATION_5 50 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 51 && BOOST_PP_ITERATION_FINISH_5 >= 51 # define BOOST_PP_ITERATION_5 51 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 52 && BOOST_PP_ITERATION_FINISH_5 >= 52 # define BOOST_PP_ITERATION_5 52 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 53 && BOOST_PP_ITERATION_FINISH_5 >= 53 # define BOOST_PP_ITERATION_5 53 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 54 && BOOST_PP_ITERATION_FINISH_5 >= 54 # define BOOST_PP_ITERATION_5 54 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 55 && BOOST_PP_ITERATION_FINISH_5 >= 55 # define BOOST_PP_ITERATION_5 55 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 56 && BOOST_PP_ITERATION_FINISH_5 >= 56 # define BOOST_PP_ITERATION_5 56 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 57 && BOOST_PP_ITERATION_FINISH_5 >= 57 # define BOOST_PP_ITERATION_5 57 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 58 && BOOST_PP_ITERATION_FINISH_5 >= 58 # define BOOST_PP_ITERATION_5 58 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 59 && BOOST_PP_ITERATION_FINISH_5 >= 59 # define BOOST_PP_ITERATION_5 59 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 60 && BOOST_PP_ITERATION_FINISH_5 >= 60 # define BOOST_PP_ITERATION_5 60 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 61 && BOOST_PP_ITERATION_FINISH_5 >= 61 # define BOOST_PP_ITERATION_5 61 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 62 && BOOST_PP_ITERATION_FINISH_5 >= 62 # define BOOST_PP_ITERATION_5 62 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 63 && BOOST_PP_ITERATION_FINISH_5 >= 63 # define BOOST_PP_ITERATION_5 63 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 64 && BOOST_PP_ITERATION_FINISH_5 >= 64 # define BOOST_PP_ITERATION_5 64 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 65 && BOOST_PP_ITERATION_FINISH_5 >= 65 # define BOOST_PP_ITERATION_5 65 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 66 && BOOST_PP_ITERATION_FINISH_5 >= 66 # define BOOST_PP_ITERATION_5 66 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 67 && BOOST_PP_ITERATION_FINISH_5 >= 67 # define BOOST_PP_ITERATION_5 67 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 68 && BOOST_PP_ITERATION_FINISH_5 >= 68 # define BOOST_PP_ITERATION_5 68 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 69 && BOOST_PP_ITERATION_FINISH_5 >= 69 # define BOOST_PP_ITERATION_5 69 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 70 && BOOST_PP_ITERATION_FINISH_5 >= 70 # define BOOST_PP_ITERATION_5 70 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 71 && BOOST_PP_ITERATION_FINISH_5 >= 71 # define BOOST_PP_ITERATION_5 71 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 72 && BOOST_PP_ITERATION_FINISH_5 >= 72 # define BOOST_PP_ITERATION_5 72 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 73 && BOOST_PP_ITERATION_FINISH_5 >= 73 # define BOOST_PP_ITERATION_5 73 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 74 && BOOST_PP_ITERATION_FINISH_5 >= 74 # define BOOST_PP_ITERATION_5 74 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 75 && BOOST_PP_ITERATION_FINISH_5 >= 75 # define BOOST_PP_ITERATION_5 75 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 76 && BOOST_PP_ITERATION_FINISH_5 >= 76 # define BOOST_PP_ITERATION_5 76 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 77 && BOOST_PP_ITERATION_FINISH_5 >= 77 # define BOOST_PP_ITERATION_5 77 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 78 && BOOST_PP_ITERATION_FINISH_5 >= 78 # define BOOST_PP_ITERATION_5 78 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 79 && BOOST_PP_ITERATION_FINISH_5 >= 79 # define BOOST_PP_ITERATION_5 79 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 80 && BOOST_PP_ITERATION_FINISH_5 >= 80 # define BOOST_PP_ITERATION_5 80 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 81 && BOOST_PP_ITERATION_FINISH_5 >= 81 # define BOOST_PP_ITERATION_5 81 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 82 && BOOST_PP_ITERATION_FINISH_5 >= 82 # define BOOST_PP_ITERATION_5 82 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 83 && BOOST_PP_ITERATION_FINISH_5 >= 83 # define BOOST_PP_ITERATION_5 83 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 84 && BOOST_PP_ITERATION_FINISH_5 >= 84 # define BOOST_PP_ITERATION_5 84 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 85 && BOOST_PP_ITERATION_FINISH_5 >= 85 # define BOOST_PP_ITERATION_5 85 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 86 && BOOST_PP_ITERATION_FINISH_5 >= 86 # define BOOST_PP_ITERATION_5 86 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 87 && BOOST_PP_ITERATION_FINISH_5 >= 87 # define BOOST_PP_ITERATION_5 87 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 88 && BOOST_PP_ITERATION_FINISH_5 >= 88 # define BOOST_PP_ITERATION_5 88 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 89 && BOOST_PP_ITERATION_FINISH_5 >= 89 # define BOOST_PP_ITERATION_5 89 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 90 && BOOST_PP_ITERATION_FINISH_5 >= 90 # define BOOST_PP_ITERATION_5 90 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 91 && BOOST_PP_ITERATION_FINISH_5 >= 91 # define BOOST_PP_ITERATION_5 91 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 92 && BOOST_PP_ITERATION_FINISH_5 >= 92 # define BOOST_PP_ITERATION_5 92 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 93 && BOOST_PP_ITERATION_FINISH_5 >= 93 # define BOOST_PP_ITERATION_5 93 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 94 && BOOST_PP_ITERATION_FINISH_5 >= 94 # define BOOST_PP_ITERATION_5 94 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 95 && BOOST_PP_ITERATION_FINISH_5 >= 95 # define BOOST_PP_ITERATION_5 95 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 96 && BOOST_PP_ITERATION_FINISH_5 >= 96 # define BOOST_PP_ITERATION_5 96 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 97 && BOOST_PP_ITERATION_FINISH_5 >= 97 # define BOOST_PP_ITERATION_5 97 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 98 && BOOST_PP_ITERATION_FINISH_5 >= 98 # define BOOST_PP_ITERATION_5 98 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 99 && BOOST_PP_ITERATION_FINISH_5 >= 99 # define BOOST_PP_ITERATION_5 99 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 100 && BOOST_PP_ITERATION_FINISH_5 >= 100 # define BOOST_PP_ITERATION_5 100 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 101 && BOOST_PP_ITERATION_FINISH_5 >= 101 # define BOOST_PP_ITERATION_5 101 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 102 && BOOST_PP_ITERATION_FINISH_5 >= 102 # define BOOST_PP_ITERATION_5 102 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 103 && BOOST_PP_ITERATION_FINISH_5 >= 103 # define BOOST_PP_ITERATION_5 103 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 104 && BOOST_PP_ITERATION_FINISH_5 >= 104 # define BOOST_PP_ITERATION_5 104 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 105 && BOOST_PP_ITERATION_FINISH_5 >= 105 # define BOOST_PP_ITERATION_5 105 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 106 && BOOST_PP_ITERATION_FINISH_5 >= 106 # define BOOST_PP_ITERATION_5 106 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 107 && BOOST_PP_ITERATION_FINISH_5 >= 107 # define BOOST_PP_ITERATION_5 107 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 108 && BOOST_PP_ITERATION_FINISH_5 >= 108 # define BOOST_PP_ITERATION_5 108 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 109 && BOOST_PP_ITERATION_FINISH_5 >= 109 # define BOOST_PP_ITERATION_5 109 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 110 && BOOST_PP_ITERATION_FINISH_5 >= 110 # define BOOST_PP_ITERATION_5 110 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 111 && BOOST_PP_ITERATION_FINISH_5 >= 111 # define BOOST_PP_ITERATION_5 111 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 112 && BOOST_PP_ITERATION_FINISH_5 >= 112 # define BOOST_PP_ITERATION_5 112 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 113 && BOOST_PP_ITERATION_FINISH_5 >= 113 # define BOOST_PP_ITERATION_5 113 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 114 && BOOST_PP_ITERATION_FINISH_5 >= 114 # define BOOST_PP_ITERATION_5 114 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 115 && BOOST_PP_ITERATION_FINISH_5 >= 115 # define BOOST_PP_ITERATION_5 115 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 116 && BOOST_PP_ITERATION_FINISH_5 >= 116 # define BOOST_PP_ITERATION_5 116 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 117 && BOOST_PP_ITERATION_FINISH_5 >= 117 # define BOOST_PP_ITERATION_5 117 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 118 && BOOST_PP_ITERATION_FINISH_5 >= 118 # define BOOST_PP_ITERATION_5 118 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 119 && BOOST_PP_ITERATION_FINISH_5 >= 119 # define BOOST_PP_ITERATION_5 119 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 120 && BOOST_PP_ITERATION_FINISH_5 >= 120 # define BOOST_PP_ITERATION_5 120 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 121 && BOOST_PP_ITERATION_FINISH_5 >= 121 # define BOOST_PP_ITERATION_5 121 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 122 && BOOST_PP_ITERATION_FINISH_5 >= 122 # define BOOST_PP_ITERATION_5 122 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 123 && BOOST_PP_ITERATION_FINISH_5 >= 123 # define BOOST_PP_ITERATION_5 123 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 124 && BOOST_PP_ITERATION_FINISH_5 >= 124 # define BOOST_PP_ITERATION_5 124 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 125 && BOOST_PP_ITERATION_FINISH_5 >= 125 # define BOOST_PP_ITERATION_5 125 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 126 && BOOST_PP_ITERATION_FINISH_5 >= 126 # define BOOST_PP_ITERATION_5 126 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 127 && BOOST_PP_ITERATION_FINISH_5 >= 127 # define BOOST_PP_ITERATION_5 127 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 128 && BOOST_PP_ITERATION_FINISH_5 >= 128 # define BOOST_PP_ITERATION_5 128 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 129 && BOOST_PP_ITERATION_FINISH_5 >= 129 # define BOOST_PP_ITERATION_5 129 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 130 && BOOST_PP_ITERATION_FINISH_5 >= 130 # define BOOST_PP_ITERATION_5 130 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 131 && BOOST_PP_ITERATION_FINISH_5 >= 131 # define BOOST_PP_ITERATION_5 131 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 132 && BOOST_PP_ITERATION_FINISH_5 >= 132 # define BOOST_PP_ITERATION_5 132 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 133 && BOOST_PP_ITERATION_FINISH_5 >= 133 # define BOOST_PP_ITERATION_5 133 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 134 && BOOST_PP_ITERATION_FINISH_5 >= 134 # define BOOST_PP_ITERATION_5 134 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 135 && BOOST_PP_ITERATION_FINISH_5 >= 135 # define BOOST_PP_ITERATION_5 135 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 136 && BOOST_PP_ITERATION_FINISH_5 >= 136 # define BOOST_PP_ITERATION_5 136 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 137 && BOOST_PP_ITERATION_FINISH_5 >= 137 # define BOOST_PP_ITERATION_5 137 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 138 && BOOST_PP_ITERATION_FINISH_5 >= 138 # define BOOST_PP_ITERATION_5 138 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 139 && BOOST_PP_ITERATION_FINISH_5 >= 139 # define BOOST_PP_ITERATION_5 139 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 140 && BOOST_PP_ITERATION_FINISH_5 >= 140 # define BOOST_PP_ITERATION_5 140 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 141 && BOOST_PP_ITERATION_FINISH_5 >= 141 # define BOOST_PP_ITERATION_5 141 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 142 && BOOST_PP_ITERATION_FINISH_5 >= 142 # define BOOST_PP_ITERATION_5 142 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 143 && BOOST_PP_ITERATION_FINISH_5 >= 143 # define BOOST_PP_ITERATION_5 143 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 144 && BOOST_PP_ITERATION_FINISH_5 >= 144 # define BOOST_PP_ITERATION_5 144 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 145 && BOOST_PP_ITERATION_FINISH_5 >= 145 # define BOOST_PP_ITERATION_5 145 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 146 && BOOST_PP_ITERATION_FINISH_5 >= 146 # define BOOST_PP_ITERATION_5 146 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 147 && BOOST_PP_ITERATION_FINISH_5 >= 147 # define BOOST_PP_ITERATION_5 147 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 148 && BOOST_PP_ITERATION_FINISH_5 >= 148 # define BOOST_PP_ITERATION_5 148 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 149 && BOOST_PP_ITERATION_FINISH_5 >= 149 # define BOOST_PP_ITERATION_5 149 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 150 && BOOST_PP_ITERATION_FINISH_5 >= 150 # define BOOST_PP_ITERATION_5 150 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 151 && BOOST_PP_ITERATION_FINISH_5 >= 151 # define BOOST_PP_ITERATION_5 151 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 152 && BOOST_PP_ITERATION_FINISH_5 >= 152 # define BOOST_PP_ITERATION_5 152 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 153 && BOOST_PP_ITERATION_FINISH_5 >= 153 # define BOOST_PP_ITERATION_5 153 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 154 && BOOST_PP_ITERATION_FINISH_5 >= 154 # define BOOST_PP_ITERATION_5 154 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 155 && BOOST_PP_ITERATION_FINISH_5 >= 155 # define BOOST_PP_ITERATION_5 155 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 156 && BOOST_PP_ITERATION_FINISH_5 >= 156 # define BOOST_PP_ITERATION_5 156 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 157 && BOOST_PP_ITERATION_FINISH_5 >= 157 # define BOOST_PP_ITERATION_5 157 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 158 && BOOST_PP_ITERATION_FINISH_5 >= 158 # define BOOST_PP_ITERATION_5 158 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 159 && BOOST_PP_ITERATION_FINISH_5 >= 159 # define BOOST_PP_ITERATION_5 159 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 160 && BOOST_PP_ITERATION_FINISH_5 >= 160 # define BOOST_PP_ITERATION_5 160 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 161 && BOOST_PP_ITERATION_FINISH_5 >= 161 # define BOOST_PP_ITERATION_5 161 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 162 && BOOST_PP_ITERATION_FINISH_5 >= 162 # define BOOST_PP_ITERATION_5 162 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 163 && BOOST_PP_ITERATION_FINISH_5 >= 163 # define BOOST_PP_ITERATION_5 163 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 164 && BOOST_PP_ITERATION_FINISH_5 >= 164 # define BOOST_PP_ITERATION_5 164 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 165 && BOOST_PP_ITERATION_FINISH_5 >= 165 # define BOOST_PP_ITERATION_5 165 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 166 && BOOST_PP_ITERATION_FINISH_5 >= 166 # define BOOST_PP_ITERATION_5 166 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 167 && BOOST_PP_ITERATION_FINISH_5 >= 167 # define BOOST_PP_ITERATION_5 167 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 168 && BOOST_PP_ITERATION_FINISH_5 >= 168 # define BOOST_PP_ITERATION_5 168 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 169 && BOOST_PP_ITERATION_FINISH_5 >= 169 # define BOOST_PP_ITERATION_5 169 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 170 && BOOST_PP_ITERATION_FINISH_5 >= 170 # define BOOST_PP_ITERATION_5 170 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 171 && BOOST_PP_ITERATION_FINISH_5 >= 171 # define BOOST_PP_ITERATION_5 171 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 172 && BOOST_PP_ITERATION_FINISH_5 >= 172 # define BOOST_PP_ITERATION_5 172 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 173 && BOOST_PP_ITERATION_FINISH_5 >= 173 # define BOOST_PP_ITERATION_5 173 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 174 && BOOST_PP_ITERATION_FINISH_5 >= 174 # define BOOST_PP_ITERATION_5 174 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 175 && BOOST_PP_ITERATION_FINISH_5 >= 175 # define BOOST_PP_ITERATION_5 175 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 176 && BOOST_PP_ITERATION_FINISH_5 >= 176 # define BOOST_PP_ITERATION_5 176 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 177 && BOOST_PP_ITERATION_FINISH_5 >= 177 # define BOOST_PP_ITERATION_5 177 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 178 && BOOST_PP_ITERATION_FINISH_5 >= 178 # define BOOST_PP_ITERATION_5 178 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 179 && BOOST_PP_ITERATION_FINISH_5 >= 179 # define BOOST_PP_ITERATION_5 179 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 180 && BOOST_PP_ITERATION_FINISH_5 >= 180 # define BOOST_PP_ITERATION_5 180 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 181 && BOOST_PP_ITERATION_FINISH_5 >= 181 # define BOOST_PP_ITERATION_5 181 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 182 && BOOST_PP_ITERATION_FINISH_5 >= 182 # define BOOST_PP_ITERATION_5 182 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 183 && BOOST_PP_ITERATION_FINISH_5 >= 183 # define BOOST_PP_ITERATION_5 183 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 184 && BOOST_PP_ITERATION_FINISH_5 >= 184 # define BOOST_PP_ITERATION_5 184 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 185 && BOOST_PP_ITERATION_FINISH_5 >= 185 # define BOOST_PP_ITERATION_5 185 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 186 && BOOST_PP_ITERATION_FINISH_5 >= 186 # define BOOST_PP_ITERATION_5 186 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 187 && BOOST_PP_ITERATION_FINISH_5 >= 187 # define BOOST_PP_ITERATION_5 187 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 188 && BOOST_PP_ITERATION_FINISH_5 >= 188 # define BOOST_PP_ITERATION_5 188 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 189 && BOOST_PP_ITERATION_FINISH_5 >= 189 # define BOOST_PP_ITERATION_5 189 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 190 && BOOST_PP_ITERATION_FINISH_5 >= 190 # define BOOST_PP_ITERATION_5 190 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 191 && BOOST_PP_ITERATION_FINISH_5 >= 191 # define BOOST_PP_ITERATION_5 191 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 192 && BOOST_PP_ITERATION_FINISH_5 >= 192 # define BOOST_PP_ITERATION_5 192 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 193 && BOOST_PP_ITERATION_FINISH_5 >= 193 # define BOOST_PP_ITERATION_5 193 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 194 && BOOST_PP_ITERATION_FINISH_5 >= 194 # define BOOST_PP_ITERATION_5 194 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 195 && BOOST_PP_ITERATION_FINISH_5 >= 195 # define BOOST_PP_ITERATION_5 195 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 196 && BOOST_PP_ITERATION_FINISH_5 >= 196 # define BOOST_PP_ITERATION_5 196 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 197 && BOOST_PP_ITERATION_FINISH_5 >= 197 # define BOOST_PP_ITERATION_5 197 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 198 && BOOST_PP_ITERATION_FINISH_5 >= 198 # define BOOST_PP_ITERATION_5 198 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 199 && BOOST_PP_ITERATION_FINISH_5 >= 199 # define BOOST_PP_ITERATION_5 199 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 200 && BOOST_PP_ITERATION_FINISH_5 >= 200 # define BOOST_PP_ITERATION_5 200 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 201 && BOOST_PP_ITERATION_FINISH_5 >= 201 # define BOOST_PP_ITERATION_5 201 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 202 && BOOST_PP_ITERATION_FINISH_5 >= 202 # define BOOST_PP_ITERATION_5 202 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 203 && BOOST_PP_ITERATION_FINISH_5 >= 203 # define BOOST_PP_ITERATION_5 203 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 204 && BOOST_PP_ITERATION_FINISH_5 >= 204 # define BOOST_PP_ITERATION_5 204 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 205 && BOOST_PP_ITERATION_FINISH_5 >= 205 # define BOOST_PP_ITERATION_5 205 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 206 && BOOST_PP_ITERATION_FINISH_5 >= 206 # define BOOST_PP_ITERATION_5 206 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 207 && BOOST_PP_ITERATION_FINISH_5 >= 207 # define BOOST_PP_ITERATION_5 207 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 208 && BOOST_PP_ITERATION_FINISH_5 >= 208 # define BOOST_PP_ITERATION_5 208 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 209 && BOOST_PP_ITERATION_FINISH_5 >= 209 # define BOOST_PP_ITERATION_5 209 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 210 && BOOST_PP_ITERATION_FINISH_5 >= 210 # define BOOST_PP_ITERATION_5 210 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 211 && BOOST_PP_ITERATION_FINISH_5 >= 211 # define BOOST_PP_ITERATION_5 211 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 212 && BOOST_PP_ITERATION_FINISH_5 >= 212 # define BOOST_PP_ITERATION_5 212 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 213 && BOOST_PP_ITERATION_FINISH_5 >= 213 # define BOOST_PP_ITERATION_5 213 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 214 && BOOST_PP_ITERATION_FINISH_5 >= 214 # define BOOST_PP_ITERATION_5 214 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 215 && BOOST_PP_ITERATION_FINISH_5 >= 215 # define BOOST_PP_ITERATION_5 215 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 216 && BOOST_PP_ITERATION_FINISH_5 >= 216 # define BOOST_PP_ITERATION_5 216 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 217 && BOOST_PP_ITERATION_FINISH_5 >= 217 # define BOOST_PP_ITERATION_5 217 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 218 && BOOST_PP_ITERATION_FINISH_5 >= 218 # define BOOST_PP_ITERATION_5 218 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 219 && BOOST_PP_ITERATION_FINISH_5 >= 219 # define BOOST_PP_ITERATION_5 219 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 220 && BOOST_PP_ITERATION_FINISH_5 >= 220 # define BOOST_PP_ITERATION_5 220 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 221 && BOOST_PP_ITERATION_FINISH_5 >= 221 # define BOOST_PP_ITERATION_5 221 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 222 && BOOST_PP_ITERATION_FINISH_5 >= 222 # define BOOST_PP_ITERATION_5 222 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 223 && BOOST_PP_ITERATION_FINISH_5 >= 223 # define BOOST_PP_ITERATION_5 223 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 224 && BOOST_PP_ITERATION_FINISH_5 >= 224 # define BOOST_PP_ITERATION_5 224 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 225 && BOOST_PP_ITERATION_FINISH_5 >= 225 # define BOOST_PP_ITERATION_5 225 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 226 && BOOST_PP_ITERATION_FINISH_5 >= 226 # define BOOST_PP_ITERATION_5 226 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 227 && BOOST_PP_ITERATION_FINISH_5 >= 227 # define BOOST_PP_ITERATION_5 227 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 228 && BOOST_PP_ITERATION_FINISH_5 >= 228 # define BOOST_PP_ITERATION_5 228 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 229 && BOOST_PP_ITERATION_FINISH_5 >= 229 # define BOOST_PP_ITERATION_5 229 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 230 && BOOST_PP_ITERATION_FINISH_5 >= 230 # define BOOST_PP_ITERATION_5 230 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 231 && BOOST_PP_ITERATION_FINISH_5 >= 231 # define BOOST_PP_ITERATION_5 231 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 232 && BOOST_PP_ITERATION_FINISH_5 >= 232 # define BOOST_PP_ITERATION_5 232 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 233 && BOOST_PP_ITERATION_FINISH_5 >= 233 # define BOOST_PP_ITERATION_5 233 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 234 && BOOST_PP_ITERATION_FINISH_5 >= 234 # define BOOST_PP_ITERATION_5 234 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 235 && BOOST_PP_ITERATION_FINISH_5 >= 235 # define BOOST_PP_ITERATION_5 235 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 236 && BOOST_PP_ITERATION_FINISH_5 >= 236 # define BOOST_PP_ITERATION_5 236 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 237 && BOOST_PP_ITERATION_FINISH_5 >= 237 # define BOOST_PP_ITERATION_5 237 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 238 && BOOST_PP_ITERATION_FINISH_5 >= 238 # define BOOST_PP_ITERATION_5 238 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 239 && BOOST_PP_ITERATION_FINISH_5 >= 239 # define BOOST_PP_ITERATION_5 239 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 240 && BOOST_PP_ITERATION_FINISH_5 >= 240 # define BOOST_PP_ITERATION_5 240 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 241 && BOOST_PP_ITERATION_FINISH_5 >= 241 # define BOOST_PP_ITERATION_5 241 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 242 && BOOST_PP_ITERATION_FINISH_5 >= 242 # define BOOST_PP_ITERATION_5 242 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 243 && BOOST_PP_ITERATION_FINISH_5 >= 243 # define BOOST_PP_ITERATION_5 243 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 244 && BOOST_PP_ITERATION_FINISH_5 >= 244 # define BOOST_PP_ITERATION_5 244 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 245 && BOOST_PP_ITERATION_FINISH_5 >= 245 # define BOOST_PP_ITERATION_5 245 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 246 && BOOST_PP_ITERATION_FINISH_5 >= 246 # define BOOST_PP_ITERATION_5 246 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 247 && BOOST_PP_ITERATION_FINISH_5 >= 247 # define BOOST_PP_ITERATION_5 247 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 248 && BOOST_PP_ITERATION_FINISH_5 >= 248 # define BOOST_PP_ITERATION_5 248 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 249 && BOOST_PP_ITERATION_FINISH_5 >= 249 # define BOOST_PP_ITERATION_5 249 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 250 && BOOST_PP_ITERATION_FINISH_5 >= 250 # define BOOST_PP_ITERATION_5 250 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 251 && BOOST_PP_ITERATION_FINISH_5 >= 251 # define BOOST_PP_ITERATION_5 251 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 252 && BOOST_PP_ITERATION_FINISH_5 >= 252 # define BOOST_PP_ITERATION_5 252 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 253 && BOOST_PP_ITERATION_FINISH_5 >= 253 # define BOOST_PP_ITERATION_5 253 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 254 && BOOST_PP_ITERATION_FINISH_5 >= 254 # define BOOST_PP_ITERATION_5 254 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 255 && BOOST_PP_ITERATION_FINISH_5 >= 255 # define BOOST_PP_ITERATION_5 255 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_START_5 <= 256 && BOOST_PP_ITERATION_FINISH_5 >= 256 # define BOOST_PP_ITERATION_5 256 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # endif # # undef BOOST_PP_ITERATION_DEPTH # define BOOST_PP_ITERATION_DEPTH() 4 # # undef BOOST_PP_ITERATION_START_5 # undef BOOST_PP_ITERATION_FINISH_5 # undef BOOST_PP_FILENAME_5 # # undef BOOST_PP_ITERATION_FLAGS_5 # undef BOOST_PP_ITERATION_PARAMS_5 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/reverse1.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if BOOST_PP_ITERATION_FINISH_1 <= 256 && BOOST_PP_ITERATION_START_1 >= 256 # define BOOST_PP_ITERATION_1 256 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 255 && BOOST_PP_ITERATION_START_1 >= 255 # define BOOST_PP_ITERATION_1 255 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 254 && BOOST_PP_ITERATION_START_1 >= 254 # define BOOST_PP_ITERATION_1 254 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 253 && BOOST_PP_ITERATION_START_1 >= 253 # define BOOST_PP_ITERATION_1 253 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 252 && BOOST_PP_ITERATION_START_1 >= 252 # define BOOST_PP_ITERATION_1 252 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 251 && BOOST_PP_ITERATION_START_1 >= 251 # define BOOST_PP_ITERATION_1 251 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 250 && BOOST_PP_ITERATION_START_1 >= 250 # define BOOST_PP_ITERATION_1 250 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 249 && BOOST_PP_ITERATION_START_1 >= 249 # define BOOST_PP_ITERATION_1 249 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 248 && BOOST_PP_ITERATION_START_1 >= 248 # define BOOST_PP_ITERATION_1 248 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 247 && BOOST_PP_ITERATION_START_1 >= 247 # define BOOST_PP_ITERATION_1 247 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 246 && BOOST_PP_ITERATION_START_1 >= 246 # define BOOST_PP_ITERATION_1 246 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 245 && BOOST_PP_ITERATION_START_1 >= 245 # define BOOST_PP_ITERATION_1 245 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 244 && BOOST_PP_ITERATION_START_1 >= 244 # define BOOST_PP_ITERATION_1 244 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 243 && BOOST_PP_ITERATION_START_1 >= 243 # define BOOST_PP_ITERATION_1 243 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 242 && BOOST_PP_ITERATION_START_1 >= 242 # define BOOST_PP_ITERATION_1 242 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 241 && BOOST_PP_ITERATION_START_1 >= 241 # define BOOST_PP_ITERATION_1 241 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 240 && BOOST_PP_ITERATION_START_1 >= 240 # define BOOST_PP_ITERATION_1 240 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 239 && BOOST_PP_ITERATION_START_1 >= 239 # define BOOST_PP_ITERATION_1 239 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 238 && BOOST_PP_ITERATION_START_1 >= 238 # define BOOST_PP_ITERATION_1 238 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 237 && BOOST_PP_ITERATION_START_1 >= 237 # define BOOST_PP_ITERATION_1 237 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 236 && BOOST_PP_ITERATION_START_1 >= 236 # define BOOST_PP_ITERATION_1 236 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 235 && BOOST_PP_ITERATION_START_1 >= 235 # define BOOST_PP_ITERATION_1 235 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 234 && BOOST_PP_ITERATION_START_1 >= 234 # define BOOST_PP_ITERATION_1 234 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 233 && BOOST_PP_ITERATION_START_1 >= 233 # define BOOST_PP_ITERATION_1 233 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 232 && BOOST_PP_ITERATION_START_1 >= 232 # define BOOST_PP_ITERATION_1 232 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 231 && BOOST_PP_ITERATION_START_1 >= 231 # define BOOST_PP_ITERATION_1 231 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 230 && BOOST_PP_ITERATION_START_1 >= 230 # define BOOST_PP_ITERATION_1 230 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 229 && BOOST_PP_ITERATION_START_1 >= 229 # define BOOST_PP_ITERATION_1 229 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 228 && BOOST_PP_ITERATION_START_1 >= 228 # define BOOST_PP_ITERATION_1 228 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 227 && BOOST_PP_ITERATION_START_1 >= 227 # define BOOST_PP_ITERATION_1 227 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 226 && BOOST_PP_ITERATION_START_1 >= 226 # define BOOST_PP_ITERATION_1 226 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 225 && BOOST_PP_ITERATION_START_1 >= 225 # define BOOST_PP_ITERATION_1 225 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 224 && BOOST_PP_ITERATION_START_1 >= 224 # define BOOST_PP_ITERATION_1 224 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 223 && BOOST_PP_ITERATION_START_1 >= 223 # define BOOST_PP_ITERATION_1 223 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 222 && BOOST_PP_ITERATION_START_1 >= 222 # define BOOST_PP_ITERATION_1 222 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 221 && BOOST_PP_ITERATION_START_1 >= 221 # define BOOST_PP_ITERATION_1 221 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 220 && BOOST_PP_ITERATION_START_1 >= 220 # define BOOST_PP_ITERATION_1 220 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 219 && BOOST_PP_ITERATION_START_1 >= 219 # define BOOST_PP_ITERATION_1 219 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 218 && BOOST_PP_ITERATION_START_1 >= 218 # define BOOST_PP_ITERATION_1 218 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 217 && BOOST_PP_ITERATION_START_1 >= 217 # define BOOST_PP_ITERATION_1 217 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 216 && BOOST_PP_ITERATION_START_1 >= 216 # define BOOST_PP_ITERATION_1 216 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 215 && BOOST_PP_ITERATION_START_1 >= 215 # define BOOST_PP_ITERATION_1 215 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 214 && BOOST_PP_ITERATION_START_1 >= 214 # define BOOST_PP_ITERATION_1 214 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 213 && BOOST_PP_ITERATION_START_1 >= 213 # define BOOST_PP_ITERATION_1 213 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 212 && BOOST_PP_ITERATION_START_1 >= 212 # define BOOST_PP_ITERATION_1 212 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 211 && BOOST_PP_ITERATION_START_1 >= 211 # define BOOST_PP_ITERATION_1 211 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 210 && BOOST_PP_ITERATION_START_1 >= 210 # define BOOST_PP_ITERATION_1 210 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 209 && BOOST_PP_ITERATION_START_1 >= 209 # define BOOST_PP_ITERATION_1 209 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 208 && BOOST_PP_ITERATION_START_1 >= 208 # define BOOST_PP_ITERATION_1 208 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 207 && BOOST_PP_ITERATION_START_1 >= 207 # define BOOST_PP_ITERATION_1 207 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 206 && BOOST_PP_ITERATION_START_1 >= 206 # define BOOST_PP_ITERATION_1 206 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 205 && BOOST_PP_ITERATION_START_1 >= 205 # define BOOST_PP_ITERATION_1 205 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 204 && BOOST_PP_ITERATION_START_1 >= 204 # define BOOST_PP_ITERATION_1 204 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 203 && BOOST_PP_ITERATION_START_1 >= 203 # define BOOST_PP_ITERATION_1 203 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 202 && BOOST_PP_ITERATION_START_1 >= 202 # define BOOST_PP_ITERATION_1 202 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 201 && BOOST_PP_ITERATION_START_1 >= 201 # define BOOST_PP_ITERATION_1 201 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 200 && BOOST_PP_ITERATION_START_1 >= 200 # define BOOST_PP_ITERATION_1 200 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 199 && BOOST_PP_ITERATION_START_1 >= 199 # define BOOST_PP_ITERATION_1 199 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 198 && BOOST_PP_ITERATION_START_1 >= 198 # define BOOST_PP_ITERATION_1 198 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 197 && BOOST_PP_ITERATION_START_1 >= 197 # define BOOST_PP_ITERATION_1 197 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 196 && BOOST_PP_ITERATION_START_1 >= 196 # define BOOST_PP_ITERATION_1 196 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 195 && BOOST_PP_ITERATION_START_1 >= 195 # define BOOST_PP_ITERATION_1 195 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 194 && BOOST_PP_ITERATION_START_1 >= 194 # define BOOST_PP_ITERATION_1 194 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 193 && BOOST_PP_ITERATION_START_1 >= 193 # define BOOST_PP_ITERATION_1 193 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 192 && BOOST_PP_ITERATION_START_1 >= 192 # define BOOST_PP_ITERATION_1 192 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 191 && BOOST_PP_ITERATION_START_1 >= 191 # define BOOST_PP_ITERATION_1 191 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 190 && BOOST_PP_ITERATION_START_1 >= 190 # define BOOST_PP_ITERATION_1 190 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 189 && BOOST_PP_ITERATION_START_1 >= 189 # define BOOST_PP_ITERATION_1 189 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 188 && BOOST_PP_ITERATION_START_1 >= 188 # define BOOST_PP_ITERATION_1 188 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 187 && BOOST_PP_ITERATION_START_1 >= 187 # define BOOST_PP_ITERATION_1 187 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 186 && BOOST_PP_ITERATION_START_1 >= 186 # define BOOST_PP_ITERATION_1 186 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 185 && BOOST_PP_ITERATION_START_1 >= 185 # define BOOST_PP_ITERATION_1 185 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 184 && BOOST_PP_ITERATION_START_1 >= 184 # define BOOST_PP_ITERATION_1 184 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 183 && BOOST_PP_ITERATION_START_1 >= 183 # define BOOST_PP_ITERATION_1 183 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 182 && BOOST_PP_ITERATION_START_1 >= 182 # define BOOST_PP_ITERATION_1 182 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 181 && BOOST_PP_ITERATION_START_1 >= 181 # define BOOST_PP_ITERATION_1 181 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 180 && BOOST_PP_ITERATION_START_1 >= 180 # define BOOST_PP_ITERATION_1 180 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 179 && BOOST_PP_ITERATION_START_1 >= 179 # define BOOST_PP_ITERATION_1 179 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 178 && BOOST_PP_ITERATION_START_1 >= 178 # define BOOST_PP_ITERATION_1 178 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 177 && BOOST_PP_ITERATION_START_1 >= 177 # define BOOST_PP_ITERATION_1 177 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 176 && BOOST_PP_ITERATION_START_1 >= 176 # define BOOST_PP_ITERATION_1 176 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 175 && BOOST_PP_ITERATION_START_1 >= 175 # define BOOST_PP_ITERATION_1 175 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 174 && BOOST_PP_ITERATION_START_1 >= 174 # define BOOST_PP_ITERATION_1 174 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 173 && BOOST_PP_ITERATION_START_1 >= 173 # define BOOST_PP_ITERATION_1 173 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 172 && BOOST_PP_ITERATION_START_1 >= 172 # define BOOST_PP_ITERATION_1 172 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 171 && BOOST_PP_ITERATION_START_1 >= 171 # define BOOST_PP_ITERATION_1 171 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 170 && BOOST_PP_ITERATION_START_1 >= 170 # define BOOST_PP_ITERATION_1 170 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 169 && BOOST_PP_ITERATION_START_1 >= 169 # define BOOST_PP_ITERATION_1 169 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 168 && BOOST_PP_ITERATION_START_1 >= 168 # define BOOST_PP_ITERATION_1 168 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 167 && BOOST_PP_ITERATION_START_1 >= 167 # define BOOST_PP_ITERATION_1 167 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 166 && BOOST_PP_ITERATION_START_1 >= 166 # define BOOST_PP_ITERATION_1 166 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 165 && BOOST_PP_ITERATION_START_1 >= 165 # define BOOST_PP_ITERATION_1 165 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 164 && BOOST_PP_ITERATION_START_1 >= 164 # define BOOST_PP_ITERATION_1 164 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 163 && BOOST_PP_ITERATION_START_1 >= 163 # define BOOST_PP_ITERATION_1 163 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 162 && BOOST_PP_ITERATION_START_1 >= 162 # define BOOST_PP_ITERATION_1 162 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 161 && BOOST_PP_ITERATION_START_1 >= 161 # define BOOST_PP_ITERATION_1 161 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 160 && BOOST_PP_ITERATION_START_1 >= 160 # define BOOST_PP_ITERATION_1 160 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 159 && BOOST_PP_ITERATION_START_1 >= 159 # define BOOST_PP_ITERATION_1 159 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 158 && BOOST_PP_ITERATION_START_1 >= 158 # define BOOST_PP_ITERATION_1 158 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 157 && BOOST_PP_ITERATION_START_1 >= 157 # define BOOST_PP_ITERATION_1 157 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 156 && BOOST_PP_ITERATION_START_1 >= 156 # define BOOST_PP_ITERATION_1 156 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 155 && BOOST_PP_ITERATION_START_1 >= 155 # define BOOST_PP_ITERATION_1 155 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 154 && BOOST_PP_ITERATION_START_1 >= 154 # define BOOST_PP_ITERATION_1 154 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 153 && BOOST_PP_ITERATION_START_1 >= 153 # define BOOST_PP_ITERATION_1 153 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 152 && BOOST_PP_ITERATION_START_1 >= 152 # define BOOST_PP_ITERATION_1 152 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 151 && BOOST_PP_ITERATION_START_1 >= 151 # define BOOST_PP_ITERATION_1 151 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 150 && BOOST_PP_ITERATION_START_1 >= 150 # define BOOST_PP_ITERATION_1 150 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 149 && BOOST_PP_ITERATION_START_1 >= 149 # define BOOST_PP_ITERATION_1 149 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 148 && BOOST_PP_ITERATION_START_1 >= 148 # define BOOST_PP_ITERATION_1 148 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 147 && BOOST_PP_ITERATION_START_1 >= 147 # define BOOST_PP_ITERATION_1 147 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 146 && BOOST_PP_ITERATION_START_1 >= 146 # define BOOST_PP_ITERATION_1 146 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 145 && BOOST_PP_ITERATION_START_1 >= 145 # define BOOST_PP_ITERATION_1 145 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 144 && BOOST_PP_ITERATION_START_1 >= 144 # define BOOST_PP_ITERATION_1 144 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 143 && BOOST_PP_ITERATION_START_1 >= 143 # define BOOST_PP_ITERATION_1 143 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 142 && BOOST_PP_ITERATION_START_1 >= 142 # define BOOST_PP_ITERATION_1 142 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 141 && BOOST_PP_ITERATION_START_1 >= 141 # define BOOST_PP_ITERATION_1 141 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 140 && BOOST_PP_ITERATION_START_1 >= 140 # define BOOST_PP_ITERATION_1 140 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 139 && BOOST_PP_ITERATION_START_1 >= 139 # define BOOST_PP_ITERATION_1 139 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 138 && BOOST_PP_ITERATION_START_1 >= 138 # define BOOST_PP_ITERATION_1 138 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 137 && BOOST_PP_ITERATION_START_1 >= 137 # define BOOST_PP_ITERATION_1 137 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 136 && BOOST_PP_ITERATION_START_1 >= 136 # define BOOST_PP_ITERATION_1 136 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 135 && BOOST_PP_ITERATION_START_1 >= 135 # define BOOST_PP_ITERATION_1 135 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 134 && BOOST_PP_ITERATION_START_1 >= 134 # define BOOST_PP_ITERATION_1 134 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 133 && BOOST_PP_ITERATION_START_1 >= 133 # define BOOST_PP_ITERATION_1 133 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 132 && BOOST_PP_ITERATION_START_1 >= 132 # define BOOST_PP_ITERATION_1 132 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 131 && BOOST_PP_ITERATION_START_1 >= 131 # define BOOST_PP_ITERATION_1 131 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 130 && BOOST_PP_ITERATION_START_1 >= 130 # define BOOST_PP_ITERATION_1 130 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 129 && BOOST_PP_ITERATION_START_1 >= 129 # define BOOST_PP_ITERATION_1 129 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 128 && BOOST_PP_ITERATION_START_1 >= 128 # define BOOST_PP_ITERATION_1 128 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 127 && BOOST_PP_ITERATION_START_1 >= 127 # define BOOST_PP_ITERATION_1 127 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 126 && BOOST_PP_ITERATION_START_1 >= 126 # define BOOST_PP_ITERATION_1 126 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 125 && BOOST_PP_ITERATION_START_1 >= 125 # define BOOST_PP_ITERATION_1 125 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 124 && BOOST_PP_ITERATION_START_1 >= 124 # define BOOST_PP_ITERATION_1 124 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 123 && BOOST_PP_ITERATION_START_1 >= 123 # define BOOST_PP_ITERATION_1 123 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 122 && BOOST_PP_ITERATION_START_1 >= 122 # define BOOST_PP_ITERATION_1 122 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 121 && BOOST_PP_ITERATION_START_1 >= 121 # define BOOST_PP_ITERATION_1 121 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 120 && BOOST_PP_ITERATION_START_1 >= 120 # define BOOST_PP_ITERATION_1 120 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 119 && BOOST_PP_ITERATION_START_1 >= 119 # define BOOST_PP_ITERATION_1 119 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 118 && BOOST_PP_ITERATION_START_1 >= 118 # define BOOST_PP_ITERATION_1 118 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 117 && BOOST_PP_ITERATION_START_1 >= 117 # define BOOST_PP_ITERATION_1 117 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 116 && BOOST_PP_ITERATION_START_1 >= 116 # define BOOST_PP_ITERATION_1 116 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 115 && BOOST_PP_ITERATION_START_1 >= 115 # define BOOST_PP_ITERATION_1 115 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 114 && BOOST_PP_ITERATION_START_1 >= 114 # define BOOST_PP_ITERATION_1 114 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 113 && BOOST_PP_ITERATION_START_1 >= 113 # define BOOST_PP_ITERATION_1 113 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 112 && BOOST_PP_ITERATION_START_1 >= 112 # define BOOST_PP_ITERATION_1 112 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 111 && BOOST_PP_ITERATION_START_1 >= 111 # define BOOST_PP_ITERATION_1 111 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 110 && BOOST_PP_ITERATION_START_1 >= 110 # define BOOST_PP_ITERATION_1 110 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 109 && BOOST_PP_ITERATION_START_1 >= 109 # define BOOST_PP_ITERATION_1 109 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 108 && BOOST_PP_ITERATION_START_1 >= 108 # define BOOST_PP_ITERATION_1 108 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 107 && BOOST_PP_ITERATION_START_1 >= 107 # define BOOST_PP_ITERATION_1 107 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 106 && BOOST_PP_ITERATION_START_1 >= 106 # define BOOST_PP_ITERATION_1 106 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 105 && BOOST_PP_ITERATION_START_1 >= 105 # define BOOST_PP_ITERATION_1 105 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 104 && BOOST_PP_ITERATION_START_1 >= 104 # define BOOST_PP_ITERATION_1 104 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 103 && BOOST_PP_ITERATION_START_1 >= 103 # define BOOST_PP_ITERATION_1 103 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 102 && BOOST_PP_ITERATION_START_1 >= 102 # define BOOST_PP_ITERATION_1 102 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 101 && BOOST_PP_ITERATION_START_1 >= 101 # define BOOST_PP_ITERATION_1 101 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 100 && BOOST_PP_ITERATION_START_1 >= 100 # define BOOST_PP_ITERATION_1 100 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 99 && BOOST_PP_ITERATION_START_1 >= 99 # define BOOST_PP_ITERATION_1 99 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 98 && BOOST_PP_ITERATION_START_1 >= 98 # define BOOST_PP_ITERATION_1 98 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 97 && BOOST_PP_ITERATION_START_1 >= 97 # define BOOST_PP_ITERATION_1 97 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 96 && BOOST_PP_ITERATION_START_1 >= 96 # define BOOST_PP_ITERATION_1 96 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 95 && BOOST_PP_ITERATION_START_1 >= 95 # define BOOST_PP_ITERATION_1 95 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 94 && BOOST_PP_ITERATION_START_1 >= 94 # define BOOST_PP_ITERATION_1 94 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 93 && BOOST_PP_ITERATION_START_1 >= 93 # define BOOST_PP_ITERATION_1 93 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 92 && BOOST_PP_ITERATION_START_1 >= 92 # define BOOST_PP_ITERATION_1 92 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 91 && BOOST_PP_ITERATION_START_1 >= 91 # define BOOST_PP_ITERATION_1 91 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 90 && BOOST_PP_ITERATION_START_1 >= 90 # define BOOST_PP_ITERATION_1 90 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 89 && BOOST_PP_ITERATION_START_1 >= 89 # define BOOST_PP_ITERATION_1 89 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 88 && BOOST_PP_ITERATION_START_1 >= 88 # define BOOST_PP_ITERATION_1 88 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 87 && BOOST_PP_ITERATION_START_1 >= 87 # define BOOST_PP_ITERATION_1 87 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 86 && BOOST_PP_ITERATION_START_1 >= 86 # define BOOST_PP_ITERATION_1 86 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 85 && BOOST_PP_ITERATION_START_1 >= 85 # define BOOST_PP_ITERATION_1 85 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 84 && BOOST_PP_ITERATION_START_1 >= 84 # define BOOST_PP_ITERATION_1 84 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 83 && BOOST_PP_ITERATION_START_1 >= 83 # define BOOST_PP_ITERATION_1 83 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 82 && BOOST_PP_ITERATION_START_1 >= 82 # define BOOST_PP_ITERATION_1 82 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 81 && BOOST_PP_ITERATION_START_1 >= 81 # define BOOST_PP_ITERATION_1 81 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 80 && BOOST_PP_ITERATION_START_1 >= 80 # define BOOST_PP_ITERATION_1 80 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 79 && BOOST_PP_ITERATION_START_1 >= 79 # define BOOST_PP_ITERATION_1 79 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 78 && BOOST_PP_ITERATION_START_1 >= 78 # define BOOST_PP_ITERATION_1 78 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 77 && BOOST_PP_ITERATION_START_1 >= 77 # define BOOST_PP_ITERATION_1 77 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 76 && BOOST_PP_ITERATION_START_1 >= 76 # define BOOST_PP_ITERATION_1 76 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 75 && BOOST_PP_ITERATION_START_1 >= 75 # define BOOST_PP_ITERATION_1 75 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 74 && BOOST_PP_ITERATION_START_1 >= 74 # define BOOST_PP_ITERATION_1 74 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 73 && BOOST_PP_ITERATION_START_1 >= 73 # define BOOST_PP_ITERATION_1 73 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 72 && BOOST_PP_ITERATION_START_1 >= 72 # define BOOST_PP_ITERATION_1 72 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 71 && BOOST_PP_ITERATION_START_1 >= 71 # define BOOST_PP_ITERATION_1 71 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 70 && BOOST_PP_ITERATION_START_1 >= 70 # define BOOST_PP_ITERATION_1 70 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 69 && BOOST_PP_ITERATION_START_1 >= 69 # define BOOST_PP_ITERATION_1 69 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 68 && BOOST_PP_ITERATION_START_1 >= 68 # define BOOST_PP_ITERATION_1 68 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 67 && BOOST_PP_ITERATION_START_1 >= 67 # define BOOST_PP_ITERATION_1 67 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 66 && BOOST_PP_ITERATION_START_1 >= 66 # define BOOST_PP_ITERATION_1 66 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 65 && BOOST_PP_ITERATION_START_1 >= 65 # define BOOST_PP_ITERATION_1 65 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 64 && BOOST_PP_ITERATION_START_1 >= 64 # define BOOST_PP_ITERATION_1 64 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 63 && BOOST_PP_ITERATION_START_1 >= 63 # define BOOST_PP_ITERATION_1 63 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 62 && BOOST_PP_ITERATION_START_1 >= 62 # define BOOST_PP_ITERATION_1 62 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 61 && BOOST_PP_ITERATION_START_1 >= 61 # define BOOST_PP_ITERATION_1 61 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 60 && BOOST_PP_ITERATION_START_1 >= 60 # define BOOST_PP_ITERATION_1 60 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 59 && BOOST_PP_ITERATION_START_1 >= 59 # define BOOST_PP_ITERATION_1 59 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 58 && BOOST_PP_ITERATION_START_1 >= 58 # define BOOST_PP_ITERATION_1 58 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 57 && BOOST_PP_ITERATION_START_1 >= 57 # define BOOST_PP_ITERATION_1 57 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 56 && BOOST_PP_ITERATION_START_1 >= 56 # define BOOST_PP_ITERATION_1 56 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 55 && BOOST_PP_ITERATION_START_1 >= 55 # define BOOST_PP_ITERATION_1 55 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 54 && BOOST_PP_ITERATION_START_1 >= 54 # define BOOST_PP_ITERATION_1 54 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 53 && BOOST_PP_ITERATION_START_1 >= 53 # define BOOST_PP_ITERATION_1 53 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 52 && BOOST_PP_ITERATION_START_1 >= 52 # define BOOST_PP_ITERATION_1 52 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 51 && BOOST_PP_ITERATION_START_1 >= 51 # define BOOST_PP_ITERATION_1 51 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 50 && BOOST_PP_ITERATION_START_1 >= 50 # define BOOST_PP_ITERATION_1 50 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 49 && BOOST_PP_ITERATION_START_1 >= 49 # define BOOST_PP_ITERATION_1 49 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 48 && BOOST_PP_ITERATION_START_1 >= 48 # define BOOST_PP_ITERATION_1 48 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 47 && BOOST_PP_ITERATION_START_1 >= 47 # define BOOST_PP_ITERATION_1 47 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 46 && BOOST_PP_ITERATION_START_1 >= 46 # define BOOST_PP_ITERATION_1 46 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 45 && BOOST_PP_ITERATION_START_1 >= 45 # define BOOST_PP_ITERATION_1 45 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 44 && BOOST_PP_ITERATION_START_1 >= 44 # define BOOST_PP_ITERATION_1 44 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 43 && BOOST_PP_ITERATION_START_1 >= 43 # define BOOST_PP_ITERATION_1 43 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 42 && BOOST_PP_ITERATION_START_1 >= 42 # define BOOST_PP_ITERATION_1 42 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 41 && BOOST_PP_ITERATION_START_1 >= 41 # define BOOST_PP_ITERATION_1 41 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 40 && BOOST_PP_ITERATION_START_1 >= 40 # define BOOST_PP_ITERATION_1 40 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 39 && BOOST_PP_ITERATION_START_1 >= 39 # define BOOST_PP_ITERATION_1 39 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 38 && BOOST_PP_ITERATION_START_1 >= 38 # define BOOST_PP_ITERATION_1 38 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 37 && BOOST_PP_ITERATION_START_1 >= 37 # define BOOST_PP_ITERATION_1 37 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 36 && BOOST_PP_ITERATION_START_1 >= 36 # define BOOST_PP_ITERATION_1 36 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 35 && BOOST_PP_ITERATION_START_1 >= 35 # define BOOST_PP_ITERATION_1 35 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 34 && BOOST_PP_ITERATION_START_1 >= 34 # define BOOST_PP_ITERATION_1 34 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 33 && BOOST_PP_ITERATION_START_1 >= 33 # define BOOST_PP_ITERATION_1 33 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 32 && BOOST_PP_ITERATION_START_1 >= 32 # define BOOST_PP_ITERATION_1 32 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 31 && BOOST_PP_ITERATION_START_1 >= 31 # define BOOST_PP_ITERATION_1 31 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 30 && BOOST_PP_ITERATION_START_1 >= 30 # define BOOST_PP_ITERATION_1 30 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 29 && BOOST_PP_ITERATION_START_1 >= 29 # define BOOST_PP_ITERATION_1 29 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 28 && BOOST_PP_ITERATION_START_1 >= 28 # define BOOST_PP_ITERATION_1 28 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 27 && BOOST_PP_ITERATION_START_1 >= 27 # define BOOST_PP_ITERATION_1 27 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 26 && BOOST_PP_ITERATION_START_1 >= 26 # define BOOST_PP_ITERATION_1 26 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 25 && BOOST_PP_ITERATION_START_1 >= 25 # define BOOST_PP_ITERATION_1 25 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 24 && BOOST_PP_ITERATION_START_1 >= 24 # define BOOST_PP_ITERATION_1 24 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 23 && BOOST_PP_ITERATION_START_1 >= 23 # define BOOST_PP_ITERATION_1 23 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 22 && BOOST_PP_ITERATION_START_1 >= 22 # define BOOST_PP_ITERATION_1 22 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 21 && BOOST_PP_ITERATION_START_1 >= 21 # define BOOST_PP_ITERATION_1 21 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 20 && BOOST_PP_ITERATION_START_1 >= 20 # define BOOST_PP_ITERATION_1 20 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 19 && BOOST_PP_ITERATION_START_1 >= 19 # define BOOST_PP_ITERATION_1 19 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 18 && BOOST_PP_ITERATION_START_1 >= 18 # define BOOST_PP_ITERATION_1 18 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 17 && BOOST_PP_ITERATION_START_1 >= 17 # define BOOST_PP_ITERATION_1 17 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 16 && BOOST_PP_ITERATION_START_1 >= 16 # define BOOST_PP_ITERATION_1 16 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 15 && BOOST_PP_ITERATION_START_1 >= 15 # define BOOST_PP_ITERATION_1 15 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 14 && BOOST_PP_ITERATION_START_1 >= 14 # define BOOST_PP_ITERATION_1 14 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 13 && BOOST_PP_ITERATION_START_1 >= 13 # define BOOST_PP_ITERATION_1 13 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 12 && BOOST_PP_ITERATION_START_1 >= 12 # define BOOST_PP_ITERATION_1 12 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 11 && BOOST_PP_ITERATION_START_1 >= 11 # define BOOST_PP_ITERATION_1 11 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 10 && BOOST_PP_ITERATION_START_1 >= 10 # define BOOST_PP_ITERATION_1 10 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 9 && BOOST_PP_ITERATION_START_1 >= 9 # define BOOST_PP_ITERATION_1 9 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 8 && BOOST_PP_ITERATION_START_1 >= 8 # define BOOST_PP_ITERATION_1 8 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 7 && BOOST_PP_ITERATION_START_1 >= 7 # define BOOST_PP_ITERATION_1 7 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 6 && BOOST_PP_ITERATION_START_1 >= 6 # define BOOST_PP_ITERATION_1 6 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 5 && BOOST_PP_ITERATION_START_1 >= 5 # define BOOST_PP_ITERATION_1 5 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 4 && BOOST_PP_ITERATION_START_1 >= 4 # define BOOST_PP_ITERATION_1 4 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 3 && BOOST_PP_ITERATION_START_1 >= 3 # define BOOST_PP_ITERATION_1 3 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 2 && BOOST_PP_ITERATION_START_1 >= 2 # define BOOST_PP_ITERATION_1 2 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 1 && BOOST_PP_ITERATION_START_1 >= 1 # define BOOST_PP_ITERATION_1 1 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif # if BOOST_PP_ITERATION_FINISH_1 <= 0 && BOOST_PP_ITERATION_START_1 >= 0 # define BOOST_PP_ITERATION_1 0 # include BOOST_PP_FILENAME_1 # undef BOOST_PP_ITERATION_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/reverse2.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if BOOST_PP_ITERATION_FINISH_2 <= 256 && BOOST_PP_ITERATION_START_2 >= 256 # define BOOST_PP_ITERATION_2 256 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 255 && BOOST_PP_ITERATION_START_2 >= 255 # define BOOST_PP_ITERATION_2 255 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 254 && BOOST_PP_ITERATION_START_2 >= 254 # define BOOST_PP_ITERATION_2 254 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 253 && BOOST_PP_ITERATION_START_2 >= 253 # define BOOST_PP_ITERATION_2 253 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 252 && BOOST_PP_ITERATION_START_2 >= 252 # define BOOST_PP_ITERATION_2 252 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 251 && BOOST_PP_ITERATION_START_2 >= 251 # define BOOST_PP_ITERATION_2 251 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 250 && BOOST_PP_ITERATION_START_2 >= 250 # define BOOST_PP_ITERATION_2 250 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 249 && BOOST_PP_ITERATION_START_2 >= 249 # define BOOST_PP_ITERATION_2 249 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 248 && BOOST_PP_ITERATION_START_2 >= 248 # define BOOST_PP_ITERATION_2 248 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 247 && BOOST_PP_ITERATION_START_2 >= 247 # define BOOST_PP_ITERATION_2 247 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 246 && BOOST_PP_ITERATION_START_2 >= 246 # define BOOST_PP_ITERATION_2 246 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 245 && BOOST_PP_ITERATION_START_2 >= 245 # define BOOST_PP_ITERATION_2 245 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 244 && BOOST_PP_ITERATION_START_2 >= 244 # define BOOST_PP_ITERATION_2 244 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 243 && BOOST_PP_ITERATION_START_2 >= 243 # define BOOST_PP_ITERATION_2 243 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 242 && BOOST_PP_ITERATION_START_2 >= 242 # define BOOST_PP_ITERATION_2 242 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 241 && BOOST_PP_ITERATION_START_2 >= 241 # define BOOST_PP_ITERATION_2 241 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 240 && BOOST_PP_ITERATION_START_2 >= 240 # define BOOST_PP_ITERATION_2 240 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 239 && BOOST_PP_ITERATION_START_2 >= 239 # define BOOST_PP_ITERATION_2 239 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 238 && BOOST_PP_ITERATION_START_2 >= 238 # define BOOST_PP_ITERATION_2 238 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 237 && BOOST_PP_ITERATION_START_2 >= 237 # define BOOST_PP_ITERATION_2 237 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 236 && BOOST_PP_ITERATION_START_2 >= 236 # define BOOST_PP_ITERATION_2 236 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 235 && BOOST_PP_ITERATION_START_2 >= 235 # define BOOST_PP_ITERATION_2 235 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 234 && BOOST_PP_ITERATION_START_2 >= 234 # define BOOST_PP_ITERATION_2 234 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 233 && BOOST_PP_ITERATION_START_2 >= 233 # define BOOST_PP_ITERATION_2 233 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 232 && BOOST_PP_ITERATION_START_2 >= 232 # define BOOST_PP_ITERATION_2 232 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 231 && BOOST_PP_ITERATION_START_2 >= 231 # define BOOST_PP_ITERATION_2 231 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 230 && BOOST_PP_ITERATION_START_2 >= 230 # define BOOST_PP_ITERATION_2 230 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 229 && BOOST_PP_ITERATION_START_2 >= 229 # define BOOST_PP_ITERATION_2 229 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 228 && BOOST_PP_ITERATION_START_2 >= 228 # define BOOST_PP_ITERATION_2 228 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 227 && BOOST_PP_ITERATION_START_2 >= 227 # define BOOST_PP_ITERATION_2 227 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 226 && BOOST_PP_ITERATION_START_2 >= 226 # define BOOST_PP_ITERATION_2 226 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 225 && BOOST_PP_ITERATION_START_2 >= 225 # define BOOST_PP_ITERATION_2 225 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 224 && BOOST_PP_ITERATION_START_2 >= 224 # define BOOST_PP_ITERATION_2 224 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 223 && BOOST_PP_ITERATION_START_2 >= 223 # define BOOST_PP_ITERATION_2 223 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 222 && BOOST_PP_ITERATION_START_2 >= 222 # define BOOST_PP_ITERATION_2 222 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 221 && BOOST_PP_ITERATION_START_2 >= 221 # define BOOST_PP_ITERATION_2 221 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 220 && BOOST_PP_ITERATION_START_2 >= 220 # define BOOST_PP_ITERATION_2 220 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 219 && BOOST_PP_ITERATION_START_2 >= 219 # define BOOST_PP_ITERATION_2 219 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 218 && BOOST_PP_ITERATION_START_2 >= 218 # define BOOST_PP_ITERATION_2 218 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 217 && BOOST_PP_ITERATION_START_2 >= 217 # define BOOST_PP_ITERATION_2 217 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 216 && BOOST_PP_ITERATION_START_2 >= 216 # define BOOST_PP_ITERATION_2 216 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 215 && BOOST_PP_ITERATION_START_2 >= 215 # define BOOST_PP_ITERATION_2 215 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 214 && BOOST_PP_ITERATION_START_2 >= 214 # define BOOST_PP_ITERATION_2 214 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 213 && BOOST_PP_ITERATION_START_2 >= 213 # define BOOST_PP_ITERATION_2 213 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 212 && BOOST_PP_ITERATION_START_2 >= 212 # define BOOST_PP_ITERATION_2 212 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 211 && BOOST_PP_ITERATION_START_2 >= 211 # define BOOST_PP_ITERATION_2 211 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 210 && BOOST_PP_ITERATION_START_2 >= 210 # define BOOST_PP_ITERATION_2 210 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 209 && BOOST_PP_ITERATION_START_2 >= 209 # define BOOST_PP_ITERATION_2 209 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 208 && BOOST_PP_ITERATION_START_2 >= 208 # define BOOST_PP_ITERATION_2 208 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 207 && BOOST_PP_ITERATION_START_2 >= 207 # define BOOST_PP_ITERATION_2 207 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 206 && BOOST_PP_ITERATION_START_2 >= 206 # define BOOST_PP_ITERATION_2 206 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 205 && BOOST_PP_ITERATION_START_2 >= 205 # define BOOST_PP_ITERATION_2 205 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 204 && BOOST_PP_ITERATION_START_2 >= 204 # define BOOST_PP_ITERATION_2 204 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 203 && BOOST_PP_ITERATION_START_2 >= 203 # define BOOST_PP_ITERATION_2 203 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 202 && BOOST_PP_ITERATION_START_2 >= 202 # define BOOST_PP_ITERATION_2 202 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 201 && BOOST_PP_ITERATION_START_2 >= 201 # define BOOST_PP_ITERATION_2 201 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 200 && BOOST_PP_ITERATION_START_2 >= 200 # define BOOST_PP_ITERATION_2 200 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 199 && BOOST_PP_ITERATION_START_2 >= 199 # define BOOST_PP_ITERATION_2 199 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 198 && BOOST_PP_ITERATION_START_2 >= 198 # define BOOST_PP_ITERATION_2 198 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 197 && BOOST_PP_ITERATION_START_2 >= 197 # define BOOST_PP_ITERATION_2 197 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 196 && BOOST_PP_ITERATION_START_2 >= 196 # define BOOST_PP_ITERATION_2 196 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 195 && BOOST_PP_ITERATION_START_2 >= 195 # define BOOST_PP_ITERATION_2 195 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 194 && BOOST_PP_ITERATION_START_2 >= 194 # define BOOST_PP_ITERATION_2 194 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 193 && BOOST_PP_ITERATION_START_2 >= 193 # define BOOST_PP_ITERATION_2 193 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 192 && BOOST_PP_ITERATION_START_2 >= 192 # define BOOST_PP_ITERATION_2 192 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 191 && BOOST_PP_ITERATION_START_2 >= 191 # define BOOST_PP_ITERATION_2 191 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 190 && BOOST_PP_ITERATION_START_2 >= 190 # define BOOST_PP_ITERATION_2 190 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 189 && BOOST_PP_ITERATION_START_2 >= 189 # define BOOST_PP_ITERATION_2 189 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 188 && BOOST_PP_ITERATION_START_2 >= 188 # define BOOST_PP_ITERATION_2 188 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 187 && BOOST_PP_ITERATION_START_2 >= 187 # define BOOST_PP_ITERATION_2 187 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 186 && BOOST_PP_ITERATION_START_2 >= 186 # define BOOST_PP_ITERATION_2 186 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 185 && BOOST_PP_ITERATION_START_2 >= 185 # define BOOST_PP_ITERATION_2 185 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 184 && BOOST_PP_ITERATION_START_2 >= 184 # define BOOST_PP_ITERATION_2 184 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 183 && BOOST_PP_ITERATION_START_2 >= 183 # define BOOST_PP_ITERATION_2 183 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 182 && BOOST_PP_ITERATION_START_2 >= 182 # define BOOST_PP_ITERATION_2 182 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 181 && BOOST_PP_ITERATION_START_2 >= 181 # define BOOST_PP_ITERATION_2 181 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 180 && BOOST_PP_ITERATION_START_2 >= 180 # define BOOST_PP_ITERATION_2 180 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 179 && BOOST_PP_ITERATION_START_2 >= 179 # define BOOST_PP_ITERATION_2 179 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 178 && BOOST_PP_ITERATION_START_2 >= 178 # define BOOST_PP_ITERATION_2 178 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 177 && BOOST_PP_ITERATION_START_2 >= 177 # define BOOST_PP_ITERATION_2 177 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 176 && BOOST_PP_ITERATION_START_2 >= 176 # define BOOST_PP_ITERATION_2 176 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 175 && BOOST_PP_ITERATION_START_2 >= 175 # define BOOST_PP_ITERATION_2 175 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 174 && BOOST_PP_ITERATION_START_2 >= 174 # define BOOST_PP_ITERATION_2 174 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 173 && BOOST_PP_ITERATION_START_2 >= 173 # define BOOST_PP_ITERATION_2 173 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 172 && BOOST_PP_ITERATION_START_2 >= 172 # define BOOST_PP_ITERATION_2 172 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 171 && BOOST_PP_ITERATION_START_2 >= 171 # define BOOST_PP_ITERATION_2 171 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 170 && BOOST_PP_ITERATION_START_2 >= 170 # define BOOST_PP_ITERATION_2 170 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 169 && BOOST_PP_ITERATION_START_2 >= 169 # define BOOST_PP_ITERATION_2 169 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 168 && BOOST_PP_ITERATION_START_2 >= 168 # define BOOST_PP_ITERATION_2 168 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 167 && BOOST_PP_ITERATION_START_2 >= 167 # define BOOST_PP_ITERATION_2 167 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 166 && BOOST_PP_ITERATION_START_2 >= 166 # define BOOST_PP_ITERATION_2 166 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 165 && BOOST_PP_ITERATION_START_2 >= 165 # define BOOST_PP_ITERATION_2 165 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 164 && BOOST_PP_ITERATION_START_2 >= 164 # define BOOST_PP_ITERATION_2 164 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 163 && BOOST_PP_ITERATION_START_2 >= 163 # define BOOST_PP_ITERATION_2 163 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 162 && BOOST_PP_ITERATION_START_2 >= 162 # define BOOST_PP_ITERATION_2 162 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 161 && BOOST_PP_ITERATION_START_2 >= 161 # define BOOST_PP_ITERATION_2 161 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 160 && BOOST_PP_ITERATION_START_2 >= 160 # define BOOST_PP_ITERATION_2 160 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 159 && BOOST_PP_ITERATION_START_2 >= 159 # define BOOST_PP_ITERATION_2 159 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 158 && BOOST_PP_ITERATION_START_2 >= 158 # define BOOST_PP_ITERATION_2 158 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 157 && BOOST_PP_ITERATION_START_2 >= 157 # define BOOST_PP_ITERATION_2 157 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 156 && BOOST_PP_ITERATION_START_2 >= 156 # define BOOST_PP_ITERATION_2 156 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 155 && BOOST_PP_ITERATION_START_2 >= 155 # define BOOST_PP_ITERATION_2 155 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 154 && BOOST_PP_ITERATION_START_2 >= 154 # define BOOST_PP_ITERATION_2 154 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 153 && BOOST_PP_ITERATION_START_2 >= 153 # define BOOST_PP_ITERATION_2 153 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 152 && BOOST_PP_ITERATION_START_2 >= 152 # define BOOST_PP_ITERATION_2 152 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 151 && BOOST_PP_ITERATION_START_2 >= 151 # define BOOST_PP_ITERATION_2 151 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 150 && BOOST_PP_ITERATION_START_2 >= 150 # define BOOST_PP_ITERATION_2 150 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 149 && BOOST_PP_ITERATION_START_2 >= 149 # define BOOST_PP_ITERATION_2 149 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 148 && BOOST_PP_ITERATION_START_2 >= 148 # define BOOST_PP_ITERATION_2 148 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 147 && BOOST_PP_ITERATION_START_2 >= 147 # define BOOST_PP_ITERATION_2 147 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 146 && BOOST_PP_ITERATION_START_2 >= 146 # define BOOST_PP_ITERATION_2 146 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 145 && BOOST_PP_ITERATION_START_2 >= 145 # define BOOST_PP_ITERATION_2 145 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 144 && BOOST_PP_ITERATION_START_2 >= 144 # define BOOST_PP_ITERATION_2 144 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 143 && BOOST_PP_ITERATION_START_2 >= 143 # define BOOST_PP_ITERATION_2 143 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 142 && BOOST_PP_ITERATION_START_2 >= 142 # define BOOST_PP_ITERATION_2 142 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 141 && BOOST_PP_ITERATION_START_2 >= 141 # define BOOST_PP_ITERATION_2 141 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 140 && BOOST_PP_ITERATION_START_2 >= 140 # define BOOST_PP_ITERATION_2 140 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 139 && BOOST_PP_ITERATION_START_2 >= 139 # define BOOST_PP_ITERATION_2 139 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 138 && BOOST_PP_ITERATION_START_2 >= 138 # define BOOST_PP_ITERATION_2 138 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 137 && BOOST_PP_ITERATION_START_2 >= 137 # define BOOST_PP_ITERATION_2 137 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 136 && BOOST_PP_ITERATION_START_2 >= 136 # define BOOST_PP_ITERATION_2 136 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 135 && BOOST_PP_ITERATION_START_2 >= 135 # define BOOST_PP_ITERATION_2 135 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 134 && BOOST_PP_ITERATION_START_2 >= 134 # define BOOST_PP_ITERATION_2 134 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 133 && BOOST_PP_ITERATION_START_2 >= 133 # define BOOST_PP_ITERATION_2 133 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 132 && BOOST_PP_ITERATION_START_2 >= 132 # define BOOST_PP_ITERATION_2 132 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 131 && BOOST_PP_ITERATION_START_2 >= 131 # define BOOST_PP_ITERATION_2 131 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 130 && BOOST_PP_ITERATION_START_2 >= 130 # define BOOST_PP_ITERATION_2 130 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 129 && BOOST_PP_ITERATION_START_2 >= 129 # define BOOST_PP_ITERATION_2 129 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 128 && BOOST_PP_ITERATION_START_2 >= 128 # define BOOST_PP_ITERATION_2 128 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 127 && BOOST_PP_ITERATION_START_2 >= 127 # define BOOST_PP_ITERATION_2 127 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 126 && BOOST_PP_ITERATION_START_2 >= 126 # define BOOST_PP_ITERATION_2 126 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 125 && BOOST_PP_ITERATION_START_2 >= 125 # define BOOST_PP_ITERATION_2 125 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 124 && BOOST_PP_ITERATION_START_2 >= 124 # define BOOST_PP_ITERATION_2 124 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 123 && BOOST_PP_ITERATION_START_2 >= 123 # define BOOST_PP_ITERATION_2 123 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 122 && BOOST_PP_ITERATION_START_2 >= 122 # define BOOST_PP_ITERATION_2 122 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 121 && BOOST_PP_ITERATION_START_2 >= 121 # define BOOST_PP_ITERATION_2 121 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 120 && BOOST_PP_ITERATION_START_2 >= 120 # define BOOST_PP_ITERATION_2 120 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 119 && BOOST_PP_ITERATION_START_2 >= 119 # define BOOST_PP_ITERATION_2 119 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 118 && BOOST_PP_ITERATION_START_2 >= 118 # define BOOST_PP_ITERATION_2 118 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 117 && BOOST_PP_ITERATION_START_2 >= 117 # define BOOST_PP_ITERATION_2 117 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 116 && BOOST_PP_ITERATION_START_2 >= 116 # define BOOST_PP_ITERATION_2 116 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 115 && BOOST_PP_ITERATION_START_2 >= 115 # define BOOST_PP_ITERATION_2 115 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 114 && BOOST_PP_ITERATION_START_2 >= 114 # define BOOST_PP_ITERATION_2 114 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 113 && BOOST_PP_ITERATION_START_2 >= 113 # define BOOST_PP_ITERATION_2 113 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 112 && BOOST_PP_ITERATION_START_2 >= 112 # define BOOST_PP_ITERATION_2 112 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 111 && BOOST_PP_ITERATION_START_2 >= 111 # define BOOST_PP_ITERATION_2 111 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 110 && BOOST_PP_ITERATION_START_2 >= 110 # define BOOST_PP_ITERATION_2 110 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 109 && BOOST_PP_ITERATION_START_2 >= 109 # define BOOST_PP_ITERATION_2 109 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 108 && BOOST_PP_ITERATION_START_2 >= 108 # define BOOST_PP_ITERATION_2 108 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 107 && BOOST_PP_ITERATION_START_2 >= 107 # define BOOST_PP_ITERATION_2 107 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 106 && BOOST_PP_ITERATION_START_2 >= 106 # define BOOST_PP_ITERATION_2 106 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 105 && BOOST_PP_ITERATION_START_2 >= 105 # define BOOST_PP_ITERATION_2 105 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 104 && BOOST_PP_ITERATION_START_2 >= 104 # define BOOST_PP_ITERATION_2 104 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 103 && BOOST_PP_ITERATION_START_2 >= 103 # define BOOST_PP_ITERATION_2 103 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 102 && BOOST_PP_ITERATION_START_2 >= 102 # define BOOST_PP_ITERATION_2 102 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 101 && BOOST_PP_ITERATION_START_2 >= 101 # define BOOST_PP_ITERATION_2 101 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 100 && BOOST_PP_ITERATION_START_2 >= 100 # define BOOST_PP_ITERATION_2 100 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 99 && BOOST_PP_ITERATION_START_2 >= 99 # define BOOST_PP_ITERATION_2 99 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 98 && BOOST_PP_ITERATION_START_2 >= 98 # define BOOST_PP_ITERATION_2 98 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 97 && BOOST_PP_ITERATION_START_2 >= 97 # define BOOST_PP_ITERATION_2 97 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 96 && BOOST_PP_ITERATION_START_2 >= 96 # define BOOST_PP_ITERATION_2 96 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 95 && BOOST_PP_ITERATION_START_2 >= 95 # define BOOST_PP_ITERATION_2 95 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 94 && BOOST_PP_ITERATION_START_2 >= 94 # define BOOST_PP_ITERATION_2 94 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 93 && BOOST_PP_ITERATION_START_2 >= 93 # define BOOST_PP_ITERATION_2 93 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 92 && BOOST_PP_ITERATION_START_2 >= 92 # define BOOST_PP_ITERATION_2 92 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 91 && BOOST_PP_ITERATION_START_2 >= 91 # define BOOST_PP_ITERATION_2 91 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 90 && BOOST_PP_ITERATION_START_2 >= 90 # define BOOST_PP_ITERATION_2 90 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 89 && BOOST_PP_ITERATION_START_2 >= 89 # define BOOST_PP_ITERATION_2 89 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 88 && BOOST_PP_ITERATION_START_2 >= 88 # define BOOST_PP_ITERATION_2 88 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 87 && BOOST_PP_ITERATION_START_2 >= 87 # define BOOST_PP_ITERATION_2 87 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 86 && BOOST_PP_ITERATION_START_2 >= 86 # define BOOST_PP_ITERATION_2 86 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 85 && BOOST_PP_ITERATION_START_2 >= 85 # define BOOST_PP_ITERATION_2 85 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 84 && BOOST_PP_ITERATION_START_2 >= 84 # define BOOST_PP_ITERATION_2 84 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 83 && BOOST_PP_ITERATION_START_2 >= 83 # define BOOST_PP_ITERATION_2 83 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 82 && BOOST_PP_ITERATION_START_2 >= 82 # define BOOST_PP_ITERATION_2 82 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 81 && BOOST_PP_ITERATION_START_2 >= 81 # define BOOST_PP_ITERATION_2 81 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 80 && BOOST_PP_ITERATION_START_2 >= 80 # define BOOST_PP_ITERATION_2 80 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 79 && BOOST_PP_ITERATION_START_2 >= 79 # define BOOST_PP_ITERATION_2 79 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 78 && BOOST_PP_ITERATION_START_2 >= 78 # define BOOST_PP_ITERATION_2 78 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 77 && BOOST_PP_ITERATION_START_2 >= 77 # define BOOST_PP_ITERATION_2 77 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 76 && BOOST_PP_ITERATION_START_2 >= 76 # define BOOST_PP_ITERATION_2 76 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 75 && BOOST_PP_ITERATION_START_2 >= 75 # define BOOST_PP_ITERATION_2 75 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 74 && BOOST_PP_ITERATION_START_2 >= 74 # define BOOST_PP_ITERATION_2 74 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 73 && BOOST_PP_ITERATION_START_2 >= 73 # define BOOST_PP_ITERATION_2 73 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 72 && BOOST_PP_ITERATION_START_2 >= 72 # define BOOST_PP_ITERATION_2 72 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 71 && BOOST_PP_ITERATION_START_2 >= 71 # define BOOST_PP_ITERATION_2 71 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 70 && BOOST_PP_ITERATION_START_2 >= 70 # define BOOST_PP_ITERATION_2 70 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 69 && BOOST_PP_ITERATION_START_2 >= 69 # define BOOST_PP_ITERATION_2 69 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 68 && BOOST_PP_ITERATION_START_2 >= 68 # define BOOST_PP_ITERATION_2 68 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 67 && BOOST_PP_ITERATION_START_2 >= 67 # define BOOST_PP_ITERATION_2 67 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 66 && BOOST_PP_ITERATION_START_2 >= 66 # define BOOST_PP_ITERATION_2 66 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 65 && BOOST_PP_ITERATION_START_2 >= 65 # define BOOST_PP_ITERATION_2 65 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 64 && BOOST_PP_ITERATION_START_2 >= 64 # define BOOST_PP_ITERATION_2 64 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 63 && BOOST_PP_ITERATION_START_2 >= 63 # define BOOST_PP_ITERATION_2 63 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 62 && BOOST_PP_ITERATION_START_2 >= 62 # define BOOST_PP_ITERATION_2 62 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 61 && BOOST_PP_ITERATION_START_2 >= 61 # define BOOST_PP_ITERATION_2 61 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 60 && BOOST_PP_ITERATION_START_2 >= 60 # define BOOST_PP_ITERATION_2 60 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 59 && BOOST_PP_ITERATION_START_2 >= 59 # define BOOST_PP_ITERATION_2 59 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 58 && BOOST_PP_ITERATION_START_2 >= 58 # define BOOST_PP_ITERATION_2 58 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 57 && BOOST_PP_ITERATION_START_2 >= 57 # define BOOST_PP_ITERATION_2 57 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 56 && BOOST_PP_ITERATION_START_2 >= 56 # define BOOST_PP_ITERATION_2 56 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 55 && BOOST_PP_ITERATION_START_2 >= 55 # define BOOST_PP_ITERATION_2 55 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 54 && BOOST_PP_ITERATION_START_2 >= 54 # define BOOST_PP_ITERATION_2 54 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 53 && BOOST_PP_ITERATION_START_2 >= 53 # define BOOST_PP_ITERATION_2 53 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 52 && BOOST_PP_ITERATION_START_2 >= 52 # define BOOST_PP_ITERATION_2 52 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 51 && BOOST_PP_ITERATION_START_2 >= 51 # define BOOST_PP_ITERATION_2 51 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 50 && BOOST_PP_ITERATION_START_2 >= 50 # define BOOST_PP_ITERATION_2 50 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 49 && BOOST_PP_ITERATION_START_2 >= 49 # define BOOST_PP_ITERATION_2 49 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 48 && BOOST_PP_ITERATION_START_2 >= 48 # define BOOST_PP_ITERATION_2 48 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 47 && BOOST_PP_ITERATION_START_2 >= 47 # define BOOST_PP_ITERATION_2 47 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 46 && BOOST_PP_ITERATION_START_2 >= 46 # define BOOST_PP_ITERATION_2 46 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 45 && BOOST_PP_ITERATION_START_2 >= 45 # define BOOST_PP_ITERATION_2 45 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 44 && BOOST_PP_ITERATION_START_2 >= 44 # define BOOST_PP_ITERATION_2 44 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 43 && BOOST_PP_ITERATION_START_2 >= 43 # define BOOST_PP_ITERATION_2 43 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 42 && BOOST_PP_ITERATION_START_2 >= 42 # define BOOST_PP_ITERATION_2 42 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 41 && BOOST_PP_ITERATION_START_2 >= 41 # define BOOST_PP_ITERATION_2 41 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 40 && BOOST_PP_ITERATION_START_2 >= 40 # define BOOST_PP_ITERATION_2 40 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 39 && BOOST_PP_ITERATION_START_2 >= 39 # define BOOST_PP_ITERATION_2 39 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 38 && BOOST_PP_ITERATION_START_2 >= 38 # define BOOST_PP_ITERATION_2 38 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 37 && BOOST_PP_ITERATION_START_2 >= 37 # define BOOST_PP_ITERATION_2 37 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 36 && BOOST_PP_ITERATION_START_2 >= 36 # define BOOST_PP_ITERATION_2 36 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 35 && BOOST_PP_ITERATION_START_2 >= 35 # define BOOST_PP_ITERATION_2 35 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 34 && BOOST_PP_ITERATION_START_2 >= 34 # define BOOST_PP_ITERATION_2 34 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 33 && BOOST_PP_ITERATION_START_2 >= 33 # define BOOST_PP_ITERATION_2 33 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 32 && BOOST_PP_ITERATION_START_2 >= 32 # define BOOST_PP_ITERATION_2 32 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 31 && BOOST_PP_ITERATION_START_2 >= 31 # define BOOST_PP_ITERATION_2 31 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 30 && BOOST_PP_ITERATION_START_2 >= 30 # define BOOST_PP_ITERATION_2 30 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 29 && BOOST_PP_ITERATION_START_2 >= 29 # define BOOST_PP_ITERATION_2 29 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 28 && BOOST_PP_ITERATION_START_2 >= 28 # define BOOST_PP_ITERATION_2 28 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 27 && BOOST_PP_ITERATION_START_2 >= 27 # define BOOST_PP_ITERATION_2 27 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 26 && BOOST_PP_ITERATION_START_2 >= 26 # define BOOST_PP_ITERATION_2 26 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 25 && BOOST_PP_ITERATION_START_2 >= 25 # define BOOST_PP_ITERATION_2 25 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 24 && BOOST_PP_ITERATION_START_2 >= 24 # define BOOST_PP_ITERATION_2 24 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 23 && BOOST_PP_ITERATION_START_2 >= 23 # define BOOST_PP_ITERATION_2 23 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 22 && BOOST_PP_ITERATION_START_2 >= 22 # define BOOST_PP_ITERATION_2 22 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 21 && BOOST_PP_ITERATION_START_2 >= 21 # define BOOST_PP_ITERATION_2 21 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 20 && BOOST_PP_ITERATION_START_2 >= 20 # define BOOST_PP_ITERATION_2 20 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 19 && BOOST_PP_ITERATION_START_2 >= 19 # define BOOST_PP_ITERATION_2 19 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 18 && BOOST_PP_ITERATION_START_2 >= 18 # define BOOST_PP_ITERATION_2 18 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 17 && BOOST_PP_ITERATION_START_2 >= 17 # define BOOST_PP_ITERATION_2 17 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 16 && BOOST_PP_ITERATION_START_2 >= 16 # define BOOST_PP_ITERATION_2 16 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 15 && BOOST_PP_ITERATION_START_2 >= 15 # define BOOST_PP_ITERATION_2 15 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 14 && BOOST_PP_ITERATION_START_2 >= 14 # define BOOST_PP_ITERATION_2 14 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 13 && BOOST_PP_ITERATION_START_2 >= 13 # define BOOST_PP_ITERATION_2 13 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 12 && BOOST_PP_ITERATION_START_2 >= 12 # define BOOST_PP_ITERATION_2 12 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 11 && BOOST_PP_ITERATION_START_2 >= 11 # define BOOST_PP_ITERATION_2 11 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 10 && BOOST_PP_ITERATION_START_2 >= 10 # define BOOST_PP_ITERATION_2 10 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 9 && BOOST_PP_ITERATION_START_2 >= 9 # define BOOST_PP_ITERATION_2 9 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 8 && BOOST_PP_ITERATION_START_2 >= 8 # define BOOST_PP_ITERATION_2 8 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 7 && BOOST_PP_ITERATION_START_2 >= 7 # define BOOST_PP_ITERATION_2 7 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 6 && BOOST_PP_ITERATION_START_2 >= 6 # define BOOST_PP_ITERATION_2 6 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 5 && BOOST_PP_ITERATION_START_2 >= 5 # define BOOST_PP_ITERATION_2 5 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 4 && BOOST_PP_ITERATION_START_2 >= 4 # define BOOST_PP_ITERATION_2 4 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 3 && BOOST_PP_ITERATION_START_2 >= 3 # define BOOST_PP_ITERATION_2 3 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 2 && BOOST_PP_ITERATION_START_2 >= 2 # define BOOST_PP_ITERATION_2 2 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 1 && BOOST_PP_ITERATION_START_2 >= 1 # define BOOST_PP_ITERATION_2 1 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif # if BOOST_PP_ITERATION_FINISH_2 <= 0 && BOOST_PP_ITERATION_START_2 >= 0 # define BOOST_PP_ITERATION_2 0 # include BOOST_PP_FILENAME_2 # undef BOOST_PP_ITERATION_2 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/reverse3.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if BOOST_PP_ITERATION_FINISH_3 <= 256 && BOOST_PP_ITERATION_START_3 >= 256 # define BOOST_PP_ITERATION_3 256 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 255 && BOOST_PP_ITERATION_START_3 >= 255 # define BOOST_PP_ITERATION_3 255 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 254 && BOOST_PP_ITERATION_START_3 >= 254 # define BOOST_PP_ITERATION_3 254 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 253 && BOOST_PP_ITERATION_START_3 >= 253 # define BOOST_PP_ITERATION_3 253 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 252 && BOOST_PP_ITERATION_START_3 >= 252 # define BOOST_PP_ITERATION_3 252 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 251 && BOOST_PP_ITERATION_START_3 >= 251 # define BOOST_PP_ITERATION_3 251 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 250 && BOOST_PP_ITERATION_START_3 >= 250 # define BOOST_PP_ITERATION_3 250 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 249 && BOOST_PP_ITERATION_START_3 >= 249 # define BOOST_PP_ITERATION_3 249 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 248 && BOOST_PP_ITERATION_START_3 >= 248 # define BOOST_PP_ITERATION_3 248 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 247 && BOOST_PP_ITERATION_START_3 >= 247 # define BOOST_PP_ITERATION_3 247 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 246 && BOOST_PP_ITERATION_START_3 >= 246 # define BOOST_PP_ITERATION_3 246 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 245 && BOOST_PP_ITERATION_START_3 >= 245 # define BOOST_PP_ITERATION_3 245 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 244 && BOOST_PP_ITERATION_START_3 >= 244 # define BOOST_PP_ITERATION_3 244 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 243 && BOOST_PP_ITERATION_START_3 >= 243 # define BOOST_PP_ITERATION_3 243 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 242 && BOOST_PP_ITERATION_START_3 >= 242 # define BOOST_PP_ITERATION_3 242 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 241 && BOOST_PP_ITERATION_START_3 >= 241 # define BOOST_PP_ITERATION_3 241 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 240 && BOOST_PP_ITERATION_START_3 >= 240 # define BOOST_PP_ITERATION_3 240 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 239 && BOOST_PP_ITERATION_START_3 >= 239 # define BOOST_PP_ITERATION_3 239 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 238 && BOOST_PP_ITERATION_START_3 >= 238 # define BOOST_PP_ITERATION_3 238 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 237 && BOOST_PP_ITERATION_START_3 >= 237 # define BOOST_PP_ITERATION_3 237 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 236 && BOOST_PP_ITERATION_START_3 >= 236 # define BOOST_PP_ITERATION_3 236 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 235 && BOOST_PP_ITERATION_START_3 >= 235 # define BOOST_PP_ITERATION_3 235 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 234 && BOOST_PP_ITERATION_START_3 >= 234 # define BOOST_PP_ITERATION_3 234 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 233 && BOOST_PP_ITERATION_START_3 >= 233 # define BOOST_PP_ITERATION_3 233 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 232 && BOOST_PP_ITERATION_START_3 >= 232 # define BOOST_PP_ITERATION_3 232 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 231 && BOOST_PP_ITERATION_START_3 >= 231 # define BOOST_PP_ITERATION_3 231 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 230 && BOOST_PP_ITERATION_START_3 >= 230 # define BOOST_PP_ITERATION_3 230 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 229 && BOOST_PP_ITERATION_START_3 >= 229 # define BOOST_PP_ITERATION_3 229 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 228 && BOOST_PP_ITERATION_START_3 >= 228 # define BOOST_PP_ITERATION_3 228 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 227 && BOOST_PP_ITERATION_START_3 >= 227 # define BOOST_PP_ITERATION_3 227 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 226 && BOOST_PP_ITERATION_START_3 >= 226 # define BOOST_PP_ITERATION_3 226 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 225 && BOOST_PP_ITERATION_START_3 >= 225 # define BOOST_PP_ITERATION_3 225 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 224 && BOOST_PP_ITERATION_START_3 >= 224 # define BOOST_PP_ITERATION_3 224 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 223 && BOOST_PP_ITERATION_START_3 >= 223 # define BOOST_PP_ITERATION_3 223 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 222 && BOOST_PP_ITERATION_START_3 >= 222 # define BOOST_PP_ITERATION_3 222 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 221 && BOOST_PP_ITERATION_START_3 >= 221 # define BOOST_PP_ITERATION_3 221 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 220 && BOOST_PP_ITERATION_START_3 >= 220 # define BOOST_PP_ITERATION_3 220 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 219 && BOOST_PP_ITERATION_START_3 >= 219 # define BOOST_PP_ITERATION_3 219 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 218 && BOOST_PP_ITERATION_START_3 >= 218 # define BOOST_PP_ITERATION_3 218 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 217 && BOOST_PP_ITERATION_START_3 >= 217 # define BOOST_PP_ITERATION_3 217 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 216 && BOOST_PP_ITERATION_START_3 >= 216 # define BOOST_PP_ITERATION_3 216 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 215 && BOOST_PP_ITERATION_START_3 >= 215 # define BOOST_PP_ITERATION_3 215 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 214 && BOOST_PP_ITERATION_START_3 >= 214 # define BOOST_PP_ITERATION_3 214 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 213 && BOOST_PP_ITERATION_START_3 >= 213 # define BOOST_PP_ITERATION_3 213 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 212 && BOOST_PP_ITERATION_START_3 >= 212 # define BOOST_PP_ITERATION_3 212 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 211 && BOOST_PP_ITERATION_START_3 >= 211 # define BOOST_PP_ITERATION_3 211 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 210 && BOOST_PP_ITERATION_START_3 >= 210 # define BOOST_PP_ITERATION_3 210 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 209 && BOOST_PP_ITERATION_START_3 >= 209 # define BOOST_PP_ITERATION_3 209 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 208 && BOOST_PP_ITERATION_START_3 >= 208 # define BOOST_PP_ITERATION_3 208 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 207 && BOOST_PP_ITERATION_START_3 >= 207 # define BOOST_PP_ITERATION_3 207 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 206 && BOOST_PP_ITERATION_START_3 >= 206 # define BOOST_PP_ITERATION_3 206 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 205 && BOOST_PP_ITERATION_START_3 >= 205 # define BOOST_PP_ITERATION_3 205 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 204 && BOOST_PP_ITERATION_START_3 >= 204 # define BOOST_PP_ITERATION_3 204 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 203 && BOOST_PP_ITERATION_START_3 >= 203 # define BOOST_PP_ITERATION_3 203 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 202 && BOOST_PP_ITERATION_START_3 >= 202 # define BOOST_PP_ITERATION_3 202 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 201 && BOOST_PP_ITERATION_START_3 >= 201 # define BOOST_PP_ITERATION_3 201 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 200 && BOOST_PP_ITERATION_START_3 >= 200 # define BOOST_PP_ITERATION_3 200 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 199 && BOOST_PP_ITERATION_START_3 >= 199 # define BOOST_PP_ITERATION_3 199 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 198 && BOOST_PP_ITERATION_START_3 >= 198 # define BOOST_PP_ITERATION_3 198 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 197 && BOOST_PP_ITERATION_START_3 >= 197 # define BOOST_PP_ITERATION_3 197 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 196 && BOOST_PP_ITERATION_START_3 >= 196 # define BOOST_PP_ITERATION_3 196 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 195 && BOOST_PP_ITERATION_START_3 >= 195 # define BOOST_PP_ITERATION_3 195 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 194 && BOOST_PP_ITERATION_START_3 >= 194 # define BOOST_PP_ITERATION_3 194 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 193 && BOOST_PP_ITERATION_START_3 >= 193 # define BOOST_PP_ITERATION_3 193 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 192 && BOOST_PP_ITERATION_START_3 >= 192 # define BOOST_PP_ITERATION_3 192 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 191 && BOOST_PP_ITERATION_START_3 >= 191 # define BOOST_PP_ITERATION_3 191 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 190 && BOOST_PP_ITERATION_START_3 >= 190 # define BOOST_PP_ITERATION_3 190 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 189 && BOOST_PP_ITERATION_START_3 >= 189 # define BOOST_PP_ITERATION_3 189 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 188 && BOOST_PP_ITERATION_START_3 >= 188 # define BOOST_PP_ITERATION_3 188 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 187 && BOOST_PP_ITERATION_START_3 >= 187 # define BOOST_PP_ITERATION_3 187 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 186 && BOOST_PP_ITERATION_START_3 >= 186 # define BOOST_PP_ITERATION_3 186 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 185 && BOOST_PP_ITERATION_START_3 >= 185 # define BOOST_PP_ITERATION_3 185 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 184 && BOOST_PP_ITERATION_START_3 >= 184 # define BOOST_PP_ITERATION_3 184 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 183 && BOOST_PP_ITERATION_START_3 >= 183 # define BOOST_PP_ITERATION_3 183 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 182 && BOOST_PP_ITERATION_START_3 >= 182 # define BOOST_PP_ITERATION_3 182 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 181 && BOOST_PP_ITERATION_START_3 >= 181 # define BOOST_PP_ITERATION_3 181 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 180 && BOOST_PP_ITERATION_START_3 >= 180 # define BOOST_PP_ITERATION_3 180 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 179 && BOOST_PP_ITERATION_START_3 >= 179 # define BOOST_PP_ITERATION_3 179 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 178 && BOOST_PP_ITERATION_START_3 >= 178 # define BOOST_PP_ITERATION_3 178 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 177 && BOOST_PP_ITERATION_START_3 >= 177 # define BOOST_PP_ITERATION_3 177 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 176 && BOOST_PP_ITERATION_START_3 >= 176 # define BOOST_PP_ITERATION_3 176 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 175 && BOOST_PP_ITERATION_START_3 >= 175 # define BOOST_PP_ITERATION_3 175 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 174 && BOOST_PP_ITERATION_START_3 >= 174 # define BOOST_PP_ITERATION_3 174 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 173 && BOOST_PP_ITERATION_START_3 >= 173 # define BOOST_PP_ITERATION_3 173 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 172 && BOOST_PP_ITERATION_START_3 >= 172 # define BOOST_PP_ITERATION_3 172 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 171 && BOOST_PP_ITERATION_START_3 >= 171 # define BOOST_PP_ITERATION_3 171 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 170 && BOOST_PP_ITERATION_START_3 >= 170 # define BOOST_PP_ITERATION_3 170 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 169 && BOOST_PP_ITERATION_START_3 >= 169 # define BOOST_PP_ITERATION_3 169 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 168 && BOOST_PP_ITERATION_START_3 >= 168 # define BOOST_PP_ITERATION_3 168 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 167 && BOOST_PP_ITERATION_START_3 >= 167 # define BOOST_PP_ITERATION_3 167 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 166 && BOOST_PP_ITERATION_START_3 >= 166 # define BOOST_PP_ITERATION_3 166 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 165 && BOOST_PP_ITERATION_START_3 >= 165 # define BOOST_PP_ITERATION_3 165 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 164 && BOOST_PP_ITERATION_START_3 >= 164 # define BOOST_PP_ITERATION_3 164 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 163 && BOOST_PP_ITERATION_START_3 >= 163 # define BOOST_PP_ITERATION_3 163 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 162 && BOOST_PP_ITERATION_START_3 >= 162 # define BOOST_PP_ITERATION_3 162 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 161 && BOOST_PP_ITERATION_START_3 >= 161 # define BOOST_PP_ITERATION_3 161 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 160 && BOOST_PP_ITERATION_START_3 >= 160 # define BOOST_PP_ITERATION_3 160 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 159 && BOOST_PP_ITERATION_START_3 >= 159 # define BOOST_PP_ITERATION_3 159 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 158 && BOOST_PP_ITERATION_START_3 >= 158 # define BOOST_PP_ITERATION_3 158 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 157 && BOOST_PP_ITERATION_START_3 >= 157 # define BOOST_PP_ITERATION_3 157 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 156 && BOOST_PP_ITERATION_START_3 >= 156 # define BOOST_PP_ITERATION_3 156 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 155 && BOOST_PP_ITERATION_START_3 >= 155 # define BOOST_PP_ITERATION_3 155 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 154 && BOOST_PP_ITERATION_START_3 >= 154 # define BOOST_PP_ITERATION_3 154 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 153 && BOOST_PP_ITERATION_START_3 >= 153 # define BOOST_PP_ITERATION_3 153 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 152 && BOOST_PP_ITERATION_START_3 >= 152 # define BOOST_PP_ITERATION_3 152 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 151 && BOOST_PP_ITERATION_START_3 >= 151 # define BOOST_PP_ITERATION_3 151 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 150 && BOOST_PP_ITERATION_START_3 >= 150 # define BOOST_PP_ITERATION_3 150 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 149 && BOOST_PP_ITERATION_START_3 >= 149 # define BOOST_PP_ITERATION_3 149 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 148 && BOOST_PP_ITERATION_START_3 >= 148 # define BOOST_PP_ITERATION_3 148 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 147 && BOOST_PP_ITERATION_START_3 >= 147 # define BOOST_PP_ITERATION_3 147 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 146 && BOOST_PP_ITERATION_START_3 >= 146 # define BOOST_PP_ITERATION_3 146 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 145 && BOOST_PP_ITERATION_START_3 >= 145 # define BOOST_PP_ITERATION_3 145 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 144 && BOOST_PP_ITERATION_START_3 >= 144 # define BOOST_PP_ITERATION_3 144 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 143 && BOOST_PP_ITERATION_START_3 >= 143 # define BOOST_PP_ITERATION_3 143 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 142 && BOOST_PP_ITERATION_START_3 >= 142 # define BOOST_PP_ITERATION_3 142 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 141 && BOOST_PP_ITERATION_START_3 >= 141 # define BOOST_PP_ITERATION_3 141 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 140 && BOOST_PP_ITERATION_START_3 >= 140 # define BOOST_PP_ITERATION_3 140 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 139 && BOOST_PP_ITERATION_START_3 >= 139 # define BOOST_PP_ITERATION_3 139 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 138 && BOOST_PP_ITERATION_START_3 >= 138 # define BOOST_PP_ITERATION_3 138 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 137 && BOOST_PP_ITERATION_START_3 >= 137 # define BOOST_PP_ITERATION_3 137 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 136 && BOOST_PP_ITERATION_START_3 >= 136 # define BOOST_PP_ITERATION_3 136 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 135 && BOOST_PP_ITERATION_START_3 >= 135 # define BOOST_PP_ITERATION_3 135 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 134 && BOOST_PP_ITERATION_START_3 >= 134 # define BOOST_PP_ITERATION_3 134 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 133 && BOOST_PP_ITERATION_START_3 >= 133 # define BOOST_PP_ITERATION_3 133 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 132 && BOOST_PP_ITERATION_START_3 >= 132 # define BOOST_PP_ITERATION_3 132 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 131 && BOOST_PP_ITERATION_START_3 >= 131 # define BOOST_PP_ITERATION_3 131 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 130 && BOOST_PP_ITERATION_START_3 >= 130 # define BOOST_PP_ITERATION_3 130 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 129 && BOOST_PP_ITERATION_START_3 >= 129 # define BOOST_PP_ITERATION_3 129 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 128 && BOOST_PP_ITERATION_START_3 >= 128 # define BOOST_PP_ITERATION_3 128 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 127 && BOOST_PP_ITERATION_START_3 >= 127 # define BOOST_PP_ITERATION_3 127 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 126 && BOOST_PP_ITERATION_START_3 >= 126 # define BOOST_PP_ITERATION_3 126 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 125 && BOOST_PP_ITERATION_START_3 >= 125 # define BOOST_PP_ITERATION_3 125 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 124 && BOOST_PP_ITERATION_START_3 >= 124 # define BOOST_PP_ITERATION_3 124 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 123 && BOOST_PP_ITERATION_START_3 >= 123 # define BOOST_PP_ITERATION_3 123 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 122 && BOOST_PP_ITERATION_START_3 >= 122 # define BOOST_PP_ITERATION_3 122 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 121 && BOOST_PP_ITERATION_START_3 >= 121 # define BOOST_PP_ITERATION_3 121 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 120 && BOOST_PP_ITERATION_START_3 >= 120 # define BOOST_PP_ITERATION_3 120 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 119 && BOOST_PP_ITERATION_START_3 >= 119 # define BOOST_PP_ITERATION_3 119 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 118 && BOOST_PP_ITERATION_START_3 >= 118 # define BOOST_PP_ITERATION_3 118 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 117 && BOOST_PP_ITERATION_START_3 >= 117 # define BOOST_PP_ITERATION_3 117 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 116 && BOOST_PP_ITERATION_START_3 >= 116 # define BOOST_PP_ITERATION_3 116 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 115 && BOOST_PP_ITERATION_START_3 >= 115 # define BOOST_PP_ITERATION_3 115 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 114 && BOOST_PP_ITERATION_START_3 >= 114 # define BOOST_PP_ITERATION_3 114 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 113 && BOOST_PP_ITERATION_START_3 >= 113 # define BOOST_PP_ITERATION_3 113 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 112 && BOOST_PP_ITERATION_START_3 >= 112 # define BOOST_PP_ITERATION_3 112 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 111 && BOOST_PP_ITERATION_START_3 >= 111 # define BOOST_PP_ITERATION_3 111 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 110 && BOOST_PP_ITERATION_START_3 >= 110 # define BOOST_PP_ITERATION_3 110 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 109 && BOOST_PP_ITERATION_START_3 >= 109 # define BOOST_PP_ITERATION_3 109 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 108 && BOOST_PP_ITERATION_START_3 >= 108 # define BOOST_PP_ITERATION_3 108 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 107 && BOOST_PP_ITERATION_START_3 >= 107 # define BOOST_PP_ITERATION_3 107 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 106 && BOOST_PP_ITERATION_START_3 >= 106 # define BOOST_PP_ITERATION_3 106 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 105 && BOOST_PP_ITERATION_START_3 >= 105 # define BOOST_PP_ITERATION_3 105 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 104 && BOOST_PP_ITERATION_START_3 >= 104 # define BOOST_PP_ITERATION_3 104 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 103 && BOOST_PP_ITERATION_START_3 >= 103 # define BOOST_PP_ITERATION_3 103 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 102 && BOOST_PP_ITERATION_START_3 >= 102 # define BOOST_PP_ITERATION_3 102 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 101 && BOOST_PP_ITERATION_START_3 >= 101 # define BOOST_PP_ITERATION_3 101 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 100 && BOOST_PP_ITERATION_START_3 >= 100 # define BOOST_PP_ITERATION_3 100 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 99 && BOOST_PP_ITERATION_START_3 >= 99 # define BOOST_PP_ITERATION_3 99 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 98 && BOOST_PP_ITERATION_START_3 >= 98 # define BOOST_PP_ITERATION_3 98 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 97 && BOOST_PP_ITERATION_START_3 >= 97 # define BOOST_PP_ITERATION_3 97 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 96 && BOOST_PP_ITERATION_START_3 >= 96 # define BOOST_PP_ITERATION_3 96 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 95 && BOOST_PP_ITERATION_START_3 >= 95 # define BOOST_PP_ITERATION_3 95 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 94 && BOOST_PP_ITERATION_START_3 >= 94 # define BOOST_PP_ITERATION_3 94 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 93 && BOOST_PP_ITERATION_START_3 >= 93 # define BOOST_PP_ITERATION_3 93 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 92 && BOOST_PP_ITERATION_START_3 >= 92 # define BOOST_PP_ITERATION_3 92 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 91 && BOOST_PP_ITERATION_START_3 >= 91 # define BOOST_PP_ITERATION_3 91 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 90 && BOOST_PP_ITERATION_START_3 >= 90 # define BOOST_PP_ITERATION_3 90 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 89 && BOOST_PP_ITERATION_START_3 >= 89 # define BOOST_PP_ITERATION_3 89 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 88 && BOOST_PP_ITERATION_START_3 >= 88 # define BOOST_PP_ITERATION_3 88 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 87 && BOOST_PP_ITERATION_START_3 >= 87 # define BOOST_PP_ITERATION_3 87 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 86 && BOOST_PP_ITERATION_START_3 >= 86 # define BOOST_PP_ITERATION_3 86 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 85 && BOOST_PP_ITERATION_START_3 >= 85 # define BOOST_PP_ITERATION_3 85 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 84 && BOOST_PP_ITERATION_START_3 >= 84 # define BOOST_PP_ITERATION_3 84 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 83 && BOOST_PP_ITERATION_START_3 >= 83 # define BOOST_PP_ITERATION_3 83 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 82 && BOOST_PP_ITERATION_START_3 >= 82 # define BOOST_PP_ITERATION_3 82 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 81 && BOOST_PP_ITERATION_START_3 >= 81 # define BOOST_PP_ITERATION_3 81 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 80 && BOOST_PP_ITERATION_START_3 >= 80 # define BOOST_PP_ITERATION_3 80 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 79 && BOOST_PP_ITERATION_START_3 >= 79 # define BOOST_PP_ITERATION_3 79 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 78 && BOOST_PP_ITERATION_START_3 >= 78 # define BOOST_PP_ITERATION_3 78 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 77 && BOOST_PP_ITERATION_START_3 >= 77 # define BOOST_PP_ITERATION_3 77 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 76 && BOOST_PP_ITERATION_START_3 >= 76 # define BOOST_PP_ITERATION_3 76 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 75 && BOOST_PP_ITERATION_START_3 >= 75 # define BOOST_PP_ITERATION_3 75 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 74 && BOOST_PP_ITERATION_START_3 >= 74 # define BOOST_PP_ITERATION_3 74 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 73 && BOOST_PP_ITERATION_START_3 >= 73 # define BOOST_PP_ITERATION_3 73 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 72 && BOOST_PP_ITERATION_START_3 >= 72 # define BOOST_PP_ITERATION_3 72 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 71 && BOOST_PP_ITERATION_START_3 >= 71 # define BOOST_PP_ITERATION_3 71 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 70 && BOOST_PP_ITERATION_START_3 >= 70 # define BOOST_PP_ITERATION_3 70 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 69 && BOOST_PP_ITERATION_START_3 >= 69 # define BOOST_PP_ITERATION_3 69 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 68 && BOOST_PP_ITERATION_START_3 >= 68 # define BOOST_PP_ITERATION_3 68 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 67 && BOOST_PP_ITERATION_START_3 >= 67 # define BOOST_PP_ITERATION_3 67 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 66 && BOOST_PP_ITERATION_START_3 >= 66 # define BOOST_PP_ITERATION_3 66 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 65 && BOOST_PP_ITERATION_START_3 >= 65 # define BOOST_PP_ITERATION_3 65 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 64 && BOOST_PP_ITERATION_START_3 >= 64 # define BOOST_PP_ITERATION_3 64 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 63 && BOOST_PP_ITERATION_START_3 >= 63 # define BOOST_PP_ITERATION_3 63 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 62 && BOOST_PP_ITERATION_START_3 >= 62 # define BOOST_PP_ITERATION_3 62 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 61 && BOOST_PP_ITERATION_START_3 >= 61 # define BOOST_PP_ITERATION_3 61 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 60 && BOOST_PP_ITERATION_START_3 >= 60 # define BOOST_PP_ITERATION_3 60 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 59 && BOOST_PP_ITERATION_START_3 >= 59 # define BOOST_PP_ITERATION_3 59 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 58 && BOOST_PP_ITERATION_START_3 >= 58 # define BOOST_PP_ITERATION_3 58 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 57 && BOOST_PP_ITERATION_START_3 >= 57 # define BOOST_PP_ITERATION_3 57 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 56 && BOOST_PP_ITERATION_START_3 >= 56 # define BOOST_PP_ITERATION_3 56 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 55 && BOOST_PP_ITERATION_START_3 >= 55 # define BOOST_PP_ITERATION_3 55 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 54 && BOOST_PP_ITERATION_START_3 >= 54 # define BOOST_PP_ITERATION_3 54 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 53 && BOOST_PP_ITERATION_START_3 >= 53 # define BOOST_PP_ITERATION_3 53 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 52 && BOOST_PP_ITERATION_START_3 >= 52 # define BOOST_PP_ITERATION_3 52 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 51 && BOOST_PP_ITERATION_START_3 >= 51 # define BOOST_PP_ITERATION_3 51 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 50 && BOOST_PP_ITERATION_START_3 >= 50 # define BOOST_PP_ITERATION_3 50 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 49 && BOOST_PP_ITERATION_START_3 >= 49 # define BOOST_PP_ITERATION_3 49 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 48 && BOOST_PP_ITERATION_START_3 >= 48 # define BOOST_PP_ITERATION_3 48 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 47 && BOOST_PP_ITERATION_START_3 >= 47 # define BOOST_PP_ITERATION_3 47 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 46 && BOOST_PP_ITERATION_START_3 >= 46 # define BOOST_PP_ITERATION_3 46 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 45 && BOOST_PP_ITERATION_START_3 >= 45 # define BOOST_PP_ITERATION_3 45 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 44 && BOOST_PP_ITERATION_START_3 >= 44 # define BOOST_PP_ITERATION_3 44 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 43 && BOOST_PP_ITERATION_START_3 >= 43 # define BOOST_PP_ITERATION_3 43 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 42 && BOOST_PP_ITERATION_START_3 >= 42 # define BOOST_PP_ITERATION_3 42 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 41 && BOOST_PP_ITERATION_START_3 >= 41 # define BOOST_PP_ITERATION_3 41 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 40 && BOOST_PP_ITERATION_START_3 >= 40 # define BOOST_PP_ITERATION_3 40 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 39 && BOOST_PP_ITERATION_START_3 >= 39 # define BOOST_PP_ITERATION_3 39 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 38 && BOOST_PP_ITERATION_START_3 >= 38 # define BOOST_PP_ITERATION_3 38 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 37 && BOOST_PP_ITERATION_START_3 >= 37 # define BOOST_PP_ITERATION_3 37 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 36 && BOOST_PP_ITERATION_START_3 >= 36 # define BOOST_PP_ITERATION_3 36 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 35 && BOOST_PP_ITERATION_START_3 >= 35 # define BOOST_PP_ITERATION_3 35 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 34 && BOOST_PP_ITERATION_START_3 >= 34 # define BOOST_PP_ITERATION_3 34 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 33 && BOOST_PP_ITERATION_START_3 >= 33 # define BOOST_PP_ITERATION_3 33 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 32 && BOOST_PP_ITERATION_START_3 >= 32 # define BOOST_PP_ITERATION_3 32 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 31 && BOOST_PP_ITERATION_START_3 >= 31 # define BOOST_PP_ITERATION_3 31 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 30 && BOOST_PP_ITERATION_START_3 >= 30 # define BOOST_PP_ITERATION_3 30 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 29 && BOOST_PP_ITERATION_START_3 >= 29 # define BOOST_PP_ITERATION_3 29 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 28 && BOOST_PP_ITERATION_START_3 >= 28 # define BOOST_PP_ITERATION_3 28 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 27 && BOOST_PP_ITERATION_START_3 >= 27 # define BOOST_PP_ITERATION_3 27 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 26 && BOOST_PP_ITERATION_START_3 >= 26 # define BOOST_PP_ITERATION_3 26 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 25 && BOOST_PP_ITERATION_START_3 >= 25 # define BOOST_PP_ITERATION_3 25 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 24 && BOOST_PP_ITERATION_START_3 >= 24 # define BOOST_PP_ITERATION_3 24 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 23 && BOOST_PP_ITERATION_START_3 >= 23 # define BOOST_PP_ITERATION_3 23 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 22 && BOOST_PP_ITERATION_START_3 >= 22 # define BOOST_PP_ITERATION_3 22 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 21 && BOOST_PP_ITERATION_START_3 >= 21 # define BOOST_PP_ITERATION_3 21 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 20 && BOOST_PP_ITERATION_START_3 >= 20 # define BOOST_PP_ITERATION_3 20 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 19 && BOOST_PP_ITERATION_START_3 >= 19 # define BOOST_PP_ITERATION_3 19 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 18 && BOOST_PP_ITERATION_START_3 >= 18 # define BOOST_PP_ITERATION_3 18 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 17 && BOOST_PP_ITERATION_START_3 >= 17 # define BOOST_PP_ITERATION_3 17 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 16 && BOOST_PP_ITERATION_START_3 >= 16 # define BOOST_PP_ITERATION_3 16 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 15 && BOOST_PP_ITERATION_START_3 >= 15 # define BOOST_PP_ITERATION_3 15 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 14 && BOOST_PP_ITERATION_START_3 >= 14 # define BOOST_PP_ITERATION_3 14 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 13 && BOOST_PP_ITERATION_START_3 >= 13 # define BOOST_PP_ITERATION_3 13 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 12 && BOOST_PP_ITERATION_START_3 >= 12 # define BOOST_PP_ITERATION_3 12 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 11 && BOOST_PP_ITERATION_START_3 >= 11 # define BOOST_PP_ITERATION_3 11 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 10 && BOOST_PP_ITERATION_START_3 >= 10 # define BOOST_PP_ITERATION_3 10 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 9 && BOOST_PP_ITERATION_START_3 >= 9 # define BOOST_PP_ITERATION_3 9 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 8 && BOOST_PP_ITERATION_START_3 >= 8 # define BOOST_PP_ITERATION_3 8 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 7 && BOOST_PP_ITERATION_START_3 >= 7 # define BOOST_PP_ITERATION_3 7 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 6 && BOOST_PP_ITERATION_START_3 >= 6 # define BOOST_PP_ITERATION_3 6 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 5 && BOOST_PP_ITERATION_START_3 >= 5 # define BOOST_PP_ITERATION_3 5 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 4 && BOOST_PP_ITERATION_START_3 >= 4 # define BOOST_PP_ITERATION_3 4 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 3 && BOOST_PP_ITERATION_START_3 >= 3 # define BOOST_PP_ITERATION_3 3 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 2 && BOOST_PP_ITERATION_START_3 >= 2 # define BOOST_PP_ITERATION_3 2 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 1 && BOOST_PP_ITERATION_START_3 >= 1 # define BOOST_PP_ITERATION_3 1 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif # if BOOST_PP_ITERATION_FINISH_3 <= 0 && BOOST_PP_ITERATION_START_3 >= 0 # define BOOST_PP_ITERATION_3 0 # include BOOST_PP_FILENAME_3 # undef BOOST_PP_ITERATION_3 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/reverse4.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if BOOST_PP_ITERATION_FINISH_4 <= 256 && BOOST_PP_ITERATION_START_4 >= 256 # define BOOST_PP_ITERATION_4 256 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 255 && BOOST_PP_ITERATION_START_4 >= 255 # define BOOST_PP_ITERATION_4 255 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 254 && BOOST_PP_ITERATION_START_4 >= 254 # define BOOST_PP_ITERATION_4 254 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 253 && BOOST_PP_ITERATION_START_4 >= 253 # define BOOST_PP_ITERATION_4 253 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 252 && BOOST_PP_ITERATION_START_4 >= 252 # define BOOST_PP_ITERATION_4 252 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 251 && BOOST_PP_ITERATION_START_4 >= 251 # define BOOST_PP_ITERATION_4 251 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 250 && BOOST_PP_ITERATION_START_4 >= 250 # define BOOST_PP_ITERATION_4 250 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 249 && BOOST_PP_ITERATION_START_4 >= 249 # define BOOST_PP_ITERATION_4 249 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 248 && BOOST_PP_ITERATION_START_4 >= 248 # define BOOST_PP_ITERATION_4 248 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 247 && BOOST_PP_ITERATION_START_4 >= 247 # define BOOST_PP_ITERATION_4 247 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 246 && BOOST_PP_ITERATION_START_4 >= 246 # define BOOST_PP_ITERATION_4 246 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 245 && BOOST_PP_ITERATION_START_4 >= 245 # define BOOST_PP_ITERATION_4 245 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 244 && BOOST_PP_ITERATION_START_4 >= 244 # define BOOST_PP_ITERATION_4 244 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 243 && BOOST_PP_ITERATION_START_4 >= 243 # define BOOST_PP_ITERATION_4 243 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 242 && BOOST_PP_ITERATION_START_4 >= 242 # define BOOST_PP_ITERATION_4 242 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 241 && BOOST_PP_ITERATION_START_4 >= 241 # define BOOST_PP_ITERATION_4 241 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 240 && BOOST_PP_ITERATION_START_4 >= 240 # define BOOST_PP_ITERATION_4 240 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 239 && BOOST_PP_ITERATION_START_4 >= 239 # define BOOST_PP_ITERATION_4 239 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 238 && BOOST_PP_ITERATION_START_4 >= 238 # define BOOST_PP_ITERATION_4 238 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 237 && BOOST_PP_ITERATION_START_4 >= 237 # define BOOST_PP_ITERATION_4 237 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 236 && BOOST_PP_ITERATION_START_4 >= 236 # define BOOST_PP_ITERATION_4 236 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 235 && BOOST_PP_ITERATION_START_4 >= 235 # define BOOST_PP_ITERATION_4 235 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 234 && BOOST_PP_ITERATION_START_4 >= 234 # define BOOST_PP_ITERATION_4 234 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 233 && BOOST_PP_ITERATION_START_4 >= 233 # define BOOST_PP_ITERATION_4 233 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 232 && BOOST_PP_ITERATION_START_4 >= 232 # define BOOST_PP_ITERATION_4 232 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 231 && BOOST_PP_ITERATION_START_4 >= 231 # define BOOST_PP_ITERATION_4 231 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 230 && BOOST_PP_ITERATION_START_4 >= 230 # define BOOST_PP_ITERATION_4 230 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 229 && BOOST_PP_ITERATION_START_4 >= 229 # define BOOST_PP_ITERATION_4 229 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 228 && BOOST_PP_ITERATION_START_4 >= 228 # define BOOST_PP_ITERATION_4 228 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 227 && BOOST_PP_ITERATION_START_4 >= 227 # define BOOST_PP_ITERATION_4 227 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 226 && BOOST_PP_ITERATION_START_4 >= 226 # define BOOST_PP_ITERATION_4 226 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 225 && BOOST_PP_ITERATION_START_4 >= 225 # define BOOST_PP_ITERATION_4 225 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 224 && BOOST_PP_ITERATION_START_4 >= 224 # define BOOST_PP_ITERATION_4 224 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 223 && BOOST_PP_ITERATION_START_4 >= 223 # define BOOST_PP_ITERATION_4 223 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 222 && BOOST_PP_ITERATION_START_4 >= 222 # define BOOST_PP_ITERATION_4 222 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 221 && BOOST_PP_ITERATION_START_4 >= 221 # define BOOST_PP_ITERATION_4 221 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 220 && BOOST_PP_ITERATION_START_4 >= 220 # define BOOST_PP_ITERATION_4 220 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 219 && BOOST_PP_ITERATION_START_4 >= 219 # define BOOST_PP_ITERATION_4 219 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 218 && BOOST_PP_ITERATION_START_4 >= 218 # define BOOST_PP_ITERATION_4 218 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 217 && BOOST_PP_ITERATION_START_4 >= 217 # define BOOST_PP_ITERATION_4 217 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 216 && BOOST_PP_ITERATION_START_4 >= 216 # define BOOST_PP_ITERATION_4 216 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 215 && BOOST_PP_ITERATION_START_4 >= 215 # define BOOST_PP_ITERATION_4 215 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 214 && BOOST_PP_ITERATION_START_4 >= 214 # define BOOST_PP_ITERATION_4 214 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 213 && BOOST_PP_ITERATION_START_4 >= 213 # define BOOST_PP_ITERATION_4 213 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 212 && BOOST_PP_ITERATION_START_4 >= 212 # define BOOST_PP_ITERATION_4 212 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 211 && BOOST_PP_ITERATION_START_4 >= 211 # define BOOST_PP_ITERATION_4 211 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 210 && BOOST_PP_ITERATION_START_4 >= 210 # define BOOST_PP_ITERATION_4 210 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 209 && BOOST_PP_ITERATION_START_4 >= 209 # define BOOST_PP_ITERATION_4 209 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 208 && BOOST_PP_ITERATION_START_4 >= 208 # define BOOST_PP_ITERATION_4 208 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 207 && BOOST_PP_ITERATION_START_4 >= 207 # define BOOST_PP_ITERATION_4 207 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 206 && BOOST_PP_ITERATION_START_4 >= 206 # define BOOST_PP_ITERATION_4 206 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 205 && BOOST_PP_ITERATION_START_4 >= 205 # define BOOST_PP_ITERATION_4 205 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 204 && BOOST_PP_ITERATION_START_4 >= 204 # define BOOST_PP_ITERATION_4 204 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 203 && BOOST_PP_ITERATION_START_4 >= 203 # define BOOST_PP_ITERATION_4 203 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 202 && BOOST_PP_ITERATION_START_4 >= 202 # define BOOST_PP_ITERATION_4 202 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 201 && BOOST_PP_ITERATION_START_4 >= 201 # define BOOST_PP_ITERATION_4 201 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 200 && BOOST_PP_ITERATION_START_4 >= 200 # define BOOST_PP_ITERATION_4 200 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 199 && BOOST_PP_ITERATION_START_4 >= 199 # define BOOST_PP_ITERATION_4 199 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 198 && BOOST_PP_ITERATION_START_4 >= 198 # define BOOST_PP_ITERATION_4 198 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 197 && BOOST_PP_ITERATION_START_4 >= 197 # define BOOST_PP_ITERATION_4 197 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 196 && BOOST_PP_ITERATION_START_4 >= 196 # define BOOST_PP_ITERATION_4 196 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 195 && BOOST_PP_ITERATION_START_4 >= 195 # define BOOST_PP_ITERATION_4 195 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 194 && BOOST_PP_ITERATION_START_4 >= 194 # define BOOST_PP_ITERATION_4 194 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 193 && BOOST_PP_ITERATION_START_4 >= 193 # define BOOST_PP_ITERATION_4 193 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 192 && BOOST_PP_ITERATION_START_4 >= 192 # define BOOST_PP_ITERATION_4 192 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 191 && BOOST_PP_ITERATION_START_4 >= 191 # define BOOST_PP_ITERATION_4 191 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 190 && BOOST_PP_ITERATION_START_4 >= 190 # define BOOST_PP_ITERATION_4 190 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 189 && BOOST_PP_ITERATION_START_4 >= 189 # define BOOST_PP_ITERATION_4 189 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 188 && BOOST_PP_ITERATION_START_4 >= 188 # define BOOST_PP_ITERATION_4 188 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 187 && BOOST_PP_ITERATION_START_4 >= 187 # define BOOST_PP_ITERATION_4 187 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 186 && BOOST_PP_ITERATION_START_4 >= 186 # define BOOST_PP_ITERATION_4 186 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 185 && BOOST_PP_ITERATION_START_4 >= 185 # define BOOST_PP_ITERATION_4 185 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 184 && BOOST_PP_ITERATION_START_4 >= 184 # define BOOST_PP_ITERATION_4 184 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 183 && BOOST_PP_ITERATION_START_4 >= 183 # define BOOST_PP_ITERATION_4 183 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 182 && BOOST_PP_ITERATION_START_4 >= 182 # define BOOST_PP_ITERATION_4 182 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 181 && BOOST_PP_ITERATION_START_4 >= 181 # define BOOST_PP_ITERATION_4 181 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 180 && BOOST_PP_ITERATION_START_4 >= 180 # define BOOST_PP_ITERATION_4 180 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 179 && BOOST_PP_ITERATION_START_4 >= 179 # define BOOST_PP_ITERATION_4 179 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 178 && BOOST_PP_ITERATION_START_4 >= 178 # define BOOST_PP_ITERATION_4 178 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 177 && BOOST_PP_ITERATION_START_4 >= 177 # define BOOST_PP_ITERATION_4 177 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 176 && BOOST_PP_ITERATION_START_4 >= 176 # define BOOST_PP_ITERATION_4 176 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 175 && BOOST_PP_ITERATION_START_4 >= 175 # define BOOST_PP_ITERATION_4 175 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 174 && BOOST_PP_ITERATION_START_4 >= 174 # define BOOST_PP_ITERATION_4 174 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 173 && BOOST_PP_ITERATION_START_4 >= 173 # define BOOST_PP_ITERATION_4 173 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 172 && BOOST_PP_ITERATION_START_4 >= 172 # define BOOST_PP_ITERATION_4 172 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 171 && BOOST_PP_ITERATION_START_4 >= 171 # define BOOST_PP_ITERATION_4 171 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 170 && BOOST_PP_ITERATION_START_4 >= 170 # define BOOST_PP_ITERATION_4 170 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 169 && BOOST_PP_ITERATION_START_4 >= 169 # define BOOST_PP_ITERATION_4 169 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 168 && BOOST_PP_ITERATION_START_4 >= 168 # define BOOST_PP_ITERATION_4 168 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 167 && BOOST_PP_ITERATION_START_4 >= 167 # define BOOST_PP_ITERATION_4 167 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 166 && BOOST_PP_ITERATION_START_4 >= 166 # define BOOST_PP_ITERATION_4 166 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 165 && BOOST_PP_ITERATION_START_4 >= 165 # define BOOST_PP_ITERATION_4 165 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 164 && BOOST_PP_ITERATION_START_4 >= 164 # define BOOST_PP_ITERATION_4 164 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 163 && BOOST_PP_ITERATION_START_4 >= 163 # define BOOST_PP_ITERATION_4 163 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 162 && BOOST_PP_ITERATION_START_4 >= 162 # define BOOST_PP_ITERATION_4 162 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 161 && BOOST_PP_ITERATION_START_4 >= 161 # define BOOST_PP_ITERATION_4 161 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 160 && BOOST_PP_ITERATION_START_4 >= 160 # define BOOST_PP_ITERATION_4 160 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 159 && BOOST_PP_ITERATION_START_4 >= 159 # define BOOST_PP_ITERATION_4 159 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 158 && BOOST_PP_ITERATION_START_4 >= 158 # define BOOST_PP_ITERATION_4 158 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 157 && BOOST_PP_ITERATION_START_4 >= 157 # define BOOST_PP_ITERATION_4 157 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 156 && BOOST_PP_ITERATION_START_4 >= 156 # define BOOST_PP_ITERATION_4 156 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 155 && BOOST_PP_ITERATION_START_4 >= 155 # define BOOST_PP_ITERATION_4 155 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 154 && BOOST_PP_ITERATION_START_4 >= 154 # define BOOST_PP_ITERATION_4 154 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 153 && BOOST_PP_ITERATION_START_4 >= 153 # define BOOST_PP_ITERATION_4 153 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 152 && BOOST_PP_ITERATION_START_4 >= 152 # define BOOST_PP_ITERATION_4 152 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 151 && BOOST_PP_ITERATION_START_4 >= 151 # define BOOST_PP_ITERATION_4 151 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 150 && BOOST_PP_ITERATION_START_4 >= 150 # define BOOST_PP_ITERATION_4 150 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 149 && BOOST_PP_ITERATION_START_4 >= 149 # define BOOST_PP_ITERATION_4 149 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 148 && BOOST_PP_ITERATION_START_4 >= 148 # define BOOST_PP_ITERATION_4 148 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 147 && BOOST_PP_ITERATION_START_4 >= 147 # define BOOST_PP_ITERATION_4 147 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 146 && BOOST_PP_ITERATION_START_4 >= 146 # define BOOST_PP_ITERATION_4 146 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 145 && BOOST_PP_ITERATION_START_4 >= 145 # define BOOST_PP_ITERATION_4 145 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 144 && BOOST_PP_ITERATION_START_4 >= 144 # define BOOST_PP_ITERATION_4 144 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 143 && BOOST_PP_ITERATION_START_4 >= 143 # define BOOST_PP_ITERATION_4 143 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 142 && BOOST_PP_ITERATION_START_4 >= 142 # define BOOST_PP_ITERATION_4 142 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 141 && BOOST_PP_ITERATION_START_4 >= 141 # define BOOST_PP_ITERATION_4 141 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 140 && BOOST_PP_ITERATION_START_4 >= 140 # define BOOST_PP_ITERATION_4 140 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 139 && BOOST_PP_ITERATION_START_4 >= 139 # define BOOST_PP_ITERATION_4 139 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 138 && BOOST_PP_ITERATION_START_4 >= 138 # define BOOST_PP_ITERATION_4 138 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 137 && BOOST_PP_ITERATION_START_4 >= 137 # define BOOST_PP_ITERATION_4 137 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 136 && BOOST_PP_ITERATION_START_4 >= 136 # define BOOST_PP_ITERATION_4 136 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 135 && BOOST_PP_ITERATION_START_4 >= 135 # define BOOST_PP_ITERATION_4 135 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 134 && BOOST_PP_ITERATION_START_4 >= 134 # define BOOST_PP_ITERATION_4 134 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 133 && BOOST_PP_ITERATION_START_4 >= 133 # define BOOST_PP_ITERATION_4 133 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 132 && BOOST_PP_ITERATION_START_4 >= 132 # define BOOST_PP_ITERATION_4 132 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 131 && BOOST_PP_ITERATION_START_4 >= 131 # define BOOST_PP_ITERATION_4 131 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 130 && BOOST_PP_ITERATION_START_4 >= 130 # define BOOST_PP_ITERATION_4 130 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 129 && BOOST_PP_ITERATION_START_4 >= 129 # define BOOST_PP_ITERATION_4 129 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 128 && BOOST_PP_ITERATION_START_4 >= 128 # define BOOST_PP_ITERATION_4 128 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 127 && BOOST_PP_ITERATION_START_4 >= 127 # define BOOST_PP_ITERATION_4 127 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 126 && BOOST_PP_ITERATION_START_4 >= 126 # define BOOST_PP_ITERATION_4 126 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 125 && BOOST_PP_ITERATION_START_4 >= 125 # define BOOST_PP_ITERATION_4 125 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 124 && BOOST_PP_ITERATION_START_4 >= 124 # define BOOST_PP_ITERATION_4 124 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 123 && BOOST_PP_ITERATION_START_4 >= 123 # define BOOST_PP_ITERATION_4 123 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 122 && BOOST_PP_ITERATION_START_4 >= 122 # define BOOST_PP_ITERATION_4 122 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 121 && BOOST_PP_ITERATION_START_4 >= 121 # define BOOST_PP_ITERATION_4 121 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 120 && BOOST_PP_ITERATION_START_4 >= 120 # define BOOST_PP_ITERATION_4 120 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 119 && BOOST_PP_ITERATION_START_4 >= 119 # define BOOST_PP_ITERATION_4 119 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 118 && BOOST_PP_ITERATION_START_4 >= 118 # define BOOST_PP_ITERATION_4 118 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 117 && BOOST_PP_ITERATION_START_4 >= 117 # define BOOST_PP_ITERATION_4 117 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 116 && BOOST_PP_ITERATION_START_4 >= 116 # define BOOST_PP_ITERATION_4 116 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 115 && BOOST_PP_ITERATION_START_4 >= 115 # define BOOST_PP_ITERATION_4 115 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 114 && BOOST_PP_ITERATION_START_4 >= 114 # define BOOST_PP_ITERATION_4 114 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 113 && BOOST_PP_ITERATION_START_4 >= 113 # define BOOST_PP_ITERATION_4 113 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 112 && BOOST_PP_ITERATION_START_4 >= 112 # define BOOST_PP_ITERATION_4 112 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 111 && BOOST_PP_ITERATION_START_4 >= 111 # define BOOST_PP_ITERATION_4 111 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 110 && BOOST_PP_ITERATION_START_4 >= 110 # define BOOST_PP_ITERATION_4 110 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 109 && BOOST_PP_ITERATION_START_4 >= 109 # define BOOST_PP_ITERATION_4 109 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 108 && BOOST_PP_ITERATION_START_4 >= 108 # define BOOST_PP_ITERATION_4 108 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 107 && BOOST_PP_ITERATION_START_4 >= 107 # define BOOST_PP_ITERATION_4 107 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 106 && BOOST_PP_ITERATION_START_4 >= 106 # define BOOST_PP_ITERATION_4 106 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 105 && BOOST_PP_ITERATION_START_4 >= 105 # define BOOST_PP_ITERATION_4 105 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 104 && BOOST_PP_ITERATION_START_4 >= 104 # define BOOST_PP_ITERATION_4 104 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 103 && BOOST_PP_ITERATION_START_4 >= 103 # define BOOST_PP_ITERATION_4 103 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 102 && BOOST_PP_ITERATION_START_4 >= 102 # define BOOST_PP_ITERATION_4 102 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 101 && BOOST_PP_ITERATION_START_4 >= 101 # define BOOST_PP_ITERATION_4 101 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 100 && BOOST_PP_ITERATION_START_4 >= 100 # define BOOST_PP_ITERATION_4 100 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 99 && BOOST_PP_ITERATION_START_4 >= 99 # define BOOST_PP_ITERATION_4 99 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 98 && BOOST_PP_ITERATION_START_4 >= 98 # define BOOST_PP_ITERATION_4 98 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 97 && BOOST_PP_ITERATION_START_4 >= 97 # define BOOST_PP_ITERATION_4 97 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 96 && BOOST_PP_ITERATION_START_4 >= 96 # define BOOST_PP_ITERATION_4 96 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 95 && BOOST_PP_ITERATION_START_4 >= 95 # define BOOST_PP_ITERATION_4 95 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 94 && BOOST_PP_ITERATION_START_4 >= 94 # define BOOST_PP_ITERATION_4 94 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 93 && BOOST_PP_ITERATION_START_4 >= 93 # define BOOST_PP_ITERATION_4 93 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 92 && BOOST_PP_ITERATION_START_4 >= 92 # define BOOST_PP_ITERATION_4 92 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 91 && BOOST_PP_ITERATION_START_4 >= 91 # define BOOST_PP_ITERATION_4 91 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 90 && BOOST_PP_ITERATION_START_4 >= 90 # define BOOST_PP_ITERATION_4 90 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 89 && BOOST_PP_ITERATION_START_4 >= 89 # define BOOST_PP_ITERATION_4 89 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 88 && BOOST_PP_ITERATION_START_4 >= 88 # define BOOST_PP_ITERATION_4 88 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 87 && BOOST_PP_ITERATION_START_4 >= 87 # define BOOST_PP_ITERATION_4 87 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 86 && BOOST_PP_ITERATION_START_4 >= 86 # define BOOST_PP_ITERATION_4 86 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 85 && BOOST_PP_ITERATION_START_4 >= 85 # define BOOST_PP_ITERATION_4 85 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 84 && BOOST_PP_ITERATION_START_4 >= 84 # define BOOST_PP_ITERATION_4 84 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 83 && BOOST_PP_ITERATION_START_4 >= 83 # define BOOST_PP_ITERATION_4 83 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 82 && BOOST_PP_ITERATION_START_4 >= 82 # define BOOST_PP_ITERATION_4 82 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 81 && BOOST_PP_ITERATION_START_4 >= 81 # define BOOST_PP_ITERATION_4 81 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 80 && BOOST_PP_ITERATION_START_4 >= 80 # define BOOST_PP_ITERATION_4 80 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 79 && BOOST_PP_ITERATION_START_4 >= 79 # define BOOST_PP_ITERATION_4 79 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 78 && BOOST_PP_ITERATION_START_4 >= 78 # define BOOST_PP_ITERATION_4 78 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 77 && BOOST_PP_ITERATION_START_4 >= 77 # define BOOST_PP_ITERATION_4 77 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 76 && BOOST_PP_ITERATION_START_4 >= 76 # define BOOST_PP_ITERATION_4 76 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 75 && BOOST_PP_ITERATION_START_4 >= 75 # define BOOST_PP_ITERATION_4 75 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 74 && BOOST_PP_ITERATION_START_4 >= 74 # define BOOST_PP_ITERATION_4 74 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 73 && BOOST_PP_ITERATION_START_4 >= 73 # define BOOST_PP_ITERATION_4 73 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 72 && BOOST_PP_ITERATION_START_4 >= 72 # define BOOST_PP_ITERATION_4 72 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 71 && BOOST_PP_ITERATION_START_4 >= 71 # define BOOST_PP_ITERATION_4 71 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 70 && BOOST_PP_ITERATION_START_4 >= 70 # define BOOST_PP_ITERATION_4 70 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 69 && BOOST_PP_ITERATION_START_4 >= 69 # define BOOST_PP_ITERATION_4 69 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 68 && BOOST_PP_ITERATION_START_4 >= 68 # define BOOST_PP_ITERATION_4 68 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 67 && BOOST_PP_ITERATION_START_4 >= 67 # define BOOST_PP_ITERATION_4 67 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 66 && BOOST_PP_ITERATION_START_4 >= 66 # define BOOST_PP_ITERATION_4 66 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 65 && BOOST_PP_ITERATION_START_4 >= 65 # define BOOST_PP_ITERATION_4 65 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 64 && BOOST_PP_ITERATION_START_4 >= 64 # define BOOST_PP_ITERATION_4 64 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 63 && BOOST_PP_ITERATION_START_4 >= 63 # define BOOST_PP_ITERATION_4 63 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 62 && BOOST_PP_ITERATION_START_4 >= 62 # define BOOST_PP_ITERATION_4 62 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 61 && BOOST_PP_ITERATION_START_4 >= 61 # define BOOST_PP_ITERATION_4 61 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 60 && BOOST_PP_ITERATION_START_4 >= 60 # define BOOST_PP_ITERATION_4 60 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 59 && BOOST_PP_ITERATION_START_4 >= 59 # define BOOST_PP_ITERATION_4 59 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 58 && BOOST_PP_ITERATION_START_4 >= 58 # define BOOST_PP_ITERATION_4 58 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 57 && BOOST_PP_ITERATION_START_4 >= 57 # define BOOST_PP_ITERATION_4 57 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 56 && BOOST_PP_ITERATION_START_4 >= 56 # define BOOST_PP_ITERATION_4 56 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 55 && BOOST_PP_ITERATION_START_4 >= 55 # define BOOST_PP_ITERATION_4 55 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 54 && BOOST_PP_ITERATION_START_4 >= 54 # define BOOST_PP_ITERATION_4 54 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 53 && BOOST_PP_ITERATION_START_4 >= 53 # define BOOST_PP_ITERATION_4 53 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 52 && BOOST_PP_ITERATION_START_4 >= 52 # define BOOST_PP_ITERATION_4 52 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 51 && BOOST_PP_ITERATION_START_4 >= 51 # define BOOST_PP_ITERATION_4 51 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 50 && BOOST_PP_ITERATION_START_4 >= 50 # define BOOST_PP_ITERATION_4 50 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 49 && BOOST_PP_ITERATION_START_4 >= 49 # define BOOST_PP_ITERATION_4 49 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 48 && BOOST_PP_ITERATION_START_4 >= 48 # define BOOST_PP_ITERATION_4 48 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 47 && BOOST_PP_ITERATION_START_4 >= 47 # define BOOST_PP_ITERATION_4 47 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 46 && BOOST_PP_ITERATION_START_4 >= 46 # define BOOST_PP_ITERATION_4 46 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 45 && BOOST_PP_ITERATION_START_4 >= 45 # define BOOST_PP_ITERATION_4 45 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 44 && BOOST_PP_ITERATION_START_4 >= 44 # define BOOST_PP_ITERATION_4 44 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 43 && BOOST_PP_ITERATION_START_4 >= 43 # define BOOST_PP_ITERATION_4 43 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 42 && BOOST_PP_ITERATION_START_4 >= 42 # define BOOST_PP_ITERATION_4 42 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 41 && BOOST_PP_ITERATION_START_4 >= 41 # define BOOST_PP_ITERATION_4 41 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 40 && BOOST_PP_ITERATION_START_4 >= 40 # define BOOST_PP_ITERATION_4 40 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 39 && BOOST_PP_ITERATION_START_4 >= 39 # define BOOST_PP_ITERATION_4 39 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 38 && BOOST_PP_ITERATION_START_4 >= 38 # define BOOST_PP_ITERATION_4 38 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 37 && BOOST_PP_ITERATION_START_4 >= 37 # define BOOST_PP_ITERATION_4 37 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 36 && BOOST_PP_ITERATION_START_4 >= 36 # define BOOST_PP_ITERATION_4 36 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 35 && BOOST_PP_ITERATION_START_4 >= 35 # define BOOST_PP_ITERATION_4 35 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 34 && BOOST_PP_ITERATION_START_4 >= 34 # define BOOST_PP_ITERATION_4 34 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 33 && BOOST_PP_ITERATION_START_4 >= 33 # define BOOST_PP_ITERATION_4 33 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 32 && BOOST_PP_ITERATION_START_4 >= 32 # define BOOST_PP_ITERATION_4 32 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 31 && BOOST_PP_ITERATION_START_4 >= 31 # define BOOST_PP_ITERATION_4 31 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 30 && BOOST_PP_ITERATION_START_4 >= 30 # define BOOST_PP_ITERATION_4 30 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 29 && BOOST_PP_ITERATION_START_4 >= 29 # define BOOST_PP_ITERATION_4 29 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 28 && BOOST_PP_ITERATION_START_4 >= 28 # define BOOST_PP_ITERATION_4 28 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 27 && BOOST_PP_ITERATION_START_4 >= 27 # define BOOST_PP_ITERATION_4 27 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 26 && BOOST_PP_ITERATION_START_4 >= 26 # define BOOST_PP_ITERATION_4 26 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 25 && BOOST_PP_ITERATION_START_4 >= 25 # define BOOST_PP_ITERATION_4 25 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 24 && BOOST_PP_ITERATION_START_4 >= 24 # define BOOST_PP_ITERATION_4 24 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 23 && BOOST_PP_ITERATION_START_4 >= 23 # define BOOST_PP_ITERATION_4 23 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 22 && BOOST_PP_ITERATION_START_4 >= 22 # define BOOST_PP_ITERATION_4 22 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 21 && BOOST_PP_ITERATION_START_4 >= 21 # define BOOST_PP_ITERATION_4 21 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 20 && BOOST_PP_ITERATION_START_4 >= 20 # define BOOST_PP_ITERATION_4 20 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 19 && BOOST_PP_ITERATION_START_4 >= 19 # define BOOST_PP_ITERATION_4 19 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 18 && BOOST_PP_ITERATION_START_4 >= 18 # define BOOST_PP_ITERATION_4 18 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 17 && BOOST_PP_ITERATION_START_4 >= 17 # define BOOST_PP_ITERATION_4 17 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 16 && BOOST_PP_ITERATION_START_4 >= 16 # define BOOST_PP_ITERATION_4 16 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 15 && BOOST_PP_ITERATION_START_4 >= 15 # define BOOST_PP_ITERATION_4 15 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 14 && BOOST_PP_ITERATION_START_4 >= 14 # define BOOST_PP_ITERATION_4 14 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 13 && BOOST_PP_ITERATION_START_4 >= 13 # define BOOST_PP_ITERATION_4 13 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 12 && BOOST_PP_ITERATION_START_4 >= 12 # define BOOST_PP_ITERATION_4 12 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 11 && BOOST_PP_ITERATION_START_4 >= 11 # define BOOST_PP_ITERATION_4 11 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 10 && BOOST_PP_ITERATION_START_4 >= 10 # define BOOST_PP_ITERATION_4 10 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 9 && BOOST_PP_ITERATION_START_4 >= 9 # define BOOST_PP_ITERATION_4 9 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 8 && BOOST_PP_ITERATION_START_4 >= 8 # define BOOST_PP_ITERATION_4 8 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 7 && BOOST_PP_ITERATION_START_4 >= 7 # define BOOST_PP_ITERATION_4 7 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 6 && BOOST_PP_ITERATION_START_4 >= 6 # define BOOST_PP_ITERATION_4 6 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 5 && BOOST_PP_ITERATION_START_4 >= 5 # define BOOST_PP_ITERATION_4 5 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 4 && BOOST_PP_ITERATION_START_4 >= 4 # define BOOST_PP_ITERATION_4 4 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 3 && BOOST_PP_ITERATION_START_4 >= 3 # define BOOST_PP_ITERATION_4 3 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 2 && BOOST_PP_ITERATION_START_4 >= 2 # define BOOST_PP_ITERATION_4 2 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 1 && BOOST_PP_ITERATION_START_4 >= 1 # define BOOST_PP_ITERATION_4 1 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif # if BOOST_PP_ITERATION_FINISH_4 <= 0 && BOOST_PP_ITERATION_START_4 >= 0 # define BOOST_PP_ITERATION_4 0 # include BOOST_PP_FILENAME_4 # undef BOOST_PP_ITERATION_4 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/iter/reverse5.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if BOOST_PP_ITERATION_FINISH_5 <= 256 && BOOST_PP_ITERATION_START_5 >= 256 # define BOOST_PP_ITERATION_5 256 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 255 && BOOST_PP_ITERATION_START_5 >= 255 # define BOOST_PP_ITERATION_5 255 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 254 && BOOST_PP_ITERATION_START_5 >= 254 # define BOOST_PP_ITERATION_5 254 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 253 && BOOST_PP_ITERATION_START_5 >= 253 # define BOOST_PP_ITERATION_5 253 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 252 && BOOST_PP_ITERATION_START_5 >= 252 # define BOOST_PP_ITERATION_5 252 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 251 && BOOST_PP_ITERATION_START_5 >= 251 # define BOOST_PP_ITERATION_5 251 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 250 && BOOST_PP_ITERATION_START_5 >= 250 # define BOOST_PP_ITERATION_5 250 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 249 && BOOST_PP_ITERATION_START_5 >= 249 # define BOOST_PP_ITERATION_5 249 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 248 && BOOST_PP_ITERATION_START_5 >= 248 # define BOOST_PP_ITERATION_5 248 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 247 && BOOST_PP_ITERATION_START_5 >= 247 # define BOOST_PP_ITERATION_5 247 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 246 && BOOST_PP_ITERATION_START_5 >= 246 # define BOOST_PP_ITERATION_5 246 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 245 && BOOST_PP_ITERATION_START_5 >= 245 # define BOOST_PP_ITERATION_5 245 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 244 && BOOST_PP_ITERATION_START_5 >= 244 # define BOOST_PP_ITERATION_5 244 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 243 && BOOST_PP_ITERATION_START_5 >= 243 # define BOOST_PP_ITERATION_5 243 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 242 && BOOST_PP_ITERATION_START_5 >= 242 # define BOOST_PP_ITERATION_5 242 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 241 && BOOST_PP_ITERATION_START_5 >= 241 # define BOOST_PP_ITERATION_5 241 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 240 && BOOST_PP_ITERATION_START_5 >= 240 # define BOOST_PP_ITERATION_5 240 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 239 && BOOST_PP_ITERATION_START_5 >= 239 # define BOOST_PP_ITERATION_5 239 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 238 && BOOST_PP_ITERATION_START_5 >= 238 # define BOOST_PP_ITERATION_5 238 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 237 && BOOST_PP_ITERATION_START_5 >= 237 # define BOOST_PP_ITERATION_5 237 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 236 && BOOST_PP_ITERATION_START_5 >= 236 # define BOOST_PP_ITERATION_5 236 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 235 && BOOST_PP_ITERATION_START_5 >= 235 # define BOOST_PP_ITERATION_5 235 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 234 && BOOST_PP_ITERATION_START_5 >= 234 # define BOOST_PP_ITERATION_5 234 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 233 && BOOST_PP_ITERATION_START_5 >= 233 # define BOOST_PP_ITERATION_5 233 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 232 && BOOST_PP_ITERATION_START_5 >= 232 # define BOOST_PP_ITERATION_5 232 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 231 && BOOST_PP_ITERATION_START_5 >= 231 # define BOOST_PP_ITERATION_5 231 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 230 && BOOST_PP_ITERATION_START_5 >= 230 # define BOOST_PP_ITERATION_5 230 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 229 && BOOST_PP_ITERATION_START_5 >= 229 # define BOOST_PP_ITERATION_5 229 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 228 && BOOST_PP_ITERATION_START_5 >= 228 # define BOOST_PP_ITERATION_5 228 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 227 && BOOST_PP_ITERATION_START_5 >= 227 # define BOOST_PP_ITERATION_5 227 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 226 && BOOST_PP_ITERATION_START_5 >= 226 # define BOOST_PP_ITERATION_5 226 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 225 && BOOST_PP_ITERATION_START_5 >= 225 # define BOOST_PP_ITERATION_5 225 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 224 && BOOST_PP_ITERATION_START_5 >= 224 # define BOOST_PP_ITERATION_5 224 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 223 && BOOST_PP_ITERATION_START_5 >= 223 # define BOOST_PP_ITERATION_5 223 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 222 && BOOST_PP_ITERATION_START_5 >= 222 # define BOOST_PP_ITERATION_5 222 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 221 && BOOST_PP_ITERATION_START_5 >= 221 # define BOOST_PP_ITERATION_5 221 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 220 && BOOST_PP_ITERATION_START_5 >= 220 # define BOOST_PP_ITERATION_5 220 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 219 && BOOST_PP_ITERATION_START_5 >= 219 # define BOOST_PP_ITERATION_5 219 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 218 && BOOST_PP_ITERATION_START_5 >= 218 # define BOOST_PP_ITERATION_5 218 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 217 && BOOST_PP_ITERATION_START_5 >= 217 # define BOOST_PP_ITERATION_5 217 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 216 && BOOST_PP_ITERATION_START_5 >= 216 # define BOOST_PP_ITERATION_5 216 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 215 && BOOST_PP_ITERATION_START_5 >= 215 # define BOOST_PP_ITERATION_5 215 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 214 && BOOST_PP_ITERATION_START_5 >= 214 # define BOOST_PP_ITERATION_5 214 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 213 && BOOST_PP_ITERATION_START_5 >= 213 # define BOOST_PP_ITERATION_5 213 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 212 && BOOST_PP_ITERATION_START_5 >= 212 # define BOOST_PP_ITERATION_5 212 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 211 && BOOST_PP_ITERATION_START_5 >= 211 # define BOOST_PP_ITERATION_5 211 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 210 && BOOST_PP_ITERATION_START_5 >= 210 # define BOOST_PP_ITERATION_5 210 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 209 && BOOST_PP_ITERATION_START_5 >= 209 # define BOOST_PP_ITERATION_5 209 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 208 && BOOST_PP_ITERATION_START_5 >= 208 # define BOOST_PP_ITERATION_5 208 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 207 && BOOST_PP_ITERATION_START_5 >= 207 # define BOOST_PP_ITERATION_5 207 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 206 && BOOST_PP_ITERATION_START_5 >= 206 # define BOOST_PP_ITERATION_5 206 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 205 && BOOST_PP_ITERATION_START_5 >= 205 # define BOOST_PP_ITERATION_5 205 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 204 && BOOST_PP_ITERATION_START_5 >= 204 # define BOOST_PP_ITERATION_5 204 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 203 && BOOST_PP_ITERATION_START_5 >= 203 # define BOOST_PP_ITERATION_5 203 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 202 && BOOST_PP_ITERATION_START_5 >= 202 # define BOOST_PP_ITERATION_5 202 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 201 && BOOST_PP_ITERATION_START_5 >= 201 # define BOOST_PP_ITERATION_5 201 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 200 && BOOST_PP_ITERATION_START_5 >= 200 # define BOOST_PP_ITERATION_5 200 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 199 && BOOST_PP_ITERATION_START_5 >= 199 # define BOOST_PP_ITERATION_5 199 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 198 && BOOST_PP_ITERATION_START_5 >= 198 # define BOOST_PP_ITERATION_5 198 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 197 && BOOST_PP_ITERATION_START_5 >= 197 # define BOOST_PP_ITERATION_5 197 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 196 && BOOST_PP_ITERATION_START_5 >= 196 # define BOOST_PP_ITERATION_5 196 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 195 && BOOST_PP_ITERATION_START_5 >= 195 # define BOOST_PP_ITERATION_5 195 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 194 && BOOST_PP_ITERATION_START_5 >= 194 # define BOOST_PP_ITERATION_5 194 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 193 && BOOST_PP_ITERATION_START_5 >= 193 # define BOOST_PP_ITERATION_5 193 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 192 && BOOST_PP_ITERATION_START_5 >= 192 # define BOOST_PP_ITERATION_5 192 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 191 && BOOST_PP_ITERATION_START_5 >= 191 # define BOOST_PP_ITERATION_5 191 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 190 && BOOST_PP_ITERATION_START_5 >= 190 # define BOOST_PP_ITERATION_5 190 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 189 && BOOST_PP_ITERATION_START_5 >= 189 # define BOOST_PP_ITERATION_5 189 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 188 && BOOST_PP_ITERATION_START_5 >= 188 # define BOOST_PP_ITERATION_5 188 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 187 && BOOST_PP_ITERATION_START_5 >= 187 # define BOOST_PP_ITERATION_5 187 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 186 && BOOST_PP_ITERATION_START_5 >= 186 # define BOOST_PP_ITERATION_5 186 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 185 && BOOST_PP_ITERATION_START_5 >= 185 # define BOOST_PP_ITERATION_5 185 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 184 && BOOST_PP_ITERATION_START_5 >= 184 # define BOOST_PP_ITERATION_5 184 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 183 && BOOST_PP_ITERATION_START_5 >= 183 # define BOOST_PP_ITERATION_5 183 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 182 && BOOST_PP_ITERATION_START_5 >= 182 # define BOOST_PP_ITERATION_5 182 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 181 && BOOST_PP_ITERATION_START_5 >= 181 # define BOOST_PP_ITERATION_5 181 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 180 && BOOST_PP_ITERATION_START_5 >= 180 # define BOOST_PP_ITERATION_5 180 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 179 && BOOST_PP_ITERATION_START_5 >= 179 # define BOOST_PP_ITERATION_5 179 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 178 && BOOST_PP_ITERATION_START_5 >= 178 # define BOOST_PP_ITERATION_5 178 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 177 && BOOST_PP_ITERATION_START_5 >= 177 # define BOOST_PP_ITERATION_5 177 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 176 && BOOST_PP_ITERATION_START_5 >= 176 # define BOOST_PP_ITERATION_5 176 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 175 && BOOST_PP_ITERATION_START_5 >= 175 # define BOOST_PP_ITERATION_5 175 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 174 && BOOST_PP_ITERATION_START_5 >= 174 # define BOOST_PP_ITERATION_5 174 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 173 && BOOST_PP_ITERATION_START_5 >= 173 # define BOOST_PP_ITERATION_5 173 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 172 && BOOST_PP_ITERATION_START_5 >= 172 # define BOOST_PP_ITERATION_5 172 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 171 && BOOST_PP_ITERATION_START_5 >= 171 # define BOOST_PP_ITERATION_5 171 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 170 && BOOST_PP_ITERATION_START_5 >= 170 # define BOOST_PP_ITERATION_5 170 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 169 && BOOST_PP_ITERATION_START_5 >= 169 # define BOOST_PP_ITERATION_5 169 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 168 && BOOST_PP_ITERATION_START_5 >= 168 # define BOOST_PP_ITERATION_5 168 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 167 && BOOST_PP_ITERATION_START_5 >= 167 # define BOOST_PP_ITERATION_5 167 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 166 && BOOST_PP_ITERATION_START_5 >= 166 # define BOOST_PP_ITERATION_5 166 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 165 && BOOST_PP_ITERATION_START_5 >= 165 # define BOOST_PP_ITERATION_5 165 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 164 && BOOST_PP_ITERATION_START_5 >= 164 # define BOOST_PP_ITERATION_5 164 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 163 && BOOST_PP_ITERATION_START_5 >= 163 # define BOOST_PP_ITERATION_5 163 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 162 && BOOST_PP_ITERATION_START_5 >= 162 # define BOOST_PP_ITERATION_5 162 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 161 && BOOST_PP_ITERATION_START_5 >= 161 # define BOOST_PP_ITERATION_5 161 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 160 && BOOST_PP_ITERATION_START_5 >= 160 # define BOOST_PP_ITERATION_5 160 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 159 && BOOST_PP_ITERATION_START_5 >= 159 # define BOOST_PP_ITERATION_5 159 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 158 && BOOST_PP_ITERATION_START_5 >= 158 # define BOOST_PP_ITERATION_5 158 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 157 && BOOST_PP_ITERATION_START_5 >= 157 # define BOOST_PP_ITERATION_5 157 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 156 && BOOST_PP_ITERATION_START_5 >= 156 # define BOOST_PP_ITERATION_5 156 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 155 && BOOST_PP_ITERATION_START_5 >= 155 # define BOOST_PP_ITERATION_5 155 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 154 && BOOST_PP_ITERATION_START_5 >= 154 # define BOOST_PP_ITERATION_5 154 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 153 && BOOST_PP_ITERATION_START_5 >= 153 # define BOOST_PP_ITERATION_5 153 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 152 && BOOST_PP_ITERATION_START_5 >= 152 # define BOOST_PP_ITERATION_5 152 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 151 && BOOST_PP_ITERATION_START_5 >= 151 # define BOOST_PP_ITERATION_5 151 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 150 && BOOST_PP_ITERATION_START_5 >= 150 # define BOOST_PP_ITERATION_5 150 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 149 && BOOST_PP_ITERATION_START_5 >= 149 # define BOOST_PP_ITERATION_5 149 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 148 && BOOST_PP_ITERATION_START_5 >= 148 # define BOOST_PP_ITERATION_5 148 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 147 && BOOST_PP_ITERATION_START_5 >= 147 # define BOOST_PP_ITERATION_5 147 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 146 && BOOST_PP_ITERATION_START_5 >= 146 # define BOOST_PP_ITERATION_5 146 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 145 && BOOST_PP_ITERATION_START_5 >= 145 # define BOOST_PP_ITERATION_5 145 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 144 && BOOST_PP_ITERATION_START_5 >= 144 # define BOOST_PP_ITERATION_5 144 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 143 && BOOST_PP_ITERATION_START_5 >= 143 # define BOOST_PP_ITERATION_5 143 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 142 && BOOST_PP_ITERATION_START_5 >= 142 # define BOOST_PP_ITERATION_5 142 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 141 && BOOST_PP_ITERATION_START_5 >= 141 # define BOOST_PP_ITERATION_5 141 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 140 && BOOST_PP_ITERATION_START_5 >= 140 # define BOOST_PP_ITERATION_5 140 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 139 && BOOST_PP_ITERATION_START_5 >= 139 # define BOOST_PP_ITERATION_5 139 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 138 && BOOST_PP_ITERATION_START_5 >= 138 # define BOOST_PP_ITERATION_5 138 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 137 && BOOST_PP_ITERATION_START_5 >= 137 # define BOOST_PP_ITERATION_5 137 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 136 && BOOST_PP_ITERATION_START_5 >= 136 # define BOOST_PP_ITERATION_5 136 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 135 && BOOST_PP_ITERATION_START_5 >= 135 # define BOOST_PP_ITERATION_5 135 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 134 && BOOST_PP_ITERATION_START_5 >= 134 # define BOOST_PP_ITERATION_5 134 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 133 && BOOST_PP_ITERATION_START_5 >= 133 # define BOOST_PP_ITERATION_5 133 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 132 && BOOST_PP_ITERATION_START_5 >= 132 # define BOOST_PP_ITERATION_5 132 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 131 && BOOST_PP_ITERATION_START_5 >= 131 # define BOOST_PP_ITERATION_5 131 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 130 && BOOST_PP_ITERATION_START_5 >= 130 # define BOOST_PP_ITERATION_5 130 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 129 && BOOST_PP_ITERATION_START_5 >= 129 # define BOOST_PP_ITERATION_5 129 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 128 && BOOST_PP_ITERATION_START_5 >= 128 # define BOOST_PP_ITERATION_5 128 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 127 && BOOST_PP_ITERATION_START_5 >= 127 # define BOOST_PP_ITERATION_5 127 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 126 && BOOST_PP_ITERATION_START_5 >= 126 # define BOOST_PP_ITERATION_5 126 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 125 && BOOST_PP_ITERATION_START_5 >= 125 # define BOOST_PP_ITERATION_5 125 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 124 && BOOST_PP_ITERATION_START_5 >= 124 # define BOOST_PP_ITERATION_5 124 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 123 && BOOST_PP_ITERATION_START_5 >= 123 # define BOOST_PP_ITERATION_5 123 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 122 && BOOST_PP_ITERATION_START_5 >= 122 # define BOOST_PP_ITERATION_5 122 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 121 && BOOST_PP_ITERATION_START_5 >= 121 # define BOOST_PP_ITERATION_5 121 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 120 && BOOST_PP_ITERATION_START_5 >= 120 # define BOOST_PP_ITERATION_5 120 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 119 && BOOST_PP_ITERATION_START_5 >= 119 # define BOOST_PP_ITERATION_5 119 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 118 && BOOST_PP_ITERATION_START_5 >= 118 # define BOOST_PP_ITERATION_5 118 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 117 && BOOST_PP_ITERATION_START_5 >= 117 # define BOOST_PP_ITERATION_5 117 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 116 && BOOST_PP_ITERATION_START_5 >= 116 # define BOOST_PP_ITERATION_5 116 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 115 && BOOST_PP_ITERATION_START_5 >= 115 # define BOOST_PP_ITERATION_5 115 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 114 && BOOST_PP_ITERATION_START_5 >= 114 # define BOOST_PP_ITERATION_5 114 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 113 && BOOST_PP_ITERATION_START_5 >= 113 # define BOOST_PP_ITERATION_5 113 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 112 && BOOST_PP_ITERATION_START_5 >= 112 # define BOOST_PP_ITERATION_5 112 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 111 && BOOST_PP_ITERATION_START_5 >= 111 # define BOOST_PP_ITERATION_5 111 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 110 && BOOST_PP_ITERATION_START_5 >= 110 # define BOOST_PP_ITERATION_5 110 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 109 && BOOST_PP_ITERATION_START_5 >= 109 # define BOOST_PP_ITERATION_5 109 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 108 && BOOST_PP_ITERATION_START_5 >= 108 # define BOOST_PP_ITERATION_5 108 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 107 && BOOST_PP_ITERATION_START_5 >= 107 # define BOOST_PP_ITERATION_5 107 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 106 && BOOST_PP_ITERATION_START_5 >= 106 # define BOOST_PP_ITERATION_5 106 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 105 && BOOST_PP_ITERATION_START_5 >= 105 # define BOOST_PP_ITERATION_5 105 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 104 && BOOST_PP_ITERATION_START_5 >= 104 # define BOOST_PP_ITERATION_5 104 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 103 && BOOST_PP_ITERATION_START_5 >= 103 # define BOOST_PP_ITERATION_5 103 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 102 && BOOST_PP_ITERATION_START_5 >= 102 # define BOOST_PP_ITERATION_5 102 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 101 && BOOST_PP_ITERATION_START_5 >= 101 # define BOOST_PP_ITERATION_5 101 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 100 && BOOST_PP_ITERATION_START_5 >= 100 # define BOOST_PP_ITERATION_5 100 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 99 && BOOST_PP_ITERATION_START_5 >= 99 # define BOOST_PP_ITERATION_5 99 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 98 && BOOST_PP_ITERATION_START_5 >= 98 # define BOOST_PP_ITERATION_5 98 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 97 && BOOST_PP_ITERATION_START_5 >= 97 # define BOOST_PP_ITERATION_5 97 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 96 && BOOST_PP_ITERATION_START_5 >= 96 # define BOOST_PP_ITERATION_5 96 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 95 && BOOST_PP_ITERATION_START_5 >= 95 # define BOOST_PP_ITERATION_5 95 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 94 && BOOST_PP_ITERATION_START_5 >= 94 # define BOOST_PP_ITERATION_5 94 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 93 && BOOST_PP_ITERATION_START_5 >= 93 # define BOOST_PP_ITERATION_5 93 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 92 && BOOST_PP_ITERATION_START_5 >= 92 # define BOOST_PP_ITERATION_5 92 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 91 && BOOST_PP_ITERATION_START_5 >= 91 # define BOOST_PP_ITERATION_5 91 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 90 && BOOST_PP_ITERATION_START_5 >= 90 # define BOOST_PP_ITERATION_5 90 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 89 && BOOST_PP_ITERATION_START_5 >= 89 # define BOOST_PP_ITERATION_5 89 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 88 && BOOST_PP_ITERATION_START_5 >= 88 # define BOOST_PP_ITERATION_5 88 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 87 && BOOST_PP_ITERATION_START_5 >= 87 # define BOOST_PP_ITERATION_5 87 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 86 && BOOST_PP_ITERATION_START_5 >= 86 # define BOOST_PP_ITERATION_5 86 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 85 && BOOST_PP_ITERATION_START_5 >= 85 # define BOOST_PP_ITERATION_5 85 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 84 && BOOST_PP_ITERATION_START_5 >= 84 # define BOOST_PP_ITERATION_5 84 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 83 && BOOST_PP_ITERATION_START_5 >= 83 # define BOOST_PP_ITERATION_5 83 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 82 && BOOST_PP_ITERATION_START_5 >= 82 # define BOOST_PP_ITERATION_5 82 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 81 && BOOST_PP_ITERATION_START_5 >= 81 # define BOOST_PP_ITERATION_5 81 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 80 && BOOST_PP_ITERATION_START_5 >= 80 # define BOOST_PP_ITERATION_5 80 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 79 && BOOST_PP_ITERATION_START_5 >= 79 # define BOOST_PP_ITERATION_5 79 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 78 && BOOST_PP_ITERATION_START_5 >= 78 # define BOOST_PP_ITERATION_5 78 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 77 && BOOST_PP_ITERATION_START_5 >= 77 # define BOOST_PP_ITERATION_5 77 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 76 && BOOST_PP_ITERATION_START_5 >= 76 # define BOOST_PP_ITERATION_5 76 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 75 && BOOST_PP_ITERATION_START_5 >= 75 # define BOOST_PP_ITERATION_5 75 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 74 && BOOST_PP_ITERATION_START_5 >= 74 # define BOOST_PP_ITERATION_5 74 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 73 && BOOST_PP_ITERATION_START_5 >= 73 # define BOOST_PP_ITERATION_5 73 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 72 && BOOST_PP_ITERATION_START_5 >= 72 # define BOOST_PP_ITERATION_5 72 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 71 && BOOST_PP_ITERATION_START_5 >= 71 # define BOOST_PP_ITERATION_5 71 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 70 && BOOST_PP_ITERATION_START_5 >= 70 # define BOOST_PP_ITERATION_5 70 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 69 && BOOST_PP_ITERATION_START_5 >= 69 # define BOOST_PP_ITERATION_5 69 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 68 && BOOST_PP_ITERATION_START_5 >= 68 # define BOOST_PP_ITERATION_5 68 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 67 && BOOST_PP_ITERATION_START_5 >= 67 # define BOOST_PP_ITERATION_5 67 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 66 && BOOST_PP_ITERATION_START_5 >= 66 # define BOOST_PP_ITERATION_5 66 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 65 && BOOST_PP_ITERATION_START_5 >= 65 # define BOOST_PP_ITERATION_5 65 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 64 && BOOST_PP_ITERATION_START_5 >= 64 # define BOOST_PP_ITERATION_5 64 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 63 && BOOST_PP_ITERATION_START_5 >= 63 # define BOOST_PP_ITERATION_5 63 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 62 && BOOST_PP_ITERATION_START_5 >= 62 # define BOOST_PP_ITERATION_5 62 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 61 && BOOST_PP_ITERATION_START_5 >= 61 # define BOOST_PP_ITERATION_5 61 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 60 && BOOST_PP_ITERATION_START_5 >= 60 # define BOOST_PP_ITERATION_5 60 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 59 && BOOST_PP_ITERATION_START_5 >= 59 # define BOOST_PP_ITERATION_5 59 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 58 && BOOST_PP_ITERATION_START_5 >= 58 # define BOOST_PP_ITERATION_5 58 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 57 && BOOST_PP_ITERATION_START_5 >= 57 # define BOOST_PP_ITERATION_5 57 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 56 && BOOST_PP_ITERATION_START_5 >= 56 # define BOOST_PP_ITERATION_5 56 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 55 && BOOST_PP_ITERATION_START_5 >= 55 # define BOOST_PP_ITERATION_5 55 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 54 && BOOST_PP_ITERATION_START_5 >= 54 # define BOOST_PP_ITERATION_5 54 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 53 && BOOST_PP_ITERATION_START_5 >= 53 # define BOOST_PP_ITERATION_5 53 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 52 && BOOST_PP_ITERATION_START_5 >= 52 # define BOOST_PP_ITERATION_5 52 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 51 && BOOST_PP_ITERATION_START_5 >= 51 # define BOOST_PP_ITERATION_5 51 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 50 && BOOST_PP_ITERATION_START_5 >= 50 # define BOOST_PP_ITERATION_5 50 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 49 && BOOST_PP_ITERATION_START_5 >= 49 # define BOOST_PP_ITERATION_5 49 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 48 && BOOST_PP_ITERATION_START_5 >= 48 # define BOOST_PP_ITERATION_5 48 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 47 && BOOST_PP_ITERATION_START_5 >= 47 # define BOOST_PP_ITERATION_5 47 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 46 && BOOST_PP_ITERATION_START_5 >= 46 # define BOOST_PP_ITERATION_5 46 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 45 && BOOST_PP_ITERATION_START_5 >= 45 # define BOOST_PP_ITERATION_5 45 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 44 && BOOST_PP_ITERATION_START_5 >= 44 # define BOOST_PP_ITERATION_5 44 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 43 && BOOST_PP_ITERATION_START_5 >= 43 # define BOOST_PP_ITERATION_5 43 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 42 && BOOST_PP_ITERATION_START_5 >= 42 # define BOOST_PP_ITERATION_5 42 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 41 && BOOST_PP_ITERATION_START_5 >= 41 # define BOOST_PP_ITERATION_5 41 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 40 && BOOST_PP_ITERATION_START_5 >= 40 # define BOOST_PP_ITERATION_5 40 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 39 && BOOST_PP_ITERATION_START_5 >= 39 # define BOOST_PP_ITERATION_5 39 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 38 && BOOST_PP_ITERATION_START_5 >= 38 # define BOOST_PP_ITERATION_5 38 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 37 && BOOST_PP_ITERATION_START_5 >= 37 # define BOOST_PP_ITERATION_5 37 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 36 && BOOST_PP_ITERATION_START_5 >= 36 # define BOOST_PP_ITERATION_5 36 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 35 && BOOST_PP_ITERATION_START_5 >= 35 # define BOOST_PP_ITERATION_5 35 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 34 && BOOST_PP_ITERATION_START_5 >= 34 # define BOOST_PP_ITERATION_5 34 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 33 && BOOST_PP_ITERATION_START_5 >= 33 # define BOOST_PP_ITERATION_5 33 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 32 && BOOST_PP_ITERATION_START_5 >= 32 # define BOOST_PP_ITERATION_5 32 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 31 && BOOST_PP_ITERATION_START_5 >= 31 # define BOOST_PP_ITERATION_5 31 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 30 && BOOST_PP_ITERATION_START_5 >= 30 # define BOOST_PP_ITERATION_5 30 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 29 && BOOST_PP_ITERATION_START_5 >= 29 # define BOOST_PP_ITERATION_5 29 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 28 && BOOST_PP_ITERATION_START_5 >= 28 # define BOOST_PP_ITERATION_5 28 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 27 && BOOST_PP_ITERATION_START_5 >= 27 # define BOOST_PP_ITERATION_5 27 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 26 && BOOST_PP_ITERATION_START_5 >= 26 # define BOOST_PP_ITERATION_5 26 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 25 && BOOST_PP_ITERATION_START_5 >= 25 # define BOOST_PP_ITERATION_5 25 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 24 && BOOST_PP_ITERATION_START_5 >= 24 # define BOOST_PP_ITERATION_5 24 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 23 && BOOST_PP_ITERATION_START_5 >= 23 # define BOOST_PP_ITERATION_5 23 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 22 && BOOST_PP_ITERATION_START_5 >= 22 # define BOOST_PP_ITERATION_5 22 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 21 && BOOST_PP_ITERATION_START_5 >= 21 # define BOOST_PP_ITERATION_5 21 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 20 && BOOST_PP_ITERATION_START_5 >= 20 # define BOOST_PP_ITERATION_5 20 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 19 && BOOST_PP_ITERATION_START_5 >= 19 # define BOOST_PP_ITERATION_5 19 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 18 && BOOST_PP_ITERATION_START_5 >= 18 # define BOOST_PP_ITERATION_5 18 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 17 && BOOST_PP_ITERATION_START_5 >= 17 # define BOOST_PP_ITERATION_5 17 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 16 && BOOST_PP_ITERATION_START_5 >= 16 # define BOOST_PP_ITERATION_5 16 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 15 && BOOST_PP_ITERATION_START_5 >= 15 # define BOOST_PP_ITERATION_5 15 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 14 && BOOST_PP_ITERATION_START_5 >= 14 # define BOOST_PP_ITERATION_5 14 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 13 && BOOST_PP_ITERATION_START_5 >= 13 # define BOOST_PP_ITERATION_5 13 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 12 && BOOST_PP_ITERATION_START_5 >= 12 # define BOOST_PP_ITERATION_5 12 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 11 && BOOST_PP_ITERATION_START_5 >= 11 # define BOOST_PP_ITERATION_5 11 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 10 && BOOST_PP_ITERATION_START_5 >= 10 # define BOOST_PP_ITERATION_5 10 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 9 && BOOST_PP_ITERATION_START_5 >= 9 # define BOOST_PP_ITERATION_5 9 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 8 && BOOST_PP_ITERATION_START_5 >= 8 # define BOOST_PP_ITERATION_5 8 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 7 && BOOST_PP_ITERATION_START_5 >= 7 # define BOOST_PP_ITERATION_5 7 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 6 && BOOST_PP_ITERATION_START_5 >= 6 # define BOOST_PP_ITERATION_5 6 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 5 && BOOST_PP_ITERATION_START_5 >= 5 # define BOOST_PP_ITERATION_5 5 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 4 && BOOST_PP_ITERATION_START_5 >= 4 # define BOOST_PP_ITERATION_5 4 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 3 && BOOST_PP_ITERATION_START_5 >= 3 # define BOOST_PP_ITERATION_5 3 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 2 && BOOST_PP_ITERATION_START_5 >= 2 # define BOOST_PP_ITERATION_5 2 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 1 && BOOST_PP_ITERATION_START_5 >= 1 # define BOOST_PP_ITERATION_5 1 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif # if BOOST_PP_ITERATION_FINISH_5 <= 0 && BOOST_PP_ITERATION_START_5 >= 0 # define BOOST_PP_ITERATION_5 0 # include BOOST_PP_FILENAME_5 # undef BOOST_PP_ITERATION_5 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/local.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if !defined(BOOST_PP_LOCAL_LIMITS) # error BOOST_PP_ERROR: local iteration boundaries are not defined # elif !defined(BOOST_PP_LOCAL_MACRO) # error BOOST_PP_ERROR: local iteration target macro is not defined # else # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_LOCAL_S BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_LOCAL_LIMITS) # define BOOST_PP_LOCAL_F BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_LOCAL_LIMITS) # else # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_LOCAL_LIMITS) # include # define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_LOCAL_LIMITS) # include # define BOOST_PP_LOCAL_S BOOST_PP_LOCAL_SE() # define BOOST_PP_LOCAL_F BOOST_PP_LOCAL_FE() # endif # endif # # if (BOOST_PP_LOCAL_S) > (BOOST_PP_LOCAL_F) # include # else # if BOOST_PP_LOCAL_C(0) BOOST_PP_LOCAL_MACRO(0) # endif # if BOOST_PP_LOCAL_C(1) BOOST_PP_LOCAL_MACRO(1) # endif # if BOOST_PP_LOCAL_C(2) BOOST_PP_LOCAL_MACRO(2) # endif # if BOOST_PP_LOCAL_C(3) BOOST_PP_LOCAL_MACRO(3) # endif # if BOOST_PP_LOCAL_C(4) BOOST_PP_LOCAL_MACRO(4) # endif # if BOOST_PP_LOCAL_C(5) BOOST_PP_LOCAL_MACRO(5) # endif # if BOOST_PP_LOCAL_C(6) BOOST_PP_LOCAL_MACRO(6) # endif # if BOOST_PP_LOCAL_C(7) BOOST_PP_LOCAL_MACRO(7) # endif # if BOOST_PP_LOCAL_C(8) BOOST_PP_LOCAL_MACRO(8) # endif # if BOOST_PP_LOCAL_C(9) BOOST_PP_LOCAL_MACRO(9) # endif # if BOOST_PP_LOCAL_C(10) BOOST_PP_LOCAL_MACRO(10) # endif # if BOOST_PP_LOCAL_C(11) BOOST_PP_LOCAL_MACRO(11) # endif # if BOOST_PP_LOCAL_C(12) BOOST_PP_LOCAL_MACRO(12) # endif # if BOOST_PP_LOCAL_C(13) BOOST_PP_LOCAL_MACRO(13) # endif # if BOOST_PP_LOCAL_C(14) BOOST_PP_LOCAL_MACRO(14) # endif # if BOOST_PP_LOCAL_C(15) BOOST_PP_LOCAL_MACRO(15) # endif # if BOOST_PP_LOCAL_C(16) BOOST_PP_LOCAL_MACRO(16) # endif # if BOOST_PP_LOCAL_C(17) BOOST_PP_LOCAL_MACRO(17) # endif # if BOOST_PP_LOCAL_C(18) BOOST_PP_LOCAL_MACRO(18) # endif # if BOOST_PP_LOCAL_C(19) BOOST_PP_LOCAL_MACRO(19) # endif # if BOOST_PP_LOCAL_C(20) BOOST_PP_LOCAL_MACRO(20) # endif # if BOOST_PP_LOCAL_C(21) BOOST_PP_LOCAL_MACRO(21) # endif # if BOOST_PP_LOCAL_C(22) BOOST_PP_LOCAL_MACRO(22) # endif # if BOOST_PP_LOCAL_C(23) BOOST_PP_LOCAL_MACRO(23) # endif # if BOOST_PP_LOCAL_C(24) BOOST_PP_LOCAL_MACRO(24) # endif # if BOOST_PP_LOCAL_C(25) BOOST_PP_LOCAL_MACRO(25) # endif # if BOOST_PP_LOCAL_C(26) BOOST_PP_LOCAL_MACRO(26) # endif # if BOOST_PP_LOCAL_C(27) BOOST_PP_LOCAL_MACRO(27) # endif # if BOOST_PP_LOCAL_C(28) BOOST_PP_LOCAL_MACRO(28) # endif # if BOOST_PP_LOCAL_C(29) BOOST_PP_LOCAL_MACRO(29) # endif # if BOOST_PP_LOCAL_C(30) BOOST_PP_LOCAL_MACRO(30) # endif # if BOOST_PP_LOCAL_C(31) BOOST_PP_LOCAL_MACRO(31) # endif # if BOOST_PP_LOCAL_C(32) BOOST_PP_LOCAL_MACRO(32) # endif # if BOOST_PP_LOCAL_C(33) BOOST_PP_LOCAL_MACRO(33) # endif # if BOOST_PP_LOCAL_C(34) BOOST_PP_LOCAL_MACRO(34) # endif # if BOOST_PP_LOCAL_C(35) BOOST_PP_LOCAL_MACRO(35) # endif # if BOOST_PP_LOCAL_C(36) BOOST_PP_LOCAL_MACRO(36) # endif # if BOOST_PP_LOCAL_C(37) BOOST_PP_LOCAL_MACRO(37) # endif # if BOOST_PP_LOCAL_C(38) BOOST_PP_LOCAL_MACRO(38) # endif # if BOOST_PP_LOCAL_C(39) BOOST_PP_LOCAL_MACRO(39) # endif # if BOOST_PP_LOCAL_C(40) BOOST_PP_LOCAL_MACRO(40) # endif # if BOOST_PP_LOCAL_C(41) BOOST_PP_LOCAL_MACRO(41) # endif # if BOOST_PP_LOCAL_C(42) BOOST_PP_LOCAL_MACRO(42) # endif # if BOOST_PP_LOCAL_C(43) BOOST_PP_LOCAL_MACRO(43) # endif # if BOOST_PP_LOCAL_C(44) BOOST_PP_LOCAL_MACRO(44) # endif # if BOOST_PP_LOCAL_C(45) BOOST_PP_LOCAL_MACRO(45) # endif # if BOOST_PP_LOCAL_C(46) BOOST_PP_LOCAL_MACRO(46) # endif # if BOOST_PP_LOCAL_C(47) BOOST_PP_LOCAL_MACRO(47) # endif # if BOOST_PP_LOCAL_C(48) BOOST_PP_LOCAL_MACRO(48) # endif # if BOOST_PP_LOCAL_C(49) BOOST_PP_LOCAL_MACRO(49) # endif # if BOOST_PP_LOCAL_C(50) BOOST_PP_LOCAL_MACRO(50) # endif # if BOOST_PP_LOCAL_C(51) BOOST_PP_LOCAL_MACRO(51) # endif # if BOOST_PP_LOCAL_C(52) BOOST_PP_LOCAL_MACRO(52) # endif # if BOOST_PP_LOCAL_C(53) BOOST_PP_LOCAL_MACRO(53) # endif # if BOOST_PP_LOCAL_C(54) BOOST_PP_LOCAL_MACRO(54) # endif # if BOOST_PP_LOCAL_C(55) BOOST_PP_LOCAL_MACRO(55) # endif # if BOOST_PP_LOCAL_C(56) BOOST_PP_LOCAL_MACRO(56) # endif # if BOOST_PP_LOCAL_C(57) BOOST_PP_LOCAL_MACRO(57) # endif # if BOOST_PP_LOCAL_C(58) BOOST_PP_LOCAL_MACRO(58) # endif # if BOOST_PP_LOCAL_C(59) BOOST_PP_LOCAL_MACRO(59) # endif # if BOOST_PP_LOCAL_C(60) BOOST_PP_LOCAL_MACRO(60) # endif # if BOOST_PP_LOCAL_C(61) BOOST_PP_LOCAL_MACRO(61) # endif # if BOOST_PP_LOCAL_C(62) BOOST_PP_LOCAL_MACRO(62) # endif # if BOOST_PP_LOCAL_C(63) BOOST_PP_LOCAL_MACRO(63) # endif # if BOOST_PP_LOCAL_C(64) BOOST_PP_LOCAL_MACRO(64) # endif # if BOOST_PP_LOCAL_C(65) BOOST_PP_LOCAL_MACRO(65) # endif # if BOOST_PP_LOCAL_C(66) BOOST_PP_LOCAL_MACRO(66) # endif # if BOOST_PP_LOCAL_C(67) BOOST_PP_LOCAL_MACRO(67) # endif # if BOOST_PP_LOCAL_C(68) BOOST_PP_LOCAL_MACRO(68) # endif # if BOOST_PP_LOCAL_C(69) BOOST_PP_LOCAL_MACRO(69) # endif # if BOOST_PP_LOCAL_C(70) BOOST_PP_LOCAL_MACRO(70) # endif # if BOOST_PP_LOCAL_C(71) BOOST_PP_LOCAL_MACRO(71) # endif # if BOOST_PP_LOCAL_C(72) BOOST_PP_LOCAL_MACRO(72) # endif # if BOOST_PP_LOCAL_C(73) BOOST_PP_LOCAL_MACRO(73) # endif # if BOOST_PP_LOCAL_C(74) BOOST_PP_LOCAL_MACRO(74) # endif # if BOOST_PP_LOCAL_C(75) BOOST_PP_LOCAL_MACRO(75) # endif # if BOOST_PP_LOCAL_C(76) BOOST_PP_LOCAL_MACRO(76) # endif # if BOOST_PP_LOCAL_C(77) BOOST_PP_LOCAL_MACRO(77) # endif # if BOOST_PP_LOCAL_C(78) BOOST_PP_LOCAL_MACRO(78) # endif # if BOOST_PP_LOCAL_C(79) BOOST_PP_LOCAL_MACRO(79) # endif # if BOOST_PP_LOCAL_C(80) BOOST_PP_LOCAL_MACRO(80) # endif # if BOOST_PP_LOCAL_C(81) BOOST_PP_LOCAL_MACRO(81) # endif # if BOOST_PP_LOCAL_C(82) BOOST_PP_LOCAL_MACRO(82) # endif # if BOOST_PP_LOCAL_C(83) BOOST_PP_LOCAL_MACRO(83) # endif # if BOOST_PP_LOCAL_C(84) BOOST_PP_LOCAL_MACRO(84) # endif # if BOOST_PP_LOCAL_C(85) BOOST_PP_LOCAL_MACRO(85) # endif # if BOOST_PP_LOCAL_C(86) BOOST_PP_LOCAL_MACRO(86) # endif # if BOOST_PP_LOCAL_C(87) BOOST_PP_LOCAL_MACRO(87) # endif # if BOOST_PP_LOCAL_C(88) BOOST_PP_LOCAL_MACRO(88) # endif # if BOOST_PP_LOCAL_C(89) BOOST_PP_LOCAL_MACRO(89) # endif # if BOOST_PP_LOCAL_C(90) BOOST_PP_LOCAL_MACRO(90) # endif # if BOOST_PP_LOCAL_C(91) BOOST_PP_LOCAL_MACRO(91) # endif # if BOOST_PP_LOCAL_C(92) BOOST_PP_LOCAL_MACRO(92) # endif # if BOOST_PP_LOCAL_C(93) BOOST_PP_LOCAL_MACRO(93) # endif # if BOOST_PP_LOCAL_C(94) BOOST_PP_LOCAL_MACRO(94) # endif # if BOOST_PP_LOCAL_C(95) BOOST_PP_LOCAL_MACRO(95) # endif # if BOOST_PP_LOCAL_C(96) BOOST_PP_LOCAL_MACRO(96) # endif # if BOOST_PP_LOCAL_C(97) BOOST_PP_LOCAL_MACRO(97) # endif # if BOOST_PP_LOCAL_C(98) BOOST_PP_LOCAL_MACRO(98) # endif # if BOOST_PP_LOCAL_C(99) BOOST_PP_LOCAL_MACRO(99) # endif # if BOOST_PP_LOCAL_C(100) BOOST_PP_LOCAL_MACRO(100) # endif # if BOOST_PP_LOCAL_C(101) BOOST_PP_LOCAL_MACRO(101) # endif # if BOOST_PP_LOCAL_C(102) BOOST_PP_LOCAL_MACRO(102) # endif # if BOOST_PP_LOCAL_C(103) BOOST_PP_LOCAL_MACRO(103) # endif # if BOOST_PP_LOCAL_C(104) BOOST_PP_LOCAL_MACRO(104) # endif # if BOOST_PP_LOCAL_C(105) BOOST_PP_LOCAL_MACRO(105) # endif # if BOOST_PP_LOCAL_C(106) BOOST_PP_LOCAL_MACRO(106) # endif # if BOOST_PP_LOCAL_C(107) BOOST_PP_LOCAL_MACRO(107) # endif # if BOOST_PP_LOCAL_C(108) BOOST_PP_LOCAL_MACRO(108) # endif # if BOOST_PP_LOCAL_C(109) BOOST_PP_LOCAL_MACRO(109) # endif # if BOOST_PP_LOCAL_C(110) BOOST_PP_LOCAL_MACRO(110) # endif # if BOOST_PP_LOCAL_C(111) BOOST_PP_LOCAL_MACRO(111) # endif # if BOOST_PP_LOCAL_C(112) BOOST_PP_LOCAL_MACRO(112) # endif # if BOOST_PP_LOCAL_C(113) BOOST_PP_LOCAL_MACRO(113) # endif # if BOOST_PP_LOCAL_C(114) BOOST_PP_LOCAL_MACRO(114) # endif # if BOOST_PP_LOCAL_C(115) BOOST_PP_LOCAL_MACRO(115) # endif # if BOOST_PP_LOCAL_C(116) BOOST_PP_LOCAL_MACRO(116) # endif # if BOOST_PP_LOCAL_C(117) BOOST_PP_LOCAL_MACRO(117) # endif # if BOOST_PP_LOCAL_C(118) BOOST_PP_LOCAL_MACRO(118) # endif # if BOOST_PP_LOCAL_C(119) BOOST_PP_LOCAL_MACRO(119) # endif # if BOOST_PP_LOCAL_C(120) BOOST_PP_LOCAL_MACRO(120) # endif # if BOOST_PP_LOCAL_C(121) BOOST_PP_LOCAL_MACRO(121) # endif # if BOOST_PP_LOCAL_C(122) BOOST_PP_LOCAL_MACRO(122) # endif # if BOOST_PP_LOCAL_C(123) BOOST_PP_LOCAL_MACRO(123) # endif # if BOOST_PP_LOCAL_C(124) BOOST_PP_LOCAL_MACRO(124) # endif # if BOOST_PP_LOCAL_C(125) BOOST_PP_LOCAL_MACRO(125) # endif # if BOOST_PP_LOCAL_C(126) BOOST_PP_LOCAL_MACRO(126) # endif # if BOOST_PP_LOCAL_C(127) BOOST_PP_LOCAL_MACRO(127) # endif # if BOOST_PP_LOCAL_C(128) BOOST_PP_LOCAL_MACRO(128) # endif # if BOOST_PP_LOCAL_C(129) BOOST_PP_LOCAL_MACRO(129) # endif # if BOOST_PP_LOCAL_C(130) BOOST_PP_LOCAL_MACRO(130) # endif # if BOOST_PP_LOCAL_C(131) BOOST_PP_LOCAL_MACRO(131) # endif # if BOOST_PP_LOCAL_C(132) BOOST_PP_LOCAL_MACRO(132) # endif # if BOOST_PP_LOCAL_C(133) BOOST_PP_LOCAL_MACRO(133) # endif # if BOOST_PP_LOCAL_C(134) BOOST_PP_LOCAL_MACRO(134) # endif # if BOOST_PP_LOCAL_C(135) BOOST_PP_LOCAL_MACRO(135) # endif # if BOOST_PP_LOCAL_C(136) BOOST_PP_LOCAL_MACRO(136) # endif # if BOOST_PP_LOCAL_C(137) BOOST_PP_LOCAL_MACRO(137) # endif # if BOOST_PP_LOCAL_C(138) BOOST_PP_LOCAL_MACRO(138) # endif # if BOOST_PP_LOCAL_C(139) BOOST_PP_LOCAL_MACRO(139) # endif # if BOOST_PP_LOCAL_C(140) BOOST_PP_LOCAL_MACRO(140) # endif # if BOOST_PP_LOCAL_C(141) BOOST_PP_LOCAL_MACRO(141) # endif # if BOOST_PP_LOCAL_C(142) BOOST_PP_LOCAL_MACRO(142) # endif # if BOOST_PP_LOCAL_C(143) BOOST_PP_LOCAL_MACRO(143) # endif # if BOOST_PP_LOCAL_C(144) BOOST_PP_LOCAL_MACRO(144) # endif # if BOOST_PP_LOCAL_C(145) BOOST_PP_LOCAL_MACRO(145) # endif # if BOOST_PP_LOCAL_C(146) BOOST_PP_LOCAL_MACRO(146) # endif # if BOOST_PP_LOCAL_C(147) BOOST_PP_LOCAL_MACRO(147) # endif # if BOOST_PP_LOCAL_C(148) BOOST_PP_LOCAL_MACRO(148) # endif # if BOOST_PP_LOCAL_C(149) BOOST_PP_LOCAL_MACRO(149) # endif # if BOOST_PP_LOCAL_C(150) BOOST_PP_LOCAL_MACRO(150) # endif # if BOOST_PP_LOCAL_C(151) BOOST_PP_LOCAL_MACRO(151) # endif # if BOOST_PP_LOCAL_C(152) BOOST_PP_LOCAL_MACRO(152) # endif # if BOOST_PP_LOCAL_C(153) BOOST_PP_LOCAL_MACRO(153) # endif # if BOOST_PP_LOCAL_C(154) BOOST_PP_LOCAL_MACRO(154) # endif # if BOOST_PP_LOCAL_C(155) BOOST_PP_LOCAL_MACRO(155) # endif # if BOOST_PP_LOCAL_C(156) BOOST_PP_LOCAL_MACRO(156) # endif # if BOOST_PP_LOCAL_C(157) BOOST_PP_LOCAL_MACRO(157) # endif # if BOOST_PP_LOCAL_C(158) BOOST_PP_LOCAL_MACRO(158) # endif # if BOOST_PP_LOCAL_C(159) BOOST_PP_LOCAL_MACRO(159) # endif # if BOOST_PP_LOCAL_C(160) BOOST_PP_LOCAL_MACRO(160) # endif # if BOOST_PP_LOCAL_C(161) BOOST_PP_LOCAL_MACRO(161) # endif # if BOOST_PP_LOCAL_C(162) BOOST_PP_LOCAL_MACRO(162) # endif # if BOOST_PP_LOCAL_C(163) BOOST_PP_LOCAL_MACRO(163) # endif # if BOOST_PP_LOCAL_C(164) BOOST_PP_LOCAL_MACRO(164) # endif # if BOOST_PP_LOCAL_C(165) BOOST_PP_LOCAL_MACRO(165) # endif # if BOOST_PP_LOCAL_C(166) BOOST_PP_LOCAL_MACRO(166) # endif # if BOOST_PP_LOCAL_C(167) BOOST_PP_LOCAL_MACRO(167) # endif # if BOOST_PP_LOCAL_C(168) BOOST_PP_LOCAL_MACRO(168) # endif # if BOOST_PP_LOCAL_C(169) BOOST_PP_LOCAL_MACRO(169) # endif # if BOOST_PP_LOCAL_C(170) BOOST_PP_LOCAL_MACRO(170) # endif # if BOOST_PP_LOCAL_C(171) BOOST_PP_LOCAL_MACRO(171) # endif # if BOOST_PP_LOCAL_C(172) BOOST_PP_LOCAL_MACRO(172) # endif # if BOOST_PP_LOCAL_C(173) BOOST_PP_LOCAL_MACRO(173) # endif # if BOOST_PP_LOCAL_C(174) BOOST_PP_LOCAL_MACRO(174) # endif # if BOOST_PP_LOCAL_C(175) BOOST_PP_LOCAL_MACRO(175) # endif # if BOOST_PP_LOCAL_C(176) BOOST_PP_LOCAL_MACRO(176) # endif # if BOOST_PP_LOCAL_C(177) BOOST_PP_LOCAL_MACRO(177) # endif # if BOOST_PP_LOCAL_C(178) BOOST_PP_LOCAL_MACRO(178) # endif # if BOOST_PP_LOCAL_C(179) BOOST_PP_LOCAL_MACRO(179) # endif # if BOOST_PP_LOCAL_C(180) BOOST_PP_LOCAL_MACRO(180) # endif # if BOOST_PP_LOCAL_C(181) BOOST_PP_LOCAL_MACRO(181) # endif # if BOOST_PP_LOCAL_C(182) BOOST_PP_LOCAL_MACRO(182) # endif # if BOOST_PP_LOCAL_C(183) BOOST_PP_LOCAL_MACRO(183) # endif # if BOOST_PP_LOCAL_C(184) BOOST_PP_LOCAL_MACRO(184) # endif # if BOOST_PP_LOCAL_C(185) BOOST_PP_LOCAL_MACRO(185) # endif # if BOOST_PP_LOCAL_C(186) BOOST_PP_LOCAL_MACRO(186) # endif # if BOOST_PP_LOCAL_C(187) BOOST_PP_LOCAL_MACRO(187) # endif # if BOOST_PP_LOCAL_C(188) BOOST_PP_LOCAL_MACRO(188) # endif # if BOOST_PP_LOCAL_C(189) BOOST_PP_LOCAL_MACRO(189) # endif # if BOOST_PP_LOCAL_C(190) BOOST_PP_LOCAL_MACRO(190) # endif # if BOOST_PP_LOCAL_C(191) BOOST_PP_LOCAL_MACRO(191) # endif # if BOOST_PP_LOCAL_C(192) BOOST_PP_LOCAL_MACRO(192) # endif # if BOOST_PP_LOCAL_C(193) BOOST_PP_LOCAL_MACRO(193) # endif # if BOOST_PP_LOCAL_C(194) BOOST_PP_LOCAL_MACRO(194) # endif # if BOOST_PP_LOCAL_C(195) BOOST_PP_LOCAL_MACRO(195) # endif # if BOOST_PP_LOCAL_C(196) BOOST_PP_LOCAL_MACRO(196) # endif # if BOOST_PP_LOCAL_C(197) BOOST_PP_LOCAL_MACRO(197) # endif # if BOOST_PP_LOCAL_C(198) BOOST_PP_LOCAL_MACRO(198) # endif # if BOOST_PP_LOCAL_C(199) BOOST_PP_LOCAL_MACRO(199) # endif # if BOOST_PP_LOCAL_C(200) BOOST_PP_LOCAL_MACRO(200) # endif # if BOOST_PP_LOCAL_C(201) BOOST_PP_LOCAL_MACRO(201) # endif # if BOOST_PP_LOCAL_C(202) BOOST_PP_LOCAL_MACRO(202) # endif # if BOOST_PP_LOCAL_C(203) BOOST_PP_LOCAL_MACRO(203) # endif # if BOOST_PP_LOCAL_C(204) BOOST_PP_LOCAL_MACRO(204) # endif # if BOOST_PP_LOCAL_C(205) BOOST_PP_LOCAL_MACRO(205) # endif # if BOOST_PP_LOCAL_C(206) BOOST_PP_LOCAL_MACRO(206) # endif # if BOOST_PP_LOCAL_C(207) BOOST_PP_LOCAL_MACRO(207) # endif # if BOOST_PP_LOCAL_C(208) BOOST_PP_LOCAL_MACRO(208) # endif # if BOOST_PP_LOCAL_C(209) BOOST_PP_LOCAL_MACRO(209) # endif # if BOOST_PP_LOCAL_C(210) BOOST_PP_LOCAL_MACRO(210) # endif # if BOOST_PP_LOCAL_C(211) BOOST_PP_LOCAL_MACRO(211) # endif # if BOOST_PP_LOCAL_C(212) BOOST_PP_LOCAL_MACRO(212) # endif # if BOOST_PP_LOCAL_C(213) BOOST_PP_LOCAL_MACRO(213) # endif # if BOOST_PP_LOCAL_C(214) BOOST_PP_LOCAL_MACRO(214) # endif # if BOOST_PP_LOCAL_C(215) BOOST_PP_LOCAL_MACRO(215) # endif # if BOOST_PP_LOCAL_C(216) BOOST_PP_LOCAL_MACRO(216) # endif # if BOOST_PP_LOCAL_C(217) BOOST_PP_LOCAL_MACRO(217) # endif # if BOOST_PP_LOCAL_C(218) BOOST_PP_LOCAL_MACRO(218) # endif # if BOOST_PP_LOCAL_C(219) BOOST_PP_LOCAL_MACRO(219) # endif # if BOOST_PP_LOCAL_C(220) BOOST_PP_LOCAL_MACRO(220) # endif # if BOOST_PP_LOCAL_C(221) BOOST_PP_LOCAL_MACRO(221) # endif # if BOOST_PP_LOCAL_C(222) BOOST_PP_LOCAL_MACRO(222) # endif # if BOOST_PP_LOCAL_C(223) BOOST_PP_LOCAL_MACRO(223) # endif # if BOOST_PP_LOCAL_C(224) BOOST_PP_LOCAL_MACRO(224) # endif # if BOOST_PP_LOCAL_C(225) BOOST_PP_LOCAL_MACRO(225) # endif # if BOOST_PP_LOCAL_C(226) BOOST_PP_LOCAL_MACRO(226) # endif # if BOOST_PP_LOCAL_C(227) BOOST_PP_LOCAL_MACRO(227) # endif # if BOOST_PP_LOCAL_C(228) BOOST_PP_LOCAL_MACRO(228) # endif # if BOOST_PP_LOCAL_C(229) BOOST_PP_LOCAL_MACRO(229) # endif # if BOOST_PP_LOCAL_C(230) BOOST_PP_LOCAL_MACRO(230) # endif # if BOOST_PP_LOCAL_C(231) BOOST_PP_LOCAL_MACRO(231) # endif # if BOOST_PP_LOCAL_C(232) BOOST_PP_LOCAL_MACRO(232) # endif # if BOOST_PP_LOCAL_C(233) BOOST_PP_LOCAL_MACRO(233) # endif # if BOOST_PP_LOCAL_C(234) BOOST_PP_LOCAL_MACRO(234) # endif # if BOOST_PP_LOCAL_C(235) BOOST_PP_LOCAL_MACRO(235) # endif # if BOOST_PP_LOCAL_C(236) BOOST_PP_LOCAL_MACRO(236) # endif # if BOOST_PP_LOCAL_C(237) BOOST_PP_LOCAL_MACRO(237) # endif # if BOOST_PP_LOCAL_C(238) BOOST_PP_LOCAL_MACRO(238) # endif # if BOOST_PP_LOCAL_C(239) BOOST_PP_LOCAL_MACRO(239) # endif # if BOOST_PP_LOCAL_C(240) BOOST_PP_LOCAL_MACRO(240) # endif # if BOOST_PP_LOCAL_C(241) BOOST_PP_LOCAL_MACRO(241) # endif # if BOOST_PP_LOCAL_C(242) BOOST_PP_LOCAL_MACRO(242) # endif # if BOOST_PP_LOCAL_C(243) BOOST_PP_LOCAL_MACRO(243) # endif # if BOOST_PP_LOCAL_C(244) BOOST_PP_LOCAL_MACRO(244) # endif # if BOOST_PP_LOCAL_C(245) BOOST_PP_LOCAL_MACRO(245) # endif # if BOOST_PP_LOCAL_C(246) BOOST_PP_LOCAL_MACRO(246) # endif # if BOOST_PP_LOCAL_C(247) BOOST_PP_LOCAL_MACRO(247) # endif # if BOOST_PP_LOCAL_C(248) BOOST_PP_LOCAL_MACRO(248) # endif # if BOOST_PP_LOCAL_C(249) BOOST_PP_LOCAL_MACRO(249) # endif # if BOOST_PP_LOCAL_C(250) BOOST_PP_LOCAL_MACRO(250) # endif # if BOOST_PP_LOCAL_C(251) BOOST_PP_LOCAL_MACRO(251) # endif # if BOOST_PP_LOCAL_C(252) BOOST_PP_LOCAL_MACRO(252) # endif # if BOOST_PP_LOCAL_C(253) BOOST_PP_LOCAL_MACRO(253) # endif # if BOOST_PP_LOCAL_C(254) BOOST_PP_LOCAL_MACRO(254) # endif # if BOOST_PP_LOCAL_C(255) BOOST_PP_LOCAL_MACRO(255) # endif # if BOOST_PP_LOCAL_C(256) BOOST_PP_LOCAL_MACRO(256) # endif # endif # # undef BOOST_PP_LOCAL_LIMITS # # undef BOOST_PP_LOCAL_S # undef BOOST_PP_LOCAL_F # # undef BOOST_PP_LOCAL_MACRO ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/rlocal.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if BOOST_PP_LOCAL_R(256) BOOST_PP_LOCAL_MACRO(256) # endif # if BOOST_PP_LOCAL_R(255) BOOST_PP_LOCAL_MACRO(255) # endif # if BOOST_PP_LOCAL_R(254) BOOST_PP_LOCAL_MACRO(254) # endif # if BOOST_PP_LOCAL_R(253) BOOST_PP_LOCAL_MACRO(253) # endif # if BOOST_PP_LOCAL_R(252) BOOST_PP_LOCAL_MACRO(252) # endif # if BOOST_PP_LOCAL_R(251) BOOST_PP_LOCAL_MACRO(251) # endif # if BOOST_PP_LOCAL_R(250) BOOST_PP_LOCAL_MACRO(250) # endif # if BOOST_PP_LOCAL_R(249) BOOST_PP_LOCAL_MACRO(249) # endif # if BOOST_PP_LOCAL_R(248) BOOST_PP_LOCAL_MACRO(248) # endif # if BOOST_PP_LOCAL_R(247) BOOST_PP_LOCAL_MACRO(247) # endif # if BOOST_PP_LOCAL_R(246) BOOST_PP_LOCAL_MACRO(246) # endif # if BOOST_PP_LOCAL_R(245) BOOST_PP_LOCAL_MACRO(245) # endif # if BOOST_PP_LOCAL_R(244) BOOST_PP_LOCAL_MACRO(244) # endif # if BOOST_PP_LOCAL_R(243) BOOST_PP_LOCAL_MACRO(243) # endif # if BOOST_PP_LOCAL_R(242) BOOST_PP_LOCAL_MACRO(242) # endif # if BOOST_PP_LOCAL_R(241) BOOST_PP_LOCAL_MACRO(241) # endif # if BOOST_PP_LOCAL_R(240) BOOST_PP_LOCAL_MACRO(240) # endif # if BOOST_PP_LOCAL_R(239) BOOST_PP_LOCAL_MACRO(239) # endif # if BOOST_PP_LOCAL_R(238) BOOST_PP_LOCAL_MACRO(238) # endif # if BOOST_PP_LOCAL_R(237) BOOST_PP_LOCAL_MACRO(237) # endif # if BOOST_PP_LOCAL_R(236) BOOST_PP_LOCAL_MACRO(236) # endif # if BOOST_PP_LOCAL_R(235) BOOST_PP_LOCAL_MACRO(235) # endif # if BOOST_PP_LOCAL_R(234) BOOST_PP_LOCAL_MACRO(234) # endif # if BOOST_PP_LOCAL_R(233) BOOST_PP_LOCAL_MACRO(233) # endif # if BOOST_PP_LOCAL_R(232) BOOST_PP_LOCAL_MACRO(232) # endif # if BOOST_PP_LOCAL_R(231) BOOST_PP_LOCAL_MACRO(231) # endif # if BOOST_PP_LOCAL_R(230) BOOST_PP_LOCAL_MACRO(230) # endif # if BOOST_PP_LOCAL_R(229) BOOST_PP_LOCAL_MACRO(229) # endif # if BOOST_PP_LOCAL_R(228) BOOST_PP_LOCAL_MACRO(228) # endif # if BOOST_PP_LOCAL_R(227) BOOST_PP_LOCAL_MACRO(227) # endif # if BOOST_PP_LOCAL_R(226) BOOST_PP_LOCAL_MACRO(226) # endif # if BOOST_PP_LOCAL_R(225) BOOST_PP_LOCAL_MACRO(225) # endif # if BOOST_PP_LOCAL_R(224) BOOST_PP_LOCAL_MACRO(224) # endif # if BOOST_PP_LOCAL_R(223) BOOST_PP_LOCAL_MACRO(223) # endif # if BOOST_PP_LOCAL_R(222) BOOST_PP_LOCAL_MACRO(222) # endif # if BOOST_PP_LOCAL_R(221) BOOST_PP_LOCAL_MACRO(221) # endif # if BOOST_PP_LOCAL_R(220) BOOST_PP_LOCAL_MACRO(220) # endif # if BOOST_PP_LOCAL_R(219) BOOST_PP_LOCAL_MACRO(219) # endif # if BOOST_PP_LOCAL_R(218) BOOST_PP_LOCAL_MACRO(218) # endif # if BOOST_PP_LOCAL_R(217) BOOST_PP_LOCAL_MACRO(217) # endif # if BOOST_PP_LOCAL_R(216) BOOST_PP_LOCAL_MACRO(216) # endif # if BOOST_PP_LOCAL_R(215) BOOST_PP_LOCAL_MACRO(215) # endif # if BOOST_PP_LOCAL_R(214) BOOST_PP_LOCAL_MACRO(214) # endif # if BOOST_PP_LOCAL_R(213) BOOST_PP_LOCAL_MACRO(213) # endif # if BOOST_PP_LOCAL_R(212) BOOST_PP_LOCAL_MACRO(212) # endif # if BOOST_PP_LOCAL_R(211) BOOST_PP_LOCAL_MACRO(211) # endif # if BOOST_PP_LOCAL_R(210) BOOST_PP_LOCAL_MACRO(210) # endif # if BOOST_PP_LOCAL_R(209) BOOST_PP_LOCAL_MACRO(209) # endif # if BOOST_PP_LOCAL_R(208) BOOST_PP_LOCAL_MACRO(208) # endif # if BOOST_PP_LOCAL_R(207) BOOST_PP_LOCAL_MACRO(207) # endif # if BOOST_PP_LOCAL_R(206) BOOST_PP_LOCAL_MACRO(206) # endif # if BOOST_PP_LOCAL_R(205) BOOST_PP_LOCAL_MACRO(205) # endif # if BOOST_PP_LOCAL_R(204) BOOST_PP_LOCAL_MACRO(204) # endif # if BOOST_PP_LOCAL_R(203) BOOST_PP_LOCAL_MACRO(203) # endif # if BOOST_PP_LOCAL_R(202) BOOST_PP_LOCAL_MACRO(202) # endif # if BOOST_PP_LOCAL_R(201) BOOST_PP_LOCAL_MACRO(201) # endif # if BOOST_PP_LOCAL_R(200) BOOST_PP_LOCAL_MACRO(200) # endif # if BOOST_PP_LOCAL_R(199) BOOST_PP_LOCAL_MACRO(199) # endif # if BOOST_PP_LOCAL_R(198) BOOST_PP_LOCAL_MACRO(198) # endif # if BOOST_PP_LOCAL_R(197) BOOST_PP_LOCAL_MACRO(197) # endif # if BOOST_PP_LOCAL_R(196) BOOST_PP_LOCAL_MACRO(196) # endif # if BOOST_PP_LOCAL_R(195) BOOST_PP_LOCAL_MACRO(195) # endif # if BOOST_PP_LOCAL_R(194) BOOST_PP_LOCAL_MACRO(194) # endif # if BOOST_PP_LOCAL_R(193) BOOST_PP_LOCAL_MACRO(193) # endif # if BOOST_PP_LOCAL_R(192) BOOST_PP_LOCAL_MACRO(192) # endif # if BOOST_PP_LOCAL_R(191) BOOST_PP_LOCAL_MACRO(191) # endif # if BOOST_PP_LOCAL_R(190) BOOST_PP_LOCAL_MACRO(190) # endif # if BOOST_PP_LOCAL_R(189) BOOST_PP_LOCAL_MACRO(189) # endif # if BOOST_PP_LOCAL_R(188) BOOST_PP_LOCAL_MACRO(188) # endif # if BOOST_PP_LOCAL_R(187) BOOST_PP_LOCAL_MACRO(187) # endif # if BOOST_PP_LOCAL_R(186) BOOST_PP_LOCAL_MACRO(186) # endif # if BOOST_PP_LOCAL_R(185) BOOST_PP_LOCAL_MACRO(185) # endif # if BOOST_PP_LOCAL_R(184) BOOST_PP_LOCAL_MACRO(184) # endif # if BOOST_PP_LOCAL_R(183) BOOST_PP_LOCAL_MACRO(183) # endif # if BOOST_PP_LOCAL_R(182) BOOST_PP_LOCAL_MACRO(182) # endif # if BOOST_PP_LOCAL_R(181) BOOST_PP_LOCAL_MACRO(181) # endif # if BOOST_PP_LOCAL_R(180) BOOST_PP_LOCAL_MACRO(180) # endif # if BOOST_PP_LOCAL_R(179) BOOST_PP_LOCAL_MACRO(179) # endif # if BOOST_PP_LOCAL_R(178) BOOST_PP_LOCAL_MACRO(178) # endif # if BOOST_PP_LOCAL_R(177) BOOST_PP_LOCAL_MACRO(177) # endif # if BOOST_PP_LOCAL_R(176) BOOST_PP_LOCAL_MACRO(176) # endif # if BOOST_PP_LOCAL_R(175) BOOST_PP_LOCAL_MACRO(175) # endif # if BOOST_PP_LOCAL_R(174) BOOST_PP_LOCAL_MACRO(174) # endif # if BOOST_PP_LOCAL_R(173) BOOST_PP_LOCAL_MACRO(173) # endif # if BOOST_PP_LOCAL_R(172) BOOST_PP_LOCAL_MACRO(172) # endif # if BOOST_PP_LOCAL_R(171) BOOST_PP_LOCAL_MACRO(171) # endif # if BOOST_PP_LOCAL_R(170) BOOST_PP_LOCAL_MACRO(170) # endif # if BOOST_PP_LOCAL_R(169) BOOST_PP_LOCAL_MACRO(169) # endif # if BOOST_PP_LOCAL_R(168) BOOST_PP_LOCAL_MACRO(168) # endif # if BOOST_PP_LOCAL_R(167) BOOST_PP_LOCAL_MACRO(167) # endif # if BOOST_PP_LOCAL_R(166) BOOST_PP_LOCAL_MACRO(166) # endif # if BOOST_PP_LOCAL_R(165) BOOST_PP_LOCAL_MACRO(165) # endif # if BOOST_PP_LOCAL_R(164) BOOST_PP_LOCAL_MACRO(164) # endif # if BOOST_PP_LOCAL_R(163) BOOST_PP_LOCAL_MACRO(163) # endif # if BOOST_PP_LOCAL_R(162) BOOST_PP_LOCAL_MACRO(162) # endif # if BOOST_PP_LOCAL_R(161) BOOST_PP_LOCAL_MACRO(161) # endif # if BOOST_PP_LOCAL_R(160) BOOST_PP_LOCAL_MACRO(160) # endif # if BOOST_PP_LOCAL_R(159) BOOST_PP_LOCAL_MACRO(159) # endif # if BOOST_PP_LOCAL_R(158) BOOST_PP_LOCAL_MACRO(158) # endif # if BOOST_PP_LOCAL_R(157) BOOST_PP_LOCAL_MACRO(157) # endif # if BOOST_PP_LOCAL_R(156) BOOST_PP_LOCAL_MACRO(156) # endif # if BOOST_PP_LOCAL_R(155) BOOST_PP_LOCAL_MACRO(155) # endif # if BOOST_PP_LOCAL_R(154) BOOST_PP_LOCAL_MACRO(154) # endif # if BOOST_PP_LOCAL_R(153) BOOST_PP_LOCAL_MACRO(153) # endif # if BOOST_PP_LOCAL_R(152) BOOST_PP_LOCAL_MACRO(152) # endif # if BOOST_PP_LOCAL_R(151) BOOST_PP_LOCAL_MACRO(151) # endif # if BOOST_PP_LOCAL_R(150) BOOST_PP_LOCAL_MACRO(150) # endif # if BOOST_PP_LOCAL_R(149) BOOST_PP_LOCAL_MACRO(149) # endif # if BOOST_PP_LOCAL_R(148) BOOST_PP_LOCAL_MACRO(148) # endif # if BOOST_PP_LOCAL_R(147) BOOST_PP_LOCAL_MACRO(147) # endif # if BOOST_PP_LOCAL_R(146) BOOST_PP_LOCAL_MACRO(146) # endif # if BOOST_PP_LOCAL_R(145) BOOST_PP_LOCAL_MACRO(145) # endif # if BOOST_PP_LOCAL_R(144) BOOST_PP_LOCAL_MACRO(144) # endif # if BOOST_PP_LOCAL_R(143) BOOST_PP_LOCAL_MACRO(143) # endif # if BOOST_PP_LOCAL_R(142) BOOST_PP_LOCAL_MACRO(142) # endif # if BOOST_PP_LOCAL_R(141) BOOST_PP_LOCAL_MACRO(141) # endif # if BOOST_PP_LOCAL_R(140) BOOST_PP_LOCAL_MACRO(140) # endif # if BOOST_PP_LOCAL_R(139) BOOST_PP_LOCAL_MACRO(139) # endif # if BOOST_PP_LOCAL_R(138) BOOST_PP_LOCAL_MACRO(138) # endif # if BOOST_PP_LOCAL_R(137) BOOST_PP_LOCAL_MACRO(137) # endif # if BOOST_PP_LOCAL_R(136) BOOST_PP_LOCAL_MACRO(136) # endif # if BOOST_PP_LOCAL_R(135) BOOST_PP_LOCAL_MACRO(135) # endif # if BOOST_PP_LOCAL_R(134) BOOST_PP_LOCAL_MACRO(134) # endif # if BOOST_PP_LOCAL_R(133) BOOST_PP_LOCAL_MACRO(133) # endif # if BOOST_PP_LOCAL_R(132) BOOST_PP_LOCAL_MACRO(132) # endif # if BOOST_PP_LOCAL_R(131) BOOST_PP_LOCAL_MACRO(131) # endif # if BOOST_PP_LOCAL_R(130) BOOST_PP_LOCAL_MACRO(130) # endif # if BOOST_PP_LOCAL_R(129) BOOST_PP_LOCAL_MACRO(129) # endif # if BOOST_PP_LOCAL_R(128) BOOST_PP_LOCAL_MACRO(128) # endif # if BOOST_PP_LOCAL_R(127) BOOST_PP_LOCAL_MACRO(127) # endif # if BOOST_PP_LOCAL_R(126) BOOST_PP_LOCAL_MACRO(126) # endif # if BOOST_PP_LOCAL_R(125) BOOST_PP_LOCAL_MACRO(125) # endif # if BOOST_PP_LOCAL_R(124) BOOST_PP_LOCAL_MACRO(124) # endif # if BOOST_PP_LOCAL_R(123) BOOST_PP_LOCAL_MACRO(123) # endif # if BOOST_PP_LOCAL_R(122) BOOST_PP_LOCAL_MACRO(122) # endif # if BOOST_PP_LOCAL_R(121) BOOST_PP_LOCAL_MACRO(121) # endif # if BOOST_PP_LOCAL_R(120) BOOST_PP_LOCAL_MACRO(120) # endif # if BOOST_PP_LOCAL_R(119) BOOST_PP_LOCAL_MACRO(119) # endif # if BOOST_PP_LOCAL_R(118) BOOST_PP_LOCAL_MACRO(118) # endif # if BOOST_PP_LOCAL_R(117) BOOST_PP_LOCAL_MACRO(117) # endif # if BOOST_PP_LOCAL_R(116) BOOST_PP_LOCAL_MACRO(116) # endif # if BOOST_PP_LOCAL_R(115) BOOST_PP_LOCAL_MACRO(115) # endif # if BOOST_PP_LOCAL_R(114) BOOST_PP_LOCAL_MACRO(114) # endif # if BOOST_PP_LOCAL_R(113) BOOST_PP_LOCAL_MACRO(113) # endif # if BOOST_PP_LOCAL_R(112) BOOST_PP_LOCAL_MACRO(112) # endif # if BOOST_PP_LOCAL_R(111) BOOST_PP_LOCAL_MACRO(111) # endif # if BOOST_PP_LOCAL_R(110) BOOST_PP_LOCAL_MACRO(110) # endif # if BOOST_PP_LOCAL_R(109) BOOST_PP_LOCAL_MACRO(109) # endif # if BOOST_PP_LOCAL_R(108) BOOST_PP_LOCAL_MACRO(108) # endif # if BOOST_PP_LOCAL_R(107) BOOST_PP_LOCAL_MACRO(107) # endif # if BOOST_PP_LOCAL_R(106) BOOST_PP_LOCAL_MACRO(106) # endif # if BOOST_PP_LOCAL_R(105) BOOST_PP_LOCAL_MACRO(105) # endif # if BOOST_PP_LOCAL_R(104) BOOST_PP_LOCAL_MACRO(104) # endif # if BOOST_PP_LOCAL_R(103) BOOST_PP_LOCAL_MACRO(103) # endif # if BOOST_PP_LOCAL_R(102) BOOST_PP_LOCAL_MACRO(102) # endif # if BOOST_PP_LOCAL_R(101) BOOST_PP_LOCAL_MACRO(101) # endif # if BOOST_PP_LOCAL_R(100) BOOST_PP_LOCAL_MACRO(100) # endif # if BOOST_PP_LOCAL_R(99) BOOST_PP_LOCAL_MACRO(99) # endif # if BOOST_PP_LOCAL_R(98) BOOST_PP_LOCAL_MACRO(98) # endif # if BOOST_PP_LOCAL_R(97) BOOST_PP_LOCAL_MACRO(97) # endif # if BOOST_PP_LOCAL_R(96) BOOST_PP_LOCAL_MACRO(96) # endif # if BOOST_PP_LOCAL_R(95) BOOST_PP_LOCAL_MACRO(95) # endif # if BOOST_PP_LOCAL_R(94) BOOST_PP_LOCAL_MACRO(94) # endif # if BOOST_PP_LOCAL_R(93) BOOST_PP_LOCAL_MACRO(93) # endif # if BOOST_PP_LOCAL_R(92) BOOST_PP_LOCAL_MACRO(92) # endif # if BOOST_PP_LOCAL_R(91) BOOST_PP_LOCAL_MACRO(91) # endif # if BOOST_PP_LOCAL_R(90) BOOST_PP_LOCAL_MACRO(90) # endif # if BOOST_PP_LOCAL_R(89) BOOST_PP_LOCAL_MACRO(89) # endif # if BOOST_PP_LOCAL_R(88) BOOST_PP_LOCAL_MACRO(88) # endif # if BOOST_PP_LOCAL_R(87) BOOST_PP_LOCAL_MACRO(87) # endif # if BOOST_PP_LOCAL_R(86) BOOST_PP_LOCAL_MACRO(86) # endif # if BOOST_PP_LOCAL_R(85) BOOST_PP_LOCAL_MACRO(85) # endif # if BOOST_PP_LOCAL_R(84) BOOST_PP_LOCAL_MACRO(84) # endif # if BOOST_PP_LOCAL_R(83) BOOST_PP_LOCAL_MACRO(83) # endif # if BOOST_PP_LOCAL_R(82) BOOST_PP_LOCAL_MACRO(82) # endif # if BOOST_PP_LOCAL_R(81) BOOST_PP_LOCAL_MACRO(81) # endif # if BOOST_PP_LOCAL_R(80) BOOST_PP_LOCAL_MACRO(80) # endif # if BOOST_PP_LOCAL_R(79) BOOST_PP_LOCAL_MACRO(79) # endif # if BOOST_PP_LOCAL_R(78) BOOST_PP_LOCAL_MACRO(78) # endif # if BOOST_PP_LOCAL_R(77) BOOST_PP_LOCAL_MACRO(77) # endif # if BOOST_PP_LOCAL_R(76) BOOST_PP_LOCAL_MACRO(76) # endif # if BOOST_PP_LOCAL_R(75) BOOST_PP_LOCAL_MACRO(75) # endif # if BOOST_PP_LOCAL_R(74) BOOST_PP_LOCAL_MACRO(74) # endif # if BOOST_PP_LOCAL_R(73) BOOST_PP_LOCAL_MACRO(73) # endif # if BOOST_PP_LOCAL_R(72) BOOST_PP_LOCAL_MACRO(72) # endif # if BOOST_PP_LOCAL_R(71) BOOST_PP_LOCAL_MACRO(71) # endif # if BOOST_PP_LOCAL_R(70) BOOST_PP_LOCAL_MACRO(70) # endif # if BOOST_PP_LOCAL_R(69) BOOST_PP_LOCAL_MACRO(69) # endif # if BOOST_PP_LOCAL_R(68) BOOST_PP_LOCAL_MACRO(68) # endif # if BOOST_PP_LOCAL_R(67) BOOST_PP_LOCAL_MACRO(67) # endif # if BOOST_PP_LOCAL_R(66) BOOST_PP_LOCAL_MACRO(66) # endif # if BOOST_PP_LOCAL_R(65) BOOST_PP_LOCAL_MACRO(65) # endif # if BOOST_PP_LOCAL_R(64) BOOST_PP_LOCAL_MACRO(64) # endif # if BOOST_PP_LOCAL_R(63) BOOST_PP_LOCAL_MACRO(63) # endif # if BOOST_PP_LOCAL_R(62) BOOST_PP_LOCAL_MACRO(62) # endif # if BOOST_PP_LOCAL_R(61) BOOST_PP_LOCAL_MACRO(61) # endif # if BOOST_PP_LOCAL_R(60) BOOST_PP_LOCAL_MACRO(60) # endif # if BOOST_PP_LOCAL_R(59) BOOST_PP_LOCAL_MACRO(59) # endif # if BOOST_PP_LOCAL_R(58) BOOST_PP_LOCAL_MACRO(58) # endif # if BOOST_PP_LOCAL_R(57) BOOST_PP_LOCAL_MACRO(57) # endif # if BOOST_PP_LOCAL_R(56) BOOST_PP_LOCAL_MACRO(56) # endif # if BOOST_PP_LOCAL_R(55) BOOST_PP_LOCAL_MACRO(55) # endif # if BOOST_PP_LOCAL_R(54) BOOST_PP_LOCAL_MACRO(54) # endif # if BOOST_PP_LOCAL_R(53) BOOST_PP_LOCAL_MACRO(53) # endif # if BOOST_PP_LOCAL_R(52) BOOST_PP_LOCAL_MACRO(52) # endif # if BOOST_PP_LOCAL_R(51) BOOST_PP_LOCAL_MACRO(51) # endif # if BOOST_PP_LOCAL_R(50) BOOST_PP_LOCAL_MACRO(50) # endif # if BOOST_PP_LOCAL_R(49) BOOST_PP_LOCAL_MACRO(49) # endif # if BOOST_PP_LOCAL_R(48) BOOST_PP_LOCAL_MACRO(48) # endif # if BOOST_PP_LOCAL_R(47) BOOST_PP_LOCAL_MACRO(47) # endif # if BOOST_PP_LOCAL_R(46) BOOST_PP_LOCAL_MACRO(46) # endif # if BOOST_PP_LOCAL_R(45) BOOST_PP_LOCAL_MACRO(45) # endif # if BOOST_PP_LOCAL_R(44) BOOST_PP_LOCAL_MACRO(44) # endif # if BOOST_PP_LOCAL_R(43) BOOST_PP_LOCAL_MACRO(43) # endif # if BOOST_PP_LOCAL_R(42) BOOST_PP_LOCAL_MACRO(42) # endif # if BOOST_PP_LOCAL_R(41) BOOST_PP_LOCAL_MACRO(41) # endif # if BOOST_PP_LOCAL_R(40) BOOST_PP_LOCAL_MACRO(40) # endif # if BOOST_PP_LOCAL_R(39) BOOST_PP_LOCAL_MACRO(39) # endif # if BOOST_PP_LOCAL_R(38) BOOST_PP_LOCAL_MACRO(38) # endif # if BOOST_PP_LOCAL_R(37) BOOST_PP_LOCAL_MACRO(37) # endif # if BOOST_PP_LOCAL_R(36) BOOST_PP_LOCAL_MACRO(36) # endif # if BOOST_PP_LOCAL_R(35) BOOST_PP_LOCAL_MACRO(35) # endif # if BOOST_PP_LOCAL_R(34) BOOST_PP_LOCAL_MACRO(34) # endif # if BOOST_PP_LOCAL_R(33) BOOST_PP_LOCAL_MACRO(33) # endif # if BOOST_PP_LOCAL_R(32) BOOST_PP_LOCAL_MACRO(32) # endif # if BOOST_PP_LOCAL_R(31) BOOST_PP_LOCAL_MACRO(31) # endif # if BOOST_PP_LOCAL_R(30) BOOST_PP_LOCAL_MACRO(30) # endif # if BOOST_PP_LOCAL_R(29) BOOST_PP_LOCAL_MACRO(29) # endif # if BOOST_PP_LOCAL_R(28) BOOST_PP_LOCAL_MACRO(28) # endif # if BOOST_PP_LOCAL_R(27) BOOST_PP_LOCAL_MACRO(27) # endif # if BOOST_PP_LOCAL_R(26) BOOST_PP_LOCAL_MACRO(26) # endif # if BOOST_PP_LOCAL_R(25) BOOST_PP_LOCAL_MACRO(25) # endif # if BOOST_PP_LOCAL_R(24) BOOST_PP_LOCAL_MACRO(24) # endif # if BOOST_PP_LOCAL_R(23) BOOST_PP_LOCAL_MACRO(23) # endif # if BOOST_PP_LOCAL_R(22) BOOST_PP_LOCAL_MACRO(22) # endif # if BOOST_PP_LOCAL_R(21) BOOST_PP_LOCAL_MACRO(21) # endif # if BOOST_PP_LOCAL_R(20) BOOST_PP_LOCAL_MACRO(20) # endif # if BOOST_PP_LOCAL_R(19) BOOST_PP_LOCAL_MACRO(19) # endif # if BOOST_PP_LOCAL_R(18) BOOST_PP_LOCAL_MACRO(18) # endif # if BOOST_PP_LOCAL_R(17) BOOST_PP_LOCAL_MACRO(17) # endif # if BOOST_PP_LOCAL_R(16) BOOST_PP_LOCAL_MACRO(16) # endif # if BOOST_PP_LOCAL_R(15) BOOST_PP_LOCAL_MACRO(15) # endif # if BOOST_PP_LOCAL_R(14) BOOST_PP_LOCAL_MACRO(14) # endif # if BOOST_PP_LOCAL_R(13) BOOST_PP_LOCAL_MACRO(13) # endif # if BOOST_PP_LOCAL_R(12) BOOST_PP_LOCAL_MACRO(12) # endif # if BOOST_PP_LOCAL_R(11) BOOST_PP_LOCAL_MACRO(11) # endif # if BOOST_PP_LOCAL_R(10) BOOST_PP_LOCAL_MACRO(10) # endif # if BOOST_PP_LOCAL_R(9) BOOST_PP_LOCAL_MACRO(9) # endif # if BOOST_PP_LOCAL_R(8) BOOST_PP_LOCAL_MACRO(8) # endif # if BOOST_PP_LOCAL_R(7) BOOST_PP_LOCAL_MACRO(7) # endif # if BOOST_PP_LOCAL_R(6) BOOST_PP_LOCAL_MACRO(6) # endif # if BOOST_PP_LOCAL_R(5) BOOST_PP_LOCAL_MACRO(5) # endif # if BOOST_PP_LOCAL_R(4) BOOST_PP_LOCAL_MACRO(4) # endif # if BOOST_PP_LOCAL_R(3) BOOST_PP_LOCAL_MACRO(3) # endif # if BOOST_PP_LOCAL_R(2) BOOST_PP_LOCAL_MACRO(2) # endif # if BOOST_PP_LOCAL_R(1) BOOST_PP_LOCAL_MACRO(1) # endif # if BOOST_PP_LOCAL_R(0) BOOST_PP_LOCAL_MACRO(0) # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/self.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # if !defined(BOOST_PP_INDIRECT_SELF) # error BOOST_PP_ERROR: no indirect file to include # endif # # define BOOST_PP_IS_SELFISH 1 # # include BOOST_PP_INDIRECT_SELF # # undef BOOST_PP_IS_SELFISH # undef BOOST_PP_INDIRECT_SELF ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/detail/start.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_LOCAL_SE # # undef BOOST_PP_LOCAL_SE_DIGIT_1 # undef BOOST_PP_LOCAL_SE_DIGIT_2 # undef BOOST_PP_LOCAL_SE_DIGIT_3 # undef BOOST_PP_LOCAL_SE_DIGIT_4 # undef BOOST_PP_LOCAL_SE_DIGIT_5 # undef BOOST_PP_LOCAL_SE_DIGIT_6 # undef BOOST_PP_LOCAL_SE_DIGIT_7 # undef BOOST_PP_LOCAL_SE_DIGIT_8 # undef BOOST_PP_LOCAL_SE_DIGIT_9 # undef BOOST_PP_LOCAL_SE_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_LOCAL_SE_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_LOCAL_SE_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_LOCAL_SE_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_LOCAL_SE_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_LOCAL_SE_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_LOCAL_SE_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_LOCAL_SE_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_LOCAL_SE_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_LOCAL_SE_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_LOCAL_SE_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_LOCAL_SE_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_LOCAL_SE_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_LOCAL_SE_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_LOCAL_SE_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_LOCAL_SE_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_LOCAL_SE_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_LOCAL_SE_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_LOCAL_SE_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_LOCAL_SE_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_LOCAL_SE_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_LOCAL_SE_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_LOCAL_SE_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_LOCAL_SE_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_LOCAL_SE_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_LOCAL_SE_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_LOCAL_SE_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_LOCAL_SE_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_LOCAL_SE_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_LOCAL_SE_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_LOCAL_SE_DIGIT_1 9 # endif # # if BOOST_PP_LOCAL_SE_DIGIT_3 # define BOOST_PP_LOCAL_SE() BOOST_PP_SLOT_CC_3(BOOST_PP_LOCAL_SE_DIGIT_3, BOOST_PP_LOCAL_SE_DIGIT_2, BOOST_PP_LOCAL_SE_DIGIT_1) # elif BOOST_PP_LOCAL_SE_DIGIT_2 # define BOOST_PP_LOCAL_SE() BOOST_PP_SLOT_CC_2(BOOST_PP_LOCAL_SE_DIGIT_2, BOOST_PP_LOCAL_SE_DIGIT_1) # else # define BOOST_PP_LOCAL_SE() BOOST_PP_LOCAL_SE_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/iterate.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ITERATION_ITERATE_HPP # define BOOST_PREPROCESSOR_ITERATION_ITERATE_HPP # # include # include # include # include # include # include # include # # /* BOOST_PP_ITERATION_DEPTH */ # # define BOOST_PP_ITERATION_DEPTH() 0 # # /* BOOST_PP_ITERATION */ # # define BOOST_PP_ITERATION() BOOST_PP_CAT(BOOST_PP_ITERATION_, BOOST_PP_ITERATION_DEPTH()) # # /* BOOST_PP_ITERATION_START && BOOST_PP_ITERATION_FINISH */ # # define BOOST_PP_ITERATION_START() BOOST_PP_CAT(BOOST_PP_ITERATION_START_, BOOST_PP_ITERATION_DEPTH()) # define BOOST_PP_ITERATION_FINISH() BOOST_PP_CAT(BOOST_PP_ITERATION_FINISH_, BOOST_PP_ITERATION_DEPTH()) # # /* BOOST_PP_ITERATION_FLAGS */ # # define BOOST_PP_ITERATION_FLAGS() (BOOST_PP_CAT(BOOST_PP_ITERATION_FLAGS_, BOOST_PP_ITERATION_DEPTH())()) # # /* BOOST_PP_FRAME_ITERATION */ # # define BOOST_PP_FRAME_ITERATION(i) BOOST_PP_CAT(BOOST_PP_ITERATION_, i) # # /* BOOST_PP_FRAME_START && BOOST_PP_FRAME_FINISH */ # # define BOOST_PP_FRAME_START(i) BOOST_PP_CAT(BOOST_PP_ITERATION_START_, i) # define BOOST_PP_FRAME_FINISH(i) BOOST_PP_CAT(BOOST_PP_ITERATION_FINISH_, i) # # /* BOOST_PP_FRAME_FLAGS */ # # define BOOST_PP_FRAME_FLAGS(i) (BOOST_PP_CAT(BOOST_PP_ITERATION_FLAGS_, i)()) # # /* BOOST_PP_RELATIVE_ITERATION */ # # define BOOST_PP_RELATIVE_ITERATION(i) BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_) # # define BOOST_PP_RELATIVE_0(m) BOOST_PP_CAT(m, BOOST_PP_ITERATION_DEPTH()) # define BOOST_PP_RELATIVE_1(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH())) # define BOOST_PP_RELATIVE_2(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH()))) # define BOOST_PP_RELATIVE_3(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH())))) # define BOOST_PP_RELATIVE_4(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH()))))) # # /* BOOST_PP_RELATIVE_START && BOOST_PP_RELATIVE_FINISH */ # # define BOOST_PP_RELATIVE_START(i) BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_START_) # define BOOST_PP_RELATIVE_FINISH(i) BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_FINISH_) # # /* BOOST_PP_RELATIVE_FLAGS */ # # define BOOST_PP_RELATIVE_FLAGS(i) (BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_FLAGS_)()) # # /* BOOST_PP_ITERATE */ # # define BOOST_PP_ITERATE() BOOST_PP_CAT(BOOST_PP_ITERATE_, BOOST_PP_INC(BOOST_PP_ITERATION_DEPTH())) # # define BOOST_PP_ITERATE_1 # define BOOST_PP_ITERATE_2 # define BOOST_PP_ITERATE_3 # define BOOST_PP_ITERATE_4 # define BOOST_PP_ITERATE_5 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/local.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ITERATION_LOCAL_HPP # define BOOST_PREPROCESSOR_ITERATION_LOCAL_HPP # # include # include # include # # /* BOOST_PP_LOCAL_ITERATE */ # # define BOOST_PP_LOCAL_ITERATE() # # define BOOST_PP_LOCAL_C(n) (BOOST_PP_LOCAL_S) <= n && (BOOST_PP_LOCAL_F) >= n # define BOOST_PP_LOCAL_R(n) (BOOST_PP_LOCAL_F) <= n && (BOOST_PP_LOCAL_S) >= n # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/iteration/self.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_ITERATION_SELF_HPP # define BOOST_PREPROCESSOR_ITERATION_SELF_HPP # # /* BOOST_PP_INCLUDE_SELF */ # # define BOOST_PP_INCLUDE_SELF() # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/adt.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * # * See http://www.boost.org for most recent version. # */ # # /* Revised by Paul Mensonides (2002) */ # # ifndef BOOST_PREPROCESSOR_LIST_ADT_HPP # define BOOST_PREPROCESSOR_LIST_ADT_HPP # # include # include # include # include # # /* BOOST_PP_LIST_CONS */ # # define BOOST_PP_LIST_CONS(head, tail) (head, tail) # # /* BOOST_PP_LIST_NIL */ # # define BOOST_PP_LIST_NIL BOOST_PP_NIL # # /* BOOST_PP_LIST_FIRST */ # # define BOOST_PP_LIST_FIRST(list) BOOST_PP_LIST_FIRST_D(list) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_LIST_FIRST_D(list) BOOST_PP_LIST_FIRST_I list # else # define BOOST_PP_LIST_FIRST_D(list) BOOST_PP_LIST_FIRST_I ## list # endif # # define BOOST_PP_LIST_FIRST_I(head, tail) head # # /* BOOST_PP_LIST_REST */ # # define BOOST_PP_LIST_REST(list) BOOST_PP_LIST_REST_D(list) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_LIST_REST_D(list) BOOST_PP_LIST_REST_I list # else # define BOOST_PP_LIST_REST_D(list) BOOST_PP_LIST_REST_I ## list # endif # # define BOOST_PP_LIST_REST_I(head, tail) tail # # /* BOOST_PP_LIST_IS_CONS */ # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_BCC() # define BOOST_PP_LIST_IS_CONS(list) BOOST_PP_LIST_IS_CONS_D(list) # define BOOST_PP_LIST_IS_CONS_D(list) BOOST_PP_LIST_IS_CONS_ ## list # define BOOST_PP_LIST_IS_CONS_(head, tail) 1 # define BOOST_PP_LIST_IS_CONS_BOOST_PP_NIL 0 # else # define BOOST_PP_LIST_IS_CONS(list) BOOST_PP_IS_BINARY(list) # endif # # /* BOOST_PP_LIST_IS_NIL */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_BCC() # define BOOST_PP_LIST_IS_NIL(list) BOOST_PP_COMPL(BOOST_PP_IS_BINARY(list)) # else # define BOOST_PP_LIST_IS_NIL(list) BOOST_PP_COMPL(BOOST_PP_LIST_IS_CONS(list)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/detail/dmc/fold_left.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_LEFT_HPP # define BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_LEFT_HPP # # include # include # include # include # # define BOOST_PP_LIST_FOLD_LEFT_1(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_2, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(2, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_2(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_3, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(3, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_3(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_4, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(4, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_4(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_5, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(5, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_5(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_6, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(6, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_6(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_7, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(7, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_7(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_8, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(8, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_8(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_9, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(9, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_9(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_10, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(10, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_10(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_11, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(11, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_11(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_12, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(12, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_12(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_13, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(13, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_13(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_14, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(14, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_14(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_15, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(15, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_15(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_16, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(16, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_16(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_17, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(17, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_17(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_18, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(18, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_18(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_19, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(19, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_19(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_20, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(20, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_20(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_21, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(21, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_21(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_22, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(22, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_22(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_23, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(23, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_23(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_24, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(24, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_24(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_25, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(25, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_25(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_26, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(26, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_26(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_27, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(27, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_27(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_28, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(28, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_28(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_29, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(29, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_29(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_30, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(30, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_30(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_31, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(31, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_31(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_32, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(32, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_32(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_33, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(33, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_33(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_34, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(34, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_34(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_35, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(35, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_35(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_36, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(36, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_36(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_37, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(37, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_37(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_38, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(38, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_38(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_39, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(39, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_39(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_40, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(40, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_40(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_41, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(41, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_41(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_42, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(42, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_42(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_43, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(43, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_43(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_44, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(44, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_44(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_45, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(45, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_45(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_46, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(46, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_46(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_47, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(47, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_47(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_48, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(48, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_48(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_49, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(49, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_49(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_50, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(50, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_50(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_51, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(51, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_51(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_52, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(52, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_52(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_53, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(53, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_53(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_54, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(54, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_54(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_55, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(55, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_55(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_56, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(56, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_56(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_57, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(57, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_57(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_58, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(58, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_58(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_59, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(59, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_59(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_60, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(60, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_60(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_61, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(61, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_61(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_62, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(62, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_62(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_63, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(63, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_63(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_64, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(64, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_64(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_65, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(65, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_65(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_66, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(66, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_66(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_67, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(67, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_67(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_68, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(68, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_68(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_69, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(69, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_69(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_70, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(70, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_70(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_71, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(71, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_71(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_72, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(72, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_72(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_73, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(73, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_73(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_74, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(74, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_74(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_75, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(75, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_75(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_76, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(76, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_76(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_77, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(77, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_77(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_78, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(78, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_78(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_79, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(79, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_79(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_80, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(80, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_80(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_81, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(81, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_81(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_82, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(82, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_82(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_83, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(83, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_83(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_84, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(84, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_84(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_85, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(85, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_85(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_86, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(86, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_86(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_87, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(87, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_87(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_88, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(88, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_88(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_89, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(89, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_89(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_90, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(90, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_90(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_91, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(91, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_91(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_92, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(92, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_92(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_93, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(93, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_93(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_94, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(94, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_94(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_95, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(95, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_95(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_96, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(96, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_96(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_97, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(97, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_97(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_98, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(98, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_98(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_99, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(99, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_99(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_100, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(100, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_100(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_101, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(101, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_101(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_102, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(102, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_102(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_103, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(103, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_103(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_104, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(104, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_104(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_105, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(105, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_105(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_106, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(106, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_106(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_107, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(107, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_107(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_108, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(108, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_108(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_109, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(109, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_109(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_110, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(110, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_110(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_111, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(111, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_111(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_112, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(112, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_112(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_113, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(113, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_113(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_114, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(114, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_114(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_115, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(115, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_115(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_116, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(116, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_116(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_117, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(117, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_117(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_118, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(118, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_118(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_119, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(119, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_119(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_120, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(120, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_120(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_121, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(121, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_121(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_122, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(122, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_122(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_123, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(123, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_123(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_124, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(124, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_124(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_125, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(125, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_125(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_126, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(126, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_126(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_127, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(127, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_127(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_128, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(128, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_128(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_129, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(129, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_129(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_130, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(130, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_130(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_131, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(131, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_131(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_132, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(132, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_132(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_133, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(133, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_133(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_134, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(134, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_134(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_135, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(135, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_135(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_136, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(136, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_136(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_137, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(137, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_137(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_138, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(138, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_138(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_139, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(139, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_139(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_140, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(140, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_140(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_141, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(141, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_141(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_142, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(142, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_142(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_143, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(143, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_143(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_144, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(144, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_144(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_145, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(145, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_145(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_146, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(146, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_146(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_147, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(147, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_147(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_148, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(148, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_148(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_149, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(149, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_149(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_150, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(150, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_150(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_151, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(151, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_151(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_152, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(152, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_152(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_153, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(153, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_153(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_154, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(154, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_154(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_155, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(155, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_155(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_156, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(156, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_156(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_157, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(157, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_157(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_158, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(158, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_158(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_159, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(159, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_159(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_160, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(160, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_160(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_161, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(161, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_161(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_162, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(162, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_162(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_163, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(163, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_163(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_164, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(164, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_164(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_165, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(165, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_165(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_166, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(166, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_166(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_167, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(167, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_167(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_168, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(168, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_168(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_169, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(169, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_169(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_170, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(170, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_170(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_171, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(171, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_171(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_172, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(172, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_172(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_173, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(173, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_173(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_174, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(174, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_174(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_175, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(175, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_175(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_176, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(176, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_176(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_177, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(177, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_177(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_178, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(178, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_178(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_179, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(179, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_179(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_180, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(180, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_180(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_181, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(181, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_181(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_182, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(182, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_182(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_183, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(183, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_183(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_184, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(184, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_184(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_185, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(185, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_185(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_186, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(186, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_186(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_187, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(187, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_187(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_188, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(188, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_188(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_189, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(189, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_189(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_190, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(190, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_190(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_191, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(191, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_191(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_192, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(192, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_192(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_193, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(193, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_193(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_194, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(194, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_194(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_195, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(195, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_195(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_196, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(196, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_196(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_197, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(197, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_197(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_198, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(198, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_198(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_199, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(199, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_199(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_200, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(200, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_200(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_201, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(201, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_201(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_202, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(202, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_202(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_203, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(203, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_203(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_204, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(204, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_204(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_205, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(205, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_205(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_206, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(206, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_206(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_207, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(207, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_207(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_208, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(208, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_208(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_209, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(209, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_209(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_210, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(210, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_210(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_211, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(211, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_211(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_212, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(212, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_212(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_213, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(213, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_213(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_214, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(214, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_214(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_215, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(215, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_215(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_216, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(216, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_216(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_217, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(217, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_217(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_218, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(218, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_218(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_219, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(219, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_219(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_220, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(220, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_220(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_221, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(221, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_221(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_222, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(222, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_222(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_223, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(223, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_223(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_224, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(224, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_224(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_225, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(225, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_225(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_226, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(226, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_226(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_227, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(227, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_227(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_228, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(228, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_228(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_229, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(229, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_229(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_230, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(230, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_230(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_231, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(231, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_231(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_232, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(232, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_232(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_233, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(233, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_233(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_234, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(234, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_234(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_235, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(235, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_235(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_236, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(236, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_236(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_237, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(237, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_237(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_238, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(238, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_238(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_239, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(239, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_239(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_240, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(240, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_240(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_241, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(241, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_241(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_242, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(242, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_242(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_243, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(243, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_243(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_244, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(244, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_244(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_245, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(245, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_245(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_246, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(246, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_246(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_247, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(247, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_247(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_248, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(248, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_248(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_249, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(249, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_249(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_250, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(250, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_250(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_251, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(251, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_251(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_252, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(252, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_252(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_253, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(253, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_253(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_254, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(254, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_254(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_255, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(255, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_255(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_256, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(256, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_256(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_257, BOOST_PP_TUPLE_ELEM_3_1)(o, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, BOOST_PP_TUPLE_ELEM_3_1)(257, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/detail/edg/fold_left.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_DETAIL_EDG_FOLD_LEFT_HPP # define BOOST_PREPROCESSOR_LIST_DETAIL_EDG_FOLD_LEFT_HPP # # include # include # include # include # # define BOOST_PP_LIST_FOLD_LEFT_1(o, s, l) BOOST_PP_LIST_FOLD_LEFT_1_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_2(o, s, l) BOOST_PP_LIST_FOLD_LEFT_2_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_3(o, s, l) BOOST_PP_LIST_FOLD_LEFT_3_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_4(o, s, l) BOOST_PP_LIST_FOLD_LEFT_4_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_5(o, s, l) BOOST_PP_LIST_FOLD_LEFT_5_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_6(o, s, l) BOOST_PP_LIST_FOLD_LEFT_6_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_7(o, s, l) BOOST_PP_LIST_FOLD_LEFT_7_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_8(o, s, l) BOOST_PP_LIST_FOLD_LEFT_8_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_9(o, s, l) BOOST_PP_LIST_FOLD_LEFT_9_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_10(o, s, l) BOOST_PP_LIST_FOLD_LEFT_10_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_11(o, s, l) BOOST_PP_LIST_FOLD_LEFT_11_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_12(o, s, l) BOOST_PP_LIST_FOLD_LEFT_12_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_13(o, s, l) BOOST_PP_LIST_FOLD_LEFT_13_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_14(o, s, l) BOOST_PP_LIST_FOLD_LEFT_14_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_15(o, s, l) BOOST_PP_LIST_FOLD_LEFT_15_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_16(o, s, l) BOOST_PP_LIST_FOLD_LEFT_16_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_17(o, s, l) BOOST_PP_LIST_FOLD_LEFT_17_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_18(o, s, l) BOOST_PP_LIST_FOLD_LEFT_18_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_19(o, s, l) BOOST_PP_LIST_FOLD_LEFT_19_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_20(o, s, l) BOOST_PP_LIST_FOLD_LEFT_20_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_21(o, s, l) BOOST_PP_LIST_FOLD_LEFT_21_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_22(o, s, l) BOOST_PP_LIST_FOLD_LEFT_22_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_23(o, s, l) BOOST_PP_LIST_FOLD_LEFT_23_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_24(o, s, l) BOOST_PP_LIST_FOLD_LEFT_24_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_25(o, s, l) BOOST_PP_LIST_FOLD_LEFT_25_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_26(o, s, l) BOOST_PP_LIST_FOLD_LEFT_26_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_27(o, s, l) BOOST_PP_LIST_FOLD_LEFT_27_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_28(o, s, l) BOOST_PP_LIST_FOLD_LEFT_28_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_29(o, s, l) BOOST_PP_LIST_FOLD_LEFT_29_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_30(o, s, l) BOOST_PP_LIST_FOLD_LEFT_30_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_31(o, s, l) BOOST_PP_LIST_FOLD_LEFT_31_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_32(o, s, l) BOOST_PP_LIST_FOLD_LEFT_32_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_33(o, s, l) BOOST_PP_LIST_FOLD_LEFT_33_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_34(o, s, l) BOOST_PP_LIST_FOLD_LEFT_34_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_35(o, s, l) BOOST_PP_LIST_FOLD_LEFT_35_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_36(o, s, l) BOOST_PP_LIST_FOLD_LEFT_36_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_37(o, s, l) BOOST_PP_LIST_FOLD_LEFT_37_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_38(o, s, l) BOOST_PP_LIST_FOLD_LEFT_38_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_39(o, s, l) BOOST_PP_LIST_FOLD_LEFT_39_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_40(o, s, l) BOOST_PP_LIST_FOLD_LEFT_40_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_41(o, s, l) BOOST_PP_LIST_FOLD_LEFT_41_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_42(o, s, l) BOOST_PP_LIST_FOLD_LEFT_42_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_43(o, s, l) BOOST_PP_LIST_FOLD_LEFT_43_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_44(o, s, l) BOOST_PP_LIST_FOLD_LEFT_44_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_45(o, s, l) BOOST_PP_LIST_FOLD_LEFT_45_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_46(o, s, l) BOOST_PP_LIST_FOLD_LEFT_46_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_47(o, s, l) BOOST_PP_LIST_FOLD_LEFT_47_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_48(o, s, l) BOOST_PP_LIST_FOLD_LEFT_48_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_49(o, s, l) BOOST_PP_LIST_FOLD_LEFT_49_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_50(o, s, l) BOOST_PP_LIST_FOLD_LEFT_50_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_51(o, s, l) BOOST_PP_LIST_FOLD_LEFT_51_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_52(o, s, l) BOOST_PP_LIST_FOLD_LEFT_52_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_53(o, s, l) BOOST_PP_LIST_FOLD_LEFT_53_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_54(o, s, l) BOOST_PP_LIST_FOLD_LEFT_54_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_55(o, s, l) BOOST_PP_LIST_FOLD_LEFT_55_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_56(o, s, l) BOOST_PP_LIST_FOLD_LEFT_56_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_57(o, s, l) BOOST_PP_LIST_FOLD_LEFT_57_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_58(o, s, l) BOOST_PP_LIST_FOLD_LEFT_58_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_59(o, s, l) BOOST_PP_LIST_FOLD_LEFT_59_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_60(o, s, l) BOOST_PP_LIST_FOLD_LEFT_60_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_61(o, s, l) BOOST_PP_LIST_FOLD_LEFT_61_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_62(o, s, l) BOOST_PP_LIST_FOLD_LEFT_62_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_63(o, s, l) BOOST_PP_LIST_FOLD_LEFT_63_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_64(o, s, l) BOOST_PP_LIST_FOLD_LEFT_64_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_65(o, s, l) BOOST_PP_LIST_FOLD_LEFT_65_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_66(o, s, l) BOOST_PP_LIST_FOLD_LEFT_66_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_67(o, s, l) BOOST_PP_LIST_FOLD_LEFT_67_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_68(o, s, l) BOOST_PP_LIST_FOLD_LEFT_68_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_69(o, s, l) BOOST_PP_LIST_FOLD_LEFT_69_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_70(o, s, l) BOOST_PP_LIST_FOLD_LEFT_70_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_71(o, s, l) BOOST_PP_LIST_FOLD_LEFT_71_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_72(o, s, l) BOOST_PP_LIST_FOLD_LEFT_72_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_73(o, s, l) BOOST_PP_LIST_FOLD_LEFT_73_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_74(o, s, l) BOOST_PP_LIST_FOLD_LEFT_74_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_75(o, s, l) BOOST_PP_LIST_FOLD_LEFT_75_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_76(o, s, l) BOOST_PP_LIST_FOLD_LEFT_76_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_77(o, s, l) BOOST_PP_LIST_FOLD_LEFT_77_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_78(o, s, l) BOOST_PP_LIST_FOLD_LEFT_78_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_79(o, s, l) BOOST_PP_LIST_FOLD_LEFT_79_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_80(o, s, l) BOOST_PP_LIST_FOLD_LEFT_80_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_81(o, s, l) BOOST_PP_LIST_FOLD_LEFT_81_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_82(o, s, l) BOOST_PP_LIST_FOLD_LEFT_82_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_83(o, s, l) BOOST_PP_LIST_FOLD_LEFT_83_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_84(o, s, l) BOOST_PP_LIST_FOLD_LEFT_84_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_85(o, s, l) BOOST_PP_LIST_FOLD_LEFT_85_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_86(o, s, l) BOOST_PP_LIST_FOLD_LEFT_86_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_87(o, s, l) BOOST_PP_LIST_FOLD_LEFT_87_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_88(o, s, l) BOOST_PP_LIST_FOLD_LEFT_88_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_89(o, s, l) BOOST_PP_LIST_FOLD_LEFT_89_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_90(o, s, l) BOOST_PP_LIST_FOLD_LEFT_90_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_91(o, s, l) BOOST_PP_LIST_FOLD_LEFT_91_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_92(o, s, l) BOOST_PP_LIST_FOLD_LEFT_92_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_93(o, s, l) BOOST_PP_LIST_FOLD_LEFT_93_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_94(o, s, l) BOOST_PP_LIST_FOLD_LEFT_94_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_95(o, s, l) BOOST_PP_LIST_FOLD_LEFT_95_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_96(o, s, l) BOOST_PP_LIST_FOLD_LEFT_96_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_97(o, s, l) BOOST_PP_LIST_FOLD_LEFT_97_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_98(o, s, l) BOOST_PP_LIST_FOLD_LEFT_98_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_99(o, s, l) BOOST_PP_LIST_FOLD_LEFT_99_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_100(o, s, l) BOOST_PP_LIST_FOLD_LEFT_100_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_101(o, s, l) BOOST_PP_LIST_FOLD_LEFT_101_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_102(o, s, l) BOOST_PP_LIST_FOLD_LEFT_102_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_103(o, s, l) BOOST_PP_LIST_FOLD_LEFT_103_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_104(o, s, l) BOOST_PP_LIST_FOLD_LEFT_104_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_105(o, s, l) BOOST_PP_LIST_FOLD_LEFT_105_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_106(o, s, l) BOOST_PP_LIST_FOLD_LEFT_106_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_107(o, s, l) BOOST_PP_LIST_FOLD_LEFT_107_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_108(o, s, l) BOOST_PP_LIST_FOLD_LEFT_108_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_109(o, s, l) BOOST_PP_LIST_FOLD_LEFT_109_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_110(o, s, l) BOOST_PP_LIST_FOLD_LEFT_110_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_111(o, s, l) BOOST_PP_LIST_FOLD_LEFT_111_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_112(o, s, l) BOOST_PP_LIST_FOLD_LEFT_112_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_113(o, s, l) BOOST_PP_LIST_FOLD_LEFT_113_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_114(o, s, l) BOOST_PP_LIST_FOLD_LEFT_114_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_115(o, s, l) BOOST_PP_LIST_FOLD_LEFT_115_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_116(o, s, l) BOOST_PP_LIST_FOLD_LEFT_116_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_117(o, s, l) BOOST_PP_LIST_FOLD_LEFT_117_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_118(o, s, l) BOOST_PP_LIST_FOLD_LEFT_118_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_119(o, s, l) BOOST_PP_LIST_FOLD_LEFT_119_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_120(o, s, l) BOOST_PP_LIST_FOLD_LEFT_120_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_121(o, s, l) BOOST_PP_LIST_FOLD_LEFT_121_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_122(o, s, l) BOOST_PP_LIST_FOLD_LEFT_122_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_123(o, s, l) BOOST_PP_LIST_FOLD_LEFT_123_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_124(o, s, l) BOOST_PP_LIST_FOLD_LEFT_124_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_125(o, s, l) BOOST_PP_LIST_FOLD_LEFT_125_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_126(o, s, l) BOOST_PP_LIST_FOLD_LEFT_126_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_127(o, s, l) BOOST_PP_LIST_FOLD_LEFT_127_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_128(o, s, l) BOOST_PP_LIST_FOLD_LEFT_128_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_129(o, s, l) BOOST_PP_LIST_FOLD_LEFT_129_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_130(o, s, l) BOOST_PP_LIST_FOLD_LEFT_130_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_131(o, s, l) BOOST_PP_LIST_FOLD_LEFT_131_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_132(o, s, l) BOOST_PP_LIST_FOLD_LEFT_132_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_133(o, s, l) BOOST_PP_LIST_FOLD_LEFT_133_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_134(o, s, l) BOOST_PP_LIST_FOLD_LEFT_134_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_135(o, s, l) BOOST_PP_LIST_FOLD_LEFT_135_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_136(o, s, l) BOOST_PP_LIST_FOLD_LEFT_136_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_137(o, s, l) BOOST_PP_LIST_FOLD_LEFT_137_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_138(o, s, l) BOOST_PP_LIST_FOLD_LEFT_138_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_139(o, s, l) BOOST_PP_LIST_FOLD_LEFT_139_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_140(o, s, l) BOOST_PP_LIST_FOLD_LEFT_140_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_141(o, s, l) BOOST_PP_LIST_FOLD_LEFT_141_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_142(o, s, l) BOOST_PP_LIST_FOLD_LEFT_142_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_143(o, s, l) BOOST_PP_LIST_FOLD_LEFT_143_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_144(o, s, l) BOOST_PP_LIST_FOLD_LEFT_144_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_145(o, s, l) BOOST_PP_LIST_FOLD_LEFT_145_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_146(o, s, l) BOOST_PP_LIST_FOLD_LEFT_146_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_147(o, s, l) BOOST_PP_LIST_FOLD_LEFT_147_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_148(o, s, l) BOOST_PP_LIST_FOLD_LEFT_148_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_149(o, s, l) BOOST_PP_LIST_FOLD_LEFT_149_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_150(o, s, l) BOOST_PP_LIST_FOLD_LEFT_150_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_151(o, s, l) BOOST_PP_LIST_FOLD_LEFT_151_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_152(o, s, l) BOOST_PP_LIST_FOLD_LEFT_152_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_153(o, s, l) BOOST_PP_LIST_FOLD_LEFT_153_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_154(o, s, l) BOOST_PP_LIST_FOLD_LEFT_154_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_155(o, s, l) BOOST_PP_LIST_FOLD_LEFT_155_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_156(o, s, l) BOOST_PP_LIST_FOLD_LEFT_156_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_157(o, s, l) BOOST_PP_LIST_FOLD_LEFT_157_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_158(o, s, l) BOOST_PP_LIST_FOLD_LEFT_158_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_159(o, s, l) BOOST_PP_LIST_FOLD_LEFT_159_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_160(o, s, l) BOOST_PP_LIST_FOLD_LEFT_160_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_161(o, s, l) BOOST_PP_LIST_FOLD_LEFT_161_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_162(o, s, l) BOOST_PP_LIST_FOLD_LEFT_162_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_163(o, s, l) BOOST_PP_LIST_FOLD_LEFT_163_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_164(o, s, l) BOOST_PP_LIST_FOLD_LEFT_164_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_165(o, s, l) BOOST_PP_LIST_FOLD_LEFT_165_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_166(o, s, l) BOOST_PP_LIST_FOLD_LEFT_166_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_167(o, s, l) BOOST_PP_LIST_FOLD_LEFT_167_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_168(o, s, l) BOOST_PP_LIST_FOLD_LEFT_168_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_169(o, s, l) BOOST_PP_LIST_FOLD_LEFT_169_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_170(o, s, l) BOOST_PP_LIST_FOLD_LEFT_170_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_171(o, s, l) BOOST_PP_LIST_FOLD_LEFT_171_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_172(o, s, l) BOOST_PP_LIST_FOLD_LEFT_172_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_173(o, s, l) BOOST_PP_LIST_FOLD_LEFT_173_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_174(o, s, l) BOOST_PP_LIST_FOLD_LEFT_174_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_175(o, s, l) BOOST_PP_LIST_FOLD_LEFT_175_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_176(o, s, l) BOOST_PP_LIST_FOLD_LEFT_176_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_177(o, s, l) BOOST_PP_LIST_FOLD_LEFT_177_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_178(o, s, l) BOOST_PP_LIST_FOLD_LEFT_178_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_179(o, s, l) BOOST_PP_LIST_FOLD_LEFT_179_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_180(o, s, l) BOOST_PP_LIST_FOLD_LEFT_180_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_181(o, s, l) BOOST_PP_LIST_FOLD_LEFT_181_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_182(o, s, l) BOOST_PP_LIST_FOLD_LEFT_182_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_183(o, s, l) BOOST_PP_LIST_FOLD_LEFT_183_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_184(o, s, l) BOOST_PP_LIST_FOLD_LEFT_184_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_185(o, s, l) BOOST_PP_LIST_FOLD_LEFT_185_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_186(o, s, l) BOOST_PP_LIST_FOLD_LEFT_186_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_187(o, s, l) BOOST_PP_LIST_FOLD_LEFT_187_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_188(o, s, l) BOOST_PP_LIST_FOLD_LEFT_188_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_189(o, s, l) BOOST_PP_LIST_FOLD_LEFT_189_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_190(o, s, l) BOOST_PP_LIST_FOLD_LEFT_190_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_191(o, s, l) BOOST_PP_LIST_FOLD_LEFT_191_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_192(o, s, l) BOOST_PP_LIST_FOLD_LEFT_192_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_193(o, s, l) BOOST_PP_LIST_FOLD_LEFT_193_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_194(o, s, l) BOOST_PP_LIST_FOLD_LEFT_194_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_195(o, s, l) BOOST_PP_LIST_FOLD_LEFT_195_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_196(o, s, l) BOOST_PP_LIST_FOLD_LEFT_196_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_197(o, s, l) BOOST_PP_LIST_FOLD_LEFT_197_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_198(o, s, l) BOOST_PP_LIST_FOLD_LEFT_198_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_199(o, s, l) BOOST_PP_LIST_FOLD_LEFT_199_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_200(o, s, l) BOOST_PP_LIST_FOLD_LEFT_200_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_201(o, s, l) BOOST_PP_LIST_FOLD_LEFT_201_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_202(o, s, l) BOOST_PP_LIST_FOLD_LEFT_202_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_203(o, s, l) BOOST_PP_LIST_FOLD_LEFT_203_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_204(o, s, l) BOOST_PP_LIST_FOLD_LEFT_204_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_205(o, s, l) BOOST_PP_LIST_FOLD_LEFT_205_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_206(o, s, l) BOOST_PP_LIST_FOLD_LEFT_206_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_207(o, s, l) BOOST_PP_LIST_FOLD_LEFT_207_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_208(o, s, l) BOOST_PP_LIST_FOLD_LEFT_208_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_209(o, s, l) BOOST_PP_LIST_FOLD_LEFT_209_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_210(o, s, l) BOOST_PP_LIST_FOLD_LEFT_210_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_211(o, s, l) BOOST_PP_LIST_FOLD_LEFT_211_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_212(o, s, l) BOOST_PP_LIST_FOLD_LEFT_212_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_213(o, s, l) BOOST_PP_LIST_FOLD_LEFT_213_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_214(o, s, l) BOOST_PP_LIST_FOLD_LEFT_214_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_215(o, s, l) BOOST_PP_LIST_FOLD_LEFT_215_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_216(o, s, l) BOOST_PP_LIST_FOLD_LEFT_216_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_217(o, s, l) BOOST_PP_LIST_FOLD_LEFT_217_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_218(o, s, l) BOOST_PP_LIST_FOLD_LEFT_218_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_219(o, s, l) BOOST_PP_LIST_FOLD_LEFT_219_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_220(o, s, l) BOOST_PP_LIST_FOLD_LEFT_220_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_221(o, s, l) BOOST_PP_LIST_FOLD_LEFT_221_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_222(o, s, l) BOOST_PP_LIST_FOLD_LEFT_222_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_223(o, s, l) BOOST_PP_LIST_FOLD_LEFT_223_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_224(o, s, l) BOOST_PP_LIST_FOLD_LEFT_224_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_225(o, s, l) BOOST_PP_LIST_FOLD_LEFT_225_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_226(o, s, l) BOOST_PP_LIST_FOLD_LEFT_226_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_227(o, s, l) BOOST_PP_LIST_FOLD_LEFT_227_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_228(o, s, l) BOOST_PP_LIST_FOLD_LEFT_228_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_229(o, s, l) BOOST_PP_LIST_FOLD_LEFT_229_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_230(o, s, l) BOOST_PP_LIST_FOLD_LEFT_230_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_231(o, s, l) BOOST_PP_LIST_FOLD_LEFT_231_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_232(o, s, l) BOOST_PP_LIST_FOLD_LEFT_232_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_233(o, s, l) BOOST_PP_LIST_FOLD_LEFT_233_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_234(o, s, l) BOOST_PP_LIST_FOLD_LEFT_234_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_235(o, s, l) BOOST_PP_LIST_FOLD_LEFT_235_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_236(o, s, l) BOOST_PP_LIST_FOLD_LEFT_236_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_237(o, s, l) BOOST_PP_LIST_FOLD_LEFT_237_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_238(o, s, l) BOOST_PP_LIST_FOLD_LEFT_238_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_239(o, s, l) BOOST_PP_LIST_FOLD_LEFT_239_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_240(o, s, l) BOOST_PP_LIST_FOLD_LEFT_240_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_241(o, s, l) BOOST_PP_LIST_FOLD_LEFT_241_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_242(o, s, l) BOOST_PP_LIST_FOLD_LEFT_242_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_243(o, s, l) BOOST_PP_LIST_FOLD_LEFT_243_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_244(o, s, l) BOOST_PP_LIST_FOLD_LEFT_244_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_245(o, s, l) BOOST_PP_LIST_FOLD_LEFT_245_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_246(o, s, l) BOOST_PP_LIST_FOLD_LEFT_246_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_247(o, s, l) BOOST_PP_LIST_FOLD_LEFT_247_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_248(o, s, l) BOOST_PP_LIST_FOLD_LEFT_248_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_249(o, s, l) BOOST_PP_LIST_FOLD_LEFT_249_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_250(o, s, l) BOOST_PP_LIST_FOLD_LEFT_250_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_251(o, s, l) BOOST_PP_LIST_FOLD_LEFT_251_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_252(o, s, l) BOOST_PP_LIST_FOLD_LEFT_252_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_253(o, s, l) BOOST_PP_LIST_FOLD_LEFT_253_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_254(o, s, l) BOOST_PP_LIST_FOLD_LEFT_254_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_255(o, s, l) BOOST_PP_LIST_FOLD_LEFT_255_D(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_256(o, s, l) BOOST_PP_LIST_FOLD_LEFT_256_D(o, s, l) # # define BOOST_PP_LIST_FOLD_LEFT_1_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_2, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(2, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_2_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_3, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(3, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_3_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_4, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(4, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_4_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_5, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(5, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_5_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_6, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(6, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_6_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_7, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(7, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_7_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_8, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(8, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_8_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_9, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(9, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_9_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_10, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(10, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_10_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_11, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(11, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_11_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_12, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(12, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_12_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_13, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(13, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_13_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_14, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(14, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_14_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_15, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(15, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_15_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_16, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(16, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_16_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_17, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(17, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_17_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_18, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(18, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_18_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_19, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(19, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_19_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_20, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(20, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_20_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_21, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(21, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_21_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_22, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(22, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_22_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_23, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(23, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_23_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_24, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(24, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_24_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_25, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(25, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_25_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_26, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(26, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_26_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_27, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(27, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_27_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_28, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(28, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_28_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_29, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(29, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_29_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_30, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(30, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_30_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_31, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(31, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_31_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_32, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(32, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_32_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_33, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(33, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_33_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_34, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(34, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_34_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_35, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(35, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_35_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_36, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(36, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_36_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_37, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(37, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_37_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_38, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(38, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_38_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_39, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(39, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_39_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_40, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(40, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_40_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_41, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(41, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_41_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_42, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(42, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_42_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_43, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(43, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_43_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_44, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(44, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_44_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_45, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(45, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_45_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_46, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(46, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_46_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_47, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(47, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_47_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_48, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(48, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_48_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_49, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(49, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_49_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_50, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(50, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_50_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_51, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(51, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_51_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_52, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(52, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_52_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_53, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(53, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_53_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_54, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(54, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_54_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_55, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(55, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_55_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_56, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(56, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_56_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_57, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(57, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_57_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_58, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(58, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_58_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_59, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(59, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_59_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_60, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(60, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_60_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_61, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(61, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_61_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_62, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(62, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_62_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_63, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(63, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_63_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_64, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(64, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_64_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_65, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(65, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_65_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_66, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(66, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_66_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_67, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(67, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_67_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_68, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(68, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_68_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_69, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(69, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_69_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_70, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(70, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_70_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_71, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(71, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_71_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_72, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(72, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_72_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_73, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(73, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_73_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_74, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(74, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_74_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_75, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(75, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_75_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_76, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(76, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_76_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_77, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(77, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_77_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_78, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(78, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_78_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_79, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(79, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_79_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_80, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(80, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_80_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_81, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(81, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_81_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_82, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(82, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_82_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_83, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(83, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_83_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_84, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(84, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_84_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_85, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(85, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_85_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_86, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(86, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_86_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_87, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(87, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_87_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_88, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(88, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_88_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_89, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(89, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_89_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_90, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(90, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_90_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_91, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(91, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_91_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_92, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(92, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_92_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_93, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(93, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_93_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_94, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(94, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_94_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_95, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(95, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_95_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_96, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(96, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_96_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_97, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(97, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_97_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_98, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(98, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_98_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_99, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(99, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_99_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_100, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(100, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_100_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_101, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(101, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_101_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_102, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(102, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_102_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_103, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(103, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_103_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_104, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(104, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_104_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_105, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(105, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_105_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_106, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(106, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_106_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_107, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(107, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_107_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_108, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(108, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_108_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_109, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(109, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_109_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_110, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(110, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_110_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_111, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(111, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_111_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_112, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(112, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_112_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_113, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(113, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_113_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_114, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(114, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_114_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_115, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(115, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_115_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_116, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(116, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_116_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_117, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(117, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_117_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_118, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(118, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_118_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_119, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(119, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_119_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_120, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(120, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_120_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_121, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(121, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_121_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_122, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(122, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_122_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_123, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(123, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_123_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_124, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(124, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_124_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_125, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(125, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_125_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_126, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(126, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_126_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_127, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(127, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_127_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_128, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(128, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_128_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_129, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(129, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_129_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_130, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(130, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_130_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_131, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(131, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_131_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_132, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(132, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_132_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_133, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(133, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_133_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_134, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(134, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_134_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_135, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(135, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_135_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_136, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(136, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_136_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_137, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(137, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_137_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_138, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(138, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_138_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_139, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(139, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_139_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_140, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(140, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_140_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_141, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(141, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_141_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_142, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(142, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_142_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_143, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(143, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_143_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_144, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(144, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_144_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_145, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(145, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_145_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_146, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(146, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_146_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_147, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(147, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_147_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_148, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(148, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_148_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_149, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(149, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_149_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_150, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(150, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_150_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_151, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(151, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_151_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_152, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(152, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_152_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_153, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(153, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_153_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_154, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(154, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_154_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_155, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(155, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_155_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_156, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(156, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_156_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_157, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(157, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_157_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_158, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(158, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_158_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_159, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(159, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_159_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_160, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(160, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_160_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_161, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(161, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_161_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_162, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(162, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_162_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_163, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(163, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_163_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_164, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(164, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_164_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_165, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(165, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_165_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_166, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(166, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_166_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_167, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(167, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_167_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_168, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(168, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_168_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_169, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(169, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_169_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_170, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(170, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_170_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_171, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(171, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_171_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_172, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(172, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_172_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_173, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(173, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_173_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_174, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(174, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_174_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_175, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(175, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_175_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_176, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(176, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_176_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_177, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(177, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_177_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_178, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(178, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_178_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_179, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(179, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_179_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_180, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(180, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_180_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_181, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(181, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_181_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_182, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(182, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_182_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_183, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(183, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_183_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_184, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(184, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_184_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_185, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(185, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_185_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_186, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(186, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_186_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_187, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(187, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_187_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_188, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(188, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_188_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_189, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(189, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_189_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_190, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(190, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_190_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_191, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(191, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_191_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_192, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(192, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_192_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_193, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(193, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_193_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_194, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(194, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_194_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_195, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(195, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_195_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_196, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(196, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_196_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_197, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(197, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_197_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_198, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(198, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_198_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_199, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(199, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_199_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_200, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(200, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_200_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_201, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(201, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_201_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_202, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(202, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_202_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_203, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(203, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_203_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_204, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(204, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_204_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_205, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(205, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_205_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_206, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(206, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_206_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_207, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(207, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_207_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_208, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(208, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_208_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_209, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(209, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_209_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_210, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(210, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_210_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_211, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(211, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_211_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_212, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(212, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_212_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_213, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(213, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_213_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_214, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(214, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_214_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_215, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(215, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_215_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_216, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(216, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_216_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_217, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(217, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_217_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_218, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(218, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_218_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_219, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(219, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_219_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_220, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(220, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_220_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_221, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(221, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_221_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_222, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(222, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_222_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_223, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(223, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_223_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_224, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(224, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_224_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_225, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(225, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_225_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_226, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(226, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_226_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_227, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(227, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_227_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_228, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(228, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_228_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_229, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(229, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_229_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_230, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(230, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_230_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_231, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(231, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_231_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_232, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(232, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_232_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_233, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(233, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_233_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_234, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(234, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_234_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_235, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(235, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_235_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_236, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(236, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_236_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_237, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(237, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_237_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_238, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(238, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_238_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_239, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(239, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_239_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_240, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(240, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_240_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_241, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(241, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_241_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_242, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(242, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_242_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_243, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(243, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_243_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_244, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(244, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_244_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_245, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(245, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_245_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_246, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(246, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_246_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_247, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(247, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_247_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_248, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(248, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_248_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_249, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(249, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_249_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_250, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(250, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_250_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_251, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(251, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_251_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_252, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(252, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_252_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_253, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(253, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_253_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_254, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(254, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_254_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_255, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(255, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_255_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_256, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(256, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_256_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_257, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(257, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/detail/edg/fold_right.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_DETAIL_EDG_FOLD_RIGHT_HPP # define BOOST_PREPROCESSOR_LIST_DETAIL_EDG_FOLD_RIGHT_HPP # # include # include # include # # define BOOST_PP_LIST_FOLD_RIGHT_1(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_1_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_2(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_2_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_3(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_3_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_4(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_4_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_5(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_5_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_6(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_6_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_7(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_7_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_8(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_8_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_9(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_9_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_10(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_10_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_11(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_11_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_12(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_12_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_13(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_13_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_14(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_14_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_15(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_15_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_16(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_16_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_17(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_17_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_18(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_18_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_19(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_19_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_20(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_20_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_21(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_21_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_22(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_22_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_23(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_23_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_24(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_24_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_25(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_25_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_26(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_26_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_27(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_27_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_28(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_28_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_29(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_29_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_30(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_30_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_31(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_31_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_32(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_32_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_33(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_33_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_34(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_34_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_35(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_35_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_36(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_36_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_37(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_37_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_38(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_38_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_39(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_39_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_40(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_40_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_41(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_41_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_42(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_42_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_43(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_43_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_44(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_44_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_45(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_45_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_46(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_46_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_47(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_47_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_48(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_48_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_49(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_49_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_50(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_50_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_51(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_51_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_52(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_52_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_53(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_53_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_54(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_54_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_55(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_55_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_56(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_56_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_57(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_57_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_58(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_58_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_59(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_59_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_60(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_60_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_61(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_61_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_62(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_62_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_63(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_63_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_64(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_64_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_65(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_65_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_66(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_66_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_67(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_67_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_68(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_68_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_69(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_69_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_70(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_70_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_71(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_71_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_72(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_72_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_73(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_73_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_74(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_74_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_75(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_75_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_76(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_76_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_77(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_77_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_78(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_78_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_79(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_79_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_80(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_80_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_81(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_81_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_82(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_82_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_83(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_83_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_84(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_84_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_85(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_85_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_86(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_86_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_87(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_87_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_88(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_88_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_89(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_89_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_90(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_90_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_91(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_91_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_92(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_92_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_93(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_93_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_94(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_94_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_95(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_95_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_96(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_96_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_97(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_97_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_98(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_98_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_99(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_99_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_100(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_100_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_101(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_101_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_102(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_102_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_103(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_103_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_104(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_104_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_105(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_105_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_106(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_106_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_107(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_107_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_108(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_108_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_109(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_109_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_110(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_110_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_111(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_111_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_112(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_112_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_113(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_113_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_114(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_114_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_115(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_115_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_116(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_116_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_117(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_117_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_118(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_118_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_119(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_119_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_120(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_120_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_121(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_121_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_122(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_122_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_123(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_123_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_124(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_124_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_125(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_125_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_126(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_126_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_127(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_127_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_128(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_128_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_129(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_129_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_130(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_130_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_131(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_131_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_132(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_132_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_133(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_133_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_134(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_134_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_135(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_135_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_136(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_136_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_137(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_137_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_138(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_138_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_139(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_139_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_140(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_140_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_141(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_141_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_142(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_142_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_143(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_143_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_144(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_144_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_145(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_145_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_146(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_146_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_147(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_147_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_148(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_148_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_149(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_149_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_150(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_150_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_151(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_151_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_152(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_152_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_153(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_153_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_154(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_154_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_155(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_155_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_156(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_156_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_157(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_157_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_158(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_158_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_159(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_159_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_160(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_160_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_161(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_161_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_162(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_162_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_163(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_163_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_164(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_164_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_165(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_165_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_166(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_166_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_167(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_167_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_168(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_168_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_169(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_169_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_170(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_170_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_171(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_171_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_172(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_172_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_173(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_173_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_174(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_174_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_175(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_175_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_176(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_176_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_177(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_177_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_178(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_178_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_179(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_179_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_180(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_180_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_181(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_181_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_182(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_182_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_183(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_183_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_184(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_184_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_185(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_185_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_186(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_186_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_187(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_187_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_188(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_188_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_189(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_189_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_190(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_190_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_191(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_191_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_192(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_192_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_193(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_193_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_194(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_194_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_195(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_195_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_196(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_196_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_197(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_197_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_198(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_198_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_199(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_199_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_200(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_200_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_201(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_201_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_202(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_202_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_203(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_203_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_204(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_204_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_205(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_205_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_206(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_206_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_207(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_207_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_208(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_208_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_209(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_209_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_210(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_210_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_211(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_211_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_212(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_212_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_213(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_213_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_214(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_214_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_215(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_215_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_216(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_216_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_217(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_217_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_218(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_218_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_219(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_219_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_220(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_220_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_221(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_221_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_222(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_222_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_223(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_223_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_224(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_224_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_225(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_225_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_226(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_226_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_227(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_227_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_228(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_228_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_229(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_229_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_230(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_230_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_231(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_231_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_232(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_232_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_233(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_233_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_234(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_234_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_235(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_235_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_236(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_236_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_237(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_237_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_238(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_238_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_239(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_239_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_240(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_240_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_241(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_241_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_242(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_242_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_243(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_243_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_244(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_244_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_245(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_245_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_246(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_246_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_247(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_247_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_248(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_248_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_249(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_249_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_250(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_250_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_251(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_251_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_252(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_252_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_253(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_253_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_254(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_254_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_255(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_255_D(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_256(o, s, l) BOOST_PP_LIST_FOLD_RIGHT_256_D(o, s, l) # # define BOOST_PP_LIST_FOLD_RIGHT_1_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(2, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_2, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_2_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(3, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_3, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_3_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(4, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_4, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_4_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(5, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_5, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_5_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(6, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_6, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_6_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(7, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_7, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_7_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(8, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_8, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_8_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(9, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_9, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_9_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(10, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_10, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_10_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(11, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_11, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_11_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(12, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_12, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_12_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(13, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_13, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_13_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(14, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_14, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_14_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(15, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_15, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_15_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(16, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_16, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_16_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(17, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_17, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_17_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(18, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_18, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_18_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(19, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_19, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_19_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(20, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_20, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_20_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(21, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_21, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_21_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(22, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_22, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_22_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(23, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_23, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_23_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(24, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_24, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_24_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(25, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_25, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_25_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(26, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_26, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_26_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(27, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_27, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_27_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(28, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_28, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_28_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(29, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_29, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_29_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(30, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_30, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_30_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(31, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_31, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_31_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(32, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_32, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_32_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(33, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_33, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_33_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(34, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_34, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_34_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(35, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_35, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_35_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(36, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_36, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_36_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(37, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_37, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_37_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(38, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_38, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_38_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(39, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_39, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_39_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(40, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_40, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_40_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(41, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_41, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_41_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(42, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_42, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_42_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(43, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_43, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_43_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(44, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_44, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_44_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(45, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_45, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_45_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(46, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_46, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_46_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(47, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_47, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_47_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(48, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_48, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_48_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(49, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_49, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_49_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(50, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_50, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_50_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(51, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_51, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_51_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(52, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_52, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_52_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(53, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_53, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_53_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(54, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_54, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_54_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(55, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_55, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_55_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(56, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_56, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_56_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(57, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_57, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_57_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(58, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_58, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_58_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(59, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_59, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_59_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(60, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_60, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_60_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(61, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_61, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_61_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(62, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_62, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_62_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(63, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_63, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_63_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(64, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_64, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_64_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(65, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_65, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_65_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(66, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_66, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_66_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(67, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_67, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_67_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(68, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_68, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_68_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(69, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_69, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_69_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(70, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_70, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_70_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(71, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_71, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_71_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(72, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_72, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_72_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(73, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_73, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_73_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(74, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_74, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_74_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(75, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_75, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_75_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(76, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_76, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_76_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(77, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_77, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_77_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(78, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_78, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_78_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(79, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_79, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_79_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(80, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_80, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_80_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(81, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_81, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_81_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(82, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_82, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_82_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(83, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_83, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_83_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(84, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_84, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_84_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(85, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_85, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_85_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(86, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_86, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_86_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(87, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_87, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_87_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(88, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_88, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_88_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(89, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_89, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_89_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(90, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_90, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_90_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(91, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_91, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_91_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(92, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_92, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_92_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(93, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_93, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_93_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(94, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_94, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_94_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(95, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_95, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_95_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(96, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_96, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_96_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(97, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_97, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_97_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(98, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_98, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_98_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(99, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_99, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_99_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(100, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_100, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_100_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(101, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_101, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_101_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(102, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_102, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_102_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(103, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_103, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_103_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(104, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_104, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_104_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(105, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_105, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_105_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(106, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_106, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_106_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(107, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_107, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_107_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(108, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_108, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_108_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(109, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_109, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_109_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(110, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_110, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_110_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(111, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_111, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_111_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(112, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_112, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_112_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(113, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_113, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_113_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(114, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_114, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_114_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(115, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_115, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_115_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(116, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_116, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_116_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(117, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_117, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_117_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(118, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_118, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_118_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(119, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_119, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_119_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(120, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_120, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_120_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(121, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_121, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_121_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(122, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_122, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_122_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(123, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_123, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_123_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(124, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_124, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_124_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(125, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_125, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_125_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(126, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_126, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_126_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(127, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_127, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_127_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(128, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_128, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_128_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(129, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_129, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_129_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(130, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_130, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_130_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(131, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_131, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_131_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(132, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_132, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_132_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(133, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_133, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_133_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(134, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_134, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_134_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(135, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_135, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_135_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(136, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_136, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_136_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(137, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_137, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_137_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(138, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_138, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_138_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(139, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_139, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_139_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(140, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_140, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_140_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(141, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_141, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_141_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(142, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_142, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_142_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(143, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_143, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_143_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(144, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_144, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_144_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(145, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_145, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_145_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(146, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_146, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_146_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(147, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_147, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_147_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(148, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_148, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_148_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(149, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_149, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_149_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(150, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_150, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_150_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(151, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_151, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_151_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(152, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_152, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_152_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(153, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_153, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_153_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(154, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_154, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_154_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(155, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_155, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_155_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(156, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_156, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_156_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(157, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_157, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_157_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(158, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_158, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_158_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(159, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_159, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_159_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(160, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_160, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_160_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(161, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_161, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_161_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(162, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_162, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_162_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(163, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_163, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_163_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(164, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_164, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_164_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(165, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_165, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_165_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(166, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_166, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_166_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(167, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_167, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_167_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(168, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_168, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_168_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(169, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_169, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_169_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(170, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_170, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_170_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(171, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_171, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_171_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(172, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_172, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_172_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(173, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_173, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_173_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(174, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_174, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_174_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(175, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_175, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_175_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(176, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_176, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_176_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(177, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_177, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_177_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(178, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_178, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_178_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(179, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_179, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_179_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(180, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_180, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_180_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(181, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_181, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_181_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(182, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_182, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_182_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(183, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_183, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_183_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(184, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_184, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_184_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(185, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_185, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_185_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(186, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_186, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_186_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(187, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_187, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_187_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(188, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_188, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_188_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(189, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_189, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_189_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(190, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_190, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_190_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(191, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_191, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_191_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(192, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_192, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_192_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(193, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_193, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_193_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(194, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_194, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_194_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(195, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_195, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_195_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(196, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_196, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_196_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(197, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_197, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_197_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(198, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_198, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_198_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(199, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_199, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_199_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(200, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_200, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_200_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(201, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_201, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_201_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(202, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_202, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_202_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(203, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_203, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_203_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(204, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_204, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_204_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(205, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_205, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_205_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(206, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_206, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_206_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(207, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_207, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_207_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(208, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_208, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_208_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(209, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_209, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_209_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(210, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_210, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_210_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(211, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_211, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_211_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(212, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_212, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_212_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(213, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_213, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_213_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(214, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_214, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_214_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(215, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_215, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_215_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(216, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_216, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_216_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(217, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_217, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_217_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(218, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_218, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_218_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(219, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_219, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_219_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(220, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_220, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_220_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(221, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_221, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_221_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(222, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_222, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_222_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(223, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_223, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_223_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(224, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_224, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_224_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(225, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_225, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_225_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(226, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_226, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_226_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(227, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_227, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_227_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(228, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_228, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_228_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(229, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_229, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_229_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(230, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_230, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_230_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(231, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_231, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_231_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(232, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_232, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_232_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(233, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_233, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_233_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(234, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_234, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_234_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(235, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_235, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_235_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(236, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_236, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_236_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(237, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_237, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_237_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(238, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_238, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_238_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(239, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_239, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_239_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(240, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_240, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_240_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(241, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_241, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_241_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(242, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_242, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_242_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(243, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_243, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_243_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(244, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_244, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_244_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(245, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_245, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_245_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(246, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_246, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_246_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(247, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_247, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_247_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(248, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_248, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_248_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(249, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_249, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_249_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(250, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_250, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_250_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(251, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_251, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_251_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(252, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_252, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_252_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(253, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_253, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_253_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(254, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_254, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_254_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(255, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_255, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_255_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(256, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_256, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # define BOOST_PP_LIST_FOLD_RIGHT_256_D(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), o, s BOOST_PP_TUPLE_EAT_3)(257, BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_RIGHT_257, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3)(o, s, BOOST_PP_LIST_REST(l)), BOOST_PP_LIST_FIRST(l)) # # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_NIL 1 # # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_1(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_2(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_3(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_4(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_5(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_6(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_7(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_8(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_9(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_10(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_11(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_12(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_13(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_14(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_15(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_16(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_17(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_18(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_19(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_20(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_21(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_22(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_23(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_24(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_25(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_26(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_27(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_28(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_29(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_30(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_31(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_32(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_33(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_34(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_35(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_36(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_37(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_38(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_39(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_40(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_41(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_42(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_43(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_44(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_45(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_46(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_47(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_48(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_49(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_50(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_51(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_52(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_53(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_54(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_55(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_56(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_57(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_58(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_59(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_60(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_61(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_62(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_63(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_64(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_65(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_66(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_67(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_68(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_69(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_70(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_71(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_72(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_73(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_74(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_75(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_76(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_77(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_78(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_79(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_80(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_81(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_82(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_83(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_84(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_85(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_86(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_87(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_88(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_89(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_90(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_91(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_92(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_93(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_94(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_95(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_96(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_97(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_98(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_99(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_100(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_101(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_102(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_103(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_104(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_105(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_106(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_107(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_108(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_109(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_110(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_111(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_112(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_113(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_114(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_115(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_116(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_117(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_118(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_119(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_120(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_121(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_122(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_123(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_124(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_125(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_126(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_127(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_128(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_129(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_130(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_131(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_132(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_133(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_134(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_135(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_136(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_137(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_138(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_139(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_140(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_141(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_142(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_143(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_144(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_145(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_146(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_147(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_148(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_149(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_150(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_151(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_152(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_153(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_154(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_155(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_156(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_157(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_158(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_159(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_160(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_161(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_162(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_163(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_164(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_165(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_166(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_167(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_168(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_169(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_170(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_171(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_172(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_173(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_174(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_175(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_176(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_177(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_178(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_179(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_180(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_181(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_182(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_183(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_184(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_185(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_186(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_187(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_188(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_189(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_190(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_191(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_192(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_193(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_194(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_195(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_196(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_197(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_198(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_199(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_200(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_201(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_202(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_203(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_204(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_205(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_206(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_207(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_208(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_209(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_210(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_211(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_212(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_213(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_214(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_215(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_216(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_217(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_218(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_219(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_220(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_221(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_222(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_223(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_224(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_225(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_226(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_227(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_228(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_229(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_230(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_231(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_232(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_233(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_234(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_235(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_236(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_237(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_238(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_239(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_240(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_241(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_242(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_243(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_244(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_245(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_246(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_247(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_248(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_249(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_250(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_251(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_252(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_253(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_254(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_255(o, s, l) 0 # define BOOST_PP_LIST_FOLD_RIGHT_CHECK_BOOST_PP_LIST_FOLD_RIGHT_256(o, s, l) 0 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/detail/fold_left.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_LEFT_HPP # define BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_LEFT_HPP # # include # include # include # include # # define BOOST_PP_LIST_FOLD_LEFT_1(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_2, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(2, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_2(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_3, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(3, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_3(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_4, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(4, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_4(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_5, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(5, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_5(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_6, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(6, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_6(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_7, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(7, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_7(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_8, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(8, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_8(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_9, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(9, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_9(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_10, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(10, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_10(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_11, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(11, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_11(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_12, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(12, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_12(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_13, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(13, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_13(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_14, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(14, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_14(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_15, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(15, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_15(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_16, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(16, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_16(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_17, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(17, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_17(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_18, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(18, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_18(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_19, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(19, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_19(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_20, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(20, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_20(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_21, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(21, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_21(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_22, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(22, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_22(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_23, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(23, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_23(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_24, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(24, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_24(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_25, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(25, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_25(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_26, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(26, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_26(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_27, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(27, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_27(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_28, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(28, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_28(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_29, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(29, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_29(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_30, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(30, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_30(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_31, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(31, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_31(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_32, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(32, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_32(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_33, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(33, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_33(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_34, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(34, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_34(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_35, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(35, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_35(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_36, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(36, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_36(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_37, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(37, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_37(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_38, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(38, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_38(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_39, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(39, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_39(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_40, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(40, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_40(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_41, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(41, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_41(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_42, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(42, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_42(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_43, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(43, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_43(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_44, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(44, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_44(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_45, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(45, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_45(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_46, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(46, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_46(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_47, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(47, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_47(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_48, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(48, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_48(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_49, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(49, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_49(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_50, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(50, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_50(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_51, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(51, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_51(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_52, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(52, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_52(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_53, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(53, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_53(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_54, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(54, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_54(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_55, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(55, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_55(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_56, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(56, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_56(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_57, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(57, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_57(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_58, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(58, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_58(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_59, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(59, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_59(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_60, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(60, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_60(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_61, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(61, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_61(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_62, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(62, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_62(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_63, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(63, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_63(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_64, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(64, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_64(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_65, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(65, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_65(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_66, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(66, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_66(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_67, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(67, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_67(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_68, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(68, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_68(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_69, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(69, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_69(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_70, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(70, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_70(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_71, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(71, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_71(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_72, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(72, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_72(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_73, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(73, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_73(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_74, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(74, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_74(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_75, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(75, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_75(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_76, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(76, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_76(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_77, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(77, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_77(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_78, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(78, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_78(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_79, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(79, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_79(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_80, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(80, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_80(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_81, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(81, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_81(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_82, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(82, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_82(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_83, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(83, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_83(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_84, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(84, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_84(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_85, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(85, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_85(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_86, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(86, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_86(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_87, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(87, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_87(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_88, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(88, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_88(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_89, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(89, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_89(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_90, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(90, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_90(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_91, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(91, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_91(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_92, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(92, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_92(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_93, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(93, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_93(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_94, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(94, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_94(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_95, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(95, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_95(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_96, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(96, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_96(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_97, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(97, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_97(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_98, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(98, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_98(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_99, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(99, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_99(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_100, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(100, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_100(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_101, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(101, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_101(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_102, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(102, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_102(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_103, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(103, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_103(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_104, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(104, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_104(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_105, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(105, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_105(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_106, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(106, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_106(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_107, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(107, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_107(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_108, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(108, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_108(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_109, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(109, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_109(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_110, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(110, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_110(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_111, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(111, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_111(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_112, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(112, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_112(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_113, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(113, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_113(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_114, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(114, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_114(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_115, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(115, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_115(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_116, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(116, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_116(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_117, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(117, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_117(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_118, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(118, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_118(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_119, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(119, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_119(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_120, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(120, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_120(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_121, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(121, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_121(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_122, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(122, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_122(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_123, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(123, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_123(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_124, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(124, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_124(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_125, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(125, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_125(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_126, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(126, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_126(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_127, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(127, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_127(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_128, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(128, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_128(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_129, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(129, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_129(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_130, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(130, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_130(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_131, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(131, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_131(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_132, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(132, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_132(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_133, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(133, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_133(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_134, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(134, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_134(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_135, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(135, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_135(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_136, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(136, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_136(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_137, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(137, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_137(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_138, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(138, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_138(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_139, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(139, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_139(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_140, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(140, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_140(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_141, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(141, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_141(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_142, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(142, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_142(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_143, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(143, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_143(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_144, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(144, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_144(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_145, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(145, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_145(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_146, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(146, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_146(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_147, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(147, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_147(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_148, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(148, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_148(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_149, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(149, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_149(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_150, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(150, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_150(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_151, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(151, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_151(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_152, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(152, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_152(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_153, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(153, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_153(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_154, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(154, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_154(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_155, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(155, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_155(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_156, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(156, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_156(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_157, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(157, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_157(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_158, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(158, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_158(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_159, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(159, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_159(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_160, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(160, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_160(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_161, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(161, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_161(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_162, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(162, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_162(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_163, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(163, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_163(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_164, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(164, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_164(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_165, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(165, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_165(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_166, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(166, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_166(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_167, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(167, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_167(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_168, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(168, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_168(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_169, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(169, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_169(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_170, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(170, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_170(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_171, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(171, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_171(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_172, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(172, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_172(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_173, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(173, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_173(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_174, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(174, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_174(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_175, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(175, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_175(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_176, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(176, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_176(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_177, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(177, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_177(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_178, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(178, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_178(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_179, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(179, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_179(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_180, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(180, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_180(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_181, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(181, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_181(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_182, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(182, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_182(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_183, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(183, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_183(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_184, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(184, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_184(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_185, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(185, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_185(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_186, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(186, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_186(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_187, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(187, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_187(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_188, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(188, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_188(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_189, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(189, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_189(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_190, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(190, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_190(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_191, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(191, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_191(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_192, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(192, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_192(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_193, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(193, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_193(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_194, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(194, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_194(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_195, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(195, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_195(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_196, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(196, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_196(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_197, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(197, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_197(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_198, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(198, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_198(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_199, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(199, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_199(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_200, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(200, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_200(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_201, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(201, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_201(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_202, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(202, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_202(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_203, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(203, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_203(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_204, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(204, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_204(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_205, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(205, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_205(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_206, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(206, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_206(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_207, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(207, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_207(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_208, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(208, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_208(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_209, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(209, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_209(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_210, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(210, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_210(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_211, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(211, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_211(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_212, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(212, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_212(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_213, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(213, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_213(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_214, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(214, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_214(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_215, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(215, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_215(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_216, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(216, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_216(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_217, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(217, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_217(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_218, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(218, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_218(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_219, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(219, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_219(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_220, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(220, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_220(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_221, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(221, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_221(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_222, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(222, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_222(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_223, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(223, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_223(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_224, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(224, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_224(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_225, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(225, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_225(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_226, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(226, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_226(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_227, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(227, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_227(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_228, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(228, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_228(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_229, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(229, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_229(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_230, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(230, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_230(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_231, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(231, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_231(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_232, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(232, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_232(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_233, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(233, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_233(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_234, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(234, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_234(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_235, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(235, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_235(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_236, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(236, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_236(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_237, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(237, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_237(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_238, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(238, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_238(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_239, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(239, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_239(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_240, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(240, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_240(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_241, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(241, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_241(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_242, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(242, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_242(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_243, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(243, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_243(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_244, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(244, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_244(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_245, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(245, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_245(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_246, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(246, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_246(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_247, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(247, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_247(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_248, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(248, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_248(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_249, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(249, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_249(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_250, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(250, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_250(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_251, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(251, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_251(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_252, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(252, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_252(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_253, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(253, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_253(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_254, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(254, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_254(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_255, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(255, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_255(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_256, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(256, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # define BOOST_PP_LIST_FOLD_LEFT_256(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_257, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(257, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l)) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/detail/fold_right.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_RIGHT_HPP # define BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_RIGHT_HPP # # include # include # # define BOOST_PP_LIST_FOLD_RIGHT_1(o, s, l) BOOST_PP_LIST_FOLD_LEFT_1(o, s, BOOST_PP_LIST_REVERSE_D(1, l)) # define BOOST_PP_LIST_FOLD_RIGHT_2(o, s, l) BOOST_PP_LIST_FOLD_LEFT_2(o, s, BOOST_PP_LIST_REVERSE_D(2, l)) # define BOOST_PP_LIST_FOLD_RIGHT_3(o, s, l) BOOST_PP_LIST_FOLD_LEFT_3(o, s, BOOST_PP_LIST_REVERSE_D(3, l)) # define BOOST_PP_LIST_FOLD_RIGHT_4(o, s, l) BOOST_PP_LIST_FOLD_LEFT_4(o, s, BOOST_PP_LIST_REVERSE_D(4, l)) # define BOOST_PP_LIST_FOLD_RIGHT_5(o, s, l) BOOST_PP_LIST_FOLD_LEFT_5(o, s, BOOST_PP_LIST_REVERSE_D(5, l)) # define BOOST_PP_LIST_FOLD_RIGHT_6(o, s, l) BOOST_PP_LIST_FOLD_LEFT_6(o, s, BOOST_PP_LIST_REVERSE_D(6, l)) # define BOOST_PP_LIST_FOLD_RIGHT_7(o, s, l) BOOST_PP_LIST_FOLD_LEFT_7(o, s, BOOST_PP_LIST_REVERSE_D(7, l)) # define BOOST_PP_LIST_FOLD_RIGHT_8(o, s, l) BOOST_PP_LIST_FOLD_LEFT_8(o, s, BOOST_PP_LIST_REVERSE_D(8, l)) # define BOOST_PP_LIST_FOLD_RIGHT_9(o, s, l) BOOST_PP_LIST_FOLD_LEFT_9(o, s, BOOST_PP_LIST_REVERSE_D(9, l)) # define BOOST_PP_LIST_FOLD_RIGHT_10(o, s, l) BOOST_PP_LIST_FOLD_LEFT_10(o, s, BOOST_PP_LIST_REVERSE_D(10, l)) # define BOOST_PP_LIST_FOLD_RIGHT_11(o, s, l) BOOST_PP_LIST_FOLD_LEFT_11(o, s, BOOST_PP_LIST_REVERSE_D(11, l)) # define BOOST_PP_LIST_FOLD_RIGHT_12(o, s, l) BOOST_PP_LIST_FOLD_LEFT_12(o, s, BOOST_PP_LIST_REVERSE_D(12, l)) # define BOOST_PP_LIST_FOLD_RIGHT_13(o, s, l) BOOST_PP_LIST_FOLD_LEFT_13(o, s, BOOST_PP_LIST_REVERSE_D(13, l)) # define BOOST_PP_LIST_FOLD_RIGHT_14(o, s, l) BOOST_PP_LIST_FOLD_LEFT_14(o, s, BOOST_PP_LIST_REVERSE_D(14, l)) # define BOOST_PP_LIST_FOLD_RIGHT_15(o, s, l) BOOST_PP_LIST_FOLD_LEFT_15(o, s, BOOST_PP_LIST_REVERSE_D(15, l)) # define BOOST_PP_LIST_FOLD_RIGHT_16(o, s, l) BOOST_PP_LIST_FOLD_LEFT_16(o, s, BOOST_PP_LIST_REVERSE_D(16, l)) # define BOOST_PP_LIST_FOLD_RIGHT_17(o, s, l) BOOST_PP_LIST_FOLD_LEFT_17(o, s, BOOST_PP_LIST_REVERSE_D(17, l)) # define BOOST_PP_LIST_FOLD_RIGHT_18(o, s, l) BOOST_PP_LIST_FOLD_LEFT_18(o, s, BOOST_PP_LIST_REVERSE_D(18, l)) # define BOOST_PP_LIST_FOLD_RIGHT_19(o, s, l) BOOST_PP_LIST_FOLD_LEFT_19(o, s, BOOST_PP_LIST_REVERSE_D(19, l)) # define BOOST_PP_LIST_FOLD_RIGHT_20(o, s, l) BOOST_PP_LIST_FOLD_LEFT_20(o, s, BOOST_PP_LIST_REVERSE_D(20, l)) # define BOOST_PP_LIST_FOLD_RIGHT_21(o, s, l) BOOST_PP_LIST_FOLD_LEFT_21(o, s, BOOST_PP_LIST_REVERSE_D(21, l)) # define BOOST_PP_LIST_FOLD_RIGHT_22(o, s, l) BOOST_PP_LIST_FOLD_LEFT_22(o, s, BOOST_PP_LIST_REVERSE_D(22, l)) # define BOOST_PP_LIST_FOLD_RIGHT_23(o, s, l) BOOST_PP_LIST_FOLD_LEFT_23(o, s, BOOST_PP_LIST_REVERSE_D(23, l)) # define BOOST_PP_LIST_FOLD_RIGHT_24(o, s, l) BOOST_PP_LIST_FOLD_LEFT_24(o, s, BOOST_PP_LIST_REVERSE_D(24, l)) # define BOOST_PP_LIST_FOLD_RIGHT_25(o, s, l) BOOST_PP_LIST_FOLD_LEFT_25(o, s, BOOST_PP_LIST_REVERSE_D(25, l)) # define BOOST_PP_LIST_FOLD_RIGHT_26(o, s, l) BOOST_PP_LIST_FOLD_LEFT_26(o, s, BOOST_PP_LIST_REVERSE_D(26, l)) # define BOOST_PP_LIST_FOLD_RIGHT_27(o, s, l) BOOST_PP_LIST_FOLD_LEFT_27(o, s, BOOST_PP_LIST_REVERSE_D(27, l)) # define BOOST_PP_LIST_FOLD_RIGHT_28(o, s, l) BOOST_PP_LIST_FOLD_LEFT_28(o, s, BOOST_PP_LIST_REVERSE_D(28, l)) # define BOOST_PP_LIST_FOLD_RIGHT_29(o, s, l) BOOST_PP_LIST_FOLD_LEFT_29(o, s, BOOST_PP_LIST_REVERSE_D(29, l)) # define BOOST_PP_LIST_FOLD_RIGHT_30(o, s, l) BOOST_PP_LIST_FOLD_LEFT_30(o, s, BOOST_PP_LIST_REVERSE_D(30, l)) # define BOOST_PP_LIST_FOLD_RIGHT_31(o, s, l) BOOST_PP_LIST_FOLD_LEFT_31(o, s, BOOST_PP_LIST_REVERSE_D(31, l)) # define BOOST_PP_LIST_FOLD_RIGHT_32(o, s, l) BOOST_PP_LIST_FOLD_LEFT_32(o, s, BOOST_PP_LIST_REVERSE_D(32, l)) # define BOOST_PP_LIST_FOLD_RIGHT_33(o, s, l) BOOST_PP_LIST_FOLD_LEFT_33(o, s, BOOST_PP_LIST_REVERSE_D(33, l)) # define BOOST_PP_LIST_FOLD_RIGHT_34(o, s, l) BOOST_PP_LIST_FOLD_LEFT_34(o, s, BOOST_PP_LIST_REVERSE_D(34, l)) # define BOOST_PP_LIST_FOLD_RIGHT_35(o, s, l) BOOST_PP_LIST_FOLD_LEFT_35(o, s, BOOST_PP_LIST_REVERSE_D(35, l)) # define BOOST_PP_LIST_FOLD_RIGHT_36(o, s, l) BOOST_PP_LIST_FOLD_LEFT_36(o, s, BOOST_PP_LIST_REVERSE_D(36, l)) # define BOOST_PP_LIST_FOLD_RIGHT_37(o, s, l) BOOST_PP_LIST_FOLD_LEFT_37(o, s, BOOST_PP_LIST_REVERSE_D(37, l)) # define BOOST_PP_LIST_FOLD_RIGHT_38(o, s, l) BOOST_PP_LIST_FOLD_LEFT_38(o, s, BOOST_PP_LIST_REVERSE_D(38, l)) # define BOOST_PP_LIST_FOLD_RIGHT_39(o, s, l) BOOST_PP_LIST_FOLD_LEFT_39(o, s, BOOST_PP_LIST_REVERSE_D(39, l)) # define BOOST_PP_LIST_FOLD_RIGHT_40(o, s, l) BOOST_PP_LIST_FOLD_LEFT_40(o, s, BOOST_PP_LIST_REVERSE_D(40, l)) # define BOOST_PP_LIST_FOLD_RIGHT_41(o, s, l) BOOST_PP_LIST_FOLD_LEFT_41(o, s, BOOST_PP_LIST_REVERSE_D(41, l)) # define BOOST_PP_LIST_FOLD_RIGHT_42(o, s, l) BOOST_PP_LIST_FOLD_LEFT_42(o, s, BOOST_PP_LIST_REVERSE_D(42, l)) # define BOOST_PP_LIST_FOLD_RIGHT_43(o, s, l) BOOST_PP_LIST_FOLD_LEFT_43(o, s, BOOST_PP_LIST_REVERSE_D(43, l)) # define BOOST_PP_LIST_FOLD_RIGHT_44(o, s, l) BOOST_PP_LIST_FOLD_LEFT_44(o, s, BOOST_PP_LIST_REVERSE_D(44, l)) # define BOOST_PP_LIST_FOLD_RIGHT_45(o, s, l) BOOST_PP_LIST_FOLD_LEFT_45(o, s, BOOST_PP_LIST_REVERSE_D(45, l)) # define BOOST_PP_LIST_FOLD_RIGHT_46(o, s, l) BOOST_PP_LIST_FOLD_LEFT_46(o, s, BOOST_PP_LIST_REVERSE_D(46, l)) # define BOOST_PP_LIST_FOLD_RIGHT_47(o, s, l) BOOST_PP_LIST_FOLD_LEFT_47(o, s, BOOST_PP_LIST_REVERSE_D(47, l)) # define BOOST_PP_LIST_FOLD_RIGHT_48(o, s, l) BOOST_PP_LIST_FOLD_LEFT_48(o, s, BOOST_PP_LIST_REVERSE_D(48, l)) # define BOOST_PP_LIST_FOLD_RIGHT_49(o, s, l) BOOST_PP_LIST_FOLD_LEFT_49(o, s, BOOST_PP_LIST_REVERSE_D(49, l)) # define BOOST_PP_LIST_FOLD_RIGHT_50(o, s, l) BOOST_PP_LIST_FOLD_LEFT_50(o, s, BOOST_PP_LIST_REVERSE_D(50, l)) # define BOOST_PP_LIST_FOLD_RIGHT_51(o, s, l) BOOST_PP_LIST_FOLD_LEFT_51(o, s, BOOST_PP_LIST_REVERSE_D(51, l)) # define BOOST_PP_LIST_FOLD_RIGHT_52(o, s, l) BOOST_PP_LIST_FOLD_LEFT_52(o, s, BOOST_PP_LIST_REVERSE_D(52, l)) # define BOOST_PP_LIST_FOLD_RIGHT_53(o, s, l) BOOST_PP_LIST_FOLD_LEFT_53(o, s, BOOST_PP_LIST_REVERSE_D(53, l)) # define BOOST_PP_LIST_FOLD_RIGHT_54(o, s, l) BOOST_PP_LIST_FOLD_LEFT_54(o, s, BOOST_PP_LIST_REVERSE_D(54, l)) # define BOOST_PP_LIST_FOLD_RIGHT_55(o, s, l) BOOST_PP_LIST_FOLD_LEFT_55(o, s, BOOST_PP_LIST_REVERSE_D(55, l)) # define BOOST_PP_LIST_FOLD_RIGHT_56(o, s, l) BOOST_PP_LIST_FOLD_LEFT_56(o, s, BOOST_PP_LIST_REVERSE_D(56, l)) # define BOOST_PP_LIST_FOLD_RIGHT_57(o, s, l) BOOST_PP_LIST_FOLD_LEFT_57(o, s, BOOST_PP_LIST_REVERSE_D(57, l)) # define BOOST_PP_LIST_FOLD_RIGHT_58(o, s, l) BOOST_PP_LIST_FOLD_LEFT_58(o, s, BOOST_PP_LIST_REVERSE_D(58, l)) # define BOOST_PP_LIST_FOLD_RIGHT_59(o, s, l) BOOST_PP_LIST_FOLD_LEFT_59(o, s, BOOST_PP_LIST_REVERSE_D(59, l)) # define BOOST_PP_LIST_FOLD_RIGHT_60(o, s, l) BOOST_PP_LIST_FOLD_LEFT_60(o, s, BOOST_PP_LIST_REVERSE_D(60, l)) # define BOOST_PP_LIST_FOLD_RIGHT_61(o, s, l) BOOST_PP_LIST_FOLD_LEFT_61(o, s, BOOST_PP_LIST_REVERSE_D(61, l)) # define BOOST_PP_LIST_FOLD_RIGHT_62(o, s, l) BOOST_PP_LIST_FOLD_LEFT_62(o, s, BOOST_PP_LIST_REVERSE_D(62, l)) # define BOOST_PP_LIST_FOLD_RIGHT_63(o, s, l) BOOST_PP_LIST_FOLD_LEFT_63(o, s, BOOST_PP_LIST_REVERSE_D(63, l)) # define BOOST_PP_LIST_FOLD_RIGHT_64(o, s, l) BOOST_PP_LIST_FOLD_LEFT_64(o, s, BOOST_PP_LIST_REVERSE_D(64, l)) # define BOOST_PP_LIST_FOLD_RIGHT_65(o, s, l) BOOST_PP_LIST_FOLD_LEFT_65(o, s, BOOST_PP_LIST_REVERSE_D(65, l)) # define BOOST_PP_LIST_FOLD_RIGHT_66(o, s, l) BOOST_PP_LIST_FOLD_LEFT_66(o, s, BOOST_PP_LIST_REVERSE_D(66, l)) # define BOOST_PP_LIST_FOLD_RIGHT_67(o, s, l) BOOST_PP_LIST_FOLD_LEFT_67(o, s, BOOST_PP_LIST_REVERSE_D(67, l)) # define BOOST_PP_LIST_FOLD_RIGHT_68(o, s, l) BOOST_PP_LIST_FOLD_LEFT_68(o, s, BOOST_PP_LIST_REVERSE_D(68, l)) # define BOOST_PP_LIST_FOLD_RIGHT_69(o, s, l) BOOST_PP_LIST_FOLD_LEFT_69(o, s, BOOST_PP_LIST_REVERSE_D(69, l)) # define BOOST_PP_LIST_FOLD_RIGHT_70(o, s, l) BOOST_PP_LIST_FOLD_LEFT_70(o, s, BOOST_PP_LIST_REVERSE_D(70, l)) # define BOOST_PP_LIST_FOLD_RIGHT_71(o, s, l) BOOST_PP_LIST_FOLD_LEFT_71(o, s, BOOST_PP_LIST_REVERSE_D(71, l)) # define BOOST_PP_LIST_FOLD_RIGHT_72(o, s, l) BOOST_PP_LIST_FOLD_LEFT_72(o, s, BOOST_PP_LIST_REVERSE_D(72, l)) # define BOOST_PP_LIST_FOLD_RIGHT_73(o, s, l) BOOST_PP_LIST_FOLD_LEFT_73(o, s, BOOST_PP_LIST_REVERSE_D(73, l)) # define BOOST_PP_LIST_FOLD_RIGHT_74(o, s, l) BOOST_PP_LIST_FOLD_LEFT_74(o, s, BOOST_PP_LIST_REVERSE_D(74, l)) # define BOOST_PP_LIST_FOLD_RIGHT_75(o, s, l) BOOST_PP_LIST_FOLD_LEFT_75(o, s, BOOST_PP_LIST_REVERSE_D(75, l)) # define BOOST_PP_LIST_FOLD_RIGHT_76(o, s, l) BOOST_PP_LIST_FOLD_LEFT_76(o, s, BOOST_PP_LIST_REVERSE_D(76, l)) # define BOOST_PP_LIST_FOLD_RIGHT_77(o, s, l) BOOST_PP_LIST_FOLD_LEFT_77(o, s, BOOST_PP_LIST_REVERSE_D(77, l)) # define BOOST_PP_LIST_FOLD_RIGHT_78(o, s, l) BOOST_PP_LIST_FOLD_LEFT_78(o, s, BOOST_PP_LIST_REVERSE_D(78, l)) # define BOOST_PP_LIST_FOLD_RIGHT_79(o, s, l) BOOST_PP_LIST_FOLD_LEFT_79(o, s, BOOST_PP_LIST_REVERSE_D(79, l)) # define BOOST_PP_LIST_FOLD_RIGHT_80(o, s, l) BOOST_PP_LIST_FOLD_LEFT_80(o, s, BOOST_PP_LIST_REVERSE_D(80, l)) # define BOOST_PP_LIST_FOLD_RIGHT_81(o, s, l) BOOST_PP_LIST_FOLD_LEFT_81(o, s, BOOST_PP_LIST_REVERSE_D(81, l)) # define BOOST_PP_LIST_FOLD_RIGHT_82(o, s, l) BOOST_PP_LIST_FOLD_LEFT_82(o, s, BOOST_PP_LIST_REVERSE_D(82, l)) # define BOOST_PP_LIST_FOLD_RIGHT_83(o, s, l) BOOST_PP_LIST_FOLD_LEFT_83(o, s, BOOST_PP_LIST_REVERSE_D(83, l)) # define BOOST_PP_LIST_FOLD_RIGHT_84(o, s, l) BOOST_PP_LIST_FOLD_LEFT_84(o, s, BOOST_PP_LIST_REVERSE_D(84, l)) # define BOOST_PP_LIST_FOLD_RIGHT_85(o, s, l) BOOST_PP_LIST_FOLD_LEFT_85(o, s, BOOST_PP_LIST_REVERSE_D(85, l)) # define BOOST_PP_LIST_FOLD_RIGHT_86(o, s, l) BOOST_PP_LIST_FOLD_LEFT_86(o, s, BOOST_PP_LIST_REVERSE_D(86, l)) # define BOOST_PP_LIST_FOLD_RIGHT_87(o, s, l) BOOST_PP_LIST_FOLD_LEFT_87(o, s, BOOST_PP_LIST_REVERSE_D(87, l)) # define BOOST_PP_LIST_FOLD_RIGHT_88(o, s, l) BOOST_PP_LIST_FOLD_LEFT_88(o, s, BOOST_PP_LIST_REVERSE_D(88, l)) # define BOOST_PP_LIST_FOLD_RIGHT_89(o, s, l) BOOST_PP_LIST_FOLD_LEFT_89(o, s, BOOST_PP_LIST_REVERSE_D(89, l)) # define BOOST_PP_LIST_FOLD_RIGHT_90(o, s, l) BOOST_PP_LIST_FOLD_LEFT_90(o, s, BOOST_PP_LIST_REVERSE_D(90, l)) # define BOOST_PP_LIST_FOLD_RIGHT_91(o, s, l) BOOST_PP_LIST_FOLD_LEFT_91(o, s, BOOST_PP_LIST_REVERSE_D(91, l)) # define BOOST_PP_LIST_FOLD_RIGHT_92(o, s, l) BOOST_PP_LIST_FOLD_LEFT_92(o, s, BOOST_PP_LIST_REVERSE_D(92, l)) # define BOOST_PP_LIST_FOLD_RIGHT_93(o, s, l) BOOST_PP_LIST_FOLD_LEFT_93(o, s, BOOST_PP_LIST_REVERSE_D(93, l)) # define BOOST_PP_LIST_FOLD_RIGHT_94(o, s, l) BOOST_PP_LIST_FOLD_LEFT_94(o, s, BOOST_PP_LIST_REVERSE_D(94, l)) # define BOOST_PP_LIST_FOLD_RIGHT_95(o, s, l) BOOST_PP_LIST_FOLD_LEFT_95(o, s, BOOST_PP_LIST_REVERSE_D(95, l)) # define BOOST_PP_LIST_FOLD_RIGHT_96(o, s, l) BOOST_PP_LIST_FOLD_LEFT_96(o, s, BOOST_PP_LIST_REVERSE_D(96, l)) # define BOOST_PP_LIST_FOLD_RIGHT_97(o, s, l) BOOST_PP_LIST_FOLD_LEFT_97(o, s, BOOST_PP_LIST_REVERSE_D(97, l)) # define BOOST_PP_LIST_FOLD_RIGHT_98(o, s, l) BOOST_PP_LIST_FOLD_LEFT_98(o, s, BOOST_PP_LIST_REVERSE_D(98, l)) # define BOOST_PP_LIST_FOLD_RIGHT_99(o, s, l) BOOST_PP_LIST_FOLD_LEFT_99(o, s, BOOST_PP_LIST_REVERSE_D(99, l)) # define BOOST_PP_LIST_FOLD_RIGHT_100(o, s, l) BOOST_PP_LIST_FOLD_LEFT_100(o, s, BOOST_PP_LIST_REVERSE_D(100, l)) # define BOOST_PP_LIST_FOLD_RIGHT_101(o, s, l) BOOST_PP_LIST_FOLD_LEFT_101(o, s, BOOST_PP_LIST_REVERSE_D(101, l)) # define BOOST_PP_LIST_FOLD_RIGHT_102(o, s, l) BOOST_PP_LIST_FOLD_LEFT_102(o, s, BOOST_PP_LIST_REVERSE_D(102, l)) # define BOOST_PP_LIST_FOLD_RIGHT_103(o, s, l) BOOST_PP_LIST_FOLD_LEFT_103(o, s, BOOST_PP_LIST_REVERSE_D(103, l)) # define BOOST_PP_LIST_FOLD_RIGHT_104(o, s, l) BOOST_PP_LIST_FOLD_LEFT_104(o, s, BOOST_PP_LIST_REVERSE_D(104, l)) # define BOOST_PP_LIST_FOLD_RIGHT_105(o, s, l) BOOST_PP_LIST_FOLD_LEFT_105(o, s, BOOST_PP_LIST_REVERSE_D(105, l)) # define BOOST_PP_LIST_FOLD_RIGHT_106(o, s, l) BOOST_PP_LIST_FOLD_LEFT_106(o, s, BOOST_PP_LIST_REVERSE_D(106, l)) # define BOOST_PP_LIST_FOLD_RIGHT_107(o, s, l) BOOST_PP_LIST_FOLD_LEFT_107(o, s, BOOST_PP_LIST_REVERSE_D(107, l)) # define BOOST_PP_LIST_FOLD_RIGHT_108(o, s, l) BOOST_PP_LIST_FOLD_LEFT_108(o, s, BOOST_PP_LIST_REVERSE_D(108, l)) # define BOOST_PP_LIST_FOLD_RIGHT_109(o, s, l) BOOST_PP_LIST_FOLD_LEFT_109(o, s, BOOST_PP_LIST_REVERSE_D(109, l)) # define BOOST_PP_LIST_FOLD_RIGHT_110(o, s, l) BOOST_PP_LIST_FOLD_LEFT_110(o, s, BOOST_PP_LIST_REVERSE_D(110, l)) # define BOOST_PP_LIST_FOLD_RIGHT_111(o, s, l) BOOST_PP_LIST_FOLD_LEFT_111(o, s, BOOST_PP_LIST_REVERSE_D(111, l)) # define BOOST_PP_LIST_FOLD_RIGHT_112(o, s, l) BOOST_PP_LIST_FOLD_LEFT_112(o, s, BOOST_PP_LIST_REVERSE_D(112, l)) # define BOOST_PP_LIST_FOLD_RIGHT_113(o, s, l) BOOST_PP_LIST_FOLD_LEFT_113(o, s, BOOST_PP_LIST_REVERSE_D(113, l)) # define BOOST_PP_LIST_FOLD_RIGHT_114(o, s, l) BOOST_PP_LIST_FOLD_LEFT_114(o, s, BOOST_PP_LIST_REVERSE_D(114, l)) # define BOOST_PP_LIST_FOLD_RIGHT_115(o, s, l) BOOST_PP_LIST_FOLD_LEFT_115(o, s, BOOST_PP_LIST_REVERSE_D(115, l)) # define BOOST_PP_LIST_FOLD_RIGHT_116(o, s, l) BOOST_PP_LIST_FOLD_LEFT_116(o, s, BOOST_PP_LIST_REVERSE_D(116, l)) # define BOOST_PP_LIST_FOLD_RIGHT_117(o, s, l) BOOST_PP_LIST_FOLD_LEFT_117(o, s, BOOST_PP_LIST_REVERSE_D(117, l)) # define BOOST_PP_LIST_FOLD_RIGHT_118(o, s, l) BOOST_PP_LIST_FOLD_LEFT_118(o, s, BOOST_PP_LIST_REVERSE_D(118, l)) # define BOOST_PP_LIST_FOLD_RIGHT_119(o, s, l) BOOST_PP_LIST_FOLD_LEFT_119(o, s, BOOST_PP_LIST_REVERSE_D(119, l)) # define BOOST_PP_LIST_FOLD_RIGHT_120(o, s, l) BOOST_PP_LIST_FOLD_LEFT_120(o, s, BOOST_PP_LIST_REVERSE_D(120, l)) # define BOOST_PP_LIST_FOLD_RIGHT_121(o, s, l) BOOST_PP_LIST_FOLD_LEFT_121(o, s, BOOST_PP_LIST_REVERSE_D(121, l)) # define BOOST_PP_LIST_FOLD_RIGHT_122(o, s, l) BOOST_PP_LIST_FOLD_LEFT_122(o, s, BOOST_PP_LIST_REVERSE_D(122, l)) # define BOOST_PP_LIST_FOLD_RIGHT_123(o, s, l) BOOST_PP_LIST_FOLD_LEFT_123(o, s, BOOST_PP_LIST_REVERSE_D(123, l)) # define BOOST_PP_LIST_FOLD_RIGHT_124(o, s, l) BOOST_PP_LIST_FOLD_LEFT_124(o, s, BOOST_PP_LIST_REVERSE_D(124, l)) # define BOOST_PP_LIST_FOLD_RIGHT_125(o, s, l) BOOST_PP_LIST_FOLD_LEFT_125(o, s, BOOST_PP_LIST_REVERSE_D(125, l)) # define BOOST_PP_LIST_FOLD_RIGHT_126(o, s, l) BOOST_PP_LIST_FOLD_LEFT_126(o, s, BOOST_PP_LIST_REVERSE_D(126, l)) # define BOOST_PP_LIST_FOLD_RIGHT_127(o, s, l) BOOST_PP_LIST_FOLD_LEFT_127(o, s, BOOST_PP_LIST_REVERSE_D(127, l)) # define BOOST_PP_LIST_FOLD_RIGHT_128(o, s, l) BOOST_PP_LIST_FOLD_LEFT_128(o, s, BOOST_PP_LIST_REVERSE_D(128, l)) # define BOOST_PP_LIST_FOLD_RIGHT_129(o, s, l) BOOST_PP_LIST_FOLD_LEFT_129(o, s, BOOST_PP_LIST_REVERSE_D(129, l)) # define BOOST_PP_LIST_FOLD_RIGHT_130(o, s, l) BOOST_PP_LIST_FOLD_LEFT_130(o, s, BOOST_PP_LIST_REVERSE_D(130, l)) # define BOOST_PP_LIST_FOLD_RIGHT_131(o, s, l) BOOST_PP_LIST_FOLD_LEFT_131(o, s, BOOST_PP_LIST_REVERSE_D(131, l)) # define BOOST_PP_LIST_FOLD_RIGHT_132(o, s, l) BOOST_PP_LIST_FOLD_LEFT_132(o, s, BOOST_PP_LIST_REVERSE_D(132, l)) # define BOOST_PP_LIST_FOLD_RIGHT_133(o, s, l) BOOST_PP_LIST_FOLD_LEFT_133(o, s, BOOST_PP_LIST_REVERSE_D(133, l)) # define BOOST_PP_LIST_FOLD_RIGHT_134(o, s, l) BOOST_PP_LIST_FOLD_LEFT_134(o, s, BOOST_PP_LIST_REVERSE_D(134, l)) # define BOOST_PP_LIST_FOLD_RIGHT_135(o, s, l) BOOST_PP_LIST_FOLD_LEFT_135(o, s, BOOST_PP_LIST_REVERSE_D(135, l)) # define BOOST_PP_LIST_FOLD_RIGHT_136(o, s, l) BOOST_PP_LIST_FOLD_LEFT_136(o, s, BOOST_PP_LIST_REVERSE_D(136, l)) # define BOOST_PP_LIST_FOLD_RIGHT_137(o, s, l) BOOST_PP_LIST_FOLD_LEFT_137(o, s, BOOST_PP_LIST_REVERSE_D(137, l)) # define BOOST_PP_LIST_FOLD_RIGHT_138(o, s, l) BOOST_PP_LIST_FOLD_LEFT_138(o, s, BOOST_PP_LIST_REVERSE_D(138, l)) # define BOOST_PP_LIST_FOLD_RIGHT_139(o, s, l) BOOST_PP_LIST_FOLD_LEFT_139(o, s, BOOST_PP_LIST_REVERSE_D(139, l)) # define BOOST_PP_LIST_FOLD_RIGHT_140(o, s, l) BOOST_PP_LIST_FOLD_LEFT_140(o, s, BOOST_PP_LIST_REVERSE_D(140, l)) # define BOOST_PP_LIST_FOLD_RIGHT_141(o, s, l) BOOST_PP_LIST_FOLD_LEFT_141(o, s, BOOST_PP_LIST_REVERSE_D(141, l)) # define BOOST_PP_LIST_FOLD_RIGHT_142(o, s, l) BOOST_PP_LIST_FOLD_LEFT_142(o, s, BOOST_PP_LIST_REVERSE_D(142, l)) # define BOOST_PP_LIST_FOLD_RIGHT_143(o, s, l) BOOST_PP_LIST_FOLD_LEFT_143(o, s, BOOST_PP_LIST_REVERSE_D(143, l)) # define BOOST_PP_LIST_FOLD_RIGHT_144(o, s, l) BOOST_PP_LIST_FOLD_LEFT_144(o, s, BOOST_PP_LIST_REVERSE_D(144, l)) # define BOOST_PP_LIST_FOLD_RIGHT_145(o, s, l) BOOST_PP_LIST_FOLD_LEFT_145(o, s, BOOST_PP_LIST_REVERSE_D(145, l)) # define BOOST_PP_LIST_FOLD_RIGHT_146(o, s, l) BOOST_PP_LIST_FOLD_LEFT_146(o, s, BOOST_PP_LIST_REVERSE_D(146, l)) # define BOOST_PP_LIST_FOLD_RIGHT_147(o, s, l) BOOST_PP_LIST_FOLD_LEFT_147(o, s, BOOST_PP_LIST_REVERSE_D(147, l)) # define BOOST_PP_LIST_FOLD_RIGHT_148(o, s, l) BOOST_PP_LIST_FOLD_LEFT_148(o, s, BOOST_PP_LIST_REVERSE_D(148, l)) # define BOOST_PP_LIST_FOLD_RIGHT_149(o, s, l) BOOST_PP_LIST_FOLD_LEFT_149(o, s, BOOST_PP_LIST_REVERSE_D(149, l)) # define BOOST_PP_LIST_FOLD_RIGHT_150(o, s, l) BOOST_PP_LIST_FOLD_LEFT_150(o, s, BOOST_PP_LIST_REVERSE_D(150, l)) # define BOOST_PP_LIST_FOLD_RIGHT_151(o, s, l) BOOST_PP_LIST_FOLD_LEFT_151(o, s, BOOST_PP_LIST_REVERSE_D(151, l)) # define BOOST_PP_LIST_FOLD_RIGHT_152(o, s, l) BOOST_PP_LIST_FOLD_LEFT_152(o, s, BOOST_PP_LIST_REVERSE_D(152, l)) # define BOOST_PP_LIST_FOLD_RIGHT_153(o, s, l) BOOST_PP_LIST_FOLD_LEFT_153(o, s, BOOST_PP_LIST_REVERSE_D(153, l)) # define BOOST_PP_LIST_FOLD_RIGHT_154(o, s, l) BOOST_PP_LIST_FOLD_LEFT_154(o, s, BOOST_PP_LIST_REVERSE_D(154, l)) # define BOOST_PP_LIST_FOLD_RIGHT_155(o, s, l) BOOST_PP_LIST_FOLD_LEFT_155(o, s, BOOST_PP_LIST_REVERSE_D(155, l)) # define BOOST_PP_LIST_FOLD_RIGHT_156(o, s, l) BOOST_PP_LIST_FOLD_LEFT_156(o, s, BOOST_PP_LIST_REVERSE_D(156, l)) # define BOOST_PP_LIST_FOLD_RIGHT_157(o, s, l) BOOST_PP_LIST_FOLD_LEFT_157(o, s, BOOST_PP_LIST_REVERSE_D(157, l)) # define BOOST_PP_LIST_FOLD_RIGHT_158(o, s, l) BOOST_PP_LIST_FOLD_LEFT_158(o, s, BOOST_PP_LIST_REVERSE_D(158, l)) # define BOOST_PP_LIST_FOLD_RIGHT_159(o, s, l) BOOST_PP_LIST_FOLD_LEFT_159(o, s, BOOST_PP_LIST_REVERSE_D(159, l)) # define BOOST_PP_LIST_FOLD_RIGHT_160(o, s, l) BOOST_PP_LIST_FOLD_LEFT_160(o, s, BOOST_PP_LIST_REVERSE_D(160, l)) # define BOOST_PP_LIST_FOLD_RIGHT_161(o, s, l) BOOST_PP_LIST_FOLD_LEFT_161(o, s, BOOST_PP_LIST_REVERSE_D(161, l)) # define BOOST_PP_LIST_FOLD_RIGHT_162(o, s, l) BOOST_PP_LIST_FOLD_LEFT_162(o, s, BOOST_PP_LIST_REVERSE_D(162, l)) # define BOOST_PP_LIST_FOLD_RIGHT_163(o, s, l) BOOST_PP_LIST_FOLD_LEFT_163(o, s, BOOST_PP_LIST_REVERSE_D(163, l)) # define BOOST_PP_LIST_FOLD_RIGHT_164(o, s, l) BOOST_PP_LIST_FOLD_LEFT_164(o, s, BOOST_PP_LIST_REVERSE_D(164, l)) # define BOOST_PP_LIST_FOLD_RIGHT_165(o, s, l) BOOST_PP_LIST_FOLD_LEFT_165(o, s, BOOST_PP_LIST_REVERSE_D(165, l)) # define BOOST_PP_LIST_FOLD_RIGHT_166(o, s, l) BOOST_PP_LIST_FOLD_LEFT_166(o, s, BOOST_PP_LIST_REVERSE_D(166, l)) # define BOOST_PP_LIST_FOLD_RIGHT_167(o, s, l) BOOST_PP_LIST_FOLD_LEFT_167(o, s, BOOST_PP_LIST_REVERSE_D(167, l)) # define BOOST_PP_LIST_FOLD_RIGHT_168(o, s, l) BOOST_PP_LIST_FOLD_LEFT_168(o, s, BOOST_PP_LIST_REVERSE_D(168, l)) # define BOOST_PP_LIST_FOLD_RIGHT_169(o, s, l) BOOST_PP_LIST_FOLD_LEFT_169(o, s, BOOST_PP_LIST_REVERSE_D(169, l)) # define BOOST_PP_LIST_FOLD_RIGHT_170(o, s, l) BOOST_PP_LIST_FOLD_LEFT_170(o, s, BOOST_PP_LIST_REVERSE_D(170, l)) # define BOOST_PP_LIST_FOLD_RIGHT_171(o, s, l) BOOST_PP_LIST_FOLD_LEFT_171(o, s, BOOST_PP_LIST_REVERSE_D(171, l)) # define BOOST_PP_LIST_FOLD_RIGHT_172(o, s, l) BOOST_PP_LIST_FOLD_LEFT_172(o, s, BOOST_PP_LIST_REVERSE_D(172, l)) # define BOOST_PP_LIST_FOLD_RIGHT_173(o, s, l) BOOST_PP_LIST_FOLD_LEFT_173(o, s, BOOST_PP_LIST_REVERSE_D(173, l)) # define BOOST_PP_LIST_FOLD_RIGHT_174(o, s, l) BOOST_PP_LIST_FOLD_LEFT_174(o, s, BOOST_PP_LIST_REVERSE_D(174, l)) # define BOOST_PP_LIST_FOLD_RIGHT_175(o, s, l) BOOST_PP_LIST_FOLD_LEFT_175(o, s, BOOST_PP_LIST_REVERSE_D(175, l)) # define BOOST_PP_LIST_FOLD_RIGHT_176(o, s, l) BOOST_PP_LIST_FOLD_LEFT_176(o, s, BOOST_PP_LIST_REVERSE_D(176, l)) # define BOOST_PP_LIST_FOLD_RIGHT_177(o, s, l) BOOST_PP_LIST_FOLD_LEFT_177(o, s, BOOST_PP_LIST_REVERSE_D(177, l)) # define BOOST_PP_LIST_FOLD_RIGHT_178(o, s, l) BOOST_PP_LIST_FOLD_LEFT_178(o, s, BOOST_PP_LIST_REVERSE_D(178, l)) # define BOOST_PP_LIST_FOLD_RIGHT_179(o, s, l) BOOST_PP_LIST_FOLD_LEFT_179(o, s, BOOST_PP_LIST_REVERSE_D(179, l)) # define BOOST_PP_LIST_FOLD_RIGHT_180(o, s, l) BOOST_PP_LIST_FOLD_LEFT_180(o, s, BOOST_PP_LIST_REVERSE_D(180, l)) # define BOOST_PP_LIST_FOLD_RIGHT_181(o, s, l) BOOST_PP_LIST_FOLD_LEFT_181(o, s, BOOST_PP_LIST_REVERSE_D(181, l)) # define BOOST_PP_LIST_FOLD_RIGHT_182(o, s, l) BOOST_PP_LIST_FOLD_LEFT_182(o, s, BOOST_PP_LIST_REVERSE_D(182, l)) # define BOOST_PP_LIST_FOLD_RIGHT_183(o, s, l) BOOST_PP_LIST_FOLD_LEFT_183(o, s, BOOST_PP_LIST_REVERSE_D(183, l)) # define BOOST_PP_LIST_FOLD_RIGHT_184(o, s, l) BOOST_PP_LIST_FOLD_LEFT_184(o, s, BOOST_PP_LIST_REVERSE_D(184, l)) # define BOOST_PP_LIST_FOLD_RIGHT_185(o, s, l) BOOST_PP_LIST_FOLD_LEFT_185(o, s, BOOST_PP_LIST_REVERSE_D(185, l)) # define BOOST_PP_LIST_FOLD_RIGHT_186(o, s, l) BOOST_PP_LIST_FOLD_LEFT_186(o, s, BOOST_PP_LIST_REVERSE_D(186, l)) # define BOOST_PP_LIST_FOLD_RIGHT_187(o, s, l) BOOST_PP_LIST_FOLD_LEFT_187(o, s, BOOST_PP_LIST_REVERSE_D(187, l)) # define BOOST_PP_LIST_FOLD_RIGHT_188(o, s, l) BOOST_PP_LIST_FOLD_LEFT_188(o, s, BOOST_PP_LIST_REVERSE_D(188, l)) # define BOOST_PP_LIST_FOLD_RIGHT_189(o, s, l) BOOST_PP_LIST_FOLD_LEFT_189(o, s, BOOST_PP_LIST_REVERSE_D(189, l)) # define BOOST_PP_LIST_FOLD_RIGHT_190(o, s, l) BOOST_PP_LIST_FOLD_LEFT_190(o, s, BOOST_PP_LIST_REVERSE_D(190, l)) # define BOOST_PP_LIST_FOLD_RIGHT_191(o, s, l) BOOST_PP_LIST_FOLD_LEFT_191(o, s, BOOST_PP_LIST_REVERSE_D(191, l)) # define BOOST_PP_LIST_FOLD_RIGHT_192(o, s, l) BOOST_PP_LIST_FOLD_LEFT_192(o, s, BOOST_PP_LIST_REVERSE_D(192, l)) # define BOOST_PP_LIST_FOLD_RIGHT_193(o, s, l) BOOST_PP_LIST_FOLD_LEFT_193(o, s, BOOST_PP_LIST_REVERSE_D(193, l)) # define BOOST_PP_LIST_FOLD_RIGHT_194(o, s, l) BOOST_PP_LIST_FOLD_LEFT_194(o, s, BOOST_PP_LIST_REVERSE_D(194, l)) # define BOOST_PP_LIST_FOLD_RIGHT_195(o, s, l) BOOST_PP_LIST_FOLD_LEFT_195(o, s, BOOST_PP_LIST_REVERSE_D(195, l)) # define BOOST_PP_LIST_FOLD_RIGHT_196(o, s, l) BOOST_PP_LIST_FOLD_LEFT_196(o, s, BOOST_PP_LIST_REVERSE_D(196, l)) # define BOOST_PP_LIST_FOLD_RIGHT_197(o, s, l) BOOST_PP_LIST_FOLD_LEFT_197(o, s, BOOST_PP_LIST_REVERSE_D(197, l)) # define BOOST_PP_LIST_FOLD_RIGHT_198(o, s, l) BOOST_PP_LIST_FOLD_LEFT_198(o, s, BOOST_PP_LIST_REVERSE_D(198, l)) # define BOOST_PP_LIST_FOLD_RIGHT_199(o, s, l) BOOST_PP_LIST_FOLD_LEFT_199(o, s, BOOST_PP_LIST_REVERSE_D(199, l)) # define BOOST_PP_LIST_FOLD_RIGHT_200(o, s, l) BOOST_PP_LIST_FOLD_LEFT_200(o, s, BOOST_PP_LIST_REVERSE_D(200, l)) # define BOOST_PP_LIST_FOLD_RIGHT_201(o, s, l) BOOST_PP_LIST_FOLD_LEFT_201(o, s, BOOST_PP_LIST_REVERSE_D(201, l)) # define BOOST_PP_LIST_FOLD_RIGHT_202(o, s, l) BOOST_PP_LIST_FOLD_LEFT_202(o, s, BOOST_PP_LIST_REVERSE_D(202, l)) # define BOOST_PP_LIST_FOLD_RIGHT_203(o, s, l) BOOST_PP_LIST_FOLD_LEFT_203(o, s, BOOST_PP_LIST_REVERSE_D(203, l)) # define BOOST_PP_LIST_FOLD_RIGHT_204(o, s, l) BOOST_PP_LIST_FOLD_LEFT_204(o, s, BOOST_PP_LIST_REVERSE_D(204, l)) # define BOOST_PP_LIST_FOLD_RIGHT_205(o, s, l) BOOST_PP_LIST_FOLD_LEFT_205(o, s, BOOST_PP_LIST_REVERSE_D(205, l)) # define BOOST_PP_LIST_FOLD_RIGHT_206(o, s, l) BOOST_PP_LIST_FOLD_LEFT_206(o, s, BOOST_PP_LIST_REVERSE_D(206, l)) # define BOOST_PP_LIST_FOLD_RIGHT_207(o, s, l) BOOST_PP_LIST_FOLD_LEFT_207(o, s, BOOST_PP_LIST_REVERSE_D(207, l)) # define BOOST_PP_LIST_FOLD_RIGHT_208(o, s, l) BOOST_PP_LIST_FOLD_LEFT_208(o, s, BOOST_PP_LIST_REVERSE_D(208, l)) # define BOOST_PP_LIST_FOLD_RIGHT_209(o, s, l) BOOST_PP_LIST_FOLD_LEFT_209(o, s, BOOST_PP_LIST_REVERSE_D(209, l)) # define BOOST_PP_LIST_FOLD_RIGHT_210(o, s, l) BOOST_PP_LIST_FOLD_LEFT_210(o, s, BOOST_PP_LIST_REVERSE_D(210, l)) # define BOOST_PP_LIST_FOLD_RIGHT_211(o, s, l) BOOST_PP_LIST_FOLD_LEFT_211(o, s, BOOST_PP_LIST_REVERSE_D(211, l)) # define BOOST_PP_LIST_FOLD_RIGHT_212(o, s, l) BOOST_PP_LIST_FOLD_LEFT_212(o, s, BOOST_PP_LIST_REVERSE_D(212, l)) # define BOOST_PP_LIST_FOLD_RIGHT_213(o, s, l) BOOST_PP_LIST_FOLD_LEFT_213(o, s, BOOST_PP_LIST_REVERSE_D(213, l)) # define BOOST_PP_LIST_FOLD_RIGHT_214(o, s, l) BOOST_PP_LIST_FOLD_LEFT_214(o, s, BOOST_PP_LIST_REVERSE_D(214, l)) # define BOOST_PP_LIST_FOLD_RIGHT_215(o, s, l) BOOST_PP_LIST_FOLD_LEFT_215(o, s, BOOST_PP_LIST_REVERSE_D(215, l)) # define BOOST_PP_LIST_FOLD_RIGHT_216(o, s, l) BOOST_PP_LIST_FOLD_LEFT_216(o, s, BOOST_PP_LIST_REVERSE_D(216, l)) # define BOOST_PP_LIST_FOLD_RIGHT_217(o, s, l) BOOST_PP_LIST_FOLD_LEFT_217(o, s, BOOST_PP_LIST_REVERSE_D(217, l)) # define BOOST_PP_LIST_FOLD_RIGHT_218(o, s, l) BOOST_PP_LIST_FOLD_LEFT_218(o, s, BOOST_PP_LIST_REVERSE_D(218, l)) # define BOOST_PP_LIST_FOLD_RIGHT_219(o, s, l) BOOST_PP_LIST_FOLD_LEFT_219(o, s, BOOST_PP_LIST_REVERSE_D(219, l)) # define BOOST_PP_LIST_FOLD_RIGHT_220(o, s, l) BOOST_PP_LIST_FOLD_LEFT_220(o, s, BOOST_PP_LIST_REVERSE_D(220, l)) # define BOOST_PP_LIST_FOLD_RIGHT_221(o, s, l) BOOST_PP_LIST_FOLD_LEFT_221(o, s, BOOST_PP_LIST_REVERSE_D(221, l)) # define BOOST_PP_LIST_FOLD_RIGHT_222(o, s, l) BOOST_PP_LIST_FOLD_LEFT_222(o, s, BOOST_PP_LIST_REVERSE_D(222, l)) # define BOOST_PP_LIST_FOLD_RIGHT_223(o, s, l) BOOST_PP_LIST_FOLD_LEFT_223(o, s, BOOST_PP_LIST_REVERSE_D(223, l)) # define BOOST_PP_LIST_FOLD_RIGHT_224(o, s, l) BOOST_PP_LIST_FOLD_LEFT_224(o, s, BOOST_PP_LIST_REVERSE_D(224, l)) # define BOOST_PP_LIST_FOLD_RIGHT_225(o, s, l) BOOST_PP_LIST_FOLD_LEFT_225(o, s, BOOST_PP_LIST_REVERSE_D(225, l)) # define BOOST_PP_LIST_FOLD_RIGHT_226(o, s, l) BOOST_PP_LIST_FOLD_LEFT_226(o, s, BOOST_PP_LIST_REVERSE_D(226, l)) # define BOOST_PP_LIST_FOLD_RIGHT_227(o, s, l) BOOST_PP_LIST_FOLD_LEFT_227(o, s, BOOST_PP_LIST_REVERSE_D(227, l)) # define BOOST_PP_LIST_FOLD_RIGHT_228(o, s, l) BOOST_PP_LIST_FOLD_LEFT_228(o, s, BOOST_PP_LIST_REVERSE_D(228, l)) # define BOOST_PP_LIST_FOLD_RIGHT_229(o, s, l) BOOST_PP_LIST_FOLD_LEFT_229(o, s, BOOST_PP_LIST_REVERSE_D(229, l)) # define BOOST_PP_LIST_FOLD_RIGHT_230(o, s, l) BOOST_PP_LIST_FOLD_LEFT_230(o, s, BOOST_PP_LIST_REVERSE_D(230, l)) # define BOOST_PP_LIST_FOLD_RIGHT_231(o, s, l) BOOST_PP_LIST_FOLD_LEFT_231(o, s, BOOST_PP_LIST_REVERSE_D(231, l)) # define BOOST_PP_LIST_FOLD_RIGHT_232(o, s, l) BOOST_PP_LIST_FOLD_LEFT_232(o, s, BOOST_PP_LIST_REVERSE_D(232, l)) # define BOOST_PP_LIST_FOLD_RIGHT_233(o, s, l) BOOST_PP_LIST_FOLD_LEFT_233(o, s, BOOST_PP_LIST_REVERSE_D(233, l)) # define BOOST_PP_LIST_FOLD_RIGHT_234(o, s, l) BOOST_PP_LIST_FOLD_LEFT_234(o, s, BOOST_PP_LIST_REVERSE_D(234, l)) # define BOOST_PP_LIST_FOLD_RIGHT_235(o, s, l) BOOST_PP_LIST_FOLD_LEFT_235(o, s, BOOST_PP_LIST_REVERSE_D(235, l)) # define BOOST_PP_LIST_FOLD_RIGHT_236(o, s, l) BOOST_PP_LIST_FOLD_LEFT_236(o, s, BOOST_PP_LIST_REVERSE_D(236, l)) # define BOOST_PP_LIST_FOLD_RIGHT_237(o, s, l) BOOST_PP_LIST_FOLD_LEFT_237(o, s, BOOST_PP_LIST_REVERSE_D(237, l)) # define BOOST_PP_LIST_FOLD_RIGHT_238(o, s, l) BOOST_PP_LIST_FOLD_LEFT_238(o, s, BOOST_PP_LIST_REVERSE_D(238, l)) # define BOOST_PP_LIST_FOLD_RIGHT_239(o, s, l) BOOST_PP_LIST_FOLD_LEFT_239(o, s, BOOST_PP_LIST_REVERSE_D(239, l)) # define BOOST_PP_LIST_FOLD_RIGHT_240(o, s, l) BOOST_PP_LIST_FOLD_LEFT_240(o, s, BOOST_PP_LIST_REVERSE_D(240, l)) # define BOOST_PP_LIST_FOLD_RIGHT_241(o, s, l) BOOST_PP_LIST_FOLD_LEFT_241(o, s, BOOST_PP_LIST_REVERSE_D(241, l)) # define BOOST_PP_LIST_FOLD_RIGHT_242(o, s, l) BOOST_PP_LIST_FOLD_LEFT_242(o, s, BOOST_PP_LIST_REVERSE_D(242, l)) # define BOOST_PP_LIST_FOLD_RIGHT_243(o, s, l) BOOST_PP_LIST_FOLD_LEFT_243(o, s, BOOST_PP_LIST_REVERSE_D(243, l)) # define BOOST_PP_LIST_FOLD_RIGHT_244(o, s, l) BOOST_PP_LIST_FOLD_LEFT_244(o, s, BOOST_PP_LIST_REVERSE_D(244, l)) # define BOOST_PP_LIST_FOLD_RIGHT_245(o, s, l) BOOST_PP_LIST_FOLD_LEFT_245(o, s, BOOST_PP_LIST_REVERSE_D(245, l)) # define BOOST_PP_LIST_FOLD_RIGHT_246(o, s, l) BOOST_PP_LIST_FOLD_LEFT_246(o, s, BOOST_PP_LIST_REVERSE_D(246, l)) # define BOOST_PP_LIST_FOLD_RIGHT_247(o, s, l) BOOST_PP_LIST_FOLD_LEFT_247(o, s, BOOST_PP_LIST_REVERSE_D(247, l)) # define BOOST_PP_LIST_FOLD_RIGHT_248(o, s, l) BOOST_PP_LIST_FOLD_LEFT_248(o, s, BOOST_PP_LIST_REVERSE_D(248, l)) # define BOOST_PP_LIST_FOLD_RIGHT_249(o, s, l) BOOST_PP_LIST_FOLD_LEFT_249(o, s, BOOST_PP_LIST_REVERSE_D(249, l)) # define BOOST_PP_LIST_FOLD_RIGHT_250(o, s, l) BOOST_PP_LIST_FOLD_LEFT_250(o, s, BOOST_PP_LIST_REVERSE_D(250, l)) # define BOOST_PP_LIST_FOLD_RIGHT_251(o, s, l) BOOST_PP_LIST_FOLD_LEFT_251(o, s, BOOST_PP_LIST_REVERSE_D(251, l)) # define BOOST_PP_LIST_FOLD_RIGHT_252(o, s, l) BOOST_PP_LIST_FOLD_LEFT_252(o, s, BOOST_PP_LIST_REVERSE_D(252, l)) # define BOOST_PP_LIST_FOLD_RIGHT_253(o, s, l) BOOST_PP_LIST_FOLD_LEFT_253(o, s, BOOST_PP_LIST_REVERSE_D(253, l)) # define BOOST_PP_LIST_FOLD_RIGHT_254(o, s, l) BOOST_PP_LIST_FOLD_LEFT_254(o, s, BOOST_PP_LIST_REVERSE_D(254, l)) # define BOOST_PP_LIST_FOLD_RIGHT_255(o, s, l) BOOST_PP_LIST_FOLD_LEFT_255(o, s, BOOST_PP_LIST_REVERSE_D(255, l)) # define BOOST_PP_LIST_FOLD_RIGHT_256(o, s, l) BOOST_PP_LIST_FOLD_LEFT_256(o, s, BOOST_PP_LIST_REVERSE_D(256, l)) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/fold_left.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_FOLD_LEFT_HPP # define BOOST_PREPROCESSOR_LIST_FOLD_LEFT_HPP # # include # include # include # include # # /* BOOST_PP_LIST_FOLD_LEFT */ # # if 0 # define BOOST_PP_LIST_FOLD_LEFT(op, state, list) # endif # # define BOOST_PP_LIST_FOLD_LEFT BOOST_PP_CAT(BOOST_PP_LIST_FOLD_LEFT_, BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256)) # # define BOOST_PP_LIST_FOLD_LEFT_257(o, s, l) BOOST_PP_ERROR(0x0004) # # define BOOST_PP_LIST_FOLD_LEFT_D(d, o, s, l) BOOST_PP_LIST_FOLD_LEFT_ ## d(o, s, l) # define BOOST_PP_LIST_FOLD_LEFT_2ND BOOST_PP_LIST_FOLD_LEFT # define BOOST_PP_LIST_FOLD_LEFT_2ND_D BOOST_PP_LIST_FOLD_LEFT_D # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # include # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # include # else # include # endif # # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_NIL 1 # # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_1(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_2(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_3(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_4(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_5(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_6(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_7(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_8(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_9(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_10(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_11(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_12(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_13(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_14(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_15(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_16(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_17(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_18(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_19(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_20(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_21(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_22(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_23(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_24(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_25(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_26(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_27(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_28(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_29(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_30(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_31(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_32(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_33(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_34(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_35(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_36(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_37(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_38(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_39(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_40(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_41(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_42(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_43(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_44(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_45(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_46(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_47(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_48(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_49(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_50(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_51(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_52(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_53(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_54(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_55(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_56(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_57(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_58(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_59(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_60(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_61(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_62(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_63(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_64(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_65(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_66(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_67(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_68(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_69(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_70(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_71(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_72(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_73(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_74(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_75(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_76(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_77(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_78(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_79(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_80(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_81(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_82(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_83(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_84(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_85(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_86(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_87(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_88(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_89(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_90(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_91(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_92(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_93(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_94(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_95(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_96(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_97(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_98(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_99(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_100(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_101(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_102(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_103(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_104(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_105(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_106(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_107(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_108(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_109(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_110(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_111(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_112(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_113(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_114(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_115(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_116(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_117(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_118(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_119(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_120(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_121(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_122(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_123(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_124(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_125(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_126(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_127(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_128(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_129(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_130(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_131(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_132(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_133(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_134(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_135(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_136(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_137(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_138(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_139(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_140(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_141(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_142(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_143(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_144(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_145(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_146(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_147(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_148(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_149(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_150(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_151(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_152(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_153(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_154(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_155(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_156(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_157(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_158(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_159(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_160(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_161(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_162(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_163(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_164(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_165(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_166(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_167(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_168(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_169(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_170(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_171(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_172(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_173(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_174(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_175(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_176(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_177(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_178(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_179(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_180(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_181(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_182(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_183(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_184(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_185(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_186(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_187(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_188(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_189(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_190(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_191(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_192(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_193(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_194(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_195(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_196(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_197(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_198(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_199(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_200(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_201(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_202(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_203(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_204(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_205(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_206(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_207(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_208(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_209(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_210(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_211(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_212(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_213(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_214(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_215(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_216(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_217(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_218(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_219(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_220(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_221(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_222(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_223(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_224(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_225(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_226(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_227(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_228(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_229(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_230(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_231(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_232(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_233(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_234(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_235(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_236(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_237(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_238(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_239(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_240(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_241(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_242(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_243(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_244(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_245(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_246(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_247(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_248(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_249(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_250(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_251(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_252(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_253(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_254(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_255(o, s, l) 0 # define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_256(o, s, l) 0 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/fold_right.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_FOLD_RIGHT_HPP # define BOOST_PREPROCESSOR_LIST_FOLD_RIGHT_HPP # # include # include # include # include # # if 0 # define BOOST_PP_LIST_FOLD_RIGHT(op, state, list) # endif # # define BOOST_PP_LIST_FOLD_RIGHT BOOST_PP_CAT(BOOST_PP_LIST_FOLD_RIGHT_, BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256)) # # define BOOST_PP_LIST_FOLD_RIGHT_257(o, s, l) BOOST_PP_ERROR(0x0004) # # define BOOST_PP_LIST_FOLD_RIGHT_D(d, o, s, l) BOOST_PP_LIST_FOLD_RIGHT_ ## d(o, s, l) # define BOOST_PP_LIST_FOLD_RIGHT_2ND BOOST_PP_LIST_FOLD_RIGHT # define BOOST_PP_LIST_FOLD_RIGHT_2ND_D BOOST_PP_LIST_FOLD_RIGHT_D # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # include # else # include # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/for_each_i.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_LIST_FOR_EACH_I_HPP # define BOOST_PREPROCESSOR_LIST_LIST_FOR_EACH_I_HPP # # include # include # include # include # include # include # # /* BOOST_PP_LIST_FOR_EACH_I */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() && ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_LIST_FOR_EACH_I(macro, data, list) BOOST_PP_FOR((macro, data, list, 0), BOOST_PP_LIST_FOR_EACH_I_P, BOOST_PP_LIST_FOR_EACH_I_O, BOOST_PP_LIST_FOR_EACH_I_M) # else # define BOOST_PP_LIST_FOR_EACH_I(macro, data, list) BOOST_PP_LIST_FOR_EACH_I_I(macro, data, list) # define BOOST_PP_LIST_FOR_EACH_I_I(macro, data, list) BOOST_PP_FOR((macro, data, list, 0), BOOST_PP_LIST_FOR_EACH_I_P, BOOST_PP_LIST_FOR_EACH_I_O, BOOST_PP_LIST_FOR_EACH_I_M) # endif # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_LIST_FOR_EACH_I_P(r, x) BOOST_PP_LIST_FOR_EACH_I_P_D x # define BOOST_PP_LIST_FOR_EACH_I_P_D(m, d, l, i) BOOST_PP_LIST_IS_CONS(l) # else # define BOOST_PP_LIST_FOR_EACH_I_P(r, x) BOOST_PP_LIST_IS_CONS(BOOST_PP_TUPLE_ELEM(4, 2, x)) # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_LIST_FOR_EACH_I_O(r, x) BOOST_PP_LIST_FOR_EACH_I_O_D x # define BOOST_PP_LIST_FOR_EACH_I_O_D(m, d, l, i) (m, d, BOOST_PP_LIST_REST(l), BOOST_PP_INC(i)) # else # define BOOST_PP_LIST_FOR_EACH_I_O(r, x) (BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_LIST_REST(BOOST_PP_TUPLE_ELEM(4, 2, x)), BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 3, x))) # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_LIST_FOR_EACH_I_M(r, x) BOOST_PP_LIST_FOR_EACH_I_M_D(r, BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_TUPLE_ELEM(4, 2, x), BOOST_PP_TUPLE_ELEM(4, 3, x)) # else # define BOOST_PP_LIST_FOR_EACH_I_M(r, x) BOOST_PP_LIST_FOR_EACH_I_M_I(r, BOOST_PP_TUPLE_REM_4 x) # define BOOST_PP_LIST_FOR_EACH_I_M_I(r, x_e) BOOST_PP_LIST_FOR_EACH_I_M_D(r, x_e) # endif # # define BOOST_PP_LIST_FOR_EACH_I_M_D(r, m, d, l, i) m(r, d, i, BOOST_PP_LIST_FIRST(l)) # # /* BOOST_PP_LIST_FOR_EACH_I_R */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_LIST_FOR_EACH_I_R(r, macro, data, list) BOOST_PP_FOR_ ## r((macro, data, list, 0), BOOST_PP_LIST_FOR_EACH_I_P, BOOST_PP_LIST_FOR_EACH_I_O, BOOST_PP_LIST_FOR_EACH_I_M) # else # define BOOST_PP_LIST_FOR_EACH_I_R(r, macro, data, list) BOOST_PP_LIST_FOR_EACH_I_R_I(r, macro, data, list) # define BOOST_PP_LIST_FOR_EACH_I_R_I(r, macro, data, list) BOOST_PP_FOR_ ## r((macro, data, list, 0), BOOST_PP_LIST_FOR_EACH_I_P, BOOST_PP_LIST_FOR_EACH_I_O, BOOST_PP_LIST_FOR_EACH_I_M) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/list/reverse.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LIST_REVERSE_HPP # define BOOST_PREPROCESSOR_LIST_REVERSE_HPP # # include # include # # /* BOOST_PP_LIST_REVERSE */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_LIST_REVERSE(list) BOOST_PP_LIST_FOLD_LEFT(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list) # else # define BOOST_PP_LIST_REVERSE(list) BOOST_PP_LIST_REVERSE_I(list) # define BOOST_PP_LIST_REVERSE_I(list) BOOST_PP_LIST_FOLD_LEFT(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list) # endif # # define BOOST_PP_LIST_REVERSE_O(d, s, x) (x, s) # # /* BOOST_PP_LIST_REVERSE_D */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_LIST_REVERSE_D(d, list) BOOST_PP_LIST_FOLD_LEFT_ ## d(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list) # else # define BOOST_PP_LIST_REVERSE_D(d, list) BOOST_PP_LIST_REVERSE_D_I(d, list) # define BOOST_PP_LIST_REVERSE_D_I(d, list) BOOST_PP_LIST_FOLD_LEFT_ ## d(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/logical/and.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LOGICAL_AND_HPP # define BOOST_PREPROCESSOR_LOGICAL_AND_HPP # # include # include # include # # /* BOOST_PP_AND */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_AND(p, q) BOOST_PP_BITAND(BOOST_PP_BOOL(p), BOOST_PP_BOOL(q)) # else # define BOOST_PP_AND(p, q) BOOST_PP_AND_I(p, q) # define BOOST_PP_AND_I(p, q) BOOST_PP_BITAND(BOOST_PP_BOOL(p), BOOST_PP_BOOL(q)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/logical/bitand.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LOGICAL_BITAND_HPP # define BOOST_PREPROCESSOR_LOGICAL_BITAND_HPP # # include # # /* BOOST_PP_BITAND */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_BITAND(x, y) BOOST_PP_BITAND_I(x, y) # else # define BOOST_PP_BITAND(x, y) BOOST_PP_BITAND_OO((x, y)) # define BOOST_PP_BITAND_OO(par) BOOST_PP_BITAND_I ## par # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_BITAND_I(x, y) BOOST_PP_BITAND_ ## x ## y # else # define BOOST_PP_BITAND_I(x, y) BOOST_PP_BITAND_ID(BOOST_PP_BITAND_ ## x ## y) # define BOOST_PP_BITAND_ID(res) res # endif # # define BOOST_PP_BITAND_00 0 # define BOOST_PP_BITAND_01 0 # define BOOST_PP_BITAND_10 0 # define BOOST_PP_BITAND_11 1 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/logical/bool.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LOGICAL_BOOL_HPP # define BOOST_PREPROCESSOR_LOGICAL_BOOL_HPP # # include # # /* BOOST_PP_BOOL */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_BOOL(x) BOOST_PP_BOOL_I(x) # else # define BOOST_PP_BOOL(x) BOOST_PP_BOOL_OO((x)) # define BOOST_PP_BOOL_OO(par) BOOST_PP_BOOL_I ## par # endif # # define BOOST_PP_BOOL_I(x) BOOST_PP_BOOL_ ## x # # define BOOST_PP_BOOL_0 0 # define BOOST_PP_BOOL_1 1 # define BOOST_PP_BOOL_2 1 # define BOOST_PP_BOOL_3 1 # define BOOST_PP_BOOL_4 1 # define BOOST_PP_BOOL_5 1 # define BOOST_PP_BOOL_6 1 # define BOOST_PP_BOOL_7 1 # define BOOST_PP_BOOL_8 1 # define BOOST_PP_BOOL_9 1 # define BOOST_PP_BOOL_10 1 # define BOOST_PP_BOOL_11 1 # define BOOST_PP_BOOL_12 1 # define BOOST_PP_BOOL_13 1 # define BOOST_PP_BOOL_14 1 # define BOOST_PP_BOOL_15 1 # define BOOST_PP_BOOL_16 1 # define BOOST_PP_BOOL_17 1 # define BOOST_PP_BOOL_18 1 # define BOOST_PP_BOOL_19 1 # define BOOST_PP_BOOL_20 1 # define BOOST_PP_BOOL_21 1 # define BOOST_PP_BOOL_22 1 # define BOOST_PP_BOOL_23 1 # define BOOST_PP_BOOL_24 1 # define BOOST_PP_BOOL_25 1 # define BOOST_PP_BOOL_26 1 # define BOOST_PP_BOOL_27 1 # define BOOST_PP_BOOL_28 1 # define BOOST_PP_BOOL_29 1 # define BOOST_PP_BOOL_30 1 # define BOOST_PP_BOOL_31 1 # define BOOST_PP_BOOL_32 1 # define BOOST_PP_BOOL_33 1 # define BOOST_PP_BOOL_34 1 # define BOOST_PP_BOOL_35 1 # define BOOST_PP_BOOL_36 1 # define BOOST_PP_BOOL_37 1 # define BOOST_PP_BOOL_38 1 # define BOOST_PP_BOOL_39 1 # define BOOST_PP_BOOL_40 1 # define BOOST_PP_BOOL_41 1 # define BOOST_PP_BOOL_42 1 # define BOOST_PP_BOOL_43 1 # define BOOST_PP_BOOL_44 1 # define BOOST_PP_BOOL_45 1 # define BOOST_PP_BOOL_46 1 # define BOOST_PP_BOOL_47 1 # define BOOST_PP_BOOL_48 1 # define BOOST_PP_BOOL_49 1 # define BOOST_PP_BOOL_50 1 # define BOOST_PP_BOOL_51 1 # define BOOST_PP_BOOL_52 1 # define BOOST_PP_BOOL_53 1 # define BOOST_PP_BOOL_54 1 # define BOOST_PP_BOOL_55 1 # define BOOST_PP_BOOL_56 1 # define BOOST_PP_BOOL_57 1 # define BOOST_PP_BOOL_58 1 # define BOOST_PP_BOOL_59 1 # define BOOST_PP_BOOL_60 1 # define BOOST_PP_BOOL_61 1 # define BOOST_PP_BOOL_62 1 # define BOOST_PP_BOOL_63 1 # define BOOST_PP_BOOL_64 1 # define BOOST_PP_BOOL_65 1 # define BOOST_PP_BOOL_66 1 # define BOOST_PP_BOOL_67 1 # define BOOST_PP_BOOL_68 1 # define BOOST_PP_BOOL_69 1 # define BOOST_PP_BOOL_70 1 # define BOOST_PP_BOOL_71 1 # define BOOST_PP_BOOL_72 1 # define BOOST_PP_BOOL_73 1 # define BOOST_PP_BOOL_74 1 # define BOOST_PP_BOOL_75 1 # define BOOST_PP_BOOL_76 1 # define BOOST_PP_BOOL_77 1 # define BOOST_PP_BOOL_78 1 # define BOOST_PP_BOOL_79 1 # define BOOST_PP_BOOL_80 1 # define BOOST_PP_BOOL_81 1 # define BOOST_PP_BOOL_82 1 # define BOOST_PP_BOOL_83 1 # define BOOST_PP_BOOL_84 1 # define BOOST_PP_BOOL_85 1 # define BOOST_PP_BOOL_86 1 # define BOOST_PP_BOOL_87 1 # define BOOST_PP_BOOL_88 1 # define BOOST_PP_BOOL_89 1 # define BOOST_PP_BOOL_90 1 # define BOOST_PP_BOOL_91 1 # define BOOST_PP_BOOL_92 1 # define BOOST_PP_BOOL_93 1 # define BOOST_PP_BOOL_94 1 # define BOOST_PP_BOOL_95 1 # define BOOST_PP_BOOL_96 1 # define BOOST_PP_BOOL_97 1 # define BOOST_PP_BOOL_98 1 # define BOOST_PP_BOOL_99 1 # define BOOST_PP_BOOL_100 1 # define BOOST_PP_BOOL_101 1 # define BOOST_PP_BOOL_102 1 # define BOOST_PP_BOOL_103 1 # define BOOST_PP_BOOL_104 1 # define BOOST_PP_BOOL_105 1 # define BOOST_PP_BOOL_106 1 # define BOOST_PP_BOOL_107 1 # define BOOST_PP_BOOL_108 1 # define BOOST_PP_BOOL_109 1 # define BOOST_PP_BOOL_110 1 # define BOOST_PP_BOOL_111 1 # define BOOST_PP_BOOL_112 1 # define BOOST_PP_BOOL_113 1 # define BOOST_PP_BOOL_114 1 # define BOOST_PP_BOOL_115 1 # define BOOST_PP_BOOL_116 1 # define BOOST_PP_BOOL_117 1 # define BOOST_PP_BOOL_118 1 # define BOOST_PP_BOOL_119 1 # define BOOST_PP_BOOL_120 1 # define BOOST_PP_BOOL_121 1 # define BOOST_PP_BOOL_122 1 # define BOOST_PP_BOOL_123 1 # define BOOST_PP_BOOL_124 1 # define BOOST_PP_BOOL_125 1 # define BOOST_PP_BOOL_126 1 # define BOOST_PP_BOOL_127 1 # define BOOST_PP_BOOL_128 1 # define BOOST_PP_BOOL_129 1 # define BOOST_PP_BOOL_130 1 # define BOOST_PP_BOOL_131 1 # define BOOST_PP_BOOL_132 1 # define BOOST_PP_BOOL_133 1 # define BOOST_PP_BOOL_134 1 # define BOOST_PP_BOOL_135 1 # define BOOST_PP_BOOL_136 1 # define BOOST_PP_BOOL_137 1 # define BOOST_PP_BOOL_138 1 # define BOOST_PP_BOOL_139 1 # define BOOST_PP_BOOL_140 1 # define BOOST_PP_BOOL_141 1 # define BOOST_PP_BOOL_142 1 # define BOOST_PP_BOOL_143 1 # define BOOST_PP_BOOL_144 1 # define BOOST_PP_BOOL_145 1 # define BOOST_PP_BOOL_146 1 # define BOOST_PP_BOOL_147 1 # define BOOST_PP_BOOL_148 1 # define BOOST_PP_BOOL_149 1 # define BOOST_PP_BOOL_150 1 # define BOOST_PP_BOOL_151 1 # define BOOST_PP_BOOL_152 1 # define BOOST_PP_BOOL_153 1 # define BOOST_PP_BOOL_154 1 # define BOOST_PP_BOOL_155 1 # define BOOST_PP_BOOL_156 1 # define BOOST_PP_BOOL_157 1 # define BOOST_PP_BOOL_158 1 # define BOOST_PP_BOOL_159 1 # define BOOST_PP_BOOL_160 1 # define BOOST_PP_BOOL_161 1 # define BOOST_PP_BOOL_162 1 # define BOOST_PP_BOOL_163 1 # define BOOST_PP_BOOL_164 1 # define BOOST_PP_BOOL_165 1 # define BOOST_PP_BOOL_166 1 # define BOOST_PP_BOOL_167 1 # define BOOST_PP_BOOL_168 1 # define BOOST_PP_BOOL_169 1 # define BOOST_PP_BOOL_170 1 # define BOOST_PP_BOOL_171 1 # define BOOST_PP_BOOL_172 1 # define BOOST_PP_BOOL_173 1 # define BOOST_PP_BOOL_174 1 # define BOOST_PP_BOOL_175 1 # define BOOST_PP_BOOL_176 1 # define BOOST_PP_BOOL_177 1 # define BOOST_PP_BOOL_178 1 # define BOOST_PP_BOOL_179 1 # define BOOST_PP_BOOL_180 1 # define BOOST_PP_BOOL_181 1 # define BOOST_PP_BOOL_182 1 # define BOOST_PP_BOOL_183 1 # define BOOST_PP_BOOL_184 1 # define BOOST_PP_BOOL_185 1 # define BOOST_PP_BOOL_186 1 # define BOOST_PP_BOOL_187 1 # define BOOST_PP_BOOL_188 1 # define BOOST_PP_BOOL_189 1 # define BOOST_PP_BOOL_190 1 # define BOOST_PP_BOOL_191 1 # define BOOST_PP_BOOL_192 1 # define BOOST_PP_BOOL_193 1 # define BOOST_PP_BOOL_194 1 # define BOOST_PP_BOOL_195 1 # define BOOST_PP_BOOL_196 1 # define BOOST_PP_BOOL_197 1 # define BOOST_PP_BOOL_198 1 # define BOOST_PP_BOOL_199 1 # define BOOST_PP_BOOL_200 1 # define BOOST_PP_BOOL_201 1 # define BOOST_PP_BOOL_202 1 # define BOOST_PP_BOOL_203 1 # define BOOST_PP_BOOL_204 1 # define BOOST_PP_BOOL_205 1 # define BOOST_PP_BOOL_206 1 # define BOOST_PP_BOOL_207 1 # define BOOST_PP_BOOL_208 1 # define BOOST_PP_BOOL_209 1 # define BOOST_PP_BOOL_210 1 # define BOOST_PP_BOOL_211 1 # define BOOST_PP_BOOL_212 1 # define BOOST_PP_BOOL_213 1 # define BOOST_PP_BOOL_214 1 # define BOOST_PP_BOOL_215 1 # define BOOST_PP_BOOL_216 1 # define BOOST_PP_BOOL_217 1 # define BOOST_PP_BOOL_218 1 # define BOOST_PP_BOOL_219 1 # define BOOST_PP_BOOL_220 1 # define BOOST_PP_BOOL_221 1 # define BOOST_PP_BOOL_222 1 # define BOOST_PP_BOOL_223 1 # define BOOST_PP_BOOL_224 1 # define BOOST_PP_BOOL_225 1 # define BOOST_PP_BOOL_226 1 # define BOOST_PP_BOOL_227 1 # define BOOST_PP_BOOL_228 1 # define BOOST_PP_BOOL_229 1 # define BOOST_PP_BOOL_230 1 # define BOOST_PP_BOOL_231 1 # define BOOST_PP_BOOL_232 1 # define BOOST_PP_BOOL_233 1 # define BOOST_PP_BOOL_234 1 # define BOOST_PP_BOOL_235 1 # define BOOST_PP_BOOL_236 1 # define BOOST_PP_BOOL_237 1 # define BOOST_PP_BOOL_238 1 # define BOOST_PP_BOOL_239 1 # define BOOST_PP_BOOL_240 1 # define BOOST_PP_BOOL_241 1 # define BOOST_PP_BOOL_242 1 # define BOOST_PP_BOOL_243 1 # define BOOST_PP_BOOL_244 1 # define BOOST_PP_BOOL_245 1 # define BOOST_PP_BOOL_246 1 # define BOOST_PP_BOOL_247 1 # define BOOST_PP_BOOL_248 1 # define BOOST_PP_BOOL_249 1 # define BOOST_PP_BOOL_250 1 # define BOOST_PP_BOOL_251 1 # define BOOST_PP_BOOL_252 1 # define BOOST_PP_BOOL_253 1 # define BOOST_PP_BOOL_254 1 # define BOOST_PP_BOOL_255 1 # define BOOST_PP_BOOL_256 1 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/logical/compl.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LOGICAL_COMPL_HPP # define BOOST_PREPROCESSOR_LOGICAL_COMPL_HPP # # include # # /* BOOST_PP_COMPL */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_COMPL(x) BOOST_PP_COMPL_I(x) # else # define BOOST_PP_COMPL(x) BOOST_PP_COMPL_OO((x)) # define BOOST_PP_COMPL_OO(par) BOOST_PP_COMPL_I ## par # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_COMPL_I(x) BOOST_PP_COMPL_ ## x # else # define BOOST_PP_COMPL_I(x) BOOST_PP_COMPL_ID(BOOST_PP_COMPL_ ## x) # define BOOST_PP_COMPL_ID(id) id # endif # # define BOOST_PP_COMPL_0 1 # define BOOST_PP_COMPL_1 0 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/logical/not.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_LOGICAL_NOT_HPP # define BOOST_PREPROCESSOR_LOGICAL_NOT_HPP # # include # include # include # # /* BOOST_PP_NOT */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_NOT(x) BOOST_PP_COMPL(BOOST_PP_BOOL(x)) # else # define BOOST_PP_NOT(x) BOOST_PP_NOT_I(x) # define BOOST_PP_NOT_I(x) BOOST_PP_COMPL(BOOST_PP_BOOL(x)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/punctuation/comma.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_PUNCTUATION_COMMA_HPP # define BOOST_PREPROCESSOR_PUNCTUATION_COMMA_HPP # # /* BOOST_PP_COMMA */ # # define BOOST_PP_COMMA() , # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/punctuation/comma_if.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_PUNCTUATION_COMMA_IF_HPP # define BOOST_PREPROCESSOR_PUNCTUATION_COMMA_IF_HPP # # include # include # include # include # # /* BOOST_PP_COMMA_IF */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_COMMA_IF(cond) BOOST_PP_IF(cond, BOOST_PP_COMMA, BOOST_PP_EMPTY)() # else # define BOOST_PP_COMMA_IF(cond) BOOST_PP_COMMA_IF_I(cond) # define BOOST_PP_COMMA_IF_I(cond) BOOST_PP_IF(cond, BOOST_PP_COMMA, BOOST_PP_EMPTY)() # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/punctuation/detail/is_begin_parens.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2014. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # #ifndef BOOST_PREPROCESSOR_DETAIL_IS_BEGIN_PARENS_HPP #define BOOST_PREPROCESSOR_DETAIL_IS_BEGIN_PARENS_HPP #if BOOST_PP_VARIADICS_MSVC #include #define BOOST_PP_DETAIL_VD_IBP_CAT(a, b) BOOST_PP_DETAIL_VD_IBP_CAT_I(a, b) #define BOOST_PP_DETAIL_VD_IBP_CAT_I(a, b) BOOST_PP_DETAIL_VD_IBP_CAT_II(a ## b) #define BOOST_PP_DETAIL_VD_IBP_CAT_II(res) res #define BOOST_PP_DETAIL_IBP_SPLIT(i, ...) \ BOOST_PP_DETAIL_VD_IBP_CAT(BOOST_PP_DETAIL_IBP_PRIMITIVE_CAT(BOOST_PP_DETAIL_IBP_SPLIT_,i)(__VA_ARGS__),BOOST_PP_EMPTY()) \ /**/ #define BOOST_PP_DETAIL_IBP_IS_VARIADIC_C(...) 1 1 #else #define BOOST_PP_DETAIL_IBP_SPLIT(i, ...) \ BOOST_PP_DETAIL_IBP_PRIMITIVE_CAT(BOOST_PP_DETAIL_IBP_SPLIT_,i)(__VA_ARGS__) \ /**/ #define BOOST_PP_DETAIL_IBP_IS_VARIADIC_C(...) 1 #endif /* BOOST_PP_VARIADICS_MSVC */ #define BOOST_PP_DETAIL_IBP_SPLIT_0(a, ...) a #define BOOST_PP_DETAIL_IBP_SPLIT_1(a, ...) __VA_ARGS__ #define BOOST_PP_DETAIL_IBP_CAT(a, ...) BOOST_PP_DETAIL_IBP_PRIMITIVE_CAT(a,__VA_ARGS__) #define BOOST_PP_DETAIL_IBP_PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ #define BOOST_PP_DETAIL_IBP_IS_VARIADIC_R_1 1, #define BOOST_PP_DETAIL_IBP_IS_VARIADIC_R_BOOST_PP_DETAIL_IBP_IS_VARIADIC_C 0, #endif /* BOOST_PREPROCESSOR_DETAIL_IS_BEGIN_PARENS_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/punctuation/is_begin_parens.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2014. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_IS_BEGIN_PARENS_HPP # define BOOST_PREPROCESSOR_IS_BEGIN_PARENS_HPP # include #if BOOST_PP_VARIADICS #include #if BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400 #define BOOST_PP_IS_BEGIN_PARENS(param) \ BOOST_PP_DETAIL_IBP_SPLIT \ ( \ 0, \ BOOST_PP_DETAIL_IBP_CAT \ ( \ BOOST_PP_DETAIL_IBP_IS_VARIADIC_R_, \ BOOST_PP_DETAIL_IBP_IS_VARIADIC_C param \ ) \ ) \ /**/ #else #define BOOST_PP_IS_BEGIN_PARENS(...) \ BOOST_PP_DETAIL_IBP_SPLIT \ ( \ 0, \ BOOST_PP_DETAIL_IBP_CAT \ ( \ BOOST_PP_DETAIL_IBP_IS_VARIADIC_R_, \ BOOST_PP_DETAIL_IBP_IS_VARIADIC_C __VA_ARGS__ \ ) \ ) \ /**/ #endif /* BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400 */ #endif /* BOOST_PP_VARIADICS */ #endif /* BOOST_PREPROCESSOR_IS_BEGIN_PARENS_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repeat.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPEAT_HPP # define BOOST_PREPROCESSOR_REPEAT_HPP # # include # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/deduce_r.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_DEDUCE_R_HPP # define BOOST_PREPROCESSOR_REPETITION_DEDUCE_R_HPP # # include # include # # /* BOOST_PP_DEDUCE_R */ # # define BOOST_PP_DEDUCE_R() BOOST_PP_AUTO_REC(BOOST_PP_FOR_P, 256) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/detail/dmc/for.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_DETAIL_FOR_HPP # define BOOST_PREPROCESSOR_REPETITION_DETAIL_FOR_HPP # # include # include # include # include # # define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_FOR_1_C(BOOST_PP_BOOL(p##(2, s)), s, p, o, m) # define BOOST_PP_FOR_2(s, p, o, m) BOOST_PP_FOR_2_C(BOOST_PP_BOOL(p##(3, s)), s, p, o, m) # define BOOST_PP_FOR_3(s, p, o, m) BOOST_PP_FOR_3_C(BOOST_PP_BOOL(p##(4, s)), s, p, o, m) # define BOOST_PP_FOR_4(s, p, o, m) BOOST_PP_FOR_4_C(BOOST_PP_BOOL(p##(5, s)), s, p, o, m) # define BOOST_PP_FOR_5(s, p, o, m) BOOST_PP_FOR_5_C(BOOST_PP_BOOL(p##(6, s)), s, p, o, m) # define BOOST_PP_FOR_6(s, p, o, m) BOOST_PP_FOR_6_C(BOOST_PP_BOOL(p##(7, s)), s, p, o, m) # define BOOST_PP_FOR_7(s, p, o, m) BOOST_PP_FOR_7_C(BOOST_PP_BOOL(p##(8, s)), s, p, o, m) # define BOOST_PP_FOR_8(s, p, o, m) BOOST_PP_FOR_8_C(BOOST_PP_BOOL(p##(9, s)), s, p, o, m) # define BOOST_PP_FOR_9(s, p, o, m) BOOST_PP_FOR_9_C(BOOST_PP_BOOL(p##(10, s)), s, p, o, m) # define BOOST_PP_FOR_10(s, p, o, m) BOOST_PP_FOR_10_C(BOOST_PP_BOOL(p##(11, s)), s, p, o, m) # define BOOST_PP_FOR_11(s, p, o, m) BOOST_PP_FOR_11_C(BOOST_PP_BOOL(p##(12, s)), s, p, o, m) # define BOOST_PP_FOR_12(s, p, o, m) BOOST_PP_FOR_12_C(BOOST_PP_BOOL(p##(13, s)), s, p, o, m) # define BOOST_PP_FOR_13(s, p, o, m) BOOST_PP_FOR_13_C(BOOST_PP_BOOL(p##(14, s)), s, p, o, m) # define BOOST_PP_FOR_14(s, p, o, m) BOOST_PP_FOR_14_C(BOOST_PP_BOOL(p##(15, s)), s, p, o, m) # define BOOST_PP_FOR_15(s, p, o, m) BOOST_PP_FOR_15_C(BOOST_PP_BOOL(p##(16, s)), s, p, o, m) # define BOOST_PP_FOR_16(s, p, o, m) BOOST_PP_FOR_16_C(BOOST_PP_BOOL(p##(17, s)), s, p, o, m) # define BOOST_PP_FOR_17(s, p, o, m) BOOST_PP_FOR_17_C(BOOST_PP_BOOL(p##(18, s)), s, p, o, m) # define BOOST_PP_FOR_18(s, p, o, m) BOOST_PP_FOR_18_C(BOOST_PP_BOOL(p##(19, s)), s, p, o, m) # define BOOST_PP_FOR_19(s, p, o, m) BOOST_PP_FOR_19_C(BOOST_PP_BOOL(p##(20, s)), s, p, o, m) # define BOOST_PP_FOR_20(s, p, o, m) BOOST_PP_FOR_20_C(BOOST_PP_BOOL(p##(21, s)), s, p, o, m) # define BOOST_PP_FOR_21(s, p, o, m) BOOST_PP_FOR_21_C(BOOST_PP_BOOL(p##(22, s)), s, p, o, m) # define BOOST_PP_FOR_22(s, p, o, m) BOOST_PP_FOR_22_C(BOOST_PP_BOOL(p##(23, s)), s, p, o, m) # define BOOST_PP_FOR_23(s, p, o, m) BOOST_PP_FOR_23_C(BOOST_PP_BOOL(p##(24, s)), s, p, o, m) # define BOOST_PP_FOR_24(s, p, o, m) BOOST_PP_FOR_24_C(BOOST_PP_BOOL(p##(25, s)), s, p, o, m) # define BOOST_PP_FOR_25(s, p, o, m) BOOST_PP_FOR_25_C(BOOST_PP_BOOL(p##(26, s)), s, p, o, m) # define BOOST_PP_FOR_26(s, p, o, m) BOOST_PP_FOR_26_C(BOOST_PP_BOOL(p##(27, s)), s, p, o, m) # define BOOST_PP_FOR_27(s, p, o, m) BOOST_PP_FOR_27_C(BOOST_PP_BOOL(p##(28, s)), s, p, o, m) # define BOOST_PP_FOR_28(s, p, o, m) BOOST_PP_FOR_28_C(BOOST_PP_BOOL(p##(29, s)), s, p, o, m) # define BOOST_PP_FOR_29(s, p, o, m) BOOST_PP_FOR_29_C(BOOST_PP_BOOL(p##(30, s)), s, p, o, m) # define BOOST_PP_FOR_30(s, p, o, m) BOOST_PP_FOR_30_C(BOOST_PP_BOOL(p##(31, s)), s, p, o, m) # define BOOST_PP_FOR_31(s, p, o, m) BOOST_PP_FOR_31_C(BOOST_PP_BOOL(p##(32, s)), s, p, o, m) # define BOOST_PP_FOR_32(s, p, o, m) BOOST_PP_FOR_32_C(BOOST_PP_BOOL(p##(33, s)), s, p, o, m) # define BOOST_PP_FOR_33(s, p, o, m) BOOST_PP_FOR_33_C(BOOST_PP_BOOL(p##(34, s)), s, p, o, m) # define BOOST_PP_FOR_34(s, p, o, m) BOOST_PP_FOR_34_C(BOOST_PP_BOOL(p##(35, s)), s, p, o, m) # define BOOST_PP_FOR_35(s, p, o, m) BOOST_PP_FOR_35_C(BOOST_PP_BOOL(p##(36, s)), s, p, o, m) # define BOOST_PP_FOR_36(s, p, o, m) BOOST_PP_FOR_36_C(BOOST_PP_BOOL(p##(37, s)), s, p, o, m) # define BOOST_PP_FOR_37(s, p, o, m) BOOST_PP_FOR_37_C(BOOST_PP_BOOL(p##(38, s)), s, p, o, m) # define BOOST_PP_FOR_38(s, p, o, m) BOOST_PP_FOR_38_C(BOOST_PP_BOOL(p##(39, s)), s, p, o, m) # define BOOST_PP_FOR_39(s, p, o, m) BOOST_PP_FOR_39_C(BOOST_PP_BOOL(p##(40, s)), s, p, o, m) # define BOOST_PP_FOR_40(s, p, o, m) BOOST_PP_FOR_40_C(BOOST_PP_BOOL(p##(41, s)), s, p, o, m) # define BOOST_PP_FOR_41(s, p, o, m) BOOST_PP_FOR_41_C(BOOST_PP_BOOL(p##(42, s)), s, p, o, m) # define BOOST_PP_FOR_42(s, p, o, m) BOOST_PP_FOR_42_C(BOOST_PP_BOOL(p##(43, s)), s, p, o, m) # define BOOST_PP_FOR_43(s, p, o, m) BOOST_PP_FOR_43_C(BOOST_PP_BOOL(p##(44, s)), s, p, o, m) # define BOOST_PP_FOR_44(s, p, o, m) BOOST_PP_FOR_44_C(BOOST_PP_BOOL(p##(45, s)), s, p, o, m) # define BOOST_PP_FOR_45(s, p, o, m) BOOST_PP_FOR_45_C(BOOST_PP_BOOL(p##(46, s)), s, p, o, m) # define BOOST_PP_FOR_46(s, p, o, m) BOOST_PP_FOR_46_C(BOOST_PP_BOOL(p##(47, s)), s, p, o, m) # define BOOST_PP_FOR_47(s, p, o, m) BOOST_PP_FOR_47_C(BOOST_PP_BOOL(p##(48, s)), s, p, o, m) # define BOOST_PP_FOR_48(s, p, o, m) BOOST_PP_FOR_48_C(BOOST_PP_BOOL(p##(49, s)), s, p, o, m) # define BOOST_PP_FOR_49(s, p, o, m) BOOST_PP_FOR_49_C(BOOST_PP_BOOL(p##(50, s)), s, p, o, m) # define BOOST_PP_FOR_50(s, p, o, m) BOOST_PP_FOR_50_C(BOOST_PP_BOOL(p##(51, s)), s, p, o, m) # define BOOST_PP_FOR_51(s, p, o, m) BOOST_PP_FOR_51_C(BOOST_PP_BOOL(p##(52, s)), s, p, o, m) # define BOOST_PP_FOR_52(s, p, o, m) BOOST_PP_FOR_52_C(BOOST_PP_BOOL(p##(53, s)), s, p, o, m) # define BOOST_PP_FOR_53(s, p, o, m) BOOST_PP_FOR_53_C(BOOST_PP_BOOL(p##(54, s)), s, p, o, m) # define BOOST_PP_FOR_54(s, p, o, m) BOOST_PP_FOR_54_C(BOOST_PP_BOOL(p##(55, s)), s, p, o, m) # define BOOST_PP_FOR_55(s, p, o, m) BOOST_PP_FOR_55_C(BOOST_PP_BOOL(p##(56, s)), s, p, o, m) # define BOOST_PP_FOR_56(s, p, o, m) BOOST_PP_FOR_56_C(BOOST_PP_BOOL(p##(57, s)), s, p, o, m) # define BOOST_PP_FOR_57(s, p, o, m) BOOST_PP_FOR_57_C(BOOST_PP_BOOL(p##(58, s)), s, p, o, m) # define BOOST_PP_FOR_58(s, p, o, m) BOOST_PP_FOR_58_C(BOOST_PP_BOOL(p##(59, s)), s, p, o, m) # define BOOST_PP_FOR_59(s, p, o, m) BOOST_PP_FOR_59_C(BOOST_PP_BOOL(p##(60, s)), s, p, o, m) # define BOOST_PP_FOR_60(s, p, o, m) BOOST_PP_FOR_60_C(BOOST_PP_BOOL(p##(61, s)), s, p, o, m) # define BOOST_PP_FOR_61(s, p, o, m) BOOST_PP_FOR_61_C(BOOST_PP_BOOL(p##(62, s)), s, p, o, m) # define BOOST_PP_FOR_62(s, p, o, m) BOOST_PP_FOR_62_C(BOOST_PP_BOOL(p##(63, s)), s, p, o, m) # define BOOST_PP_FOR_63(s, p, o, m) BOOST_PP_FOR_63_C(BOOST_PP_BOOL(p##(64, s)), s, p, o, m) # define BOOST_PP_FOR_64(s, p, o, m) BOOST_PP_FOR_64_C(BOOST_PP_BOOL(p##(65, s)), s, p, o, m) # define BOOST_PP_FOR_65(s, p, o, m) BOOST_PP_FOR_65_C(BOOST_PP_BOOL(p##(66, s)), s, p, o, m) # define BOOST_PP_FOR_66(s, p, o, m) BOOST_PP_FOR_66_C(BOOST_PP_BOOL(p##(67, s)), s, p, o, m) # define BOOST_PP_FOR_67(s, p, o, m) BOOST_PP_FOR_67_C(BOOST_PP_BOOL(p##(68, s)), s, p, o, m) # define BOOST_PP_FOR_68(s, p, o, m) BOOST_PP_FOR_68_C(BOOST_PP_BOOL(p##(69, s)), s, p, o, m) # define BOOST_PP_FOR_69(s, p, o, m) BOOST_PP_FOR_69_C(BOOST_PP_BOOL(p##(70, s)), s, p, o, m) # define BOOST_PP_FOR_70(s, p, o, m) BOOST_PP_FOR_70_C(BOOST_PP_BOOL(p##(71, s)), s, p, o, m) # define BOOST_PP_FOR_71(s, p, o, m) BOOST_PP_FOR_71_C(BOOST_PP_BOOL(p##(72, s)), s, p, o, m) # define BOOST_PP_FOR_72(s, p, o, m) BOOST_PP_FOR_72_C(BOOST_PP_BOOL(p##(73, s)), s, p, o, m) # define BOOST_PP_FOR_73(s, p, o, m) BOOST_PP_FOR_73_C(BOOST_PP_BOOL(p##(74, s)), s, p, o, m) # define BOOST_PP_FOR_74(s, p, o, m) BOOST_PP_FOR_74_C(BOOST_PP_BOOL(p##(75, s)), s, p, o, m) # define BOOST_PP_FOR_75(s, p, o, m) BOOST_PP_FOR_75_C(BOOST_PP_BOOL(p##(76, s)), s, p, o, m) # define BOOST_PP_FOR_76(s, p, o, m) BOOST_PP_FOR_76_C(BOOST_PP_BOOL(p##(77, s)), s, p, o, m) # define BOOST_PP_FOR_77(s, p, o, m) BOOST_PP_FOR_77_C(BOOST_PP_BOOL(p##(78, s)), s, p, o, m) # define BOOST_PP_FOR_78(s, p, o, m) BOOST_PP_FOR_78_C(BOOST_PP_BOOL(p##(79, s)), s, p, o, m) # define BOOST_PP_FOR_79(s, p, o, m) BOOST_PP_FOR_79_C(BOOST_PP_BOOL(p##(80, s)), s, p, o, m) # define BOOST_PP_FOR_80(s, p, o, m) BOOST_PP_FOR_80_C(BOOST_PP_BOOL(p##(81, s)), s, p, o, m) # define BOOST_PP_FOR_81(s, p, o, m) BOOST_PP_FOR_81_C(BOOST_PP_BOOL(p##(82, s)), s, p, o, m) # define BOOST_PP_FOR_82(s, p, o, m) BOOST_PP_FOR_82_C(BOOST_PP_BOOL(p##(83, s)), s, p, o, m) # define BOOST_PP_FOR_83(s, p, o, m) BOOST_PP_FOR_83_C(BOOST_PP_BOOL(p##(84, s)), s, p, o, m) # define BOOST_PP_FOR_84(s, p, o, m) BOOST_PP_FOR_84_C(BOOST_PP_BOOL(p##(85, s)), s, p, o, m) # define BOOST_PP_FOR_85(s, p, o, m) BOOST_PP_FOR_85_C(BOOST_PP_BOOL(p##(86, s)), s, p, o, m) # define BOOST_PP_FOR_86(s, p, o, m) BOOST_PP_FOR_86_C(BOOST_PP_BOOL(p##(87, s)), s, p, o, m) # define BOOST_PP_FOR_87(s, p, o, m) BOOST_PP_FOR_87_C(BOOST_PP_BOOL(p##(88, s)), s, p, o, m) # define BOOST_PP_FOR_88(s, p, o, m) BOOST_PP_FOR_88_C(BOOST_PP_BOOL(p##(89, s)), s, p, o, m) # define BOOST_PP_FOR_89(s, p, o, m) BOOST_PP_FOR_89_C(BOOST_PP_BOOL(p##(90, s)), s, p, o, m) # define BOOST_PP_FOR_90(s, p, o, m) BOOST_PP_FOR_90_C(BOOST_PP_BOOL(p##(91, s)), s, p, o, m) # define BOOST_PP_FOR_91(s, p, o, m) BOOST_PP_FOR_91_C(BOOST_PP_BOOL(p##(92, s)), s, p, o, m) # define BOOST_PP_FOR_92(s, p, o, m) BOOST_PP_FOR_92_C(BOOST_PP_BOOL(p##(93, s)), s, p, o, m) # define BOOST_PP_FOR_93(s, p, o, m) BOOST_PP_FOR_93_C(BOOST_PP_BOOL(p##(94, s)), s, p, o, m) # define BOOST_PP_FOR_94(s, p, o, m) BOOST_PP_FOR_94_C(BOOST_PP_BOOL(p##(95, s)), s, p, o, m) # define BOOST_PP_FOR_95(s, p, o, m) BOOST_PP_FOR_95_C(BOOST_PP_BOOL(p##(96, s)), s, p, o, m) # define BOOST_PP_FOR_96(s, p, o, m) BOOST_PP_FOR_96_C(BOOST_PP_BOOL(p##(97, s)), s, p, o, m) # define BOOST_PP_FOR_97(s, p, o, m) BOOST_PP_FOR_97_C(BOOST_PP_BOOL(p##(98, s)), s, p, o, m) # define BOOST_PP_FOR_98(s, p, o, m) BOOST_PP_FOR_98_C(BOOST_PP_BOOL(p##(99, s)), s, p, o, m) # define BOOST_PP_FOR_99(s, p, o, m) BOOST_PP_FOR_99_C(BOOST_PP_BOOL(p##(100, s)), s, p, o, m) # define BOOST_PP_FOR_100(s, p, o, m) BOOST_PP_FOR_100_C(BOOST_PP_BOOL(p##(101, s)), s, p, o, m) # define BOOST_PP_FOR_101(s, p, o, m) BOOST_PP_FOR_101_C(BOOST_PP_BOOL(p##(102, s)), s, p, o, m) # define BOOST_PP_FOR_102(s, p, o, m) BOOST_PP_FOR_102_C(BOOST_PP_BOOL(p##(103, s)), s, p, o, m) # define BOOST_PP_FOR_103(s, p, o, m) BOOST_PP_FOR_103_C(BOOST_PP_BOOL(p##(104, s)), s, p, o, m) # define BOOST_PP_FOR_104(s, p, o, m) BOOST_PP_FOR_104_C(BOOST_PP_BOOL(p##(105, s)), s, p, o, m) # define BOOST_PP_FOR_105(s, p, o, m) BOOST_PP_FOR_105_C(BOOST_PP_BOOL(p##(106, s)), s, p, o, m) # define BOOST_PP_FOR_106(s, p, o, m) BOOST_PP_FOR_106_C(BOOST_PP_BOOL(p##(107, s)), s, p, o, m) # define BOOST_PP_FOR_107(s, p, o, m) BOOST_PP_FOR_107_C(BOOST_PP_BOOL(p##(108, s)), s, p, o, m) # define BOOST_PP_FOR_108(s, p, o, m) BOOST_PP_FOR_108_C(BOOST_PP_BOOL(p##(109, s)), s, p, o, m) # define BOOST_PP_FOR_109(s, p, o, m) BOOST_PP_FOR_109_C(BOOST_PP_BOOL(p##(110, s)), s, p, o, m) # define BOOST_PP_FOR_110(s, p, o, m) BOOST_PP_FOR_110_C(BOOST_PP_BOOL(p##(111, s)), s, p, o, m) # define BOOST_PP_FOR_111(s, p, o, m) BOOST_PP_FOR_111_C(BOOST_PP_BOOL(p##(112, s)), s, p, o, m) # define BOOST_PP_FOR_112(s, p, o, m) BOOST_PP_FOR_112_C(BOOST_PP_BOOL(p##(113, s)), s, p, o, m) # define BOOST_PP_FOR_113(s, p, o, m) BOOST_PP_FOR_113_C(BOOST_PP_BOOL(p##(114, s)), s, p, o, m) # define BOOST_PP_FOR_114(s, p, o, m) BOOST_PP_FOR_114_C(BOOST_PP_BOOL(p##(115, s)), s, p, o, m) # define BOOST_PP_FOR_115(s, p, o, m) BOOST_PP_FOR_115_C(BOOST_PP_BOOL(p##(116, s)), s, p, o, m) # define BOOST_PP_FOR_116(s, p, o, m) BOOST_PP_FOR_116_C(BOOST_PP_BOOL(p##(117, s)), s, p, o, m) # define BOOST_PP_FOR_117(s, p, o, m) BOOST_PP_FOR_117_C(BOOST_PP_BOOL(p##(118, s)), s, p, o, m) # define BOOST_PP_FOR_118(s, p, o, m) BOOST_PP_FOR_118_C(BOOST_PP_BOOL(p##(119, s)), s, p, o, m) # define BOOST_PP_FOR_119(s, p, o, m) BOOST_PP_FOR_119_C(BOOST_PP_BOOL(p##(120, s)), s, p, o, m) # define BOOST_PP_FOR_120(s, p, o, m) BOOST_PP_FOR_120_C(BOOST_PP_BOOL(p##(121, s)), s, p, o, m) # define BOOST_PP_FOR_121(s, p, o, m) BOOST_PP_FOR_121_C(BOOST_PP_BOOL(p##(122, s)), s, p, o, m) # define BOOST_PP_FOR_122(s, p, o, m) BOOST_PP_FOR_122_C(BOOST_PP_BOOL(p##(123, s)), s, p, o, m) # define BOOST_PP_FOR_123(s, p, o, m) BOOST_PP_FOR_123_C(BOOST_PP_BOOL(p##(124, s)), s, p, o, m) # define BOOST_PP_FOR_124(s, p, o, m) BOOST_PP_FOR_124_C(BOOST_PP_BOOL(p##(125, s)), s, p, o, m) # define BOOST_PP_FOR_125(s, p, o, m) BOOST_PP_FOR_125_C(BOOST_PP_BOOL(p##(126, s)), s, p, o, m) # define BOOST_PP_FOR_126(s, p, o, m) BOOST_PP_FOR_126_C(BOOST_PP_BOOL(p##(127, s)), s, p, o, m) # define BOOST_PP_FOR_127(s, p, o, m) BOOST_PP_FOR_127_C(BOOST_PP_BOOL(p##(128, s)), s, p, o, m) # define BOOST_PP_FOR_128(s, p, o, m) BOOST_PP_FOR_128_C(BOOST_PP_BOOL(p##(129, s)), s, p, o, m) # define BOOST_PP_FOR_129(s, p, o, m) BOOST_PP_FOR_129_C(BOOST_PP_BOOL(p##(130, s)), s, p, o, m) # define BOOST_PP_FOR_130(s, p, o, m) BOOST_PP_FOR_130_C(BOOST_PP_BOOL(p##(131, s)), s, p, o, m) # define BOOST_PP_FOR_131(s, p, o, m) BOOST_PP_FOR_131_C(BOOST_PP_BOOL(p##(132, s)), s, p, o, m) # define BOOST_PP_FOR_132(s, p, o, m) BOOST_PP_FOR_132_C(BOOST_PP_BOOL(p##(133, s)), s, p, o, m) # define BOOST_PP_FOR_133(s, p, o, m) BOOST_PP_FOR_133_C(BOOST_PP_BOOL(p##(134, s)), s, p, o, m) # define BOOST_PP_FOR_134(s, p, o, m) BOOST_PP_FOR_134_C(BOOST_PP_BOOL(p##(135, s)), s, p, o, m) # define BOOST_PP_FOR_135(s, p, o, m) BOOST_PP_FOR_135_C(BOOST_PP_BOOL(p##(136, s)), s, p, o, m) # define BOOST_PP_FOR_136(s, p, o, m) BOOST_PP_FOR_136_C(BOOST_PP_BOOL(p##(137, s)), s, p, o, m) # define BOOST_PP_FOR_137(s, p, o, m) BOOST_PP_FOR_137_C(BOOST_PP_BOOL(p##(138, s)), s, p, o, m) # define BOOST_PP_FOR_138(s, p, o, m) BOOST_PP_FOR_138_C(BOOST_PP_BOOL(p##(139, s)), s, p, o, m) # define BOOST_PP_FOR_139(s, p, o, m) BOOST_PP_FOR_139_C(BOOST_PP_BOOL(p##(140, s)), s, p, o, m) # define BOOST_PP_FOR_140(s, p, o, m) BOOST_PP_FOR_140_C(BOOST_PP_BOOL(p##(141, s)), s, p, o, m) # define BOOST_PP_FOR_141(s, p, o, m) BOOST_PP_FOR_141_C(BOOST_PP_BOOL(p##(142, s)), s, p, o, m) # define BOOST_PP_FOR_142(s, p, o, m) BOOST_PP_FOR_142_C(BOOST_PP_BOOL(p##(143, s)), s, p, o, m) # define BOOST_PP_FOR_143(s, p, o, m) BOOST_PP_FOR_143_C(BOOST_PP_BOOL(p##(144, s)), s, p, o, m) # define BOOST_PP_FOR_144(s, p, o, m) BOOST_PP_FOR_144_C(BOOST_PP_BOOL(p##(145, s)), s, p, o, m) # define BOOST_PP_FOR_145(s, p, o, m) BOOST_PP_FOR_145_C(BOOST_PP_BOOL(p##(146, s)), s, p, o, m) # define BOOST_PP_FOR_146(s, p, o, m) BOOST_PP_FOR_146_C(BOOST_PP_BOOL(p##(147, s)), s, p, o, m) # define BOOST_PP_FOR_147(s, p, o, m) BOOST_PP_FOR_147_C(BOOST_PP_BOOL(p##(148, s)), s, p, o, m) # define BOOST_PP_FOR_148(s, p, o, m) BOOST_PP_FOR_148_C(BOOST_PP_BOOL(p##(149, s)), s, p, o, m) # define BOOST_PP_FOR_149(s, p, o, m) BOOST_PP_FOR_149_C(BOOST_PP_BOOL(p##(150, s)), s, p, o, m) # define BOOST_PP_FOR_150(s, p, o, m) BOOST_PP_FOR_150_C(BOOST_PP_BOOL(p##(151, s)), s, p, o, m) # define BOOST_PP_FOR_151(s, p, o, m) BOOST_PP_FOR_151_C(BOOST_PP_BOOL(p##(152, s)), s, p, o, m) # define BOOST_PP_FOR_152(s, p, o, m) BOOST_PP_FOR_152_C(BOOST_PP_BOOL(p##(153, s)), s, p, o, m) # define BOOST_PP_FOR_153(s, p, o, m) BOOST_PP_FOR_153_C(BOOST_PP_BOOL(p##(154, s)), s, p, o, m) # define BOOST_PP_FOR_154(s, p, o, m) BOOST_PP_FOR_154_C(BOOST_PP_BOOL(p##(155, s)), s, p, o, m) # define BOOST_PP_FOR_155(s, p, o, m) BOOST_PP_FOR_155_C(BOOST_PP_BOOL(p##(156, s)), s, p, o, m) # define BOOST_PP_FOR_156(s, p, o, m) BOOST_PP_FOR_156_C(BOOST_PP_BOOL(p##(157, s)), s, p, o, m) # define BOOST_PP_FOR_157(s, p, o, m) BOOST_PP_FOR_157_C(BOOST_PP_BOOL(p##(158, s)), s, p, o, m) # define BOOST_PP_FOR_158(s, p, o, m) BOOST_PP_FOR_158_C(BOOST_PP_BOOL(p##(159, s)), s, p, o, m) # define BOOST_PP_FOR_159(s, p, o, m) BOOST_PP_FOR_159_C(BOOST_PP_BOOL(p##(160, s)), s, p, o, m) # define BOOST_PP_FOR_160(s, p, o, m) BOOST_PP_FOR_160_C(BOOST_PP_BOOL(p##(161, s)), s, p, o, m) # define BOOST_PP_FOR_161(s, p, o, m) BOOST_PP_FOR_161_C(BOOST_PP_BOOL(p##(162, s)), s, p, o, m) # define BOOST_PP_FOR_162(s, p, o, m) BOOST_PP_FOR_162_C(BOOST_PP_BOOL(p##(163, s)), s, p, o, m) # define BOOST_PP_FOR_163(s, p, o, m) BOOST_PP_FOR_163_C(BOOST_PP_BOOL(p##(164, s)), s, p, o, m) # define BOOST_PP_FOR_164(s, p, o, m) BOOST_PP_FOR_164_C(BOOST_PP_BOOL(p##(165, s)), s, p, o, m) # define BOOST_PP_FOR_165(s, p, o, m) BOOST_PP_FOR_165_C(BOOST_PP_BOOL(p##(166, s)), s, p, o, m) # define BOOST_PP_FOR_166(s, p, o, m) BOOST_PP_FOR_166_C(BOOST_PP_BOOL(p##(167, s)), s, p, o, m) # define BOOST_PP_FOR_167(s, p, o, m) BOOST_PP_FOR_167_C(BOOST_PP_BOOL(p##(168, s)), s, p, o, m) # define BOOST_PP_FOR_168(s, p, o, m) BOOST_PP_FOR_168_C(BOOST_PP_BOOL(p##(169, s)), s, p, o, m) # define BOOST_PP_FOR_169(s, p, o, m) BOOST_PP_FOR_169_C(BOOST_PP_BOOL(p##(170, s)), s, p, o, m) # define BOOST_PP_FOR_170(s, p, o, m) BOOST_PP_FOR_170_C(BOOST_PP_BOOL(p##(171, s)), s, p, o, m) # define BOOST_PP_FOR_171(s, p, o, m) BOOST_PP_FOR_171_C(BOOST_PP_BOOL(p##(172, s)), s, p, o, m) # define BOOST_PP_FOR_172(s, p, o, m) BOOST_PP_FOR_172_C(BOOST_PP_BOOL(p##(173, s)), s, p, o, m) # define BOOST_PP_FOR_173(s, p, o, m) BOOST_PP_FOR_173_C(BOOST_PP_BOOL(p##(174, s)), s, p, o, m) # define BOOST_PP_FOR_174(s, p, o, m) BOOST_PP_FOR_174_C(BOOST_PP_BOOL(p##(175, s)), s, p, o, m) # define BOOST_PP_FOR_175(s, p, o, m) BOOST_PP_FOR_175_C(BOOST_PP_BOOL(p##(176, s)), s, p, o, m) # define BOOST_PP_FOR_176(s, p, o, m) BOOST_PP_FOR_176_C(BOOST_PP_BOOL(p##(177, s)), s, p, o, m) # define BOOST_PP_FOR_177(s, p, o, m) BOOST_PP_FOR_177_C(BOOST_PP_BOOL(p##(178, s)), s, p, o, m) # define BOOST_PP_FOR_178(s, p, o, m) BOOST_PP_FOR_178_C(BOOST_PP_BOOL(p##(179, s)), s, p, o, m) # define BOOST_PP_FOR_179(s, p, o, m) BOOST_PP_FOR_179_C(BOOST_PP_BOOL(p##(180, s)), s, p, o, m) # define BOOST_PP_FOR_180(s, p, o, m) BOOST_PP_FOR_180_C(BOOST_PP_BOOL(p##(181, s)), s, p, o, m) # define BOOST_PP_FOR_181(s, p, o, m) BOOST_PP_FOR_181_C(BOOST_PP_BOOL(p##(182, s)), s, p, o, m) # define BOOST_PP_FOR_182(s, p, o, m) BOOST_PP_FOR_182_C(BOOST_PP_BOOL(p##(183, s)), s, p, o, m) # define BOOST_PP_FOR_183(s, p, o, m) BOOST_PP_FOR_183_C(BOOST_PP_BOOL(p##(184, s)), s, p, o, m) # define BOOST_PP_FOR_184(s, p, o, m) BOOST_PP_FOR_184_C(BOOST_PP_BOOL(p##(185, s)), s, p, o, m) # define BOOST_PP_FOR_185(s, p, o, m) BOOST_PP_FOR_185_C(BOOST_PP_BOOL(p##(186, s)), s, p, o, m) # define BOOST_PP_FOR_186(s, p, o, m) BOOST_PP_FOR_186_C(BOOST_PP_BOOL(p##(187, s)), s, p, o, m) # define BOOST_PP_FOR_187(s, p, o, m) BOOST_PP_FOR_187_C(BOOST_PP_BOOL(p##(188, s)), s, p, o, m) # define BOOST_PP_FOR_188(s, p, o, m) BOOST_PP_FOR_188_C(BOOST_PP_BOOL(p##(189, s)), s, p, o, m) # define BOOST_PP_FOR_189(s, p, o, m) BOOST_PP_FOR_189_C(BOOST_PP_BOOL(p##(190, s)), s, p, o, m) # define BOOST_PP_FOR_190(s, p, o, m) BOOST_PP_FOR_190_C(BOOST_PP_BOOL(p##(191, s)), s, p, o, m) # define BOOST_PP_FOR_191(s, p, o, m) BOOST_PP_FOR_191_C(BOOST_PP_BOOL(p##(192, s)), s, p, o, m) # define BOOST_PP_FOR_192(s, p, o, m) BOOST_PP_FOR_192_C(BOOST_PP_BOOL(p##(193, s)), s, p, o, m) # define BOOST_PP_FOR_193(s, p, o, m) BOOST_PP_FOR_193_C(BOOST_PP_BOOL(p##(194, s)), s, p, o, m) # define BOOST_PP_FOR_194(s, p, o, m) BOOST_PP_FOR_194_C(BOOST_PP_BOOL(p##(195, s)), s, p, o, m) # define BOOST_PP_FOR_195(s, p, o, m) BOOST_PP_FOR_195_C(BOOST_PP_BOOL(p##(196, s)), s, p, o, m) # define BOOST_PP_FOR_196(s, p, o, m) BOOST_PP_FOR_196_C(BOOST_PP_BOOL(p##(197, s)), s, p, o, m) # define BOOST_PP_FOR_197(s, p, o, m) BOOST_PP_FOR_197_C(BOOST_PP_BOOL(p##(198, s)), s, p, o, m) # define BOOST_PP_FOR_198(s, p, o, m) BOOST_PP_FOR_198_C(BOOST_PP_BOOL(p##(199, s)), s, p, o, m) # define BOOST_PP_FOR_199(s, p, o, m) BOOST_PP_FOR_199_C(BOOST_PP_BOOL(p##(200, s)), s, p, o, m) # define BOOST_PP_FOR_200(s, p, o, m) BOOST_PP_FOR_200_C(BOOST_PP_BOOL(p##(201, s)), s, p, o, m) # define BOOST_PP_FOR_201(s, p, o, m) BOOST_PP_FOR_201_C(BOOST_PP_BOOL(p##(202, s)), s, p, o, m) # define BOOST_PP_FOR_202(s, p, o, m) BOOST_PP_FOR_202_C(BOOST_PP_BOOL(p##(203, s)), s, p, o, m) # define BOOST_PP_FOR_203(s, p, o, m) BOOST_PP_FOR_203_C(BOOST_PP_BOOL(p##(204, s)), s, p, o, m) # define BOOST_PP_FOR_204(s, p, o, m) BOOST_PP_FOR_204_C(BOOST_PP_BOOL(p##(205, s)), s, p, o, m) # define BOOST_PP_FOR_205(s, p, o, m) BOOST_PP_FOR_205_C(BOOST_PP_BOOL(p##(206, s)), s, p, o, m) # define BOOST_PP_FOR_206(s, p, o, m) BOOST_PP_FOR_206_C(BOOST_PP_BOOL(p##(207, s)), s, p, o, m) # define BOOST_PP_FOR_207(s, p, o, m) BOOST_PP_FOR_207_C(BOOST_PP_BOOL(p##(208, s)), s, p, o, m) # define BOOST_PP_FOR_208(s, p, o, m) BOOST_PP_FOR_208_C(BOOST_PP_BOOL(p##(209, s)), s, p, o, m) # define BOOST_PP_FOR_209(s, p, o, m) BOOST_PP_FOR_209_C(BOOST_PP_BOOL(p##(210, s)), s, p, o, m) # define BOOST_PP_FOR_210(s, p, o, m) BOOST_PP_FOR_210_C(BOOST_PP_BOOL(p##(211, s)), s, p, o, m) # define BOOST_PP_FOR_211(s, p, o, m) BOOST_PP_FOR_211_C(BOOST_PP_BOOL(p##(212, s)), s, p, o, m) # define BOOST_PP_FOR_212(s, p, o, m) BOOST_PP_FOR_212_C(BOOST_PP_BOOL(p##(213, s)), s, p, o, m) # define BOOST_PP_FOR_213(s, p, o, m) BOOST_PP_FOR_213_C(BOOST_PP_BOOL(p##(214, s)), s, p, o, m) # define BOOST_PP_FOR_214(s, p, o, m) BOOST_PP_FOR_214_C(BOOST_PP_BOOL(p##(215, s)), s, p, o, m) # define BOOST_PP_FOR_215(s, p, o, m) BOOST_PP_FOR_215_C(BOOST_PP_BOOL(p##(216, s)), s, p, o, m) # define BOOST_PP_FOR_216(s, p, o, m) BOOST_PP_FOR_216_C(BOOST_PP_BOOL(p##(217, s)), s, p, o, m) # define BOOST_PP_FOR_217(s, p, o, m) BOOST_PP_FOR_217_C(BOOST_PP_BOOL(p##(218, s)), s, p, o, m) # define BOOST_PP_FOR_218(s, p, o, m) BOOST_PP_FOR_218_C(BOOST_PP_BOOL(p##(219, s)), s, p, o, m) # define BOOST_PP_FOR_219(s, p, o, m) BOOST_PP_FOR_219_C(BOOST_PP_BOOL(p##(220, s)), s, p, o, m) # define BOOST_PP_FOR_220(s, p, o, m) BOOST_PP_FOR_220_C(BOOST_PP_BOOL(p##(221, s)), s, p, o, m) # define BOOST_PP_FOR_221(s, p, o, m) BOOST_PP_FOR_221_C(BOOST_PP_BOOL(p##(222, s)), s, p, o, m) # define BOOST_PP_FOR_222(s, p, o, m) BOOST_PP_FOR_222_C(BOOST_PP_BOOL(p##(223, s)), s, p, o, m) # define BOOST_PP_FOR_223(s, p, o, m) BOOST_PP_FOR_223_C(BOOST_PP_BOOL(p##(224, s)), s, p, o, m) # define BOOST_PP_FOR_224(s, p, o, m) BOOST_PP_FOR_224_C(BOOST_PP_BOOL(p##(225, s)), s, p, o, m) # define BOOST_PP_FOR_225(s, p, o, m) BOOST_PP_FOR_225_C(BOOST_PP_BOOL(p##(226, s)), s, p, o, m) # define BOOST_PP_FOR_226(s, p, o, m) BOOST_PP_FOR_226_C(BOOST_PP_BOOL(p##(227, s)), s, p, o, m) # define BOOST_PP_FOR_227(s, p, o, m) BOOST_PP_FOR_227_C(BOOST_PP_BOOL(p##(228, s)), s, p, o, m) # define BOOST_PP_FOR_228(s, p, o, m) BOOST_PP_FOR_228_C(BOOST_PP_BOOL(p##(229, s)), s, p, o, m) # define BOOST_PP_FOR_229(s, p, o, m) BOOST_PP_FOR_229_C(BOOST_PP_BOOL(p##(230, s)), s, p, o, m) # define BOOST_PP_FOR_230(s, p, o, m) BOOST_PP_FOR_230_C(BOOST_PP_BOOL(p##(231, s)), s, p, o, m) # define BOOST_PP_FOR_231(s, p, o, m) BOOST_PP_FOR_231_C(BOOST_PP_BOOL(p##(232, s)), s, p, o, m) # define BOOST_PP_FOR_232(s, p, o, m) BOOST_PP_FOR_232_C(BOOST_PP_BOOL(p##(233, s)), s, p, o, m) # define BOOST_PP_FOR_233(s, p, o, m) BOOST_PP_FOR_233_C(BOOST_PP_BOOL(p##(234, s)), s, p, o, m) # define BOOST_PP_FOR_234(s, p, o, m) BOOST_PP_FOR_234_C(BOOST_PP_BOOL(p##(235, s)), s, p, o, m) # define BOOST_PP_FOR_235(s, p, o, m) BOOST_PP_FOR_235_C(BOOST_PP_BOOL(p##(236, s)), s, p, o, m) # define BOOST_PP_FOR_236(s, p, o, m) BOOST_PP_FOR_236_C(BOOST_PP_BOOL(p##(237, s)), s, p, o, m) # define BOOST_PP_FOR_237(s, p, o, m) BOOST_PP_FOR_237_C(BOOST_PP_BOOL(p##(238, s)), s, p, o, m) # define BOOST_PP_FOR_238(s, p, o, m) BOOST_PP_FOR_238_C(BOOST_PP_BOOL(p##(239, s)), s, p, o, m) # define BOOST_PP_FOR_239(s, p, o, m) BOOST_PP_FOR_239_C(BOOST_PP_BOOL(p##(240, s)), s, p, o, m) # define BOOST_PP_FOR_240(s, p, o, m) BOOST_PP_FOR_240_C(BOOST_PP_BOOL(p##(241, s)), s, p, o, m) # define BOOST_PP_FOR_241(s, p, o, m) BOOST_PP_FOR_241_C(BOOST_PP_BOOL(p##(242, s)), s, p, o, m) # define BOOST_PP_FOR_242(s, p, o, m) BOOST_PP_FOR_242_C(BOOST_PP_BOOL(p##(243, s)), s, p, o, m) # define BOOST_PP_FOR_243(s, p, o, m) BOOST_PP_FOR_243_C(BOOST_PP_BOOL(p##(244, s)), s, p, o, m) # define BOOST_PP_FOR_244(s, p, o, m) BOOST_PP_FOR_244_C(BOOST_PP_BOOL(p##(245, s)), s, p, o, m) # define BOOST_PP_FOR_245(s, p, o, m) BOOST_PP_FOR_245_C(BOOST_PP_BOOL(p##(246, s)), s, p, o, m) # define BOOST_PP_FOR_246(s, p, o, m) BOOST_PP_FOR_246_C(BOOST_PP_BOOL(p##(247, s)), s, p, o, m) # define BOOST_PP_FOR_247(s, p, o, m) BOOST_PP_FOR_247_C(BOOST_PP_BOOL(p##(248, s)), s, p, o, m) # define BOOST_PP_FOR_248(s, p, o, m) BOOST_PP_FOR_248_C(BOOST_PP_BOOL(p##(249, s)), s, p, o, m) # define BOOST_PP_FOR_249(s, p, o, m) BOOST_PP_FOR_249_C(BOOST_PP_BOOL(p##(250, s)), s, p, o, m) # define BOOST_PP_FOR_250(s, p, o, m) BOOST_PP_FOR_250_C(BOOST_PP_BOOL(p##(251, s)), s, p, o, m) # define BOOST_PP_FOR_251(s, p, o, m) BOOST_PP_FOR_251_C(BOOST_PP_BOOL(p##(252, s)), s, p, o, m) # define BOOST_PP_FOR_252(s, p, o, m) BOOST_PP_FOR_252_C(BOOST_PP_BOOL(p##(253, s)), s, p, o, m) # define BOOST_PP_FOR_253(s, p, o, m) BOOST_PP_FOR_253_C(BOOST_PP_BOOL(p##(254, s)), s, p, o, m) # define BOOST_PP_FOR_254(s, p, o, m) BOOST_PP_FOR_254_C(BOOST_PP_BOOL(p##(255, s)), s, p, o, m) # define BOOST_PP_FOR_255(s, p, o, m) BOOST_PP_FOR_255_C(BOOST_PP_BOOL(p##(256, s)), s, p, o, m) # define BOOST_PP_FOR_256(s, p, o, m) BOOST_PP_FOR_256_C(BOOST_PP_BOOL(p##(257, s)), s, p, o, m) # # define BOOST_PP_FOR_1_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(2, s) BOOST_PP_IIF(c, BOOST_PP_FOR_2, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(2, s), p, o, m) # define BOOST_PP_FOR_2_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(3, s) BOOST_PP_IIF(c, BOOST_PP_FOR_3, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(3, s), p, o, m) # define BOOST_PP_FOR_3_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(4, s) BOOST_PP_IIF(c, BOOST_PP_FOR_4, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(4, s), p, o, m) # define BOOST_PP_FOR_4_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(5, s) BOOST_PP_IIF(c, BOOST_PP_FOR_5, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(5, s), p, o, m) # define BOOST_PP_FOR_5_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(6, s) BOOST_PP_IIF(c, BOOST_PP_FOR_6, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(6, s), p, o, m) # define BOOST_PP_FOR_6_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(7, s) BOOST_PP_IIF(c, BOOST_PP_FOR_7, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(7, s), p, o, m) # define BOOST_PP_FOR_7_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(8, s) BOOST_PP_IIF(c, BOOST_PP_FOR_8, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(8, s), p, o, m) # define BOOST_PP_FOR_8_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(9, s) BOOST_PP_IIF(c, BOOST_PP_FOR_9, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(9, s), p, o, m) # define BOOST_PP_FOR_9_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(10, s) BOOST_PP_IIF(c, BOOST_PP_FOR_10, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(10, s), p, o, m) # define BOOST_PP_FOR_10_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(11, s) BOOST_PP_IIF(c, BOOST_PP_FOR_11, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(11, s), p, o, m) # define BOOST_PP_FOR_11_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(12, s) BOOST_PP_IIF(c, BOOST_PP_FOR_12, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(12, s), p, o, m) # define BOOST_PP_FOR_12_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(13, s) BOOST_PP_IIF(c, BOOST_PP_FOR_13, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(13, s), p, o, m) # define BOOST_PP_FOR_13_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(14, s) BOOST_PP_IIF(c, BOOST_PP_FOR_14, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(14, s), p, o, m) # define BOOST_PP_FOR_14_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(15, s) BOOST_PP_IIF(c, BOOST_PP_FOR_15, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(15, s), p, o, m) # define BOOST_PP_FOR_15_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(16, s) BOOST_PP_IIF(c, BOOST_PP_FOR_16, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(16, s), p, o, m) # define BOOST_PP_FOR_16_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(17, s) BOOST_PP_IIF(c, BOOST_PP_FOR_17, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(17, s), p, o, m) # define BOOST_PP_FOR_17_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(18, s) BOOST_PP_IIF(c, BOOST_PP_FOR_18, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(18, s), p, o, m) # define BOOST_PP_FOR_18_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(19, s) BOOST_PP_IIF(c, BOOST_PP_FOR_19, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(19, s), p, o, m) # define BOOST_PP_FOR_19_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(20, s) BOOST_PP_IIF(c, BOOST_PP_FOR_20, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(20, s), p, o, m) # define BOOST_PP_FOR_20_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(21, s) BOOST_PP_IIF(c, BOOST_PP_FOR_21, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(21, s), p, o, m) # define BOOST_PP_FOR_21_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(22, s) BOOST_PP_IIF(c, BOOST_PP_FOR_22, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(22, s), p, o, m) # define BOOST_PP_FOR_22_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(23, s) BOOST_PP_IIF(c, BOOST_PP_FOR_23, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(23, s), p, o, m) # define BOOST_PP_FOR_23_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(24, s) BOOST_PP_IIF(c, BOOST_PP_FOR_24, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(24, s), p, o, m) # define BOOST_PP_FOR_24_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(25, s) BOOST_PP_IIF(c, BOOST_PP_FOR_25, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(25, s), p, o, m) # define BOOST_PP_FOR_25_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(26, s) BOOST_PP_IIF(c, BOOST_PP_FOR_26, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(26, s), p, o, m) # define BOOST_PP_FOR_26_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(27, s) BOOST_PP_IIF(c, BOOST_PP_FOR_27, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(27, s), p, o, m) # define BOOST_PP_FOR_27_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(28, s) BOOST_PP_IIF(c, BOOST_PP_FOR_28, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(28, s), p, o, m) # define BOOST_PP_FOR_28_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(29, s) BOOST_PP_IIF(c, BOOST_PP_FOR_29, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(29, s), p, o, m) # define BOOST_PP_FOR_29_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(30, s) BOOST_PP_IIF(c, BOOST_PP_FOR_30, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(30, s), p, o, m) # define BOOST_PP_FOR_30_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(31, s) BOOST_PP_IIF(c, BOOST_PP_FOR_31, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(31, s), p, o, m) # define BOOST_PP_FOR_31_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(32, s) BOOST_PP_IIF(c, BOOST_PP_FOR_32, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(32, s), p, o, m) # define BOOST_PP_FOR_32_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(33, s) BOOST_PP_IIF(c, BOOST_PP_FOR_33, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(33, s), p, o, m) # define BOOST_PP_FOR_33_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(34, s) BOOST_PP_IIF(c, BOOST_PP_FOR_34, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(34, s), p, o, m) # define BOOST_PP_FOR_34_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(35, s) BOOST_PP_IIF(c, BOOST_PP_FOR_35, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(35, s), p, o, m) # define BOOST_PP_FOR_35_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(36, s) BOOST_PP_IIF(c, BOOST_PP_FOR_36, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(36, s), p, o, m) # define BOOST_PP_FOR_36_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(37, s) BOOST_PP_IIF(c, BOOST_PP_FOR_37, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(37, s), p, o, m) # define BOOST_PP_FOR_37_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(38, s) BOOST_PP_IIF(c, BOOST_PP_FOR_38, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(38, s), p, o, m) # define BOOST_PP_FOR_38_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(39, s) BOOST_PP_IIF(c, BOOST_PP_FOR_39, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(39, s), p, o, m) # define BOOST_PP_FOR_39_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(40, s) BOOST_PP_IIF(c, BOOST_PP_FOR_40, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(40, s), p, o, m) # define BOOST_PP_FOR_40_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(41, s) BOOST_PP_IIF(c, BOOST_PP_FOR_41, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(41, s), p, o, m) # define BOOST_PP_FOR_41_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(42, s) BOOST_PP_IIF(c, BOOST_PP_FOR_42, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(42, s), p, o, m) # define BOOST_PP_FOR_42_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(43, s) BOOST_PP_IIF(c, BOOST_PP_FOR_43, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(43, s), p, o, m) # define BOOST_PP_FOR_43_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(44, s) BOOST_PP_IIF(c, BOOST_PP_FOR_44, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(44, s), p, o, m) # define BOOST_PP_FOR_44_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(45, s) BOOST_PP_IIF(c, BOOST_PP_FOR_45, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(45, s), p, o, m) # define BOOST_PP_FOR_45_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(46, s) BOOST_PP_IIF(c, BOOST_PP_FOR_46, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(46, s), p, o, m) # define BOOST_PP_FOR_46_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(47, s) BOOST_PP_IIF(c, BOOST_PP_FOR_47, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(47, s), p, o, m) # define BOOST_PP_FOR_47_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(48, s) BOOST_PP_IIF(c, BOOST_PP_FOR_48, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(48, s), p, o, m) # define BOOST_PP_FOR_48_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(49, s) BOOST_PP_IIF(c, BOOST_PP_FOR_49, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(49, s), p, o, m) # define BOOST_PP_FOR_49_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(50, s) BOOST_PP_IIF(c, BOOST_PP_FOR_50, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(50, s), p, o, m) # define BOOST_PP_FOR_50_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(51, s) BOOST_PP_IIF(c, BOOST_PP_FOR_51, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(51, s), p, o, m) # define BOOST_PP_FOR_51_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(52, s) BOOST_PP_IIF(c, BOOST_PP_FOR_52, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(52, s), p, o, m) # define BOOST_PP_FOR_52_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(53, s) BOOST_PP_IIF(c, BOOST_PP_FOR_53, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(53, s), p, o, m) # define BOOST_PP_FOR_53_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(54, s) BOOST_PP_IIF(c, BOOST_PP_FOR_54, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(54, s), p, o, m) # define BOOST_PP_FOR_54_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(55, s) BOOST_PP_IIF(c, BOOST_PP_FOR_55, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(55, s), p, o, m) # define BOOST_PP_FOR_55_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(56, s) BOOST_PP_IIF(c, BOOST_PP_FOR_56, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(56, s), p, o, m) # define BOOST_PP_FOR_56_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(57, s) BOOST_PP_IIF(c, BOOST_PP_FOR_57, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(57, s), p, o, m) # define BOOST_PP_FOR_57_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(58, s) BOOST_PP_IIF(c, BOOST_PP_FOR_58, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(58, s), p, o, m) # define BOOST_PP_FOR_58_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(59, s) BOOST_PP_IIF(c, BOOST_PP_FOR_59, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(59, s), p, o, m) # define BOOST_PP_FOR_59_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(60, s) BOOST_PP_IIF(c, BOOST_PP_FOR_60, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(60, s), p, o, m) # define BOOST_PP_FOR_60_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(61, s) BOOST_PP_IIF(c, BOOST_PP_FOR_61, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(61, s), p, o, m) # define BOOST_PP_FOR_61_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(62, s) BOOST_PP_IIF(c, BOOST_PP_FOR_62, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(62, s), p, o, m) # define BOOST_PP_FOR_62_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(63, s) BOOST_PP_IIF(c, BOOST_PP_FOR_63, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(63, s), p, o, m) # define BOOST_PP_FOR_63_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(64, s) BOOST_PP_IIF(c, BOOST_PP_FOR_64, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(64, s), p, o, m) # define BOOST_PP_FOR_64_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(65, s) BOOST_PP_IIF(c, BOOST_PP_FOR_65, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(65, s), p, o, m) # define BOOST_PP_FOR_65_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(66, s) BOOST_PP_IIF(c, BOOST_PP_FOR_66, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(66, s), p, o, m) # define BOOST_PP_FOR_66_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(67, s) BOOST_PP_IIF(c, BOOST_PP_FOR_67, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(67, s), p, o, m) # define BOOST_PP_FOR_67_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(68, s) BOOST_PP_IIF(c, BOOST_PP_FOR_68, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(68, s), p, o, m) # define BOOST_PP_FOR_68_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(69, s) BOOST_PP_IIF(c, BOOST_PP_FOR_69, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(69, s), p, o, m) # define BOOST_PP_FOR_69_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(70, s) BOOST_PP_IIF(c, BOOST_PP_FOR_70, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(70, s), p, o, m) # define BOOST_PP_FOR_70_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(71, s) BOOST_PP_IIF(c, BOOST_PP_FOR_71, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(71, s), p, o, m) # define BOOST_PP_FOR_71_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(72, s) BOOST_PP_IIF(c, BOOST_PP_FOR_72, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(72, s), p, o, m) # define BOOST_PP_FOR_72_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(73, s) BOOST_PP_IIF(c, BOOST_PP_FOR_73, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(73, s), p, o, m) # define BOOST_PP_FOR_73_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(74, s) BOOST_PP_IIF(c, BOOST_PP_FOR_74, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(74, s), p, o, m) # define BOOST_PP_FOR_74_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(75, s) BOOST_PP_IIF(c, BOOST_PP_FOR_75, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(75, s), p, o, m) # define BOOST_PP_FOR_75_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(76, s) BOOST_PP_IIF(c, BOOST_PP_FOR_76, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(76, s), p, o, m) # define BOOST_PP_FOR_76_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(77, s) BOOST_PP_IIF(c, BOOST_PP_FOR_77, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(77, s), p, o, m) # define BOOST_PP_FOR_77_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(78, s) BOOST_PP_IIF(c, BOOST_PP_FOR_78, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(78, s), p, o, m) # define BOOST_PP_FOR_78_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(79, s) BOOST_PP_IIF(c, BOOST_PP_FOR_79, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(79, s), p, o, m) # define BOOST_PP_FOR_79_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(80, s) BOOST_PP_IIF(c, BOOST_PP_FOR_80, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(80, s), p, o, m) # define BOOST_PP_FOR_80_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(81, s) BOOST_PP_IIF(c, BOOST_PP_FOR_81, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(81, s), p, o, m) # define BOOST_PP_FOR_81_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(82, s) BOOST_PP_IIF(c, BOOST_PP_FOR_82, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(82, s), p, o, m) # define BOOST_PP_FOR_82_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(83, s) BOOST_PP_IIF(c, BOOST_PP_FOR_83, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(83, s), p, o, m) # define BOOST_PP_FOR_83_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(84, s) BOOST_PP_IIF(c, BOOST_PP_FOR_84, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(84, s), p, o, m) # define BOOST_PP_FOR_84_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(85, s) BOOST_PP_IIF(c, BOOST_PP_FOR_85, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(85, s), p, o, m) # define BOOST_PP_FOR_85_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(86, s) BOOST_PP_IIF(c, BOOST_PP_FOR_86, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(86, s), p, o, m) # define BOOST_PP_FOR_86_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(87, s) BOOST_PP_IIF(c, BOOST_PP_FOR_87, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(87, s), p, o, m) # define BOOST_PP_FOR_87_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(88, s) BOOST_PP_IIF(c, BOOST_PP_FOR_88, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(88, s), p, o, m) # define BOOST_PP_FOR_88_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(89, s) BOOST_PP_IIF(c, BOOST_PP_FOR_89, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(89, s), p, o, m) # define BOOST_PP_FOR_89_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(90, s) BOOST_PP_IIF(c, BOOST_PP_FOR_90, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(90, s), p, o, m) # define BOOST_PP_FOR_90_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(91, s) BOOST_PP_IIF(c, BOOST_PP_FOR_91, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(91, s), p, o, m) # define BOOST_PP_FOR_91_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(92, s) BOOST_PP_IIF(c, BOOST_PP_FOR_92, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(92, s), p, o, m) # define BOOST_PP_FOR_92_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(93, s) BOOST_PP_IIF(c, BOOST_PP_FOR_93, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(93, s), p, o, m) # define BOOST_PP_FOR_93_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(94, s) BOOST_PP_IIF(c, BOOST_PP_FOR_94, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(94, s), p, o, m) # define BOOST_PP_FOR_94_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(95, s) BOOST_PP_IIF(c, BOOST_PP_FOR_95, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(95, s), p, o, m) # define BOOST_PP_FOR_95_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(96, s) BOOST_PP_IIF(c, BOOST_PP_FOR_96, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(96, s), p, o, m) # define BOOST_PP_FOR_96_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(97, s) BOOST_PP_IIF(c, BOOST_PP_FOR_97, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(97, s), p, o, m) # define BOOST_PP_FOR_97_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(98, s) BOOST_PP_IIF(c, BOOST_PP_FOR_98, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(98, s), p, o, m) # define BOOST_PP_FOR_98_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(99, s) BOOST_PP_IIF(c, BOOST_PP_FOR_99, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(99, s), p, o, m) # define BOOST_PP_FOR_99_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(100, s) BOOST_PP_IIF(c, BOOST_PP_FOR_100, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(100, s), p, o, m) # define BOOST_PP_FOR_100_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(101, s) BOOST_PP_IIF(c, BOOST_PP_FOR_101, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(101, s), p, o, m) # define BOOST_PP_FOR_101_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(102, s) BOOST_PP_IIF(c, BOOST_PP_FOR_102, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(102, s), p, o, m) # define BOOST_PP_FOR_102_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(103, s) BOOST_PP_IIF(c, BOOST_PP_FOR_103, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(103, s), p, o, m) # define BOOST_PP_FOR_103_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(104, s) BOOST_PP_IIF(c, BOOST_PP_FOR_104, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(104, s), p, o, m) # define BOOST_PP_FOR_104_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(105, s) BOOST_PP_IIF(c, BOOST_PP_FOR_105, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(105, s), p, o, m) # define BOOST_PP_FOR_105_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(106, s) BOOST_PP_IIF(c, BOOST_PP_FOR_106, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(106, s), p, o, m) # define BOOST_PP_FOR_106_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(107, s) BOOST_PP_IIF(c, BOOST_PP_FOR_107, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(107, s), p, o, m) # define BOOST_PP_FOR_107_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(108, s) BOOST_PP_IIF(c, BOOST_PP_FOR_108, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(108, s), p, o, m) # define BOOST_PP_FOR_108_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(109, s) BOOST_PP_IIF(c, BOOST_PP_FOR_109, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(109, s), p, o, m) # define BOOST_PP_FOR_109_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(110, s) BOOST_PP_IIF(c, BOOST_PP_FOR_110, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(110, s), p, o, m) # define BOOST_PP_FOR_110_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(111, s) BOOST_PP_IIF(c, BOOST_PP_FOR_111, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(111, s), p, o, m) # define BOOST_PP_FOR_111_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(112, s) BOOST_PP_IIF(c, BOOST_PP_FOR_112, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(112, s), p, o, m) # define BOOST_PP_FOR_112_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(113, s) BOOST_PP_IIF(c, BOOST_PP_FOR_113, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(113, s), p, o, m) # define BOOST_PP_FOR_113_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(114, s) BOOST_PP_IIF(c, BOOST_PP_FOR_114, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(114, s), p, o, m) # define BOOST_PP_FOR_114_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(115, s) BOOST_PP_IIF(c, BOOST_PP_FOR_115, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(115, s), p, o, m) # define BOOST_PP_FOR_115_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(116, s) BOOST_PP_IIF(c, BOOST_PP_FOR_116, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(116, s), p, o, m) # define BOOST_PP_FOR_116_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(117, s) BOOST_PP_IIF(c, BOOST_PP_FOR_117, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(117, s), p, o, m) # define BOOST_PP_FOR_117_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(118, s) BOOST_PP_IIF(c, BOOST_PP_FOR_118, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(118, s), p, o, m) # define BOOST_PP_FOR_118_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(119, s) BOOST_PP_IIF(c, BOOST_PP_FOR_119, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(119, s), p, o, m) # define BOOST_PP_FOR_119_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(120, s) BOOST_PP_IIF(c, BOOST_PP_FOR_120, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(120, s), p, o, m) # define BOOST_PP_FOR_120_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(121, s) BOOST_PP_IIF(c, BOOST_PP_FOR_121, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(121, s), p, o, m) # define BOOST_PP_FOR_121_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(122, s) BOOST_PP_IIF(c, BOOST_PP_FOR_122, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(122, s), p, o, m) # define BOOST_PP_FOR_122_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(123, s) BOOST_PP_IIF(c, BOOST_PP_FOR_123, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(123, s), p, o, m) # define BOOST_PP_FOR_123_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(124, s) BOOST_PP_IIF(c, BOOST_PP_FOR_124, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(124, s), p, o, m) # define BOOST_PP_FOR_124_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(125, s) BOOST_PP_IIF(c, BOOST_PP_FOR_125, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(125, s), p, o, m) # define BOOST_PP_FOR_125_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(126, s) BOOST_PP_IIF(c, BOOST_PP_FOR_126, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(126, s), p, o, m) # define BOOST_PP_FOR_126_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(127, s) BOOST_PP_IIF(c, BOOST_PP_FOR_127, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(127, s), p, o, m) # define BOOST_PP_FOR_127_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(128, s) BOOST_PP_IIF(c, BOOST_PP_FOR_128, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(128, s), p, o, m) # define BOOST_PP_FOR_128_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(129, s) BOOST_PP_IIF(c, BOOST_PP_FOR_129, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(129, s), p, o, m) # define BOOST_PP_FOR_129_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(130, s) BOOST_PP_IIF(c, BOOST_PP_FOR_130, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(130, s), p, o, m) # define BOOST_PP_FOR_130_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(131, s) BOOST_PP_IIF(c, BOOST_PP_FOR_131, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(131, s), p, o, m) # define BOOST_PP_FOR_131_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(132, s) BOOST_PP_IIF(c, BOOST_PP_FOR_132, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(132, s), p, o, m) # define BOOST_PP_FOR_132_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(133, s) BOOST_PP_IIF(c, BOOST_PP_FOR_133, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(133, s), p, o, m) # define BOOST_PP_FOR_133_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(134, s) BOOST_PP_IIF(c, BOOST_PP_FOR_134, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(134, s), p, o, m) # define BOOST_PP_FOR_134_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(135, s) BOOST_PP_IIF(c, BOOST_PP_FOR_135, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(135, s), p, o, m) # define BOOST_PP_FOR_135_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(136, s) BOOST_PP_IIF(c, BOOST_PP_FOR_136, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(136, s), p, o, m) # define BOOST_PP_FOR_136_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(137, s) BOOST_PP_IIF(c, BOOST_PP_FOR_137, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(137, s), p, o, m) # define BOOST_PP_FOR_137_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(138, s) BOOST_PP_IIF(c, BOOST_PP_FOR_138, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(138, s), p, o, m) # define BOOST_PP_FOR_138_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(139, s) BOOST_PP_IIF(c, BOOST_PP_FOR_139, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(139, s), p, o, m) # define BOOST_PP_FOR_139_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(140, s) BOOST_PP_IIF(c, BOOST_PP_FOR_140, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(140, s), p, o, m) # define BOOST_PP_FOR_140_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(141, s) BOOST_PP_IIF(c, BOOST_PP_FOR_141, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(141, s), p, o, m) # define BOOST_PP_FOR_141_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(142, s) BOOST_PP_IIF(c, BOOST_PP_FOR_142, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(142, s), p, o, m) # define BOOST_PP_FOR_142_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(143, s) BOOST_PP_IIF(c, BOOST_PP_FOR_143, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(143, s), p, o, m) # define BOOST_PP_FOR_143_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(144, s) BOOST_PP_IIF(c, BOOST_PP_FOR_144, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(144, s), p, o, m) # define BOOST_PP_FOR_144_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(145, s) BOOST_PP_IIF(c, BOOST_PP_FOR_145, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(145, s), p, o, m) # define BOOST_PP_FOR_145_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(146, s) BOOST_PP_IIF(c, BOOST_PP_FOR_146, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(146, s), p, o, m) # define BOOST_PP_FOR_146_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(147, s) BOOST_PP_IIF(c, BOOST_PP_FOR_147, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(147, s), p, o, m) # define BOOST_PP_FOR_147_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(148, s) BOOST_PP_IIF(c, BOOST_PP_FOR_148, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(148, s), p, o, m) # define BOOST_PP_FOR_148_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(149, s) BOOST_PP_IIF(c, BOOST_PP_FOR_149, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(149, s), p, o, m) # define BOOST_PP_FOR_149_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(150, s) BOOST_PP_IIF(c, BOOST_PP_FOR_150, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(150, s), p, o, m) # define BOOST_PP_FOR_150_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(151, s) BOOST_PP_IIF(c, BOOST_PP_FOR_151, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(151, s), p, o, m) # define BOOST_PP_FOR_151_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(152, s) BOOST_PP_IIF(c, BOOST_PP_FOR_152, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(152, s), p, o, m) # define BOOST_PP_FOR_152_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(153, s) BOOST_PP_IIF(c, BOOST_PP_FOR_153, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(153, s), p, o, m) # define BOOST_PP_FOR_153_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(154, s) BOOST_PP_IIF(c, BOOST_PP_FOR_154, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(154, s), p, o, m) # define BOOST_PP_FOR_154_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(155, s) BOOST_PP_IIF(c, BOOST_PP_FOR_155, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(155, s), p, o, m) # define BOOST_PP_FOR_155_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(156, s) BOOST_PP_IIF(c, BOOST_PP_FOR_156, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(156, s), p, o, m) # define BOOST_PP_FOR_156_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(157, s) BOOST_PP_IIF(c, BOOST_PP_FOR_157, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(157, s), p, o, m) # define BOOST_PP_FOR_157_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(158, s) BOOST_PP_IIF(c, BOOST_PP_FOR_158, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(158, s), p, o, m) # define BOOST_PP_FOR_158_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(159, s) BOOST_PP_IIF(c, BOOST_PP_FOR_159, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(159, s), p, o, m) # define BOOST_PP_FOR_159_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(160, s) BOOST_PP_IIF(c, BOOST_PP_FOR_160, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(160, s), p, o, m) # define BOOST_PP_FOR_160_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(161, s) BOOST_PP_IIF(c, BOOST_PP_FOR_161, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(161, s), p, o, m) # define BOOST_PP_FOR_161_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(162, s) BOOST_PP_IIF(c, BOOST_PP_FOR_162, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(162, s), p, o, m) # define BOOST_PP_FOR_162_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(163, s) BOOST_PP_IIF(c, BOOST_PP_FOR_163, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(163, s), p, o, m) # define BOOST_PP_FOR_163_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(164, s) BOOST_PP_IIF(c, BOOST_PP_FOR_164, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(164, s), p, o, m) # define BOOST_PP_FOR_164_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(165, s) BOOST_PP_IIF(c, BOOST_PP_FOR_165, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(165, s), p, o, m) # define BOOST_PP_FOR_165_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(166, s) BOOST_PP_IIF(c, BOOST_PP_FOR_166, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(166, s), p, o, m) # define BOOST_PP_FOR_166_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(167, s) BOOST_PP_IIF(c, BOOST_PP_FOR_167, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(167, s), p, o, m) # define BOOST_PP_FOR_167_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(168, s) BOOST_PP_IIF(c, BOOST_PP_FOR_168, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(168, s), p, o, m) # define BOOST_PP_FOR_168_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(169, s) BOOST_PP_IIF(c, BOOST_PP_FOR_169, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(169, s), p, o, m) # define BOOST_PP_FOR_169_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(170, s) BOOST_PP_IIF(c, BOOST_PP_FOR_170, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(170, s), p, o, m) # define BOOST_PP_FOR_170_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(171, s) BOOST_PP_IIF(c, BOOST_PP_FOR_171, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(171, s), p, o, m) # define BOOST_PP_FOR_171_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(172, s) BOOST_PP_IIF(c, BOOST_PP_FOR_172, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(172, s), p, o, m) # define BOOST_PP_FOR_172_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(173, s) BOOST_PP_IIF(c, BOOST_PP_FOR_173, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(173, s), p, o, m) # define BOOST_PP_FOR_173_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(174, s) BOOST_PP_IIF(c, BOOST_PP_FOR_174, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(174, s), p, o, m) # define BOOST_PP_FOR_174_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(175, s) BOOST_PP_IIF(c, BOOST_PP_FOR_175, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(175, s), p, o, m) # define BOOST_PP_FOR_175_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(176, s) BOOST_PP_IIF(c, BOOST_PP_FOR_176, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(176, s), p, o, m) # define BOOST_PP_FOR_176_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(177, s) BOOST_PP_IIF(c, BOOST_PP_FOR_177, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(177, s), p, o, m) # define BOOST_PP_FOR_177_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(178, s) BOOST_PP_IIF(c, BOOST_PP_FOR_178, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(178, s), p, o, m) # define BOOST_PP_FOR_178_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(179, s) BOOST_PP_IIF(c, BOOST_PP_FOR_179, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(179, s), p, o, m) # define BOOST_PP_FOR_179_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(180, s) BOOST_PP_IIF(c, BOOST_PP_FOR_180, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(180, s), p, o, m) # define BOOST_PP_FOR_180_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(181, s) BOOST_PP_IIF(c, BOOST_PP_FOR_181, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(181, s), p, o, m) # define BOOST_PP_FOR_181_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(182, s) BOOST_PP_IIF(c, BOOST_PP_FOR_182, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(182, s), p, o, m) # define BOOST_PP_FOR_182_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(183, s) BOOST_PP_IIF(c, BOOST_PP_FOR_183, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(183, s), p, o, m) # define BOOST_PP_FOR_183_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(184, s) BOOST_PP_IIF(c, BOOST_PP_FOR_184, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(184, s), p, o, m) # define BOOST_PP_FOR_184_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(185, s) BOOST_PP_IIF(c, BOOST_PP_FOR_185, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(185, s), p, o, m) # define BOOST_PP_FOR_185_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(186, s) BOOST_PP_IIF(c, BOOST_PP_FOR_186, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(186, s), p, o, m) # define BOOST_PP_FOR_186_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(187, s) BOOST_PP_IIF(c, BOOST_PP_FOR_187, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(187, s), p, o, m) # define BOOST_PP_FOR_187_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(188, s) BOOST_PP_IIF(c, BOOST_PP_FOR_188, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(188, s), p, o, m) # define BOOST_PP_FOR_188_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(189, s) BOOST_PP_IIF(c, BOOST_PP_FOR_189, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(189, s), p, o, m) # define BOOST_PP_FOR_189_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(190, s) BOOST_PP_IIF(c, BOOST_PP_FOR_190, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(190, s), p, o, m) # define BOOST_PP_FOR_190_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(191, s) BOOST_PP_IIF(c, BOOST_PP_FOR_191, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(191, s), p, o, m) # define BOOST_PP_FOR_191_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(192, s) BOOST_PP_IIF(c, BOOST_PP_FOR_192, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(192, s), p, o, m) # define BOOST_PP_FOR_192_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(193, s) BOOST_PP_IIF(c, BOOST_PP_FOR_193, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(193, s), p, o, m) # define BOOST_PP_FOR_193_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(194, s) BOOST_PP_IIF(c, BOOST_PP_FOR_194, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(194, s), p, o, m) # define BOOST_PP_FOR_194_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(195, s) BOOST_PP_IIF(c, BOOST_PP_FOR_195, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(195, s), p, o, m) # define BOOST_PP_FOR_195_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(196, s) BOOST_PP_IIF(c, BOOST_PP_FOR_196, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(196, s), p, o, m) # define BOOST_PP_FOR_196_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(197, s) BOOST_PP_IIF(c, BOOST_PP_FOR_197, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(197, s), p, o, m) # define BOOST_PP_FOR_197_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(198, s) BOOST_PP_IIF(c, BOOST_PP_FOR_198, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(198, s), p, o, m) # define BOOST_PP_FOR_198_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(199, s) BOOST_PP_IIF(c, BOOST_PP_FOR_199, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(199, s), p, o, m) # define BOOST_PP_FOR_199_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(200, s) BOOST_PP_IIF(c, BOOST_PP_FOR_200, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(200, s), p, o, m) # define BOOST_PP_FOR_200_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(201, s) BOOST_PP_IIF(c, BOOST_PP_FOR_201, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(201, s), p, o, m) # define BOOST_PP_FOR_201_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(202, s) BOOST_PP_IIF(c, BOOST_PP_FOR_202, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(202, s), p, o, m) # define BOOST_PP_FOR_202_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(203, s) BOOST_PP_IIF(c, BOOST_PP_FOR_203, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(203, s), p, o, m) # define BOOST_PP_FOR_203_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(204, s) BOOST_PP_IIF(c, BOOST_PP_FOR_204, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(204, s), p, o, m) # define BOOST_PP_FOR_204_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(205, s) BOOST_PP_IIF(c, BOOST_PP_FOR_205, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(205, s), p, o, m) # define BOOST_PP_FOR_205_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(206, s) BOOST_PP_IIF(c, BOOST_PP_FOR_206, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(206, s), p, o, m) # define BOOST_PP_FOR_206_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(207, s) BOOST_PP_IIF(c, BOOST_PP_FOR_207, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(207, s), p, o, m) # define BOOST_PP_FOR_207_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(208, s) BOOST_PP_IIF(c, BOOST_PP_FOR_208, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(208, s), p, o, m) # define BOOST_PP_FOR_208_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(209, s) BOOST_PP_IIF(c, BOOST_PP_FOR_209, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(209, s), p, o, m) # define BOOST_PP_FOR_209_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(210, s) BOOST_PP_IIF(c, BOOST_PP_FOR_210, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(210, s), p, o, m) # define BOOST_PP_FOR_210_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(211, s) BOOST_PP_IIF(c, BOOST_PP_FOR_211, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(211, s), p, o, m) # define BOOST_PP_FOR_211_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(212, s) BOOST_PP_IIF(c, BOOST_PP_FOR_212, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(212, s), p, o, m) # define BOOST_PP_FOR_212_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(213, s) BOOST_PP_IIF(c, BOOST_PP_FOR_213, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(213, s), p, o, m) # define BOOST_PP_FOR_213_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(214, s) BOOST_PP_IIF(c, BOOST_PP_FOR_214, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(214, s), p, o, m) # define BOOST_PP_FOR_214_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(215, s) BOOST_PP_IIF(c, BOOST_PP_FOR_215, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(215, s), p, o, m) # define BOOST_PP_FOR_215_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(216, s) BOOST_PP_IIF(c, BOOST_PP_FOR_216, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(216, s), p, o, m) # define BOOST_PP_FOR_216_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(217, s) BOOST_PP_IIF(c, BOOST_PP_FOR_217, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(217, s), p, o, m) # define BOOST_PP_FOR_217_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(218, s) BOOST_PP_IIF(c, BOOST_PP_FOR_218, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(218, s), p, o, m) # define BOOST_PP_FOR_218_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(219, s) BOOST_PP_IIF(c, BOOST_PP_FOR_219, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(219, s), p, o, m) # define BOOST_PP_FOR_219_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(220, s) BOOST_PP_IIF(c, BOOST_PP_FOR_220, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(220, s), p, o, m) # define BOOST_PP_FOR_220_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(221, s) BOOST_PP_IIF(c, BOOST_PP_FOR_221, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(221, s), p, o, m) # define BOOST_PP_FOR_221_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(222, s) BOOST_PP_IIF(c, BOOST_PP_FOR_222, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(222, s), p, o, m) # define BOOST_PP_FOR_222_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(223, s) BOOST_PP_IIF(c, BOOST_PP_FOR_223, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(223, s), p, o, m) # define BOOST_PP_FOR_223_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(224, s) BOOST_PP_IIF(c, BOOST_PP_FOR_224, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(224, s), p, o, m) # define BOOST_PP_FOR_224_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(225, s) BOOST_PP_IIF(c, BOOST_PP_FOR_225, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(225, s), p, o, m) # define BOOST_PP_FOR_225_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(226, s) BOOST_PP_IIF(c, BOOST_PP_FOR_226, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(226, s), p, o, m) # define BOOST_PP_FOR_226_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(227, s) BOOST_PP_IIF(c, BOOST_PP_FOR_227, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(227, s), p, o, m) # define BOOST_PP_FOR_227_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(228, s) BOOST_PP_IIF(c, BOOST_PP_FOR_228, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(228, s), p, o, m) # define BOOST_PP_FOR_228_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(229, s) BOOST_PP_IIF(c, BOOST_PP_FOR_229, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(229, s), p, o, m) # define BOOST_PP_FOR_229_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(230, s) BOOST_PP_IIF(c, BOOST_PP_FOR_230, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(230, s), p, o, m) # define BOOST_PP_FOR_230_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(231, s) BOOST_PP_IIF(c, BOOST_PP_FOR_231, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(231, s), p, o, m) # define BOOST_PP_FOR_231_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(232, s) BOOST_PP_IIF(c, BOOST_PP_FOR_232, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(232, s), p, o, m) # define BOOST_PP_FOR_232_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(233, s) BOOST_PP_IIF(c, BOOST_PP_FOR_233, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(233, s), p, o, m) # define BOOST_PP_FOR_233_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(234, s) BOOST_PP_IIF(c, BOOST_PP_FOR_234, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(234, s), p, o, m) # define BOOST_PP_FOR_234_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(235, s) BOOST_PP_IIF(c, BOOST_PP_FOR_235, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(235, s), p, o, m) # define BOOST_PP_FOR_235_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(236, s) BOOST_PP_IIF(c, BOOST_PP_FOR_236, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(236, s), p, o, m) # define BOOST_PP_FOR_236_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(237, s) BOOST_PP_IIF(c, BOOST_PP_FOR_237, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(237, s), p, o, m) # define BOOST_PP_FOR_237_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(238, s) BOOST_PP_IIF(c, BOOST_PP_FOR_238, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(238, s), p, o, m) # define BOOST_PP_FOR_238_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(239, s) BOOST_PP_IIF(c, BOOST_PP_FOR_239, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(239, s), p, o, m) # define BOOST_PP_FOR_239_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(240, s) BOOST_PP_IIF(c, BOOST_PP_FOR_240, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(240, s), p, o, m) # define BOOST_PP_FOR_240_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(241, s) BOOST_PP_IIF(c, BOOST_PP_FOR_241, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(241, s), p, o, m) # define BOOST_PP_FOR_241_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(242, s) BOOST_PP_IIF(c, BOOST_PP_FOR_242, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(242, s), p, o, m) # define BOOST_PP_FOR_242_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(243, s) BOOST_PP_IIF(c, BOOST_PP_FOR_243, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(243, s), p, o, m) # define BOOST_PP_FOR_243_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(244, s) BOOST_PP_IIF(c, BOOST_PP_FOR_244, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(244, s), p, o, m) # define BOOST_PP_FOR_244_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(245, s) BOOST_PP_IIF(c, BOOST_PP_FOR_245, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(245, s), p, o, m) # define BOOST_PP_FOR_245_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(246, s) BOOST_PP_IIF(c, BOOST_PP_FOR_246, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(246, s), p, o, m) # define BOOST_PP_FOR_246_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(247, s) BOOST_PP_IIF(c, BOOST_PP_FOR_247, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(247, s), p, o, m) # define BOOST_PP_FOR_247_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(248, s) BOOST_PP_IIF(c, BOOST_PP_FOR_248, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(248, s), p, o, m) # define BOOST_PP_FOR_248_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(249, s) BOOST_PP_IIF(c, BOOST_PP_FOR_249, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(249, s), p, o, m) # define BOOST_PP_FOR_249_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(250, s) BOOST_PP_IIF(c, BOOST_PP_FOR_250, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(250, s), p, o, m) # define BOOST_PP_FOR_250_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(251, s) BOOST_PP_IIF(c, BOOST_PP_FOR_251, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(251, s), p, o, m) # define BOOST_PP_FOR_251_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(252, s) BOOST_PP_IIF(c, BOOST_PP_FOR_252, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(252, s), p, o, m) # define BOOST_PP_FOR_252_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(253, s) BOOST_PP_IIF(c, BOOST_PP_FOR_253, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(253, s), p, o, m) # define BOOST_PP_FOR_253_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(254, s) BOOST_PP_IIF(c, BOOST_PP_FOR_254, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(254, s), p, o, m) # define BOOST_PP_FOR_254_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(255, s) BOOST_PP_IIF(c, BOOST_PP_FOR_255, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(255, s), p, o, m) # define BOOST_PP_FOR_255_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(256, s) BOOST_PP_IIF(c, BOOST_PP_FOR_256, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(256, s), p, o, m) # define BOOST_PP_FOR_256_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(257, s) BOOST_PP_IIF(c, BOOST_PP_FOR_257, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(257, s), p, o, m) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/detail/edg/for.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_DETAIL_EDG_FOR_HPP # define BOOST_PREPROCESSOR_REPETITION_DETAIL_EDG_FOR_HPP # # include # include # # define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_FOR_1_I(s, p, o, m) # define BOOST_PP_FOR_2(s, p, o, m) BOOST_PP_FOR_2_I(s, p, o, m) # define BOOST_PP_FOR_3(s, p, o, m) BOOST_PP_FOR_3_I(s, p, o, m) # define BOOST_PP_FOR_4(s, p, o, m) BOOST_PP_FOR_4_I(s, p, o, m) # define BOOST_PP_FOR_5(s, p, o, m) BOOST_PP_FOR_5_I(s, p, o, m) # define BOOST_PP_FOR_6(s, p, o, m) BOOST_PP_FOR_6_I(s, p, o, m) # define BOOST_PP_FOR_7(s, p, o, m) BOOST_PP_FOR_7_I(s, p, o, m) # define BOOST_PP_FOR_8(s, p, o, m) BOOST_PP_FOR_8_I(s, p, o, m) # define BOOST_PP_FOR_9(s, p, o, m) BOOST_PP_FOR_9_I(s, p, o, m) # define BOOST_PP_FOR_10(s, p, o, m) BOOST_PP_FOR_10_I(s, p, o, m) # define BOOST_PP_FOR_11(s, p, o, m) BOOST_PP_FOR_11_I(s, p, o, m) # define BOOST_PP_FOR_12(s, p, o, m) BOOST_PP_FOR_12_I(s, p, o, m) # define BOOST_PP_FOR_13(s, p, o, m) BOOST_PP_FOR_13_I(s, p, o, m) # define BOOST_PP_FOR_14(s, p, o, m) BOOST_PP_FOR_14_I(s, p, o, m) # define BOOST_PP_FOR_15(s, p, o, m) BOOST_PP_FOR_15_I(s, p, o, m) # define BOOST_PP_FOR_16(s, p, o, m) BOOST_PP_FOR_16_I(s, p, o, m) # define BOOST_PP_FOR_17(s, p, o, m) BOOST_PP_FOR_17_I(s, p, o, m) # define BOOST_PP_FOR_18(s, p, o, m) BOOST_PP_FOR_18_I(s, p, o, m) # define BOOST_PP_FOR_19(s, p, o, m) BOOST_PP_FOR_19_I(s, p, o, m) # define BOOST_PP_FOR_20(s, p, o, m) BOOST_PP_FOR_20_I(s, p, o, m) # define BOOST_PP_FOR_21(s, p, o, m) BOOST_PP_FOR_21_I(s, p, o, m) # define BOOST_PP_FOR_22(s, p, o, m) BOOST_PP_FOR_22_I(s, p, o, m) # define BOOST_PP_FOR_23(s, p, o, m) BOOST_PP_FOR_23_I(s, p, o, m) # define BOOST_PP_FOR_24(s, p, o, m) BOOST_PP_FOR_24_I(s, p, o, m) # define BOOST_PP_FOR_25(s, p, o, m) BOOST_PP_FOR_25_I(s, p, o, m) # define BOOST_PP_FOR_26(s, p, o, m) BOOST_PP_FOR_26_I(s, p, o, m) # define BOOST_PP_FOR_27(s, p, o, m) BOOST_PP_FOR_27_I(s, p, o, m) # define BOOST_PP_FOR_28(s, p, o, m) BOOST_PP_FOR_28_I(s, p, o, m) # define BOOST_PP_FOR_29(s, p, o, m) BOOST_PP_FOR_29_I(s, p, o, m) # define BOOST_PP_FOR_30(s, p, o, m) BOOST_PP_FOR_30_I(s, p, o, m) # define BOOST_PP_FOR_31(s, p, o, m) BOOST_PP_FOR_31_I(s, p, o, m) # define BOOST_PP_FOR_32(s, p, o, m) BOOST_PP_FOR_32_I(s, p, o, m) # define BOOST_PP_FOR_33(s, p, o, m) BOOST_PP_FOR_33_I(s, p, o, m) # define BOOST_PP_FOR_34(s, p, o, m) BOOST_PP_FOR_34_I(s, p, o, m) # define BOOST_PP_FOR_35(s, p, o, m) BOOST_PP_FOR_35_I(s, p, o, m) # define BOOST_PP_FOR_36(s, p, o, m) BOOST_PP_FOR_36_I(s, p, o, m) # define BOOST_PP_FOR_37(s, p, o, m) BOOST_PP_FOR_37_I(s, p, o, m) # define BOOST_PP_FOR_38(s, p, o, m) BOOST_PP_FOR_38_I(s, p, o, m) # define BOOST_PP_FOR_39(s, p, o, m) BOOST_PP_FOR_39_I(s, p, o, m) # define BOOST_PP_FOR_40(s, p, o, m) BOOST_PP_FOR_40_I(s, p, o, m) # define BOOST_PP_FOR_41(s, p, o, m) BOOST_PP_FOR_41_I(s, p, o, m) # define BOOST_PP_FOR_42(s, p, o, m) BOOST_PP_FOR_42_I(s, p, o, m) # define BOOST_PP_FOR_43(s, p, o, m) BOOST_PP_FOR_43_I(s, p, o, m) # define BOOST_PP_FOR_44(s, p, o, m) BOOST_PP_FOR_44_I(s, p, o, m) # define BOOST_PP_FOR_45(s, p, o, m) BOOST_PP_FOR_45_I(s, p, o, m) # define BOOST_PP_FOR_46(s, p, o, m) BOOST_PP_FOR_46_I(s, p, o, m) # define BOOST_PP_FOR_47(s, p, o, m) BOOST_PP_FOR_47_I(s, p, o, m) # define BOOST_PP_FOR_48(s, p, o, m) BOOST_PP_FOR_48_I(s, p, o, m) # define BOOST_PP_FOR_49(s, p, o, m) BOOST_PP_FOR_49_I(s, p, o, m) # define BOOST_PP_FOR_50(s, p, o, m) BOOST_PP_FOR_50_I(s, p, o, m) # define BOOST_PP_FOR_51(s, p, o, m) BOOST_PP_FOR_51_I(s, p, o, m) # define BOOST_PP_FOR_52(s, p, o, m) BOOST_PP_FOR_52_I(s, p, o, m) # define BOOST_PP_FOR_53(s, p, o, m) BOOST_PP_FOR_53_I(s, p, o, m) # define BOOST_PP_FOR_54(s, p, o, m) BOOST_PP_FOR_54_I(s, p, o, m) # define BOOST_PP_FOR_55(s, p, o, m) BOOST_PP_FOR_55_I(s, p, o, m) # define BOOST_PP_FOR_56(s, p, o, m) BOOST_PP_FOR_56_I(s, p, o, m) # define BOOST_PP_FOR_57(s, p, o, m) BOOST_PP_FOR_57_I(s, p, o, m) # define BOOST_PP_FOR_58(s, p, o, m) BOOST_PP_FOR_58_I(s, p, o, m) # define BOOST_PP_FOR_59(s, p, o, m) BOOST_PP_FOR_59_I(s, p, o, m) # define BOOST_PP_FOR_60(s, p, o, m) BOOST_PP_FOR_60_I(s, p, o, m) # define BOOST_PP_FOR_61(s, p, o, m) BOOST_PP_FOR_61_I(s, p, o, m) # define BOOST_PP_FOR_62(s, p, o, m) BOOST_PP_FOR_62_I(s, p, o, m) # define BOOST_PP_FOR_63(s, p, o, m) BOOST_PP_FOR_63_I(s, p, o, m) # define BOOST_PP_FOR_64(s, p, o, m) BOOST_PP_FOR_64_I(s, p, o, m) # define BOOST_PP_FOR_65(s, p, o, m) BOOST_PP_FOR_65_I(s, p, o, m) # define BOOST_PP_FOR_66(s, p, o, m) BOOST_PP_FOR_66_I(s, p, o, m) # define BOOST_PP_FOR_67(s, p, o, m) BOOST_PP_FOR_67_I(s, p, o, m) # define BOOST_PP_FOR_68(s, p, o, m) BOOST_PP_FOR_68_I(s, p, o, m) # define BOOST_PP_FOR_69(s, p, o, m) BOOST_PP_FOR_69_I(s, p, o, m) # define BOOST_PP_FOR_70(s, p, o, m) BOOST_PP_FOR_70_I(s, p, o, m) # define BOOST_PP_FOR_71(s, p, o, m) BOOST_PP_FOR_71_I(s, p, o, m) # define BOOST_PP_FOR_72(s, p, o, m) BOOST_PP_FOR_72_I(s, p, o, m) # define BOOST_PP_FOR_73(s, p, o, m) BOOST_PP_FOR_73_I(s, p, o, m) # define BOOST_PP_FOR_74(s, p, o, m) BOOST_PP_FOR_74_I(s, p, o, m) # define BOOST_PP_FOR_75(s, p, o, m) BOOST_PP_FOR_75_I(s, p, o, m) # define BOOST_PP_FOR_76(s, p, o, m) BOOST_PP_FOR_76_I(s, p, o, m) # define BOOST_PP_FOR_77(s, p, o, m) BOOST_PP_FOR_77_I(s, p, o, m) # define BOOST_PP_FOR_78(s, p, o, m) BOOST_PP_FOR_78_I(s, p, o, m) # define BOOST_PP_FOR_79(s, p, o, m) BOOST_PP_FOR_79_I(s, p, o, m) # define BOOST_PP_FOR_80(s, p, o, m) BOOST_PP_FOR_80_I(s, p, o, m) # define BOOST_PP_FOR_81(s, p, o, m) BOOST_PP_FOR_81_I(s, p, o, m) # define BOOST_PP_FOR_82(s, p, o, m) BOOST_PP_FOR_82_I(s, p, o, m) # define BOOST_PP_FOR_83(s, p, o, m) BOOST_PP_FOR_83_I(s, p, o, m) # define BOOST_PP_FOR_84(s, p, o, m) BOOST_PP_FOR_84_I(s, p, o, m) # define BOOST_PP_FOR_85(s, p, o, m) BOOST_PP_FOR_85_I(s, p, o, m) # define BOOST_PP_FOR_86(s, p, o, m) BOOST_PP_FOR_86_I(s, p, o, m) # define BOOST_PP_FOR_87(s, p, o, m) BOOST_PP_FOR_87_I(s, p, o, m) # define BOOST_PP_FOR_88(s, p, o, m) BOOST_PP_FOR_88_I(s, p, o, m) # define BOOST_PP_FOR_89(s, p, o, m) BOOST_PP_FOR_89_I(s, p, o, m) # define BOOST_PP_FOR_90(s, p, o, m) BOOST_PP_FOR_90_I(s, p, o, m) # define BOOST_PP_FOR_91(s, p, o, m) BOOST_PP_FOR_91_I(s, p, o, m) # define BOOST_PP_FOR_92(s, p, o, m) BOOST_PP_FOR_92_I(s, p, o, m) # define BOOST_PP_FOR_93(s, p, o, m) BOOST_PP_FOR_93_I(s, p, o, m) # define BOOST_PP_FOR_94(s, p, o, m) BOOST_PP_FOR_94_I(s, p, o, m) # define BOOST_PP_FOR_95(s, p, o, m) BOOST_PP_FOR_95_I(s, p, o, m) # define BOOST_PP_FOR_96(s, p, o, m) BOOST_PP_FOR_96_I(s, p, o, m) # define BOOST_PP_FOR_97(s, p, o, m) BOOST_PP_FOR_97_I(s, p, o, m) # define BOOST_PP_FOR_98(s, p, o, m) BOOST_PP_FOR_98_I(s, p, o, m) # define BOOST_PP_FOR_99(s, p, o, m) BOOST_PP_FOR_99_I(s, p, o, m) # define BOOST_PP_FOR_100(s, p, o, m) BOOST_PP_FOR_100_I(s, p, o, m) # define BOOST_PP_FOR_101(s, p, o, m) BOOST_PP_FOR_101_I(s, p, o, m) # define BOOST_PP_FOR_102(s, p, o, m) BOOST_PP_FOR_102_I(s, p, o, m) # define BOOST_PP_FOR_103(s, p, o, m) BOOST_PP_FOR_103_I(s, p, o, m) # define BOOST_PP_FOR_104(s, p, o, m) BOOST_PP_FOR_104_I(s, p, o, m) # define BOOST_PP_FOR_105(s, p, o, m) BOOST_PP_FOR_105_I(s, p, o, m) # define BOOST_PP_FOR_106(s, p, o, m) BOOST_PP_FOR_106_I(s, p, o, m) # define BOOST_PP_FOR_107(s, p, o, m) BOOST_PP_FOR_107_I(s, p, o, m) # define BOOST_PP_FOR_108(s, p, o, m) BOOST_PP_FOR_108_I(s, p, o, m) # define BOOST_PP_FOR_109(s, p, o, m) BOOST_PP_FOR_109_I(s, p, o, m) # define BOOST_PP_FOR_110(s, p, o, m) BOOST_PP_FOR_110_I(s, p, o, m) # define BOOST_PP_FOR_111(s, p, o, m) BOOST_PP_FOR_111_I(s, p, o, m) # define BOOST_PP_FOR_112(s, p, o, m) BOOST_PP_FOR_112_I(s, p, o, m) # define BOOST_PP_FOR_113(s, p, o, m) BOOST_PP_FOR_113_I(s, p, o, m) # define BOOST_PP_FOR_114(s, p, o, m) BOOST_PP_FOR_114_I(s, p, o, m) # define BOOST_PP_FOR_115(s, p, o, m) BOOST_PP_FOR_115_I(s, p, o, m) # define BOOST_PP_FOR_116(s, p, o, m) BOOST_PP_FOR_116_I(s, p, o, m) # define BOOST_PP_FOR_117(s, p, o, m) BOOST_PP_FOR_117_I(s, p, o, m) # define BOOST_PP_FOR_118(s, p, o, m) BOOST_PP_FOR_118_I(s, p, o, m) # define BOOST_PP_FOR_119(s, p, o, m) BOOST_PP_FOR_119_I(s, p, o, m) # define BOOST_PP_FOR_120(s, p, o, m) BOOST_PP_FOR_120_I(s, p, o, m) # define BOOST_PP_FOR_121(s, p, o, m) BOOST_PP_FOR_121_I(s, p, o, m) # define BOOST_PP_FOR_122(s, p, o, m) BOOST_PP_FOR_122_I(s, p, o, m) # define BOOST_PP_FOR_123(s, p, o, m) BOOST_PP_FOR_123_I(s, p, o, m) # define BOOST_PP_FOR_124(s, p, o, m) BOOST_PP_FOR_124_I(s, p, o, m) # define BOOST_PP_FOR_125(s, p, o, m) BOOST_PP_FOR_125_I(s, p, o, m) # define BOOST_PP_FOR_126(s, p, o, m) BOOST_PP_FOR_126_I(s, p, o, m) # define BOOST_PP_FOR_127(s, p, o, m) BOOST_PP_FOR_127_I(s, p, o, m) # define BOOST_PP_FOR_128(s, p, o, m) BOOST_PP_FOR_128_I(s, p, o, m) # define BOOST_PP_FOR_129(s, p, o, m) BOOST_PP_FOR_129_I(s, p, o, m) # define BOOST_PP_FOR_130(s, p, o, m) BOOST_PP_FOR_130_I(s, p, o, m) # define BOOST_PP_FOR_131(s, p, o, m) BOOST_PP_FOR_131_I(s, p, o, m) # define BOOST_PP_FOR_132(s, p, o, m) BOOST_PP_FOR_132_I(s, p, o, m) # define BOOST_PP_FOR_133(s, p, o, m) BOOST_PP_FOR_133_I(s, p, o, m) # define BOOST_PP_FOR_134(s, p, o, m) BOOST_PP_FOR_134_I(s, p, o, m) # define BOOST_PP_FOR_135(s, p, o, m) BOOST_PP_FOR_135_I(s, p, o, m) # define BOOST_PP_FOR_136(s, p, o, m) BOOST_PP_FOR_136_I(s, p, o, m) # define BOOST_PP_FOR_137(s, p, o, m) BOOST_PP_FOR_137_I(s, p, o, m) # define BOOST_PP_FOR_138(s, p, o, m) BOOST_PP_FOR_138_I(s, p, o, m) # define BOOST_PP_FOR_139(s, p, o, m) BOOST_PP_FOR_139_I(s, p, o, m) # define BOOST_PP_FOR_140(s, p, o, m) BOOST_PP_FOR_140_I(s, p, o, m) # define BOOST_PP_FOR_141(s, p, o, m) BOOST_PP_FOR_141_I(s, p, o, m) # define BOOST_PP_FOR_142(s, p, o, m) BOOST_PP_FOR_142_I(s, p, o, m) # define BOOST_PP_FOR_143(s, p, o, m) BOOST_PP_FOR_143_I(s, p, o, m) # define BOOST_PP_FOR_144(s, p, o, m) BOOST_PP_FOR_144_I(s, p, o, m) # define BOOST_PP_FOR_145(s, p, o, m) BOOST_PP_FOR_145_I(s, p, o, m) # define BOOST_PP_FOR_146(s, p, o, m) BOOST_PP_FOR_146_I(s, p, o, m) # define BOOST_PP_FOR_147(s, p, o, m) BOOST_PP_FOR_147_I(s, p, o, m) # define BOOST_PP_FOR_148(s, p, o, m) BOOST_PP_FOR_148_I(s, p, o, m) # define BOOST_PP_FOR_149(s, p, o, m) BOOST_PP_FOR_149_I(s, p, o, m) # define BOOST_PP_FOR_150(s, p, o, m) BOOST_PP_FOR_150_I(s, p, o, m) # define BOOST_PP_FOR_151(s, p, o, m) BOOST_PP_FOR_151_I(s, p, o, m) # define BOOST_PP_FOR_152(s, p, o, m) BOOST_PP_FOR_152_I(s, p, o, m) # define BOOST_PP_FOR_153(s, p, o, m) BOOST_PP_FOR_153_I(s, p, o, m) # define BOOST_PP_FOR_154(s, p, o, m) BOOST_PP_FOR_154_I(s, p, o, m) # define BOOST_PP_FOR_155(s, p, o, m) BOOST_PP_FOR_155_I(s, p, o, m) # define BOOST_PP_FOR_156(s, p, o, m) BOOST_PP_FOR_156_I(s, p, o, m) # define BOOST_PP_FOR_157(s, p, o, m) BOOST_PP_FOR_157_I(s, p, o, m) # define BOOST_PP_FOR_158(s, p, o, m) BOOST_PP_FOR_158_I(s, p, o, m) # define BOOST_PP_FOR_159(s, p, o, m) BOOST_PP_FOR_159_I(s, p, o, m) # define BOOST_PP_FOR_160(s, p, o, m) BOOST_PP_FOR_160_I(s, p, o, m) # define BOOST_PP_FOR_161(s, p, o, m) BOOST_PP_FOR_161_I(s, p, o, m) # define BOOST_PP_FOR_162(s, p, o, m) BOOST_PP_FOR_162_I(s, p, o, m) # define BOOST_PP_FOR_163(s, p, o, m) BOOST_PP_FOR_163_I(s, p, o, m) # define BOOST_PP_FOR_164(s, p, o, m) BOOST_PP_FOR_164_I(s, p, o, m) # define BOOST_PP_FOR_165(s, p, o, m) BOOST_PP_FOR_165_I(s, p, o, m) # define BOOST_PP_FOR_166(s, p, o, m) BOOST_PP_FOR_166_I(s, p, o, m) # define BOOST_PP_FOR_167(s, p, o, m) BOOST_PP_FOR_167_I(s, p, o, m) # define BOOST_PP_FOR_168(s, p, o, m) BOOST_PP_FOR_168_I(s, p, o, m) # define BOOST_PP_FOR_169(s, p, o, m) BOOST_PP_FOR_169_I(s, p, o, m) # define BOOST_PP_FOR_170(s, p, o, m) BOOST_PP_FOR_170_I(s, p, o, m) # define BOOST_PP_FOR_171(s, p, o, m) BOOST_PP_FOR_171_I(s, p, o, m) # define BOOST_PP_FOR_172(s, p, o, m) BOOST_PP_FOR_172_I(s, p, o, m) # define BOOST_PP_FOR_173(s, p, o, m) BOOST_PP_FOR_173_I(s, p, o, m) # define BOOST_PP_FOR_174(s, p, o, m) BOOST_PP_FOR_174_I(s, p, o, m) # define BOOST_PP_FOR_175(s, p, o, m) BOOST_PP_FOR_175_I(s, p, o, m) # define BOOST_PP_FOR_176(s, p, o, m) BOOST_PP_FOR_176_I(s, p, o, m) # define BOOST_PP_FOR_177(s, p, o, m) BOOST_PP_FOR_177_I(s, p, o, m) # define BOOST_PP_FOR_178(s, p, o, m) BOOST_PP_FOR_178_I(s, p, o, m) # define BOOST_PP_FOR_179(s, p, o, m) BOOST_PP_FOR_179_I(s, p, o, m) # define BOOST_PP_FOR_180(s, p, o, m) BOOST_PP_FOR_180_I(s, p, o, m) # define BOOST_PP_FOR_181(s, p, o, m) BOOST_PP_FOR_181_I(s, p, o, m) # define BOOST_PP_FOR_182(s, p, o, m) BOOST_PP_FOR_182_I(s, p, o, m) # define BOOST_PP_FOR_183(s, p, o, m) BOOST_PP_FOR_183_I(s, p, o, m) # define BOOST_PP_FOR_184(s, p, o, m) BOOST_PP_FOR_184_I(s, p, o, m) # define BOOST_PP_FOR_185(s, p, o, m) BOOST_PP_FOR_185_I(s, p, o, m) # define BOOST_PP_FOR_186(s, p, o, m) BOOST_PP_FOR_186_I(s, p, o, m) # define BOOST_PP_FOR_187(s, p, o, m) BOOST_PP_FOR_187_I(s, p, o, m) # define BOOST_PP_FOR_188(s, p, o, m) BOOST_PP_FOR_188_I(s, p, o, m) # define BOOST_PP_FOR_189(s, p, o, m) BOOST_PP_FOR_189_I(s, p, o, m) # define BOOST_PP_FOR_190(s, p, o, m) BOOST_PP_FOR_190_I(s, p, o, m) # define BOOST_PP_FOR_191(s, p, o, m) BOOST_PP_FOR_191_I(s, p, o, m) # define BOOST_PP_FOR_192(s, p, o, m) BOOST_PP_FOR_192_I(s, p, o, m) # define BOOST_PP_FOR_193(s, p, o, m) BOOST_PP_FOR_193_I(s, p, o, m) # define BOOST_PP_FOR_194(s, p, o, m) BOOST_PP_FOR_194_I(s, p, o, m) # define BOOST_PP_FOR_195(s, p, o, m) BOOST_PP_FOR_195_I(s, p, o, m) # define BOOST_PP_FOR_196(s, p, o, m) BOOST_PP_FOR_196_I(s, p, o, m) # define BOOST_PP_FOR_197(s, p, o, m) BOOST_PP_FOR_197_I(s, p, o, m) # define BOOST_PP_FOR_198(s, p, o, m) BOOST_PP_FOR_198_I(s, p, o, m) # define BOOST_PP_FOR_199(s, p, o, m) BOOST_PP_FOR_199_I(s, p, o, m) # define BOOST_PP_FOR_200(s, p, o, m) BOOST_PP_FOR_200_I(s, p, o, m) # define BOOST_PP_FOR_201(s, p, o, m) BOOST_PP_FOR_201_I(s, p, o, m) # define BOOST_PP_FOR_202(s, p, o, m) BOOST_PP_FOR_202_I(s, p, o, m) # define BOOST_PP_FOR_203(s, p, o, m) BOOST_PP_FOR_203_I(s, p, o, m) # define BOOST_PP_FOR_204(s, p, o, m) BOOST_PP_FOR_204_I(s, p, o, m) # define BOOST_PP_FOR_205(s, p, o, m) BOOST_PP_FOR_205_I(s, p, o, m) # define BOOST_PP_FOR_206(s, p, o, m) BOOST_PP_FOR_206_I(s, p, o, m) # define BOOST_PP_FOR_207(s, p, o, m) BOOST_PP_FOR_207_I(s, p, o, m) # define BOOST_PP_FOR_208(s, p, o, m) BOOST_PP_FOR_208_I(s, p, o, m) # define BOOST_PP_FOR_209(s, p, o, m) BOOST_PP_FOR_209_I(s, p, o, m) # define BOOST_PP_FOR_210(s, p, o, m) BOOST_PP_FOR_210_I(s, p, o, m) # define BOOST_PP_FOR_211(s, p, o, m) BOOST_PP_FOR_211_I(s, p, o, m) # define BOOST_PP_FOR_212(s, p, o, m) BOOST_PP_FOR_212_I(s, p, o, m) # define BOOST_PP_FOR_213(s, p, o, m) BOOST_PP_FOR_213_I(s, p, o, m) # define BOOST_PP_FOR_214(s, p, o, m) BOOST_PP_FOR_214_I(s, p, o, m) # define BOOST_PP_FOR_215(s, p, o, m) BOOST_PP_FOR_215_I(s, p, o, m) # define BOOST_PP_FOR_216(s, p, o, m) BOOST_PP_FOR_216_I(s, p, o, m) # define BOOST_PP_FOR_217(s, p, o, m) BOOST_PP_FOR_217_I(s, p, o, m) # define BOOST_PP_FOR_218(s, p, o, m) BOOST_PP_FOR_218_I(s, p, o, m) # define BOOST_PP_FOR_219(s, p, o, m) BOOST_PP_FOR_219_I(s, p, o, m) # define BOOST_PP_FOR_220(s, p, o, m) BOOST_PP_FOR_220_I(s, p, o, m) # define BOOST_PP_FOR_221(s, p, o, m) BOOST_PP_FOR_221_I(s, p, o, m) # define BOOST_PP_FOR_222(s, p, o, m) BOOST_PP_FOR_222_I(s, p, o, m) # define BOOST_PP_FOR_223(s, p, o, m) BOOST_PP_FOR_223_I(s, p, o, m) # define BOOST_PP_FOR_224(s, p, o, m) BOOST_PP_FOR_224_I(s, p, o, m) # define BOOST_PP_FOR_225(s, p, o, m) BOOST_PP_FOR_225_I(s, p, o, m) # define BOOST_PP_FOR_226(s, p, o, m) BOOST_PP_FOR_226_I(s, p, o, m) # define BOOST_PP_FOR_227(s, p, o, m) BOOST_PP_FOR_227_I(s, p, o, m) # define BOOST_PP_FOR_228(s, p, o, m) BOOST_PP_FOR_228_I(s, p, o, m) # define BOOST_PP_FOR_229(s, p, o, m) BOOST_PP_FOR_229_I(s, p, o, m) # define BOOST_PP_FOR_230(s, p, o, m) BOOST_PP_FOR_230_I(s, p, o, m) # define BOOST_PP_FOR_231(s, p, o, m) BOOST_PP_FOR_231_I(s, p, o, m) # define BOOST_PP_FOR_232(s, p, o, m) BOOST_PP_FOR_232_I(s, p, o, m) # define BOOST_PP_FOR_233(s, p, o, m) BOOST_PP_FOR_233_I(s, p, o, m) # define BOOST_PP_FOR_234(s, p, o, m) BOOST_PP_FOR_234_I(s, p, o, m) # define BOOST_PP_FOR_235(s, p, o, m) BOOST_PP_FOR_235_I(s, p, o, m) # define BOOST_PP_FOR_236(s, p, o, m) BOOST_PP_FOR_236_I(s, p, o, m) # define BOOST_PP_FOR_237(s, p, o, m) BOOST_PP_FOR_237_I(s, p, o, m) # define BOOST_PP_FOR_238(s, p, o, m) BOOST_PP_FOR_238_I(s, p, o, m) # define BOOST_PP_FOR_239(s, p, o, m) BOOST_PP_FOR_239_I(s, p, o, m) # define BOOST_PP_FOR_240(s, p, o, m) BOOST_PP_FOR_240_I(s, p, o, m) # define BOOST_PP_FOR_241(s, p, o, m) BOOST_PP_FOR_241_I(s, p, o, m) # define BOOST_PP_FOR_242(s, p, o, m) BOOST_PP_FOR_242_I(s, p, o, m) # define BOOST_PP_FOR_243(s, p, o, m) BOOST_PP_FOR_243_I(s, p, o, m) # define BOOST_PP_FOR_244(s, p, o, m) BOOST_PP_FOR_244_I(s, p, o, m) # define BOOST_PP_FOR_245(s, p, o, m) BOOST_PP_FOR_245_I(s, p, o, m) # define BOOST_PP_FOR_246(s, p, o, m) BOOST_PP_FOR_246_I(s, p, o, m) # define BOOST_PP_FOR_247(s, p, o, m) BOOST_PP_FOR_247_I(s, p, o, m) # define BOOST_PP_FOR_248(s, p, o, m) BOOST_PP_FOR_248_I(s, p, o, m) # define BOOST_PP_FOR_249(s, p, o, m) BOOST_PP_FOR_249_I(s, p, o, m) # define BOOST_PP_FOR_250(s, p, o, m) BOOST_PP_FOR_250_I(s, p, o, m) # define BOOST_PP_FOR_251(s, p, o, m) BOOST_PP_FOR_251_I(s, p, o, m) # define BOOST_PP_FOR_252(s, p, o, m) BOOST_PP_FOR_252_I(s, p, o, m) # define BOOST_PP_FOR_253(s, p, o, m) BOOST_PP_FOR_253_I(s, p, o, m) # define BOOST_PP_FOR_254(s, p, o, m) BOOST_PP_FOR_254_I(s, p, o, m) # define BOOST_PP_FOR_255(s, p, o, m) BOOST_PP_FOR_255_I(s, p, o, m) # define BOOST_PP_FOR_256(s, p, o, m) BOOST_PP_FOR_256_I(s, p, o, m) # # define BOOST_PP_FOR_1_I(s, p, o, m) BOOST_PP_IF(p(2, s), m, BOOST_PP_TUPLE_EAT_2)(2, s) BOOST_PP_IF(p(2, s), BOOST_PP_FOR_2, BOOST_PP_TUPLE_EAT_4)(o(2, s), p, o, m) # define BOOST_PP_FOR_2_I(s, p, o, m) BOOST_PP_IF(p(3, s), m, BOOST_PP_TUPLE_EAT_2)(3, s) BOOST_PP_IF(p(3, s), BOOST_PP_FOR_3, BOOST_PP_TUPLE_EAT_4)(o(3, s), p, o, m) # define BOOST_PP_FOR_3_I(s, p, o, m) BOOST_PP_IF(p(4, s), m, BOOST_PP_TUPLE_EAT_2)(4, s) BOOST_PP_IF(p(4, s), BOOST_PP_FOR_4, BOOST_PP_TUPLE_EAT_4)(o(4, s), p, o, m) # define BOOST_PP_FOR_4_I(s, p, o, m) BOOST_PP_IF(p(5, s), m, BOOST_PP_TUPLE_EAT_2)(5, s) BOOST_PP_IF(p(5, s), BOOST_PP_FOR_5, BOOST_PP_TUPLE_EAT_4)(o(5, s), p, o, m) # define BOOST_PP_FOR_5_I(s, p, o, m) BOOST_PP_IF(p(6, s), m, BOOST_PP_TUPLE_EAT_2)(6, s) BOOST_PP_IF(p(6, s), BOOST_PP_FOR_6, BOOST_PP_TUPLE_EAT_4)(o(6, s), p, o, m) # define BOOST_PP_FOR_6_I(s, p, o, m) BOOST_PP_IF(p(7, s), m, BOOST_PP_TUPLE_EAT_2)(7, s) BOOST_PP_IF(p(7, s), BOOST_PP_FOR_7, BOOST_PP_TUPLE_EAT_4)(o(7, s), p, o, m) # define BOOST_PP_FOR_7_I(s, p, o, m) BOOST_PP_IF(p(8, s), m, BOOST_PP_TUPLE_EAT_2)(8, s) BOOST_PP_IF(p(8, s), BOOST_PP_FOR_8, BOOST_PP_TUPLE_EAT_4)(o(8, s), p, o, m) # define BOOST_PP_FOR_8_I(s, p, o, m) BOOST_PP_IF(p(9, s), m, BOOST_PP_TUPLE_EAT_2)(9, s) BOOST_PP_IF(p(9, s), BOOST_PP_FOR_9, BOOST_PP_TUPLE_EAT_4)(o(9, s), p, o, m) # define BOOST_PP_FOR_9_I(s, p, o, m) BOOST_PP_IF(p(10, s), m, BOOST_PP_TUPLE_EAT_2)(10, s) BOOST_PP_IF(p(10, s), BOOST_PP_FOR_10, BOOST_PP_TUPLE_EAT_4)(o(10, s), p, o, m) # define BOOST_PP_FOR_10_I(s, p, o, m) BOOST_PP_IF(p(11, s), m, BOOST_PP_TUPLE_EAT_2)(11, s) BOOST_PP_IF(p(11, s), BOOST_PP_FOR_11, BOOST_PP_TUPLE_EAT_4)(o(11, s), p, o, m) # define BOOST_PP_FOR_11_I(s, p, o, m) BOOST_PP_IF(p(12, s), m, BOOST_PP_TUPLE_EAT_2)(12, s) BOOST_PP_IF(p(12, s), BOOST_PP_FOR_12, BOOST_PP_TUPLE_EAT_4)(o(12, s), p, o, m) # define BOOST_PP_FOR_12_I(s, p, o, m) BOOST_PP_IF(p(13, s), m, BOOST_PP_TUPLE_EAT_2)(13, s) BOOST_PP_IF(p(13, s), BOOST_PP_FOR_13, BOOST_PP_TUPLE_EAT_4)(o(13, s), p, o, m) # define BOOST_PP_FOR_13_I(s, p, o, m) BOOST_PP_IF(p(14, s), m, BOOST_PP_TUPLE_EAT_2)(14, s) BOOST_PP_IF(p(14, s), BOOST_PP_FOR_14, BOOST_PP_TUPLE_EAT_4)(o(14, s), p, o, m) # define BOOST_PP_FOR_14_I(s, p, o, m) BOOST_PP_IF(p(15, s), m, BOOST_PP_TUPLE_EAT_2)(15, s) BOOST_PP_IF(p(15, s), BOOST_PP_FOR_15, BOOST_PP_TUPLE_EAT_4)(o(15, s), p, o, m) # define BOOST_PP_FOR_15_I(s, p, o, m) BOOST_PP_IF(p(16, s), m, BOOST_PP_TUPLE_EAT_2)(16, s) BOOST_PP_IF(p(16, s), BOOST_PP_FOR_16, BOOST_PP_TUPLE_EAT_4)(o(16, s), p, o, m) # define BOOST_PP_FOR_16_I(s, p, o, m) BOOST_PP_IF(p(17, s), m, BOOST_PP_TUPLE_EAT_2)(17, s) BOOST_PP_IF(p(17, s), BOOST_PP_FOR_17, BOOST_PP_TUPLE_EAT_4)(o(17, s), p, o, m) # define BOOST_PP_FOR_17_I(s, p, o, m) BOOST_PP_IF(p(18, s), m, BOOST_PP_TUPLE_EAT_2)(18, s) BOOST_PP_IF(p(18, s), BOOST_PP_FOR_18, BOOST_PP_TUPLE_EAT_4)(o(18, s), p, o, m) # define BOOST_PP_FOR_18_I(s, p, o, m) BOOST_PP_IF(p(19, s), m, BOOST_PP_TUPLE_EAT_2)(19, s) BOOST_PP_IF(p(19, s), BOOST_PP_FOR_19, BOOST_PP_TUPLE_EAT_4)(o(19, s), p, o, m) # define BOOST_PP_FOR_19_I(s, p, o, m) BOOST_PP_IF(p(20, s), m, BOOST_PP_TUPLE_EAT_2)(20, s) BOOST_PP_IF(p(20, s), BOOST_PP_FOR_20, BOOST_PP_TUPLE_EAT_4)(o(20, s), p, o, m) # define BOOST_PP_FOR_20_I(s, p, o, m) BOOST_PP_IF(p(21, s), m, BOOST_PP_TUPLE_EAT_2)(21, s) BOOST_PP_IF(p(21, s), BOOST_PP_FOR_21, BOOST_PP_TUPLE_EAT_4)(o(21, s), p, o, m) # define BOOST_PP_FOR_21_I(s, p, o, m) BOOST_PP_IF(p(22, s), m, BOOST_PP_TUPLE_EAT_2)(22, s) BOOST_PP_IF(p(22, s), BOOST_PP_FOR_22, BOOST_PP_TUPLE_EAT_4)(o(22, s), p, o, m) # define BOOST_PP_FOR_22_I(s, p, o, m) BOOST_PP_IF(p(23, s), m, BOOST_PP_TUPLE_EAT_2)(23, s) BOOST_PP_IF(p(23, s), BOOST_PP_FOR_23, BOOST_PP_TUPLE_EAT_4)(o(23, s), p, o, m) # define BOOST_PP_FOR_23_I(s, p, o, m) BOOST_PP_IF(p(24, s), m, BOOST_PP_TUPLE_EAT_2)(24, s) BOOST_PP_IF(p(24, s), BOOST_PP_FOR_24, BOOST_PP_TUPLE_EAT_4)(o(24, s), p, o, m) # define BOOST_PP_FOR_24_I(s, p, o, m) BOOST_PP_IF(p(25, s), m, BOOST_PP_TUPLE_EAT_2)(25, s) BOOST_PP_IF(p(25, s), BOOST_PP_FOR_25, BOOST_PP_TUPLE_EAT_4)(o(25, s), p, o, m) # define BOOST_PP_FOR_25_I(s, p, o, m) BOOST_PP_IF(p(26, s), m, BOOST_PP_TUPLE_EAT_2)(26, s) BOOST_PP_IF(p(26, s), BOOST_PP_FOR_26, BOOST_PP_TUPLE_EAT_4)(o(26, s), p, o, m) # define BOOST_PP_FOR_26_I(s, p, o, m) BOOST_PP_IF(p(27, s), m, BOOST_PP_TUPLE_EAT_2)(27, s) BOOST_PP_IF(p(27, s), BOOST_PP_FOR_27, BOOST_PP_TUPLE_EAT_4)(o(27, s), p, o, m) # define BOOST_PP_FOR_27_I(s, p, o, m) BOOST_PP_IF(p(28, s), m, BOOST_PP_TUPLE_EAT_2)(28, s) BOOST_PP_IF(p(28, s), BOOST_PP_FOR_28, BOOST_PP_TUPLE_EAT_4)(o(28, s), p, o, m) # define BOOST_PP_FOR_28_I(s, p, o, m) BOOST_PP_IF(p(29, s), m, BOOST_PP_TUPLE_EAT_2)(29, s) BOOST_PP_IF(p(29, s), BOOST_PP_FOR_29, BOOST_PP_TUPLE_EAT_4)(o(29, s), p, o, m) # define BOOST_PP_FOR_29_I(s, p, o, m) BOOST_PP_IF(p(30, s), m, BOOST_PP_TUPLE_EAT_2)(30, s) BOOST_PP_IF(p(30, s), BOOST_PP_FOR_30, BOOST_PP_TUPLE_EAT_4)(o(30, s), p, o, m) # define BOOST_PP_FOR_30_I(s, p, o, m) BOOST_PP_IF(p(31, s), m, BOOST_PP_TUPLE_EAT_2)(31, s) BOOST_PP_IF(p(31, s), BOOST_PP_FOR_31, BOOST_PP_TUPLE_EAT_4)(o(31, s), p, o, m) # define BOOST_PP_FOR_31_I(s, p, o, m) BOOST_PP_IF(p(32, s), m, BOOST_PP_TUPLE_EAT_2)(32, s) BOOST_PP_IF(p(32, s), BOOST_PP_FOR_32, BOOST_PP_TUPLE_EAT_4)(o(32, s), p, o, m) # define BOOST_PP_FOR_32_I(s, p, o, m) BOOST_PP_IF(p(33, s), m, BOOST_PP_TUPLE_EAT_2)(33, s) BOOST_PP_IF(p(33, s), BOOST_PP_FOR_33, BOOST_PP_TUPLE_EAT_4)(o(33, s), p, o, m) # define BOOST_PP_FOR_33_I(s, p, o, m) BOOST_PP_IF(p(34, s), m, BOOST_PP_TUPLE_EAT_2)(34, s) BOOST_PP_IF(p(34, s), BOOST_PP_FOR_34, BOOST_PP_TUPLE_EAT_4)(o(34, s), p, o, m) # define BOOST_PP_FOR_34_I(s, p, o, m) BOOST_PP_IF(p(35, s), m, BOOST_PP_TUPLE_EAT_2)(35, s) BOOST_PP_IF(p(35, s), BOOST_PP_FOR_35, BOOST_PP_TUPLE_EAT_4)(o(35, s), p, o, m) # define BOOST_PP_FOR_35_I(s, p, o, m) BOOST_PP_IF(p(36, s), m, BOOST_PP_TUPLE_EAT_2)(36, s) BOOST_PP_IF(p(36, s), BOOST_PP_FOR_36, BOOST_PP_TUPLE_EAT_4)(o(36, s), p, o, m) # define BOOST_PP_FOR_36_I(s, p, o, m) BOOST_PP_IF(p(37, s), m, BOOST_PP_TUPLE_EAT_2)(37, s) BOOST_PP_IF(p(37, s), BOOST_PP_FOR_37, BOOST_PP_TUPLE_EAT_4)(o(37, s), p, o, m) # define BOOST_PP_FOR_37_I(s, p, o, m) BOOST_PP_IF(p(38, s), m, BOOST_PP_TUPLE_EAT_2)(38, s) BOOST_PP_IF(p(38, s), BOOST_PP_FOR_38, BOOST_PP_TUPLE_EAT_4)(o(38, s), p, o, m) # define BOOST_PP_FOR_38_I(s, p, o, m) BOOST_PP_IF(p(39, s), m, BOOST_PP_TUPLE_EAT_2)(39, s) BOOST_PP_IF(p(39, s), BOOST_PP_FOR_39, BOOST_PP_TUPLE_EAT_4)(o(39, s), p, o, m) # define BOOST_PP_FOR_39_I(s, p, o, m) BOOST_PP_IF(p(40, s), m, BOOST_PP_TUPLE_EAT_2)(40, s) BOOST_PP_IF(p(40, s), BOOST_PP_FOR_40, BOOST_PP_TUPLE_EAT_4)(o(40, s), p, o, m) # define BOOST_PP_FOR_40_I(s, p, o, m) BOOST_PP_IF(p(41, s), m, BOOST_PP_TUPLE_EAT_2)(41, s) BOOST_PP_IF(p(41, s), BOOST_PP_FOR_41, BOOST_PP_TUPLE_EAT_4)(o(41, s), p, o, m) # define BOOST_PP_FOR_41_I(s, p, o, m) BOOST_PP_IF(p(42, s), m, BOOST_PP_TUPLE_EAT_2)(42, s) BOOST_PP_IF(p(42, s), BOOST_PP_FOR_42, BOOST_PP_TUPLE_EAT_4)(o(42, s), p, o, m) # define BOOST_PP_FOR_42_I(s, p, o, m) BOOST_PP_IF(p(43, s), m, BOOST_PP_TUPLE_EAT_2)(43, s) BOOST_PP_IF(p(43, s), BOOST_PP_FOR_43, BOOST_PP_TUPLE_EAT_4)(o(43, s), p, o, m) # define BOOST_PP_FOR_43_I(s, p, o, m) BOOST_PP_IF(p(44, s), m, BOOST_PP_TUPLE_EAT_2)(44, s) BOOST_PP_IF(p(44, s), BOOST_PP_FOR_44, BOOST_PP_TUPLE_EAT_4)(o(44, s), p, o, m) # define BOOST_PP_FOR_44_I(s, p, o, m) BOOST_PP_IF(p(45, s), m, BOOST_PP_TUPLE_EAT_2)(45, s) BOOST_PP_IF(p(45, s), BOOST_PP_FOR_45, BOOST_PP_TUPLE_EAT_4)(o(45, s), p, o, m) # define BOOST_PP_FOR_45_I(s, p, o, m) BOOST_PP_IF(p(46, s), m, BOOST_PP_TUPLE_EAT_2)(46, s) BOOST_PP_IF(p(46, s), BOOST_PP_FOR_46, BOOST_PP_TUPLE_EAT_4)(o(46, s), p, o, m) # define BOOST_PP_FOR_46_I(s, p, o, m) BOOST_PP_IF(p(47, s), m, BOOST_PP_TUPLE_EAT_2)(47, s) BOOST_PP_IF(p(47, s), BOOST_PP_FOR_47, BOOST_PP_TUPLE_EAT_4)(o(47, s), p, o, m) # define BOOST_PP_FOR_47_I(s, p, o, m) BOOST_PP_IF(p(48, s), m, BOOST_PP_TUPLE_EAT_2)(48, s) BOOST_PP_IF(p(48, s), BOOST_PP_FOR_48, BOOST_PP_TUPLE_EAT_4)(o(48, s), p, o, m) # define BOOST_PP_FOR_48_I(s, p, o, m) BOOST_PP_IF(p(49, s), m, BOOST_PP_TUPLE_EAT_2)(49, s) BOOST_PP_IF(p(49, s), BOOST_PP_FOR_49, BOOST_PP_TUPLE_EAT_4)(o(49, s), p, o, m) # define BOOST_PP_FOR_49_I(s, p, o, m) BOOST_PP_IF(p(50, s), m, BOOST_PP_TUPLE_EAT_2)(50, s) BOOST_PP_IF(p(50, s), BOOST_PP_FOR_50, BOOST_PP_TUPLE_EAT_4)(o(50, s), p, o, m) # define BOOST_PP_FOR_50_I(s, p, o, m) BOOST_PP_IF(p(51, s), m, BOOST_PP_TUPLE_EAT_2)(51, s) BOOST_PP_IF(p(51, s), BOOST_PP_FOR_51, BOOST_PP_TUPLE_EAT_4)(o(51, s), p, o, m) # define BOOST_PP_FOR_51_I(s, p, o, m) BOOST_PP_IF(p(52, s), m, BOOST_PP_TUPLE_EAT_2)(52, s) BOOST_PP_IF(p(52, s), BOOST_PP_FOR_52, BOOST_PP_TUPLE_EAT_4)(o(52, s), p, o, m) # define BOOST_PP_FOR_52_I(s, p, o, m) BOOST_PP_IF(p(53, s), m, BOOST_PP_TUPLE_EAT_2)(53, s) BOOST_PP_IF(p(53, s), BOOST_PP_FOR_53, BOOST_PP_TUPLE_EAT_4)(o(53, s), p, o, m) # define BOOST_PP_FOR_53_I(s, p, o, m) BOOST_PP_IF(p(54, s), m, BOOST_PP_TUPLE_EAT_2)(54, s) BOOST_PP_IF(p(54, s), BOOST_PP_FOR_54, BOOST_PP_TUPLE_EAT_4)(o(54, s), p, o, m) # define BOOST_PP_FOR_54_I(s, p, o, m) BOOST_PP_IF(p(55, s), m, BOOST_PP_TUPLE_EAT_2)(55, s) BOOST_PP_IF(p(55, s), BOOST_PP_FOR_55, BOOST_PP_TUPLE_EAT_4)(o(55, s), p, o, m) # define BOOST_PP_FOR_55_I(s, p, o, m) BOOST_PP_IF(p(56, s), m, BOOST_PP_TUPLE_EAT_2)(56, s) BOOST_PP_IF(p(56, s), BOOST_PP_FOR_56, BOOST_PP_TUPLE_EAT_4)(o(56, s), p, o, m) # define BOOST_PP_FOR_56_I(s, p, o, m) BOOST_PP_IF(p(57, s), m, BOOST_PP_TUPLE_EAT_2)(57, s) BOOST_PP_IF(p(57, s), BOOST_PP_FOR_57, BOOST_PP_TUPLE_EAT_4)(o(57, s), p, o, m) # define BOOST_PP_FOR_57_I(s, p, o, m) BOOST_PP_IF(p(58, s), m, BOOST_PP_TUPLE_EAT_2)(58, s) BOOST_PP_IF(p(58, s), BOOST_PP_FOR_58, BOOST_PP_TUPLE_EAT_4)(o(58, s), p, o, m) # define BOOST_PP_FOR_58_I(s, p, o, m) BOOST_PP_IF(p(59, s), m, BOOST_PP_TUPLE_EAT_2)(59, s) BOOST_PP_IF(p(59, s), BOOST_PP_FOR_59, BOOST_PP_TUPLE_EAT_4)(o(59, s), p, o, m) # define BOOST_PP_FOR_59_I(s, p, o, m) BOOST_PP_IF(p(60, s), m, BOOST_PP_TUPLE_EAT_2)(60, s) BOOST_PP_IF(p(60, s), BOOST_PP_FOR_60, BOOST_PP_TUPLE_EAT_4)(o(60, s), p, o, m) # define BOOST_PP_FOR_60_I(s, p, o, m) BOOST_PP_IF(p(61, s), m, BOOST_PP_TUPLE_EAT_2)(61, s) BOOST_PP_IF(p(61, s), BOOST_PP_FOR_61, BOOST_PP_TUPLE_EAT_4)(o(61, s), p, o, m) # define BOOST_PP_FOR_61_I(s, p, o, m) BOOST_PP_IF(p(62, s), m, BOOST_PP_TUPLE_EAT_2)(62, s) BOOST_PP_IF(p(62, s), BOOST_PP_FOR_62, BOOST_PP_TUPLE_EAT_4)(o(62, s), p, o, m) # define BOOST_PP_FOR_62_I(s, p, o, m) BOOST_PP_IF(p(63, s), m, BOOST_PP_TUPLE_EAT_2)(63, s) BOOST_PP_IF(p(63, s), BOOST_PP_FOR_63, BOOST_PP_TUPLE_EAT_4)(o(63, s), p, o, m) # define BOOST_PP_FOR_63_I(s, p, o, m) BOOST_PP_IF(p(64, s), m, BOOST_PP_TUPLE_EAT_2)(64, s) BOOST_PP_IF(p(64, s), BOOST_PP_FOR_64, BOOST_PP_TUPLE_EAT_4)(o(64, s), p, o, m) # define BOOST_PP_FOR_64_I(s, p, o, m) BOOST_PP_IF(p(65, s), m, BOOST_PP_TUPLE_EAT_2)(65, s) BOOST_PP_IF(p(65, s), BOOST_PP_FOR_65, BOOST_PP_TUPLE_EAT_4)(o(65, s), p, o, m) # define BOOST_PP_FOR_65_I(s, p, o, m) BOOST_PP_IF(p(66, s), m, BOOST_PP_TUPLE_EAT_2)(66, s) BOOST_PP_IF(p(66, s), BOOST_PP_FOR_66, BOOST_PP_TUPLE_EAT_4)(o(66, s), p, o, m) # define BOOST_PP_FOR_66_I(s, p, o, m) BOOST_PP_IF(p(67, s), m, BOOST_PP_TUPLE_EAT_2)(67, s) BOOST_PP_IF(p(67, s), BOOST_PP_FOR_67, BOOST_PP_TUPLE_EAT_4)(o(67, s), p, o, m) # define BOOST_PP_FOR_67_I(s, p, o, m) BOOST_PP_IF(p(68, s), m, BOOST_PP_TUPLE_EAT_2)(68, s) BOOST_PP_IF(p(68, s), BOOST_PP_FOR_68, BOOST_PP_TUPLE_EAT_4)(o(68, s), p, o, m) # define BOOST_PP_FOR_68_I(s, p, o, m) BOOST_PP_IF(p(69, s), m, BOOST_PP_TUPLE_EAT_2)(69, s) BOOST_PP_IF(p(69, s), BOOST_PP_FOR_69, BOOST_PP_TUPLE_EAT_4)(o(69, s), p, o, m) # define BOOST_PP_FOR_69_I(s, p, o, m) BOOST_PP_IF(p(70, s), m, BOOST_PP_TUPLE_EAT_2)(70, s) BOOST_PP_IF(p(70, s), BOOST_PP_FOR_70, BOOST_PP_TUPLE_EAT_4)(o(70, s), p, o, m) # define BOOST_PP_FOR_70_I(s, p, o, m) BOOST_PP_IF(p(71, s), m, BOOST_PP_TUPLE_EAT_2)(71, s) BOOST_PP_IF(p(71, s), BOOST_PP_FOR_71, BOOST_PP_TUPLE_EAT_4)(o(71, s), p, o, m) # define BOOST_PP_FOR_71_I(s, p, o, m) BOOST_PP_IF(p(72, s), m, BOOST_PP_TUPLE_EAT_2)(72, s) BOOST_PP_IF(p(72, s), BOOST_PP_FOR_72, BOOST_PP_TUPLE_EAT_4)(o(72, s), p, o, m) # define BOOST_PP_FOR_72_I(s, p, o, m) BOOST_PP_IF(p(73, s), m, BOOST_PP_TUPLE_EAT_2)(73, s) BOOST_PP_IF(p(73, s), BOOST_PP_FOR_73, BOOST_PP_TUPLE_EAT_4)(o(73, s), p, o, m) # define BOOST_PP_FOR_73_I(s, p, o, m) BOOST_PP_IF(p(74, s), m, BOOST_PP_TUPLE_EAT_2)(74, s) BOOST_PP_IF(p(74, s), BOOST_PP_FOR_74, BOOST_PP_TUPLE_EAT_4)(o(74, s), p, o, m) # define BOOST_PP_FOR_74_I(s, p, o, m) BOOST_PP_IF(p(75, s), m, BOOST_PP_TUPLE_EAT_2)(75, s) BOOST_PP_IF(p(75, s), BOOST_PP_FOR_75, BOOST_PP_TUPLE_EAT_4)(o(75, s), p, o, m) # define BOOST_PP_FOR_75_I(s, p, o, m) BOOST_PP_IF(p(76, s), m, BOOST_PP_TUPLE_EAT_2)(76, s) BOOST_PP_IF(p(76, s), BOOST_PP_FOR_76, BOOST_PP_TUPLE_EAT_4)(o(76, s), p, o, m) # define BOOST_PP_FOR_76_I(s, p, o, m) BOOST_PP_IF(p(77, s), m, BOOST_PP_TUPLE_EAT_2)(77, s) BOOST_PP_IF(p(77, s), BOOST_PP_FOR_77, BOOST_PP_TUPLE_EAT_4)(o(77, s), p, o, m) # define BOOST_PP_FOR_77_I(s, p, o, m) BOOST_PP_IF(p(78, s), m, BOOST_PP_TUPLE_EAT_2)(78, s) BOOST_PP_IF(p(78, s), BOOST_PP_FOR_78, BOOST_PP_TUPLE_EAT_4)(o(78, s), p, o, m) # define BOOST_PP_FOR_78_I(s, p, o, m) BOOST_PP_IF(p(79, s), m, BOOST_PP_TUPLE_EAT_2)(79, s) BOOST_PP_IF(p(79, s), BOOST_PP_FOR_79, BOOST_PP_TUPLE_EAT_4)(o(79, s), p, o, m) # define BOOST_PP_FOR_79_I(s, p, o, m) BOOST_PP_IF(p(80, s), m, BOOST_PP_TUPLE_EAT_2)(80, s) BOOST_PP_IF(p(80, s), BOOST_PP_FOR_80, BOOST_PP_TUPLE_EAT_4)(o(80, s), p, o, m) # define BOOST_PP_FOR_80_I(s, p, o, m) BOOST_PP_IF(p(81, s), m, BOOST_PP_TUPLE_EAT_2)(81, s) BOOST_PP_IF(p(81, s), BOOST_PP_FOR_81, BOOST_PP_TUPLE_EAT_4)(o(81, s), p, o, m) # define BOOST_PP_FOR_81_I(s, p, o, m) BOOST_PP_IF(p(82, s), m, BOOST_PP_TUPLE_EAT_2)(82, s) BOOST_PP_IF(p(82, s), BOOST_PP_FOR_82, BOOST_PP_TUPLE_EAT_4)(o(82, s), p, o, m) # define BOOST_PP_FOR_82_I(s, p, o, m) BOOST_PP_IF(p(83, s), m, BOOST_PP_TUPLE_EAT_2)(83, s) BOOST_PP_IF(p(83, s), BOOST_PP_FOR_83, BOOST_PP_TUPLE_EAT_4)(o(83, s), p, o, m) # define BOOST_PP_FOR_83_I(s, p, o, m) BOOST_PP_IF(p(84, s), m, BOOST_PP_TUPLE_EAT_2)(84, s) BOOST_PP_IF(p(84, s), BOOST_PP_FOR_84, BOOST_PP_TUPLE_EAT_4)(o(84, s), p, o, m) # define BOOST_PP_FOR_84_I(s, p, o, m) BOOST_PP_IF(p(85, s), m, BOOST_PP_TUPLE_EAT_2)(85, s) BOOST_PP_IF(p(85, s), BOOST_PP_FOR_85, BOOST_PP_TUPLE_EAT_4)(o(85, s), p, o, m) # define BOOST_PP_FOR_85_I(s, p, o, m) BOOST_PP_IF(p(86, s), m, BOOST_PP_TUPLE_EAT_2)(86, s) BOOST_PP_IF(p(86, s), BOOST_PP_FOR_86, BOOST_PP_TUPLE_EAT_4)(o(86, s), p, o, m) # define BOOST_PP_FOR_86_I(s, p, o, m) BOOST_PP_IF(p(87, s), m, BOOST_PP_TUPLE_EAT_2)(87, s) BOOST_PP_IF(p(87, s), BOOST_PP_FOR_87, BOOST_PP_TUPLE_EAT_4)(o(87, s), p, o, m) # define BOOST_PP_FOR_87_I(s, p, o, m) BOOST_PP_IF(p(88, s), m, BOOST_PP_TUPLE_EAT_2)(88, s) BOOST_PP_IF(p(88, s), BOOST_PP_FOR_88, BOOST_PP_TUPLE_EAT_4)(o(88, s), p, o, m) # define BOOST_PP_FOR_88_I(s, p, o, m) BOOST_PP_IF(p(89, s), m, BOOST_PP_TUPLE_EAT_2)(89, s) BOOST_PP_IF(p(89, s), BOOST_PP_FOR_89, BOOST_PP_TUPLE_EAT_4)(o(89, s), p, o, m) # define BOOST_PP_FOR_89_I(s, p, o, m) BOOST_PP_IF(p(90, s), m, BOOST_PP_TUPLE_EAT_2)(90, s) BOOST_PP_IF(p(90, s), BOOST_PP_FOR_90, BOOST_PP_TUPLE_EAT_4)(o(90, s), p, o, m) # define BOOST_PP_FOR_90_I(s, p, o, m) BOOST_PP_IF(p(91, s), m, BOOST_PP_TUPLE_EAT_2)(91, s) BOOST_PP_IF(p(91, s), BOOST_PP_FOR_91, BOOST_PP_TUPLE_EAT_4)(o(91, s), p, o, m) # define BOOST_PP_FOR_91_I(s, p, o, m) BOOST_PP_IF(p(92, s), m, BOOST_PP_TUPLE_EAT_2)(92, s) BOOST_PP_IF(p(92, s), BOOST_PP_FOR_92, BOOST_PP_TUPLE_EAT_4)(o(92, s), p, o, m) # define BOOST_PP_FOR_92_I(s, p, o, m) BOOST_PP_IF(p(93, s), m, BOOST_PP_TUPLE_EAT_2)(93, s) BOOST_PP_IF(p(93, s), BOOST_PP_FOR_93, BOOST_PP_TUPLE_EAT_4)(o(93, s), p, o, m) # define BOOST_PP_FOR_93_I(s, p, o, m) BOOST_PP_IF(p(94, s), m, BOOST_PP_TUPLE_EAT_2)(94, s) BOOST_PP_IF(p(94, s), BOOST_PP_FOR_94, BOOST_PP_TUPLE_EAT_4)(o(94, s), p, o, m) # define BOOST_PP_FOR_94_I(s, p, o, m) BOOST_PP_IF(p(95, s), m, BOOST_PP_TUPLE_EAT_2)(95, s) BOOST_PP_IF(p(95, s), BOOST_PP_FOR_95, BOOST_PP_TUPLE_EAT_4)(o(95, s), p, o, m) # define BOOST_PP_FOR_95_I(s, p, o, m) BOOST_PP_IF(p(96, s), m, BOOST_PP_TUPLE_EAT_2)(96, s) BOOST_PP_IF(p(96, s), BOOST_PP_FOR_96, BOOST_PP_TUPLE_EAT_4)(o(96, s), p, o, m) # define BOOST_PP_FOR_96_I(s, p, o, m) BOOST_PP_IF(p(97, s), m, BOOST_PP_TUPLE_EAT_2)(97, s) BOOST_PP_IF(p(97, s), BOOST_PP_FOR_97, BOOST_PP_TUPLE_EAT_4)(o(97, s), p, o, m) # define BOOST_PP_FOR_97_I(s, p, o, m) BOOST_PP_IF(p(98, s), m, BOOST_PP_TUPLE_EAT_2)(98, s) BOOST_PP_IF(p(98, s), BOOST_PP_FOR_98, BOOST_PP_TUPLE_EAT_4)(o(98, s), p, o, m) # define BOOST_PP_FOR_98_I(s, p, o, m) BOOST_PP_IF(p(99, s), m, BOOST_PP_TUPLE_EAT_2)(99, s) BOOST_PP_IF(p(99, s), BOOST_PP_FOR_99, BOOST_PP_TUPLE_EAT_4)(o(99, s), p, o, m) # define BOOST_PP_FOR_99_I(s, p, o, m) BOOST_PP_IF(p(100, s), m, BOOST_PP_TUPLE_EAT_2)(100, s) BOOST_PP_IF(p(100, s), BOOST_PP_FOR_100, BOOST_PP_TUPLE_EAT_4)(o(100, s), p, o, m) # define BOOST_PP_FOR_100_I(s, p, o, m) BOOST_PP_IF(p(101, s), m, BOOST_PP_TUPLE_EAT_2)(101, s) BOOST_PP_IF(p(101, s), BOOST_PP_FOR_101, BOOST_PP_TUPLE_EAT_4)(o(101, s), p, o, m) # define BOOST_PP_FOR_101_I(s, p, o, m) BOOST_PP_IF(p(102, s), m, BOOST_PP_TUPLE_EAT_2)(102, s) BOOST_PP_IF(p(102, s), BOOST_PP_FOR_102, BOOST_PP_TUPLE_EAT_4)(o(102, s), p, o, m) # define BOOST_PP_FOR_102_I(s, p, o, m) BOOST_PP_IF(p(103, s), m, BOOST_PP_TUPLE_EAT_2)(103, s) BOOST_PP_IF(p(103, s), BOOST_PP_FOR_103, BOOST_PP_TUPLE_EAT_4)(o(103, s), p, o, m) # define BOOST_PP_FOR_103_I(s, p, o, m) BOOST_PP_IF(p(104, s), m, BOOST_PP_TUPLE_EAT_2)(104, s) BOOST_PP_IF(p(104, s), BOOST_PP_FOR_104, BOOST_PP_TUPLE_EAT_4)(o(104, s), p, o, m) # define BOOST_PP_FOR_104_I(s, p, o, m) BOOST_PP_IF(p(105, s), m, BOOST_PP_TUPLE_EAT_2)(105, s) BOOST_PP_IF(p(105, s), BOOST_PP_FOR_105, BOOST_PP_TUPLE_EAT_4)(o(105, s), p, o, m) # define BOOST_PP_FOR_105_I(s, p, o, m) BOOST_PP_IF(p(106, s), m, BOOST_PP_TUPLE_EAT_2)(106, s) BOOST_PP_IF(p(106, s), BOOST_PP_FOR_106, BOOST_PP_TUPLE_EAT_4)(o(106, s), p, o, m) # define BOOST_PP_FOR_106_I(s, p, o, m) BOOST_PP_IF(p(107, s), m, BOOST_PP_TUPLE_EAT_2)(107, s) BOOST_PP_IF(p(107, s), BOOST_PP_FOR_107, BOOST_PP_TUPLE_EAT_4)(o(107, s), p, o, m) # define BOOST_PP_FOR_107_I(s, p, o, m) BOOST_PP_IF(p(108, s), m, BOOST_PP_TUPLE_EAT_2)(108, s) BOOST_PP_IF(p(108, s), BOOST_PP_FOR_108, BOOST_PP_TUPLE_EAT_4)(o(108, s), p, o, m) # define BOOST_PP_FOR_108_I(s, p, o, m) BOOST_PP_IF(p(109, s), m, BOOST_PP_TUPLE_EAT_2)(109, s) BOOST_PP_IF(p(109, s), BOOST_PP_FOR_109, BOOST_PP_TUPLE_EAT_4)(o(109, s), p, o, m) # define BOOST_PP_FOR_109_I(s, p, o, m) BOOST_PP_IF(p(110, s), m, BOOST_PP_TUPLE_EAT_2)(110, s) BOOST_PP_IF(p(110, s), BOOST_PP_FOR_110, BOOST_PP_TUPLE_EAT_4)(o(110, s), p, o, m) # define BOOST_PP_FOR_110_I(s, p, o, m) BOOST_PP_IF(p(111, s), m, BOOST_PP_TUPLE_EAT_2)(111, s) BOOST_PP_IF(p(111, s), BOOST_PP_FOR_111, BOOST_PP_TUPLE_EAT_4)(o(111, s), p, o, m) # define BOOST_PP_FOR_111_I(s, p, o, m) BOOST_PP_IF(p(112, s), m, BOOST_PP_TUPLE_EAT_2)(112, s) BOOST_PP_IF(p(112, s), BOOST_PP_FOR_112, BOOST_PP_TUPLE_EAT_4)(o(112, s), p, o, m) # define BOOST_PP_FOR_112_I(s, p, o, m) BOOST_PP_IF(p(113, s), m, BOOST_PP_TUPLE_EAT_2)(113, s) BOOST_PP_IF(p(113, s), BOOST_PP_FOR_113, BOOST_PP_TUPLE_EAT_4)(o(113, s), p, o, m) # define BOOST_PP_FOR_113_I(s, p, o, m) BOOST_PP_IF(p(114, s), m, BOOST_PP_TUPLE_EAT_2)(114, s) BOOST_PP_IF(p(114, s), BOOST_PP_FOR_114, BOOST_PP_TUPLE_EAT_4)(o(114, s), p, o, m) # define BOOST_PP_FOR_114_I(s, p, o, m) BOOST_PP_IF(p(115, s), m, BOOST_PP_TUPLE_EAT_2)(115, s) BOOST_PP_IF(p(115, s), BOOST_PP_FOR_115, BOOST_PP_TUPLE_EAT_4)(o(115, s), p, o, m) # define BOOST_PP_FOR_115_I(s, p, o, m) BOOST_PP_IF(p(116, s), m, BOOST_PP_TUPLE_EAT_2)(116, s) BOOST_PP_IF(p(116, s), BOOST_PP_FOR_116, BOOST_PP_TUPLE_EAT_4)(o(116, s), p, o, m) # define BOOST_PP_FOR_116_I(s, p, o, m) BOOST_PP_IF(p(117, s), m, BOOST_PP_TUPLE_EAT_2)(117, s) BOOST_PP_IF(p(117, s), BOOST_PP_FOR_117, BOOST_PP_TUPLE_EAT_4)(o(117, s), p, o, m) # define BOOST_PP_FOR_117_I(s, p, o, m) BOOST_PP_IF(p(118, s), m, BOOST_PP_TUPLE_EAT_2)(118, s) BOOST_PP_IF(p(118, s), BOOST_PP_FOR_118, BOOST_PP_TUPLE_EAT_4)(o(118, s), p, o, m) # define BOOST_PP_FOR_118_I(s, p, o, m) BOOST_PP_IF(p(119, s), m, BOOST_PP_TUPLE_EAT_2)(119, s) BOOST_PP_IF(p(119, s), BOOST_PP_FOR_119, BOOST_PP_TUPLE_EAT_4)(o(119, s), p, o, m) # define BOOST_PP_FOR_119_I(s, p, o, m) BOOST_PP_IF(p(120, s), m, BOOST_PP_TUPLE_EAT_2)(120, s) BOOST_PP_IF(p(120, s), BOOST_PP_FOR_120, BOOST_PP_TUPLE_EAT_4)(o(120, s), p, o, m) # define BOOST_PP_FOR_120_I(s, p, o, m) BOOST_PP_IF(p(121, s), m, BOOST_PP_TUPLE_EAT_2)(121, s) BOOST_PP_IF(p(121, s), BOOST_PP_FOR_121, BOOST_PP_TUPLE_EAT_4)(o(121, s), p, o, m) # define BOOST_PP_FOR_121_I(s, p, o, m) BOOST_PP_IF(p(122, s), m, BOOST_PP_TUPLE_EAT_2)(122, s) BOOST_PP_IF(p(122, s), BOOST_PP_FOR_122, BOOST_PP_TUPLE_EAT_4)(o(122, s), p, o, m) # define BOOST_PP_FOR_122_I(s, p, o, m) BOOST_PP_IF(p(123, s), m, BOOST_PP_TUPLE_EAT_2)(123, s) BOOST_PP_IF(p(123, s), BOOST_PP_FOR_123, BOOST_PP_TUPLE_EAT_4)(o(123, s), p, o, m) # define BOOST_PP_FOR_123_I(s, p, o, m) BOOST_PP_IF(p(124, s), m, BOOST_PP_TUPLE_EAT_2)(124, s) BOOST_PP_IF(p(124, s), BOOST_PP_FOR_124, BOOST_PP_TUPLE_EAT_4)(o(124, s), p, o, m) # define BOOST_PP_FOR_124_I(s, p, o, m) BOOST_PP_IF(p(125, s), m, BOOST_PP_TUPLE_EAT_2)(125, s) BOOST_PP_IF(p(125, s), BOOST_PP_FOR_125, BOOST_PP_TUPLE_EAT_4)(o(125, s), p, o, m) # define BOOST_PP_FOR_125_I(s, p, o, m) BOOST_PP_IF(p(126, s), m, BOOST_PP_TUPLE_EAT_2)(126, s) BOOST_PP_IF(p(126, s), BOOST_PP_FOR_126, BOOST_PP_TUPLE_EAT_4)(o(126, s), p, o, m) # define BOOST_PP_FOR_126_I(s, p, o, m) BOOST_PP_IF(p(127, s), m, BOOST_PP_TUPLE_EAT_2)(127, s) BOOST_PP_IF(p(127, s), BOOST_PP_FOR_127, BOOST_PP_TUPLE_EAT_4)(o(127, s), p, o, m) # define BOOST_PP_FOR_127_I(s, p, o, m) BOOST_PP_IF(p(128, s), m, BOOST_PP_TUPLE_EAT_2)(128, s) BOOST_PP_IF(p(128, s), BOOST_PP_FOR_128, BOOST_PP_TUPLE_EAT_4)(o(128, s), p, o, m) # define BOOST_PP_FOR_128_I(s, p, o, m) BOOST_PP_IF(p(129, s), m, BOOST_PP_TUPLE_EAT_2)(129, s) BOOST_PP_IF(p(129, s), BOOST_PP_FOR_129, BOOST_PP_TUPLE_EAT_4)(o(129, s), p, o, m) # define BOOST_PP_FOR_129_I(s, p, o, m) BOOST_PP_IF(p(130, s), m, BOOST_PP_TUPLE_EAT_2)(130, s) BOOST_PP_IF(p(130, s), BOOST_PP_FOR_130, BOOST_PP_TUPLE_EAT_4)(o(130, s), p, o, m) # define BOOST_PP_FOR_130_I(s, p, o, m) BOOST_PP_IF(p(131, s), m, BOOST_PP_TUPLE_EAT_2)(131, s) BOOST_PP_IF(p(131, s), BOOST_PP_FOR_131, BOOST_PP_TUPLE_EAT_4)(o(131, s), p, o, m) # define BOOST_PP_FOR_131_I(s, p, o, m) BOOST_PP_IF(p(132, s), m, BOOST_PP_TUPLE_EAT_2)(132, s) BOOST_PP_IF(p(132, s), BOOST_PP_FOR_132, BOOST_PP_TUPLE_EAT_4)(o(132, s), p, o, m) # define BOOST_PP_FOR_132_I(s, p, o, m) BOOST_PP_IF(p(133, s), m, BOOST_PP_TUPLE_EAT_2)(133, s) BOOST_PP_IF(p(133, s), BOOST_PP_FOR_133, BOOST_PP_TUPLE_EAT_4)(o(133, s), p, o, m) # define BOOST_PP_FOR_133_I(s, p, o, m) BOOST_PP_IF(p(134, s), m, BOOST_PP_TUPLE_EAT_2)(134, s) BOOST_PP_IF(p(134, s), BOOST_PP_FOR_134, BOOST_PP_TUPLE_EAT_4)(o(134, s), p, o, m) # define BOOST_PP_FOR_134_I(s, p, o, m) BOOST_PP_IF(p(135, s), m, BOOST_PP_TUPLE_EAT_2)(135, s) BOOST_PP_IF(p(135, s), BOOST_PP_FOR_135, BOOST_PP_TUPLE_EAT_4)(o(135, s), p, o, m) # define BOOST_PP_FOR_135_I(s, p, o, m) BOOST_PP_IF(p(136, s), m, BOOST_PP_TUPLE_EAT_2)(136, s) BOOST_PP_IF(p(136, s), BOOST_PP_FOR_136, BOOST_PP_TUPLE_EAT_4)(o(136, s), p, o, m) # define BOOST_PP_FOR_136_I(s, p, o, m) BOOST_PP_IF(p(137, s), m, BOOST_PP_TUPLE_EAT_2)(137, s) BOOST_PP_IF(p(137, s), BOOST_PP_FOR_137, BOOST_PP_TUPLE_EAT_4)(o(137, s), p, o, m) # define BOOST_PP_FOR_137_I(s, p, o, m) BOOST_PP_IF(p(138, s), m, BOOST_PP_TUPLE_EAT_2)(138, s) BOOST_PP_IF(p(138, s), BOOST_PP_FOR_138, BOOST_PP_TUPLE_EAT_4)(o(138, s), p, o, m) # define BOOST_PP_FOR_138_I(s, p, o, m) BOOST_PP_IF(p(139, s), m, BOOST_PP_TUPLE_EAT_2)(139, s) BOOST_PP_IF(p(139, s), BOOST_PP_FOR_139, BOOST_PP_TUPLE_EAT_4)(o(139, s), p, o, m) # define BOOST_PP_FOR_139_I(s, p, o, m) BOOST_PP_IF(p(140, s), m, BOOST_PP_TUPLE_EAT_2)(140, s) BOOST_PP_IF(p(140, s), BOOST_PP_FOR_140, BOOST_PP_TUPLE_EAT_4)(o(140, s), p, o, m) # define BOOST_PP_FOR_140_I(s, p, o, m) BOOST_PP_IF(p(141, s), m, BOOST_PP_TUPLE_EAT_2)(141, s) BOOST_PP_IF(p(141, s), BOOST_PP_FOR_141, BOOST_PP_TUPLE_EAT_4)(o(141, s), p, o, m) # define BOOST_PP_FOR_141_I(s, p, o, m) BOOST_PP_IF(p(142, s), m, BOOST_PP_TUPLE_EAT_2)(142, s) BOOST_PP_IF(p(142, s), BOOST_PP_FOR_142, BOOST_PP_TUPLE_EAT_4)(o(142, s), p, o, m) # define BOOST_PP_FOR_142_I(s, p, o, m) BOOST_PP_IF(p(143, s), m, BOOST_PP_TUPLE_EAT_2)(143, s) BOOST_PP_IF(p(143, s), BOOST_PP_FOR_143, BOOST_PP_TUPLE_EAT_4)(o(143, s), p, o, m) # define BOOST_PP_FOR_143_I(s, p, o, m) BOOST_PP_IF(p(144, s), m, BOOST_PP_TUPLE_EAT_2)(144, s) BOOST_PP_IF(p(144, s), BOOST_PP_FOR_144, BOOST_PP_TUPLE_EAT_4)(o(144, s), p, o, m) # define BOOST_PP_FOR_144_I(s, p, o, m) BOOST_PP_IF(p(145, s), m, BOOST_PP_TUPLE_EAT_2)(145, s) BOOST_PP_IF(p(145, s), BOOST_PP_FOR_145, BOOST_PP_TUPLE_EAT_4)(o(145, s), p, o, m) # define BOOST_PP_FOR_145_I(s, p, o, m) BOOST_PP_IF(p(146, s), m, BOOST_PP_TUPLE_EAT_2)(146, s) BOOST_PP_IF(p(146, s), BOOST_PP_FOR_146, BOOST_PP_TUPLE_EAT_4)(o(146, s), p, o, m) # define BOOST_PP_FOR_146_I(s, p, o, m) BOOST_PP_IF(p(147, s), m, BOOST_PP_TUPLE_EAT_2)(147, s) BOOST_PP_IF(p(147, s), BOOST_PP_FOR_147, BOOST_PP_TUPLE_EAT_4)(o(147, s), p, o, m) # define BOOST_PP_FOR_147_I(s, p, o, m) BOOST_PP_IF(p(148, s), m, BOOST_PP_TUPLE_EAT_2)(148, s) BOOST_PP_IF(p(148, s), BOOST_PP_FOR_148, BOOST_PP_TUPLE_EAT_4)(o(148, s), p, o, m) # define BOOST_PP_FOR_148_I(s, p, o, m) BOOST_PP_IF(p(149, s), m, BOOST_PP_TUPLE_EAT_2)(149, s) BOOST_PP_IF(p(149, s), BOOST_PP_FOR_149, BOOST_PP_TUPLE_EAT_4)(o(149, s), p, o, m) # define BOOST_PP_FOR_149_I(s, p, o, m) BOOST_PP_IF(p(150, s), m, BOOST_PP_TUPLE_EAT_2)(150, s) BOOST_PP_IF(p(150, s), BOOST_PP_FOR_150, BOOST_PP_TUPLE_EAT_4)(o(150, s), p, o, m) # define BOOST_PP_FOR_150_I(s, p, o, m) BOOST_PP_IF(p(151, s), m, BOOST_PP_TUPLE_EAT_2)(151, s) BOOST_PP_IF(p(151, s), BOOST_PP_FOR_151, BOOST_PP_TUPLE_EAT_4)(o(151, s), p, o, m) # define BOOST_PP_FOR_151_I(s, p, o, m) BOOST_PP_IF(p(152, s), m, BOOST_PP_TUPLE_EAT_2)(152, s) BOOST_PP_IF(p(152, s), BOOST_PP_FOR_152, BOOST_PP_TUPLE_EAT_4)(o(152, s), p, o, m) # define BOOST_PP_FOR_152_I(s, p, o, m) BOOST_PP_IF(p(153, s), m, BOOST_PP_TUPLE_EAT_2)(153, s) BOOST_PP_IF(p(153, s), BOOST_PP_FOR_153, BOOST_PP_TUPLE_EAT_4)(o(153, s), p, o, m) # define BOOST_PP_FOR_153_I(s, p, o, m) BOOST_PP_IF(p(154, s), m, BOOST_PP_TUPLE_EAT_2)(154, s) BOOST_PP_IF(p(154, s), BOOST_PP_FOR_154, BOOST_PP_TUPLE_EAT_4)(o(154, s), p, o, m) # define BOOST_PP_FOR_154_I(s, p, o, m) BOOST_PP_IF(p(155, s), m, BOOST_PP_TUPLE_EAT_2)(155, s) BOOST_PP_IF(p(155, s), BOOST_PP_FOR_155, BOOST_PP_TUPLE_EAT_4)(o(155, s), p, o, m) # define BOOST_PP_FOR_155_I(s, p, o, m) BOOST_PP_IF(p(156, s), m, BOOST_PP_TUPLE_EAT_2)(156, s) BOOST_PP_IF(p(156, s), BOOST_PP_FOR_156, BOOST_PP_TUPLE_EAT_4)(o(156, s), p, o, m) # define BOOST_PP_FOR_156_I(s, p, o, m) BOOST_PP_IF(p(157, s), m, BOOST_PP_TUPLE_EAT_2)(157, s) BOOST_PP_IF(p(157, s), BOOST_PP_FOR_157, BOOST_PP_TUPLE_EAT_4)(o(157, s), p, o, m) # define BOOST_PP_FOR_157_I(s, p, o, m) BOOST_PP_IF(p(158, s), m, BOOST_PP_TUPLE_EAT_2)(158, s) BOOST_PP_IF(p(158, s), BOOST_PP_FOR_158, BOOST_PP_TUPLE_EAT_4)(o(158, s), p, o, m) # define BOOST_PP_FOR_158_I(s, p, o, m) BOOST_PP_IF(p(159, s), m, BOOST_PP_TUPLE_EAT_2)(159, s) BOOST_PP_IF(p(159, s), BOOST_PP_FOR_159, BOOST_PP_TUPLE_EAT_4)(o(159, s), p, o, m) # define BOOST_PP_FOR_159_I(s, p, o, m) BOOST_PP_IF(p(160, s), m, BOOST_PP_TUPLE_EAT_2)(160, s) BOOST_PP_IF(p(160, s), BOOST_PP_FOR_160, BOOST_PP_TUPLE_EAT_4)(o(160, s), p, o, m) # define BOOST_PP_FOR_160_I(s, p, o, m) BOOST_PP_IF(p(161, s), m, BOOST_PP_TUPLE_EAT_2)(161, s) BOOST_PP_IF(p(161, s), BOOST_PP_FOR_161, BOOST_PP_TUPLE_EAT_4)(o(161, s), p, o, m) # define BOOST_PP_FOR_161_I(s, p, o, m) BOOST_PP_IF(p(162, s), m, BOOST_PP_TUPLE_EAT_2)(162, s) BOOST_PP_IF(p(162, s), BOOST_PP_FOR_162, BOOST_PP_TUPLE_EAT_4)(o(162, s), p, o, m) # define BOOST_PP_FOR_162_I(s, p, o, m) BOOST_PP_IF(p(163, s), m, BOOST_PP_TUPLE_EAT_2)(163, s) BOOST_PP_IF(p(163, s), BOOST_PP_FOR_163, BOOST_PP_TUPLE_EAT_4)(o(163, s), p, o, m) # define BOOST_PP_FOR_163_I(s, p, o, m) BOOST_PP_IF(p(164, s), m, BOOST_PP_TUPLE_EAT_2)(164, s) BOOST_PP_IF(p(164, s), BOOST_PP_FOR_164, BOOST_PP_TUPLE_EAT_4)(o(164, s), p, o, m) # define BOOST_PP_FOR_164_I(s, p, o, m) BOOST_PP_IF(p(165, s), m, BOOST_PP_TUPLE_EAT_2)(165, s) BOOST_PP_IF(p(165, s), BOOST_PP_FOR_165, BOOST_PP_TUPLE_EAT_4)(o(165, s), p, o, m) # define BOOST_PP_FOR_165_I(s, p, o, m) BOOST_PP_IF(p(166, s), m, BOOST_PP_TUPLE_EAT_2)(166, s) BOOST_PP_IF(p(166, s), BOOST_PP_FOR_166, BOOST_PP_TUPLE_EAT_4)(o(166, s), p, o, m) # define BOOST_PP_FOR_166_I(s, p, o, m) BOOST_PP_IF(p(167, s), m, BOOST_PP_TUPLE_EAT_2)(167, s) BOOST_PP_IF(p(167, s), BOOST_PP_FOR_167, BOOST_PP_TUPLE_EAT_4)(o(167, s), p, o, m) # define BOOST_PP_FOR_167_I(s, p, o, m) BOOST_PP_IF(p(168, s), m, BOOST_PP_TUPLE_EAT_2)(168, s) BOOST_PP_IF(p(168, s), BOOST_PP_FOR_168, BOOST_PP_TUPLE_EAT_4)(o(168, s), p, o, m) # define BOOST_PP_FOR_168_I(s, p, o, m) BOOST_PP_IF(p(169, s), m, BOOST_PP_TUPLE_EAT_2)(169, s) BOOST_PP_IF(p(169, s), BOOST_PP_FOR_169, BOOST_PP_TUPLE_EAT_4)(o(169, s), p, o, m) # define BOOST_PP_FOR_169_I(s, p, o, m) BOOST_PP_IF(p(170, s), m, BOOST_PP_TUPLE_EAT_2)(170, s) BOOST_PP_IF(p(170, s), BOOST_PP_FOR_170, BOOST_PP_TUPLE_EAT_4)(o(170, s), p, o, m) # define BOOST_PP_FOR_170_I(s, p, o, m) BOOST_PP_IF(p(171, s), m, BOOST_PP_TUPLE_EAT_2)(171, s) BOOST_PP_IF(p(171, s), BOOST_PP_FOR_171, BOOST_PP_TUPLE_EAT_4)(o(171, s), p, o, m) # define BOOST_PP_FOR_171_I(s, p, o, m) BOOST_PP_IF(p(172, s), m, BOOST_PP_TUPLE_EAT_2)(172, s) BOOST_PP_IF(p(172, s), BOOST_PP_FOR_172, BOOST_PP_TUPLE_EAT_4)(o(172, s), p, o, m) # define BOOST_PP_FOR_172_I(s, p, o, m) BOOST_PP_IF(p(173, s), m, BOOST_PP_TUPLE_EAT_2)(173, s) BOOST_PP_IF(p(173, s), BOOST_PP_FOR_173, BOOST_PP_TUPLE_EAT_4)(o(173, s), p, o, m) # define BOOST_PP_FOR_173_I(s, p, o, m) BOOST_PP_IF(p(174, s), m, BOOST_PP_TUPLE_EAT_2)(174, s) BOOST_PP_IF(p(174, s), BOOST_PP_FOR_174, BOOST_PP_TUPLE_EAT_4)(o(174, s), p, o, m) # define BOOST_PP_FOR_174_I(s, p, o, m) BOOST_PP_IF(p(175, s), m, BOOST_PP_TUPLE_EAT_2)(175, s) BOOST_PP_IF(p(175, s), BOOST_PP_FOR_175, BOOST_PP_TUPLE_EAT_4)(o(175, s), p, o, m) # define BOOST_PP_FOR_175_I(s, p, o, m) BOOST_PP_IF(p(176, s), m, BOOST_PP_TUPLE_EAT_2)(176, s) BOOST_PP_IF(p(176, s), BOOST_PP_FOR_176, BOOST_PP_TUPLE_EAT_4)(o(176, s), p, o, m) # define BOOST_PP_FOR_176_I(s, p, o, m) BOOST_PP_IF(p(177, s), m, BOOST_PP_TUPLE_EAT_2)(177, s) BOOST_PP_IF(p(177, s), BOOST_PP_FOR_177, BOOST_PP_TUPLE_EAT_4)(o(177, s), p, o, m) # define BOOST_PP_FOR_177_I(s, p, o, m) BOOST_PP_IF(p(178, s), m, BOOST_PP_TUPLE_EAT_2)(178, s) BOOST_PP_IF(p(178, s), BOOST_PP_FOR_178, BOOST_PP_TUPLE_EAT_4)(o(178, s), p, o, m) # define BOOST_PP_FOR_178_I(s, p, o, m) BOOST_PP_IF(p(179, s), m, BOOST_PP_TUPLE_EAT_2)(179, s) BOOST_PP_IF(p(179, s), BOOST_PP_FOR_179, BOOST_PP_TUPLE_EAT_4)(o(179, s), p, o, m) # define BOOST_PP_FOR_179_I(s, p, o, m) BOOST_PP_IF(p(180, s), m, BOOST_PP_TUPLE_EAT_2)(180, s) BOOST_PP_IF(p(180, s), BOOST_PP_FOR_180, BOOST_PP_TUPLE_EAT_4)(o(180, s), p, o, m) # define BOOST_PP_FOR_180_I(s, p, o, m) BOOST_PP_IF(p(181, s), m, BOOST_PP_TUPLE_EAT_2)(181, s) BOOST_PP_IF(p(181, s), BOOST_PP_FOR_181, BOOST_PP_TUPLE_EAT_4)(o(181, s), p, o, m) # define BOOST_PP_FOR_181_I(s, p, o, m) BOOST_PP_IF(p(182, s), m, BOOST_PP_TUPLE_EAT_2)(182, s) BOOST_PP_IF(p(182, s), BOOST_PP_FOR_182, BOOST_PP_TUPLE_EAT_4)(o(182, s), p, o, m) # define BOOST_PP_FOR_182_I(s, p, o, m) BOOST_PP_IF(p(183, s), m, BOOST_PP_TUPLE_EAT_2)(183, s) BOOST_PP_IF(p(183, s), BOOST_PP_FOR_183, BOOST_PP_TUPLE_EAT_4)(o(183, s), p, o, m) # define BOOST_PP_FOR_183_I(s, p, o, m) BOOST_PP_IF(p(184, s), m, BOOST_PP_TUPLE_EAT_2)(184, s) BOOST_PP_IF(p(184, s), BOOST_PP_FOR_184, BOOST_PP_TUPLE_EAT_4)(o(184, s), p, o, m) # define BOOST_PP_FOR_184_I(s, p, o, m) BOOST_PP_IF(p(185, s), m, BOOST_PP_TUPLE_EAT_2)(185, s) BOOST_PP_IF(p(185, s), BOOST_PP_FOR_185, BOOST_PP_TUPLE_EAT_4)(o(185, s), p, o, m) # define BOOST_PP_FOR_185_I(s, p, o, m) BOOST_PP_IF(p(186, s), m, BOOST_PP_TUPLE_EAT_2)(186, s) BOOST_PP_IF(p(186, s), BOOST_PP_FOR_186, BOOST_PP_TUPLE_EAT_4)(o(186, s), p, o, m) # define BOOST_PP_FOR_186_I(s, p, o, m) BOOST_PP_IF(p(187, s), m, BOOST_PP_TUPLE_EAT_2)(187, s) BOOST_PP_IF(p(187, s), BOOST_PP_FOR_187, BOOST_PP_TUPLE_EAT_4)(o(187, s), p, o, m) # define BOOST_PP_FOR_187_I(s, p, o, m) BOOST_PP_IF(p(188, s), m, BOOST_PP_TUPLE_EAT_2)(188, s) BOOST_PP_IF(p(188, s), BOOST_PP_FOR_188, BOOST_PP_TUPLE_EAT_4)(o(188, s), p, o, m) # define BOOST_PP_FOR_188_I(s, p, o, m) BOOST_PP_IF(p(189, s), m, BOOST_PP_TUPLE_EAT_2)(189, s) BOOST_PP_IF(p(189, s), BOOST_PP_FOR_189, BOOST_PP_TUPLE_EAT_4)(o(189, s), p, o, m) # define BOOST_PP_FOR_189_I(s, p, o, m) BOOST_PP_IF(p(190, s), m, BOOST_PP_TUPLE_EAT_2)(190, s) BOOST_PP_IF(p(190, s), BOOST_PP_FOR_190, BOOST_PP_TUPLE_EAT_4)(o(190, s), p, o, m) # define BOOST_PP_FOR_190_I(s, p, o, m) BOOST_PP_IF(p(191, s), m, BOOST_PP_TUPLE_EAT_2)(191, s) BOOST_PP_IF(p(191, s), BOOST_PP_FOR_191, BOOST_PP_TUPLE_EAT_4)(o(191, s), p, o, m) # define BOOST_PP_FOR_191_I(s, p, o, m) BOOST_PP_IF(p(192, s), m, BOOST_PP_TUPLE_EAT_2)(192, s) BOOST_PP_IF(p(192, s), BOOST_PP_FOR_192, BOOST_PP_TUPLE_EAT_4)(o(192, s), p, o, m) # define BOOST_PP_FOR_192_I(s, p, o, m) BOOST_PP_IF(p(193, s), m, BOOST_PP_TUPLE_EAT_2)(193, s) BOOST_PP_IF(p(193, s), BOOST_PP_FOR_193, BOOST_PP_TUPLE_EAT_4)(o(193, s), p, o, m) # define BOOST_PP_FOR_193_I(s, p, o, m) BOOST_PP_IF(p(194, s), m, BOOST_PP_TUPLE_EAT_2)(194, s) BOOST_PP_IF(p(194, s), BOOST_PP_FOR_194, BOOST_PP_TUPLE_EAT_4)(o(194, s), p, o, m) # define BOOST_PP_FOR_194_I(s, p, o, m) BOOST_PP_IF(p(195, s), m, BOOST_PP_TUPLE_EAT_2)(195, s) BOOST_PP_IF(p(195, s), BOOST_PP_FOR_195, BOOST_PP_TUPLE_EAT_4)(o(195, s), p, o, m) # define BOOST_PP_FOR_195_I(s, p, o, m) BOOST_PP_IF(p(196, s), m, BOOST_PP_TUPLE_EAT_2)(196, s) BOOST_PP_IF(p(196, s), BOOST_PP_FOR_196, BOOST_PP_TUPLE_EAT_4)(o(196, s), p, o, m) # define BOOST_PP_FOR_196_I(s, p, o, m) BOOST_PP_IF(p(197, s), m, BOOST_PP_TUPLE_EAT_2)(197, s) BOOST_PP_IF(p(197, s), BOOST_PP_FOR_197, BOOST_PP_TUPLE_EAT_4)(o(197, s), p, o, m) # define BOOST_PP_FOR_197_I(s, p, o, m) BOOST_PP_IF(p(198, s), m, BOOST_PP_TUPLE_EAT_2)(198, s) BOOST_PP_IF(p(198, s), BOOST_PP_FOR_198, BOOST_PP_TUPLE_EAT_4)(o(198, s), p, o, m) # define BOOST_PP_FOR_198_I(s, p, o, m) BOOST_PP_IF(p(199, s), m, BOOST_PP_TUPLE_EAT_2)(199, s) BOOST_PP_IF(p(199, s), BOOST_PP_FOR_199, BOOST_PP_TUPLE_EAT_4)(o(199, s), p, o, m) # define BOOST_PP_FOR_199_I(s, p, o, m) BOOST_PP_IF(p(200, s), m, BOOST_PP_TUPLE_EAT_2)(200, s) BOOST_PP_IF(p(200, s), BOOST_PP_FOR_200, BOOST_PP_TUPLE_EAT_4)(o(200, s), p, o, m) # define BOOST_PP_FOR_200_I(s, p, o, m) BOOST_PP_IF(p(201, s), m, BOOST_PP_TUPLE_EAT_2)(201, s) BOOST_PP_IF(p(201, s), BOOST_PP_FOR_201, BOOST_PP_TUPLE_EAT_4)(o(201, s), p, o, m) # define BOOST_PP_FOR_201_I(s, p, o, m) BOOST_PP_IF(p(202, s), m, BOOST_PP_TUPLE_EAT_2)(202, s) BOOST_PP_IF(p(202, s), BOOST_PP_FOR_202, BOOST_PP_TUPLE_EAT_4)(o(202, s), p, o, m) # define BOOST_PP_FOR_202_I(s, p, o, m) BOOST_PP_IF(p(203, s), m, BOOST_PP_TUPLE_EAT_2)(203, s) BOOST_PP_IF(p(203, s), BOOST_PP_FOR_203, BOOST_PP_TUPLE_EAT_4)(o(203, s), p, o, m) # define BOOST_PP_FOR_203_I(s, p, o, m) BOOST_PP_IF(p(204, s), m, BOOST_PP_TUPLE_EAT_2)(204, s) BOOST_PP_IF(p(204, s), BOOST_PP_FOR_204, BOOST_PP_TUPLE_EAT_4)(o(204, s), p, o, m) # define BOOST_PP_FOR_204_I(s, p, o, m) BOOST_PP_IF(p(205, s), m, BOOST_PP_TUPLE_EAT_2)(205, s) BOOST_PP_IF(p(205, s), BOOST_PP_FOR_205, BOOST_PP_TUPLE_EAT_4)(o(205, s), p, o, m) # define BOOST_PP_FOR_205_I(s, p, o, m) BOOST_PP_IF(p(206, s), m, BOOST_PP_TUPLE_EAT_2)(206, s) BOOST_PP_IF(p(206, s), BOOST_PP_FOR_206, BOOST_PP_TUPLE_EAT_4)(o(206, s), p, o, m) # define BOOST_PP_FOR_206_I(s, p, o, m) BOOST_PP_IF(p(207, s), m, BOOST_PP_TUPLE_EAT_2)(207, s) BOOST_PP_IF(p(207, s), BOOST_PP_FOR_207, BOOST_PP_TUPLE_EAT_4)(o(207, s), p, o, m) # define BOOST_PP_FOR_207_I(s, p, o, m) BOOST_PP_IF(p(208, s), m, BOOST_PP_TUPLE_EAT_2)(208, s) BOOST_PP_IF(p(208, s), BOOST_PP_FOR_208, BOOST_PP_TUPLE_EAT_4)(o(208, s), p, o, m) # define BOOST_PP_FOR_208_I(s, p, o, m) BOOST_PP_IF(p(209, s), m, BOOST_PP_TUPLE_EAT_2)(209, s) BOOST_PP_IF(p(209, s), BOOST_PP_FOR_209, BOOST_PP_TUPLE_EAT_4)(o(209, s), p, o, m) # define BOOST_PP_FOR_209_I(s, p, o, m) BOOST_PP_IF(p(210, s), m, BOOST_PP_TUPLE_EAT_2)(210, s) BOOST_PP_IF(p(210, s), BOOST_PP_FOR_210, BOOST_PP_TUPLE_EAT_4)(o(210, s), p, o, m) # define BOOST_PP_FOR_210_I(s, p, o, m) BOOST_PP_IF(p(211, s), m, BOOST_PP_TUPLE_EAT_2)(211, s) BOOST_PP_IF(p(211, s), BOOST_PP_FOR_211, BOOST_PP_TUPLE_EAT_4)(o(211, s), p, o, m) # define BOOST_PP_FOR_211_I(s, p, o, m) BOOST_PP_IF(p(212, s), m, BOOST_PP_TUPLE_EAT_2)(212, s) BOOST_PP_IF(p(212, s), BOOST_PP_FOR_212, BOOST_PP_TUPLE_EAT_4)(o(212, s), p, o, m) # define BOOST_PP_FOR_212_I(s, p, o, m) BOOST_PP_IF(p(213, s), m, BOOST_PP_TUPLE_EAT_2)(213, s) BOOST_PP_IF(p(213, s), BOOST_PP_FOR_213, BOOST_PP_TUPLE_EAT_4)(o(213, s), p, o, m) # define BOOST_PP_FOR_213_I(s, p, o, m) BOOST_PP_IF(p(214, s), m, BOOST_PP_TUPLE_EAT_2)(214, s) BOOST_PP_IF(p(214, s), BOOST_PP_FOR_214, BOOST_PP_TUPLE_EAT_4)(o(214, s), p, o, m) # define BOOST_PP_FOR_214_I(s, p, o, m) BOOST_PP_IF(p(215, s), m, BOOST_PP_TUPLE_EAT_2)(215, s) BOOST_PP_IF(p(215, s), BOOST_PP_FOR_215, BOOST_PP_TUPLE_EAT_4)(o(215, s), p, o, m) # define BOOST_PP_FOR_215_I(s, p, o, m) BOOST_PP_IF(p(216, s), m, BOOST_PP_TUPLE_EAT_2)(216, s) BOOST_PP_IF(p(216, s), BOOST_PP_FOR_216, BOOST_PP_TUPLE_EAT_4)(o(216, s), p, o, m) # define BOOST_PP_FOR_216_I(s, p, o, m) BOOST_PP_IF(p(217, s), m, BOOST_PP_TUPLE_EAT_2)(217, s) BOOST_PP_IF(p(217, s), BOOST_PP_FOR_217, BOOST_PP_TUPLE_EAT_4)(o(217, s), p, o, m) # define BOOST_PP_FOR_217_I(s, p, o, m) BOOST_PP_IF(p(218, s), m, BOOST_PP_TUPLE_EAT_2)(218, s) BOOST_PP_IF(p(218, s), BOOST_PP_FOR_218, BOOST_PP_TUPLE_EAT_4)(o(218, s), p, o, m) # define BOOST_PP_FOR_218_I(s, p, o, m) BOOST_PP_IF(p(219, s), m, BOOST_PP_TUPLE_EAT_2)(219, s) BOOST_PP_IF(p(219, s), BOOST_PP_FOR_219, BOOST_PP_TUPLE_EAT_4)(o(219, s), p, o, m) # define BOOST_PP_FOR_219_I(s, p, o, m) BOOST_PP_IF(p(220, s), m, BOOST_PP_TUPLE_EAT_2)(220, s) BOOST_PP_IF(p(220, s), BOOST_PP_FOR_220, BOOST_PP_TUPLE_EAT_4)(o(220, s), p, o, m) # define BOOST_PP_FOR_220_I(s, p, o, m) BOOST_PP_IF(p(221, s), m, BOOST_PP_TUPLE_EAT_2)(221, s) BOOST_PP_IF(p(221, s), BOOST_PP_FOR_221, BOOST_PP_TUPLE_EAT_4)(o(221, s), p, o, m) # define BOOST_PP_FOR_221_I(s, p, o, m) BOOST_PP_IF(p(222, s), m, BOOST_PP_TUPLE_EAT_2)(222, s) BOOST_PP_IF(p(222, s), BOOST_PP_FOR_222, BOOST_PP_TUPLE_EAT_4)(o(222, s), p, o, m) # define BOOST_PP_FOR_222_I(s, p, o, m) BOOST_PP_IF(p(223, s), m, BOOST_PP_TUPLE_EAT_2)(223, s) BOOST_PP_IF(p(223, s), BOOST_PP_FOR_223, BOOST_PP_TUPLE_EAT_4)(o(223, s), p, o, m) # define BOOST_PP_FOR_223_I(s, p, o, m) BOOST_PP_IF(p(224, s), m, BOOST_PP_TUPLE_EAT_2)(224, s) BOOST_PP_IF(p(224, s), BOOST_PP_FOR_224, BOOST_PP_TUPLE_EAT_4)(o(224, s), p, o, m) # define BOOST_PP_FOR_224_I(s, p, o, m) BOOST_PP_IF(p(225, s), m, BOOST_PP_TUPLE_EAT_2)(225, s) BOOST_PP_IF(p(225, s), BOOST_PP_FOR_225, BOOST_PP_TUPLE_EAT_4)(o(225, s), p, o, m) # define BOOST_PP_FOR_225_I(s, p, o, m) BOOST_PP_IF(p(226, s), m, BOOST_PP_TUPLE_EAT_2)(226, s) BOOST_PP_IF(p(226, s), BOOST_PP_FOR_226, BOOST_PP_TUPLE_EAT_4)(o(226, s), p, o, m) # define BOOST_PP_FOR_226_I(s, p, o, m) BOOST_PP_IF(p(227, s), m, BOOST_PP_TUPLE_EAT_2)(227, s) BOOST_PP_IF(p(227, s), BOOST_PP_FOR_227, BOOST_PP_TUPLE_EAT_4)(o(227, s), p, o, m) # define BOOST_PP_FOR_227_I(s, p, o, m) BOOST_PP_IF(p(228, s), m, BOOST_PP_TUPLE_EAT_2)(228, s) BOOST_PP_IF(p(228, s), BOOST_PP_FOR_228, BOOST_PP_TUPLE_EAT_4)(o(228, s), p, o, m) # define BOOST_PP_FOR_228_I(s, p, o, m) BOOST_PP_IF(p(229, s), m, BOOST_PP_TUPLE_EAT_2)(229, s) BOOST_PP_IF(p(229, s), BOOST_PP_FOR_229, BOOST_PP_TUPLE_EAT_4)(o(229, s), p, o, m) # define BOOST_PP_FOR_229_I(s, p, o, m) BOOST_PP_IF(p(230, s), m, BOOST_PP_TUPLE_EAT_2)(230, s) BOOST_PP_IF(p(230, s), BOOST_PP_FOR_230, BOOST_PP_TUPLE_EAT_4)(o(230, s), p, o, m) # define BOOST_PP_FOR_230_I(s, p, o, m) BOOST_PP_IF(p(231, s), m, BOOST_PP_TUPLE_EAT_2)(231, s) BOOST_PP_IF(p(231, s), BOOST_PP_FOR_231, BOOST_PP_TUPLE_EAT_4)(o(231, s), p, o, m) # define BOOST_PP_FOR_231_I(s, p, o, m) BOOST_PP_IF(p(232, s), m, BOOST_PP_TUPLE_EAT_2)(232, s) BOOST_PP_IF(p(232, s), BOOST_PP_FOR_232, BOOST_PP_TUPLE_EAT_4)(o(232, s), p, o, m) # define BOOST_PP_FOR_232_I(s, p, o, m) BOOST_PP_IF(p(233, s), m, BOOST_PP_TUPLE_EAT_2)(233, s) BOOST_PP_IF(p(233, s), BOOST_PP_FOR_233, BOOST_PP_TUPLE_EAT_4)(o(233, s), p, o, m) # define BOOST_PP_FOR_233_I(s, p, o, m) BOOST_PP_IF(p(234, s), m, BOOST_PP_TUPLE_EAT_2)(234, s) BOOST_PP_IF(p(234, s), BOOST_PP_FOR_234, BOOST_PP_TUPLE_EAT_4)(o(234, s), p, o, m) # define BOOST_PP_FOR_234_I(s, p, o, m) BOOST_PP_IF(p(235, s), m, BOOST_PP_TUPLE_EAT_2)(235, s) BOOST_PP_IF(p(235, s), BOOST_PP_FOR_235, BOOST_PP_TUPLE_EAT_4)(o(235, s), p, o, m) # define BOOST_PP_FOR_235_I(s, p, o, m) BOOST_PP_IF(p(236, s), m, BOOST_PP_TUPLE_EAT_2)(236, s) BOOST_PP_IF(p(236, s), BOOST_PP_FOR_236, BOOST_PP_TUPLE_EAT_4)(o(236, s), p, o, m) # define BOOST_PP_FOR_236_I(s, p, o, m) BOOST_PP_IF(p(237, s), m, BOOST_PP_TUPLE_EAT_2)(237, s) BOOST_PP_IF(p(237, s), BOOST_PP_FOR_237, BOOST_PP_TUPLE_EAT_4)(o(237, s), p, o, m) # define BOOST_PP_FOR_237_I(s, p, o, m) BOOST_PP_IF(p(238, s), m, BOOST_PP_TUPLE_EAT_2)(238, s) BOOST_PP_IF(p(238, s), BOOST_PP_FOR_238, BOOST_PP_TUPLE_EAT_4)(o(238, s), p, o, m) # define BOOST_PP_FOR_238_I(s, p, o, m) BOOST_PP_IF(p(239, s), m, BOOST_PP_TUPLE_EAT_2)(239, s) BOOST_PP_IF(p(239, s), BOOST_PP_FOR_239, BOOST_PP_TUPLE_EAT_4)(o(239, s), p, o, m) # define BOOST_PP_FOR_239_I(s, p, o, m) BOOST_PP_IF(p(240, s), m, BOOST_PP_TUPLE_EAT_2)(240, s) BOOST_PP_IF(p(240, s), BOOST_PP_FOR_240, BOOST_PP_TUPLE_EAT_4)(o(240, s), p, o, m) # define BOOST_PP_FOR_240_I(s, p, o, m) BOOST_PP_IF(p(241, s), m, BOOST_PP_TUPLE_EAT_2)(241, s) BOOST_PP_IF(p(241, s), BOOST_PP_FOR_241, BOOST_PP_TUPLE_EAT_4)(o(241, s), p, o, m) # define BOOST_PP_FOR_241_I(s, p, o, m) BOOST_PP_IF(p(242, s), m, BOOST_PP_TUPLE_EAT_2)(242, s) BOOST_PP_IF(p(242, s), BOOST_PP_FOR_242, BOOST_PP_TUPLE_EAT_4)(o(242, s), p, o, m) # define BOOST_PP_FOR_242_I(s, p, o, m) BOOST_PP_IF(p(243, s), m, BOOST_PP_TUPLE_EAT_2)(243, s) BOOST_PP_IF(p(243, s), BOOST_PP_FOR_243, BOOST_PP_TUPLE_EAT_4)(o(243, s), p, o, m) # define BOOST_PP_FOR_243_I(s, p, o, m) BOOST_PP_IF(p(244, s), m, BOOST_PP_TUPLE_EAT_2)(244, s) BOOST_PP_IF(p(244, s), BOOST_PP_FOR_244, BOOST_PP_TUPLE_EAT_4)(o(244, s), p, o, m) # define BOOST_PP_FOR_244_I(s, p, o, m) BOOST_PP_IF(p(245, s), m, BOOST_PP_TUPLE_EAT_2)(245, s) BOOST_PP_IF(p(245, s), BOOST_PP_FOR_245, BOOST_PP_TUPLE_EAT_4)(o(245, s), p, o, m) # define BOOST_PP_FOR_245_I(s, p, o, m) BOOST_PP_IF(p(246, s), m, BOOST_PP_TUPLE_EAT_2)(246, s) BOOST_PP_IF(p(246, s), BOOST_PP_FOR_246, BOOST_PP_TUPLE_EAT_4)(o(246, s), p, o, m) # define BOOST_PP_FOR_246_I(s, p, o, m) BOOST_PP_IF(p(247, s), m, BOOST_PP_TUPLE_EAT_2)(247, s) BOOST_PP_IF(p(247, s), BOOST_PP_FOR_247, BOOST_PP_TUPLE_EAT_4)(o(247, s), p, o, m) # define BOOST_PP_FOR_247_I(s, p, o, m) BOOST_PP_IF(p(248, s), m, BOOST_PP_TUPLE_EAT_2)(248, s) BOOST_PP_IF(p(248, s), BOOST_PP_FOR_248, BOOST_PP_TUPLE_EAT_4)(o(248, s), p, o, m) # define BOOST_PP_FOR_248_I(s, p, o, m) BOOST_PP_IF(p(249, s), m, BOOST_PP_TUPLE_EAT_2)(249, s) BOOST_PP_IF(p(249, s), BOOST_PP_FOR_249, BOOST_PP_TUPLE_EAT_4)(o(249, s), p, o, m) # define BOOST_PP_FOR_249_I(s, p, o, m) BOOST_PP_IF(p(250, s), m, BOOST_PP_TUPLE_EAT_2)(250, s) BOOST_PP_IF(p(250, s), BOOST_PP_FOR_250, BOOST_PP_TUPLE_EAT_4)(o(250, s), p, o, m) # define BOOST_PP_FOR_250_I(s, p, o, m) BOOST_PP_IF(p(251, s), m, BOOST_PP_TUPLE_EAT_2)(251, s) BOOST_PP_IF(p(251, s), BOOST_PP_FOR_251, BOOST_PP_TUPLE_EAT_4)(o(251, s), p, o, m) # define BOOST_PP_FOR_251_I(s, p, o, m) BOOST_PP_IF(p(252, s), m, BOOST_PP_TUPLE_EAT_2)(252, s) BOOST_PP_IF(p(252, s), BOOST_PP_FOR_252, BOOST_PP_TUPLE_EAT_4)(o(252, s), p, o, m) # define BOOST_PP_FOR_252_I(s, p, o, m) BOOST_PP_IF(p(253, s), m, BOOST_PP_TUPLE_EAT_2)(253, s) BOOST_PP_IF(p(253, s), BOOST_PP_FOR_253, BOOST_PP_TUPLE_EAT_4)(o(253, s), p, o, m) # define BOOST_PP_FOR_253_I(s, p, o, m) BOOST_PP_IF(p(254, s), m, BOOST_PP_TUPLE_EAT_2)(254, s) BOOST_PP_IF(p(254, s), BOOST_PP_FOR_254, BOOST_PP_TUPLE_EAT_4)(o(254, s), p, o, m) # define BOOST_PP_FOR_254_I(s, p, o, m) BOOST_PP_IF(p(255, s), m, BOOST_PP_TUPLE_EAT_2)(255, s) BOOST_PP_IF(p(255, s), BOOST_PP_FOR_255, BOOST_PP_TUPLE_EAT_4)(o(255, s), p, o, m) # define BOOST_PP_FOR_255_I(s, p, o, m) BOOST_PP_IF(p(256, s), m, BOOST_PP_TUPLE_EAT_2)(256, s) BOOST_PP_IF(p(256, s), BOOST_PP_FOR_256, BOOST_PP_TUPLE_EAT_4)(o(256, s), p, o, m) # define BOOST_PP_FOR_256_I(s, p, o, m) BOOST_PP_IF(p(257, s), m, BOOST_PP_TUPLE_EAT_2)(257, s) BOOST_PP_IF(p(257, s), BOOST_PP_FOR_257, BOOST_PP_TUPLE_EAT_4)(o(257, s), p, o, m) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/detail/for.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_DETAIL_FOR_HPP # define BOOST_PREPROCESSOR_REPETITION_DETAIL_FOR_HPP # # include # include # include # include # # define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_FOR_1_C(BOOST_PP_BOOL(p(2, s)), s, p, o, m) # define BOOST_PP_FOR_2(s, p, o, m) BOOST_PP_FOR_2_C(BOOST_PP_BOOL(p(3, s)), s, p, o, m) # define BOOST_PP_FOR_3(s, p, o, m) BOOST_PP_FOR_3_C(BOOST_PP_BOOL(p(4, s)), s, p, o, m) # define BOOST_PP_FOR_4(s, p, o, m) BOOST_PP_FOR_4_C(BOOST_PP_BOOL(p(5, s)), s, p, o, m) # define BOOST_PP_FOR_5(s, p, o, m) BOOST_PP_FOR_5_C(BOOST_PP_BOOL(p(6, s)), s, p, o, m) # define BOOST_PP_FOR_6(s, p, o, m) BOOST_PP_FOR_6_C(BOOST_PP_BOOL(p(7, s)), s, p, o, m) # define BOOST_PP_FOR_7(s, p, o, m) BOOST_PP_FOR_7_C(BOOST_PP_BOOL(p(8, s)), s, p, o, m) # define BOOST_PP_FOR_8(s, p, o, m) BOOST_PP_FOR_8_C(BOOST_PP_BOOL(p(9, s)), s, p, o, m) # define BOOST_PP_FOR_9(s, p, o, m) BOOST_PP_FOR_9_C(BOOST_PP_BOOL(p(10, s)), s, p, o, m) # define BOOST_PP_FOR_10(s, p, o, m) BOOST_PP_FOR_10_C(BOOST_PP_BOOL(p(11, s)), s, p, o, m) # define BOOST_PP_FOR_11(s, p, o, m) BOOST_PP_FOR_11_C(BOOST_PP_BOOL(p(12, s)), s, p, o, m) # define BOOST_PP_FOR_12(s, p, o, m) BOOST_PP_FOR_12_C(BOOST_PP_BOOL(p(13, s)), s, p, o, m) # define BOOST_PP_FOR_13(s, p, o, m) BOOST_PP_FOR_13_C(BOOST_PP_BOOL(p(14, s)), s, p, o, m) # define BOOST_PP_FOR_14(s, p, o, m) BOOST_PP_FOR_14_C(BOOST_PP_BOOL(p(15, s)), s, p, o, m) # define BOOST_PP_FOR_15(s, p, o, m) BOOST_PP_FOR_15_C(BOOST_PP_BOOL(p(16, s)), s, p, o, m) # define BOOST_PP_FOR_16(s, p, o, m) BOOST_PP_FOR_16_C(BOOST_PP_BOOL(p(17, s)), s, p, o, m) # define BOOST_PP_FOR_17(s, p, o, m) BOOST_PP_FOR_17_C(BOOST_PP_BOOL(p(18, s)), s, p, o, m) # define BOOST_PP_FOR_18(s, p, o, m) BOOST_PP_FOR_18_C(BOOST_PP_BOOL(p(19, s)), s, p, o, m) # define BOOST_PP_FOR_19(s, p, o, m) BOOST_PP_FOR_19_C(BOOST_PP_BOOL(p(20, s)), s, p, o, m) # define BOOST_PP_FOR_20(s, p, o, m) BOOST_PP_FOR_20_C(BOOST_PP_BOOL(p(21, s)), s, p, o, m) # define BOOST_PP_FOR_21(s, p, o, m) BOOST_PP_FOR_21_C(BOOST_PP_BOOL(p(22, s)), s, p, o, m) # define BOOST_PP_FOR_22(s, p, o, m) BOOST_PP_FOR_22_C(BOOST_PP_BOOL(p(23, s)), s, p, o, m) # define BOOST_PP_FOR_23(s, p, o, m) BOOST_PP_FOR_23_C(BOOST_PP_BOOL(p(24, s)), s, p, o, m) # define BOOST_PP_FOR_24(s, p, o, m) BOOST_PP_FOR_24_C(BOOST_PP_BOOL(p(25, s)), s, p, o, m) # define BOOST_PP_FOR_25(s, p, o, m) BOOST_PP_FOR_25_C(BOOST_PP_BOOL(p(26, s)), s, p, o, m) # define BOOST_PP_FOR_26(s, p, o, m) BOOST_PP_FOR_26_C(BOOST_PP_BOOL(p(27, s)), s, p, o, m) # define BOOST_PP_FOR_27(s, p, o, m) BOOST_PP_FOR_27_C(BOOST_PP_BOOL(p(28, s)), s, p, o, m) # define BOOST_PP_FOR_28(s, p, o, m) BOOST_PP_FOR_28_C(BOOST_PP_BOOL(p(29, s)), s, p, o, m) # define BOOST_PP_FOR_29(s, p, o, m) BOOST_PP_FOR_29_C(BOOST_PP_BOOL(p(30, s)), s, p, o, m) # define BOOST_PP_FOR_30(s, p, o, m) BOOST_PP_FOR_30_C(BOOST_PP_BOOL(p(31, s)), s, p, o, m) # define BOOST_PP_FOR_31(s, p, o, m) BOOST_PP_FOR_31_C(BOOST_PP_BOOL(p(32, s)), s, p, o, m) # define BOOST_PP_FOR_32(s, p, o, m) BOOST_PP_FOR_32_C(BOOST_PP_BOOL(p(33, s)), s, p, o, m) # define BOOST_PP_FOR_33(s, p, o, m) BOOST_PP_FOR_33_C(BOOST_PP_BOOL(p(34, s)), s, p, o, m) # define BOOST_PP_FOR_34(s, p, o, m) BOOST_PP_FOR_34_C(BOOST_PP_BOOL(p(35, s)), s, p, o, m) # define BOOST_PP_FOR_35(s, p, o, m) BOOST_PP_FOR_35_C(BOOST_PP_BOOL(p(36, s)), s, p, o, m) # define BOOST_PP_FOR_36(s, p, o, m) BOOST_PP_FOR_36_C(BOOST_PP_BOOL(p(37, s)), s, p, o, m) # define BOOST_PP_FOR_37(s, p, o, m) BOOST_PP_FOR_37_C(BOOST_PP_BOOL(p(38, s)), s, p, o, m) # define BOOST_PP_FOR_38(s, p, o, m) BOOST_PP_FOR_38_C(BOOST_PP_BOOL(p(39, s)), s, p, o, m) # define BOOST_PP_FOR_39(s, p, o, m) BOOST_PP_FOR_39_C(BOOST_PP_BOOL(p(40, s)), s, p, o, m) # define BOOST_PP_FOR_40(s, p, o, m) BOOST_PP_FOR_40_C(BOOST_PP_BOOL(p(41, s)), s, p, o, m) # define BOOST_PP_FOR_41(s, p, o, m) BOOST_PP_FOR_41_C(BOOST_PP_BOOL(p(42, s)), s, p, o, m) # define BOOST_PP_FOR_42(s, p, o, m) BOOST_PP_FOR_42_C(BOOST_PP_BOOL(p(43, s)), s, p, o, m) # define BOOST_PP_FOR_43(s, p, o, m) BOOST_PP_FOR_43_C(BOOST_PP_BOOL(p(44, s)), s, p, o, m) # define BOOST_PP_FOR_44(s, p, o, m) BOOST_PP_FOR_44_C(BOOST_PP_BOOL(p(45, s)), s, p, o, m) # define BOOST_PP_FOR_45(s, p, o, m) BOOST_PP_FOR_45_C(BOOST_PP_BOOL(p(46, s)), s, p, o, m) # define BOOST_PP_FOR_46(s, p, o, m) BOOST_PP_FOR_46_C(BOOST_PP_BOOL(p(47, s)), s, p, o, m) # define BOOST_PP_FOR_47(s, p, o, m) BOOST_PP_FOR_47_C(BOOST_PP_BOOL(p(48, s)), s, p, o, m) # define BOOST_PP_FOR_48(s, p, o, m) BOOST_PP_FOR_48_C(BOOST_PP_BOOL(p(49, s)), s, p, o, m) # define BOOST_PP_FOR_49(s, p, o, m) BOOST_PP_FOR_49_C(BOOST_PP_BOOL(p(50, s)), s, p, o, m) # define BOOST_PP_FOR_50(s, p, o, m) BOOST_PP_FOR_50_C(BOOST_PP_BOOL(p(51, s)), s, p, o, m) # define BOOST_PP_FOR_51(s, p, o, m) BOOST_PP_FOR_51_C(BOOST_PP_BOOL(p(52, s)), s, p, o, m) # define BOOST_PP_FOR_52(s, p, o, m) BOOST_PP_FOR_52_C(BOOST_PP_BOOL(p(53, s)), s, p, o, m) # define BOOST_PP_FOR_53(s, p, o, m) BOOST_PP_FOR_53_C(BOOST_PP_BOOL(p(54, s)), s, p, o, m) # define BOOST_PP_FOR_54(s, p, o, m) BOOST_PP_FOR_54_C(BOOST_PP_BOOL(p(55, s)), s, p, o, m) # define BOOST_PP_FOR_55(s, p, o, m) BOOST_PP_FOR_55_C(BOOST_PP_BOOL(p(56, s)), s, p, o, m) # define BOOST_PP_FOR_56(s, p, o, m) BOOST_PP_FOR_56_C(BOOST_PP_BOOL(p(57, s)), s, p, o, m) # define BOOST_PP_FOR_57(s, p, o, m) BOOST_PP_FOR_57_C(BOOST_PP_BOOL(p(58, s)), s, p, o, m) # define BOOST_PP_FOR_58(s, p, o, m) BOOST_PP_FOR_58_C(BOOST_PP_BOOL(p(59, s)), s, p, o, m) # define BOOST_PP_FOR_59(s, p, o, m) BOOST_PP_FOR_59_C(BOOST_PP_BOOL(p(60, s)), s, p, o, m) # define BOOST_PP_FOR_60(s, p, o, m) BOOST_PP_FOR_60_C(BOOST_PP_BOOL(p(61, s)), s, p, o, m) # define BOOST_PP_FOR_61(s, p, o, m) BOOST_PP_FOR_61_C(BOOST_PP_BOOL(p(62, s)), s, p, o, m) # define BOOST_PP_FOR_62(s, p, o, m) BOOST_PP_FOR_62_C(BOOST_PP_BOOL(p(63, s)), s, p, o, m) # define BOOST_PP_FOR_63(s, p, o, m) BOOST_PP_FOR_63_C(BOOST_PP_BOOL(p(64, s)), s, p, o, m) # define BOOST_PP_FOR_64(s, p, o, m) BOOST_PP_FOR_64_C(BOOST_PP_BOOL(p(65, s)), s, p, o, m) # define BOOST_PP_FOR_65(s, p, o, m) BOOST_PP_FOR_65_C(BOOST_PP_BOOL(p(66, s)), s, p, o, m) # define BOOST_PP_FOR_66(s, p, o, m) BOOST_PP_FOR_66_C(BOOST_PP_BOOL(p(67, s)), s, p, o, m) # define BOOST_PP_FOR_67(s, p, o, m) BOOST_PP_FOR_67_C(BOOST_PP_BOOL(p(68, s)), s, p, o, m) # define BOOST_PP_FOR_68(s, p, o, m) BOOST_PP_FOR_68_C(BOOST_PP_BOOL(p(69, s)), s, p, o, m) # define BOOST_PP_FOR_69(s, p, o, m) BOOST_PP_FOR_69_C(BOOST_PP_BOOL(p(70, s)), s, p, o, m) # define BOOST_PP_FOR_70(s, p, o, m) BOOST_PP_FOR_70_C(BOOST_PP_BOOL(p(71, s)), s, p, o, m) # define BOOST_PP_FOR_71(s, p, o, m) BOOST_PP_FOR_71_C(BOOST_PP_BOOL(p(72, s)), s, p, o, m) # define BOOST_PP_FOR_72(s, p, o, m) BOOST_PP_FOR_72_C(BOOST_PP_BOOL(p(73, s)), s, p, o, m) # define BOOST_PP_FOR_73(s, p, o, m) BOOST_PP_FOR_73_C(BOOST_PP_BOOL(p(74, s)), s, p, o, m) # define BOOST_PP_FOR_74(s, p, o, m) BOOST_PP_FOR_74_C(BOOST_PP_BOOL(p(75, s)), s, p, o, m) # define BOOST_PP_FOR_75(s, p, o, m) BOOST_PP_FOR_75_C(BOOST_PP_BOOL(p(76, s)), s, p, o, m) # define BOOST_PP_FOR_76(s, p, o, m) BOOST_PP_FOR_76_C(BOOST_PP_BOOL(p(77, s)), s, p, o, m) # define BOOST_PP_FOR_77(s, p, o, m) BOOST_PP_FOR_77_C(BOOST_PP_BOOL(p(78, s)), s, p, o, m) # define BOOST_PP_FOR_78(s, p, o, m) BOOST_PP_FOR_78_C(BOOST_PP_BOOL(p(79, s)), s, p, o, m) # define BOOST_PP_FOR_79(s, p, o, m) BOOST_PP_FOR_79_C(BOOST_PP_BOOL(p(80, s)), s, p, o, m) # define BOOST_PP_FOR_80(s, p, o, m) BOOST_PP_FOR_80_C(BOOST_PP_BOOL(p(81, s)), s, p, o, m) # define BOOST_PP_FOR_81(s, p, o, m) BOOST_PP_FOR_81_C(BOOST_PP_BOOL(p(82, s)), s, p, o, m) # define BOOST_PP_FOR_82(s, p, o, m) BOOST_PP_FOR_82_C(BOOST_PP_BOOL(p(83, s)), s, p, o, m) # define BOOST_PP_FOR_83(s, p, o, m) BOOST_PP_FOR_83_C(BOOST_PP_BOOL(p(84, s)), s, p, o, m) # define BOOST_PP_FOR_84(s, p, o, m) BOOST_PP_FOR_84_C(BOOST_PP_BOOL(p(85, s)), s, p, o, m) # define BOOST_PP_FOR_85(s, p, o, m) BOOST_PP_FOR_85_C(BOOST_PP_BOOL(p(86, s)), s, p, o, m) # define BOOST_PP_FOR_86(s, p, o, m) BOOST_PP_FOR_86_C(BOOST_PP_BOOL(p(87, s)), s, p, o, m) # define BOOST_PP_FOR_87(s, p, o, m) BOOST_PP_FOR_87_C(BOOST_PP_BOOL(p(88, s)), s, p, o, m) # define BOOST_PP_FOR_88(s, p, o, m) BOOST_PP_FOR_88_C(BOOST_PP_BOOL(p(89, s)), s, p, o, m) # define BOOST_PP_FOR_89(s, p, o, m) BOOST_PP_FOR_89_C(BOOST_PP_BOOL(p(90, s)), s, p, o, m) # define BOOST_PP_FOR_90(s, p, o, m) BOOST_PP_FOR_90_C(BOOST_PP_BOOL(p(91, s)), s, p, o, m) # define BOOST_PP_FOR_91(s, p, o, m) BOOST_PP_FOR_91_C(BOOST_PP_BOOL(p(92, s)), s, p, o, m) # define BOOST_PP_FOR_92(s, p, o, m) BOOST_PP_FOR_92_C(BOOST_PP_BOOL(p(93, s)), s, p, o, m) # define BOOST_PP_FOR_93(s, p, o, m) BOOST_PP_FOR_93_C(BOOST_PP_BOOL(p(94, s)), s, p, o, m) # define BOOST_PP_FOR_94(s, p, o, m) BOOST_PP_FOR_94_C(BOOST_PP_BOOL(p(95, s)), s, p, o, m) # define BOOST_PP_FOR_95(s, p, o, m) BOOST_PP_FOR_95_C(BOOST_PP_BOOL(p(96, s)), s, p, o, m) # define BOOST_PP_FOR_96(s, p, o, m) BOOST_PP_FOR_96_C(BOOST_PP_BOOL(p(97, s)), s, p, o, m) # define BOOST_PP_FOR_97(s, p, o, m) BOOST_PP_FOR_97_C(BOOST_PP_BOOL(p(98, s)), s, p, o, m) # define BOOST_PP_FOR_98(s, p, o, m) BOOST_PP_FOR_98_C(BOOST_PP_BOOL(p(99, s)), s, p, o, m) # define BOOST_PP_FOR_99(s, p, o, m) BOOST_PP_FOR_99_C(BOOST_PP_BOOL(p(100, s)), s, p, o, m) # define BOOST_PP_FOR_100(s, p, o, m) BOOST_PP_FOR_100_C(BOOST_PP_BOOL(p(101, s)), s, p, o, m) # define BOOST_PP_FOR_101(s, p, o, m) BOOST_PP_FOR_101_C(BOOST_PP_BOOL(p(102, s)), s, p, o, m) # define BOOST_PP_FOR_102(s, p, o, m) BOOST_PP_FOR_102_C(BOOST_PP_BOOL(p(103, s)), s, p, o, m) # define BOOST_PP_FOR_103(s, p, o, m) BOOST_PP_FOR_103_C(BOOST_PP_BOOL(p(104, s)), s, p, o, m) # define BOOST_PP_FOR_104(s, p, o, m) BOOST_PP_FOR_104_C(BOOST_PP_BOOL(p(105, s)), s, p, o, m) # define BOOST_PP_FOR_105(s, p, o, m) BOOST_PP_FOR_105_C(BOOST_PP_BOOL(p(106, s)), s, p, o, m) # define BOOST_PP_FOR_106(s, p, o, m) BOOST_PP_FOR_106_C(BOOST_PP_BOOL(p(107, s)), s, p, o, m) # define BOOST_PP_FOR_107(s, p, o, m) BOOST_PP_FOR_107_C(BOOST_PP_BOOL(p(108, s)), s, p, o, m) # define BOOST_PP_FOR_108(s, p, o, m) BOOST_PP_FOR_108_C(BOOST_PP_BOOL(p(109, s)), s, p, o, m) # define BOOST_PP_FOR_109(s, p, o, m) BOOST_PP_FOR_109_C(BOOST_PP_BOOL(p(110, s)), s, p, o, m) # define BOOST_PP_FOR_110(s, p, o, m) BOOST_PP_FOR_110_C(BOOST_PP_BOOL(p(111, s)), s, p, o, m) # define BOOST_PP_FOR_111(s, p, o, m) BOOST_PP_FOR_111_C(BOOST_PP_BOOL(p(112, s)), s, p, o, m) # define BOOST_PP_FOR_112(s, p, o, m) BOOST_PP_FOR_112_C(BOOST_PP_BOOL(p(113, s)), s, p, o, m) # define BOOST_PP_FOR_113(s, p, o, m) BOOST_PP_FOR_113_C(BOOST_PP_BOOL(p(114, s)), s, p, o, m) # define BOOST_PP_FOR_114(s, p, o, m) BOOST_PP_FOR_114_C(BOOST_PP_BOOL(p(115, s)), s, p, o, m) # define BOOST_PP_FOR_115(s, p, o, m) BOOST_PP_FOR_115_C(BOOST_PP_BOOL(p(116, s)), s, p, o, m) # define BOOST_PP_FOR_116(s, p, o, m) BOOST_PP_FOR_116_C(BOOST_PP_BOOL(p(117, s)), s, p, o, m) # define BOOST_PP_FOR_117(s, p, o, m) BOOST_PP_FOR_117_C(BOOST_PP_BOOL(p(118, s)), s, p, o, m) # define BOOST_PP_FOR_118(s, p, o, m) BOOST_PP_FOR_118_C(BOOST_PP_BOOL(p(119, s)), s, p, o, m) # define BOOST_PP_FOR_119(s, p, o, m) BOOST_PP_FOR_119_C(BOOST_PP_BOOL(p(120, s)), s, p, o, m) # define BOOST_PP_FOR_120(s, p, o, m) BOOST_PP_FOR_120_C(BOOST_PP_BOOL(p(121, s)), s, p, o, m) # define BOOST_PP_FOR_121(s, p, o, m) BOOST_PP_FOR_121_C(BOOST_PP_BOOL(p(122, s)), s, p, o, m) # define BOOST_PP_FOR_122(s, p, o, m) BOOST_PP_FOR_122_C(BOOST_PP_BOOL(p(123, s)), s, p, o, m) # define BOOST_PP_FOR_123(s, p, o, m) BOOST_PP_FOR_123_C(BOOST_PP_BOOL(p(124, s)), s, p, o, m) # define BOOST_PP_FOR_124(s, p, o, m) BOOST_PP_FOR_124_C(BOOST_PP_BOOL(p(125, s)), s, p, o, m) # define BOOST_PP_FOR_125(s, p, o, m) BOOST_PP_FOR_125_C(BOOST_PP_BOOL(p(126, s)), s, p, o, m) # define BOOST_PP_FOR_126(s, p, o, m) BOOST_PP_FOR_126_C(BOOST_PP_BOOL(p(127, s)), s, p, o, m) # define BOOST_PP_FOR_127(s, p, o, m) BOOST_PP_FOR_127_C(BOOST_PP_BOOL(p(128, s)), s, p, o, m) # define BOOST_PP_FOR_128(s, p, o, m) BOOST_PP_FOR_128_C(BOOST_PP_BOOL(p(129, s)), s, p, o, m) # define BOOST_PP_FOR_129(s, p, o, m) BOOST_PP_FOR_129_C(BOOST_PP_BOOL(p(130, s)), s, p, o, m) # define BOOST_PP_FOR_130(s, p, o, m) BOOST_PP_FOR_130_C(BOOST_PP_BOOL(p(131, s)), s, p, o, m) # define BOOST_PP_FOR_131(s, p, o, m) BOOST_PP_FOR_131_C(BOOST_PP_BOOL(p(132, s)), s, p, o, m) # define BOOST_PP_FOR_132(s, p, o, m) BOOST_PP_FOR_132_C(BOOST_PP_BOOL(p(133, s)), s, p, o, m) # define BOOST_PP_FOR_133(s, p, o, m) BOOST_PP_FOR_133_C(BOOST_PP_BOOL(p(134, s)), s, p, o, m) # define BOOST_PP_FOR_134(s, p, o, m) BOOST_PP_FOR_134_C(BOOST_PP_BOOL(p(135, s)), s, p, o, m) # define BOOST_PP_FOR_135(s, p, o, m) BOOST_PP_FOR_135_C(BOOST_PP_BOOL(p(136, s)), s, p, o, m) # define BOOST_PP_FOR_136(s, p, o, m) BOOST_PP_FOR_136_C(BOOST_PP_BOOL(p(137, s)), s, p, o, m) # define BOOST_PP_FOR_137(s, p, o, m) BOOST_PP_FOR_137_C(BOOST_PP_BOOL(p(138, s)), s, p, o, m) # define BOOST_PP_FOR_138(s, p, o, m) BOOST_PP_FOR_138_C(BOOST_PP_BOOL(p(139, s)), s, p, o, m) # define BOOST_PP_FOR_139(s, p, o, m) BOOST_PP_FOR_139_C(BOOST_PP_BOOL(p(140, s)), s, p, o, m) # define BOOST_PP_FOR_140(s, p, o, m) BOOST_PP_FOR_140_C(BOOST_PP_BOOL(p(141, s)), s, p, o, m) # define BOOST_PP_FOR_141(s, p, o, m) BOOST_PP_FOR_141_C(BOOST_PP_BOOL(p(142, s)), s, p, o, m) # define BOOST_PP_FOR_142(s, p, o, m) BOOST_PP_FOR_142_C(BOOST_PP_BOOL(p(143, s)), s, p, o, m) # define BOOST_PP_FOR_143(s, p, o, m) BOOST_PP_FOR_143_C(BOOST_PP_BOOL(p(144, s)), s, p, o, m) # define BOOST_PP_FOR_144(s, p, o, m) BOOST_PP_FOR_144_C(BOOST_PP_BOOL(p(145, s)), s, p, o, m) # define BOOST_PP_FOR_145(s, p, o, m) BOOST_PP_FOR_145_C(BOOST_PP_BOOL(p(146, s)), s, p, o, m) # define BOOST_PP_FOR_146(s, p, o, m) BOOST_PP_FOR_146_C(BOOST_PP_BOOL(p(147, s)), s, p, o, m) # define BOOST_PP_FOR_147(s, p, o, m) BOOST_PP_FOR_147_C(BOOST_PP_BOOL(p(148, s)), s, p, o, m) # define BOOST_PP_FOR_148(s, p, o, m) BOOST_PP_FOR_148_C(BOOST_PP_BOOL(p(149, s)), s, p, o, m) # define BOOST_PP_FOR_149(s, p, o, m) BOOST_PP_FOR_149_C(BOOST_PP_BOOL(p(150, s)), s, p, o, m) # define BOOST_PP_FOR_150(s, p, o, m) BOOST_PP_FOR_150_C(BOOST_PP_BOOL(p(151, s)), s, p, o, m) # define BOOST_PP_FOR_151(s, p, o, m) BOOST_PP_FOR_151_C(BOOST_PP_BOOL(p(152, s)), s, p, o, m) # define BOOST_PP_FOR_152(s, p, o, m) BOOST_PP_FOR_152_C(BOOST_PP_BOOL(p(153, s)), s, p, o, m) # define BOOST_PP_FOR_153(s, p, o, m) BOOST_PP_FOR_153_C(BOOST_PP_BOOL(p(154, s)), s, p, o, m) # define BOOST_PP_FOR_154(s, p, o, m) BOOST_PP_FOR_154_C(BOOST_PP_BOOL(p(155, s)), s, p, o, m) # define BOOST_PP_FOR_155(s, p, o, m) BOOST_PP_FOR_155_C(BOOST_PP_BOOL(p(156, s)), s, p, o, m) # define BOOST_PP_FOR_156(s, p, o, m) BOOST_PP_FOR_156_C(BOOST_PP_BOOL(p(157, s)), s, p, o, m) # define BOOST_PP_FOR_157(s, p, o, m) BOOST_PP_FOR_157_C(BOOST_PP_BOOL(p(158, s)), s, p, o, m) # define BOOST_PP_FOR_158(s, p, o, m) BOOST_PP_FOR_158_C(BOOST_PP_BOOL(p(159, s)), s, p, o, m) # define BOOST_PP_FOR_159(s, p, o, m) BOOST_PP_FOR_159_C(BOOST_PP_BOOL(p(160, s)), s, p, o, m) # define BOOST_PP_FOR_160(s, p, o, m) BOOST_PP_FOR_160_C(BOOST_PP_BOOL(p(161, s)), s, p, o, m) # define BOOST_PP_FOR_161(s, p, o, m) BOOST_PP_FOR_161_C(BOOST_PP_BOOL(p(162, s)), s, p, o, m) # define BOOST_PP_FOR_162(s, p, o, m) BOOST_PP_FOR_162_C(BOOST_PP_BOOL(p(163, s)), s, p, o, m) # define BOOST_PP_FOR_163(s, p, o, m) BOOST_PP_FOR_163_C(BOOST_PP_BOOL(p(164, s)), s, p, o, m) # define BOOST_PP_FOR_164(s, p, o, m) BOOST_PP_FOR_164_C(BOOST_PP_BOOL(p(165, s)), s, p, o, m) # define BOOST_PP_FOR_165(s, p, o, m) BOOST_PP_FOR_165_C(BOOST_PP_BOOL(p(166, s)), s, p, o, m) # define BOOST_PP_FOR_166(s, p, o, m) BOOST_PP_FOR_166_C(BOOST_PP_BOOL(p(167, s)), s, p, o, m) # define BOOST_PP_FOR_167(s, p, o, m) BOOST_PP_FOR_167_C(BOOST_PP_BOOL(p(168, s)), s, p, o, m) # define BOOST_PP_FOR_168(s, p, o, m) BOOST_PP_FOR_168_C(BOOST_PP_BOOL(p(169, s)), s, p, o, m) # define BOOST_PP_FOR_169(s, p, o, m) BOOST_PP_FOR_169_C(BOOST_PP_BOOL(p(170, s)), s, p, o, m) # define BOOST_PP_FOR_170(s, p, o, m) BOOST_PP_FOR_170_C(BOOST_PP_BOOL(p(171, s)), s, p, o, m) # define BOOST_PP_FOR_171(s, p, o, m) BOOST_PP_FOR_171_C(BOOST_PP_BOOL(p(172, s)), s, p, o, m) # define BOOST_PP_FOR_172(s, p, o, m) BOOST_PP_FOR_172_C(BOOST_PP_BOOL(p(173, s)), s, p, o, m) # define BOOST_PP_FOR_173(s, p, o, m) BOOST_PP_FOR_173_C(BOOST_PP_BOOL(p(174, s)), s, p, o, m) # define BOOST_PP_FOR_174(s, p, o, m) BOOST_PP_FOR_174_C(BOOST_PP_BOOL(p(175, s)), s, p, o, m) # define BOOST_PP_FOR_175(s, p, o, m) BOOST_PP_FOR_175_C(BOOST_PP_BOOL(p(176, s)), s, p, o, m) # define BOOST_PP_FOR_176(s, p, o, m) BOOST_PP_FOR_176_C(BOOST_PP_BOOL(p(177, s)), s, p, o, m) # define BOOST_PP_FOR_177(s, p, o, m) BOOST_PP_FOR_177_C(BOOST_PP_BOOL(p(178, s)), s, p, o, m) # define BOOST_PP_FOR_178(s, p, o, m) BOOST_PP_FOR_178_C(BOOST_PP_BOOL(p(179, s)), s, p, o, m) # define BOOST_PP_FOR_179(s, p, o, m) BOOST_PP_FOR_179_C(BOOST_PP_BOOL(p(180, s)), s, p, o, m) # define BOOST_PP_FOR_180(s, p, o, m) BOOST_PP_FOR_180_C(BOOST_PP_BOOL(p(181, s)), s, p, o, m) # define BOOST_PP_FOR_181(s, p, o, m) BOOST_PP_FOR_181_C(BOOST_PP_BOOL(p(182, s)), s, p, o, m) # define BOOST_PP_FOR_182(s, p, o, m) BOOST_PP_FOR_182_C(BOOST_PP_BOOL(p(183, s)), s, p, o, m) # define BOOST_PP_FOR_183(s, p, o, m) BOOST_PP_FOR_183_C(BOOST_PP_BOOL(p(184, s)), s, p, o, m) # define BOOST_PP_FOR_184(s, p, o, m) BOOST_PP_FOR_184_C(BOOST_PP_BOOL(p(185, s)), s, p, o, m) # define BOOST_PP_FOR_185(s, p, o, m) BOOST_PP_FOR_185_C(BOOST_PP_BOOL(p(186, s)), s, p, o, m) # define BOOST_PP_FOR_186(s, p, o, m) BOOST_PP_FOR_186_C(BOOST_PP_BOOL(p(187, s)), s, p, o, m) # define BOOST_PP_FOR_187(s, p, o, m) BOOST_PP_FOR_187_C(BOOST_PP_BOOL(p(188, s)), s, p, o, m) # define BOOST_PP_FOR_188(s, p, o, m) BOOST_PP_FOR_188_C(BOOST_PP_BOOL(p(189, s)), s, p, o, m) # define BOOST_PP_FOR_189(s, p, o, m) BOOST_PP_FOR_189_C(BOOST_PP_BOOL(p(190, s)), s, p, o, m) # define BOOST_PP_FOR_190(s, p, o, m) BOOST_PP_FOR_190_C(BOOST_PP_BOOL(p(191, s)), s, p, o, m) # define BOOST_PP_FOR_191(s, p, o, m) BOOST_PP_FOR_191_C(BOOST_PP_BOOL(p(192, s)), s, p, o, m) # define BOOST_PP_FOR_192(s, p, o, m) BOOST_PP_FOR_192_C(BOOST_PP_BOOL(p(193, s)), s, p, o, m) # define BOOST_PP_FOR_193(s, p, o, m) BOOST_PP_FOR_193_C(BOOST_PP_BOOL(p(194, s)), s, p, o, m) # define BOOST_PP_FOR_194(s, p, o, m) BOOST_PP_FOR_194_C(BOOST_PP_BOOL(p(195, s)), s, p, o, m) # define BOOST_PP_FOR_195(s, p, o, m) BOOST_PP_FOR_195_C(BOOST_PP_BOOL(p(196, s)), s, p, o, m) # define BOOST_PP_FOR_196(s, p, o, m) BOOST_PP_FOR_196_C(BOOST_PP_BOOL(p(197, s)), s, p, o, m) # define BOOST_PP_FOR_197(s, p, o, m) BOOST_PP_FOR_197_C(BOOST_PP_BOOL(p(198, s)), s, p, o, m) # define BOOST_PP_FOR_198(s, p, o, m) BOOST_PP_FOR_198_C(BOOST_PP_BOOL(p(199, s)), s, p, o, m) # define BOOST_PP_FOR_199(s, p, o, m) BOOST_PP_FOR_199_C(BOOST_PP_BOOL(p(200, s)), s, p, o, m) # define BOOST_PP_FOR_200(s, p, o, m) BOOST_PP_FOR_200_C(BOOST_PP_BOOL(p(201, s)), s, p, o, m) # define BOOST_PP_FOR_201(s, p, o, m) BOOST_PP_FOR_201_C(BOOST_PP_BOOL(p(202, s)), s, p, o, m) # define BOOST_PP_FOR_202(s, p, o, m) BOOST_PP_FOR_202_C(BOOST_PP_BOOL(p(203, s)), s, p, o, m) # define BOOST_PP_FOR_203(s, p, o, m) BOOST_PP_FOR_203_C(BOOST_PP_BOOL(p(204, s)), s, p, o, m) # define BOOST_PP_FOR_204(s, p, o, m) BOOST_PP_FOR_204_C(BOOST_PP_BOOL(p(205, s)), s, p, o, m) # define BOOST_PP_FOR_205(s, p, o, m) BOOST_PP_FOR_205_C(BOOST_PP_BOOL(p(206, s)), s, p, o, m) # define BOOST_PP_FOR_206(s, p, o, m) BOOST_PP_FOR_206_C(BOOST_PP_BOOL(p(207, s)), s, p, o, m) # define BOOST_PP_FOR_207(s, p, o, m) BOOST_PP_FOR_207_C(BOOST_PP_BOOL(p(208, s)), s, p, o, m) # define BOOST_PP_FOR_208(s, p, o, m) BOOST_PP_FOR_208_C(BOOST_PP_BOOL(p(209, s)), s, p, o, m) # define BOOST_PP_FOR_209(s, p, o, m) BOOST_PP_FOR_209_C(BOOST_PP_BOOL(p(210, s)), s, p, o, m) # define BOOST_PP_FOR_210(s, p, o, m) BOOST_PP_FOR_210_C(BOOST_PP_BOOL(p(211, s)), s, p, o, m) # define BOOST_PP_FOR_211(s, p, o, m) BOOST_PP_FOR_211_C(BOOST_PP_BOOL(p(212, s)), s, p, o, m) # define BOOST_PP_FOR_212(s, p, o, m) BOOST_PP_FOR_212_C(BOOST_PP_BOOL(p(213, s)), s, p, o, m) # define BOOST_PP_FOR_213(s, p, o, m) BOOST_PP_FOR_213_C(BOOST_PP_BOOL(p(214, s)), s, p, o, m) # define BOOST_PP_FOR_214(s, p, o, m) BOOST_PP_FOR_214_C(BOOST_PP_BOOL(p(215, s)), s, p, o, m) # define BOOST_PP_FOR_215(s, p, o, m) BOOST_PP_FOR_215_C(BOOST_PP_BOOL(p(216, s)), s, p, o, m) # define BOOST_PP_FOR_216(s, p, o, m) BOOST_PP_FOR_216_C(BOOST_PP_BOOL(p(217, s)), s, p, o, m) # define BOOST_PP_FOR_217(s, p, o, m) BOOST_PP_FOR_217_C(BOOST_PP_BOOL(p(218, s)), s, p, o, m) # define BOOST_PP_FOR_218(s, p, o, m) BOOST_PP_FOR_218_C(BOOST_PP_BOOL(p(219, s)), s, p, o, m) # define BOOST_PP_FOR_219(s, p, o, m) BOOST_PP_FOR_219_C(BOOST_PP_BOOL(p(220, s)), s, p, o, m) # define BOOST_PP_FOR_220(s, p, o, m) BOOST_PP_FOR_220_C(BOOST_PP_BOOL(p(221, s)), s, p, o, m) # define BOOST_PP_FOR_221(s, p, o, m) BOOST_PP_FOR_221_C(BOOST_PP_BOOL(p(222, s)), s, p, o, m) # define BOOST_PP_FOR_222(s, p, o, m) BOOST_PP_FOR_222_C(BOOST_PP_BOOL(p(223, s)), s, p, o, m) # define BOOST_PP_FOR_223(s, p, o, m) BOOST_PP_FOR_223_C(BOOST_PP_BOOL(p(224, s)), s, p, o, m) # define BOOST_PP_FOR_224(s, p, o, m) BOOST_PP_FOR_224_C(BOOST_PP_BOOL(p(225, s)), s, p, o, m) # define BOOST_PP_FOR_225(s, p, o, m) BOOST_PP_FOR_225_C(BOOST_PP_BOOL(p(226, s)), s, p, o, m) # define BOOST_PP_FOR_226(s, p, o, m) BOOST_PP_FOR_226_C(BOOST_PP_BOOL(p(227, s)), s, p, o, m) # define BOOST_PP_FOR_227(s, p, o, m) BOOST_PP_FOR_227_C(BOOST_PP_BOOL(p(228, s)), s, p, o, m) # define BOOST_PP_FOR_228(s, p, o, m) BOOST_PP_FOR_228_C(BOOST_PP_BOOL(p(229, s)), s, p, o, m) # define BOOST_PP_FOR_229(s, p, o, m) BOOST_PP_FOR_229_C(BOOST_PP_BOOL(p(230, s)), s, p, o, m) # define BOOST_PP_FOR_230(s, p, o, m) BOOST_PP_FOR_230_C(BOOST_PP_BOOL(p(231, s)), s, p, o, m) # define BOOST_PP_FOR_231(s, p, o, m) BOOST_PP_FOR_231_C(BOOST_PP_BOOL(p(232, s)), s, p, o, m) # define BOOST_PP_FOR_232(s, p, o, m) BOOST_PP_FOR_232_C(BOOST_PP_BOOL(p(233, s)), s, p, o, m) # define BOOST_PP_FOR_233(s, p, o, m) BOOST_PP_FOR_233_C(BOOST_PP_BOOL(p(234, s)), s, p, o, m) # define BOOST_PP_FOR_234(s, p, o, m) BOOST_PP_FOR_234_C(BOOST_PP_BOOL(p(235, s)), s, p, o, m) # define BOOST_PP_FOR_235(s, p, o, m) BOOST_PP_FOR_235_C(BOOST_PP_BOOL(p(236, s)), s, p, o, m) # define BOOST_PP_FOR_236(s, p, o, m) BOOST_PP_FOR_236_C(BOOST_PP_BOOL(p(237, s)), s, p, o, m) # define BOOST_PP_FOR_237(s, p, o, m) BOOST_PP_FOR_237_C(BOOST_PP_BOOL(p(238, s)), s, p, o, m) # define BOOST_PP_FOR_238(s, p, o, m) BOOST_PP_FOR_238_C(BOOST_PP_BOOL(p(239, s)), s, p, o, m) # define BOOST_PP_FOR_239(s, p, o, m) BOOST_PP_FOR_239_C(BOOST_PP_BOOL(p(240, s)), s, p, o, m) # define BOOST_PP_FOR_240(s, p, o, m) BOOST_PP_FOR_240_C(BOOST_PP_BOOL(p(241, s)), s, p, o, m) # define BOOST_PP_FOR_241(s, p, o, m) BOOST_PP_FOR_241_C(BOOST_PP_BOOL(p(242, s)), s, p, o, m) # define BOOST_PP_FOR_242(s, p, o, m) BOOST_PP_FOR_242_C(BOOST_PP_BOOL(p(243, s)), s, p, o, m) # define BOOST_PP_FOR_243(s, p, o, m) BOOST_PP_FOR_243_C(BOOST_PP_BOOL(p(244, s)), s, p, o, m) # define BOOST_PP_FOR_244(s, p, o, m) BOOST_PP_FOR_244_C(BOOST_PP_BOOL(p(245, s)), s, p, o, m) # define BOOST_PP_FOR_245(s, p, o, m) BOOST_PP_FOR_245_C(BOOST_PP_BOOL(p(246, s)), s, p, o, m) # define BOOST_PP_FOR_246(s, p, o, m) BOOST_PP_FOR_246_C(BOOST_PP_BOOL(p(247, s)), s, p, o, m) # define BOOST_PP_FOR_247(s, p, o, m) BOOST_PP_FOR_247_C(BOOST_PP_BOOL(p(248, s)), s, p, o, m) # define BOOST_PP_FOR_248(s, p, o, m) BOOST_PP_FOR_248_C(BOOST_PP_BOOL(p(249, s)), s, p, o, m) # define BOOST_PP_FOR_249(s, p, o, m) BOOST_PP_FOR_249_C(BOOST_PP_BOOL(p(250, s)), s, p, o, m) # define BOOST_PP_FOR_250(s, p, o, m) BOOST_PP_FOR_250_C(BOOST_PP_BOOL(p(251, s)), s, p, o, m) # define BOOST_PP_FOR_251(s, p, o, m) BOOST_PP_FOR_251_C(BOOST_PP_BOOL(p(252, s)), s, p, o, m) # define BOOST_PP_FOR_252(s, p, o, m) BOOST_PP_FOR_252_C(BOOST_PP_BOOL(p(253, s)), s, p, o, m) # define BOOST_PP_FOR_253(s, p, o, m) BOOST_PP_FOR_253_C(BOOST_PP_BOOL(p(254, s)), s, p, o, m) # define BOOST_PP_FOR_254(s, p, o, m) BOOST_PP_FOR_254_C(BOOST_PP_BOOL(p(255, s)), s, p, o, m) # define BOOST_PP_FOR_255(s, p, o, m) BOOST_PP_FOR_255_C(BOOST_PP_BOOL(p(256, s)), s, p, o, m) # define BOOST_PP_FOR_256(s, p, o, m) BOOST_PP_FOR_256_C(BOOST_PP_BOOL(p(257, s)), s, p, o, m) # # define BOOST_PP_FOR_1_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(2, s) BOOST_PP_IIF(c, BOOST_PP_FOR_2, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(2, s), p, o, m) # define BOOST_PP_FOR_2_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(3, s) BOOST_PP_IIF(c, BOOST_PP_FOR_3, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(3, s), p, o, m) # define BOOST_PP_FOR_3_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(4, s) BOOST_PP_IIF(c, BOOST_PP_FOR_4, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(4, s), p, o, m) # define BOOST_PP_FOR_4_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(5, s) BOOST_PP_IIF(c, BOOST_PP_FOR_5, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(5, s), p, o, m) # define BOOST_PP_FOR_5_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(6, s) BOOST_PP_IIF(c, BOOST_PP_FOR_6, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(6, s), p, o, m) # define BOOST_PP_FOR_6_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(7, s) BOOST_PP_IIF(c, BOOST_PP_FOR_7, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(7, s), p, o, m) # define BOOST_PP_FOR_7_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(8, s) BOOST_PP_IIF(c, BOOST_PP_FOR_8, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(8, s), p, o, m) # define BOOST_PP_FOR_8_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(9, s) BOOST_PP_IIF(c, BOOST_PP_FOR_9, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(9, s), p, o, m) # define BOOST_PP_FOR_9_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(10, s) BOOST_PP_IIF(c, BOOST_PP_FOR_10, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(10, s), p, o, m) # define BOOST_PP_FOR_10_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(11, s) BOOST_PP_IIF(c, BOOST_PP_FOR_11, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(11, s), p, o, m) # define BOOST_PP_FOR_11_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(12, s) BOOST_PP_IIF(c, BOOST_PP_FOR_12, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(12, s), p, o, m) # define BOOST_PP_FOR_12_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(13, s) BOOST_PP_IIF(c, BOOST_PP_FOR_13, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(13, s), p, o, m) # define BOOST_PP_FOR_13_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(14, s) BOOST_PP_IIF(c, BOOST_PP_FOR_14, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(14, s), p, o, m) # define BOOST_PP_FOR_14_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(15, s) BOOST_PP_IIF(c, BOOST_PP_FOR_15, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(15, s), p, o, m) # define BOOST_PP_FOR_15_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(16, s) BOOST_PP_IIF(c, BOOST_PP_FOR_16, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(16, s), p, o, m) # define BOOST_PP_FOR_16_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(17, s) BOOST_PP_IIF(c, BOOST_PP_FOR_17, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(17, s), p, o, m) # define BOOST_PP_FOR_17_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(18, s) BOOST_PP_IIF(c, BOOST_PP_FOR_18, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(18, s), p, o, m) # define BOOST_PP_FOR_18_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(19, s) BOOST_PP_IIF(c, BOOST_PP_FOR_19, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(19, s), p, o, m) # define BOOST_PP_FOR_19_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(20, s) BOOST_PP_IIF(c, BOOST_PP_FOR_20, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(20, s), p, o, m) # define BOOST_PP_FOR_20_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(21, s) BOOST_PP_IIF(c, BOOST_PP_FOR_21, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(21, s), p, o, m) # define BOOST_PP_FOR_21_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(22, s) BOOST_PP_IIF(c, BOOST_PP_FOR_22, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(22, s), p, o, m) # define BOOST_PP_FOR_22_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(23, s) BOOST_PP_IIF(c, BOOST_PP_FOR_23, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(23, s), p, o, m) # define BOOST_PP_FOR_23_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(24, s) BOOST_PP_IIF(c, BOOST_PP_FOR_24, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(24, s), p, o, m) # define BOOST_PP_FOR_24_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(25, s) BOOST_PP_IIF(c, BOOST_PP_FOR_25, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(25, s), p, o, m) # define BOOST_PP_FOR_25_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(26, s) BOOST_PP_IIF(c, BOOST_PP_FOR_26, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(26, s), p, o, m) # define BOOST_PP_FOR_26_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(27, s) BOOST_PP_IIF(c, BOOST_PP_FOR_27, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(27, s), p, o, m) # define BOOST_PP_FOR_27_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(28, s) BOOST_PP_IIF(c, BOOST_PP_FOR_28, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(28, s), p, o, m) # define BOOST_PP_FOR_28_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(29, s) BOOST_PP_IIF(c, BOOST_PP_FOR_29, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(29, s), p, o, m) # define BOOST_PP_FOR_29_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(30, s) BOOST_PP_IIF(c, BOOST_PP_FOR_30, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(30, s), p, o, m) # define BOOST_PP_FOR_30_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(31, s) BOOST_PP_IIF(c, BOOST_PP_FOR_31, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(31, s), p, o, m) # define BOOST_PP_FOR_31_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(32, s) BOOST_PP_IIF(c, BOOST_PP_FOR_32, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(32, s), p, o, m) # define BOOST_PP_FOR_32_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(33, s) BOOST_PP_IIF(c, BOOST_PP_FOR_33, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(33, s), p, o, m) # define BOOST_PP_FOR_33_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(34, s) BOOST_PP_IIF(c, BOOST_PP_FOR_34, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(34, s), p, o, m) # define BOOST_PP_FOR_34_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(35, s) BOOST_PP_IIF(c, BOOST_PP_FOR_35, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(35, s), p, o, m) # define BOOST_PP_FOR_35_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(36, s) BOOST_PP_IIF(c, BOOST_PP_FOR_36, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(36, s), p, o, m) # define BOOST_PP_FOR_36_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(37, s) BOOST_PP_IIF(c, BOOST_PP_FOR_37, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(37, s), p, o, m) # define BOOST_PP_FOR_37_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(38, s) BOOST_PP_IIF(c, BOOST_PP_FOR_38, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(38, s), p, o, m) # define BOOST_PP_FOR_38_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(39, s) BOOST_PP_IIF(c, BOOST_PP_FOR_39, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(39, s), p, o, m) # define BOOST_PP_FOR_39_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(40, s) BOOST_PP_IIF(c, BOOST_PP_FOR_40, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(40, s), p, o, m) # define BOOST_PP_FOR_40_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(41, s) BOOST_PP_IIF(c, BOOST_PP_FOR_41, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(41, s), p, o, m) # define BOOST_PP_FOR_41_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(42, s) BOOST_PP_IIF(c, BOOST_PP_FOR_42, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(42, s), p, o, m) # define BOOST_PP_FOR_42_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(43, s) BOOST_PP_IIF(c, BOOST_PP_FOR_43, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(43, s), p, o, m) # define BOOST_PP_FOR_43_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(44, s) BOOST_PP_IIF(c, BOOST_PP_FOR_44, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(44, s), p, o, m) # define BOOST_PP_FOR_44_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(45, s) BOOST_PP_IIF(c, BOOST_PP_FOR_45, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(45, s), p, o, m) # define BOOST_PP_FOR_45_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(46, s) BOOST_PP_IIF(c, BOOST_PP_FOR_46, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(46, s), p, o, m) # define BOOST_PP_FOR_46_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(47, s) BOOST_PP_IIF(c, BOOST_PP_FOR_47, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(47, s), p, o, m) # define BOOST_PP_FOR_47_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(48, s) BOOST_PP_IIF(c, BOOST_PP_FOR_48, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(48, s), p, o, m) # define BOOST_PP_FOR_48_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(49, s) BOOST_PP_IIF(c, BOOST_PP_FOR_49, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(49, s), p, o, m) # define BOOST_PP_FOR_49_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(50, s) BOOST_PP_IIF(c, BOOST_PP_FOR_50, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(50, s), p, o, m) # define BOOST_PP_FOR_50_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(51, s) BOOST_PP_IIF(c, BOOST_PP_FOR_51, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(51, s), p, o, m) # define BOOST_PP_FOR_51_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(52, s) BOOST_PP_IIF(c, BOOST_PP_FOR_52, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(52, s), p, o, m) # define BOOST_PP_FOR_52_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(53, s) BOOST_PP_IIF(c, BOOST_PP_FOR_53, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(53, s), p, o, m) # define BOOST_PP_FOR_53_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(54, s) BOOST_PP_IIF(c, BOOST_PP_FOR_54, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(54, s), p, o, m) # define BOOST_PP_FOR_54_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(55, s) BOOST_PP_IIF(c, BOOST_PP_FOR_55, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(55, s), p, o, m) # define BOOST_PP_FOR_55_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(56, s) BOOST_PP_IIF(c, BOOST_PP_FOR_56, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(56, s), p, o, m) # define BOOST_PP_FOR_56_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(57, s) BOOST_PP_IIF(c, BOOST_PP_FOR_57, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(57, s), p, o, m) # define BOOST_PP_FOR_57_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(58, s) BOOST_PP_IIF(c, BOOST_PP_FOR_58, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(58, s), p, o, m) # define BOOST_PP_FOR_58_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(59, s) BOOST_PP_IIF(c, BOOST_PP_FOR_59, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(59, s), p, o, m) # define BOOST_PP_FOR_59_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(60, s) BOOST_PP_IIF(c, BOOST_PP_FOR_60, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(60, s), p, o, m) # define BOOST_PP_FOR_60_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(61, s) BOOST_PP_IIF(c, BOOST_PP_FOR_61, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(61, s), p, o, m) # define BOOST_PP_FOR_61_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(62, s) BOOST_PP_IIF(c, BOOST_PP_FOR_62, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(62, s), p, o, m) # define BOOST_PP_FOR_62_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(63, s) BOOST_PP_IIF(c, BOOST_PP_FOR_63, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(63, s), p, o, m) # define BOOST_PP_FOR_63_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(64, s) BOOST_PP_IIF(c, BOOST_PP_FOR_64, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(64, s), p, o, m) # define BOOST_PP_FOR_64_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(65, s) BOOST_PP_IIF(c, BOOST_PP_FOR_65, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(65, s), p, o, m) # define BOOST_PP_FOR_65_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(66, s) BOOST_PP_IIF(c, BOOST_PP_FOR_66, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(66, s), p, o, m) # define BOOST_PP_FOR_66_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(67, s) BOOST_PP_IIF(c, BOOST_PP_FOR_67, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(67, s), p, o, m) # define BOOST_PP_FOR_67_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(68, s) BOOST_PP_IIF(c, BOOST_PP_FOR_68, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(68, s), p, o, m) # define BOOST_PP_FOR_68_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(69, s) BOOST_PP_IIF(c, BOOST_PP_FOR_69, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(69, s), p, o, m) # define BOOST_PP_FOR_69_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(70, s) BOOST_PP_IIF(c, BOOST_PP_FOR_70, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(70, s), p, o, m) # define BOOST_PP_FOR_70_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(71, s) BOOST_PP_IIF(c, BOOST_PP_FOR_71, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(71, s), p, o, m) # define BOOST_PP_FOR_71_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(72, s) BOOST_PP_IIF(c, BOOST_PP_FOR_72, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(72, s), p, o, m) # define BOOST_PP_FOR_72_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(73, s) BOOST_PP_IIF(c, BOOST_PP_FOR_73, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(73, s), p, o, m) # define BOOST_PP_FOR_73_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(74, s) BOOST_PP_IIF(c, BOOST_PP_FOR_74, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(74, s), p, o, m) # define BOOST_PP_FOR_74_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(75, s) BOOST_PP_IIF(c, BOOST_PP_FOR_75, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(75, s), p, o, m) # define BOOST_PP_FOR_75_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(76, s) BOOST_PP_IIF(c, BOOST_PP_FOR_76, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(76, s), p, o, m) # define BOOST_PP_FOR_76_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(77, s) BOOST_PP_IIF(c, BOOST_PP_FOR_77, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(77, s), p, o, m) # define BOOST_PP_FOR_77_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(78, s) BOOST_PP_IIF(c, BOOST_PP_FOR_78, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(78, s), p, o, m) # define BOOST_PP_FOR_78_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(79, s) BOOST_PP_IIF(c, BOOST_PP_FOR_79, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(79, s), p, o, m) # define BOOST_PP_FOR_79_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(80, s) BOOST_PP_IIF(c, BOOST_PP_FOR_80, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(80, s), p, o, m) # define BOOST_PP_FOR_80_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(81, s) BOOST_PP_IIF(c, BOOST_PP_FOR_81, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(81, s), p, o, m) # define BOOST_PP_FOR_81_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(82, s) BOOST_PP_IIF(c, BOOST_PP_FOR_82, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(82, s), p, o, m) # define BOOST_PP_FOR_82_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(83, s) BOOST_PP_IIF(c, BOOST_PP_FOR_83, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(83, s), p, o, m) # define BOOST_PP_FOR_83_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(84, s) BOOST_PP_IIF(c, BOOST_PP_FOR_84, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(84, s), p, o, m) # define BOOST_PP_FOR_84_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(85, s) BOOST_PP_IIF(c, BOOST_PP_FOR_85, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(85, s), p, o, m) # define BOOST_PP_FOR_85_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(86, s) BOOST_PP_IIF(c, BOOST_PP_FOR_86, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(86, s), p, o, m) # define BOOST_PP_FOR_86_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(87, s) BOOST_PP_IIF(c, BOOST_PP_FOR_87, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(87, s), p, o, m) # define BOOST_PP_FOR_87_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(88, s) BOOST_PP_IIF(c, BOOST_PP_FOR_88, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(88, s), p, o, m) # define BOOST_PP_FOR_88_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(89, s) BOOST_PP_IIF(c, BOOST_PP_FOR_89, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(89, s), p, o, m) # define BOOST_PP_FOR_89_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(90, s) BOOST_PP_IIF(c, BOOST_PP_FOR_90, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(90, s), p, o, m) # define BOOST_PP_FOR_90_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(91, s) BOOST_PP_IIF(c, BOOST_PP_FOR_91, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(91, s), p, o, m) # define BOOST_PP_FOR_91_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(92, s) BOOST_PP_IIF(c, BOOST_PP_FOR_92, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(92, s), p, o, m) # define BOOST_PP_FOR_92_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(93, s) BOOST_PP_IIF(c, BOOST_PP_FOR_93, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(93, s), p, o, m) # define BOOST_PP_FOR_93_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(94, s) BOOST_PP_IIF(c, BOOST_PP_FOR_94, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(94, s), p, o, m) # define BOOST_PP_FOR_94_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(95, s) BOOST_PP_IIF(c, BOOST_PP_FOR_95, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(95, s), p, o, m) # define BOOST_PP_FOR_95_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(96, s) BOOST_PP_IIF(c, BOOST_PP_FOR_96, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(96, s), p, o, m) # define BOOST_PP_FOR_96_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(97, s) BOOST_PP_IIF(c, BOOST_PP_FOR_97, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(97, s), p, o, m) # define BOOST_PP_FOR_97_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(98, s) BOOST_PP_IIF(c, BOOST_PP_FOR_98, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(98, s), p, o, m) # define BOOST_PP_FOR_98_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(99, s) BOOST_PP_IIF(c, BOOST_PP_FOR_99, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(99, s), p, o, m) # define BOOST_PP_FOR_99_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(100, s) BOOST_PP_IIF(c, BOOST_PP_FOR_100, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(100, s), p, o, m) # define BOOST_PP_FOR_100_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(101, s) BOOST_PP_IIF(c, BOOST_PP_FOR_101, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(101, s), p, o, m) # define BOOST_PP_FOR_101_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(102, s) BOOST_PP_IIF(c, BOOST_PP_FOR_102, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(102, s), p, o, m) # define BOOST_PP_FOR_102_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(103, s) BOOST_PP_IIF(c, BOOST_PP_FOR_103, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(103, s), p, o, m) # define BOOST_PP_FOR_103_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(104, s) BOOST_PP_IIF(c, BOOST_PP_FOR_104, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(104, s), p, o, m) # define BOOST_PP_FOR_104_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(105, s) BOOST_PP_IIF(c, BOOST_PP_FOR_105, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(105, s), p, o, m) # define BOOST_PP_FOR_105_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(106, s) BOOST_PP_IIF(c, BOOST_PP_FOR_106, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(106, s), p, o, m) # define BOOST_PP_FOR_106_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(107, s) BOOST_PP_IIF(c, BOOST_PP_FOR_107, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(107, s), p, o, m) # define BOOST_PP_FOR_107_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(108, s) BOOST_PP_IIF(c, BOOST_PP_FOR_108, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(108, s), p, o, m) # define BOOST_PP_FOR_108_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(109, s) BOOST_PP_IIF(c, BOOST_PP_FOR_109, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(109, s), p, o, m) # define BOOST_PP_FOR_109_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(110, s) BOOST_PP_IIF(c, BOOST_PP_FOR_110, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(110, s), p, o, m) # define BOOST_PP_FOR_110_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(111, s) BOOST_PP_IIF(c, BOOST_PP_FOR_111, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(111, s), p, o, m) # define BOOST_PP_FOR_111_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(112, s) BOOST_PP_IIF(c, BOOST_PP_FOR_112, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(112, s), p, o, m) # define BOOST_PP_FOR_112_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(113, s) BOOST_PP_IIF(c, BOOST_PP_FOR_113, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(113, s), p, o, m) # define BOOST_PP_FOR_113_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(114, s) BOOST_PP_IIF(c, BOOST_PP_FOR_114, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(114, s), p, o, m) # define BOOST_PP_FOR_114_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(115, s) BOOST_PP_IIF(c, BOOST_PP_FOR_115, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(115, s), p, o, m) # define BOOST_PP_FOR_115_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(116, s) BOOST_PP_IIF(c, BOOST_PP_FOR_116, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(116, s), p, o, m) # define BOOST_PP_FOR_116_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(117, s) BOOST_PP_IIF(c, BOOST_PP_FOR_117, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(117, s), p, o, m) # define BOOST_PP_FOR_117_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(118, s) BOOST_PP_IIF(c, BOOST_PP_FOR_118, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(118, s), p, o, m) # define BOOST_PP_FOR_118_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(119, s) BOOST_PP_IIF(c, BOOST_PP_FOR_119, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(119, s), p, o, m) # define BOOST_PP_FOR_119_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(120, s) BOOST_PP_IIF(c, BOOST_PP_FOR_120, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(120, s), p, o, m) # define BOOST_PP_FOR_120_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(121, s) BOOST_PP_IIF(c, BOOST_PP_FOR_121, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(121, s), p, o, m) # define BOOST_PP_FOR_121_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(122, s) BOOST_PP_IIF(c, BOOST_PP_FOR_122, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(122, s), p, o, m) # define BOOST_PP_FOR_122_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(123, s) BOOST_PP_IIF(c, BOOST_PP_FOR_123, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(123, s), p, o, m) # define BOOST_PP_FOR_123_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(124, s) BOOST_PP_IIF(c, BOOST_PP_FOR_124, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(124, s), p, o, m) # define BOOST_PP_FOR_124_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(125, s) BOOST_PP_IIF(c, BOOST_PP_FOR_125, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(125, s), p, o, m) # define BOOST_PP_FOR_125_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(126, s) BOOST_PP_IIF(c, BOOST_PP_FOR_126, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(126, s), p, o, m) # define BOOST_PP_FOR_126_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(127, s) BOOST_PP_IIF(c, BOOST_PP_FOR_127, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(127, s), p, o, m) # define BOOST_PP_FOR_127_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(128, s) BOOST_PP_IIF(c, BOOST_PP_FOR_128, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(128, s), p, o, m) # define BOOST_PP_FOR_128_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(129, s) BOOST_PP_IIF(c, BOOST_PP_FOR_129, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(129, s), p, o, m) # define BOOST_PP_FOR_129_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(130, s) BOOST_PP_IIF(c, BOOST_PP_FOR_130, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(130, s), p, o, m) # define BOOST_PP_FOR_130_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(131, s) BOOST_PP_IIF(c, BOOST_PP_FOR_131, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(131, s), p, o, m) # define BOOST_PP_FOR_131_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(132, s) BOOST_PP_IIF(c, BOOST_PP_FOR_132, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(132, s), p, o, m) # define BOOST_PP_FOR_132_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(133, s) BOOST_PP_IIF(c, BOOST_PP_FOR_133, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(133, s), p, o, m) # define BOOST_PP_FOR_133_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(134, s) BOOST_PP_IIF(c, BOOST_PP_FOR_134, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(134, s), p, o, m) # define BOOST_PP_FOR_134_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(135, s) BOOST_PP_IIF(c, BOOST_PP_FOR_135, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(135, s), p, o, m) # define BOOST_PP_FOR_135_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(136, s) BOOST_PP_IIF(c, BOOST_PP_FOR_136, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(136, s), p, o, m) # define BOOST_PP_FOR_136_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(137, s) BOOST_PP_IIF(c, BOOST_PP_FOR_137, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(137, s), p, o, m) # define BOOST_PP_FOR_137_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(138, s) BOOST_PP_IIF(c, BOOST_PP_FOR_138, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(138, s), p, o, m) # define BOOST_PP_FOR_138_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(139, s) BOOST_PP_IIF(c, BOOST_PP_FOR_139, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(139, s), p, o, m) # define BOOST_PP_FOR_139_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(140, s) BOOST_PP_IIF(c, BOOST_PP_FOR_140, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(140, s), p, o, m) # define BOOST_PP_FOR_140_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(141, s) BOOST_PP_IIF(c, BOOST_PP_FOR_141, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(141, s), p, o, m) # define BOOST_PP_FOR_141_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(142, s) BOOST_PP_IIF(c, BOOST_PP_FOR_142, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(142, s), p, o, m) # define BOOST_PP_FOR_142_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(143, s) BOOST_PP_IIF(c, BOOST_PP_FOR_143, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(143, s), p, o, m) # define BOOST_PP_FOR_143_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(144, s) BOOST_PP_IIF(c, BOOST_PP_FOR_144, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(144, s), p, o, m) # define BOOST_PP_FOR_144_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(145, s) BOOST_PP_IIF(c, BOOST_PP_FOR_145, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(145, s), p, o, m) # define BOOST_PP_FOR_145_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(146, s) BOOST_PP_IIF(c, BOOST_PP_FOR_146, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(146, s), p, o, m) # define BOOST_PP_FOR_146_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(147, s) BOOST_PP_IIF(c, BOOST_PP_FOR_147, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(147, s), p, o, m) # define BOOST_PP_FOR_147_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(148, s) BOOST_PP_IIF(c, BOOST_PP_FOR_148, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(148, s), p, o, m) # define BOOST_PP_FOR_148_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(149, s) BOOST_PP_IIF(c, BOOST_PP_FOR_149, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(149, s), p, o, m) # define BOOST_PP_FOR_149_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(150, s) BOOST_PP_IIF(c, BOOST_PP_FOR_150, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(150, s), p, o, m) # define BOOST_PP_FOR_150_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(151, s) BOOST_PP_IIF(c, BOOST_PP_FOR_151, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(151, s), p, o, m) # define BOOST_PP_FOR_151_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(152, s) BOOST_PP_IIF(c, BOOST_PP_FOR_152, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(152, s), p, o, m) # define BOOST_PP_FOR_152_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(153, s) BOOST_PP_IIF(c, BOOST_PP_FOR_153, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(153, s), p, o, m) # define BOOST_PP_FOR_153_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(154, s) BOOST_PP_IIF(c, BOOST_PP_FOR_154, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(154, s), p, o, m) # define BOOST_PP_FOR_154_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(155, s) BOOST_PP_IIF(c, BOOST_PP_FOR_155, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(155, s), p, o, m) # define BOOST_PP_FOR_155_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(156, s) BOOST_PP_IIF(c, BOOST_PP_FOR_156, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(156, s), p, o, m) # define BOOST_PP_FOR_156_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(157, s) BOOST_PP_IIF(c, BOOST_PP_FOR_157, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(157, s), p, o, m) # define BOOST_PP_FOR_157_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(158, s) BOOST_PP_IIF(c, BOOST_PP_FOR_158, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(158, s), p, o, m) # define BOOST_PP_FOR_158_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(159, s) BOOST_PP_IIF(c, BOOST_PP_FOR_159, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(159, s), p, o, m) # define BOOST_PP_FOR_159_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(160, s) BOOST_PP_IIF(c, BOOST_PP_FOR_160, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(160, s), p, o, m) # define BOOST_PP_FOR_160_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(161, s) BOOST_PP_IIF(c, BOOST_PP_FOR_161, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(161, s), p, o, m) # define BOOST_PP_FOR_161_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(162, s) BOOST_PP_IIF(c, BOOST_PP_FOR_162, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(162, s), p, o, m) # define BOOST_PP_FOR_162_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(163, s) BOOST_PP_IIF(c, BOOST_PP_FOR_163, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(163, s), p, o, m) # define BOOST_PP_FOR_163_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(164, s) BOOST_PP_IIF(c, BOOST_PP_FOR_164, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(164, s), p, o, m) # define BOOST_PP_FOR_164_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(165, s) BOOST_PP_IIF(c, BOOST_PP_FOR_165, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(165, s), p, o, m) # define BOOST_PP_FOR_165_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(166, s) BOOST_PP_IIF(c, BOOST_PP_FOR_166, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(166, s), p, o, m) # define BOOST_PP_FOR_166_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(167, s) BOOST_PP_IIF(c, BOOST_PP_FOR_167, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(167, s), p, o, m) # define BOOST_PP_FOR_167_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(168, s) BOOST_PP_IIF(c, BOOST_PP_FOR_168, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(168, s), p, o, m) # define BOOST_PP_FOR_168_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(169, s) BOOST_PP_IIF(c, BOOST_PP_FOR_169, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(169, s), p, o, m) # define BOOST_PP_FOR_169_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(170, s) BOOST_PP_IIF(c, BOOST_PP_FOR_170, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(170, s), p, o, m) # define BOOST_PP_FOR_170_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(171, s) BOOST_PP_IIF(c, BOOST_PP_FOR_171, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(171, s), p, o, m) # define BOOST_PP_FOR_171_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(172, s) BOOST_PP_IIF(c, BOOST_PP_FOR_172, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(172, s), p, o, m) # define BOOST_PP_FOR_172_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(173, s) BOOST_PP_IIF(c, BOOST_PP_FOR_173, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(173, s), p, o, m) # define BOOST_PP_FOR_173_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(174, s) BOOST_PP_IIF(c, BOOST_PP_FOR_174, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(174, s), p, o, m) # define BOOST_PP_FOR_174_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(175, s) BOOST_PP_IIF(c, BOOST_PP_FOR_175, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(175, s), p, o, m) # define BOOST_PP_FOR_175_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(176, s) BOOST_PP_IIF(c, BOOST_PP_FOR_176, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(176, s), p, o, m) # define BOOST_PP_FOR_176_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(177, s) BOOST_PP_IIF(c, BOOST_PP_FOR_177, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(177, s), p, o, m) # define BOOST_PP_FOR_177_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(178, s) BOOST_PP_IIF(c, BOOST_PP_FOR_178, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(178, s), p, o, m) # define BOOST_PP_FOR_178_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(179, s) BOOST_PP_IIF(c, BOOST_PP_FOR_179, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(179, s), p, o, m) # define BOOST_PP_FOR_179_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(180, s) BOOST_PP_IIF(c, BOOST_PP_FOR_180, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(180, s), p, o, m) # define BOOST_PP_FOR_180_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(181, s) BOOST_PP_IIF(c, BOOST_PP_FOR_181, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(181, s), p, o, m) # define BOOST_PP_FOR_181_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(182, s) BOOST_PP_IIF(c, BOOST_PP_FOR_182, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(182, s), p, o, m) # define BOOST_PP_FOR_182_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(183, s) BOOST_PP_IIF(c, BOOST_PP_FOR_183, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(183, s), p, o, m) # define BOOST_PP_FOR_183_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(184, s) BOOST_PP_IIF(c, BOOST_PP_FOR_184, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(184, s), p, o, m) # define BOOST_PP_FOR_184_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(185, s) BOOST_PP_IIF(c, BOOST_PP_FOR_185, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(185, s), p, o, m) # define BOOST_PP_FOR_185_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(186, s) BOOST_PP_IIF(c, BOOST_PP_FOR_186, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(186, s), p, o, m) # define BOOST_PP_FOR_186_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(187, s) BOOST_PP_IIF(c, BOOST_PP_FOR_187, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(187, s), p, o, m) # define BOOST_PP_FOR_187_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(188, s) BOOST_PP_IIF(c, BOOST_PP_FOR_188, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(188, s), p, o, m) # define BOOST_PP_FOR_188_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(189, s) BOOST_PP_IIF(c, BOOST_PP_FOR_189, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(189, s), p, o, m) # define BOOST_PP_FOR_189_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(190, s) BOOST_PP_IIF(c, BOOST_PP_FOR_190, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(190, s), p, o, m) # define BOOST_PP_FOR_190_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(191, s) BOOST_PP_IIF(c, BOOST_PP_FOR_191, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(191, s), p, o, m) # define BOOST_PP_FOR_191_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(192, s) BOOST_PP_IIF(c, BOOST_PP_FOR_192, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(192, s), p, o, m) # define BOOST_PP_FOR_192_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(193, s) BOOST_PP_IIF(c, BOOST_PP_FOR_193, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(193, s), p, o, m) # define BOOST_PP_FOR_193_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(194, s) BOOST_PP_IIF(c, BOOST_PP_FOR_194, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(194, s), p, o, m) # define BOOST_PP_FOR_194_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(195, s) BOOST_PP_IIF(c, BOOST_PP_FOR_195, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(195, s), p, o, m) # define BOOST_PP_FOR_195_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(196, s) BOOST_PP_IIF(c, BOOST_PP_FOR_196, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(196, s), p, o, m) # define BOOST_PP_FOR_196_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(197, s) BOOST_PP_IIF(c, BOOST_PP_FOR_197, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(197, s), p, o, m) # define BOOST_PP_FOR_197_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(198, s) BOOST_PP_IIF(c, BOOST_PP_FOR_198, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(198, s), p, o, m) # define BOOST_PP_FOR_198_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(199, s) BOOST_PP_IIF(c, BOOST_PP_FOR_199, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(199, s), p, o, m) # define BOOST_PP_FOR_199_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(200, s) BOOST_PP_IIF(c, BOOST_PP_FOR_200, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(200, s), p, o, m) # define BOOST_PP_FOR_200_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(201, s) BOOST_PP_IIF(c, BOOST_PP_FOR_201, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(201, s), p, o, m) # define BOOST_PP_FOR_201_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(202, s) BOOST_PP_IIF(c, BOOST_PP_FOR_202, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(202, s), p, o, m) # define BOOST_PP_FOR_202_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(203, s) BOOST_PP_IIF(c, BOOST_PP_FOR_203, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(203, s), p, o, m) # define BOOST_PP_FOR_203_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(204, s) BOOST_PP_IIF(c, BOOST_PP_FOR_204, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(204, s), p, o, m) # define BOOST_PP_FOR_204_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(205, s) BOOST_PP_IIF(c, BOOST_PP_FOR_205, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(205, s), p, o, m) # define BOOST_PP_FOR_205_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(206, s) BOOST_PP_IIF(c, BOOST_PP_FOR_206, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(206, s), p, o, m) # define BOOST_PP_FOR_206_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(207, s) BOOST_PP_IIF(c, BOOST_PP_FOR_207, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(207, s), p, o, m) # define BOOST_PP_FOR_207_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(208, s) BOOST_PP_IIF(c, BOOST_PP_FOR_208, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(208, s), p, o, m) # define BOOST_PP_FOR_208_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(209, s) BOOST_PP_IIF(c, BOOST_PP_FOR_209, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(209, s), p, o, m) # define BOOST_PP_FOR_209_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(210, s) BOOST_PP_IIF(c, BOOST_PP_FOR_210, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(210, s), p, o, m) # define BOOST_PP_FOR_210_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(211, s) BOOST_PP_IIF(c, BOOST_PP_FOR_211, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(211, s), p, o, m) # define BOOST_PP_FOR_211_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(212, s) BOOST_PP_IIF(c, BOOST_PP_FOR_212, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(212, s), p, o, m) # define BOOST_PP_FOR_212_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(213, s) BOOST_PP_IIF(c, BOOST_PP_FOR_213, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(213, s), p, o, m) # define BOOST_PP_FOR_213_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(214, s) BOOST_PP_IIF(c, BOOST_PP_FOR_214, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(214, s), p, o, m) # define BOOST_PP_FOR_214_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(215, s) BOOST_PP_IIF(c, BOOST_PP_FOR_215, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(215, s), p, o, m) # define BOOST_PP_FOR_215_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(216, s) BOOST_PP_IIF(c, BOOST_PP_FOR_216, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(216, s), p, o, m) # define BOOST_PP_FOR_216_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(217, s) BOOST_PP_IIF(c, BOOST_PP_FOR_217, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(217, s), p, o, m) # define BOOST_PP_FOR_217_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(218, s) BOOST_PP_IIF(c, BOOST_PP_FOR_218, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(218, s), p, o, m) # define BOOST_PP_FOR_218_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(219, s) BOOST_PP_IIF(c, BOOST_PP_FOR_219, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(219, s), p, o, m) # define BOOST_PP_FOR_219_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(220, s) BOOST_PP_IIF(c, BOOST_PP_FOR_220, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(220, s), p, o, m) # define BOOST_PP_FOR_220_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(221, s) BOOST_PP_IIF(c, BOOST_PP_FOR_221, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(221, s), p, o, m) # define BOOST_PP_FOR_221_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(222, s) BOOST_PP_IIF(c, BOOST_PP_FOR_222, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(222, s), p, o, m) # define BOOST_PP_FOR_222_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(223, s) BOOST_PP_IIF(c, BOOST_PP_FOR_223, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(223, s), p, o, m) # define BOOST_PP_FOR_223_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(224, s) BOOST_PP_IIF(c, BOOST_PP_FOR_224, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(224, s), p, o, m) # define BOOST_PP_FOR_224_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(225, s) BOOST_PP_IIF(c, BOOST_PP_FOR_225, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(225, s), p, o, m) # define BOOST_PP_FOR_225_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(226, s) BOOST_PP_IIF(c, BOOST_PP_FOR_226, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(226, s), p, o, m) # define BOOST_PP_FOR_226_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(227, s) BOOST_PP_IIF(c, BOOST_PP_FOR_227, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(227, s), p, o, m) # define BOOST_PP_FOR_227_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(228, s) BOOST_PP_IIF(c, BOOST_PP_FOR_228, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(228, s), p, o, m) # define BOOST_PP_FOR_228_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(229, s) BOOST_PP_IIF(c, BOOST_PP_FOR_229, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(229, s), p, o, m) # define BOOST_PP_FOR_229_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(230, s) BOOST_PP_IIF(c, BOOST_PP_FOR_230, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(230, s), p, o, m) # define BOOST_PP_FOR_230_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(231, s) BOOST_PP_IIF(c, BOOST_PP_FOR_231, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(231, s), p, o, m) # define BOOST_PP_FOR_231_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(232, s) BOOST_PP_IIF(c, BOOST_PP_FOR_232, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(232, s), p, o, m) # define BOOST_PP_FOR_232_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(233, s) BOOST_PP_IIF(c, BOOST_PP_FOR_233, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(233, s), p, o, m) # define BOOST_PP_FOR_233_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(234, s) BOOST_PP_IIF(c, BOOST_PP_FOR_234, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(234, s), p, o, m) # define BOOST_PP_FOR_234_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(235, s) BOOST_PP_IIF(c, BOOST_PP_FOR_235, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(235, s), p, o, m) # define BOOST_PP_FOR_235_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(236, s) BOOST_PP_IIF(c, BOOST_PP_FOR_236, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(236, s), p, o, m) # define BOOST_PP_FOR_236_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(237, s) BOOST_PP_IIF(c, BOOST_PP_FOR_237, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(237, s), p, o, m) # define BOOST_PP_FOR_237_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(238, s) BOOST_PP_IIF(c, BOOST_PP_FOR_238, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(238, s), p, o, m) # define BOOST_PP_FOR_238_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(239, s) BOOST_PP_IIF(c, BOOST_PP_FOR_239, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(239, s), p, o, m) # define BOOST_PP_FOR_239_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(240, s) BOOST_PP_IIF(c, BOOST_PP_FOR_240, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(240, s), p, o, m) # define BOOST_PP_FOR_240_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(241, s) BOOST_PP_IIF(c, BOOST_PP_FOR_241, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(241, s), p, o, m) # define BOOST_PP_FOR_241_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(242, s) BOOST_PP_IIF(c, BOOST_PP_FOR_242, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(242, s), p, o, m) # define BOOST_PP_FOR_242_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(243, s) BOOST_PP_IIF(c, BOOST_PP_FOR_243, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(243, s), p, o, m) # define BOOST_PP_FOR_243_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(244, s) BOOST_PP_IIF(c, BOOST_PP_FOR_244, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(244, s), p, o, m) # define BOOST_PP_FOR_244_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(245, s) BOOST_PP_IIF(c, BOOST_PP_FOR_245, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(245, s), p, o, m) # define BOOST_PP_FOR_245_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(246, s) BOOST_PP_IIF(c, BOOST_PP_FOR_246, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(246, s), p, o, m) # define BOOST_PP_FOR_246_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(247, s) BOOST_PP_IIF(c, BOOST_PP_FOR_247, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(247, s), p, o, m) # define BOOST_PP_FOR_247_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(248, s) BOOST_PP_IIF(c, BOOST_PP_FOR_248, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(248, s), p, o, m) # define BOOST_PP_FOR_248_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(249, s) BOOST_PP_IIF(c, BOOST_PP_FOR_249, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(249, s), p, o, m) # define BOOST_PP_FOR_249_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(250, s) BOOST_PP_IIF(c, BOOST_PP_FOR_250, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(250, s), p, o, m) # define BOOST_PP_FOR_250_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(251, s) BOOST_PP_IIF(c, BOOST_PP_FOR_251, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(251, s), p, o, m) # define BOOST_PP_FOR_251_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(252, s) BOOST_PP_IIF(c, BOOST_PP_FOR_252, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(252, s), p, o, m) # define BOOST_PP_FOR_252_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(253, s) BOOST_PP_IIF(c, BOOST_PP_FOR_253, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(253, s), p, o, m) # define BOOST_PP_FOR_253_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(254, s) BOOST_PP_IIF(c, BOOST_PP_FOR_254, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(254, s), p, o, m) # define BOOST_PP_FOR_254_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(255, s) BOOST_PP_IIF(c, BOOST_PP_FOR_255, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(255, s), p, o, m) # define BOOST_PP_FOR_255_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(256, s) BOOST_PP_IIF(c, BOOST_PP_FOR_256, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(256, s), p, o, m) # define BOOST_PP_FOR_256_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(257, s) BOOST_PP_IIF(c, BOOST_PP_FOR_257, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(257, s), p, o, m) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/detail/msvc/for.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_DETAIL_MSVC_FOR_HPP # define BOOST_PREPROCESSOR_REPETITION_DETAIL_MSVC_FOR_HPP # # include # include # # define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_IF(p(2, s), m, BOOST_PP_TUPLE_EAT_2)(2, s) BOOST_PP_IF(p(2, s), BOOST_PP_FOR_2, BOOST_PP_TUPLE_EAT_4)(o(2, s), p, o, m) # define BOOST_PP_FOR_2(s, p, o, m) BOOST_PP_IF(p(3, s), m, BOOST_PP_TUPLE_EAT_2)(3, s) BOOST_PP_IF(p(3, s), BOOST_PP_FOR_3, BOOST_PP_TUPLE_EAT_4)(o(3, s), p, o, m) # define BOOST_PP_FOR_3(s, p, o, m) BOOST_PP_IF(p(4, s), m, BOOST_PP_TUPLE_EAT_2)(4, s) BOOST_PP_IF(p(4, s), BOOST_PP_FOR_4, BOOST_PP_TUPLE_EAT_4)(o(4, s), p, o, m) # define BOOST_PP_FOR_4(s, p, o, m) BOOST_PP_IF(p(5, s), m, BOOST_PP_TUPLE_EAT_2)(5, s) BOOST_PP_IF(p(5, s), BOOST_PP_FOR_5, BOOST_PP_TUPLE_EAT_4)(o(5, s), p, o, m) # define BOOST_PP_FOR_5(s, p, o, m) BOOST_PP_IF(p(6, s), m, BOOST_PP_TUPLE_EAT_2)(6, s) BOOST_PP_IF(p(6, s), BOOST_PP_FOR_6, BOOST_PP_TUPLE_EAT_4)(o(6, s), p, o, m) # define BOOST_PP_FOR_6(s, p, o, m) BOOST_PP_IF(p(7, s), m, BOOST_PP_TUPLE_EAT_2)(7, s) BOOST_PP_IF(p(7, s), BOOST_PP_FOR_7, BOOST_PP_TUPLE_EAT_4)(o(7, s), p, o, m) # define BOOST_PP_FOR_7(s, p, o, m) BOOST_PP_IF(p(8, s), m, BOOST_PP_TUPLE_EAT_2)(8, s) BOOST_PP_IF(p(8, s), BOOST_PP_FOR_8, BOOST_PP_TUPLE_EAT_4)(o(8, s), p, o, m) # define BOOST_PP_FOR_8(s, p, o, m) BOOST_PP_IF(p(9, s), m, BOOST_PP_TUPLE_EAT_2)(9, s) BOOST_PP_IF(p(9, s), BOOST_PP_FOR_9, BOOST_PP_TUPLE_EAT_4)(o(9, s), p, o, m) # define BOOST_PP_FOR_9(s, p, o, m) BOOST_PP_IF(p(10, s), m, BOOST_PP_TUPLE_EAT_2)(10, s) BOOST_PP_IF(p(10, s), BOOST_PP_FOR_10, BOOST_PP_TUPLE_EAT_4)(o(10, s), p, o, m) # define BOOST_PP_FOR_10(s, p, o, m) BOOST_PP_IF(p(11, s), m, BOOST_PP_TUPLE_EAT_2)(11, s) BOOST_PP_IF(p(11, s), BOOST_PP_FOR_11, BOOST_PP_TUPLE_EAT_4)(o(11, s), p, o, m) # define BOOST_PP_FOR_11(s, p, o, m) BOOST_PP_IF(p(12, s), m, BOOST_PP_TUPLE_EAT_2)(12, s) BOOST_PP_IF(p(12, s), BOOST_PP_FOR_12, BOOST_PP_TUPLE_EAT_4)(o(12, s), p, o, m) # define BOOST_PP_FOR_12(s, p, o, m) BOOST_PP_IF(p(13, s), m, BOOST_PP_TUPLE_EAT_2)(13, s) BOOST_PP_IF(p(13, s), BOOST_PP_FOR_13, BOOST_PP_TUPLE_EAT_4)(o(13, s), p, o, m) # define BOOST_PP_FOR_13(s, p, o, m) BOOST_PP_IF(p(14, s), m, BOOST_PP_TUPLE_EAT_2)(14, s) BOOST_PP_IF(p(14, s), BOOST_PP_FOR_14, BOOST_PP_TUPLE_EAT_4)(o(14, s), p, o, m) # define BOOST_PP_FOR_14(s, p, o, m) BOOST_PP_IF(p(15, s), m, BOOST_PP_TUPLE_EAT_2)(15, s) BOOST_PP_IF(p(15, s), BOOST_PP_FOR_15, BOOST_PP_TUPLE_EAT_4)(o(15, s), p, o, m) # define BOOST_PP_FOR_15(s, p, o, m) BOOST_PP_IF(p(16, s), m, BOOST_PP_TUPLE_EAT_2)(16, s) BOOST_PP_IF(p(16, s), BOOST_PP_FOR_16, BOOST_PP_TUPLE_EAT_4)(o(16, s), p, o, m) # define BOOST_PP_FOR_16(s, p, o, m) BOOST_PP_IF(p(17, s), m, BOOST_PP_TUPLE_EAT_2)(17, s) BOOST_PP_IF(p(17, s), BOOST_PP_FOR_17, BOOST_PP_TUPLE_EAT_4)(o(17, s), p, o, m) # define BOOST_PP_FOR_17(s, p, o, m) BOOST_PP_IF(p(18, s), m, BOOST_PP_TUPLE_EAT_2)(18, s) BOOST_PP_IF(p(18, s), BOOST_PP_FOR_18, BOOST_PP_TUPLE_EAT_4)(o(18, s), p, o, m) # define BOOST_PP_FOR_18(s, p, o, m) BOOST_PP_IF(p(19, s), m, BOOST_PP_TUPLE_EAT_2)(19, s) BOOST_PP_IF(p(19, s), BOOST_PP_FOR_19, BOOST_PP_TUPLE_EAT_4)(o(19, s), p, o, m) # define BOOST_PP_FOR_19(s, p, o, m) BOOST_PP_IF(p(20, s), m, BOOST_PP_TUPLE_EAT_2)(20, s) BOOST_PP_IF(p(20, s), BOOST_PP_FOR_20, BOOST_PP_TUPLE_EAT_4)(o(20, s), p, o, m) # define BOOST_PP_FOR_20(s, p, o, m) BOOST_PP_IF(p(21, s), m, BOOST_PP_TUPLE_EAT_2)(21, s) BOOST_PP_IF(p(21, s), BOOST_PP_FOR_21, BOOST_PP_TUPLE_EAT_4)(o(21, s), p, o, m) # define BOOST_PP_FOR_21(s, p, o, m) BOOST_PP_IF(p(22, s), m, BOOST_PP_TUPLE_EAT_2)(22, s) BOOST_PP_IF(p(22, s), BOOST_PP_FOR_22, BOOST_PP_TUPLE_EAT_4)(o(22, s), p, o, m) # define BOOST_PP_FOR_22(s, p, o, m) BOOST_PP_IF(p(23, s), m, BOOST_PP_TUPLE_EAT_2)(23, s) BOOST_PP_IF(p(23, s), BOOST_PP_FOR_23, BOOST_PP_TUPLE_EAT_4)(o(23, s), p, o, m) # define BOOST_PP_FOR_23(s, p, o, m) BOOST_PP_IF(p(24, s), m, BOOST_PP_TUPLE_EAT_2)(24, s) BOOST_PP_IF(p(24, s), BOOST_PP_FOR_24, BOOST_PP_TUPLE_EAT_4)(o(24, s), p, o, m) # define BOOST_PP_FOR_24(s, p, o, m) BOOST_PP_IF(p(25, s), m, BOOST_PP_TUPLE_EAT_2)(25, s) BOOST_PP_IF(p(25, s), BOOST_PP_FOR_25, BOOST_PP_TUPLE_EAT_4)(o(25, s), p, o, m) # define BOOST_PP_FOR_25(s, p, o, m) BOOST_PP_IF(p(26, s), m, BOOST_PP_TUPLE_EAT_2)(26, s) BOOST_PP_IF(p(26, s), BOOST_PP_FOR_26, BOOST_PP_TUPLE_EAT_4)(o(26, s), p, o, m) # define BOOST_PP_FOR_26(s, p, o, m) BOOST_PP_IF(p(27, s), m, BOOST_PP_TUPLE_EAT_2)(27, s) BOOST_PP_IF(p(27, s), BOOST_PP_FOR_27, BOOST_PP_TUPLE_EAT_4)(o(27, s), p, o, m) # define BOOST_PP_FOR_27(s, p, o, m) BOOST_PP_IF(p(28, s), m, BOOST_PP_TUPLE_EAT_2)(28, s) BOOST_PP_IF(p(28, s), BOOST_PP_FOR_28, BOOST_PP_TUPLE_EAT_4)(o(28, s), p, o, m) # define BOOST_PP_FOR_28(s, p, o, m) BOOST_PP_IF(p(29, s), m, BOOST_PP_TUPLE_EAT_2)(29, s) BOOST_PP_IF(p(29, s), BOOST_PP_FOR_29, BOOST_PP_TUPLE_EAT_4)(o(29, s), p, o, m) # define BOOST_PP_FOR_29(s, p, o, m) BOOST_PP_IF(p(30, s), m, BOOST_PP_TUPLE_EAT_2)(30, s) BOOST_PP_IF(p(30, s), BOOST_PP_FOR_30, BOOST_PP_TUPLE_EAT_4)(o(30, s), p, o, m) # define BOOST_PP_FOR_30(s, p, o, m) BOOST_PP_IF(p(31, s), m, BOOST_PP_TUPLE_EAT_2)(31, s) BOOST_PP_IF(p(31, s), BOOST_PP_FOR_31, BOOST_PP_TUPLE_EAT_4)(o(31, s), p, o, m) # define BOOST_PP_FOR_31(s, p, o, m) BOOST_PP_IF(p(32, s), m, BOOST_PP_TUPLE_EAT_2)(32, s) BOOST_PP_IF(p(32, s), BOOST_PP_FOR_32, BOOST_PP_TUPLE_EAT_4)(o(32, s), p, o, m) # define BOOST_PP_FOR_32(s, p, o, m) BOOST_PP_IF(p(33, s), m, BOOST_PP_TUPLE_EAT_2)(33, s) BOOST_PP_IF(p(33, s), BOOST_PP_FOR_33, BOOST_PP_TUPLE_EAT_4)(o(33, s), p, o, m) # define BOOST_PP_FOR_33(s, p, o, m) BOOST_PP_IF(p(34, s), m, BOOST_PP_TUPLE_EAT_2)(34, s) BOOST_PP_IF(p(34, s), BOOST_PP_FOR_34, BOOST_PP_TUPLE_EAT_4)(o(34, s), p, o, m) # define BOOST_PP_FOR_34(s, p, o, m) BOOST_PP_IF(p(35, s), m, BOOST_PP_TUPLE_EAT_2)(35, s) BOOST_PP_IF(p(35, s), BOOST_PP_FOR_35, BOOST_PP_TUPLE_EAT_4)(o(35, s), p, o, m) # define BOOST_PP_FOR_35(s, p, o, m) BOOST_PP_IF(p(36, s), m, BOOST_PP_TUPLE_EAT_2)(36, s) BOOST_PP_IF(p(36, s), BOOST_PP_FOR_36, BOOST_PP_TUPLE_EAT_4)(o(36, s), p, o, m) # define BOOST_PP_FOR_36(s, p, o, m) BOOST_PP_IF(p(37, s), m, BOOST_PP_TUPLE_EAT_2)(37, s) BOOST_PP_IF(p(37, s), BOOST_PP_FOR_37, BOOST_PP_TUPLE_EAT_4)(o(37, s), p, o, m) # define BOOST_PP_FOR_37(s, p, o, m) BOOST_PP_IF(p(38, s), m, BOOST_PP_TUPLE_EAT_2)(38, s) BOOST_PP_IF(p(38, s), BOOST_PP_FOR_38, BOOST_PP_TUPLE_EAT_4)(o(38, s), p, o, m) # define BOOST_PP_FOR_38(s, p, o, m) BOOST_PP_IF(p(39, s), m, BOOST_PP_TUPLE_EAT_2)(39, s) BOOST_PP_IF(p(39, s), BOOST_PP_FOR_39, BOOST_PP_TUPLE_EAT_4)(o(39, s), p, o, m) # define BOOST_PP_FOR_39(s, p, o, m) BOOST_PP_IF(p(40, s), m, BOOST_PP_TUPLE_EAT_2)(40, s) BOOST_PP_IF(p(40, s), BOOST_PP_FOR_40, BOOST_PP_TUPLE_EAT_4)(o(40, s), p, o, m) # define BOOST_PP_FOR_40(s, p, o, m) BOOST_PP_IF(p(41, s), m, BOOST_PP_TUPLE_EAT_2)(41, s) BOOST_PP_IF(p(41, s), BOOST_PP_FOR_41, BOOST_PP_TUPLE_EAT_4)(o(41, s), p, o, m) # define BOOST_PP_FOR_41(s, p, o, m) BOOST_PP_IF(p(42, s), m, BOOST_PP_TUPLE_EAT_2)(42, s) BOOST_PP_IF(p(42, s), BOOST_PP_FOR_42, BOOST_PP_TUPLE_EAT_4)(o(42, s), p, o, m) # define BOOST_PP_FOR_42(s, p, o, m) BOOST_PP_IF(p(43, s), m, BOOST_PP_TUPLE_EAT_2)(43, s) BOOST_PP_IF(p(43, s), BOOST_PP_FOR_43, BOOST_PP_TUPLE_EAT_4)(o(43, s), p, o, m) # define BOOST_PP_FOR_43(s, p, o, m) BOOST_PP_IF(p(44, s), m, BOOST_PP_TUPLE_EAT_2)(44, s) BOOST_PP_IF(p(44, s), BOOST_PP_FOR_44, BOOST_PP_TUPLE_EAT_4)(o(44, s), p, o, m) # define BOOST_PP_FOR_44(s, p, o, m) BOOST_PP_IF(p(45, s), m, BOOST_PP_TUPLE_EAT_2)(45, s) BOOST_PP_IF(p(45, s), BOOST_PP_FOR_45, BOOST_PP_TUPLE_EAT_4)(o(45, s), p, o, m) # define BOOST_PP_FOR_45(s, p, o, m) BOOST_PP_IF(p(46, s), m, BOOST_PP_TUPLE_EAT_2)(46, s) BOOST_PP_IF(p(46, s), BOOST_PP_FOR_46, BOOST_PP_TUPLE_EAT_4)(o(46, s), p, o, m) # define BOOST_PP_FOR_46(s, p, o, m) BOOST_PP_IF(p(47, s), m, BOOST_PP_TUPLE_EAT_2)(47, s) BOOST_PP_IF(p(47, s), BOOST_PP_FOR_47, BOOST_PP_TUPLE_EAT_4)(o(47, s), p, o, m) # define BOOST_PP_FOR_47(s, p, o, m) BOOST_PP_IF(p(48, s), m, BOOST_PP_TUPLE_EAT_2)(48, s) BOOST_PP_IF(p(48, s), BOOST_PP_FOR_48, BOOST_PP_TUPLE_EAT_4)(o(48, s), p, o, m) # define BOOST_PP_FOR_48(s, p, o, m) BOOST_PP_IF(p(49, s), m, BOOST_PP_TUPLE_EAT_2)(49, s) BOOST_PP_IF(p(49, s), BOOST_PP_FOR_49, BOOST_PP_TUPLE_EAT_4)(o(49, s), p, o, m) # define BOOST_PP_FOR_49(s, p, o, m) BOOST_PP_IF(p(50, s), m, BOOST_PP_TUPLE_EAT_2)(50, s) BOOST_PP_IF(p(50, s), BOOST_PP_FOR_50, BOOST_PP_TUPLE_EAT_4)(o(50, s), p, o, m) # define BOOST_PP_FOR_50(s, p, o, m) BOOST_PP_IF(p(51, s), m, BOOST_PP_TUPLE_EAT_2)(51, s) BOOST_PP_IF(p(51, s), BOOST_PP_FOR_51, BOOST_PP_TUPLE_EAT_4)(o(51, s), p, o, m) # define BOOST_PP_FOR_51(s, p, o, m) BOOST_PP_IF(p(52, s), m, BOOST_PP_TUPLE_EAT_2)(52, s) BOOST_PP_IF(p(52, s), BOOST_PP_FOR_52, BOOST_PP_TUPLE_EAT_4)(o(52, s), p, o, m) # define BOOST_PP_FOR_52(s, p, o, m) BOOST_PP_IF(p(53, s), m, BOOST_PP_TUPLE_EAT_2)(53, s) BOOST_PP_IF(p(53, s), BOOST_PP_FOR_53, BOOST_PP_TUPLE_EAT_4)(o(53, s), p, o, m) # define BOOST_PP_FOR_53(s, p, o, m) BOOST_PP_IF(p(54, s), m, BOOST_PP_TUPLE_EAT_2)(54, s) BOOST_PP_IF(p(54, s), BOOST_PP_FOR_54, BOOST_PP_TUPLE_EAT_4)(o(54, s), p, o, m) # define BOOST_PP_FOR_54(s, p, o, m) BOOST_PP_IF(p(55, s), m, BOOST_PP_TUPLE_EAT_2)(55, s) BOOST_PP_IF(p(55, s), BOOST_PP_FOR_55, BOOST_PP_TUPLE_EAT_4)(o(55, s), p, o, m) # define BOOST_PP_FOR_55(s, p, o, m) BOOST_PP_IF(p(56, s), m, BOOST_PP_TUPLE_EAT_2)(56, s) BOOST_PP_IF(p(56, s), BOOST_PP_FOR_56, BOOST_PP_TUPLE_EAT_4)(o(56, s), p, o, m) # define BOOST_PP_FOR_56(s, p, o, m) BOOST_PP_IF(p(57, s), m, BOOST_PP_TUPLE_EAT_2)(57, s) BOOST_PP_IF(p(57, s), BOOST_PP_FOR_57, BOOST_PP_TUPLE_EAT_4)(o(57, s), p, o, m) # define BOOST_PP_FOR_57(s, p, o, m) BOOST_PP_IF(p(58, s), m, BOOST_PP_TUPLE_EAT_2)(58, s) BOOST_PP_IF(p(58, s), BOOST_PP_FOR_58, BOOST_PP_TUPLE_EAT_4)(o(58, s), p, o, m) # define BOOST_PP_FOR_58(s, p, o, m) BOOST_PP_IF(p(59, s), m, BOOST_PP_TUPLE_EAT_2)(59, s) BOOST_PP_IF(p(59, s), BOOST_PP_FOR_59, BOOST_PP_TUPLE_EAT_4)(o(59, s), p, o, m) # define BOOST_PP_FOR_59(s, p, o, m) BOOST_PP_IF(p(60, s), m, BOOST_PP_TUPLE_EAT_2)(60, s) BOOST_PP_IF(p(60, s), BOOST_PP_FOR_60, BOOST_PP_TUPLE_EAT_4)(o(60, s), p, o, m) # define BOOST_PP_FOR_60(s, p, o, m) BOOST_PP_IF(p(61, s), m, BOOST_PP_TUPLE_EAT_2)(61, s) BOOST_PP_IF(p(61, s), BOOST_PP_FOR_61, BOOST_PP_TUPLE_EAT_4)(o(61, s), p, o, m) # define BOOST_PP_FOR_61(s, p, o, m) BOOST_PP_IF(p(62, s), m, BOOST_PP_TUPLE_EAT_2)(62, s) BOOST_PP_IF(p(62, s), BOOST_PP_FOR_62, BOOST_PP_TUPLE_EAT_4)(o(62, s), p, o, m) # define BOOST_PP_FOR_62(s, p, o, m) BOOST_PP_IF(p(63, s), m, BOOST_PP_TUPLE_EAT_2)(63, s) BOOST_PP_IF(p(63, s), BOOST_PP_FOR_63, BOOST_PP_TUPLE_EAT_4)(o(63, s), p, o, m) # define BOOST_PP_FOR_63(s, p, o, m) BOOST_PP_IF(p(64, s), m, BOOST_PP_TUPLE_EAT_2)(64, s) BOOST_PP_IF(p(64, s), BOOST_PP_FOR_64, BOOST_PP_TUPLE_EAT_4)(o(64, s), p, o, m) # define BOOST_PP_FOR_64(s, p, o, m) BOOST_PP_IF(p(65, s), m, BOOST_PP_TUPLE_EAT_2)(65, s) BOOST_PP_IF(p(65, s), BOOST_PP_FOR_65, BOOST_PP_TUPLE_EAT_4)(o(65, s), p, o, m) # define BOOST_PP_FOR_65(s, p, o, m) BOOST_PP_IF(p(66, s), m, BOOST_PP_TUPLE_EAT_2)(66, s) BOOST_PP_IF(p(66, s), BOOST_PP_FOR_66, BOOST_PP_TUPLE_EAT_4)(o(66, s), p, o, m) # define BOOST_PP_FOR_66(s, p, o, m) BOOST_PP_IF(p(67, s), m, BOOST_PP_TUPLE_EAT_2)(67, s) BOOST_PP_IF(p(67, s), BOOST_PP_FOR_67, BOOST_PP_TUPLE_EAT_4)(o(67, s), p, o, m) # define BOOST_PP_FOR_67(s, p, o, m) BOOST_PP_IF(p(68, s), m, BOOST_PP_TUPLE_EAT_2)(68, s) BOOST_PP_IF(p(68, s), BOOST_PP_FOR_68, BOOST_PP_TUPLE_EAT_4)(o(68, s), p, o, m) # define BOOST_PP_FOR_68(s, p, o, m) BOOST_PP_IF(p(69, s), m, BOOST_PP_TUPLE_EAT_2)(69, s) BOOST_PP_IF(p(69, s), BOOST_PP_FOR_69, BOOST_PP_TUPLE_EAT_4)(o(69, s), p, o, m) # define BOOST_PP_FOR_69(s, p, o, m) BOOST_PP_IF(p(70, s), m, BOOST_PP_TUPLE_EAT_2)(70, s) BOOST_PP_IF(p(70, s), BOOST_PP_FOR_70, BOOST_PP_TUPLE_EAT_4)(o(70, s), p, o, m) # define BOOST_PP_FOR_70(s, p, o, m) BOOST_PP_IF(p(71, s), m, BOOST_PP_TUPLE_EAT_2)(71, s) BOOST_PP_IF(p(71, s), BOOST_PP_FOR_71, BOOST_PP_TUPLE_EAT_4)(o(71, s), p, o, m) # define BOOST_PP_FOR_71(s, p, o, m) BOOST_PP_IF(p(72, s), m, BOOST_PP_TUPLE_EAT_2)(72, s) BOOST_PP_IF(p(72, s), BOOST_PP_FOR_72, BOOST_PP_TUPLE_EAT_4)(o(72, s), p, o, m) # define BOOST_PP_FOR_72(s, p, o, m) BOOST_PP_IF(p(73, s), m, BOOST_PP_TUPLE_EAT_2)(73, s) BOOST_PP_IF(p(73, s), BOOST_PP_FOR_73, BOOST_PP_TUPLE_EAT_4)(o(73, s), p, o, m) # define BOOST_PP_FOR_73(s, p, o, m) BOOST_PP_IF(p(74, s), m, BOOST_PP_TUPLE_EAT_2)(74, s) BOOST_PP_IF(p(74, s), BOOST_PP_FOR_74, BOOST_PP_TUPLE_EAT_4)(o(74, s), p, o, m) # define BOOST_PP_FOR_74(s, p, o, m) BOOST_PP_IF(p(75, s), m, BOOST_PP_TUPLE_EAT_2)(75, s) BOOST_PP_IF(p(75, s), BOOST_PP_FOR_75, BOOST_PP_TUPLE_EAT_4)(o(75, s), p, o, m) # define BOOST_PP_FOR_75(s, p, o, m) BOOST_PP_IF(p(76, s), m, BOOST_PP_TUPLE_EAT_2)(76, s) BOOST_PP_IF(p(76, s), BOOST_PP_FOR_76, BOOST_PP_TUPLE_EAT_4)(o(76, s), p, o, m) # define BOOST_PP_FOR_76(s, p, o, m) BOOST_PP_IF(p(77, s), m, BOOST_PP_TUPLE_EAT_2)(77, s) BOOST_PP_IF(p(77, s), BOOST_PP_FOR_77, BOOST_PP_TUPLE_EAT_4)(o(77, s), p, o, m) # define BOOST_PP_FOR_77(s, p, o, m) BOOST_PP_IF(p(78, s), m, BOOST_PP_TUPLE_EAT_2)(78, s) BOOST_PP_IF(p(78, s), BOOST_PP_FOR_78, BOOST_PP_TUPLE_EAT_4)(o(78, s), p, o, m) # define BOOST_PP_FOR_78(s, p, o, m) BOOST_PP_IF(p(79, s), m, BOOST_PP_TUPLE_EAT_2)(79, s) BOOST_PP_IF(p(79, s), BOOST_PP_FOR_79, BOOST_PP_TUPLE_EAT_4)(o(79, s), p, o, m) # define BOOST_PP_FOR_79(s, p, o, m) BOOST_PP_IF(p(80, s), m, BOOST_PP_TUPLE_EAT_2)(80, s) BOOST_PP_IF(p(80, s), BOOST_PP_FOR_80, BOOST_PP_TUPLE_EAT_4)(o(80, s), p, o, m) # define BOOST_PP_FOR_80(s, p, o, m) BOOST_PP_IF(p(81, s), m, BOOST_PP_TUPLE_EAT_2)(81, s) BOOST_PP_IF(p(81, s), BOOST_PP_FOR_81, BOOST_PP_TUPLE_EAT_4)(o(81, s), p, o, m) # define BOOST_PP_FOR_81(s, p, o, m) BOOST_PP_IF(p(82, s), m, BOOST_PP_TUPLE_EAT_2)(82, s) BOOST_PP_IF(p(82, s), BOOST_PP_FOR_82, BOOST_PP_TUPLE_EAT_4)(o(82, s), p, o, m) # define BOOST_PP_FOR_82(s, p, o, m) BOOST_PP_IF(p(83, s), m, BOOST_PP_TUPLE_EAT_2)(83, s) BOOST_PP_IF(p(83, s), BOOST_PP_FOR_83, BOOST_PP_TUPLE_EAT_4)(o(83, s), p, o, m) # define BOOST_PP_FOR_83(s, p, o, m) BOOST_PP_IF(p(84, s), m, BOOST_PP_TUPLE_EAT_2)(84, s) BOOST_PP_IF(p(84, s), BOOST_PP_FOR_84, BOOST_PP_TUPLE_EAT_4)(o(84, s), p, o, m) # define BOOST_PP_FOR_84(s, p, o, m) BOOST_PP_IF(p(85, s), m, BOOST_PP_TUPLE_EAT_2)(85, s) BOOST_PP_IF(p(85, s), BOOST_PP_FOR_85, BOOST_PP_TUPLE_EAT_4)(o(85, s), p, o, m) # define BOOST_PP_FOR_85(s, p, o, m) BOOST_PP_IF(p(86, s), m, BOOST_PP_TUPLE_EAT_2)(86, s) BOOST_PP_IF(p(86, s), BOOST_PP_FOR_86, BOOST_PP_TUPLE_EAT_4)(o(86, s), p, o, m) # define BOOST_PP_FOR_86(s, p, o, m) BOOST_PP_IF(p(87, s), m, BOOST_PP_TUPLE_EAT_2)(87, s) BOOST_PP_IF(p(87, s), BOOST_PP_FOR_87, BOOST_PP_TUPLE_EAT_4)(o(87, s), p, o, m) # define BOOST_PP_FOR_87(s, p, o, m) BOOST_PP_IF(p(88, s), m, BOOST_PP_TUPLE_EAT_2)(88, s) BOOST_PP_IF(p(88, s), BOOST_PP_FOR_88, BOOST_PP_TUPLE_EAT_4)(o(88, s), p, o, m) # define BOOST_PP_FOR_88(s, p, o, m) BOOST_PP_IF(p(89, s), m, BOOST_PP_TUPLE_EAT_2)(89, s) BOOST_PP_IF(p(89, s), BOOST_PP_FOR_89, BOOST_PP_TUPLE_EAT_4)(o(89, s), p, o, m) # define BOOST_PP_FOR_89(s, p, o, m) BOOST_PP_IF(p(90, s), m, BOOST_PP_TUPLE_EAT_2)(90, s) BOOST_PP_IF(p(90, s), BOOST_PP_FOR_90, BOOST_PP_TUPLE_EAT_4)(o(90, s), p, o, m) # define BOOST_PP_FOR_90(s, p, o, m) BOOST_PP_IF(p(91, s), m, BOOST_PP_TUPLE_EAT_2)(91, s) BOOST_PP_IF(p(91, s), BOOST_PP_FOR_91, BOOST_PP_TUPLE_EAT_4)(o(91, s), p, o, m) # define BOOST_PP_FOR_91(s, p, o, m) BOOST_PP_IF(p(92, s), m, BOOST_PP_TUPLE_EAT_2)(92, s) BOOST_PP_IF(p(92, s), BOOST_PP_FOR_92, BOOST_PP_TUPLE_EAT_4)(o(92, s), p, o, m) # define BOOST_PP_FOR_92(s, p, o, m) BOOST_PP_IF(p(93, s), m, BOOST_PP_TUPLE_EAT_2)(93, s) BOOST_PP_IF(p(93, s), BOOST_PP_FOR_93, BOOST_PP_TUPLE_EAT_4)(o(93, s), p, o, m) # define BOOST_PP_FOR_93(s, p, o, m) BOOST_PP_IF(p(94, s), m, BOOST_PP_TUPLE_EAT_2)(94, s) BOOST_PP_IF(p(94, s), BOOST_PP_FOR_94, BOOST_PP_TUPLE_EAT_4)(o(94, s), p, o, m) # define BOOST_PP_FOR_94(s, p, o, m) BOOST_PP_IF(p(95, s), m, BOOST_PP_TUPLE_EAT_2)(95, s) BOOST_PP_IF(p(95, s), BOOST_PP_FOR_95, BOOST_PP_TUPLE_EAT_4)(o(95, s), p, o, m) # define BOOST_PP_FOR_95(s, p, o, m) BOOST_PP_IF(p(96, s), m, BOOST_PP_TUPLE_EAT_2)(96, s) BOOST_PP_IF(p(96, s), BOOST_PP_FOR_96, BOOST_PP_TUPLE_EAT_4)(o(96, s), p, o, m) # define BOOST_PP_FOR_96(s, p, o, m) BOOST_PP_IF(p(97, s), m, BOOST_PP_TUPLE_EAT_2)(97, s) BOOST_PP_IF(p(97, s), BOOST_PP_FOR_97, BOOST_PP_TUPLE_EAT_4)(o(97, s), p, o, m) # define BOOST_PP_FOR_97(s, p, o, m) BOOST_PP_IF(p(98, s), m, BOOST_PP_TUPLE_EAT_2)(98, s) BOOST_PP_IF(p(98, s), BOOST_PP_FOR_98, BOOST_PP_TUPLE_EAT_4)(o(98, s), p, o, m) # define BOOST_PP_FOR_98(s, p, o, m) BOOST_PP_IF(p(99, s), m, BOOST_PP_TUPLE_EAT_2)(99, s) BOOST_PP_IF(p(99, s), BOOST_PP_FOR_99, BOOST_PP_TUPLE_EAT_4)(o(99, s), p, o, m) # define BOOST_PP_FOR_99(s, p, o, m) BOOST_PP_IF(p(100, s), m, BOOST_PP_TUPLE_EAT_2)(100, s) BOOST_PP_IF(p(100, s), BOOST_PP_FOR_100, BOOST_PP_TUPLE_EAT_4)(o(100, s), p, o, m) # define BOOST_PP_FOR_100(s, p, o, m) BOOST_PP_IF(p(101, s), m, BOOST_PP_TUPLE_EAT_2)(101, s) BOOST_PP_IF(p(101, s), BOOST_PP_FOR_101, BOOST_PP_TUPLE_EAT_4)(o(101, s), p, o, m) # define BOOST_PP_FOR_101(s, p, o, m) BOOST_PP_IF(p(102, s), m, BOOST_PP_TUPLE_EAT_2)(102, s) BOOST_PP_IF(p(102, s), BOOST_PP_FOR_102, BOOST_PP_TUPLE_EAT_4)(o(102, s), p, o, m) # define BOOST_PP_FOR_102(s, p, o, m) BOOST_PP_IF(p(103, s), m, BOOST_PP_TUPLE_EAT_2)(103, s) BOOST_PP_IF(p(103, s), BOOST_PP_FOR_103, BOOST_PP_TUPLE_EAT_4)(o(103, s), p, o, m) # define BOOST_PP_FOR_103(s, p, o, m) BOOST_PP_IF(p(104, s), m, BOOST_PP_TUPLE_EAT_2)(104, s) BOOST_PP_IF(p(104, s), BOOST_PP_FOR_104, BOOST_PP_TUPLE_EAT_4)(o(104, s), p, o, m) # define BOOST_PP_FOR_104(s, p, o, m) BOOST_PP_IF(p(105, s), m, BOOST_PP_TUPLE_EAT_2)(105, s) BOOST_PP_IF(p(105, s), BOOST_PP_FOR_105, BOOST_PP_TUPLE_EAT_4)(o(105, s), p, o, m) # define BOOST_PP_FOR_105(s, p, o, m) BOOST_PP_IF(p(106, s), m, BOOST_PP_TUPLE_EAT_2)(106, s) BOOST_PP_IF(p(106, s), BOOST_PP_FOR_106, BOOST_PP_TUPLE_EAT_4)(o(106, s), p, o, m) # define BOOST_PP_FOR_106(s, p, o, m) BOOST_PP_IF(p(107, s), m, BOOST_PP_TUPLE_EAT_2)(107, s) BOOST_PP_IF(p(107, s), BOOST_PP_FOR_107, BOOST_PP_TUPLE_EAT_4)(o(107, s), p, o, m) # define BOOST_PP_FOR_107(s, p, o, m) BOOST_PP_IF(p(108, s), m, BOOST_PP_TUPLE_EAT_2)(108, s) BOOST_PP_IF(p(108, s), BOOST_PP_FOR_108, BOOST_PP_TUPLE_EAT_4)(o(108, s), p, o, m) # define BOOST_PP_FOR_108(s, p, o, m) BOOST_PP_IF(p(109, s), m, BOOST_PP_TUPLE_EAT_2)(109, s) BOOST_PP_IF(p(109, s), BOOST_PP_FOR_109, BOOST_PP_TUPLE_EAT_4)(o(109, s), p, o, m) # define BOOST_PP_FOR_109(s, p, o, m) BOOST_PP_IF(p(110, s), m, BOOST_PP_TUPLE_EAT_2)(110, s) BOOST_PP_IF(p(110, s), BOOST_PP_FOR_110, BOOST_PP_TUPLE_EAT_4)(o(110, s), p, o, m) # define BOOST_PP_FOR_110(s, p, o, m) BOOST_PP_IF(p(111, s), m, BOOST_PP_TUPLE_EAT_2)(111, s) BOOST_PP_IF(p(111, s), BOOST_PP_FOR_111, BOOST_PP_TUPLE_EAT_4)(o(111, s), p, o, m) # define BOOST_PP_FOR_111(s, p, o, m) BOOST_PP_IF(p(112, s), m, BOOST_PP_TUPLE_EAT_2)(112, s) BOOST_PP_IF(p(112, s), BOOST_PP_FOR_112, BOOST_PP_TUPLE_EAT_4)(o(112, s), p, o, m) # define BOOST_PP_FOR_112(s, p, o, m) BOOST_PP_IF(p(113, s), m, BOOST_PP_TUPLE_EAT_2)(113, s) BOOST_PP_IF(p(113, s), BOOST_PP_FOR_113, BOOST_PP_TUPLE_EAT_4)(o(113, s), p, o, m) # define BOOST_PP_FOR_113(s, p, o, m) BOOST_PP_IF(p(114, s), m, BOOST_PP_TUPLE_EAT_2)(114, s) BOOST_PP_IF(p(114, s), BOOST_PP_FOR_114, BOOST_PP_TUPLE_EAT_4)(o(114, s), p, o, m) # define BOOST_PP_FOR_114(s, p, o, m) BOOST_PP_IF(p(115, s), m, BOOST_PP_TUPLE_EAT_2)(115, s) BOOST_PP_IF(p(115, s), BOOST_PP_FOR_115, BOOST_PP_TUPLE_EAT_4)(o(115, s), p, o, m) # define BOOST_PP_FOR_115(s, p, o, m) BOOST_PP_IF(p(116, s), m, BOOST_PP_TUPLE_EAT_2)(116, s) BOOST_PP_IF(p(116, s), BOOST_PP_FOR_116, BOOST_PP_TUPLE_EAT_4)(o(116, s), p, o, m) # define BOOST_PP_FOR_116(s, p, o, m) BOOST_PP_IF(p(117, s), m, BOOST_PP_TUPLE_EAT_2)(117, s) BOOST_PP_IF(p(117, s), BOOST_PP_FOR_117, BOOST_PP_TUPLE_EAT_4)(o(117, s), p, o, m) # define BOOST_PP_FOR_117(s, p, o, m) BOOST_PP_IF(p(118, s), m, BOOST_PP_TUPLE_EAT_2)(118, s) BOOST_PP_IF(p(118, s), BOOST_PP_FOR_118, BOOST_PP_TUPLE_EAT_4)(o(118, s), p, o, m) # define BOOST_PP_FOR_118(s, p, o, m) BOOST_PP_IF(p(119, s), m, BOOST_PP_TUPLE_EAT_2)(119, s) BOOST_PP_IF(p(119, s), BOOST_PP_FOR_119, BOOST_PP_TUPLE_EAT_4)(o(119, s), p, o, m) # define BOOST_PP_FOR_119(s, p, o, m) BOOST_PP_IF(p(120, s), m, BOOST_PP_TUPLE_EAT_2)(120, s) BOOST_PP_IF(p(120, s), BOOST_PP_FOR_120, BOOST_PP_TUPLE_EAT_4)(o(120, s), p, o, m) # define BOOST_PP_FOR_120(s, p, o, m) BOOST_PP_IF(p(121, s), m, BOOST_PP_TUPLE_EAT_2)(121, s) BOOST_PP_IF(p(121, s), BOOST_PP_FOR_121, BOOST_PP_TUPLE_EAT_4)(o(121, s), p, o, m) # define BOOST_PP_FOR_121(s, p, o, m) BOOST_PP_IF(p(122, s), m, BOOST_PP_TUPLE_EAT_2)(122, s) BOOST_PP_IF(p(122, s), BOOST_PP_FOR_122, BOOST_PP_TUPLE_EAT_4)(o(122, s), p, o, m) # define BOOST_PP_FOR_122(s, p, o, m) BOOST_PP_IF(p(123, s), m, BOOST_PP_TUPLE_EAT_2)(123, s) BOOST_PP_IF(p(123, s), BOOST_PP_FOR_123, BOOST_PP_TUPLE_EAT_4)(o(123, s), p, o, m) # define BOOST_PP_FOR_123(s, p, o, m) BOOST_PP_IF(p(124, s), m, BOOST_PP_TUPLE_EAT_2)(124, s) BOOST_PP_IF(p(124, s), BOOST_PP_FOR_124, BOOST_PP_TUPLE_EAT_4)(o(124, s), p, o, m) # define BOOST_PP_FOR_124(s, p, o, m) BOOST_PP_IF(p(125, s), m, BOOST_PP_TUPLE_EAT_2)(125, s) BOOST_PP_IF(p(125, s), BOOST_PP_FOR_125, BOOST_PP_TUPLE_EAT_4)(o(125, s), p, o, m) # define BOOST_PP_FOR_125(s, p, o, m) BOOST_PP_IF(p(126, s), m, BOOST_PP_TUPLE_EAT_2)(126, s) BOOST_PP_IF(p(126, s), BOOST_PP_FOR_126, BOOST_PP_TUPLE_EAT_4)(o(126, s), p, o, m) # define BOOST_PP_FOR_126(s, p, o, m) BOOST_PP_IF(p(127, s), m, BOOST_PP_TUPLE_EAT_2)(127, s) BOOST_PP_IF(p(127, s), BOOST_PP_FOR_127, BOOST_PP_TUPLE_EAT_4)(o(127, s), p, o, m) # define BOOST_PP_FOR_127(s, p, o, m) BOOST_PP_IF(p(128, s), m, BOOST_PP_TUPLE_EAT_2)(128, s) BOOST_PP_IF(p(128, s), BOOST_PP_FOR_128, BOOST_PP_TUPLE_EAT_4)(o(128, s), p, o, m) # define BOOST_PP_FOR_128(s, p, o, m) BOOST_PP_IF(p(129, s), m, BOOST_PP_TUPLE_EAT_2)(129, s) BOOST_PP_IF(p(129, s), BOOST_PP_FOR_129, BOOST_PP_TUPLE_EAT_4)(o(129, s), p, o, m) # define BOOST_PP_FOR_129(s, p, o, m) BOOST_PP_IF(p(130, s), m, BOOST_PP_TUPLE_EAT_2)(130, s) BOOST_PP_IF(p(130, s), BOOST_PP_FOR_130, BOOST_PP_TUPLE_EAT_4)(o(130, s), p, o, m) # define BOOST_PP_FOR_130(s, p, o, m) BOOST_PP_IF(p(131, s), m, BOOST_PP_TUPLE_EAT_2)(131, s) BOOST_PP_IF(p(131, s), BOOST_PP_FOR_131, BOOST_PP_TUPLE_EAT_4)(o(131, s), p, o, m) # define BOOST_PP_FOR_131(s, p, o, m) BOOST_PP_IF(p(132, s), m, BOOST_PP_TUPLE_EAT_2)(132, s) BOOST_PP_IF(p(132, s), BOOST_PP_FOR_132, BOOST_PP_TUPLE_EAT_4)(o(132, s), p, o, m) # define BOOST_PP_FOR_132(s, p, o, m) BOOST_PP_IF(p(133, s), m, BOOST_PP_TUPLE_EAT_2)(133, s) BOOST_PP_IF(p(133, s), BOOST_PP_FOR_133, BOOST_PP_TUPLE_EAT_4)(o(133, s), p, o, m) # define BOOST_PP_FOR_133(s, p, o, m) BOOST_PP_IF(p(134, s), m, BOOST_PP_TUPLE_EAT_2)(134, s) BOOST_PP_IF(p(134, s), BOOST_PP_FOR_134, BOOST_PP_TUPLE_EAT_4)(o(134, s), p, o, m) # define BOOST_PP_FOR_134(s, p, o, m) BOOST_PP_IF(p(135, s), m, BOOST_PP_TUPLE_EAT_2)(135, s) BOOST_PP_IF(p(135, s), BOOST_PP_FOR_135, BOOST_PP_TUPLE_EAT_4)(o(135, s), p, o, m) # define BOOST_PP_FOR_135(s, p, o, m) BOOST_PP_IF(p(136, s), m, BOOST_PP_TUPLE_EAT_2)(136, s) BOOST_PP_IF(p(136, s), BOOST_PP_FOR_136, BOOST_PP_TUPLE_EAT_4)(o(136, s), p, o, m) # define BOOST_PP_FOR_136(s, p, o, m) BOOST_PP_IF(p(137, s), m, BOOST_PP_TUPLE_EAT_2)(137, s) BOOST_PP_IF(p(137, s), BOOST_PP_FOR_137, BOOST_PP_TUPLE_EAT_4)(o(137, s), p, o, m) # define BOOST_PP_FOR_137(s, p, o, m) BOOST_PP_IF(p(138, s), m, BOOST_PP_TUPLE_EAT_2)(138, s) BOOST_PP_IF(p(138, s), BOOST_PP_FOR_138, BOOST_PP_TUPLE_EAT_4)(o(138, s), p, o, m) # define BOOST_PP_FOR_138(s, p, o, m) BOOST_PP_IF(p(139, s), m, BOOST_PP_TUPLE_EAT_2)(139, s) BOOST_PP_IF(p(139, s), BOOST_PP_FOR_139, BOOST_PP_TUPLE_EAT_4)(o(139, s), p, o, m) # define BOOST_PP_FOR_139(s, p, o, m) BOOST_PP_IF(p(140, s), m, BOOST_PP_TUPLE_EAT_2)(140, s) BOOST_PP_IF(p(140, s), BOOST_PP_FOR_140, BOOST_PP_TUPLE_EAT_4)(o(140, s), p, o, m) # define BOOST_PP_FOR_140(s, p, o, m) BOOST_PP_IF(p(141, s), m, BOOST_PP_TUPLE_EAT_2)(141, s) BOOST_PP_IF(p(141, s), BOOST_PP_FOR_141, BOOST_PP_TUPLE_EAT_4)(o(141, s), p, o, m) # define BOOST_PP_FOR_141(s, p, o, m) BOOST_PP_IF(p(142, s), m, BOOST_PP_TUPLE_EAT_2)(142, s) BOOST_PP_IF(p(142, s), BOOST_PP_FOR_142, BOOST_PP_TUPLE_EAT_4)(o(142, s), p, o, m) # define BOOST_PP_FOR_142(s, p, o, m) BOOST_PP_IF(p(143, s), m, BOOST_PP_TUPLE_EAT_2)(143, s) BOOST_PP_IF(p(143, s), BOOST_PP_FOR_143, BOOST_PP_TUPLE_EAT_4)(o(143, s), p, o, m) # define BOOST_PP_FOR_143(s, p, o, m) BOOST_PP_IF(p(144, s), m, BOOST_PP_TUPLE_EAT_2)(144, s) BOOST_PP_IF(p(144, s), BOOST_PP_FOR_144, BOOST_PP_TUPLE_EAT_4)(o(144, s), p, o, m) # define BOOST_PP_FOR_144(s, p, o, m) BOOST_PP_IF(p(145, s), m, BOOST_PP_TUPLE_EAT_2)(145, s) BOOST_PP_IF(p(145, s), BOOST_PP_FOR_145, BOOST_PP_TUPLE_EAT_4)(o(145, s), p, o, m) # define BOOST_PP_FOR_145(s, p, o, m) BOOST_PP_IF(p(146, s), m, BOOST_PP_TUPLE_EAT_2)(146, s) BOOST_PP_IF(p(146, s), BOOST_PP_FOR_146, BOOST_PP_TUPLE_EAT_4)(o(146, s), p, o, m) # define BOOST_PP_FOR_146(s, p, o, m) BOOST_PP_IF(p(147, s), m, BOOST_PP_TUPLE_EAT_2)(147, s) BOOST_PP_IF(p(147, s), BOOST_PP_FOR_147, BOOST_PP_TUPLE_EAT_4)(o(147, s), p, o, m) # define BOOST_PP_FOR_147(s, p, o, m) BOOST_PP_IF(p(148, s), m, BOOST_PP_TUPLE_EAT_2)(148, s) BOOST_PP_IF(p(148, s), BOOST_PP_FOR_148, BOOST_PP_TUPLE_EAT_4)(o(148, s), p, o, m) # define BOOST_PP_FOR_148(s, p, o, m) BOOST_PP_IF(p(149, s), m, BOOST_PP_TUPLE_EAT_2)(149, s) BOOST_PP_IF(p(149, s), BOOST_PP_FOR_149, BOOST_PP_TUPLE_EAT_4)(o(149, s), p, o, m) # define BOOST_PP_FOR_149(s, p, o, m) BOOST_PP_IF(p(150, s), m, BOOST_PP_TUPLE_EAT_2)(150, s) BOOST_PP_IF(p(150, s), BOOST_PP_FOR_150, BOOST_PP_TUPLE_EAT_4)(o(150, s), p, o, m) # define BOOST_PP_FOR_150(s, p, o, m) BOOST_PP_IF(p(151, s), m, BOOST_PP_TUPLE_EAT_2)(151, s) BOOST_PP_IF(p(151, s), BOOST_PP_FOR_151, BOOST_PP_TUPLE_EAT_4)(o(151, s), p, o, m) # define BOOST_PP_FOR_151(s, p, o, m) BOOST_PP_IF(p(152, s), m, BOOST_PP_TUPLE_EAT_2)(152, s) BOOST_PP_IF(p(152, s), BOOST_PP_FOR_152, BOOST_PP_TUPLE_EAT_4)(o(152, s), p, o, m) # define BOOST_PP_FOR_152(s, p, o, m) BOOST_PP_IF(p(153, s), m, BOOST_PP_TUPLE_EAT_2)(153, s) BOOST_PP_IF(p(153, s), BOOST_PP_FOR_153, BOOST_PP_TUPLE_EAT_4)(o(153, s), p, o, m) # define BOOST_PP_FOR_153(s, p, o, m) BOOST_PP_IF(p(154, s), m, BOOST_PP_TUPLE_EAT_2)(154, s) BOOST_PP_IF(p(154, s), BOOST_PP_FOR_154, BOOST_PP_TUPLE_EAT_4)(o(154, s), p, o, m) # define BOOST_PP_FOR_154(s, p, o, m) BOOST_PP_IF(p(155, s), m, BOOST_PP_TUPLE_EAT_2)(155, s) BOOST_PP_IF(p(155, s), BOOST_PP_FOR_155, BOOST_PP_TUPLE_EAT_4)(o(155, s), p, o, m) # define BOOST_PP_FOR_155(s, p, o, m) BOOST_PP_IF(p(156, s), m, BOOST_PP_TUPLE_EAT_2)(156, s) BOOST_PP_IF(p(156, s), BOOST_PP_FOR_156, BOOST_PP_TUPLE_EAT_4)(o(156, s), p, o, m) # define BOOST_PP_FOR_156(s, p, o, m) BOOST_PP_IF(p(157, s), m, BOOST_PP_TUPLE_EAT_2)(157, s) BOOST_PP_IF(p(157, s), BOOST_PP_FOR_157, BOOST_PP_TUPLE_EAT_4)(o(157, s), p, o, m) # define BOOST_PP_FOR_157(s, p, o, m) BOOST_PP_IF(p(158, s), m, BOOST_PP_TUPLE_EAT_2)(158, s) BOOST_PP_IF(p(158, s), BOOST_PP_FOR_158, BOOST_PP_TUPLE_EAT_4)(o(158, s), p, o, m) # define BOOST_PP_FOR_158(s, p, o, m) BOOST_PP_IF(p(159, s), m, BOOST_PP_TUPLE_EAT_2)(159, s) BOOST_PP_IF(p(159, s), BOOST_PP_FOR_159, BOOST_PP_TUPLE_EAT_4)(o(159, s), p, o, m) # define BOOST_PP_FOR_159(s, p, o, m) BOOST_PP_IF(p(160, s), m, BOOST_PP_TUPLE_EAT_2)(160, s) BOOST_PP_IF(p(160, s), BOOST_PP_FOR_160, BOOST_PP_TUPLE_EAT_4)(o(160, s), p, o, m) # define BOOST_PP_FOR_160(s, p, o, m) BOOST_PP_IF(p(161, s), m, BOOST_PP_TUPLE_EAT_2)(161, s) BOOST_PP_IF(p(161, s), BOOST_PP_FOR_161, BOOST_PP_TUPLE_EAT_4)(o(161, s), p, o, m) # define BOOST_PP_FOR_161(s, p, o, m) BOOST_PP_IF(p(162, s), m, BOOST_PP_TUPLE_EAT_2)(162, s) BOOST_PP_IF(p(162, s), BOOST_PP_FOR_162, BOOST_PP_TUPLE_EAT_4)(o(162, s), p, o, m) # define BOOST_PP_FOR_162(s, p, o, m) BOOST_PP_IF(p(163, s), m, BOOST_PP_TUPLE_EAT_2)(163, s) BOOST_PP_IF(p(163, s), BOOST_PP_FOR_163, BOOST_PP_TUPLE_EAT_4)(o(163, s), p, o, m) # define BOOST_PP_FOR_163(s, p, o, m) BOOST_PP_IF(p(164, s), m, BOOST_PP_TUPLE_EAT_2)(164, s) BOOST_PP_IF(p(164, s), BOOST_PP_FOR_164, BOOST_PP_TUPLE_EAT_4)(o(164, s), p, o, m) # define BOOST_PP_FOR_164(s, p, o, m) BOOST_PP_IF(p(165, s), m, BOOST_PP_TUPLE_EAT_2)(165, s) BOOST_PP_IF(p(165, s), BOOST_PP_FOR_165, BOOST_PP_TUPLE_EAT_4)(o(165, s), p, o, m) # define BOOST_PP_FOR_165(s, p, o, m) BOOST_PP_IF(p(166, s), m, BOOST_PP_TUPLE_EAT_2)(166, s) BOOST_PP_IF(p(166, s), BOOST_PP_FOR_166, BOOST_PP_TUPLE_EAT_4)(o(166, s), p, o, m) # define BOOST_PP_FOR_166(s, p, o, m) BOOST_PP_IF(p(167, s), m, BOOST_PP_TUPLE_EAT_2)(167, s) BOOST_PP_IF(p(167, s), BOOST_PP_FOR_167, BOOST_PP_TUPLE_EAT_4)(o(167, s), p, o, m) # define BOOST_PP_FOR_167(s, p, o, m) BOOST_PP_IF(p(168, s), m, BOOST_PP_TUPLE_EAT_2)(168, s) BOOST_PP_IF(p(168, s), BOOST_PP_FOR_168, BOOST_PP_TUPLE_EAT_4)(o(168, s), p, o, m) # define BOOST_PP_FOR_168(s, p, o, m) BOOST_PP_IF(p(169, s), m, BOOST_PP_TUPLE_EAT_2)(169, s) BOOST_PP_IF(p(169, s), BOOST_PP_FOR_169, BOOST_PP_TUPLE_EAT_4)(o(169, s), p, o, m) # define BOOST_PP_FOR_169(s, p, o, m) BOOST_PP_IF(p(170, s), m, BOOST_PP_TUPLE_EAT_2)(170, s) BOOST_PP_IF(p(170, s), BOOST_PP_FOR_170, BOOST_PP_TUPLE_EAT_4)(o(170, s), p, o, m) # define BOOST_PP_FOR_170(s, p, o, m) BOOST_PP_IF(p(171, s), m, BOOST_PP_TUPLE_EAT_2)(171, s) BOOST_PP_IF(p(171, s), BOOST_PP_FOR_171, BOOST_PP_TUPLE_EAT_4)(o(171, s), p, o, m) # define BOOST_PP_FOR_171(s, p, o, m) BOOST_PP_IF(p(172, s), m, BOOST_PP_TUPLE_EAT_2)(172, s) BOOST_PP_IF(p(172, s), BOOST_PP_FOR_172, BOOST_PP_TUPLE_EAT_4)(o(172, s), p, o, m) # define BOOST_PP_FOR_172(s, p, o, m) BOOST_PP_IF(p(173, s), m, BOOST_PP_TUPLE_EAT_2)(173, s) BOOST_PP_IF(p(173, s), BOOST_PP_FOR_173, BOOST_PP_TUPLE_EAT_4)(o(173, s), p, o, m) # define BOOST_PP_FOR_173(s, p, o, m) BOOST_PP_IF(p(174, s), m, BOOST_PP_TUPLE_EAT_2)(174, s) BOOST_PP_IF(p(174, s), BOOST_PP_FOR_174, BOOST_PP_TUPLE_EAT_4)(o(174, s), p, o, m) # define BOOST_PP_FOR_174(s, p, o, m) BOOST_PP_IF(p(175, s), m, BOOST_PP_TUPLE_EAT_2)(175, s) BOOST_PP_IF(p(175, s), BOOST_PP_FOR_175, BOOST_PP_TUPLE_EAT_4)(o(175, s), p, o, m) # define BOOST_PP_FOR_175(s, p, o, m) BOOST_PP_IF(p(176, s), m, BOOST_PP_TUPLE_EAT_2)(176, s) BOOST_PP_IF(p(176, s), BOOST_PP_FOR_176, BOOST_PP_TUPLE_EAT_4)(o(176, s), p, o, m) # define BOOST_PP_FOR_176(s, p, o, m) BOOST_PP_IF(p(177, s), m, BOOST_PP_TUPLE_EAT_2)(177, s) BOOST_PP_IF(p(177, s), BOOST_PP_FOR_177, BOOST_PP_TUPLE_EAT_4)(o(177, s), p, o, m) # define BOOST_PP_FOR_177(s, p, o, m) BOOST_PP_IF(p(178, s), m, BOOST_PP_TUPLE_EAT_2)(178, s) BOOST_PP_IF(p(178, s), BOOST_PP_FOR_178, BOOST_PP_TUPLE_EAT_4)(o(178, s), p, o, m) # define BOOST_PP_FOR_178(s, p, o, m) BOOST_PP_IF(p(179, s), m, BOOST_PP_TUPLE_EAT_2)(179, s) BOOST_PP_IF(p(179, s), BOOST_PP_FOR_179, BOOST_PP_TUPLE_EAT_4)(o(179, s), p, o, m) # define BOOST_PP_FOR_179(s, p, o, m) BOOST_PP_IF(p(180, s), m, BOOST_PP_TUPLE_EAT_2)(180, s) BOOST_PP_IF(p(180, s), BOOST_PP_FOR_180, BOOST_PP_TUPLE_EAT_4)(o(180, s), p, o, m) # define BOOST_PP_FOR_180(s, p, o, m) BOOST_PP_IF(p(181, s), m, BOOST_PP_TUPLE_EAT_2)(181, s) BOOST_PP_IF(p(181, s), BOOST_PP_FOR_181, BOOST_PP_TUPLE_EAT_4)(o(181, s), p, o, m) # define BOOST_PP_FOR_181(s, p, o, m) BOOST_PP_IF(p(182, s), m, BOOST_PP_TUPLE_EAT_2)(182, s) BOOST_PP_IF(p(182, s), BOOST_PP_FOR_182, BOOST_PP_TUPLE_EAT_4)(o(182, s), p, o, m) # define BOOST_PP_FOR_182(s, p, o, m) BOOST_PP_IF(p(183, s), m, BOOST_PP_TUPLE_EAT_2)(183, s) BOOST_PP_IF(p(183, s), BOOST_PP_FOR_183, BOOST_PP_TUPLE_EAT_4)(o(183, s), p, o, m) # define BOOST_PP_FOR_183(s, p, o, m) BOOST_PP_IF(p(184, s), m, BOOST_PP_TUPLE_EAT_2)(184, s) BOOST_PP_IF(p(184, s), BOOST_PP_FOR_184, BOOST_PP_TUPLE_EAT_4)(o(184, s), p, o, m) # define BOOST_PP_FOR_184(s, p, o, m) BOOST_PP_IF(p(185, s), m, BOOST_PP_TUPLE_EAT_2)(185, s) BOOST_PP_IF(p(185, s), BOOST_PP_FOR_185, BOOST_PP_TUPLE_EAT_4)(o(185, s), p, o, m) # define BOOST_PP_FOR_185(s, p, o, m) BOOST_PP_IF(p(186, s), m, BOOST_PP_TUPLE_EAT_2)(186, s) BOOST_PP_IF(p(186, s), BOOST_PP_FOR_186, BOOST_PP_TUPLE_EAT_4)(o(186, s), p, o, m) # define BOOST_PP_FOR_186(s, p, o, m) BOOST_PP_IF(p(187, s), m, BOOST_PP_TUPLE_EAT_2)(187, s) BOOST_PP_IF(p(187, s), BOOST_PP_FOR_187, BOOST_PP_TUPLE_EAT_4)(o(187, s), p, o, m) # define BOOST_PP_FOR_187(s, p, o, m) BOOST_PP_IF(p(188, s), m, BOOST_PP_TUPLE_EAT_2)(188, s) BOOST_PP_IF(p(188, s), BOOST_PP_FOR_188, BOOST_PP_TUPLE_EAT_4)(o(188, s), p, o, m) # define BOOST_PP_FOR_188(s, p, o, m) BOOST_PP_IF(p(189, s), m, BOOST_PP_TUPLE_EAT_2)(189, s) BOOST_PP_IF(p(189, s), BOOST_PP_FOR_189, BOOST_PP_TUPLE_EAT_4)(o(189, s), p, o, m) # define BOOST_PP_FOR_189(s, p, o, m) BOOST_PP_IF(p(190, s), m, BOOST_PP_TUPLE_EAT_2)(190, s) BOOST_PP_IF(p(190, s), BOOST_PP_FOR_190, BOOST_PP_TUPLE_EAT_4)(o(190, s), p, o, m) # define BOOST_PP_FOR_190(s, p, o, m) BOOST_PP_IF(p(191, s), m, BOOST_PP_TUPLE_EAT_2)(191, s) BOOST_PP_IF(p(191, s), BOOST_PP_FOR_191, BOOST_PP_TUPLE_EAT_4)(o(191, s), p, o, m) # define BOOST_PP_FOR_191(s, p, o, m) BOOST_PP_IF(p(192, s), m, BOOST_PP_TUPLE_EAT_2)(192, s) BOOST_PP_IF(p(192, s), BOOST_PP_FOR_192, BOOST_PP_TUPLE_EAT_4)(o(192, s), p, o, m) # define BOOST_PP_FOR_192(s, p, o, m) BOOST_PP_IF(p(193, s), m, BOOST_PP_TUPLE_EAT_2)(193, s) BOOST_PP_IF(p(193, s), BOOST_PP_FOR_193, BOOST_PP_TUPLE_EAT_4)(o(193, s), p, o, m) # define BOOST_PP_FOR_193(s, p, o, m) BOOST_PP_IF(p(194, s), m, BOOST_PP_TUPLE_EAT_2)(194, s) BOOST_PP_IF(p(194, s), BOOST_PP_FOR_194, BOOST_PP_TUPLE_EAT_4)(o(194, s), p, o, m) # define BOOST_PP_FOR_194(s, p, o, m) BOOST_PP_IF(p(195, s), m, BOOST_PP_TUPLE_EAT_2)(195, s) BOOST_PP_IF(p(195, s), BOOST_PP_FOR_195, BOOST_PP_TUPLE_EAT_4)(o(195, s), p, o, m) # define BOOST_PP_FOR_195(s, p, o, m) BOOST_PP_IF(p(196, s), m, BOOST_PP_TUPLE_EAT_2)(196, s) BOOST_PP_IF(p(196, s), BOOST_PP_FOR_196, BOOST_PP_TUPLE_EAT_4)(o(196, s), p, o, m) # define BOOST_PP_FOR_196(s, p, o, m) BOOST_PP_IF(p(197, s), m, BOOST_PP_TUPLE_EAT_2)(197, s) BOOST_PP_IF(p(197, s), BOOST_PP_FOR_197, BOOST_PP_TUPLE_EAT_4)(o(197, s), p, o, m) # define BOOST_PP_FOR_197(s, p, o, m) BOOST_PP_IF(p(198, s), m, BOOST_PP_TUPLE_EAT_2)(198, s) BOOST_PP_IF(p(198, s), BOOST_PP_FOR_198, BOOST_PP_TUPLE_EAT_4)(o(198, s), p, o, m) # define BOOST_PP_FOR_198(s, p, o, m) BOOST_PP_IF(p(199, s), m, BOOST_PP_TUPLE_EAT_2)(199, s) BOOST_PP_IF(p(199, s), BOOST_PP_FOR_199, BOOST_PP_TUPLE_EAT_4)(o(199, s), p, o, m) # define BOOST_PP_FOR_199(s, p, o, m) BOOST_PP_IF(p(200, s), m, BOOST_PP_TUPLE_EAT_2)(200, s) BOOST_PP_IF(p(200, s), BOOST_PP_FOR_200, BOOST_PP_TUPLE_EAT_4)(o(200, s), p, o, m) # define BOOST_PP_FOR_200(s, p, o, m) BOOST_PP_IF(p(201, s), m, BOOST_PP_TUPLE_EAT_2)(201, s) BOOST_PP_IF(p(201, s), BOOST_PP_FOR_201, BOOST_PP_TUPLE_EAT_4)(o(201, s), p, o, m) # define BOOST_PP_FOR_201(s, p, o, m) BOOST_PP_IF(p(202, s), m, BOOST_PP_TUPLE_EAT_2)(202, s) BOOST_PP_IF(p(202, s), BOOST_PP_FOR_202, BOOST_PP_TUPLE_EAT_4)(o(202, s), p, o, m) # define BOOST_PP_FOR_202(s, p, o, m) BOOST_PP_IF(p(203, s), m, BOOST_PP_TUPLE_EAT_2)(203, s) BOOST_PP_IF(p(203, s), BOOST_PP_FOR_203, BOOST_PP_TUPLE_EAT_4)(o(203, s), p, o, m) # define BOOST_PP_FOR_203(s, p, o, m) BOOST_PP_IF(p(204, s), m, BOOST_PP_TUPLE_EAT_2)(204, s) BOOST_PP_IF(p(204, s), BOOST_PP_FOR_204, BOOST_PP_TUPLE_EAT_4)(o(204, s), p, o, m) # define BOOST_PP_FOR_204(s, p, o, m) BOOST_PP_IF(p(205, s), m, BOOST_PP_TUPLE_EAT_2)(205, s) BOOST_PP_IF(p(205, s), BOOST_PP_FOR_205, BOOST_PP_TUPLE_EAT_4)(o(205, s), p, o, m) # define BOOST_PP_FOR_205(s, p, o, m) BOOST_PP_IF(p(206, s), m, BOOST_PP_TUPLE_EAT_2)(206, s) BOOST_PP_IF(p(206, s), BOOST_PP_FOR_206, BOOST_PP_TUPLE_EAT_4)(o(206, s), p, o, m) # define BOOST_PP_FOR_206(s, p, o, m) BOOST_PP_IF(p(207, s), m, BOOST_PP_TUPLE_EAT_2)(207, s) BOOST_PP_IF(p(207, s), BOOST_PP_FOR_207, BOOST_PP_TUPLE_EAT_4)(o(207, s), p, o, m) # define BOOST_PP_FOR_207(s, p, o, m) BOOST_PP_IF(p(208, s), m, BOOST_PP_TUPLE_EAT_2)(208, s) BOOST_PP_IF(p(208, s), BOOST_PP_FOR_208, BOOST_PP_TUPLE_EAT_4)(o(208, s), p, o, m) # define BOOST_PP_FOR_208(s, p, o, m) BOOST_PP_IF(p(209, s), m, BOOST_PP_TUPLE_EAT_2)(209, s) BOOST_PP_IF(p(209, s), BOOST_PP_FOR_209, BOOST_PP_TUPLE_EAT_4)(o(209, s), p, o, m) # define BOOST_PP_FOR_209(s, p, o, m) BOOST_PP_IF(p(210, s), m, BOOST_PP_TUPLE_EAT_2)(210, s) BOOST_PP_IF(p(210, s), BOOST_PP_FOR_210, BOOST_PP_TUPLE_EAT_4)(o(210, s), p, o, m) # define BOOST_PP_FOR_210(s, p, o, m) BOOST_PP_IF(p(211, s), m, BOOST_PP_TUPLE_EAT_2)(211, s) BOOST_PP_IF(p(211, s), BOOST_PP_FOR_211, BOOST_PP_TUPLE_EAT_4)(o(211, s), p, o, m) # define BOOST_PP_FOR_211(s, p, o, m) BOOST_PP_IF(p(212, s), m, BOOST_PP_TUPLE_EAT_2)(212, s) BOOST_PP_IF(p(212, s), BOOST_PP_FOR_212, BOOST_PP_TUPLE_EAT_4)(o(212, s), p, o, m) # define BOOST_PP_FOR_212(s, p, o, m) BOOST_PP_IF(p(213, s), m, BOOST_PP_TUPLE_EAT_2)(213, s) BOOST_PP_IF(p(213, s), BOOST_PP_FOR_213, BOOST_PP_TUPLE_EAT_4)(o(213, s), p, o, m) # define BOOST_PP_FOR_213(s, p, o, m) BOOST_PP_IF(p(214, s), m, BOOST_PP_TUPLE_EAT_2)(214, s) BOOST_PP_IF(p(214, s), BOOST_PP_FOR_214, BOOST_PP_TUPLE_EAT_4)(o(214, s), p, o, m) # define BOOST_PP_FOR_214(s, p, o, m) BOOST_PP_IF(p(215, s), m, BOOST_PP_TUPLE_EAT_2)(215, s) BOOST_PP_IF(p(215, s), BOOST_PP_FOR_215, BOOST_PP_TUPLE_EAT_4)(o(215, s), p, o, m) # define BOOST_PP_FOR_215(s, p, o, m) BOOST_PP_IF(p(216, s), m, BOOST_PP_TUPLE_EAT_2)(216, s) BOOST_PP_IF(p(216, s), BOOST_PP_FOR_216, BOOST_PP_TUPLE_EAT_4)(o(216, s), p, o, m) # define BOOST_PP_FOR_216(s, p, o, m) BOOST_PP_IF(p(217, s), m, BOOST_PP_TUPLE_EAT_2)(217, s) BOOST_PP_IF(p(217, s), BOOST_PP_FOR_217, BOOST_PP_TUPLE_EAT_4)(o(217, s), p, o, m) # define BOOST_PP_FOR_217(s, p, o, m) BOOST_PP_IF(p(218, s), m, BOOST_PP_TUPLE_EAT_2)(218, s) BOOST_PP_IF(p(218, s), BOOST_PP_FOR_218, BOOST_PP_TUPLE_EAT_4)(o(218, s), p, o, m) # define BOOST_PP_FOR_218(s, p, o, m) BOOST_PP_IF(p(219, s), m, BOOST_PP_TUPLE_EAT_2)(219, s) BOOST_PP_IF(p(219, s), BOOST_PP_FOR_219, BOOST_PP_TUPLE_EAT_4)(o(219, s), p, o, m) # define BOOST_PP_FOR_219(s, p, o, m) BOOST_PP_IF(p(220, s), m, BOOST_PP_TUPLE_EAT_2)(220, s) BOOST_PP_IF(p(220, s), BOOST_PP_FOR_220, BOOST_PP_TUPLE_EAT_4)(o(220, s), p, o, m) # define BOOST_PP_FOR_220(s, p, o, m) BOOST_PP_IF(p(221, s), m, BOOST_PP_TUPLE_EAT_2)(221, s) BOOST_PP_IF(p(221, s), BOOST_PP_FOR_221, BOOST_PP_TUPLE_EAT_4)(o(221, s), p, o, m) # define BOOST_PP_FOR_221(s, p, o, m) BOOST_PP_IF(p(222, s), m, BOOST_PP_TUPLE_EAT_2)(222, s) BOOST_PP_IF(p(222, s), BOOST_PP_FOR_222, BOOST_PP_TUPLE_EAT_4)(o(222, s), p, o, m) # define BOOST_PP_FOR_222(s, p, o, m) BOOST_PP_IF(p(223, s), m, BOOST_PP_TUPLE_EAT_2)(223, s) BOOST_PP_IF(p(223, s), BOOST_PP_FOR_223, BOOST_PP_TUPLE_EAT_4)(o(223, s), p, o, m) # define BOOST_PP_FOR_223(s, p, o, m) BOOST_PP_IF(p(224, s), m, BOOST_PP_TUPLE_EAT_2)(224, s) BOOST_PP_IF(p(224, s), BOOST_PP_FOR_224, BOOST_PP_TUPLE_EAT_4)(o(224, s), p, o, m) # define BOOST_PP_FOR_224(s, p, o, m) BOOST_PP_IF(p(225, s), m, BOOST_PP_TUPLE_EAT_2)(225, s) BOOST_PP_IF(p(225, s), BOOST_PP_FOR_225, BOOST_PP_TUPLE_EAT_4)(o(225, s), p, o, m) # define BOOST_PP_FOR_225(s, p, o, m) BOOST_PP_IF(p(226, s), m, BOOST_PP_TUPLE_EAT_2)(226, s) BOOST_PP_IF(p(226, s), BOOST_PP_FOR_226, BOOST_PP_TUPLE_EAT_4)(o(226, s), p, o, m) # define BOOST_PP_FOR_226(s, p, o, m) BOOST_PP_IF(p(227, s), m, BOOST_PP_TUPLE_EAT_2)(227, s) BOOST_PP_IF(p(227, s), BOOST_PP_FOR_227, BOOST_PP_TUPLE_EAT_4)(o(227, s), p, o, m) # define BOOST_PP_FOR_227(s, p, o, m) BOOST_PP_IF(p(228, s), m, BOOST_PP_TUPLE_EAT_2)(228, s) BOOST_PP_IF(p(228, s), BOOST_PP_FOR_228, BOOST_PP_TUPLE_EAT_4)(o(228, s), p, o, m) # define BOOST_PP_FOR_228(s, p, o, m) BOOST_PP_IF(p(229, s), m, BOOST_PP_TUPLE_EAT_2)(229, s) BOOST_PP_IF(p(229, s), BOOST_PP_FOR_229, BOOST_PP_TUPLE_EAT_4)(o(229, s), p, o, m) # define BOOST_PP_FOR_229(s, p, o, m) BOOST_PP_IF(p(230, s), m, BOOST_PP_TUPLE_EAT_2)(230, s) BOOST_PP_IF(p(230, s), BOOST_PP_FOR_230, BOOST_PP_TUPLE_EAT_4)(o(230, s), p, o, m) # define BOOST_PP_FOR_230(s, p, o, m) BOOST_PP_IF(p(231, s), m, BOOST_PP_TUPLE_EAT_2)(231, s) BOOST_PP_IF(p(231, s), BOOST_PP_FOR_231, BOOST_PP_TUPLE_EAT_4)(o(231, s), p, o, m) # define BOOST_PP_FOR_231(s, p, o, m) BOOST_PP_IF(p(232, s), m, BOOST_PP_TUPLE_EAT_2)(232, s) BOOST_PP_IF(p(232, s), BOOST_PP_FOR_232, BOOST_PP_TUPLE_EAT_4)(o(232, s), p, o, m) # define BOOST_PP_FOR_232(s, p, o, m) BOOST_PP_IF(p(233, s), m, BOOST_PP_TUPLE_EAT_2)(233, s) BOOST_PP_IF(p(233, s), BOOST_PP_FOR_233, BOOST_PP_TUPLE_EAT_4)(o(233, s), p, o, m) # define BOOST_PP_FOR_233(s, p, o, m) BOOST_PP_IF(p(234, s), m, BOOST_PP_TUPLE_EAT_2)(234, s) BOOST_PP_IF(p(234, s), BOOST_PP_FOR_234, BOOST_PP_TUPLE_EAT_4)(o(234, s), p, o, m) # define BOOST_PP_FOR_234(s, p, o, m) BOOST_PP_IF(p(235, s), m, BOOST_PP_TUPLE_EAT_2)(235, s) BOOST_PP_IF(p(235, s), BOOST_PP_FOR_235, BOOST_PP_TUPLE_EAT_4)(o(235, s), p, o, m) # define BOOST_PP_FOR_235(s, p, o, m) BOOST_PP_IF(p(236, s), m, BOOST_PP_TUPLE_EAT_2)(236, s) BOOST_PP_IF(p(236, s), BOOST_PP_FOR_236, BOOST_PP_TUPLE_EAT_4)(o(236, s), p, o, m) # define BOOST_PP_FOR_236(s, p, o, m) BOOST_PP_IF(p(237, s), m, BOOST_PP_TUPLE_EAT_2)(237, s) BOOST_PP_IF(p(237, s), BOOST_PP_FOR_237, BOOST_PP_TUPLE_EAT_4)(o(237, s), p, o, m) # define BOOST_PP_FOR_237(s, p, o, m) BOOST_PP_IF(p(238, s), m, BOOST_PP_TUPLE_EAT_2)(238, s) BOOST_PP_IF(p(238, s), BOOST_PP_FOR_238, BOOST_PP_TUPLE_EAT_4)(o(238, s), p, o, m) # define BOOST_PP_FOR_238(s, p, o, m) BOOST_PP_IF(p(239, s), m, BOOST_PP_TUPLE_EAT_2)(239, s) BOOST_PP_IF(p(239, s), BOOST_PP_FOR_239, BOOST_PP_TUPLE_EAT_4)(o(239, s), p, o, m) # define BOOST_PP_FOR_239(s, p, o, m) BOOST_PP_IF(p(240, s), m, BOOST_PP_TUPLE_EAT_2)(240, s) BOOST_PP_IF(p(240, s), BOOST_PP_FOR_240, BOOST_PP_TUPLE_EAT_4)(o(240, s), p, o, m) # define BOOST_PP_FOR_240(s, p, o, m) BOOST_PP_IF(p(241, s), m, BOOST_PP_TUPLE_EAT_2)(241, s) BOOST_PP_IF(p(241, s), BOOST_PP_FOR_241, BOOST_PP_TUPLE_EAT_4)(o(241, s), p, o, m) # define BOOST_PP_FOR_241(s, p, o, m) BOOST_PP_IF(p(242, s), m, BOOST_PP_TUPLE_EAT_2)(242, s) BOOST_PP_IF(p(242, s), BOOST_PP_FOR_242, BOOST_PP_TUPLE_EAT_4)(o(242, s), p, o, m) # define BOOST_PP_FOR_242(s, p, o, m) BOOST_PP_IF(p(243, s), m, BOOST_PP_TUPLE_EAT_2)(243, s) BOOST_PP_IF(p(243, s), BOOST_PP_FOR_243, BOOST_PP_TUPLE_EAT_4)(o(243, s), p, o, m) # define BOOST_PP_FOR_243(s, p, o, m) BOOST_PP_IF(p(244, s), m, BOOST_PP_TUPLE_EAT_2)(244, s) BOOST_PP_IF(p(244, s), BOOST_PP_FOR_244, BOOST_PP_TUPLE_EAT_4)(o(244, s), p, o, m) # define BOOST_PP_FOR_244(s, p, o, m) BOOST_PP_IF(p(245, s), m, BOOST_PP_TUPLE_EAT_2)(245, s) BOOST_PP_IF(p(245, s), BOOST_PP_FOR_245, BOOST_PP_TUPLE_EAT_4)(o(245, s), p, o, m) # define BOOST_PP_FOR_245(s, p, o, m) BOOST_PP_IF(p(246, s), m, BOOST_PP_TUPLE_EAT_2)(246, s) BOOST_PP_IF(p(246, s), BOOST_PP_FOR_246, BOOST_PP_TUPLE_EAT_4)(o(246, s), p, o, m) # define BOOST_PP_FOR_246(s, p, o, m) BOOST_PP_IF(p(247, s), m, BOOST_PP_TUPLE_EAT_2)(247, s) BOOST_PP_IF(p(247, s), BOOST_PP_FOR_247, BOOST_PP_TUPLE_EAT_4)(o(247, s), p, o, m) # define BOOST_PP_FOR_247(s, p, o, m) BOOST_PP_IF(p(248, s), m, BOOST_PP_TUPLE_EAT_2)(248, s) BOOST_PP_IF(p(248, s), BOOST_PP_FOR_248, BOOST_PP_TUPLE_EAT_4)(o(248, s), p, o, m) # define BOOST_PP_FOR_248(s, p, o, m) BOOST_PP_IF(p(249, s), m, BOOST_PP_TUPLE_EAT_2)(249, s) BOOST_PP_IF(p(249, s), BOOST_PP_FOR_249, BOOST_PP_TUPLE_EAT_4)(o(249, s), p, o, m) # define BOOST_PP_FOR_249(s, p, o, m) BOOST_PP_IF(p(250, s), m, BOOST_PP_TUPLE_EAT_2)(250, s) BOOST_PP_IF(p(250, s), BOOST_PP_FOR_250, BOOST_PP_TUPLE_EAT_4)(o(250, s), p, o, m) # define BOOST_PP_FOR_250(s, p, o, m) BOOST_PP_IF(p(251, s), m, BOOST_PP_TUPLE_EAT_2)(251, s) BOOST_PP_IF(p(251, s), BOOST_PP_FOR_251, BOOST_PP_TUPLE_EAT_4)(o(251, s), p, o, m) # define BOOST_PP_FOR_251(s, p, o, m) BOOST_PP_IF(p(252, s), m, BOOST_PP_TUPLE_EAT_2)(252, s) BOOST_PP_IF(p(252, s), BOOST_PP_FOR_252, BOOST_PP_TUPLE_EAT_4)(o(252, s), p, o, m) # define BOOST_PP_FOR_252(s, p, o, m) BOOST_PP_IF(p(253, s), m, BOOST_PP_TUPLE_EAT_2)(253, s) BOOST_PP_IF(p(253, s), BOOST_PP_FOR_253, BOOST_PP_TUPLE_EAT_4)(o(253, s), p, o, m) # define BOOST_PP_FOR_253(s, p, o, m) BOOST_PP_IF(p(254, s), m, BOOST_PP_TUPLE_EAT_2)(254, s) BOOST_PP_IF(p(254, s), BOOST_PP_FOR_254, BOOST_PP_TUPLE_EAT_4)(o(254, s), p, o, m) # define BOOST_PP_FOR_254(s, p, o, m) BOOST_PP_IF(p(255, s), m, BOOST_PP_TUPLE_EAT_2)(255, s) BOOST_PP_IF(p(255, s), BOOST_PP_FOR_255, BOOST_PP_TUPLE_EAT_4)(o(255, s), p, o, m) # define BOOST_PP_FOR_255(s, p, o, m) BOOST_PP_IF(p(256, s), m, BOOST_PP_TUPLE_EAT_2)(256, s) BOOST_PP_IF(p(256, s), BOOST_PP_FOR_256, BOOST_PP_TUPLE_EAT_4)(o(256, s), p, o, m) # define BOOST_PP_FOR_256(s, p, o, m) BOOST_PP_IF(p(257, s), m, BOOST_PP_TUPLE_EAT_2)(257, s) BOOST_PP_IF(p(257, s), BOOST_PP_FOR_257, BOOST_PP_TUPLE_EAT_4)(o(257, s), p, o, m) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_HPP # # include # include # include # include # include # include # include # include # # /* BOOST_PP_ENUM */ # # if 0 # define BOOST_PP_ENUM(count, macro, data) # endif # # define BOOST_PP_ENUM BOOST_PP_CAT(BOOST_PP_ENUM_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_1(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_M_1, (m, d)) # define BOOST_PP_ENUM_2(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_M_2, (m, d)) # define BOOST_PP_ENUM_3(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_M_3, (m, d)) # else # define BOOST_PP_ENUM_1(c, m, d) BOOST_PP_ENUM_1_I(c, m, d) # define BOOST_PP_ENUM_2(c, m, d) BOOST_PP_ENUM_2_I(c, m, d) # define BOOST_PP_ENUM_3(c, m, d) BOOST_PP_ENUM_3_I(c, m, d) # define BOOST_PP_ENUM_1_I(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_M_1, (m, d)) # define BOOST_PP_ENUM_2_I(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_M_2, (m, d)) # define BOOST_PP_ENUM_3_I(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_M_3, (m, d)) # endif # # define BOOST_PP_ENUM_4(c, m, d) BOOST_PP_ERROR(0x0003) # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_ENUM_M_1(z, n, md) BOOST_PP_ENUM_M_1_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_M_2(z, n, md) BOOST_PP_ENUM_M_2_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_M_3(z, n, md) BOOST_PP_ENUM_M_3_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_M_1_IM(z, n, im) BOOST_PP_ENUM_M_1_I(z, n, im) # define BOOST_PP_ENUM_M_2_IM(z, n, im) BOOST_PP_ENUM_M_2_I(z, n, im) # define BOOST_PP_ENUM_M_3_IM(z, n, im) BOOST_PP_ENUM_M_3_I(z, n, im) # else # define BOOST_PP_ENUM_M_1(z, n, md) BOOST_PP_ENUM_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # define BOOST_PP_ENUM_M_2(z, n, md) BOOST_PP_ENUM_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # define BOOST_PP_ENUM_M_3(z, n, md) BOOST_PP_ENUM_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # endif # # define BOOST_PP_ENUM_M_1_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d) # define BOOST_PP_ENUM_M_2_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d) # define BOOST_PP_ENUM_M_3_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum_binary_params.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_BINARY_PARAMS_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_BINARY_PARAMS_HPP # # include # include # include # include # include # include # # /* BOOST_PP_ENUM_BINARY_PARAMS */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_BINARY_PARAMS(count, p1, p2) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2)) # else # define BOOST_PP_ENUM_BINARY_PARAMS(count, p1, p2) BOOST_PP_ENUM_BINARY_PARAMS_I(count, p1, p2) # define BOOST_PP_ENUM_BINARY_PARAMS_I(count, p1, p2) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2)) # endif # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_ENUM_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_BINARY_PARAMS_M_IM(z, n, BOOST_PP_TUPLE_REM_2 pp) # define BOOST_PP_ENUM_BINARY_PARAMS_M_IM(z, n, im) BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, im) # else # define BOOST_PP_ENUM_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, pp), BOOST_PP_TUPLE_ELEM(2, 1, pp)) # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, p1, p2) BOOST_PP_ENUM_BINARY_PARAMS_M_II(z, n, p1, p2) # define BOOST_PP_ENUM_BINARY_PARAMS_M_II(z, n, p1, p2) BOOST_PP_COMMA_IF(n) p1 ## n p2 ## n # else # define BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, p1, p2) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(p1, n) BOOST_PP_CAT(p2, n) # endif # # /* BOOST_PP_ENUM_BINARY_PARAMS_Z */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2)) # else # define BOOST_PP_ENUM_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_ENUM_BINARY_PARAMS_Z_I(z, count, p1, p2) # define BOOST_PP_ENUM_BINARY_PARAMS_Z_I(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum_params.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_HPP # # include # include # include # # /* BOOST_PP_ENUM_PARAMS */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_PARAMS(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_PARAMS_M, param) # else # define BOOST_PP_ENUM_PARAMS(count, param) BOOST_PP_ENUM_PARAMS_I(count, param) # define BOOST_PP_ENUM_PARAMS_I(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_PARAMS_M, param) # endif # # define BOOST_PP_ENUM_PARAMS_M(z, n, param) BOOST_PP_COMMA_IF(n) param ## n # # /* BOOST_PP_ENUM_PARAMS_Z */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_PARAMS_Z(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_PARAMS_M, param) # else # define BOOST_PP_ENUM_PARAMS_Z(z, count, param) BOOST_PP_ENUM_PARAMS_Z_I(z, count, param) # define BOOST_PP_ENUM_PARAMS_Z_I(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_PARAMS_M, param) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum_params_with_a_default.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_A_DEFAULT_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_A_DEFAULT_HPP # # include # include # include # # /* BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT */ # # define BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(count, param, def) BOOST_PP_ENUM_BINARY_PARAMS(count, param, = def BOOST_PP_INTERCEPT) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum_shifted.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_HPP # # include # include # include # include # include # include # include # include # include # include # # /* BOOST_PP_ENUM_SHIFTED */ # # if 0 # define BOOST_PP_ENUM_SHIFTED(count, macro, data) # endif # # define BOOST_PP_ENUM_SHIFTED BOOST_PP_CAT(BOOST_PP_ENUM_SHIFTED_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_SHIFTED_1(c, m, d) BOOST_PP_REPEAT_1(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_1, (m, d)) # define BOOST_PP_ENUM_SHIFTED_2(c, m, d) BOOST_PP_REPEAT_2(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_2, (m, d)) # define BOOST_PP_ENUM_SHIFTED_3(c, m, d) BOOST_PP_REPEAT_3(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_3, (m, d)) # else # define BOOST_PP_ENUM_SHIFTED_1(c, m, d) BOOST_PP_ENUM_SHIFTED_1_I(c, m, d) # define BOOST_PP_ENUM_SHIFTED_2(c, m, d) BOOST_PP_ENUM_SHIFTED_1_2(c, m, d) # define BOOST_PP_ENUM_SHIFTED_3(c, m, d) BOOST_PP_ENUM_SHIFTED_1_3(c, m, d) # define BOOST_PP_ENUM_SHIFTED_1_I(c, m, d) BOOST_PP_REPEAT_1(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_1, (m, d)) # define BOOST_PP_ENUM_SHIFTED_2_I(c, m, d) BOOST_PP_REPEAT_2(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_2, (m, d)) # define BOOST_PP_ENUM_SHIFTED_3_I(c, m, d) BOOST_PP_REPEAT_3(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_3, (m, d)) # endif # # define BOOST_PP_ENUM_SHIFTED_4(c, m, d) BOOST_PP_ERROR(0x0003) # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_ENUM_SHIFTED_M_1(z, n, md) BOOST_PP_ENUM_SHIFTED_M_1_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_SHIFTED_M_2(z, n, md) BOOST_PP_ENUM_SHIFTED_M_2_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_SHIFTED_M_3(z, n, md) BOOST_PP_ENUM_SHIFTED_M_3_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_SHIFTED_M_1_IM(z, n, im) BOOST_PP_ENUM_SHIFTED_M_1_I(z, n, im) # define BOOST_PP_ENUM_SHIFTED_M_2_IM(z, n, im) BOOST_PP_ENUM_SHIFTED_M_2_I(z, n, im) # define BOOST_PP_ENUM_SHIFTED_M_3_IM(z, n, im) BOOST_PP_ENUM_SHIFTED_M_3_I(z, n, im) # else # define BOOST_PP_ENUM_SHIFTED_M_1(z, n, md) BOOST_PP_ENUM_SHIFTED_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # define BOOST_PP_ENUM_SHIFTED_M_2(z, n, md) BOOST_PP_ENUM_SHIFTED_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # define BOOST_PP_ENUM_SHIFTED_M_3(z, n, md) BOOST_PP_ENUM_SHIFTED_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # endif # # define BOOST_PP_ENUM_SHIFTED_M_1_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, BOOST_PP_INC(n), d) # define BOOST_PP_ENUM_SHIFTED_M_2_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, BOOST_PP_INC(n), d) # define BOOST_PP_ENUM_SHIFTED_M_3_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, BOOST_PP_INC(n), d) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum_shifted_params.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_PARAMS_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_PARAMS_HPP # # include # include # include # include # include # include # # /* BOOST_PP_ENUM_SHIFTED_PARAMS */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_SHIFTED_PARAMS(count, param) BOOST_PP_REPEAT(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param) # else # define BOOST_PP_ENUM_SHIFTED_PARAMS(count, param) BOOST_PP_ENUM_SHIFTED_PARAMS_I(count, param) # define BOOST_PP_ENUM_SHIFTED_PARAMS_I(count, param) BOOST_PP_REPEAT(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param) # endif # # define BOOST_PP_ENUM_SHIFTED_PARAMS_M(z, n, param) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(param, BOOST_PP_INC(n)) # # /* BOOST_PP_ENUM_SHIFTED_PARAMS_Z */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, count, param) BOOST_PP_REPEAT_ ## z(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param) # else # define BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, count, param) BOOST_PP_ENUM_SHIFTED_PARAMS_Z_I(z, count, param) # define BOOST_PP_ENUM_SHIFTED_PARAMS_Z_I(z, count, param) BOOST_PP_REPEAT_ ## z(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum_trailing.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_HPP # # include # include # include # include # include # include # include # # /* BOOST_PP_ENUM_TRAILING */ # # if 0 # define BOOST_PP_ENUM_TRAILING(count, macro, data) # endif # # define BOOST_PP_ENUM_TRAILING BOOST_PP_CAT(BOOST_PP_ENUM_TRAILING_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_TRAILING_1(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_TRAILING_M_1, (m, d)) # define BOOST_PP_ENUM_TRAILING_2(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_TRAILING_M_2, (m, d)) # define BOOST_PP_ENUM_TRAILING_3(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_TRAILING_M_3, (m, d)) # else # define BOOST_PP_ENUM_TRAILING_1(c, m, d) BOOST_PP_ENUM_TRAILING_1_I(c, m, d) # define BOOST_PP_ENUM_TRAILING_2(c, m, d) BOOST_PP_ENUM_TRAILING_2_I(c, m, d) # define BOOST_PP_ENUM_TRAILING_3(c, m, d) BOOST_PP_ENUM_TRAILING_3_I(c, m, d) # define BOOST_PP_ENUM_TRAILING_1_I(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_TRAILING_M_1, (m, d)) # define BOOST_PP_ENUM_TRAILING_2_I(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_TRAILING_M_2, (m, d)) # define BOOST_PP_ENUM_TRAILING_3_I(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_TRAILING_M_3, (m, d)) # endif # # define BOOST_PP_ENUM_TRAILING_4(c, m, d) BOOST_PP_ERROR(0x0003) # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_ENUM_TRAILING_M_1(z, n, md) BOOST_PP_ENUM_TRAILING_M_1_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_TRAILING_M_2(z, n, md) BOOST_PP_ENUM_TRAILING_M_2_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_TRAILING_M_3(z, n, md) BOOST_PP_ENUM_TRAILING_M_3_IM(z, n, BOOST_PP_TUPLE_REM_2 md) # define BOOST_PP_ENUM_TRAILING_M_1_IM(z, n, im) BOOST_PP_ENUM_TRAILING_M_1_I(z, n, im) # define BOOST_PP_ENUM_TRAILING_M_2_IM(z, n, im) BOOST_PP_ENUM_TRAILING_M_2_I(z, n, im) # define BOOST_PP_ENUM_TRAILING_M_3_IM(z, n, im) BOOST_PP_ENUM_TRAILING_M_3_I(z, n, im) # else # define BOOST_PP_ENUM_TRAILING_M_1(z, n, md) BOOST_PP_ENUM_TRAILING_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # define BOOST_PP_ENUM_TRAILING_M_2(z, n, md) BOOST_PP_ENUM_TRAILING_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # define BOOST_PP_ENUM_TRAILING_M_3(z, n, md) BOOST_PP_ENUM_TRAILING_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md)) # endif # # define BOOST_PP_ENUM_TRAILING_M_1_I(z, n, m, d) , m(z, n, d) # define BOOST_PP_ENUM_TRAILING_M_2_I(z, n, m, d) , m(z, n, d) # define BOOST_PP_ENUM_TRAILING_M_3_I(z, n, m, d) , m(z, n, d) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/enum_trailing_params.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_PARAMS_HPP # define BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_PARAMS_HPP # # include # include # # /* BOOST_PP_ENUM_TRAILING_PARAMS */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_TRAILING_PARAMS(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param) # else # define BOOST_PP_ENUM_TRAILING_PARAMS(count, param) BOOST_PP_ENUM_TRAILING_PARAMS_I(count, param) # define BOOST_PP_ENUM_TRAILING_PARAMS_I(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param) # endif # # define BOOST_PP_ENUM_TRAILING_PARAMS_M(z, n, param) , param ## n # # /* BOOST_PP_ENUM_TRAILING_PARAMS_Z */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param) # else # define BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, count, param) BOOST_PP_ENUM_TRAILING_PARAMS_Z_I(z, count, param) # define BOOST_PP_ENUM_TRAILING_PARAMS_Z_I(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/for.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_FOR_HPP # define BOOST_PREPROCESSOR_REPETITION_FOR_HPP # # include # include # include # include # include # # /* BOOST_PP_FOR */ # # if 0 # define BOOST_PP_FOR(state, pred, op, macro) # endif # # define BOOST_PP_FOR BOOST_PP_CAT(BOOST_PP_FOR_, BOOST_PP_AUTO_REC(BOOST_PP_FOR_P, 256)) # # define BOOST_PP_FOR_P(n) BOOST_PP_CAT(BOOST_PP_FOR_CHECK_, BOOST_PP_FOR_ ## n(1, BOOST_PP_FOR_SR_P, BOOST_PP_FOR_SR_O, BOOST_PP_FOR_SR_M)) # # define BOOST_PP_FOR_SR_P(r, s) s # define BOOST_PP_FOR_SR_O(r, s) 0 # define BOOST_PP_FOR_SR_M(r, s) BOOST_PP_NIL # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # include # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # include # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # include # else # include # endif # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # define BOOST_PP_FOR_257_PR(s, p) BOOST_PP_BOOL(p##(257, s)) # else # define BOOST_PP_FOR_257_PR(s, p) BOOST_PP_BOOL(p(257, s)) # endif # define BOOST_PP_FOR_257_ERROR() BOOST_PP_ERROR(0x0002) # define BOOST_PP_FOR_257(s, p, o, m) \ BOOST_PP_IIF \ ( \ BOOST_PP_FOR_257_PR(s,p), \ BOOST_PP_FOR_257_ERROR, \ BOOST_PP_EMPTY \ ) \ () \ /**/ // # define BOOST_PP_FOR_257(s, p, o, m) BOOST_PP_ERROR(0x0002) # # define BOOST_PP_FOR_CHECK_BOOST_PP_NIL 1 # # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_1(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_2(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_3(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_4(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_5(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_6(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_7(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_8(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_9(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_10(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_11(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_12(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_13(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_14(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_15(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_16(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_17(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_18(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_19(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_20(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_21(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_22(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_23(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_24(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_25(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_26(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_27(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_28(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_29(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_30(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_31(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_32(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_33(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_34(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_35(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_36(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_37(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_38(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_39(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_40(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_41(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_42(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_43(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_44(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_45(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_46(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_47(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_48(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_49(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_50(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_51(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_52(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_53(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_54(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_55(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_56(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_57(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_58(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_59(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_60(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_61(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_62(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_63(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_64(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_65(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_66(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_67(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_68(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_69(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_70(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_71(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_72(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_73(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_74(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_75(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_76(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_77(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_78(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_79(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_80(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_81(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_82(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_83(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_84(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_85(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_86(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_87(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_88(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_89(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_90(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_91(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_92(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_93(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_94(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_95(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_96(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_97(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_98(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_99(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_100(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_101(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_102(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_103(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_104(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_105(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_106(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_107(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_108(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_109(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_110(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_111(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_112(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_113(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_114(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_115(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_116(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_117(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_118(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_119(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_120(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_121(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_122(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_123(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_124(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_125(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_126(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_127(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_128(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_129(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_130(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_131(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_132(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_133(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_134(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_135(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_136(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_137(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_138(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_139(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_140(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_141(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_142(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_143(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_144(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_145(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_146(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_147(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_148(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_149(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_150(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_151(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_152(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_153(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_154(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_155(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_156(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_157(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_158(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_159(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_160(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_161(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_162(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_163(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_164(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_165(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_166(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_167(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_168(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_169(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_170(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_171(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_172(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_173(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_174(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_175(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_176(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_177(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_178(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_179(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_180(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_181(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_182(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_183(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_184(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_185(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_186(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_187(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_188(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_189(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_190(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_191(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_192(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_193(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_194(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_195(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_196(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_197(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_198(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_199(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_200(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_201(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_202(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_203(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_204(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_205(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_206(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_207(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_208(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_209(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_210(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_211(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_212(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_213(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_214(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_215(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_216(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_217(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_218(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_219(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_220(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_221(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_222(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_223(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_224(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_225(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_226(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_227(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_228(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_229(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_230(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_231(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_232(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_233(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_234(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_235(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_236(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_237(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_238(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_239(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_240(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_241(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_242(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_243(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_244(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_245(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_246(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_247(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_248(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_249(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_250(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_251(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_252(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_253(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_254(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_255(s, p, o, m) 0 # define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_256(s, p, o, m) 0 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/repeat.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_REPEAT_HPP # define BOOST_PREPROCESSOR_REPETITION_REPEAT_HPP # # include # include # include # include # include # # /* BOOST_PP_REPEAT */ # # if 0 # define BOOST_PP_REPEAT(count, macro, data) # endif # # define BOOST_PP_REPEAT BOOST_PP_CAT(BOOST_PP_REPEAT_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)) # # define BOOST_PP_REPEAT_P(n) BOOST_PP_CAT(BOOST_PP_REPEAT_CHECK_, BOOST_PP_REPEAT_ ## n(1, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3, BOOST_PP_NIL)) # # define BOOST_PP_REPEAT_CHECK_BOOST_PP_NIL 1 # define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_1(c, m, d) 0 # define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_2(c, m, d) 0 # define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_3(c, m, d) 0 # # define BOOST_PP_REPEAT_1(c, m, d) BOOST_PP_REPEAT_1_I(c, m, d) # define BOOST_PP_REPEAT_2(c, m, d) BOOST_PP_REPEAT_2_I(c, m, d) # define BOOST_PP_REPEAT_3(c, m, d) BOOST_PP_REPEAT_3_I(c, m, d) # define BOOST_PP_REPEAT_4(c, m, d) BOOST_PP_ERROR(0x0003) # # define BOOST_PP_REPEAT_1_I(c, m, d) BOOST_PP_REPEAT_1_ ## c(m, d) # define BOOST_PP_REPEAT_2_I(c, m, d) BOOST_PP_REPEAT_2_ ## c(m, d) # define BOOST_PP_REPEAT_3_I(c, m, d) BOOST_PP_REPEAT_3_ ## c(m, d) # # define BOOST_PP_REPEAT_1ST BOOST_PP_REPEAT_1 # define BOOST_PP_REPEAT_2ND BOOST_PP_REPEAT_2 # define BOOST_PP_REPEAT_3RD BOOST_PP_REPEAT_3 # # define BOOST_PP_REPEAT_1_0(m, d) # define BOOST_PP_REPEAT_1_1(m, d) m(2, 0, d) # define BOOST_PP_REPEAT_1_2(m, d) BOOST_PP_REPEAT_1_1(m, d) m(2, 1, d) # define BOOST_PP_REPEAT_1_3(m, d) BOOST_PP_REPEAT_1_2(m, d) m(2, 2, d) # define BOOST_PP_REPEAT_1_4(m, d) BOOST_PP_REPEAT_1_3(m, d) m(2, 3, d) # define BOOST_PP_REPEAT_1_5(m, d) BOOST_PP_REPEAT_1_4(m, d) m(2, 4, d) # define BOOST_PP_REPEAT_1_6(m, d) BOOST_PP_REPEAT_1_5(m, d) m(2, 5, d) # define BOOST_PP_REPEAT_1_7(m, d) BOOST_PP_REPEAT_1_6(m, d) m(2, 6, d) # define BOOST_PP_REPEAT_1_8(m, d) BOOST_PP_REPEAT_1_7(m, d) m(2, 7, d) # define BOOST_PP_REPEAT_1_9(m, d) BOOST_PP_REPEAT_1_8(m, d) m(2, 8, d) # define BOOST_PP_REPEAT_1_10(m, d) BOOST_PP_REPEAT_1_9(m, d) m(2, 9, d) # define BOOST_PP_REPEAT_1_11(m, d) BOOST_PP_REPEAT_1_10(m, d) m(2, 10, d) # define BOOST_PP_REPEAT_1_12(m, d) BOOST_PP_REPEAT_1_11(m, d) m(2, 11, d) # define BOOST_PP_REPEAT_1_13(m, d) BOOST_PP_REPEAT_1_12(m, d) m(2, 12, d) # define BOOST_PP_REPEAT_1_14(m, d) BOOST_PP_REPEAT_1_13(m, d) m(2, 13, d) # define BOOST_PP_REPEAT_1_15(m, d) BOOST_PP_REPEAT_1_14(m, d) m(2, 14, d) # define BOOST_PP_REPEAT_1_16(m, d) BOOST_PP_REPEAT_1_15(m, d) m(2, 15, d) # define BOOST_PP_REPEAT_1_17(m, d) BOOST_PP_REPEAT_1_16(m, d) m(2, 16, d) # define BOOST_PP_REPEAT_1_18(m, d) BOOST_PP_REPEAT_1_17(m, d) m(2, 17, d) # define BOOST_PP_REPEAT_1_19(m, d) BOOST_PP_REPEAT_1_18(m, d) m(2, 18, d) # define BOOST_PP_REPEAT_1_20(m, d) BOOST_PP_REPEAT_1_19(m, d) m(2, 19, d) # define BOOST_PP_REPEAT_1_21(m, d) BOOST_PP_REPEAT_1_20(m, d) m(2, 20, d) # define BOOST_PP_REPEAT_1_22(m, d) BOOST_PP_REPEAT_1_21(m, d) m(2, 21, d) # define BOOST_PP_REPEAT_1_23(m, d) BOOST_PP_REPEAT_1_22(m, d) m(2, 22, d) # define BOOST_PP_REPEAT_1_24(m, d) BOOST_PP_REPEAT_1_23(m, d) m(2, 23, d) # define BOOST_PP_REPEAT_1_25(m, d) BOOST_PP_REPEAT_1_24(m, d) m(2, 24, d) # define BOOST_PP_REPEAT_1_26(m, d) BOOST_PP_REPEAT_1_25(m, d) m(2, 25, d) # define BOOST_PP_REPEAT_1_27(m, d) BOOST_PP_REPEAT_1_26(m, d) m(2, 26, d) # define BOOST_PP_REPEAT_1_28(m, d) BOOST_PP_REPEAT_1_27(m, d) m(2, 27, d) # define BOOST_PP_REPEAT_1_29(m, d) BOOST_PP_REPEAT_1_28(m, d) m(2, 28, d) # define BOOST_PP_REPEAT_1_30(m, d) BOOST_PP_REPEAT_1_29(m, d) m(2, 29, d) # define BOOST_PP_REPEAT_1_31(m, d) BOOST_PP_REPEAT_1_30(m, d) m(2, 30, d) # define BOOST_PP_REPEAT_1_32(m, d) BOOST_PP_REPEAT_1_31(m, d) m(2, 31, d) # define BOOST_PP_REPEAT_1_33(m, d) BOOST_PP_REPEAT_1_32(m, d) m(2, 32, d) # define BOOST_PP_REPEAT_1_34(m, d) BOOST_PP_REPEAT_1_33(m, d) m(2, 33, d) # define BOOST_PP_REPEAT_1_35(m, d) BOOST_PP_REPEAT_1_34(m, d) m(2, 34, d) # define BOOST_PP_REPEAT_1_36(m, d) BOOST_PP_REPEAT_1_35(m, d) m(2, 35, d) # define BOOST_PP_REPEAT_1_37(m, d) BOOST_PP_REPEAT_1_36(m, d) m(2, 36, d) # define BOOST_PP_REPEAT_1_38(m, d) BOOST_PP_REPEAT_1_37(m, d) m(2, 37, d) # define BOOST_PP_REPEAT_1_39(m, d) BOOST_PP_REPEAT_1_38(m, d) m(2, 38, d) # define BOOST_PP_REPEAT_1_40(m, d) BOOST_PP_REPEAT_1_39(m, d) m(2, 39, d) # define BOOST_PP_REPEAT_1_41(m, d) BOOST_PP_REPEAT_1_40(m, d) m(2, 40, d) # define BOOST_PP_REPEAT_1_42(m, d) BOOST_PP_REPEAT_1_41(m, d) m(2, 41, d) # define BOOST_PP_REPEAT_1_43(m, d) BOOST_PP_REPEAT_1_42(m, d) m(2, 42, d) # define BOOST_PP_REPEAT_1_44(m, d) BOOST_PP_REPEAT_1_43(m, d) m(2, 43, d) # define BOOST_PP_REPEAT_1_45(m, d) BOOST_PP_REPEAT_1_44(m, d) m(2, 44, d) # define BOOST_PP_REPEAT_1_46(m, d) BOOST_PP_REPEAT_1_45(m, d) m(2, 45, d) # define BOOST_PP_REPEAT_1_47(m, d) BOOST_PP_REPEAT_1_46(m, d) m(2, 46, d) # define BOOST_PP_REPEAT_1_48(m, d) BOOST_PP_REPEAT_1_47(m, d) m(2, 47, d) # define BOOST_PP_REPEAT_1_49(m, d) BOOST_PP_REPEAT_1_48(m, d) m(2, 48, d) # define BOOST_PP_REPEAT_1_50(m, d) BOOST_PP_REPEAT_1_49(m, d) m(2, 49, d) # define BOOST_PP_REPEAT_1_51(m, d) BOOST_PP_REPEAT_1_50(m, d) m(2, 50, d) # define BOOST_PP_REPEAT_1_52(m, d) BOOST_PP_REPEAT_1_51(m, d) m(2, 51, d) # define BOOST_PP_REPEAT_1_53(m, d) BOOST_PP_REPEAT_1_52(m, d) m(2, 52, d) # define BOOST_PP_REPEAT_1_54(m, d) BOOST_PP_REPEAT_1_53(m, d) m(2, 53, d) # define BOOST_PP_REPEAT_1_55(m, d) BOOST_PP_REPEAT_1_54(m, d) m(2, 54, d) # define BOOST_PP_REPEAT_1_56(m, d) BOOST_PP_REPEAT_1_55(m, d) m(2, 55, d) # define BOOST_PP_REPEAT_1_57(m, d) BOOST_PP_REPEAT_1_56(m, d) m(2, 56, d) # define BOOST_PP_REPEAT_1_58(m, d) BOOST_PP_REPEAT_1_57(m, d) m(2, 57, d) # define BOOST_PP_REPEAT_1_59(m, d) BOOST_PP_REPEAT_1_58(m, d) m(2, 58, d) # define BOOST_PP_REPEAT_1_60(m, d) BOOST_PP_REPEAT_1_59(m, d) m(2, 59, d) # define BOOST_PP_REPEAT_1_61(m, d) BOOST_PP_REPEAT_1_60(m, d) m(2, 60, d) # define BOOST_PP_REPEAT_1_62(m, d) BOOST_PP_REPEAT_1_61(m, d) m(2, 61, d) # define BOOST_PP_REPEAT_1_63(m, d) BOOST_PP_REPEAT_1_62(m, d) m(2, 62, d) # define BOOST_PP_REPEAT_1_64(m, d) BOOST_PP_REPEAT_1_63(m, d) m(2, 63, d) # define BOOST_PP_REPEAT_1_65(m, d) BOOST_PP_REPEAT_1_64(m, d) m(2, 64, d) # define BOOST_PP_REPEAT_1_66(m, d) BOOST_PP_REPEAT_1_65(m, d) m(2, 65, d) # define BOOST_PP_REPEAT_1_67(m, d) BOOST_PP_REPEAT_1_66(m, d) m(2, 66, d) # define BOOST_PP_REPEAT_1_68(m, d) BOOST_PP_REPEAT_1_67(m, d) m(2, 67, d) # define BOOST_PP_REPEAT_1_69(m, d) BOOST_PP_REPEAT_1_68(m, d) m(2, 68, d) # define BOOST_PP_REPEAT_1_70(m, d) BOOST_PP_REPEAT_1_69(m, d) m(2, 69, d) # define BOOST_PP_REPEAT_1_71(m, d) BOOST_PP_REPEAT_1_70(m, d) m(2, 70, d) # define BOOST_PP_REPEAT_1_72(m, d) BOOST_PP_REPEAT_1_71(m, d) m(2, 71, d) # define BOOST_PP_REPEAT_1_73(m, d) BOOST_PP_REPEAT_1_72(m, d) m(2, 72, d) # define BOOST_PP_REPEAT_1_74(m, d) BOOST_PP_REPEAT_1_73(m, d) m(2, 73, d) # define BOOST_PP_REPEAT_1_75(m, d) BOOST_PP_REPEAT_1_74(m, d) m(2, 74, d) # define BOOST_PP_REPEAT_1_76(m, d) BOOST_PP_REPEAT_1_75(m, d) m(2, 75, d) # define BOOST_PP_REPEAT_1_77(m, d) BOOST_PP_REPEAT_1_76(m, d) m(2, 76, d) # define BOOST_PP_REPEAT_1_78(m, d) BOOST_PP_REPEAT_1_77(m, d) m(2, 77, d) # define BOOST_PP_REPEAT_1_79(m, d) BOOST_PP_REPEAT_1_78(m, d) m(2, 78, d) # define BOOST_PP_REPEAT_1_80(m, d) BOOST_PP_REPEAT_1_79(m, d) m(2, 79, d) # define BOOST_PP_REPEAT_1_81(m, d) BOOST_PP_REPEAT_1_80(m, d) m(2, 80, d) # define BOOST_PP_REPEAT_1_82(m, d) BOOST_PP_REPEAT_1_81(m, d) m(2, 81, d) # define BOOST_PP_REPEAT_1_83(m, d) BOOST_PP_REPEAT_1_82(m, d) m(2, 82, d) # define BOOST_PP_REPEAT_1_84(m, d) BOOST_PP_REPEAT_1_83(m, d) m(2, 83, d) # define BOOST_PP_REPEAT_1_85(m, d) BOOST_PP_REPEAT_1_84(m, d) m(2, 84, d) # define BOOST_PP_REPEAT_1_86(m, d) BOOST_PP_REPEAT_1_85(m, d) m(2, 85, d) # define BOOST_PP_REPEAT_1_87(m, d) BOOST_PP_REPEAT_1_86(m, d) m(2, 86, d) # define BOOST_PP_REPEAT_1_88(m, d) BOOST_PP_REPEAT_1_87(m, d) m(2, 87, d) # define BOOST_PP_REPEAT_1_89(m, d) BOOST_PP_REPEAT_1_88(m, d) m(2, 88, d) # define BOOST_PP_REPEAT_1_90(m, d) BOOST_PP_REPEAT_1_89(m, d) m(2, 89, d) # define BOOST_PP_REPEAT_1_91(m, d) BOOST_PP_REPEAT_1_90(m, d) m(2, 90, d) # define BOOST_PP_REPEAT_1_92(m, d) BOOST_PP_REPEAT_1_91(m, d) m(2, 91, d) # define BOOST_PP_REPEAT_1_93(m, d) BOOST_PP_REPEAT_1_92(m, d) m(2, 92, d) # define BOOST_PP_REPEAT_1_94(m, d) BOOST_PP_REPEAT_1_93(m, d) m(2, 93, d) # define BOOST_PP_REPEAT_1_95(m, d) BOOST_PP_REPEAT_1_94(m, d) m(2, 94, d) # define BOOST_PP_REPEAT_1_96(m, d) BOOST_PP_REPEAT_1_95(m, d) m(2, 95, d) # define BOOST_PP_REPEAT_1_97(m, d) BOOST_PP_REPEAT_1_96(m, d) m(2, 96, d) # define BOOST_PP_REPEAT_1_98(m, d) BOOST_PP_REPEAT_1_97(m, d) m(2, 97, d) # define BOOST_PP_REPEAT_1_99(m, d) BOOST_PP_REPEAT_1_98(m, d) m(2, 98, d) # define BOOST_PP_REPEAT_1_100(m, d) BOOST_PP_REPEAT_1_99(m, d) m(2, 99, d) # define BOOST_PP_REPEAT_1_101(m, d) BOOST_PP_REPEAT_1_100(m, d) m(2, 100, d) # define BOOST_PP_REPEAT_1_102(m, d) BOOST_PP_REPEAT_1_101(m, d) m(2, 101, d) # define BOOST_PP_REPEAT_1_103(m, d) BOOST_PP_REPEAT_1_102(m, d) m(2, 102, d) # define BOOST_PP_REPEAT_1_104(m, d) BOOST_PP_REPEAT_1_103(m, d) m(2, 103, d) # define BOOST_PP_REPEAT_1_105(m, d) BOOST_PP_REPEAT_1_104(m, d) m(2, 104, d) # define BOOST_PP_REPEAT_1_106(m, d) BOOST_PP_REPEAT_1_105(m, d) m(2, 105, d) # define BOOST_PP_REPEAT_1_107(m, d) BOOST_PP_REPEAT_1_106(m, d) m(2, 106, d) # define BOOST_PP_REPEAT_1_108(m, d) BOOST_PP_REPEAT_1_107(m, d) m(2, 107, d) # define BOOST_PP_REPEAT_1_109(m, d) BOOST_PP_REPEAT_1_108(m, d) m(2, 108, d) # define BOOST_PP_REPEAT_1_110(m, d) BOOST_PP_REPEAT_1_109(m, d) m(2, 109, d) # define BOOST_PP_REPEAT_1_111(m, d) BOOST_PP_REPEAT_1_110(m, d) m(2, 110, d) # define BOOST_PP_REPEAT_1_112(m, d) BOOST_PP_REPEAT_1_111(m, d) m(2, 111, d) # define BOOST_PP_REPEAT_1_113(m, d) BOOST_PP_REPEAT_1_112(m, d) m(2, 112, d) # define BOOST_PP_REPEAT_1_114(m, d) BOOST_PP_REPEAT_1_113(m, d) m(2, 113, d) # define BOOST_PP_REPEAT_1_115(m, d) BOOST_PP_REPEAT_1_114(m, d) m(2, 114, d) # define BOOST_PP_REPEAT_1_116(m, d) BOOST_PP_REPEAT_1_115(m, d) m(2, 115, d) # define BOOST_PP_REPEAT_1_117(m, d) BOOST_PP_REPEAT_1_116(m, d) m(2, 116, d) # define BOOST_PP_REPEAT_1_118(m, d) BOOST_PP_REPEAT_1_117(m, d) m(2, 117, d) # define BOOST_PP_REPEAT_1_119(m, d) BOOST_PP_REPEAT_1_118(m, d) m(2, 118, d) # define BOOST_PP_REPEAT_1_120(m, d) BOOST_PP_REPEAT_1_119(m, d) m(2, 119, d) # define BOOST_PP_REPEAT_1_121(m, d) BOOST_PP_REPEAT_1_120(m, d) m(2, 120, d) # define BOOST_PP_REPEAT_1_122(m, d) BOOST_PP_REPEAT_1_121(m, d) m(2, 121, d) # define BOOST_PP_REPEAT_1_123(m, d) BOOST_PP_REPEAT_1_122(m, d) m(2, 122, d) # define BOOST_PP_REPEAT_1_124(m, d) BOOST_PP_REPEAT_1_123(m, d) m(2, 123, d) # define BOOST_PP_REPEAT_1_125(m, d) BOOST_PP_REPEAT_1_124(m, d) m(2, 124, d) # define BOOST_PP_REPEAT_1_126(m, d) BOOST_PP_REPEAT_1_125(m, d) m(2, 125, d) # define BOOST_PP_REPEAT_1_127(m, d) BOOST_PP_REPEAT_1_126(m, d) m(2, 126, d) # define BOOST_PP_REPEAT_1_128(m, d) BOOST_PP_REPEAT_1_127(m, d) m(2, 127, d) # define BOOST_PP_REPEAT_1_129(m, d) BOOST_PP_REPEAT_1_128(m, d) m(2, 128, d) # define BOOST_PP_REPEAT_1_130(m, d) BOOST_PP_REPEAT_1_129(m, d) m(2, 129, d) # define BOOST_PP_REPEAT_1_131(m, d) BOOST_PP_REPEAT_1_130(m, d) m(2, 130, d) # define BOOST_PP_REPEAT_1_132(m, d) BOOST_PP_REPEAT_1_131(m, d) m(2, 131, d) # define BOOST_PP_REPEAT_1_133(m, d) BOOST_PP_REPEAT_1_132(m, d) m(2, 132, d) # define BOOST_PP_REPEAT_1_134(m, d) BOOST_PP_REPEAT_1_133(m, d) m(2, 133, d) # define BOOST_PP_REPEAT_1_135(m, d) BOOST_PP_REPEAT_1_134(m, d) m(2, 134, d) # define BOOST_PP_REPEAT_1_136(m, d) BOOST_PP_REPEAT_1_135(m, d) m(2, 135, d) # define BOOST_PP_REPEAT_1_137(m, d) BOOST_PP_REPEAT_1_136(m, d) m(2, 136, d) # define BOOST_PP_REPEAT_1_138(m, d) BOOST_PP_REPEAT_1_137(m, d) m(2, 137, d) # define BOOST_PP_REPEAT_1_139(m, d) BOOST_PP_REPEAT_1_138(m, d) m(2, 138, d) # define BOOST_PP_REPEAT_1_140(m, d) BOOST_PP_REPEAT_1_139(m, d) m(2, 139, d) # define BOOST_PP_REPEAT_1_141(m, d) BOOST_PP_REPEAT_1_140(m, d) m(2, 140, d) # define BOOST_PP_REPEAT_1_142(m, d) BOOST_PP_REPEAT_1_141(m, d) m(2, 141, d) # define BOOST_PP_REPEAT_1_143(m, d) BOOST_PP_REPEAT_1_142(m, d) m(2, 142, d) # define BOOST_PP_REPEAT_1_144(m, d) BOOST_PP_REPEAT_1_143(m, d) m(2, 143, d) # define BOOST_PP_REPEAT_1_145(m, d) BOOST_PP_REPEAT_1_144(m, d) m(2, 144, d) # define BOOST_PP_REPEAT_1_146(m, d) BOOST_PP_REPEAT_1_145(m, d) m(2, 145, d) # define BOOST_PP_REPEAT_1_147(m, d) BOOST_PP_REPEAT_1_146(m, d) m(2, 146, d) # define BOOST_PP_REPEAT_1_148(m, d) BOOST_PP_REPEAT_1_147(m, d) m(2, 147, d) # define BOOST_PP_REPEAT_1_149(m, d) BOOST_PP_REPEAT_1_148(m, d) m(2, 148, d) # define BOOST_PP_REPEAT_1_150(m, d) BOOST_PP_REPEAT_1_149(m, d) m(2, 149, d) # define BOOST_PP_REPEAT_1_151(m, d) BOOST_PP_REPEAT_1_150(m, d) m(2, 150, d) # define BOOST_PP_REPEAT_1_152(m, d) BOOST_PP_REPEAT_1_151(m, d) m(2, 151, d) # define BOOST_PP_REPEAT_1_153(m, d) BOOST_PP_REPEAT_1_152(m, d) m(2, 152, d) # define BOOST_PP_REPEAT_1_154(m, d) BOOST_PP_REPEAT_1_153(m, d) m(2, 153, d) # define BOOST_PP_REPEAT_1_155(m, d) BOOST_PP_REPEAT_1_154(m, d) m(2, 154, d) # define BOOST_PP_REPEAT_1_156(m, d) BOOST_PP_REPEAT_1_155(m, d) m(2, 155, d) # define BOOST_PP_REPEAT_1_157(m, d) BOOST_PP_REPEAT_1_156(m, d) m(2, 156, d) # define BOOST_PP_REPEAT_1_158(m, d) BOOST_PP_REPEAT_1_157(m, d) m(2, 157, d) # define BOOST_PP_REPEAT_1_159(m, d) BOOST_PP_REPEAT_1_158(m, d) m(2, 158, d) # define BOOST_PP_REPEAT_1_160(m, d) BOOST_PP_REPEAT_1_159(m, d) m(2, 159, d) # define BOOST_PP_REPEAT_1_161(m, d) BOOST_PP_REPEAT_1_160(m, d) m(2, 160, d) # define BOOST_PP_REPEAT_1_162(m, d) BOOST_PP_REPEAT_1_161(m, d) m(2, 161, d) # define BOOST_PP_REPEAT_1_163(m, d) BOOST_PP_REPEAT_1_162(m, d) m(2, 162, d) # define BOOST_PP_REPEAT_1_164(m, d) BOOST_PP_REPEAT_1_163(m, d) m(2, 163, d) # define BOOST_PP_REPEAT_1_165(m, d) BOOST_PP_REPEAT_1_164(m, d) m(2, 164, d) # define BOOST_PP_REPEAT_1_166(m, d) BOOST_PP_REPEAT_1_165(m, d) m(2, 165, d) # define BOOST_PP_REPEAT_1_167(m, d) BOOST_PP_REPEAT_1_166(m, d) m(2, 166, d) # define BOOST_PP_REPEAT_1_168(m, d) BOOST_PP_REPEAT_1_167(m, d) m(2, 167, d) # define BOOST_PP_REPEAT_1_169(m, d) BOOST_PP_REPEAT_1_168(m, d) m(2, 168, d) # define BOOST_PP_REPEAT_1_170(m, d) BOOST_PP_REPEAT_1_169(m, d) m(2, 169, d) # define BOOST_PP_REPEAT_1_171(m, d) BOOST_PP_REPEAT_1_170(m, d) m(2, 170, d) # define BOOST_PP_REPEAT_1_172(m, d) BOOST_PP_REPEAT_1_171(m, d) m(2, 171, d) # define BOOST_PP_REPEAT_1_173(m, d) BOOST_PP_REPEAT_1_172(m, d) m(2, 172, d) # define BOOST_PP_REPEAT_1_174(m, d) BOOST_PP_REPEAT_1_173(m, d) m(2, 173, d) # define BOOST_PP_REPEAT_1_175(m, d) BOOST_PP_REPEAT_1_174(m, d) m(2, 174, d) # define BOOST_PP_REPEAT_1_176(m, d) BOOST_PP_REPEAT_1_175(m, d) m(2, 175, d) # define BOOST_PP_REPEAT_1_177(m, d) BOOST_PP_REPEAT_1_176(m, d) m(2, 176, d) # define BOOST_PP_REPEAT_1_178(m, d) BOOST_PP_REPEAT_1_177(m, d) m(2, 177, d) # define BOOST_PP_REPEAT_1_179(m, d) BOOST_PP_REPEAT_1_178(m, d) m(2, 178, d) # define BOOST_PP_REPEAT_1_180(m, d) BOOST_PP_REPEAT_1_179(m, d) m(2, 179, d) # define BOOST_PP_REPEAT_1_181(m, d) BOOST_PP_REPEAT_1_180(m, d) m(2, 180, d) # define BOOST_PP_REPEAT_1_182(m, d) BOOST_PP_REPEAT_1_181(m, d) m(2, 181, d) # define BOOST_PP_REPEAT_1_183(m, d) BOOST_PP_REPEAT_1_182(m, d) m(2, 182, d) # define BOOST_PP_REPEAT_1_184(m, d) BOOST_PP_REPEAT_1_183(m, d) m(2, 183, d) # define BOOST_PP_REPEAT_1_185(m, d) BOOST_PP_REPEAT_1_184(m, d) m(2, 184, d) # define BOOST_PP_REPEAT_1_186(m, d) BOOST_PP_REPEAT_1_185(m, d) m(2, 185, d) # define BOOST_PP_REPEAT_1_187(m, d) BOOST_PP_REPEAT_1_186(m, d) m(2, 186, d) # define BOOST_PP_REPEAT_1_188(m, d) BOOST_PP_REPEAT_1_187(m, d) m(2, 187, d) # define BOOST_PP_REPEAT_1_189(m, d) BOOST_PP_REPEAT_1_188(m, d) m(2, 188, d) # define BOOST_PP_REPEAT_1_190(m, d) BOOST_PP_REPEAT_1_189(m, d) m(2, 189, d) # define BOOST_PP_REPEAT_1_191(m, d) BOOST_PP_REPEAT_1_190(m, d) m(2, 190, d) # define BOOST_PP_REPEAT_1_192(m, d) BOOST_PP_REPEAT_1_191(m, d) m(2, 191, d) # define BOOST_PP_REPEAT_1_193(m, d) BOOST_PP_REPEAT_1_192(m, d) m(2, 192, d) # define BOOST_PP_REPEAT_1_194(m, d) BOOST_PP_REPEAT_1_193(m, d) m(2, 193, d) # define BOOST_PP_REPEAT_1_195(m, d) BOOST_PP_REPEAT_1_194(m, d) m(2, 194, d) # define BOOST_PP_REPEAT_1_196(m, d) BOOST_PP_REPEAT_1_195(m, d) m(2, 195, d) # define BOOST_PP_REPEAT_1_197(m, d) BOOST_PP_REPEAT_1_196(m, d) m(2, 196, d) # define BOOST_PP_REPEAT_1_198(m, d) BOOST_PP_REPEAT_1_197(m, d) m(2, 197, d) # define BOOST_PP_REPEAT_1_199(m, d) BOOST_PP_REPEAT_1_198(m, d) m(2, 198, d) # define BOOST_PP_REPEAT_1_200(m, d) BOOST_PP_REPEAT_1_199(m, d) m(2, 199, d) # define BOOST_PP_REPEAT_1_201(m, d) BOOST_PP_REPEAT_1_200(m, d) m(2, 200, d) # define BOOST_PP_REPEAT_1_202(m, d) BOOST_PP_REPEAT_1_201(m, d) m(2, 201, d) # define BOOST_PP_REPEAT_1_203(m, d) BOOST_PP_REPEAT_1_202(m, d) m(2, 202, d) # define BOOST_PP_REPEAT_1_204(m, d) BOOST_PP_REPEAT_1_203(m, d) m(2, 203, d) # define BOOST_PP_REPEAT_1_205(m, d) BOOST_PP_REPEAT_1_204(m, d) m(2, 204, d) # define BOOST_PP_REPEAT_1_206(m, d) BOOST_PP_REPEAT_1_205(m, d) m(2, 205, d) # define BOOST_PP_REPEAT_1_207(m, d) BOOST_PP_REPEAT_1_206(m, d) m(2, 206, d) # define BOOST_PP_REPEAT_1_208(m, d) BOOST_PP_REPEAT_1_207(m, d) m(2, 207, d) # define BOOST_PP_REPEAT_1_209(m, d) BOOST_PP_REPEAT_1_208(m, d) m(2, 208, d) # define BOOST_PP_REPEAT_1_210(m, d) BOOST_PP_REPEAT_1_209(m, d) m(2, 209, d) # define BOOST_PP_REPEAT_1_211(m, d) BOOST_PP_REPEAT_1_210(m, d) m(2, 210, d) # define BOOST_PP_REPEAT_1_212(m, d) BOOST_PP_REPEAT_1_211(m, d) m(2, 211, d) # define BOOST_PP_REPEAT_1_213(m, d) BOOST_PP_REPEAT_1_212(m, d) m(2, 212, d) # define BOOST_PP_REPEAT_1_214(m, d) BOOST_PP_REPEAT_1_213(m, d) m(2, 213, d) # define BOOST_PP_REPEAT_1_215(m, d) BOOST_PP_REPEAT_1_214(m, d) m(2, 214, d) # define BOOST_PP_REPEAT_1_216(m, d) BOOST_PP_REPEAT_1_215(m, d) m(2, 215, d) # define BOOST_PP_REPEAT_1_217(m, d) BOOST_PP_REPEAT_1_216(m, d) m(2, 216, d) # define BOOST_PP_REPEAT_1_218(m, d) BOOST_PP_REPEAT_1_217(m, d) m(2, 217, d) # define BOOST_PP_REPEAT_1_219(m, d) BOOST_PP_REPEAT_1_218(m, d) m(2, 218, d) # define BOOST_PP_REPEAT_1_220(m, d) BOOST_PP_REPEAT_1_219(m, d) m(2, 219, d) # define BOOST_PP_REPEAT_1_221(m, d) BOOST_PP_REPEAT_1_220(m, d) m(2, 220, d) # define BOOST_PP_REPEAT_1_222(m, d) BOOST_PP_REPEAT_1_221(m, d) m(2, 221, d) # define BOOST_PP_REPEAT_1_223(m, d) BOOST_PP_REPEAT_1_222(m, d) m(2, 222, d) # define BOOST_PP_REPEAT_1_224(m, d) BOOST_PP_REPEAT_1_223(m, d) m(2, 223, d) # define BOOST_PP_REPEAT_1_225(m, d) BOOST_PP_REPEAT_1_224(m, d) m(2, 224, d) # define BOOST_PP_REPEAT_1_226(m, d) BOOST_PP_REPEAT_1_225(m, d) m(2, 225, d) # define BOOST_PP_REPEAT_1_227(m, d) BOOST_PP_REPEAT_1_226(m, d) m(2, 226, d) # define BOOST_PP_REPEAT_1_228(m, d) BOOST_PP_REPEAT_1_227(m, d) m(2, 227, d) # define BOOST_PP_REPEAT_1_229(m, d) BOOST_PP_REPEAT_1_228(m, d) m(2, 228, d) # define BOOST_PP_REPEAT_1_230(m, d) BOOST_PP_REPEAT_1_229(m, d) m(2, 229, d) # define BOOST_PP_REPEAT_1_231(m, d) BOOST_PP_REPEAT_1_230(m, d) m(2, 230, d) # define BOOST_PP_REPEAT_1_232(m, d) BOOST_PP_REPEAT_1_231(m, d) m(2, 231, d) # define BOOST_PP_REPEAT_1_233(m, d) BOOST_PP_REPEAT_1_232(m, d) m(2, 232, d) # define BOOST_PP_REPEAT_1_234(m, d) BOOST_PP_REPEAT_1_233(m, d) m(2, 233, d) # define BOOST_PP_REPEAT_1_235(m, d) BOOST_PP_REPEAT_1_234(m, d) m(2, 234, d) # define BOOST_PP_REPEAT_1_236(m, d) BOOST_PP_REPEAT_1_235(m, d) m(2, 235, d) # define BOOST_PP_REPEAT_1_237(m, d) BOOST_PP_REPEAT_1_236(m, d) m(2, 236, d) # define BOOST_PP_REPEAT_1_238(m, d) BOOST_PP_REPEAT_1_237(m, d) m(2, 237, d) # define BOOST_PP_REPEAT_1_239(m, d) BOOST_PP_REPEAT_1_238(m, d) m(2, 238, d) # define BOOST_PP_REPEAT_1_240(m, d) BOOST_PP_REPEAT_1_239(m, d) m(2, 239, d) # define BOOST_PP_REPEAT_1_241(m, d) BOOST_PP_REPEAT_1_240(m, d) m(2, 240, d) # define BOOST_PP_REPEAT_1_242(m, d) BOOST_PP_REPEAT_1_241(m, d) m(2, 241, d) # define BOOST_PP_REPEAT_1_243(m, d) BOOST_PP_REPEAT_1_242(m, d) m(2, 242, d) # define BOOST_PP_REPEAT_1_244(m, d) BOOST_PP_REPEAT_1_243(m, d) m(2, 243, d) # define BOOST_PP_REPEAT_1_245(m, d) BOOST_PP_REPEAT_1_244(m, d) m(2, 244, d) # define BOOST_PP_REPEAT_1_246(m, d) BOOST_PP_REPEAT_1_245(m, d) m(2, 245, d) # define BOOST_PP_REPEAT_1_247(m, d) BOOST_PP_REPEAT_1_246(m, d) m(2, 246, d) # define BOOST_PP_REPEAT_1_248(m, d) BOOST_PP_REPEAT_1_247(m, d) m(2, 247, d) # define BOOST_PP_REPEAT_1_249(m, d) BOOST_PP_REPEAT_1_248(m, d) m(2, 248, d) # define BOOST_PP_REPEAT_1_250(m, d) BOOST_PP_REPEAT_1_249(m, d) m(2, 249, d) # define BOOST_PP_REPEAT_1_251(m, d) BOOST_PP_REPEAT_1_250(m, d) m(2, 250, d) # define BOOST_PP_REPEAT_1_252(m, d) BOOST_PP_REPEAT_1_251(m, d) m(2, 251, d) # define BOOST_PP_REPEAT_1_253(m, d) BOOST_PP_REPEAT_1_252(m, d) m(2, 252, d) # define BOOST_PP_REPEAT_1_254(m, d) BOOST_PP_REPEAT_1_253(m, d) m(2, 253, d) # define BOOST_PP_REPEAT_1_255(m, d) BOOST_PP_REPEAT_1_254(m, d) m(2, 254, d) # define BOOST_PP_REPEAT_1_256(m, d) BOOST_PP_REPEAT_1_255(m, d) m(2, 255, d) # # define BOOST_PP_REPEAT_2_0(m, d) # define BOOST_PP_REPEAT_2_1(m, d) m(3, 0, d) # define BOOST_PP_REPEAT_2_2(m, d) BOOST_PP_REPEAT_2_1(m, d) m(3, 1, d) # define BOOST_PP_REPEAT_2_3(m, d) BOOST_PP_REPEAT_2_2(m, d) m(3, 2, d) # define BOOST_PP_REPEAT_2_4(m, d) BOOST_PP_REPEAT_2_3(m, d) m(3, 3, d) # define BOOST_PP_REPEAT_2_5(m, d) BOOST_PP_REPEAT_2_4(m, d) m(3, 4, d) # define BOOST_PP_REPEAT_2_6(m, d) BOOST_PP_REPEAT_2_5(m, d) m(3, 5, d) # define BOOST_PP_REPEAT_2_7(m, d) BOOST_PP_REPEAT_2_6(m, d) m(3, 6, d) # define BOOST_PP_REPEAT_2_8(m, d) BOOST_PP_REPEAT_2_7(m, d) m(3, 7, d) # define BOOST_PP_REPEAT_2_9(m, d) BOOST_PP_REPEAT_2_8(m, d) m(3, 8, d) # define BOOST_PP_REPEAT_2_10(m, d) BOOST_PP_REPEAT_2_9(m, d) m(3, 9, d) # define BOOST_PP_REPEAT_2_11(m, d) BOOST_PP_REPEAT_2_10(m, d) m(3, 10, d) # define BOOST_PP_REPEAT_2_12(m, d) BOOST_PP_REPEAT_2_11(m, d) m(3, 11, d) # define BOOST_PP_REPEAT_2_13(m, d) BOOST_PP_REPEAT_2_12(m, d) m(3, 12, d) # define BOOST_PP_REPEAT_2_14(m, d) BOOST_PP_REPEAT_2_13(m, d) m(3, 13, d) # define BOOST_PP_REPEAT_2_15(m, d) BOOST_PP_REPEAT_2_14(m, d) m(3, 14, d) # define BOOST_PP_REPEAT_2_16(m, d) BOOST_PP_REPEAT_2_15(m, d) m(3, 15, d) # define BOOST_PP_REPEAT_2_17(m, d) BOOST_PP_REPEAT_2_16(m, d) m(3, 16, d) # define BOOST_PP_REPEAT_2_18(m, d) BOOST_PP_REPEAT_2_17(m, d) m(3, 17, d) # define BOOST_PP_REPEAT_2_19(m, d) BOOST_PP_REPEAT_2_18(m, d) m(3, 18, d) # define BOOST_PP_REPEAT_2_20(m, d) BOOST_PP_REPEAT_2_19(m, d) m(3, 19, d) # define BOOST_PP_REPEAT_2_21(m, d) BOOST_PP_REPEAT_2_20(m, d) m(3, 20, d) # define BOOST_PP_REPEAT_2_22(m, d) BOOST_PP_REPEAT_2_21(m, d) m(3, 21, d) # define BOOST_PP_REPEAT_2_23(m, d) BOOST_PP_REPEAT_2_22(m, d) m(3, 22, d) # define BOOST_PP_REPEAT_2_24(m, d) BOOST_PP_REPEAT_2_23(m, d) m(3, 23, d) # define BOOST_PP_REPEAT_2_25(m, d) BOOST_PP_REPEAT_2_24(m, d) m(3, 24, d) # define BOOST_PP_REPEAT_2_26(m, d) BOOST_PP_REPEAT_2_25(m, d) m(3, 25, d) # define BOOST_PP_REPEAT_2_27(m, d) BOOST_PP_REPEAT_2_26(m, d) m(3, 26, d) # define BOOST_PP_REPEAT_2_28(m, d) BOOST_PP_REPEAT_2_27(m, d) m(3, 27, d) # define BOOST_PP_REPEAT_2_29(m, d) BOOST_PP_REPEAT_2_28(m, d) m(3, 28, d) # define BOOST_PP_REPEAT_2_30(m, d) BOOST_PP_REPEAT_2_29(m, d) m(3, 29, d) # define BOOST_PP_REPEAT_2_31(m, d) BOOST_PP_REPEAT_2_30(m, d) m(3, 30, d) # define BOOST_PP_REPEAT_2_32(m, d) BOOST_PP_REPEAT_2_31(m, d) m(3, 31, d) # define BOOST_PP_REPEAT_2_33(m, d) BOOST_PP_REPEAT_2_32(m, d) m(3, 32, d) # define BOOST_PP_REPEAT_2_34(m, d) BOOST_PP_REPEAT_2_33(m, d) m(3, 33, d) # define BOOST_PP_REPEAT_2_35(m, d) BOOST_PP_REPEAT_2_34(m, d) m(3, 34, d) # define BOOST_PP_REPEAT_2_36(m, d) BOOST_PP_REPEAT_2_35(m, d) m(3, 35, d) # define BOOST_PP_REPEAT_2_37(m, d) BOOST_PP_REPEAT_2_36(m, d) m(3, 36, d) # define BOOST_PP_REPEAT_2_38(m, d) BOOST_PP_REPEAT_2_37(m, d) m(3, 37, d) # define BOOST_PP_REPEAT_2_39(m, d) BOOST_PP_REPEAT_2_38(m, d) m(3, 38, d) # define BOOST_PP_REPEAT_2_40(m, d) BOOST_PP_REPEAT_2_39(m, d) m(3, 39, d) # define BOOST_PP_REPEAT_2_41(m, d) BOOST_PP_REPEAT_2_40(m, d) m(3, 40, d) # define BOOST_PP_REPEAT_2_42(m, d) BOOST_PP_REPEAT_2_41(m, d) m(3, 41, d) # define BOOST_PP_REPEAT_2_43(m, d) BOOST_PP_REPEAT_2_42(m, d) m(3, 42, d) # define BOOST_PP_REPEAT_2_44(m, d) BOOST_PP_REPEAT_2_43(m, d) m(3, 43, d) # define BOOST_PP_REPEAT_2_45(m, d) BOOST_PP_REPEAT_2_44(m, d) m(3, 44, d) # define BOOST_PP_REPEAT_2_46(m, d) BOOST_PP_REPEAT_2_45(m, d) m(3, 45, d) # define BOOST_PP_REPEAT_2_47(m, d) BOOST_PP_REPEAT_2_46(m, d) m(3, 46, d) # define BOOST_PP_REPEAT_2_48(m, d) BOOST_PP_REPEAT_2_47(m, d) m(3, 47, d) # define BOOST_PP_REPEAT_2_49(m, d) BOOST_PP_REPEAT_2_48(m, d) m(3, 48, d) # define BOOST_PP_REPEAT_2_50(m, d) BOOST_PP_REPEAT_2_49(m, d) m(3, 49, d) # define BOOST_PP_REPEAT_2_51(m, d) BOOST_PP_REPEAT_2_50(m, d) m(3, 50, d) # define BOOST_PP_REPEAT_2_52(m, d) BOOST_PP_REPEAT_2_51(m, d) m(3, 51, d) # define BOOST_PP_REPEAT_2_53(m, d) BOOST_PP_REPEAT_2_52(m, d) m(3, 52, d) # define BOOST_PP_REPEAT_2_54(m, d) BOOST_PP_REPEAT_2_53(m, d) m(3, 53, d) # define BOOST_PP_REPEAT_2_55(m, d) BOOST_PP_REPEAT_2_54(m, d) m(3, 54, d) # define BOOST_PP_REPEAT_2_56(m, d) BOOST_PP_REPEAT_2_55(m, d) m(3, 55, d) # define BOOST_PP_REPEAT_2_57(m, d) BOOST_PP_REPEAT_2_56(m, d) m(3, 56, d) # define BOOST_PP_REPEAT_2_58(m, d) BOOST_PP_REPEAT_2_57(m, d) m(3, 57, d) # define BOOST_PP_REPEAT_2_59(m, d) BOOST_PP_REPEAT_2_58(m, d) m(3, 58, d) # define BOOST_PP_REPEAT_2_60(m, d) BOOST_PP_REPEAT_2_59(m, d) m(3, 59, d) # define BOOST_PP_REPEAT_2_61(m, d) BOOST_PP_REPEAT_2_60(m, d) m(3, 60, d) # define BOOST_PP_REPEAT_2_62(m, d) BOOST_PP_REPEAT_2_61(m, d) m(3, 61, d) # define BOOST_PP_REPEAT_2_63(m, d) BOOST_PP_REPEAT_2_62(m, d) m(3, 62, d) # define BOOST_PP_REPEAT_2_64(m, d) BOOST_PP_REPEAT_2_63(m, d) m(3, 63, d) # define BOOST_PP_REPEAT_2_65(m, d) BOOST_PP_REPEAT_2_64(m, d) m(3, 64, d) # define BOOST_PP_REPEAT_2_66(m, d) BOOST_PP_REPEAT_2_65(m, d) m(3, 65, d) # define BOOST_PP_REPEAT_2_67(m, d) BOOST_PP_REPEAT_2_66(m, d) m(3, 66, d) # define BOOST_PP_REPEAT_2_68(m, d) BOOST_PP_REPEAT_2_67(m, d) m(3, 67, d) # define BOOST_PP_REPEAT_2_69(m, d) BOOST_PP_REPEAT_2_68(m, d) m(3, 68, d) # define BOOST_PP_REPEAT_2_70(m, d) BOOST_PP_REPEAT_2_69(m, d) m(3, 69, d) # define BOOST_PP_REPEAT_2_71(m, d) BOOST_PP_REPEAT_2_70(m, d) m(3, 70, d) # define BOOST_PP_REPEAT_2_72(m, d) BOOST_PP_REPEAT_2_71(m, d) m(3, 71, d) # define BOOST_PP_REPEAT_2_73(m, d) BOOST_PP_REPEAT_2_72(m, d) m(3, 72, d) # define BOOST_PP_REPEAT_2_74(m, d) BOOST_PP_REPEAT_2_73(m, d) m(3, 73, d) # define BOOST_PP_REPEAT_2_75(m, d) BOOST_PP_REPEAT_2_74(m, d) m(3, 74, d) # define BOOST_PP_REPEAT_2_76(m, d) BOOST_PP_REPEAT_2_75(m, d) m(3, 75, d) # define BOOST_PP_REPEAT_2_77(m, d) BOOST_PP_REPEAT_2_76(m, d) m(3, 76, d) # define BOOST_PP_REPEAT_2_78(m, d) BOOST_PP_REPEAT_2_77(m, d) m(3, 77, d) # define BOOST_PP_REPEAT_2_79(m, d) BOOST_PP_REPEAT_2_78(m, d) m(3, 78, d) # define BOOST_PP_REPEAT_2_80(m, d) BOOST_PP_REPEAT_2_79(m, d) m(3, 79, d) # define BOOST_PP_REPEAT_2_81(m, d) BOOST_PP_REPEAT_2_80(m, d) m(3, 80, d) # define BOOST_PP_REPEAT_2_82(m, d) BOOST_PP_REPEAT_2_81(m, d) m(3, 81, d) # define BOOST_PP_REPEAT_2_83(m, d) BOOST_PP_REPEAT_2_82(m, d) m(3, 82, d) # define BOOST_PP_REPEAT_2_84(m, d) BOOST_PP_REPEAT_2_83(m, d) m(3, 83, d) # define BOOST_PP_REPEAT_2_85(m, d) BOOST_PP_REPEAT_2_84(m, d) m(3, 84, d) # define BOOST_PP_REPEAT_2_86(m, d) BOOST_PP_REPEAT_2_85(m, d) m(3, 85, d) # define BOOST_PP_REPEAT_2_87(m, d) BOOST_PP_REPEAT_2_86(m, d) m(3, 86, d) # define BOOST_PP_REPEAT_2_88(m, d) BOOST_PP_REPEAT_2_87(m, d) m(3, 87, d) # define BOOST_PP_REPEAT_2_89(m, d) BOOST_PP_REPEAT_2_88(m, d) m(3, 88, d) # define BOOST_PP_REPEAT_2_90(m, d) BOOST_PP_REPEAT_2_89(m, d) m(3, 89, d) # define BOOST_PP_REPEAT_2_91(m, d) BOOST_PP_REPEAT_2_90(m, d) m(3, 90, d) # define BOOST_PP_REPEAT_2_92(m, d) BOOST_PP_REPEAT_2_91(m, d) m(3, 91, d) # define BOOST_PP_REPEAT_2_93(m, d) BOOST_PP_REPEAT_2_92(m, d) m(3, 92, d) # define BOOST_PP_REPEAT_2_94(m, d) BOOST_PP_REPEAT_2_93(m, d) m(3, 93, d) # define BOOST_PP_REPEAT_2_95(m, d) BOOST_PP_REPEAT_2_94(m, d) m(3, 94, d) # define BOOST_PP_REPEAT_2_96(m, d) BOOST_PP_REPEAT_2_95(m, d) m(3, 95, d) # define BOOST_PP_REPEAT_2_97(m, d) BOOST_PP_REPEAT_2_96(m, d) m(3, 96, d) # define BOOST_PP_REPEAT_2_98(m, d) BOOST_PP_REPEAT_2_97(m, d) m(3, 97, d) # define BOOST_PP_REPEAT_2_99(m, d) BOOST_PP_REPEAT_2_98(m, d) m(3, 98, d) # define BOOST_PP_REPEAT_2_100(m, d) BOOST_PP_REPEAT_2_99(m, d) m(3, 99, d) # define BOOST_PP_REPEAT_2_101(m, d) BOOST_PP_REPEAT_2_100(m, d) m(3, 100, d) # define BOOST_PP_REPEAT_2_102(m, d) BOOST_PP_REPEAT_2_101(m, d) m(3, 101, d) # define BOOST_PP_REPEAT_2_103(m, d) BOOST_PP_REPEAT_2_102(m, d) m(3, 102, d) # define BOOST_PP_REPEAT_2_104(m, d) BOOST_PP_REPEAT_2_103(m, d) m(3, 103, d) # define BOOST_PP_REPEAT_2_105(m, d) BOOST_PP_REPEAT_2_104(m, d) m(3, 104, d) # define BOOST_PP_REPEAT_2_106(m, d) BOOST_PP_REPEAT_2_105(m, d) m(3, 105, d) # define BOOST_PP_REPEAT_2_107(m, d) BOOST_PP_REPEAT_2_106(m, d) m(3, 106, d) # define BOOST_PP_REPEAT_2_108(m, d) BOOST_PP_REPEAT_2_107(m, d) m(3, 107, d) # define BOOST_PP_REPEAT_2_109(m, d) BOOST_PP_REPEAT_2_108(m, d) m(3, 108, d) # define BOOST_PP_REPEAT_2_110(m, d) BOOST_PP_REPEAT_2_109(m, d) m(3, 109, d) # define BOOST_PP_REPEAT_2_111(m, d) BOOST_PP_REPEAT_2_110(m, d) m(3, 110, d) # define BOOST_PP_REPEAT_2_112(m, d) BOOST_PP_REPEAT_2_111(m, d) m(3, 111, d) # define BOOST_PP_REPEAT_2_113(m, d) BOOST_PP_REPEAT_2_112(m, d) m(3, 112, d) # define BOOST_PP_REPEAT_2_114(m, d) BOOST_PP_REPEAT_2_113(m, d) m(3, 113, d) # define BOOST_PP_REPEAT_2_115(m, d) BOOST_PP_REPEAT_2_114(m, d) m(3, 114, d) # define BOOST_PP_REPEAT_2_116(m, d) BOOST_PP_REPEAT_2_115(m, d) m(3, 115, d) # define BOOST_PP_REPEAT_2_117(m, d) BOOST_PP_REPEAT_2_116(m, d) m(3, 116, d) # define BOOST_PP_REPEAT_2_118(m, d) BOOST_PP_REPEAT_2_117(m, d) m(3, 117, d) # define BOOST_PP_REPEAT_2_119(m, d) BOOST_PP_REPEAT_2_118(m, d) m(3, 118, d) # define BOOST_PP_REPEAT_2_120(m, d) BOOST_PP_REPEAT_2_119(m, d) m(3, 119, d) # define BOOST_PP_REPEAT_2_121(m, d) BOOST_PP_REPEAT_2_120(m, d) m(3, 120, d) # define BOOST_PP_REPEAT_2_122(m, d) BOOST_PP_REPEAT_2_121(m, d) m(3, 121, d) # define BOOST_PP_REPEAT_2_123(m, d) BOOST_PP_REPEAT_2_122(m, d) m(3, 122, d) # define BOOST_PP_REPEAT_2_124(m, d) BOOST_PP_REPEAT_2_123(m, d) m(3, 123, d) # define BOOST_PP_REPEAT_2_125(m, d) BOOST_PP_REPEAT_2_124(m, d) m(3, 124, d) # define BOOST_PP_REPEAT_2_126(m, d) BOOST_PP_REPEAT_2_125(m, d) m(3, 125, d) # define BOOST_PP_REPEAT_2_127(m, d) BOOST_PP_REPEAT_2_126(m, d) m(3, 126, d) # define BOOST_PP_REPEAT_2_128(m, d) BOOST_PP_REPEAT_2_127(m, d) m(3, 127, d) # define BOOST_PP_REPEAT_2_129(m, d) BOOST_PP_REPEAT_2_128(m, d) m(3, 128, d) # define BOOST_PP_REPEAT_2_130(m, d) BOOST_PP_REPEAT_2_129(m, d) m(3, 129, d) # define BOOST_PP_REPEAT_2_131(m, d) BOOST_PP_REPEAT_2_130(m, d) m(3, 130, d) # define BOOST_PP_REPEAT_2_132(m, d) BOOST_PP_REPEAT_2_131(m, d) m(3, 131, d) # define BOOST_PP_REPEAT_2_133(m, d) BOOST_PP_REPEAT_2_132(m, d) m(3, 132, d) # define BOOST_PP_REPEAT_2_134(m, d) BOOST_PP_REPEAT_2_133(m, d) m(3, 133, d) # define BOOST_PP_REPEAT_2_135(m, d) BOOST_PP_REPEAT_2_134(m, d) m(3, 134, d) # define BOOST_PP_REPEAT_2_136(m, d) BOOST_PP_REPEAT_2_135(m, d) m(3, 135, d) # define BOOST_PP_REPEAT_2_137(m, d) BOOST_PP_REPEAT_2_136(m, d) m(3, 136, d) # define BOOST_PP_REPEAT_2_138(m, d) BOOST_PP_REPEAT_2_137(m, d) m(3, 137, d) # define BOOST_PP_REPEAT_2_139(m, d) BOOST_PP_REPEAT_2_138(m, d) m(3, 138, d) # define BOOST_PP_REPEAT_2_140(m, d) BOOST_PP_REPEAT_2_139(m, d) m(3, 139, d) # define BOOST_PP_REPEAT_2_141(m, d) BOOST_PP_REPEAT_2_140(m, d) m(3, 140, d) # define BOOST_PP_REPEAT_2_142(m, d) BOOST_PP_REPEAT_2_141(m, d) m(3, 141, d) # define BOOST_PP_REPEAT_2_143(m, d) BOOST_PP_REPEAT_2_142(m, d) m(3, 142, d) # define BOOST_PP_REPEAT_2_144(m, d) BOOST_PP_REPEAT_2_143(m, d) m(3, 143, d) # define BOOST_PP_REPEAT_2_145(m, d) BOOST_PP_REPEAT_2_144(m, d) m(3, 144, d) # define BOOST_PP_REPEAT_2_146(m, d) BOOST_PP_REPEAT_2_145(m, d) m(3, 145, d) # define BOOST_PP_REPEAT_2_147(m, d) BOOST_PP_REPEAT_2_146(m, d) m(3, 146, d) # define BOOST_PP_REPEAT_2_148(m, d) BOOST_PP_REPEAT_2_147(m, d) m(3, 147, d) # define BOOST_PP_REPEAT_2_149(m, d) BOOST_PP_REPEAT_2_148(m, d) m(3, 148, d) # define BOOST_PP_REPEAT_2_150(m, d) BOOST_PP_REPEAT_2_149(m, d) m(3, 149, d) # define BOOST_PP_REPEAT_2_151(m, d) BOOST_PP_REPEAT_2_150(m, d) m(3, 150, d) # define BOOST_PP_REPEAT_2_152(m, d) BOOST_PP_REPEAT_2_151(m, d) m(3, 151, d) # define BOOST_PP_REPEAT_2_153(m, d) BOOST_PP_REPEAT_2_152(m, d) m(3, 152, d) # define BOOST_PP_REPEAT_2_154(m, d) BOOST_PP_REPEAT_2_153(m, d) m(3, 153, d) # define BOOST_PP_REPEAT_2_155(m, d) BOOST_PP_REPEAT_2_154(m, d) m(3, 154, d) # define BOOST_PP_REPEAT_2_156(m, d) BOOST_PP_REPEAT_2_155(m, d) m(3, 155, d) # define BOOST_PP_REPEAT_2_157(m, d) BOOST_PP_REPEAT_2_156(m, d) m(3, 156, d) # define BOOST_PP_REPEAT_2_158(m, d) BOOST_PP_REPEAT_2_157(m, d) m(3, 157, d) # define BOOST_PP_REPEAT_2_159(m, d) BOOST_PP_REPEAT_2_158(m, d) m(3, 158, d) # define BOOST_PP_REPEAT_2_160(m, d) BOOST_PP_REPEAT_2_159(m, d) m(3, 159, d) # define BOOST_PP_REPEAT_2_161(m, d) BOOST_PP_REPEAT_2_160(m, d) m(3, 160, d) # define BOOST_PP_REPEAT_2_162(m, d) BOOST_PP_REPEAT_2_161(m, d) m(3, 161, d) # define BOOST_PP_REPEAT_2_163(m, d) BOOST_PP_REPEAT_2_162(m, d) m(3, 162, d) # define BOOST_PP_REPEAT_2_164(m, d) BOOST_PP_REPEAT_2_163(m, d) m(3, 163, d) # define BOOST_PP_REPEAT_2_165(m, d) BOOST_PP_REPEAT_2_164(m, d) m(3, 164, d) # define BOOST_PP_REPEAT_2_166(m, d) BOOST_PP_REPEAT_2_165(m, d) m(3, 165, d) # define BOOST_PP_REPEAT_2_167(m, d) BOOST_PP_REPEAT_2_166(m, d) m(3, 166, d) # define BOOST_PP_REPEAT_2_168(m, d) BOOST_PP_REPEAT_2_167(m, d) m(3, 167, d) # define BOOST_PP_REPEAT_2_169(m, d) BOOST_PP_REPEAT_2_168(m, d) m(3, 168, d) # define BOOST_PP_REPEAT_2_170(m, d) BOOST_PP_REPEAT_2_169(m, d) m(3, 169, d) # define BOOST_PP_REPEAT_2_171(m, d) BOOST_PP_REPEAT_2_170(m, d) m(3, 170, d) # define BOOST_PP_REPEAT_2_172(m, d) BOOST_PP_REPEAT_2_171(m, d) m(3, 171, d) # define BOOST_PP_REPEAT_2_173(m, d) BOOST_PP_REPEAT_2_172(m, d) m(3, 172, d) # define BOOST_PP_REPEAT_2_174(m, d) BOOST_PP_REPEAT_2_173(m, d) m(3, 173, d) # define BOOST_PP_REPEAT_2_175(m, d) BOOST_PP_REPEAT_2_174(m, d) m(3, 174, d) # define BOOST_PP_REPEAT_2_176(m, d) BOOST_PP_REPEAT_2_175(m, d) m(3, 175, d) # define BOOST_PP_REPEAT_2_177(m, d) BOOST_PP_REPEAT_2_176(m, d) m(3, 176, d) # define BOOST_PP_REPEAT_2_178(m, d) BOOST_PP_REPEAT_2_177(m, d) m(3, 177, d) # define BOOST_PP_REPEAT_2_179(m, d) BOOST_PP_REPEAT_2_178(m, d) m(3, 178, d) # define BOOST_PP_REPEAT_2_180(m, d) BOOST_PP_REPEAT_2_179(m, d) m(3, 179, d) # define BOOST_PP_REPEAT_2_181(m, d) BOOST_PP_REPEAT_2_180(m, d) m(3, 180, d) # define BOOST_PP_REPEAT_2_182(m, d) BOOST_PP_REPEAT_2_181(m, d) m(3, 181, d) # define BOOST_PP_REPEAT_2_183(m, d) BOOST_PP_REPEAT_2_182(m, d) m(3, 182, d) # define BOOST_PP_REPEAT_2_184(m, d) BOOST_PP_REPEAT_2_183(m, d) m(3, 183, d) # define BOOST_PP_REPEAT_2_185(m, d) BOOST_PP_REPEAT_2_184(m, d) m(3, 184, d) # define BOOST_PP_REPEAT_2_186(m, d) BOOST_PP_REPEAT_2_185(m, d) m(3, 185, d) # define BOOST_PP_REPEAT_2_187(m, d) BOOST_PP_REPEAT_2_186(m, d) m(3, 186, d) # define BOOST_PP_REPEAT_2_188(m, d) BOOST_PP_REPEAT_2_187(m, d) m(3, 187, d) # define BOOST_PP_REPEAT_2_189(m, d) BOOST_PP_REPEAT_2_188(m, d) m(3, 188, d) # define BOOST_PP_REPEAT_2_190(m, d) BOOST_PP_REPEAT_2_189(m, d) m(3, 189, d) # define BOOST_PP_REPEAT_2_191(m, d) BOOST_PP_REPEAT_2_190(m, d) m(3, 190, d) # define BOOST_PP_REPEAT_2_192(m, d) BOOST_PP_REPEAT_2_191(m, d) m(3, 191, d) # define BOOST_PP_REPEAT_2_193(m, d) BOOST_PP_REPEAT_2_192(m, d) m(3, 192, d) # define BOOST_PP_REPEAT_2_194(m, d) BOOST_PP_REPEAT_2_193(m, d) m(3, 193, d) # define BOOST_PP_REPEAT_2_195(m, d) BOOST_PP_REPEAT_2_194(m, d) m(3, 194, d) # define BOOST_PP_REPEAT_2_196(m, d) BOOST_PP_REPEAT_2_195(m, d) m(3, 195, d) # define BOOST_PP_REPEAT_2_197(m, d) BOOST_PP_REPEAT_2_196(m, d) m(3, 196, d) # define BOOST_PP_REPEAT_2_198(m, d) BOOST_PP_REPEAT_2_197(m, d) m(3, 197, d) # define BOOST_PP_REPEAT_2_199(m, d) BOOST_PP_REPEAT_2_198(m, d) m(3, 198, d) # define BOOST_PP_REPEAT_2_200(m, d) BOOST_PP_REPEAT_2_199(m, d) m(3, 199, d) # define BOOST_PP_REPEAT_2_201(m, d) BOOST_PP_REPEAT_2_200(m, d) m(3, 200, d) # define BOOST_PP_REPEAT_2_202(m, d) BOOST_PP_REPEAT_2_201(m, d) m(3, 201, d) # define BOOST_PP_REPEAT_2_203(m, d) BOOST_PP_REPEAT_2_202(m, d) m(3, 202, d) # define BOOST_PP_REPEAT_2_204(m, d) BOOST_PP_REPEAT_2_203(m, d) m(3, 203, d) # define BOOST_PP_REPEAT_2_205(m, d) BOOST_PP_REPEAT_2_204(m, d) m(3, 204, d) # define BOOST_PP_REPEAT_2_206(m, d) BOOST_PP_REPEAT_2_205(m, d) m(3, 205, d) # define BOOST_PP_REPEAT_2_207(m, d) BOOST_PP_REPEAT_2_206(m, d) m(3, 206, d) # define BOOST_PP_REPEAT_2_208(m, d) BOOST_PP_REPEAT_2_207(m, d) m(3, 207, d) # define BOOST_PP_REPEAT_2_209(m, d) BOOST_PP_REPEAT_2_208(m, d) m(3, 208, d) # define BOOST_PP_REPEAT_2_210(m, d) BOOST_PP_REPEAT_2_209(m, d) m(3, 209, d) # define BOOST_PP_REPEAT_2_211(m, d) BOOST_PP_REPEAT_2_210(m, d) m(3, 210, d) # define BOOST_PP_REPEAT_2_212(m, d) BOOST_PP_REPEAT_2_211(m, d) m(3, 211, d) # define BOOST_PP_REPEAT_2_213(m, d) BOOST_PP_REPEAT_2_212(m, d) m(3, 212, d) # define BOOST_PP_REPEAT_2_214(m, d) BOOST_PP_REPEAT_2_213(m, d) m(3, 213, d) # define BOOST_PP_REPEAT_2_215(m, d) BOOST_PP_REPEAT_2_214(m, d) m(3, 214, d) # define BOOST_PP_REPEAT_2_216(m, d) BOOST_PP_REPEAT_2_215(m, d) m(3, 215, d) # define BOOST_PP_REPEAT_2_217(m, d) BOOST_PP_REPEAT_2_216(m, d) m(3, 216, d) # define BOOST_PP_REPEAT_2_218(m, d) BOOST_PP_REPEAT_2_217(m, d) m(3, 217, d) # define BOOST_PP_REPEAT_2_219(m, d) BOOST_PP_REPEAT_2_218(m, d) m(3, 218, d) # define BOOST_PP_REPEAT_2_220(m, d) BOOST_PP_REPEAT_2_219(m, d) m(3, 219, d) # define BOOST_PP_REPEAT_2_221(m, d) BOOST_PP_REPEAT_2_220(m, d) m(3, 220, d) # define BOOST_PP_REPEAT_2_222(m, d) BOOST_PP_REPEAT_2_221(m, d) m(3, 221, d) # define BOOST_PP_REPEAT_2_223(m, d) BOOST_PP_REPEAT_2_222(m, d) m(3, 222, d) # define BOOST_PP_REPEAT_2_224(m, d) BOOST_PP_REPEAT_2_223(m, d) m(3, 223, d) # define BOOST_PP_REPEAT_2_225(m, d) BOOST_PP_REPEAT_2_224(m, d) m(3, 224, d) # define BOOST_PP_REPEAT_2_226(m, d) BOOST_PP_REPEAT_2_225(m, d) m(3, 225, d) # define BOOST_PP_REPEAT_2_227(m, d) BOOST_PP_REPEAT_2_226(m, d) m(3, 226, d) # define BOOST_PP_REPEAT_2_228(m, d) BOOST_PP_REPEAT_2_227(m, d) m(3, 227, d) # define BOOST_PP_REPEAT_2_229(m, d) BOOST_PP_REPEAT_2_228(m, d) m(3, 228, d) # define BOOST_PP_REPEAT_2_230(m, d) BOOST_PP_REPEAT_2_229(m, d) m(3, 229, d) # define BOOST_PP_REPEAT_2_231(m, d) BOOST_PP_REPEAT_2_230(m, d) m(3, 230, d) # define BOOST_PP_REPEAT_2_232(m, d) BOOST_PP_REPEAT_2_231(m, d) m(3, 231, d) # define BOOST_PP_REPEAT_2_233(m, d) BOOST_PP_REPEAT_2_232(m, d) m(3, 232, d) # define BOOST_PP_REPEAT_2_234(m, d) BOOST_PP_REPEAT_2_233(m, d) m(3, 233, d) # define BOOST_PP_REPEAT_2_235(m, d) BOOST_PP_REPEAT_2_234(m, d) m(3, 234, d) # define BOOST_PP_REPEAT_2_236(m, d) BOOST_PP_REPEAT_2_235(m, d) m(3, 235, d) # define BOOST_PP_REPEAT_2_237(m, d) BOOST_PP_REPEAT_2_236(m, d) m(3, 236, d) # define BOOST_PP_REPEAT_2_238(m, d) BOOST_PP_REPEAT_2_237(m, d) m(3, 237, d) # define BOOST_PP_REPEAT_2_239(m, d) BOOST_PP_REPEAT_2_238(m, d) m(3, 238, d) # define BOOST_PP_REPEAT_2_240(m, d) BOOST_PP_REPEAT_2_239(m, d) m(3, 239, d) # define BOOST_PP_REPEAT_2_241(m, d) BOOST_PP_REPEAT_2_240(m, d) m(3, 240, d) # define BOOST_PP_REPEAT_2_242(m, d) BOOST_PP_REPEAT_2_241(m, d) m(3, 241, d) # define BOOST_PP_REPEAT_2_243(m, d) BOOST_PP_REPEAT_2_242(m, d) m(3, 242, d) # define BOOST_PP_REPEAT_2_244(m, d) BOOST_PP_REPEAT_2_243(m, d) m(3, 243, d) # define BOOST_PP_REPEAT_2_245(m, d) BOOST_PP_REPEAT_2_244(m, d) m(3, 244, d) # define BOOST_PP_REPEAT_2_246(m, d) BOOST_PP_REPEAT_2_245(m, d) m(3, 245, d) # define BOOST_PP_REPEAT_2_247(m, d) BOOST_PP_REPEAT_2_246(m, d) m(3, 246, d) # define BOOST_PP_REPEAT_2_248(m, d) BOOST_PP_REPEAT_2_247(m, d) m(3, 247, d) # define BOOST_PP_REPEAT_2_249(m, d) BOOST_PP_REPEAT_2_248(m, d) m(3, 248, d) # define BOOST_PP_REPEAT_2_250(m, d) BOOST_PP_REPEAT_2_249(m, d) m(3, 249, d) # define BOOST_PP_REPEAT_2_251(m, d) BOOST_PP_REPEAT_2_250(m, d) m(3, 250, d) # define BOOST_PP_REPEAT_2_252(m, d) BOOST_PP_REPEAT_2_251(m, d) m(3, 251, d) # define BOOST_PP_REPEAT_2_253(m, d) BOOST_PP_REPEAT_2_252(m, d) m(3, 252, d) # define BOOST_PP_REPEAT_2_254(m, d) BOOST_PP_REPEAT_2_253(m, d) m(3, 253, d) # define BOOST_PP_REPEAT_2_255(m, d) BOOST_PP_REPEAT_2_254(m, d) m(3, 254, d) # define BOOST_PP_REPEAT_2_256(m, d) BOOST_PP_REPEAT_2_255(m, d) m(3, 255, d) # # define BOOST_PP_REPEAT_3_0(m, d) # define BOOST_PP_REPEAT_3_1(m, d) m(4, 0, d) # define BOOST_PP_REPEAT_3_2(m, d) BOOST_PP_REPEAT_3_1(m, d) m(4, 1, d) # define BOOST_PP_REPEAT_3_3(m, d) BOOST_PP_REPEAT_3_2(m, d) m(4, 2, d) # define BOOST_PP_REPEAT_3_4(m, d) BOOST_PP_REPEAT_3_3(m, d) m(4, 3, d) # define BOOST_PP_REPEAT_3_5(m, d) BOOST_PP_REPEAT_3_4(m, d) m(4, 4, d) # define BOOST_PP_REPEAT_3_6(m, d) BOOST_PP_REPEAT_3_5(m, d) m(4, 5, d) # define BOOST_PP_REPEAT_3_7(m, d) BOOST_PP_REPEAT_3_6(m, d) m(4, 6, d) # define BOOST_PP_REPEAT_3_8(m, d) BOOST_PP_REPEAT_3_7(m, d) m(4, 7, d) # define BOOST_PP_REPEAT_3_9(m, d) BOOST_PP_REPEAT_3_8(m, d) m(4, 8, d) # define BOOST_PP_REPEAT_3_10(m, d) BOOST_PP_REPEAT_3_9(m, d) m(4, 9, d) # define BOOST_PP_REPEAT_3_11(m, d) BOOST_PP_REPEAT_3_10(m, d) m(4, 10, d) # define BOOST_PP_REPEAT_3_12(m, d) BOOST_PP_REPEAT_3_11(m, d) m(4, 11, d) # define BOOST_PP_REPEAT_3_13(m, d) BOOST_PP_REPEAT_3_12(m, d) m(4, 12, d) # define BOOST_PP_REPEAT_3_14(m, d) BOOST_PP_REPEAT_3_13(m, d) m(4, 13, d) # define BOOST_PP_REPEAT_3_15(m, d) BOOST_PP_REPEAT_3_14(m, d) m(4, 14, d) # define BOOST_PP_REPEAT_3_16(m, d) BOOST_PP_REPEAT_3_15(m, d) m(4, 15, d) # define BOOST_PP_REPEAT_3_17(m, d) BOOST_PP_REPEAT_3_16(m, d) m(4, 16, d) # define BOOST_PP_REPEAT_3_18(m, d) BOOST_PP_REPEAT_3_17(m, d) m(4, 17, d) # define BOOST_PP_REPEAT_3_19(m, d) BOOST_PP_REPEAT_3_18(m, d) m(4, 18, d) # define BOOST_PP_REPEAT_3_20(m, d) BOOST_PP_REPEAT_3_19(m, d) m(4, 19, d) # define BOOST_PP_REPEAT_3_21(m, d) BOOST_PP_REPEAT_3_20(m, d) m(4, 20, d) # define BOOST_PP_REPEAT_3_22(m, d) BOOST_PP_REPEAT_3_21(m, d) m(4, 21, d) # define BOOST_PP_REPEAT_3_23(m, d) BOOST_PP_REPEAT_3_22(m, d) m(4, 22, d) # define BOOST_PP_REPEAT_3_24(m, d) BOOST_PP_REPEAT_3_23(m, d) m(4, 23, d) # define BOOST_PP_REPEAT_3_25(m, d) BOOST_PP_REPEAT_3_24(m, d) m(4, 24, d) # define BOOST_PP_REPEAT_3_26(m, d) BOOST_PP_REPEAT_3_25(m, d) m(4, 25, d) # define BOOST_PP_REPEAT_3_27(m, d) BOOST_PP_REPEAT_3_26(m, d) m(4, 26, d) # define BOOST_PP_REPEAT_3_28(m, d) BOOST_PP_REPEAT_3_27(m, d) m(4, 27, d) # define BOOST_PP_REPEAT_3_29(m, d) BOOST_PP_REPEAT_3_28(m, d) m(4, 28, d) # define BOOST_PP_REPEAT_3_30(m, d) BOOST_PP_REPEAT_3_29(m, d) m(4, 29, d) # define BOOST_PP_REPEAT_3_31(m, d) BOOST_PP_REPEAT_3_30(m, d) m(4, 30, d) # define BOOST_PP_REPEAT_3_32(m, d) BOOST_PP_REPEAT_3_31(m, d) m(4, 31, d) # define BOOST_PP_REPEAT_3_33(m, d) BOOST_PP_REPEAT_3_32(m, d) m(4, 32, d) # define BOOST_PP_REPEAT_3_34(m, d) BOOST_PP_REPEAT_3_33(m, d) m(4, 33, d) # define BOOST_PP_REPEAT_3_35(m, d) BOOST_PP_REPEAT_3_34(m, d) m(4, 34, d) # define BOOST_PP_REPEAT_3_36(m, d) BOOST_PP_REPEAT_3_35(m, d) m(4, 35, d) # define BOOST_PP_REPEAT_3_37(m, d) BOOST_PP_REPEAT_3_36(m, d) m(4, 36, d) # define BOOST_PP_REPEAT_3_38(m, d) BOOST_PP_REPEAT_3_37(m, d) m(4, 37, d) # define BOOST_PP_REPEAT_3_39(m, d) BOOST_PP_REPEAT_3_38(m, d) m(4, 38, d) # define BOOST_PP_REPEAT_3_40(m, d) BOOST_PP_REPEAT_3_39(m, d) m(4, 39, d) # define BOOST_PP_REPEAT_3_41(m, d) BOOST_PP_REPEAT_3_40(m, d) m(4, 40, d) # define BOOST_PP_REPEAT_3_42(m, d) BOOST_PP_REPEAT_3_41(m, d) m(4, 41, d) # define BOOST_PP_REPEAT_3_43(m, d) BOOST_PP_REPEAT_3_42(m, d) m(4, 42, d) # define BOOST_PP_REPEAT_3_44(m, d) BOOST_PP_REPEAT_3_43(m, d) m(4, 43, d) # define BOOST_PP_REPEAT_3_45(m, d) BOOST_PP_REPEAT_3_44(m, d) m(4, 44, d) # define BOOST_PP_REPEAT_3_46(m, d) BOOST_PP_REPEAT_3_45(m, d) m(4, 45, d) # define BOOST_PP_REPEAT_3_47(m, d) BOOST_PP_REPEAT_3_46(m, d) m(4, 46, d) # define BOOST_PP_REPEAT_3_48(m, d) BOOST_PP_REPEAT_3_47(m, d) m(4, 47, d) # define BOOST_PP_REPEAT_3_49(m, d) BOOST_PP_REPEAT_3_48(m, d) m(4, 48, d) # define BOOST_PP_REPEAT_3_50(m, d) BOOST_PP_REPEAT_3_49(m, d) m(4, 49, d) # define BOOST_PP_REPEAT_3_51(m, d) BOOST_PP_REPEAT_3_50(m, d) m(4, 50, d) # define BOOST_PP_REPEAT_3_52(m, d) BOOST_PP_REPEAT_3_51(m, d) m(4, 51, d) # define BOOST_PP_REPEAT_3_53(m, d) BOOST_PP_REPEAT_3_52(m, d) m(4, 52, d) # define BOOST_PP_REPEAT_3_54(m, d) BOOST_PP_REPEAT_3_53(m, d) m(4, 53, d) # define BOOST_PP_REPEAT_3_55(m, d) BOOST_PP_REPEAT_3_54(m, d) m(4, 54, d) # define BOOST_PP_REPEAT_3_56(m, d) BOOST_PP_REPEAT_3_55(m, d) m(4, 55, d) # define BOOST_PP_REPEAT_3_57(m, d) BOOST_PP_REPEAT_3_56(m, d) m(4, 56, d) # define BOOST_PP_REPEAT_3_58(m, d) BOOST_PP_REPEAT_3_57(m, d) m(4, 57, d) # define BOOST_PP_REPEAT_3_59(m, d) BOOST_PP_REPEAT_3_58(m, d) m(4, 58, d) # define BOOST_PP_REPEAT_3_60(m, d) BOOST_PP_REPEAT_3_59(m, d) m(4, 59, d) # define BOOST_PP_REPEAT_3_61(m, d) BOOST_PP_REPEAT_3_60(m, d) m(4, 60, d) # define BOOST_PP_REPEAT_3_62(m, d) BOOST_PP_REPEAT_3_61(m, d) m(4, 61, d) # define BOOST_PP_REPEAT_3_63(m, d) BOOST_PP_REPEAT_3_62(m, d) m(4, 62, d) # define BOOST_PP_REPEAT_3_64(m, d) BOOST_PP_REPEAT_3_63(m, d) m(4, 63, d) # define BOOST_PP_REPEAT_3_65(m, d) BOOST_PP_REPEAT_3_64(m, d) m(4, 64, d) # define BOOST_PP_REPEAT_3_66(m, d) BOOST_PP_REPEAT_3_65(m, d) m(4, 65, d) # define BOOST_PP_REPEAT_3_67(m, d) BOOST_PP_REPEAT_3_66(m, d) m(4, 66, d) # define BOOST_PP_REPEAT_3_68(m, d) BOOST_PP_REPEAT_3_67(m, d) m(4, 67, d) # define BOOST_PP_REPEAT_3_69(m, d) BOOST_PP_REPEAT_3_68(m, d) m(4, 68, d) # define BOOST_PP_REPEAT_3_70(m, d) BOOST_PP_REPEAT_3_69(m, d) m(4, 69, d) # define BOOST_PP_REPEAT_3_71(m, d) BOOST_PP_REPEAT_3_70(m, d) m(4, 70, d) # define BOOST_PP_REPEAT_3_72(m, d) BOOST_PP_REPEAT_3_71(m, d) m(4, 71, d) # define BOOST_PP_REPEAT_3_73(m, d) BOOST_PP_REPEAT_3_72(m, d) m(4, 72, d) # define BOOST_PP_REPEAT_3_74(m, d) BOOST_PP_REPEAT_3_73(m, d) m(4, 73, d) # define BOOST_PP_REPEAT_3_75(m, d) BOOST_PP_REPEAT_3_74(m, d) m(4, 74, d) # define BOOST_PP_REPEAT_3_76(m, d) BOOST_PP_REPEAT_3_75(m, d) m(4, 75, d) # define BOOST_PP_REPEAT_3_77(m, d) BOOST_PP_REPEAT_3_76(m, d) m(4, 76, d) # define BOOST_PP_REPEAT_3_78(m, d) BOOST_PP_REPEAT_3_77(m, d) m(4, 77, d) # define BOOST_PP_REPEAT_3_79(m, d) BOOST_PP_REPEAT_3_78(m, d) m(4, 78, d) # define BOOST_PP_REPEAT_3_80(m, d) BOOST_PP_REPEAT_3_79(m, d) m(4, 79, d) # define BOOST_PP_REPEAT_3_81(m, d) BOOST_PP_REPEAT_3_80(m, d) m(4, 80, d) # define BOOST_PP_REPEAT_3_82(m, d) BOOST_PP_REPEAT_3_81(m, d) m(4, 81, d) # define BOOST_PP_REPEAT_3_83(m, d) BOOST_PP_REPEAT_3_82(m, d) m(4, 82, d) # define BOOST_PP_REPEAT_3_84(m, d) BOOST_PP_REPEAT_3_83(m, d) m(4, 83, d) # define BOOST_PP_REPEAT_3_85(m, d) BOOST_PP_REPEAT_3_84(m, d) m(4, 84, d) # define BOOST_PP_REPEAT_3_86(m, d) BOOST_PP_REPEAT_3_85(m, d) m(4, 85, d) # define BOOST_PP_REPEAT_3_87(m, d) BOOST_PP_REPEAT_3_86(m, d) m(4, 86, d) # define BOOST_PP_REPEAT_3_88(m, d) BOOST_PP_REPEAT_3_87(m, d) m(4, 87, d) # define BOOST_PP_REPEAT_3_89(m, d) BOOST_PP_REPEAT_3_88(m, d) m(4, 88, d) # define BOOST_PP_REPEAT_3_90(m, d) BOOST_PP_REPEAT_3_89(m, d) m(4, 89, d) # define BOOST_PP_REPEAT_3_91(m, d) BOOST_PP_REPEAT_3_90(m, d) m(4, 90, d) # define BOOST_PP_REPEAT_3_92(m, d) BOOST_PP_REPEAT_3_91(m, d) m(4, 91, d) # define BOOST_PP_REPEAT_3_93(m, d) BOOST_PP_REPEAT_3_92(m, d) m(4, 92, d) # define BOOST_PP_REPEAT_3_94(m, d) BOOST_PP_REPEAT_3_93(m, d) m(4, 93, d) # define BOOST_PP_REPEAT_3_95(m, d) BOOST_PP_REPEAT_3_94(m, d) m(4, 94, d) # define BOOST_PP_REPEAT_3_96(m, d) BOOST_PP_REPEAT_3_95(m, d) m(4, 95, d) # define BOOST_PP_REPEAT_3_97(m, d) BOOST_PP_REPEAT_3_96(m, d) m(4, 96, d) # define BOOST_PP_REPEAT_3_98(m, d) BOOST_PP_REPEAT_3_97(m, d) m(4, 97, d) # define BOOST_PP_REPEAT_3_99(m, d) BOOST_PP_REPEAT_3_98(m, d) m(4, 98, d) # define BOOST_PP_REPEAT_3_100(m, d) BOOST_PP_REPEAT_3_99(m, d) m(4, 99, d) # define BOOST_PP_REPEAT_3_101(m, d) BOOST_PP_REPEAT_3_100(m, d) m(4, 100, d) # define BOOST_PP_REPEAT_3_102(m, d) BOOST_PP_REPEAT_3_101(m, d) m(4, 101, d) # define BOOST_PP_REPEAT_3_103(m, d) BOOST_PP_REPEAT_3_102(m, d) m(4, 102, d) # define BOOST_PP_REPEAT_3_104(m, d) BOOST_PP_REPEAT_3_103(m, d) m(4, 103, d) # define BOOST_PP_REPEAT_3_105(m, d) BOOST_PP_REPEAT_3_104(m, d) m(4, 104, d) # define BOOST_PP_REPEAT_3_106(m, d) BOOST_PP_REPEAT_3_105(m, d) m(4, 105, d) # define BOOST_PP_REPEAT_3_107(m, d) BOOST_PP_REPEAT_3_106(m, d) m(4, 106, d) # define BOOST_PP_REPEAT_3_108(m, d) BOOST_PP_REPEAT_3_107(m, d) m(4, 107, d) # define BOOST_PP_REPEAT_3_109(m, d) BOOST_PP_REPEAT_3_108(m, d) m(4, 108, d) # define BOOST_PP_REPEAT_3_110(m, d) BOOST_PP_REPEAT_3_109(m, d) m(4, 109, d) # define BOOST_PP_REPEAT_3_111(m, d) BOOST_PP_REPEAT_3_110(m, d) m(4, 110, d) # define BOOST_PP_REPEAT_3_112(m, d) BOOST_PP_REPEAT_3_111(m, d) m(4, 111, d) # define BOOST_PP_REPEAT_3_113(m, d) BOOST_PP_REPEAT_3_112(m, d) m(4, 112, d) # define BOOST_PP_REPEAT_3_114(m, d) BOOST_PP_REPEAT_3_113(m, d) m(4, 113, d) # define BOOST_PP_REPEAT_3_115(m, d) BOOST_PP_REPEAT_3_114(m, d) m(4, 114, d) # define BOOST_PP_REPEAT_3_116(m, d) BOOST_PP_REPEAT_3_115(m, d) m(4, 115, d) # define BOOST_PP_REPEAT_3_117(m, d) BOOST_PP_REPEAT_3_116(m, d) m(4, 116, d) # define BOOST_PP_REPEAT_3_118(m, d) BOOST_PP_REPEAT_3_117(m, d) m(4, 117, d) # define BOOST_PP_REPEAT_3_119(m, d) BOOST_PP_REPEAT_3_118(m, d) m(4, 118, d) # define BOOST_PP_REPEAT_3_120(m, d) BOOST_PP_REPEAT_3_119(m, d) m(4, 119, d) # define BOOST_PP_REPEAT_3_121(m, d) BOOST_PP_REPEAT_3_120(m, d) m(4, 120, d) # define BOOST_PP_REPEAT_3_122(m, d) BOOST_PP_REPEAT_3_121(m, d) m(4, 121, d) # define BOOST_PP_REPEAT_3_123(m, d) BOOST_PP_REPEAT_3_122(m, d) m(4, 122, d) # define BOOST_PP_REPEAT_3_124(m, d) BOOST_PP_REPEAT_3_123(m, d) m(4, 123, d) # define BOOST_PP_REPEAT_3_125(m, d) BOOST_PP_REPEAT_3_124(m, d) m(4, 124, d) # define BOOST_PP_REPEAT_3_126(m, d) BOOST_PP_REPEAT_3_125(m, d) m(4, 125, d) # define BOOST_PP_REPEAT_3_127(m, d) BOOST_PP_REPEAT_3_126(m, d) m(4, 126, d) # define BOOST_PP_REPEAT_3_128(m, d) BOOST_PP_REPEAT_3_127(m, d) m(4, 127, d) # define BOOST_PP_REPEAT_3_129(m, d) BOOST_PP_REPEAT_3_128(m, d) m(4, 128, d) # define BOOST_PP_REPEAT_3_130(m, d) BOOST_PP_REPEAT_3_129(m, d) m(4, 129, d) # define BOOST_PP_REPEAT_3_131(m, d) BOOST_PP_REPEAT_3_130(m, d) m(4, 130, d) # define BOOST_PP_REPEAT_3_132(m, d) BOOST_PP_REPEAT_3_131(m, d) m(4, 131, d) # define BOOST_PP_REPEAT_3_133(m, d) BOOST_PP_REPEAT_3_132(m, d) m(4, 132, d) # define BOOST_PP_REPEAT_3_134(m, d) BOOST_PP_REPEAT_3_133(m, d) m(4, 133, d) # define BOOST_PP_REPEAT_3_135(m, d) BOOST_PP_REPEAT_3_134(m, d) m(4, 134, d) # define BOOST_PP_REPEAT_3_136(m, d) BOOST_PP_REPEAT_3_135(m, d) m(4, 135, d) # define BOOST_PP_REPEAT_3_137(m, d) BOOST_PP_REPEAT_3_136(m, d) m(4, 136, d) # define BOOST_PP_REPEAT_3_138(m, d) BOOST_PP_REPEAT_3_137(m, d) m(4, 137, d) # define BOOST_PP_REPEAT_3_139(m, d) BOOST_PP_REPEAT_3_138(m, d) m(4, 138, d) # define BOOST_PP_REPEAT_3_140(m, d) BOOST_PP_REPEAT_3_139(m, d) m(4, 139, d) # define BOOST_PP_REPEAT_3_141(m, d) BOOST_PP_REPEAT_3_140(m, d) m(4, 140, d) # define BOOST_PP_REPEAT_3_142(m, d) BOOST_PP_REPEAT_3_141(m, d) m(4, 141, d) # define BOOST_PP_REPEAT_3_143(m, d) BOOST_PP_REPEAT_3_142(m, d) m(4, 142, d) # define BOOST_PP_REPEAT_3_144(m, d) BOOST_PP_REPEAT_3_143(m, d) m(4, 143, d) # define BOOST_PP_REPEAT_3_145(m, d) BOOST_PP_REPEAT_3_144(m, d) m(4, 144, d) # define BOOST_PP_REPEAT_3_146(m, d) BOOST_PP_REPEAT_3_145(m, d) m(4, 145, d) # define BOOST_PP_REPEAT_3_147(m, d) BOOST_PP_REPEAT_3_146(m, d) m(4, 146, d) # define BOOST_PP_REPEAT_3_148(m, d) BOOST_PP_REPEAT_3_147(m, d) m(4, 147, d) # define BOOST_PP_REPEAT_3_149(m, d) BOOST_PP_REPEAT_3_148(m, d) m(4, 148, d) # define BOOST_PP_REPEAT_3_150(m, d) BOOST_PP_REPEAT_3_149(m, d) m(4, 149, d) # define BOOST_PP_REPEAT_3_151(m, d) BOOST_PP_REPEAT_3_150(m, d) m(4, 150, d) # define BOOST_PP_REPEAT_3_152(m, d) BOOST_PP_REPEAT_3_151(m, d) m(4, 151, d) # define BOOST_PP_REPEAT_3_153(m, d) BOOST_PP_REPEAT_3_152(m, d) m(4, 152, d) # define BOOST_PP_REPEAT_3_154(m, d) BOOST_PP_REPEAT_3_153(m, d) m(4, 153, d) # define BOOST_PP_REPEAT_3_155(m, d) BOOST_PP_REPEAT_3_154(m, d) m(4, 154, d) # define BOOST_PP_REPEAT_3_156(m, d) BOOST_PP_REPEAT_3_155(m, d) m(4, 155, d) # define BOOST_PP_REPEAT_3_157(m, d) BOOST_PP_REPEAT_3_156(m, d) m(4, 156, d) # define BOOST_PP_REPEAT_3_158(m, d) BOOST_PP_REPEAT_3_157(m, d) m(4, 157, d) # define BOOST_PP_REPEAT_3_159(m, d) BOOST_PP_REPEAT_3_158(m, d) m(4, 158, d) # define BOOST_PP_REPEAT_3_160(m, d) BOOST_PP_REPEAT_3_159(m, d) m(4, 159, d) # define BOOST_PP_REPEAT_3_161(m, d) BOOST_PP_REPEAT_3_160(m, d) m(4, 160, d) # define BOOST_PP_REPEAT_3_162(m, d) BOOST_PP_REPEAT_3_161(m, d) m(4, 161, d) # define BOOST_PP_REPEAT_3_163(m, d) BOOST_PP_REPEAT_3_162(m, d) m(4, 162, d) # define BOOST_PP_REPEAT_3_164(m, d) BOOST_PP_REPEAT_3_163(m, d) m(4, 163, d) # define BOOST_PP_REPEAT_3_165(m, d) BOOST_PP_REPEAT_3_164(m, d) m(4, 164, d) # define BOOST_PP_REPEAT_3_166(m, d) BOOST_PP_REPEAT_3_165(m, d) m(4, 165, d) # define BOOST_PP_REPEAT_3_167(m, d) BOOST_PP_REPEAT_3_166(m, d) m(4, 166, d) # define BOOST_PP_REPEAT_3_168(m, d) BOOST_PP_REPEAT_3_167(m, d) m(4, 167, d) # define BOOST_PP_REPEAT_3_169(m, d) BOOST_PP_REPEAT_3_168(m, d) m(4, 168, d) # define BOOST_PP_REPEAT_3_170(m, d) BOOST_PP_REPEAT_3_169(m, d) m(4, 169, d) # define BOOST_PP_REPEAT_3_171(m, d) BOOST_PP_REPEAT_3_170(m, d) m(4, 170, d) # define BOOST_PP_REPEAT_3_172(m, d) BOOST_PP_REPEAT_3_171(m, d) m(4, 171, d) # define BOOST_PP_REPEAT_3_173(m, d) BOOST_PP_REPEAT_3_172(m, d) m(4, 172, d) # define BOOST_PP_REPEAT_3_174(m, d) BOOST_PP_REPEAT_3_173(m, d) m(4, 173, d) # define BOOST_PP_REPEAT_3_175(m, d) BOOST_PP_REPEAT_3_174(m, d) m(4, 174, d) # define BOOST_PP_REPEAT_3_176(m, d) BOOST_PP_REPEAT_3_175(m, d) m(4, 175, d) # define BOOST_PP_REPEAT_3_177(m, d) BOOST_PP_REPEAT_3_176(m, d) m(4, 176, d) # define BOOST_PP_REPEAT_3_178(m, d) BOOST_PP_REPEAT_3_177(m, d) m(4, 177, d) # define BOOST_PP_REPEAT_3_179(m, d) BOOST_PP_REPEAT_3_178(m, d) m(4, 178, d) # define BOOST_PP_REPEAT_3_180(m, d) BOOST_PP_REPEAT_3_179(m, d) m(4, 179, d) # define BOOST_PP_REPEAT_3_181(m, d) BOOST_PP_REPEAT_3_180(m, d) m(4, 180, d) # define BOOST_PP_REPEAT_3_182(m, d) BOOST_PP_REPEAT_3_181(m, d) m(4, 181, d) # define BOOST_PP_REPEAT_3_183(m, d) BOOST_PP_REPEAT_3_182(m, d) m(4, 182, d) # define BOOST_PP_REPEAT_3_184(m, d) BOOST_PP_REPEAT_3_183(m, d) m(4, 183, d) # define BOOST_PP_REPEAT_3_185(m, d) BOOST_PP_REPEAT_3_184(m, d) m(4, 184, d) # define BOOST_PP_REPEAT_3_186(m, d) BOOST_PP_REPEAT_3_185(m, d) m(4, 185, d) # define BOOST_PP_REPEAT_3_187(m, d) BOOST_PP_REPEAT_3_186(m, d) m(4, 186, d) # define BOOST_PP_REPEAT_3_188(m, d) BOOST_PP_REPEAT_3_187(m, d) m(4, 187, d) # define BOOST_PP_REPEAT_3_189(m, d) BOOST_PP_REPEAT_3_188(m, d) m(4, 188, d) # define BOOST_PP_REPEAT_3_190(m, d) BOOST_PP_REPEAT_3_189(m, d) m(4, 189, d) # define BOOST_PP_REPEAT_3_191(m, d) BOOST_PP_REPEAT_3_190(m, d) m(4, 190, d) # define BOOST_PP_REPEAT_3_192(m, d) BOOST_PP_REPEAT_3_191(m, d) m(4, 191, d) # define BOOST_PP_REPEAT_3_193(m, d) BOOST_PP_REPEAT_3_192(m, d) m(4, 192, d) # define BOOST_PP_REPEAT_3_194(m, d) BOOST_PP_REPEAT_3_193(m, d) m(4, 193, d) # define BOOST_PP_REPEAT_3_195(m, d) BOOST_PP_REPEAT_3_194(m, d) m(4, 194, d) # define BOOST_PP_REPEAT_3_196(m, d) BOOST_PP_REPEAT_3_195(m, d) m(4, 195, d) # define BOOST_PP_REPEAT_3_197(m, d) BOOST_PP_REPEAT_3_196(m, d) m(4, 196, d) # define BOOST_PP_REPEAT_3_198(m, d) BOOST_PP_REPEAT_3_197(m, d) m(4, 197, d) # define BOOST_PP_REPEAT_3_199(m, d) BOOST_PP_REPEAT_3_198(m, d) m(4, 198, d) # define BOOST_PP_REPEAT_3_200(m, d) BOOST_PP_REPEAT_3_199(m, d) m(4, 199, d) # define BOOST_PP_REPEAT_3_201(m, d) BOOST_PP_REPEAT_3_200(m, d) m(4, 200, d) # define BOOST_PP_REPEAT_3_202(m, d) BOOST_PP_REPEAT_3_201(m, d) m(4, 201, d) # define BOOST_PP_REPEAT_3_203(m, d) BOOST_PP_REPEAT_3_202(m, d) m(4, 202, d) # define BOOST_PP_REPEAT_3_204(m, d) BOOST_PP_REPEAT_3_203(m, d) m(4, 203, d) # define BOOST_PP_REPEAT_3_205(m, d) BOOST_PP_REPEAT_3_204(m, d) m(4, 204, d) # define BOOST_PP_REPEAT_3_206(m, d) BOOST_PP_REPEAT_3_205(m, d) m(4, 205, d) # define BOOST_PP_REPEAT_3_207(m, d) BOOST_PP_REPEAT_3_206(m, d) m(4, 206, d) # define BOOST_PP_REPEAT_3_208(m, d) BOOST_PP_REPEAT_3_207(m, d) m(4, 207, d) # define BOOST_PP_REPEAT_3_209(m, d) BOOST_PP_REPEAT_3_208(m, d) m(4, 208, d) # define BOOST_PP_REPEAT_3_210(m, d) BOOST_PP_REPEAT_3_209(m, d) m(4, 209, d) # define BOOST_PP_REPEAT_3_211(m, d) BOOST_PP_REPEAT_3_210(m, d) m(4, 210, d) # define BOOST_PP_REPEAT_3_212(m, d) BOOST_PP_REPEAT_3_211(m, d) m(4, 211, d) # define BOOST_PP_REPEAT_3_213(m, d) BOOST_PP_REPEAT_3_212(m, d) m(4, 212, d) # define BOOST_PP_REPEAT_3_214(m, d) BOOST_PP_REPEAT_3_213(m, d) m(4, 213, d) # define BOOST_PP_REPEAT_3_215(m, d) BOOST_PP_REPEAT_3_214(m, d) m(4, 214, d) # define BOOST_PP_REPEAT_3_216(m, d) BOOST_PP_REPEAT_3_215(m, d) m(4, 215, d) # define BOOST_PP_REPEAT_3_217(m, d) BOOST_PP_REPEAT_3_216(m, d) m(4, 216, d) # define BOOST_PP_REPEAT_3_218(m, d) BOOST_PP_REPEAT_3_217(m, d) m(4, 217, d) # define BOOST_PP_REPEAT_3_219(m, d) BOOST_PP_REPEAT_3_218(m, d) m(4, 218, d) # define BOOST_PP_REPEAT_3_220(m, d) BOOST_PP_REPEAT_3_219(m, d) m(4, 219, d) # define BOOST_PP_REPEAT_3_221(m, d) BOOST_PP_REPEAT_3_220(m, d) m(4, 220, d) # define BOOST_PP_REPEAT_3_222(m, d) BOOST_PP_REPEAT_3_221(m, d) m(4, 221, d) # define BOOST_PP_REPEAT_3_223(m, d) BOOST_PP_REPEAT_3_222(m, d) m(4, 222, d) # define BOOST_PP_REPEAT_3_224(m, d) BOOST_PP_REPEAT_3_223(m, d) m(4, 223, d) # define BOOST_PP_REPEAT_3_225(m, d) BOOST_PP_REPEAT_3_224(m, d) m(4, 224, d) # define BOOST_PP_REPEAT_3_226(m, d) BOOST_PP_REPEAT_3_225(m, d) m(4, 225, d) # define BOOST_PP_REPEAT_3_227(m, d) BOOST_PP_REPEAT_3_226(m, d) m(4, 226, d) # define BOOST_PP_REPEAT_3_228(m, d) BOOST_PP_REPEAT_3_227(m, d) m(4, 227, d) # define BOOST_PP_REPEAT_3_229(m, d) BOOST_PP_REPEAT_3_228(m, d) m(4, 228, d) # define BOOST_PP_REPEAT_3_230(m, d) BOOST_PP_REPEAT_3_229(m, d) m(4, 229, d) # define BOOST_PP_REPEAT_3_231(m, d) BOOST_PP_REPEAT_3_230(m, d) m(4, 230, d) # define BOOST_PP_REPEAT_3_232(m, d) BOOST_PP_REPEAT_3_231(m, d) m(4, 231, d) # define BOOST_PP_REPEAT_3_233(m, d) BOOST_PP_REPEAT_3_232(m, d) m(4, 232, d) # define BOOST_PP_REPEAT_3_234(m, d) BOOST_PP_REPEAT_3_233(m, d) m(4, 233, d) # define BOOST_PP_REPEAT_3_235(m, d) BOOST_PP_REPEAT_3_234(m, d) m(4, 234, d) # define BOOST_PP_REPEAT_3_236(m, d) BOOST_PP_REPEAT_3_235(m, d) m(4, 235, d) # define BOOST_PP_REPEAT_3_237(m, d) BOOST_PP_REPEAT_3_236(m, d) m(4, 236, d) # define BOOST_PP_REPEAT_3_238(m, d) BOOST_PP_REPEAT_3_237(m, d) m(4, 237, d) # define BOOST_PP_REPEAT_3_239(m, d) BOOST_PP_REPEAT_3_238(m, d) m(4, 238, d) # define BOOST_PP_REPEAT_3_240(m, d) BOOST_PP_REPEAT_3_239(m, d) m(4, 239, d) # define BOOST_PP_REPEAT_3_241(m, d) BOOST_PP_REPEAT_3_240(m, d) m(4, 240, d) # define BOOST_PP_REPEAT_3_242(m, d) BOOST_PP_REPEAT_3_241(m, d) m(4, 241, d) # define BOOST_PP_REPEAT_3_243(m, d) BOOST_PP_REPEAT_3_242(m, d) m(4, 242, d) # define BOOST_PP_REPEAT_3_244(m, d) BOOST_PP_REPEAT_3_243(m, d) m(4, 243, d) # define BOOST_PP_REPEAT_3_245(m, d) BOOST_PP_REPEAT_3_244(m, d) m(4, 244, d) # define BOOST_PP_REPEAT_3_246(m, d) BOOST_PP_REPEAT_3_245(m, d) m(4, 245, d) # define BOOST_PP_REPEAT_3_247(m, d) BOOST_PP_REPEAT_3_246(m, d) m(4, 246, d) # define BOOST_PP_REPEAT_3_248(m, d) BOOST_PP_REPEAT_3_247(m, d) m(4, 247, d) # define BOOST_PP_REPEAT_3_249(m, d) BOOST_PP_REPEAT_3_248(m, d) m(4, 248, d) # define BOOST_PP_REPEAT_3_250(m, d) BOOST_PP_REPEAT_3_249(m, d) m(4, 249, d) # define BOOST_PP_REPEAT_3_251(m, d) BOOST_PP_REPEAT_3_250(m, d) m(4, 250, d) # define BOOST_PP_REPEAT_3_252(m, d) BOOST_PP_REPEAT_3_251(m, d) m(4, 251, d) # define BOOST_PP_REPEAT_3_253(m, d) BOOST_PP_REPEAT_3_252(m, d) m(4, 252, d) # define BOOST_PP_REPEAT_3_254(m, d) BOOST_PP_REPEAT_3_253(m, d) m(4, 253, d) # define BOOST_PP_REPEAT_3_255(m, d) BOOST_PP_REPEAT_3_254(m, d) m(4, 254, d) # define BOOST_PP_REPEAT_3_256(m, d) BOOST_PP_REPEAT_3_255(m, d) m(4, 255, d) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/repetition/repeat_from_to.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_REPETITION_REPEAT_FROM_TO_HPP # define BOOST_PREPROCESSOR_REPETITION_REPEAT_FROM_TO_HPP # # include # include # include # include # include # include # include # include # include # include # # /* BOOST_PP_REPEAT_FROM_TO */ # # if 0 # define BOOST_PP_REPEAT_FROM_TO(first, last, macro, data) # endif # # define BOOST_PP_REPEAT_FROM_TO BOOST_PP_CAT(BOOST_PP_REPEAT_FROM_TO_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)) # # define BOOST_PP_REPEAT_FROM_TO_1(f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_1(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256), f, l, m, dt) # define BOOST_PP_REPEAT_FROM_TO_2(f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_2(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256), f, l, m, dt) # define BOOST_PP_REPEAT_FROM_TO_3(f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_3(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256), f, l, m, dt) # define BOOST_PP_REPEAT_FROM_TO_4(f, l, m, dt) BOOST_PP_ERROR(0x0003) # # define BOOST_PP_REPEAT_FROM_TO_1ST BOOST_PP_REPEAT_FROM_TO_1 # define BOOST_PP_REPEAT_FROM_TO_2ND BOOST_PP_REPEAT_FROM_TO_2 # define BOOST_PP_REPEAT_FROM_TO_3RD BOOST_PP_REPEAT_FROM_TO_3 # # /* BOOST_PP_REPEAT_FROM_TO_D */ # # if 0 # define BOOST_PP_REPEAT_FROM_TO_D(d, first, last, macro, data) # endif # # define BOOST_PP_REPEAT_FROM_TO_D BOOST_PP_CAT(BOOST_PP_REPEAT_FROM_TO_D_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_REPEAT_FROM_TO_D_1(d, f, l, m, dt) BOOST_PP_REPEAT_1(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_1, (d, f, m, dt)) # define BOOST_PP_REPEAT_FROM_TO_D_2(d, f, l, m, dt) BOOST_PP_REPEAT_2(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_2, (d, f, m, dt)) # define BOOST_PP_REPEAT_FROM_TO_D_3(d, f, l, m, dt) BOOST_PP_REPEAT_3(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_3, (d, f, m, dt)) # else # define BOOST_PP_REPEAT_FROM_TO_D_1(d, f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_1_I(d, f, l, m, dt) # define BOOST_PP_REPEAT_FROM_TO_D_2(d, f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_2_I(d, f, l, m, dt) # define BOOST_PP_REPEAT_FROM_TO_D_3(d, f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_3_I(d, f, l, m, dt) # define BOOST_PP_REPEAT_FROM_TO_D_1_I(d, f, l, m, dt) BOOST_PP_REPEAT_1(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_1, (d, f, m, dt)) # define BOOST_PP_REPEAT_FROM_TO_D_2_I(d, f, l, m, dt) BOOST_PP_REPEAT_2(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_2, (d, f, m, dt)) # define BOOST_PP_REPEAT_FROM_TO_D_3_I(d, f, l, m, dt) BOOST_PP_REPEAT_3(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_3, (d, f, m, dt)) # endif # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_REPEAT_FROM_TO_M_1(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_1_IM(z, n, BOOST_PP_TUPLE_REM_4 dfmd) # define BOOST_PP_REPEAT_FROM_TO_M_2(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_2_IM(z, n, BOOST_PP_TUPLE_REM_4 dfmd) # define BOOST_PP_REPEAT_FROM_TO_M_3(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_3_IM(z, n, BOOST_PP_TUPLE_REM_4 dfmd) # define BOOST_PP_REPEAT_FROM_TO_M_1_IM(z, n, im) BOOST_PP_REPEAT_FROM_TO_M_1_I(z, n, im) # define BOOST_PP_REPEAT_FROM_TO_M_2_IM(z, n, im) BOOST_PP_REPEAT_FROM_TO_M_2_I(z, n, im) # define BOOST_PP_REPEAT_FROM_TO_M_3_IM(z, n, im) BOOST_PP_REPEAT_FROM_TO_M_3_I(z, n, im) # else # define BOOST_PP_REPEAT_FROM_TO_M_1(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(4, 0, dfmd), BOOST_PP_TUPLE_ELEM(4, 1, dfmd), BOOST_PP_TUPLE_ELEM(4, 2, dfmd), BOOST_PP_TUPLE_ELEM(4, 3, dfmd)) # define BOOST_PP_REPEAT_FROM_TO_M_2(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(4, 0, dfmd), BOOST_PP_TUPLE_ELEM(4, 1, dfmd), BOOST_PP_TUPLE_ELEM(4, 2, dfmd), BOOST_PP_TUPLE_ELEM(4, 3, dfmd)) # define BOOST_PP_REPEAT_FROM_TO_M_3(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(4, 0, dfmd), BOOST_PP_TUPLE_ELEM(4, 1, dfmd), BOOST_PP_TUPLE_ELEM(4, 2, dfmd), BOOST_PP_TUPLE_ELEM(4, 3, dfmd)) # endif # # define BOOST_PP_REPEAT_FROM_TO_M_1_I(z, n, d, f, m, dt) BOOST_PP_REPEAT_FROM_TO_M_1_II(z, BOOST_PP_ADD_D(d, n, f), m, dt) # define BOOST_PP_REPEAT_FROM_TO_M_2_I(z, n, d, f, m, dt) BOOST_PP_REPEAT_FROM_TO_M_2_II(z, BOOST_PP_ADD_D(d, n, f), m, dt) # define BOOST_PP_REPEAT_FROM_TO_M_3_I(z, n, d, f, m, dt) BOOST_PP_REPEAT_FROM_TO_M_3_II(z, BOOST_PP_ADD_D(d, n, f), m, dt) # # define BOOST_PP_REPEAT_FROM_TO_M_1_II(z, n, m, dt) m(z, n, dt) # define BOOST_PP_REPEAT_FROM_TO_M_2_II(z, n, m, dt) m(z, n, dt) # define BOOST_PP_REPEAT_FROM_TO_M_3_II(z, n, m, dt) m(z, n, dt) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/selection/max.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SELECTION_MAX_HPP # define BOOST_PREPROCESSOR_SELECTION_MAX_HPP # # include # include # include # # /* BOOST_PP_MAX */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_MAX(x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL(x, y), y, x) # else # define BOOST_PP_MAX(x, y) BOOST_PP_MAX_I(x, y) # define BOOST_PP_MAX_I(x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL(x, y), y, x) # endif # # /* BOOST_PP_MAX_D */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_MAX_D(d, x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL_D(d, x, y), y, x) # else # define BOOST_PP_MAX_D(d, x, y) BOOST_PP_MAX_D_I(d, x, y) # define BOOST_PP_MAX_D_I(d, x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL_D(d, x, y), y, x) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/detail/is_empty.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2015. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_DETAIL_IS_EMPTY_HPP # define BOOST_PREPROCESSOR_SEQ_DETAIL_IS_EMPTY_HPP # # include # include # include # include # include # /* An empty seq is one that is just BOOST_PP_SEQ_NIL */ # # define BOOST_PP_SEQ_DETAIL_IS_EMPTY(seq) \ BOOST_PP_COMPL \ ( \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq) \ ) \ /**/ # # define BOOST_PP_SEQ_DETAIL_IS_EMPTY_SIZE(size) \ BOOST_PP_COMPL \ ( \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(size) \ ) \ /**/ # # define BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq) \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq)) \ /**/ # # define BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(size) \ BOOST_PP_BOOL(size) \ /**/ # # define BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq) \ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq (nil))) \ /**/ # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/detail/split.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_DETAIL_SPLIT_HPP # define BOOST_PREPROCESSOR_SEQ_DETAIL_SPLIT_HPP # # include # # /* BOOST_PP_SEQ_SPLIT */ # # define BOOST_PP_SEQ_SPLIT(n, seq) BOOST_PP_SEQ_SPLIT_D(n, seq) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_SPLIT_D(n, seq) (BOOST_PP_SEQ_SPLIT_ ## n seq) # else # define BOOST_PP_SEQ_SPLIT_D(n, seq) (BOOST_PP_SEQ_SPLIT_ ## n ## seq) # endif # # define BOOST_PP_SEQ_SPLIT_1(x) (x), # define BOOST_PP_SEQ_SPLIT_2(x) (x) BOOST_PP_SEQ_SPLIT_1 # define BOOST_PP_SEQ_SPLIT_3(x) (x) BOOST_PP_SEQ_SPLIT_2 # define BOOST_PP_SEQ_SPLIT_4(x) (x) BOOST_PP_SEQ_SPLIT_3 # define BOOST_PP_SEQ_SPLIT_5(x) (x) BOOST_PP_SEQ_SPLIT_4 # define BOOST_PP_SEQ_SPLIT_6(x) (x) BOOST_PP_SEQ_SPLIT_5 # define BOOST_PP_SEQ_SPLIT_7(x) (x) BOOST_PP_SEQ_SPLIT_6 # define BOOST_PP_SEQ_SPLIT_8(x) (x) BOOST_PP_SEQ_SPLIT_7 # define BOOST_PP_SEQ_SPLIT_9(x) (x) BOOST_PP_SEQ_SPLIT_8 # define BOOST_PP_SEQ_SPLIT_10(x) (x) BOOST_PP_SEQ_SPLIT_9 # define BOOST_PP_SEQ_SPLIT_11(x) (x) BOOST_PP_SEQ_SPLIT_10 # define BOOST_PP_SEQ_SPLIT_12(x) (x) BOOST_PP_SEQ_SPLIT_11 # define BOOST_PP_SEQ_SPLIT_13(x) (x) BOOST_PP_SEQ_SPLIT_12 # define BOOST_PP_SEQ_SPLIT_14(x) (x) BOOST_PP_SEQ_SPLIT_13 # define BOOST_PP_SEQ_SPLIT_15(x) (x) BOOST_PP_SEQ_SPLIT_14 # define BOOST_PP_SEQ_SPLIT_16(x) (x) BOOST_PP_SEQ_SPLIT_15 # define BOOST_PP_SEQ_SPLIT_17(x) (x) BOOST_PP_SEQ_SPLIT_16 # define BOOST_PP_SEQ_SPLIT_18(x) (x) BOOST_PP_SEQ_SPLIT_17 # define BOOST_PP_SEQ_SPLIT_19(x) (x) BOOST_PP_SEQ_SPLIT_18 # define BOOST_PP_SEQ_SPLIT_20(x) (x) BOOST_PP_SEQ_SPLIT_19 # define BOOST_PP_SEQ_SPLIT_21(x) (x) BOOST_PP_SEQ_SPLIT_20 # define BOOST_PP_SEQ_SPLIT_22(x) (x) BOOST_PP_SEQ_SPLIT_21 # define BOOST_PP_SEQ_SPLIT_23(x) (x) BOOST_PP_SEQ_SPLIT_22 # define BOOST_PP_SEQ_SPLIT_24(x) (x) BOOST_PP_SEQ_SPLIT_23 # define BOOST_PP_SEQ_SPLIT_25(x) (x) BOOST_PP_SEQ_SPLIT_24 # define BOOST_PP_SEQ_SPLIT_26(x) (x) BOOST_PP_SEQ_SPLIT_25 # define BOOST_PP_SEQ_SPLIT_27(x) (x) BOOST_PP_SEQ_SPLIT_26 # define BOOST_PP_SEQ_SPLIT_28(x) (x) BOOST_PP_SEQ_SPLIT_27 # define BOOST_PP_SEQ_SPLIT_29(x) (x) BOOST_PP_SEQ_SPLIT_28 # define BOOST_PP_SEQ_SPLIT_30(x) (x) BOOST_PP_SEQ_SPLIT_29 # define BOOST_PP_SEQ_SPLIT_31(x) (x) BOOST_PP_SEQ_SPLIT_30 # define BOOST_PP_SEQ_SPLIT_32(x) (x) BOOST_PP_SEQ_SPLIT_31 # define BOOST_PP_SEQ_SPLIT_33(x) (x) BOOST_PP_SEQ_SPLIT_32 # define BOOST_PP_SEQ_SPLIT_34(x) (x) BOOST_PP_SEQ_SPLIT_33 # define BOOST_PP_SEQ_SPLIT_35(x) (x) BOOST_PP_SEQ_SPLIT_34 # define BOOST_PP_SEQ_SPLIT_36(x) (x) BOOST_PP_SEQ_SPLIT_35 # define BOOST_PP_SEQ_SPLIT_37(x) (x) BOOST_PP_SEQ_SPLIT_36 # define BOOST_PP_SEQ_SPLIT_38(x) (x) BOOST_PP_SEQ_SPLIT_37 # define BOOST_PP_SEQ_SPLIT_39(x) (x) BOOST_PP_SEQ_SPLIT_38 # define BOOST_PP_SEQ_SPLIT_40(x) (x) BOOST_PP_SEQ_SPLIT_39 # define BOOST_PP_SEQ_SPLIT_41(x) (x) BOOST_PP_SEQ_SPLIT_40 # define BOOST_PP_SEQ_SPLIT_42(x) (x) BOOST_PP_SEQ_SPLIT_41 # define BOOST_PP_SEQ_SPLIT_43(x) (x) BOOST_PP_SEQ_SPLIT_42 # define BOOST_PP_SEQ_SPLIT_44(x) (x) BOOST_PP_SEQ_SPLIT_43 # define BOOST_PP_SEQ_SPLIT_45(x) (x) BOOST_PP_SEQ_SPLIT_44 # define BOOST_PP_SEQ_SPLIT_46(x) (x) BOOST_PP_SEQ_SPLIT_45 # define BOOST_PP_SEQ_SPLIT_47(x) (x) BOOST_PP_SEQ_SPLIT_46 # define BOOST_PP_SEQ_SPLIT_48(x) (x) BOOST_PP_SEQ_SPLIT_47 # define BOOST_PP_SEQ_SPLIT_49(x) (x) BOOST_PP_SEQ_SPLIT_48 # define BOOST_PP_SEQ_SPLIT_50(x) (x) BOOST_PP_SEQ_SPLIT_49 # define BOOST_PP_SEQ_SPLIT_51(x) (x) BOOST_PP_SEQ_SPLIT_50 # define BOOST_PP_SEQ_SPLIT_52(x) (x) BOOST_PP_SEQ_SPLIT_51 # define BOOST_PP_SEQ_SPLIT_53(x) (x) BOOST_PP_SEQ_SPLIT_52 # define BOOST_PP_SEQ_SPLIT_54(x) (x) BOOST_PP_SEQ_SPLIT_53 # define BOOST_PP_SEQ_SPLIT_55(x) (x) BOOST_PP_SEQ_SPLIT_54 # define BOOST_PP_SEQ_SPLIT_56(x) (x) BOOST_PP_SEQ_SPLIT_55 # define BOOST_PP_SEQ_SPLIT_57(x) (x) BOOST_PP_SEQ_SPLIT_56 # define BOOST_PP_SEQ_SPLIT_58(x) (x) BOOST_PP_SEQ_SPLIT_57 # define BOOST_PP_SEQ_SPLIT_59(x) (x) BOOST_PP_SEQ_SPLIT_58 # define BOOST_PP_SEQ_SPLIT_60(x) (x) BOOST_PP_SEQ_SPLIT_59 # define BOOST_PP_SEQ_SPLIT_61(x) (x) BOOST_PP_SEQ_SPLIT_60 # define BOOST_PP_SEQ_SPLIT_62(x) (x) BOOST_PP_SEQ_SPLIT_61 # define BOOST_PP_SEQ_SPLIT_63(x) (x) BOOST_PP_SEQ_SPLIT_62 # define BOOST_PP_SEQ_SPLIT_64(x) (x) BOOST_PP_SEQ_SPLIT_63 # define BOOST_PP_SEQ_SPLIT_65(x) (x) BOOST_PP_SEQ_SPLIT_64 # define BOOST_PP_SEQ_SPLIT_66(x) (x) BOOST_PP_SEQ_SPLIT_65 # define BOOST_PP_SEQ_SPLIT_67(x) (x) BOOST_PP_SEQ_SPLIT_66 # define BOOST_PP_SEQ_SPLIT_68(x) (x) BOOST_PP_SEQ_SPLIT_67 # define BOOST_PP_SEQ_SPLIT_69(x) (x) BOOST_PP_SEQ_SPLIT_68 # define BOOST_PP_SEQ_SPLIT_70(x) (x) BOOST_PP_SEQ_SPLIT_69 # define BOOST_PP_SEQ_SPLIT_71(x) (x) BOOST_PP_SEQ_SPLIT_70 # define BOOST_PP_SEQ_SPLIT_72(x) (x) BOOST_PP_SEQ_SPLIT_71 # define BOOST_PP_SEQ_SPLIT_73(x) (x) BOOST_PP_SEQ_SPLIT_72 # define BOOST_PP_SEQ_SPLIT_74(x) (x) BOOST_PP_SEQ_SPLIT_73 # define BOOST_PP_SEQ_SPLIT_75(x) (x) BOOST_PP_SEQ_SPLIT_74 # define BOOST_PP_SEQ_SPLIT_76(x) (x) BOOST_PP_SEQ_SPLIT_75 # define BOOST_PP_SEQ_SPLIT_77(x) (x) BOOST_PP_SEQ_SPLIT_76 # define BOOST_PP_SEQ_SPLIT_78(x) (x) BOOST_PP_SEQ_SPLIT_77 # define BOOST_PP_SEQ_SPLIT_79(x) (x) BOOST_PP_SEQ_SPLIT_78 # define BOOST_PP_SEQ_SPLIT_80(x) (x) BOOST_PP_SEQ_SPLIT_79 # define BOOST_PP_SEQ_SPLIT_81(x) (x) BOOST_PP_SEQ_SPLIT_80 # define BOOST_PP_SEQ_SPLIT_82(x) (x) BOOST_PP_SEQ_SPLIT_81 # define BOOST_PP_SEQ_SPLIT_83(x) (x) BOOST_PP_SEQ_SPLIT_82 # define BOOST_PP_SEQ_SPLIT_84(x) (x) BOOST_PP_SEQ_SPLIT_83 # define BOOST_PP_SEQ_SPLIT_85(x) (x) BOOST_PP_SEQ_SPLIT_84 # define BOOST_PP_SEQ_SPLIT_86(x) (x) BOOST_PP_SEQ_SPLIT_85 # define BOOST_PP_SEQ_SPLIT_87(x) (x) BOOST_PP_SEQ_SPLIT_86 # define BOOST_PP_SEQ_SPLIT_88(x) (x) BOOST_PP_SEQ_SPLIT_87 # define BOOST_PP_SEQ_SPLIT_89(x) (x) BOOST_PP_SEQ_SPLIT_88 # define BOOST_PP_SEQ_SPLIT_90(x) (x) BOOST_PP_SEQ_SPLIT_89 # define BOOST_PP_SEQ_SPLIT_91(x) (x) BOOST_PP_SEQ_SPLIT_90 # define BOOST_PP_SEQ_SPLIT_92(x) (x) BOOST_PP_SEQ_SPLIT_91 # define BOOST_PP_SEQ_SPLIT_93(x) (x) BOOST_PP_SEQ_SPLIT_92 # define BOOST_PP_SEQ_SPLIT_94(x) (x) BOOST_PP_SEQ_SPLIT_93 # define BOOST_PP_SEQ_SPLIT_95(x) (x) BOOST_PP_SEQ_SPLIT_94 # define BOOST_PP_SEQ_SPLIT_96(x) (x) BOOST_PP_SEQ_SPLIT_95 # define BOOST_PP_SEQ_SPLIT_97(x) (x) BOOST_PP_SEQ_SPLIT_96 # define BOOST_PP_SEQ_SPLIT_98(x) (x) BOOST_PP_SEQ_SPLIT_97 # define BOOST_PP_SEQ_SPLIT_99(x) (x) BOOST_PP_SEQ_SPLIT_98 # define BOOST_PP_SEQ_SPLIT_100(x) (x) BOOST_PP_SEQ_SPLIT_99 # define BOOST_PP_SEQ_SPLIT_101(x) (x) BOOST_PP_SEQ_SPLIT_100 # define BOOST_PP_SEQ_SPLIT_102(x) (x) BOOST_PP_SEQ_SPLIT_101 # define BOOST_PP_SEQ_SPLIT_103(x) (x) BOOST_PP_SEQ_SPLIT_102 # define BOOST_PP_SEQ_SPLIT_104(x) (x) BOOST_PP_SEQ_SPLIT_103 # define BOOST_PP_SEQ_SPLIT_105(x) (x) BOOST_PP_SEQ_SPLIT_104 # define BOOST_PP_SEQ_SPLIT_106(x) (x) BOOST_PP_SEQ_SPLIT_105 # define BOOST_PP_SEQ_SPLIT_107(x) (x) BOOST_PP_SEQ_SPLIT_106 # define BOOST_PP_SEQ_SPLIT_108(x) (x) BOOST_PP_SEQ_SPLIT_107 # define BOOST_PP_SEQ_SPLIT_109(x) (x) BOOST_PP_SEQ_SPLIT_108 # define BOOST_PP_SEQ_SPLIT_110(x) (x) BOOST_PP_SEQ_SPLIT_109 # define BOOST_PP_SEQ_SPLIT_111(x) (x) BOOST_PP_SEQ_SPLIT_110 # define BOOST_PP_SEQ_SPLIT_112(x) (x) BOOST_PP_SEQ_SPLIT_111 # define BOOST_PP_SEQ_SPLIT_113(x) (x) BOOST_PP_SEQ_SPLIT_112 # define BOOST_PP_SEQ_SPLIT_114(x) (x) BOOST_PP_SEQ_SPLIT_113 # define BOOST_PP_SEQ_SPLIT_115(x) (x) BOOST_PP_SEQ_SPLIT_114 # define BOOST_PP_SEQ_SPLIT_116(x) (x) BOOST_PP_SEQ_SPLIT_115 # define BOOST_PP_SEQ_SPLIT_117(x) (x) BOOST_PP_SEQ_SPLIT_116 # define BOOST_PP_SEQ_SPLIT_118(x) (x) BOOST_PP_SEQ_SPLIT_117 # define BOOST_PP_SEQ_SPLIT_119(x) (x) BOOST_PP_SEQ_SPLIT_118 # define BOOST_PP_SEQ_SPLIT_120(x) (x) BOOST_PP_SEQ_SPLIT_119 # define BOOST_PP_SEQ_SPLIT_121(x) (x) BOOST_PP_SEQ_SPLIT_120 # define BOOST_PP_SEQ_SPLIT_122(x) (x) BOOST_PP_SEQ_SPLIT_121 # define BOOST_PP_SEQ_SPLIT_123(x) (x) BOOST_PP_SEQ_SPLIT_122 # define BOOST_PP_SEQ_SPLIT_124(x) (x) BOOST_PP_SEQ_SPLIT_123 # define BOOST_PP_SEQ_SPLIT_125(x) (x) BOOST_PP_SEQ_SPLIT_124 # define BOOST_PP_SEQ_SPLIT_126(x) (x) BOOST_PP_SEQ_SPLIT_125 # define BOOST_PP_SEQ_SPLIT_127(x) (x) BOOST_PP_SEQ_SPLIT_126 # define BOOST_PP_SEQ_SPLIT_128(x) (x) BOOST_PP_SEQ_SPLIT_127 # define BOOST_PP_SEQ_SPLIT_129(x) (x) BOOST_PP_SEQ_SPLIT_128 # define BOOST_PP_SEQ_SPLIT_130(x) (x) BOOST_PP_SEQ_SPLIT_129 # define BOOST_PP_SEQ_SPLIT_131(x) (x) BOOST_PP_SEQ_SPLIT_130 # define BOOST_PP_SEQ_SPLIT_132(x) (x) BOOST_PP_SEQ_SPLIT_131 # define BOOST_PP_SEQ_SPLIT_133(x) (x) BOOST_PP_SEQ_SPLIT_132 # define BOOST_PP_SEQ_SPLIT_134(x) (x) BOOST_PP_SEQ_SPLIT_133 # define BOOST_PP_SEQ_SPLIT_135(x) (x) BOOST_PP_SEQ_SPLIT_134 # define BOOST_PP_SEQ_SPLIT_136(x) (x) BOOST_PP_SEQ_SPLIT_135 # define BOOST_PP_SEQ_SPLIT_137(x) (x) BOOST_PP_SEQ_SPLIT_136 # define BOOST_PP_SEQ_SPLIT_138(x) (x) BOOST_PP_SEQ_SPLIT_137 # define BOOST_PP_SEQ_SPLIT_139(x) (x) BOOST_PP_SEQ_SPLIT_138 # define BOOST_PP_SEQ_SPLIT_140(x) (x) BOOST_PP_SEQ_SPLIT_139 # define BOOST_PP_SEQ_SPLIT_141(x) (x) BOOST_PP_SEQ_SPLIT_140 # define BOOST_PP_SEQ_SPLIT_142(x) (x) BOOST_PP_SEQ_SPLIT_141 # define BOOST_PP_SEQ_SPLIT_143(x) (x) BOOST_PP_SEQ_SPLIT_142 # define BOOST_PP_SEQ_SPLIT_144(x) (x) BOOST_PP_SEQ_SPLIT_143 # define BOOST_PP_SEQ_SPLIT_145(x) (x) BOOST_PP_SEQ_SPLIT_144 # define BOOST_PP_SEQ_SPLIT_146(x) (x) BOOST_PP_SEQ_SPLIT_145 # define BOOST_PP_SEQ_SPLIT_147(x) (x) BOOST_PP_SEQ_SPLIT_146 # define BOOST_PP_SEQ_SPLIT_148(x) (x) BOOST_PP_SEQ_SPLIT_147 # define BOOST_PP_SEQ_SPLIT_149(x) (x) BOOST_PP_SEQ_SPLIT_148 # define BOOST_PP_SEQ_SPLIT_150(x) (x) BOOST_PP_SEQ_SPLIT_149 # define BOOST_PP_SEQ_SPLIT_151(x) (x) BOOST_PP_SEQ_SPLIT_150 # define BOOST_PP_SEQ_SPLIT_152(x) (x) BOOST_PP_SEQ_SPLIT_151 # define BOOST_PP_SEQ_SPLIT_153(x) (x) BOOST_PP_SEQ_SPLIT_152 # define BOOST_PP_SEQ_SPLIT_154(x) (x) BOOST_PP_SEQ_SPLIT_153 # define BOOST_PP_SEQ_SPLIT_155(x) (x) BOOST_PP_SEQ_SPLIT_154 # define BOOST_PP_SEQ_SPLIT_156(x) (x) BOOST_PP_SEQ_SPLIT_155 # define BOOST_PP_SEQ_SPLIT_157(x) (x) BOOST_PP_SEQ_SPLIT_156 # define BOOST_PP_SEQ_SPLIT_158(x) (x) BOOST_PP_SEQ_SPLIT_157 # define BOOST_PP_SEQ_SPLIT_159(x) (x) BOOST_PP_SEQ_SPLIT_158 # define BOOST_PP_SEQ_SPLIT_160(x) (x) BOOST_PP_SEQ_SPLIT_159 # define BOOST_PP_SEQ_SPLIT_161(x) (x) BOOST_PP_SEQ_SPLIT_160 # define BOOST_PP_SEQ_SPLIT_162(x) (x) BOOST_PP_SEQ_SPLIT_161 # define BOOST_PP_SEQ_SPLIT_163(x) (x) BOOST_PP_SEQ_SPLIT_162 # define BOOST_PP_SEQ_SPLIT_164(x) (x) BOOST_PP_SEQ_SPLIT_163 # define BOOST_PP_SEQ_SPLIT_165(x) (x) BOOST_PP_SEQ_SPLIT_164 # define BOOST_PP_SEQ_SPLIT_166(x) (x) BOOST_PP_SEQ_SPLIT_165 # define BOOST_PP_SEQ_SPLIT_167(x) (x) BOOST_PP_SEQ_SPLIT_166 # define BOOST_PP_SEQ_SPLIT_168(x) (x) BOOST_PP_SEQ_SPLIT_167 # define BOOST_PP_SEQ_SPLIT_169(x) (x) BOOST_PP_SEQ_SPLIT_168 # define BOOST_PP_SEQ_SPLIT_170(x) (x) BOOST_PP_SEQ_SPLIT_169 # define BOOST_PP_SEQ_SPLIT_171(x) (x) BOOST_PP_SEQ_SPLIT_170 # define BOOST_PP_SEQ_SPLIT_172(x) (x) BOOST_PP_SEQ_SPLIT_171 # define BOOST_PP_SEQ_SPLIT_173(x) (x) BOOST_PP_SEQ_SPLIT_172 # define BOOST_PP_SEQ_SPLIT_174(x) (x) BOOST_PP_SEQ_SPLIT_173 # define BOOST_PP_SEQ_SPLIT_175(x) (x) BOOST_PP_SEQ_SPLIT_174 # define BOOST_PP_SEQ_SPLIT_176(x) (x) BOOST_PP_SEQ_SPLIT_175 # define BOOST_PP_SEQ_SPLIT_177(x) (x) BOOST_PP_SEQ_SPLIT_176 # define BOOST_PP_SEQ_SPLIT_178(x) (x) BOOST_PP_SEQ_SPLIT_177 # define BOOST_PP_SEQ_SPLIT_179(x) (x) BOOST_PP_SEQ_SPLIT_178 # define BOOST_PP_SEQ_SPLIT_180(x) (x) BOOST_PP_SEQ_SPLIT_179 # define BOOST_PP_SEQ_SPLIT_181(x) (x) BOOST_PP_SEQ_SPLIT_180 # define BOOST_PP_SEQ_SPLIT_182(x) (x) BOOST_PP_SEQ_SPLIT_181 # define BOOST_PP_SEQ_SPLIT_183(x) (x) BOOST_PP_SEQ_SPLIT_182 # define BOOST_PP_SEQ_SPLIT_184(x) (x) BOOST_PP_SEQ_SPLIT_183 # define BOOST_PP_SEQ_SPLIT_185(x) (x) BOOST_PP_SEQ_SPLIT_184 # define BOOST_PP_SEQ_SPLIT_186(x) (x) BOOST_PP_SEQ_SPLIT_185 # define BOOST_PP_SEQ_SPLIT_187(x) (x) BOOST_PP_SEQ_SPLIT_186 # define BOOST_PP_SEQ_SPLIT_188(x) (x) BOOST_PP_SEQ_SPLIT_187 # define BOOST_PP_SEQ_SPLIT_189(x) (x) BOOST_PP_SEQ_SPLIT_188 # define BOOST_PP_SEQ_SPLIT_190(x) (x) BOOST_PP_SEQ_SPLIT_189 # define BOOST_PP_SEQ_SPLIT_191(x) (x) BOOST_PP_SEQ_SPLIT_190 # define BOOST_PP_SEQ_SPLIT_192(x) (x) BOOST_PP_SEQ_SPLIT_191 # define BOOST_PP_SEQ_SPLIT_193(x) (x) BOOST_PP_SEQ_SPLIT_192 # define BOOST_PP_SEQ_SPLIT_194(x) (x) BOOST_PP_SEQ_SPLIT_193 # define BOOST_PP_SEQ_SPLIT_195(x) (x) BOOST_PP_SEQ_SPLIT_194 # define BOOST_PP_SEQ_SPLIT_196(x) (x) BOOST_PP_SEQ_SPLIT_195 # define BOOST_PP_SEQ_SPLIT_197(x) (x) BOOST_PP_SEQ_SPLIT_196 # define BOOST_PP_SEQ_SPLIT_198(x) (x) BOOST_PP_SEQ_SPLIT_197 # define BOOST_PP_SEQ_SPLIT_199(x) (x) BOOST_PP_SEQ_SPLIT_198 # define BOOST_PP_SEQ_SPLIT_200(x) (x) BOOST_PP_SEQ_SPLIT_199 # define BOOST_PP_SEQ_SPLIT_201(x) (x) BOOST_PP_SEQ_SPLIT_200 # define BOOST_PP_SEQ_SPLIT_202(x) (x) BOOST_PP_SEQ_SPLIT_201 # define BOOST_PP_SEQ_SPLIT_203(x) (x) BOOST_PP_SEQ_SPLIT_202 # define BOOST_PP_SEQ_SPLIT_204(x) (x) BOOST_PP_SEQ_SPLIT_203 # define BOOST_PP_SEQ_SPLIT_205(x) (x) BOOST_PP_SEQ_SPLIT_204 # define BOOST_PP_SEQ_SPLIT_206(x) (x) BOOST_PP_SEQ_SPLIT_205 # define BOOST_PP_SEQ_SPLIT_207(x) (x) BOOST_PP_SEQ_SPLIT_206 # define BOOST_PP_SEQ_SPLIT_208(x) (x) BOOST_PP_SEQ_SPLIT_207 # define BOOST_PP_SEQ_SPLIT_209(x) (x) BOOST_PP_SEQ_SPLIT_208 # define BOOST_PP_SEQ_SPLIT_210(x) (x) BOOST_PP_SEQ_SPLIT_209 # define BOOST_PP_SEQ_SPLIT_211(x) (x) BOOST_PP_SEQ_SPLIT_210 # define BOOST_PP_SEQ_SPLIT_212(x) (x) BOOST_PP_SEQ_SPLIT_211 # define BOOST_PP_SEQ_SPLIT_213(x) (x) BOOST_PP_SEQ_SPLIT_212 # define BOOST_PP_SEQ_SPLIT_214(x) (x) BOOST_PP_SEQ_SPLIT_213 # define BOOST_PP_SEQ_SPLIT_215(x) (x) BOOST_PP_SEQ_SPLIT_214 # define BOOST_PP_SEQ_SPLIT_216(x) (x) BOOST_PP_SEQ_SPLIT_215 # define BOOST_PP_SEQ_SPLIT_217(x) (x) BOOST_PP_SEQ_SPLIT_216 # define BOOST_PP_SEQ_SPLIT_218(x) (x) BOOST_PP_SEQ_SPLIT_217 # define BOOST_PP_SEQ_SPLIT_219(x) (x) BOOST_PP_SEQ_SPLIT_218 # define BOOST_PP_SEQ_SPLIT_220(x) (x) BOOST_PP_SEQ_SPLIT_219 # define BOOST_PP_SEQ_SPLIT_221(x) (x) BOOST_PP_SEQ_SPLIT_220 # define BOOST_PP_SEQ_SPLIT_222(x) (x) BOOST_PP_SEQ_SPLIT_221 # define BOOST_PP_SEQ_SPLIT_223(x) (x) BOOST_PP_SEQ_SPLIT_222 # define BOOST_PP_SEQ_SPLIT_224(x) (x) BOOST_PP_SEQ_SPLIT_223 # define BOOST_PP_SEQ_SPLIT_225(x) (x) BOOST_PP_SEQ_SPLIT_224 # define BOOST_PP_SEQ_SPLIT_226(x) (x) BOOST_PP_SEQ_SPLIT_225 # define BOOST_PP_SEQ_SPLIT_227(x) (x) BOOST_PP_SEQ_SPLIT_226 # define BOOST_PP_SEQ_SPLIT_228(x) (x) BOOST_PP_SEQ_SPLIT_227 # define BOOST_PP_SEQ_SPLIT_229(x) (x) BOOST_PP_SEQ_SPLIT_228 # define BOOST_PP_SEQ_SPLIT_230(x) (x) BOOST_PP_SEQ_SPLIT_229 # define BOOST_PP_SEQ_SPLIT_231(x) (x) BOOST_PP_SEQ_SPLIT_230 # define BOOST_PP_SEQ_SPLIT_232(x) (x) BOOST_PP_SEQ_SPLIT_231 # define BOOST_PP_SEQ_SPLIT_233(x) (x) BOOST_PP_SEQ_SPLIT_232 # define BOOST_PP_SEQ_SPLIT_234(x) (x) BOOST_PP_SEQ_SPLIT_233 # define BOOST_PP_SEQ_SPLIT_235(x) (x) BOOST_PP_SEQ_SPLIT_234 # define BOOST_PP_SEQ_SPLIT_236(x) (x) BOOST_PP_SEQ_SPLIT_235 # define BOOST_PP_SEQ_SPLIT_237(x) (x) BOOST_PP_SEQ_SPLIT_236 # define BOOST_PP_SEQ_SPLIT_238(x) (x) BOOST_PP_SEQ_SPLIT_237 # define BOOST_PP_SEQ_SPLIT_239(x) (x) BOOST_PP_SEQ_SPLIT_238 # define BOOST_PP_SEQ_SPLIT_240(x) (x) BOOST_PP_SEQ_SPLIT_239 # define BOOST_PP_SEQ_SPLIT_241(x) (x) BOOST_PP_SEQ_SPLIT_240 # define BOOST_PP_SEQ_SPLIT_242(x) (x) BOOST_PP_SEQ_SPLIT_241 # define BOOST_PP_SEQ_SPLIT_243(x) (x) BOOST_PP_SEQ_SPLIT_242 # define BOOST_PP_SEQ_SPLIT_244(x) (x) BOOST_PP_SEQ_SPLIT_243 # define BOOST_PP_SEQ_SPLIT_245(x) (x) BOOST_PP_SEQ_SPLIT_244 # define BOOST_PP_SEQ_SPLIT_246(x) (x) BOOST_PP_SEQ_SPLIT_245 # define BOOST_PP_SEQ_SPLIT_247(x) (x) BOOST_PP_SEQ_SPLIT_246 # define BOOST_PP_SEQ_SPLIT_248(x) (x) BOOST_PP_SEQ_SPLIT_247 # define BOOST_PP_SEQ_SPLIT_249(x) (x) BOOST_PP_SEQ_SPLIT_248 # define BOOST_PP_SEQ_SPLIT_250(x) (x) BOOST_PP_SEQ_SPLIT_249 # define BOOST_PP_SEQ_SPLIT_251(x) (x) BOOST_PP_SEQ_SPLIT_250 # define BOOST_PP_SEQ_SPLIT_252(x) (x) BOOST_PP_SEQ_SPLIT_251 # define BOOST_PP_SEQ_SPLIT_253(x) (x) BOOST_PP_SEQ_SPLIT_252 # define BOOST_PP_SEQ_SPLIT_254(x) (x) BOOST_PP_SEQ_SPLIT_253 # define BOOST_PP_SEQ_SPLIT_255(x) (x) BOOST_PP_SEQ_SPLIT_254 # define BOOST_PP_SEQ_SPLIT_256(x) (x) BOOST_PP_SEQ_SPLIT_255 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/elem.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_ELEM_HPP # define BOOST_PREPROCESSOR_SEQ_ELEM_HPP # # include # include # include # # /* BOOST_PP_SEQ_ELEM */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_ELEM(i, seq) BOOST_PP_SEQ_ELEM_I(i, seq) # else # define BOOST_PP_SEQ_ELEM(i, seq) BOOST_PP_SEQ_ELEM_I((i, seq)) # endif # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_SEQ_ELEM_I(i, seq) BOOST_PP_SEQ_ELEM_II((BOOST_PP_SEQ_ELEM_ ## i seq)) # define BOOST_PP_SEQ_ELEM_II(res) BOOST_PP_SEQ_ELEM_IV(BOOST_PP_SEQ_ELEM_III res) # define BOOST_PP_SEQ_ELEM_III(x, _) x BOOST_PP_EMPTY() # define BOOST_PP_SEQ_ELEM_IV(x) x # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_ELEM_I(par) BOOST_PP_SEQ_ELEM_II ## par # define BOOST_PP_SEQ_ELEM_II(i, seq) BOOST_PP_SEQ_ELEM_III(BOOST_PP_SEQ_ELEM_ ## i ## seq) # define BOOST_PP_SEQ_ELEM_III(im) BOOST_PP_SEQ_ELEM_IV(im) # define BOOST_PP_SEQ_ELEM_IV(x, _) x # else # if defined(__IBMC__) || defined(__IBMCPP__) # define BOOST_PP_SEQ_ELEM_I(i, seq) BOOST_PP_SEQ_ELEM_II(BOOST_PP_CAT(BOOST_PP_SEQ_ELEM_ ## i, seq)) # else # define BOOST_PP_SEQ_ELEM_I(i, seq) BOOST_PP_SEQ_ELEM_II(BOOST_PP_SEQ_ELEM_ ## i seq) # endif # define BOOST_PP_SEQ_ELEM_II(im) BOOST_PP_SEQ_ELEM_III(im) # define BOOST_PP_SEQ_ELEM_III(x, _) x # endif # # define BOOST_PP_SEQ_ELEM_0(x) x, BOOST_PP_NIL # define BOOST_PP_SEQ_ELEM_1(_) BOOST_PP_SEQ_ELEM_0 # define BOOST_PP_SEQ_ELEM_2(_) BOOST_PP_SEQ_ELEM_1 # define BOOST_PP_SEQ_ELEM_3(_) BOOST_PP_SEQ_ELEM_2 # define BOOST_PP_SEQ_ELEM_4(_) BOOST_PP_SEQ_ELEM_3 # define BOOST_PP_SEQ_ELEM_5(_) BOOST_PP_SEQ_ELEM_4 # define BOOST_PP_SEQ_ELEM_6(_) BOOST_PP_SEQ_ELEM_5 # define BOOST_PP_SEQ_ELEM_7(_) BOOST_PP_SEQ_ELEM_6 # define BOOST_PP_SEQ_ELEM_8(_) BOOST_PP_SEQ_ELEM_7 # define BOOST_PP_SEQ_ELEM_9(_) BOOST_PP_SEQ_ELEM_8 # define BOOST_PP_SEQ_ELEM_10(_) BOOST_PP_SEQ_ELEM_9 # define BOOST_PP_SEQ_ELEM_11(_) BOOST_PP_SEQ_ELEM_10 # define BOOST_PP_SEQ_ELEM_12(_) BOOST_PP_SEQ_ELEM_11 # define BOOST_PP_SEQ_ELEM_13(_) BOOST_PP_SEQ_ELEM_12 # define BOOST_PP_SEQ_ELEM_14(_) BOOST_PP_SEQ_ELEM_13 # define BOOST_PP_SEQ_ELEM_15(_) BOOST_PP_SEQ_ELEM_14 # define BOOST_PP_SEQ_ELEM_16(_) BOOST_PP_SEQ_ELEM_15 # define BOOST_PP_SEQ_ELEM_17(_) BOOST_PP_SEQ_ELEM_16 # define BOOST_PP_SEQ_ELEM_18(_) BOOST_PP_SEQ_ELEM_17 # define BOOST_PP_SEQ_ELEM_19(_) BOOST_PP_SEQ_ELEM_18 # define BOOST_PP_SEQ_ELEM_20(_) BOOST_PP_SEQ_ELEM_19 # define BOOST_PP_SEQ_ELEM_21(_) BOOST_PP_SEQ_ELEM_20 # define BOOST_PP_SEQ_ELEM_22(_) BOOST_PP_SEQ_ELEM_21 # define BOOST_PP_SEQ_ELEM_23(_) BOOST_PP_SEQ_ELEM_22 # define BOOST_PP_SEQ_ELEM_24(_) BOOST_PP_SEQ_ELEM_23 # define BOOST_PP_SEQ_ELEM_25(_) BOOST_PP_SEQ_ELEM_24 # define BOOST_PP_SEQ_ELEM_26(_) BOOST_PP_SEQ_ELEM_25 # define BOOST_PP_SEQ_ELEM_27(_) BOOST_PP_SEQ_ELEM_26 # define BOOST_PP_SEQ_ELEM_28(_) BOOST_PP_SEQ_ELEM_27 # define BOOST_PP_SEQ_ELEM_29(_) BOOST_PP_SEQ_ELEM_28 # define BOOST_PP_SEQ_ELEM_30(_) BOOST_PP_SEQ_ELEM_29 # define BOOST_PP_SEQ_ELEM_31(_) BOOST_PP_SEQ_ELEM_30 # define BOOST_PP_SEQ_ELEM_32(_) BOOST_PP_SEQ_ELEM_31 # define BOOST_PP_SEQ_ELEM_33(_) BOOST_PP_SEQ_ELEM_32 # define BOOST_PP_SEQ_ELEM_34(_) BOOST_PP_SEQ_ELEM_33 # define BOOST_PP_SEQ_ELEM_35(_) BOOST_PP_SEQ_ELEM_34 # define BOOST_PP_SEQ_ELEM_36(_) BOOST_PP_SEQ_ELEM_35 # define BOOST_PP_SEQ_ELEM_37(_) BOOST_PP_SEQ_ELEM_36 # define BOOST_PP_SEQ_ELEM_38(_) BOOST_PP_SEQ_ELEM_37 # define BOOST_PP_SEQ_ELEM_39(_) BOOST_PP_SEQ_ELEM_38 # define BOOST_PP_SEQ_ELEM_40(_) BOOST_PP_SEQ_ELEM_39 # define BOOST_PP_SEQ_ELEM_41(_) BOOST_PP_SEQ_ELEM_40 # define BOOST_PP_SEQ_ELEM_42(_) BOOST_PP_SEQ_ELEM_41 # define BOOST_PP_SEQ_ELEM_43(_) BOOST_PP_SEQ_ELEM_42 # define BOOST_PP_SEQ_ELEM_44(_) BOOST_PP_SEQ_ELEM_43 # define BOOST_PP_SEQ_ELEM_45(_) BOOST_PP_SEQ_ELEM_44 # define BOOST_PP_SEQ_ELEM_46(_) BOOST_PP_SEQ_ELEM_45 # define BOOST_PP_SEQ_ELEM_47(_) BOOST_PP_SEQ_ELEM_46 # define BOOST_PP_SEQ_ELEM_48(_) BOOST_PP_SEQ_ELEM_47 # define BOOST_PP_SEQ_ELEM_49(_) BOOST_PP_SEQ_ELEM_48 # define BOOST_PP_SEQ_ELEM_50(_) BOOST_PP_SEQ_ELEM_49 # define BOOST_PP_SEQ_ELEM_51(_) BOOST_PP_SEQ_ELEM_50 # define BOOST_PP_SEQ_ELEM_52(_) BOOST_PP_SEQ_ELEM_51 # define BOOST_PP_SEQ_ELEM_53(_) BOOST_PP_SEQ_ELEM_52 # define BOOST_PP_SEQ_ELEM_54(_) BOOST_PP_SEQ_ELEM_53 # define BOOST_PP_SEQ_ELEM_55(_) BOOST_PP_SEQ_ELEM_54 # define BOOST_PP_SEQ_ELEM_56(_) BOOST_PP_SEQ_ELEM_55 # define BOOST_PP_SEQ_ELEM_57(_) BOOST_PP_SEQ_ELEM_56 # define BOOST_PP_SEQ_ELEM_58(_) BOOST_PP_SEQ_ELEM_57 # define BOOST_PP_SEQ_ELEM_59(_) BOOST_PP_SEQ_ELEM_58 # define BOOST_PP_SEQ_ELEM_60(_) BOOST_PP_SEQ_ELEM_59 # define BOOST_PP_SEQ_ELEM_61(_) BOOST_PP_SEQ_ELEM_60 # define BOOST_PP_SEQ_ELEM_62(_) BOOST_PP_SEQ_ELEM_61 # define BOOST_PP_SEQ_ELEM_63(_) BOOST_PP_SEQ_ELEM_62 # define BOOST_PP_SEQ_ELEM_64(_) BOOST_PP_SEQ_ELEM_63 # define BOOST_PP_SEQ_ELEM_65(_) BOOST_PP_SEQ_ELEM_64 # define BOOST_PP_SEQ_ELEM_66(_) BOOST_PP_SEQ_ELEM_65 # define BOOST_PP_SEQ_ELEM_67(_) BOOST_PP_SEQ_ELEM_66 # define BOOST_PP_SEQ_ELEM_68(_) BOOST_PP_SEQ_ELEM_67 # define BOOST_PP_SEQ_ELEM_69(_) BOOST_PP_SEQ_ELEM_68 # define BOOST_PP_SEQ_ELEM_70(_) BOOST_PP_SEQ_ELEM_69 # define BOOST_PP_SEQ_ELEM_71(_) BOOST_PP_SEQ_ELEM_70 # define BOOST_PP_SEQ_ELEM_72(_) BOOST_PP_SEQ_ELEM_71 # define BOOST_PP_SEQ_ELEM_73(_) BOOST_PP_SEQ_ELEM_72 # define BOOST_PP_SEQ_ELEM_74(_) BOOST_PP_SEQ_ELEM_73 # define BOOST_PP_SEQ_ELEM_75(_) BOOST_PP_SEQ_ELEM_74 # define BOOST_PP_SEQ_ELEM_76(_) BOOST_PP_SEQ_ELEM_75 # define BOOST_PP_SEQ_ELEM_77(_) BOOST_PP_SEQ_ELEM_76 # define BOOST_PP_SEQ_ELEM_78(_) BOOST_PP_SEQ_ELEM_77 # define BOOST_PP_SEQ_ELEM_79(_) BOOST_PP_SEQ_ELEM_78 # define BOOST_PP_SEQ_ELEM_80(_) BOOST_PP_SEQ_ELEM_79 # define BOOST_PP_SEQ_ELEM_81(_) BOOST_PP_SEQ_ELEM_80 # define BOOST_PP_SEQ_ELEM_82(_) BOOST_PP_SEQ_ELEM_81 # define BOOST_PP_SEQ_ELEM_83(_) BOOST_PP_SEQ_ELEM_82 # define BOOST_PP_SEQ_ELEM_84(_) BOOST_PP_SEQ_ELEM_83 # define BOOST_PP_SEQ_ELEM_85(_) BOOST_PP_SEQ_ELEM_84 # define BOOST_PP_SEQ_ELEM_86(_) BOOST_PP_SEQ_ELEM_85 # define BOOST_PP_SEQ_ELEM_87(_) BOOST_PP_SEQ_ELEM_86 # define BOOST_PP_SEQ_ELEM_88(_) BOOST_PP_SEQ_ELEM_87 # define BOOST_PP_SEQ_ELEM_89(_) BOOST_PP_SEQ_ELEM_88 # define BOOST_PP_SEQ_ELEM_90(_) BOOST_PP_SEQ_ELEM_89 # define BOOST_PP_SEQ_ELEM_91(_) BOOST_PP_SEQ_ELEM_90 # define BOOST_PP_SEQ_ELEM_92(_) BOOST_PP_SEQ_ELEM_91 # define BOOST_PP_SEQ_ELEM_93(_) BOOST_PP_SEQ_ELEM_92 # define BOOST_PP_SEQ_ELEM_94(_) BOOST_PP_SEQ_ELEM_93 # define BOOST_PP_SEQ_ELEM_95(_) BOOST_PP_SEQ_ELEM_94 # define BOOST_PP_SEQ_ELEM_96(_) BOOST_PP_SEQ_ELEM_95 # define BOOST_PP_SEQ_ELEM_97(_) BOOST_PP_SEQ_ELEM_96 # define BOOST_PP_SEQ_ELEM_98(_) BOOST_PP_SEQ_ELEM_97 # define BOOST_PP_SEQ_ELEM_99(_) BOOST_PP_SEQ_ELEM_98 # define BOOST_PP_SEQ_ELEM_100(_) BOOST_PP_SEQ_ELEM_99 # define BOOST_PP_SEQ_ELEM_101(_) BOOST_PP_SEQ_ELEM_100 # define BOOST_PP_SEQ_ELEM_102(_) BOOST_PP_SEQ_ELEM_101 # define BOOST_PP_SEQ_ELEM_103(_) BOOST_PP_SEQ_ELEM_102 # define BOOST_PP_SEQ_ELEM_104(_) BOOST_PP_SEQ_ELEM_103 # define BOOST_PP_SEQ_ELEM_105(_) BOOST_PP_SEQ_ELEM_104 # define BOOST_PP_SEQ_ELEM_106(_) BOOST_PP_SEQ_ELEM_105 # define BOOST_PP_SEQ_ELEM_107(_) BOOST_PP_SEQ_ELEM_106 # define BOOST_PP_SEQ_ELEM_108(_) BOOST_PP_SEQ_ELEM_107 # define BOOST_PP_SEQ_ELEM_109(_) BOOST_PP_SEQ_ELEM_108 # define BOOST_PP_SEQ_ELEM_110(_) BOOST_PP_SEQ_ELEM_109 # define BOOST_PP_SEQ_ELEM_111(_) BOOST_PP_SEQ_ELEM_110 # define BOOST_PP_SEQ_ELEM_112(_) BOOST_PP_SEQ_ELEM_111 # define BOOST_PP_SEQ_ELEM_113(_) BOOST_PP_SEQ_ELEM_112 # define BOOST_PP_SEQ_ELEM_114(_) BOOST_PP_SEQ_ELEM_113 # define BOOST_PP_SEQ_ELEM_115(_) BOOST_PP_SEQ_ELEM_114 # define BOOST_PP_SEQ_ELEM_116(_) BOOST_PP_SEQ_ELEM_115 # define BOOST_PP_SEQ_ELEM_117(_) BOOST_PP_SEQ_ELEM_116 # define BOOST_PP_SEQ_ELEM_118(_) BOOST_PP_SEQ_ELEM_117 # define BOOST_PP_SEQ_ELEM_119(_) BOOST_PP_SEQ_ELEM_118 # define BOOST_PP_SEQ_ELEM_120(_) BOOST_PP_SEQ_ELEM_119 # define BOOST_PP_SEQ_ELEM_121(_) BOOST_PP_SEQ_ELEM_120 # define BOOST_PP_SEQ_ELEM_122(_) BOOST_PP_SEQ_ELEM_121 # define BOOST_PP_SEQ_ELEM_123(_) BOOST_PP_SEQ_ELEM_122 # define BOOST_PP_SEQ_ELEM_124(_) BOOST_PP_SEQ_ELEM_123 # define BOOST_PP_SEQ_ELEM_125(_) BOOST_PP_SEQ_ELEM_124 # define BOOST_PP_SEQ_ELEM_126(_) BOOST_PP_SEQ_ELEM_125 # define BOOST_PP_SEQ_ELEM_127(_) BOOST_PP_SEQ_ELEM_126 # define BOOST_PP_SEQ_ELEM_128(_) BOOST_PP_SEQ_ELEM_127 # define BOOST_PP_SEQ_ELEM_129(_) BOOST_PP_SEQ_ELEM_128 # define BOOST_PP_SEQ_ELEM_130(_) BOOST_PP_SEQ_ELEM_129 # define BOOST_PP_SEQ_ELEM_131(_) BOOST_PP_SEQ_ELEM_130 # define BOOST_PP_SEQ_ELEM_132(_) BOOST_PP_SEQ_ELEM_131 # define BOOST_PP_SEQ_ELEM_133(_) BOOST_PP_SEQ_ELEM_132 # define BOOST_PP_SEQ_ELEM_134(_) BOOST_PP_SEQ_ELEM_133 # define BOOST_PP_SEQ_ELEM_135(_) BOOST_PP_SEQ_ELEM_134 # define BOOST_PP_SEQ_ELEM_136(_) BOOST_PP_SEQ_ELEM_135 # define BOOST_PP_SEQ_ELEM_137(_) BOOST_PP_SEQ_ELEM_136 # define BOOST_PP_SEQ_ELEM_138(_) BOOST_PP_SEQ_ELEM_137 # define BOOST_PP_SEQ_ELEM_139(_) BOOST_PP_SEQ_ELEM_138 # define BOOST_PP_SEQ_ELEM_140(_) BOOST_PP_SEQ_ELEM_139 # define BOOST_PP_SEQ_ELEM_141(_) BOOST_PP_SEQ_ELEM_140 # define BOOST_PP_SEQ_ELEM_142(_) BOOST_PP_SEQ_ELEM_141 # define BOOST_PP_SEQ_ELEM_143(_) BOOST_PP_SEQ_ELEM_142 # define BOOST_PP_SEQ_ELEM_144(_) BOOST_PP_SEQ_ELEM_143 # define BOOST_PP_SEQ_ELEM_145(_) BOOST_PP_SEQ_ELEM_144 # define BOOST_PP_SEQ_ELEM_146(_) BOOST_PP_SEQ_ELEM_145 # define BOOST_PP_SEQ_ELEM_147(_) BOOST_PP_SEQ_ELEM_146 # define BOOST_PP_SEQ_ELEM_148(_) BOOST_PP_SEQ_ELEM_147 # define BOOST_PP_SEQ_ELEM_149(_) BOOST_PP_SEQ_ELEM_148 # define BOOST_PP_SEQ_ELEM_150(_) BOOST_PP_SEQ_ELEM_149 # define BOOST_PP_SEQ_ELEM_151(_) BOOST_PP_SEQ_ELEM_150 # define BOOST_PP_SEQ_ELEM_152(_) BOOST_PP_SEQ_ELEM_151 # define BOOST_PP_SEQ_ELEM_153(_) BOOST_PP_SEQ_ELEM_152 # define BOOST_PP_SEQ_ELEM_154(_) BOOST_PP_SEQ_ELEM_153 # define BOOST_PP_SEQ_ELEM_155(_) BOOST_PP_SEQ_ELEM_154 # define BOOST_PP_SEQ_ELEM_156(_) BOOST_PP_SEQ_ELEM_155 # define BOOST_PP_SEQ_ELEM_157(_) BOOST_PP_SEQ_ELEM_156 # define BOOST_PP_SEQ_ELEM_158(_) BOOST_PP_SEQ_ELEM_157 # define BOOST_PP_SEQ_ELEM_159(_) BOOST_PP_SEQ_ELEM_158 # define BOOST_PP_SEQ_ELEM_160(_) BOOST_PP_SEQ_ELEM_159 # define BOOST_PP_SEQ_ELEM_161(_) BOOST_PP_SEQ_ELEM_160 # define BOOST_PP_SEQ_ELEM_162(_) BOOST_PP_SEQ_ELEM_161 # define BOOST_PP_SEQ_ELEM_163(_) BOOST_PP_SEQ_ELEM_162 # define BOOST_PP_SEQ_ELEM_164(_) BOOST_PP_SEQ_ELEM_163 # define BOOST_PP_SEQ_ELEM_165(_) BOOST_PP_SEQ_ELEM_164 # define BOOST_PP_SEQ_ELEM_166(_) BOOST_PP_SEQ_ELEM_165 # define BOOST_PP_SEQ_ELEM_167(_) BOOST_PP_SEQ_ELEM_166 # define BOOST_PP_SEQ_ELEM_168(_) BOOST_PP_SEQ_ELEM_167 # define BOOST_PP_SEQ_ELEM_169(_) BOOST_PP_SEQ_ELEM_168 # define BOOST_PP_SEQ_ELEM_170(_) BOOST_PP_SEQ_ELEM_169 # define BOOST_PP_SEQ_ELEM_171(_) BOOST_PP_SEQ_ELEM_170 # define BOOST_PP_SEQ_ELEM_172(_) BOOST_PP_SEQ_ELEM_171 # define BOOST_PP_SEQ_ELEM_173(_) BOOST_PP_SEQ_ELEM_172 # define BOOST_PP_SEQ_ELEM_174(_) BOOST_PP_SEQ_ELEM_173 # define BOOST_PP_SEQ_ELEM_175(_) BOOST_PP_SEQ_ELEM_174 # define BOOST_PP_SEQ_ELEM_176(_) BOOST_PP_SEQ_ELEM_175 # define BOOST_PP_SEQ_ELEM_177(_) BOOST_PP_SEQ_ELEM_176 # define BOOST_PP_SEQ_ELEM_178(_) BOOST_PP_SEQ_ELEM_177 # define BOOST_PP_SEQ_ELEM_179(_) BOOST_PP_SEQ_ELEM_178 # define BOOST_PP_SEQ_ELEM_180(_) BOOST_PP_SEQ_ELEM_179 # define BOOST_PP_SEQ_ELEM_181(_) BOOST_PP_SEQ_ELEM_180 # define BOOST_PP_SEQ_ELEM_182(_) BOOST_PP_SEQ_ELEM_181 # define BOOST_PP_SEQ_ELEM_183(_) BOOST_PP_SEQ_ELEM_182 # define BOOST_PP_SEQ_ELEM_184(_) BOOST_PP_SEQ_ELEM_183 # define BOOST_PP_SEQ_ELEM_185(_) BOOST_PP_SEQ_ELEM_184 # define BOOST_PP_SEQ_ELEM_186(_) BOOST_PP_SEQ_ELEM_185 # define BOOST_PP_SEQ_ELEM_187(_) BOOST_PP_SEQ_ELEM_186 # define BOOST_PP_SEQ_ELEM_188(_) BOOST_PP_SEQ_ELEM_187 # define BOOST_PP_SEQ_ELEM_189(_) BOOST_PP_SEQ_ELEM_188 # define BOOST_PP_SEQ_ELEM_190(_) BOOST_PP_SEQ_ELEM_189 # define BOOST_PP_SEQ_ELEM_191(_) BOOST_PP_SEQ_ELEM_190 # define BOOST_PP_SEQ_ELEM_192(_) BOOST_PP_SEQ_ELEM_191 # define BOOST_PP_SEQ_ELEM_193(_) BOOST_PP_SEQ_ELEM_192 # define BOOST_PP_SEQ_ELEM_194(_) BOOST_PP_SEQ_ELEM_193 # define BOOST_PP_SEQ_ELEM_195(_) BOOST_PP_SEQ_ELEM_194 # define BOOST_PP_SEQ_ELEM_196(_) BOOST_PP_SEQ_ELEM_195 # define BOOST_PP_SEQ_ELEM_197(_) BOOST_PP_SEQ_ELEM_196 # define BOOST_PP_SEQ_ELEM_198(_) BOOST_PP_SEQ_ELEM_197 # define BOOST_PP_SEQ_ELEM_199(_) BOOST_PP_SEQ_ELEM_198 # define BOOST_PP_SEQ_ELEM_200(_) BOOST_PP_SEQ_ELEM_199 # define BOOST_PP_SEQ_ELEM_201(_) BOOST_PP_SEQ_ELEM_200 # define BOOST_PP_SEQ_ELEM_202(_) BOOST_PP_SEQ_ELEM_201 # define BOOST_PP_SEQ_ELEM_203(_) BOOST_PP_SEQ_ELEM_202 # define BOOST_PP_SEQ_ELEM_204(_) BOOST_PP_SEQ_ELEM_203 # define BOOST_PP_SEQ_ELEM_205(_) BOOST_PP_SEQ_ELEM_204 # define BOOST_PP_SEQ_ELEM_206(_) BOOST_PP_SEQ_ELEM_205 # define BOOST_PP_SEQ_ELEM_207(_) BOOST_PP_SEQ_ELEM_206 # define BOOST_PP_SEQ_ELEM_208(_) BOOST_PP_SEQ_ELEM_207 # define BOOST_PP_SEQ_ELEM_209(_) BOOST_PP_SEQ_ELEM_208 # define BOOST_PP_SEQ_ELEM_210(_) BOOST_PP_SEQ_ELEM_209 # define BOOST_PP_SEQ_ELEM_211(_) BOOST_PP_SEQ_ELEM_210 # define BOOST_PP_SEQ_ELEM_212(_) BOOST_PP_SEQ_ELEM_211 # define BOOST_PP_SEQ_ELEM_213(_) BOOST_PP_SEQ_ELEM_212 # define BOOST_PP_SEQ_ELEM_214(_) BOOST_PP_SEQ_ELEM_213 # define BOOST_PP_SEQ_ELEM_215(_) BOOST_PP_SEQ_ELEM_214 # define BOOST_PP_SEQ_ELEM_216(_) BOOST_PP_SEQ_ELEM_215 # define BOOST_PP_SEQ_ELEM_217(_) BOOST_PP_SEQ_ELEM_216 # define BOOST_PP_SEQ_ELEM_218(_) BOOST_PP_SEQ_ELEM_217 # define BOOST_PP_SEQ_ELEM_219(_) BOOST_PP_SEQ_ELEM_218 # define BOOST_PP_SEQ_ELEM_220(_) BOOST_PP_SEQ_ELEM_219 # define BOOST_PP_SEQ_ELEM_221(_) BOOST_PP_SEQ_ELEM_220 # define BOOST_PP_SEQ_ELEM_222(_) BOOST_PP_SEQ_ELEM_221 # define BOOST_PP_SEQ_ELEM_223(_) BOOST_PP_SEQ_ELEM_222 # define BOOST_PP_SEQ_ELEM_224(_) BOOST_PP_SEQ_ELEM_223 # define BOOST_PP_SEQ_ELEM_225(_) BOOST_PP_SEQ_ELEM_224 # define BOOST_PP_SEQ_ELEM_226(_) BOOST_PP_SEQ_ELEM_225 # define BOOST_PP_SEQ_ELEM_227(_) BOOST_PP_SEQ_ELEM_226 # define BOOST_PP_SEQ_ELEM_228(_) BOOST_PP_SEQ_ELEM_227 # define BOOST_PP_SEQ_ELEM_229(_) BOOST_PP_SEQ_ELEM_228 # define BOOST_PP_SEQ_ELEM_230(_) BOOST_PP_SEQ_ELEM_229 # define BOOST_PP_SEQ_ELEM_231(_) BOOST_PP_SEQ_ELEM_230 # define BOOST_PP_SEQ_ELEM_232(_) BOOST_PP_SEQ_ELEM_231 # define BOOST_PP_SEQ_ELEM_233(_) BOOST_PP_SEQ_ELEM_232 # define BOOST_PP_SEQ_ELEM_234(_) BOOST_PP_SEQ_ELEM_233 # define BOOST_PP_SEQ_ELEM_235(_) BOOST_PP_SEQ_ELEM_234 # define BOOST_PP_SEQ_ELEM_236(_) BOOST_PP_SEQ_ELEM_235 # define BOOST_PP_SEQ_ELEM_237(_) BOOST_PP_SEQ_ELEM_236 # define BOOST_PP_SEQ_ELEM_238(_) BOOST_PP_SEQ_ELEM_237 # define BOOST_PP_SEQ_ELEM_239(_) BOOST_PP_SEQ_ELEM_238 # define BOOST_PP_SEQ_ELEM_240(_) BOOST_PP_SEQ_ELEM_239 # define BOOST_PP_SEQ_ELEM_241(_) BOOST_PP_SEQ_ELEM_240 # define BOOST_PP_SEQ_ELEM_242(_) BOOST_PP_SEQ_ELEM_241 # define BOOST_PP_SEQ_ELEM_243(_) BOOST_PP_SEQ_ELEM_242 # define BOOST_PP_SEQ_ELEM_244(_) BOOST_PP_SEQ_ELEM_243 # define BOOST_PP_SEQ_ELEM_245(_) BOOST_PP_SEQ_ELEM_244 # define BOOST_PP_SEQ_ELEM_246(_) BOOST_PP_SEQ_ELEM_245 # define BOOST_PP_SEQ_ELEM_247(_) BOOST_PP_SEQ_ELEM_246 # define BOOST_PP_SEQ_ELEM_248(_) BOOST_PP_SEQ_ELEM_247 # define BOOST_PP_SEQ_ELEM_249(_) BOOST_PP_SEQ_ELEM_248 # define BOOST_PP_SEQ_ELEM_250(_) BOOST_PP_SEQ_ELEM_249 # define BOOST_PP_SEQ_ELEM_251(_) BOOST_PP_SEQ_ELEM_250 # define BOOST_PP_SEQ_ELEM_252(_) BOOST_PP_SEQ_ELEM_251 # define BOOST_PP_SEQ_ELEM_253(_) BOOST_PP_SEQ_ELEM_252 # define BOOST_PP_SEQ_ELEM_254(_) BOOST_PP_SEQ_ELEM_253 # define BOOST_PP_SEQ_ELEM_255(_) BOOST_PP_SEQ_ELEM_254 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/enum.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_ENUM_HPP # define BOOST_PREPROCESSOR_SEQ_ENUM_HPP # # include # include # include # # /* BOOST_PP_SEQ_ENUM */ # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_ENUM(seq) BOOST_PP_SEQ_ENUM_I(seq) # define BOOST_PP_SEQ_ENUM_I(seq) BOOST_PP_CAT(BOOST_PP_SEQ_ENUM_, BOOST_PP_SEQ_SIZE(seq)) seq # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_ENUM(seq) BOOST_PP_SEQ_ENUM_I(BOOST_PP_SEQ_SIZE(seq), seq) # define BOOST_PP_SEQ_ENUM_I(size, seq) BOOST_PP_CAT(BOOST_PP_SEQ_ENUM_, size) seq # else # define BOOST_PP_SEQ_ENUM(seq) BOOST_PP_CAT(BOOST_PP_SEQ_ENUM_, BOOST_PP_SEQ_SIZE(seq)) seq # endif # # define BOOST_PP_SEQ_ENUM_1(x) x # define BOOST_PP_SEQ_ENUM_2(x) x, BOOST_PP_SEQ_ENUM_1 # define BOOST_PP_SEQ_ENUM_3(x) x, BOOST_PP_SEQ_ENUM_2 # define BOOST_PP_SEQ_ENUM_4(x) x, BOOST_PP_SEQ_ENUM_3 # define BOOST_PP_SEQ_ENUM_5(x) x, BOOST_PP_SEQ_ENUM_4 # define BOOST_PP_SEQ_ENUM_6(x) x, BOOST_PP_SEQ_ENUM_5 # define BOOST_PP_SEQ_ENUM_7(x) x, BOOST_PP_SEQ_ENUM_6 # define BOOST_PP_SEQ_ENUM_8(x) x, BOOST_PP_SEQ_ENUM_7 # define BOOST_PP_SEQ_ENUM_9(x) x, BOOST_PP_SEQ_ENUM_8 # define BOOST_PP_SEQ_ENUM_10(x) x, BOOST_PP_SEQ_ENUM_9 # define BOOST_PP_SEQ_ENUM_11(x) x, BOOST_PP_SEQ_ENUM_10 # define BOOST_PP_SEQ_ENUM_12(x) x, BOOST_PP_SEQ_ENUM_11 # define BOOST_PP_SEQ_ENUM_13(x) x, BOOST_PP_SEQ_ENUM_12 # define BOOST_PP_SEQ_ENUM_14(x) x, BOOST_PP_SEQ_ENUM_13 # define BOOST_PP_SEQ_ENUM_15(x) x, BOOST_PP_SEQ_ENUM_14 # define BOOST_PP_SEQ_ENUM_16(x) x, BOOST_PP_SEQ_ENUM_15 # define BOOST_PP_SEQ_ENUM_17(x) x, BOOST_PP_SEQ_ENUM_16 # define BOOST_PP_SEQ_ENUM_18(x) x, BOOST_PP_SEQ_ENUM_17 # define BOOST_PP_SEQ_ENUM_19(x) x, BOOST_PP_SEQ_ENUM_18 # define BOOST_PP_SEQ_ENUM_20(x) x, BOOST_PP_SEQ_ENUM_19 # define BOOST_PP_SEQ_ENUM_21(x) x, BOOST_PP_SEQ_ENUM_20 # define BOOST_PP_SEQ_ENUM_22(x) x, BOOST_PP_SEQ_ENUM_21 # define BOOST_PP_SEQ_ENUM_23(x) x, BOOST_PP_SEQ_ENUM_22 # define BOOST_PP_SEQ_ENUM_24(x) x, BOOST_PP_SEQ_ENUM_23 # define BOOST_PP_SEQ_ENUM_25(x) x, BOOST_PP_SEQ_ENUM_24 # define BOOST_PP_SEQ_ENUM_26(x) x, BOOST_PP_SEQ_ENUM_25 # define BOOST_PP_SEQ_ENUM_27(x) x, BOOST_PP_SEQ_ENUM_26 # define BOOST_PP_SEQ_ENUM_28(x) x, BOOST_PP_SEQ_ENUM_27 # define BOOST_PP_SEQ_ENUM_29(x) x, BOOST_PP_SEQ_ENUM_28 # define BOOST_PP_SEQ_ENUM_30(x) x, BOOST_PP_SEQ_ENUM_29 # define BOOST_PP_SEQ_ENUM_31(x) x, BOOST_PP_SEQ_ENUM_30 # define BOOST_PP_SEQ_ENUM_32(x) x, BOOST_PP_SEQ_ENUM_31 # define BOOST_PP_SEQ_ENUM_33(x) x, BOOST_PP_SEQ_ENUM_32 # define BOOST_PP_SEQ_ENUM_34(x) x, BOOST_PP_SEQ_ENUM_33 # define BOOST_PP_SEQ_ENUM_35(x) x, BOOST_PP_SEQ_ENUM_34 # define BOOST_PP_SEQ_ENUM_36(x) x, BOOST_PP_SEQ_ENUM_35 # define BOOST_PP_SEQ_ENUM_37(x) x, BOOST_PP_SEQ_ENUM_36 # define BOOST_PP_SEQ_ENUM_38(x) x, BOOST_PP_SEQ_ENUM_37 # define BOOST_PP_SEQ_ENUM_39(x) x, BOOST_PP_SEQ_ENUM_38 # define BOOST_PP_SEQ_ENUM_40(x) x, BOOST_PP_SEQ_ENUM_39 # define BOOST_PP_SEQ_ENUM_41(x) x, BOOST_PP_SEQ_ENUM_40 # define BOOST_PP_SEQ_ENUM_42(x) x, BOOST_PP_SEQ_ENUM_41 # define BOOST_PP_SEQ_ENUM_43(x) x, BOOST_PP_SEQ_ENUM_42 # define BOOST_PP_SEQ_ENUM_44(x) x, BOOST_PP_SEQ_ENUM_43 # define BOOST_PP_SEQ_ENUM_45(x) x, BOOST_PP_SEQ_ENUM_44 # define BOOST_PP_SEQ_ENUM_46(x) x, BOOST_PP_SEQ_ENUM_45 # define BOOST_PP_SEQ_ENUM_47(x) x, BOOST_PP_SEQ_ENUM_46 # define BOOST_PP_SEQ_ENUM_48(x) x, BOOST_PP_SEQ_ENUM_47 # define BOOST_PP_SEQ_ENUM_49(x) x, BOOST_PP_SEQ_ENUM_48 # define BOOST_PP_SEQ_ENUM_50(x) x, BOOST_PP_SEQ_ENUM_49 # define BOOST_PP_SEQ_ENUM_51(x) x, BOOST_PP_SEQ_ENUM_50 # define BOOST_PP_SEQ_ENUM_52(x) x, BOOST_PP_SEQ_ENUM_51 # define BOOST_PP_SEQ_ENUM_53(x) x, BOOST_PP_SEQ_ENUM_52 # define BOOST_PP_SEQ_ENUM_54(x) x, BOOST_PP_SEQ_ENUM_53 # define BOOST_PP_SEQ_ENUM_55(x) x, BOOST_PP_SEQ_ENUM_54 # define BOOST_PP_SEQ_ENUM_56(x) x, BOOST_PP_SEQ_ENUM_55 # define BOOST_PP_SEQ_ENUM_57(x) x, BOOST_PP_SEQ_ENUM_56 # define BOOST_PP_SEQ_ENUM_58(x) x, BOOST_PP_SEQ_ENUM_57 # define BOOST_PP_SEQ_ENUM_59(x) x, BOOST_PP_SEQ_ENUM_58 # define BOOST_PP_SEQ_ENUM_60(x) x, BOOST_PP_SEQ_ENUM_59 # define BOOST_PP_SEQ_ENUM_61(x) x, BOOST_PP_SEQ_ENUM_60 # define BOOST_PP_SEQ_ENUM_62(x) x, BOOST_PP_SEQ_ENUM_61 # define BOOST_PP_SEQ_ENUM_63(x) x, BOOST_PP_SEQ_ENUM_62 # define BOOST_PP_SEQ_ENUM_64(x) x, BOOST_PP_SEQ_ENUM_63 # define BOOST_PP_SEQ_ENUM_65(x) x, BOOST_PP_SEQ_ENUM_64 # define BOOST_PP_SEQ_ENUM_66(x) x, BOOST_PP_SEQ_ENUM_65 # define BOOST_PP_SEQ_ENUM_67(x) x, BOOST_PP_SEQ_ENUM_66 # define BOOST_PP_SEQ_ENUM_68(x) x, BOOST_PP_SEQ_ENUM_67 # define BOOST_PP_SEQ_ENUM_69(x) x, BOOST_PP_SEQ_ENUM_68 # define BOOST_PP_SEQ_ENUM_70(x) x, BOOST_PP_SEQ_ENUM_69 # define BOOST_PP_SEQ_ENUM_71(x) x, BOOST_PP_SEQ_ENUM_70 # define BOOST_PP_SEQ_ENUM_72(x) x, BOOST_PP_SEQ_ENUM_71 # define BOOST_PP_SEQ_ENUM_73(x) x, BOOST_PP_SEQ_ENUM_72 # define BOOST_PP_SEQ_ENUM_74(x) x, BOOST_PP_SEQ_ENUM_73 # define BOOST_PP_SEQ_ENUM_75(x) x, BOOST_PP_SEQ_ENUM_74 # define BOOST_PP_SEQ_ENUM_76(x) x, BOOST_PP_SEQ_ENUM_75 # define BOOST_PP_SEQ_ENUM_77(x) x, BOOST_PP_SEQ_ENUM_76 # define BOOST_PP_SEQ_ENUM_78(x) x, BOOST_PP_SEQ_ENUM_77 # define BOOST_PP_SEQ_ENUM_79(x) x, BOOST_PP_SEQ_ENUM_78 # define BOOST_PP_SEQ_ENUM_80(x) x, BOOST_PP_SEQ_ENUM_79 # define BOOST_PP_SEQ_ENUM_81(x) x, BOOST_PP_SEQ_ENUM_80 # define BOOST_PP_SEQ_ENUM_82(x) x, BOOST_PP_SEQ_ENUM_81 # define BOOST_PP_SEQ_ENUM_83(x) x, BOOST_PP_SEQ_ENUM_82 # define BOOST_PP_SEQ_ENUM_84(x) x, BOOST_PP_SEQ_ENUM_83 # define BOOST_PP_SEQ_ENUM_85(x) x, BOOST_PP_SEQ_ENUM_84 # define BOOST_PP_SEQ_ENUM_86(x) x, BOOST_PP_SEQ_ENUM_85 # define BOOST_PP_SEQ_ENUM_87(x) x, BOOST_PP_SEQ_ENUM_86 # define BOOST_PP_SEQ_ENUM_88(x) x, BOOST_PP_SEQ_ENUM_87 # define BOOST_PP_SEQ_ENUM_89(x) x, BOOST_PP_SEQ_ENUM_88 # define BOOST_PP_SEQ_ENUM_90(x) x, BOOST_PP_SEQ_ENUM_89 # define BOOST_PP_SEQ_ENUM_91(x) x, BOOST_PP_SEQ_ENUM_90 # define BOOST_PP_SEQ_ENUM_92(x) x, BOOST_PP_SEQ_ENUM_91 # define BOOST_PP_SEQ_ENUM_93(x) x, BOOST_PP_SEQ_ENUM_92 # define BOOST_PP_SEQ_ENUM_94(x) x, BOOST_PP_SEQ_ENUM_93 # define BOOST_PP_SEQ_ENUM_95(x) x, BOOST_PP_SEQ_ENUM_94 # define BOOST_PP_SEQ_ENUM_96(x) x, BOOST_PP_SEQ_ENUM_95 # define BOOST_PP_SEQ_ENUM_97(x) x, BOOST_PP_SEQ_ENUM_96 # define BOOST_PP_SEQ_ENUM_98(x) x, BOOST_PP_SEQ_ENUM_97 # define BOOST_PP_SEQ_ENUM_99(x) x, BOOST_PP_SEQ_ENUM_98 # define BOOST_PP_SEQ_ENUM_100(x) x, BOOST_PP_SEQ_ENUM_99 # define BOOST_PP_SEQ_ENUM_101(x) x, BOOST_PP_SEQ_ENUM_100 # define BOOST_PP_SEQ_ENUM_102(x) x, BOOST_PP_SEQ_ENUM_101 # define BOOST_PP_SEQ_ENUM_103(x) x, BOOST_PP_SEQ_ENUM_102 # define BOOST_PP_SEQ_ENUM_104(x) x, BOOST_PP_SEQ_ENUM_103 # define BOOST_PP_SEQ_ENUM_105(x) x, BOOST_PP_SEQ_ENUM_104 # define BOOST_PP_SEQ_ENUM_106(x) x, BOOST_PP_SEQ_ENUM_105 # define BOOST_PP_SEQ_ENUM_107(x) x, BOOST_PP_SEQ_ENUM_106 # define BOOST_PP_SEQ_ENUM_108(x) x, BOOST_PP_SEQ_ENUM_107 # define BOOST_PP_SEQ_ENUM_109(x) x, BOOST_PP_SEQ_ENUM_108 # define BOOST_PP_SEQ_ENUM_110(x) x, BOOST_PP_SEQ_ENUM_109 # define BOOST_PP_SEQ_ENUM_111(x) x, BOOST_PP_SEQ_ENUM_110 # define BOOST_PP_SEQ_ENUM_112(x) x, BOOST_PP_SEQ_ENUM_111 # define BOOST_PP_SEQ_ENUM_113(x) x, BOOST_PP_SEQ_ENUM_112 # define BOOST_PP_SEQ_ENUM_114(x) x, BOOST_PP_SEQ_ENUM_113 # define BOOST_PP_SEQ_ENUM_115(x) x, BOOST_PP_SEQ_ENUM_114 # define BOOST_PP_SEQ_ENUM_116(x) x, BOOST_PP_SEQ_ENUM_115 # define BOOST_PP_SEQ_ENUM_117(x) x, BOOST_PP_SEQ_ENUM_116 # define BOOST_PP_SEQ_ENUM_118(x) x, BOOST_PP_SEQ_ENUM_117 # define BOOST_PP_SEQ_ENUM_119(x) x, BOOST_PP_SEQ_ENUM_118 # define BOOST_PP_SEQ_ENUM_120(x) x, BOOST_PP_SEQ_ENUM_119 # define BOOST_PP_SEQ_ENUM_121(x) x, BOOST_PP_SEQ_ENUM_120 # define BOOST_PP_SEQ_ENUM_122(x) x, BOOST_PP_SEQ_ENUM_121 # define BOOST_PP_SEQ_ENUM_123(x) x, BOOST_PP_SEQ_ENUM_122 # define BOOST_PP_SEQ_ENUM_124(x) x, BOOST_PP_SEQ_ENUM_123 # define BOOST_PP_SEQ_ENUM_125(x) x, BOOST_PP_SEQ_ENUM_124 # define BOOST_PP_SEQ_ENUM_126(x) x, BOOST_PP_SEQ_ENUM_125 # define BOOST_PP_SEQ_ENUM_127(x) x, BOOST_PP_SEQ_ENUM_126 # define BOOST_PP_SEQ_ENUM_128(x) x, BOOST_PP_SEQ_ENUM_127 # define BOOST_PP_SEQ_ENUM_129(x) x, BOOST_PP_SEQ_ENUM_128 # define BOOST_PP_SEQ_ENUM_130(x) x, BOOST_PP_SEQ_ENUM_129 # define BOOST_PP_SEQ_ENUM_131(x) x, BOOST_PP_SEQ_ENUM_130 # define BOOST_PP_SEQ_ENUM_132(x) x, BOOST_PP_SEQ_ENUM_131 # define BOOST_PP_SEQ_ENUM_133(x) x, BOOST_PP_SEQ_ENUM_132 # define BOOST_PP_SEQ_ENUM_134(x) x, BOOST_PP_SEQ_ENUM_133 # define BOOST_PP_SEQ_ENUM_135(x) x, BOOST_PP_SEQ_ENUM_134 # define BOOST_PP_SEQ_ENUM_136(x) x, BOOST_PP_SEQ_ENUM_135 # define BOOST_PP_SEQ_ENUM_137(x) x, BOOST_PP_SEQ_ENUM_136 # define BOOST_PP_SEQ_ENUM_138(x) x, BOOST_PP_SEQ_ENUM_137 # define BOOST_PP_SEQ_ENUM_139(x) x, BOOST_PP_SEQ_ENUM_138 # define BOOST_PP_SEQ_ENUM_140(x) x, BOOST_PP_SEQ_ENUM_139 # define BOOST_PP_SEQ_ENUM_141(x) x, BOOST_PP_SEQ_ENUM_140 # define BOOST_PP_SEQ_ENUM_142(x) x, BOOST_PP_SEQ_ENUM_141 # define BOOST_PP_SEQ_ENUM_143(x) x, BOOST_PP_SEQ_ENUM_142 # define BOOST_PP_SEQ_ENUM_144(x) x, BOOST_PP_SEQ_ENUM_143 # define BOOST_PP_SEQ_ENUM_145(x) x, BOOST_PP_SEQ_ENUM_144 # define BOOST_PP_SEQ_ENUM_146(x) x, BOOST_PP_SEQ_ENUM_145 # define BOOST_PP_SEQ_ENUM_147(x) x, BOOST_PP_SEQ_ENUM_146 # define BOOST_PP_SEQ_ENUM_148(x) x, BOOST_PP_SEQ_ENUM_147 # define BOOST_PP_SEQ_ENUM_149(x) x, BOOST_PP_SEQ_ENUM_148 # define BOOST_PP_SEQ_ENUM_150(x) x, BOOST_PP_SEQ_ENUM_149 # define BOOST_PP_SEQ_ENUM_151(x) x, BOOST_PP_SEQ_ENUM_150 # define BOOST_PP_SEQ_ENUM_152(x) x, BOOST_PP_SEQ_ENUM_151 # define BOOST_PP_SEQ_ENUM_153(x) x, BOOST_PP_SEQ_ENUM_152 # define BOOST_PP_SEQ_ENUM_154(x) x, BOOST_PP_SEQ_ENUM_153 # define BOOST_PP_SEQ_ENUM_155(x) x, BOOST_PP_SEQ_ENUM_154 # define BOOST_PP_SEQ_ENUM_156(x) x, BOOST_PP_SEQ_ENUM_155 # define BOOST_PP_SEQ_ENUM_157(x) x, BOOST_PP_SEQ_ENUM_156 # define BOOST_PP_SEQ_ENUM_158(x) x, BOOST_PP_SEQ_ENUM_157 # define BOOST_PP_SEQ_ENUM_159(x) x, BOOST_PP_SEQ_ENUM_158 # define BOOST_PP_SEQ_ENUM_160(x) x, BOOST_PP_SEQ_ENUM_159 # define BOOST_PP_SEQ_ENUM_161(x) x, BOOST_PP_SEQ_ENUM_160 # define BOOST_PP_SEQ_ENUM_162(x) x, BOOST_PP_SEQ_ENUM_161 # define BOOST_PP_SEQ_ENUM_163(x) x, BOOST_PP_SEQ_ENUM_162 # define BOOST_PP_SEQ_ENUM_164(x) x, BOOST_PP_SEQ_ENUM_163 # define BOOST_PP_SEQ_ENUM_165(x) x, BOOST_PP_SEQ_ENUM_164 # define BOOST_PP_SEQ_ENUM_166(x) x, BOOST_PP_SEQ_ENUM_165 # define BOOST_PP_SEQ_ENUM_167(x) x, BOOST_PP_SEQ_ENUM_166 # define BOOST_PP_SEQ_ENUM_168(x) x, BOOST_PP_SEQ_ENUM_167 # define BOOST_PP_SEQ_ENUM_169(x) x, BOOST_PP_SEQ_ENUM_168 # define BOOST_PP_SEQ_ENUM_170(x) x, BOOST_PP_SEQ_ENUM_169 # define BOOST_PP_SEQ_ENUM_171(x) x, BOOST_PP_SEQ_ENUM_170 # define BOOST_PP_SEQ_ENUM_172(x) x, BOOST_PP_SEQ_ENUM_171 # define BOOST_PP_SEQ_ENUM_173(x) x, BOOST_PP_SEQ_ENUM_172 # define BOOST_PP_SEQ_ENUM_174(x) x, BOOST_PP_SEQ_ENUM_173 # define BOOST_PP_SEQ_ENUM_175(x) x, BOOST_PP_SEQ_ENUM_174 # define BOOST_PP_SEQ_ENUM_176(x) x, BOOST_PP_SEQ_ENUM_175 # define BOOST_PP_SEQ_ENUM_177(x) x, BOOST_PP_SEQ_ENUM_176 # define BOOST_PP_SEQ_ENUM_178(x) x, BOOST_PP_SEQ_ENUM_177 # define BOOST_PP_SEQ_ENUM_179(x) x, BOOST_PP_SEQ_ENUM_178 # define BOOST_PP_SEQ_ENUM_180(x) x, BOOST_PP_SEQ_ENUM_179 # define BOOST_PP_SEQ_ENUM_181(x) x, BOOST_PP_SEQ_ENUM_180 # define BOOST_PP_SEQ_ENUM_182(x) x, BOOST_PP_SEQ_ENUM_181 # define BOOST_PP_SEQ_ENUM_183(x) x, BOOST_PP_SEQ_ENUM_182 # define BOOST_PP_SEQ_ENUM_184(x) x, BOOST_PP_SEQ_ENUM_183 # define BOOST_PP_SEQ_ENUM_185(x) x, BOOST_PP_SEQ_ENUM_184 # define BOOST_PP_SEQ_ENUM_186(x) x, BOOST_PP_SEQ_ENUM_185 # define BOOST_PP_SEQ_ENUM_187(x) x, BOOST_PP_SEQ_ENUM_186 # define BOOST_PP_SEQ_ENUM_188(x) x, BOOST_PP_SEQ_ENUM_187 # define BOOST_PP_SEQ_ENUM_189(x) x, BOOST_PP_SEQ_ENUM_188 # define BOOST_PP_SEQ_ENUM_190(x) x, BOOST_PP_SEQ_ENUM_189 # define BOOST_PP_SEQ_ENUM_191(x) x, BOOST_PP_SEQ_ENUM_190 # define BOOST_PP_SEQ_ENUM_192(x) x, BOOST_PP_SEQ_ENUM_191 # define BOOST_PP_SEQ_ENUM_193(x) x, BOOST_PP_SEQ_ENUM_192 # define BOOST_PP_SEQ_ENUM_194(x) x, BOOST_PP_SEQ_ENUM_193 # define BOOST_PP_SEQ_ENUM_195(x) x, BOOST_PP_SEQ_ENUM_194 # define BOOST_PP_SEQ_ENUM_196(x) x, BOOST_PP_SEQ_ENUM_195 # define BOOST_PP_SEQ_ENUM_197(x) x, BOOST_PP_SEQ_ENUM_196 # define BOOST_PP_SEQ_ENUM_198(x) x, BOOST_PP_SEQ_ENUM_197 # define BOOST_PP_SEQ_ENUM_199(x) x, BOOST_PP_SEQ_ENUM_198 # define BOOST_PP_SEQ_ENUM_200(x) x, BOOST_PP_SEQ_ENUM_199 # define BOOST_PP_SEQ_ENUM_201(x) x, BOOST_PP_SEQ_ENUM_200 # define BOOST_PP_SEQ_ENUM_202(x) x, BOOST_PP_SEQ_ENUM_201 # define BOOST_PP_SEQ_ENUM_203(x) x, BOOST_PP_SEQ_ENUM_202 # define BOOST_PP_SEQ_ENUM_204(x) x, BOOST_PP_SEQ_ENUM_203 # define BOOST_PP_SEQ_ENUM_205(x) x, BOOST_PP_SEQ_ENUM_204 # define BOOST_PP_SEQ_ENUM_206(x) x, BOOST_PP_SEQ_ENUM_205 # define BOOST_PP_SEQ_ENUM_207(x) x, BOOST_PP_SEQ_ENUM_206 # define BOOST_PP_SEQ_ENUM_208(x) x, BOOST_PP_SEQ_ENUM_207 # define BOOST_PP_SEQ_ENUM_209(x) x, BOOST_PP_SEQ_ENUM_208 # define BOOST_PP_SEQ_ENUM_210(x) x, BOOST_PP_SEQ_ENUM_209 # define BOOST_PP_SEQ_ENUM_211(x) x, BOOST_PP_SEQ_ENUM_210 # define BOOST_PP_SEQ_ENUM_212(x) x, BOOST_PP_SEQ_ENUM_211 # define BOOST_PP_SEQ_ENUM_213(x) x, BOOST_PP_SEQ_ENUM_212 # define BOOST_PP_SEQ_ENUM_214(x) x, BOOST_PP_SEQ_ENUM_213 # define BOOST_PP_SEQ_ENUM_215(x) x, BOOST_PP_SEQ_ENUM_214 # define BOOST_PP_SEQ_ENUM_216(x) x, BOOST_PP_SEQ_ENUM_215 # define BOOST_PP_SEQ_ENUM_217(x) x, BOOST_PP_SEQ_ENUM_216 # define BOOST_PP_SEQ_ENUM_218(x) x, BOOST_PP_SEQ_ENUM_217 # define BOOST_PP_SEQ_ENUM_219(x) x, BOOST_PP_SEQ_ENUM_218 # define BOOST_PP_SEQ_ENUM_220(x) x, BOOST_PP_SEQ_ENUM_219 # define BOOST_PP_SEQ_ENUM_221(x) x, BOOST_PP_SEQ_ENUM_220 # define BOOST_PP_SEQ_ENUM_222(x) x, BOOST_PP_SEQ_ENUM_221 # define BOOST_PP_SEQ_ENUM_223(x) x, BOOST_PP_SEQ_ENUM_222 # define BOOST_PP_SEQ_ENUM_224(x) x, BOOST_PP_SEQ_ENUM_223 # define BOOST_PP_SEQ_ENUM_225(x) x, BOOST_PP_SEQ_ENUM_224 # define BOOST_PP_SEQ_ENUM_226(x) x, BOOST_PP_SEQ_ENUM_225 # define BOOST_PP_SEQ_ENUM_227(x) x, BOOST_PP_SEQ_ENUM_226 # define BOOST_PP_SEQ_ENUM_228(x) x, BOOST_PP_SEQ_ENUM_227 # define BOOST_PP_SEQ_ENUM_229(x) x, BOOST_PP_SEQ_ENUM_228 # define BOOST_PP_SEQ_ENUM_230(x) x, BOOST_PP_SEQ_ENUM_229 # define BOOST_PP_SEQ_ENUM_231(x) x, BOOST_PP_SEQ_ENUM_230 # define BOOST_PP_SEQ_ENUM_232(x) x, BOOST_PP_SEQ_ENUM_231 # define BOOST_PP_SEQ_ENUM_233(x) x, BOOST_PP_SEQ_ENUM_232 # define BOOST_PP_SEQ_ENUM_234(x) x, BOOST_PP_SEQ_ENUM_233 # define BOOST_PP_SEQ_ENUM_235(x) x, BOOST_PP_SEQ_ENUM_234 # define BOOST_PP_SEQ_ENUM_236(x) x, BOOST_PP_SEQ_ENUM_235 # define BOOST_PP_SEQ_ENUM_237(x) x, BOOST_PP_SEQ_ENUM_236 # define BOOST_PP_SEQ_ENUM_238(x) x, BOOST_PP_SEQ_ENUM_237 # define BOOST_PP_SEQ_ENUM_239(x) x, BOOST_PP_SEQ_ENUM_238 # define BOOST_PP_SEQ_ENUM_240(x) x, BOOST_PP_SEQ_ENUM_239 # define BOOST_PP_SEQ_ENUM_241(x) x, BOOST_PP_SEQ_ENUM_240 # define BOOST_PP_SEQ_ENUM_242(x) x, BOOST_PP_SEQ_ENUM_241 # define BOOST_PP_SEQ_ENUM_243(x) x, BOOST_PP_SEQ_ENUM_242 # define BOOST_PP_SEQ_ENUM_244(x) x, BOOST_PP_SEQ_ENUM_243 # define BOOST_PP_SEQ_ENUM_245(x) x, BOOST_PP_SEQ_ENUM_244 # define BOOST_PP_SEQ_ENUM_246(x) x, BOOST_PP_SEQ_ENUM_245 # define BOOST_PP_SEQ_ENUM_247(x) x, BOOST_PP_SEQ_ENUM_246 # define BOOST_PP_SEQ_ENUM_248(x) x, BOOST_PP_SEQ_ENUM_247 # define BOOST_PP_SEQ_ENUM_249(x) x, BOOST_PP_SEQ_ENUM_248 # define BOOST_PP_SEQ_ENUM_250(x) x, BOOST_PP_SEQ_ENUM_249 # define BOOST_PP_SEQ_ENUM_251(x) x, BOOST_PP_SEQ_ENUM_250 # define BOOST_PP_SEQ_ENUM_252(x) x, BOOST_PP_SEQ_ENUM_251 # define BOOST_PP_SEQ_ENUM_253(x) x, BOOST_PP_SEQ_ENUM_252 # define BOOST_PP_SEQ_ENUM_254(x) x, BOOST_PP_SEQ_ENUM_253 # define BOOST_PP_SEQ_ENUM_255(x) x, BOOST_PP_SEQ_ENUM_254 # define BOOST_PP_SEQ_ENUM_256(x) x, BOOST_PP_SEQ_ENUM_255 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/first_n.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_FIRST_N_HPP # define BOOST_PREPROCESSOR_SEQ_FIRST_N_HPP # # include # include # include # include # include # # /* BOOST_PP_SEQ_FIRST_N */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_FIRST_N(n, seq) BOOST_PP_IF(n, BOOST_PP_TUPLE_ELEM, BOOST_PP_TUPLE_EAT_3)(2, 0, BOOST_PP_SEQ_SPLIT(n, seq (nil))) # else # define BOOST_PP_SEQ_FIRST_N(n, seq) BOOST_PP_SEQ_FIRST_N_I(n, seq) # define BOOST_PP_SEQ_FIRST_N_I(n, seq) BOOST_PP_IF(n, BOOST_PP_TUPLE_ELEM, BOOST_PP_TUPLE_EAT_3)(2, 0, BOOST_PP_SEQ_SPLIT(n, seq (nil))) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/fold_left.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_FOLD_LEFT_HPP # define BOOST_PREPROCESSOR_SEQ_FOLD_LEFT_HPP # # include # include # include # include # include # include # include # # /* BOOST_PP_SEQ_FOLD_LEFT */ # # if 0 # define BOOST_PP_SEQ_FOLD_LEFT(op, state, seq) ... # endif # # define BOOST_PP_SEQ_FOLD_LEFT BOOST_PP_CAT(BOOST_PP_SEQ_FOLD_LEFT_, BOOST_PP_AUTO_REC(BOOST_PP_SEQ_FOLD_LEFT_P, 256)) # define BOOST_PP_SEQ_FOLD_LEFT_P(n) BOOST_PP_CAT(BOOST_PP_SEQ_FOLD_LEFT_CHECK_, BOOST_PP_SEQ_FOLD_LEFT_I_ ## n(BOOST_PP_SEQ_FOLD_LEFT_O, BOOST_PP_NIL, (nil), 1)) # define BOOST_PP_SEQ_FOLD_LEFT_O(s, st, _) st # # define BOOST_PP_SEQ_FOLD_LEFT_257(op, st, ss) BOOST_PP_ERROR(0x0005) # define BOOST_PP_SEQ_FOLD_LEFT_I_257(op, st, ss, sz) BOOST_PP_ERROR(0x0005) # # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_NIL 1 # # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_1(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_2(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_3(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_4(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_5(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_6(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_7(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_8(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_9(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_10(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_11(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_12(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_13(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_14(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_15(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_16(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_17(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_18(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_19(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_20(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_21(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_22(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_23(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_24(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_25(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_26(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_27(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_28(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_29(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_30(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_31(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_32(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_33(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_34(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_35(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_36(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_37(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_38(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_39(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_40(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_41(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_42(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_43(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_44(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_45(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_46(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_47(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_48(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_49(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_50(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_51(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_52(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_53(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_54(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_55(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_56(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_57(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_58(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_59(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_60(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_61(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_62(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_63(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_64(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_65(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_66(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_67(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_68(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_69(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_70(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_71(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_72(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_73(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_74(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_75(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_76(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_77(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_78(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_79(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_80(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_81(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_82(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_83(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_84(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_85(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_86(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_87(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_88(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_89(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_90(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_91(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_92(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_93(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_94(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_95(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_96(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_97(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_98(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_99(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_100(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_101(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_102(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_103(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_104(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_105(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_106(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_107(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_108(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_109(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_110(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_111(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_112(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_113(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_114(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_115(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_116(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_117(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_118(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_119(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_120(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_121(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_122(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_123(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_124(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_125(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_126(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_127(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_128(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_129(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_130(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_131(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_132(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_133(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_134(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_135(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_136(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_137(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_138(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_139(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_140(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_141(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_142(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_143(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_144(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_145(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_146(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_147(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_148(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_149(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_150(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_151(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_152(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_153(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_154(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_155(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_156(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_157(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_158(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_159(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_160(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_161(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_162(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_163(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_164(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_165(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_166(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_167(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_168(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_169(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_170(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_171(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_172(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_173(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_174(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_175(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_176(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_177(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_178(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_179(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_180(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_181(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_182(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_183(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_184(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_185(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_186(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_187(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_188(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_189(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_190(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_191(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_192(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_193(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_194(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_195(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_196(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_197(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_198(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_199(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_200(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_201(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_202(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_203(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_204(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_205(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_206(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_207(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_208(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_209(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_210(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_211(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_212(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_213(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_214(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_215(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_216(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_217(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_218(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_219(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_220(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_221(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_222(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_223(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_224(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_225(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_226(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_227(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_228(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_229(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_230(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_231(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_232(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_233(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_234(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_235(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_236(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_237(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_238(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_239(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_240(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_241(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_242(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_243(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_244(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_245(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_246(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_247(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_248(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_249(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_250(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_251(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_252(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_253(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_254(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_255(op, st, ss, sz) 0 # define BOOST_PP_SEQ_FOLD_LEFT_CHECK_BOOST_PP_SEQ_FOLD_LEFT_I_256(op, st, ss, sz) 0 # # define BOOST_PP_SEQ_FOLD_LEFT_F(op, st, ss, sz) st # # define BOOST_PP_SEQ_FOLD_LEFT_1(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_1(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_2(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_2(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_3(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_3(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_4(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_4(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_5(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_5(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_6(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_6(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_7(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_7(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_8(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_8(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_9(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_9(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_10(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_10(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_11(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_11(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_12(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_12(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_13(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_13(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_14(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_14(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_15(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_15(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_16(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_16(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_17(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_17(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_18(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_18(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_19(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_19(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_20(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_20(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_21(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_21(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_22(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_22(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_23(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_23(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_24(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_24(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_25(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_25(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_26(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_26(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_27(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_27(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_28(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_28(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_29(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_29(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_30(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_30(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_31(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_31(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_32(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_32(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_33(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_33(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_34(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_34(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_35(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_35(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_36(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_36(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_37(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_37(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_38(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_38(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_39(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_39(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_40(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_40(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_41(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_41(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_42(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_42(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_43(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_43(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_44(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_44(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_45(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_45(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_46(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_46(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_47(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_47(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_48(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_48(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_49(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_49(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_50(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_50(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_51(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_51(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_52(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_52(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_53(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_53(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_54(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_54(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_55(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_55(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_56(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_56(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_57(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_57(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_58(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_58(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_59(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_59(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_60(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_60(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_61(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_61(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_62(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_62(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_63(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_63(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_64(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_64(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_65(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_65(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_66(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_66(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_67(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_67(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_68(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_68(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_69(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_69(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_70(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_70(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_71(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_71(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_72(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_72(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_73(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_73(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_74(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_74(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_75(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_75(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_76(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_76(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_77(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_77(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_78(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_78(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_79(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_79(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_80(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_80(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_81(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_81(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_82(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_82(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_83(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_83(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_84(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_84(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_85(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_85(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_86(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_86(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_87(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_87(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_88(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_88(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_89(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_89(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_90(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_90(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_91(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_91(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_92(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_92(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_93(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_93(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_94(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_94(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_95(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_95(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_96(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_96(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_97(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_97(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_98(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_98(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_99(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_99(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_100(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_100(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_101(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_101(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_102(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_102(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_103(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_103(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_104(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_104(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_105(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_105(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_106(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_106(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_107(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_107(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_108(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_108(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_109(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_109(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_110(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_110(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_111(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_111(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_112(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_112(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_113(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_113(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_114(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_114(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_115(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_115(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_116(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_116(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_117(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_117(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_118(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_118(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_119(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_119(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_120(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_120(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_121(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_121(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_122(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_122(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_123(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_123(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_124(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_124(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_125(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_125(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_126(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_126(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_127(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_127(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_128(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_128(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_129(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_129(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_130(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_130(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_131(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_131(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_132(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_132(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_133(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_133(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_134(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_134(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_135(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_135(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_136(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_136(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_137(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_137(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_138(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_138(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_139(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_139(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_140(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_140(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_141(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_141(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_142(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_142(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_143(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_143(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_144(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_144(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_145(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_145(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_146(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_146(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_147(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_147(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_148(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_148(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_149(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_149(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_150(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_150(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_151(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_151(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_152(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_152(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_153(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_153(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_154(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_154(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_155(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_155(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_156(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_156(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_157(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_157(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_158(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_158(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_159(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_159(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_160(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_160(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_161(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_161(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_162(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_162(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_163(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_163(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_164(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_164(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_165(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_165(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_166(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_166(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_167(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_167(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_168(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_168(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_169(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_169(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_170(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_170(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_171(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_171(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_172(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_172(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_173(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_173(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_174(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_174(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_175(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_175(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_176(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_176(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_177(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_177(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_178(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_178(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_179(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_179(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_180(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_180(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_181(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_181(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_182(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_182(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_183(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_183(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_184(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_184(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_185(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_185(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_186(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_186(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_187(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_187(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_188(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_188(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_189(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_189(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_190(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_190(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_191(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_191(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_192(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_192(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_193(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_193(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_194(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_194(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_195(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_195(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_196(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_196(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_197(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_197(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_198(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_198(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_199(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_199(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_200(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_200(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_201(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_201(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_202(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_202(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_203(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_203(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_204(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_204(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_205(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_205(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_206(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_206(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_207(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_207(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_208(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_208(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_209(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_209(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_210(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_210(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_211(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_211(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_212(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_212(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_213(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_213(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_214(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_214(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_215(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_215(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_216(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_216(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_217(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_217(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_218(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_218(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_219(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_219(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_220(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_220(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_221(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_221(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_222(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_222(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_223(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_223(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_224(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_224(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_225(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_225(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_226(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_226(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_227(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_227(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_228(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_228(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_229(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_229(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_230(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_230(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_231(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_231(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_232(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_232(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_233(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_233(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_234(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_234(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_235(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_235(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_236(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_236(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_237(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_237(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_238(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_238(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_239(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_239(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_240(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_240(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_241(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_241(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_242(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_242(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_243(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_243(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_244(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_244(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_245(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_245(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_246(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_246(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_247(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_247(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_248(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_248(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_249(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_249(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_250(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_250(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_251(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_251(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_252(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_252(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_253(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_253(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_254(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_254(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_255(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_255(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # define BOOST_PP_SEQ_FOLD_LEFT_256(op, st, ss) BOOST_PP_SEQ_FOLD_LEFT_I_256(op, st, ss, BOOST_PP_SEQ_SIZE(ss)) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() # define BOOST_PP_SEQ_FOLD_LEFT_I_1(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_2, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(2, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_2(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_3, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(3, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_3(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_4, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(4, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_4(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_5, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(5, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_5(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_6, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(6, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_6(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_7, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(7, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_7(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_8, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(8, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_8(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_9, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(9, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_9(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_10, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(10, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_10(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_11, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(11, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_11(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_12, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(12, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_12(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_13, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(13, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_13(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_14, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(14, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_14(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_15, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(15, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_15(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_16, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(16, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_16(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_17, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(17, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_17(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_18, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(18, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_18(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_19, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(19, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_19(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_20, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(20, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_20(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_21, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(21, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_21(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_22, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(22, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_22(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_23, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(23, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_23(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_24, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(24, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_24(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_25, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(25, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_25(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_26, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(26, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_26(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_27, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(27, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_27(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_28, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(28, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_28(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_29, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(29, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_29(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_30, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(30, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_30(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_31, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(31, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_31(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_32, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(32, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_32(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_33, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(33, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_33(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_34, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(34, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_34(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_35, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(35, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_35(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_36, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(36, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_36(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_37, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(37, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_37(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_38, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(38, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_38(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_39, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(39, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_39(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_40, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(40, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_40(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_41, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(41, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_41(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_42, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(42, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_42(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_43, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(43, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_43(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_44, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(44, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_44(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_45, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(45, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_45(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_46, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(46, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_46(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_47, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(47, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_47(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_48, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(48, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_48(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_49, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(49, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_49(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_50, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(50, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_50(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_51, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(51, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_51(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_52, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(52, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_52(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_53, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(53, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_53(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_54, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(54, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_54(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_55, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(55, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_55(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_56, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(56, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_56(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_57, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(57, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_57(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_58, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(58, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_58(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_59, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(59, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_59(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_60, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(60, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_60(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_61, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(61, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_61(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_62, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(62, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_62(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_63, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(63, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_63(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_64, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(64, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_64(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_65, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(65, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_65(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_66, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(66, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_66(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_67, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(67, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_67(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_68, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(68, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_68(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_69, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(69, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_69(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_70, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(70, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_70(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_71, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(71, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_71(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_72, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(72, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_72(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_73, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(73, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_73(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_74, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(74, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_74(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_75, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(75, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_75(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_76, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(76, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_76(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_77, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(77, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_77(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_78, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(78, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_78(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_79, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(79, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_79(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_80, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(80, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_80(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_81, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(81, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_81(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_82, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(82, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_82(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_83, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(83, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_83(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_84, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(84, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_84(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_85, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(85, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_85(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_86, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(86, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_86(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_87, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(87, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_87(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_88, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(88, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_88(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_89, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(89, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_89(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_90, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(90, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_90(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_91, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(91, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_91(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_92, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(92, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_92(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_93, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(93, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_93(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_94, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(94, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_94(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_95, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(95, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_95(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_96, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(96, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_96(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_97, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(97, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_97(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_98, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(98, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_98(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_99, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(99, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_99(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_100, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(100, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_100(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_101, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(101, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_101(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_102, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(102, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_102(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_103, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(103, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_103(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_104, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(104, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_104(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_105, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(105, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_105(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_106, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(106, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_106(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_107, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(107, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_107(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_108, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(108, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_108(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_109, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(109, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_109(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_110, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(110, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_110(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_111, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(111, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_111(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_112, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(112, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_112(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_113, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(113, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_113(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_114, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(114, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_114(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_115, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(115, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_115(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_116, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(116, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_116(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_117, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(117, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_117(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_118, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(118, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_118(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_119, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(119, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_119(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_120, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(120, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_120(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_121, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(121, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_121(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_122, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(122, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_122(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_123, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(123, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_123(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_124, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(124, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_124(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_125, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(125, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_125(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_126, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(126, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_126(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_127, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(127, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_127(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_128, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(128, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_128(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_129, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(129, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_129(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_130, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(130, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_130(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_131, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(131, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_131(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_132, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(132, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_132(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_133, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(133, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_133(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_134, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(134, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_134(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_135, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(135, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_135(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_136, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(136, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_136(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_137, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(137, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_137(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_138, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(138, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_138(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_139, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(139, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_139(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_140, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(140, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_140(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_141, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(141, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_141(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_142, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(142, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_142(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_143, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(143, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_143(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_144, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(144, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_144(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_145, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(145, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_145(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_146, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(146, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_146(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_147, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(147, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_147(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_148, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(148, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_148(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_149, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(149, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_149(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_150, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(150, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_150(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_151, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(151, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_151(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_152, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(152, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_152(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_153, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(153, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_153(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_154, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(154, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_154(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_155, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(155, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_155(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_156, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(156, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_156(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_157, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(157, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_157(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_158, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(158, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_158(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_159, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(159, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_159(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_160, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(160, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_160(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_161, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(161, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_161(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_162, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(162, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_162(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_163, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(163, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_163(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_164, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(164, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_164(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_165, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(165, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_165(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_166, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(166, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_166(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_167, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(167, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_167(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_168, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(168, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_168(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_169, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(169, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_169(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_170, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(170, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_170(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_171, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(171, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_171(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_172, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(172, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_172(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_173, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(173, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_173(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_174, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(174, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_174(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_175, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(175, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_175(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_176, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(176, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_176(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_177, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(177, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_177(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_178, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(178, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_178(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_179, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(179, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_179(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_180, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(180, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_180(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_181, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(181, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_181(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_182, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(182, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_182(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_183, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(183, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_183(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_184, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(184, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_184(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_185, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(185, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_185(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_186, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(186, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_186(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_187, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(187, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_187(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_188, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(188, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_188(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_189, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(189, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_189(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_190, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(190, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_190(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_191, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(191, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_191(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_192, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(192, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_192(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_193, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(193, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_193(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_194, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(194, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_194(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_195, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(195, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_195(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_196, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(196, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_196(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_197, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(197, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_197(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_198, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(198, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_198(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_199, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(199, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_199(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_200, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(200, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_200(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_201, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(201, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_201(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_202, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(202, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_202(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_203, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(203, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_203(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_204, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(204, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_204(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_205, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(205, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_205(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_206, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(206, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_206(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_207, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(207, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_207(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_208, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(208, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_208(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_209, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(209, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_209(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_210, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(210, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_210(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_211, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(211, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_211(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_212, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(212, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_212(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_213, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(213, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_213(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_214, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(214, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_214(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_215, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(215, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_215(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_216, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(216, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_216(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_217, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(217, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_217(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_218, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(218, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_218(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_219, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(219, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_219(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_220, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(220, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_220(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_221, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(221, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_221(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_222, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(222, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_222(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_223, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(223, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_223(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_224, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(224, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_224(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_225, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(225, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_225(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_226, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(226, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_226(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_227, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(227, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_227(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_228, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(228, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_228(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_229, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(229, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_229(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_230, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(230, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_230(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_231, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(231, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_231(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_232, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(232, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_232(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_233, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(233, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_233(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_234, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(234, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_234(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_235, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(235, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_235(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_236, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(236, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_236(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_237, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(237, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_237(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_238, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(238, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_238(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_239, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(239, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_239(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_240, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(240, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_240(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_241, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(241, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_241(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_242, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(242, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_242(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_243, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(243, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_243(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_244, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(244, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_244(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_245, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(245, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_245(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_246, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(246, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_246(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_247, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(247, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_247(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_248, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(248, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_248(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_249, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(249, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_249(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_250, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(250, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_250(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_251, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(251, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_251(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_252, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(252, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_252(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_253, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(253, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_253(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_254, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(254, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_254(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_255, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(255, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_255(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_256, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(256, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_256(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_257, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op(257, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # else # define BOOST_PP_SEQ_FOLD_LEFT_I_1(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_2, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(2, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_2(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_3, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(3, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_3(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_4, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(4, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_4(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_5, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(5, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_5(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_6, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(6, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_6(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_7, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(7, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_7(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_8, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(8, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_8(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_9, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(9, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_9(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_10, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(10, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_10(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_11, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(11, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_11(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_12, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(12, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_12(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_13, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(13, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_13(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_14, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(14, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_14(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_15, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(15, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_15(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_16, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(16, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_16(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_17, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(17, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_17(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_18, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(18, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_18(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_19, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(19, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_19(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_20, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(20, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_20(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_21, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(21, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_21(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_22, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(22, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_22(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_23, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(23, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_23(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_24, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(24, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_24(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_25, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(25, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_25(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_26, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(26, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_26(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_27, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(27, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_27(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_28, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(28, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_28(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_29, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(29, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_29(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_30, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(30, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_30(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_31, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(31, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_31(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_32, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(32, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_32(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_33, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(33, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_33(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_34, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(34, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_34(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_35, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(35, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_35(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_36, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(36, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_36(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_37, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(37, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_37(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_38, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(38, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_38(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_39, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(39, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_39(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_40, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(40, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_40(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_41, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(41, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_41(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_42, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(42, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_42(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_43, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(43, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_43(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_44, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(44, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_44(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_45, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(45, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_45(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_46, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(46, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_46(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_47, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(47, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_47(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_48, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(48, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_48(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_49, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(49, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_49(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_50, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(50, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_50(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_51, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(51, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_51(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_52, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(52, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_52(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_53, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(53, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_53(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_54, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(54, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_54(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_55, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(55, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_55(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_56, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(56, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_56(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_57, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(57, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_57(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_58, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(58, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_58(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_59, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(59, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_59(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_60, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(60, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_60(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_61, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(61, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_61(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_62, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(62, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_62(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_63, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(63, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_63(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_64, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(64, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_64(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_65, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(65, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_65(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_66, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(66, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_66(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_67, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(67, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_67(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_68, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(68, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_68(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_69, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(69, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_69(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_70, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(70, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_70(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_71, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(71, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_71(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_72, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(72, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_72(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_73, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(73, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_73(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_74, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(74, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_74(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_75, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(75, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_75(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_76, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(76, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_76(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_77, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(77, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_77(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_78, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(78, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_78(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_79, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(79, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_79(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_80, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(80, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_80(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_81, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(81, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_81(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_82, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(82, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_82(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_83, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(83, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_83(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_84, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(84, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_84(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_85, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(85, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_85(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_86, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(86, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_86(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_87, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(87, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_87(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_88, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(88, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_88(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_89, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(89, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_89(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_90, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(90, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_90(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_91, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(91, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_91(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_92, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(92, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_92(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_93, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(93, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_93(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_94, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(94, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_94(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_95, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(95, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_95(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_96, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(96, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_96(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_97, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(97, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_97(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_98, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(98, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_98(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_99, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(99, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_99(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_100, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(100, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_100(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_101, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(101, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_101(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_102, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(102, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_102(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_103, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(103, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_103(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_104, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(104, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_104(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_105, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(105, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_105(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_106, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(106, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_106(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_107, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(107, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_107(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_108, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(108, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_108(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_109, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(109, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_109(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_110, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(110, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_110(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_111, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(111, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_111(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_112, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(112, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_112(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_113, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(113, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_113(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_114, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(114, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_114(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_115, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(115, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_115(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_116, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(116, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_116(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_117, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(117, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_117(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_118, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(118, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_118(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_119, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(119, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_119(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_120, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(120, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_120(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_121, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(121, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_121(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_122, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(122, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_122(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_123, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(123, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_123(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_124, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(124, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_124(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_125, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(125, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_125(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_126, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(126, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_126(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_127, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(127, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_127(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_128, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(128, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_128(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_129, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(129, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_129(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_130, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(130, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_130(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_131, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(131, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_131(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_132, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(132, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_132(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_133, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(133, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_133(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_134, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(134, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_134(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_135, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(135, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_135(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_136, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(136, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_136(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_137, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(137, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_137(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_138, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(138, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_138(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_139, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(139, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_139(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_140, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(140, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_140(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_141, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(141, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_141(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_142, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(142, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_142(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_143, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(143, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_143(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_144, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(144, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_144(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_145, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(145, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_145(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_146, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(146, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_146(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_147, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(147, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_147(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_148, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(148, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_148(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_149, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(149, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_149(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_150, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(150, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_150(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_151, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(151, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_151(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_152, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(152, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_152(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_153, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(153, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_153(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_154, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(154, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_154(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_155, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(155, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_155(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_156, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(156, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_156(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_157, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(157, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_157(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_158, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(158, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_158(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_159, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(159, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_159(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_160, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(160, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_160(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_161, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(161, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_161(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_162, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(162, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_162(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_163, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(163, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_163(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_164, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(164, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_164(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_165, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(165, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_165(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_166, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(166, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_166(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_167, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(167, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_167(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_168, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(168, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_168(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_169, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(169, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_169(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_170, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(170, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_170(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_171, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(171, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_171(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_172, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(172, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_172(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_173, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(173, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_173(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_174, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(174, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_174(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_175, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(175, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_175(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_176, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(176, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_176(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_177, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(177, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_177(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_178, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(178, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_178(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_179, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(179, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_179(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_180, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(180, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_180(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_181, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(181, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_181(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_182, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(182, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_182(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_183, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(183, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_183(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_184, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(184, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_184(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_185, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(185, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_185(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_186, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(186, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_186(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_187, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(187, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_187(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_188, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(188, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_188(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_189, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(189, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_189(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_190, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(190, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_190(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_191, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(191, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_191(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_192, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(192, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_192(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_193, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(193, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_193(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_194, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(194, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_194(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_195, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(195, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_195(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_196, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(196, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_196(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_197, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(197, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_197(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_198, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(198, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_198(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_199, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(199, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_199(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_200, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(200, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_200(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_201, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(201, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_201(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_202, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(202, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_202(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_203, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(203, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_203(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_204, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(204, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_204(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_205, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(205, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_205(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_206, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(206, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_206(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_207, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(207, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_207(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_208, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(208, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_208(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_209, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(209, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_209(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_210, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(210, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_210(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_211, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(211, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_211(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_212, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(212, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_212(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_213, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(213, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_213(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_214, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(214, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_214(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_215, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(215, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_215(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_216, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(216, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_216(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_217, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(217, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_217(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_218, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(218, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_218(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_219, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(219, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_219(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_220, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(220, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_220(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_221, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(221, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_221(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_222, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(222, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_222(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_223, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(223, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_223(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_224, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(224, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_224(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_225, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(225, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_225(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_226, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(226, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_226(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_227, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(227, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_227(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_228, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(228, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_228(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_229, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(229, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_229(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_230, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(230, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_230(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_231, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(231, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_231(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_232, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(232, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_232(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_233, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(233, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_233(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_234, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(234, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_234(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_235, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(235, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_235(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_236, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(236, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_236(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_237, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(237, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_237(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_238, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(238, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_238(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_239, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(239, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_239(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_240, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(240, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_240(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_241, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(241, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_241(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_242, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(242, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_242(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_243, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(243, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_243(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_244, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(244, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_244(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_245, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(245, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_245(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_246, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(246, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_246(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_247, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(247, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_247(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_248, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(248, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_248(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_249, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(249, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_249(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_250, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(250, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_250(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_251, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(251, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_251(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_252, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(252, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_252(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_253, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(253, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_253(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_254, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(254, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_254(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_255, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(255, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_255(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_256, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(256, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # define BOOST_PP_SEQ_FOLD_LEFT_I_256(op, st, ss, sz) BOOST_PP_IF(BOOST_PP_DEC(sz), BOOST_PP_SEQ_FOLD_LEFT_I_257, BOOST_PP_SEQ_FOLD_LEFT_F)(op, op##(257, st, BOOST_PP_SEQ_HEAD(ss)), BOOST_PP_SEQ_TAIL(ss), BOOST_PP_DEC(sz)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/for_each.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_FOR_EACH_HPP # define BOOST_PREPROCESSOR_SEQ_FOR_EACH_HPP # # include # include # include # include # include # include # include # include # include # include # # /* BOOST_PP_SEQ_FOR_EACH */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_FOR_EACH(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK(macro, data, seq) # else # define BOOST_PP_SEQ_FOR_EACH(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_D(macro, data, seq) # define BOOST_PP_SEQ_FOR_EACH_D(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK(macro, data, seq) # endif # # define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC(macro, data, seq) BOOST_PP_FOR((macro, data, seq, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M) # define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY(macro, data, seq) # # define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK(macro, data, seq) \ BOOST_PP_IIF \ ( \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC, \ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY \ ) \ (macro, data, seq) \ /**/ # # define BOOST_PP_SEQ_FOR_EACH_P(r, x) BOOST_PP_TUPLE_ELEM(4, 3, x) # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_SEQ_FOR_EACH_O(r, x) BOOST_PP_SEQ_FOR_EACH_O_I x # else # define BOOST_PP_SEQ_FOR_EACH_O(r, x) BOOST_PP_SEQ_FOR_EACH_O_I(BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_TUPLE_ELEM(4, 2, x), BOOST_PP_TUPLE_ELEM(4, 3, x)) # endif # # define BOOST_PP_SEQ_FOR_EACH_O_I(macro, data, seq, sz) \ BOOST_PP_SEQ_FOR_EACH_O_I_DEC(macro, data, seq, BOOST_PP_DEC(sz)) \ /**/ # define BOOST_PP_SEQ_FOR_EACH_O_I_DEC(macro, data, seq, sz) \ ( \ macro, \ data, \ BOOST_PP_IF \ ( \ sz, \ BOOST_PP_SEQ_FOR_EACH_O_I_TAIL, \ BOOST_PP_SEQ_FOR_EACH_O_I_NIL \ ) \ (seq), \ sz \ ) \ /**/ # define BOOST_PP_SEQ_FOR_EACH_O_I_TAIL(seq) BOOST_PP_SEQ_TAIL(seq) # define BOOST_PP_SEQ_FOR_EACH_O_I_NIL(seq) BOOST_PP_NIL # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_IM(r, BOOST_PP_TUPLE_REM_4 x) # define BOOST_PP_SEQ_FOR_EACH_M_IM(r, im) BOOST_PP_SEQ_FOR_EACH_M_I(r, im) # else # define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_I(r, BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_TUPLE_ELEM(4, 2, x), BOOST_PP_TUPLE_ELEM(4, 3, x)) # endif # # define BOOST_PP_SEQ_FOR_EACH_M_I(r, macro, data, seq, sz) macro(r, data, BOOST_PP_SEQ_HEAD(seq)) # # /* BOOST_PP_SEQ_FOR_EACH_R */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_FOR_EACH_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_R(r, macro, data, seq) # else # define BOOST_PP_SEQ_FOR_EACH_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_R_I(r, macro, data, seq) # define BOOST_PP_SEQ_FOR_EACH_R_I(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_R(r, macro, data, seq) # endif # # define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC_R(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M) # define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY_R(r, macro, data, seq) # # define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_R(r, macro, data, seq) \ BOOST_PP_IIF \ ( \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC_R, \ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY_R \ ) \ (r, macro, data, seq) \ /**/ # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/for_each_i.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_FOR_EACH_I_HPP # define BOOST_PREPROCESSOR_SEQ_FOR_EACH_I_HPP # # include # include # include # include # include # include # include # include # include # include # include # # /* BOOST_PP_SEQ_FOR_EACH_I */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_FOR_EACH_I(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK(macro, data, seq) # else # define BOOST_PP_SEQ_FOR_EACH_I(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_I(macro, data, seq) # define BOOST_PP_SEQ_FOR_EACH_I_I(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK(macro, data, seq) # endif # # define BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EXEC(macro, data, seq) BOOST_PP_FOR((macro, data, seq, 0, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M) # define BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EMPTY(macro, data, seq) # # define BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK(macro, data, seq) \ BOOST_PP_IIF \ ( \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \ BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EXEC, \ BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EMPTY \ ) \ (macro, data, seq) \ /**/ # # define BOOST_PP_SEQ_FOR_EACH_I_P(r, x) BOOST_PP_TUPLE_ELEM(5, 4, x) # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_SEQ_FOR_EACH_I_O(r, x) BOOST_PP_SEQ_FOR_EACH_I_O_I x # else # define BOOST_PP_SEQ_FOR_EACH_I_O(r, x) BOOST_PP_SEQ_FOR_EACH_I_O_I(BOOST_PP_TUPLE_ELEM(5, 0, x), BOOST_PP_TUPLE_ELEM(5, 1, x), BOOST_PP_TUPLE_ELEM(5, 2, x), BOOST_PP_TUPLE_ELEM(5, 3, x), BOOST_PP_TUPLE_ELEM(5, 4, x)) # endif # # define BOOST_PP_SEQ_FOR_EACH_I_O_I(macro, data, seq, i, sz) \ BOOST_PP_SEQ_FOR_EACH_I_O_I_DEC(macro, data, seq, i, BOOST_PP_DEC(sz)) \ /**/ # define BOOST_PP_SEQ_FOR_EACH_I_O_I_DEC(macro, data, seq, i, sz) \ ( \ macro, \ data, \ BOOST_PP_IF \ ( \ sz, \ BOOST_PP_SEQ_FOR_EACH_I_O_I_TAIL, \ BOOST_PP_SEQ_FOR_EACH_I_O_I_NIL \ ) \ (seq), \ BOOST_PP_INC(i), \ sz \ ) \ /**/ # define BOOST_PP_SEQ_FOR_EACH_I_O_I_TAIL(seq) BOOST_PP_SEQ_TAIL(seq) # define BOOST_PP_SEQ_FOR_EACH_I_O_I_NIL(seq) BOOST_PP_NIL # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, BOOST_PP_TUPLE_REM_5 x) # define BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, im) BOOST_PP_SEQ_FOR_EACH_I_M_I(r, im) # else # define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_I(r, BOOST_PP_TUPLE_ELEM(5, 0, x), BOOST_PP_TUPLE_ELEM(5, 1, x), BOOST_PP_TUPLE_ELEM(5, 2, x), BOOST_PP_TUPLE_ELEM(5, 3, x), BOOST_PP_TUPLE_ELEM(5, 4, x)) # endif # # define BOOST_PP_SEQ_FOR_EACH_I_M_I(r, macro, data, seq, i, sz) macro(r, data, i, BOOST_PP_SEQ_HEAD(seq)) # # /* BOOST_PP_SEQ_FOR_EACH_I_R */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_FOR_EACH_I_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK(r, macro, data, seq) # else # define BOOST_PP_SEQ_FOR_EACH_I_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_R_I(r, macro, data, seq) # define BOOST_PP_SEQ_FOR_EACH_I_R_I(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK(r, macro, data, seq) # endif # # define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq, 0, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M) # define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EMPTY(r, macro, data, seq) # # define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK(r, macro, data, seq) \ BOOST_PP_IIF \ ( \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \ BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC, \ BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EMPTY \ ) \ (r, macro, data, seq) \ /**/ # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/for_each_product.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_FOR_EACH_PRODUCT_HPP # define BOOST_PREPROCESSOR_SEQ_FOR_EACH_PRODUCT_HPP # # include # include # include # include # include # include # include # include # # /* BOOST_PP_SEQ_FOR_EACH_PRODUCT */ # # define BOOST_PP_SEQ_FOR_EACH_PRODUCT(macro, sets) BOOST_PP_SEQ_FOR_EACH_PRODUCT_E(BOOST_PP_FOR, macro, sets) # # /* BOOST_PP_SEQ_FOR_EACH_PRODUCT_R */ # # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_R(r, macro, sets) BOOST_PP_SEQ_FOR_EACH_PRODUCT_E(BOOST_PP_FOR_ ## r, macro, sets) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_E(impl, macro, sets) impl((BOOST_PP_SEQ_HEAD(sets)(nil), BOOST_PP_SEQ_TAIL(sets)(nil), (nil), macro), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_0) # else # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_E(impl, macro, sets) BOOST_PP_SEQ_FOR_EACH_PRODUCT_E_I(impl, macro, sets) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_E_I(impl, macro, sets) impl((BOOST_PP_SEQ_HEAD(sets)(nil), BOOST_PP_SEQ_TAIL(sets)(nil), (nil), macro), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_0) # endif # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT() # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_P(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_P_I data # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_P_I(cset, rset, res, macro) BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(cset)) # else # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_P(r, data) BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(4, 0, data))) # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_O(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_O_I data # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_O_I(cset, rset, res, macro) (BOOST_PP_SEQ_TAIL(cset), rset, res, macro) # else # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_O(r, data) (BOOST_PP_SEQ_TAIL(BOOST_PP_TUPLE_ELEM(4, 0, data)), BOOST_PP_TUPLE_ELEM(4, 1, data), BOOST_PP_TUPLE_ELEM(4, 2, data), BOOST_PP_TUPLE_ELEM(4, 3, data)) # endif # # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, i) BOOST_PP_IF(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(4, 1, data))), BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_ ## i, BOOST_PP_SEQ_FOR_EACH_PRODUCT_I) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_I(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_I_I(r, BOOST_PP_TUPLE_ELEM(4, 0, data), BOOST_PP_TUPLE_ELEM(4, 1, data), BOOST_PP_TUPLE_ELEM(4, 2, data), BOOST_PP_TUPLE_ELEM(4, 3, data)) # else # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_I(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_I_IM(r, BOOST_PP_TUPLE_REM_4 data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_I_IM(r, im) BOOST_PP_SEQ_FOR_EACH_PRODUCT_I_I(r, im) # endif # # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_I_I(r, cset, rset, res, macro) macro(r, BOOST_PP_SEQ_TAIL(res (BOOST_PP_SEQ_HEAD(cset)))) # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_H_I data # else # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_H_I(BOOST_PP_TUPLE_ELEM(4, 0, data), BOOST_PP_TUPLE_ELEM(4, 1, data), BOOST_PP_TUPLE_ELEM(4, 2, data), BOOST_PP_TUPLE_ELEM(4, 3, data)) # endif # # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_H_I(cset, rset, res, macro) (BOOST_PP_SEQ_HEAD(rset)(nil), BOOST_PP_SEQ_TAIL(rset), res (BOOST_PP_SEQ_HEAD(cset)), macro) # # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_0(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 0)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_1(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 1)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_2(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 2)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_3(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 3)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_4(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 4)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_5(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 5)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_6(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 6)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_7(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 7)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_8(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 8)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_9(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 9)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_10(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 10)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_11(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 11)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_12(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 12)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_13(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 13)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_14(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 14)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_15(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 15)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_16(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 16)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_17(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 17)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_18(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 18)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_19(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 19)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_20(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 20)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_21(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 21)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_22(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 22)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_23(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 23)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_24(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 24)(r, data) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_25(r, data) BOOST_PP_SEQ_FOR_EACH_PRODUCT_C(data, 25)(r, data) # # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_0(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_1) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_1(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_2) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_2(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_3) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_3(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_4) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_4(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_5) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_5(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_6) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_6(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_7) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_7(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_8) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_8(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_9) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_9(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_10) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_10(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_11) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_11(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_12) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_12(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_13) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_13(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_14) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_14(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_15) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_15(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_16) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_16(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_17) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_17(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_18) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_18(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_19) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_19(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_20) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_20(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_21) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_21(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_22) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_22(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_23) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_23(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_24) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_24(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_25) # define BOOST_PP_SEQ_FOR_EACH_PRODUCT_N_25(r, data) BOOST_PP_FOR_ ## r(BOOST_PP_SEQ_FOR_EACH_PRODUCT_H(data), BOOST_PP_SEQ_FOR_EACH_PRODUCT_P, BOOST_PP_SEQ_FOR_EACH_PRODUCT_O, BOOST_PP_SEQ_FOR_EACH_PRODUCT_M_26) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/push_back.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_PUSH_BACK_HPP # define BOOST_PREPROCESSOR_SEQ_PUSH_BACK_HPP # # /* BOOST_PP_SEQ_PUSH_BACK */ # # define BOOST_PP_SEQ_PUSH_BACK(seq, elem) seq(elem) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/rest_n.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_REST_N_HPP # define BOOST_PREPROCESSOR_SEQ_REST_N_HPP # # include # include # include # include # include # include # include # include # include # # /* BOOST_PP_SEQ_REST_N */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_REST_N(n, seq) BOOST_PP_SEQ_REST_N_DETAIL_EXEC(n, seq, BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq)) # else # define BOOST_PP_SEQ_REST_N(n, seq) BOOST_PP_SEQ_REST_N_I(n, seq) # define BOOST_PP_SEQ_REST_N_I(n, seq) BOOST_PP_SEQ_REST_N_DETAIL_EXEC(n, seq, BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq)) # endif # # define BOOST_PP_SEQ_REST_N_DETAIL_EXEC(n, seq, size) \ BOOST_PP_EXPR_IIF \ ( \ BOOST_PP_BITAND \ ( \ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(size), \ BOOST_PP_NOT_EQUAL(n,size) \ ), \ BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_SEQ_SPLIT(BOOST_PP_INC(n), BOOST_PP_IDENTITY( (nil) seq )))() \ ) \ /**/ # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/seq.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_SEQ_HPP # define BOOST_PREPROCESSOR_SEQ_SEQ_HPP # # include # include # # /* BOOST_PP_SEQ_HEAD */ # # define BOOST_PP_SEQ_HEAD(seq) BOOST_PP_SEQ_ELEM(0, seq) # # /* BOOST_PP_SEQ_TAIL */ # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_TAIL(seq) BOOST_PP_SEQ_TAIL_1((seq)) # define BOOST_PP_SEQ_TAIL_1(par) BOOST_PP_SEQ_TAIL_2 ## par # define BOOST_PP_SEQ_TAIL_2(seq) BOOST_PP_SEQ_TAIL_I ## seq # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_SEQ_TAIL(seq) BOOST_PP_SEQ_TAIL_ID(BOOST_PP_SEQ_TAIL_I seq) # define BOOST_PP_SEQ_TAIL_ID(id) id # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_TAIL(seq) BOOST_PP_SEQ_TAIL_D(seq) # define BOOST_PP_SEQ_TAIL_D(seq) BOOST_PP_SEQ_TAIL_I seq # else # define BOOST_PP_SEQ_TAIL(seq) BOOST_PP_SEQ_TAIL_I seq # endif # # define BOOST_PP_SEQ_TAIL_I(x) # # /* BOOST_PP_SEQ_NIL */ # # define BOOST_PP_SEQ_NIL(x) (x) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/size.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_SIZE_HPP # define BOOST_PREPROCESSOR_SEQ_SIZE_HPP # # include # include # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_SEQ_SIZE(seq) BOOST_PP_SEQ_SIZE_I((seq)) # define BOOST_PP_SEQ_SIZE_I(par) BOOST_PP_SEQ_SIZE_II ## par # define BOOST_PP_SEQ_SIZE_II(seq) BOOST_PP_CAT(BOOST_PP_SEQ_SIZE_, BOOST_PP_SEQ_SIZE_0 ## seq) # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() || BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_SEQ_SIZE(seq) BOOST_PP_SEQ_SIZE_I(seq) # define BOOST_PP_SEQ_SIZE_I(seq) BOOST_PP_CAT(BOOST_PP_SEQ_SIZE_, BOOST_PP_SEQ_SIZE_0 seq) # elif defined(__IBMC__) || defined(__IBMCPP__) # define BOOST_PP_SEQ_SIZE(seq) BOOST_PP_CAT(BOOST_PP_SEQ_SIZE_, BOOST_PP_CAT(BOOST_PP_SEQ_SIZE_0, seq)) # else # define BOOST_PP_SEQ_SIZE(seq) BOOST_PP_CAT(BOOST_PP_SEQ_SIZE_, BOOST_PP_SEQ_SIZE_0 seq) # endif # # define BOOST_PP_SEQ_SIZE_0(_) BOOST_PP_SEQ_SIZE_1 # define BOOST_PP_SEQ_SIZE_1(_) BOOST_PP_SEQ_SIZE_2 # define BOOST_PP_SEQ_SIZE_2(_) BOOST_PP_SEQ_SIZE_3 # define BOOST_PP_SEQ_SIZE_3(_) BOOST_PP_SEQ_SIZE_4 # define BOOST_PP_SEQ_SIZE_4(_) BOOST_PP_SEQ_SIZE_5 # define BOOST_PP_SEQ_SIZE_5(_) BOOST_PP_SEQ_SIZE_6 # define BOOST_PP_SEQ_SIZE_6(_) BOOST_PP_SEQ_SIZE_7 # define BOOST_PP_SEQ_SIZE_7(_) BOOST_PP_SEQ_SIZE_8 # define BOOST_PP_SEQ_SIZE_8(_) BOOST_PP_SEQ_SIZE_9 # define BOOST_PP_SEQ_SIZE_9(_) BOOST_PP_SEQ_SIZE_10 # define BOOST_PP_SEQ_SIZE_10(_) BOOST_PP_SEQ_SIZE_11 # define BOOST_PP_SEQ_SIZE_11(_) BOOST_PP_SEQ_SIZE_12 # define BOOST_PP_SEQ_SIZE_12(_) BOOST_PP_SEQ_SIZE_13 # define BOOST_PP_SEQ_SIZE_13(_) BOOST_PP_SEQ_SIZE_14 # define BOOST_PP_SEQ_SIZE_14(_) BOOST_PP_SEQ_SIZE_15 # define BOOST_PP_SEQ_SIZE_15(_) BOOST_PP_SEQ_SIZE_16 # define BOOST_PP_SEQ_SIZE_16(_) BOOST_PP_SEQ_SIZE_17 # define BOOST_PP_SEQ_SIZE_17(_) BOOST_PP_SEQ_SIZE_18 # define BOOST_PP_SEQ_SIZE_18(_) BOOST_PP_SEQ_SIZE_19 # define BOOST_PP_SEQ_SIZE_19(_) BOOST_PP_SEQ_SIZE_20 # define BOOST_PP_SEQ_SIZE_20(_) BOOST_PP_SEQ_SIZE_21 # define BOOST_PP_SEQ_SIZE_21(_) BOOST_PP_SEQ_SIZE_22 # define BOOST_PP_SEQ_SIZE_22(_) BOOST_PP_SEQ_SIZE_23 # define BOOST_PP_SEQ_SIZE_23(_) BOOST_PP_SEQ_SIZE_24 # define BOOST_PP_SEQ_SIZE_24(_) BOOST_PP_SEQ_SIZE_25 # define BOOST_PP_SEQ_SIZE_25(_) BOOST_PP_SEQ_SIZE_26 # define BOOST_PP_SEQ_SIZE_26(_) BOOST_PP_SEQ_SIZE_27 # define BOOST_PP_SEQ_SIZE_27(_) BOOST_PP_SEQ_SIZE_28 # define BOOST_PP_SEQ_SIZE_28(_) BOOST_PP_SEQ_SIZE_29 # define BOOST_PP_SEQ_SIZE_29(_) BOOST_PP_SEQ_SIZE_30 # define BOOST_PP_SEQ_SIZE_30(_) BOOST_PP_SEQ_SIZE_31 # define BOOST_PP_SEQ_SIZE_31(_) BOOST_PP_SEQ_SIZE_32 # define BOOST_PP_SEQ_SIZE_32(_) BOOST_PP_SEQ_SIZE_33 # define BOOST_PP_SEQ_SIZE_33(_) BOOST_PP_SEQ_SIZE_34 # define BOOST_PP_SEQ_SIZE_34(_) BOOST_PP_SEQ_SIZE_35 # define BOOST_PP_SEQ_SIZE_35(_) BOOST_PP_SEQ_SIZE_36 # define BOOST_PP_SEQ_SIZE_36(_) BOOST_PP_SEQ_SIZE_37 # define BOOST_PP_SEQ_SIZE_37(_) BOOST_PP_SEQ_SIZE_38 # define BOOST_PP_SEQ_SIZE_38(_) BOOST_PP_SEQ_SIZE_39 # define BOOST_PP_SEQ_SIZE_39(_) BOOST_PP_SEQ_SIZE_40 # define BOOST_PP_SEQ_SIZE_40(_) BOOST_PP_SEQ_SIZE_41 # define BOOST_PP_SEQ_SIZE_41(_) BOOST_PP_SEQ_SIZE_42 # define BOOST_PP_SEQ_SIZE_42(_) BOOST_PP_SEQ_SIZE_43 # define BOOST_PP_SEQ_SIZE_43(_) BOOST_PP_SEQ_SIZE_44 # define BOOST_PP_SEQ_SIZE_44(_) BOOST_PP_SEQ_SIZE_45 # define BOOST_PP_SEQ_SIZE_45(_) BOOST_PP_SEQ_SIZE_46 # define BOOST_PP_SEQ_SIZE_46(_) BOOST_PP_SEQ_SIZE_47 # define BOOST_PP_SEQ_SIZE_47(_) BOOST_PP_SEQ_SIZE_48 # define BOOST_PP_SEQ_SIZE_48(_) BOOST_PP_SEQ_SIZE_49 # define BOOST_PP_SEQ_SIZE_49(_) BOOST_PP_SEQ_SIZE_50 # define BOOST_PP_SEQ_SIZE_50(_) BOOST_PP_SEQ_SIZE_51 # define BOOST_PP_SEQ_SIZE_51(_) BOOST_PP_SEQ_SIZE_52 # define BOOST_PP_SEQ_SIZE_52(_) BOOST_PP_SEQ_SIZE_53 # define BOOST_PP_SEQ_SIZE_53(_) BOOST_PP_SEQ_SIZE_54 # define BOOST_PP_SEQ_SIZE_54(_) BOOST_PP_SEQ_SIZE_55 # define BOOST_PP_SEQ_SIZE_55(_) BOOST_PP_SEQ_SIZE_56 # define BOOST_PP_SEQ_SIZE_56(_) BOOST_PP_SEQ_SIZE_57 # define BOOST_PP_SEQ_SIZE_57(_) BOOST_PP_SEQ_SIZE_58 # define BOOST_PP_SEQ_SIZE_58(_) BOOST_PP_SEQ_SIZE_59 # define BOOST_PP_SEQ_SIZE_59(_) BOOST_PP_SEQ_SIZE_60 # define BOOST_PP_SEQ_SIZE_60(_) BOOST_PP_SEQ_SIZE_61 # define BOOST_PP_SEQ_SIZE_61(_) BOOST_PP_SEQ_SIZE_62 # define BOOST_PP_SEQ_SIZE_62(_) BOOST_PP_SEQ_SIZE_63 # define BOOST_PP_SEQ_SIZE_63(_) BOOST_PP_SEQ_SIZE_64 # define BOOST_PP_SEQ_SIZE_64(_) BOOST_PP_SEQ_SIZE_65 # define BOOST_PP_SEQ_SIZE_65(_) BOOST_PP_SEQ_SIZE_66 # define BOOST_PP_SEQ_SIZE_66(_) BOOST_PP_SEQ_SIZE_67 # define BOOST_PP_SEQ_SIZE_67(_) BOOST_PP_SEQ_SIZE_68 # define BOOST_PP_SEQ_SIZE_68(_) BOOST_PP_SEQ_SIZE_69 # define BOOST_PP_SEQ_SIZE_69(_) BOOST_PP_SEQ_SIZE_70 # define BOOST_PP_SEQ_SIZE_70(_) BOOST_PP_SEQ_SIZE_71 # define BOOST_PP_SEQ_SIZE_71(_) BOOST_PP_SEQ_SIZE_72 # define BOOST_PP_SEQ_SIZE_72(_) BOOST_PP_SEQ_SIZE_73 # define BOOST_PP_SEQ_SIZE_73(_) BOOST_PP_SEQ_SIZE_74 # define BOOST_PP_SEQ_SIZE_74(_) BOOST_PP_SEQ_SIZE_75 # define BOOST_PP_SEQ_SIZE_75(_) BOOST_PP_SEQ_SIZE_76 # define BOOST_PP_SEQ_SIZE_76(_) BOOST_PP_SEQ_SIZE_77 # define BOOST_PP_SEQ_SIZE_77(_) BOOST_PP_SEQ_SIZE_78 # define BOOST_PP_SEQ_SIZE_78(_) BOOST_PP_SEQ_SIZE_79 # define BOOST_PP_SEQ_SIZE_79(_) BOOST_PP_SEQ_SIZE_80 # define BOOST_PP_SEQ_SIZE_80(_) BOOST_PP_SEQ_SIZE_81 # define BOOST_PP_SEQ_SIZE_81(_) BOOST_PP_SEQ_SIZE_82 # define BOOST_PP_SEQ_SIZE_82(_) BOOST_PP_SEQ_SIZE_83 # define BOOST_PP_SEQ_SIZE_83(_) BOOST_PP_SEQ_SIZE_84 # define BOOST_PP_SEQ_SIZE_84(_) BOOST_PP_SEQ_SIZE_85 # define BOOST_PP_SEQ_SIZE_85(_) BOOST_PP_SEQ_SIZE_86 # define BOOST_PP_SEQ_SIZE_86(_) BOOST_PP_SEQ_SIZE_87 # define BOOST_PP_SEQ_SIZE_87(_) BOOST_PP_SEQ_SIZE_88 # define BOOST_PP_SEQ_SIZE_88(_) BOOST_PP_SEQ_SIZE_89 # define BOOST_PP_SEQ_SIZE_89(_) BOOST_PP_SEQ_SIZE_90 # define BOOST_PP_SEQ_SIZE_90(_) BOOST_PP_SEQ_SIZE_91 # define BOOST_PP_SEQ_SIZE_91(_) BOOST_PP_SEQ_SIZE_92 # define BOOST_PP_SEQ_SIZE_92(_) BOOST_PP_SEQ_SIZE_93 # define BOOST_PP_SEQ_SIZE_93(_) BOOST_PP_SEQ_SIZE_94 # define BOOST_PP_SEQ_SIZE_94(_) BOOST_PP_SEQ_SIZE_95 # define BOOST_PP_SEQ_SIZE_95(_) BOOST_PP_SEQ_SIZE_96 # define BOOST_PP_SEQ_SIZE_96(_) BOOST_PP_SEQ_SIZE_97 # define BOOST_PP_SEQ_SIZE_97(_) BOOST_PP_SEQ_SIZE_98 # define BOOST_PP_SEQ_SIZE_98(_) BOOST_PP_SEQ_SIZE_99 # define BOOST_PP_SEQ_SIZE_99(_) BOOST_PP_SEQ_SIZE_100 # define BOOST_PP_SEQ_SIZE_100(_) BOOST_PP_SEQ_SIZE_101 # define BOOST_PP_SEQ_SIZE_101(_) BOOST_PP_SEQ_SIZE_102 # define BOOST_PP_SEQ_SIZE_102(_) BOOST_PP_SEQ_SIZE_103 # define BOOST_PP_SEQ_SIZE_103(_) BOOST_PP_SEQ_SIZE_104 # define BOOST_PP_SEQ_SIZE_104(_) BOOST_PP_SEQ_SIZE_105 # define BOOST_PP_SEQ_SIZE_105(_) BOOST_PP_SEQ_SIZE_106 # define BOOST_PP_SEQ_SIZE_106(_) BOOST_PP_SEQ_SIZE_107 # define BOOST_PP_SEQ_SIZE_107(_) BOOST_PP_SEQ_SIZE_108 # define BOOST_PP_SEQ_SIZE_108(_) BOOST_PP_SEQ_SIZE_109 # define BOOST_PP_SEQ_SIZE_109(_) BOOST_PP_SEQ_SIZE_110 # define BOOST_PP_SEQ_SIZE_110(_) BOOST_PP_SEQ_SIZE_111 # define BOOST_PP_SEQ_SIZE_111(_) BOOST_PP_SEQ_SIZE_112 # define BOOST_PP_SEQ_SIZE_112(_) BOOST_PP_SEQ_SIZE_113 # define BOOST_PP_SEQ_SIZE_113(_) BOOST_PP_SEQ_SIZE_114 # define BOOST_PP_SEQ_SIZE_114(_) BOOST_PP_SEQ_SIZE_115 # define BOOST_PP_SEQ_SIZE_115(_) BOOST_PP_SEQ_SIZE_116 # define BOOST_PP_SEQ_SIZE_116(_) BOOST_PP_SEQ_SIZE_117 # define BOOST_PP_SEQ_SIZE_117(_) BOOST_PP_SEQ_SIZE_118 # define BOOST_PP_SEQ_SIZE_118(_) BOOST_PP_SEQ_SIZE_119 # define BOOST_PP_SEQ_SIZE_119(_) BOOST_PP_SEQ_SIZE_120 # define BOOST_PP_SEQ_SIZE_120(_) BOOST_PP_SEQ_SIZE_121 # define BOOST_PP_SEQ_SIZE_121(_) BOOST_PP_SEQ_SIZE_122 # define BOOST_PP_SEQ_SIZE_122(_) BOOST_PP_SEQ_SIZE_123 # define BOOST_PP_SEQ_SIZE_123(_) BOOST_PP_SEQ_SIZE_124 # define BOOST_PP_SEQ_SIZE_124(_) BOOST_PP_SEQ_SIZE_125 # define BOOST_PP_SEQ_SIZE_125(_) BOOST_PP_SEQ_SIZE_126 # define BOOST_PP_SEQ_SIZE_126(_) BOOST_PP_SEQ_SIZE_127 # define BOOST_PP_SEQ_SIZE_127(_) BOOST_PP_SEQ_SIZE_128 # define BOOST_PP_SEQ_SIZE_128(_) BOOST_PP_SEQ_SIZE_129 # define BOOST_PP_SEQ_SIZE_129(_) BOOST_PP_SEQ_SIZE_130 # define BOOST_PP_SEQ_SIZE_130(_) BOOST_PP_SEQ_SIZE_131 # define BOOST_PP_SEQ_SIZE_131(_) BOOST_PP_SEQ_SIZE_132 # define BOOST_PP_SEQ_SIZE_132(_) BOOST_PP_SEQ_SIZE_133 # define BOOST_PP_SEQ_SIZE_133(_) BOOST_PP_SEQ_SIZE_134 # define BOOST_PP_SEQ_SIZE_134(_) BOOST_PP_SEQ_SIZE_135 # define BOOST_PP_SEQ_SIZE_135(_) BOOST_PP_SEQ_SIZE_136 # define BOOST_PP_SEQ_SIZE_136(_) BOOST_PP_SEQ_SIZE_137 # define BOOST_PP_SEQ_SIZE_137(_) BOOST_PP_SEQ_SIZE_138 # define BOOST_PP_SEQ_SIZE_138(_) BOOST_PP_SEQ_SIZE_139 # define BOOST_PP_SEQ_SIZE_139(_) BOOST_PP_SEQ_SIZE_140 # define BOOST_PP_SEQ_SIZE_140(_) BOOST_PP_SEQ_SIZE_141 # define BOOST_PP_SEQ_SIZE_141(_) BOOST_PP_SEQ_SIZE_142 # define BOOST_PP_SEQ_SIZE_142(_) BOOST_PP_SEQ_SIZE_143 # define BOOST_PP_SEQ_SIZE_143(_) BOOST_PP_SEQ_SIZE_144 # define BOOST_PP_SEQ_SIZE_144(_) BOOST_PP_SEQ_SIZE_145 # define BOOST_PP_SEQ_SIZE_145(_) BOOST_PP_SEQ_SIZE_146 # define BOOST_PP_SEQ_SIZE_146(_) BOOST_PP_SEQ_SIZE_147 # define BOOST_PP_SEQ_SIZE_147(_) BOOST_PP_SEQ_SIZE_148 # define BOOST_PP_SEQ_SIZE_148(_) BOOST_PP_SEQ_SIZE_149 # define BOOST_PP_SEQ_SIZE_149(_) BOOST_PP_SEQ_SIZE_150 # define BOOST_PP_SEQ_SIZE_150(_) BOOST_PP_SEQ_SIZE_151 # define BOOST_PP_SEQ_SIZE_151(_) BOOST_PP_SEQ_SIZE_152 # define BOOST_PP_SEQ_SIZE_152(_) BOOST_PP_SEQ_SIZE_153 # define BOOST_PP_SEQ_SIZE_153(_) BOOST_PP_SEQ_SIZE_154 # define BOOST_PP_SEQ_SIZE_154(_) BOOST_PP_SEQ_SIZE_155 # define BOOST_PP_SEQ_SIZE_155(_) BOOST_PP_SEQ_SIZE_156 # define BOOST_PP_SEQ_SIZE_156(_) BOOST_PP_SEQ_SIZE_157 # define BOOST_PP_SEQ_SIZE_157(_) BOOST_PP_SEQ_SIZE_158 # define BOOST_PP_SEQ_SIZE_158(_) BOOST_PP_SEQ_SIZE_159 # define BOOST_PP_SEQ_SIZE_159(_) BOOST_PP_SEQ_SIZE_160 # define BOOST_PP_SEQ_SIZE_160(_) BOOST_PP_SEQ_SIZE_161 # define BOOST_PP_SEQ_SIZE_161(_) BOOST_PP_SEQ_SIZE_162 # define BOOST_PP_SEQ_SIZE_162(_) BOOST_PP_SEQ_SIZE_163 # define BOOST_PP_SEQ_SIZE_163(_) BOOST_PP_SEQ_SIZE_164 # define BOOST_PP_SEQ_SIZE_164(_) BOOST_PP_SEQ_SIZE_165 # define BOOST_PP_SEQ_SIZE_165(_) BOOST_PP_SEQ_SIZE_166 # define BOOST_PP_SEQ_SIZE_166(_) BOOST_PP_SEQ_SIZE_167 # define BOOST_PP_SEQ_SIZE_167(_) BOOST_PP_SEQ_SIZE_168 # define BOOST_PP_SEQ_SIZE_168(_) BOOST_PP_SEQ_SIZE_169 # define BOOST_PP_SEQ_SIZE_169(_) BOOST_PP_SEQ_SIZE_170 # define BOOST_PP_SEQ_SIZE_170(_) BOOST_PP_SEQ_SIZE_171 # define BOOST_PP_SEQ_SIZE_171(_) BOOST_PP_SEQ_SIZE_172 # define BOOST_PP_SEQ_SIZE_172(_) BOOST_PP_SEQ_SIZE_173 # define BOOST_PP_SEQ_SIZE_173(_) BOOST_PP_SEQ_SIZE_174 # define BOOST_PP_SEQ_SIZE_174(_) BOOST_PP_SEQ_SIZE_175 # define BOOST_PP_SEQ_SIZE_175(_) BOOST_PP_SEQ_SIZE_176 # define BOOST_PP_SEQ_SIZE_176(_) BOOST_PP_SEQ_SIZE_177 # define BOOST_PP_SEQ_SIZE_177(_) BOOST_PP_SEQ_SIZE_178 # define BOOST_PP_SEQ_SIZE_178(_) BOOST_PP_SEQ_SIZE_179 # define BOOST_PP_SEQ_SIZE_179(_) BOOST_PP_SEQ_SIZE_180 # define BOOST_PP_SEQ_SIZE_180(_) BOOST_PP_SEQ_SIZE_181 # define BOOST_PP_SEQ_SIZE_181(_) BOOST_PP_SEQ_SIZE_182 # define BOOST_PP_SEQ_SIZE_182(_) BOOST_PP_SEQ_SIZE_183 # define BOOST_PP_SEQ_SIZE_183(_) BOOST_PP_SEQ_SIZE_184 # define BOOST_PP_SEQ_SIZE_184(_) BOOST_PP_SEQ_SIZE_185 # define BOOST_PP_SEQ_SIZE_185(_) BOOST_PP_SEQ_SIZE_186 # define BOOST_PP_SEQ_SIZE_186(_) BOOST_PP_SEQ_SIZE_187 # define BOOST_PP_SEQ_SIZE_187(_) BOOST_PP_SEQ_SIZE_188 # define BOOST_PP_SEQ_SIZE_188(_) BOOST_PP_SEQ_SIZE_189 # define BOOST_PP_SEQ_SIZE_189(_) BOOST_PP_SEQ_SIZE_190 # define BOOST_PP_SEQ_SIZE_190(_) BOOST_PP_SEQ_SIZE_191 # define BOOST_PP_SEQ_SIZE_191(_) BOOST_PP_SEQ_SIZE_192 # define BOOST_PP_SEQ_SIZE_192(_) BOOST_PP_SEQ_SIZE_193 # define BOOST_PP_SEQ_SIZE_193(_) BOOST_PP_SEQ_SIZE_194 # define BOOST_PP_SEQ_SIZE_194(_) BOOST_PP_SEQ_SIZE_195 # define BOOST_PP_SEQ_SIZE_195(_) BOOST_PP_SEQ_SIZE_196 # define BOOST_PP_SEQ_SIZE_196(_) BOOST_PP_SEQ_SIZE_197 # define BOOST_PP_SEQ_SIZE_197(_) BOOST_PP_SEQ_SIZE_198 # define BOOST_PP_SEQ_SIZE_198(_) BOOST_PP_SEQ_SIZE_199 # define BOOST_PP_SEQ_SIZE_199(_) BOOST_PP_SEQ_SIZE_200 # define BOOST_PP_SEQ_SIZE_200(_) BOOST_PP_SEQ_SIZE_201 # define BOOST_PP_SEQ_SIZE_201(_) BOOST_PP_SEQ_SIZE_202 # define BOOST_PP_SEQ_SIZE_202(_) BOOST_PP_SEQ_SIZE_203 # define BOOST_PP_SEQ_SIZE_203(_) BOOST_PP_SEQ_SIZE_204 # define BOOST_PP_SEQ_SIZE_204(_) BOOST_PP_SEQ_SIZE_205 # define BOOST_PP_SEQ_SIZE_205(_) BOOST_PP_SEQ_SIZE_206 # define BOOST_PP_SEQ_SIZE_206(_) BOOST_PP_SEQ_SIZE_207 # define BOOST_PP_SEQ_SIZE_207(_) BOOST_PP_SEQ_SIZE_208 # define BOOST_PP_SEQ_SIZE_208(_) BOOST_PP_SEQ_SIZE_209 # define BOOST_PP_SEQ_SIZE_209(_) BOOST_PP_SEQ_SIZE_210 # define BOOST_PP_SEQ_SIZE_210(_) BOOST_PP_SEQ_SIZE_211 # define BOOST_PP_SEQ_SIZE_211(_) BOOST_PP_SEQ_SIZE_212 # define BOOST_PP_SEQ_SIZE_212(_) BOOST_PP_SEQ_SIZE_213 # define BOOST_PP_SEQ_SIZE_213(_) BOOST_PP_SEQ_SIZE_214 # define BOOST_PP_SEQ_SIZE_214(_) BOOST_PP_SEQ_SIZE_215 # define BOOST_PP_SEQ_SIZE_215(_) BOOST_PP_SEQ_SIZE_216 # define BOOST_PP_SEQ_SIZE_216(_) BOOST_PP_SEQ_SIZE_217 # define BOOST_PP_SEQ_SIZE_217(_) BOOST_PP_SEQ_SIZE_218 # define BOOST_PP_SEQ_SIZE_218(_) BOOST_PP_SEQ_SIZE_219 # define BOOST_PP_SEQ_SIZE_219(_) BOOST_PP_SEQ_SIZE_220 # define BOOST_PP_SEQ_SIZE_220(_) BOOST_PP_SEQ_SIZE_221 # define BOOST_PP_SEQ_SIZE_221(_) BOOST_PP_SEQ_SIZE_222 # define BOOST_PP_SEQ_SIZE_222(_) BOOST_PP_SEQ_SIZE_223 # define BOOST_PP_SEQ_SIZE_223(_) BOOST_PP_SEQ_SIZE_224 # define BOOST_PP_SEQ_SIZE_224(_) BOOST_PP_SEQ_SIZE_225 # define BOOST_PP_SEQ_SIZE_225(_) BOOST_PP_SEQ_SIZE_226 # define BOOST_PP_SEQ_SIZE_226(_) BOOST_PP_SEQ_SIZE_227 # define BOOST_PP_SEQ_SIZE_227(_) BOOST_PP_SEQ_SIZE_228 # define BOOST_PP_SEQ_SIZE_228(_) BOOST_PP_SEQ_SIZE_229 # define BOOST_PP_SEQ_SIZE_229(_) BOOST_PP_SEQ_SIZE_230 # define BOOST_PP_SEQ_SIZE_230(_) BOOST_PP_SEQ_SIZE_231 # define BOOST_PP_SEQ_SIZE_231(_) BOOST_PP_SEQ_SIZE_232 # define BOOST_PP_SEQ_SIZE_232(_) BOOST_PP_SEQ_SIZE_233 # define BOOST_PP_SEQ_SIZE_233(_) BOOST_PP_SEQ_SIZE_234 # define BOOST_PP_SEQ_SIZE_234(_) BOOST_PP_SEQ_SIZE_235 # define BOOST_PP_SEQ_SIZE_235(_) BOOST_PP_SEQ_SIZE_236 # define BOOST_PP_SEQ_SIZE_236(_) BOOST_PP_SEQ_SIZE_237 # define BOOST_PP_SEQ_SIZE_237(_) BOOST_PP_SEQ_SIZE_238 # define BOOST_PP_SEQ_SIZE_238(_) BOOST_PP_SEQ_SIZE_239 # define BOOST_PP_SEQ_SIZE_239(_) BOOST_PP_SEQ_SIZE_240 # define BOOST_PP_SEQ_SIZE_240(_) BOOST_PP_SEQ_SIZE_241 # define BOOST_PP_SEQ_SIZE_241(_) BOOST_PP_SEQ_SIZE_242 # define BOOST_PP_SEQ_SIZE_242(_) BOOST_PP_SEQ_SIZE_243 # define BOOST_PP_SEQ_SIZE_243(_) BOOST_PP_SEQ_SIZE_244 # define BOOST_PP_SEQ_SIZE_244(_) BOOST_PP_SEQ_SIZE_245 # define BOOST_PP_SEQ_SIZE_245(_) BOOST_PP_SEQ_SIZE_246 # define BOOST_PP_SEQ_SIZE_246(_) BOOST_PP_SEQ_SIZE_247 # define BOOST_PP_SEQ_SIZE_247(_) BOOST_PP_SEQ_SIZE_248 # define BOOST_PP_SEQ_SIZE_248(_) BOOST_PP_SEQ_SIZE_249 # define BOOST_PP_SEQ_SIZE_249(_) BOOST_PP_SEQ_SIZE_250 # define BOOST_PP_SEQ_SIZE_250(_) BOOST_PP_SEQ_SIZE_251 # define BOOST_PP_SEQ_SIZE_251(_) BOOST_PP_SEQ_SIZE_252 # define BOOST_PP_SEQ_SIZE_252(_) BOOST_PP_SEQ_SIZE_253 # define BOOST_PP_SEQ_SIZE_253(_) BOOST_PP_SEQ_SIZE_254 # define BOOST_PP_SEQ_SIZE_254(_) BOOST_PP_SEQ_SIZE_255 # define BOOST_PP_SEQ_SIZE_255(_) BOOST_PP_SEQ_SIZE_256 # define BOOST_PP_SEQ_SIZE_256(_) BOOST_PP_SEQ_SIZE_257 # # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_0 0 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_1 1 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_2 2 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_3 3 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_4 4 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_5 5 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_6 6 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_7 7 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_8 8 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_9 9 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_10 10 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_11 11 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_12 12 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_13 13 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_14 14 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_15 15 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_16 16 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_17 17 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_18 18 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_19 19 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_20 20 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_21 21 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_22 22 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_23 23 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_24 24 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_25 25 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_26 26 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_27 27 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_28 28 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_29 29 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_30 30 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_31 31 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_32 32 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_33 33 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_34 34 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_35 35 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_36 36 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_37 37 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_38 38 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_39 39 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_40 40 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_41 41 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_42 42 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_43 43 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_44 44 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_45 45 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_46 46 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_47 47 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_48 48 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_49 49 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_50 50 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_51 51 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_52 52 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_53 53 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_54 54 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_55 55 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_56 56 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_57 57 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_58 58 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_59 59 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_60 60 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_61 61 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_62 62 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_63 63 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_64 64 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_65 65 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_66 66 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_67 67 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_68 68 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_69 69 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_70 70 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_71 71 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_72 72 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_73 73 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_74 74 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_75 75 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_76 76 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_77 77 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_78 78 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_79 79 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_80 80 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_81 81 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_82 82 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_83 83 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_84 84 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_85 85 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_86 86 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_87 87 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_88 88 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_89 89 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_90 90 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_91 91 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_92 92 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_93 93 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_94 94 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_95 95 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_96 96 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_97 97 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_98 98 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_99 99 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_100 100 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_101 101 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_102 102 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_103 103 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_104 104 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_105 105 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_106 106 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_107 107 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_108 108 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_109 109 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_110 110 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_111 111 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_112 112 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_113 113 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_114 114 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_115 115 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_116 116 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_117 117 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_118 118 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_119 119 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_120 120 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_121 121 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_122 122 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_123 123 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_124 124 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_125 125 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_126 126 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_127 127 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_128 128 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_129 129 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_130 130 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_131 131 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_132 132 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_133 133 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_134 134 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_135 135 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_136 136 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_137 137 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_138 138 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_139 139 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_140 140 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_141 141 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_142 142 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_143 143 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_144 144 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_145 145 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_146 146 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_147 147 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_148 148 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_149 149 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_150 150 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_151 151 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_152 152 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_153 153 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_154 154 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_155 155 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_156 156 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_157 157 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_158 158 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_159 159 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_160 160 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_161 161 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_162 162 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_163 163 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_164 164 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_165 165 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_166 166 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_167 167 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_168 168 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_169 169 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_170 170 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_171 171 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_172 172 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_173 173 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_174 174 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_175 175 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_176 176 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_177 177 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_178 178 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_179 179 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_180 180 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_181 181 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_182 182 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_183 183 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_184 184 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_185 185 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_186 186 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_187 187 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_188 188 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_189 189 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_190 190 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_191 191 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_192 192 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_193 193 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_194 194 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_195 195 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_196 196 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_197 197 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_198 198 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_199 199 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_200 200 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_201 201 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_202 202 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_203 203 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_204 204 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_205 205 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_206 206 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_207 207 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_208 208 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_209 209 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_210 210 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_211 211 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_212 212 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_213 213 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_214 214 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_215 215 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_216 216 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_217 217 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_218 218 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_219 219 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_220 220 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_221 221 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_222 222 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_223 223 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_224 224 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_225 225 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_226 226 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_227 227 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_228 228 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_229 229 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_230 230 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_231 231 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_232 232 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_233 233 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_234 234 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_235 235 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_236 236 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_237 237 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_238 238 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_239 239 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_240 240 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_241 241 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_242 242 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_243 243 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_244 244 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_245 245 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_246 246 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_247 247 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_248 248 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_249 249 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_250 250 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_251 251 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_252 252 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_253 253 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_254 254 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_255 255 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_256 256 # define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_257 257 # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/seq/subseq.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SEQ_SUBSEQ_HPP # define BOOST_PREPROCESSOR_SEQ_SUBSEQ_HPP # # include # include # include # # /* BOOST_PP_SEQ_SUBSEQ */ # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_SEQ_SUBSEQ(seq, i, len) BOOST_PP_SEQ_FIRST_N(len, BOOST_PP_SEQ_REST_N(i, seq)) # else # define BOOST_PP_SEQ_SUBSEQ(seq, i, len) BOOST_PP_SEQ_SUBSEQ_I(seq, i, len) # define BOOST_PP_SEQ_SUBSEQ_I(seq, i, len) BOOST_PP_SEQ_FIRST_N(len, BOOST_PP_SEQ_REST_N(i, seq)) # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/counter.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2005. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # define BOOST_PP_VALUE BOOST_PP_COUNTER + 1 # # include # # undef BOOST_PP_COUNTER # # undef BOOST_PP_COUNTER_DIGIT_1 # undef BOOST_PP_COUNTER_DIGIT_2 # undef BOOST_PP_COUNTER_DIGIT_3 # undef BOOST_PP_COUNTER_DIGIT_4 # undef BOOST_PP_COUNTER_DIGIT_5 # undef BOOST_PP_COUNTER_DIGIT_6 # undef BOOST_PP_COUNTER_DIGIT_7 # undef BOOST_PP_COUNTER_DIGIT_8 # undef BOOST_PP_COUNTER_DIGIT_9 # undef BOOST_PP_COUNTER_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_10 == 0 # define BOOST_PP_COUNTER_DIGIT_10 0 # elif BOOST_PP_SLOT_TEMP_10 == 1 # define BOOST_PP_COUNTER_DIGIT_10 1 # elif BOOST_PP_SLOT_TEMP_10 == 2 # define BOOST_PP_COUNTER_DIGIT_10 2 # elif BOOST_PP_SLOT_TEMP_10 == 3 # define BOOST_PP_COUNTER_DIGIT_10 3 # elif BOOST_PP_SLOT_TEMP_10 == 4 # define BOOST_PP_COUNTER_DIGIT_10 4 # elif BOOST_PP_SLOT_TEMP_10 == 5 # define BOOST_PP_COUNTER_DIGIT_10 5 # elif BOOST_PP_SLOT_TEMP_10 == 6 # define BOOST_PP_COUNTER_DIGIT_10 6 # elif BOOST_PP_SLOT_TEMP_10 == 7 # define BOOST_PP_COUNTER_DIGIT_10 7 # elif BOOST_PP_SLOT_TEMP_10 == 8 # define BOOST_PP_COUNTER_DIGIT_10 8 # elif BOOST_PP_SLOT_TEMP_10 == 9 # define BOOST_PP_COUNTER_DIGIT_10 9 # endif # # if BOOST_PP_SLOT_TEMP_9 == 0 # define BOOST_PP_COUNTER_DIGIT_9 0 # elif BOOST_PP_SLOT_TEMP_9 == 1 # define BOOST_PP_COUNTER_DIGIT_9 1 # elif BOOST_PP_SLOT_TEMP_9 == 2 # define BOOST_PP_COUNTER_DIGIT_9 2 # elif BOOST_PP_SLOT_TEMP_9 == 3 # define BOOST_PP_COUNTER_DIGIT_9 3 # elif BOOST_PP_SLOT_TEMP_9 == 4 # define BOOST_PP_COUNTER_DIGIT_9 4 # elif BOOST_PP_SLOT_TEMP_9 == 5 # define BOOST_PP_COUNTER_DIGIT_9 5 # elif BOOST_PP_SLOT_TEMP_9 == 6 # define BOOST_PP_COUNTER_DIGIT_9 6 # elif BOOST_PP_SLOT_TEMP_9 == 7 # define BOOST_PP_COUNTER_DIGIT_9 7 # elif BOOST_PP_SLOT_TEMP_9 == 8 # define BOOST_PP_COUNTER_DIGIT_9 8 # elif BOOST_PP_SLOT_TEMP_9 == 9 # define BOOST_PP_COUNTER_DIGIT_9 9 # endif # # if BOOST_PP_SLOT_TEMP_8 == 0 # define BOOST_PP_COUNTER_DIGIT_8 0 # elif BOOST_PP_SLOT_TEMP_8 == 1 # define BOOST_PP_COUNTER_DIGIT_8 1 # elif BOOST_PP_SLOT_TEMP_8 == 2 # define BOOST_PP_COUNTER_DIGIT_8 2 # elif BOOST_PP_SLOT_TEMP_8 == 3 # define BOOST_PP_COUNTER_DIGIT_8 3 # elif BOOST_PP_SLOT_TEMP_8 == 4 # define BOOST_PP_COUNTER_DIGIT_8 4 # elif BOOST_PP_SLOT_TEMP_8 == 5 # define BOOST_PP_COUNTER_DIGIT_8 5 # elif BOOST_PP_SLOT_TEMP_8 == 6 # define BOOST_PP_COUNTER_DIGIT_8 6 # elif BOOST_PP_SLOT_TEMP_8 == 7 # define BOOST_PP_COUNTER_DIGIT_8 7 # elif BOOST_PP_SLOT_TEMP_8 == 8 # define BOOST_PP_COUNTER_DIGIT_8 8 # elif BOOST_PP_SLOT_TEMP_8 == 9 # define BOOST_PP_COUNTER_DIGIT_8 9 # endif # # if BOOST_PP_SLOT_TEMP_7 == 0 # define BOOST_PP_COUNTER_DIGIT_7 0 # elif BOOST_PP_SLOT_TEMP_7 == 1 # define BOOST_PP_COUNTER_DIGIT_7 1 # elif BOOST_PP_SLOT_TEMP_7 == 2 # define BOOST_PP_COUNTER_DIGIT_7 2 # elif BOOST_PP_SLOT_TEMP_7 == 3 # define BOOST_PP_COUNTER_DIGIT_7 3 # elif BOOST_PP_SLOT_TEMP_7 == 4 # define BOOST_PP_COUNTER_DIGIT_7 4 # elif BOOST_PP_SLOT_TEMP_7 == 5 # define BOOST_PP_COUNTER_DIGIT_7 5 # elif BOOST_PP_SLOT_TEMP_7 == 6 # define BOOST_PP_COUNTER_DIGIT_7 6 # elif BOOST_PP_SLOT_TEMP_7 == 7 # define BOOST_PP_COUNTER_DIGIT_7 7 # elif BOOST_PP_SLOT_TEMP_7 == 8 # define BOOST_PP_COUNTER_DIGIT_7 8 # elif BOOST_PP_SLOT_TEMP_7 == 9 # define BOOST_PP_COUNTER_DIGIT_7 9 # endif # # if BOOST_PP_SLOT_TEMP_6 == 0 # define BOOST_PP_COUNTER_DIGIT_6 0 # elif BOOST_PP_SLOT_TEMP_6 == 1 # define BOOST_PP_COUNTER_DIGIT_6 1 # elif BOOST_PP_SLOT_TEMP_6 == 2 # define BOOST_PP_COUNTER_DIGIT_6 2 # elif BOOST_PP_SLOT_TEMP_6 == 3 # define BOOST_PP_COUNTER_DIGIT_6 3 # elif BOOST_PP_SLOT_TEMP_6 == 4 # define BOOST_PP_COUNTER_DIGIT_6 4 # elif BOOST_PP_SLOT_TEMP_6 == 5 # define BOOST_PP_COUNTER_DIGIT_6 5 # elif BOOST_PP_SLOT_TEMP_6 == 6 # define BOOST_PP_COUNTER_DIGIT_6 6 # elif BOOST_PP_SLOT_TEMP_6 == 7 # define BOOST_PP_COUNTER_DIGIT_6 7 # elif BOOST_PP_SLOT_TEMP_6 == 8 # define BOOST_PP_COUNTER_DIGIT_6 8 # elif BOOST_PP_SLOT_TEMP_6 == 9 # define BOOST_PP_COUNTER_DIGIT_6 9 # endif # # if BOOST_PP_SLOT_TEMP_5 == 0 # define BOOST_PP_COUNTER_DIGIT_5 0 # elif BOOST_PP_SLOT_TEMP_5 == 1 # define BOOST_PP_COUNTER_DIGIT_5 1 # elif BOOST_PP_SLOT_TEMP_5 == 2 # define BOOST_PP_COUNTER_DIGIT_5 2 # elif BOOST_PP_SLOT_TEMP_5 == 3 # define BOOST_PP_COUNTER_DIGIT_5 3 # elif BOOST_PP_SLOT_TEMP_5 == 4 # define BOOST_PP_COUNTER_DIGIT_5 4 # elif BOOST_PP_SLOT_TEMP_5 == 5 # define BOOST_PP_COUNTER_DIGIT_5 5 # elif BOOST_PP_SLOT_TEMP_5 == 6 # define BOOST_PP_COUNTER_DIGIT_5 6 # elif BOOST_PP_SLOT_TEMP_5 == 7 # define BOOST_PP_COUNTER_DIGIT_5 7 # elif BOOST_PP_SLOT_TEMP_5 == 8 # define BOOST_PP_COUNTER_DIGIT_5 8 # elif BOOST_PP_SLOT_TEMP_5 == 9 # define BOOST_PP_COUNTER_DIGIT_5 9 # endif # # if BOOST_PP_SLOT_TEMP_4 == 0 # define BOOST_PP_COUNTER_DIGIT_4 0 # elif BOOST_PP_SLOT_TEMP_4 == 1 # define BOOST_PP_COUNTER_DIGIT_4 1 # elif BOOST_PP_SLOT_TEMP_4 == 2 # define BOOST_PP_COUNTER_DIGIT_4 2 # elif BOOST_PP_SLOT_TEMP_4 == 3 # define BOOST_PP_COUNTER_DIGIT_4 3 # elif BOOST_PP_SLOT_TEMP_4 == 4 # define BOOST_PP_COUNTER_DIGIT_4 4 # elif BOOST_PP_SLOT_TEMP_4 == 5 # define BOOST_PP_COUNTER_DIGIT_4 5 # elif BOOST_PP_SLOT_TEMP_4 == 6 # define BOOST_PP_COUNTER_DIGIT_4 6 # elif BOOST_PP_SLOT_TEMP_4 == 7 # define BOOST_PP_COUNTER_DIGIT_4 7 # elif BOOST_PP_SLOT_TEMP_4 == 8 # define BOOST_PP_COUNTER_DIGIT_4 8 # elif BOOST_PP_SLOT_TEMP_4 == 9 # define BOOST_PP_COUNTER_DIGIT_4 9 # endif # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_COUNTER_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_COUNTER_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_COUNTER_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_COUNTER_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_COUNTER_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_COUNTER_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_COUNTER_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_COUNTER_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_COUNTER_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_COUNTER_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_COUNTER_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_COUNTER_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_COUNTER_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_COUNTER_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_COUNTER_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_COUNTER_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_COUNTER_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_COUNTER_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_COUNTER_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_COUNTER_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_COUNTER_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_COUNTER_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_COUNTER_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_COUNTER_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_COUNTER_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_COUNTER_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_COUNTER_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_COUNTER_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_COUNTER_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_COUNTER_DIGIT_1 9 # endif # # if BOOST_PP_COUNTER_DIGIT_10 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_10(BOOST_PP_COUNTER_DIGIT_10, BOOST_PP_COUNTER_DIGIT_9, BOOST_PP_COUNTER_DIGIT_8, BOOST_PP_COUNTER_DIGIT_7, BOOST_PP_COUNTER_DIGIT_6, BOOST_PP_COUNTER_DIGIT_5, BOOST_PP_COUNTER_DIGIT_4, BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_9 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_9(BOOST_PP_COUNTER_DIGIT_9, BOOST_PP_COUNTER_DIGIT_8, BOOST_PP_COUNTER_DIGIT_7, BOOST_PP_COUNTER_DIGIT_6, BOOST_PP_COUNTER_DIGIT_5, BOOST_PP_COUNTER_DIGIT_4, BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_8 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_8(BOOST_PP_COUNTER_DIGIT_8, BOOST_PP_COUNTER_DIGIT_7, BOOST_PP_COUNTER_DIGIT_6, BOOST_PP_COUNTER_DIGIT_5, BOOST_PP_COUNTER_DIGIT_4, BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_7 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_7(BOOST_PP_COUNTER_DIGIT_7, BOOST_PP_COUNTER_DIGIT_6, BOOST_PP_COUNTER_DIGIT_5, BOOST_PP_COUNTER_DIGIT_4, BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_6 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_6(BOOST_PP_COUNTER_DIGIT_6, BOOST_PP_COUNTER_DIGIT_5, BOOST_PP_COUNTER_DIGIT_4, BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_5 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_5(BOOST_PP_COUNTER_DIGIT_5, BOOST_PP_COUNTER_DIGIT_4, BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_4 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_4(BOOST_PP_COUNTER_DIGIT_4, BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_3 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_3(BOOST_PP_COUNTER_DIGIT_3, BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # elif BOOST_PP_COUNTER_DIGIT_2 # define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_2(BOOST_PP_COUNTER_DIGIT_2, BOOST_PP_COUNTER_DIGIT_1) # else # define BOOST_PP_COUNTER BOOST_PP_COUNTER_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/def.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SLOT_DETAIL_DEF_HPP # define BOOST_PREPROCESSOR_SLOT_DETAIL_DEF_HPP # # /* BOOST_PP_SLOT_OFFSET_x */ # # define BOOST_PP_SLOT_OFFSET_10(x) (x) % 1000000000UL # define BOOST_PP_SLOT_OFFSET_9(x) BOOST_PP_SLOT_OFFSET_10(x) % 100000000UL # define BOOST_PP_SLOT_OFFSET_8(x) BOOST_PP_SLOT_OFFSET_9(x) % 10000000UL # define BOOST_PP_SLOT_OFFSET_7(x) BOOST_PP_SLOT_OFFSET_8(x) % 1000000UL # define BOOST_PP_SLOT_OFFSET_6(x) BOOST_PP_SLOT_OFFSET_7(x) % 100000UL # define BOOST_PP_SLOT_OFFSET_5(x) BOOST_PP_SLOT_OFFSET_6(x) % 10000UL # define BOOST_PP_SLOT_OFFSET_4(x) BOOST_PP_SLOT_OFFSET_5(x) % 1000UL # define BOOST_PP_SLOT_OFFSET_3(x) BOOST_PP_SLOT_OFFSET_4(x) % 100UL # define BOOST_PP_SLOT_OFFSET_2(x) BOOST_PP_SLOT_OFFSET_3(x) % 10UL # # /* BOOST_PP_SLOT_CC_x */ # # define BOOST_PP_SLOT_CC_2(a, b) BOOST_PP_SLOT_CC_2_D(a, b) # define BOOST_PP_SLOT_CC_3(a, b, c) BOOST_PP_SLOT_CC_3_D(a, b, c) # define BOOST_PP_SLOT_CC_4(a, b, c, d) BOOST_PP_SLOT_CC_4_D(a, b, c, d) # define BOOST_PP_SLOT_CC_5(a, b, c, d, e) BOOST_PP_SLOT_CC_5_D(a, b, c, d, e) # define BOOST_PP_SLOT_CC_6(a, b, c, d, e, f) BOOST_PP_SLOT_CC_6_D(a, b, c, d, e, f) # define BOOST_PP_SLOT_CC_7(a, b, c, d, e, f, g) BOOST_PP_SLOT_CC_7_D(a, b, c, d, e, f, g) # define BOOST_PP_SLOT_CC_8(a, b, c, d, e, f, g, h) BOOST_PP_SLOT_CC_8_D(a, b, c, d, e, f, g, h) # define BOOST_PP_SLOT_CC_9(a, b, c, d, e, f, g, h, i) BOOST_PP_SLOT_CC_9_D(a, b, c, d, e, f, g, h, i) # define BOOST_PP_SLOT_CC_10(a, b, c, d, e, f, g, h, i, j) BOOST_PP_SLOT_CC_10_D(a, b, c, d, e, f, g, h, i, j) # # define BOOST_PP_SLOT_CC_2_D(a, b) a ## b # define BOOST_PP_SLOT_CC_3_D(a, b, c) a ## b ## c # define BOOST_PP_SLOT_CC_4_D(a, b, c, d) a ## b ## c ## d # define BOOST_PP_SLOT_CC_5_D(a, b, c, d, e) a ## b ## c ## d ## e # define BOOST_PP_SLOT_CC_6_D(a, b, c, d, e, f) a ## b ## c ## d ## e ## f # define BOOST_PP_SLOT_CC_7_D(a, b, c, d, e, f, g) a ## b ## c ## d ## e ## f ## g # define BOOST_PP_SLOT_CC_8_D(a, b, c, d, e, f, g, h) a ## b ## c ## d ## e ## f ## g ## h # define BOOST_PP_SLOT_CC_9_D(a, b, c, d, e, f, g, h, i) a ## b ## c ## d ## e ## f ## g ## h ## i # define BOOST_PP_SLOT_CC_10_D(a, b, c, d, e, f, g, h, i, j) a ## b ## c ## d ## e ## f ## g ## h ## i ## j # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/shared.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PP_VALUE # error BOOST_PP_ERROR: BOOST_PP_VALUE is not defined # endif # # undef BOOST_PP_SLOT_TEMP_1 # undef BOOST_PP_SLOT_TEMP_2 # undef BOOST_PP_SLOT_TEMP_3 # undef BOOST_PP_SLOT_TEMP_4 # undef BOOST_PP_SLOT_TEMP_5 # undef BOOST_PP_SLOT_TEMP_6 # undef BOOST_PP_SLOT_TEMP_7 # undef BOOST_PP_SLOT_TEMP_8 # undef BOOST_PP_SLOT_TEMP_9 # undef BOOST_PP_SLOT_TEMP_10 # # if (BOOST_PP_VALUE) / 1000000000UL == 0 # define BOOST_PP_SLOT_TEMP_10 0 # elif (BOOST_PP_VALUE) / 1000000000UL == 1 # define BOOST_PP_SLOT_TEMP_10 1 # elif (BOOST_PP_VALUE) / 1000000000UL == 2 # define BOOST_PP_SLOT_TEMP_10 2 # elif (BOOST_PP_VALUE) / 1000000000UL == 3 # define BOOST_PP_SLOT_TEMP_10 3 # elif (BOOST_PP_VALUE) / 1000000000UL == 4 # define BOOST_PP_SLOT_TEMP_10 4 # elif (BOOST_PP_VALUE) / 1000000000UL == 5 # define BOOST_PP_SLOT_TEMP_10 5 # elif (BOOST_PP_VALUE) / 1000000000UL == 6 # define BOOST_PP_SLOT_TEMP_10 6 # elif (BOOST_PP_VALUE) / 1000000000UL == 7 # define BOOST_PP_SLOT_TEMP_10 7 # elif (BOOST_PP_VALUE) / 1000000000UL == 8 # define BOOST_PP_SLOT_TEMP_10 8 # elif (BOOST_PP_VALUE) / 1000000000UL == 9 # define BOOST_PP_SLOT_TEMP_10 9 # endif # # if BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 0 # define BOOST_PP_SLOT_TEMP_9 0 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 1 # define BOOST_PP_SLOT_TEMP_9 1 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 2 # define BOOST_PP_SLOT_TEMP_9 2 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 3 # define BOOST_PP_SLOT_TEMP_9 3 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 4 # define BOOST_PP_SLOT_TEMP_9 4 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 5 # define BOOST_PP_SLOT_TEMP_9 5 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 6 # define BOOST_PP_SLOT_TEMP_9 6 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 7 # define BOOST_PP_SLOT_TEMP_9 7 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 8 # define BOOST_PP_SLOT_TEMP_9 8 # elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 9 # define BOOST_PP_SLOT_TEMP_9 9 # endif # # if BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 0 # define BOOST_PP_SLOT_TEMP_8 0 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 1 # define BOOST_PP_SLOT_TEMP_8 1 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 2 # define BOOST_PP_SLOT_TEMP_8 2 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 3 # define BOOST_PP_SLOT_TEMP_8 3 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 4 # define BOOST_PP_SLOT_TEMP_8 4 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 5 # define BOOST_PP_SLOT_TEMP_8 5 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 6 # define BOOST_PP_SLOT_TEMP_8 6 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 7 # define BOOST_PP_SLOT_TEMP_8 7 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 8 # define BOOST_PP_SLOT_TEMP_8 8 # elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 9 # define BOOST_PP_SLOT_TEMP_8 9 # endif # # if BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 0 # define BOOST_PP_SLOT_TEMP_7 0 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 1 # define BOOST_PP_SLOT_TEMP_7 1 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 2 # define BOOST_PP_SLOT_TEMP_7 2 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 3 # define BOOST_PP_SLOT_TEMP_7 3 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 4 # define BOOST_PP_SLOT_TEMP_7 4 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 5 # define BOOST_PP_SLOT_TEMP_7 5 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 6 # define BOOST_PP_SLOT_TEMP_7 6 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 7 # define BOOST_PP_SLOT_TEMP_7 7 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 8 # define BOOST_PP_SLOT_TEMP_7 8 # elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 9 # define BOOST_PP_SLOT_TEMP_7 9 # endif # # if BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 0 # define BOOST_PP_SLOT_TEMP_6 0 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 1 # define BOOST_PP_SLOT_TEMP_6 1 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 2 # define BOOST_PP_SLOT_TEMP_6 2 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 3 # define BOOST_PP_SLOT_TEMP_6 3 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 4 # define BOOST_PP_SLOT_TEMP_6 4 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 5 # define BOOST_PP_SLOT_TEMP_6 5 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 6 # define BOOST_PP_SLOT_TEMP_6 6 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 7 # define BOOST_PP_SLOT_TEMP_6 7 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 8 # define BOOST_PP_SLOT_TEMP_6 8 # elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 9 # define BOOST_PP_SLOT_TEMP_6 9 # endif # # if BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 0 # define BOOST_PP_SLOT_TEMP_5 0 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 1 # define BOOST_PP_SLOT_TEMP_5 1 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 2 # define BOOST_PP_SLOT_TEMP_5 2 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 3 # define BOOST_PP_SLOT_TEMP_5 3 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 4 # define BOOST_PP_SLOT_TEMP_5 4 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 5 # define BOOST_PP_SLOT_TEMP_5 5 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 6 # define BOOST_PP_SLOT_TEMP_5 6 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 7 # define BOOST_PP_SLOT_TEMP_5 7 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 8 # define BOOST_PP_SLOT_TEMP_5 8 # elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 9 # define BOOST_PP_SLOT_TEMP_5 9 # endif # # if BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 0 # define BOOST_PP_SLOT_TEMP_4 0 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 1 # define BOOST_PP_SLOT_TEMP_4 1 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 2 # define BOOST_PP_SLOT_TEMP_4 2 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 3 # define BOOST_PP_SLOT_TEMP_4 3 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 4 # define BOOST_PP_SLOT_TEMP_4 4 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 5 # define BOOST_PP_SLOT_TEMP_4 5 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 6 # define BOOST_PP_SLOT_TEMP_4 6 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 7 # define BOOST_PP_SLOT_TEMP_4 7 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 8 # define BOOST_PP_SLOT_TEMP_4 8 # elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 9 # define BOOST_PP_SLOT_TEMP_4 9 # endif # # if BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 0 # define BOOST_PP_SLOT_TEMP_3 0 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 1 # define BOOST_PP_SLOT_TEMP_3 1 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 2 # define BOOST_PP_SLOT_TEMP_3 2 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 3 # define BOOST_PP_SLOT_TEMP_3 3 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 4 # define BOOST_PP_SLOT_TEMP_3 4 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 5 # define BOOST_PP_SLOT_TEMP_3 5 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 6 # define BOOST_PP_SLOT_TEMP_3 6 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 7 # define BOOST_PP_SLOT_TEMP_3 7 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 8 # define BOOST_PP_SLOT_TEMP_3 8 # elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 9 # define BOOST_PP_SLOT_TEMP_3 9 # endif # # if BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 0 # define BOOST_PP_SLOT_TEMP_2 0 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 1 # define BOOST_PP_SLOT_TEMP_2 1 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 2 # define BOOST_PP_SLOT_TEMP_2 2 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 3 # define BOOST_PP_SLOT_TEMP_2 3 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 4 # define BOOST_PP_SLOT_TEMP_2 4 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 5 # define BOOST_PP_SLOT_TEMP_2 5 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 6 # define BOOST_PP_SLOT_TEMP_2 6 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 7 # define BOOST_PP_SLOT_TEMP_2 7 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 8 # define BOOST_PP_SLOT_TEMP_2 8 # elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 9 # define BOOST_PP_SLOT_TEMP_2 9 # endif # # if BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 0 # define BOOST_PP_SLOT_TEMP_1 0 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 1 # define BOOST_PP_SLOT_TEMP_1 1 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 2 # define BOOST_PP_SLOT_TEMP_1 2 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 3 # define BOOST_PP_SLOT_TEMP_1 3 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 4 # define BOOST_PP_SLOT_TEMP_1 4 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 5 # define BOOST_PP_SLOT_TEMP_1 5 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 6 # define BOOST_PP_SLOT_TEMP_1 6 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 7 # define BOOST_PP_SLOT_TEMP_1 7 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 8 # define BOOST_PP_SLOT_TEMP_1 8 # elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 9 # define BOOST_PP_SLOT_TEMP_1 9 # endif # # undef BOOST_PP_VALUE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/slot1.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_SLOT_1 # # undef BOOST_PP_SLOT_1_DIGIT_1 # undef BOOST_PP_SLOT_1_DIGIT_2 # undef BOOST_PP_SLOT_1_DIGIT_3 # undef BOOST_PP_SLOT_1_DIGIT_4 # undef BOOST_PP_SLOT_1_DIGIT_5 # undef BOOST_PP_SLOT_1_DIGIT_6 # undef BOOST_PP_SLOT_1_DIGIT_7 # undef BOOST_PP_SLOT_1_DIGIT_8 # undef BOOST_PP_SLOT_1_DIGIT_9 # undef BOOST_PP_SLOT_1_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_10 == 0 # define BOOST_PP_SLOT_1_DIGIT_10 0 # elif BOOST_PP_SLOT_TEMP_10 == 1 # define BOOST_PP_SLOT_1_DIGIT_10 1 # elif BOOST_PP_SLOT_TEMP_10 == 2 # define BOOST_PP_SLOT_1_DIGIT_10 2 # elif BOOST_PP_SLOT_TEMP_10 == 3 # define BOOST_PP_SLOT_1_DIGIT_10 3 # elif BOOST_PP_SLOT_TEMP_10 == 4 # define BOOST_PP_SLOT_1_DIGIT_10 4 # elif BOOST_PP_SLOT_TEMP_10 == 5 # define BOOST_PP_SLOT_1_DIGIT_10 5 # elif BOOST_PP_SLOT_TEMP_10 == 6 # define BOOST_PP_SLOT_1_DIGIT_10 6 # elif BOOST_PP_SLOT_TEMP_10 == 7 # define BOOST_PP_SLOT_1_DIGIT_10 7 # elif BOOST_PP_SLOT_TEMP_10 == 8 # define BOOST_PP_SLOT_1_DIGIT_10 8 # elif BOOST_PP_SLOT_TEMP_10 == 9 # define BOOST_PP_SLOT_1_DIGIT_10 9 # endif # # if BOOST_PP_SLOT_TEMP_9 == 0 # define BOOST_PP_SLOT_1_DIGIT_9 0 # elif BOOST_PP_SLOT_TEMP_9 == 1 # define BOOST_PP_SLOT_1_DIGIT_9 1 # elif BOOST_PP_SLOT_TEMP_9 == 2 # define BOOST_PP_SLOT_1_DIGIT_9 2 # elif BOOST_PP_SLOT_TEMP_9 == 3 # define BOOST_PP_SLOT_1_DIGIT_9 3 # elif BOOST_PP_SLOT_TEMP_9 == 4 # define BOOST_PP_SLOT_1_DIGIT_9 4 # elif BOOST_PP_SLOT_TEMP_9 == 5 # define BOOST_PP_SLOT_1_DIGIT_9 5 # elif BOOST_PP_SLOT_TEMP_9 == 6 # define BOOST_PP_SLOT_1_DIGIT_9 6 # elif BOOST_PP_SLOT_TEMP_9 == 7 # define BOOST_PP_SLOT_1_DIGIT_9 7 # elif BOOST_PP_SLOT_TEMP_9 == 8 # define BOOST_PP_SLOT_1_DIGIT_9 8 # elif BOOST_PP_SLOT_TEMP_9 == 9 # define BOOST_PP_SLOT_1_DIGIT_9 9 # endif # # if BOOST_PP_SLOT_TEMP_8 == 0 # define BOOST_PP_SLOT_1_DIGIT_8 0 # elif BOOST_PP_SLOT_TEMP_8 == 1 # define BOOST_PP_SLOT_1_DIGIT_8 1 # elif BOOST_PP_SLOT_TEMP_8 == 2 # define BOOST_PP_SLOT_1_DIGIT_8 2 # elif BOOST_PP_SLOT_TEMP_8 == 3 # define BOOST_PP_SLOT_1_DIGIT_8 3 # elif BOOST_PP_SLOT_TEMP_8 == 4 # define BOOST_PP_SLOT_1_DIGIT_8 4 # elif BOOST_PP_SLOT_TEMP_8 == 5 # define BOOST_PP_SLOT_1_DIGIT_8 5 # elif BOOST_PP_SLOT_TEMP_8 == 6 # define BOOST_PP_SLOT_1_DIGIT_8 6 # elif BOOST_PP_SLOT_TEMP_8 == 7 # define BOOST_PP_SLOT_1_DIGIT_8 7 # elif BOOST_PP_SLOT_TEMP_8 == 8 # define BOOST_PP_SLOT_1_DIGIT_8 8 # elif BOOST_PP_SLOT_TEMP_8 == 9 # define BOOST_PP_SLOT_1_DIGIT_8 9 # endif # # if BOOST_PP_SLOT_TEMP_7 == 0 # define BOOST_PP_SLOT_1_DIGIT_7 0 # elif BOOST_PP_SLOT_TEMP_7 == 1 # define BOOST_PP_SLOT_1_DIGIT_7 1 # elif BOOST_PP_SLOT_TEMP_7 == 2 # define BOOST_PP_SLOT_1_DIGIT_7 2 # elif BOOST_PP_SLOT_TEMP_7 == 3 # define BOOST_PP_SLOT_1_DIGIT_7 3 # elif BOOST_PP_SLOT_TEMP_7 == 4 # define BOOST_PP_SLOT_1_DIGIT_7 4 # elif BOOST_PP_SLOT_TEMP_7 == 5 # define BOOST_PP_SLOT_1_DIGIT_7 5 # elif BOOST_PP_SLOT_TEMP_7 == 6 # define BOOST_PP_SLOT_1_DIGIT_7 6 # elif BOOST_PP_SLOT_TEMP_7 == 7 # define BOOST_PP_SLOT_1_DIGIT_7 7 # elif BOOST_PP_SLOT_TEMP_7 == 8 # define BOOST_PP_SLOT_1_DIGIT_7 8 # elif BOOST_PP_SLOT_TEMP_7 == 9 # define BOOST_PP_SLOT_1_DIGIT_7 9 # endif # # if BOOST_PP_SLOT_TEMP_6 == 0 # define BOOST_PP_SLOT_1_DIGIT_6 0 # elif BOOST_PP_SLOT_TEMP_6 == 1 # define BOOST_PP_SLOT_1_DIGIT_6 1 # elif BOOST_PP_SLOT_TEMP_6 == 2 # define BOOST_PP_SLOT_1_DIGIT_6 2 # elif BOOST_PP_SLOT_TEMP_6 == 3 # define BOOST_PP_SLOT_1_DIGIT_6 3 # elif BOOST_PP_SLOT_TEMP_6 == 4 # define BOOST_PP_SLOT_1_DIGIT_6 4 # elif BOOST_PP_SLOT_TEMP_6 == 5 # define BOOST_PP_SLOT_1_DIGIT_6 5 # elif BOOST_PP_SLOT_TEMP_6 == 6 # define BOOST_PP_SLOT_1_DIGIT_6 6 # elif BOOST_PP_SLOT_TEMP_6 == 7 # define BOOST_PP_SLOT_1_DIGIT_6 7 # elif BOOST_PP_SLOT_TEMP_6 == 8 # define BOOST_PP_SLOT_1_DIGIT_6 8 # elif BOOST_PP_SLOT_TEMP_6 == 9 # define BOOST_PP_SLOT_1_DIGIT_6 9 # endif # # if BOOST_PP_SLOT_TEMP_5 == 0 # define BOOST_PP_SLOT_1_DIGIT_5 0 # elif BOOST_PP_SLOT_TEMP_5 == 1 # define BOOST_PP_SLOT_1_DIGIT_5 1 # elif BOOST_PP_SLOT_TEMP_5 == 2 # define BOOST_PP_SLOT_1_DIGIT_5 2 # elif BOOST_PP_SLOT_TEMP_5 == 3 # define BOOST_PP_SLOT_1_DIGIT_5 3 # elif BOOST_PP_SLOT_TEMP_5 == 4 # define BOOST_PP_SLOT_1_DIGIT_5 4 # elif BOOST_PP_SLOT_TEMP_5 == 5 # define BOOST_PP_SLOT_1_DIGIT_5 5 # elif BOOST_PP_SLOT_TEMP_5 == 6 # define BOOST_PP_SLOT_1_DIGIT_5 6 # elif BOOST_PP_SLOT_TEMP_5 == 7 # define BOOST_PP_SLOT_1_DIGIT_5 7 # elif BOOST_PP_SLOT_TEMP_5 == 8 # define BOOST_PP_SLOT_1_DIGIT_5 8 # elif BOOST_PP_SLOT_TEMP_5 == 9 # define BOOST_PP_SLOT_1_DIGIT_5 9 # endif # # if BOOST_PP_SLOT_TEMP_4 == 0 # define BOOST_PP_SLOT_1_DIGIT_4 0 # elif BOOST_PP_SLOT_TEMP_4 == 1 # define BOOST_PP_SLOT_1_DIGIT_4 1 # elif BOOST_PP_SLOT_TEMP_4 == 2 # define BOOST_PP_SLOT_1_DIGIT_4 2 # elif BOOST_PP_SLOT_TEMP_4 == 3 # define BOOST_PP_SLOT_1_DIGIT_4 3 # elif BOOST_PP_SLOT_TEMP_4 == 4 # define BOOST_PP_SLOT_1_DIGIT_4 4 # elif BOOST_PP_SLOT_TEMP_4 == 5 # define BOOST_PP_SLOT_1_DIGIT_4 5 # elif BOOST_PP_SLOT_TEMP_4 == 6 # define BOOST_PP_SLOT_1_DIGIT_4 6 # elif BOOST_PP_SLOT_TEMP_4 == 7 # define BOOST_PP_SLOT_1_DIGIT_4 7 # elif BOOST_PP_SLOT_TEMP_4 == 8 # define BOOST_PP_SLOT_1_DIGIT_4 8 # elif BOOST_PP_SLOT_TEMP_4 == 9 # define BOOST_PP_SLOT_1_DIGIT_4 9 # endif # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_SLOT_1_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_SLOT_1_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_SLOT_1_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_SLOT_1_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_SLOT_1_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_SLOT_1_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_SLOT_1_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_SLOT_1_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_SLOT_1_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_SLOT_1_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_SLOT_1_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_SLOT_1_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_SLOT_1_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_SLOT_1_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_SLOT_1_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_SLOT_1_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_SLOT_1_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_SLOT_1_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_SLOT_1_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_SLOT_1_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_SLOT_1_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_SLOT_1_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_SLOT_1_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_SLOT_1_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_SLOT_1_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_SLOT_1_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_SLOT_1_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_SLOT_1_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_SLOT_1_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_SLOT_1_DIGIT_1 9 # endif # # if BOOST_PP_SLOT_1_DIGIT_10 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_10(BOOST_PP_SLOT_1_DIGIT_10, BOOST_PP_SLOT_1_DIGIT_9, BOOST_PP_SLOT_1_DIGIT_8, BOOST_PP_SLOT_1_DIGIT_7, BOOST_PP_SLOT_1_DIGIT_6, BOOST_PP_SLOT_1_DIGIT_5, BOOST_PP_SLOT_1_DIGIT_4, BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_9 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_9(BOOST_PP_SLOT_1_DIGIT_9, BOOST_PP_SLOT_1_DIGIT_8, BOOST_PP_SLOT_1_DIGIT_7, BOOST_PP_SLOT_1_DIGIT_6, BOOST_PP_SLOT_1_DIGIT_5, BOOST_PP_SLOT_1_DIGIT_4, BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_8 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_8(BOOST_PP_SLOT_1_DIGIT_8, BOOST_PP_SLOT_1_DIGIT_7, BOOST_PP_SLOT_1_DIGIT_6, BOOST_PP_SLOT_1_DIGIT_5, BOOST_PP_SLOT_1_DIGIT_4, BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_7 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_7(BOOST_PP_SLOT_1_DIGIT_7, BOOST_PP_SLOT_1_DIGIT_6, BOOST_PP_SLOT_1_DIGIT_5, BOOST_PP_SLOT_1_DIGIT_4, BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_6 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_6(BOOST_PP_SLOT_1_DIGIT_6, BOOST_PP_SLOT_1_DIGIT_5, BOOST_PP_SLOT_1_DIGIT_4, BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_5 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_5(BOOST_PP_SLOT_1_DIGIT_5, BOOST_PP_SLOT_1_DIGIT_4, BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_4 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_4(BOOST_PP_SLOT_1_DIGIT_4, BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_3 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_3(BOOST_PP_SLOT_1_DIGIT_3, BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # elif BOOST_PP_SLOT_1_DIGIT_2 # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_CC_2(BOOST_PP_SLOT_1_DIGIT_2, BOOST_PP_SLOT_1_DIGIT_1) # else # define BOOST_PP_SLOT_1() BOOST_PP_SLOT_1_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/slot2.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_SLOT_2 # # undef BOOST_PP_SLOT_2_DIGIT_1 # undef BOOST_PP_SLOT_2_DIGIT_2 # undef BOOST_PP_SLOT_2_DIGIT_3 # undef BOOST_PP_SLOT_2_DIGIT_4 # undef BOOST_PP_SLOT_2_DIGIT_5 # undef BOOST_PP_SLOT_2_DIGIT_6 # undef BOOST_PP_SLOT_2_DIGIT_7 # undef BOOST_PP_SLOT_2_DIGIT_8 # undef BOOST_PP_SLOT_2_DIGIT_9 # undef BOOST_PP_SLOT_2_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_10 == 0 # define BOOST_PP_SLOT_2_DIGIT_10 0 # elif BOOST_PP_SLOT_TEMP_10 == 1 # define BOOST_PP_SLOT_2_DIGIT_10 1 # elif BOOST_PP_SLOT_TEMP_10 == 2 # define BOOST_PP_SLOT_2_DIGIT_10 2 # elif BOOST_PP_SLOT_TEMP_10 == 3 # define BOOST_PP_SLOT_2_DIGIT_10 3 # elif BOOST_PP_SLOT_TEMP_10 == 4 # define BOOST_PP_SLOT_2_DIGIT_10 4 # elif BOOST_PP_SLOT_TEMP_10 == 5 # define BOOST_PP_SLOT_2_DIGIT_10 5 # elif BOOST_PP_SLOT_TEMP_10 == 6 # define BOOST_PP_SLOT_2_DIGIT_10 6 # elif BOOST_PP_SLOT_TEMP_10 == 7 # define BOOST_PP_SLOT_2_DIGIT_10 7 # elif BOOST_PP_SLOT_TEMP_10 == 8 # define BOOST_PP_SLOT_2_DIGIT_10 8 # elif BOOST_PP_SLOT_TEMP_10 == 9 # define BOOST_PP_SLOT_2_DIGIT_10 9 # endif # # if BOOST_PP_SLOT_TEMP_9 == 0 # define BOOST_PP_SLOT_2_DIGIT_9 0 # elif BOOST_PP_SLOT_TEMP_9 == 1 # define BOOST_PP_SLOT_2_DIGIT_9 1 # elif BOOST_PP_SLOT_TEMP_9 == 2 # define BOOST_PP_SLOT_2_DIGIT_9 2 # elif BOOST_PP_SLOT_TEMP_9 == 3 # define BOOST_PP_SLOT_2_DIGIT_9 3 # elif BOOST_PP_SLOT_TEMP_9 == 4 # define BOOST_PP_SLOT_2_DIGIT_9 4 # elif BOOST_PP_SLOT_TEMP_9 == 5 # define BOOST_PP_SLOT_2_DIGIT_9 5 # elif BOOST_PP_SLOT_TEMP_9 == 6 # define BOOST_PP_SLOT_2_DIGIT_9 6 # elif BOOST_PP_SLOT_TEMP_9 == 7 # define BOOST_PP_SLOT_2_DIGIT_9 7 # elif BOOST_PP_SLOT_TEMP_9 == 8 # define BOOST_PP_SLOT_2_DIGIT_9 8 # elif BOOST_PP_SLOT_TEMP_9 == 9 # define BOOST_PP_SLOT_2_DIGIT_9 9 # endif # # if BOOST_PP_SLOT_TEMP_8 == 0 # define BOOST_PP_SLOT_2_DIGIT_8 0 # elif BOOST_PP_SLOT_TEMP_8 == 1 # define BOOST_PP_SLOT_2_DIGIT_8 1 # elif BOOST_PP_SLOT_TEMP_8 == 2 # define BOOST_PP_SLOT_2_DIGIT_8 2 # elif BOOST_PP_SLOT_TEMP_8 == 3 # define BOOST_PP_SLOT_2_DIGIT_8 3 # elif BOOST_PP_SLOT_TEMP_8 == 4 # define BOOST_PP_SLOT_2_DIGIT_8 4 # elif BOOST_PP_SLOT_TEMP_8 == 5 # define BOOST_PP_SLOT_2_DIGIT_8 5 # elif BOOST_PP_SLOT_TEMP_8 == 6 # define BOOST_PP_SLOT_2_DIGIT_8 6 # elif BOOST_PP_SLOT_TEMP_8 == 7 # define BOOST_PP_SLOT_2_DIGIT_8 7 # elif BOOST_PP_SLOT_TEMP_8 == 8 # define BOOST_PP_SLOT_2_DIGIT_8 8 # elif BOOST_PP_SLOT_TEMP_8 == 9 # define BOOST_PP_SLOT_2_DIGIT_8 9 # endif # # if BOOST_PP_SLOT_TEMP_7 == 0 # define BOOST_PP_SLOT_2_DIGIT_7 0 # elif BOOST_PP_SLOT_TEMP_7 == 1 # define BOOST_PP_SLOT_2_DIGIT_7 1 # elif BOOST_PP_SLOT_TEMP_7 == 2 # define BOOST_PP_SLOT_2_DIGIT_7 2 # elif BOOST_PP_SLOT_TEMP_7 == 3 # define BOOST_PP_SLOT_2_DIGIT_7 3 # elif BOOST_PP_SLOT_TEMP_7 == 4 # define BOOST_PP_SLOT_2_DIGIT_7 4 # elif BOOST_PP_SLOT_TEMP_7 == 5 # define BOOST_PP_SLOT_2_DIGIT_7 5 # elif BOOST_PP_SLOT_TEMP_7 == 6 # define BOOST_PP_SLOT_2_DIGIT_7 6 # elif BOOST_PP_SLOT_TEMP_7 == 7 # define BOOST_PP_SLOT_2_DIGIT_7 7 # elif BOOST_PP_SLOT_TEMP_7 == 8 # define BOOST_PP_SLOT_2_DIGIT_7 8 # elif BOOST_PP_SLOT_TEMP_7 == 9 # define BOOST_PP_SLOT_2_DIGIT_7 9 # endif # # if BOOST_PP_SLOT_TEMP_6 == 0 # define BOOST_PP_SLOT_2_DIGIT_6 0 # elif BOOST_PP_SLOT_TEMP_6 == 1 # define BOOST_PP_SLOT_2_DIGIT_6 1 # elif BOOST_PP_SLOT_TEMP_6 == 2 # define BOOST_PP_SLOT_2_DIGIT_6 2 # elif BOOST_PP_SLOT_TEMP_6 == 3 # define BOOST_PP_SLOT_2_DIGIT_6 3 # elif BOOST_PP_SLOT_TEMP_6 == 4 # define BOOST_PP_SLOT_2_DIGIT_6 4 # elif BOOST_PP_SLOT_TEMP_6 == 5 # define BOOST_PP_SLOT_2_DIGIT_6 5 # elif BOOST_PP_SLOT_TEMP_6 == 6 # define BOOST_PP_SLOT_2_DIGIT_6 6 # elif BOOST_PP_SLOT_TEMP_6 == 7 # define BOOST_PP_SLOT_2_DIGIT_6 7 # elif BOOST_PP_SLOT_TEMP_6 == 8 # define BOOST_PP_SLOT_2_DIGIT_6 8 # elif BOOST_PP_SLOT_TEMP_6 == 9 # define BOOST_PP_SLOT_2_DIGIT_6 9 # endif # # if BOOST_PP_SLOT_TEMP_5 == 0 # define BOOST_PP_SLOT_2_DIGIT_5 0 # elif BOOST_PP_SLOT_TEMP_5 == 1 # define BOOST_PP_SLOT_2_DIGIT_5 1 # elif BOOST_PP_SLOT_TEMP_5 == 2 # define BOOST_PP_SLOT_2_DIGIT_5 2 # elif BOOST_PP_SLOT_TEMP_5 == 3 # define BOOST_PP_SLOT_2_DIGIT_5 3 # elif BOOST_PP_SLOT_TEMP_5 == 4 # define BOOST_PP_SLOT_2_DIGIT_5 4 # elif BOOST_PP_SLOT_TEMP_5 == 5 # define BOOST_PP_SLOT_2_DIGIT_5 5 # elif BOOST_PP_SLOT_TEMP_5 == 6 # define BOOST_PP_SLOT_2_DIGIT_5 6 # elif BOOST_PP_SLOT_TEMP_5 == 7 # define BOOST_PP_SLOT_2_DIGIT_5 7 # elif BOOST_PP_SLOT_TEMP_5 == 8 # define BOOST_PP_SLOT_2_DIGIT_5 8 # elif BOOST_PP_SLOT_TEMP_5 == 9 # define BOOST_PP_SLOT_2_DIGIT_5 9 # endif # # if BOOST_PP_SLOT_TEMP_4 == 0 # define BOOST_PP_SLOT_2_DIGIT_4 0 # elif BOOST_PP_SLOT_TEMP_4 == 1 # define BOOST_PP_SLOT_2_DIGIT_4 1 # elif BOOST_PP_SLOT_TEMP_4 == 2 # define BOOST_PP_SLOT_2_DIGIT_4 2 # elif BOOST_PP_SLOT_TEMP_4 == 3 # define BOOST_PP_SLOT_2_DIGIT_4 3 # elif BOOST_PP_SLOT_TEMP_4 == 4 # define BOOST_PP_SLOT_2_DIGIT_4 4 # elif BOOST_PP_SLOT_TEMP_4 == 5 # define BOOST_PP_SLOT_2_DIGIT_4 5 # elif BOOST_PP_SLOT_TEMP_4 == 6 # define BOOST_PP_SLOT_2_DIGIT_4 6 # elif BOOST_PP_SLOT_TEMP_4 == 7 # define BOOST_PP_SLOT_2_DIGIT_4 7 # elif BOOST_PP_SLOT_TEMP_4 == 8 # define BOOST_PP_SLOT_2_DIGIT_4 8 # elif BOOST_PP_SLOT_TEMP_4 == 9 # define BOOST_PP_SLOT_2_DIGIT_4 9 # endif # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_SLOT_2_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_SLOT_2_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_SLOT_2_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_SLOT_2_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_SLOT_2_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_SLOT_2_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_SLOT_2_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_SLOT_2_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_SLOT_2_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_SLOT_2_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_SLOT_2_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_SLOT_2_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_SLOT_2_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_SLOT_2_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_SLOT_2_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_SLOT_2_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_SLOT_2_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_SLOT_2_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_SLOT_2_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_SLOT_2_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_SLOT_2_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_SLOT_2_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_SLOT_2_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_SLOT_2_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_SLOT_2_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_SLOT_2_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_SLOT_2_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_SLOT_2_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_SLOT_2_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_SLOT_2_DIGIT_1 9 # endif # # if BOOST_PP_SLOT_2_DIGIT_10 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_10(BOOST_PP_SLOT_2_DIGIT_10, BOOST_PP_SLOT_2_DIGIT_9, BOOST_PP_SLOT_2_DIGIT_8, BOOST_PP_SLOT_2_DIGIT_7, BOOST_PP_SLOT_2_DIGIT_6, BOOST_PP_SLOT_2_DIGIT_5, BOOST_PP_SLOT_2_DIGIT_4, BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_9 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_9(BOOST_PP_SLOT_2_DIGIT_9, BOOST_PP_SLOT_2_DIGIT_8, BOOST_PP_SLOT_2_DIGIT_7, BOOST_PP_SLOT_2_DIGIT_6, BOOST_PP_SLOT_2_DIGIT_5, BOOST_PP_SLOT_2_DIGIT_4, BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_8 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_8(BOOST_PP_SLOT_2_DIGIT_8, BOOST_PP_SLOT_2_DIGIT_7, BOOST_PP_SLOT_2_DIGIT_6, BOOST_PP_SLOT_2_DIGIT_5, BOOST_PP_SLOT_2_DIGIT_4, BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_7 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_7(BOOST_PP_SLOT_2_DIGIT_7, BOOST_PP_SLOT_2_DIGIT_6, BOOST_PP_SLOT_2_DIGIT_5, BOOST_PP_SLOT_2_DIGIT_4, BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_6 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_6(BOOST_PP_SLOT_2_DIGIT_6, BOOST_PP_SLOT_2_DIGIT_5, BOOST_PP_SLOT_2_DIGIT_4, BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_5 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_5(BOOST_PP_SLOT_2_DIGIT_5, BOOST_PP_SLOT_2_DIGIT_4, BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_4 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_4(BOOST_PP_SLOT_2_DIGIT_4, BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_3 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_3(BOOST_PP_SLOT_2_DIGIT_3, BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # elif BOOST_PP_SLOT_2_DIGIT_2 # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_CC_2(BOOST_PP_SLOT_2_DIGIT_2, BOOST_PP_SLOT_2_DIGIT_1) # else # define BOOST_PP_SLOT_2() BOOST_PP_SLOT_2_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/slot3.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_SLOT_3 # # undef BOOST_PP_SLOT_3_DIGIT_1 # undef BOOST_PP_SLOT_3_DIGIT_2 # undef BOOST_PP_SLOT_3_DIGIT_3 # undef BOOST_PP_SLOT_3_DIGIT_4 # undef BOOST_PP_SLOT_3_DIGIT_5 # undef BOOST_PP_SLOT_3_DIGIT_6 # undef BOOST_PP_SLOT_3_DIGIT_7 # undef BOOST_PP_SLOT_3_DIGIT_8 # undef BOOST_PP_SLOT_3_DIGIT_9 # undef BOOST_PP_SLOT_3_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_10 == 0 # define BOOST_PP_SLOT_3_DIGIT_10 0 # elif BOOST_PP_SLOT_TEMP_10 == 1 # define BOOST_PP_SLOT_3_DIGIT_10 1 # elif BOOST_PP_SLOT_TEMP_10 == 2 # define BOOST_PP_SLOT_3_DIGIT_10 2 # elif BOOST_PP_SLOT_TEMP_10 == 3 # define BOOST_PP_SLOT_3_DIGIT_10 3 # elif BOOST_PP_SLOT_TEMP_10 == 4 # define BOOST_PP_SLOT_3_DIGIT_10 4 # elif BOOST_PP_SLOT_TEMP_10 == 5 # define BOOST_PP_SLOT_3_DIGIT_10 5 # elif BOOST_PP_SLOT_TEMP_10 == 6 # define BOOST_PP_SLOT_3_DIGIT_10 6 # elif BOOST_PP_SLOT_TEMP_10 == 7 # define BOOST_PP_SLOT_3_DIGIT_10 7 # elif BOOST_PP_SLOT_TEMP_10 == 8 # define BOOST_PP_SLOT_3_DIGIT_10 8 # elif BOOST_PP_SLOT_TEMP_10 == 9 # define BOOST_PP_SLOT_3_DIGIT_10 9 # endif # # if BOOST_PP_SLOT_TEMP_9 == 0 # define BOOST_PP_SLOT_3_DIGIT_9 0 # elif BOOST_PP_SLOT_TEMP_9 == 1 # define BOOST_PP_SLOT_3_DIGIT_9 1 # elif BOOST_PP_SLOT_TEMP_9 == 2 # define BOOST_PP_SLOT_3_DIGIT_9 2 # elif BOOST_PP_SLOT_TEMP_9 == 3 # define BOOST_PP_SLOT_3_DIGIT_9 3 # elif BOOST_PP_SLOT_TEMP_9 == 4 # define BOOST_PP_SLOT_3_DIGIT_9 4 # elif BOOST_PP_SLOT_TEMP_9 == 5 # define BOOST_PP_SLOT_3_DIGIT_9 5 # elif BOOST_PP_SLOT_TEMP_9 == 6 # define BOOST_PP_SLOT_3_DIGIT_9 6 # elif BOOST_PP_SLOT_TEMP_9 == 7 # define BOOST_PP_SLOT_3_DIGIT_9 7 # elif BOOST_PP_SLOT_TEMP_9 == 8 # define BOOST_PP_SLOT_3_DIGIT_9 8 # elif BOOST_PP_SLOT_TEMP_9 == 9 # define BOOST_PP_SLOT_3_DIGIT_9 9 # endif # # if BOOST_PP_SLOT_TEMP_8 == 0 # define BOOST_PP_SLOT_3_DIGIT_8 0 # elif BOOST_PP_SLOT_TEMP_8 == 1 # define BOOST_PP_SLOT_3_DIGIT_8 1 # elif BOOST_PP_SLOT_TEMP_8 == 2 # define BOOST_PP_SLOT_3_DIGIT_8 2 # elif BOOST_PP_SLOT_TEMP_8 == 3 # define BOOST_PP_SLOT_3_DIGIT_8 3 # elif BOOST_PP_SLOT_TEMP_8 == 4 # define BOOST_PP_SLOT_3_DIGIT_8 4 # elif BOOST_PP_SLOT_TEMP_8 == 5 # define BOOST_PP_SLOT_3_DIGIT_8 5 # elif BOOST_PP_SLOT_TEMP_8 == 6 # define BOOST_PP_SLOT_3_DIGIT_8 6 # elif BOOST_PP_SLOT_TEMP_8 == 7 # define BOOST_PP_SLOT_3_DIGIT_8 7 # elif BOOST_PP_SLOT_TEMP_8 == 8 # define BOOST_PP_SLOT_3_DIGIT_8 8 # elif BOOST_PP_SLOT_TEMP_8 == 9 # define BOOST_PP_SLOT_3_DIGIT_8 9 # endif # # if BOOST_PP_SLOT_TEMP_7 == 0 # define BOOST_PP_SLOT_3_DIGIT_7 0 # elif BOOST_PP_SLOT_TEMP_7 == 1 # define BOOST_PP_SLOT_3_DIGIT_7 1 # elif BOOST_PP_SLOT_TEMP_7 == 2 # define BOOST_PP_SLOT_3_DIGIT_7 2 # elif BOOST_PP_SLOT_TEMP_7 == 3 # define BOOST_PP_SLOT_3_DIGIT_7 3 # elif BOOST_PP_SLOT_TEMP_7 == 4 # define BOOST_PP_SLOT_3_DIGIT_7 4 # elif BOOST_PP_SLOT_TEMP_7 == 5 # define BOOST_PP_SLOT_3_DIGIT_7 5 # elif BOOST_PP_SLOT_TEMP_7 == 6 # define BOOST_PP_SLOT_3_DIGIT_7 6 # elif BOOST_PP_SLOT_TEMP_7 == 7 # define BOOST_PP_SLOT_3_DIGIT_7 7 # elif BOOST_PP_SLOT_TEMP_7 == 8 # define BOOST_PP_SLOT_3_DIGIT_7 8 # elif BOOST_PP_SLOT_TEMP_7 == 9 # define BOOST_PP_SLOT_3_DIGIT_7 9 # endif # # if BOOST_PP_SLOT_TEMP_6 == 0 # define BOOST_PP_SLOT_3_DIGIT_6 0 # elif BOOST_PP_SLOT_TEMP_6 == 1 # define BOOST_PP_SLOT_3_DIGIT_6 1 # elif BOOST_PP_SLOT_TEMP_6 == 2 # define BOOST_PP_SLOT_3_DIGIT_6 2 # elif BOOST_PP_SLOT_TEMP_6 == 3 # define BOOST_PP_SLOT_3_DIGIT_6 3 # elif BOOST_PP_SLOT_TEMP_6 == 4 # define BOOST_PP_SLOT_3_DIGIT_6 4 # elif BOOST_PP_SLOT_TEMP_6 == 5 # define BOOST_PP_SLOT_3_DIGIT_6 5 # elif BOOST_PP_SLOT_TEMP_6 == 6 # define BOOST_PP_SLOT_3_DIGIT_6 6 # elif BOOST_PP_SLOT_TEMP_6 == 7 # define BOOST_PP_SLOT_3_DIGIT_6 7 # elif BOOST_PP_SLOT_TEMP_6 == 8 # define BOOST_PP_SLOT_3_DIGIT_6 8 # elif BOOST_PP_SLOT_TEMP_6 == 9 # define BOOST_PP_SLOT_3_DIGIT_6 9 # endif # # if BOOST_PP_SLOT_TEMP_5 == 0 # define BOOST_PP_SLOT_3_DIGIT_5 0 # elif BOOST_PP_SLOT_TEMP_5 == 1 # define BOOST_PP_SLOT_3_DIGIT_5 1 # elif BOOST_PP_SLOT_TEMP_5 == 2 # define BOOST_PP_SLOT_3_DIGIT_5 2 # elif BOOST_PP_SLOT_TEMP_5 == 3 # define BOOST_PP_SLOT_3_DIGIT_5 3 # elif BOOST_PP_SLOT_TEMP_5 == 4 # define BOOST_PP_SLOT_3_DIGIT_5 4 # elif BOOST_PP_SLOT_TEMP_5 == 5 # define BOOST_PP_SLOT_3_DIGIT_5 5 # elif BOOST_PP_SLOT_TEMP_5 == 6 # define BOOST_PP_SLOT_3_DIGIT_5 6 # elif BOOST_PP_SLOT_TEMP_5 == 7 # define BOOST_PP_SLOT_3_DIGIT_5 7 # elif BOOST_PP_SLOT_TEMP_5 == 8 # define BOOST_PP_SLOT_3_DIGIT_5 8 # elif BOOST_PP_SLOT_TEMP_5 == 9 # define BOOST_PP_SLOT_3_DIGIT_5 9 # endif # # if BOOST_PP_SLOT_TEMP_4 == 0 # define BOOST_PP_SLOT_3_DIGIT_4 0 # elif BOOST_PP_SLOT_TEMP_4 == 1 # define BOOST_PP_SLOT_3_DIGIT_4 1 # elif BOOST_PP_SLOT_TEMP_4 == 2 # define BOOST_PP_SLOT_3_DIGIT_4 2 # elif BOOST_PP_SLOT_TEMP_4 == 3 # define BOOST_PP_SLOT_3_DIGIT_4 3 # elif BOOST_PP_SLOT_TEMP_4 == 4 # define BOOST_PP_SLOT_3_DIGIT_4 4 # elif BOOST_PP_SLOT_TEMP_4 == 5 # define BOOST_PP_SLOT_3_DIGIT_4 5 # elif BOOST_PP_SLOT_TEMP_4 == 6 # define BOOST_PP_SLOT_3_DIGIT_4 6 # elif BOOST_PP_SLOT_TEMP_4 == 7 # define BOOST_PP_SLOT_3_DIGIT_4 7 # elif BOOST_PP_SLOT_TEMP_4 == 8 # define BOOST_PP_SLOT_3_DIGIT_4 8 # elif BOOST_PP_SLOT_TEMP_4 == 9 # define BOOST_PP_SLOT_3_DIGIT_4 9 # endif # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_SLOT_3_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_SLOT_3_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_SLOT_3_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_SLOT_3_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_SLOT_3_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_SLOT_3_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_SLOT_3_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_SLOT_3_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_SLOT_3_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_SLOT_3_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_SLOT_3_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_SLOT_3_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_SLOT_3_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_SLOT_3_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_SLOT_3_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_SLOT_3_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_SLOT_3_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_SLOT_3_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_SLOT_3_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_SLOT_3_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_SLOT_3_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_SLOT_3_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_SLOT_3_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_SLOT_3_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_SLOT_3_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_SLOT_3_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_SLOT_3_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_SLOT_3_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_SLOT_3_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_SLOT_3_DIGIT_1 9 # endif # # if BOOST_PP_SLOT_3_DIGIT_10 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_10(BOOST_PP_SLOT_3_DIGIT_10, BOOST_PP_SLOT_3_DIGIT_9, BOOST_PP_SLOT_3_DIGIT_8, BOOST_PP_SLOT_3_DIGIT_7, BOOST_PP_SLOT_3_DIGIT_6, BOOST_PP_SLOT_3_DIGIT_5, BOOST_PP_SLOT_3_DIGIT_4, BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_9 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_9(BOOST_PP_SLOT_3_DIGIT_9, BOOST_PP_SLOT_3_DIGIT_8, BOOST_PP_SLOT_3_DIGIT_7, BOOST_PP_SLOT_3_DIGIT_6, BOOST_PP_SLOT_3_DIGIT_5, BOOST_PP_SLOT_3_DIGIT_4, BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_8 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_8(BOOST_PP_SLOT_3_DIGIT_8, BOOST_PP_SLOT_3_DIGIT_7, BOOST_PP_SLOT_3_DIGIT_6, BOOST_PP_SLOT_3_DIGIT_5, BOOST_PP_SLOT_3_DIGIT_4, BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_7 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_7(BOOST_PP_SLOT_3_DIGIT_7, BOOST_PP_SLOT_3_DIGIT_6, BOOST_PP_SLOT_3_DIGIT_5, BOOST_PP_SLOT_3_DIGIT_4, BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_6 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_6(BOOST_PP_SLOT_3_DIGIT_6, BOOST_PP_SLOT_3_DIGIT_5, BOOST_PP_SLOT_3_DIGIT_4, BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_5 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_5(BOOST_PP_SLOT_3_DIGIT_5, BOOST_PP_SLOT_3_DIGIT_4, BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_4 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_4(BOOST_PP_SLOT_3_DIGIT_4, BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_3 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_3(BOOST_PP_SLOT_3_DIGIT_3, BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # elif BOOST_PP_SLOT_3_DIGIT_2 # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_CC_2(BOOST_PP_SLOT_3_DIGIT_2, BOOST_PP_SLOT_3_DIGIT_1) # else # define BOOST_PP_SLOT_3() BOOST_PP_SLOT_3_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/slot4.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_SLOT_4 # # undef BOOST_PP_SLOT_4_DIGIT_1 # undef BOOST_PP_SLOT_4_DIGIT_2 # undef BOOST_PP_SLOT_4_DIGIT_3 # undef BOOST_PP_SLOT_4_DIGIT_4 # undef BOOST_PP_SLOT_4_DIGIT_5 # undef BOOST_PP_SLOT_4_DIGIT_6 # undef BOOST_PP_SLOT_4_DIGIT_7 # undef BOOST_PP_SLOT_4_DIGIT_8 # undef BOOST_PP_SLOT_4_DIGIT_9 # undef BOOST_PP_SLOT_4_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_10 == 0 # define BOOST_PP_SLOT_4_DIGIT_10 0 # elif BOOST_PP_SLOT_TEMP_10 == 1 # define BOOST_PP_SLOT_4_DIGIT_10 1 # elif BOOST_PP_SLOT_TEMP_10 == 2 # define BOOST_PP_SLOT_4_DIGIT_10 2 # elif BOOST_PP_SLOT_TEMP_10 == 3 # define BOOST_PP_SLOT_4_DIGIT_10 3 # elif BOOST_PP_SLOT_TEMP_10 == 4 # define BOOST_PP_SLOT_4_DIGIT_10 4 # elif BOOST_PP_SLOT_TEMP_10 == 5 # define BOOST_PP_SLOT_4_DIGIT_10 5 # elif BOOST_PP_SLOT_TEMP_10 == 6 # define BOOST_PP_SLOT_4_DIGIT_10 6 # elif BOOST_PP_SLOT_TEMP_10 == 7 # define BOOST_PP_SLOT_4_DIGIT_10 7 # elif BOOST_PP_SLOT_TEMP_10 == 8 # define BOOST_PP_SLOT_4_DIGIT_10 8 # elif BOOST_PP_SLOT_TEMP_10 == 9 # define BOOST_PP_SLOT_4_DIGIT_10 9 # endif # # if BOOST_PP_SLOT_TEMP_9 == 0 # define BOOST_PP_SLOT_4_DIGIT_9 0 # elif BOOST_PP_SLOT_TEMP_9 == 1 # define BOOST_PP_SLOT_4_DIGIT_9 1 # elif BOOST_PP_SLOT_TEMP_9 == 2 # define BOOST_PP_SLOT_4_DIGIT_9 2 # elif BOOST_PP_SLOT_TEMP_9 == 3 # define BOOST_PP_SLOT_4_DIGIT_9 3 # elif BOOST_PP_SLOT_TEMP_9 == 4 # define BOOST_PP_SLOT_4_DIGIT_9 4 # elif BOOST_PP_SLOT_TEMP_9 == 5 # define BOOST_PP_SLOT_4_DIGIT_9 5 # elif BOOST_PP_SLOT_TEMP_9 == 6 # define BOOST_PP_SLOT_4_DIGIT_9 6 # elif BOOST_PP_SLOT_TEMP_9 == 7 # define BOOST_PP_SLOT_4_DIGIT_9 7 # elif BOOST_PP_SLOT_TEMP_9 == 8 # define BOOST_PP_SLOT_4_DIGIT_9 8 # elif BOOST_PP_SLOT_TEMP_9 == 9 # define BOOST_PP_SLOT_4_DIGIT_9 9 # endif # # if BOOST_PP_SLOT_TEMP_8 == 0 # define BOOST_PP_SLOT_4_DIGIT_8 0 # elif BOOST_PP_SLOT_TEMP_8 == 1 # define BOOST_PP_SLOT_4_DIGIT_8 1 # elif BOOST_PP_SLOT_TEMP_8 == 2 # define BOOST_PP_SLOT_4_DIGIT_8 2 # elif BOOST_PP_SLOT_TEMP_8 == 3 # define BOOST_PP_SLOT_4_DIGIT_8 3 # elif BOOST_PP_SLOT_TEMP_8 == 4 # define BOOST_PP_SLOT_4_DIGIT_8 4 # elif BOOST_PP_SLOT_TEMP_8 == 5 # define BOOST_PP_SLOT_4_DIGIT_8 5 # elif BOOST_PP_SLOT_TEMP_8 == 6 # define BOOST_PP_SLOT_4_DIGIT_8 6 # elif BOOST_PP_SLOT_TEMP_8 == 7 # define BOOST_PP_SLOT_4_DIGIT_8 7 # elif BOOST_PP_SLOT_TEMP_8 == 8 # define BOOST_PP_SLOT_4_DIGIT_8 8 # elif BOOST_PP_SLOT_TEMP_8 == 9 # define BOOST_PP_SLOT_4_DIGIT_8 9 # endif # # if BOOST_PP_SLOT_TEMP_7 == 0 # define BOOST_PP_SLOT_4_DIGIT_7 0 # elif BOOST_PP_SLOT_TEMP_7 == 1 # define BOOST_PP_SLOT_4_DIGIT_7 1 # elif BOOST_PP_SLOT_TEMP_7 == 2 # define BOOST_PP_SLOT_4_DIGIT_7 2 # elif BOOST_PP_SLOT_TEMP_7 == 3 # define BOOST_PP_SLOT_4_DIGIT_7 3 # elif BOOST_PP_SLOT_TEMP_7 == 4 # define BOOST_PP_SLOT_4_DIGIT_7 4 # elif BOOST_PP_SLOT_TEMP_7 == 5 # define BOOST_PP_SLOT_4_DIGIT_7 5 # elif BOOST_PP_SLOT_TEMP_7 == 6 # define BOOST_PP_SLOT_4_DIGIT_7 6 # elif BOOST_PP_SLOT_TEMP_7 == 7 # define BOOST_PP_SLOT_4_DIGIT_7 7 # elif BOOST_PP_SLOT_TEMP_7 == 8 # define BOOST_PP_SLOT_4_DIGIT_7 8 # elif BOOST_PP_SLOT_TEMP_7 == 9 # define BOOST_PP_SLOT_4_DIGIT_7 9 # endif # # if BOOST_PP_SLOT_TEMP_6 == 0 # define BOOST_PP_SLOT_4_DIGIT_6 0 # elif BOOST_PP_SLOT_TEMP_6 == 1 # define BOOST_PP_SLOT_4_DIGIT_6 1 # elif BOOST_PP_SLOT_TEMP_6 == 2 # define BOOST_PP_SLOT_4_DIGIT_6 2 # elif BOOST_PP_SLOT_TEMP_6 == 3 # define BOOST_PP_SLOT_4_DIGIT_6 3 # elif BOOST_PP_SLOT_TEMP_6 == 4 # define BOOST_PP_SLOT_4_DIGIT_6 4 # elif BOOST_PP_SLOT_TEMP_6 == 5 # define BOOST_PP_SLOT_4_DIGIT_6 5 # elif BOOST_PP_SLOT_TEMP_6 == 6 # define BOOST_PP_SLOT_4_DIGIT_6 6 # elif BOOST_PP_SLOT_TEMP_6 == 7 # define BOOST_PP_SLOT_4_DIGIT_6 7 # elif BOOST_PP_SLOT_TEMP_6 == 8 # define BOOST_PP_SLOT_4_DIGIT_6 8 # elif BOOST_PP_SLOT_TEMP_6 == 9 # define BOOST_PP_SLOT_4_DIGIT_6 9 # endif # # if BOOST_PP_SLOT_TEMP_5 == 0 # define BOOST_PP_SLOT_4_DIGIT_5 0 # elif BOOST_PP_SLOT_TEMP_5 == 1 # define BOOST_PP_SLOT_4_DIGIT_5 1 # elif BOOST_PP_SLOT_TEMP_5 == 2 # define BOOST_PP_SLOT_4_DIGIT_5 2 # elif BOOST_PP_SLOT_TEMP_5 == 3 # define BOOST_PP_SLOT_4_DIGIT_5 3 # elif BOOST_PP_SLOT_TEMP_5 == 4 # define BOOST_PP_SLOT_4_DIGIT_5 4 # elif BOOST_PP_SLOT_TEMP_5 == 5 # define BOOST_PP_SLOT_4_DIGIT_5 5 # elif BOOST_PP_SLOT_TEMP_5 == 6 # define BOOST_PP_SLOT_4_DIGIT_5 6 # elif BOOST_PP_SLOT_TEMP_5 == 7 # define BOOST_PP_SLOT_4_DIGIT_5 7 # elif BOOST_PP_SLOT_TEMP_5 == 8 # define BOOST_PP_SLOT_4_DIGIT_5 8 # elif BOOST_PP_SLOT_TEMP_5 == 9 # define BOOST_PP_SLOT_4_DIGIT_5 9 # endif # # if BOOST_PP_SLOT_TEMP_4 == 0 # define BOOST_PP_SLOT_4_DIGIT_4 0 # elif BOOST_PP_SLOT_TEMP_4 == 1 # define BOOST_PP_SLOT_4_DIGIT_4 1 # elif BOOST_PP_SLOT_TEMP_4 == 2 # define BOOST_PP_SLOT_4_DIGIT_4 2 # elif BOOST_PP_SLOT_TEMP_4 == 3 # define BOOST_PP_SLOT_4_DIGIT_4 3 # elif BOOST_PP_SLOT_TEMP_4 == 4 # define BOOST_PP_SLOT_4_DIGIT_4 4 # elif BOOST_PP_SLOT_TEMP_4 == 5 # define BOOST_PP_SLOT_4_DIGIT_4 5 # elif BOOST_PP_SLOT_TEMP_4 == 6 # define BOOST_PP_SLOT_4_DIGIT_4 6 # elif BOOST_PP_SLOT_TEMP_4 == 7 # define BOOST_PP_SLOT_4_DIGIT_4 7 # elif BOOST_PP_SLOT_TEMP_4 == 8 # define BOOST_PP_SLOT_4_DIGIT_4 8 # elif BOOST_PP_SLOT_TEMP_4 == 9 # define BOOST_PP_SLOT_4_DIGIT_4 9 # endif # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_SLOT_4_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_SLOT_4_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_SLOT_4_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_SLOT_4_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_SLOT_4_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_SLOT_4_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_SLOT_4_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_SLOT_4_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_SLOT_4_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_SLOT_4_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_SLOT_4_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_SLOT_4_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_SLOT_4_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_SLOT_4_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_SLOT_4_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_SLOT_4_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_SLOT_4_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_SLOT_4_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_SLOT_4_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_SLOT_4_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_SLOT_4_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_SLOT_4_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_SLOT_4_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_SLOT_4_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_SLOT_4_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_SLOT_4_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_SLOT_4_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_SLOT_4_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_SLOT_4_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_SLOT_4_DIGIT_1 9 # endif # # if BOOST_PP_SLOT_4_DIGIT_10 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_10(BOOST_PP_SLOT_4_DIGIT_10, BOOST_PP_SLOT_4_DIGIT_9, BOOST_PP_SLOT_4_DIGIT_8, BOOST_PP_SLOT_4_DIGIT_7, BOOST_PP_SLOT_4_DIGIT_6, BOOST_PP_SLOT_4_DIGIT_5, BOOST_PP_SLOT_4_DIGIT_4, BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_9 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_9(BOOST_PP_SLOT_4_DIGIT_9, BOOST_PP_SLOT_4_DIGIT_8, BOOST_PP_SLOT_4_DIGIT_7, BOOST_PP_SLOT_4_DIGIT_6, BOOST_PP_SLOT_4_DIGIT_5, BOOST_PP_SLOT_4_DIGIT_4, BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_8 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_8(BOOST_PP_SLOT_4_DIGIT_8, BOOST_PP_SLOT_4_DIGIT_7, BOOST_PP_SLOT_4_DIGIT_6, BOOST_PP_SLOT_4_DIGIT_5, BOOST_PP_SLOT_4_DIGIT_4, BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_7 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_7(BOOST_PP_SLOT_4_DIGIT_7, BOOST_PP_SLOT_4_DIGIT_6, BOOST_PP_SLOT_4_DIGIT_5, BOOST_PP_SLOT_4_DIGIT_4, BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_6 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_6(BOOST_PP_SLOT_4_DIGIT_6, BOOST_PP_SLOT_4_DIGIT_5, BOOST_PP_SLOT_4_DIGIT_4, BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_5 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_5(BOOST_PP_SLOT_4_DIGIT_5, BOOST_PP_SLOT_4_DIGIT_4, BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_4 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_4(BOOST_PP_SLOT_4_DIGIT_4, BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_3 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_3(BOOST_PP_SLOT_4_DIGIT_3, BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # elif BOOST_PP_SLOT_4_DIGIT_2 # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_CC_2(BOOST_PP_SLOT_4_DIGIT_2, BOOST_PP_SLOT_4_DIGIT_1) # else # define BOOST_PP_SLOT_4() BOOST_PP_SLOT_4_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/detail/slot5.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # include # # undef BOOST_PP_SLOT_5 # # undef BOOST_PP_SLOT_5_DIGIT_1 # undef BOOST_PP_SLOT_5_DIGIT_2 # undef BOOST_PP_SLOT_5_DIGIT_3 # undef BOOST_PP_SLOT_5_DIGIT_4 # undef BOOST_PP_SLOT_5_DIGIT_5 # undef BOOST_PP_SLOT_5_DIGIT_6 # undef BOOST_PP_SLOT_5_DIGIT_7 # undef BOOST_PP_SLOT_5_DIGIT_8 # undef BOOST_PP_SLOT_5_DIGIT_9 # undef BOOST_PP_SLOT_5_DIGIT_10 # # if BOOST_PP_SLOT_TEMP_10 == 0 # define BOOST_PP_SLOT_5_DIGIT_10 0 # elif BOOST_PP_SLOT_TEMP_10 == 1 # define BOOST_PP_SLOT_5_DIGIT_10 1 # elif BOOST_PP_SLOT_TEMP_10 == 2 # define BOOST_PP_SLOT_5_DIGIT_10 2 # elif BOOST_PP_SLOT_TEMP_10 == 3 # define BOOST_PP_SLOT_5_DIGIT_10 3 # elif BOOST_PP_SLOT_TEMP_10 == 4 # define BOOST_PP_SLOT_5_DIGIT_10 4 # elif BOOST_PP_SLOT_TEMP_10 == 5 # define BOOST_PP_SLOT_5_DIGIT_10 5 # elif BOOST_PP_SLOT_TEMP_10 == 6 # define BOOST_PP_SLOT_5_DIGIT_10 6 # elif BOOST_PP_SLOT_TEMP_10 == 7 # define BOOST_PP_SLOT_5_DIGIT_10 7 # elif BOOST_PP_SLOT_TEMP_10 == 8 # define BOOST_PP_SLOT_5_DIGIT_10 8 # elif BOOST_PP_SLOT_TEMP_10 == 9 # define BOOST_PP_SLOT_5_DIGIT_10 9 # endif # # if BOOST_PP_SLOT_TEMP_9 == 0 # define BOOST_PP_SLOT_5_DIGIT_9 0 # elif BOOST_PP_SLOT_TEMP_9 == 1 # define BOOST_PP_SLOT_5_DIGIT_9 1 # elif BOOST_PP_SLOT_TEMP_9 == 2 # define BOOST_PP_SLOT_5_DIGIT_9 2 # elif BOOST_PP_SLOT_TEMP_9 == 3 # define BOOST_PP_SLOT_5_DIGIT_9 3 # elif BOOST_PP_SLOT_TEMP_9 == 4 # define BOOST_PP_SLOT_5_DIGIT_9 4 # elif BOOST_PP_SLOT_TEMP_9 == 5 # define BOOST_PP_SLOT_5_DIGIT_9 5 # elif BOOST_PP_SLOT_TEMP_9 == 6 # define BOOST_PP_SLOT_5_DIGIT_9 6 # elif BOOST_PP_SLOT_TEMP_9 == 7 # define BOOST_PP_SLOT_5_DIGIT_9 7 # elif BOOST_PP_SLOT_TEMP_9 == 8 # define BOOST_PP_SLOT_5_DIGIT_9 8 # elif BOOST_PP_SLOT_TEMP_9 == 9 # define BOOST_PP_SLOT_5_DIGIT_9 9 # endif # # if BOOST_PP_SLOT_TEMP_8 == 0 # define BOOST_PP_SLOT_5_DIGIT_8 0 # elif BOOST_PP_SLOT_TEMP_8 == 1 # define BOOST_PP_SLOT_5_DIGIT_8 1 # elif BOOST_PP_SLOT_TEMP_8 == 2 # define BOOST_PP_SLOT_5_DIGIT_8 2 # elif BOOST_PP_SLOT_TEMP_8 == 3 # define BOOST_PP_SLOT_5_DIGIT_8 3 # elif BOOST_PP_SLOT_TEMP_8 == 4 # define BOOST_PP_SLOT_5_DIGIT_8 4 # elif BOOST_PP_SLOT_TEMP_8 == 5 # define BOOST_PP_SLOT_5_DIGIT_8 5 # elif BOOST_PP_SLOT_TEMP_8 == 6 # define BOOST_PP_SLOT_5_DIGIT_8 6 # elif BOOST_PP_SLOT_TEMP_8 == 7 # define BOOST_PP_SLOT_5_DIGIT_8 7 # elif BOOST_PP_SLOT_TEMP_8 == 8 # define BOOST_PP_SLOT_5_DIGIT_8 8 # elif BOOST_PP_SLOT_TEMP_8 == 9 # define BOOST_PP_SLOT_5_DIGIT_8 9 # endif # # if BOOST_PP_SLOT_TEMP_7 == 0 # define BOOST_PP_SLOT_5_DIGIT_7 0 # elif BOOST_PP_SLOT_TEMP_7 == 1 # define BOOST_PP_SLOT_5_DIGIT_7 1 # elif BOOST_PP_SLOT_TEMP_7 == 2 # define BOOST_PP_SLOT_5_DIGIT_7 2 # elif BOOST_PP_SLOT_TEMP_7 == 3 # define BOOST_PP_SLOT_5_DIGIT_7 3 # elif BOOST_PP_SLOT_TEMP_7 == 4 # define BOOST_PP_SLOT_5_DIGIT_7 4 # elif BOOST_PP_SLOT_TEMP_7 == 5 # define BOOST_PP_SLOT_5_DIGIT_7 5 # elif BOOST_PP_SLOT_TEMP_7 == 6 # define BOOST_PP_SLOT_5_DIGIT_7 6 # elif BOOST_PP_SLOT_TEMP_7 == 7 # define BOOST_PP_SLOT_5_DIGIT_7 7 # elif BOOST_PP_SLOT_TEMP_7 == 8 # define BOOST_PP_SLOT_5_DIGIT_7 8 # elif BOOST_PP_SLOT_TEMP_7 == 9 # define BOOST_PP_SLOT_5_DIGIT_7 9 # endif # # if BOOST_PP_SLOT_TEMP_6 == 0 # define BOOST_PP_SLOT_5_DIGIT_6 0 # elif BOOST_PP_SLOT_TEMP_6 == 1 # define BOOST_PP_SLOT_5_DIGIT_6 1 # elif BOOST_PP_SLOT_TEMP_6 == 2 # define BOOST_PP_SLOT_5_DIGIT_6 2 # elif BOOST_PP_SLOT_TEMP_6 == 3 # define BOOST_PP_SLOT_5_DIGIT_6 3 # elif BOOST_PP_SLOT_TEMP_6 == 4 # define BOOST_PP_SLOT_5_DIGIT_6 4 # elif BOOST_PP_SLOT_TEMP_6 == 5 # define BOOST_PP_SLOT_5_DIGIT_6 5 # elif BOOST_PP_SLOT_TEMP_6 == 6 # define BOOST_PP_SLOT_5_DIGIT_6 6 # elif BOOST_PP_SLOT_TEMP_6 == 7 # define BOOST_PP_SLOT_5_DIGIT_6 7 # elif BOOST_PP_SLOT_TEMP_6 == 8 # define BOOST_PP_SLOT_5_DIGIT_6 8 # elif BOOST_PP_SLOT_TEMP_6 == 9 # define BOOST_PP_SLOT_5_DIGIT_6 9 # endif # # if BOOST_PP_SLOT_TEMP_5 == 0 # define BOOST_PP_SLOT_5_DIGIT_5 0 # elif BOOST_PP_SLOT_TEMP_5 == 1 # define BOOST_PP_SLOT_5_DIGIT_5 1 # elif BOOST_PP_SLOT_TEMP_5 == 2 # define BOOST_PP_SLOT_5_DIGIT_5 2 # elif BOOST_PP_SLOT_TEMP_5 == 3 # define BOOST_PP_SLOT_5_DIGIT_5 3 # elif BOOST_PP_SLOT_TEMP_5 == 4 # define BOOST_PP_SLOT_5_DIGIT_5 4 # elif BOOST_PP_SLOT_TEMP_5 == 5 # define BOOST_PP_SLOT_5_DIGIT_5 5 # elif BOOST_PP_SLOT_TEMP_5 == 6 # define BOOST_PP_SLOT_5_DIGIT_5 6 # elif BOOST_PP_SLOT_TEMP_5 == 7 # define BOOST_PP_SLOT_5_DIGIT_5 7 # elif BOOST_PP_SLOT_TEMP_5 == 8 # define BOOST_PP_SLOT_5_DIGIT_5 8 # elif BOOST_PP_SLOT_TEMP_5 == 9 # define BOOST_PP_SLOT_5_DIGIT_5 9 # endif # # if BOOST_PP_SLOT_TEMP_4 == 0 # define BOOST_PP_SLOT_5_DIGIT_4 0 # elif BOOST_PP_SLOT_TEMP_4 == 1 # define BOOST_PP_SLOT_5_DIGIT_4 1 # elif BOOST_PP_SLOT_TEMP_4 == 2 # define BOOST_PP_SLOT_5_DIGIT_4 2 # elif BOOST_PP_SLOT_TEMP_4 == 3 # define BOOST_PP_SLOT_5_DIGIT_4 3 # elif BOOST_PP_SLOT_TEMP_4 == 4 # define BOOST_PP_SLOT_5_DIGIT_4 4 # elif BOOST_PP_SLOT_TEMP_4 == 5 # define BOOST_PP_SLOT_5_DIGIT_4 5 # elif BOOST_PP_SLOT_TEMP_4 == 6 # define BOOST_PP_SLOT_5_DIGIT_4 6 # elif BOOST_PP_SLOT_TEMP_4 == 7 # define BOOST_PP_SLOT_5_DIGIT_4 7 # elif BOOST_PP_SLOT_TEMP_4 == 8 # define BOOST_PP_SLOT_5_DIGIT_4 8 # elif BOOST_PP_SLOT_TEMP_4 == 9 # define BOOST_PP_SLOT_5_DIGIT_4 9 # endif # # if BOOST_PP_SLOT_TEMP_3 == 0 # define BOOST_PP_SLOT_5_DIGIT_3 0 # elif BOOST_PP_SLOT_TEMP_3 == 1 # define BOOST_PP_SLOT_5_DIGIT_3 1 # elif BOOST_PP_SLOT_TEMP_3 == 2 # define BOOST_PP_SLOT_5_DIGIT_3 2 # elif BOOST_PP_SLOT_TEMP_3 == 3 # define BOOST_PP_SLOT_5_DIGIT_3 3 # elif BOOST_PP_SLOT_TEMP_3 == 4 # define BOOST_PP_SLOT_5_DIGIT_3 4 # elif BOOST_PP_SLOT_TEMP_3 == 5 # define BOOST_PP_SLOT_5_DIGIT_3 5 # elif BOOST_PP_SLOT_TEMP_3 == 6 # define BOOST_PP_SLOT_5_DIGIT_3 6 # elif BOOST_PP_SLOT_TEMP_3 == 7 # define BOOST_PP_SLOT_5_DIGIT_3 7 # elif BOOST_PP_SLOT_TEMP_3 == 8 # define BOOST_PP_SLOT_5_DIGIT_3 8 # elif BOOST_PP_SLOT_TEMP_3 == 9 # define BOOST_PP_SLOT_5_DIGIT_3 9 # endif # # if BOOST_PP_SLOT_TEMP_2 == 0 # define BOOST_PP_SLOT_5_DIGIT_2 0 # elif BOOST_PP_SLOT_TEMP_2 == 1 # define BOOST_PP_SLOT_5_DIGIT_2 1 # elif BOOST_PP_SLOT_TEMP_2 == 2 # define BOOST_PP_SLOT_5_DIGIT_2 2 # elif BOOST_PP_SLOT_TEMP_2 == 3 # define BOOST_PP_SLOT_5_DIGIT_2 3 # elif BOOST_PP_SLOT_TEMP_2 == 4 # define BOOST_PP_SLOT_5_DIGIT_2 4 # elif BOOST_PP_SLOT_TEMP_2 == 5 # define BOOST_PP_SLOT_5_DIGIT_2 5 # elif BOOST_PP_SLOT_TEMP_2 == 6 # define BOOST_PP_SLOT_5_DIGIT_2 6 # elif BOOST_PP_SLOT_TEMP_2 == 7 # define BOOST_PP_SLOT_5_DIGIT_2 7 # elif BOOST_PP_SLOT_TEMP_2 == 8 # define BOOST_PP_SLOT_5_DIGIT_2 8 # elif BOOST_PP_SLOT_TEMP_2 == 9 # define BOOST_PP_SLOT_5_DIGIT_2 9 # endif # # if BOOST_PP_SLOT_TEMP_1 == 0 # define BOOST_PP_SLOT_5_DIGIT_1 0 # elif BOOST_PP_SLOT_TEMP_1 == 1 # define BOOST_PP_SLOT_5_DIGIT_1 1 # elif BOOST_PP_SLOT_TEMP_1 == 2 # define BOOST_PP_SLOT_5_DIGIT_1 2 # elif BOOST_PP_SLOT_TEMP_1 == 3 # define BOOST_PP_SLOT_5_DIGIT_1 3 # elif BOOST_PP_SLOT_TEMP_1 == 4 # define BOOST_PP_SLOT_5_DIGIT_1 4 # elif BOOST_PP_SLOT_TEMP_1 == 5 # define BOOST_PP_SLOT_5_DIGIT_1 5 # elif BOOST_PP_SLOT_TEMP_1 == 6 # define BOOST_PP_SLOT_5_DIGIT_1 6 # elif BOOST_PP_SLOT_TEMP_1 == 7 # define BOOST_PP_SLOT_5_DIGIT_1 7 # elif BOOST_PP_SLOT_TEMP_1 == 8 # define BOOST_PP_SLOT_5_DIGIT_1 8 # elif BOOST_PP_SLOT_TEMP_1 == 9 # define BOOST_PP_SLOT_5_DIGIT_1 9 # endif # # if BOOST_PP_SLOT_5_DIGIT_10 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_10(BOOST_PP_SLOT_5_DIGIT_10, BOOST_PP_SLOT_5_DIGIT_9, BOOST_PP_SLOT_5_DIGIT_8, BOOST_PP_SLOT_5_DIGIT_7, BOOST_PP_SLOT_5_DIGIT_6, BOOST_PP_SLOT_5_DIGIT_5, BOOST_PP_SLOT_5_DIGIT_4, BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_9 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_9(BOOST_PP_SLOT_5_DIGIT_9, BOOST_PP_SLOT_5_DIGIT_8, BOOST_PP_SLOT_5_DIGIT_7, BOOST_PP_SLOT_5_DIGIT_6, BOOST_PP_SLOT_5_DIGIT_5, BOOST_PP_SLOT_5_DIGIT_4, BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_8 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_8(BOOST_PP_SLOT_5_DIGIT_8, BOOST_PP_SLOT_5_DIGIT_7, BOOST_PP_SLOT_5_DIGIT_6, BOOST_PP_SLOT_5_DIGIT_5, BOOST_PP_SLOT_5_DIGIT_4, BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_7 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_7(BOOST_PP_SLOT_5_DIGIT_7, BOOST_PP_SLOT_5_DIGIT_6, BOOST_PP_SLOT_5_DIGIT_5, BOOST_PP_SLOT_5_DIGIT_4, BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_6 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_6(BOOST_PP_SLOT_5_DIGIT_6, BOOST_PP_SLOT_5_DIGIT_5, BOOST_PP_SLOT_5_DIGIT_4, BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_5 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_5(BOOST_PP_SLOT_5_DIGIT_5, BOOST_PP_SLOT_5_DIGIT_4, BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_4 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_4(BOOST_PP_SLOT_5_DIGIT_4, BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_3 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_3(BOOST_PP_SLOT_5_DIGIT_3, BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # elif BOOST_PP_SLOT_5_DIGIT_2 # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_CC_2(BOOST_PP_SLOT_5_DIGIT_2, BOOST_PP_SLOT_5_DIGIT_1) # else # define BOOST_PP_SLOT_5() BOOST_PP_SLOT_5_DIGIT_1 # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/slot/slot.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002. # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_SLOT_SLOT_HPP # define BOOST_PREPROCESSOR_SLOT_SLOT_HPP # # include # include # # /* BOOST_PP_ASSIGN_SLOT */ # # define BOOST_PP_ASSIGN_SLOT(i) BOOST_PP_CAT(BOOST_PP_ASSIGN_SLOT_, i) # # define BOOST_PP_ASSIGN_SLOT_1 # define BOOST_PP_ASSIGN_SLOT_2 # define BOOST_PP_ASSIGN_SLOT_3 # define BOOST_PP_ASSIGN_SLOT_4 # define BOOST_PP_ASSIGN_SLOT_5 # # /* BOOST_PP_SLOT */ # # define BOOST_PP_SLOT(i) BOOST_PP_CAT(BOOST_PP_SLOT_, i)() # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/stringize.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_STRINGIZE_HPP # define BOOST_PREPROCESSOR_STRINGIZE_HPP # # include # # /* BOOST_PP_STRINGIZE */ # # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_A((text)) # define BOOST_PP_STRINGIZE_A(arg) BOOST_PP_STRINGIZE_I arg # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_OO((text)) # define BOOST_PP_STRINGIZE_OO(par) BOOST_PP_STRINGIZE_I ## par # else # define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_I(text) # endif # # define BOOST_PP_STRINGIZE_I(text) #text # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/tuple/detail/is_single_return.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2014. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_TUPLE_DETAIL_IS_SINGLE_RETURN_HPP # define BOOST_PREPROCESSOR_TUPLE_DETAIL_IS_SINGLE_RETURN_HPP # # include # # /* BOOST_PP_TUPLE_IS_SINGLE_RETURN */ # # if BOOST_PP_VARIADICS && BOOST_PP_VARIADICS_MSVC # include # include # include # define BOOST_PP_TUPLE_IS_SINGLE_RETURN(sr,nsr,tuple) \ BOOST_PP_IIF(BOOST_PP_IS_1(BOOST_PP_TUPLE_SIZE(tuple)),sr,nsr) \ /**/ # endif /* BOOST_PP_VARIADICS && BOOST_PP_VARIADICS_MSVC */ # # endif /* BOOST_PREPROCESSOR_TUPLE_DETAIL_IS_SINGLE_RETURN_HPP */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/tuple/eat.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002-2011) */ # /* Revised by Edward Diener (2011,2015) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_TUPLE_EAT_HPP # define BOOST_PREPROCESSOR_TUPLE_EAT_HPP # # include # # /* BOOST_PP_EAT */ # # if BOOST_PP_VARIADICS # define BOOST_PP_EAT(...) # else # define BOOST_PP_EAT(x) # endif # # /* BOOST_PP_TUPLE_EAT */ # # if BOOST_PP_VARIADICS # define BOOST_PP_TUPLE_EAT(size) BOOST_PP_EAT # else # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_TUPLE_EAT(size) BOOST_PP_TUPLE_EAT_I(size) # else # define BOOST_PP_TUPLE_EAT(size) BOOST_PP_TUPLE_EAT_OO((size)) # define BOOST_PP_TUPLE_EAT_OO(par) BOOST_PP_TUPLE_EAT_I ## par # endif # define BOOST_PP_TUPLE_EAT_I(size) BOOST_PP_TUPLE_EAT_ ## size # endif # # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_TUPLE_EAT_N(size) BOOST_PP_TUPLE_EAT_N_I(size) # else # define BOOST_PP_TUPLE_EAT_N(size) BOOST_PP_TUPLE_EAT_N_OO((size)) # define BOOST_PP_TUPLE_EAT_N_OO(par) BOOST_PP_TUPLE_EAT_N_I ## par # endif # define BOOST_PP_TUPLE_EAT_N_I(size) BOOST_PP_TUPLE_EAT_ ## size # # define BOOST_PP_TUPLE_EAT_1(e0) # define BOOST_PP_TUPLE_EAT_2(e0, e1) # define BOOST_PP_TUPLE_EAT_3(e0, e1, e2) # define BOOST_PP_TUPLE_EAT_4(e0, e1, e2, e3) # define BOOST_PP_TUPLE_EAT_5(e0, e1, e2, e3, e4) # define BOOST_PP_TUPLE_EAT_6(e0, e1, e2, e3, e4, e5) # define BOOST_PP_TUPLE_EAT_7(e0, e1, e2, e3, e4, e5, e6) # define BOOST_PP_TUPLE_EAT_8(e0, e1, e2, e3, e4, e5, e6, e7) # define BOOST_PP_TUPLE_EAT_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) # define BOOST_PP_TUPLE_EAT_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) # define BOOST_PP_TUPLE_EAT_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) # define BOOST_PP_TUPLE_EAT_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) # define BOOST_PP_TUPLE_EAT_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) # define BOOST_PP_TUPLE_EAT_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) # define BOOST_PP_TUPLE_EAT_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) # define BOOST_PP_TUPLE_EAT_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) # define BOOST_PP_TUPLE_EAT_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) # define BOOST_PP_TUPLE_EAT_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) # define BOOST_PP_TUPLE_EAT_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) # define BOOST_PP_TUPLE_EAT_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) # define BOOST_PP_TUPLE_EAT_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20) # define BOOST_PP_TUPLE_EAT_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21) # define BOOST_PP_TUPLE_EAT_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22) # define BOOST_PP_TUPLE_EAT_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23) # define BOOST_PP_TUPLE_EAT_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24) # define BOOST_PP_TUPLE_EAT_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25) # define BOOST_PP_TUPLE_EAT_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26) # define BOOST_PP_TUPLE_EAT_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27) # define BOOST_PP_TUPLE_EAT_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28) # define BOOST_PP_TUPLE_EAT_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29) # define BOOST_PP_TUPLE_EAT_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30) # define BOOST_PP_TUPLE_EAT_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31) # define BOOST_PP_TUPLE_EAT_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32) # define BOOST_PP_TUPLE_EAT_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33) # define BOOST_PP_TUPLE_EAT_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34) # define BOOST_PP_TUPLE_EAT_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35) # define BOOST_PP_TUPLE_EAT_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36) # define BOOST_PP_TUPLE_EAT_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37) # define BOOST_PP_TUPLE_EAT_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38) # define BOOST_PP_TUPLE_EAT_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39) # define BOOST_PP_TUPLE_EAT_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40) # define BOOST_PP_TUPLE_EAT_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41) # define BOOST_PP_TUPLE_EAT_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42) # define BOOST_PP_TUPLE_EAT_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43) # define BOOST_PP_TUPLE_EAT_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44) # define BOOST_PP_TUPLE_EAT_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45) # define BOOST_PP_TUPLE_EAT_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46) # define BOOST_PP_TUPLE_EAT_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47) # define BOOST_PP_TUPLE_EAT_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48) # define BOOST_PP_TUPLE_EAT_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49) # define BOOST_PP_TUPLE_EAT_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50) # define BOOST_PP_TUPLE_EAT_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51) # define BOOST_PP_TUPLE_EAT_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52) # define BOOST_PP_TUPLE_EAT_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53) # define BOOST_PP_TUPLE_EAT_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54) # define BOOST_PP_TUPLE_EAT_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55) # define BOOST_PP_TUPLE_EAT_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56) # define BOOST_PP_TUPLE_EAT_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57) # define BOOST_PP_TUPLE_EAT_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58) # define BOOST_PP_TUPLE_EAT_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59) # define BOOST_PP_TUPLE_EAT_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60) # define BOOST_PP_TUPLE_EAT_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61) # define BOOST_PP_TUPLE_EAT_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62) # define BOOST_PP_TUPLE_EAT_64(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/tuple/elem.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002-2011) */ # /* Revised by Edward Diener (2011,2014) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_TUPLE_ELEM_HPP # define BOOST_PREPROCESSOR_TUPLE_ELEM_HPP # # include # include # include # include # include # include # include # # if BOOST_PP_VARIADICS # if BOOST_PP_VARIADICS_MSVC # define BOOST_PP_TUPLE_ELEM(...) BOOST_PP_TUPLE_ELEM_I(BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_ELEM_O_, __VA_ARGS__), (__VA_ARGS__)) # define BOOST_PP_TUPLE_ELEM_I(m, args) BOOST_PP_TUPLE_ELEM_II(m, args) # define BOOST_PP_TUPLE_ELEM_II(m, args) BOOST_PP_CAT(m ## args,) /* Use BOOST_PP_REM_CAT if it is a single element tuple ( which might be empty ) else use BOOST_PP_REM. This fixes a VC++ problem with an empty tuple and BOOST_PP_TUPLE_ELEM functionality. See tuple_elem_bug_test.cxx. */ # define BOOST_PP_TUPLE_ELEM_O_2(n, tuple) \ BOOST_PP_VARIADIC_ELEM(n, BOOST_PP_EXPAND(BOOST_PP_TUPLE_IS_SINGLE_RETURN(BOOST_PP_REM_CAT,BOOST_PP_REM,tuple) tuple)) \ /**/ # else # define BOOST_PP_TUPLE_ELEM(...) BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_ELEM_O_, __VA_ARGS__)(__VA_ARGS__) # define BOOST_PP_TUPLE_ELEM_O_2(n, tuple) BOOST_PP_VARIADIC_ELEM(n, BOOST_PP_REM tuple) # endif # define BOOST_PP_TUPLE_ELEM_O_3(size, n, tuple) BOOST_PP_TUPLE_ELEM_O_2(n, tuple) # else # if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_TUPLE_ELEM(size, n, tuple) BOOST_PP_TUPLE_ELEM_I(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_, n), BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_E_, size), tuple)) # define BOOST_PP_TUPLE_ELEM_I(m, args) BOOST_PP_TUPLE_ELEM_II(m, args) # define BOOST_PP_TUPLE_ELEM_II(m, args) BOOST_PP_CAT(m ## args,) # elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_TUPLE_ELEM(size, n, tuple) BOOST_PP_TUPLE_ELEM_I_OO((size, n, tuple)) # define BOOST_PP_TUPLE_ELEM_I_OO(par) BOOST_PP_TUPLE_ELEM_I ## par # define BOOST_PP_TUPLE_ELEM_I(size, n, tuple) BOOST_PP_TUPLE_ELEM_II((n, BOOST_PP_TUPLE_ELEM_E_ ## size ## tuple)) # define BOOST_PP_TUPLE_ELEM_II(par) BOOST_PP_TUPLE_ELEM_III_OO(par) # define BOOST_PP_TUPLE_ELEM_III_OO(par) BOOST_PP_TUPLE_ELEM_III ## par # define BOOST_PP_TUPLE_ELEM_III(n, etuple) BOOST_PP_TUPLE_ELEM_ ## n ## etuple # else # define BOOST_PP_TUPLE_ELEM(size, n, tuple) BOOST_PP_TUPLE_ELEM_I(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_, n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_E_, size) tuple) # define BOOST_PP_TUPLE_ELEM_I(x) x # endif # define BOOST_PP_TUPLE_ELEM_E_1(e0) (e0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_2(e0, e1) (e0, e1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_3(e0, e1, e2) (e0, e1, e2, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_4(e0, e1, e2, e3) (e0, e1, e2, e3, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_5(e0, e1, e2, e3, e4) (e0, e1, e2, e3, e4, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_6(e0, e1, e2, e3, e4, e5) (e0, e1, e2, e3, e4, e5, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_7(e0, e1, e2, e3, e4, e5, e6) (e0, e1, e2, e3, e4, e5, e6, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_8(e0, e1, e2, e3, e4, e5, e6, e7) (e0, e1, e2, e3, e4, e5, e6, e7, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) (e0, e1, e2, e3, e4, e5, e6, e7, e8, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, ?, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, ?, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, ?, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, ?, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, ?, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, ?, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, ?, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, ?, ?) # define BOOST_PP_TUPLE_ELEM_E_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, ?) # define BOOST_PP_TUPLE_ELEM_E_64 # define BOOST_PP_TUPLE_ELEM_0(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e0 # define BOOST_PP_TUPLE_ELEM_1(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e1 # define BOOST_PP_TUPLE_ELEM_2(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e2 # define BOOST_PP_TUPLE_ELEM_3(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e3 # define BOOST_PP_TUPLE_ELEM_4(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e4 # define BOOST_PP_TUPLE_ELEM_5(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e5 # define BOOST_PP_TUPLE_ELEM_6(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e6 # define BOOST_PP_TUPLE_ELEM_7(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e7 # define BOOST_PP_TUPLE_ELEM_8(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e8 # define BOOST_PP_TUPLE_ELEM_9(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e9 # define BOOST_PP_TUPLE_ELEM_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e10 # define BOOST_PP_TUPLE_ELEM_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e11 # define BOOST_PP_TUPLE_ELEM_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e12 # define BOOST_PP_TUPLE_ELEM_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e13 # define BOOST_PP_TUPLE_ELEM_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e14 # define BOOST_PP_TUPLE_ELEM_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e15 # define BOOST_PP_TUPLE_ELEM_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e16 # define BOOST_PP_TUPLE_ELEM_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e17 # define BOOST_PP_TUPLE_ELEM_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e18 # define BOOST_PP_TUPLE_ELEM_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e19 # define BOOST_PP_TUPLE_ELEM_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e20 # define BOOST_PP_TUPLE_ELEM_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e21 # define BOOST_PP_TUPLE_ELEM_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e22 # define BOOST_PP_TUPLE_ELEM_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e23 # define BOOST_PP_TUPLE_ELEM_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e24 # define BOOST_PP_TUPLE_ELEM_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e25 # define BOOST_PP_TUPLE_ELEM_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e26 # define BOOST_PP_TUPLE_ELEM_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e27 # define BOOST_PP_TUPLE_ELEM_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e28 # define BOOST_PP_TUPLE_ELEM_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e29 # define BOOST_PP_TUPLE_ELEM_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e30 # define BOOST_PP_TUPLE_ELEM_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e31 # define BOOST_PP_TUPLE_ELEM_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e32 # define BOOST_PP_TUPLE_ELEM_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e33 # define BOOST_PP_TUPLE_ELEM_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e34 # define BOOST_PP_TUPLE_ELEM_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e35 # define BOOST_PP_TUPLE_ELEM_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e36 # define BOOST_PP_TUPLE_ELEM_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e37 # define BOOST_PP_TUPLE_ELEM_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e38 # define BOOST_PP_TUPLE_ELEM_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e39 # define BOOST_PP_TUPLE_ELEM_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e40 # define BOOST_PP_TUPLE_ELEM_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e41 # define BOOST_PP_TUPLE_ELEM_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e42 # define BOOST_PP_TUPLE_ELEM_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e43 # define BOOST_PP_TUPLE_ELEM_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e44 # define BOOST_PP_TUPLE_ELEM_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e45 # define BOOST_PP_TUPLE_ELEM_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e46 # define BOOST_PP_TUPLE_ELEM_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e47 # define BOOST_PP_TUPLE_ELEM_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e48 # define BOOST_PP_TUPLE_ELEM_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e49 # define BOOST_PP_TUPLE_ELEM_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e50 # define BOOST_PP_TUPLE_ELEM_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e51 # define BOOST_PP_TUPLE_ELEM_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e52 # define BOOST_PP_TUPLE_ELEM_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e53 # define BOOST_PP_TUPLE_ELEM_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e54 # define BOOST_PP_TUPLE_ELEM_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e55 # define BOOST_PP_TUPLE_ELEM_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e56 # define BOOST_PP_TUPLE_ELEM_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e57 # define BOOST_PP_TUPLE_ELEM_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e58 # define BOOST_PP_TUPLE_ELEM_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e59 # define BOOST_PP_TUPLE_ELEM_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e60 # define BOOST_PP_TUPLE_ELEM_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e61 # define BOOST_PP_TUPLE_ELEM_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e62 # define BOOST_PP_TUPLE_ELEM_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e63 # endif # # /* directly used elsewhere in Boost... */ # # define BOOST_PP_TUPLE_ELEM_1_0(a) a # # define BOOST_PP_TUPLE_ELEM_2_0(a, b) a # define BOOST_PP_TUPLE_ELEM_2_1(a, b) b # # define BOOST_PP_TUPLE_ELEM_3_0(a, b, c) a # define BOOST_PP_TUPLE_ELEM_3_1(a, b, c) b # define BOOST_PP_TUPLE_ELEM_3_2(a, b, c) c # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/tuple/rem.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Paul Mensonides 2002-2011. * # * (C) Copyright Edward Diener 2011,2013. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_TUPLE_REM_HPP # define BOOST_PREPROCESSOR_TUPLE_REM_HPP # # include # include # include # include # include # # /* BOOST_PP_REM */ # # if BOOST_PP_VARIADICS # if BOOST_PP_VARIADICS_MSVC /* To be used internally when __VA_ARGS__ could be empty ( or is a single element ) */ # define BOOST_PP_REM_CAT(...) BOOST_PP_CAT(__VA_ARGS__,) # endif # define BOOST_PP_REM(...) __VA_ARGS__ # else # define BOOST_PP_REM(x) x # endif # # /* BOOST_PP_TUPLE_REM */ # /* VC++8.0 cannot handle the variadic version of BOOST_PP_TUPLE_REM(size) */ # if BOOST_PP_VARIADICS && !(BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400) # if BOOST_PP_VARIADICS_MSVC /* To be used internally when the size could be 0 ( or 1 ) */ # define BOOST_PP_TUPLE_REM_CAT(size) BOOST_PP_REM_CAT # endif # define BOOST_PP_TUPLE_REM(size) BOOST_PP_REM # else # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_TUPLE_REM(size) BOOST_PP_TUPLE_REM_I(size) # else # define BOOST_PP_TUPLE_REM(size) BOOST_PP_TUPLE_REM_OO((size)) # define BOOST_PP_TUPLE_REM_OO(par) BOOST_PP_TUPLE_REM_I ## par # endif # define BOOST_PP_TUPLE_REM_I(size) BOOST_PP_TUPLE_REM_ ## size # endif # define BOOST_PP_TUPLE_REM_0() # define BOOST_PP_TUPLE_REM_1(e0) e0 # define BOOST_PP_TUPLE_REM_2(e0, e1) e0, e1 # define BOOST_PP_TUPLE_REM_3(e0, e1, e2) e0, e1, e2 # define BOOST_PP_TUPLE_REM_4(e0, e1, e2, e3) e0, e1, e2, e3 # define BOOST_PP_TUPLE_REM_5(e0, e1, e2, e3, e4) e0, e1, e2, e3, e4 # define BOOST_PP_TUPLE_REM_6(e0, e1, e2, e3, e4, e5) e0, e1, e2, e3, e4, e5 # define BOOST_PP_TUPLE_REM_7(e0, e1, e2, e3, e4, e5, e6) e0, e1, e2, e3, e4, e5, e6 # define BOOST_PP_TUPLE_REM_8(e0, e1, e2, e3, e4, e5, e6, e7) e0, e1, e2, e3, e4, e5, e6, e7 # define BOOST_PP_TUPLE_REM_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) e0, e1, e2, e3, e4, e5, e6, e7, e8 # define BOOST_PP_TUPLE_REM_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9 # define BOOST_PP_TUPLE_REM_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10 # define BOOST_PP_TUPLE_REM_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11 # define BOOST_PP_TUPLE_REM_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 # define BOOST_PP_TUPLE_REM_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13 # define BOOST_PP_TUPLE_REM_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14 # define BOOST_PP_TUPLE_REM_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15 # define BOOST_PP_TUPLE_REM_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16 # define BOOST_PP_TUPLE_REM_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17 # define BOOST_PP_TUPLE_REM_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18 # define BOOST_PP_TUPLE_REM_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19 # define BOOST_PP_TUPLE_REM_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20 # define BOOST_PP_TUPLE_REM_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21 # define BOOST_PP_TUPLE_REM_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22 # define BOOST_PP_TUPLE_REM_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23 # define BOOST_PP_TUPLE_REM_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24 # define BOOST_PP_TUPLE_REM_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25 # define BOOST_PP_TUPLE_REM_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26 # define BOOST_PP_TUPLE_REM_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27 # define BOOST_PP_TUPLE_REM_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28 # define BOOST_PP_TUPLE_REM_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29 # define BOOST_PP_TUPLE_REM_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30 # define BOOST_PP_TUPLE_REM_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31 # define BOOST_PP_TUPLE_REM_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32 # define BOOST_PP_TUPLE_REM_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33 # define BOOST_PP_TUPLE_REM_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34 # define BOOST_PP_TUPLE_REM_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35 # define BOOST_PP_TUPLE_REM_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36 # define BOOST_PP_TUPLE_REM_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37 # define BOOST_PP_TUPLE_REM_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38 # define BOOST_PP_TUPLE_REM_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39 # define BOOST_PP_TUPLE_REM_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40 # define BOOST_PP_TUPLE_REM_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41 # define BOOST_PP_TUPLE_REM_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42 # define BOOST_PP_TUPLE_REM_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43 # define BOOST_PP_TUPLE_REM_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44 # define BOOST_PP_TUPLE_REM_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45 # define BOOST_PP_TUPLE_REM_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46 # define BOOST_PP_TUPLE_REM_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47 # define BOOST_PP_TUPLE_REM_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48 # define BOOST_PP_TUPLE_REM_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49 # define BOOST_PP_TUPLE_REM_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50 # define BOOST_PP_TUPLE_REM_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51 # define BOOST_PP_TUPLE_REM_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52 # define BOOST_PP_TUPLE_REM_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53 # define BOOST_PP_TUPLE_REM_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54 # define BOOST_PP_TUPLE_REM_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55 # define BOOST_PP_TUPLE_REM_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56 # define BOOST_PP_TUPLE_REM_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57 # define BOOST_PP_TUPLE_REM_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58 # define BOOST_PP_TUPLE_REM_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59 # define BOOST_PP_TUPLE_REM_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60 # define BOOST_PP_TUPLE_REM_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61 # define BOOST_PP_TUPLE_REM_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62 # define BOOST_PP_TUPLE_REM_64(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63 # # /* BOOST_PP_TUPLE_REM_CTOR */ # # if BOOST_PP_VARIADICS # if BOOST_PP_VARIADICS_MSVC # define BOOST_PP_TUPLE_REM_CTOR(...) BOOST_PP_TUPLE_REM_CTOR_I(BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_REM_CTOR_O_, __VA_ARGS__), (__VA_ARGS__)) # define BOOST_PP_TUPLE_REM_CTOR_I(m, args) BOOST_PP_TUPLE_REM_CTOR_II(m, args) # define BOOST_PP_TUPLE_REM_CTOR_II(m, args) BOOST_PP_CAT(m ## args,) # define BOOST_PP_TUPLE_REM_CTOR_O_1(tuple) BOOST_PP_EXPAND(BOOST_PP_TUPLE_IS_SINGLE_RETURN(BOOST_PP_REM_CAT,BOOST_PP_REM,tuple) tuple) # else # define BOOST_PP_TUPLE_REM_CTOR(...) BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_REM_CTOR_O_, __VA_ARGS__)(__VA_ARGS__) # define BOOST_PP_TUPLE_REM_CTOR_O_1(tuple) BOOST_PP_REM tuple # endif # define BOOST_PP_TUPLE_REM_CTOR_O_2(size, tuple) BOOST_PP_TUPLE_REM_CTOR_O_1(tuple) # else # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG() # define BOOST_PP_TUPLE_REM_CTOR(size, tuple) BOOST_PP_TUPLE_REM_CTOR_I(BOOST_PP_TUPLE_REM(size), tuple) # else # define BOOST_PP_TUPLE_REM_CTOR(size, tuple) BOOST_PP_TUPLE_REM_CTOR_D(size, tuple) # define BOOST_PP_TUPLE_REM_CTOR_D(size, tuple) BOOST_PP_TUPLE_REM_CTOR_I(BOOST_PP_TUPLE_REM(size), tuple) # endif # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_TUPLE_REM_CTOR_I(ext, tuple) ext tuple # else # define BOOST_PP_TUPLE_REM_CTOR_I(ext, tuple) BOOST_PP_TUPLE_REM_CTOR_OO((ext, tuple)) # define BOOST_PP_TUPLE_REM_CTOR_OO(par) BOOST_PP_TUPLE_REM_CTOR_II ## par # define BOOST_PP_TUPLE_REM_CTOR_II(ext, tuple) ext ## tuple # endif # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/tuple/size.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2011. * # * (C) Copyright Paul Mensonides 2011. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_TUPLE_SIZE_HPP # define BOOST_PREPROCESSOR_TUPLE_SIZE_HPP # # include # include # include # # if BOOST_PP_VARIADICS # if BOOST_PP_VARIADICS_MSVC # define BOOST_PP_TUPLE_SIZE(tuple) BOOST_PP_CAT(BOOST_PP_VARIADIC_SIZE tuple,) # else # define BOOST_PP_TUPLE_SIZE(tuple) BOOST_PP_VARIADIC_SIZE tuple # endif # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/tuple/to_list.hpp ================================================ # /* Copyright (C) 2001 # * Housemarque Oy # * http://www.housemarque.com # * # * Distributed under the Boost Software License, Version 1.0. (See # * accompanying file LICENSE_1_0.txt or copy at # * http://www.boost.org/LICENSE_1_0.txt) # */ # # /* Revised by Paul Mensonides (2002-2011) */ # /* Revised by Edward Diener (2011) */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_TUPLE_TO_LIST_HPP # define BOOST_PREPROCESSOR_TUPLE_TO_LIST_HPP # # include # include # include # include # include # # /* BOOST_PP_TUPLE_TO_LIST */ # # if BOOST_PP_VARIADICS # if BOOST_PP_VARIADICS_MSVC # define BOOST_PP_TUPLE_TO_LIST(...) BOOST_PP_TUPLE_TO_LIST_I(BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_TO_LIST_O_, __VA_ARGS__), (__VA_ARGS__)) # define BOOST_PP_TUPLE_TO_LIST_I(m, args) BOOST_PP_TUPLE_TO_LIST_II(m, args) # define BOOST_PP_TUPLE_TO_LIST_II(m, args) BOOST_PP_CAT(m ## args,) # define BOOST_PP_TUPLE_TO_LIST_O_1(tuple) BOOST_PP_CAT(BOOST_PP_TUPLE_TO_LIST_, BOOST_PP_TUPLE_SIZE(tuple)) tuple # else # define BOOST_PP_TUPLE_TO_LIST(...) BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_TO_LIST_O_, __VA_ARGS__)(__VA_ARGS__) # define BOOST_PP_TUPLE_TO_LIST_O_1(tuple) BOOST_PP_CAT(BOOST_PP_TUPLE_TO_LIST_, BOOST_PP_VARIADIC_SIZE tuple) tuple # endif # define BOOST_PP_TUPLE_TO_LIST_O_2(size, tuple) BOOST_PP_TUPLE_TO_LIST_O_1(tuple) # else # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() # define BOOST_PP_TUPLE_TO_LIST(size, tuple) BOOST_PP_TUPLE_TO_LIST_I(size, tuple) # if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() # define BOOST_PP_TUPLE_TO_LIST_I(s, t) BOOST_PP_TUPLE_TO_LIST_ ## s t # else # define BOOST_PP_TUPLE_TO_LIST_I(s, t) BOOST_PP_TUPLE_TO_LIST_II(BOOST_PP_TUPLE_TO_LIST_ ## s t) # define BOOST_PP_TUPLE_TO_LIST_II(res) res # endif # else # define BOOST_PP_TUPLE_TO_LIST(size, tuple) BOOST_PP_TUPLE_TO_LIST_OO((size, tuple)) # define BOOST_PP_TUPLE_TO_LIST_OO(par) BOOST_PP_TUPLE_TO_LIST_I ## par # define BOOST_PP_TUPLE_TO_LIST_I(s, t) BOOST_PP_TUPLE_TO_LIST_ ## s ## t # endif # endif # # define BOOST_PP_TUPLE_TO_LIST_1(e0) (e0, BOOST_PP_NIL) # define BOOST_PP_TUPLE_TO_LIST_2(e0, e1) (e0, (e1, BOOST_PP_NIL)) # define BOOST_PP_TUPLE_TO_LIST_3(e0, e1, e2) (e0, (e1, (e2, BOOST_PP_NIL))) # define BOOST_PP_TUPLE_TO_LIST_4(e0, e1, e2, e3) (e0, (e1, (e2, (e3, BOOST_PP_NIL)))) # define BOOST_PP_TUPLE_TO_LIST_5(e0, e1, e2, e3, e4) (e0, (e1, (e2, (e3, (e4, BOOST_PP_NIL))))) # define BOOST_PP_TUPLE_TO_LIST_6(e0, e1, e2, e3, e4, e5) (e0, (e1, (e2, (e3, (e4, (e5, BOOST_PP_NIL)))))) # define BOOST_PP_TUPLE_TO_LIST_7(e0, e1, e2, e3, e4, e5, e6) (e0, (e1, (e2, (e3, (e4, (e5, (e6, BOOST_PP_NIL))))))) # define BOOST_PP_TUPLE_TO_LIST_8(e0, e1, e2, e3, e4, e5, e6, e7) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, BOOST_PP_NIL)))))))) # define BOOST_PP_TUPLE_TO_LIST_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, BOOST_PP_NIL))))))))) # define BOOST_PP_TUPLE_TO_LIST_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, BOOST_PP_NIL)))))))))) # define BOOST_PP_TUPLE_TO_LIST_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, BOOST_PP_NIL))))))))))) # define BOOST_PP_TUPLE_TO_LIST_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, BOOST_PP_NIL)))))))))))) # define BOOST_PP_TUPLE_TO_LIST_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, BOOST_PP_NIL))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, BOOST_PP_NIL)))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, BOOST_PP_NIL))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, BOOST_PP_NIL)))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, BOOST_PP_NIL))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, BOOST_PP_NIL)))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, BOOST_PP_NIL))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, BOOST_PP_NIL)))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, BOOST_PP_NIL))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, BOOST_PP_NIL)))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, BOOST_PP_NIL))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, BOOST_PP_NIL)))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, BOOST_PP_NIL))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, BOOST_PP_NIL)))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, BOOST_PP_NIL))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, BOOST_PP_NIL)))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, BOOST_PP_NIL))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, BOOST_PP_NIL)))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, BOOST_PP_NIL))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, BOOST_PP_NIL)))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, BOOST_PP_NIL))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, BOOST_PP_NIL)))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, BOOST_PP_NIL))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, (e57, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, (e57, (e58, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, (e57, (e58, (e59, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, (e57, (e58, (e59, (e60, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, (e57, (e58, (e59, (e60, (e61, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, (e57, (e58, (e59, (e60, (e61, (e62, BOOST_PP_NIL))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # define BOOST_PP_TUPLE_TO_LIST_64(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) (e0, (e1, (e2, (e3, (e4, (e5, (e6, (e7, (e8, (e9, (e10, (e11, (e12, (e13, (e14, (e15, (e16, (e17, (e18, (e19, (e20, (e21, (e22, (e23, (e24, (e25, (e26, (e27, (e28, (e29, (e30, (e31, (e32, (e33, (e34, (e35, (e36, (e37, (e38, (e39, (e40, (e41, (e42, (e43, (e44, (e45, (e46, (e47, (e48, (e49, (e50, (e51, (e52, (e53, (e54, (e55, (e56, (e57, (e58, (e59, (e60, (e61, (e62, (e63, BOOST_PP_NIL)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/variadic/elem.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2011. * # * (C) Copyright Paul Mensonides 2011. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_VARIADIC_ELEM_HPP # define BOOST_PREPROCESSOR_VARIADIC_ELEM_HPP # # include # include # # /* BOOST_PP_VARIADIC_ELEM */ # # if BOOST_PP_VARIADICS # if BOOST_PP_VARIADICS_MSVC # define BOOST_PP_VARIADIC_ELEM(n, ...) BOOST_PP_VARIADIC_ELEM_I(n,__VA_ARGS__) # define BOOST_PP_VARIADIC_ELEM_I(n, ...) BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM_, n)(__VA_ARGS__,),) # else # define BOOST_PP_VARIADIC_ELEM(n, ...) BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM_, n)(__VA_ARGS__,) # endif # define BOOST_PP_VARIADIC_ELEM_0(e0, ...) e0 # define BOOST_PP_VARIADIC_ELEM_1(e0, e1, ...) e1 # define BOOST_PP_VARIADIC_ELEM_2(e0, e1, e2, ...) e2 # define BOOST_PP_VARIADIC_ELEM_3(e0, e1, e2, e3, ...) e3 # define BOOST_PP_VARIADIC_ELEM_4(e0, e1, e2, e3, e4, ...) e4 # define BOOST_PP_VARIADIC_ELEM_5(e0, e1, e2, e3, e4, e5, ...) e5 # define BOOST_PP_VARIADIC_ELEM_6(e0, e1, e2, e3, e4, e5, e6, ...) e6 # define BOOST_PP_VARIADIC_ELEM_7(e0, e1, e2, e3, e4, e5, e6, e7, ...) e7 # define BOOST_PP_VARIADIC_ELEM_8(e0, e1, e2, e3, e4, e5, e6, e7, e8, ...) e8 # define BOOST_PP_VARIADIC_ELEM_9(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ...) e9 # define BOOST_PP_VARIADIC_ELEM_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, ...) e10 # define BOOST_PP_VARIADIC_ELEM_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, ...) e11 # define BOOST_PP_VARIADIC_ELEM_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, ...) e12 # define BOOST_PP_VARIADIC_ELEM_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, ...) e13 # define BOOST_PP_VARIADIC_ELEM_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, ...) e14 # define BOOST_PP_VARIADIC_ELEM_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, ...) e15 # define BOOST_PP_VARIADIC_ELEM_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, ...) e16 # define BOOST_PP_VARIADIC_ELEM_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, ...) e17 # define BOOST_PP_VARIADIC_ELEM_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, ...) e18 # define BOOST_PP_VARIADIC_ELEM_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, ...) e19 # define BOOST_PP_VARIADIC_ELEM_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, ...) e20 # define BOOST_PP_VARIADIC_ELEM_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, ...) e21 # define BOOST_PP_VARIADIC_ELEM_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, ...) e22 # define BOOST_PP_VARIADIC_ELEM_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, ...) e23 # define BOOST_PP_VARIADIC_ELEM_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, ...) e24 # define BOOST_PP_VARIADIC_ELEM_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, ...) e25 # define BOOST_PP_VARIADIC_ELEM_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, ...) e26 # define BOOST_PP_VARIADIC_ELEM_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, ...) e27 # define BOOST_PP_VARIADIC_ELEM_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, ...) e28 # define BOOST_PP_VARIADIC_ELEM_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, ...) e29 # define BOOST_PP_VARIADIC_ELEM_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, ...) e30 # define BOOST_PP_VARIADIC_ELEM_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, ...) e31 # define BOOST_PP_VARIADIC_ELEM_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, ...) e32 # define BOOST_PP_VARIADIC_ELEM_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, ...) e33 # define BOOST_PP_VARIADIC_ELEM_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, ...) e34 # define BOOST_PP_VARIADIC_ELEM_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, ...) e35 # define BOOST_PP_VARIADIC_ELEM_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, ...) e36 # define BOOST_PP_VARIADIC_ELEM_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, ...) e37 # define BOOST_PP_VARIADIC_ELEM_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, ...) e38 # define BOOST_PP_VARIADIC_ELEM_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, ...) e39 # define BOOST_PP_VARIADIC_ELEM_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, ...) e40 # define BOOST_PP_VARIADIC_ELEM_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, ...) e41 # define BOOST_PP_VARIADIC_ELEM_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, ...) e42 # define BOOST_PP_VARIADIC_ELEM_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, ...) e43 # define BOOST_PP_VARIADIC_ELEM_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, ...) e44 # define BOOST_PP_VARIADIC_ELEM_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, ...) e45 # define BOOST_PP_VARIADIC_ELEM_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, ...) e46 # define BOOST_PP_VARIADIC_ELEM_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, ...) e47 # define BOOST_PP_VARIADIC_ELEM_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, ...) e48 # define BOOST_PP_VARIADIC_ELEM_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, ...) e49 # define BOOST_PP_VARIADIC_ELEM_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, ...) e50 # define BOOST_PP_VARIADIC_ELEM_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, ...) e51 # define BOOST_PP_VARIADIC_ELEM_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, ...) e52 # define BOOST_PP_VARIADIC_ELEM_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, ...) e53 # define BOOST_PP_VARIADIC_ELEM_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, ...) e54 # define BOOST_PP_VARIADIC_ELEM_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, ...) e55 # define BOOST_PP_VARIADIC_ELEM_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, ...) e56 # define BOOST_PP_VARIADIC_ELEM_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, ...) e57 # define BOOST_PP_VARIADIC_ELEM_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, ...) e58 # define BOOST_PP_VARIADIC_ELEM_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, ...) e59 # define BOOST_PP_VARIADIC_ELEM_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, ...) e60 # define BOOST_PP_VARIADIC_ELEM_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, ...) e61 # define BOOST_PP_VARIADIC_ELEM_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, ...) e62 # define BOOST_PP_VARIADIC_ELEM_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, ...) e63 # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/preprocessor/variadic/size.hpp ================================================ # /* ************************************************************************** # * * # * (C) Copyright Edward Diener 2011. * # * (C) Copyright Paul Mensonides 2011. * # * Distributed under the Boost Software License, Version 1.0. (See * # * accompanying file LICENSE_1_0.txt or copy at * # * http://www.boost.org/LICENSE_1_0.txt) * # * * # ************************************************************************** */ # # /* See http://www.boost.org for most recent version. */ # # ifndef BOOST_PREPROCESSOR_VARIADIC_SIZE_HPP # define BOOST_PREPROCESSOR_VARIADIC_SIZE_HPP # # include # include # # /* BOOST_PP_VARIADIC_SIZE */ # # if BOOST_PP_VARIADICS # if BOOST_PP_VARIADICS_MSVC # define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_CAT(BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),) # else # define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,) # endif # define BOOST_PP_VARIADIC_SIZE_I(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, size, ...) size # endif # # endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/static_assert.hpp ================================================ // (C) Copyright John Maddock 2000. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/static_assert for documentation. /* Revision history: 02 August 2000 Initial version. */ #ifndef BOOST_STATIC_ASSERT_HPP #define BOOST_STATIC_ASSERT_HPP #include #include #if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) // // This is horrible, but it seems to be the only we can shut up the // "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]" // warning that get spewed out otherwise in non-C++11 mode. // #pragma GCC system_header #endif #ifndef BOOST_NO_CXX11_STATIC_ASSERT # ifndef BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_STATIC_ASSERT_MSG( ... ) static_assert(__VA_ARGS__) # else # define BOOST_STATIC_ASSERT_MSG( B, Msg ) static_assert( B, Msg ) # endif #else # define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B ) #endif #ifdef __BORLANDC__ // // workaround for buggy integral-constant expression support: #define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS #endif #if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) // gcc 3.3 and 3.4 don't produce good error messages with the default version: # define BOOST_SA_GCC_WORKAROUND #endif // // If the compiler issues warnings about old C style casts, // then enable this: // #if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) # ifndef BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) ((__VA_ARGS__) == 0 ? false : true) # else # define BOOST_STATIC_ASSERT_BOOL_CAST( x ) ((x) == 0 ? false : true) # endif #else # ifndef BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) (bool)(__VA_ARGS__) # else # define BOOST_STATIC_ASSERT_BOOL_CAST(x) (bool)(x) # endif #endif #ifndef BOOST_NO_CXX11_STATIC_ASSERT # ifndef BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__) # else # define BOOST_STATIC_ASSERT( B ) static_assert(B, #B) # endif #else namespace boost{ // HP aCC cannot deal with missing names for template value parameters template struct STATIC_ASSERTION_FAILURE; template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; // HP aCC cannot deal with missing names for template value parameters template struct static_assert_test{}; } // // Implicit instantiation requires that all member declarations be // instantiated, but that the definitions are *not* instantiated. // // It's not particularly clear how this applies to enum's or typedefs; // both are described as declarations [7.1.3] and [7.2] in the standard, // however some compilers use "delayed evaluation" of one or more of // these when implicitly instantiating templates. We use typedef declarations // by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum // version gets better results from your compiler... // // Implementation: // Both of these versions rely on sizeof(incomplete_type) generating an error // message containing the name of the incomplete type. We use // "STATIC_ASSERTION_FAILURE" as the type name here to generate // an eye catching error message. The result of the sizeof expression is either // used as an enum initialiser, or as a template argument depending which version // is in use... // Note that the argument to the assert is explicitly cast to bool using old- // style casts: too many compilers currently have problems with static_cast // when used inside integral constant expressions. // #if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) #if defined(BOOST_MSVC) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) #define BOOST_STATIC_ASSERT( B ) \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\ BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) #elif defined(BOOST_MSVC) #define BOOST_STATIC_ASSERT(...) \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST (__VA_ARGS__) >)>\ BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) #elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) // agurt 15/sep/02: a special care is needed to force Intel C++ issue an error // instead of warning in case of failure # define BOOST_STATIC_ASSERT( B ) \ typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ] #elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && !defined(BOOST_NO_CXX11_VARIADIC_MACROS) // agurt 15/sep/02: a special care is needed to force Intel C++ issue an error // instead of warning in case of failure # define BOOST_STATIC_ASSERT(...) \ typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >::value ] #elif defined(__sgi) // special version for SGI MIPSpro compiler #define BOOST_STATIC_ASSERT( B ) \ BOOST_STATIC_CONSTANT(bool, \ BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< \ BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\ BOOST_JOIN(boost_static_assert_typedef_, __LINE__) #elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // special version for CodeWarrior <= 8.x #define BOOST_STATIC_ASSERT( B ) \ BOOST_STATIC_CONSTANT(int, \ BOOST_JOIN(boost_static_assert_test_, __LINE__) = \ sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) ) #else // generic version # ifndef BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_STATIC_ASSERT( ... ) \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\ BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED # else # define BOOST_STATIC_ASSERT( B ) \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\ BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED # endif #endif #else // alternative enum based implementation: # ifndef BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_STATIC_ASSERT( ... ) \ enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( __VA_ARGS__ ) >) } # else # define BOOST_STATIC_ASSERT(B) \ enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } # endif #endif #endif // defined(BOOST_NO_CXX11_STATIC_ASSERT) #endif // BOOST_STATIC_ASSERT_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/swap.hpp ================================================ /* * Copyright (c) 2014 Glen Fernandes * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_SWAP_HPP #define BOOST_SWAP_HPP // The header file at this path is deprecated; // use boost/core/swap.hpp instead. #include #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/throw_exception.hpp ================================================ #ifndef UUID_AA15E74A856F11E08B8D93F24824019B #define UUID_AA15E74A856F11E08B8D93F24824019B #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma warning(push,1) #endif // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif // // boost/throw_exception.hpp // // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // http://www.boost.org/libs/utility/throw_exception.html // #include #include #include #if !defined( BOOST_EXCEPTION_DISABLE ) && defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x593) ) # define BOOST_EXCEPTION_DISABLE #endif #if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1310 ) # define BOOST_EXCEPTION_DISABLE #endif #if !defined( BOOST_EXCEPTION_DISABLE ) # include #if !defined(BOOST_THROW_EXCEPTION_CURRENT_FUNCTION) # include # define BOOST_THROW_EXCEPTION_CURRENT_FUNCTION BOOST_CURRENT_FUNCTION #endif # define BOOST_THROW_EXCEPTION(x) ::boost::exception_detail::throw_exception_(x,BOOST_THROW_EXCEPTION_CURRENT_FUNCTION,__FILE__,__LINE__) #else # define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x) #endif namespace boost { #ifdef BOOST_NO_EXCEPTIONS void throw_exception( std::exception const & e ); // user defined #else inline void throw_exception_assert_compatibility( std::exception const & ) { } template BOOST_NORETURN inline void throw_exception( E const & e ) { //All boost exceptions are required to derive from std::exception, //to ensure compatibility with BOOST_NO_EXCEPTIONS. throw_exception_assert_compatibility(e); #ifndef BOOST_EXCEPTION_DISABLE throw enable_current_exception(enable_error_info(e)); #else throw e; #endif } #endif #if !defined( BOOST_EXCEPTION_DISABLE ) namespace exception_detail { template BOOST_NORETURN void throw_exception_( E const & x, char const * current_function, char const * file, int line ) { boost::throw_exception( set_info( set_info( set_info( enable_error_info(x), throw_function(current_function)), throw_file(file)), throw_line(line))); } } #endif } // namespace boost #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma warning(pop) #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/add_const.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_ADD_CONST_HPP_INCLUDED #define BOOST_TT_ADD_CONST_HPP_INCLUDED #include namespace boost { // * convert a type T to const type - add_const // this is not required since the result is always // the same as "T const", but it does suppress warnings // from some compilers: #if defined(BOOST_MSVC) // This bogus warning will appear when add_const is applied to a // const volatile reference because we can't detect const volatile // references with MSVC6. # pragma warning(push) # pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored #endif template struct add_const { typedef T const type; }; #if defined(BOOST_MSVC) # pragma warning(pop) #endif template struct add_const { typedef T& type; }; } // namespace boost #endif // BOOST_TT_ADD_CONST_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/add_lvalue_reference.hpp ================================================ // Copyright 2010 John Maddock // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP #define BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP #include namespace boost{ template struct add_lvalue_reference { typedef typename boost::add_reference::type type; }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct add_lvalue_reference { typedef T& type; }; #endif } #endif // BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/add_reference.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_ADD_REFERENCE_HPP_INCLUDED #define BOOST_TT_ADD_REFERENCE_HPP_INCLUDED #include #include namespace boost { namespace detail { // // We can't filter out rvalue_references at the same level as // references or we get ambiguities from msvc: // template struct add_reference_impl { typedef T& type; }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct add_reference_impl { typedef T&& type; }; #endif } // namespace detail template struct add_reference { typedef typename boost::detail::add_reference_impl::type type; }; template struct add_reference { typedef T& type; }; // these full specialisations are always required: template <> struct add_reference { typedef void type; }; #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template <> struct add_reference { typedef void type; }; template <> struct add_reference { typedef void type; }; template <> struct add_reference { typedef void type; }; #endif } // namespace boost #endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/add_rvalue_reference.hpp ================================================ // add_rvalue_reference.hpp ---------------------------------------------------------// // Copyright 2010 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP #define BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP #include //----------------------------------------------------------------------------// #include #include //----------------------------------------------------------------------------// // // // C++03 implementation of // // 20.9.7.2 Reference modifications [meta.trans.ref] // // Written by Vicente J. Botet Escriba // // // // If T names an object or function type then the member typedef type // shall name T&&; otherwise, type shall name T. [ Note: This rule reflects // the semantics of reference collapsing. For example, when a type T names // a type T1&, the type add_rvalue_reference::type is not an rvalue // reference. -end note ] //----------------------------------------------------------------------------// namespace boost { namespace type_traits_detail { template struct add_rvalue_reference_helper { typedef T type; }; #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template struct add_rvalue_reference_helper { typedef T&& type; }; #endif template struct add_rvalue_reference_imp { typedef typename boost::type_traits_detail::add_rvalue_reference_helper ::value == false && is_reference::value == false) >::type type; }; } template struct add_rvalue_reference { typedef typename boost::type_traits_detail::add_rvalue_reference_imp::type type; }; } // namespace boost #endif // BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/add_volatile.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_ADD_VOLATILE_HPP_INCLUDED #define BOOST_TT_ADD_VOLATILE_HPP_INCLUDED #include namespace boost { // * convert a type T to volatile type - add_volatile // this is not required since the result is always // the same as "T volatile", but it does suppress warnings // from some compilers: #if defined(BOOST_MSVC) // This bogus warning will appear when add_volatile is applied to a // const volatile reference because we can't detect const volatile // references with MSVC6. # pragma warning(push) # pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored #endif template struct add_volatile{ typedef T volatile type; }; #if defined(BOOST_MSVC) # pragma warning(pop) #endif template struct add_volatile{ typedef T& type; }; } // namespace boost #endif // BOOST_TT_ADD_VOLATILE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/conditional.hpp ================================================ // (C) Copyright John Maddock 2010. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_CONDITIONAL_HPP_INCLUDED #define BOOST_TT_CONDITIONAL_HPP_INCLUDED namespace boost { template struct conditional { typedef T type; }; template struct conditional { typedef U type; }; } // namespace boost #endif // BOOST_TT_CONDITIONAL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/declval.hpp ================================================ // declval.hpp -------------------------------------------------------------// // Copyright 2010 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED #define BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED #include //----------------------------------------------------------------------------// #include //----------------------------------------------------------------------------// // // // C++03 implementation of // // 20.2.4 Function template declval [declval] // // Written by Vicente J. Botet Escriba // // // // 1 The library provides the function template declval to simplify the // definition of expressions which occur as unevaluated operands. // 2 Remarks: If this function is used, the program is ill-formed. // 3 Remarks: The template parameter T of declval may be an incomplete type. // [ Example: // // template // decltype(static_cast(declval())) convert(From&&); // // declares a function template convert which only participates in overloading // if the type From can be explicitly converted to type To. For another example // see class template common_type (20.9.7.6). -end example ] //----------------------------------------------------------------------------// namespace boost { template typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand } // namespace boost #endif // BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/detail/config.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_CONFIG_HPP_INCLUDED #define BOOST_TT_CONFIG_HPP_INCLUDED #ifndef BOOST_CONFIG_HPP #include #endif #include #include // // whenever we have a conversion function with ellipses // it needs to be declared __cdecl to suppress compiler // warnings from MS and Borland compilers (this *must* // appear before we include is_same.hpp below): #if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32)) # define BOOST_TT_DECL __cdecl #else # define BOOST_TT_DECL /**/ #endif # if (BOOST_WORKAROUND(__MWERKS__, < 0x3000) \ || BOOST_WORKAROUND(__IBMCPP__, < 600 ) \ || BOOST_WORKAROUND(__BORLANDC__, < 0x5A0) \ || defined(__ghs) \ || BOOST_WORKAROUND(__HP_aCC, < 60700) \ || BOOST_WORKAROUND(MPW_CPLUS, BOOST_TESTED_AT(0x890)) \ || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))) \ && defined(BOOST_NO_IS_ABSTRACT) # define BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION 1 #endif #ifndef BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION # define BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION 1 #endif // // define BOOST_TT_TEST_MS_FUNC_SIGS // when we want to test __stdcall etc function types with is_function etc // (Note, does not work with Borland, even though it does support __stdcall etc): // #if defined(_MSC_EXTENSIONS) && !defined(__BORLANDC__) # define BOOST_TT_TEST_MS_FUNC_SIGS #endif // // define BOOST_TT_NO_CV_FUNC_TEST // if tests for cv-qualified member functions don't // work in is_member_function_pointer // #if BOOST_WORKAROUND(__MWERKS__, < 0x3000) || BOOST_WORKAROUND(__IBMCPP__, <= 600) # define BOOST_TT_NO_CV_FUNC_TEST #endif // // Macros that have been deprecated, defined here for backwards compatibility: // #define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(x) #define BOOST_TT_BROKEN_COMPILER_SPEC(x) #endif // BOOST_TT_CONFIG_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/detail/is_function_ptr_helper.hpp ================================================ // Copyright 2000 John Maddock (john@johnmaddock.co.uk) // Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com) // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED #define BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED #if defined(BOOST_TT_PREPROCESSING_MODE) // // Hide these #include from dependency analysers as // these are required in maintenance mode only: // #define PP1 #include PP1 #undef PP1 #define PP1 #include PP1 #undef PP1 #define PP1 #include PP1 #undef PP1 #endif namespace boost { namespace type_traits { template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = false); }; #if !defined(BOOST_TT_PREPROCESSING_MODE) // preprocessor-generated part, don't edit by hand! template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; #else #undef BOOST_STATIC_CONSTANT #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, 25, "boost/type_traits/detail/is_function_ptr_helper.hpp")) #include BOOST_PP_ITERATE() #endif // BOOST_TT_PREPROCESSING_MODE } // namespace type_traits } // namespace boost #endif // BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED ///// iteration #else #define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; @#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING template struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; @#endif #undef BOOST_PP_COUNTER #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/detail/is_function_ptr_tester.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_TT_DETAIL_IS_FUNCTION_PTR_TESTER_HPP_INCLUDED #define BOOST_TT_DETAIL_IS_FUNCTION_PTR_TESTER_HPP_INCLUDED #include #if defined(BOOST_TT_PREPROCESSING_MODE) // // Hide include dependencies from analysers since they're // only require in maintenance mode: // #define PP1 #define PP2 #define PP3 #include PP1 #include PP2 #include PP3 #undef PP1 #undef PP2 #undef PP3 #endif namespace boost { namespace type_traits { // Note it is acceptable to use ellipsis here, since the argument will // always be a pointer type of some sort (JM 2005/06/04): no_type BOOST_TT_DECL is_function_ptr_tester(...); #if !defined(BOOST_TT_PREPROCESSING_MODE) // pre-processed code, don't edit, try GNU cpp with // cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename template yes_type is_function_ptr_tester(R (*)()); template yes_type is_function_ptr_tester(R (*)( ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)()); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)()); #endif template yes_type is_function_ptr_tester(R (__cdecl*)()); #endif template yes_type is_function_ptr_tester(R (*)( T0)); template yes_type is_function_ptr_tester(R (*)( T0 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); #endif template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); template yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...)); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); #ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); #endif template yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); #endif #else #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, 25, "boost/type_traits/detail/is_function_ptr_tester.hpp")) #include BOOST_PP_ITERATE() #endif // BOOST_TT_PREPROCESSING_MODE } // namespace type_traits } // namespace boost #endif // BOOST_TT_DETAIL_IS_FUNCTION_PTR_TESTER_HPP_INCLUDED ///// iteration #else #define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) #undef __stdcall #undef __fastcall #undef __cdecl template yes_type is_function_ptr_tester(R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); @#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING template yes_type is_function_ptr_tester(R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...)); @#endif @#ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_function_ptr_tester(R (__stdcall*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); @#ifndef _MANAGED template yes_type is_function_ptr_tester(R (__fastcall*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); @#endif template yes_type is_function_ptr_tester(R (__cdecl*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); @#endif #undef BOOST_PP_COUNTER #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED #define BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED #include #if defined(BOOST_TT_PREPROCESSING_MODE) // // Maintenance mode, hide include dependencies // from trackers: // #define PPI #include PPI #undef PPI #define PPI #include PPI #undef PPI #define PPI #include PPI #undef PPI #endif namespace boost { namespace type_traits { template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = false); }; #if !defined(BOOST_TT_PREPROCESSING_MODE) // pre-processed code, don't edit, try GNU cpp with // cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; #endif #else #undef BOOST_STATIC_CONSTANT #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, 25, "boost/type_traits/detail/is_mem_fun_pointer_impl.hpp")) #include BOOST_PP_ITERATE() #endif // BOOST_TT_PREPROCESSING_MODE } // namespace type_traits } // namespace boost #endif // BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED ///// iteration #else #define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; @#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; @#endif @#if !defined(BOOST_TT_NO_CV_FUNC_TEST) template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; @#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; template struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; @#endif @#endif #undef BOOST_PP_COUNTER #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #if !defined(BOOST_PP_IS_ITERATING) ///// header body #ifndef BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_TESTER_HPP_INCLUDED #define BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_TESTER_HPP_INCLUDED #include #include #if defined(BOOST_TT_PREPROCESSING_MODE) // // Maintentance mode, hide include dependencies // from dependency trackers: // #define PPI #include PPI #undef PPI #define PPI #include PPI #undef PPI #define #include PPI #undef #endif namespace boost { namespace type_traits { no_type BOOST_TT_DECL is_mem_fun_pointer_tester(...); #if !defined(BOOST_TT_PREPROCESSING_MODE) // pre-processed code, don't edit, try GNU cpp with // cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)()); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)() const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)() volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)() const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)()); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)() const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)() volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)() const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)()); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)() const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)() volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)() const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)()); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)() const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)() volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)() const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) const volatile); #ifdef BOOST_TT_TEST_MS_FUNC_SIGS template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); #ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); #endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); #endif #else #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, 25, "boost/type_traits/detail/is_mem_fun_pointer_tester.hpp")) #include BOOST_PP_ITERATE() #endif // BOOST_TT_PREPROCESSING_MODE } // namespace type_traits } // namespace boost #endif // BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_TESTER_HPP_INCLUDED ///// iteration #else #define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) #undef __stdcall #undef __fastcall #undef __cdecl template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); @#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...)); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) const); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) volatile); template yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) const volatile); @#endif @#ifdef BOOST_TT_TEST_MS_FUNC_SIGS // Other calling conventions used by MS compatible compilers: template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); template yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); @#ifndef _MANAGED template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); template yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); @#endif template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); template yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); @#endif #undef BOOST_PP_COUNTER #endif // BOOST_PP_IS_ITERATING ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/detail/yes_no_type.hpp ================================================ // (C) Copyright John Maddock and Steve Cleary 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // // macros and helpers for working with integral-constant-expressions. #ifndef BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED #define BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED namespace boost { namespace type_traits { typedef char yes_type; struct no_type { char padding[8]; }; } // namespace type_traits } // namespace boost #endif // BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/has_trivial_assign.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_HAS_TRIVIAL_ASSIGN_HPP_INCLUDED #define BOOST_TT_HAS_TRIVIAL_ASSIGN_HPP_INCLUDED #include #include #include #if !defined(BOOST_HAS_TRIVIAL_ASSIGN) || defined(BOOST_MSVC) || defined(__GNUC__) || defined(BOOST_INTEL) || defined(__SUNPRO_CC) || defined(__clang) #include #include #include #include #endif namespace boost { template struct has_trivial_assign : public integral_constant < bool, #ifdef BOOST_HAS_TRIVIAL_ASSIGN BOOST_HAS_TRIVIAL_ASSIGN(T) #else ::boost::is_pod::value && !::boost::is_const::value && !::boost::is_volatile::value #endif > {}; template<> struct has_trivial_assign : public false_type{}; #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template<> struct has_trivial_assign : public false_type{}; template<> struct has_trivial_assign : public false_type{}; template<> struct has_trivial_assign : public false_type{}; #endif template struct has_trivial_assign : public false_type{}; template struct has_trivial_assign : public false_type{}; #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template struct has_trivial_assign : public false_type{}; #endif // Arrays are not explictly assignable: template struct has_trivial_assign : public false_type{}; template struct has_trivial_assign : public false_type{}; } // namespace boost #endif // BOOST_TT_HAS_TRIVIAL_ASSIGN_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/has_trivial_destructor.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED #define BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED #include #include #ifdef BOOST_HAS_TRIVIAL_DESTRUCTOR #if defined(BOOST_INTEL) || defined(BOOST_MSVC) #include #endif #ifdef BOOST_HAS_SGI_TYPE_TRAITS #include #endif #if defined(__GNUC__) || defined(__clang) || defined(__SUNPRO_CC) #include #endif namespace boost { template struct has_trivial_destructor : public integral_constant{}; #else #include namespace boost{ template struct has_trivial_destructor : public integral_constant::value>{}; #endif template <> struct has_trivial_destructor : public false_type{}; #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template <> struct has_trivial_destructor : public false_type{}; template <> struct has_trivial_destructor : public false_type{}; template <> struct has_trivial_destructor : public false_type{}; #endif } // namespace boost #endif // BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/integral_constant.hpp ================================================ // (C) Copyright John Maddock 2015. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP #define BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP #include #include #if (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) ) namespace boost{ namespace mpl { template struct bool_; template struct integral_c; struct integral_c_tag; } } #else namespace mpl_{ template struct bool_; template struct integral_c; struct integral_c_tag; } namespace boost { namespace mpl { using ::mpl_::bool_; using ::mpl_::integral_c; using ::mpl_::integral_c_tag; } } #endif namespace boost{ template struct integral_constant { typedef mpl::integral_c_tag tag; typedef T value_type; typedef integral_constant type; static const T value = val; // // This helper function is just to disable type-punning // warnings from GCC: // template static U& dereference(U* p) { return *p; } operator const mpl::integral_c& ()const { static const char data[sizeof(long)] = { 0 }; return dereference(reinterpret_cast*>(&data)); } BOOST_CONSTEXPR operator T()const { return val; } }; template T const integral_constant::value; template struct integral_constant { typedef mpl::integral_c_tag tag; typedef bool value_type; typedef integral_constant type; static const bool value = val; // // This helper function is just to disable type-punning // warnings from GCC: // template static T& dereference(T* p) { return *p; } operator const mpl::bool_& ()const { static const char data = 0; return dereference(reinterpret_cast*>(&data)); } BOOST_CONSTEXPR operator bool()const { return val; } }; template bool const integral_constant::value; typedef integral_constant true_type; typedef integral_constant false_type; } #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/intrinsics.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_INTRINSICS_HPP_INCLUDED #define BOOST_TT_INTRINSICS_HPP_INCLUDED #ifndef BOOST_TT_DISABLE_INTRINSICS #include #ifndef BOOST_TT_CONFIG_HPP_INCLUDED #include #endif // // Helper macros for builtin compiler support. // If your compiler has builtin support for any of the following // traits concepts, then redefine the appropriate macros to pick // up on the compiler support: // // (these should largely ignore cv-qualifiers) // BOOST_IS_UNION(T) should evaluate to true if T is a union type // BOOST_IS_POD(T) should evaluate to true if T is a POD type // BOOST_IS_EMPTY(T) should evaluate to true if T is an empty class type (and not a union) // BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect // BOOST_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy // BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy // BOOST_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy // BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy // BOOST_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect // BOOST_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw // BOOST_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw // BOOST_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw // BOOST_HAS_VIRTUAL_DESTRUCTOR(T) should evaluate to true T has a virtual destructor // BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T) should evaluate to true if T has a non-throwing move constructor. // BOOST_IS_NOTHROW_MOVE_ASSIGN(T) should evaluate to true if T has a non-throwing move assignment operator. // // The following can also be defined: when detected our implementation is greatly simplified. // // BOOST_IS_ABSTRACT(T) true if T is an abstract type // BOOST_IS_BASE_OF(T,U) true if T is a base class of U // BOOST_IS_CLASS(T) true if T is a class type (and not a union) // BOOST_IS_CONVERTIBLE(T,U) true if T is convertible to U // BOOST_IS_ENUM(T) true is T is an enum // BOOST_IS_POLYMORPHIC(T) true if T is a polymorphic type // BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T. // // define BOOST_TT_DISABLE_INTRINSICS to prevent any intrinsics being used (mostly used when testing) // #ifdef BOOST_HAS_SGI_TYPE_TRAITS // Hook into SGI's __type_traits class, this will pick up user supplied // specializations as well as SGI - compiler supplied specializations. # include # ifdef __NetBSD__ // There are two different versions of type_traits.h on NetBSD on Spark // use an implicit include via algorithm instead, to make sure we get // the same version as the std lib: # include # else # include # endif # define BOOST_IS_POD(T) ::boost::is_same< typename ::__type_traits::is_POD_type, ::__true_type>::value # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) ::boost::is_same< typename ::__type_traits::has_trivial_default_constructor, ::__true_type>::value # define BOOST_HAS_TRIVIAL_COPY(T) ::boost::is_same< typename ::__type_traits::has_trivial_copy_constructor, ::__true_type>::value # define BOOST_HAS_TRIVIAL_ASSIGN(T) ::boost::is_same< typename ::__type_traits::has_trivial_assignment_operator, ::__true_type>::value # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) ::boost::is_same< typename ::__type_traits::has_trivial_destructor, ::__true_type>::value # ifdef __sgi # define BOOST_HAS_TYPE_TRAITS_INTRINSICS # endif #endif #if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000) // Metrowerks compiler is acquiring intrinsic type traits support // post version 8. We hook into the published interface to pick up // user defined specializations as well as compiler intrinsics as // and when they become available: # include # define BOOST_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union::value # define BOOST_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD::value # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor::value # define BOOST_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor::value # define BOOST_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment::value # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor::value # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\ || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)) // // Note that even though these intrinsics rely on other type traits classes // we do not #include those here as it produces cyclic dependencies and // can cause the intrinsics to not even be used at all! // # define BOOST_IS_UNION(T) __is_union(T) # define BOOST_IS_POD(T) (__is_pod(T) && __has_trivial_constructor(T)) # define BOOST_IS_EMPTY(T) __is_empty(T) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) || ( ::boost::is_pod::value && ! ::boost::is_const::value && !::boost::is_volatile::value)) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) || ::boost::is_pod::value) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) || ::boost::has_trivial_constructor::value) #if !defined(BOOST_INTEL) # define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) || ::boost::has_trivial_copy::value) && !is_array::value) # define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) || ::boost::is_pod::value) #elif (_MSC_VER >= 1900) # define BOOST_HAS_NOTHROW_COPY(T) ((__is_nothrow_constructible(T, typename add_lvalue_reference::type>::type)) && !is_array::value) # define BOOST_HAS_TRIVIAL_COPY(T) (__is_trivially_constructible(T, typename add_lvalue_reference::type>::type)) #endif # define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) || ::boost::has_trivial_assign::value) # define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) # define BOOST_IS_ABSTRACT(T) __is_abstract(T) # define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) # define BOOST_IS_CLASS(T) __is_class(T) # define BOOST_IS_CONVERTIBLE(T,U) ((__is_convertible_to(T,U) || (is_same::value && !is_function::value)) && !__is_abstract(U)) # define BOOST_IS_ENUM(T) __is_enum(T) // This one fails if the default alignment has been changed with /Zp: // # define BOOST_ALIGNMENT_OF(T) __alignof(T) # if defined(_MSC_VER) && (_MSC_VER >= 1700) # define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) ((__has_trivial_move_constructor(T) || boost::is_pod::value) && ! ::boost::is_volatile::value && ! ::boost::is_reference::value) # define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) ((__has_trivial_move_assign(T) || boost::is_pod::value) && ! ::boost::is_const::value && !::boost::is_volatile::value && ! ::boost::is_reference::value) # endif #ifndef BOOST_NO_CXX11_FINAL // This one doesn't quite always do the right thing on older VC++ versions // we really need it when the final keyword is supporyted though: # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) #endif #if _MSC_FULL_VER >= 180020827 # define BOOST_IS_NOTHROW_MOVE_ASSIGN(T) (__is_nothrow_assignable(T&, T&&)) # define BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T) (__is_nothrow_constructible(T, T&&)) #endif # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif #if defined(__DMC__) && (__DMC__ >= 0x848) // For Digital Mars C++, www.digitalmars.com # define BOOST_IS_UNION(T) (__typeinfo(T) & 0x400) # define BOOST_IS_POD(T) (__typeinfo(T) & 0x800) # define BOOST_IS_EMPTY(T) (__typeinfo(T) & 0x1000) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__typeinfo(T) & 0x10) # define BOOST_HAS_TRIVIAL_COPY(T) (__typeinfo(T) & 0x20) # define BOOST_HAS_TRIVIAL_ASSIGN(T) (__typeinfo(T) & 0x40) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__typeinfo(T) & 0x8) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__typeinfo(T) & 0x80) # define BOOST_HAS_NOTHROW_COPY(T) (__typeinfo(T) & 0x100) # define BOOST_HAS_NOTHROW_ASSIGN(T) (__typeinfo(T) & 0x200) # define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) (__typeinfo(T) & 0x4) # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif #if defined(BOOST_CLANG) && defined(__has_feature) && !defined(__CUDACC__) // // Note that these intrinsics are disabled for the CUDA meta-compiler as it appears // to not support them, even though the underlying clang compiler does so. // This is a rubbish fix as it basically stops type traits from working correctly, // but maybe the best we can do for now. See https://svn.boost.org/trac/boost/ticket/10694 // // // Note that even though these intrinsics rely on other type traits classes // we do not #include those here as it produces cyclic dependencies and // can cause the intrinsics to not even be used at all! // # include # if __has_feature(is_union) # define BOOST_IS_UNION(T) __is_union(T) # endif # if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod) # define BOOST_IS_POD(T) __is_pod(T) # endif # if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty) # define BOOST_IS_EMPTY(T) __is_empty(T) # endif # if __has_feature(has_trivial_constructor) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # endif # if __has_feature(has_trivial_copy) # define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference::value) # endif # if __has_feature(has_trivial_assign) # define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile::value && is_assignable::value) # endif # if __has_feature(has_trivial_destructor) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) && is_destructible::value) # endif # if __has_feature(has_nothrow_constructor) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) && is_default_constructible::value) # endif # if __has_feature(has_nothrow_copy) # define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) # endif # if __has_feature(has_nothrow_assign) # define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile::value && is_assignable::value) # endif # if __has_feature(has_virtual_destructor) # define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) # endif # if __has_feature(is_abstract) # define BOOST_IS_ABSTRACT(T) __is_abstract(T) # endif # if __has_feature(is_base_of) # define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) # endif # if __has_feature(is_class) # define BOOST_IS_CLASS(T) __is_class(T) # endif # if __has_feature(is_convertible_to) # define BOOST_IS_CONVERTIBLE(T,U) __is_convertible_to(T,U) # endif # if __has_feature(is_enum) # define BOOST_IS_ENUM(T) __is_enum(T) # endif # if __has_feature(is_polymorphic) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # endif # if __has_feature(has_trivial_move_constructor) # define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__has_trivial_move_constructor(T) && is_constructible::value && !::boost::is_volatile::value) # endif # if __has_feature(has_trivial_move_assign) # define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__has_trivial_move_assign(T) && is_assignable::value && !::boost::is_volatile::value) # endif # if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) || !defined(__GNUC__) // GCC sometimes lies about alignment requirements // of type double on 32-bit unix platforms, use the // old implementation instead in that case: # define BOOST_ALIGNMENT_OF(T) __alignof(T) # endif # if __has_feature(is_final) # define BOOST_IS_FINAL(T) __is_final(T) # endif # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG) // // Note that even though these intrinsics rely on other type traits classes // we do not #include those here as it produces cyclic dependencies and // can cause the intrinsics to not even be used at all! // #ifdef BOOST_INTEL # define BOOST_INTEL_TT_OPTS || is_pod::value #else # define BOOST_INTEL_TT_OPTS #endif # define BOOST_IS_UNION(T) __is_union(T) # define BOOST_IS_POD(T) __is_pod(T) # define BOOST_IS_EMPTY(T) __is_empty(T) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile::value) # define BOOST_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_INTEL_TT_OPTS) && !is_reference::value) #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 # define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile::value && ! ::boost::is_const::value && is_assignable::value) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_INTEL_TT_OPTS && is_destructible::value) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) && is_default_constructible::value BOOST_INTEL_TT_OPTS) # define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) # define BOOST_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_const::value && is_assignable::value) #else # define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile::value && ! ::boost::is_const::value) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_INTEL_TT_OPTS) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_INTEL_TT_OPTS) # define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_reference::value && !is_array::value) # define BOOST_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_const::value && !is_array::value) #endif # define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) # define BOOST_IS_ABSTRACT(T) __is_abstract(T) # define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) # define BOOST_IS_CLASS(T) __is_class(T) # define BOOST_IS_ENUM(T) __is_enum(T) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) // GCC sometimes lies about alignment requirements // of type double on 32-bit unix platforms, use the // old implementation instead in that case: # define BOOST_ALIGNMENT_OF(T) __alignof__(T) # endif # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) # define BOOST_IS_FINAL(T) __is_final(T) # endif # if (__GNUC__ >= 5) && (__cplusplus >= 201103) # define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_trivially_assignable(T&, T&&) && is_assignable::value && !::boost::is_volatile::value) # define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_trivially_constructible(T, T&&) && is_constructible::value && !::boost::is_volatile::value) # endif # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif #if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) # define BOOST_IS_UNION(T) __oracle_is_union(T) # define BOOST_IS_POD(T) (__oracle_is_pod(T) && !is_function::value) # define BOOST_IS_EMPTY(T) __oracle_is_empty(T) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__oracle_has_trivial_constructor(T) && ! ::boost::is_volatile::value) # define BOOST_HAS_TRIVIAL_COPY(T) (__oracle_has_trivial_copy(T) && !is_reference::value) # define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__oracle_has_trivial_assign(T) || __oracle_is_trivial(T)) && ! ::boost::is_volatile::value && ! ::boost::is_const::value && is_assignable::value) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__oracle_has_trivial_destructor(T) && is_destructible::value) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) ((__oracle_has_nothrow_constructor(T) || __oracle_has_trivial_constructor(T) || __oracle_is_trivial(T)) && is_default_constructible::value) // __oracle_has_nothrow_copy appears to behave the same as __oracle_has_nothrow_assign, disabled for now: //# define BOOST_HAS_NOTHROW_COPY(T) ((__oracle_has_nothrow_copy(T) || __oracle_has_trivial_copy(T) || __oracle_is_trivial(T)) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) # define BOOST_HAS_NOTHROW_ASSIGN(T) ((__oracle_has_nothrow_assign(T) || __oracle_has_trivial_assign(T) || __oracle_is_trivial(T)) && !is_volatile::value && !is_const::value && is_assignable::value) # define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __oracle_has_virtual_destructor(T) # define BOOST_IS_ABSTRACT(T) __oracle_is_abstract(T) //# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) # define BOOST_IS_CLASS(T) __oracle_is_class(T) # define BOOST_IS_ENUM(T) __oracle_is_enum(T) # define BOOST_IS_POLYMORPHIC(T) __oracle_is_polymorphic(T) # define BOOST_ALIGNMENT_OF(T) __alignof__(T) # define BOOST_IS_FINAL(T) __oracle_is_final(T) # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif #if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) # include # include # include # define BOOST_IS_UNION(T) __is_union(T) # define BOOST_IS_POD(T) __is_pod(T) # define BOOST_IS_EMPTY(T) __is_empty(T) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference::value) # define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile::value) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T) # define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile::value && !is_reference::value) # define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile::value) # define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) # define BOOST_IS_ABSTRACT(T) __is_abstract(T) # define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) # define BOOST_IS_CLASS(T) __is_class(T) # define BOOST_IS_ENUM(T) __is_enum(T) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # define BOOST_ALIGNMENT_OF(T) __alignof__(T) # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif # if defined(__CODEGEARC__) # include # include # include # include # define BOOST_IS_UNION(T) __is_union(T) # define BOOST_IS_POD(T) __is_pod(T) # define BOOST_IS_EMPTY(T) __is_empty(T) # define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T)) # define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T) && !is_reference::value) # define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile::value) # define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T)) # define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T)) # define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T) && !is_volatile::value && !is_reference::value) # define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile::value) # define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) # define BOOST_IS_ABSTRACT(T) __is_abstract(T) # define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_void::value && !is_void::value) # define BOOST_IS_CLASS(T) __is_class(T) # define BOOST_IS_CONVERTIBLE(T,U) (__is_convertible(T,U) || is_void::value) # define BOOST_IS_ENUM(T) __is_enum(T) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # define BOOST_ALIGNMENT_OF(T) alignof(T) # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif #endif // BOOST_TT_DISABLE_INTRINSICS #endif // BOOST_TT_INTRINSICS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_abstract.hpp ================================================ #ifndef BOOST_TT_IS_ABSTRACT_CLASS_HPP #define BOOST_TT_IS_ABSTRACT_CLASS_HPP #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // is_abstract_class.hpp: // // (C) Copyright 2002 Rani Sharoni (rani_sharoni@hotmail.com) and Robert Ramey // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org for updates, documentation, and revision history. // // Compile type discovery whether given type is abstract class or not. // // Requires DR 337 to be supported by compiler // (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#337). // // // Believed (Jan 2004) to work on: // - GCC 3.4 // - VC++ 7.1 // - compilers with new EDG frontend (Intel C++ 7, Comeau 4.3.2) // // Doesn't work on: // - VC++6, VC++7.0 and less // - GCC 3.3.X and less // - Borland C++ 6 and less // // // History: // - Originally written by Rani Sharoni, see // http://groups.google.com/groups?selm=df893da6.0207110613.75b2fe90%40posting.google.com // At this time supported by EDG (Intel C++ 7, Comeau 4.3.2) and VC7.1. // - Adapted and added into Boost.Serialization library by Robert Ramey // (starting with submission #10). // - Jan 2004: GCC 3.4 fixed to support DR337 (Giovanni Bajo). // - Jan 2004: modified to be part of Boost.TypeTraits (Pavel Vozenilek). // - Nov 2004: Christoph Ludwig found that the implementation did not work with // template types and gcc-3.4 or VC7.1, fix due to Christoph Ludwig // and John Maddock. // - Dec 2004: Added new config macro BOOST_NO_IS_ABSTRACT which causes the template // to degrade gracefully, rather than trash the compiler (John Maddock). // #include #include #ifndef BOOST_IS_ABSTRACT #include #include #include #ifdef BOOST_NO_IS_ABSTRACT #include #endif #endif namespace boost { namespace detail{ #ifdef BOOST_IS_ABSTRACT template struct is_abstract_imp { BOOST_STATIC_CONSTANT(bool, value = BOOST_IS_ABSTRACT(T)); }; #elif !defined(BOOST_NO_IS_ABSTRACT) template struct is_abstract_imp2 { // Deduction fails if T is void, function type, // reference type (14.8.2/2)or an abstract class type // according to review status issue #337 // template static type_traits::no_type check_sig(U (*)[1]); template static type_traits::yes_type check_sig(...); // // T must be a complete type, further if T is a template then // it must be instantiated in order for us to get the right answer: // BOOST_STATIC_ASSERT(sizeof(T) != 0); // GCC2 won't even parse this template if we embed the computation // of s1 in the computation of value. #ifdef __GNUC__ BOOST_STATIC_CONSTANT(std::size_t, s1 = sizeof(is_abstract_imp2::template check_sig(0))); #else #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(push) #pragma warning(disable:6334) #endif BOOST_STATIC_CONSTANT(std::size_t, s1 = sizeof(check_sig(0))); #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(pop) #endif #endif BOOST_STATIC_CONSTANT(bool, value = (s1 == sizeof(type_traits::yes_type))); }; template struct is_abstract_select { template struct rebind { typedef is_abstract_imp2 type; }; }; template <> struct is_abstract_select { template struct rebind { typedef false_type type; }; }; template struct is_abstract_imp { typedef is_abstract_select< ::boost::is_class::value> selector; typedef typename selector::template rebind binder; typedef typename binder::type type; BOOST_STATIC_CONSTANT(bool, value = type::value); }; #endif } #ifndef BOOST_NO_IS_ABSTRACT template struct is_abstract : public integral_constant::value> {}; #else template struct is_abstract : public integral_constant::value> {}; #endif } // namespace boost #endif //BOOST_TT_IS_ABSTRACT_CLASS_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_arithmetic.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED #define BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED #include #include namespace boost { template struct is_arithmetic : public integral_constant::value || is_floating_point::value> {}; } // namespace boost #endif // BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_array.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Some fixes for is_array are based on a newsgroup posting by Jonathan Lundquist. #ifndef BOOST_TT_IS_ARRAY_HPP_INCLUDED #define BOOST_TT_IS_ARRAY_HPP_INCLUDED #include #include namespace boost { #if defined( __CODEGEARC__ ) template struct is_array : public integral_constant {}; #else template struct is_array : public false_type {}; #if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) template struct is_array : public true_type {}; template struct is_array : public true_type{}; template struct is_array : public true_type{}; template struct is_array : public true_type{}; #if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) template struct is_array : public true_type{}; template struct is_array : public true_type{}; template struct is_array : public true_type{}; template struct is_array : public true_type{}; #endif #endif #endif } // namespace boost #endif // BOOST_TT_IS_ARRAY_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_assignable.hpp ================================================ // (C) Copyright John Maddock 2015. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED #define BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED #include #include namespace boost{ template struct is_assignable; } #if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) #include #include namespace boost{ namespace detail{ struct is_assignable_imp { template() = boost::declval())> static boost::type_traits::yes_type test(int); template static boost::type_traits::no_type test(...); }; } template struct is_assignable : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)>{}; template struct is_assignable : public is_assignable{}; template struct is_assignable : public is_assignable{}; template struct is_assignable : public is_assignable{}; template struct is_assignable : public is_assignable{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; #else #include #include namespace boost{ // We don't know how to implement this: template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant::value && is_pod::type>::value>{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; /* template <> struct is_assignable : public integral_constant{}; template <> struct is_assignable : public integral_constant{}; template <> struct is_assignable : public integral_constant{}; template <> struct is_assignable : public integral_constant{}; */ #endif } // namespace boost #endif // BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_base_and_derived.hpp ================================================ // (C) Copyright Rani Sharoni 2003. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED #define BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED #include #include #ifndef BOOST_IS_BASE_OF #include #include #include #include #include #endif #include #include namespace boost { namespace detail { #ifndef BOOST_IS_BASE_OF #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) \ && !BOOST_WORKAROUND(__SUNPRO_CC , <= 0x540) \ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243) \ && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) // The EDG version number is a lower estimate. // It is not currently known which EDG version // exactly fixes the problem. /************************************************************************* This version detects ambiguous base classes and private base classes correctly, and was devised by Rani Sharoni. Explanation by Terje Slettebo and Rani Sharoni. Let's take the multiple base class below as an example, and the following will also show why there's not a problem with private or ambiguous base class: struct B {}; struct B1 : B {}; struct B2 : B {}; struct D : private B1, private B2 {}; is_base_and_derived::value; First, some terminology: SC - Standard conversion UDC - User-defined conversion A user-defined conversion sequence consists of an SC, followed by an UDC, followed by another SC. Either SC may be the identity conversion. When passing the default-constructed Host object to the overloaded check_sig() functions (initialization 8.5/14/4/3), we have several viable implicit conversion sequences: For "static no_type check_sig(B const volatile *, int)" we have the conversion sequences: C -> C const (SC - Qualification Adjustment) -> B const volatile* (UDC) C -> D const volatile* (UDC) -> B1 const volatile* / B2 const volatile* -> B const volatile* (SC - Conversion) For "static yes_type check_sig(D const volatile *, T)" we have the conversion sequence: C -> D const volatile* (UDC) According to 13.3.3.1/4, in context of user-defined conversion only the standard conversion sequence is considered when selecting the best viable function, so it only considers up to the user-defined conversion. For the first function this means choosing between C -> C const and C -> C, and it chooses the latter, because it's a proper subset (13.3.3.2/3/2) of the former. Therefore, we have: C -> D const volatile* (UDC) -> B1 const volatile* / B2 const volatile* -> B const volatile* (SC - Conversion) C -> D const volatile* (UDC) Here, the principle of the "shortest subsequence" applies again, and it chooses C -> D const volatile*. This shows that it doesn't even need to consider the multiple paths to B, or accessibility, as that possibility is eliminated before it could possibly cause ambiguity or access violation. If D is not derived from B, it has to choose between C -> C const -> B const volatile* for the first function, and C -> D const volatile* for the second function, which are just as good (both requires a UDC, 13.3.3.2), had it not been for the fact that "static no_type check_sig(B const volatile *, int)" is not templated, which makes C -> C const -> B const volatile* the best choice (13.3.3/1/4), resulting in "no". Also, if Host::operator B const volatile* hadn't been const, the two conversion sequences for "static no_type check_sig(B const volatile *, int)", in the case where D is derived from B, would have been ambiguous. See also http://groups.google.com/groups?selm=df893da6.0301280859.522081f7%40posting. google.com and links therein. *************************************************************************/ template struct bd_helper { // // This VC7.1 specific workaround stops the compiler from generating // an internal compiler error when compiling with /vmg (thanks to // Aleksey Gurtovoy for figuring out the workaround). // #if !BOOST_WORKAROUND(BOOST_MSVC, == 1310) template static type_traits::yes_type check_sig(D const volatile *, T); static type_traits::no_type check_sig(B const volatile *, int); #else static type_traits::yes_type check_sig(D const volatile *, long); static type_traits::no_type check_sig(B const volatile * const&, int); #endif }; template struct is_base_and_derived_impl2 { #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(push) #pragma warning(disable:6334) #endif // // May silently do the wrong thing with incomplete types // unless we trap them here: // BOOST_STATIC_ASSERT(sizeof(B) != 0); BOOST_STATIC_ASSERT(sizeof(D) != 0); struct Host { #if !BOOST_WORKAROUND(BOOST_MSVC, == 1310) operator B const volatile *() const; #else operator B const volatile * const&() const; #endif operator D const volatile *(); }; BOOST_STATIC_CONSTANT(bool, value = sizeof(bd_helper::check_sig(Host(), 0)) == sizeof(type_traits::yes_type)); #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(pop) #endif }; #else // // broken version: // template struct is_base_and_derived_impl2 { BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible::value)); }; #define BOOST_BROKEN_IS_BASE_AND_DERIVED #endif template struct is_base_and_derived_impl3 { BOOST_STATIC_CONSTANT(bool, value = false); }; template struct is_base_and_derived_select { template struct rebind { typedef is_base_and_derived_impl3 type; }; }; template <> struct is_base_and_derived_select { template struct rebind { typedef is_base_and_derived_impl2 type; }; }; template struct is_base_and_derived_impl { typedef typename remove_cv::type ncvB; typedef typename remove_cv::type ncvD; typedef is_base_and_derived_select< ::boost::is_class::value, ::boost::is_class::value, ::boost::is_same::value> selector; typedef typename selector::template rebind binder; typedef typename binder::type bound_type; BOOST_STATIC_CONSTANT(bool, value = bound_type::value); }; #else template struct is_base_and_derived_impl { typedef typename remove_cv::type ncvB; typedef typename remove_cv::type ncvD; BOOST_STATIC_CONSTANT(bool, value = (BOOST_IS_BASE_OF(B,D) && ! ::boost::is_same::value)); }; #endif } // namespace detail template struct is_base_and_derived : public integral_constant::value)> {}; template struct is_base_and_derived : public false_type{}; template struct is_base_and_derived : public false_type{}; template struct is_base_and_derived : public false_type{}; #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) template struct is_base_and_derived : public true_type{}; #endif } // namespace boost #endif // BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_class.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000-2003. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_CLASS_HPP_INCLUDED #define BOOST_TT_IS_CLASS_HPP_INCLUDED #include #include #include #ifndef BOOST_IS_CLASS # include #ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION # include #else # include # include # include # include # include #endif #endif // BOOST_IS_CLASS namespace boost { namespace detail { #ifndef BOOST_IS_CLASS #ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION // This is actually the conforming implementation which works with // abstract classes. However, enough compilers have trouble with // it that most will use the one in // boost/type_traits/object_traits.hpp. This implementation // actually works with VC7.0, but other interactions seem to fail // when we use it. // is_class<> metafunction due to Paul Mensonides // (leavings@attbi.com). For more details: // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 #if defined(__GNUC__) && !defined(__EDG_VERSION__) template ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); template ::boost::type_traits::no_type is_class_tester(...); template struct is_class_impl { BOOST_STATIC_CONSTANT(bool, value = sizeof(is_class_tester(0)) == sizeof(::boost::type_traits::yes_type) && ! ::boost::is_union::value ); }; #else template struct is_class_impl { template static ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); template static ::boost::type_traits::no_type is_class_tester(...); BOOST_STATIC_CONSTANT(bool, value = sizeof(is_class_tester(0)) == sizeof(::boost::type_traits::yes_type) && ! ::boost::is_union::value ); }; #endif #else template struct is_class_impl { BOOST_STATIC_CONSTANT(bool, value = ! ::boost::is_union::value >::value && ! ::boost::is_scalar::value && ! ::boost::is_array::value && ! ::boost::is_reference::value && ! ::boost::is_void::value && ! ::boost::is_function::value ); }; # endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION # else // BOOST_IS_CLASS template struct is_class_impl { BOOST_STATIC_CONSTANT(bool, value = BOOST_IS_CLASS(T)); }; # endif // BOOST_IS_CLASS } // namespace detail template struct is_class : public integral_constant::value> {}; # ifdef __EDG_VERSION__ template struct is_class : public is_class{}; template struct is_class : public is_class{}; template struct is_class : public is_class{}; # endif } // namespace boost #endif // BOOST_TT_IS_CLASS_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_const.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). #ifndef BOOST_TT_IS_CONST_HPP_INCLUDED #define BOOST_TT_IS_CONST_HPP_INCLUDED #include namespace boost { #if defined( __CODEGEARC__ ) template struct is_const : public integral_constant {}; #else template struct is_const : public false_type {}; template struct is_const : public true_type{}; template struct is_const : public true_type{}; template struct is_const : public true_type{}; #endif } // namespace boost #endif // BOOST_TT_IS_CONST_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_convertible.hpp ================================================ // Copyright 2000 John Maddock (john@johnmaddock.co.uk) // Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu) // Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED #define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED #include #include #ifndef BOOST_IS_CONVERTIBLE #include #include #include #include #include #if !defined(BOOST_NO_IS_ABSTRACT) #include #endif #include #include #include #if defined(__MWERKS__) #include #endif #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) # include #endif #elif defined(BOOST_MSVC) || defined(BOOST_INTEL) #include #include #endif // BOOST_IS_CONVERTIBLE namespace boost { #ifndef BOOST_IS_CONVERTIBLE // is one type convertible to another? // // there are multiple versions of the is_convertible // template, almost every compiler seems to require its // own version. // // Thanks to Andrei Alexandrescu for the original version of the // conversion detection technique! // namespace detail { #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(BOOST_GCC) && (BOOST_GCC < 40700)) // This is a C++11 conforming version, place this first and use it wherever possible: # define BOOST_TT_CXX11_IS_CONVERTIBLE template struct or_helper { static const bool value = (A::value || B::value || C::value); }; template, boost::is_function, boost::is_array >::value> struct is_convertible_basic_impl { // Nothing converts to function or array, but void converts to void: static const bool value = is_void::value; }; template class is_convertible_basic_impl { typedef char one; typedef int two; template static void test_aux(To1); template static decltype(test_aux(boost::declval()), one()) test(int); template static two test(...); public: static const bool value = sizeof(test(0)) == 1; }; #elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560) // // special version for Borland compilers // this version breaks when used for some // UDT conversions: // template struct is_convertible_impl { #pragma option push -w-8074 // This workaround for Borland breaks the EDG C++ frontend, // so we only use it for Borland. template struct checker { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T); }; static typename add_lvalue_reference::type _m_from; static bool const value = sizeof( checker::_m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type); #pragma option pop }; #elif defined(__GNUC__) || defined(__BORLANDC__) && (__BORLANDC__ < 0x600) // special version for gcc compiler + recent Borland versions // note that this does not pass UDT's through (...) struct any_conversion { template any_conversion(const volatile T&); template any_conversion(const T&); template any_conversion(volatile T&); template any_conversion(T&); }; template struct checker { static boost::type_traits::no_type _m_check(any_conversion ...); static boost::type_traits::yes_type _m_check(T, int); }; template struct is_convertible_basic_impl { typedef typename add_lvalue_reference::type lvalue_type; typedef typename add_rvalue_reference::type rvalue_type; static lvalue_type _m_from; #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6))) static bool const value = sizeof( boost::detail::checker::_m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type); #else static bool const value = sizeof( boost::detail::checker::_m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type); #endif }; #elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \ || defined(__IBMCPP__) || defined(__HP_aCC) // // This is *almost* an ideal world implementation as it doesn't rely // on undefined behaviour by passing UDT's through (...). // Unfortunately it doesn't quite pass all the tests for most compilers (sigh...) // Enable this for your compiler if is_convertible_test.cpp will compile it... // // Note we do not enable this for VC7.1, because even though it passes all the // type_traits tests it is known to cause problems when instantiation occurs // deep within the instantiation tree :-( // struct any_conversion { template any_conversion(const volatile T&); template any_conversion(const T&); template any_conversion(volatile T&); // we need this constructor to catch references to functions // (which can not be cv-qualified): template any_conversion(T&); }; template struct is_convertible_basic_impl { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int); typedef typename add_lvalue_reference::type lvalue_type; typedef typename add_rvalue_reference::type rvalue_type; static lvalue_type _m_from; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type) ); #else BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type) ); #endif }; #elif defined(__DMC__) struct any_conversion { template any_conversion(const volatile T&); template any_conversion(const T&); template any_conversion(volatile T&); // we need this constructor to catch references to functions // (which can not be cv-qualified): template any_conversion(T&); }; template struct is_convertible_basic_impl { // Using '...' doesn't always work on Digital Mars. This version seems to. template static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion, float, T); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int); typedef typename add_lvalue_reference::type lvalue_type; typedef typename add_rvalue_reference::type rvalue_type; static lvalue_type _m_from; // Static constants sometime cause the conversion of _m_from to To to be // called. This doesn't happen with an enum. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES enum { value = sizeof( _m_check(static_cast(_m_from), 0, 0) ) == sizeof(::boost::type_traits::yes_type) }; #else enum { value = sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type) }; #endif }; #elif defined(__MWERKS__) // // CW works with the technique implemented above for EDG, except when From // is a function type (or a reference to such a type), in which case // any_conversion won't be accepted as a valid conversion. We detect this // exceptional situation and channel it through an alternative algorithm. // template struct is_convertible_basic_impl_aux; struct any_conversion { template any_conversion(const volatile T&); template any_conversion(const T&); template any_conversion(volatile T&); template any_conversion(T&); }; template struct is_convertible_basic_impl_aux { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int); typedef typename add_lvalue_reference::type lvalue_type; typedef typename add_rvalue_reference::type rvalue_type; static lvalue_type _m_from; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type) ); #else BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type) ); #endif }; template struct is_convertible_basic_impl_aux { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To); typedef typename add_lvalue_reference::type lvalue_type; typedef typename add_rvalue_reference::type rvalue_type; static lvalue_type _m_from; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(static_cast(_m_from)) ) == sizeof(::boost::type_traits::yes_type) ); #else BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type) ); #endif }; template struct is_convertible_basic_impl: is_convertible_basic_impl_aux< From,To, ::boost::is_function::type>::value > {}; #else // // This version seems to work pretty well for a wide spectrum of compilers, // however it does rely on undefined behaviour by passing UDT's through (...). // //Workaround for old compilers like MSVC 7.1 to avoid //forming a reference to an array of unknown bound template struct is_convertible_basic_impl_add_lvalue_reference : add_lvalue_reference {}; template struct is_convertible_basic_impl_add_lvalue_reference { typedef From type []; }; template struct is_convertible_basic_impl { static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To); typedef typename is_convertible_basic_impl_add_lvalue_reference::type lvalue_type; static lvalue_type _m_from; #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable:4244) #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(disable:6334) #endif #endif #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES typedef typename add_rvalue_reference::type rvalue_type; BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(static_cast(_m_from)) ) == sizeof(::boost::type_traits::yes_type) ); #else BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type) ); #endif #ifdef BOOST_MSVC #pragma warning(pop) #endif }; #endif // is_convertible_impl #if defined(__DMC__) // As before, a static constant sometimes causes errors on Digital Mars. template struct is_convertible_impl { enum { value = ( ::boost::detail::is_convertible_basic_impl::value && ! ::boost::is_array::value && ! ::boost::is_function::value) }; }; #elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551 template struct is_convertible_impl { BOOST_STATIC_CONSTANT(bool, value = ( ::boost::detail::is_convertible_basic_impl::value && !::boost::is_array::value && !::boost::is_function::value)); }; #endif template struct is_convertible_impl_select { template struct rebind { typedef is_convertible_impl type; }; }; template <> struct is_convertible_impl_select { template struct rebind { typedef true_type type; }; }; template <> struct is_convertible_impl_select { template struct rebind { typedef false_type type; }; }; template <> struct is_convertible_impl_select { template struct rebind { typedef false_type type; }; }; template struct is_convertible_impl_dispatch_base { #if !BOOST_WORKAROUND(__HP_aCC, < 60700) typedef is_convertible_impl_select< ::boost::is_arithmetic::value, ::boost::is_arithmetic::value, #if !defined(BOOST_NO_IS_ABSTRACT) && !defined(BOOST_TT_CXX11_IS_CONVERTIBLE) // We need to filter out abstract types, only if we don't have a strictly conforming C++11 version: ::boost::is_abstract::value #else false #endif > selector; #else typedef is_convertible_impl_select selector; #endif typedef typename selector::template rebind isc_binder; typedef typename isc_binder::type type; }; template struct is_convertible_impl_dispatch : public is_convertible_impl_dispatch_base::type {}; // // Now add the full and partial specialisations // for void types, these are common to all the // implementation above: // #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; template <> struct is_convertible_impl_dispatch : public true_type{}; #else template <> struct is_convertible_impl_dispatch : public true_type{}; #endif // BOOST_NO_CV_VOID_SPECIALIZATIONS template struct is_convertible_impl_dispatch : public false_type{}; template struct is_convertible_impl_dispatch : public false_type{}; #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template struct is_convertible_impl_dispatch : public false_type{}; template struct is_convertible_impl_dispatch : public false_type{}; template struct is_convertible_impl_dispatch : public false_type{}; template struct is_convertible_impl_dispatch : public false_type{}; template struct is_convertible_impl_dispatch : public false_type{}; template struct is_convertible_impl_dispatch : public false_type{}; #endif } // namespace detail template struct is_convertible : public integral_constant::value> {}; #else template struct is_convertible : public integral_constant {}; #endif } // namespace boost #endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_destructible.hpp ================================================ // (C) Copyright John Maddock 2015. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_DESTRUCTIBLE_HPP_INCLUDED #define BOOST_TT_IS_DESTRUCTIBLE_HPP_INCLUDED #include #include #if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) #include #include namespace boost{ namespace detail{ struct is_destructible_imp { template().~T())> static boost::type_traits::yes_type test(int); template static boost::type_traits::no_type test(...); }; } template struct is_destructible : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)>{}; #else #include #include namespace boost{ // We don't know how to implement this: template struct is_destructible : public integral_constant::value || is_class::value>{}; #endif template <> struct is_destructible : public false_type{}; template <> struct is_destructible : public false_type{}; template <> struct is_destructible : public false_type{}; template <> struct is_destructible : public false_type{}; template struct is_destructible : public is_destructible{}; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct is_destructible : public is_destructible{}; #endif template struct is_destructible : public is_destructible{}; template struct is_destructible : public is_destructible{}; } // namespace boost #endif // BOOST_TT_IS_DESTRUCTIBLE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_enum.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_ENUM_HPP_INCLUDED #define BOOST_TT_IS_ENUM_HPP_INCLUDED #include #include #ifndef BOOST_IS_ENUM #include #include #include #include #include #ifdef __GNUC__ #include #endif #include #if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) # include # include #endif #endif namespace boost { #ifndef BOOST_IS_ENUM #if !(defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)) namespace detail { #if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) template struct is_class_or_union { BOOST_STATIC_CONSTANT(bool, value = ::boost::is_class::value || ::boost::is_union::value); }; #else template struct is_class_or_union { # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))// we simply can't detect it this way. BOOST_STATIC_CONSTANT(bool, value = false); # else template static ::boost::type_traits::yes_type is_class_or_union_tester(void(U::*)(void)); # if BOOST_WORKAROUND(__MWERKS__, <= 0x3000) // no SFINAE static ::boost::type_traits::no_type is_class_or_union_tester(...); BOOST_STATIC_CONSTANT( bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type)); # else template static ::boost::type_traits::no_type is_class_or_union_tester(...); BOOST_STATIC_CONSTANT( bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type)); # endif # endif }; #endif struct int_convertible { int_convertible(int); }; // Don't evaluate convertibility to int_convertible unless the type // is non-arithmetic. This suppresses warnings with GCC. template struct is_enum_helper { template struct type { BOOST_STATIC_CONSTANT(bool, value = false); }; }; template <> struct is_enum_helper { template struct type { static const bool value = ::boost::is_convertible::type, ::boost::detail::int_convertible>::value; }; }; template struct is_enum_impl { //typedef ::boost::add_reference ar_t; //typedef typename ar_t::type r_type; #if defined(__GNUC__) #ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION // We MUST check for is_class_or_union on conforming compilers in // order to correctly deduce that noncopyable types are not enums // (dwa 2002/04/15)... BOOST_STATIC_CONSTANT(bool, selector = ::boost::is_arithmetic::value || ::boost::is_reference::value || ::boost::is_function::value || is_class_or_union::value || is_array::value); #else // ...however, not checking is_class_or_union on non-conforming // compilers prevents a dependency recursion. BOOST_STATIC_CONSTANT(bool, selector = ::boost::is_arithmetic::value || ::boost::is_reference::value || ::boost::is_function::value || is_array::value); #endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION #else // !defined(__GNUC__): BOOST_STATIC_CONSTANT(bool, selector = ::boost::is_arithmetic::value || ::boost::is_reference::value || is_class_or_union::value || is_array::value); #endif #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) typedef ::boost::detail::is_enum_helper< ::boost::detail::is_enum_impl::selector > se_t; #else typedef ::boost::detail::is_enum_helper se_t; #endif typedef typename se_t::template type helper; BOOST_STATIC_CONSTANT(bool, value = helper::value); }; } // namespace detail template struct is_enum : public integral_constant::value> {}; #else // __BORLANDC__ // // buggy is_convertible prevents working // implementation of is_enum: template struct is_enum : public integral_constant {}; #endif #else // BOOST_IS_ENUM template struct is_enum : public integral_constant {}; #endif } // namespace boost #endif // BOOST_TT_IS_ENUM_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_floating_point.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000-2005. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TYPE_TRAITS_IS_FLOATING_HPP_INCLUDED #define BOOST_TYPE_TRAITS_IS_FLOATING_HPP_INCLUDED #include namespace boost { //* is a type T a floating-point type described in the standard (3.9.1p8) template struct is_floating_point : public false_type{}; template struct is_floating_point : public is_floating_point{}; template struct is_floating_point : public is_floating_point{}; template struct is_floating_point : public is_floating_point{}; template<> struct is_floating_point : public true_type{}; template<> struct is_floating_point : public true_type{}; template<> struct is_floating_point : public true_type{}; #if defined(BOOST_HAS_FLOAT128) template<> struct is_floating_point<__float128> : public true_type{}; #endif } // namespace boost #endif // BOOST_TYPE_TRAITS_IS_FLOAT_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_function.hpp ================================================ // Copyright 2000 John Maddock (john@johnmaddock.co.uk) // Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com) // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_FUNCTION_HPP_INCLUDED #define BOOST_TT_IS_FUNCTION_HPP_INCLUDED #include #include #if !defined(BOOST_TT_TEST_MS_FUNC_SIGS) # include #else # include # include #endif // is a type a function? // Please note that this implementation is unnecessarily complex: // we could just use !is_convertible::value, // except that some compilers erroneously allow conversions from // function pointers to void*. namespace boost { #if !defined( __CODEGEARC__ ) namespace detail { #if !defined(BOOST_TT_TEST_MS_FUNC_SIGS) template struct is_function_chooser { template< typename T > struct result_ : public false_type {}; }; template <> struct is_function_chooser { template< typename T > struct result_ : public ::boost::type_traits::is_function_ptr_helper {}; }; template struct is_function_impl : public is_function_chooser< ::boost::is_reference::value > ::BOOST_NESTED_TEMPLATE result_ { }; #else template struct is_function_impl { #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(push) #pragma warning(disable:6334) #endif static T* t; BOOST_STATIC_CONSTANT( bool, value = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type) ); #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(pop) #endif }; template struct is_function_impl : public false_type {}; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct is_function_impl : public false_type {}; #endif #endif } // namespace detail #endif // !defined( __CODEGEARC__ ) #if defined( __CODEGEARC__ ) template struct is_function : integral_constant {}; #else template struct is_function : integral_constant::value> {}; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct is_function : public false_type {}; #endif #endif } // namespace boost #endif // BOOST_TT_IS_FUNCTION_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_integral.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_INTEGRAL_HPP_INCLUDED #define BOOST_TT_IS_INTEGRAL_HPP_INCLUDED #include #include namespace boost { #if defined( __CODEGEARC__ ) template struct is_integral : public integral_constant {}; #else template struct is_integral : public false_type {}; template struct is_integral : public is_integral {}; template struct is_integral : public is_integral{}; template struct is_integral : public is_integral{}; //* is a type T an [cv-qualified-] integral type described in the standard (3.9.1p3) // as an extension we include long long, as this is likely to be added to the // standard at a later date template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; #ifndef BOOST_NO_INTRINSIC_WCHAR_T // If the following line fails to compile and you're using the Intel // compiler, see http://lists.boost.org/MailArchives/boost-users/msg06567.php, // and define BOOST_NO_INTRINSIC_WCHAR_T on the command line. template<> struct is_integral : public true_type{}; #endif // Same set of integral types as in boost/type_traits/integral_promotion.hpp. // Please, keep in sync. -- Alexander Nasonov #if (defined(BOOST_INTEL_CXX_VERSION) && defined(_MSC_VER) && (BOOST_INTEL_CXX_VERSION <= 600)) \ || (defined(__BORLANDC__) && (__BORLANDC__ == 0x600) && (_MSC_VER < 1300)) template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; template<> struct is_integral<__int8> : public true_type{}; template<> struct is_integral<__int16> : public true_type{}; template<> struct is_integral<__int32> : public true_type{}; #ifdef __BORLANDC__ template<> struct is_integral : public true_type{}; template<> struct is_integral<__int64> : public true_type{}; #endif #endif # if defined(BOOST_HAS_LONG_LONG) template<> struct is_integral< ::boost::ulong_long_type> : public true_type{}; template<> struct is_integral< ::boost::long_long_type> : public true_type{}; #elif defined(BOOST_HAS_MS_INT64) template<> struct is_integral : public true_type{}; template<> struct is_integral<__int64> : public true_type{}; #endif #ifdef BOOST_HAS_INT128 template<> struct is_integral : public true_type{}; template<> struct is_integral : public true_type{}; #endif #ifndef BOOST_NO_CXX11_CHAR16_T template<> struct is_integral : public true_type{}; #endif #ifndef BOOST_NO_CXX11_CHAR32_T template<> struct is_integral : public true_type{}; #endif #endif // non-CodeGear implementation } // namespace boost #endif // BOOST_TT_IS_INTEGRAL_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_lvalue_reference.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_lvalue_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). #ifndef BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED #define BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED #include namespace boost { #if defined( __CODEGEARC__ ) template struct is_lvalue_reference : public integral_constant{}; #else template struct is_lvalue_reference : public false_type{}; template struct is_lvalue_reference : public true_type{}; #if defined(BOOST_ILLEGAL_CV_REFERENCES) // these are illegal specialisations; cv-qualifies applied to // references have no effect according to [8.3.2p1], // C++ Builder requires them though as it treats cv-qualified // references as distinct types... template struct is_lvalue_reference : public true_type{}; template struct is_lvalue_reference : public true_type{}; template struct is_lvalue_reference : public true_type{}; #endif #endif } // namespace boost #endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_member_function_pointer.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED #define BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED #include #include #if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(BOOST_TT_TEST_MS_FUNC_SIGS) // // Note: we use the "workaround" version for MSVC because it works for // __stdcall etc function types, where as the partial specialisation // version does not do so. // # include # include # include #else # include # include # include # include #endif namespace boost { #if defined( __CODEGEARC__ ) template struct is_member_function_pointer : public integral_constant {}; #elif !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(BOOST_TT_TEST_MS_FUNC_SIGS) template struct is_member_function_pointer : public ::boost::integral_constant::type>::value>{}; #else namespace detail { #ifndef __BORLANDC__ template struct is_mem_fun_pointer_select { template struct result_ : public false_type{}; }; template <> struct is_mem_fun_pointer_select { template struct result_ { #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(push) #pragma warning(disable:6334) #endif static T* make_t; typedef result_ self_type; BOOST_STATIC_CONSTANT( bool, value = ( 1 == sizeof(::boost::type_traits::is_mem_fun_pointer_tester(self_type::make_t)) )); #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) #pragma warning(pop) #endif }; }; template struct is_member_function_pointer_impl : public is_mem_fun_pointer_select< ::boost::is_reference::value || ::boost::is_array::value>::template result_{}; template struct is_member_function_pointer_impl : public false_type{}; #else // Borland C++ template struct is_member_function_pointer_impl { static T* m_t; BOOST_STATIC_CONSTANT( bool, value = (1 == sizeof(type_traits::is_mem_fun_pointer_tester(m_t))) ); }; template struct is_member_function_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = false); }; #endif template<> struct is_member_function_pointer_impl : public false_type{}; #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template<> struct is_member_function_pointer_impl : public false_type{}; template<> struct is_member_function_pointer_impl : public false_type{}; template<> struct is_member_function_pointer_impl : public false_type{}; #endif } // namespace detail template struct is_member_function_pointer : public integral_constant::value>{}; #endif } // namespace boost #endif // BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_member_pointer.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). #ifndef BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED #define BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED #include #include namespace boost { #if defined( __CODEGEARC__ ) template struct is_member_pointer : public integral_constant{}; #else template struct is_member_pointer : public integral_constant::value>{}; template struct is_member_pointer : public true_type{}; #if !BOOST_WORKAROUND(__MWERKS__,<=0x3003) && !BOOST_WORKAROUND(__IBMCPP__, <=600) template struct is_member_pointer : public true_type{}; template struct is_member_pointer : public true_type{}; template struct is_member_pointer : public true_type{}; #endif #endif } // namespace boost #endif // BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_pod.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_POD_HPP_INCLUDED #define BOOST_TT_IS_POD_HPP_INCLUDED #include #include #include #include #ifdef __SUNPRO_CC #include #endif #include #ifndef BOOST_IS_POD #define BOOST_INTERNAL_IS_POD(T) false #else #define BOOST_INTERNAL_IS_POD(T) BOOST_IS_POD(T) #endif namespace boost { // forward declaration, needed by 'is_pod_array_helper' template below template< typename T > struct is_POD; template struct is_pod : public integral_constant::value || ::boost::is_void::value || BOOST_INTERNAL_IS_POD(T)> {}; #if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) template struct is_pod : public is_pod{}; #endif // the following help compilers without partial specialization support: template<> struct is_pod : public true_type{}; #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS template<> struct is_pod : public true_type{}; template<> struct is_pod : public true_type{}; template<> struct is_pod : public true_type{}; #endif template struct is_POD : public is_pod{}; } // namespace boost #undef BOOST_INTERNAL_IS_POD #endif // BOOST_TT_IS_POD_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_pointer.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). #ifndef BOOST_TT_IS_POINTER_HPP_INCLUDED #define BOOST_TT_IS_POINTER_HPP_INCLUDED #include namespace boost { #if defined( __CODEGEARC__ ) template struct is_pointer : public integral_constant{}; #else template struct is_pointer : public false_type{}; template struct is_pointer : public true_type{}; template struct is_pointer : public true_type{}; template struct is_pointer : public true_type{}; template struct is_pointer : public true_type{}; #ifdef BOOST_MSVC template struct is_pointer : public is_pointer{}; template struct is_pointer : public is_pointer{}; template struct is_pointer : public is_pointer{}; #endif #endif } // namespace boost #endif // BOOST_TT_IS_POINTER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_polymorphic.hpp ================================================ // (C) Copyright John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_POLYMORPHIC_HPP #define BOOST_TT_IS_POLYMORPHIC_HPP #include #include #ifndef BOOST_IS_POLYMORPHIC #include #endif #include #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700) #pragma warning(push) #pragma warning(disable:4250) #endif namespace boost{ #ifndef BOOST_IS_POLYMORPHIC namespace detail{ template struct is_polymorphic_imp1 { # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) // CWPro7 should return false always. typedef char d1, (&d2)[2]; # else struct d1 : public T { d1(); # if !defined(__GNUC__) // this raises warnings with some classes, and buys nothing with GCC ~d1()throw(); # endif char padding[256]; private: // keep some picky compilers happy: d1(const d1&); d1& operator=(const d1&); }; struct d2 : public T { d2(); virtual ~d2()throw(); # if !defined(BOOST_MSVC) && !defined(__ICL) // for some reason this messes up VC++ when T has virtual bases, // probably likewise for compilers that use the same ABI: struct unique{}; virtual void unique_name_to_boost5487629(unique*); # endif char padding[256]; private: // keep some picky compilers happy: d2(const d2&); d2& operator=(const d2&); }; # endif BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1))); }; template struct is_polymorphic_imp1 : public is_polymorphic_imp1{}; template struct is_polymorphic_imp1 : public is_polymorphic_imp1{}; template struct is_polymorphic_imp1 : public is_polymorphic_imp1{}; template struct is_polymorphic_imp2 { BOOST_STATIC_CONSTANT(bool, value = false); }; template struct is_polymorphic_selector { template struct rebind { typedef is_polymorphic_imp2 type; }; }; template <> struct is_polymorphic_selector { template struct rebind { typedef is_polymorphic_imp1 type; }; }; template struct is_polymorphic_imp { typedef is_polymorphic_selector< ::boost::is_class::value> selector; typedef typename selector::template rebind binder; typedef typename binder::type imp_type; BOOST_STATIC_CONSTANT(bool, value = imp_type::value); }; } // namespace detail template struct is_polymorphic : public integral_constant::value> {}; #else // BOOST_IS_POLYMORPHIC template struct is_polymorphic : public integral_constant {}; #endif } // namespace boost #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700) #pragma warning(pop) #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_reference.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000, 2010. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_REFERENCE_HPP_INCLUDED #define BOOST_TT_IS_REFERENCE_HPP_INCLUDED #include #include namespace boost { template struct is_reference : public integral_constant< bool, ::boost::is_lvalue_reference::value || ::boost::is_rvalue_reference::value> {}; } // namespace boost #endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_rvalue_reference.hpp ================================================ // (C) John Maddock 2010. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED #define BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED #include #include namespace boost { template struct is_rvalue_reference : public false_type {}; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct is_rvalue_reference : public true_type {}; #endif } // namespace boost #endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_same.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). #ifndef BOOST_TT_IS_SAME_HPP_INCLUDED #define BOOST_TT_IS_SAME_HPP_INCLUDED #include namespace boost { template struct is_same : public false_type {}; template struct is_same : public true_type {}; #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) // without this, Borland's compiler gives the wrong answer for // references to arrays: template struct is_same : public true_type{}; #endif } // namespace boost #endif // BOOST_TT_IS_SAME_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_scalar.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_SCALAR_HPP_INCLUDED #define BOOST_TT_IS_SCALAR_HPP_INCLUDED #include #include #include #include #include namespace boost { template struct is_scalar : public integral_constant::value || ::boost::is_enum::value || ::boost::is_pointer::value || ::boost::is_member_pointer::value> {}; } // namespace boost #endif // BOOST_TT_IS_SCALAR_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_signed.hpp ================================================ // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_SIGNED_HPP_INCLUDED #define BOOST_TT_IS_SIGNED_HPP_INCLUDED #include #include #include #include namespace boost { #if !defined( __CODEGEARC__ ) #if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1310) && \ !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) &&\ !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) namespace detail{ template struct is_signed_values { // // Note that we cannot use BOOST_STATIC_CONSTANT here, using enum's // rather than "real" static constants simply doesn't work or give // the correct answer. // typedef typename remove_cv::type no_cv_t; static const no_cv_t minus_one = (static_cast(-1)); static const no_cv_t zero = (static_cast(0)); }; template struct is_signed_helper { typedef typename remove_cv::type no_cv_t; BOOST_STATIC_CONSTANT(bool, value = (!(::boost::detail::is_signed_values::minus_one > boost::detail::is_signed_values::zero))); }; template struct is_signed_select_helper { template struct rebind { typedef is_signed_helper type; }; }; template <> struct is_signed_select_helper { template struct rebind { typedef false_type type; }; }; template struct is_signed_impl { typedef ::boost::detail::is_signed_select_helper< ::boost::is_integral::value || ::boost::is_enum::value> selector; typedef typename selector::template rebind binder; typedef typename binder::type type; BOOST_STATIC_CONSTANT(bool, value = type::value); }; } template struct is_signed : public integral_constant::value> {}; #else template struct is_signed : public false_type{}; #endif #else //defined( __CODEGEARC__ ) template struct is_signed : public integral_constant{}; #endif template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; #ifdef BOOST_HAS_LONG_LONG template <> struct is_signed< ::boost::long_long_type> : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed< ::boost::ulong_long_type> : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; #endif #if defined(CHAR_MIN) #if CHAR_MIN != 0 template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; #else template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; #endif #endif #if defined(WCHAR_MIN) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) #if WCHAR_MIN != 0 template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; template <> struct is_signed : public true_type{}; #else template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; template <> struct is_signed : public false_type{}; #endif #endif } // namespace boost #endif // BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_union.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_UNION_HPP_INCLUDED #define BOOST_TT_IS_UNION_HPP_INCLUDED #include #include namespace boost { #ifdef BOOST_IS_UNION template struct is_union : public integral_constant {}; #else template struct is_union : public integral_constant {}; #endif template struct is_union : public is_union{}; template struct is_union : public is_union{}; template struct is_union : public is_union{}; } // namespace boost #endif // BOOST_TT_IS_UNION_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_unsigned.hpp ================================================ // (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_UNSIGNED_HPP_INCLUDED #define BOOST_TT_IS_UNSIGNED_HPP_INCLUDED #include #include #include #include namespace boost { #if !defined( __CODEGEARC__ ) #if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1310) &&\ !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) &&\ !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) namespace detail{ template struct is_unsigned_values { // // Note that we cannot use BOOST_STATIC_CONSTANT here, using enum's // rather than "real" static constants simply doesn't work or give // the correct answer. // typedef typename remove_cv::type no_cv_t; static const no_cv_t minus_one = (static_cast(-1)); static const no_cv_t zero = (static_cast(0)); }; template struct is_ununsigned_helper { BOOST_STATIC_CONSTANT(bool, value = (::boost::detail::is_unsigned_values::minus_one > ::boost::detail::is_unsigned_values::zero)); }; template struct is_unsigned_select_helper { template struct rebind { typedef is_ununsigned_helper type; }; }; template <> struct is_unsigned_select_helper { template struct rebind { typedef false_type type; }; }; template struct is_unsigned { typedef ::boost::detail::is_unsigned_select_helper< ::boost::is_integral::value || ::boost::is_enum::value > selector; typedef typename selector::template rebind binder; typedef typename binder::type type; BOOST_STATIC_CONSTANT(bool, value = type::value); }; } // namespace detail template struct is_unsigned : public integral_constant::value> {}; #else template struct is_unsigned : public false_type{}; #endif #else // defined( __CODEGEARC__ ) template struct is_unsigned : public integral_constant {}; #endif template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned< short> : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned< int> : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned< long> : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; #ifdef BOOST_HAS_LONG_LONG template <> struct is_unsigned< ::boost::ulong_long_type> : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned< ::boost::long_long_type> : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; #endif #if defined(CHAR_MIN) #if CHAR_MIN == 0 template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; #else template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; #endif #endif #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && defined(WCHAR_MIN) #if WCHAR_MIN == 0 template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; template <> struct is_unsigned : public true_type{}; #else template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; template <> struct is_unsigned : public false_type{}; #endif #endif } // namespace boost #endif // BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_void.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_IS_VOID_HPP_INCLUDED #define BOOST_TT_IS_VOID_HPP_INCLUDED #include namespace boost { template struct is_void : public false_type {}; template<> struct is_void : public true_type {}; template<> struct is_void : public true_type{}; template<> struct is_void : public true_type{}; template<> struct is_void : public true_type{}; } // namespace boost #endif // BOOST_TT_IS_VOID_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/is_volatile.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, // Howard Hinnant and John Maddock 2000. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. // Fixed is_pointer, is_reference, is_const, is_volatile, is_same, // is_member_pointer based on the Simulated Partial Specialization work // of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or // http://groups.yahoo.com/group/boost/message/5441 // Some workarounds in here use ideas suggested from "Generic: // Mappings between Types and Values" // by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). #ifndef BOOST_TT_IS_VOLATILE_HPP_INCLUDED #define BOOST_TT_IS_VOLATILE_HPP_INCLUDED #include namespace boost { #if defined( __CODEGEARC__ ) template struct is_volatile : public integral_constant {}; #else template struct is_volatile : public false_type {}; template struct is_volatile : public true_type{}; template struct is_volatile : public true_type{}; template struct is_volatile : public true_type{}; #endif } // namespace boost #endif // BOOST_TT_IS_VOLATILE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/make_signed.hpp ================================================ // (C) Copyright John Maddock 2007. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_MAKE_SIGNED_HPP_INCLUDED #define BOOST_TT_MAKE_SIGNED_HPP_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { template struct make_signed { private: BOOST_STATIC_ASSERT_MSG(( ::boost::is_integral::value || ::boost::is_enum::value), "The template argument to make_signed must be an integer or enum type."); BOOST_STATIC_ASSERT_MSG(!(::boost::is_same::type, bool>::value), "The template argument to make_signed must not be the type bool."); typedef typename remove_cv::type t_no_cv; typedef typename conditional< (::boost::is_signed::value && ::boost::is_integral::value && ! ::boost::is_same::value && ! ::boost::is_same::value && ! ::boost::is_same::value), T, typename conditional< (::boost::is_integral::value && ! ::boost::is_same::value && ! ::boost::is_same::value && ! ::boost::is_same::value), typename conditional< is_same::value, signed char, typename conditional< is_same::value, signed short, typename conditional< is_same::value, int, typename conditional< is_same::value, long, #if defined(BOOST_HAS_LONG_LONG) #ifdef BOOST_HAS_INT128 typename conditional< sizeof(t_no_cv) == sizeof(boost::long_long_type), boost::long_long_type, boost::int128_type >::type #else boost::long_long_type #endif #elif defined(BOOST_HAS_MS_INT64) __int64 #else long #endif >::type >::type >::type >::type, // Not a regular integer type: typename conditional< sizeof(t_no_cv) == sizeof(unsigned char), signed char, typename conditional< sizeof(t_no_cv) == sizeof(unsigned short), signed short, typename conditional< sizeof(t_no_cv) == sizeof(unsigned int), int, typename conditional< sizeof(t_no_cv) == sizeof(unsigned long), long, #if defined(BOOST_HAS_LONG_LONG) #ifdef BOOST_HAS_INT128 typename conditional< sizeof(t_no_cv) == sizeof(boost::long_long_type), boost::long_long_type, boost::int128_type >::type #else boost::long_long_type #endif #elif defined(BOOST_HAS_MS_INT64) __int64 #else long #endif >::type >::type >::type >::type >::type >::type base_integer_type; // Add back any const qualifier: typedef typename conditional< is_const::value, typename add_const::type, base_integer_type >::type const_base_integer_type; public: // Add back any volatile qualifier: typedef typename conditional< is_volatile::value, typename add_volatile::type, const_base_integer_type >::type type; }; } // namespace boost #endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/remove_const.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_REMOVE_CONST_HPP_INCLUDED #define BOOST_TT_REMOVE_CONST_HPP_INCLUDED #include #include #include namespace boost { // convert a type T to a non-cv-qualified type - remove_const template struct remove_const{ typedef T type; }; template struct remove_const{ typedef T type; }; #if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) template struct remove_const{ typedef T type[N]; }; #if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) template struct remove_const{ typedef T type[]; }; #endif #endif } // namespace boost #endif // BOOST_TT_REMOVE_CONST_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/remove_cv.hpp ================================================ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard // Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_REMOVE_CV_HPP_INCLUDED #define BOOST_TT_REMOVE_CV_HPP_INCLUDED #include #include #include namespace boost { // convert a type T to a non-cv-qualified type - remove_cv template struct remove_cv{ typedef T type; }; template struct remove_cv{ typedef T type; }; template struct remove_cv{ typedef T type; }; template struct remove_cv{ typedef T type; }; #if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) template struct remove_cv{ typedef T type[N]; }; template struct remove_cv{ typedef T type[N]; }; template struct remove_cv{ typedef T type[N]; }; #if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) template struct remove_cv{ typedef T type[]; }; template struct remove_cv{ typedef T type[]; }; template struct remove_cv{ typedef T type[]; }; #endif #endif } // namespace boost #endif // BOOST_TT_REMOVE_CV_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/type_traits/remove_reference.hpp ================================================ // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt). // // See http://www.boost.org/libs/type_traits for most recent version including documentation. #ifndef BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED #define BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED #include #include namespace boost { namespace detail{ // // We can't filter out rvalue_references at the same level as // references or we get ambiguities from msvc: // template struct remove_rvalue_ref { typedef T type; }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct remove_rvalue_ref { typedef T type; }; #endif } // namespace detail template struct remove_reference{ typedef typename boost::detail::remove_rvalue_ref::type type; }; template struct remove_reference{ typedef T type; }; #if defined(BOOST_ILLEGAL_CV_REFERENCES) // these are illegal specialisations; cv-qualifies applied to // references have no effect according to [8.3.2p1], // C++ Builder requires them though as it treats cv-qualified // references as distinct types... template struct remove_reference{ typedef T type; }; template struct remove_reference{ typedef T type; }; template struct remove_reference{ typedef T type; }; #endif } // namespace boost #endif // BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/utility/declval.hpp ================================================ // declval.hpp -------------------------------------------------------------// // Copyright 2010 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_UTILITY_DECLVAL_HPP #define BOOST_UTILITY_DECLVAL_HPP #include #endif // BOOST_UTILITY_DECLVAL_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/utility/detail/result_of_iterate.hpp ================================================ // Boost result_of library // Copyright Douglas Gregor 2004. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Copyright Daniel Walker, Eric Niebler, Michel Morin 2008-2012. // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or // copy at http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org/libs/utility #if !defined(BOOST_PP_IS_ITERATING) # error Boost result_of - do not include this file! #endif // CWPro8 requires an argument in a function type specialization #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0 # define BOOST_RESULT_OF_ARGS void #else # define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T) #endif #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template struct tr1_result_of : mpl::if_< mpl::or_< is_pointer, is_member_function_pointer > , boost::detail::tr1_result_of_impl< typename remove_cv::type, typename remove_cv::type(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type::value)> , boost::detail::tr1_result_of_impl< F, F(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type::value)> >::type { }; #endif #ifdef BOOST_RESULT_OF_USE_DECLTYPE template struct result_of : detail::cpp0x_result_of { }; #endif // BOOST_RESULT_OF_USE_DECLTYPE #ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK template struct result_of : mpl::if_, detail::has_result >, tr1_result_of, detail::cpp0x_result_of >::type { }; #endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK #if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) namespace detail { template struct cpp0x_result_of : mpl::if_< is_member_function_pointer , detail::tr1_result_of_impl< typename remove_cv::type, typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false > , detail::cpp0x_result_of_impl< F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)) > >::type {}; #ifdef BOOST_NO_SFINAE_EXPR template struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()); template struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()) { R operator()(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const; typedef result_of_private_type const &(*pfn_t)(...); operator pfn_t() const volatile; }; template struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()); template struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()) : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()) {}; template struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()) : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()) {}; template struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION()) : mpl::eval_if< is_class::type>, result_of_wrap_callable_class, mpl::identity::type> > > {}; template struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) { typedef typename BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())::type wrapper_t; static const bool value = ( sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type( (boost::declval()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT)), result_of_weird_type()) )) ); typedef mpl::bool_ type; }; template struct cpp0x_result_of_impl : lazy_enable_if< BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) , cpp0x_result_of_impl > {}; template struct cpp0x_result_of_impl { typedef decltype( boost::declval()( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) ) ) type; }; #else // BOOST_NO_SFINAE_EXPR template struct cpp0x_result_of_impl()( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) ) )>::type> { typedef decltype( boost::declval()( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) ) ) type; }; #endif // BOOST_NO_SFINAE_EXPR } // namespace detail #else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template struct result_of : tr1_result_of { }; #endif #endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) #undef BOOST_RESULT_OF_ARGS #if BOOST_PP_ITERATION() >= 1 namespace detail { template struct tr1_result_of_impl { typedef R type; }; template struct tr1_result_of_impl { typedef R type; }; #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template struct tr1_result_of_impl { typedef R type; }; template struct tr1_result_of_impl { typedef R type; }; template struct tr1_result_of_impl { typedef R type; }; template struct tr1_result_of_impl { typedef R type; }; #endif } #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/utility/enable_if.hpp ================================================ /* * Copyright (c) 2014 Glen Fernandes * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_UTILITY_ENABLE_IF_HPP #define BOOST_UTILITY_ENABLE_IF_HPP // The header file at this path is deprecated; // use boost/core/enable_if.hpp instead. #include #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/utility/result_of.hpp ================================================ // Boost result_of library // Copyright Douglas Gregor 2004. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org/libs/utility #ifndef BOOST_RESULT_OF_HPP #define BOOST_RESULT_OF_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 16 #endif // Use the decltype-based version of result_of by default if the compiler // supports N3276 . // The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE, // BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one! #if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \ (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \ (defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) # error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \ BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time. #endif #if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) # error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined. #endif #ifndef BOOST_RESULT_OF_USE_TR1 # ifndef BOOST_RESULT_OF_USE_DECLTYPE # ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK # ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE) # define BOOST_RESULT_OF_USE_DECLTYPE # else # define BOOST_RESULT_OF_USE_TR1 # endif # endif # endif #endif namespace boost { template struct result_of; template struct tr1_result_of; // a TR1-style implementation of result_of #if !defined(BOOST_NO_SFINAE) namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) // Work around a nvcc bug by only defining has_result when it's needed. #ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result) #endif template struct tr1_result_of_impl; template struct cpp0x_result_of; #ifdef BOOST_NO_SFINAE_EXPR // There doesn't seem to be any other way to turn this off such that the presence of // the user-defined operator,() below doesn't cause spurious warning all over the place, // so unconditionally turn it off. #if BOOST_MSVC # pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used #endif struct result_of_private_type {}; struct result_of_weird_type { friend result_of_private_type operator,(result_of_private_type, result_of_weird_type); }; typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1 typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2 template result_of_no_type result_of_is_private_type(T const &); result_of_yes_type result_of_is_private_type(result_of_private_type); template struct result_of_callable_class : C { result_of_callable_class(); typedef result_of_private_type const &(*pfn_t)(...); operator pfn_t() const volatile; }; template struct result_of_wrap_callable_class { typedef result_of_callable_class type; }; template struct result_of_wrap_callable_class { typedef result_of_callable_class const type; }; template struct result_of_wrap_callable_class { typedef result_of_callable_class volatile type; }; template struct result_of_wrap_callable_class { typedef result_of_callable_class const volatile type; }; template struct result_of_wrap_callable_class { typedef typename result_of_wrap_callable_class::type &type; }; template struct cpp0x_result_of_impl; #else // BOOST_NO_SFINAE_EXPR template struct result_of_always_void { typedef void type; }; template struct cpp0x_result_of_impl {}; #endif // BOOST_NO_SFINAE_EXPR template struct result_of_void_impl { typedef void type; }; template struct result_of_void_impl { typedef R type; }; template struct result_of_void_impl { typedef R type; }; // Determine the return type of a function pointer or pointer to member. template struct result_of_pointer : tr1_result_of_impl::type, FArgs, false> { }; template struct tr1_result_of_impl { typedef typename F::result_type type; }; template struct is_function_with_no_args : mpl::false_ {}; template struct is_function_with_no_args : mpl::true_ {}; template struct result_of_nested_result : F::template result {}; template struct tr1_result_of_impl : mpl::if_, result_of_void_impl, result_of_nested_result >::type {}; } // end namespace detail #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,)) #include BOOST_PP_ITERATE() #else # define BOOST_NO_RESULT_OF 1 #endif } #endif // BOOST_RESULT_OF_HPP ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boost/version.hpp ================================================ // Boost version.hpp configuration header file ------------------------------// // (C) Copyright John maddock 1999. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/config for documentation #ifndef BOOST_VERSION_HPP #define BOOST_VERSION_HPP // // Caution: this is the only Boost header that is guaranteed // to change with every Boost release. Including this header // will cause a recompile every time a new Boost version is // used. // // BOOST_VERSION % 100 is the patch level // BOOST_VERSION / 100 % 1000 is the minor version // BOOST_VERSION / 100000 is the major version #define BOOST_VERSION 106000 // // BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION // but as a *string* in the form "x_y[_z]" where x is the major version // number, y is the minor version number, and z is the patch level if not 0. // This is used by to select which library version to link to. #define BOOST_LIB_VERSION "1_60" #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/boostqueue.h ================================================ #pragma once #include #include "boost/lockfree/queue.hpp" #include "wrappers.h" template struct BoostQueueWrapper { public: typedef DummyToken producer_token_t; typedef DummyToken consumer_token_t; public: BoostQueueWrapper() : q(/* starting capacity */ 16384) { } template inline bool enqueue(U&& item) { return q.push(std::forward(item)); } inline bool try_dequeue(T& item) { return q.pop(item); } // Dummy token methods (not used) bool enqueue(producer_token_t const&, T const&) { return false; } bool try_enqueue(producer_token_t, T const&) { return false; } bool try_dequeue(consumer_token_t, T& item) { return false; } template bool enqueue_bulk(It, size_t) { return false; } template bool enqueue_bulk(producer_token_t const&, It, size_t) { return false; } template size_t try_dequeue_bulk(It, size_t) { return 0; } template size_t try_dequeue_bulk(consumer_token_t, It, size_t) { return 0; } private: boost::lockfree::queue q; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/cpuid.cpp ================================================ #include #include #include #include #include "cpuid.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include // See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683194(v=vs.85).aspx typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); // Helper function to count set bits in the processor mask. int countBitsSet(ULONG_PTR bitMask) { int result = 0; while (bitMask != 0) { result += (int)(bitMask & 1); bitMask >>= 1; } return result; } bool getProcessorInfoFromOS(int& cpus, int& cores, int& logicalCores, double& clockSpeed) { cpus = 0; cores = 0; logicalCores = 0; clockSpeed = 0; // Clock speed HKEY hKey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_EXECUTE, &hKey) == ERROR_SUCCESS) { DWORD type = REG_DWORD; DWORD val; DWORD cbData = sizeof(val); if (RegQueryValueEx(hKey, TEXT("~MHz"), NULL, &type, (LPBYTE)&val, &cbData) == ERROR_SUCCESS) { if (type == REG_DWORD && cbData == sizeof(DWORD)) { clockSpeed = val / 1000.0; } } } if (clockSpeed == 0) { // Can't access registry, try QueryPerformanceFrequency (nearly always same speed as CPU) LARGE_INTEGER f; if (!QueryPerformanceFrequency(&f)) { return false; } clockSpeed = f.QuadPart / 1000.0 / 1000.0; } // Everything else LPFN_GLPI glpi; glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation"); if (glpi == NULL) { return false; } PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; DWORD bufferLength = 0; if (glpi(buffer, &bufferLength) == TRUE) { return false; } while (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (buffer != NULL) { std::free(buffer); } buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)std::malloc(bufferLength); if (buffer == NULL) { return false; } if (glpi(buffer, &bufferLength) == TRUE) { if (bufferLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) * sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) != bufferLength) { // sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) must have changed (different from at compile time) std::free(buffer); return false; } auto end = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)((char*)buffer + bufferLength); for (auto ptr = buffer; ptr != end; ++ptr) { switch (ptr->Relationship) { case RelationProcessorCore: ++cores; logicalCores += countBitsSet(ptr->ProcessorMask); break; case RelationProcessorPackage: ++cpus; break; default: break; } } std::free(buffer); return true; } } if (buffer != NULL) { std::free(buffer); } return false; } #else // TODO bool getProcessorInfoFromOS(int& cpus, int& cores, int& logicalCores, double& clockSpeed) { return false; } #endif #if defined(__x86_64__) || defined(_M_AMD64) || defined(__amd64__) || defined (_M_X64) || defined(_M_IX86) || defined(__i386__) #define MOODYCAMEL_X86_OR_X64 #endif #ifdef MOODYCAMEL_X86_OR_X64 struct CPUIDInfo { std::uint32_t data[4]; }; #ifdef _MSC_VER #include inline CPUIDInfo cpuid(std::uint32_t eax) { CPUIDInfo info; __cpuidex((int*)&info.data[0], eax, 0); return info; } #else // Assume GCC-compatible inline assembly syntax inline CPUIDInfo cpuid(std::uint32_t eax) { CPUIDInfo info; asm volatile("cpuid" : "=a" (info.data[0]), "=b" (info.data[1]), "=c" (info.data[2]), "=d" (info.data[3]) : "a" (eax), "c" (0)); return info; } #endif #endif // MOODYCAMEL_X86_OR_X64 namespace moodycamel { const char* getCPUString() { // TODO: Support non-x86/-x64 architectures #ifdef MOODYCAMEL_X86_OR_X64 static char buf[128] = { 0 }; if (buf[0] != 0) { return buf; } CPUIDInfo info = cpuid(0x80000000); std::uint32_t ex = info.data[0]; for (std::uint32_t i = 0; i + 0x80000002 <= ex && i != 3; ++i) { *(reinterpret_cast(buf) + i) = cpuid(i + 0x80000002); } if (buf[0] == 0) { strcpy(buf, UNKNOWN_CPU_STRING); return buf; } info = cpuid(0); if (info.data[0] < 1) { // cpuid(1) not supported return buf; } // Add number of CPUs, cores, HT, and GHz info = cpuid(1); bool ht = ((info.data[3] >> 28) & 1) == 1; // Note: This is also 1 on most multi-core systems, even if there's no HT int cpus, cores, logicalCores; double clockSpeed; if (!getProcessorInfoFromOS(cpus, cores, logicalCores, clockSpeed)) { return buf; } // Strip @ nGHz if any, since we re-calculate this ourselves int atIndex; for (atIndex = (int)std::strlen(buf) - 1; atIndex != -1; --atIndex) { if (buf[atIndex] == '@') { if (atIndex > 0 && buf[atIndex - 1] == ' ') { --atIndex; } buf[atIndex] = '\0'; break; } } char* str = buf + std::strlen(buf); if (cpus > 1) { // Assume identical CPUs logicalCores /= cpus; cores /= cpus; std::sprintf(str, " x%d", cpus); str += strlen(str); } ht = ht && logicalCores != cores; std::sprintf(str, " with %d core%s%s @ %.1fGHz%s", cores, cores == 1 ? "" : "s", ht ? " (HyperThreaded)" : "", clockSpeed, cpus > 1 ? " each" : ""); return buf; #else return UNKNOWN_CPU_STRING; #endif } } ================================================ FILE: src/third_party/concurrentqueue/benchmarks/cpuid.h ================================================ #pragma once namespace moodycamel { static const char UNKNOWN_CPU_STRING[] = "unknown processor"; // Returns a string representing the system's CPU info. // Assumes an x86/x64 architecture (returns UNKNOWN_CPU_STRING otherwise). // Returned string is valid in perpetuity. // Not thread safe. const char* getCPUString(); } ================================================ FILE: src/third_party/concurrentqueue/benchmarks/extract_graph_data.py ================================================ #!/usr/bin/python # A simple script that reads the last run from the benchmark log file, # and creates two CSV files containing the data required to make pretty # performance graphs for enqueuing and dequeueing. # The x-axis of the graph is meant to be the number of threads (first column), with # the y-axis representing thousands of operations/second/thread (one column per queue). import sys import re def extract(bench, log, data, hasBulk = True): # data = { thread_count: [ locked, boost, tbb, moodycamel, moodycamel_tok, moodycamel_bulk ], ... } def do_extract(bench, queue_header): block = re.search(r'^' + bench + r':.*?' + queue_header + r'\s*(.*?)\s*^\s*Operations per second', log, re.S | re.M | re.I).group(1) for threads, opsst in re.findall(r'^\s*(\d+)\s+thread.*?([0-9\.]+[kMG]?\s*$)', block, re.M | re.I): threads = int(threads) multiplier = 1 if opsst[-1] in 'kMG': multiplier = { 'k': 1000, 'M': 1000000, 'G': 1000000000 }[opsst[-1]] opsst = opsst[:-1] opsst = int(float(opsst) * multiplier) if threads not in data: data[threads] = [] data[threads].append(opsst) do_extract(bench, 'LockBasedQueue') do_extract(bench, 'boost::lockfree::queue') do_extract(bench, 'tbb::concurrent_queue') do_extract(bench, 'Without tokens') do_extract(bench, 'With tokens') if hasBulk: do_extract(bench + ' bulk', 'With tokens') def write_csv(data, path, hasBulk = True): with open(path, 'w') as f: f.write('threads,"std::queue + std::mutex","boost::lockfree::queue","tbb::concurrent_queue","moodycamel::ConcurrentQueue (no tokens)","moodycamel::ConcurrentQueue",' + ('"moodycamel::ConcurrentQueue (bulk)"' if hasBulk else '') + '\n') for threads in sorted(data.keys()): f.write(str(threads)) for opsst in data[threads]: f.write(',' + str(opsst)) f.write('\n') try: filename = 'benchmarks.log' if len(sys.argv) < 2 else sys.argv[1] with open(filename, 'r') as f: pieces = f.read().split('--- New run') log = pieces[-1] enq_data = { } extract('only enqueue', log, enq_data) deq_data = { } extract('only dequeue', log, deq_data) heavy_data = { } extract('heavy concurrent', log, heavy_data, False) write_csv(enq_data, 'enqueue.csv') write_csv(deq_data, 'dequeue.csv') write_csv(heavy_data, 'heavy.csv', False) except IOError: print 'Usage: ' + sys.argv[0] + ' path/to/benchmarks.log' ================================================ FILE: src/third_party/concurrentqueue/benchmarks/lockbasedqueue.h ================================================ // ©2013-2014 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this file). #pragma once #include "wrappers.h" #include // Naïve implementation of a simple lock-based queue. A std::mutex is obtained for every // method. Note that while the queue size is not fixed, each enqueue operation allocates // memory, and each dequeue frees memory. template class LockBasedQueue { public: typedef DummyToken producer_token_t; typedef DummyToken consumer_token_t; public: LockBasedQueue() { tail = nullptr; head = nullptr; } ~LockBasedQueue() { while (head != nullptr) { Node* next = head->next; delete head; head = next; } } template inline bool enqueue(U&& item) { Node* node = new Node(item); std::lock_guard guard(mutex); if (tail == nullptr) { head = tail = node; } else { tail->next = node; tail = node; } return true; } inline bool try_dequeue(T& item) { std::lock_guard guard(mutex); if (head == nullptr) { return false; } else { item = std::move(head->item); Node* next = head->next; delete head; head = next; if (head == nullptr) { tail = nullptr; } return true; } } // Dummy token methods (not used) bool enqueue(producer_token_t const&, T const&) { return false; } bool try_enqueue(producer_token_t, T const&) { return false; } bool try_dequeue(consumer_token_t, T& item) { return false; } template bool enqueue_bulk(It, size_t) { return false; } template bool enqueue_bulk(producer_token_t const&, It, size_t) { return false; } template size_t try_dequeue_bulk(It, size_t) { return 0; } template size_t try_dequeue_bulk(consumer_token_t, It, size_t) { return 0; } private: struct Node { T item; Node* next; template Node(U&& item) : item(std::forward(item)), next(nullptr) { } }; std::mutex mutex; Node* head; Node* tail; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/simplelockfree.h ================================================ // ©2013-2014 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this file). #pragma once #include "wrappers.h" #include #include #if defined(_MSC_VER) && _MSC_VER < 1900 #define alignas(T) #endif // Fairly simple, yet correct, implementation of a simple lock-free queue based on linked pointers with CAS template class SimpleLockFreeQueue { public: typedef DummyToken producer_token_t; typedef DummyToken consumer_token_t; // Total maximum capacity: 2**39 (half a terabyte's worth -- off-by-one aligned indices) static const int UBER_BLOCKS = 256; static const int UBER_BLOCK_SIZE = 256; static const int ULTRA_BLOCK_SIZE = 256; static const int SUPER_BLOCK_SIZE = 256; static const int BLOCK_SIZE = 128; private: static const uint64_t VERSION_MASK = 0xFFFFFF0000000000ULL; static const uint64_t VERSION_INCR = 0x0000010000000000ULL; static const uint64_t UBER_BLOCK_IDX_MASK = 0xFF00000000ULL; static const uint64_t UBER_BLOCK_MASK = 0x00FF000000ULL; static const uint64_t ULTRA_BLOCK_MASK = 0x0000FF0000ULL; static const uint64_t SUPER_BLOCK_MASK = 0x000000FF00ULL; static const uint64_t BLOCK_MASK = 0x00000000FEULL; static const uint64_t UBER_BLOCK_IDX_SHIFT = 32; static const uint64_t UBER_BLOCK_SHIFT = 24; static const uint64_t ULTRA_BLOCK_SHIFT = 16; static const uint64_t SUPER_BLOCK_SHIFT = 8; static const uint64_t BLOCK_SHIFT = 1; typedef std::uint64_t idx_t; public: SimpleLockFreeQueue() : nextNodeIdx(2), freeListHead(0) { // Invariants: Head and tail are never null auto initialNode = allocate_blank_node(); head.store(set_consumed_flag(initialNode), std::memory_order_relaxed); tail.store(initialNode, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); } ~SimpleLockFreeQueue() { std::atomic_thread_fence(std::memory_order_seq_cst); idx_t idx = head.load(std::memory_order_relaxed); if (is_consumed(idx)) { idx = clear_consumed_flag(idx); auto node = get_node_at(idx); auto next = node->next.load(std::memory_order_relaxed); node->~Node(); idx = next; } while (idx != 0) { auto node = get_node_at(idx); auto next = node->next.load(std::memory_order_relaxed); node->item()->~T(); node->~Node(); idx = next; } idx = freeListHead.load(std::memory_order_relaxed); while (idx != 0) { auto node = get_node_at(idx); auto next = node->next.load(std::memory_order_relaxed); node->~Node(); idx = next; } } template inline bool enqueue(U&& item) { idx_t nodeIdx = allocate_node_for(std::forward(item)); auto tail_ = tail.load(std::memory_order_relaxed); while (!tail.compare_exchange_weak(tail_, nodeIdx, std::memory_order_release, std::memory_order_relaxed)) continue; get_node_at(tail_)->next.store(nodeIdx, std::memory_order_release); return true; } inline bool try_dequeue(T& item) { while (true) { auto rawHead_ = head.load(std::memory_order_acquire); auto head_ = clear_consumed_flag(rawHead_); auto headNode = get_node_at(head_); auto next = headNode->next.load(std::memory_order_relaxed); if (next == 0) { // Can't move head (that would make head null), but can try to dequeue the node at head anyway if (is_consumed(rawHead_)) { return false; } if (head.compare_exchange_strong(head_, set_consumed_flag(head_), std::memory_order_release, std::memory_order_relaxed)) { // Whee, we own the right to dequeue this item item = std::move(*headNode->item()); headNode->item()->~T(); return true; } } else { // Remove node whether it's already been consumed or not; if it hasn't been consumed, consume it! // head_->next can't possibly change, since once it's not null nobody writes to it (and ABA is avoided with versioning) if (head.compare_exchange_weak(rawHead_, next, std::memory_order_acq_rel, std::memory_order_relaxed)) { // Aha, we successfully moved the head. But does it have anything in it? if (!is_consumed(rawHead_)) { item = std::move(*headNode->item()); headNode->item()->~T(); } add_node_to_free_list(head_, headNode); if (!is_consumed(rawHead_)) { return true; } } } } } // Dummy token methods (not used) bool enqueue(producer_token_t const&, T const&) { return false; } bool try_enqueue(producer_token_t, T const&) { return false; } bool try_dequeue(consumer_token_t, T& item) { return false; } template bool enqueue_bulk(It, size_t) { return false; } template bool enqueue_bulk(producer_token_t const&, It, size_t) { return false; } template size_t try_dequeue_bulk(It, size_t) { return 0; } template size_t try_dequeue_bulk(consumer_token_t, It, size_t) { return 0; } private: struct Node { std::atomic next; alignas(T) char rawItem[sizeof(T)]; template Node(U&& item) : next(0) { new (this->item()) T(std::forward(item)); } Node() : next(0) { } inline T* item() { return reinterpret_cast(rawItem); } }; struct Block { alignas(Node) char nodes[sizeof(Node) * BLOCK_SIZE]; inline char* node_pos(idx_t idx) { return nodes + ((idx & BLOCK_MASK) >> BLOCK_SHIFT) * sizeof(Node); } }; template struct HigherOrderBlock { std::atomic subblocks[BlockSize]; HigherOrderBlock() { for (int i = 0; i != BlockSize; ++i) { subblocks[i].store(nullptr, std::memory_order_release); } } ~HigherOrderBlock() { for (int i = 0; i != BlockSize; ++i) { if (subblocks[i].load(std::memory_order_relaxed) != nullptr) { delete subblocks[i].load(std::memory_order_relaxed); } } } }; typedef HigherOrderBlock SuperBlock; typedef HigherOrderBlock UltraBlock; typedef HigherOrderBlock UberBlock; typedef HigherOrderBlock UberBlockContainer; private: inline idx_t set_consumed_flag(idx_t idx) { return idx | (idx_t)1; } inline idx_t clear_consumed_flag(idx_t idx) { return idx & ~(idx_t)1; } inline bool is_consumed(idx_t idx) { return (idx & 1) != 0; } inline void add_node_to_free_list(idx_t idx, Node* node) { auto head = freeListHead.load(std::memory_order_relaxed); do { node->next.store(head, std::memory_order_relaxed); } while (!freeListHead.compare_exchange_weak(head, idx, std::memory_order_release, std::memory_order_relaxed)); } inline idx_t try_get_node_from_free_list() { auto head = freeListHead.load(std::memory_order_acquire); while (head != 0 && !freeListHead.compare_exchange_weak(head, get_node_at(head)->next.load(std::memory_order_relaxed), std::memory_order_acquire)) { continue; } if (head != 0) { // Increment version head = (head & ~VERSION_MASK) | ((head + VERSION_INCR) & VERSION_MASK); } return head; } inline Node* get_node_at(idx_t idx) { auto uberBlock = uberBlockContainer.subblocks[(idx & UBER_BLOCK_IDX_MASK) >> UBER_BLOCK_IDX_SHIFT].load(std::memory_order_relaxed); auto ultraBlock = uberBlock->subblocks[(idx & UBER_BLOCK_MASK) >> UBER_BLOCK_SHIFT].load(std::memory_order_relaxed); auto superBlock = ultraBlock->subblocks[(idx & ULTRA_BLOCK_MASK) >> ULTRA_BLOCK_SHIFT].load(std::memory_order_relaxed); auto block = superBlock->subblocks[(idx & SUPER_BLOCK_MASK) >> SUPER_BLOCK_SHIFT].load(std::memory_order_relaxed); return reinterpret_cast(block->node_pos(idx)); } template inline idx_t allocate_node_for(U&& item) { auto idx = try_get_node_from_free_list(); if (idx != 0) { auto node = get_node_at(idx); node->next.store(0, std::memory_order_relaxed); new (node->item()) T(std::forward(item)); return idx; } new (new_node_address(idx)) Node(std::forward(item)); return idx; } inline idx_t allocate_blank_node() { idx_t idx; new (new_node_address(idx)) Node(); return idx; } inline char* new_node_address(idx_t& idx) { idx = nextNodeIdx.fetch_add(static_cast(1) << BLOCK_SHIFT, std::memory_order_relaxed); std::size_t uberBlockContainerIdx = (idx & UBER_BLOCK_IDX_MASK) >> UBER_BLOCK_IDX_SHIFT; std::size_t uberBlockIdx = (idx & UBER_BLOCK_MASK) >> UBER_BLOCK_SHIFT; std::size_t ultraBlockIdx = (idx & ULTRA_BLOCK_MASK) >> ULTRA_BLOCK_SHIFT; std::size_t superBlockIdx = (idx & SUPER_BLOCK_MASK) >> SUPER_BLOCK_SHIFT; auto uberBlock = lookup_subblock(&uberBlockContainer, uberBlockContainerIdx); auto ultraBlock = lookup_subblock(uberBlock, uberBlockIdx); auto superBlock = lookup_subblock(ultraBlock, ultraBlockIdx); auto block = lookup_subblock(superBlock, superBlockIdx); return block->node_pos(idx); } template inline TSubBlock* lookup_subblock(TBlock* block, std::size_t idx) { auto ptr = block->subblocks[idx].load(std::memory_order_acquire); if (ptr == nullptr) { auto newBlock = new TSubBlock(); if (!block->subblocks[idx].compare_exchange_strong(ptr, newBlock, std::memory_order_release, std::memory_order_acquire)) { delete newBlock; } else { ptr = newBlock; } } return ptr; } private: std::atomic nextNodeIdx; std::atomic head; std::atomic tail; std::atomic freeListHead; UberBlockContainer uberBlockContainer; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/stdqueue.h ================================================ // ©2014 Cameron Desrochers. #pragma once #include #include "wrappers.h" // Simple wrapper around std::queue (not thread safe) template class StdQueueWrapper { public: typedef DummyToken producer_token_t; typedef DummyToken consumer_token_t; public: template inline bool enqueue(U&& item) { q.push(std::forward(item)); return true; } inline bool try_dequeue(T& item) { if (q.empty()) { return false; } item = std::move(q.front()); q.pop(); return true; } // Dummy token methods (not used) bool enqueue(producer_token_t const&, T const&) { return false; } bool try_enqueue(producer_token_t, T const&) { return false; } bool try_dequeue(consumer_token_t, T& item) { return false; } template bool enqueue_bulk(It, size_t) { return false; } template bool enqueue_bulk(producer_token_t const&, It, size_t) { return false; } template size_t try_dequeue_bulk(It, size_t) { return 0; } template size_t try_dequeue_bulk(consumer_token_t, It, size_t) { return 0; } private: std::queue q; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/COPYING ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ---------------- END OF Gnu General Public License ---------------- The source code of Threading Building Blocks is distributed under version 2 of the GNU General Public License, with the so-called "runtime exception," as follows (or see any header or implementation file): As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/README.txt ================================================ This is a partial copy of the Intel TBB open source version. The version taken is 4.3, obtained from https://www.threadingbuildingblocks.org/download The files in this directory consist of the files taken from src/tbb and include/tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/aggregator.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__aggregator_H #define __TBB__aggregator_H #if !TBB_PREVIEW_AGGREGATOR #error Set TBB_PREVIEW_AGGREGATOR before including aggregator.h #endif #include "atomic.h" #include "tbb_profiling.h" namespace tbb { namespace interface6 { using namespace tbb::internal; class aggregator_operation { template friend class aggregator_ext; uintptr_t status; aggregator_operation* my_next; public: enum aggregator_operation_status { agg_waiting=0, agg_finished }; aggregator_operation() : status(agg_waiting), my_next(NULL) {} /// Call start before handling this operation void start() { call_itt_notify(acquired, &status); } /// Call finish when done handling this operation /** The operation will be released to its originating thread, and possibly deleted. */ void finish() { itt_store_word_with_release(status, uintptr_t(agg_finished)); } aggregator_operation* next() { return itt_hide_load_word(my_next);} void set_next(aggregator_operation* n) { itt_hide_store_word(my_next, n); } }; namespace internal { class basic_operation_base : public aggregator_operation { friend class basic_handler; virtual void apply_body() = 0; public: basic_operation_base() : aggregator_operation() {} virtual ~basic_operation_base() {} }; template class basic_operation : public basic_operation_base, no_assign { const Body& my_body; /*override*/ void apply_body() { my_body(); } public: basic_operation(const Body& b) : basic_operation_base(), my_body(b) {} }; class basic_handler { public: basic_handler() {} void operator()(aggregator_operation* op_list) const { while (op_list) { // ITT note: &(op_list->status) tag is used to cover accesses to the operation data. // The executing thread "acquires" the tag (see start()) and then performs // the associated operation w/o triggering a race condition diagnostics. // A thread that created the operation is waiting for its status (see execute_impl()), // so when this thread is done with the operation, it will "release" the tag // and update the status (see finish()) to give control back to the waiting thread. basic_operation_base& request = static_cast(*op_list); // IMPORTANT: need to advance op_list to op_list->next() before calling request.finish() op_list = op_list->next(); request.start(); request.apply_body(); request.finish(); } } }; } // namespace internal //! Aggregator base class and expert interface /** An aggregator for collecting operations coming from multiple sources and executing them serially on a single thread. */ template class aggregator_ext : tbb::internal::no_copy { public: aggregator_ext(const handler_type& h) : handler_busy(0), handle_operations(h) { mailbox = NULL; } //! EXPERT INTERFACE: Enter a user-made operation into the aggregator's mailbox. /** Details of user-made operations must be handled by user-provided handler */ void process(aggregator_operation *op) { execute_impl(*op); } protected: /** Place operation in mailbox, then either handle mailbox or wait for the operation to be completed by a different thread. */ void execute_impl(aggregator_operation& op) { aggregator_operation* res; // ITT note: &(op.status) tag is used to cover accesses to this operation. This // thread has created the operation, and now releases it so that the handler // thread may handle the associated operation w/o triggering a race condition; // thus this tag will be acquired just before the operation is handled in the // handle_operations functor. call_itt_notify(releasing, &(op.status)); // insert the operation in the queue do { // ITT may flag the following line as a race; it is a false positive: // This is an atomic read; we don't provide itt_hide_load_word for atomics op.my_next = res = mailbox; // NOT A RACE } while (mailbox.compare_and_swap(&op, res) != res); if (!res) { // first in the list; handle the operations // ITT note: &mailbox tag covers access to the handler_busy flag, which this // waiting handler thread will try to set before entering handle_operations. call_itt_notify(acquired, &mailbox); start_handle_operations(); __TBB_ASSERT(op.status, NULL); } else { // not first; wait for op to be ready call_itt_notify(prepare, &(op.status)); spin_wait_while_eq(op.status, uintptr_t(aggregator_operation::agg_waiting)); itt_load_word_with_acquire(op.status); } } private: //! An atomically updated list (aka mailbox) of aggregator_operations atomic mailbox; //! Controls thread access to handle_operations /** Behaves as boolean flag where 0=false, 1=true */ uintptr_t handler_busy; handler_type handle_operations; //! Trigger the handling of operations when the handler is free void start_handle_operations() { aggregator_operation *pending_operations; // ITT note: &handler_busy tag covers access to mailbox as it is passed // between active and waiting handlers. Below, the waiting handler waits until // the active handler releases, and the waiting handler acquires &handler_busy as // it becomes the active_handler. The release point is at the end of this // function, when all operations in mailbox have been handled by the // owner of this aggregator. call_itt_notify(prepare, &handler_busy); // get handler_busy: only one thread can possibly spin here at a time spin_wait_until_eq(handler_busy, uintptr_t(0)); call_itt_notify(acquired, &handler_busy); // acquire fence not necessary here due to causality rule and surrounding atomics __TBB_store_with_release(handler_busy, uintptr_t(1)); // ITT note: &mailbox tag covers access to the handler_busy flag itself. // Capturing the state of the mailbox signifies that handler_busy has been // set and a new active handler will now process that list's operations. call_itt_notify(releasing, &mailbox); // grab pending_operations pending_operations = mailbox.fetch_and_store(NULL); // handle all the operations handle_operations(pending_operations); // release the handler itt_store_word_with_release(handler_busy, uintptr_t(0)); } }; //! Basic aggregator interface class aggregator : private aggregator_ext { public: aggregator() : aggregator_ext(internal::basic_handler()) {} //! BASIC INTERFACE: Enter a function for exclusive execution by the aggregator. /** The calling thread stores the function object in a basic_operation and places the operation in the aggregator's mailbox */ template void execute(const Body& b) { internal::basic_operation op(b); this->execute_impl(op); } }; } // namespace interface6 using interface6::aggregator; using interface6::aggregator_ext; using interface6::aggregator_operation; } // namespace tbb #endif // __TBB__aggregator_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/aligned_space.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_aligned_space_H #define __TBB_aligned_space_H #include "tbb_stddef.h" #include "tbb_machine.h" namespace tbb { //! Block of space aligned sufficiently to construct an array T with N elements. /** The elements are not constructed or destroyed by this class. @ingroup memory_allocation */ template class aligned_space { private: typedef __TBB_TypeWithAlignmentAtLeastAsStrict(T) element_type; element_type array[(sizeof(T)*N+sizeof(element_type)-1)/sizeof(element_type)]; public: //! Pointer to beginning of array T* begin() {return internal::punned_cast(this);} //! Pointer to one past last element in array. T* end() {return begin()+N;} }; } // namespace tbb #endif /* __TBB_aligned_space_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/arena.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "scheduler.h" #include "governor.h" #include "arena.h" #include "itt_notify.h" #include "semaphore.h" #include #if __TBB_STATISTICS_STDOUT #include #endif namespace tbb { namespace internal { void arena::process( generic_scheduler& s ) { __TBB_ASSERT( is_alive(my_guard), NULL ); __TBB_ASSERT( governor::is_set(&s), NULL ); __TBB_ASSERT( !s.my_innermost_running_task, NULL ); __TBB_ASSERT( !s.my_dispatching_task, NULL ); __TBB_ASSERT( my_num_slots != 1, NULL ); // Start search for an empty slot from the one we occupied the last time unsigned index = s.my_arena_index < my_num_slots ? s.my_arena_index : s.my_random.get() % (my_num_slots - 1) + 1, end = index; __TBB_ASSERT( index != 0, "A worker cannot occupy slot 0" ); __TBB_ASSERT( index < my_num_slots, NULL ); // Find a vacant slot for ( ;; ) { if ( !my_slots[index].my_scheduler && as_atomic(my_slots[index].my_scheduler).compare_and_swap(&s, NULL ) == NULL ) break; if ( ++index == my_num_slots ) index = 1; if ( index == end ) { // Likely this arena is already saturated goto quit; } } ITT_NOTIFY(sync_acquired, my_slots + index); s.my_arena = this; s.my_arena_index = index; s.my_arena_slot = my_slots + index; #if __TBB_TASK_PRIORITY s.my_local_reload_epoch = *s.my_ref_reload_epoch; __TBB_ASSERT( !s.my_offloaded_tasks, NULL ); #endif /* __TBB_TASK_PRIORITY */ s.attach_mailbox( affinity_id(index+1) ); s.my_arena_slot->hint_for_pop = index; // initial value for round-robin #if !__TBB_FP_CONTEXT my_cpu_ctl_env.set_env(); #endif #if __TBB_SCHEDULER_OBSERVER __TBB_ASSERT( !s.my_last_local_observer, "There cannot be notified local observers when entering arena" ); my_observers.notify_entry_observers( s.my_last_local_observer, /*worker=*/true ); #endif /* __TBB_SCHEDULER_OBSERVER */ atomic_update( my_limit, index + 1, std::less() ); for ( ;; ) { // Try to steal a task. // Passing reference count is technically unnecessary in this context, // but omitting it here would add checks inside the function. __TBB_ASSERT( is_alive(my_guard), NULL ); task* t = s.receive_or_steal_task( s.my_dummy_task->prefix().ref_count, /*return_if_no_work=*/true ); if (t) { // A side effect of receive_or_steal_task is that my_innermost_running_task can be set. // But for the outermost dispatch loop of a worker it has to be NULL. s.my_innermost_running_task = NULL; __TBB_ASSERT( !s.my_dispatching_task, NULL ); s.local_wait_for_all(*s.my_dummy_task,t); } __TBB_ASSERT ( __TBB_load_relaxed(s.my_arena_slot->head) == __TBB_load_relaxed(s.my_arena_slot->tail), "Worker cannot leave arena while its task pool is not empty" ); __TBB_ASSERT( s.my_arena_slot->task_pool == EmptyTaskPool, "Empty task pool is not marked appropriately" ); // This check prevents relinquishing more than necessary workers because // of the non-atomicity of the decision making procedure if (num_workers_active() > my_num_workers_allotted) break; } #if __TBB_SCHEDULER_OBSERVER my_observers.notify_exit_observers( s.my_last_local_observer, /*worker=*/true ); s.my_last_local_observer = NULL; #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_PRIORITY if ( s.my_offloaded_tasks ) orphan_offloaded_tasks( s ); #endif /* __TBB_TASK_PRIORITY */ #if __TBB_STATISTICS ++s.my_counters.arena_roundtrips; *my_slots[index].my_counters += s.my_counters; s.my_counters.reset(); #endif /* __TBB_STATISTICS */ __TBB_store_with_release( my_slots[index].my_scheduler, (generic_scheduler*)NULL ); s.my_arena_slot = 0; // detached from slot s.my_inbox.detach(); __TBB_ASSERT( s.my_inbox.is_idle_state(true), NULL ); __TBB_ASSERT( !s.my_innermost_running_task, NULL ); __TBB_ASSERT( !s.my_dispatching_task, NULL ); __TBB_ASSERT( is_alive(my_guard), NULL ); quit: // In contrast to earlier versions of TBB (before 3.0 U5) now it is possible // that arena may be temporarily left unpopulated by threads. See comments in // arena::on_thread_leaving() for more details. #if !__TBB_TRACK_PRIORITY_LEVEL_SATURATION on_thread_leaving(); #endif /* !__TBB_TRACK_PRIORITY_LEVEL_SATURATION */ } arena::arena ( market& m, unsigned max_num_workers ) { __TBB_ASSERT( !my_guard, "improperly allocated arena?" ); __TBB_ASSERT( sizeof(my_slots[0]) % NFS_GetLineSize()==0, "arena::slot size not multiple of cache line size" ); __TBB_ASSERT( (uintptr_t)this % NFS_GetLineSize()==0, "arena misaligned" ); #if __TBB_TASK_PRIORITY __TBB_ASSERT( !my_reload_epoch && !my_orphaned_tasks && !my_skipped_fifo_priority, "New arena object is not zeroed" ); #endif /* __TBB_TASK_PRIORITY */ my_market = &m; my_limit = 1; // Two slots are mandatory: for the master, and for 1 worker (required to support starvation resistant tasks). my_num_slots = num_slots_to_reserve(max_num_workers); my_max_num_workers = max_num_workers; my_references = 1; // accounts for the master #if __TBB_TASK_PRIORITY my_bottom_priority = my_top_priority = normalized_normal_priority; #endif /* __TBB_TASK_PRIORITY */ my_aba_epoch = m.my_arenas_aba_epoch; #if __TBB_SCHEDULER_OBSERVER my_observers.my_arena = this; #endif /* __TBB_SCHEDULER_OBSERVER */ __TBB_ASSERT ( my_max_num_workers < my_num_slots, NULL ); // Construct slots. Mark internal synchronization elements for the tools. for( unsigned i = 0; i < my_num_slots; ++i ) { __TBB_ASSERT( !my_slots[i].my_scheduler && !my_slots[i].task_pool, NULL ); __TBB_ASSERT( !my_slots[i].task_pool_ptr, NULL ); __TBB_ASSERT( !my_slots[i].my_task_pool_size, NULL ); ITT_SYNC_CREATE(my_slots + i, SyncType_Scheduler, SyncObj_WorkerTaskPool); mailbox(i+1).construct(); ITT_SYNC_CREATE(&mailbox(i+1), SyncType_Scheduler, SyncObj_Mailbox); my_slots[i].hint_for_pop = i; #if __TBB_STATISTICS my_slots[i].my_counters = new ( NFS_Allocate(1, sizeof(statistics_counters), NULL) ) statistics_counters; #endif /* __TBB_STATISTICS */ } #if __TBB_TASK_PRIORITY for ( intptr_t i = 0; i < num_priority_levels; ++i ) { my_task_stream[i].initialize(my_num_slots); ITT_SYNC_CREATE(my_task_stream + i, SyncType_Scheduler, SyncObj_TaskStream); } #else /* !__TBB_TASK_PRIORITY */ my_task_stream.initialize(my_num_slots); ITT_SYNC_CREATE(&my_task_stream, SyncType_Scheduler, SyncObj_TaskStream); #endif /* !__TBB_TASK_PRIORITY */ my_mandatory_concurrency = false; #if __TBB_TASK_GROUP_CONTEXT // Context to be used by root tasks by default (if the user has not specified one). // The arena's context should not capture fp settings for the sake of backward compatibility. my_default_ctx = new ( NFS_Allocate(1, sizeof(task_group_context), NULL) ) task_group_context(task_group_context::isolated, task_group_context::default_traits); #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_FP_CONTEXT my_default_ctx->capture_fp_settings(); #else my_cpu_ctl_env.get_env(); #endif } arena& arena::allocate_arena( market& m, unsigned max_num_workers ) { __TBB_ASSERT( sizeof(base_type) + sizeof(arena_slot) == sizeof(arena), "All arena data fields must go to arena_base" ); __TBB_ASSERT( sizeof(base_type) % NFS_GetLineSize() == 0, "arena slots area misaligned: wrong padding" ); __TBB_ASSERT( sizeof(mail_outbox) == NFS_MaxLineSize, "Mailbox padding is wrong" ); size_t n = allocation_size(max_num_workers); unsigned char* storage = (unsigned char*)NFS_Allocate( 1, n, NULL ); // Zero all slots to indicate that they are empty memset( storage, 0, n ); return *new( storage + num_slots_to_reserve(max_num_workers) * sizeof(mail_outbox) ) arena(m, max_num_workers); } void arena::free_arena () { __TBB_ASSERT( is_alive(my_guard), NULL ); __TBB_ASSERT( !my_references, "There are threads in the dying arena" ); __TBB_ASSERT( !my_num_workers_requested && !my_num_workers_allotted, "Dying arena requests workers" ); __TBB_ASSERT( my_pool_state == SNAPSHOT_EMPTY || !my_max_num_workers, "Inconsistent state of a dying arena" ); #if !__TBB_STATISTICS_EARLY_DUMP GATHER_STATISTIC( dump_arena_statistics() ); #endif poison_value( my_guard ); intptr_t drained = 0; for ( unsigned i = 0; i < my_num_slots; ++i ) { __TBB_ASSERT( !my_slots[i].my_scheduler, "arena slot is not empty" ); #if !__TBB_TASK_ARENA __TBB_ASSERT( my_slots[i].task_pool == EmptyTaskPool, NULL ); #else //TODO: understand the assertion and modify #endif __TBB_ASSERT( my_slots[i].head == my_slots[i].tail, NULL ); // TODO: replace by is_quiescent_local_task_pool_empty my_slots[i].free_task_pool(); #if __TBB_STATISTICS NFS_Free( my_slots[i].my_counters ); #endif /* __TBB_STATISTICS */ drained += mailbox(i+1).drain(); } #if __TBB_TASK_PRIORITY && TBB_USE_ASSERT for ( intptr_t i = 0; i < num_priority_levels; ++i ) __TBB_ASSERT(my_task_stream[i].empty() && my_task_stream[i].drain()==0, "Not all enqueued tasks were executed"); #elif !__TBB_TASK_PRIORITY __TBB_ASSERT(my_task_stream.empty() && my_task_stream.drain()==0, "Not all enqueued tasks were executed"); #endif /* !__TBB_TASK_PRIORITY */ #if __TBB_COUNT_TASK_NODES my_market->update_task_node_count( -drained ); #endif /* __TBB_COUNT_TASK_NODES */ my_market->release(); #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT( my_default_ctx, "Master thread never entered the arena?" ); my_default_ctx->~task_group_context(); NFS_Free(my_default_ctx); #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_SCHEDULER_OBSERVER if ( !my_observers.empty() ) my_observers.clear(); #endif /* __TBB_SCHEDULER_OBSERVER */ void* storage = &mailbox(my_num_slots); __TBB_ASSERT( my_references == 0, NULL ); __TBB_ASSERT( my_pool_state == SNAPSHOT_EMPTY || !my_max_num_workers, NULL ); this->~arena(); #if TBB_USE_ASSERT > 1 memset( storage, 0, allocation_size(my_max_num_workers) ); #endif /* TBB_USE_ASSERT */ NFS_Free( storage ); } #if __TBB_STATISTICS void arena::dump_arena_statistics () { statistics_counters total; for( unsigned i = 0; i < my_num_slots; ++i ) { #if __TBB_STATISTICS_EARLY_DUMP generic_scheduler* s = my_slots[i].my_scheduler; if ( s ) *my_slots[i].my_counters += s->my_counters; #else __TBB_ASSERT( !my_slots[i].my_scheduler, NULL ); #endif if ( i != 0 ) { total += *my_slots[i].my_counters; dump_statistics( *my_slots[i].my_counters, i ); } } dump_statistics( *my_slots[0].my_counters, 0 ); #if __TBB_STATISTICS_STDOUT #if !__TBB_STATISTICS_TOTALS_ONLY printf( "----------------------------------------------\n" ); #endif dump_statistics( total, workers_counters_total ); total += *my_slots[0].my_counters; dump_statistics( total, arena_counters_total ); #if !__TBB_STATISTICS_TOTALS_ONLY printf( "==============================================\n" ); #endif #endif /* __TBB_STATISTICS_STDOUT */ } #endif /* __TBB_STATISTICS */ #if __TBB_TASK_PRIORITY // The method inspects a scheduler to determine: // 1. if it has tasks that can be retrieved and executed (via the return value); // 2. if it has any tasks at all, including those of lower priority (via tasks_present); // 3. if it is able to work with enqueued tasks (via dequeuing_possible). inline bool arena::may_have_tasks ( generic_scheduler* s, bool& tasks_present, bool& dequeuing_possible ) { if ( !s #if __TBB_TASK_ARENA || s->my_arena != this #endif ) return false; dequeuing_possible |= s->worker_outermost_level(); if ( s->my_pool_reshuffling_pending ) { // This primary task pool is nonempty and may contain tasks at the current // priority level. Its owner is winnowing lower priority tasks at the moment. tasks_present = true; return true; } if ( s->my_offloaded_tasks ) { tasks_present = true; if ( s->my_local_reload_epoch < *s->my_ref_reload_epoch ) { // This scheduler's offload area is nonempty and may contain tasks at the // current priority level. return true; } } return false; } void arena::orphan_offloaded_tasks(generic_scheduler& s) { __TBB_ASSERT( s.my_offloaded_tasks, NULL ); GATHER_STATISTIC( ++s.my_counters.prio_orphanings ); ++my_abandonment_epoch; __TBB_ASSERT( s.my_offloaded_task_list_tail_link && !*s.my_offloaded_task_list_tail_link, NULL ); task* orphans; do { orphans = const_cast(my_orphaned_tasks); *s.my_offloaded_task_list_tail_link = orphans; } while ( as_atomic(my_orphaned_tasks).compare_and_swap(s.my_offloaded_tasks, orphans) != orphans ); s.my_offloaded_tasks = NULL; #if TBB_USE_ASSERT s.my_offloaded_task_list_tail_link = NULL; #endif /* TBB_USE_ASSERT */ } #endif /* __TBB_TASK_PRIORITY */ bool arena::is_out_of_work() { // TODO: rework it to return at least a hint about where a task was found; better if the task itself. for(;;) { pool_state_t snapshot = my_pool_state; switch( snapshot ) { case SNAPSHOT_EMPTY: return true; case SNAPSHOT_FULL: { // Use unique id for "busy" in order to avoid ABA problems. const pool_state_t busy = pool_state_t(&busy); // Request permission to take snapshot if( my_pool_state.compare_and_swap( busy, SNAPSHOT_FULL )==SNAPSHOT_FULL ) { // Got permission. Take the snapshot. // NOTE: This is not a lock, as the state can be set to FULL at // any moment by a thread that spawns/enqueues new task. size_t n = my_limit; // Make local copies of volatile parameters. Their change during // snapshot taking procedure invalidates the attempt, and returns // this thread into the dispatch loop. #if __TBB_TASK_PRIORITY intptr_t top_priority = my_top_priority; uintptr_t reload_epoch = my_reload_epoch; // Inspect primary task pools first #endif /* __TBB_TASK_PRIORITY */ size_t k; for( k=0; kmy_arenas_list_mutex.lock(); generic_scheduler *s = my_slots[0].my_scheduler; if ( s && as_atomic(my_slots[0].my_scheduler).compare_and_swap(LockedMaster, s) == s ) { //TODO: remove need to lock __TBB_ASSERT( my_slots[0].my_scheduler == LockedMaster && s != LockedMaster, NULL ); work_absent = !may_have_tasks( s, tasks_present, dequeuing_possible ); __TBB_store_with_release( my_slots[0].my_scheduler, s ); } my_market->my_arenas_list_mutex.unlock(); // The following loop is subject to data races. While k-th slot's // scheduler is being examined, corresponding worker can either // leave to RML or migrate to another arena. // But the races are not prevented because all of them are benign. // First, the code relies on the fact that worker thread's scheduler // object persists until the whole library is deinitialized. // Second, in the worst case the races can only cause another // round of stealing attempts to be undertaken. Introducing complex // synchronization into this coldest part of the scheduler's control // flow does not seem to make sense because it both is unlikely to // ever have any observable performance effect, and will require // additional synchronization code on the hotter paths. for( k = 1; work_absent && k < n; ++k ) { if( my_pool_state!=busy ) return false; // the work was published work_absent = !may_have_tasks( my_slots[k].my_scheduler, tasks_present, dequeuing_possible ); } // Preclude premature switching arena off because of a race in the previous loop. work_absent = work_absent && !__TBB_load_with_acquire(my_orphaned_tasks) && abandonment_epoch == my_abandonment_epoch; } #endif /* __TBB_TASK_PRIORITY */ // Test and test-and-set. if( my_pool_state==busy ) { #if __TBB_TASK_PRIORITY bool no_fifo_tasks = my_task_stream[top_priority].empty(); work_absent = work_absent && (!dequeuing_possible || no_fifo_tasks) && top_priority == my_top_priority && reload_epoch == my_reload_epoch; #else bool no_fifo_tasks = my_task_stream.empty(); work_absent = work_absent && no_fifo_tasks; #endif /* __TBB_TASK_PRIORITY */ if( work_absent ) { #if __TBB_TASK_PRIORITY if ( top_priority > my_bottom_priority ) { if ( my_market->lower_arena_priority(*this, top_priority - 1, reload_epoch) && !my_task_stream[top_priority].empty() ) { atomic_update( my_skipped_fifo_priority, top_priority, std::less()); } } else if ( !tasks_present && !my_orphaned_tasks && no_fifo_tasks ) { #endif /* __TBB_TASK_PRIORITY */ // save current demand value before setting SNAPSHOT_EMPTY, // to avoid race with advertise_new_work. int current_demand = (int)my_max_num_workers; if( my_pool_state.compare_and_swap( SNAPSHOT_EMPTY, busy )==busy ) { // This thread transitioned pool to empty state, and thus is // responsible for telling RML that there is no other work to do. my_market->adjust_demand( *this, -current_demand ); #if __TBB_TASK_PRIORITY // Check for the presence of enqueued tasks "lost" on some of // priority levels because updating arena priority and switching // arena into "populated" (FULL) state happen non-atomically. // Imposing atomicity would require task::enqueue() to use a lock, // which is unacceptable. bool switch_back = false; for ( int p = 0; p < num_priority_levels; ++p ) { if ( !my_task_stream[p].empty() ) { switch_back = true; if ( p < my_bottom_priority || p > my_top_priority ) my_market->update_arena_priority(*this, p); } } if ( switch_back ) advertise_new_work(); #endif /* __TBB_TASK_PRIORITY */ return true; } return false; #if __TBB_TASK_PRIORITY } #endif /* __TBB_TASK_PRIORITY */ } // Undo previous transition SNAPSHOT_FULL-->busy, unless another thread undid it. my_pool_state.compare_and_swap( SNAPSHOT_FULL, busy ); } } return false; } default: // Another thread is taking a snapshot. return false; } } } #if __TBB_COUNT_TASK_NODES intptr_t arena::workers_task_node_count() { intptr_t result = 0; for( unsigned i = 1; i < my_num_slots; ++i ) { generic_scheduler* s = my_slots[i].my_scheduler; if( s ) result += s->my_task_node_count; } return result; } #endif /* __TBB_COUNT_TASK_NODES */ void arena::enqueue_task( task& t, intptr_t prio, FastRandom &random ) { #if __TBB_RECYCLE_TO_ENQUEUE __TBB_ASSERT( t.state()==task::allocated || t.state()==task::to_enqueue, "attempt to enqueue task with inappropriate state" ); #else __TBB_ASSERT( t.state()==task::allocated, "attempt to enqueue task that is not in 'allocated' state" ); #endif t.prefix().state = task::ready; t.prefix().extra_state |= es_task_enqueued; // enqueued task marker #if TBB_USE_ASSERT if( task* parent = t.parent() ) { internal::reference_count ref_count = parent->prefix().ref_count; __TBB_ASSERT( ref_count!=0, "attempt to enqueue task whose parent has a ref_count==0 (forgot to set_ref_count?)" ); __TBB_ASSERT( ref_count>0, "attempt to enqueue task whose parent has a ref_count<0" ); parent->prefix().extra_state |= es_ref_count_active; } __TBB_ASSERT(t.prefix().affinity==affinity_id(0), "affinity is ignored for enqueued tasks"); #endif /* TBB_USE_ASSERT */ #if __TBB_TASK_PRIORITY intptr_t p = prio ? normalize_priority(priority_t(prio)) : normalized_normal_priority; assert_priority_valid(p); task_stream &ts = my_task_stream[p]; #else /* !__TBB_TASK_PRIORITY */ __TBB_ASSERT_EX(prio == 0, "the library is not configured to respect the task priority"); task_stream &ts = my_task_stream; #endif /* !__TBB_TASK_PRIORITY */ ITT_NOTIFY(sync_releasing, &ts); ts.push( &t, random ); #if __TBB_TASK_PRIORITY if ( p != my_top_priority ) my_market->update_arena_priority( *this, p ); #endif /* __TBB_TASK_PRIORITY */ advertise_new_work< /*Spawned=*/ false >(); #if __TBB_TASK_PRIORITY if ( p != my_top_priority ) my_market->update_arena_priority( *this, p ); #endif /* __TBB_TASK_PRIORITY */ } #if __TBB_TASK_ARENA struct nested_arena_context : no_copy { generic_scheduler &my_scheduler; scheduler_state const my_orig_state; void *my_orig_ptr; bool my_adjusting; nested_arena_context(generic_scheduler *s, arena* a, bool needs_adjusting, bool as_worker = false) : my_scheduler(*s), my_orig_state(*s), my_orig_ptr(NULL), my_adjusting(needs_adjusting) { s->nested_arena_entry(a, *this, as_worker); } ~nested_arena_context() { my_scheduler.nested_arena_exit(*this); (scheduler_state&)my_scheduler = my_orig_state; // restore arena settings } }; void generic_scheduler::nested_arena_entry(arena* a, nested_arena_context& c, bool as_worker) { if( a == my_arena ) { #if __TBB_TASK_GROUP_CONTEXT c.my_orig_ptr = my_innermost_running_task = new(&allocate_task(sizeof(empty_task), NULL, a->my_default_ctx)) empty_task; #endif return; } __TBB_ASSERT( is_alive(a->my_guard), NULL ); // overwrite arena settings #if __TBB_TASK_PRIORITY if ( my_offloaded_tasks ) my_arena->orphan_offloaded_tasks( *this ); my_ref_top_priority = &a->my_top_priority; my_ref_reload_epoch = &a->my_reload_epoch; my_local_reload_epoch = a->my_reload_epoch; #endif /* __TBB_TASK_PRIORITY */ my_arena = a; my_arena_index = 0; my_arena_slot = my_arena->my_slots + my_arena_index; my_inbox.detach(); // TODO: mailboxes were not designed for switching, add copy constructor? attach_mailbox( affinity_id(my_arena_index+1) ); my_innermost_running_task = my_dispatching_task = as_worker? NULL : my_dummy_task; #if __TBB_TASK_GROUP_CONTEXT // save dummy's context and replace it by arena's context c.my_orig_ptr = my_dummy_task->prefix().context; my_dummy_task->prefix().context = a->my_default_ctx; #endif #if __TBB_ARENA_OBSERVER my_last_local_observer = 0; // TODO: try optimize number of calls my_arena->my_observers.notify_entry_observers( my_last_local_observer, /*worker=*/false ); #endif // TODO? ITT_NOTIFY(sync_acquired, a->my_slots + index); // TODO: it requires market to have P workers (not P-1) // TODO: it still allows temporary oversubscription by 1 worker (due to my_max_num_workers) // TODO: a preempted worker should be excluded from assignment to other arenas e.g. my_slack-- if( c.my_adjusting ) my_arena->my_market->adjust_demand(*my_arena, -1); } void generic_scheduler::nested_arena_exit(nested_arena_context& c) { if( my_arena == c.my_orig_state.my_arena ) { #if __TBB_TASK_GROUP_CONTEXT free_task(*(task*)c.my_orig_ptr); // TODO: use scoped_task instead? #endif return; } if( c.my_adjusting ) my_arena->my_market->adjust_demand(*my_arena, 1); #if __TBB_ARENA_OBSERVER my_arena->my_observers.notify_exit_observers( my_last_local_observer, /*worker=*/false ); #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_PRIORITY if ( my_offloaded_tasks ) my_arena->orphan_offloaded_tasks( *this ); my_local_reload_epoch = *c.my_orig_state.my_ref_reload_epoch; while ( as_atomic(my_arena->my_slots[0].my_scheduler).compare_and_swap( NULL, this) != this ) __TBB_Yield(); // TODO: task priority can use master slot for locking while accessing the scheduler #else // Free the master slot. TODO: support multiple masters __TBB_store_with_release(my_arena->my_slots[0].my_scheduler, (generic_scheduler*)NULL); #endif my_arena->my_exit_monitors.notify_all_relaxed(); // TODO: fix concurrent monitor to use notify_one (test MultipleMastersPart4 fails) #if __TBB_TASK_GROUP_CONTEXT // restore context of dummy task my_dummy_task->prefix().context = (task_group_context*)c.my_orig_ptr; #endif } void generic_scheduler::wait_until_empty() { my_dummy_task->prefix().ref_count++; // prevents exit from local_wait_for_all when local work is done enforcing the stealing while( my_arena->my_pool_state != arena::SNAPSHOT_EMPTY ) local_wait_for_all(*my_dummy_task, NULL); my_dummy_task->prefix().ref_count--; } #endif /* __TBB_TASK_ARENA */ } // namespace internal } // namespace tbb #if __TBB_TASK_ARENA #include "scheduler_utility.h" namespace tbb { namespace interface7 { namespace internal { void task_arena_base::internal_initialize( ) { __TBB_ASSERT( my_master_slots <= 1, "Number of slots reserved for master can be only [0,1]"); if( my_master_slots > 1 ) my_master_slots = 1; // TODO: make more masters if( my_max_concurrency < 1 ) my_max_concurrency = (int)governor::default_num_threads(); // TODO: reimplement in an efficient way. We need a scheduler instance in this thread // but the scheduler is only required for task allocation and fifo random seeds until // master wants to join the arena. (Idea - to create a restricted specialization) // It is excessive to create an implicit arena for master here anyway. But scheduler // instance implies master thread to be always connected with arena. // browse recursively into init_scheduler and arena::process for details if( !governor::local_scheduler_if_initialized() ) governor::init_scheduler( (unsigned)my_max_concurrency - my_master_slots + 1/*TODO: address in market instead*/, 0, true ); // TODO: we will need to introduce a mechanism for global settings, including stack size, used by all arenas arena* new_arena = &market::create_arena( my_max_concurrency - my_master_slots/*it's +1 slot for num_masters=0*/, ThreadStackSize ); if(as_atomic(my_arena).compare_and_swap(new_arena, NULL) != NULL) { // there is a race possible on my_initialized __TBB_ASSERT(my_arena, NULL); // other thread was the first new_arena->on_thread_leaving(); // deallocate new arena } #if __TBB_TASK_GROUP_CONTEXT else { my_context = new_arena->my_default_ctx; my_context->my_version_and_traits |= my_version_and_traits & exact_exception_flag; } #endif } void task_arena_base::internal_terminate( ) { if( my_arena ) {// task_arena was initialized #if __TBB_STATISTICS_EARLY_DUMP GATHER_STATISTIC( my_arena->dump_arena_statistics() ); #endif my_arena->on_thread_leaving(); my_arena = 0; #if __TBB_TASK_GROUP_CONTEXT my_context = 0; #endif } } void task_arena_base::internal_enqueue( task& t, intptr_t prio ) const { __TBB_ASSERT(my_arena, NULL); generic_scheduler* s = governor::local_scheduler_if_initialized(); __TBB_ASSERT(s, "Scheduler is not initialized"); // we allocated a task so can expect the scheduler #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT(my_arena->my_default_ctx == t.prefix().context, NULL); __TBB_ASSERT(!my_arena->my_default_ctx->is_group_execution_cancelled(), // TODO: any better idea? "The task will not be executed because default task_group_context of task_arena is cancelled. Has previously enqueued task thrown an exception?"); #endif my_arena->enqueue_task( t, prio, s->my_random ); } class delegated_task : public task { internal::delegate_base & my_delegate; concurrent_monitor & my_monitor; task * my_root; /*override*/ task* execute() { generic_scheduler& s = *(generic_scheduler*)prefix().owner; __TBB_ASSERT(s.worker_outermost_level() || s.master_outermost_level(), "expected to be enqueued and received on the outermost level"); // but this task can mimics outermost level, detect it if( s.master_outermost_level() && s.my_dummy_task->state() == task::executing ) { #if TBB_USE_EXCEPTIONS // RTTI is available, check whether the cast is valid __TBB_ASSERT(dynamic_cast(s.my_dummy_task), 0); #endif set_ref_count(1); // required by the semantics of recycle_to_enqueue() recycle_to_enqueue(); return NULL; } struct outermost_context : internal::no_copy { delegated_task * t; generic_scheduler & s; task * orig_dummy; task_group_context * orig_ctx; outermost_context(delegated_task *_t, generic_scheduler &_s) : t(_t), s(_s) { orig_dummy = s.my_dummy_task; #if __TBB_TASK_GROUP_CONTEXT orig_ctx = t->prefix().context; t->prefix().context = s.my_arena->my_default_ctx; #endif s.my_dummy_task = t; // mimics outermost master __TBB_ASSERT(s.my_innermost_running_task == t, NULL); } ~outermost_context() { s.my_dummy_task = orig_dummy; #if TBB_USE_EXCEPTIONS // restore context for sake of registering potential exception t->prefix().context = orig_ctx; #endif } } scope(this, s); my_delegate(); return NULL; } ~delegated_task() { // potential exception was already registered. It must happen before the notification __TBB_ASSERT(my_root->ref_count()==2, NULL); __TBB_store_with_release(my_root->prefix().ref_count, 1); // must precede the wakeup my_monitor.notify_relaxed(*this); } public: delegated_task( internal::delegate_base & d, concurrent_monitor & s, task * t ) : my_delegate(d), my_monitor(s), my_root(t) {} // predicate for concurrent_monitor notification bool operator()(uintptr_t ctx) const { return (void*)ctx == (void*)&my_delegate; } }; void task_arena_base::internal_execute( internal::delegate_base& d) const { __TBB_ASSERT(my_arena, NULL); generic_scheduler* s = governor::local_scheduler(); __TBB_ASSERT(s, "Scheduler is not initialized"); // TODO: is it safe to assign slot to a scheduler which is not yet switched? // TODO TEMP: one master, make more masters if( s->my_arena == my_arena || (!__TBB_load_with_acquire(my_arena->my_slots[0].my_scheduler) && as_atomic(my_arena->my_slots[0].my_scheduler).compare_and_swap(s, NULL ) == NULL) ) { cpu_ctl_env_helper cpu_ctl_helper; cpu_ctl_helper.set_env( __TBB_CONTEXT_ARG1(my_context) ); #if TBB_USE_EXCEPTIONS try { #endif //TODO: replace dummy tasks for workers as well to avoid using of the_dummy_context nested_arena_context scope(s, my_arena, !my_master_slots); d(); #if TBB_USE_EXCEPTIONS } catch(...) { cpu_ctl_helper.restore_default(); // TODO: is it needed on Windows? if( my_version_and_traits & exact_exception_flag ) throw; else { task_group_context exception_container( task_group_context::isolated, task_group_context::default_traits & ~task_group_context::exact_exception ); exception_container.register_pending_exception(); __TBB_ASSERT(exception_container.my_exception, NULL); exception_container.my_exception->throw_self(); } } #endif } else { concurrent_monitor::thread_context waiter; #if __TBB_TASK_GROUP_CONTEXT task_group_context exec_context( task_group_context::isolated, my_version_and_traits & exact_exception_flag ); #if __TBB_FP_CONTEXT exec_context.copy_fp_settings( *my_context ); #endif #endif auto_empty_task root(__TBB_CONTEXT_ARG(s, &exec_context)); root.prefix().ref_count = 2; my_arena->enqueue_task( *new( task::allocate_root(__TBB_CONTEXT_ARG1(exec_context)) ) delegated_task(d, my_arena->my_exit_monitors, &root), 0, s->my_random ); // TODO: priority? do { my_arena->my_exit_monitors.prepare_wait(waiter, (uintptr_t)&d); if( __TBB_load_with_acquire(root.prefix().ref_count) < 2 ) { my_arena->my_exit_monitors.cancel_wait(waiter); break; } else if( !__TBB_load_with_acquire(my_arena->my_slots[0].my_scheduler) // TODO: refactor into a function? && as_atomic(my_arena->my_slots[0].my_scheduler).compare_and_swap(s, NULL ) == NULL ) { my_arena->my_exit_monitors.cancel_wait(waiter); nested_arena_context scope(s, my_arena, !my_master_slots); s->local_wait_for_all(root, NULL); #if TBB_USE_EXCEPTIONS __TBB_ASSERT( !exec_context.my_exception, NULL ); // exception can be thrown above, not deferred #endif __TBB_ASSERT( root.prefix().ref_count == 0, NULL ); break; } else { my_arena->my_exit_monitors.commit_wait(waiter); } } while( __TBB_load_with_acquire(root.prefix().ref_count) == 2 ); #if TBB_USE_EXCEPTIONS // process possible exception if( task_group_context::exception_container_type *pe = exec_context.my_exception ) pe->throw_self(); #endif } } // this wait task is a temporary approach to wait for arena emptiness for masters without slots // TODO: it will be rather reworked for one source of notification from is_out_of_work class wait_task : public task { binary_semaphore & my_signal; /*override*/ task* execute() { generic_scheduler* s = governor::local_scheduler_if_initialized(); __TBB_ASSERT( s, NULL ); if( s->my_arena_index && s->worker_outermost_level() ) {// on outermost level of workers only s->local_wait_for_all( *s->my_dummy_task, NULL ); // run remaining tasks } else s->my_arena->is_out_of_work(); // avoids starvation of internal_wait: issuing this task makes arena full my_signal.V(); return NULL; } public: wait_task ( binary_semaphore & sema ) : my_signal(sema) {} }; void task_arena_base::internal_wait() const { __TBB_ASSERT(my_arena, NULL); generic_scheduler* s = governor::local_scheduler(); __TBB_ASSERT(s, "Scheduler is not initialized"); __TBB_ASSERT(s->my_arena != my_arena || s->my_arena_index == 0, "task_arena::wait_until_empty() is not supported within a worker context" ); if( s->my_arena == my_arena ) { //unsupported, but try do something for outermost master __TBB_ASSERT(s->master_outermost_level(), "unsupported"); if( !s->my_arena_index ) while( my_arena->num_workers_active() ) s->wait_until_empty(); } else for(;;) { while( my_arena->my_pool_state != arena::SNAPSHOT_EMPTY ) { if( !__TBB_load_with_acquire(my_arena->my_slots[0].my_scheduler) // TODO TEMP: one master, make more masters && as_atomic(my_arena->my_slots[0].my_scheduler).compare_and_swap(s, NULL) == NULL ) { nested_arena_context a(s, my_arena, !my_master_slots, true); s->wait_until_empty(); } else { binary_semaphore waiter; // TODO: replace by a single event notification from is_out_of_work internal_enqueue( *new( task::allocate_root(__TBB_CONTEXT_ARG1(*my_context)) ) wait_task(waiter), 0 ); // TODO: priority? waiter.P(); // TODO: concurrent_monitor } } if( !my_arena->num_workers_active() && !my_arena->my_slots[0].my_scheduler) // no activity break; // spin until workers active but avoid spinning in a worker __TBB_Yield(); // wait until workers and master leave } } /*static*/ int task_arena_base::internal_current_slot() { generic_scheduler* s = governor::local_scheduler_if_initialized(); return s? int(s->my_arena_index) : -1; } } // tbb::interfaceX::internal } // tbb::interfaceX } // tbb #endif /* __TBB_TASK_ARENA */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/arena.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_arena_H #define _TBB_arena_H #include "tbb/tbb_stddef.h" #include "tbb/atomic.h" #include "tbb/tbb_machine.h" #include "scheduler_common.h" #include "intrusive_list.h" #include "task_stream.h" #include "../rml/include/rml_tbb.h" #include "mailbox.h" #include "observer_proxy.h" #include "market.h" #include "governor.h" #if __TBB_TASK_ARENA #include "concurrent_monitor.h" #endif namespace tbb { class task_group_context; class allocate_root_with_context_proxy; namespace internal { //! arena data except the array of slots /** Separated in order to simplify padding. Intrusive list node base class is used by market to form a list of arenas. **/ struct arena_base : padded { //! Number of workers that have been marked out by the resource manager to service the arena unsigned my_num_workers_allotted; // heavy use in stealing loop //! References of the arena /** Counts workers and master references separately. Bit 0 indicates reference from implicit master or explicit task_arena; the next bits contain number of workers servicing the arena.*/ atomic my_references; // heavy use in stealing loop #if __TBB_TASK_PRIORITY //! Highest priority of recently spawned or enqueued tasks. volatile intptr_t my_top_priority; // heavy use in stealing loop //! Maximal currently busy slot. atomic my_limit; // heavy use in stealing loop //! Task pool for the tasks scheduled via task::enqueue() method /** Such scheduling guarantees eventual execution even if - new tasks are constantly coming (by extracting scheduled tasks in relaxed FIFO order); - the enqueuing thread does not call any of wait_for_all methods. **/ task_stream my_task_stream[num_priority_levels]; // heavy use in stealing loop #else /* !__TBB_TASK_PRIORITY */ //! Task pool for the tasks scheduled via task::enqueue() method /** Such scheduling guarantees eventual execution even if - new tasks are constantly coming (by extracting scheduled tasks in relaxed FIFO order); - the enqueuing thread does not call any of wait_for_all methods. **/ task_stream my_task_stream; // heavy use in stealing loop //! Maximal currently busy slot. atomic my_limit; // heavy use in stealing loop #endif /* !__TBB_TASK_PRIORITY */ //! Number of workers that are currently requested from the resource manager int my_num_workers_requested; //! Number of slots in the arena unsigned my_num_slots; //! Number of workers requested by the master thread owning the arena unsigned my_max_num_workers; //! Market owning this arena market* my_market; //! ABA prevention marker uintptr_t my_aba_epoch; #if !__TBB_FP_CONTEXT //! FPU control settings of arena's master thread captured at the moment of arena instantiation. __TBB_cpu_ctl_env_t my_cpu_ctl_env; #endif #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION int my_num_workers_present; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ //! Current task pool state and estimate of available tasks amount. /** The estimate is either 0 (SNAPSHOT_EMPTY) or infinity (SNAPSHOT_FULL). Special state is "busy" (any other unsigned value). Note that the implementation of arena::is_busy_or_empty() requires my_pool_state to be unsigned. */ tbb::atomic my_pool_state; #if __TBB_TASK_GROUP_CONTEXT //! Default task group context. /** Used by root tasks allocated directly by the master thread (not from inside a TBB task) without explicit context specification. **/ task_group_context* my_default_ctx; #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_SCHEDULER_OBSERVER //! List of local observers attached to this arena. observer_list my_observers; #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_PRIORITY //! Lowest normalized priority of available spawned or enqueued tasks. intptr_t my_bottom_priority; //! Tracks events that may bring tasks in offload areas to the top priority level. /** Incremented when arena top priority changes or a task group priority is elevated to the current arena's top level. **/ uintptr_t my_reload_epoch; //! List of offloaded tasks abandoned by workers revoked by the market task* my_orphaned_tasks; //! Counter used to track the occurrence of recent orphaning and re-sharing operations. tbb::atomic my_abandonment_epoch; //! Highest priority level containing enqueued tasks /** It being greater than 0 means that high priority enqueued tasks had to be bypassed because all workers were blocked in nested dispatch loops and were unable to progress at then current priority level. **/ tbb::atomic my_skipped_fifo_priority; #endif /* !__TBB_TASK_PRIORITY */ //! Indicates if there is an oversubscribing worker created to service enqueued tasks. bool my_mandatory_concurrency; #if __TBB_TASK_ARENA //! exit notifications after arena slot is released concurrent_monitor my_exit_monitors; #endif #if TBB_USE_ASSERT //! Used to trap accesses to the object after its destruction. uintptr_t my_guard; #endif /* TBB_USE_ASSERT */ }; // struct arena_base class arena #if (__GNUC__<4 || __GNUC__==4 && __GNUC_MINOR__==0) && !__INTEL_COMPILER : public padded #else : private padded #endif { private: friend class generic_scheduler; template friend class custom_scheduler; friend class governor; friend class task_scheduler_observer_v3; friend class market; friend class tbb::task; friend class tbb::task_group_context; friend class allocate_root_with_context_proxy; friend class intrusive_list; friend class interface7::internal::task_arena_base; // declared in scheduler_common.h friend class interface7::internal::delegated_task; friend class interface7::internal::wait_task; typedef padded base_type; //! Constructor arena ( market&, unsigned max_num_workers ); //! Allocate an instance of arena. static arena& allocate_arena( market&, unsigned max_num_workers ); static int unsigned num_slots_to_reserve ( unsigned max_num_workers ) { return max(2u, max_num_workers + 1); } static int allocation_size ( unsigned max_num_workers ) { return sizeof(base_type) + num_slots_to_reserve(max_num_workers) * (sizeof(mail_outbox) + sizeof(arena_slot)); } #if __TBB_TASK_GROUP_CONTEXT //! Finds all contexts affected by the state change and propagates the new state to them. /** The propagation is relayed to the market because tasks created by one master thread can be passed to and executed by other masters. This means that context trees can span several arenas at once and thus state change propagation cannot be generally localized to one arena only. **/ template bool propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Get reference to mailbox corresponding to given affinity_id. mail_outbox& mailbox( affinity_id id ) { __TBB_ASSERT( 0> 1; } //! If necessary, raise a flag that there is new job in arena. template void advertise_new_work(); //! Check if there is job anywhere in arena. /** Return true if no job or if arena is being cleaned up. */ bool is_out_of_work(); //! enqueue a task into starvation-resistance queue void enqueue_task( task&, intptr_t, FastRandom & ); //! Registers the worker with the arena and enters TBB scheduler dispatch loop void process( generic_scheduler& ); //! Notification that worker or master leaves its arena template inline void on_thread_leaving ( ); #if __TBB_STATISTICS //! Outputs internal statistics accumulated by the arena void dump_arena_statistics (); #endif /* __TBB_STATISTICS */ #if __TBB_TASK_PRIORITY //! Check if recent priority changes may bring some tasks to the current priority level soon /** /param tasks_present indicates presence of tasks at any priority level. **/ inline bool may_have_tasks ( generic_scheduler*, bool& tasks_present, bool& dequeuing_possible ); //! Puts offloaded tasks into global list of orphaned tasks void orphan_offloaded_tasks ( generic_scheduler& s ); #endif /* __TBB_TASK_PRIORITY */ #if __TBB_COUNT_TASK_NODES //! Returns the number of task objects "living" in worker threads intptr_t workers_task_node_count(); #endif /** Must be the last data field */ arena_slot my_slots[1]; }; // class arena template inline void arena::on_thread_leaving ( ) { // // Implementation of arena destruction synchronization logic contained various // bugs/flaws at the different stages of its evolution, so below is a detailed // description of the issues taken into consideration in the framework of the // current design. // // In case of using fire-and-forget tasks (scheduled via task::enqueue()) // master thread is allowed to leave its arena before all its work is executed, // and market may temporarily revoke all workers from this arena. Since revoked // workers never attempt to reset arena state to EMPTY and cancel its request // to RML for threads, the arena object is destroyed only when both the last // thread is leaving it and arena's state is EMPTY (that is its master thread // left and it does not contain any work). // // A worker that checks for work presence and transitions arena to the EMPTY // state (in snapshot taking procedure arena::is_out_of_work()) updates // arena::my_pool_state first and only then arena::my_num_workers_requested. // So the check for work absence must be done against the latter field. // // In a time window between decrementing the active threads count and checking // if there is an outstanding request for workers. New worker thread may arrive, // finish remaining work, set arena state to empty, and leave decrementing its // refcount and destroying. Then the current thread will destroy the arena // the second time. To preclude it a local copy of the outstanding request // value can be stored before decrementing active threads count. // // But this technique may cause two other problem. When the stored request is // zero, it is possible that arena still has threads and they can generate new // tasks and thus re-establish non-zero requests. Then all the threads can be // revoked (as described above) leaving this thread the last one, and causing // it to destroy non-empty arena. // // The other problem takes place when the stored request is non-zero. Another // thread may complete the work, set arena state to empty, and leave without // arena destruction before this thread decrements the refcount. This thread // cannot destroy the arena either. Thus the arena may be "orphaned". // // In both cases we cannot dereference arena pointer after the refcount is // decremented, as our arena may already be destroyed. // // If this is the master thread, market can be concurrently destroyed. // In case of workers market's liveness is ensured by the RML connection // rundown protocol, according to which the client (i.e. the market) lives // until RML server notifies it about connection termination, and this // notification is fired only after all workers return into RML. // // Thus if we decremented refcount to zero we ask the market to check arena // state (including the fact if it is alive) under the lock. // uintptr_t aba_epoch = my_aba_epoch; market* m = my_market; __TBB_ASSERT(my_references > int(!is_master), "broken arena reference counter"); if ( (my_references -= is_master? 1:2 ) == 0 ) // worker's counter starts from bit 1 market::try_destroy_arena( m, this, aba_epoch, is_master ); } template void arena::advertise_new_work() { if( !Spawned ) { // i.e. the work was enqueued if( my_max_num_workers==0 ) { my_max_num_workers = 1; __TBB_ASSERT(!my_mandatory_concurrency, ""); my_mandatory_concurrency = true; __TBB_ASSERT(!num_workers_active(), ""); my_pool_state = SNAPSHOT_FULL; my_market->adjust_demand( *this, 1 ); return; } // Local memory fence is required to avoid missed wakeups; see the comment below. // Starvation resistant tasks require mandatory concurrency, so missed wakeups are unacceptable. atomic_fence(); } // Double-check idiom that, in case of spawning, is deliberately sloppy about memory fences. // Technically, to avoid missed wakeups, there should be a full memory fence between the point we // released the task pool (i.e. spawned task) and read the arena's state. However, adding such a // fence might hurt overall performance more than it helps, because the fence would be executed // on every task pool release, even when stealing does not occur. Since TBB allows parallelism, // but never promises parallelism, the missed wakeup is not a correctness problem. pool_state_t snapshot = my_pool_state; if( is_busy_or_empty(snapshot) ) { // Attempt to mark as full. The compare_and_swap below is a little unusual because the // result is compared to a value that can be different than the comparand argument. if( my_pool_state.compare_and_swap( SNAPSHOT_FULL, snapshot )==SNAPSHOT_EMPTY ) { if( snapshot!=SNAPSHOT_EMPTY ) { // This thread read "busy" into snapshot, and then another thread transitioned // my_pool_state to "empty" in the meantime, which caused the compare_and_swap above // to fail. Attempt to transition my_pool_state from "empty" to "full". if( my_pool_state.compare_and_swap( SNAPSHOT_FULL, SNAPSHOT_EMPTY )!=SNAPSHOT_EMPTY ) { // Some other thread transitioned my_pool_state from "empty", and hence became // responsible for waking up workers. return; } } // This thread transitioned pool from empty to full state, and thus is responsible for // telling RML that there is work to do. if( Spawned ) { if( my_mandatory_concurrency ) { __TBB_ASSERT(my_max_num_workers==1, ""); __TBB_ASSERT(!governor::local_scheduler()->is_worker(), ""); // There was deliberate oversubscription on 1 core for sake of starvation-resistant tasks. // Now a single active thread (must be the master) supposedly starts a new parallel region // with relaxed sequential semantics, and oversubscription should be avoided. // Demand for workers has been decreased to 0 during SNAPSHOT_EMPTY, so just keep it. my_max_num_workers = 0; my_mandatory_concurrency = false; return; } } my_market->adjust_demand( *this, my_max_num_workers ); } } } } // namespace internal } // namespace tbb #endif /* _TBB_arena_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/atomic.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_atomic_H #define __TBB_atomic_H #include #if _MSC_VER #define __TBB_LONG_LONG __int64 #else #define __TBB_LONG_LONG long long #endif /* _MSC_VER */ #include "tbb_machine.h" #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings #pragma warning (push) #pragma warning (disable: 4244 4267 4512) #endif namespace tbb { //! Specifies memory semantics. enum memory_semantics { //! Sequential consistency full_fence, //! Acquire acquire, //! Release release, //! No ordering relaxed }; //! @cond INTERNAL namespace internal { #if __TBB_ATTRIBUTE_ALIGNED_PRESENT #define __TBB_DECL_ATOMIC_FIELD(t,f,a) t f __attribute__ ((aligned(a))); #elif __TBB_DECLSPEC_ALIGN_PRESENT #define __TBB_DECL_ATOMIC_FIELD(t,f,a) __declspec(align(a)) t f; #else #error Do not know syntax for forcing alignment. #endif template struct atomic_rep; // Primary template declared, but never defined. template<> struct atomic_rep<1> { // Specialization typedef int8_t word; }; template<> struct atomic_rep<2> { // Specialization typedef int16_t word; }; template<> struct atomic_rep<4> { // Specialization #if _MSC_VER && !_WIN64 // Work-around that avoids spurious /Wp64 warnings typedef intptr_t word; #else typedef int32_t word; #endif }; #if __TBB_64BIT_ATOMICS template<> struct atomic_rep<8> { // Specialization typedef int64_t word; }; #endif template struct aligned_storage; //the specializations are needed to please MSVC syntax of __declspec(align()) which accept _literal_ constants only #if __TBB_ATOMIC_CTORS #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S) \ template \ struct aligned_storage { \ __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S) \ aligned_storage() = default ; \ constexpr aligned_storage(value_type value):my_value(value){} \ }; \ #else #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S) \ template \ struct aligned_storage { \ __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S) \ }; \ #endif template struct aligned_storage { value_type my_value; #if __TBB_ATOMIC_CTORS aligned_storage() = default ; constexpr aligned_storage(value_type value):my_value(value){} #endif }; ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(2) ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(4) #if __TBB_64BIT_ATOMICS ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(8) #endif template struct atomic_traits; // Primary template declared, but not defined. #define __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(S,M) \ template<> struct atomic_traits { \ typedef atomic_rep::word word; \ inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) { \ return __TBB_machine_cmpswp##S##M(location,new_value,comparand); \ } \ inline static word fetch_and_add( volatile void* location, word addend ) { \ return __TBB_machine_fetchadd##S##M(location,addend); \ } \ inline static word fetch_and_store( volatile void* location, word value ) { \ return __TBB_machine_fetchstore##S##M(location,value); \ } \ }; #define __TBB_DECL_ATOMIC_PRIMITIVES(S) \ template \ struct atomic_traits { \ typedef atomic_rep::word word; \ inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) { \ return __TBB_machine_cmpswp##S(location,new_value,comparand); \ } \ inline static word fetch_and_add( volatile void* location, word addend ) { \ return __TBB_machine_fetchadd##S(location,addend); \ } \ inline static word fetch_and_store( volatile void* location, word value ) { \ return __TBB_machine_fetchstore##S(location,value); \ } \ }; template struct atomic_load_store_traits; // Primary template declaration #define __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(M) \ template<> struct atomic_load_store_traits { \ template \ inline static T load( const volatile T& location ) { \ return __TBB_load_##M( location ); \ } \ template \ inline static void store( volatile T& location, T value ) { \ __TBB_store_##M( location, value ); \ } \ } #if __TBB_USE_FENCED_ATOMICS __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,release) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,release) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,release) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,relaxed) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,relaxed) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,relaxed) #if __TBB_64BIT_ATOMICS __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,release) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,relaxed) #endif #else /* !__TBB_USE_FENCED_ATOMICS */ __TBB_DECL_ATOMIC_PRIMITIVES(1) __TBB_DECL_ATOMIC_PRIMITIVES(2) __TBB_DECL_ATOMIC_PRIMITIVES(4) #if __TBB_64BIT_ATOMICS __TBB_DECL_ATOMIC_PRIMITIVES(8) #endif #endif /* !__TBB_USE_FENCED_ATOMICS */ __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(full_fence); __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(acquire); __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(release); __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(relaxed); //! Additive inverse of 1 for type T. /** Various compilers issue various warnings if -1 is used with various integer types. The baroque expression below avoids all the warnings (we hope). */ #define __TBB_MINUS_ONE(T) (T(T(0)-T(1))) //! Base class that provides basic functionality for atomic without fetch_and_add. /** Works for any type T that has the same size as an integral type, has a trivial constructor/destructor, and can be copied/compared by memcpy/memcmp. */ template struct atomic_impl { protected: aligned_storage my_storage; private: //TODO: rechecks on recent versions of gcc if union is still the _only_ way to do a conversion without warnings //! Union type used to convert type T to underlying integral type. template union converter { typedef typename atomic_rep::word bits_type; converter(){} converter(value_type a_value) : value(a_value) {} value_type value; bits_type bits; }; template static typename converter::bits_type to_bits(value_t value){ return converter(value).bits; } template static value_t to_value(typename converter::bits_type bits){ converter u; u.bits = bits; return u.value; } template union ptr_converter; //Primary template declared, but never defined. template union ptr_converter { ptr_converter(){} ptr_converter(value_t* a_value) : value(a_value) {} value_t* value; uintptr_t bits; }; //TODO: check if making to_bits accepting reference (thus unifying it with to_bits_ref) //does not hurt performance template static typename converter::bits_type & to_bits_ref(value_t& value){ //TODO: this #ifdef is temporary workaround, as union conversion seems to fail //on suncc for 64 bit types for 32 bit target #if !__SUNPRO_CC return *(typename converter::bits_type*)ptr_converter(&value).bits; #else return *(typename converter::bits_type*)(&value); #endif } public: typedef T value_type; #if __TBB_ATOMIC_CTORS atomic_impl() = default ; constexpr atomic_impl(value_type value):my_storage(value){} #endif template value_type fetch_and_store( value_type value ) { return to_value( internal::atomic_traits::fetch_and_store( &my_storage.my_value, to_bits(value) ) ); } value_type fetch_and_store( value_type value ) { return fetch_and_store(value); } template value_type compare_and_swap( value_type value, value_type comparand ) { return to_value( internal::atomic_traits::compare_and_swap( &my_storage.my_value, to_bits(value), to_bits(comparand) ) ); } value_type compare_and_swap( value_type value, value_type comparand ) { return compare_and_swap(value,comparand); } operator value_type() const volatile { // volatile qualifier here for backwards compatibility return to_value( __TBB_load_with_acquire( to_bits_ref(my_storage.my_value) ) ); } template value_type load () const { return to_value( internal::atomic_load_store_traits::load( to_bits_ref(my_storage.my_value) ) ); } value_type load () const { return load(); } template void store ( value_type value ) { internal::atomic_load_store_traits::store( to_bits_ref(my_storage.my_value), to_bits(value)); } void store ( value_type value ) { store( value ); } protected: value_type store_with_release( value_type rhs ) { //TODO: unify with store __TBB_store_with_release( to_bits_ref(my_storage.my_value), to_bits(rhs) ); return rhs; } }; //! Base class that provides basic functionality for atomic with fetch_and_add. /** I is the underlying type. D is the difference type. StepType should be char if I is an integral type, and T if I is a T*. */ template struct atomic_impl_with_arithmetic: atomic_impl { public: typedef I value_type; #if __TBB_ATOMIC_CTORS atomic_impl_with_arithmetic() = default ; constexpr atomic_impl_with_arithmetic(value_type value): atomic_impl(value){} #endif template value_type fetch_and_add( D addend ) { return value_type(internal::atomic_traits::fetch_and_add( &this->my_storage.my_value, addend*sizeof(StepType) )); } value_type fetch_and_add( D addend ) { return fetch_and_add(addend); } template value_type fetch_and_increment() { return fetch_and_add(1); } value_type fetch_and_increment() { return fetch_and_add(1); } template value_type fetch_and_decrement() { return fetch_and_add(__TBB_MINUS_ONE(D)); } value_type fetch_and_decrement() { return fetch_and_add(__TBB_MINUS_ONE(D)); } public: value_type operator+=( D value ) { return fetch_and_add(value)+value; } value_type operator-=( D value ) { // Additive inverse of value computed using binary minus, // instead of unary minus, for sake of avoiding compiler warnings. return operator+=(D(0)-value); } value_type operator++() { return fetch_and_add(1)+1; } value_type operator--() { return fetch_and_add(__TBB_MINUS_ONE(D))-1; } value_type operator++(int) { return fetch_and_add(1); } value_type operator--(int) { return fetch_and_add(__TBB_MINUS_ONE(D)); } }; } /* Internal */ //! @endcond //! Primary template for atomic. /** See the Reference for details. @ingroup synchronization */ template struct atomic: internal::atomic_impl { #if __TBB_ATOMIC_CTORS atomic() = default; constexpr atomic(T arg): internal::atomic_impl(arg) {} #endif T operator=( T rhs ) { // "this" required here in strict ISO C++ because store_with_release is a dependent name return this->store_with_release(rhs); } atomic& operator=( const atomic& rhs ) {this->store_with_release(rhs); return *this;} }; #if __TBB_ATOMIC_CTORS #define __TBB_DECL_ATOMIC(T) \ template<> struct atomic: internal::atomic_impl_with_arithmetic { \ atomic() = default; \ constexpr atomic(T arg): internal::atomic_impl_with_arithmetic(arg) {} \ \ T operator=( T rhs ) {return store_with_release(rhs);} \ atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ }; #else #define __TBB_DECL_ATOMIC(T) \ template<> struct atomic: internal::atomic_impl_with_arithmetic { \ T operator=( T rhs ) {return store_with_release(rhs);} \ atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ }; #endif #if __TBB_64BIT_ATOMICS //TODO: consider adding non-default (and atomic) copy constructor for 32bit platform __TBB_DECL_ATOMIC(__TBB_LONG_LONG) __TBB_DECL_ATOMIC(unsigned __TBB_LONG_LONG) #else // test_atomic will verify that sizeof(long long)==8 #endif __TBB_DECL_ATOMIC(long) __TBB_DECL_ATOMIC(unsigned long) #if _MSC_VER && !_WIN64 #if __TBB_ATOMIC_CTORS /* Special version of __TBB_DECL_ATOMIC that avoids gratuitous warnings from cl /Wp64 option. It is identical to __TBB_DECL_ATOMIC(unsigned) except that it replaces operator=(T) with an operator=(U) that explicitly converts the U to a T. Types T and U should be type synonyms on the platform. Type U should be the wider variant of T from the perspective of /Wp64. */ #define __TBB_DECL_ATOMIC_ALT(T,U) \ template<> struct atomic: internal::atomic_impl_with_arithmetic { \ atomic() = default ; \ constexpr atomic(T arg): internal::atomic_impl_with_arithmetic(arg) {} \ T operator=( U rhs ) {return store_with_release(T(rhs));} \ atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ }; #else #define __TBB_DECL_ATOMIC_ALT(T,U) \ template<> struct atomic: internal::atomic_impl_with_arithmetic { \ T operator=( U rhs ) {return store_with_release(T(rhs));} \ atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ }; #endif __TBB_DECL_ATOMIC_ALT(unsigned,size_t) __TBB_DECL_ATOMIC_ALT(int,ptrdiff_t) #else __TBB_DECL_ATOMIC(unsigned) __TBB_DECL_ATOMIC(int) #endif /* _MSC_VER && !_WIN64 */ __TBB_DECL_ATOMIC(unsigned short) __TBB_DECL_ATOMIC(short) __TBB_DECL_ATOMIC(char) __TBB_DECL_ATOMIC(signed char) __TBB_DECL_ATOMIC(unsigned char) #if !_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED) __TBB_DECL_ATOMIC(wchar_t) #endif /* _MSC_VER||!defined(_NATIVE_WCHAR_T_DEFINED) */ //! Specialization for atomic with arithmetic and operator->. template struct atomic: internal::atomic_impl_with_arithmetic { #if __TBB_ATOMIC_CTORS atomic() = default ; constexpr atomic(T* arg): internal::atomic_impl_with_arithmetic(arg) {} #endif T* operator=( T* rhs ) { // "this" required here in strict ISO C++ because store_with_release is a dependent name return this->store_with_release(rhs); } atomic& operator=( const atomic& rhs ) { this->store_with_release(rhs); return *this; } T* operator->() const { return (*this); } }; //! Specialization for atomic, for sake of not allowing arithmetic or operator->. template<> struct atomic: internal::atomic_impl { #if __TBB_ATOMIC_CTORS atomic() = default ; constexpr atomic(void* arg): internal::atomic_impl(arg) {} #endif void* operator=( void* rhs ) { // "this" required here in strict ISO C++ because store_with_release is a dependent name return this->store_with_release(rhs); } atomic& operator=( const atomic& rhs ) { this->store_with_release(rhs); return *this; } }; // Helpers to workaround ugly syntax of calling template member function of a // template class with template argument dependent on template parameters. template T load ( const atomic& a ) { return a.template load(); } template void store ( atomic& a, T value ) { a.template store(value); } namespace interface6{ //! Make an atomic for use in an initialization (list), as an alternative to zero-initialization or normal assignment. template atomic make_atomic(T t) { atomic a; store(a,t); return a; } } using interface6::make_atomic; namespace internal { template void swap(atomic & lhs, atomic & rhs){ T tmp = load(lhs); store(lhs,load(rhs)); store(rhs,tmp); } // only to aid in the gradual conversion of ordinary variables to proper atomics template inline atomic& as_atomic( T& t ) { return (atomic&)t; } } // namespace tbb::internal } // namespace tbb #if _MSC_VER && !__INTEL_COMPILER #pragma warning (pop) #endif // warnings 4244, 4267 are back #endif /* __TBB_atomic_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/blocked_range.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_blocked_range_H #define __TBB_blocked_range_H #include "tbb_stddef.h" namespace tbb { /** \page range_req Requirements on range concept Class \c R implementing the concept of range must define: - \code R::R( const R& ); \endcode Copy constructor - \code R::~R(); \endcode Destructor - \code bool R::is_divisible() const; \endcode True if range can be partitioned into two subranges - \code bool R::empty() const; \endcode True if range is empty - \code R::R( R& r, split ); \endcode Split range \c r into two subranges. **/ //! A range over which to iterate. /** @ingroup algorithms */ template class blocked_range { public: //! Type of a value /** Called a const_iterator for sake of algorithms that need to treat a blocked_range as an STL container. */ typedef Value const_iterator; //! Type for size of a range typedef std::size_t size_type; //! Construct range with default-constructed values for begin and end. /** Requires that Value have a default constructor. */ blocked_range() : my_end(), my_begin() {} //! Construct range over half-open interval [begin,end), with the given grainsize. blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) : my_end(end_), my_begin(begin_), my_grainsize(grainsize_) { __TBB_ASSERT( my_grainsize>0, "grainsize must be positive" ); } //! Beginning of range. const_iterator begin() const {return my_begin;} //! One past last value in range. const_iterator end() const {return my_end;} //! Size of the range /** Unspecified if end() friend class blocked_range2d; template friend class blocked_range3d; }; } // namespace tbb #endif /* __TBB_blocked_range_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/blocked_range2d.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_blocked_range2d_H #define __TBB_blocked_range2d_H #include "tbb_stddef.h" #include "blocked_range.h" namespace tbb { //! A 2-dimensional range that models the Range concept. /** @ingroup algorithms */ template class blocked_range2d { public: //! Type for size of an iteration range typedef blocked_range row_range_type; typedef blocked_range col_range_type; private: row_range_type my_rows; col_range_type my_cols; public: blocked_range2d( RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize, ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) : my_rows(row_begin,row_end,row_grainsize), my_cols(col_begin,col_end,col_grainsize) { } blocked_range2d( RowValue row_begin, RowValue row_end, ColValue col_begin, ColValue col_end ) : my_rows(row_begin,row_end), my_cols(col_begin,col_end) { } //! True if range is empty bool empty() const { // Yes, it is a logical OR here, not AND. return my_rows.empty() || my_cols.empty(); } //! True if range is divisible into two pieces. bool is_divisible() const { return my_rows.is_divisible() || my_cols.is_divisible(); } blocked_range2d( blocked_range2d& r, split ) : my_rows(r.my_rows), my_cols(r.my_cols) { split split_obj; do_split(r, split_obj); } #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES //! Static field to support proportional split static const bool is_divisible_in_proportion = true; blocked_range2d( blocked_range2d& r, proportional_split& proportion ) : my_rows(r.my_rows), my_cols(r.my_cols) { do_split(r, proportion); } #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ template void do_split( blocked_range2d& r, Split& split_obj ) { if( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) { my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); } else { my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj); } } //! The rows of the iteration space const row_range_type& rows() const {return my_rows;} //! The columns of the iteration space const col_range_type& cols() const {return my_cols;} }; } // namespace tbb #endif /* __TBB_blocked_range2d_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/blocked_range3d.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_blocked_range3d_H #define __TBB_blocked_range3d_H #include "tbb_stddef.h" #include "blocked_range.h" namespace tbb { //! A 3-dimensional range that models the Range concept. /** @ingroup algorithms */ template class blocked_range3d { public: //! Type for size of an iteration range typedef blocked_range page_range_type; typedef blocked_range row_range_type; typedef blocked_range col_range_type; private: page_range_type my_pages; row_range_type my_rows; col_range_type my_cols; public: blocked_range3d( PageValue page_begin, PageValue page_end, RowValue row_begin, RowValue row_end, ColValue col_begin, ColValue col_end ) : my_pages(page_begin,page_end), my_rows(row_begin,row_end), my_cols(col_begin,col_end) { } blocked_range3d( PageValue page_begin, PageValue page_end, typename page_range_type::size_type page_grainsize, RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize, ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) : my_pages(page_begin,page_end,page_grainsize), my_rows(row_begin,row_end,row_grainsize), my_cols(col_begin,col_end,col_grainsize) { } //! True if range is empty bool empty() const { // Yes, it is a logical OR here, not AND. return my_pages.empty() || my_rows.empty() || my_cols.empty(); } //! True if range is divisible into two pieces. bool is_divisible() const { return my_pages.is_divisible() || my_rows.is_divisible() || my_cols.is_divisible(); } blocked_range3d( blocked_range3d& r, split ) : my_pages(r.my_pages), my_rows(r.my_rows), my_cols(r.my_cols) { split split_obj; do_split(r, split_obj); } #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES //! Static field to support proportional split static const bool is_divisible_in_proportion = true; blocked_range3d( blocked_range3d& r, proportional_split& proportion ) : my_pages(r.my_pages), my_rows(r.my_rows), my_cols(r.my_cols) { do_split(r, proportion); } #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ template void do_split( blocked_range3d& r, Split& split_obj) { if ( my_pages.size()*double(my_rows.grainsize()) < my_rows.size()*double(my_pages.grainsize()) ) { if ( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) { my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); } else { my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj); } } else { if ( my_pages.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_pages.grainsize()) ) { my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); } else { my_pages.my_begin = page_range_type::do_split(r.my_pages, split_obj); } } } //! The pages of the iteration space const page_range_type& pages() const {return my_pages;} //! The rows of the iteration space const row_range_type& rows() const {return my_rows;} //! The columns of the iteration space const col_range_type& cols() const {return my_cols;} }; } // namespace tbb #endif /* __TBB_blocked_range3d_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/cache_aligned_allocator.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" #include "tbb/cache_aligned_allocator.h" #include "tbb/tbb_allocator.h" #include "tbb/tbb_exception.h" #include "tbb_misc.h" #include "dynamic_link.h" #include #if _WIN32||_WIN64 #include "tbb/machine/windows_api.h" #else #include #endif /* _WIN32||_WIN64 */ using namespace std; #if __TBB_WEAK_SYMBOLS_PRESENT #pragma weak scalable_malloc #pragma weak scalable_free #pragma weak scalable_aligned_malloc #pragma weak scalable_aligned_free extern "C" { void* scalable_malloc( size_t ); void scalable_free( void* ); void* scalable_aligned_malloc( size_t, size_t ); void scalable_aligned_free( void* ); } #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ namespace tbb { namespace internal { //! Dummy routine used for first indirect call via MallocHandler. static void* DummyMalloc( size_t size ); //! Dummy routine used for first indirect call via FreeHandler. static void DummyFree( void * ptr ); //! Handler for memory allocation static void* (*MallocHandler)( size_t size ) = &DummyMalloc; //! Handler for memory deallocation static void (*FreeHandler)( void* pointer ) = &DummyFree; //! Dummy routine used for first indirect call via padded_allocate_handler. static void* dummy_padded_allocate( size_t bytes, size_t alignment ); //! Dummy routine used for first indirect call via padded_free_handler. static void dummy_padded_free( void * ptr ); // ! Allocates memory using standard malloc. It is used when scalable_allocator is not available static void* padded_allocate( size_t bytes, size_t alignment ); // ! Allocates memory using standard free. It is used when scalable_allocator is not available static void padded_free( void* p ); //! Handler for padded memory allocation static void* (*padded_allocate_handler)( size_t bytes, size_t alignment ) = &dummy_padded_allocate; //! Handler for padded memory deallocation static void (*padded_free_handler)( void* p ) = &dummy_padded_free; //! Table describing how to link the handlers. static const dynamic_link_descriptor MallocLinkTable[] = { DLD(scalable_malloc, MallocHandler), DLD(scalable_free, FreeHandler), DLD(scalable_aligned_malloc, padded_allocate_handler), DLD(scalable_aligned_free, padded_free_handler), }; #if TBB_USE_DEBUG #define DEBUG_SUFFIX "_debug" #else #define DEBUG_SUFFIX #endif /* TBB_USE_DEBUG */ // MALLOCLIB_NAME is the name of the TBB memory allocator library. #if _WIN32||_WIN64 #define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll" #elif __APPLE__ #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".dylib" #elif __FreeBSD__ || __NetBSD__ || __sun || _AIX || __ANDROID__ #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so" #elif __linux__ // Note that order of these #elif's is important! #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX __TBB_STRING(.so.TBB_COMPATIBLE_INTERFACE_VERSION) #else #error Unknown OS #endif //! Initialize the allocation/free handler pointers. /** Caller is responsible for ensuring this routine is called exactly once. The routine attempts to dynamically link with the TBB memory allocator. If that allocator is not found, it links to malloc and free. */ void initialize_handler_pointers() { __TBB_ASSERT( MallocHandler==&DummyMalloc, NULL ); bool success = dynamic_link( MALLOCLIB_NAME, MallocLinkTable, 4 ); if( !success ) { // If unsuccessful, set the handlers to the default routines. // This must be done now, and not before FillDynamicLinks runs, because if other // threads call the handlers, we want them to go through the DoOneTimeInitializations logic, // which forces them to wait. FreeHandler = &free; MallocHandler = &malloc; padded_allocate_handler = &padded_allocate; padded_free_handler = &padded_free; } #if !__TBB_RML_STATIC PrintExtraVersionInfo( "ALLOCATOR", success?"scalable_malloc":"malloc" ); #endif } static tbb::atomic initialization_state; void initialize_cache_aligned_allocator() { atomic_do_once( &initialize_handler_pointers, initialization_state ); } //! Executed on very first call through MallocHandler static void* DummyMalloc( size_t size ) { initialize_cache_aligned_allocator(); __TBB_ASSERT( MallocHandler!=&DummyMalloc, NULL ); return (*MallocHandler)( size ); } //! Executed on very first call through FreeHandler static void DummyFree( void * ptr ) { initialize_cache_aligned_allocator(); __TBB_ASSERT( FreeHandler!=&DummyFree, NULL ); (*FreeHandler)( ptr ); } //! Executed on very first call through padded_allocate_handler static void* dummy_padded_allocate( size_t bytes, size_t alignment ) { initialize_cache_aligned_allocator(); __TBB_ASSERT( padded_allocate_handler!=&dummy_padded_allocate, NULL ); return (*padded_allocate_handler)(bytes, alignment); } //! Executed on very first call through padded_free_handler static void dummy_padded_free( void * ptr ) { initialize_cache_aligned_allocator(); __TBB_ASSERT( padded_free_handler!=&dummy_padded_free, NULL ); (*padded_free_handler)( ptr ); } static size_t NFS_LineSize = 128; size_t NFS_GetLineSize() { return NFS_LineSize; } #if _MSC_VER && !defined(__INTEL_COMPILER) // unary minus operator applied to unsigned type, result still unsigned #pragma warning( disable: 4146 4706 ) #endif void* NFS_Allocate( size_t n, size_t element_size, void* /*hint*/ ) { size_t m = NFS_LineSize; __TBB_ASSERT( m<=NFS_MaxLineSize, "illegal value for NFS_LineSize" ); __TBB_ASSERT( (m & (m-1))==0, "must be power of two" ); size_t bytes = n*element_size; if (bytes=0x4096, "attempt to free block not obtained from cache_aligned_allocator" ); // Recover where block actually starts unsigned char* base = ((unsigned char**)p)[-1]; __TBB_ASSERT( (void*)((uintptr_t)(base+NFS_LineSize)&-NFS_LineSize)==p, "not allocated by NFS_Allocate?" ); free(base); } } void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n ) { void* result = (*MallocHandler) (n); if (!result) { throw_exception(eid_bad_alloc); } return result; } void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p ) { if( p ) { (*FreeHandler)( p ); } } bool __TBB_EXPORTED_FUNC is_malloc_used_v3() { if (MallocHandler == &DummyMalloc) { void* void_ptr = (*MallocHandler)(1); (*FreeHandler)(void_ptr); } __TBB_ASSERT( MallocHandler!=&DummyMalloc && FreeHandler!=&DummyFree, NULL ); // Cast to void avoids type mismatch errors on some compilers (e.g. __IBMCPP__) __TBB_ASSERT( !(((void*)MallocHandler==(void*)&malloc) ^ ((void*)FreeHandler==(void*)&free)), "Both shim pointers must refer to routines from the same package (either TBB or CRT)" ); return (void*)MallocHandler == (void*)&malloc; } } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/cache_aligned_allocator.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_cache_aligned_allocator_H #define __TBB_cache_aligned_allocator_H #include #include "tbb_stddef.h" #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #include // std::forward #endif namespace tbb { //! @cond INTERNAL namespace internal { //! Cache/sector line size. /** @ingroup memory_allocation */ size_t __TBB_EXPORTED_FUNC NFS_GetLineSize(); //! Allocate memory on cache/sector line boundary. /** @ingroup memory_allocation */ void* __TBB_EXPORTED_FUNC NFS_Allocate( size_t n_element, size_t element_size, void* hint ); //! Free memory allocated by NFS_Allocate. /** Freeing a NULL pointer is allowed, but has no effect. @ingroup memory_allocation */ void __TBB_EXPORTED_FUNC NFS_Free( void* ); } //! @endcond #if _MSC_VER && !defined(__INTEL_COMPILER) // Workaround for erroneous "unreferenced parameter" warning in method destroy. #pragma warning (push) #pragma warning (disable: 4100) #endif //! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 /** The members are ordered the same way they are in section 20.4.1 of the ISO C++ standard. @ingroup memory_allocation */ template class cache_aligned_allocator { public: typedef typename internal::allocator_type::value_type value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef cache_aligned_allocator other; }; cache_aligned_allocator() throw() {} cache_aligned_allocator( const cache_aligned_allocator& ) throw() {} template cache_aligned_allocator(const cache_aligned_allocator&) throw() {} pointer address(reference x) const {return &x;} const_pointer address(const_reference x) const {return &x;} //! Allocate space for n objects, starting on a cache/sector line. pointer allocate( size_type n, const void* hint=0 ) { // The "hint" argument is always ignored in NFS_Allocate thus const_cast shouldn't hurt return pointer(internal::NFS_Allocate( n, sizeof(value_type), const_cast(hint) )); } //! Free block of memory that starts on a cache line void deallocate( pointer p, size_type ) { internal::NFS_Free(p); } //! Largest value for which method allocate might succeed. size_type max_size() const throw() { return (~size_t(0)-internal::NFS_MaxLineSize)/sizeof(value_type); } //! Copy-construct value at location pointed to by p. #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC template void construct(U *p, Args&&... args) { ::new((void *)p) U(std::forward(args)...); } #else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #if __TBB_CPP11_RVALUE_REF_PRESENT void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));} #endif void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} #endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC //! Destroy value at location pointed to by p. void destroy( pointer p ) {p->~value_type();} }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4100 is back //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ template<> class cache_aligned_allocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef cache_aligned_allocator other; }; }; template inline bool operator==( const cache_aligned_allocator&, const cache_aligned_allocator& ) {return true;} template inline bool operator!=( const cache_aligned_allocator&, const cache_aligned_allocator& ) {return false;} } // namespace tbb #endif /* __TBB_cache_aligned_allocator_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/cilk-tbb-interop.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* The API to enable interoperability between Intel(R) Cilk(TM) Plus and Intel(R) Threading Building Blocks. */ #ifndef CILK_TBB_INTEROP_H #define CILK_TBB_INTEROP_H #ifndef _WIN32 #ifdef IN_CILK_RUNTIME #define CILK_EXPORT __attribute__((visibility("protected"))) #else #define CILK_EXPORT /* nothing */ #endif #else #ifdef IN_CILK_RUNTIME #define CILK_EXPORT __declspec(dllexport) #else #define CILK_EXPORT __declspec(dllimport) #endif // IN_CILK_RUNTIME #endif // _WIN32 #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* A return code. 0 indicates success */ typedef int __cilk_tbb_retcode; enum __cilk_tbb_stack_op { CILK_TBB_STACK_ORPHAN, // disconnecting stack from a thread CILK_TBB_STACK_ADOPT, // reconnecting orphaned stack to a trhead CILK_TBB_STACK_RELEASE // releasing stack }; typedef __cilk_tbb_retcode (*__cilk_tbb_pfn_stack_op)(enum __cilk_tbb_stack_op, void* data); typedef __cilk_tbb_retcode (*__cilk_tbb_pfn_unwatch_stacks)(void *data); /* Each thunk structure has two pointers: "routine" and "data". The caller of the thunk invokes *routine, passing "data" as the void* parameter. */ /* Thunk invoked by Intel Cilk Plus runtime (cilkrts) when it changes the relationship between a stack and a thread. It does not matter what stack the thunk runs on. The thread (not fiber) on which the thunk runs is important. CILK_TBB_STACK_ORPHAN The thunk must be invoked on the thread disconnecting itself from the stack. Must "happen before" the stack is adopted elsewhere. CILK_TBB_STACK_ADOPT The thunk must be invoked on the thread adopting the stack. CILK_TBB_STACK_RELEASE The thunk must be invoked on the thread doing the releasing, Must "happen before" the stack is used elsewhere. When a non-empty stack is transfered between threads, the first thread must orphan it and the second thread must adopt it. An empty stack can be transfered similarly, or simply released by the first thread. Here is a summary of the actions as transitions on a state machine. watch ORPHAN -->--> -->-- / \ / \ (freed empty stack) (TBB sees stack running on thread) (stack in limbo) | \ / \ / | | --<-- --<-- | ^ RELEASE or ADOPT V \ unwatch / \ / --------------------------<--------------------------- RELEASE */ struct __cilk_tbb_stack_op_thunk { __cilk_tbb_pfn_stack_op routine; void* data; /* Set by TBB */ }; /* Thunk invoked by TBB when it is no longer interested in watching the stack bound to the current thread. */ struct __cilk_tbb_unwatch_thunk { __cilk_tbb_pfn_unwatch_stacks routine; void* data; }; /* Defined by cilkrts, called by TBB. Requests that cilkrts invoke __cilk_tbb_stack_op_thunk when it orphans a stack. cilkrts sets *u to a thunk that TBB should call when it is no longer interested in watching the stack. */ CILK_EXPORT __cilk_tbb_retcode __cilkrts_watch_stack(struct __cilk_tbb_unwatch_thunk* u, struct __cilk_tbb_stack_op_thunk o); #ifdef __cplusplus } #endif /* __cplusplus */ #endif // CILK_TBB_INTEROP_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/combinable.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_combinable_H #define __TBB_combinable_H #include "enumerable_thread_specific.h" #include "cache_aligned_allocator.h" namespace tbb { /** \name combinable **/ //@{ //! Thread-local storage with optional reduction /** @ingroup containers */ template class combinable { private: typedef typename tbb::cache_aligned_allocator my_alloc; typedef typename tbb::enumerable_thread_specific my_ets_type; my_ets_type my_ets; public: combinable() { } template combinable( finit _finit) : my_ets(_finit) { } //! destructor ~combinable() { } combinable(const combinable& other) : my_ets(other.my_ets) { } combinable & operator=( const combinable & other) { my_ets = other.my_ets; return *this; } void clear() { my_ets.clear(); } T& local() { return my_ets.local(); } T& local(bool & exists) { return my_ets.local(exists); } // combine_func_t has signature T(T,T) or T(const T&, const T&) template T combine(combine_func_t f_combine) { return my_ets.combine(f_combine); } // combine_func_t has signature void(T) or void(const T&) template void combine_each(combine_func_t f_combine) { my_ets.combine_each(f_combine); } }; } // namespace tbb #endif /* __TBB_combinable_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/compat/condition_variable ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_condition_variable_H #define __TBB_condition_variable_H #if _WIN32||_WIN64 #include "../machine/windows_api.h" namespace tbb { namespace interface5 { namespace internal { struct condition_variable_using_event { //! Event for blocking waiting threads. HANDLE event; //! Protects invariants involving n_waiters, release_count, and epoch. CRITICAL_SECTION mutex; //! Number of threads waiting on this condition variable int n_waiters; //! Number of threads remaining that should no longer wait on this condition variable. int release_count; //! To keep threads from waking up prematurely with earlier signals. unsigned epoch; }; }}} // namespace tbb::interface5::internal #ifndef CONDITION_VARIABLE_INIT typedef void* CONDITION_VARIABLE; typedef CONDITION_VARIABLE* PCONDITION_VARIABLE; #endif #else /* if not _WIN32||_WIN64 */ #include // some systems need it for ETIMEDOUT #include #if __linux__ #include #else /* generic Unix */ #include #endif #endif /* _WIN32||_WIN64 */ #include "../tbb_stddef.h" #include "../mutex.h" #include "../tbb_thread.h" #include "../tbb_exception.h" #include "../tbb_profiling.h" namespace tbb { namespace interface5 { // C++0x standard working draft 30.4.3 // Lock tag types struct defer_lock_t { }; //! do not acquire ownership of the mutex struct try_to_lock_t { }; //! try to acquire ownership of the mutex without blocking struct adopt_lock_t { }; //! assume the calling thread has already const defer_lock_t defer_lock = {}; const try_to_lock_t try_to_lock = {}; const adopt_lock_t adopt_lock = {}; // C++0x standard working draft 30.4.3.1 //! lock_guard template class lock_guard : tbb::internal::no_copy { public: //! mutex type typedef M mutex_type; //! Constructor /** precondition: If mutex_type is not a recursive mutex, the calling thread does not own the mutex m. */ explicit lock_guard(mutex_type& m) : pm(m) {m.lock();} //! Adopt_lock constructor /** precondition: the calling thread owns the mutex m. */ lock_guard(mutex_type& m, adopt_lock_t) : pm(m) {} //! Destructor ~lock_guard() { pm.unlock(); } private: mutex_type& pm; }; // C++0x standard working draft 30.4.3.2 //! unique_lock template class unique_lock : tbb::internal::no_copy { friend class condition_variable; public: typedef M mutex_type; // 30.4.3.2.1 construct/copy/destroy // NB: Without constructors that take an r-value reference to a unique_lock, the following constructor is of little use. //! Constructor /** postcondition: pm==0 && owns==false */ unique_lock() : pm(NULL), owns(false) {} //! Constructor /** precondition: if mutex_type is not a recursive mutex, the calling thread does not own the mutex m. If the precondition is not met, a deadlock occurs. postcondition: pm==&m and owns==true */ explicit unique_lock(mutex_type& m) : pm(&m) {m.lock(); owns=true;} //! Defer_lock constructor /** postcondition: pm==&m and owns==false */ unique_lock(mutex_type& m, defer_lock_t) : pm(&m), owns(false) {} //! Try_to_lock constructor /** precondition: if mutex_type is not a recursive mutex, the calling thread does not own the mutex m. If the precondition is not met, a deadlock occurs. postcondition: pm==&m and owns==res where res is the value returned by the call to m.try_lock(). */ unique_lock(mutex_type& m, try_to_lock_t) : pm(&m) {owns = m.try_lock();} //! Adopt_lock constructor /** precondition: the calling thread owns the mutex. If it does not, mutex->unlock() would fail. postcondition: pm==&m and owns==true */ unique_lock(mutex_type& m, adopt_lock_t) : pm(&m), owns(true) {} //! Timed unique_lock acquisition. /** To avoid requiring support for namespace chrono, this method deviates from the working draft in that it uses tbb::tick_count::interval_t to specify the time duration. */ unique_lock(mutex_type& m, const tick_count::interval_t &i) : pm(&m) {owns = try_lock_for( i );} //! Destructor ~unique_lock() { if( owns ) pm->unlock(); } // 30.4.3.2.2 locking //! Lock the mutex and own it. void lock() { if( pm ) { if( !owns ) { pm->lock(); owns = true; } else throw_exception_v4( tbb::internal::eid_possible_deadlock ); } else throw_exception_v4( tbb::internal::eid_operation_not_permitted ); __TBB_ASSERT( owns, NULL ); } //! Try to lock the mutex. /** If successful, note that this lock owns it. Otherwise, set it false. */ bool try_lock() { if( pm ) { if( !owns ) owns = pm->try_lock(); else throw_exception_v4( tbb::internal::eid_possible_deadlock ); } else throw_exception_v4( tbb::internal::eid_operation_not_permitted ); return owns; } //! Try to lock the mutex. bool try_lock_for( const tick_count::interval_t &i ); //! Unlock the mutex /** And note that this lock no longer owns it. */ void unlock() { if( owns ) { pm->unlock(); owns = false; } else throw_exception_v4( tbb::internal::eid_operation_not_permitted ); __TBB_ASSERT( !owns, NULL ); } // 30.4.3.2.3 modifiers //! Swap the two unique locks void swap(unique_lock& u) { mutex_type* t_pm = u.pm; u.pm = pm; pm = t_pm; bool t_owns = u.owns; u.owns = owns; owns = t_owns; } //! Release control over the mutex. mutex_type* release() { mutex_type* o_pm = pm; pm = NULL; owns = false; return o_pm; } // 30.4.3.2.4 observers //! Does this lock own the mutex? bool owns_lock() const { return owns; } // TODO: Un-comment 'explicit' when the last non-C++0x compiler support is dropped //! Does this lock own the mutex? /*explicit*/ operator bool() const { return owns; } //! Return the mutex that this lock currently has. mutex_type* mutex() const { return pm; } private: mutex_type* pm; bool owns; }; template bool unique_lock::try_lock_for( const tick_count::interval_t &i) { const int unique_lock_tick = 100; /* microseconds; 0.1 milliseconds */ // the smallest wait-time is 0.1 milliseconds. bool res = pm->try_lock(); int duration_in_micro; if( !res && (duration_in_micro=int(i.seconds()*1e6))>unique_lock_tick ) { tick_count::interval_t i_100( double(unique_lock_tick)/1e6 /* seconds */); // 100 microseconds = 0.1*10E-3 do { this_tbb_thread::sleep(i_100); // sleep for 100 micro seconds duration_in_micro -= unique_lock_tick; res = pm->try_lock(); } while( !res && duration_in_micro>unique_lock_tick ); } return (owns=res); } //! Swap the two unique locks that have the mutexes of same type template void swap(unique_lock& x, unique_lock& y) { x.swap( y ); } namespace internal { #if _WIN32||_WIN64 union condvar_impl_t { condition_variable_using_event cv_event; CONDITION_VARIABLE cv_native; }; void __TBB_EXPORTED_FUNC internal_initialize_condition_variable( condvar_impl_t& cv ); void __TBB_EXPORTED_FUNC internal_destroy_condition_variable( condvar_impl_t& cv ); void __TBB_EXPORTED_FUNC internal_condition_variable_notify_one( condvar_impl_t& cv ); void __TBB_EXPORTED_FUNC internal_condition_variable_notify_all( condvar_impl_t& cv ); bool __TBB_EXPORTED_FUNC internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx, const tick_count::interval_t* i = NULL ); #else /* if !(_WIN32||_WIN64), i.e., POSIX threads */ typedef pthread_cond_t condvar_impl_t; #endif } // namespace internal //! cv_status /** C++0x standard working draft 30.5 */ enum cv_status { no_timeout, timeout }; //! condition variable /** C++0x standard working draft 30.5.1 @ingroup synchronization */ class condition_variable : tbb::internal::no_copy { public: //! Constructor condition_variable() { #if _WIN32||_WIN64 internal_initialize_condition_variable( my_cv ); #else pthread_cond_init( &my_cv, NULL ); #endif } //! Destructor ~condition_variable() { //precondition: There shall be no thread blocked on *this. #if _WIN32||_WIN64 internal_destroy_condition_variable( my_cv ); #else pthread_cond_destroy( &my_cv ); #endif } //! Notify one thread and wake it up void notify_one() { #if _WIN32||_WIN64 internal_condition_variable_notify_one( my_cv ); #else pthread_cond_signal( &my_cv ); #endif } //! Notify all threads void notify_all() { #if _WIN32||_WIN64 internal_condition_variable_notify_all( my_cv ); #else pthread_cond_broadcast( &my_cv ); #endif } //! Release the mutex associated with the lock and wait on this condition variable void wait(unique_lock& lock); //! Wait on this condition variable while pred is false template void wait(unique_lock& lock, Predicate pred) { while( !pred() ) wait( lock ); } //! Timed version of wait() cv_status wait_for(unique_lock& lock, const tick_count::interval_t &i ); //! Timed version of the predicated wait /** The loop terminates when pred() returns true or when the time duration specified by rel_time (i) has elapsed. */ template bool wait_for(unique_lock& lock, const tick_count::interval_t &i, Predicate pred) { while( !pred() ) { cv_status st = wait_for( lock, i ); if( st==timeout ) return pred(); } return true; } // C++0x standard working draft. 30.2.3 typedef internal::condvar_impl_t* native_handle_type; native_handle_type native_handle() { return (native_handle_type) &my_cv; } private: internal::condvar_impl_t my_cv; }; #if _WIN32||_WIN64 inline void condition_variable::wait( unique_lock& lock ) { __TBB_ASSERT( lock.owns, NULL ); lock.owns = false; if( !internal_condition_variable_wait( my_cv, lock.mutex() ) ) { int ec = GetLastError(); // on Windows 7, SleepConditionVariableCS() may return ERROR_TIMEOUT while the doc says it returns WAIT_TIMEOUT __TBB_ASSERT_EX( ec!=WAIT_TIMEOUT&&ec!=ERROR_TIMEOUT, NULL ); lock.owns = true; throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); } lock.owns = true; } inline cv_status condition_variable::wait_for( unique_lock& lock, const tick_count::interval_t& i ) { cv_status rc = no_timeout; __TBB_ASSERT( lock.owns, NULL ); lock.owns = false; // condvar_wait could be SleepConditionVariableCS (or SleepConditionVariableSRW) or our own pre-vista cond_var_wait() if( !internal_condition_variable_wait( my_cv, lock.mutex(), &i ) ) { int ec = GetLastError(); if( ec==WAIT_TIMEOUT || ec==ERROR_TIMEOUT ) rc = timeout; else { lock.owns = true; throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); } } lock.owns = true; return rc; } #else /* !(_WIN32||_WIN64) */ inline void condition_variable::wait( unique_lock& lock ) { __TBB_ASSERT( lock.owns, NULL ); lock.owns = false; if( pthread_cond_wait( &my_cv, lock.mutex()->native_handle() ) ) { lock.owns = true; throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); } // upon successful return, the mutex has been locked and is owned by the calling thread. lock.owns = true; } inline cv_status condition_variable::wait_for( unique_lock& lock, const tick_count::interval_t& i ) { #if __linux__ struct timespec req; double sec = i.seconds(); clock_gettime( CLOCK_REALTIME, &req ); req.tv_sec += static_cast(sec); req.tv_nsec += static_cast( (sec - static_cast(sec))*1e9 ); #else /* generic Unix */ struct timeval tv; struct timespec req; double sec = i.seconds(); int status = gettimeofday(&tv, NULL); __TBB_ASSERT_EX( status==0, "gettimeofday failed" ); req.tv_sec = tv.tv_sec + static_cast(sec); req.tv_nsec = tv.tv_usec*1000 + static_cast( (sec - static_cast(sec))*1e9 ); #endif /*(choice of OS) */ if( req.tv_nsec>=1e9 ) { req.tv_sec += 1; req.tv_nsec -= static_cast(1e9); } __TBB_ASSERT( 0<=req.tv_nsec && req.tv_nsec<1e9, NULL ); int ec; cv_status rc = no_timeout; __TBB_ASSERT( lock.owns, NULL ); lock.owns = false; if( ( ec=pthread_cond_timedwait( &my_cv, lock.mutex()->native_handle(), &req ) ) ) { if( ec==ETIMEDOUT ) rc = timeout; else { __TBB_ASSERT( lock.try_lock()==false, NULL ); lock.owns = true; throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); } } lock.owns = true; return rc; } #endif /* !(_WIN32||_WIN64) */ } // namespace interface5 __TBB_DEFINE_PROFILING_SET_NAME(interface5::condition_variable) } // namespace tbb #if TBB_IMPLEMENT_CPP0X namespace std { using tbb::interface5::defer_lock_t; using tbb::interface5::try_to_lock_t; using tbb::interface5::adopt_lock_t; using tbb::interface5::defer_lock; using tbb::interface5::try_to_lock; using tbb::interface5::adopt_lock; using tbb::interface5::lock_guard; using tbb::interface5::unique_lock; using tbb::interface5::swap; /* this is for void std::swap(unique_lock&,unique_lock&) */ using tbb::interface5::condition_variable; using tbb::interface5::cv_status; using tbb::interface5::timeout; using tbb::interface5::no_timeout; } // namespace std #endif /* TBB_IMPLEMENT_CPP0X */ #endif /* __TBB_condition_variable_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/compat/ppl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_compat_ppl_H #define __TBB_compat_ppl_H #include "../task_group.h" #include "../parallel_invoke.h" #include "../parallel_for_each.h" #include "../parallel_for.h" #include "../tbb_exception.h" #include "../critical_section.h" #include "../reader_writer_lock.h" #include "../combinable.h" namespace Concurrency { #if __TBB_TASK_GROUP_CONTEXT using tbb::task_handle; using tbb::task_group_status; using tbb::task_group; using tbb::structured_task_group; using tbb::invalid_multiple_scheduling; using tbb::missing_wait; using tbb::make_task; using tbb::not_complete; using tbb::complete; using tbb::canceled; using tbb::is_current_task_group_canceling; #endif /* __TBB_TASK_GROUP_CONTEXT */ using tbb::parallel_invoke; using tbb::strict_ppl::parallel_for; using tbb::parallel_for_each; using tbb::critical_section; using tbb::reader_writer_lock; using tbb::combinable; using tbb::improper_lock; } // namespace Concurrency #endif /* __TBB_compat_ppl_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/compat/thread ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_thread_H #define __TBB_thread_H #include "../tbb_thread.h" #if TBB_IMPLEMENT_CPP0X namespace std { typedef tbb::tbb_thread thread; namespace this_thread { using tbb::this_tbb_thread::get_id; using tbb::this_tbb_thread::yield; inline void sleep_for(const tbb::tick_count::interval_t& rel_time) { tbb::internal::thread_sleep_v3( rel_time ); } } } #endif /* TBB_IMPLEMENT_CPP0X */ #endif /* __TBB_thread_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/compat/tuple ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tuple_H #define __TBB_tuple_H #include #include "../tbb_stddef.h" // build preprocessor variables for varying number of arguments // Need the leading comma so the empty __TBB_T_PACK will not cause a syntax error. #if __TBB_VARIADIC_MAX <= 5 #define __TBB_T_PACK #define __TBB_U_PACK #define __TBB_TYPENAME_T_PACK #define __TBB_TYPENAME_U_PACK #define __TBB_NULL_TYPE_PACK #define __TBB_REF_T_PARAM_PACK #define __TBB_CONST_REF_T_PARAM_PACK #define __TBB_T_PARAM_LIST_PACK #define __TBB_CONST_NULL_REF_PACK // #elif __TBB_VARIADIC_MAX == 6 #define __TBB_T_PACK ,__T5 #define __TBB_U_PACK ,__U5 #define __TBB_TYPENAME_T_PACK , typename __T5 #define __TBB_TYPENAME_U_PACK , typename __U5 #define __TBB_NULL_TYPE_PACK , null_type #define __TBB_REF_T_PARAM_PACK ,__T5& t5 #define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5 #define __TBB_T_PARAM_LIST_PACK ,t5 #define __TBB_CONST_NULL_REF_PACK , const null_type& // #elif __TBB_VARIADIC_MAX == 7 #define __TBB_T_PACK ,__T5, __T6 #define __TBB_U_PACK ,__U5, __U6 #define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6 #define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6 #define __TBB_NULL_TYPE_PACK , null_type, null_type #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6 #define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5, const __T6& t6 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type& // #elif __TBB_VARIADIC_MAX == 8 #define __TBB_T_PACK ,__T5, __T6, __T7 #define __TBB_U_PACK ,__U5, __U6, __U7 #define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6, typename __T7 #define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6, typename __U7 #define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7 #define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type& // #elif __TBB_VARIADIC_MAX == 9 #define __TBB_T_PACK ,__T5, __T6, __T7, __T8 #define __TBB_U_PACK ,__U5, __U6, __U7, __U8 #define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8 #define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8 #define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8 #define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type& // #elif __TBB_VARIADIC_MAX >= 10 #define __TBB_T_PACK ,__T5, __T6, __T7, __T8, __T9 #define __TBB_U_PACK ,__U5, __U6, __U7, __U8, __U9 #define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8, typename __T9 #define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8, typename __U9 #define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type, null_type #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8, __T9& t9 #define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8, const __T9& t9 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 ,t9 #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type&, const null_type& #endif namespace tbb { namespace interface5 { namespace internal { struct null_type { }; } using internal::null_type; // tuple forward declaration template = 6 , typename __T5=null_type #if __TBB_VARIADIC_MAX >= 7 , typename __T6=null_type #if __TBB_VARIADIC_MAX >= 8 , typename __T7=null_type #if __TBB_VARIADIC_MAX >= 9 , typename __T8=null_type #if __TBB_VARIADIC_MAX >= 10 , typename __T9=null_type #endif #endif #endif #endif #endif > class tuple; namespace internal { // const null_type temp inline const null_type cnull() { return null_type(); } // cons forward declaration template struct cons; // type of a component of the cons template struct component { typedef typename __T::tail_type next; typedef typename component<__N-1,next>::type type; }; template struct component<0,__T> { typedef typename __T::head_type type; }; template<> struct component<0,null_type> { typedef null_type type; }; // const version of component template struct component<__N, const __T> { typedef typename __T::tail_type next; typedef const typename component<__N-1,next>::type type; }; template struct component<0, const __T> { typedef const typename __T::head_type type; }; // helper class for getting components of cons template< int __N> struct get_helper { template inline static typename component<__N, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) { return get_helper<__N-1>::get(ti.tail); } template inline static typename component<__N, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) { return get_helper<__N-1>::get(ti.tail); } }; template<> struct get_helper<0> { template inline static typename component<0, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) { return ti.head; } template inline static typename component<0, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) { return ti.head; } }; // traits adaptor template struct tuple_traits { typedef cons <__T0, typename tuple_traits<__T1, __T2, __T3, __T4 __TBB_T_PACK , null_type>::U > U; }; template struct tuple_traits<__T0, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > { typedef cons<__T0, null_type> U; }; template<> struct tuple_traits { typedef null_type U; }; // core cons defs template struct cons{ typedef __HT head_type; typedef __TT tail_type; head_type head; tail_type tail; static const int length = 1 + tail_type::length; // default constructors explicit cons() : head(), tail() { } // non-default constructors cons(head_type& h, const tail_type& t) : head(h), tail(t) { } template cons(const __T0& t0, const __T1& t1, const __T2& t2, const __T3& t3, const __T4& t4 __TBB_CONST_REF_T_PARAM_PACK) : head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK, cnull()) { } template cons(__T0& t0, __T1& t1, __T2& t2, __T3& t3, __T4& t4 __TBB_REF_T_PARAM_PACK) : head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK , cnull()) { } template cons(const cons<__HT1,__TT1>& other) : head(other.head), tail(other.tail) { } cons& operator=(const cons& other) { head = other.head; tail = other.tail; return *this; } friend bool operator==(const cons& me, const cons& other) { return me.head == other.head && me.tail == other.tail; } friend bool operator<(const cons& me, const cons& other) { return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); } friend bool operator>(const cons& me, const cons& other) { return other=(const cons& me, const cons& other) { return !(meother); } template friend bool operator==(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return me.head == other.head && me.tail == other.tail; } template friend bool operator<(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); } template friend bool operator>(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return other friend bool operator!=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me==other); } template friend bool operator>=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me friend bool operator<=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me>other); } }; // cons template struct cons<__HT,null_type> { typedef __HT head_type; typedef null_type tail_type; head_type head; static const int length = 1; // default constructor cons() : head() { /*std::cout << "default constructor 1\n";*/ } cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head() { /*std::cout << "default constructor 2\n";*/ } // non-default constructor template cons(__T1& t1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t1) { /*std::cout << "non-default a1, t1== " << t1 << "\n";*/} cons(head_type& h, const null_type& = null_type() ) : head(h) { } cons(const head_type& t0, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t0) { } // converting constructor template cons(__HT1 h1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(h1) { } // copy constructor template cons( const cons<__HT1, null_type>& other) : head(other.head) { } // assignment operator cons& operator=(const cons& other) { head = other.head; return *this; } friend bool operator==(const cons& me, const cons& other) { return me.head == other.head; } friend bool operator<(const cons& me, const cons& other) { return me.head < other.head; } friend bool operator>(const cons& me, const cons& other) { return otherother); } friend bool operator>=(const cons& me, const cons& other) {return !(me friend bool operator==(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return me.head == other.head; } template friend bool operator<(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return me.head < other.head; } template friend bool operator>(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return other friend bool operator!=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me==other); } template friend bool operator<=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me>other); } template friend bool operator>=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me struct cons { typedef null_type tail_type; static const int length = 0; }; // wrapper for default constructor template inline const __T wrap_dcons(__T*) { return __T(); } } // namespace internal // tuple definition template class tuple : public internal::tuple_traits<__T0, __T1, __T2, __T3, __T4 __TBB_T_PACK >::U { // friends template friend class tuple_size; template friend struct tuple_element; // stl components typedef tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > value_type; typedef value_type *pointer; typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; typedef size_t size_type; typedef typename internal::tuple_traits<__T0,__T1,__T2,__T3, __T4 __TBB_T_PACK >::U my_cons; public: tuple(const __T0& t0=internal::wrap_dcons((__T0*)NULL) ,const __T1& t1=internal::wrap_dcons((__T1*)NULL) ,const __T2& t2=internal::wrap_dcons((__T2*)NULL) ,const __T3& t3=internal::wrap_dcons((__T3*)NULL) ,const __T4& t4=internal::wrap_dcons((__T4*)NULL) #if __TBB_VARIADIC_MAX >= 6 ,const __T5& t5=internal::wrap_dcons((__T5*)NULL) #if __TBB_VARIADIC_MAX >= 7 ,const __T6& t6=internal::wrap_dcons((__T6*)NULL) #if __TBB_VARIADIC_MAX >= 8 ,const __T7& t7=internal::wrap_dcons((__T7*)NULL) #if __TBB_VARIADIC_MAX >= 9 ,const __T8& t8=internal::wrap_dcons((__T8*)NULL) #if __TBB_VARIADIC_MAX >= 10 ,const __T9& t9=internal::wrap_dcons((__T9*)NULL) #endif #endif #endif #endif #endif ) : my_cons(t0,t1,t2,t3,t4 __TBB_T_PARAM_LIST_PACK) { } template struct internal_tuple_element { typedef typename internal::component<__N,my_cons>::type type; }; template typename internal_tuple_element<__N>::type& get() { return internal::get_helper<__N>::get(*this); } template typename internal_tuple_element<__N>::type const& get() const { return internal::get_helper<__N>::get(*this); } template tuple& operator=(const internal::cons<__U1,__U2>& other) { my_cons::operator=(other); return *this; } template tuple& operator=(const std::pair<__U1,__U2>& other) { // __TBB_ASSERT(tuple_size::value == 2, "Invalid size for pair to tuple assignment"); this->head = other.first; this->tail.head = other.second; return *this; } friend bool operator==(const tuple& me, const tuple& other) {return static_cast(me)==(other);} friend bool operator<(const tuple& me, const tuple& other) {return static_cast(me)<(other);} friend bool operator>(const tuple& me, const tuple& other) {return static_cast(me)>(other);} friend bool operator!=(const tuple& me, const tuple& other) {return static_cast(me)!=(other);} friend bool operator>=(const tuple& me, const tuple& other) {return static_cast(me)>=(other);} friend bool operator<=(const tuple& me, const tuple& other) {return static_cast(me)<=(other);} }; // tuple // empty tuple template<> class tuple : public null_type { }; // helper classes template < typename __T> class tuple_size { public: static const size_t value = 1 + tuple_size::value; }; template <> class tuple_size > { public: static const size_t value = 0; }; template <> class tuple_size { public: static const size_t value = 0; }; template struct tuple_element { typedef typename internal::component<__N, typename __T::my_cons>::type type; }; template inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type& get(tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); } template inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type const& get(const tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); } } // interface5 } // tbb #if !__TBB_CPP11_TUPLE_PRESENT namespace tbb { namespace flow { using tbb::interface5::tuple; using tbb::interface5::tuple_size; using tbb::interface5::tuple_element; using tbb::interface5::get; } } #endif #undef __TBB_T_PACK #undef __TBB_U_PACK #undef __TBB_TYPENAME_T_PACK #undef __TBB_TYPENAME_U_PACK #undef __TBB_NULL_TYPE_PACK #undef __TBB_REF_T_PARAM_PACK #undef __TBB_CONST_REF_T_PARAM_PACK #undef __TBB_T_PARAM_LIST_PACK #undef __TBB_CONST_NULL_REF_PACK #endif /* __TBB_tuple_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_hash_map.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/concurrent_hash_map.h" namespace tbb { namespace internal { #if !TBB_NO_LEGACY struct hash_map_segment_base { typedef spin_rw_mutex segment_mutex_t; //! Type of a hash code. typedef size_t hashcode_t; //! Log2 of n_segment static const size_t n_segment_bits = 6; //! Maximum size of array of chains static const size_t max_physical_size = size_t(1)<<(8*sizeof(hashcode_t)-n_segment_bits); //! Mutex that protects this segment segment_mutex_t my_mutex; // Number of nodes atomic my_logical_size; // Size of chains /** Always zero or a power of two */ size_t my_physical_size; //! True if my_logical_size>=my_physical_size. /** Used to support Intel(R) Thread Checker. */ bool __TBB_EXPORTED_METHOD internal_grow_predicate() const; }; bool hash_map_segment_base::internal_grow_predicate() const { // Intel(R) Thread Checker considers the following reads to be races, so we hide them in the // library so that Intel(R) Thread Checker will ignore them. The reads are used in a double-check // context, so the program is nonetheless correct despite the race. return my_logical_size >= my_physical_size && my_physical_size < max_physical_size; } #endif//!TBB_NO_LEGACY } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_hash_map.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_concurrent_hash_map_H #define __TBB_concurrent_hash_map_H #include "tbb_stddef.h" #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #include // Need std::pair #include // Need std::memset #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif #include "cache_aligned_allocator.h" #include "tbb_allocator.h" #include "spin_rw_mutex.h" #include "atomic.h" #include "tbb_exception.h" #include "tbb_profiling.h" #include "internal/_concurrent_unordered_impl.h" // Need tbb_hasher #if __TBB_INITIALIZER_LISTS_PRESENT #include #endif #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS #include #endif #if __TBB_STATISTICS #include #endif namespace tbb { //! hash_compare that is default argument for concurrent_hash_map template struct tbb_hash_compare { static size_t hash( const Key& a ) { return tbb_hasher(a); } static bool equal( const Key& a, const Key& b ) { return a == b; } }; namespace interface5 { template, typename A = tbb_allocator > > class concurrent_hash_map; //! @cond INTERNAL namespace internal { using namespace tbb::internal; //! Type of a hash code. typedef size_t hashcode_t; //! Node base type struct hash_map_node_base : tbb::internal::no_copy { //! Mutex type typedef spin_rw_mutex mutex_t; //! Scoped lock type for mutex typedef mutex_t::scoped_lock scoped_t; //! Next node in chain hash_map_node_base *next; mutex_t mutex; }; //! Incompleteness flag value static hash_map_node_base *const rehash_req = reinterpret_cast(size_t(3)); //! Rehashed empty bucket flag static hash_map_node_base *const empty_rehashed = reinterpret_cast(size_t(0)); //! base class of concurrent_hash_map class hash_map_base { public: //! Size type typedef size_t size_type; //! Type of a hash code. typedef size_t hashcode_t; //! Segment index type typedef size_t segment_index_t; //! Node base type typedef hash_map_node_base node_base; //! Bucket type struct bucket : tbb::internal::no_copy { //! Mutex type for buckets typedef spin_rw_mutex mutex_t; //! Scoped lock type for mutex typedef mutex_t::scoped_lock scoped_t; mutex_t mutex; node_base *node_list; }; //! Count of segments in the first block static size_type const embedded_block = 1; //! Count of segments in the first block static size_type const embedded_buckets = 1< my_mask; //! Segment pointers table. Also prevents false sharing between my_mask and my_size segments_table_t my_table; //! Size of container in stored items atomic my_size; // It must be in separate cache line from my_mask due to performance effects //! Zero segment bucket my_embedded_segment[embedded_buckets]; #if __TBB_STATISTICS atomic my_info_resizes; // concurrent ones mutable atomic my_info_restarts; // race collisions atomic my_info_rehashes; // invocations of rehash_bucket #endif //! Constructor hash_map_base() { std::memset( this, 0, pointers_per_table*sizeof(segment_ptr_t) // 32*4=128 or 64*8=512 + sizeof(my_size) + sizeof(my_mask) // 4+4 or 8+8 + embedded_buckets*sizeof(bucket) ); // n*8 or n*16 for( size_type i = 0; i < embedded_block; i++ ) // fill the table my_table[i] = my_embedded_segment + segment_base(i); my_mask = embedded_buckets - 1; __TBB_ASSERT( embedded_block <= first_block, "The first block number must include embedded blocks"); #if __TBB_STATISTICS my_info_resizes = 0; // concurrent ones my_info_restarts = 0; // race collisions my_info_rehashes = 0; // invocations of rehash_bucket #endif } //! @return segment index of given index in the array static segment_index_t segment_index_of( size_type index ) { return segment_index_t( __TBB_Log2( index|1 ) ); } //! @return the first array index of given segment static segment_index_t segment_base( segment_index_t k ) { return (segment_index_t(1)<(ptr) > uintptr_t(63); } //! Initialize buckets static void init_buckets( segment_ptr_t ptr, size_type sz, bool is_initial ) { if( is_initial ) std::memset(ptr, 0, sz*sizeof(bucket) ); else for(size_type i = 0; i < sz; i++, ptr++) { *reinterpret_cast(&ptr->mutex) = 0; ptr->node_list = rehash_req; } } //! Add node @arg n to bucket @arg b static void add_to_bucket( bucket *b, node_base *n ) { __TBB_ASSERT(b->node_list != rehash_req, NULL); n->next = b->node_list; b->node_list = n; // its under lock and flag is set } //! Exception safety helper struct enable_segment_failsafe : tbb::internal::no_copy { segment_ptr_t *my_segment_ptr; enable_segment_failsafe(segments_table_t &table, segment_index_t k) : my_segment_ptr(&table[k]) {} ~enable_segment_failsafe() { if( my_segment_ptr ) *my_segment_ptr = 0; // indicate no allocation in progress } }; //! Enable segment void enable_segment( segment_index_t k, bool is_initial = false ) { __TBB_ASSERT( k, "Zero segment must be embedded" ); enable_segment_failsafe watchdog( my_table, k ); cache_aligned_allocator alloc; size_type sz; __TBB_ASSERT( !is_valid(my_table[k]), "Wrong concurrent assignment"); if( k >= first_block ) { sz = segment_size( k ); segment_ptr_t ptr = alloc.allocate( sz ); init_buckets( ptr, sz, is_initial ); itt_hide_store_word( my_table[k], ptr ); sz <<= 1;// double it to get entire capacity of the container } else { // the first block __TBB_ASSERT( k == embedded_block, "Wrong segment index" ); sz = segment_size( first_block ); segment_ptr_t ptr = alloc.allocate( sz - embedded_buckets ); init_buckets( ptr, sz - embedded_buckets, is_initial ); ptr -= segment_base(embedded_block); for(segment_index_t i = embedded_block; i < first_block; i++) // calc the offsets itt_hide_store_word( my_table[i], ptr + segment_base(i) ); } itt_store_word_with_release( my_mask, sz-1 ); watchdog.my_segment_ptr = 0; } //! Get bucket by (masked) hashcode bucket *get_bucket( hashcode_t h ) const throw() { // TODO: add throw() everywhere? segment_index_t s = segment_index_of( h ); h -= segment_base(s); segment_ptr_t seg = my_table[s]; __TBB_ASSERT( is_valid(seg), "hashcode must be cut by valid mask for allocated segments" ); return &seg[h]; } // internal serial rehashing helper void mark_rehashed_levels( hashcode_t h ) throw () { segment_index_t s = segment_index_of( h ); while( segment_ptr_t seg = my_table[++s] ) if( seg[h].node_list == rehash_req ) { seg[h].node_list = empty_rehashed; mark_rehashed_levels( h + ((hashcode_t)1<node_list) != rehash_req ) { #if __TBB_STATISTICS my_info_restarts++; // race collisions #endif return true; } } return false; } //! Insert a node and check for load factor. @return segment index to enable. segment_index_t insert_new_node( bucket *b, node_base *n, hashcode_t mask ) { size_type sz = ++my_size; // prefix form is to enforce allocation after the first item inserted add_to_bucket( b, n ); // check load factor if( sz >= mask ) { // TODO: add custom load_factor segment_index_t new_seg = __TBB_Log2( mask+1 ); //optimized segment_index_of __TBB_ASSERT( is_valid(my_table[new_seg-1]), "new allocations must not publish new mask until segment has allocated"); static const segment_ptr_t is_allocating = (segment_ptr_t)2; if( !itt_hide_load_word(my_table[new_seg]) && as_atomic(my_table[new_seg]).compare_and_swap(is_allocating, NULL) == NULL ) return new_seg; // The value must be processed } return 0; } //! Prepare enough segments for number of buckets void reserve(size_type buckets) { if( !buckets-- ) return; bool is_initial = !my_size; for( size_type m = my_mask; buckets > m; m = my_mask ) enable_segment( segment_index_of( m+1 ), is_initial ); } //! Swap hash_map_bases void internal_swap(hash_map_base &table) { using std::swap; swap(this->my_mask, table.my_mask); swap(this->my_size, table.my_size); for(size_type i = 0; i < embedded_buckets; i++) swap(this->my_embedded_segment[i].node_list, table.my_embedded_segment[i].node_list); for(size_type i = embedded_block; i < pointers_per_table; i++) swap(this->my_table[i], table.my_table[i]); } }; template class hash_map_range; //! Meets requirements of a forward iterator for STL */ /** Value is either the T or const T type of the container. @ingroup containers */ template class hash_map_iterator : public std::iterator { typedef Container map_type; typedef typename Container::node node; typedef hash_map_base::node_base node_base; typedef hash_map_base::bucket bucket; template friend bool operator==( const hash_map_iterator& i, const hash_map_iterator& j ); template friend bool operator!=( const hash_map_iterator& i, const hash_map_iterator& j ); template friend ptrdiff_t operator-( const hash_map_iterator& i, const hash_map_iterator& j ); template friend class hash_map_iterator; template friend class hash_map_range; void advance_to_next_bucket() { // TODO?: refactor to iterator_base class size_t k = my_index+1; while( my_bucket && k <= my_map->my_mask ) { // Following test uses 2's-complement wizardry if( k& (k-2) ) // not the beginning of a segment ++my_bucket; else my_bucket = my_map->get_bucket( k ); my_node = static_cast( my_bucket->node_list ); if( hash_map_base::is_valid(my_node) ) { my_index = k; return; } ++k; } my_bucket = 0; my_node = 0; my_index = k; // the end } #if !defined(_MSC_VER) || defined(__INTEL_COMPILER) template friend class interface5::concurrent_hash_map; #else public: // workaround #endif //! concurrent_hash_map over which we are iterating. const Container *my_map; //! Index in hash table for current item size_t my_index; //! Pointer to bucket const bucket *my_bucket; //! Pointer to node that has current item node *my_node; hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n ); public: //! Construct undefined iterator hash_map_iterator() {} hash_map_iterator( const hash_map_iterator &other ) : my_map(other.my_map), my_index(other.my_index), my_bucket(other.my_bucket), my_node(other.my_node) {} Value& operator*() const { __TBB_ASSERT( hash_map_base::is_valid(my_node), "iterator uninitialized or at end of container?" ); return my_node->item; } Value* operator->() const {return &operator*();} hash_map_iterator& operator++(); //! Post increment hash_map_iterator operator++(int) { hash_map_iterator old(*this); operator++(); return old; } }; template hash_map_iterator::hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n ) : my_map(&map), my_index(index), my_bucket(b), my_node( static_cast(n) ) { if( b && !hash_map_base::is_valid(n) ) advance_to_next_bucket(); } template hash_map_iterator& hash_map_iterator::operator++() { my_node = static_cast( my_node->next ); if( !my_node ) advance_to_next_bucket(); return *this; } template bool operator==( const hash_map_iterator& i, const hash_map_iterator& j ) { return i.my_node == j.my_node && i.my_map == j.my_map; } template bool operator!=( const hash_map_iterator& i, const hash_map_iterator& j ) { return i.my_node != j.my_node || i.my_map != j.my_map; } //! Range class used with concurrent_hash_map /** @ingroup containers */ template class hash_map_range { typedef typename Iterator::map_type map_type; Iterator my_begin; Iterator my_end; mutable Iterator my_midpoint; size_t my_grainsize; //! Set my_midpoint to point approximately half way between my_begin and my_end. void set_midpoint() const; template friend class hash_map_range; public: //! Type for size of a range typedef std::size_t size_type; typedef typename Iterator::value_type value_type; typedef typename Iterator::reference reference; typedef typename Iterator::difference_type difference_type; typedef Iterator iterator; //! True if range is empty. bool empty() const {return my_begin==my_end;} //! True if range can be partitioned into two subranges. bool is_divisible() const { return my_midpoint!=my_end; } //! Split range. hash_map_range( hash_map_range& r, split ) : my_end(r.my_end), my_grainsize(r.my_grainsize) { r.my_end = my_begin = r.my_midpoint; __TBB_ASSERT( !empty(), "Splitting despite the range is not divisible" ); __TBB_ASSERT( !r.empty(), "Splitting despite the range is not divisible" ); set_midpoint(); r.set_midpoint(); } //! type conversion template hash_map_range( hash_map_range& r) : my_begin(r.my_begin), my_end(r.my_end), my_midpoint(r.my_midpoint), my_grainsize(r.my_grainsize) {} //! Init range with container and grainsize specified hash_map_range( const map_type &map, size_type grainsize_ = 1 ) : my_begin( Iterator( map, 0, map.my_embedded_segment, map.my_embedded_segment->node_list ) ), my_end( Iterator( map, map.my_mask + 1, 0, 0 ) ), my_grainsize( grainsize_ ) { __TBB_ASSERT( grainsize_>0, "grainsize must be positive" ); set_midpoint(); } const Iterator& begin() const {return my_begin;} const Iterator& end() const {return my_end;} //! The grain size for this range. size_type grainsize() const {return my_grainsize;} }; template void hash_map_range::set_midpoint() const { // Split by groups of nodes size_t m = my_end.my_index-my_begin.my_index; if( m > my_grainsize ) { m = my_begin.my_index + m/2u; hash_map_base::bucket *b = my_begin.my_map->get_bucket(m); my_midpoint = Iterator(*my_begin.my_map,m,b,b->node_list); } else { my_midpoint = my_end; } __TBB_ASSERT( my_begin.my_index <= my_midpoint.my_index, "my_begin is after my_midpoint" ); __TBB_ASSERT( my_midpoint.my_index <= my_end.my_index, "my_midpoint is after my_end" ); __TBB_ASSERT( my_begin != my_midpoint || my_begin == my_end, "[my_begin, my_midpoint) range should not be empty" ); } } // internal //! @endcond #if _MSC_VER && !defined(__INTEL_COMPILER) // Suppress "conditional expression is constant" warning. #pragma warning( push ) #pragma warning( disable: 4127 ) #endif //! Unordered map from Key to T. /** concurrent_hash_map is associative container with concurrent access. @par Compatibility The class meets all Container Requirements from C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1). @par Exception Safety - Hash function is not permitted to throw an exception. User-defined types Key and T are forbidden from throwing an exception in destructors. - If exception happens during insert() operations, it has no effect (unless exception raised by HashCompare::hash() function during grow_segment). - If exception happens during operator=() operation, the container can have a part of source items, and methods size() and empty() can return wrong results. @par Changes since TBB 2.1 - Replaced internal algorithm and data structure. Patent is pending. - Added buckets number argument for constructor @par Changes since TBB 2.0 - Fixed exception-safety - Added template argument for allocator - Added allocator argument in constructors - Added constructor from a range of iterators - Added several new overloaded insert() methods - Added get_allocator() - Added swap() - Added count() - Added overloaded erase(accessor &) and erase(const_accessor&) - Added equal_range() [const] - Added [const_]pointer, [const_]reference, and allocator_type types - Added global functions: operator==(), operator!=(), and swap() @ingroup containers */ template class concurrent_hash_map : protected internal::hash_map_base { template friend class internal::hash_map_iterator; template friend class internal::hash_map_range; public: typedef Key key_type; typedef T mapped_type; typedef std::pair value_type; typedef hash_map_base::size_type size_type; typedef ptrdiff_t difference_type; typedef value_type *pointer; typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; typedef internal::hash_map_iterator iterator; typedef internal::hash_map_iterator const_iterator; typedef internal::hash_map_range range_type; typedef internal::hash_map_range const_range_type; typedef Allocator allocator_type; protected: friend class const_accessor; struct node; typedef typename Allocator::template rebind::other node_allocator_type; node_allocator_type my_allocator; HashCompare my_hash_compare; struct node : public node_base { value_type item; node( const Key &key ) : item(key, T()) {} node( const Key &key, const T &t ) : item(key, t) {} #if __TBB_CPP11_RVALUE_REF_PRESENT node( value_type&& i ) : item(std::move(i)){} #endif //__TBB_CPP11_RVALUE_REF_PRESENT node( const value_type& i ) : item(i) {} // exception-safe allocation, see C++ Standard 2003, clause 5.3.4p17 void *operator new( size_t /*size*/, node_allocator_type &a ) { void *ptr = a.allocate(1); if(!ptr) tbb::internal::throw_exception(tbb::internal::eid_bad_alloc); return ptr; } // match placement-new form above to be called if exception thrown in constructor void operator delete( void *ptr, node_allocator_type &a ) { a.deallocate(static_cast(ptr),1); } }; void delete_node( node_base *n ) { my_allocator.destroy( static_cast(n) ); my_allocator.deallocate( static_cast(n), 1); } static node* allocate_node_copy_construct(node_allocator_type& allocator, const Key &key, const T * t){ return new( allocator ) node(key, *t); } static node* allocate_node_default_construct(node_allocator_type& allocator, const Key &key, const T * ){ return new( allocator ) node(key); } static node* do_not_allocate_node(node_allocator_type& , const Key &, const T * ){ __TBB_ASSERT(false,"this dummy function should not be called"); return NULL; } node *search_bucket( const key_type &key, bucket *b ) const { node *n = static_cast( b->node_list ); while( is_valid(n) && !my_hash_compare.equal(key, n->item.first) ) n = static_cast( n->next ); __TBB_ASSERT(n != internal::rehash_req, "Search can be executed only for rehashed bucket"); return n; } //! bucket accessor is to find, rehash, acquire a lock, and access a bucket class bucket_accessor : public bucket::scoped_t { bucket *my_b; public: bucket_accessor( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) { acquire( base, h, writer ); } //! find a bucket by masked hashcode, optionally rehash, and acquire the lock inline void acquire( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) { my_b = base->get_bucket( h ); // TODO: actually, notification is unnecessary here, just hiding double-check if( itt_load_word_with_acquire(my_b->node_list) == internal::rehash_req && try_acquire( my_b->mutex, /*write=*/true ) ) { if( my_b->node_list == internal::rehash_req ) base->rehash_bucket( my_b, h ); //recursive rehashing } else bucket::scoped_t::acquire( my_b->mutex, writer ); __TBB_ASSERT( my_b->node_list != internal::rehash_req, NULL); } //! check whether bucket is locked for write bool is_writer() { return bucket::scoped_t::is_writer; } //! get bucket pointer bucket *operator() () { return my_b; } }; // TODO refactor to hash_base void rehash_bucket( bucket *b_new, const hashcode_t h ) { __TBB_ASSERT( *(intptr_t*)(&b_new->mutex), "b_new must be locked (for write)"); __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" ); __TBB_store_with_release(b_new->node_list, internal::empty_rehashed); // mark rehashed hashcode_t mask = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit #if __TBB_STATISTICS my_info_rehashes++; // invocations of rehash_bucket #endif bucket_accessor b_old( this, h & mask ); mask = (mask<<1) | 1; // get full mask for new bucket __TBB_ASSERT( (mask&(mask+1))==0 && (h & mask) == h, NULL ); restart: for( node_base **p = &b_old()->node_list, *n = __TBB_load_with_acquire(*p); is_valid(n); n = *p ) { hashcode_t c = my_hash_compare.hash( static_cast(n)->item.first ); #if TBB_USE_ASSERT hashcode_t bmask = h & (mask>>1); bmask = bmask==0? 1 : ( 1u<<(__TBB_Log2( bmask )+1 ) ) - 1; // minimal mask of parent bucket __TBB_ASSERT( (c & bmask) == (h & bmask), "hash() function changed for key in table" ); #endif if( (c & mask) == h ) { if( !b_old.is_writer() ) if( !b_old.upgrade_to_writer() ) { goto restart; // node ptr can be invalid due to concurrent erase } *p = n->next; // exclude from b_old add_to_bucket( b_new, n ); } else p = &n->next; // iterate to next item } } struct call_clear_on_leave { concurrent_hash_map* my_ch_map; call_clear_on_leave( concurrent_hash_map* a_ch_map ) : my_ch_map(a_ch_map) {} void dismiss() {my_ch_map = 0;} ~call_clear_on_leave(){ if (my_ch_map){ my_ch_map->clear(); } } }; public: class accessor; //! Combines data access, locking, and garbage collection. class const_accessor : private node::scoped_t /*which derived from no_copy*/ { friend class concurrent_hash_map; friend class accessor; public: //! Type of value typedef const typename concurrent_hash_map::value_type value_type; //! True if result is empty. bool empty() const { return !my_node; } //! Set to null void release() { if( my_node ) { node::scoped_t::release(); my_node = 0; } } //! Return reference to associated value in hash table. const_reference operator*() const { __TBB_ASSERT( my_node, "attempt to dereference empty accessor" ); return my_node->item; } //! Return pointer to associated value in hash table. const_pointer operator->() const { return &operator*(); } //! Create empty result const_accessor() : my_node(NULL) {} //! Destroy result after releasing the underlying reference. ~const_accessor() { my_node = NULL; // scoped lock's release() is called in its destructor } protected: bool is_writer() { return node::scoped_t::is_writer; } node *my_node; hashcode_t my_hash; }; //! Allows write access to elements and combines data access, locking, and garbage collection. class accessor: public const_accessor { public: //! Type of value typedef typename concurrent_hash_map::value_type value_type; //! Return reference to associated value in hash table. reference operator*() const { __TBB_ASSERT( this->my_node, "attempt to dereference empty accessor" ); return this->my_node->item; } //! Return pointer to associated value in hash table. pointer operator->() const { return &operator*(); } }; //! Construct empty table. concurrent_hash_map( const allocator_type &a = allocator_type() ) : internal::hash_map_base(), my_allocator(a) {} //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. concurrent_hash_map( size_type n, const allocator_type &a = allocator_type() ) : my_allocator(a) { reserve( n ); } //! Copy constructor concurrent_hash_map( const concurrent_hash_map &table, const allocator_type &a = allocator_type() ) : internal::hash_map_base(), my_allocator(a) { internal_copy(table); } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move constructor concurrent_hash_map( concurrent_hash_map &&table ) : internal::hash_map_base(), my_allocator(std::move(table.get_allocator())) { swap(table); } //! Move constructor concurrent_hash_map( concurrent_hash_map &&table, const allocator_type &a ) : internal::hash_map_base(), my_allocator(a) { if (a == table.get_allocator()){ this->swap(table); }else{ call_clear_on_leave scope_guard(this); internal_copy(std::make_move_iterator(table.begin()), std::make_move_iterator(table.end())); scope_guard.dismiss(); } } #endif //__TBB_CPP11_RVALUE_REF_PRESENT //! Construction with copying iteration range and given allocator instance template concurrent_hash_map( I first, I last, const allocator_type &a = allocator_type() ) : my_allocator(a) { reserve( std::distance(first, last) ); // TODO: load_factor? internal_copy(first, last); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. concurrent_hash_map( std::initializer_list il, const allocator_type &a = allocator_type() ) : my_allocator(a) { reserve(il.size()); internal_copy(il.begin(), il.end()); } #endif //__TBB_INITIALIZER_LISTS_PRESENT //! Assignment concurrent_hash_map& operator=( const concurrent_hash_map &table ) { if( this!=&table ) { clear(); internal_copy(table); } return *this; } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move Assignment concurrent_hash_map& operator=( concurrent_hash_map &&table ) { if(this != &table){ typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; if(pocma_t::value || this->my_allocator == table.my_allocator) { concurrent_hash_map trash (std::move(*this)); //TODO: swapping allocators here may be a problem, replace with single direction moving iff pocma is set this->swap(table); } else { //do per element move concurrent_hash_map moved_copy(std::move(table), this->my_allocator); this->swap(moved_copy); } } return *this; } #endif //__TBB_CPP11_RVALUE_REF_PRESENT #if __TBB_INITIALIZER_LISTS_PRESENT //! Assignment concurrent_hash_map& operator=( std::initializer_list il ) { clear(); reserve(il.size()); internal_copy(il.begin(), il.end()); return *this; } #endif //__TBB_INITIALIZER_LISTS_PRESENT //! Rehashes and optionally resizes the whole table. /** Useful to optimize performance before or after concurrent operations. Also enables using of find() and count() concurrent methods in serial context. */ void rehash(size_type n = 0); //! Clear table void clear(); //! Clear table and destroy it. ~concurrent_hash_map() { clear(); } //------------------------------------------------------------------------ // Parallel algorithm support //------------------------------------------------------------------------ range_type range( size_type grainsize=1 ) { return range_type( *this, grainsize ); } const_range_type range( size_type grainsize=1 ) const { return const_range_type( *this, grainsize ); } //------------------------------------------------------------------------ // STL support - not thread-safe methods //------------------------------------------------------------------------ iterator begin() { return iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); } iterator end() { return iterator( *this, 0, 0, 0 ); } const_iterator begin() const { return const_iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); } const_iterator end() const { return const_iterator( *this, 0, 0, 0 ); } std::pair equal_range( const Key& key ) { return internal_equal_range( key, end() ); } std::pair equal_range( const Key& key ) const { return internal_equal_range( key, end() ); } //! Number of items in table. size_type size() const { return my_size; } //! True if size()==0. bool empty() const { return my_size == 0; } //! Upper bound on size. size_type max_size() const {return (~size_type(0))/sizeof(node);} //! Returns the current number of buckets size_type bucket_count() const { return my_mask+1; } //! return allocator object allocator_type get_allocator() const { return this->my_allocator; } //! swap two instances. Iterators are invalidated void swap( concurrent_hash_map &table ); //------------------------------------------------------------------------ // concurrent map operations //------------------------------------------------------------------------ //! Return count of items (0 or 1) size_type count( const Key &key ) const { return const_cast(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false, &do_not_allocate_node ); } //! Find item and acquire a read lock on the item. /** Return true if item is found, false otherwise. */ bool find( const_accessor &result, const Key &key ) const { result.release(); return const_cast(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false, &do_not_allocate_node ); } //! Find item and acquire a write lock on the item. /** Return true if item is found, false otherwise. */ bool find( accessor &result, const Key &key ) { result.release(); return lookup(/*insert*/false, key, NULL, &result, /*write=*/true, &do_not_allocate_node ); } //! Insert item (if not already present) and acquire a read lock on the item. /** Returns true if item is new. */ bool insert( const_accessor &result, const Key &key ) { result.release(); return lookup(/*insert*/true, key, NULL, &result, /*write=*/false, &allocate_node_default_construct ); } //! Insert item (if not already present) and acquire a write lock on the item. /** Returns true if item is new. */ bool insert( accessor &result, const Key &key ) { result.release(); return lookup(/*insert*/true, key, NULL, &result, /*write=*/true, &allocate_node_default_construct ); } //! Insert item by copying if there is no such key present already and acquire a read lock on the item. /** Returns true if item is new. */ bool insert( const_accessor &result, const value_type &value ) { result.release(); return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false, &allocate_node_copy_construct ); } //! Insert item by copying if there is no such key present already and acquire a write lock on the item. /** Returns true if item is new. */ bool insert( accessor &result, const value_type &value ) { result.release(); return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true, &allocate_node_copy_construct ); } //! Insert item by copying if there is no such key present already /** Returns true if item is inserted. */ bool insert( const value_type &value ) { return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false, &allocate_node_copy_construct ); } //! Insert range [first, last) template void insert( I first, I last ) { for ( ; first != last; ++first ) insert( *first ); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Insert initializer list void insert( std::initializer_list il ) { insert( il.begin(), il.end() ); } #endif //__TBB_INITIALIZER_LISTS_PRESENT //! Erase item. /** Return true if item was erased by particularly this call. */ bool erase( const Key& key ); //! Erase item by const_accessor. /** Return true if item was erased by particularly this call. */ bool erase( const_accessor& item_accessor ) { return exclude( item_accessor ); } //! Erase item by accessor. /** Return true if item was erased by particularly this call. */ bool erase( accessor& item_accessor ) { return exclude( item_accessor ); } protected: //! Insert or find item and optionally acquire a lock on the item. bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node* (*allocate_node)(node_allocator_type& , const Key &, const T * ) ) ; //! delete item by accessor bool exclude( const_accessor &item_accessor ); //! Returns an iterator for an item defined by the key, or for the next item after it (if upper==true) template std::pair internal_equal_range( const Key& key, I end ) const; //! Copy "source" to *this, where *this must start out empty. void internal_copy( const concurrent_hash_map& source ); template void internal_copy( I first, I last ); //! Fast find when no concurrent erasure is used. For internal use inside TBB only! /** Return pointer to item with given key, or NULL if no such item exists. Must not be called concurrently with erasure operations. */ const_pointer internal_fast_find( const Key& key ) const { hashcode_t h = my_hash_compare.hash( key ); hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); node *n; restart: __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); bucket *b = get_bucket( h & m ); // TODO: actually, notification is unnecessary here, just hiding double-check if( itt_load_word_with_acquire(b->node_list) == internal::rehash_req ) { bucket::scoped_t lock; if( lock.try_acquire( b->mutex, /*write=*/true ) ) { if( b->node_list == internal::rehash_req) const_cast(this)->rehash_bucket( b, h & m ); //recursive rehashing } else lock.acquire( b->mutex, /*write=*/false ); __TBB_ASSERT(b->node_list!=internal::rehash_req,NULL); } n = search_bucket( key, b ); if( n ) return &n->item; else if( check_mask_race( h, m ) ) goto restart; return 0; } }; template bool concurrent_hash_map::lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node* (*allocate_node)(node_allocator_type& , const Key&, const T*) ) { __TBB_ASSERT( !result || !result->my_node, NULL ); bool return_value; hashcode_t const h = my_hash_compare.hash( key ); hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); segment_index_t grow_segment = 0; node *n, *tmp_n = 0; restart: {//lock scope __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); return_value = false; // get bucket bucket_accessor b( this, h & m ); // find a node n = search_bucket( key, b() ); if( op_insert ) { // [opt] insert a key if( !n ) { if( !tmp_n ) { tmp_n = allocate_node(my_allocator, key, t); } if( !b.is_writer() && !b.upgrade_to_writer() ) { // TODO: improved insertion // Rerun search_list, in case another thread inserted the item during the upgrade. n = search_bucket( key, b() ); if( is_valid(n) ) { // unfortunately, it did b.downgrade_to_reader(); goto exists; } } if( check_mask_race(h, m) ) goto restart; // b.release() is done in ~b(). // insert and set flag to grow the container grow_segment = insert_new_node( b(), n = tmp_n, m ); tmp_n = 0; return_value = true; } } else { // find or count if( !n ) { if( check_mask_race( h, m ) ) goto restart; // b.release() is done in ~b(). TODO: replace by continue return false; } return_value = true; } exists: if( !result ) goto check_growth; // TODO: the following seems as generic/regular operation // acquire the item if( !result->try_acquire( n->mutex, write ) ) { for( tbb::internal::atomic_backoff backoff(true);; ) { if( result->try_acquire( n->mutex, write ) ) break; if( !backoff.bounded_pause() ) { // the wait takes really long, restart the operation b.release(); __TBB_ASSERT( !op_insert || !return_value, "Can't acquire new item in locked bucket?" ); __TBB_Yield(); m = (hashcode_t) itt_load_word_with_acquire( my_mask ); goto restart; } } } }//lock scope result->my_node = n; result->my_hash = h; check_growth: // [opt] grow the container if( grow_segment ) { #if __TBB_STATISTICS my_info_resizes++; // concurrent ones #endif enable_segment( grow_segment ); } if( tmp_n ) // if op_insert only delete_node( tmp_n ); return return_value; } template template std::pair concurrent_hash_map::internal_equal_range( const Key& key, I end_ ) const { hashcode_t h = my_hash_compare.hash( key ); hashcode_t m = my_mask; __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); h &= m; bucket *b = get_bucket( h ); while( b->node_list == internal::rehash_req ) { m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit b = get_bucket( h &= m ); } node *n = search_bucket( key, b ); if( !n ) return std::make_pair(end_, end_); iterator lower(*this, h, b, n), upper(lower); return std::make_pair(lower, ++upper); } template bool concurrent_hash_map::exclude( const_accessor &item_accessor ) { __TBB_ASSERT( item_accessor.my_node, NULL ); node_base *const n = item_accessor.my_node; hashcode_t const h = item_accessor.my_hash; hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); do { // get bucket bucket_accessor b( this, h & m, /*writer=*/true ); node_base **p = &b()->node_list; while( *p && *p != n ) p = &(*p)->next; if( !*p ) { // someone else was first if( check_mask_race( h, m ) ) continue; item_accessor.release(); return false; } __TBB_ASSERT( *p == n, NULL ); *p = n->next; // remove from container my_size--; break; } while(true); if( !item_accessor.is_writer() ) // need to get exclusive lock item_accessor.upgrade_to_writer(); // return value means nothing here item_accessor.release(); delete_node( n ); // Only one thread can delete it return true; } template bool concurrent_hash_map::erase( const Key &key ) { node_base *n; hashcode_t const h = my_hash_compare.hash( key ); hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); restart: {//lock scope // get bucket bucket_accessor b( this, h & m ); search: node_base **p = &b()->node_list; n = *p; while( is_valid(n) && !my_hash_compare.equal(key, static_cast(n)->item.first ) ) { p = &n->next; n = *p; } if( !n ) { // not found, but mask could be changed if( check_mask_race( h, m ) ) goto restart; return false; } else if( !b.is_writer() && !b.upgrade_to_writer() ) { if( check_mask_race( h, m ) ) // contended upgrade, check mask goto restart; goto search; } *p = n->next; my_size--; } { typename node::scoped_t item_locker( n->mutex, /*write=*/true ); } // note: there should be no threads pretending to acquire this mutex again, do not try to upgrade const_accessor! delete_node( n ); // Only one thread can delete it due to write lock on the bucket return true; } template void concurrent_hash_map::swap(concurrent_hash_map &table) { //TODO: respect C++11 allocator_traits::propogate_on_constainer_swap using std::swap; swap(this->my_allocator, table.my_allocator); swap(this->my_hash_compare, table.my_hash_compare); internal_swap(table); } template void concurrent_hash_map::rehash(size_type sz) { reserve( sz ); // TODO: add reduction of number of buckets as well hashcode_t mask = my_mask; hashcode_t b = (mask+1)>>1; // size or first index of the last segment __TBB_ASSERT((b&(b-1))==0, NULL); // zero or power of 2 bucket *bp = get_bucket( b ); // only the last segment should be scanned for rehashing for(; b <= mask; b++, bp++ ) { node_base *n = bp->node_list; __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" ); __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" ); if( n == internal::rehash_req ) { // rehash bucket, conditional because rehashing of a previous bucket may affect this one hashcode_t h = b; bucket *b_old = bp; do { __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" ); hashcode_t m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit b_old = get_bucket( h &= m ); } while( b_old->node_list == internal::rehash_req ); // now h - is index of the root rehashed bucket b_old mark_rehashed_levels( h ); // mark all non-rehashed children recursively across all segments for( node_base **p = &b_old->node_list, *q = *p; is_valid(q); q = *p ) { hashcode_t c = my_hash_compare.hash( static_cast(q)->item.first ); if( (c & mask) != h ) { // should be rehashed *p = q->next; // exclude from b_old bucket *b_new = get_bucket( c & mask ); __TBB_ASSERT( b_new->node_list != internal::rehash_req, "hash() function changed for key in table or internal error" ); add_to_bucket( b_new, q ); } else p = &q->next; // iterate to next item } } } #if TBB_USE_PERFORMANCE_WARNINGS int current_size = int(my_size), buckets = int(mask)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics static bool reported = false; #endif #if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS for( b = 0; b <= mask; b++ ) {// only last segment should be scanned for rehashing if( b & (b-2) ) ++bp; // not the beginning of a segment else bp = get_bucket( b ); node_base *n = bp->node_list; __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" ); __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed, "Broken internal structure" ); #if TBB_USE_PERFORMANCE_WARNINGS if( n == internal::empty_rehashed ) empty_buckets++; else if( n->next ) overpopulated_buckets++; #endif #if TBB_USE_ASSERT for( ; is_valid(n); n = n->next ) { hashcode_t h = my_hash_compare.hash( static_cast(n)->item.first ) & mask; __TBB_ASSERT( h == b, "hash() function changed for key in table or internal error" ); } #endif } #endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS #if TBB_USE_PERFORMANCE_WARNINGS if( buckets > current_size) empty_buckets -= buckets - current_size; else overpopulated_buckets -= current_size - buckets; // TODO: load_factor? if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) { tbb::internal::runtime_warning( "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d", typeid(*this).name(), current_size, empty_buckets, overpopulated_buckets ); reported = true; } #endif } template void concurrent_hash_map::clear() { hashcode_t m = my_mask; __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); #if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS int current_size = int(my_size), buckets = int(m)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics static bool reported = false; #endif bucket *bp = 0; // check consistency for( segment_index_t b = 0; b <= m; b++ ) { if( b & (b-2) ) ++bp; // not the beginning of a segment else bp = get_bucket( b ); node_base *n = bp->node_list; __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" ); __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during clear() execution" ); #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS if( n == internal::empty_rehashed ) empty_buckets++; else if( n == internal::rehash_req ) buckets--; else if( n->next ) overpopulated_buckets++; #endif #if __TBB_EXTRA_DEBUG for(; is_valid(n); n = n->next ) { hashcode_t h = my_hash_compare.hash( static_cast(n)->item.first ); h &= m; __TBB_ASSERT( h == b || get_bucket(h)->node_list == internal::rehash_req, "hash() function changed for key in table or internal error" ); } #endif } #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS #if __TBB_STATISTICS printf( "items=%d buckets: capacity=%d rehashed=%d empty=%d overpopulated=%d" " concurrent: resizes=%u rehashes=%u restarts=%u\n", current_size, int(m+1), buckets, empty_buckets, overpopulated_buckets, unsigned(my_info_resizes), unsigned(my_info_rehashes), unsigned(my_info_restarts) ); my_info_resizes = 0; // concurrent ones my_info_restarts = 0; // race collisions my_info_rehashes = 0; // invocations of rehash_bucket #endif if( buckets > current_size) empty_buckets -= buckets - current_size; else overpopulated_buckets -= current_size - buckets; // TODO: load_factor? if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) { tbb::internal::runtime_warning( "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d", typeid(*this).name(), current_size, empty_buckets, overpopulated_buckets ); reported = true; } #endif #endif//TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS my_size = 0; segment_index_t s = segment_index_of( m ); __TBB_ASSERT( s+1 == pointers_per_table || !my_table[s+1], "wrong mask or concurrent grow" ); cache_aligned_allocator alloc; do { __TBB_ASSERT( is_valid( my_table[s] ), "wrong mask or concurrent grow" ); segment_ptr_t buckets_ptr = my_table[s]; size_type sz = segment_size( s ? s : 1 ); for( segment_index_t i = 0; i < sz; i++ ) for( node_base *n = buckets_ptr[i].node_list; is_valid(n); n = buckets_ptr[i].node_list ) { buckets_ptr[i].node_list = n->next; delete_node( n ); } if( s >= first_block) // the first segment or the next alloc.deallocate( buckets_ptr, sz ); else if( s == embedded_block && embedded_block != first_block ) alloc.deallocate( buckets_ptr, segment_size(first_block)-embedded_buckets ); if( s >= embedded_block ) my_table[s] = 0; } while(s-- > 0); my_mask = embedded_buckets - 1; } template void concurrent_hash_map::internal_copy( const concurrent_hash_map& source ) { reserve( source.my_size ); // TODO: load_factor? hashcode_t mask = source.my_mask; if( my_mask == mask ) { // optimized version bucket *dst = 0, *src = 0; bool rehash_required = false; for( hashcode_t k = 0; k <= mask; k++ ) { if( k & (k-2) ) ++dst,src++; // not the beginning of a segment else { dst = get_bucket( k ); src = source.get_bucket( k ); } __TBB_ASSERT( dst->node_list != internal::rehash_req, "Invalid bucket in destination table"); node *n = static_cast( src->node_list ); if( n == internal::rehash_req ) { // source is not rehashed, items are in previous buckets rehash_required = true; dst->node_list = internal::rehash_req; } else for(; n; n = static_cast( n->next ) ) { add_to_bucket( dst, new( my_allocator ) node(n->item.first, n->item.second) ); ++my_size; // TODO: replace by non-atomic op } } if( rehash_required ) rehash(); } else internal_copy( source.begin(), source.end() ); } template template void concurrent_hash_map::internal_copy(I first, I last) { hashcode_t m = my_mask; for(; first != last; ++first) { hashcode_t h = my_hash_compare.hash( (*first).first ); bucket *b = get_bucket( h & m ); __TBB_ASSERT( b->node_list != internal::rehash_req, "Invalid bucket in destination table"); node *n = new( my_allocator ) node(*first); add_to_bucket( b, n ); ++my_size; // TODO: replace by non-atomic op } } } // namespace interface5 using interface5::concurrent_hash_map; template inline bool operator==(const concurrent_hash_map &a, const concurrent_hash_map &b) { if(a.size() != b.size()) return false; typename concurrent_hash_map::const_iterator i(a.begin()), i_end(a.end()); typename concurrent_hash_map::const_iterator j, j_end(b.end()); for(; i != i_end; ++i) { j = b.equal_range(i->first).first; if( j == j_end || !(i->second == j->second) ) return false; } return true; } template inline bool operator!=(const concurrent_hash_map &a, const concurrent_hash_map &b) { return !(a == b); } template inline void swap(concurrent_hash_map &a, concurrent_hash_map &b) { a.swap( b ); } #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning( pop ) #endif // warning 4127 is back } // namespace tbb #endif /* __TBB_concurrent_hash_map_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_lru_cache.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_concurrent_lru_cache_H #define __TBB_concurrent_lru_cache_H #if ! TBB_PREVIEW_CONCURRENT_LRU_CACHE #error Set TBB_PREVIEW_CONCURRENT_LRU_CACHE to include concurrent_lru_cache.h #endif #include #include #include "tbb_stddef.h" #include "atomic.h" #include "internal/_aggregator_impl.h" namespace tbb{ namespace interface6 { template class concurrent_lru_cache : internal::no_assign{ private: typedef concurrent_lru_cache self_type; typedef value_functor_type value_function_type; typedef std::size_t ref_counter_type; struct map_value_type; typedef std::map map_storage_type; typedef std::list lru_list_type; struct map_value_type { value_type my_value; ref_counter_type my_ref_counter; typename lru_list_type::iterator my_lru_list_iterator; bool my_is_ready; map_value_type (value_type const& a_value, ref_counter_type a_ref_counter, typename lru_list_type::iterator a_lru_list_iterator, bool a_is_ready) : my_value(a_value), my_ref_counter(a_ref_counter), my_lru_list_iterator (a_lru_list_iterator), my_is_ready(a_is_ready) {} }; class handle_object; struct aggregator_operation; typedef aggregator_operation aggregated_operation_type; typedef tbb::internal::aggregating_functor aggregator_function_type; friend class tbb::internal::aggregating_functor; typedef tbb::internal::aggregator aggregator_type; private: value_function_type my_value_function; std::size_t const my_number_of_lru_history_items; map_storage_type my_map_storage; lru_list_type my_lru_list; aggregator_type my_aggregator; public: typedef handle_object handle; public: concurrent_lru_cache(value_function_type f, std::size_t number_of_lru_history_items) : my_value_function(f),my_number_of_lru_history_items(number_of_lru_history_items) { my_aggregator.initialize_handler(aggregator_function_type(this)); } handle_object operator[](key_type k){ retrieve_aggregator_operation op(k); my_aggregator.execute(&op); if (op.is_new_value_needed()){ op.result().second.my_value = my_value_function(k); __TBB_store_with_release(op.result().second.my_is_ready, true); }else{ tbb::internal::spin_wait_while_eq(op.result().second.my_is_ready,false); } return handle_object(*this,op.result()); } private: void signal_end_of_usage(typename map_storage_type::reference value_ref){ signal_end_of_usage_aggregator_operation op(value_ref); my_aggregator.execute(&op); } private: struct handle_move_t:no_assign{ concurrent_lru_cache & my_cache_ref; typename map_storage_type::reference my_map_record_ref; handle_move_t(concurrent_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_ref(cache_ref),my_map_record_ref(value_ref) {}; }; class handle_object { concurrent_lru_cache * my_cache_pointer; typename map_storage_type::reference my_map_record_ref; public: handle_object(concurrent_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_pointer(&cache_ref), my_map_record_ref(value_ref) {} handle_object(handle_move_t m):my_cache_pointer(&m.my_cache_ref), my_map_record_ref(m.my_map_record_ref){} operator handle_move_t(){ return move(*this);} value_type& value(){ __TBB_ASSERT(my_cache_pointer,"get value from moved from object?"); return my_map_record_ref.second.my_value; } ~handle_object(){ if (my_cache_pointer){ my_cache_pointer->signal_end_of_usage(my_map_record_ref); } } private: friend handle_move_t move(handle_object& h){ return handle_object::move(h); } static handle_move_t move(handle_object& h){ __TBB_ASSERT(h.my_cache_pointer,"move from the same object twice ?"); concurrent_lru_cache * cache_pointer = NULL; std::swap(cache_pointer,h.my_cache_pointer); return handle_move_t(*cache_pointer,h.my_map_record_ref); } private: void operator=(handle_object&); #if __SUNPRO_CC // Presumably due to a compiler error, private copy constructor // breaks expressions like handle h = cache[key]; public: #endif handle_object(handle_object &); }; private: //TODO: looks like aggregator_operation is a perfect match for statically typed variant type struct aggregator_operation : tbb::internal::aggregated_operation{ enum e_op_type {op_retive, op_signal_end_of_usage}; //TODO: try to use pointer to function apply_visitor here //TODO: try virtual functions and measure the difference e_op_type my_operation_type; aggregator_operation(e_op_type operation_type): my_operation_type(operation_type) {} void cast_and_handle(self_type& container ){ if (my_operation_type==op_retive){ static_cast(this)->handle(container); }else{ static_cast(this)->handle(container); } } }; struct retrieve_aggregator_operation : aggregator_operation, private internal::no_assign { key_type my_key; typename map_storage_type::pointer my_result_map_record_pointer; bool my_is_new_value_needed; retrieve_aggregator_operation(key_type key):aggregator_operation(aggregator_operation::op_retive),my_key(key),my_is_new_value_needed(false){} void handle(self_type& container ){ my_result_map_record_pointer = & container.retrieve_serial(my_key,my_is_new_value_needed); } typename map_storage_type::reference result(){ return * my_result_map_record_pointer; } bool is_new_value_needed(){return my_is_new_value_needed;} }; struct signal_end_of_usage_aggregator_operation : aggregator_operation, private internal::no_assign { typename map_storage_type::reference my_map_record_ref; signal_end_of_usage_aggregator_operation(typename map_storage_type::reference map_record_ref):aggregator_operation(aggregator_operation::op_signal_end_of_usage),my_map_record_ref(map_record_ref){} void handle(self_type& container ){ container.signal_end_of_usage_serial(my_map_record_ref); } }; private: void handle_operations(aggregator_operation* op_list){ while(op_list){ op_list->cast_and_handle(*this); aggregator_operation* tmp = op_list; op_list=op_list->next; tbb::internal::itt_store_word_with_release(tmp->status, uintptr_t(1)); } } private: typename map_storage_type::reference retrieve_serial(key_type k, bool& is_new_value_needed){ typename map_storage_type::iterator it = my_map_storage.find(k); if (it == my_map_storage.end()){ it = my_map_storage.insert(it,std::make_pair(k,map_value_type(value_type(),0,my_lru_list.end(),false))); is_new_value_needed = true; }else { typename lru_list_type::iterator list_it = it->second.my_lru_list_iterator; if (list_it!=my_lru_list.end()) { __TBB_ASSERT(!it->second.my_ref_counter,"item to be evicted should not have a live references"); //item is going to be used. Therefore it is not a subject for eviction //so - remove it from LRU history. my_lru_list.erase(list_it); it->second.my_lru_list_iterator= my_lru_list.end(); } } ++(it->second.my_ref_counter); return *it; } void signal_end_of_usage_serial(typename map_storage_type::reference map_record_ref){ typename map_storage_type::iterator it = my_map_storage.find(map_record_ref.first); __TBB_ASSERT(it!=my_map_storage.end(),"cache should not return past-end iterators to outer world"); __TBB_ASSERT(&(*it) == &map_record_ref,"dangling reference has been returned to outside world? data race ?"); __TBB_ASSERT( my_lru_list.end()== std::find(my_lru_list.begin(),my_lru_list.end(),it), "object in use should not be in list of unused objects "); if (! --(it->second.my_ref_counter)){ //it was the last reference so put it to the LRU history if (my_lru_list.size()>=my_number_of_lru_history_items){ //evict items in order to get a space size_t number_of_elements_to_evict = 1 + my_lru_list.size() - my_number_of_lru_history_items; for (size_t i=0; isecond.my_ref_counter,"item to be evicted should not have a live references"); my_lru_list.pop_back(); my_map_storage.erase(it_to_evict); } } my_lru_list.push_front(it); it->second.my_lru_list_iterator = my_lru_list.begin(); } } }; } // namespace interface6 using interface6::concurrent_lru_cache; } // namespace tbb #endif //__TBB_concurrent_lru_cache_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_monitor.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "concurrent_monitor.h" namespace tbb { namespace internal { void concurrent_monitor::thread_context::init() { new (sema.begin()) binary_semaphore; ready = true; } concurrent_monitor::~concurrent_monitor() { abort_all(); __TBB_ASSERT( waitset_ec.empty(), "waitset not empty?" ); } void concurrent_monitor::prepare_wait( thread_context& thr, uintptr_t ctx ) { if( !thr.ready ) thr.init(); // this is good place to pump previous spurious wakeup else if( thr.spurious ) { thr.spurious = false; thr.semaphore().P(); } thr.context = ctx; thr.in_waitset = true; { tbb::spin_mutex::scoped_lock l( mutex_ec ); __TBB_store_relaxed( thr.epoch, __TBB_load_relaxed(epoch) ); waitset_ec.add( (waitset_t::node_t*)&thr ); } atomic_fence(); } void concurrent_monitor::cancel_wait( thread_context& thr ) { // spurious wakeup will be pumped in the following prepare_wait() thr.spurious = true; // try to remove node from waitset bool th_in_waitset = thr.in_waitset; if( th_in_waitset ) { tbb::spin_mutex::scoped_lock l( mutex_ec ); if (thr.in_waitset) { // successfully removed from waitset, // so there will be no spurious wakeup thr.in_waitset = false; thr.spurious = false; waitset_ec.remove( (waitset_t::node_t&)thr ); } } } void concurrent_monitor::notify_one_relaxed() { if( waitset_ec.empty() ) return; waitset_node_t* n; const waitset_node_t* end = waitset_ec.end(); { tbb::spin_mutex::scoped_lock l( mutex_ec ); __TBB_store_relaxed( epoch, __TBB_load_relaxed(epoch) + 1 ); n = waitset_ec.front(); if( n!=end ) { waitset_ec.remove( *n ); to_thread_context(n)->in_waitset = false; } } if( n!=end ) to_thread_context(n)->semaphore().V(); } void concurrent_monitor::notify_all_relaxed() { if( waitset_ec.empty() ) return; dllist_t temp; const waitset_node_t* end; { tbb::spin_mutex::scoped_lock l( mutex_ec ); __TBB_store_relaxed( epoch, __TBB_load_relaxed(epoch) + 1 ); waitset_ec.flush_to( temp ); end = temp.end(); for( waitset_node_t* n=temp.front(); n!=end; n=n->next ) to_thread_context(n)->in_waitset = false; } waitset_node_t* nxt; for( waitset_node_t* n=temp.front(); n!=end; n=nxt ) { nxt = n->next; to_thread_context(n)->semaphore().V(); } #if TBB_USE_ASSERT temp.clear(); #endif } void concurrent_monitor::abort_all_relaxed() { if( waitset_ec.empty() ) return; dllist_t temp; const waitset_node_t* end; { tbb::spin_mutex::scoped_lock l( mutex_ec ); __TBB_store_relaxed( epoch, __TBB_load_relaxed(epoch) + 1 ); waitset_ec.flush_to( temp ); end = temp.end(); for( waitset_node_t* n=temp.front(); n!=end; n=n->next ) to_thread_context(n)->in_waitset = false; } waitset_node_t* nxt; for( waitset_node_t* n=temp.front(); n!=end; n=nxt ) { nxt = n->next; to_thread_context(n)->aborted = true; to_thread_context(n)->semaphore().V(); } #if TBB_USE_ASSERT temp.clear(); #endif } } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_monitor.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_concurrent_monitor_H #define __TBB_concurrent_monitor_H #include "tbb/tbb_stddef.h" #include "tbb/atomic.h" #include "tbb/spin_mutex.h" #include "tbb/tbb_exception.h" #include "tbb/aligned_space.h" #include "semaphore.h" namespace tbb { namespace internal { //! Circular doubly-linked list with sentinel /** head.next points to the front and head.prev points to the back */ class circular_doubly_linked_list_with_sentinel : no_copy { public: struct node_t { node_t* next; node_t* prev; explicit node_t() : next((node_t*)(uintptr_t)0xcdcdcdcd), prev((node_t*)(uintptr_t)0xcdcdcdcd) {} }; // ctor circular_doubly_linked_list_with_sentinel() {clear();} // dtor ~circular_doubly_linked_list_with_sentinel() {__TBB_ASSERT( head.next==&head && head.prev==&head, "the list is not empty" );} inline size_t size() const {return count;} inline bool empty() const {return size()==0;} inline node_t* front() const {return head.next;} inline node_t* last() const {return head.prev;} inline node_t* begin() const {return front();} inline const node_t* end() const {return &head;} //! add to the back of the list inline void add( node_t* n ) { __TBB_store_relaxed(count, __TBB_load_relaxed(count) + 1); n->prev = head.prev; n->next = &head; head.prev->next = n; head.prev = n; } //! remove node 'n' inline void remove( node_t& n ) { __TBB_store_relaxed(count, __TBB_load_relaxed(count) - 1); n.prev->next = n.next; n.next->prev = n.prev; } //! move all elements to 'lst' and initialize the 'this' list inline void flush_to( circular_doubly_linked_list_with_sentinel& lst ) { if( const size_t l_count = __TBB_load_relaxed(count) ) { __TBB_store_relaxed(lst.count, l_count); lst.head.next = head.next; lst.head.prev = head.prev; head.next->prev = &lst.head; head.prev->next = &lst.head; clear(); } } void clear() {head.next = head.prev = &head; __TBB_store_relaxed(count, 0);} private: __TBB_atomic size_t count; node_t head; }; typedef circular_doubly_linked_list_with_sentinel waitset_t; typedef circular_doubly_linked_list_with_sentinel dllist_t; typedef circular_doubly_linked_list_with_sentinel::node_t waitset_node_t; //! concurrent_monitor /** fine-grained concurrent_monitor implementation */ class concurrent_monitor : no_copy { public: /** per-thread descriptor for concurrent_monitor */ class thread_context : waitset_node_t, no_copy { friend class concurrent_monitor; public: thread_context() : spurious(false), aborted(false), ready(false), context(0) { epoch = 0; in_waitset = false; } ~thread_context() { if (ready) { if( spurious ) semaphore().P(); semaphore().~binary_semaphore(); } } binary_semaphore& semaphore() { return *sema.begin(); } private: //! The method for lazy initialization of the thread_context's semaphore. // Inlining of the method is undesirable, due to extra instructions for // exception support added at caller side. __TBB_NOINLINE( void init() ); tbb::aligned_space sema; __TBB_atomic unsigned epoch; tbb::atomic in_waitset; bool spurious; bool aborted; bool ready; uintptr_t context; }; //! ctor concurrent_monitor() {__TBB_store_relaxed(epoch, 0);} //! dtor ~concurrent_monitor() ; //! prepare wait by inserting 'thr' into the wait queue void prepare_wait( thread_context& thr, uintptr_t ctx = 0 ); //! Commit wait if event count has not changed; otherwise, cancel wait. /** Returns true if committed, false if canceled. */ inline bool commit_wait( thread_context& thr ) { const bool do_it = thr.epoch == __TBB_load_relaxed(epoch); // this check is just an optimization if( do_it ) { __TBB_ASSERT( thr.ready, "use of commit_wait() without prior prepare_wait()"); thr.semaphore().P(); __TBB_ASSERT( !thr.in_waitset, "still in the queue?" ); if( thr.aborted ) throw_exception( eid_user_abort ); } else { cancel_wait( thr ); } return do_it; } //! Cancel the wait. Removes the thread from the wait queue if not removed yet. void cancel_wait( thread_context& thr ); //! Wait for a condition to be satisfied with waiting-on context template void wait( WaitUntil until, Context on ); //! Notify one thread about the event void notify_one() {atomic_fence(); notify_one_relaxed();} //! Notify one thread about the event. Relaxed version. void notify_one_relaxed(); //! Notify all waiting threads of the event void notify_all() {atomic_fence(); notify_all_relaxed();} //! Notify all waiting threads of the event; Relaxed version void notify_all_relaxed(); //! Notify waiting threads of the event that satisfies the given predicate template void notify( const P& predicate ) {atomic_fence(); notify_relaxed( predicate );} //! Notify waiting threads of the event that satisfies the given predicate; Relaxed version template void notify_relaxed( const P& predicate ); //! Abort any sleeping threads at the time of the call void abort_all() {atomic_fence(); abort_all_relaxed(); } //! Abort any sleeping threads at the time of the call; Relaxed version void abort_all_relaxed(); private: tbb::spin_mutex mutex_ec; waitset_t waitset_ec; __TBB_atomic unsigned epoch; thread_context* to_thread_context( waitset_node_t* n ) { return static_cast(n); } }; template void concurrent_monitor::wait( WaitUntil until, Context on ) { bool slept = false; thread_context thr_ctx; prepare_wait( thr_ctx, on() ); while( !until() ) { if( (slept = commit_wait( thr_ctx ) )==true ) if( until() ) break; slept = false; prepare_wait( thr_ctx, on() ); } if( !slept ) cancel_wait( thr_ctx ); } template void concurrent_monitor::notify_relaxed( const P& predicate ) { if( waitset_ec.empty() ) return; dllist_t temp; waitset_node_t* nxt; const waitset_node_t* end = waitset_ec.end(); { tbb::spin_mutex::scoped_lock l( mutex_ec ); __TBB_store_relaxed(epoch, __TBB_load_relaxed(epoch) + 1); for( waitset_node_t* n=waitset_ec.last(); n!=end; n=nxt ) { nxt = n->prev; thread_context* thr = to_thread_context( n ); if( predicate( thr->context ) ) { waitset_ec.remove( *n ); thr->in_waitset = false; temp.add( n ); } } } end = temp.end(); for( waitset_node_t* n=temp.front(); n!=end; n=nxt ) { nxt = n->next; to_thread_context(n)->semaphore().V(); } #if TBB_USE_ASSERT temp.clear(); #endif } } // namespace internal } // namespace tbb #endif /* __TBB_concurrent_monitor_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_priority_queue.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_concurrent_priority_queue_H #define __TBB_concurrent_priority_queue_H #include "atomic.h" #include "cache_aligned_allocator.h" #include "tbb_exception.h" #include "tbb_stddef.h" #include "tbb_profiling.h" #include "internal/_aggregator_impl.h" #include #include #include #if __TBB_INITIALIZER_LISTS_PRESENT #include #endif namespace tbb { namespace interface5 { using namespace tbb::internal; //! Concurrent priority queue template , typename A=cache_aligned_allocator > class concurrent_priority_queue { public: //! Element type in the queue. typedef T value_type; //! Reference type typedef T& reference; //! Const reference type typedef const T& const_reference; //! Integral type for representing size of the queue. typedef size_t size_type; //! Difference type for iterator typedef ptrdiff_t difference_type; //! Allocator type typedef A allocator_type; //! Constructs a new concurrent_priority_queue with default capacity explicit concurrent_priority_queue(const allocator_type& a = allocator_type()) : mark(0), my_size(0), data(a) { my_aggregator.initialize_handler(my_functor_t(this)); } //! Constructs a new concurrent_priority_queue with init_sz capacity explicit concurrent_priority_queue(size_type init_capacity, const allocator_type& a = allocator_type()) : mark(0), my_size(0), data(a) { data.reserve(init_capacity); my_aggregator.initialize_handler(my_functor_t(this)); } //! [begin,end) constructor template concurrent_priority_queue(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : mark(0), data(begin, end, a) { my_aggregator.initialize_handler(my_functor_t(this)); heapify(); my_size = data.size(); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from std::initializer_list concurrent_priority_queue(std::initializer_list init_list, const allocator_type &a = allocator_type()) : mark(0),data(init_list.begin(), init_list.end(), a) { my_aggregator.initialize_handler(my_functor_t(this)); heapify(); my_size = data.size(); } #endif //# __TBB_INITIALIZER_LISTS_PRESENT //! Copy constructor /** This operation is unsafe if there are pending concurrent operations on the src queue. */ explicit concurrent_priority_queue(const concurrent_priority_queue& src) : mark(src.mark), my_size(src.my_size), data(src.data.begin(), src.data.end(), src.data.get_allocator()) { my_aggregator.initialize_handler(my_functor_t(this)); heapify(); } //! Copy constructor with specific allocator /** This operation is unsafe if there are pending concurrent operations on the src queue. */ concurrent_priority_queue(const concurrent_priority_queue& src, const allocator_type& a) : mark(src.mark), my_size(src.my_size), data(src.data.begin(), src.data.end(), a) { my_aggregator.initialize_handler(my_functor_t(this)); heapify(); } //! Assignment operator /** This operation is unsafe if there are pending concurrent operations on the src queue. */ concurrent_priority_queue& operator=(const concurrent_priority_queue& src) { if (this != &src) { vector_t(src.data.begin(), src.data.end(), src.data.get_allocator()).swap(data); mark = src.mark; my_size = src.my_size; } return *this; } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move constructor /** This operation is unsafe if there are pending concurrent operations on the src queue. */ concurrent_priority_queue(concurrent_priority_queue&& src) : mark(src.mark), my_size(src.my_size), data(std::move(src.data)) { my_aggregator.initialize_handler(my_functor_t(this)); } //! Move constructor with specific allocator /** This operation is unsafe if there are pending concurrent operations on the src queue. */ concurrent_priority_queue(concurrent_priority_queue&& src, const allocator_type& a) : mark(src.mark), my_size(src.my_size), #if __TBB_ALLOCATOR_TRAITS_PRESENT data(std::move(src.data), a) #else // Some early version of C++11 STL vector does not have a constructor of vector(vector&& , allocator). // It seems that the reason is absence of support of allocator_traits (stateful allocators). data(a) #endif //__TBB_ALLOCATOR_TRAITS_PRESENT { my_aggregator.initialize_handler(my_functor_t(this)); #if !__TBB_ALLOCATOR_TRAITS_PRESENT if (a != src.data.get_allocator()){ data.reserve(src.data.size()); data.assign(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end())); }else{ data = std::move(src.data); } #endif //!__TBB_ALLOCATOR_TRAITS_PRESENT } //! Move assignment operator /** This operation is unsafe if there are pending concurrent operations on the src queue. */ concurrent_priority_queue& operator=( concurrent_priority_queue&& src) { if (this != &src) { mark = src.mark; my_size = src.my_size; #if !__TBB_ALLOCATOR_TRAITS_PRESENT if (data.get_allocator() != src.data.get_allocator()){ vector_t(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end()), data.get_allocator()).swap(data); }else #endif //!__TBB_ALLOCATOR_TRAITS_PRESENT { data = std::move(src.data); } } return *this; } #endif //__TBB_CPP11_RVALUE_REF_PRESENT //! Assign the queue from [begin,end) range, not thread-safe template void assign(InputIterator begin, InputIterator end) { vector_t(begin, end, data.get_allocator()).swap(data); mark = 0; my_size = data.size(); heapify(); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Assign the queue from std::initializer_list, not thread-safe void assign(std::initializer_list il) { this->assign(il.begin(), il.end()); } //! Assign from std::initializer_list, not thread-safe concurrent_priority_queue& operator=(std::initializer_list il) { this->assign(il.begin(), il.end()); return *this; } #endif //# __TBB_INITIALIZER_LISTS_PRESENT //! Returns true if empty, false otherwise /** Returned value may not reflect results of pending operations. This operation reads shared data and will trigger a race condition. */ bool empty() const { return size()==0; } //! Returns the current number of elements contained in the queue /** Returned value may not reflect results of pending operations. This operation reads shared data and will trigger a race condition. */ size_type size() const { return __TBB_load_with_acquire(my_size); } //! Pushes elem onto the queue, increasing capacity of queue if necessary /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ void push(const_reference elem) { cpq_operation op_data(elem, PUSH_OP); my_aggregator.execute(&op_data); if (op_data.status == FAILED) // exception thrown throw_exception(eid_bad_alloc); } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Pushes elem onto the queue, increasing capacity of queue if necessary /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ void push(value_type &&elem) { cpq_operation op_data(elem, PUSH_RVALUE_OP); my_aggregator.execute(&op_data); if (op_data.status == FAILED) // exception thrown throw_exception(eid_bad_alloc); } #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT //! Constructs a new element using args as the arguments for its construction and pushes it onto the queue */ /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ template void emplace(Args&&... args) { push(value_type(std::forward(args)...)); } #endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ //! Gets a reference to and removes highest priority element /** If a highest priority element was found, sets elem and returns true, otherwise returns false. This operation can be safely used concurrently with other push, try_pop or emplace operations. */ bool try_pop(reference elem) { cpq_operation op_data(POP_OP); op_data.elem = &elem; my_aggregator.execute(&op_data); return op_data.status==SUCCEEDED; } //! Clear the queue; not thread-safe /** This operation is unsafe if there are pending concurrent operations on the queue. Resets size, effectively emptying queue; does not free space. May not clear elements added in pending operations. */ void clear() { data.clear(); mark = 0; my_size = 0; } //! Swap this queue with another; not thread-safe /** This operation is unsafe if there are pending concurrent operations on the queue. */ void swap(concurrent_priority_queue& q) { using std::swap; data.swap(q.data); swap(mark, q.mark); swap(my_size, q.my_size); } //! Return allocator object allocator_type get_allocator() const { return data.get_allocator(); } private: enum operation_type {INVALID_OP, PUSH_OP, POP_OP, PUSH_RVALUE_OP}; enum operation_status { WAIT=0, SUCCEEDED, FAILED }; class cpq_operation : public aggregated_operation { public: operation_type type; union { value_type *elem; size_type sz; }; cpq_operation(const_reference e, operation_type t) : type(t), elem(const_cast(&e)) {} cpq_operation(operation_type t) : type(t) {} }; class my_functor_t { concurrent_priority_queue *cpq; public: my_functor_t() {} my_functor_t(concurrent_priority_queue *cpq_) : cpq(cpq_) {} void operator()(cpq_operation* op_list) { cpq->handle_operations(op_list); } }; typedef tbb::internal::aggregator< my_functor_t, cpq_operation > aggregator_t; aggregator_t my_aggregator; //! Padding added to avoid false sharing char padding1[NFS_MaxLineSize - sizeof(aggregator_t)]; //! The point at which unsorted elements begin size_type mark; __TBB_atomic size_type my_size; Compare compare; //! Padding added to avoid false sharing char padding2[NFS_MaxLineSize - (2*sizeof(size_type)) - sizeof(Compare)]; //! Storage for the heap of elements in queue, plus unheapified elements /** data has the following structure: binary unheapified heap elements ____|_______|____ | | | v v v [_|...|_|_|...|_| |...| ] 0 ^ ^ ^ | | |__capacity | |__my_size |__mark Thus, data stores the binary heap starting at position 0 through mark-1 (it may be empty). Then there are 0 or more elements that have not yet been inserted into the heap, in positions mark through my_size-1. */ typedef std::vector vector_t; vector_t data; void handle_operations(cpq_operation *op_list) { cpq_operation *tmp, *pop_list=NULL; __TBB_ASSERT(mark == data.size(), NULL); // First pass processes all constant (amortized; reallocation may happen) time pushes and pops. while (op_list) { // ITT note: &(op_list->status) tag is used to cover accesses to op_list // node. This thread is going to handle the operation, and so will acquire it // and perform the associated operation w/o triggering a race condition; the // thread that created the operation is waiting on the status field, so when // this thread is done with the operation, it will perform a // store_with_release to give control back to the waiting thread in // aggregator::insert_operation. call_itt_notify(acquired, &(op_list->status)); __TBB_ASSERT(op_list->type != INVALID_OP, NULL); tmp = op_list; op_list = itt_hide_load_word(op_list->next); if (tmp->type == POP_OP) { if (mark < data.size() && compare(data[0], data[data.size()-1])) { // there are newly pushed elems and the last one // is higher than top *(tmp->elem) = move(data[data.size()-1]); __TBB_store_with_release(my_size, my_size-1); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); data.pop_back(); __TBB_ASSERT(mark<=data.size(), NULL); } else { // no convenient item to pop; postpone itt_hide_store_word(tmp->next, pop_list); pop_list = tmp; } } else { // PUSH_OP or PUSH_RVALUE_OP __TBB_ASSERT(tmp->type == PUSH_OP || tmp->type == PUSH_RVALUE_OP, "Unknown operation" ); __TBB_TRY{ if (tmp->type == PUSH_OP) { data.push_back(*(tmp->elem)); } else { data.push_back(move(*(tmp->elem))); } __TBB_store_with_release(my_size, my_size + 1); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); } __TBB_CATCH(...) { itt_store_word_with_release(tmp->status, uintptr_t(FAILED)); } } } // second pass processes pop operations while (pop_list) { tmp = pop_list; pop_list = itt_hide_load_word(pop_list->next); __TBB_ASSERT(tmp->type == POP_OP, NULL); if (data.empty()) { itt_store_word_with_release(tmp->status, uintptr_t(FAILED)); } else { __TBB_ASSERT(mark<=data.size(), NULL); if (mark < data.size() && compare(data[0], data[data.size()-1])) { // there are newly pushed elems and the last one is // higher than top *(tmp->elem) = move(data[data.size()-1]); __TBB_store_with_release(my_size, my_size-1); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); data.pop_back(); } else { // extract top and push last element down heap *(tmp->elem) = move(data[0]); __TBB_store_with_release(my_size, my_size-1); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); reheap(); } } } // heapify any leftover pushed elements before doing the next // batch of operations if (mark0) mark = 1; for (; mark>1; if (!compare(data[parent], to_place)) break; data[cur_pos] = move(data[parent]); cur_pos = parent; } while( cur_pos ); data[cur_pos] = move(to_place); } } //! Re-heapify after an extraction /** Re-heapify by pushing last element down the heap from the root. */ void reheap() { size_type cur_pos=0, child=1; while (child < mark) { size_type target = child; if (child+1 < mark && compare(data[child], data[child+1])) ++target; // target now has the higher priority child if (compare(data[target], data[data.size()-1])) break; data[cur_pos] = move(data[target]); cur_pos = target; child = (cur_pos<<1)+1; } if (cur_pos != data.size()-1) data[cur_pos] = move(data[data.size()-1]); data.pop_back(); if (mark > data.size()) mark = data.size(); } }; } // namespace interface5 using interface5::concurrent_priority_queue; } // namespace tbb #endif /* __TBB_concurrent_priority_queue_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_queue.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_stddef.h" #include "tbb/tbb_machine.h" #include "tbb/tbb_exception.h" // Define required to satisfy test in internal file. #define __TBB_concurrent_queue_H #include "tbb/internal/_concurrent_queue_impl.h" #include "concurrent_monitor.h" #include "itt_notify.h" #include #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include // for memset() #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif using namespace std; #if defined(_MSC_VER) && defined(_Wp64) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (disable: 4267) #endif #define RECORD_EVENTS 0 namespace tbb { namespace internal { typedef concurrent_queue_base_v3 concurrent_queue_base; typedef size_t ticket; //! A queue using simple locking. /** For efficiency, this class has no constructor. The caller is expected to zero-initialize it. */ struct micro_queue { typedef concurrent_queue_base::page page; friend class micro_queue_pop_finalizer; atomic head_page; atomic head_counter; atomic tail_page; atomic tail_counter; spin_mutex page_mutex; void push( const void* item, ticket k, concurrent_queue_base& base, concurrent_queue_base::copy_specifics op_type ); void abort_push( ticket k, concurrent_queue_base& base ); bool pop( void* dst, ticket k, concurrent_queue_base& base ); micro_queue& assign( const micro_queue& src, concurrent_queue_base& base, concurrent_queue_base::copy_specifics op_type ); page* make_copy ( concurrent_queue_base& base, const page* src_page, size_t begin_in_page, size_t end_in_page, ticket& g_index, concurrent_queue_base::copy_specifics op_type ) ; void make_invalid( ticket k ); }; // we need to yank it out of micro_queue because of concurrent_queue_base::deallocate_page being virtual. class micro_queue_pop_finalizer: no_copy { typedef concurrent_queue_base::page page; ticket my_ticket; micro_queue& my_queue; page* my_page; concurrent_queue_base &base; public: micro_queue_pop_finalizer( micro_queue& queue, concurrent_queue_base& b, ticket k, page* p ) : my_ticket(k), my_queue(queue), my_page(p), base(b) {} ~micro_queue_pop_finalizer() { page* p = my_page; if( p ) { spin_mutex::scoped_lock lock( my_queue.page_mutex ); page* q = p->next; my_queue.head_page = q; if( !q ) { my_queue.tail_page = NULL; } } my_queue.head_counter = my_ticket; if( p ) base.deallocate_page( p ); } }; struct predicate_leq { ticket t; predicate_leq( ticket t_ ) : t(t_) {} bool operator() ( uintptr_t p ) const {return (ticket)p<=t;} }; //! Internal representation of a ConcurrentQueue. /** For efficiency, this class has no constructor. The caller is expected to zero-initialize it. */ class concurrent_queue_rep { public: private: friend struct micro_queue; //! Approximately n_queue/golden ratio static const size_t phi = 3; public: //! Must be power of 2 static const size_t n_queue = 8; //! Map ticket to an array index static size_t index( ticket k ) { return k*phi%n_queue; } atomic head_counter; concurrent_monitor items_avail; atomic n_invalid_entries; char pad1[NFS_MaxLineSize-((sizeof(atomic)+sizeof(concurrent_monitor)+sizeof(atomic))&(NFS_MaxLineSize-1))]; atomic tail_counter; concurrent_monitor slots_avail; char pad2[NFS_MaxLineSize-((sizeof(atomic)+sizeof(concurrent_monitor))&(NFS_MaxLineSize-1))]; micro_queue array[n_queue]; micro_queue& choose( ticket k ) { // The formula here approximates LRU in a cache-oblivious way. return array[index(k)]; } //! Value for effective_capacity that denotes unbounded queue. static const ptrdiff_t infinite_capacity = ptrdiff_t(~size_t(0)/2); }; #if _MSC_VER && !defined(__INTEL_COMPILER) // unary minus operator applied to unsigned type, result still unsigned #pragma warning( push ) #pragma warning( disable: 4146 ) #endif static void* invalid_page; //------------------------------------------------------------------------ // micro_queue //------------------------------------------------------------------------ void micro_queue::push( const void* item, ticket k, concurrent_queue_base& base, concurrent_queue_base::copy_specifics op_type ) { k &= -concurrent_queue_rep::n_queue; page* p = NULL; // find index on page where we would put the data size_t index = modulo_power_of_two( k/concurrent_queue_rep::n_queue, base.items_per_page ); if( !index ) { // make a new page __TBB_TRY { p = base.allocate_page(); } __TBB_CATCH(...) { ++base.my_rep->n_invalid_entries; make_invalid( k ); } p->mask = 0; p->next = NULL; } // wait for my turn if( tail_counter!=k ) // The developer insisted on keeping first check out of the backoff loop for( atomic_backoff b(true);;b.pause() ) { ticket tail = tail_counter; if( tail==k ) break; else if( tail&0x1 ) { // no memory. throws an exception; assumes concurrent_queue_rep::n_queue>1 ++base.my_rep->n_invalid_entries; throw_exception( eid_bad_last_alloc ); } } if( p ) { // page is newly allocated; insert in micro_queue spin_mutex::scoped_lock lock( page_mutex ); if( page* q = tail_page ) q->next = p; else head_page = p; tail_page = p; } if (item) { p = tail_page; ITT_NOTIFY( sync_acquired, p ); __TBB_TRY { if( concurrent_queue_base::copy == op_type ) { base.copy_item( *p, index, item ); } else { __TBB_ASSERT( concurrent_queue_base::move == op_type, NULL ); static_cast(base).move_item( *p, index, item ); } } __TBB_CATCH(...) { ++base.my_rep->n_invalid_entries; tail_counter += concurrent_queue_rep::n_queue; __TBB_RETHROW(); } ITT_NOTIFY( sync_releasing, p ); // If no exception was thrown, mark item as present. p->mask |= uintptr_t(1)<n_invalid_entries; tail_counter += concurrent_queue_rep::n_queue; } void micro_queue::abort_push( ticket k, concurrent_queue_base& base ) { push(NULL, k, base, concurrent_queue_base::copy); } bool micro_queue::pop( void* dst, ticket k, concurrent_queue_base& base ) { k &= -concurrent_queue_rep::n_queue; spin_wait_until_eq( head_counter, k ); spin_wait_while_eq( tail_counter, k ); page& p = *head_page; __TBB_ASSERT( &p, NULL ); size_t index = modulo_power_of_two( k/concurrent_queue_rep::n_queue, base.items_per_page ); bool success = false; { micro_queue_pop_finalizer finalizer( *this, base, k+concurrent_queue_rep::n_queue, index==base.items_per_page-1 ? &p : NULL ); if( p.mask & uintptr_t(1)<n_invalid_entries; } } return success; } micro_queue& micro_queue::assign( const micro_queue& src, concurrent_queue_base& base, concurrent_queue_base::copy_specifics op_type ) { head_counter = src.head_counter; tail_counter = src.tail_counter; const page* srcp = src.head_page; if( srcp ) { ticket g_index = head_counter; __TBB_TRY { size_t n_items = (tail_counter-head_counter)/concurrent_queue_rep::n_queue; size_t index = modulo_power_of_two( head_counter/concurrent_queue_rep::n_queue, base.items_per_page ); size_t end_in_first_page = (index+n_itemsnext; srcp!=src.tail_page; srcp=srcp->next ) { cur_page->next = make_copy( base, srcp, 0, base.items_per_page, g_index, op_type ); cur_page = cur_page->next; } __TBB_ASSERT( srcp==src.tail_page, NULL ); size_t last_index = modulo_power_of_two( tail_counter/concurrent_queue_rep::n_queue, base.items_per_page ); if( last_index==0 ) last_index = base.items_per_page; cur_page->next = make_copy( base, srcp, 0, last_index, g_index, op_type ); cur_page = cur_page->next; } tail_page = cur_page; } __TBB_CATCH(...) { make_invalid( g_index ); } } else { head_page = tail_page = NULL; } return *this; } concurrent_queue_base::page* micro_queue::make_copy( concurrent_queue_base& base, const concurrent_queue_base::page* src_page, size_t begin_in_page, size_t end_in_page, ticket& g_index, concurrent_queue_base::copy_specifics op_type ) { page* new_page = base.allocate_page(); new_page->next = NULL; new_page->mask = src_page->mask; for( ; begin_in_page!=end_in_page; ++begin_in_page, ++g_index ) if( new_page->mask & uintptr_t(1)<(base).move_page_item( *new_page, begin_in_page, *src_page, begin_in_page ); } return new_page; } void micro_queue::make_invalid( ticket k ) { static concurrent_queue_base::page dummy = {static_cast((void*)1), 0}; // mark it so that no more pushes are allowed. invalid_page = &dummy; { spin_mutex::scoped_lock lock( page_mutex ); tail_counter = k+concurrent_queue_rep::n_queue+1; if( page* q = tail_page ) q->next = static_cast(invalid_page); else head_page = static_cast(invalid_page); tail_page = static_cast(invalid_page); } __TBB_RETHROW(); } #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning( pop ) #endif // warning 4146 is back //------------------------------------------------------------------------ // concurrent_queue_base //------------------------------------------------------------------------ concurrent_queue_base_v3::concurrent_queue_base_v3( size_t item_sz ) { items_per_page = item_sz<= 8 ? 32 : item_sz<= 16 ? 16 : item_sz<= 32 ? 8 : item_sz<= 64 ? 4 : item_sz<=128 ? 2 : 1; my_capacity = size_t(-1)/(item_sz>1 ? item_sz : 2); my_rep = cache_aligned_allocator().allocate(1); __TBB_ASSERT( (size_t)my_rep % NFS_GetLineSize()==0, "alignment error" ); __TBB_ASSERT( (size_t)&my_rep->head_counter % NFS_GetLineSize()==0, "alignment error" ); __TBB_ASSERT( (size_t)&my_rep->tail_counter % NFS_GetLineSize()==0, "alignment error" ); __TBB_ASSERT( (size_t)&my_rep->array % NFS_GetLineSize()==0, "alignment error" ); memset(my_rep,0,sizeof(concurrent_queue_rep)); new ( &my_rep->items_avail ) concurrent_monitor(); new ( &my_rep->slots_avail ) concurrent_monitor(); this->item_size = item_sz; } concurrent_queue_base_v3::~concurrent_queue_base_v3() { size_t nq = my_rep->n_queue; for( size_t i=0; iarray[i].tail_page==NULL, "pages were not freed properly" ); cache_aligned_allocator().deallocate(my_rep,1); } void concurrent_queue_base_v3::internal_push( const void* src ) { internal_insert_item( src, copy ); } void concurrent_queue_base_v8::internal_push_move( const void* src ) { internal_insert_item( src, move ); } void concurrent_queue_base_v3::internal_insert_item( const void* src, copy_specifics op_type ) { concurrent_queue_rep& r = *my_rep; ticket k = r.tail_counter++; ptrdiff_t e = my_capacity; #if DO_ITT_NOTIFY bool sync_prepare_done = false; #endif if( (ptrdiff_t)(k-r.head_counter)>=e ) { // queue is full #if DO_ITT_NOTIFY if( !sync_prepare_done ) { ITT_NOTIFY( sync_prepare, &sync_prepare_done ); sync_prepare_done = true; } #endif bool slept = false; concurrent_monitor::thread_context thr_ctx; r.slots_avail.prepare_wait( thr_ctx, ((ptrdiff_t)(k-e)) ); while( (ptrdiff_t)(k-r.head_counter)>=const_cast(e = my_capacity) ) { __TBB_TRY { slept = r.slots_avail.commit_wait( thr_ctx ); } __TBB_CATCH( tbb::user_abort& ) { r.choose(k).abort_push(k, *this); __TBB_RETHROW(); } __TBB_CATCH(...) { __TBB_RETHROW(); } if (slept == true) break; r.slots_avail.prepare_wait( thr_ctx, ((ptrdiff_t)(k-e)) ); } if( !slept ) r.slots_avail.cancel_wait( thr_ctx ); } ITT_NOTIFY( sync_acquired, &sync_prepare_done ); __TBB_ASSERT( (ptrdiff_t)(k-r.head_counter)0, NULL); } while( !r.choose(k).pop(dst,k,*this) ); // wake up a producer.. r.slots_avail.notify( predicate_leq(k) ); } void concurrent_queue_base_v3::internal_abort() { concurrent_queue_rep& r = *my_rep; r.items_avail.abort_all(); r.slots_avail.abort_all(); } bool concurrent_queue_base_v3::internal_pop_if_present( void* dst ) { concurrent_queue_rep& r = *my_rep; ticket k; do { k = r.head_counter; for(;;) { if( (ptrdiff_t)(r.tail_counter-k)<=0 ) { // Queue is empty return false; } // Queue had item with ticket k when we looked. Attempt to get that item. ticket tk=k; k = r.head_counter.compare_and_swap( tk+1, tk ); if( k==tk ) break; // Another thread snatched the item, retry. } } while( !r.choose( k ).pop( dst, k, *this ) ); r.slots_avail.notify( predicate_leq(k) ); return true; } bool concurrent_queue_base_v3::internal_push_if_not_full( const void* src ) { return internal_insert_if_not_full( src, copy ); } bool concurrent_queue_base_v8::internal_push_move_if_not_full( const void* src ) { return internal_insert_if_not_full( src, move ); } bool concurrent_queue_base_v3::internal_insert_if_not_full( const void* src, copy_specifics op_type ) { concurrent_queue_rep& r = *my_rep; ticket k = r.tail_counter; for(;;) { if( (ptrdiff_t)(k-r.head_counter)>=my_capacity ) { // Queue is full return false; } // Queue had empty slot with ticket k when we looked. Attempt to claim that slot. ticket tk=k; k = r.tail_counter.compare_and_swap( tk+1, tk ); if( k==tk ) break; // Another thread claimed the slot, so retry. } r.choose(k).push(src, k, *this, op_type); r.items_avail.notify( predicate_leq(k) ); return true; } ptrdiff_t concurrent_queue_base_v3::internal_size() const { __TBB_ASSERT( sizeof(ptrdiff_t)<=sizeof(size_t), NULL ); return ptrdiff_t(my_rep->tail_counter-my_rep->head_counter-my_rep->n_invalid_entries); } bool concurrent_queue_base_v3::internal_empty() const { ticket tc = my_rep->tail_counter; ticket hc = my_rep->head_counter; // if tc!=r.tail_counter, the queue was not empty at some point between the two reads. return ( tc==my_rep->tail_counter && ptrdiff_t(tc-hc-my_rep->n_invalid_entries)<=0 ); } void concurrent_queue_base_v3::internal_set_capacity( ptrdiff_t capacity, size_t /*item_sz*/ ) { my_capacity = capacity<0 ? concurrent_queue_rep::infinite_capacity : capacity; } void concurrent_queue_base_v3::internal_finish_clear() { size_t nq = my_rep->n_queue; for( size_t i=0; iarray[i].tail_page; __TBB_ASSERT( my_rep->array[i].head_page==tp, "at most one page should remain" ); if( tp!=NULL) { if( tp!=invalid_page ) deallocate_page( tp ); my_rep->array[i].tail_page = NULL; } } } void concurrent_queue_base_v3::internal_throw_exception() const { throw_exception( eid_bad_alloc ); } void concurrent_queue_base_v3::internal_assign( const concurrent_queue_base& src, copy_specifics op_type ) { items_per_page = src.items_per_page; my_capacity = src.my_capacity; // copy concurrent_queue_rep. my_rep->head_counter = src.my_rep->head_counter; my_rep->tail_counter = src.my_rep->tail_counter; my_rep->n_invalid_entries = src.my_rep->n_invalid_entries; // copy micro_queues for( size_t i = 0; in_queue; ++i ) my_rep->array[i].assign( src.my_rep->array[i], *this, op_type ); __TBB_ASSERT( my_rep->head_counter==src.my_rep->head_counter && my_rep->tail_counter==src.my_rep->tail_counter, "the source concurrent queue should not be concurrently modified." ); } void concurrent_queue_base_v3::assign( const concurrent_queue_base& src ) { internal_assign( src, copy ); } void concurrent_queue_base_v8::move_content( concurrent_queue_base_v8& src ) { internal_assign( src, move ); } //------------------------------------------------------------------------ // concurrent_queue_iterator_rep //------------------------------------------------------------------------ class concurrent_queue_iterator_rep: no_assign { public: ticket head_counter; const concurrent_queue_base& my_queue; const size_t offset_of_last; concurrent_queue_base::page* array[concurrent_queue_rep::n_queue]; concurrent_queue_iterator_rep( const concurrent_queue_base& queue, size_t offset_of_last_ ) : head_counter(queue.my_rep->head_counter), my_queue(queue), offset_of_last(offset_of_last_) { const concurrent_queue_rep& rep = *queue.my_rep; for( size_t k=0; ktail_counter ) { item = NULL; return true; } else { concurrent_queue_base::page* p = array[concurrent_queue_rep::index(k)]; __TBB_ASSERT(p,NULL); size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, my_queue.items_per_page ); item = static_cast(static_cast(p)) + offset_of_last + my_queue.item_size*i; return (p->mask & uintptr_t(1)<().allocate(1); new( my_rep ) concurrent_queue_iterator_rep(queue,offset_of_last); size_t k = my_rep->head_counter; if( !my_rep->get_item(my_item, k) ) advance(); } concurrent_queue_iterator_base_v3::concurrent_queue_iterator_base_v3( const concurrent_queue_base& queue ) { initialize(queue,0); } concurrent_queue_iterator_base_v3::concurrent_queue_iterator_base_v3( const concurrent_queue_base& queue, size_t offset_of_last ) { initialize(queue,offset_of_last); } void concurrent_queue_iterator_base_v3::assign( const concurrent_queue_iterator_base& other ) { if( my_rep!=other.my_rep ) { if( my_rep ) { cache_aligned_allocator().deallocate(my_rep, 1); my_rep = NULL; } if( other.my_rep ) { my_rep = cache_aligned_allocator().allocate(1); new( my_rep ) concurrent_queue_iterator_rep( *other.my_rep ); } } my_item = other.my_item; } void concurrent_queue_iterator_base_v3::advance() { __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" ); size_t k = my_rep->head_counter; const concurrent_queue_base& queue = my_rep->my_queue; #if TBB_USE_ASSERT void* tmp; my_rep->get_item(tmp,k); __TBB_ASSERT( my_item==tmp, NULL ); #endif /* TBB_USE_ASSERT */ size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, queue.items_per_page ); if( i==queue.items_per_page-1 ) { concurrent_queue_base::page*& root = my_rep->array[concurrent_queue_rep::index(k)]; root = root->next; } // advance k my_rep->head_counter = ++k; if( !my_rep->get_item(my_item, k) ) advance(); } concurrent_queue_iterator_base_v3::~concurrent_queue_iterator_base_v3() { //delete my_rep; cache_aligned_allocator().deallocate(my_rep, 1); my_rep = NULL; } } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_queue.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_concurrent_queue_H #define __TBB_concurrent_queue_H #include "internal/_concurrent_queue_impl.h" namespace tbb { namespace strict_ppl { //! A high-performance thread-safe non-blocking concurrent queue. /** Multiple threads may each push and pop concurrently. Assignment construction is not allowed. @ingroup containers */ template > class concurrent_queue: public internal::concurrent_queue_base_v3 { template friend class internal::concurrent_queue_iterator; //! Allocator type typedef typename A::template rebind::other page_allocator_type; page_allocator_type my_allocator; //! Allocates a block of size n (bytes) /*override*/ virtual void *allocate_block( size_t n ) { void *b = reinterpret_cast(my_allocator.allocate( n )); if( !b ) internal::throw_exception(internal::eid_bad_alloc); return b; } //! Deallocates block created by allocate_block. /*override*/ virtual void deallocate_block( void *b, size_t n ) { my_allocator.deallocate( reinterpret_cast(b), n ); } static void copy_construct_item(T* location, const void* src){ new (location) T(*static_cast(src)); } #if __TBB_CPP11_RVALUE_REF_PRESENT static void move_construct_item(T* location, const void* src) { new (location) T( std::move(*static_cast(const_cast(src))) ); } #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ public: //! Element type in the queue. typedef T value_type; //! Reference type typedef T& reference; //! Const reference type typedef const T& const_reference; //! Integral type for representing size of the queue. typedef size_t size_type; //! Difference type for iterator typedef ptrdiff_t difference_type; //! Allocator type typedef A allocator_type; //! Construct empty queue explicit concurrent_queue(const allocator_type& a = allocator_type()) : my_allocator( a ) { } //! [begin,end) constructor template concurrent_queue( InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : my_allocator( a ) { for( ; begin != end; ++begin ) this->push(*begin); } //! Copy constructor concurrent_queue( const concurrent_queue& src, const allocator_type& a = allocator_type()) : internal::concurrent_queue_base_v3(), my_allocator( a ) { this->assign( src, copy_construct_item ); } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move constructors concurrent_queue( concurrent_queue&& src ) : internal::concurrent_queue_base_v3(), my_allocator( std::move(src.my_allocator) ) { this->internal_swap( src ); } concurrent_queue( concurrent_queue&& src, const allocator_type& a ) : internal::concurrent_queue_base_v3(), my_allocator( a ) { // checking that memory allocated by one instance of allocator can be deallocated // with another if( my_allocator == src.my_allocator) { this->internal_swap( src ); } else { // allocators are different => performing per-element move this->assign( src, move_construct_item ); src.clear(); } } #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ //! Destroy queue ~concurrent_queue(); //! Enqueue an item at tail of queue. void push( const T& source ) { this->internal_push( &source, copy_construct_item ); } #if __TBB_CPP11_RVALUE_REF_PRESENT void push( T&& source ) { this->internal_push( &source, move_construct_item ); } #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT template void emplace( Arguments&&... args ) { push( T(std::forward( args )...) ); } #endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ //! Attempt to dequeue an item from head of queue. /** Does not wait for item to become available. Returns true if successful; false otherwise. */ bool try_pop( T& result ) { return this->internal_try_pop( &result ); } //! Return the number of items in the queue; thread unsafe size_type unsafe_size() const {return this->internal_size();} //! Equivalent to size()==0. bool empty() const {return this->internal_empty();} //! Clear the queue. not thread-safe. void clear() ; //! Return allocator object allocator_type get_allocator() const { return this->my_allocator; } typedef internal::concurrent_queue_iterator iterator; typedef internal::concurrent_queue_iterator const_iterator; //------------------------------------------------------------------------ // The iterators are intended only for debugging. They are slow and not thread safe. //------------------------------------------------------------------------ iterator unsafe_begin() {return iterator(*this);} iterator unsafe_end() {return iterator();} const_iterator unsafe_begin() const {return const_iterator(*this);} const_iterator unsafe_end() const {return const_iterator();} } ; template concurrent_queue::~concurrent_queue() { clear(); this->internal_finish_clear(); } template void concurrent_queue::clear() { while( !empty() ) { T value; this->internal_try_pop(&value); } } } // namespace strict_ppl //! A high-performance thread-safe blocking concurrent bounded queue. /** This is the pre-PPL TBB concurrent queue which supports boundedness and blocking semantics. Note that method names agree with the PPL-style concurrent queue. Multiple threads may each push and pop concurrently. Assignment construction is not allowed. @ingroup containers */ template > class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 { template friend class internal::concurrent_queue_iterator; //! Allocator type typedef typename A::template rebind::other page_allocator_type; page_allocator_type my_allocator; typedef typename concurrent_queue_base_v3::padded_page padded_page; typedef typename concurrent_queue_base_v3::copy_specifics copy_specifics; //! Class used to ensure exception-safety of method "pop" class destroyer: internal::no_copy { T& my_value; public: destroyer( T& value ) : my_value(value) {} ~destroyer() {my_value.~T();} }; T& get_ref( page& p, size_t index ) { __TBB_ASSERT( index(static_cast(&p))->last)[index]; } /*override*/ virtual void copy_item( page& dst, size_t index, const void* src ) { new( &get_ref(dst,index) ) T(*static_cast(src)); } #if __TBB_CPP11_RVALUE_REF_PRESENT /*override*/ virtual void move_item( page& dst, size_t index, const void* src ) { new( &get_ref(dst,index) ) T( std::move(*static_cast(const_cast(src))) ); } #else /*override*/ virtual void move_item( page&, size_t, const void* ) { __TBB_ASSERT( false, "Unreachable code" ); } #endif /*override*/ virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) { new( &get_ref(dst,dindex) ) T( get_ref( const_cast(src), sindex ) ); } #if __TBB_CPP11_RVALUE_REF_PRESENT /*override*/ virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) { new( &get_ref(dst,dindex) ) T( std::move(get_ref( const_cast(src), sindex )) ); } #else /*override*/ virtual void move_page_item( page&, size_t, const page&, size_t ) { __TBB_ASSERT( false, "Unreachable code" ); } #endif /*override*/ virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) { T& from = get_ref(src,index); destroyer d(from); *static_cast(dst) = tbb::internal::move( from ); } /*override*/ virtual page *allocate_page() { size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T); page *p = reinterpret_cast(my_allocator.allocate( n )); if( !p ) internal::throw_exception(internal::eid_bad_alloc); return p; } /*override*/ virtual void deallocate_page( page *p ) { size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T); my_allocator.deallocate( reinterpret_cast(p), n ); } public: //! Element type in the queue. typedef T value_type; //! Allocator type typedef A allocator_type; //! Reference type typedef T& reference; //! Const reference type typedef const T& const_reference; //! Integral type for representing size of the queue. /** Note that the size_type is a signed integral type. This is because the size can be negative if there are pending pops without corresponding pushes. */ typedef std::ptrdiff_t size_type; //! Difference type for iterator typedef std::ptrdiff_t difference_type; //! Construct empty queue explicit concurrent_bounded_queue(const allocator_type& a = allocator_type()) : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) { } //! Copy constructor concurrent_bounded_queue( const concurrent_bounded_queue& src, const allocator_type& a = allocator_type()) : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) { assign( src ); } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move constructors concurrent_bounded_queue( concurrent_bounded_queue&& src ) : concurrent_queue_base_v8( sizeof(T) ), my_allocator( std::move(src.my_allocator) ) { internal_swap( src ); } concurrent_bounded_queue( concurrent_bounded_queue&& src, const allocator_type& a ) : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) { // checking that memory allocated by one instance of allocator can be deallocated // with another if( my_allocator == src.my_allocator) { this->internal_swap( src ); } else { // allocators are different => performing per-element move this->move_content( src ); src.clear(); } } #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ //! [begin,end) constructor template concurrent_bounded_queue( InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) { for( ; begin != end; ++begin ) internal_push_if_not_full(&*begin); } //! Destroy queue ~concurrent_bounded_queue(); //! Enqueue an item at tail of queue. void push( const T& source ) { internal_push( &source ); } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move an item at tail of queue. void push( T&& source ) { internal_push_move( &source ); } #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT template void emplace( Arguments&&... args ) { push( T(std::forward( args )...) ); } #endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ //! Dequeue item from head of queue. /** Block until an item becomes available, and then dequeue it. */ void pop( T& destination ) { internal_pop( &destination ); } #if TBB_USE_EXCEPTIONS //! Abort all pending queue operations void abort() { internal_abort(); } #endif //! Enqueue an item at tail of queue if queue is not already full. /** Does not wait for queue to become not full. Returns true if item is pushed; false if queue was already full. */ bool try_push( const T& source ) { return internal_push_if_not_full( &source ); } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move an item at tail of queue if queue is not already full. /** Does not wait for queue to become not full. Returns true if item is pushed; false if queue was already full. */ bool try_push( T&& source ) { return internal_push_move_if_not_full( &source ); } #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT template bool try_emplace( Arguments&&... args ) { return try_push( T(std::forward( args )...) ); } #endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ //! Attempt to dequeue an item from head of queue. /** Does not wait for item to become available. Returns true if successful; false otherwise. */ bool try_pop( T& destination ) { return internal_pop_if_present( &destination ); } //! Return number of pushes minus number of pops. /** Note that the result can be negative if there are pops waiting for the corresponding pushes. The result can also exceed capacity() if there are push operations in flight. */ size_type size() const {return internal_size();} //! Equivalent to size()<=0. bool empty() const {return internal_empty();} //! Maximum number of allowed elements size_type capacity() const { return my_capacity; } //! Set the capacity /** Setting the capacity to 0 causes subsequent try_push operations to always fail, and subsequent push operations to block forever. */ void set_capacity( size_type new_capacity ) { internal_set_capacity( new_capacity, sizeof(T) ); } //! return allocator object allocator_type get_allocator() const { return this->my_allocator; } //! clear the queue. not thread-safe. void clear() ; typedef internal::concurrent_queue_iterator iterator; typedef internal::concurrent_queue_iterator const_iterator; //------------------------------------------------------------------------ // The iterators are intended only for debugging. They are slow and not thread safe. //------------------------------------------------------------------------ iterator unsafe_begin() {return iterator(*this);} iterator unsafe_end() {return iterator();} const_iterator unsafe_begin() const {return const_iterator(*this);} const_iterator unsafe_end() const {return const_iterator();} }; template concurrent_bounded_queue::~concurrent_bounded_queue() { clear(); internal_finish_clear(); } template void concurrent_bounded_queue::clear() { while( !empty() ) { T value; internal_pop_if_present(&value); } } using strict_ppl::concurrent_queue; } // namespace tbb #endif /* __TBB_concurrent_queue_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_unordered_map.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Container implementations in this header are based on PPL implementations provided by Microsoft. */ #ifndef __TBB_concurrent_unordered_map_H #define __TBB_concurrent_unordered_map_H #include "internal/_concurrent_unordered_impl.h" namespace tbb { namespace interface5 { // Template class for hash map traits template class concurrent_unordered_map_traits { protected: typedef std::pair value_type; typedef Key key_type; typedef Hash_compare hash_compare; typedef typename Allocator::template rebind::other allocator_type; enum { allow_multimapping = Allow_multimapping }; concurrent_unordered_map_traits() : my_hash_compare() {} concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {} class value_compare : public std::binary_function { friend class concurrent_unordered_map_traits; public: bool operator()(const value_type& left, const value_type& right) const { return (my_hash_compare(left.first, right.first)); } value_compare(const hash_compare& comparator) : my_hash_compare(comparator) {} protected: hash_compare my_hash_compare; // the comparator predicate for keys }; template static const Key& get_key(const std::pair& value) { return (value.first); } hash_compare my_hash_compare; // the comparator predicate for keys }; template , typename Key_equality = std::equal_to, typename Allocator = tbb::tbb_allocator > > class concurrent_unordered_map : public internal::concurrent_unordered_base< concurrent_unordered_map_traits, Allocator, false> > { // Base type definitions typedef internal::hash_compare hash_compare; typedef concurrent_unordered_map_traits traits_type; typedef internal::concurrent_unordered_base< traits_type > base_type; #if __TBB_EXTRA_DEBUG public: #endif using traits_type::allow_multimapping; public: using base_type::end; using base_type::find; using base_type::insert; // Type definitions typedef Key key_type; typedef typename base_type::value_type value_type; typedef T mapped_type; typedef Hasher hasher; typedef Key_equality key_equal; typedef hash_compare key_compare; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::size_type size_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator local_iterator; typedef typename base_type::const_iterator const_local_iterator; // Construction/destruction/copying explicit concurrent_unordered_map(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) { } concurrent_unordered_map(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) { } template concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) { insert(first, last); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from initializer_list concurrent_unordered_map(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) { this->insert(il.begin(),il.end()); } #endif //# __TBB_INITIALIZER_LISTS_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_map(const concurrent_unordered_map& table) : base_type(table) { } concurrent_unordered_map& operator=(const concurrent_unordered_map& table) { return static_cast(base_type::operator=(table)); } concurrent_unordered_map(concurrent_unordered_map&& table) : base_type(std::move(table)) { } concurrent_unordered_map& operator=(concurrent_unordered_map&& table) { return static_cast(base_type::operator=(std::move(table))); } #endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a) : base_type(table, a) { } #if __TBB_CPP11_RVALUE_REF_PRESENT concurrent_unordered_map(concurrent_unordered_map&& table, const Allocator& a) : base_type(std::move(table), a) { } #endif // Observers mapped_type& operator[](const key_type& key) { iterator where = find(key); if (where == end()) { where = insert(std::pair(key, mapped_type())).first; } return ((*where).second); } mapped_type& at(const key_type& key) { iterator where = find(key); if (where == end()) { tbb::internal::throw_exception(tbb::internal::eid_invalid_key); } return ((*where).second); } const mapped_type& at(const key_type& key) const { const_iterator where = find(key); if (where == end()) { tbb::internal::throw_exception(tbb::internal::eid_invalid_key); } return ((*where).second); } }; template < typename Key, typename T, typename Hasher = tbb::tbb_hash, typename Key_equality = std::equal_to, typename Allocator = tbb::tbb_allocator > > class concurrent_unordered_multimap : public internal::concurrent_unordered_base< concurrent_unordered_map_traits< Key, T, internal::hash_compare, Allocator, true> > { // Base type definitions typedef internal::hash_compare hash_compare; typedef concurrent_unordered_map_traits traits_type; typedef internal::concurrent_unordered_base base_type; #if __TBB_EXTRA_DEBUG public: #endif using traits_type::allow_multimapping; public: using base_type::insert; // Type definitions typedef Key key_type; typedef typename base_type::value_type value_type; typedef T mapped_type; typedef Hasher hasher; typedef Key_equality key_equal; typedef hash_compare key_compare; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::size_type size_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator local_iterator; typedef typename base_type::const_iterator const_local_iterator; // Construction/destruction/copying explicit concurrent_unordered_multimap(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) { } concurrent_unordered_multimap(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) { } template concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets,key_compare(_Hasher,_Key_equality), a) { insert(first, last); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from initializer_list concurrent_unordered_multimap(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) { this->insert(il.begin(),il.end()); } #endif //# __TBB_INITIALIZER_LISTS_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_multimap(const concurrent_unordered_multimap& table) : base_type(table) { } concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table) { return static_cast(base_type::operator=(table)); } concurrent_unordered_multimap(concurrent_unordered_multimap&& table) : base_type(std::move(table)) { } concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table) { return static_cast(base_type::operator=(std::move(table))); } #endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a) : base_type(table, a) { } #if __TBB_CPP11_RVALUE_REF_PRESENT concurrent_unordered_multimap(concurrent_unordered_multimap&& table, const Allocator& a) : base_type(std::move(table), a) { } #endif }; } // namespace interface5 using interface5::concurrent_unordered_map; using interface5::concurrent_unordered_multimap; } // namespace tbb #endif// __TBB_concurrent_unordered_map_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_unordered_set.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Container implementations in this header are based on PPL implementations provided by Microsoft. */ #ifndef __TBB_concurrent_unordered_set_H #define __TBB_concurrent_unordered_set_H #include "internal/_concurrent_unordered_impl.h" namespace tbb { namespace interface5 { // Template class for hash set traits template class concurrent_unordered_set_traits { protected: typedef Key value_type; typedef Key key_type; typedef Hash_compare hash_compare; typedef typename Allocator::template rebind::other allocator_type; enum { allow_multimapping = Allow_multimapping }; concurrent_unordered_set_traits() : my_hash_compare() {} concurrent_unordered_set_traits(const hash_compare& hc) : my_hash_compare(hc) {} typedef hash_compare value_compare; static const Key& get_key(const value_type& value) { return value; } hash_compare my_hash_compare; // the comparator predicate for keys }; template , typename Key_equality = std::equal_to, typename Allocator = tbb::tbb_allocator > class concurrent_unordered_set : public internal::concurrent_unordered_base< concurrent_unordered_set_traits, Allocator, false> > { // Base type definitions typedef internal::hash_compare hash_compare; typedef internal::concurrent_unordered_base< concurrent_unordered_set_traits > base_type; typedef concurrent_unordered_set_traits, Allocator, false> traits_type; #if __TBB_EXTRA_DEBUG public: #endif using traits_type::allow_multimapping; public: using base_type::insert; // Type definitions typedef Key key_type; typedef typename base_type::value_type value_type; typedef Key mapped_type; typedef Hasher hasher; typedef Key_equality key_equal; typedef hash_compare key_compare; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::size_type size_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator local_iterator; typedef typename base_type::const_iterator const_local_iterator; // Construction/destruction/copying explicit concurrent_unordered_set(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) { } concurrent_unordered_set(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) { } template concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) { insert(first, last); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from initializer_list concurrent_unordered_set(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) { this->insert(il.begin(),il.end()); } #endif //# __TBB_INITIALIZER_LISTS_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_set(const concurrent_unordered_set& table) : base_type(table) { } concurrent_unordered_set& operator=(const concurrent_unordered_set& table) { return static_cast(base_type::operator=(table)); } concurrent_unordered_set(concurrent_unordered_set&& table) : base_type(std::move(table)) { } concurrent_unordered_set& operator=(concurrent_unordered_set&& table) { return static_cast(base_type::operator=(std::move(table))); } #endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_set(const concurrent_unordered_set& table, const Allocator& a) : base_type(table, a) { } #if __TBB_CPP11_RVALUE_REF_PRESENT concurrent_unordered_set(concurrent_unordered_set&& table, const Allocator& a) : base_type(std::move(table), a) { } #endif //__TBB_CPP11_RVALUE_REF_PRESENT }; template , typename Key_equality = std::equal_to, typename Allocator = tbb::tbb_allocator > class concurrent_unordered_multiset : public internal::concurrent_unordered_base< concurrent_unordered_set_traits, Allocator, true> > { // Base type definitions typedef internal::hash_compare hash_compare; typedef concurrent_unordered_set_traits traits_type; typedef internal::concurrent_unordered_base< traits_type > base_type; #if __TBB_EXTRA_DEBUG public: #endif using traits_type::allow_multimapping; public: using base_type::insert; // Type definitions typedef Key key_type; typedef typename base_type::value_type value_type; typedef Key mapped_type; typedef Hasher hasher; typedef Key_equality key_equal; typedef hash_compare key_compare; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::size_type size_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator local_iterator; typedef typename base_type::const_iterator const_local_iterator; // Construction/destruction/copying explicit concurrent_unordered_multiset(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) { } concurrent_unordered_multiset(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) { } template concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) { insert(first, last); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from initializer_list concurrent_unordered_multiset(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) { this->insert(il.begin(),il.end()); } #endif //# __TBB_INITIALIZER_LISTS_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_multiset(const concurrent_unordered_multiset& table) : base_type(table) { } concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& table) { return static_cast(base_type::operator=(table)); } concurrent_unordered_multiset(concurrent_unordered_multiset&& table) : base_type(std::move(table)) { } concurrent_unordered_multiset& operator=(concurrent_unordered_multiset&& table) { return static_cast(base_type::operator=(std::move(table))); } #endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN concurrent_unordered_multiset(const concurrent_unordered_multiset& table, const Allocator& a) : base_type(table, a) { } #if __TBB_CPP11_RVALUE_REF_PRESENT concurrent_unordered_multiset(concurrent_unordered_multiset&& table, const Allocator& a) : base_type(std::move(table), a) { } #endif //__TBB_CPP11_RVALUE_REF_PRESENT }; } // namespace interface5 using interface5::concurrent_unordered_set; using interface5::concurrent_unordered_multiset; } // namespace tbb #endif// __TBB_concurrent_unordered_set_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_vector.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if (_MSC_VER) //MSVC 10 "deprecated" application of some std:: algorithms to raw pointers as not safe. //The reason is that destination is not checked against bounds/having enough place. #define _SCL_SECURE_NO_WARNINGS #endif #include "tbb/concurrent_vector.h" #include "tbb/cache_aligned_allocator.h" #include "tbb/tbb_exception.h" #include "tbb_misc.h" #include "itt_notify.h" #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #include //for uninitialized_fill_n #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif #if defined(_MSC_VER) && defined(_Wp64) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (disable: 4267) #endif using namespace std; namespace tbb { namespace internal { class concurrent_vector_base_v3::helper :no_assign { public: //! memory page size static const size_type page_size = 4096; inline static bool incompact_predicate(size_type size) { // assert size != 0, see source/test/test_vector_layout.cpp return size < page_size || ((size-1)%page_size < page_size/2 && size < page_size * 128); // for more details } inline static size_type find_segment_end(const concurrent_vector_base_v3 &v) { segment_t *s = v.my_segment; segment_index_t u = s==v.my_storage? pointers_per_short_table : pointers_per_long_table; segment_index_t k = 0; while( k < u && (s[k].load()==segment_allocated() )) ++k; return k; } // TODO: optimize accesses to my_first_block //! assign first segment size. k - is index of last segment to be allocated, not a count of segments inline static void assign_first_segment_if_necessary(concurrent_vector_base_v3 &v, segment_index_t k) { if( !v.my_first_block ) { /* There was a suggestion to set first segment according to incompact_predicate: while( k && !helper::incompact_predicate(segment_size( k ) * element_size) ) --k; // while previous vector size is compact, decrement // reasons to not do it: // * constructor(n) is not ready to accept fragmented segments // * backward compatibility due to that constructor // * current version gives additional guarantee and faster init. // * two calls to reserve() will give the same effect. */ v.my_first_block.compare_and_swap(k+1, 0); // store number of segments } } inline static void *allocate_segment(concurrent_vector_base_v3 &v, size_type n) { void *ptr = v.vector_allocator_ptr(v, n); if(!ptr) throw_exception(eid_bad_alloc); // check for bad allocation, throw exception return ptr; } //! Publish segment so other threads can see it. template inline static void publish_segment( segment_t& s, argument_type rhs ) { // see also itt_store_pointer_with_release_v3() ITT_NOTIFY( sync_releasing, &s ); s.store(rhs); } static size_type enable_segment(concurrent_vector_base_v3 &v, size_type k, size_type element_size, bool mark_as_not_used_on_failure = false); // TODO: rename as get_segments_table() and return segment pointer inline static void extend_table_if_necessary(concurrent_vector_base_v3 &v, size_type k, size_type start ) { if(k >= pointers_per_short_table && v.my_segment == v.my_storage) extend_segment_table(v, start ); } static void extend_segment_table(concurrent_vector_base_v3 &v, size_type start); struct segment_not_used_predicate: no_assign { segment_t &s; segment_not_used_predicate(segment_t &segment) : s(segment) {} bool operator()() const { return s.load() == segment_not_used ();} }; inline static segment_t& acquire_segment(concurrent_vector_base_v3 &v, size_type index, size_type element_size, bool owner) { segment_t &s = v.my_segment[index]; // TODO: pass v.my_segment as argument if( s.load() == segment_not_used() ) { // do not check for segment_allocation_failed state if( owner ) { enable_segment( v, index, element_size ); } else { ITT_NOTIFY(sync_prepare, &s); spin_wait_while(segment_not_used_predicate(s)); ITT_NOTIFY(sync_acquired, &s); } } else { ITT_NOTIFY(sync_acquired, &s); } if(s.load() != segment_allocated()) throw_exception(eid_bad_last_alloc); // throw custom exception, because it's hard to recover correctly after segment_allocation_failed state return s; } ///// non-static fields of helper for exception-safe iteration across segments segment_t *table;// TODO: review all segment_index_t as just short type size_type first_block, k, sz, start, finish, element_size; helper(segment_t *segments, size_type fb, size_type esize, size_type index, size_type s, size_type f) throw() : table(segments), first_block(fb), k(index), sz(0), start(s), finish(f), element_size(esize) {} inline void first_segment() throw() { __TBB_ASSERT( start <= finish, NULL ); __TBB_ASSERT( first_block || !finish, NULL ); if( k < first_block ) k = 0; // process solid segment at a time size_type base = segment_base( k ); __TBB_ASSERT( base <= start, NULL ); finish -= base; start -= base; // rebase as offsets from segment k sz = k ? base : segment_size( first_block ); // sz==base for k>0 } inline void next_segment() throw() { finish -= sz; start = 0; // offsets from next segment if( !k ) k = first_block; else { ++k; sz = segment_size( k ); } } template inline size_type apply(const F &func) { first_segment(); while( sz < finish ) { // work for more than one segment //TODO: remove extra load() of table[k] inside func func( table[k], table[k].load().pointer() + element_size*start, sz - start ); next_segment(); } func( table[k], table[k].load().pointer() + element_size*start, finish - start ); return k; } inline segment_value_t get_segment_value(size_type index, bool wait) { segment_t &s = table[index]; if( wait && (s.load() == segment_not_used()) ) { ITT_NOTIFY(sync_prepare, &s); spin_wait_while(segment_not_used_predicate(s)); ITT_NOTIFY(sync_acquired, &s); } return s.load(); } ~helper() { if( sz >= finish ) return; // the work is done correctly cleanup(); } //! Out of line code to assists destructor in infrequent cases. void cleanup(); /// TODO: turn into lambda functions when available struct init_body { internal_array_op2 func; const void *arg; init_body(internal_array_op2 init, const void *src) : func(init), arg(src) {} void operator()(segment_t &, void *begin, size_type n) const { func( begin, arg, n ); } }; struct safe_init_body { internal_array_op2 func; const void *arg; safe_init_body(internal_array_op2 init, const void *src) : func(init), arg(src) {} void operator()(segment_t &s, void *begin, size_type n) const { if(s.load() != segment_allocated()) throw_exception(eid_bad_last_alloc); // throw custom exception func( begin, arg, n ); } }; struct destroy_body { internal_array_op1 func; destroy_body(internal_array_op1 destroy) : func(destroy) {} void operator()(segment_t &s, void *begin, size_type n) const { if(s.load() == segment_allocated()) func( begin, n ); } }; }; void concurrent_vector_base_v3::helper::extend_segment_table(concurrent_vector_base_v3 &v, concurrent_vector_base_v3::size_type start) { if( start > segment_size(pointers_per_short_table) ) start = segment_size(pointers_per_short_table); // If other threads are trying to set pointers in the short segment, wait for them to finish their // assignments before we copy the short segment to the long segment. Note: grow_to_at_least depends on it for( segment_index_t i = 0; segment_base(i) < start && v.my_segment == v.my_storage; i++ ){ if(v.my_storage[i].load() == segment_not_used()) { ITT_NOTIFY(sync_prepare, &v.my_storage[i]); atomic_backoff backoff(true); while( v.my_segment == v.my_storage && (v.my_storage[i].load() == segment_not_used()) ) backoff.pause(); ITT_NOTIFY(sync_acquired, &v.my_storage[i]); } } if( v.my_segment != v.my_storage ) return; segment_t* new_segment_table = (segment_t*)NFS_Allocate( pointers_per_long_table, sizeof(segment_t), NULL ); __TBB_ASSERT(new_segment_table, "NFS_Allocate should throws exception if it cannot allocate the requested storage, and not returns zero pointer" ); std::uninitialized_fill_n(new_segment_table,size_t(pointers_per_long_table),segment_t()); //init newly allocated table //TODO: replace with static assert __TBB_STATIC_ASSERT(pointers_per_long_table >= pointers_per_short_table, "size of the big table should be not lesser than of the small one, as we copy values to it" ); std::copy(v.my_storage, v.my_storage+pointers_per_short_table, new_segment_table);//copy values from old table, here operator= of segment_t is used if( v.my_segment.compare_and_swap( new_segment_table, v.my_storage ) != v.my_storage ) NFS_Free( new_segment_table ); // else TODO: add ITT_NOTIFY signals for v.my_segment? } concurrent_vector_base_v3::size_type concurrent_vector_base_v3::helper::enable_segment(concurrent_vector_base_v3 &v, concurrent_vector_base_v3::size_type k, concurrent_vector_base_v3::size_type element_size, bool mark_as_not_used_on_failure ) { struct segment_scope_guard : no_copy{ segment_t* my_segment_ptr; bool my_mark_as_not_used; segment_scope_guard(segment_t& segment, bool mark_as_not_used) : my_segment_ptr(&segment), my_mark_as_not_used(mark_as_not_used){} void dismiss(){ my_segment_ptr = 0;} ~segment_scope_guard(){ if (my_segment_ptr){ if (!my_mark_as_not_used){ publish_segment(*my_segment_ptr, segment_allocation_failed()); }else{ publish_segment(*my_segment_ptr, segment_not_used()); } } } }; segment_t* s = v.my_segment; // TODO: optimize out as argument? Optimize accesses to my_first_block __TBB_ASSERT(s[k].load() != segment_allocated(), "concurrent operation during growth?"); size_type size_of_enabled_segment = segment_size(k); size_type size_to_allocate = size_of_enabled_segment; if( !k ) { assign_first_segment_if_necessary(v, default_initial_segments-1); size_of_enabled_segment = 2 ; size_to_allocate = segment_size(v.my_first_block); } else { spin_wait_while_eq( v.my_first_block, segment_index_t(0) ); } if( k && (k < v.my_first_block)){ //no need to allocate anything // s[0].array is changed only once ( 0 -> !0 ) and points to uninitialized memory segment_value_t array0 = s[0].load(); if(array0 == segment_not_used()){ // sync_prepare called only if there is a wait ITT_NOTIFY(sync_prepare, &s[0]); spin_wait_while( segment_not_used_predicate(s[0])); array0 = s[0].load(); } ITT_NOTIFY(sync_acquired, &s[0]); if(array0 != segment_allocated()) { // check for segment_allocation_failed state of initial segment publish_segment(s[k], segment_allocation_failed()); // and assign segment_allocation_failed state here throw_exception(eid_bad_last_alloc); // throw custom exception } publish_segment( s[k], static_cast(array0.pointer() + segment_base(k)*element_size ) ); } else { segment_scope_guard k_segment_guard(s[k], mark_as_not_used_on_failure); publish_segment(s[k], allocate_segment(v, size_to_allocate)); k_segment_guard.dismiss(); } return size_of_enabled_segment; } void concurrent_vector_base_v3::helper::cleanup() { if( !sz ) { // allocation failed, restore the table segment_index_t k_start = k, k_end = segment_index_of(finish-1); if( segment_base( k_start ) < start ) get_segment_value(k_start++, true); // wait if( k_start < first_block ) { segment_value_t segment0 = get_segment_value(0, start>0); // wait if necessary if((segment0 != segment_not_used()) && !k_start ) ++k_start; if(segment0 != segment_allocated()) for(; k_start < first_block && k_start <= k_end; ++k_start ) publish_segment(table[k_start], segment_allocation_failed()); else for(; k_start < first_block && k_start <= k_end; ++k_start ) publish_segment(table[k_start], static_cast( (segment0.pointer()) + segment_base(k_start)*element_size) ); } for(; k_start <= k_end; ++k_start ) // not in first block if(table[k_start].load() == segment_not_used()) publish_segment(table[k_start], segment_allocation_failed()); // fill allocated items first_segment(); goto recover; } while( sz <= finish ) { // there is still work for at least one segment next_segment(); recover: segment_value_t array = table[k].load(); if(array == segment_allocated()) std::memset( (array.pointer()) + element_size*start, 0, ((sz() != segment_allocated(), "Segment should have been freed. Please recompile with new TBB before using exceptions."); #endif my_segment = my_storage; NFS_Free( s ); } } concurrent_vector_base_v3::size_type concurrent_vector_base_v3::internal_capacity() const { return segment_base( helper::find_segment_end(*this) ); } void concurrent_vector_base_v3::internal_throw_exception(size_type t) const { switch(t) { case 0: throw_exception(eid_out_of_range); case 1: throw_exception(eid_segment_range_error); case 2: throw_exception(eid_index_range_error); } } void concurrent_vector_base_v3::internal_reserve( size_type n, size_type element_size, size_type max_size ) { if( n>max_size ) throw_exception(eid_reservation_length_error); __TBB_ASSERT( n, NULL ); helper::assign_first_segment_if_necessary(*this, segment_index_of(n-1)); segment_index_t k = helper::find_segment_end(*this); for( ; segment_base(k)() != segment_allocated()) helper::enable_segment(*this, k, element_size, true ); //in case of failure mark segments as not used } } //TODO: Looks like atomic loads can be done relaxed here, as the only place this method is called from //is the constructor, which does not require synchronization (for more details see comment in the // concurrent_vector_base constructor). void concurrent_vector_base_v3::internal_copy( const concurrent_vector_base_v3& src, size_type element_size, internal_array_op2 copy ) { size_type n = src.my_early_size; __TBB_ASSERT( my_segment == my_storage, NULL); if( n ) { helper::assign_first_segment_if_necessary(*this, segment_index_of(n-1)); size_type b; for( segment_index_t k=0; (b=segment_base(k))() == src.my_storage && k >= pointers_per_short_table) || (src.my_segment[k].load() != segment_allocated())) { my_early_size = b; break; } helper::extend_table_if_necessary(*this, k, 0); size_type m = helper::enable_segment(*this, k, element_size); if( m > n-b ) m = n-b; my_early_size = b+m; copy( my_segment[k].load().pointer(), src.my_segment[k].load().pointer(), m ); } } } void concurrent_vector_base_v3::internal_assign( const concurrent_vector_base_v3& src, size_type element_size, internal_array_op1 destroy, internal_array_op2 assign, internal_array_op2 copy ) { size_type n = src.my_early_size; while( my_early_size>n ) { // TODO: improve segment_index_t k = segment_index_of( my_early_size-1 ); size_type b=segment_base(k); size_type new_end = b>=n ? b : n; __TBB_ASSERT( my_early_size>new_end, NULL ); if( my_segment[k].load() != segment_allocated()) // check vector was broken before throw_exception(eid_bad_last_alloc); // throw custom exception // destructors are supposed to not throw any exceptions destroy( my_segment[k].load().pointer() + element_size*(new_end-b), my_early_size-new_end ); my_early_size = new_end; } size_type dst_initialized_size = my_early_size; my_early_size = n; helper::assign_first_segment_if_necessary(*this, segment_index_of(n)); size_type b; for( segment_index_t k=0; (b=segment_base(k))() == src.my_storage && k >= pointers_per_short_table) || src.my_segment[k].load() != segment_allocated() ) { // if source is damaged my_early_size = b; break; // TODO: it may cause undestructed items } helper::extend_table_if_necessary(*this, k, 0); if( my_segment[k].load() == segment_not_used()) helper::enable_segment(*this, k, element_size); else if( my_segment[k].load() != segment_allocated() ) throw_exception(eid_bad_last_alloc); // throw custom exception size_type m = k? segment_size(k) : 2; if( m > n-b ) m = n-b; size_type a = 0; if( dst_initialized_size>b ) { a = dst_initialized_size-b; if( a>m ) a = m; assign( my_segment[k].load().pointer(), src.my_segment[k].load().pointer(), a ); m -= a; a *= element_size; } if( m>0 ) copy( my_segment[k].load().pointer() + a, src.my_segment[k].load().pointer() + a, m ); } __TBB_ASSERT( src.my_early_size==n, "detected use of concurrent_vector::operator= with right side that was concurrently modified" ); } void* concurrent_vector_base_v3::internal_push_back( size_type element_size, size_type& index ) { __TBB_ASSERT( sizeof(my_early_size)==sizeof(uintptr_t), NULL ); size_type tmp = my_early_size.fetch_and_increment(); index = tmp; segment_index_t k_old = segment_index_of( tmp ); size_type base = segment_base(k_old); helper::extend_table_if_necessary(*this, k_old, tmp); segment_t& s = helper::acquire_segment(*this, k_old, element_size, base==tmp); size_type j_begin = tmp-base; return (void*)(s.load().pointer() + element_size*j_begin); } void concurrent_vector_base_v3::internal_grow_to_at_least( size_type new_size, size_type element_size, internal_array_op2 init, const void *src ) { internal_grow_to_at_least_with_result( new_size, element_size, init, src ); } concurrent_vector_base_v3::size_type concurrent_vector_base_v3::internal_grow_to_at_least_with_result( size_type new_size, size_type element_size, internal_array_op2 init, const void *src ) { size_type e = my_early_size; while( e= pointers_per_short_table && my_segment == my_storage ) { spin_wait_while_eq( my_segment, my_storage ); } for( i = 0; i <= k_old; ++i ) { segment_t &s = my_segment[i]; if(s.load() == segment_not_used()) { ITT_NOTIFY(sync_prepare, &s); atomic_backoff backoff(true); while( my_segment[i].load() == segment_not_used() ) // my_segment may change concurrently backoff.pause(); ITT_NOTIFY(sync_acquired, &s); } if( my_segment[i].load() != segment_allocated() ) throw_exception(eid_bad_last_alloc); } #if TBB_USE_DEBUG size_type capacity = internal_capacity(); __TBB_ASSERT( capacity >= new_size, NULL); #endif return e; } concurrent_vector_base_v3::size_type concurrent_vector_base_v3::internal_grow_by( size_type delta, size_type element_size, internal_array_op2 init, const void *src ) { size_type result = my_early_size.fetch_and_add(delta); internal_grow( result, result+delta, element_size, init, src ); return result; } void concurrent_vector_base_v3::internal_grow( const size_type start, size_type finish, size_type element_size, internal_array_op2 init, const void *src ) { __TBB_ASSERT( start k_start && k_end >= range.first_block; --k_end ) // allocate segments in reverse order helper::acquire_segment(*this, k_end, element_size, true/*for k_end>k_start*/); for(; k_start <= k_end; ++k_start ) // but allocate first block in straight order helper::acquire_segment(*this, k_start, element_size, segment_base( k_start ) >= start ); range.apply( helper::init_body(init, src) ); } void concurrent_vector_base_v3::internal_resize( size_type n, size_type element_size, size_type max_size, const void *src, internal_array_op1 destroy, internal_array_op2 init ) { size_type j = my_early_size; if( n > j ) { // construct items internal_reserve(n, element_size, max_size); my_early_size = n; helper for_each(my_segment, my_first_block, element_size, segment_index_of(j), j, n); for_each.apply( helper::safe_init_body(init, src) ); } else { my_early_size = n; helper for_each(my_segment, my_first_block, element_size, segment_index_of(n), n, j); for_each.apply( helper::destroy_body(destroy) ); } } concurrent_vector_base_v3::segment_index_t concurrent_vector_base_v3::internal_clear( internal_array_op1 destroy ) { __TBB_ASSERT( my_segment, NULL ); size_type j = my_early_size; my_early_size = 0; helper for_each(my_segment, my_first_block, 0, 0, 0, j); // element_size is safe to be zero if 'start' is zero j = for_each.apply( helper::destroy_body(destroy) ); size_type i = helper::find_segment_end(*this); return j < i? i : j+1; } void *concurrent_vector_base_v3::internal_compact( size_type element_size, void *table, internal_array_op1 destroy, internal_array_op2 copy ) { const size_type my_size = my_early_size; const segment_index_t k_end = helper::find_segment_end(*this); // allocated segments const segment_index_t k_stop = my_size? segment_index_of(my_size-1) + 1 : 0; // number of segments to store existing items: 0=>0; 1,2=>1; 3,4=>2; [5-8]=>3;.. const segment_index_t first_block = my_first_block; // number of merged segments, getting values from atomics segment_index_t k = first_block; if(k_stop < first_block) k = k_stop; else while (k < k_stop && helper::incompact_predicate(segment_size( k ) * element_size) ) k++; if(k_stop == k_end && k == first_block) return NULL; segment_t *const segment_table = my_segment; internal_segments_table &old = *static_cast( table ); //this call is left here for sake of backward compatibility, and as a placeholder for table initialization std::fill_n(old.table,sizeof(old.table)/sizeof(old.table[0]),segment_t()); old.first_block=0; if ( k != first_block && k ) // first segment optimization { // exception can occur here void *seg = helper::allocate_segment(*this, segment_size(k)); old.table[0].store(seg); old.first_block = k; // fill info for freeing new segment if exception occurs // copy items to the new segment size_type my_segment_size = segment_size( first_block ); for (segment_index_t i = 0, j = 0; i < k && j < my_size; j = my_segment_size) { __TBB_ASSERT( segment_table[i].load() == segment_allocated(), NULL); void *s = static_cast( static_cast(seg) + segment_base(i)*element_size ); //TODO: refactor to use std::min if(j + my_segment_size >= my_size) my_segment_size = my_size - j; __TBB_TRY { // exception can occur here copy( s, segment_table[i].load().pointer(), my_segment_size ); } __TBB_CATCH(...) { // destroy all the already copied items helper for_each(&old.table[0], old.first_block, element_size, 0, 0, segment_base(i)+ my_segment_size); for_each.apply( helper::destroy_body(destroy) ); __TBB_RETHROW(); } my_segment_size = i? segment_size( ++i ) : segment_size( i = first_block ); } // commit the changes std::copy(segment_table,segment_table + k,old.table); for (segment_index_t i = 0; i < k; i++) { segment_table[i].store(static_cast( static_cast(seg) + segment_base(i)*element_size )); } old.first_block = first_block; my_first_block = k; // now, first_block != my_first_block // destroy original copies my_segment_size = segment_size( first_block ); // old.first_block actually for (segment_index_t i = 0, j = 0; i < k && j < my_size; j = my_segment_size) { if(j + my_segment_size >= my_size) my_segment_size = my_size - j; // destructors are supposed to not throw any exceptions destroy( old.table[i].load().pointer(), my_segment_size ); my_segment_size = i? segment_size( ++i ) : segment_size( i = first_block ); } } // free unnecessary segments allocated by reserve() call if ( k_stop < k_end ) { old.first_block = first_block; std::copy(segment_table+k_stop, segment_table+k_end, old.table+k_stop ); std::fill_n(segment_table+k_stop, (k_end-k_stop), segment_t()); if( !k ) my_first_block = 0; } return table; } void concurrent_vector_base_v3::internal_swap(concurrent_vector_base_v3& v) { size_type my_sz = my_early_size.load(); size_type v_sz = v.my_early_size.load(); if(!my_sz && !v_sz) return; bool my_was_short = (my_segment.load() == my_storage); bool v_was_short = (v.my_segment.load() == v.my_storage); //In C++11, this would be: swap(my_storage, v.my_storage); for (int i=0; i < pointers_per_short_table; ++i){ swap(my_storage[i], v.my_storage[i]); } tbb::internal::swap(my_first_block, v.my_first_block); tbb::internal::swap(my_segment, v.my_segment); if (my_was_short){ v.my_segment.store(v.my_storage); } if(v_was_short){ my_segment.store(my_storage); } my_early_size.store(v_sz); v.my_early_size.store(my_sz); } } // namespace internal } // tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/concurrent_vector.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_concurrent_vector_H #define __TBB_concurrent_vector_H #include "tbb_stddef.h" #include "tbb_exception.h" #include "atomic.h" #include "cache_aligned_allocator.h" #include "blocked_range.h" #include "tbb_machine.h" #include "tbb_profiling.h" #include #include // for memset() #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #include #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif #if _MSC_VER==1500 && !__INTEL_COMPILER // VS2008/VC9 seems to have an issue; limits pull in math.h #pragma warning( push ) #pragma warning( disable: 4985 ) #endif #include /* std::numeric_limits */ #if _MSC_VER==1500 && !__INTEL_COMPILER #pragma warning( pop ) #endif #if __TBB_INITIALIZER_LISTS_PRESENT #include #endif #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (push) #if defined(_Wp64) #pragma warning (disable: 4267) #endif #pragma warning (disable: 4127) //warning C4127: conditional expression is constant #endif namespace tbb { template > class concurrent_vector; template class vector_iterator; //! @cond INTERNAL namespace internal { //! Bad allocation marker static void *const vector_allocation_error_flag = reinterpret_cast(size_t(63)); //! Exception helper function template void handle_unconstructed_elements(T* array, size_t n_of_elements){ std::memset(array, 0, n_of_elements * sizeof(T)); } //! Base class of concurrent vector implementation. /** @ingroup containers */ class concurrent_vector_base_v3 { protected: // Basic types declarations typedef size_t segment_index_t; typedef size_t size_type; // Using enumerations due to Mac linking problems of static const variables enum { // Size constants default_initial_segments = 1, // 2 initial items //! Number of slots for segment pointers inside the class pointers_per_short_table = 3, // to fit into 8 words of entire structure pointers_per_long_table = sizeof(segment_index_t) * 8 // one segment per bit }; struct segment_not_used {}; struct segment_allocated {}; struct segment_allocation_failed {}; class segment_t; class segment_value_t { void* array; private: //TODO: More elegant way to grant access to selected functions _only_? friend class segment_t; explicit segment_value_t(void* an_array):array(an_array) {} public: friend bool operator==(segment_value_t const& lhs, segment_not_used ) { return lhs.array == 0;} friend bool operator==(segment_value_t const& lhs, segment_allocated) { return lhs.array > internal::vector_allocation_error_flag;} friend bool operator==(segment_value_t const& lhs, segment_allocation_failed) { return lhs.array == internal::vector_allocation_error_flag;} template friend bool operator!=(segment_value_t const& lhs, argument_type arg) { return ! (lhs == arg);} template T* pointer() const { return static_cast(const_cast(array)); } }; // Segment pointer. class segment_t { atomic array; public: segment_t(){ store(segment_not_used());} //Copy ctor and assignment operator are defined to ease using of stl algorithms. //These algorithms usually not a synchronization point, so, semantic is //intentionally relaxed here. segment_t(segment_t const& rhs ){ array.store(rhs.array.load());} void swap(segment_t & rhs ){ tbb::internal::swap(array, rhs.array); } segment_t& operator=(segment_t const& rhs ){ array.store(rhs.array.load()); return *this; } template segment_value_t load() const { return segment_value_t(array.load());} template void store(segment_not_used) { array.store(0); } template void store(segment_allocation_failed) { __TBB_ASSERT(load() != segment_allocated(),"transition from \"allocated\" to \"allocation failed\" state looks non-logical"); array.store(internal::vector_allocation_error_flag); } template void store(void* allocated_segment_pointer) __TBB_NOEXCEPT(true) { __TBB_ASSERT(segment_value_t(allocated_segment_pointer) == segment_allocated(), "other overloads of store should be used for marking segment as not_used or allocation_failed" ); array.store(allocated_segment_pointer); } #if TBB_USE_ASSERT ~segment_t() { __TBB_ASSERT(load() != segment_allocated(), "should have been freed by clear" ); } #endif /* TBB_USE_ASSERT */ }; friend void swap(segment_t & , segment_t & ) __TBB_NOEXCEPT(true); // Data fields //! allocator function pointer void* (*vector_allocator_ptr)(concurrent_vector_base_v3 &, size_t); //! count of segments in the first block atomic my_first_block; //! Requested size of vector atomic my_early_size; //! Pointer to the segments table atomic my_segment; //! embedded storage of segment pointers segment_t my_storage[pointers_per_short_table]; // Methods concurrent_vector_base_v3() { //Here the semantic is intentionally relaxed. //The reason this is next: //Object that is in middle of construction (i.e. its constructor is not yet finished) //cannot be used concurrently until the construction is finished. //Thus to flag other threads that construction is finished, some synchronization with //acquire-release semantic should be done by the (external) code that uses the vector. //So, no need to do the synchronization inside the vector. my_early_size.store(0); my_first_block.store(0); // here is not default_initial_segments my_segment.store(my_storage); } __TBB_EXPORTED_METHOD ~concurrent_vector_base_v3(); //these helpers methods use the fact that segments are allocated so //that every segment size is a (increasing) power of 2. //with one exception 0 segment has size of 2 as well segment 1; //e.g. size of segment with index of 3 is 2^3=8; static segment_index_t segment_index_of( size_type index ) { return segment_index_t( __TBB_Log2( index|1 ) ); } static segment_index_t segment_base( segment_index_t k ) { return (segment_index_t(1)< friend class vector_iterator; }; inline void swap(concurrent_vector_base_v3::segment_t & lhs, concurrent_vector_base_v3::segment_t & rhs) __TBB_NOEXCEPT(true) { lhs.swap(rhs); } typedef concurrent_vector_base_v3 concurrent_vector_base; //! Meets requirements of a forward iterator for STL and a Value for a blocked_range.*/ /** Value is either the T or const T type of the container. @ingroup containers */ template class vector_iterator { //! concurrent_vector over which we are iterating. Container* my_vector; //! Index into the vector size_t my_index; //! Caches my_vector->internal_subscript(my_index) /** NULL if cached value is not available */ mutable Value* my_item; template friend vector_iterator operator+( ptrdiff_t offset, const vector_iterator& v ); template friend bool operator==( const vector_iterator& i, const vector_iterator& j ); template friend bool operator<( const vector_iterator& i, const vector_iterator& j ); template friend ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ); template friend class internal::vector_iterator; #if !defined(_MSC_VER) || defined(__INTEL_COMPILER) template friend class tbb::concurrent_vector; #else public: // workaround for MSVC #endif vector_iterator( const Container& vector, size_t index, void *ptr = 0 ) : my_vector(const_cast(&vector)), my_index(index), my_item(static_cast(ptr)) {} public: //! Default constructor vector_iterator() : my_vector(NULL), my_index(~size_t(0)), my_item(NULL) {} vector_iterator( const vector_iterator& other ) : my_vector(other.my_vector), my_index(other.my_index), my_item(other.my_item) {} vector_iterator operator+( ptrdiff_t offset ) const { return vector_iterator( *my_vector, my_index+offset ); } vector_iterator &operator+=( ptrdiff_t offset ) { my_index+=offset; my_item = NULL; return *this; } vector_iterator operator-( ptrdiff_t offset ) const { return vector_iterator( *my_vector, my_index-offset ); } vector_iterator &operator-=( ptrdiff_t offset ) { my_index-=offset; my_item = NULL; return *this; } Value& operator*() const { Value* item = my_item; if( !item ) { item = my_item = &my_vector->internal_subscript(my_index); } __TBB_ASSERT( item==&my_vector->internal_subscript(my_index), "corrupt cache" ); return *item; } Value& operator[]( ptrdiff_t k ) const { return my_vector->internal_subscript(my_index+k); } Value* operator->() const {return &operator*();} //! Pre increment vector_iterator& operator++() { size_t element_index = ++my_index; if( my_item ) { //TODO: consider using of knowledge about "first_block optimization" here as well? if( concurrent_vector_base::is_first_element_in_segment(element_index)) { //if the iterator crosses a segment boundary, the pointer become invalid //as possibly next segment is in another memory location my_item= NULL; } else { ++my_item; } } return *this; } //! Pre decrement vector_iterator& operator--() { __TBB_ASSERT( my_index>0, "operator--() applied to iterator already at beginning of concurrent_vector" ); size_t element_index = my_index--; if( my_item ) { if(concurrent_vector_base::is_first_element_in_segment(element_index)) { //if the iterator crosses a segment boundary, the pointer become invalid //as possibly next segment is in another memory location my_item= NULL; } else { --my_item; } } return *this; } //! Post increment vector_iterator operator++(int) { vector_iterator result = *this; operator++(); return result; } //! Post decrement vector_iterator operator--(int) { vector_iterator result = *this; operator--(); return result; } // STL support typedef ptrdiff_t difference_type; typedef Value value_type; typedef Value* pointer; typedef Value& reference; typedef std::random_access_iterator_tag iterator_category; }; template vector_iterator operator+( ptrdiff_t offset, const vector_iterator& v ) { return vector_iterator( *v.my_vector, v.my_index+offset ); } template bool operator==( const vector_iterator& i, const vector_iterator& j ) { return i.my_index==j.my_index && i.my_vector == j.my_vector; } template bool operator!=( const vector_iterator& i, const vector_iterator& j ) { return !(i==j); } template bool operator<( const vector_iterator& i, const vector_iterator& j ) { return i.my_index bool operator>( const vector_iterator& i, const vector_iterator& j ) { return j bool operator>=( const vector_iterator& i, const vector_iterator& j ) { return !(i bool operator<=( const vector_iterator& i, const vector_iterator& j ) { return !(j ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ) { return ptrdiff_t(i.my_index)-ptrdiff_t(j.my_index); } template class allocator_base { public: typedef typename A::template rebind::other allocator_type; allocator_type my_allocator; allocator_base(const allocator_type &a = allocator_type() ) : my_allocator(a) {} }; } // namespace internal //! @endcond //! Concurrent vector container /** concurrent_vector is a container having the following main properties: - It provides random indexed access to its elements. The index of the first element is 0. - It ensures safe concurrent growing its size (different threads can safely append new elements). - Adding new elements does not invalidate existing iterators and does not change indices of existing items. @par Compatibility The class meets all Container Requirements and Reversible Container Requirements from C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1). But it doesn't meet Sequence Requirements due to absence of insert() and erase() methods. @par Exception Safety Methods working with memory allocation and/or new elements construction can throw an exception if allocator fails to allocate memory or element's default constructor throws one. Concurrent vector's element of type T must conform to the following requirements: - Throwing an exception is forbidden for destructor of T. - Default constructor of T must not throw an exception OR its non-virtual destructor must safely work when its object memory is zero-initialized. . Otherwise, the program's behavior is undefined. @par If an exception happens inside growth or assignment operation, an instance of the vector becomes invalid unless it is stated otherwise in the method documentation. Invalid state means: - There are no guarantees that all items were initialized by a constructor. The rest of items is zero-filled, including item where exception happens. - An invalid vector instance cannot be repaired; it is unable to grow anymore. - Size and capacity reported by the vector are incorrect, and calculated as if the failed operation were successful. - Attempt to access not allocated elements using operator[] or iterators results in access violation or segmentation fault exception, and in case of using at() method a C++ exception is thrown. . If a concurrent grow operation successfully completes, all the elements it has added to the vector will remain valid and accessible even if one of subsequent grow operations fails. @par Fragmentation Unlike an STL vector, a concurrent_vector does not move existing elements if it needs to allocate more memory. The container is divided into a series of contiguous arrays of elements. The first reservation, growth, or assignment operation determines the size of the first array. Using small number of elements as initial size incurs fragmentation that may increase element access time. Internal layout can be optimized by method compact() that merges several smaller arrays into one solid. @par Changes since TBB 2.1 - Fixed guarantees of concurrent_vector::size() and grow_to_at_least() methods to assure elements are allocated. - Methods end()/rbegin()/back() are partly thread-safe since they use size() to get the end of vector - Added resize() methods (not thread-safe) - Added cbegin/cend/crbegin/crend methods - Changed return type of methods grow* and push_back to iterator @par Changes since TBB 2.0 - Implemented exception-safety guarantees - Added template argument for allocator - Added allocator argument in constructors - Faster index calculation - First growth call specifies a number of segments to be merged in the first allocation. - Fixed memory blow up for swarm of vector's instances of small size - Added grow_by(size_type n, const_reference t) growth using copying constructor to init new items. - Added STL-like constructors. - Added operators ==, < and derivatives - Added at() method, approved for using after an exception was thrown inside the vector - Added get_allocator() method. - Added assign() methods - Added compact() method to defragment first segments - Added swap() method - range() defaults on grainsize = 1 supporting auto grainsize algorithms. @ingroup containers */ template class concurrent_vector: protected internal::allocator_base, private internal::concurrent_vector_base { private: template class generic_range_type: public blocked_range { public: typedef T value_type; typedef T& reference; typedef const T& const_reference; typedef I iterator; typedef ptrdiff_t difference_type; generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range(begin_,end_,grainsize_) {} template generic_range_type( const generic_range_type& r) : blocked_range(r.begin(),r.end(),r.grainsize()) {} generic_range_type( generic_range_type& r, split ) : blocked_range(r,split()) {} }; template friend class internal::vector_iterator; public: //------------------------------------------------------------------------ // STL compatible types //------------------------------------------------------------------------ typedef internal::concurrent_vector_base_v3::size_type size_type; typedef typename internal::allocator_base::allocator_type allocator_type; typedef T value_type; typedef ptrdiff_t difference_type; typedef T& reference; typedef const T& const_reference; typedef T *pointer; typedef const T *const_pointer; typedef internal::vector_iterator iterator; typedef internal::vector_iterator const_iterator; #if !defined(_MSC_VER) || _CPPLIB_VER>=300 // Assume ISO standard definition of std::reverse_iterator typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #else // Use non-standard std::reverse_iterator typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #endif /* defined(_MSC_VER) && (_MSC_VER<1300) */ //------------------------------------------------------------------------ // Parallel algorithm support //------------------------------------------------------------------------ typedef generic_range_type range_type; typedef generic_range_type const_range_type; //------------------------------------------------------------------------ // STL compatible constructors & destructors //------------------------------------------------------------------------ //! Construct empty vector. explicit concurrent_vector(const allocator_type &a = allocator_type()) : internal::allocator_base(a), internal::concurrent_vector_base() { vector_allocator_ptr = &internal_allocator; } //Constructors are not required to have synchronization //(for more details see comment in the concurrent_vector_base constructor). #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from initializer_list concurrent_vector(std::initializer_list init_list, const allocator_type &a = allocator_type()) : internal::allocator_base(a), internal::concurrent_vector_base() { vector_allocator_ptr = &internal_allocator; __TBB_TRY { internal_assign_iterators(init_list.begin(), init_list.end()); } __TBB_CATCH(...) { segment_t *table = my_segment.load();; internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); __TBB_RETHROW(); } } #endif //# __TBB_INITIALIZER_LISTS_PRESENT //! Copying constructor concurrent_vector( const concurrent_vector& vector, const allocator_type& a = allocator_type() ) : internal::allocator_base(a), internal::concurrent_vector_base() { vector_allocator_ptr = &internal_allocator; __TBB_TRY { internal_copy(vector, sizeof(T), ©_array); } __TBB_CATCH(...) { segment_t *table = my_segment.load(); internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); __TBB_RETHROW(); } } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move constructor //TODO add __TBB_NOEXCEPT(true) and static_assert(std::has_nothrow_move_constructor::value) concurrent_vector( concurrent_vector&& source) : internal::allocator_base(std::move(source)), internal::concurrent_vector_base() { vector_allocator_ptr = &internal_allocator; concurrent_vector_base_v3::internal_swap(source); } concurrent_vector( concurrent_vector&& source, const allocator_type& a) : internal::allocator_base(a), internal::concurrent_vector_base() { vector_allocator_ptr = &internal_allocator; //C++ standard requires instances of an allocator being compared for equality, //which means that memory allocated by one instance is possible to deallocate with the other one. if (a == source.my_allocator) { concurrent_vector_base_v3::internal_swap(source); } else { __TBB_TRY { internal_copy(source, sizeof(T), &move_array); } __TBB_CATCH(...) { segment_t *table = my_segment.load(); internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); __TBB_RETHROW(); } } } #endif //! Copying constructor for vector with different allocator type template concurrent_vector( const concurrent_vector& vector, const allocator_type& a = allocator_type() ) : internal::allocator_base(a), internal::concurrent_vector_base() { vector_allocator_ptr = &internal_allocator; __TBB_TRY { internal_copy(vector.internal_vector_base(), sizeof(T), ©_array); } __TBB_CATCH(...) { segment_t *table = my_segment.load(); internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); __TBB_RETHROW(); } } //! Construction with initial size specified by argument n explicit concurrent_vector(size_type n) { vector_allocator_ptr = &internal_allocator; __TBB_TRY { internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array ); } __TBB_CATCH(...) { segment_t *table = my_segment.load(); internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); __TBB_RETHROW(); } } //! Construction with initial size specified by argument n, initialization by copying of t, and given allocator instance concurrent_vector(size_type n, const_reference t, const allocator_type& a = allocator_type()) : internal::allocator_base(a) { vector_allocator_ptr = &internal_allocator; __TBB_TRY { internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); } __TBB_CATCH(...) { segment_t *table = my_segment.load(); internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); __TBB_RETHROW(); } } //! Construction with copying iteration range and given allocator instance template concurrent_vector(I first, I last, const allocator_type &a = allocator_type()) : internal::allocator_base(a) { vector_allocator_ptr = &internal_allocator; __TBB_TRY { internal_assign_range(first, last, static_cast::is_integer> *>(0) ); } __TBB_CATCH(...) { segment_t *table = my_segment.load(); internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); __TBB_RETHROW(); } } //! Assignment concurrent_vector& operator=( const concurrent_vector& vector ) { if( this != &vector ) internal_assign(vector, sizeof(T), &destroy_array, &assign_array, ©_array); return *this; } #if __TBB_CPP11_RVALUE_REF_PRESENT //TODO: add __TBB_NOEXCEPT() //! Move assignment concurrent_vector& operator=( concurrent_vector&& other ) { __TBB_ASSERT(this != &other, "Move assignment to itself is prohibited "); typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; if(pocma_t::value || this->my_allocator == other.my_allocator) { concurrent_vector trash (std::move(*this)); internal_swap(other); if (pocma_t::value) { this->my_allocator = std::move(other.my_allocator); } } else { internal_assign(other, sizeof(T), &destroy_array, &move_assign_array, &move_array); } return *this; } #endif //TODO: add an template assignment operator? (i.e. with different element type) //! Assignment for vector with different allocator type template concurrent_vector& operator=( const concurrent_vector& vector ) { if( static_cast( this ) != static_cast( &vector ) ) internal_assign(vector.internal_vector_base(), sizeof(T), &destroy_array, &assign_array, ©_array); return *this; } #if __TBB_INITIALIZER_LISTS_PRESENT //! Assignment for initializer_list concurrent_vector& operator=( std::initializer_list init_list ) { internal_clear(&destroy_array); internal_assign_iterators(init_list.begin(), init_list.end()); return *this; } #endif //#if __TBB_INITIALIZER_LISTS_PRESENT //------------------------------------------------------------------------ // Concurrent operations //------------------------------------------------------------------------ //! Grow by "delta" elements. /** Returns iterator pointing to the first new element. */ iterator grow_by( size_type delta ) { return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size.load()); } //! Grow by "delta" elements using copying constructor. /** Returns iterator pointing to the first new element. */ iterator grow_by( size_type delta, const_reference t ) { return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast(&t) ) : my_early_size.load()); } /** Returns iterator pointing to the first new element. */ template iterator grow_by( I first, I last ) { typename std::iterator_traits::difference_type delta = std::distance(first, last); __TBB_ASSERT( delta >= 0, NULL); return iterator(*this, delta ? internal_grow_by(delta, sizeof(T), ©_range, static_cast(&first)) : my_early_size.load()); } #if __TBB_INITIALIZER_LISTS_PRESENT /** Returns iterator pointing to the first new element. */ iterator grow_by( std::initializer_list init_list ) { return grow_by( init_list.begin(), init_list.end() ); } #endif //#if __TBB_INITIALIZER_LISTS_PRESENT //! Append minimal sequence of elements such that size()>=n. /** The new elements are default constructed. Blocks until all elements in range [0..n) are allocated. May return while other elements are being constructed by other threads. Returns iterator that points to beginning of appended sequence. If no elements were appended, returns iterator pointing to nth element. */ iterator grow_to_at_least( size_type n ) { size_type m=0; if( n ) { m = internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array, NULL ); if( m>n ) m=n; } return iterator(*this, m); }; /** Analogous to grow_to_at_least( size_type n ) with exception that the new elements are initialized by copying of t instead of default construction. */ iterator grow_to_at_least( size_type n, const_reference t ) { size_type m=0; if( n ) { m = internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array_by, &t); if( m>n ) m=n; } return iterator(*this, m); }; //! Push item /** Returns iterator pointing to the new element. */ iterator push_back( const_reference item ) { size_type k; T* ptr = static_cast(internal_push_back(sizeof(T),k)); element_construction_guard g(ptr); new(ptr) T(item); g.dismiss(); return iterator(*this, k, ptr); } #if __TBB_CPP11_RVALUE_REF_PRESENT //! Push item, move-aware /** Returns iterator pointing to the new element. */ iterator push_back( T&& item ) { size_type k; T* ptr = static_cast(internal_push_back(sizeof(T),k)); element_construction_guard g(ptr); new(ptr) T(std::move(item)); g.dismiss(); return iterator(*this, k, ptr); } #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT //! Push item, create item "in place" with provided arguments /** Returns iterator pointing to the new element. */ template iterator emplace_back( Args&&... args) { size_type k; T* ptr = static_cast(internal_push_back(sizeof(T),k)); element_construction_guard g(ptr); new(ptr) T( std::forward(args)...); g.dismiss(); return iterator(*this, k, ptr); } #endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT #endif //__TBB_CPP11_RVALUE_REF_PRESENT //! Get reference to element at given index. /** This method is thread-safe for concurrent reads, and also while growing the vector, as long as the calling thread has checked that index < size(). */ reference operator[]( size_type index ) { return internal_subscript(index); } //! Get const reference to element at given index. const_reference operator[]( size_type index ) const { return internal_subscript(index); } //! Get reference to element at given index. Throws exceptions on errors. reference at( size_type index ) { return internal_subscript_with_exceptions(index); } //! Get const reference to element at given index. Throws exceptions on errors. const_reference at( size_type index ) const { return internal_subscript_with_exceptions(index); } //! Get range for iterating with parallel algorithms range_type range( size_t grainsize = 1 ) { return range_type( begin(), end(), grainsize ); } //! Get const range for iterating with parallel algorithms const_range_type range( size_t grainsize = 1 ) const { return const_range_type( begin(), end(), grainsize ); } //------------------------------------------------------------------------ // Capacity //------------------------------------------------------------------------ //! Return size of vector. It may include elements under construction size_type size() const { size_type sz = my_early_size, cp = internal_capacity(); return cp < sz ? cp : sz; } //! Return false if vector is not empty or has elements under construction at least. bool empty() const {return !my_early_size;} //! Maximum size to which array can grow without allocating more memory. Concurrent allocations are not included in the value. size_type capacity() const {return internal_capacity();} //! Allocate enough space to grow to size n without having to allocate more memory later. /** Like most of the methods provided for STL compatibility, this method is *not* thread safe. The capacity afterwards may be bigger than the requested reservation. */ void reserve( size_type n ) { if( n ) internal_reserve(n, sizeof(T), max_size()); } //! Resize the vector. Not thread-safe. void resize( size_type n ) { internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array ); } //! Resize the vector, copy t for new elements. Not thread-safe. void resize( size_type n, const_reference t ) { internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); } //! Optimize memory usage and fragmentation. void shrink_to_fit(); //! Upper bound on argument to reserve. size_type max_size() const {return (~size_type(0))/sizeof(T);} //------------------------------------------------------------------------ // STL support //------------------------------------------------------------------------ //! start iterator iterator begin() {return iterator(*this,0);} //! end iterator iterator end() {return iterator(*this,size());} //! start const iterator const_iterator begin() const {return const_iterator(*this,0);} //! end const iterator const_iterator end() const {return const_iterator(*this,size());} //! start const iterator const_iterator cbegin() const {return const_iterator(*this,0);} //! end const iterator const_iterator cend() const {return const_iterator(*this,size());} //! reverse start iterator reverse_iterator rbegin() {return reverse_iterator(end());} //! reverse end iterator reverse_iterator rend() {return reverse_iterator(begin());} //! reverse start const iterator const_reverse_iterator rbegin() const {return const_reverse_iterator(end());} //! reverse end const iterator const_reverse_iterator rend() const {return const_reverse_iterator(begin());} //! reverse start const iterator const_reverse_iterator crbegin() const {return const_reverse_iterator(end());} //! reverse end const iterator const_reverse_iterator crend() const {return const_reverse_iterator(begin());} //! the first item reference front() { __TBB_ASSERT( size()>0, NULL); return (my_segment[0].template load().template pointer())[0]; } //! the first item const const_reference front() const { __TBB_ASSERT( size()>0, NULL); return static_cast(my_segment[0].array)[0]; } //! the last item reference back() { __TBB_ASSERT( size()>0, NULL); return internal_subscript( size()-1 ); } //! the last item const const_reference back() const { __TBB_ASSERT( size()>0, NULL); return internal_subscript( size()-1 ); } //! return allocator object allocator_type get_allocator() const { return this->my_allocator; } //! assign n items by copying t item void assign(size_type n, const_reference t) { clear(); internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); } //! assign range [first, last) template void assign(I first, I last) { clear(); internal_assign_range( first, last, static_cast::is_integer> *>(0) ); } #if __TBB_INITIALIZER_LISTS_PRESENT //! assigns an initializer list void assign(std::initializer_list init_list) { clear(); internal_assign_iterators( init_list.begin(), init_list.end()); } #endif //# __TBB_INITIALIZER_LISTS_PRESENT //! swap two instances void swap(concurrent_vector &vector) { using std::swap; if( this != &vector ) { concurrent_vector_base_v3::internal_swap(static_cast(vector)); swap(this->my_allocator, vector.my_allocator); } } //! Clear container while keeping memory allocated. /** To free up the memory, use in conjunction with method compact(). Not thread safe **/ void clear() { internal_clear(&destroy_array); } //! Clear and destroy vector. ~concurrent_vector() { segment_t *table = my_segment.load(); internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); // base class destructor call should be then } const internal::concurrent_vector_base_v3 &internal_vector_base() const { return *this; } private: //! Allocate k items static void *internal_allocator(internal::concurrent_vector_base_v3 &vb, size_t k) { return static_cast&>(vb).my_allocator.allocate(k); } //! Free k segments from table void internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block); //! Get reference to element at given index. T& internal_subscript( size_type index ) const; //! Get reference to element at given index with errors checks T& internal_subscript_with_exceptions( size_type index ) const; //! assign n items by copying t void internal_assign_n(size_type n, const_pointer p) { internal_resize( n, sizeof(T), max_size(), static_cast(p), &destroy_array, p? &initialize_array_by : &initialize_array ); } //! helper class template class is_integer_tag; //! assign integer items by copying when arguments are treated as iterators. See C++ Standard 2003 23.1.1p9 template void internal_assign_range(I first, I last, is_integer_tag *) { internal_assign_n(static_cast(first), &static_cast(last)); } //! inline proxy assign by iterators template void internal_assign_range(I first, I last, is_integer_tag *) { internal_assign_iterators(first, last); } //! assign by iterators template void internal_assign_iterators(I first, I last); //these functions are marked __TBB_EXPORTED_FUNC as they are called from within the library //! Construct n instances of T, starting at "begin". static void __TBB_EXPORTED_FUNC initialize_array( void* begin, const void*, size_type n ); //! Copy-construct n instances of T, starting at "begin". static void __TBB_EXPORTED_FUNC initialize_array_by( void* begin, const void* src, size_type n ); //! Copy-construct n instances of T by copying single element pointed to by src, starting at "dst". static void __TBB_EXPORTED_FUNC copy_array( void* dst, const void* src, size_type n ); #if __TBB_CPP11_RVALUE_REF_PRESENT //! Move-construct n instances of T, starting at "dst" by copying according element of src array. static void __TBB_EXPORTED_FUNC move_array( void* dst, const void* src, size_type n ); //! Move-assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array. static void __TBB_EXPORTED_FUNC move_assign_array( void* dst, const void* src, size_type n ); #endif //! Copy-construct n instances of T, starting at "dst" by iterator range of [p_type_erased_iterator, p_type_erased_iterator+n). template static void __TBB_EXPORTED_FUNC copy_range( void* dst, const void* p_type_erased_iterator, size_type n ); //! Assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array. static void __TBB_EXPORTED_FUNC assign_array( void* dst, const void* src, size_type n ); //! Destroy n instances of T, starting at "begin". static void __TBB_EXPORTED_FUNC destroy_array( void* begin, size_type n ); //! Exception-aware helper class for filling a segment by exception-danger operators of user class class internal_loop_guide : internal::no_copy { public: const pointer array; const size_type n; size_type i; static const T* as_const_pointer(const void *ptr) { return static_cast(ptr); } static T* as_pointer(const void *src) { return static_cast(const_cast(src)); } internal_loop_guide(size_type ntrials, void *ptr) : array(as_pointer(ptr)), n(ntrials), i(0) {} void init() { for(; i < n; ++i) new( &array[i] ) T(); } void init(const void *src) { for(; i < n; ++i) new( &array[i] ) T(*as_const_pointer(src)); } void copy(const void *src) { for(; i < n; ++i) new( &array[i] ) T(as_const_pointer(src)[i]); } void assign(const void *src) { for(; i < n; ++i) array[i] = as_const_pointer(src)[i]; } #if __TBB_CPP11_RVALUE_REF_PRESENT void move_assign(const void *src) { for(; i < n; ++i) array[i] = std::move(as_pointer(src)[i]); } void move_construct(const void *src) { for(; i < n; ++i) new( &array[i] ) T( std::move(as_pointer(src)[i]) ); } #endif //TODO: rename to construct_range template void iterate(I &src) { for(; i < n; ++i, ++src) new( &array[i] ) T( *src ); } ~internal_loop_guide() { if(i < n) {// if an exception was raised, fill the rest of items with zeros internal::handle_unconstructed_elements(array+i, n-i); } } }; class element_construction_guard : internal::no_copy{ pointer element; public: element_construction_guard(pointer an_element) : element (an_element){} void dismiss(){ element = NULL; } ~element_construction_guard(){ if (element){ internal::handle_unconstructed_elements(element, 1); } } }; }; #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (push) #pragma warning (disable: 4701) // potentially uninitialized local variable "old" #endif template void concurrent_vector::shrink_to_fit() { internal_segments_table old; __TBB_TRY { if( internal_compact( sizeof(T), &old, &destroy_array, ©_array ) ) internal_free_segments( old.table, pointers_per_long_table, old.first_block ); // free joined and unnecessary segments } __TBB_CATCH(...) { if( old.first_block ) // free segment allocated for compacting. Only for support of exceptions in ctor of user T[ype] internal_free_segments( old.table, 1, old.first_block ); __TBB_RETHROW(); } } #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4701 is back template void concurrent_vector::internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block) { // Free the arrays while( k > first_block ) { --k; segment_value_t segment_value = table[k].load(); table[k].store(segment_not_used()); if( segment_value == segment_allocated() ) // check for correct segment pointer this->my_allocator.deallocate( (segment_value.pointer()), segment_size(k) ); } segment_value_t segment_value = table[0].load(); if( segment_value == segment_allocated() ) { __TBB_ASSERT( first_block > 0, NULL ); while(k > 0) table[--k].store(segment_not_used()); this->my_allocator.deallocate( (segment_value.pointer()), segment_size(first_block) ); } } template T& concurrent_vector::internal_subscript( size_type index ) const { //TODO: unify both versions of internal_subscript __TBB_ASSERT( index < my_early_size, "index out of bounds" ); size_type j = index; segment_index_t k = segment_base_index_of( j ); __TBB_ASSERT( my_segment.load() != my_storage || k < pointers_per_short_table, "index is being allocated" ); //no need in load with acquire (load) since thread works in own space or gets //the information about added elements via some form of external synchronization //TODO: why not make a load of my_segment relaxed as well ? //TODO: add an assertion that my_segment[k] is properly aligned to please ITT segment_value_t segment_value = my_segment[k].template load(); __TBB_ASSERT( segment_value != segment_allocation_failed(), "the instance is broken by bad allocation. Use at() instead" ); __TBB_ASSERT( segment_value != segment_not_used(), "index is being allocated" ); return (( segment_value.pointer()))[j]; } template T& concurrent_vector::internal_subscript_with_exceptions( size_type index ) const { if( index >= my_early_size ) internal::throw_exception(internal::eid_out_of_range); // throw std::out_of_range size_type j = index; segment_index_t k = segment_base_index_of( j ); //TODO: refactor this condition into separate helper function, e.g. fits_into_small_table if( my_segment.load() == my_storage && k >= pointers_per_short_table ) internal::throw_exception(internal::eid_segment_range_error); // throw std::range_error // no need in load with acquire (load) since thread works in own space or gets //the information about added elements via some form of external synchronization //TODO: why not make a load of my_segment relaxed as well ? //TODO: add an assertion that my_segment[k] is properly aligned to please ITT segment_value_t segment_value = my_segment[k].template load(); if( segment_value != segment_allocated() ) // check for correct segment pointer internal::throw_exception(internal::eid_index_range_error); // throw std::range_error return (segment_value.pointer())[j]; } template template void concurrent_vector::internal_assign_iterators(I first, I last) { __TBB_ASSERT(my_early_size == 0, NULL); size_type n = std::distance(first, last); if( !n ) return; internal_reserve(n, sizeof(T), max_size()); my_early_size = n; segment_index_t k = 0; //TODO: unify segment iteration code with concurrent_base_v3::helper size_type sz = segment_size( my_first_block ); while( sz < n ) { internal_loop_guide loop(sz, my_segment[k].template load().template pointer()); loop.iterate(first); n -= sz; if( !k ) k = my_first_block; else { ++k; sz <<= 1; } } internal_loop_guide loop(n, my_segment[k].template load().template pointer()); loop.iterate(first); } template void concurrent_vector::initialize_array( void* begin, const void *, size_type n ) { internal_loop_guide loop(n, begin); loop.init(); } template void concurrent_vector::initialize_array_by( void* begin, const void *src, size_type n ) { internal_loop_guide loop(n, begin); loop.init(src); } template void concurrent_vector::copy_array( void* dst, const void* src, size_type n ) { internal_loop_guide loop(n, dst); loop.copy(src); } #if __TBB_CPP11_RVALUE_REF_PRESENT template void concurrent_vector::move_array( void* dst, const void* src, size_type n ) { internal_loop_guide loop(n, dst); loop.move_construct(src); } template void concurrent_vector::move_assign_array( void* dst, const void* src, size_type n ) { internal_loop_guide loop(n, dst); loop.move_assign(src); } #endif template template void concurrent_vector::copy_range( void* dst, const void* p_type_erased_iterator, size_type n ){ I & iterator ((*const_cast(static_cast(p_type_erased_iterator)))); internal_loop_guide loop(n, dst); loop.iterate(iterator); } template void concurrent_vector::assign_array( void* dst, const void* src, size_type n ) { internal_loop_guide loop(n, dst); loop.assign(src); } #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warning #pragma warning (push) #pragma warning (disable: 4189) #endif template void concurrent_vector::destroy_array( void* begin, size_type n ) { T* array = static_cast(begin); for( size_type j=n; j>0; --j ) array[j-1].~T(); // destructors are supposed to not throw any exceptions } #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4189 is back // concurrent_vector's template functions template inline bool operator==(const concurrent_vector &a, const concurrent_vector &b) { //TODO: call size() only once per vector (in operator==) // Simply: return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); if(a.size() != b.size()) return false; typename concurrent_vector::const_iterator i(a.begin()); typename concurrent_vector::const_iterator j(b.begin()); for(; i != a.end(); ++i, ++j) if( !(*i == *j) ) return false; return true; } template inline bool operator!=(const concurrent_vector &a, const concurrent_vector &b) { return !(a == b); } template inline bool operator<(const concurrent_vector &a, const concurrent_vector &b) { return (std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())); } template inline bool operator>(const concurrent_vector &a, const concurrent_vector &b) { return b < a; } template inline bool operator<=(const concurrent_vector &a, const concurrent_vector &b) { return !(b < a); } template inline bool operator>=(const concurrent_vector &a, const concurrent_vector &b) { return !(a < b); } template inline void swap(concurrent_vector &a, concurrent_vector &b) { a.swap( b ); } } // namespace tbb #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4267,4127 are back #endif /* __TBB_concurrent_vector_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/condition_variable.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" #include "tbb/compat/condition_variable" #include "tbb/atomic.h" #include "tbb_misc.h" #include "dynamic_link.h" #include "itt_notify.h" namespace tbb { namespace internal { //condition_variable #if _WIN32||_WIN64 using tbb::interface5::internal::condition_variable_using_event; static atomic condvar_api_state; void WINAPI init_condvar_using_event( condition_variable_using_event* cv_event ) { // TODO: For Metro port, we can always use the API for condition variables, without dynamic_link etc. cv_event->event = CreateEventEx(NULL, NULL, 0x1 /*CREATE_EVENT_MANUAL_RESET*/, EVENT_ALL_ACCESS ); InitializeCriticalSectionEx( &cv_event->mutex, 4000, 0 ); cv_event->n_waiters = 0; cv_event->release_count = 0; cv_event->epoch = 0; } BOOL WINAPI sleep_condition_variable_cs_using_event( condition_variable_using_event* cv_event, LPCRITICAL_SECTION cs, DWORD dwMilliseconds ) { EnterCriticalSection( &cv_event->mutex ); ++cv_event->n_waiters; unsigned my_generation = cv_event->epoch; LeaveCriticalSection( &cv_event->mutex ); LeaveCriticalSection( cs ); for (;;) { // should come here at least once DWORD rc = WaitForSingleObjectEx( cv_event->event, dwMilliseconds, FALSE ); EnterCriticalSection( &cv_event->mutex ); if( rc!=WAIT_OBJECT_0 ) { --cv_event->n_waiters; LeaveCriticalSection( &cv_event->mutex ); if( rc==WAIT_TIMEOUT ) { SetLastError( WAIT_TIMEOUT ); EnterCriticalSection( cs ); } return false; } __TBB_ASSERT( rc==WAIT_OBJECT_0, NULL ); if( cv_event->release_count>0 && cv_event->epoch!=my_generation ) break; LeaveCriticalSection( &cv_event->mutex ); } // still in the critical section --cv_event->n_waiters; int count = --cv_event->release_count; LeaveCriticalSection( &cv_event->mutex ); if( count==0 ) { __TBB_ASSERT( cv_event->event, "Premature destruction of condition variable?" ); ResetEvent( cv_event->event ); } EnterCriticalSection( cs ); return true; } void WINAPI wake_condition_variable_using_event( condition_variable_using_event* cv_event ) { EnterCriticalSection( &cv_event->mutex ); if( cv_event->n_waiters>cv_event->release_count ) { SetEvent( cv_event->event ); // Signal the manual-reset event. ++cv_event->release_count; ++cv_event->epoch; } LeaveCriticalSection( &cv_event->mutex ); } void WINAPI wake_all_condition_variable_using_event( condition_variable_using_event* cv_event ) { EnterCriticalSection( &cv_event->mutex ); if( cv_event->n_waiters>0 ) { SetEvent( cv_event->event ); cv_event->release_count = cv_event->n_waiters; ++cv_event->epoch; } LeaveCriticalSection( &cv_event->mutex ); } void WINAPI destroy_condvar_using_event( condition_variable_using_event* cv_event ) { HANDLE my_event = cv_event->event; EnterCriticalSection( &cv_event->mutex ); // NULL is an invalid HANDLE value cv_event->event = NULL; if( cv_event->n_waiters>0 ) { LeaveCriticalSection( &cv_event->mutex ); spin_wait_until_eq( cv_event->n_waiters, 0 ); // make sure the last thread completes its access to cv EnterCriticalSection( &cv_event->mutex ); } LeaveCriticalSection( &cv_event->mutex ); CloseHandle( my_event ); } void WINAPI destroy_condvar_noop( CONDITION_VARIABLE* /*cv*/ ) { /*no op*/ } static void (WINAPI *__TBB_init_condvar)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&init_condvar_using_event; static BOOL (WINAPI *__TBB_condvar_wait)( PCONDITION_VARIABLE, LPCRITICAL_SECTION, DWORD ) = (BOOL (WINAPI *)(PCONDITION_VARIABLE,LPCRITICAL_SECTION, DWORD))&sleep_condition_variable_cs_using_event; static void (WINAPI *__TBB_condvar_notify_one)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&wake_condition_variable_using_event; static void (WINAPI *__TBB_condvar_notify_all)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&wake_all_condition_variable_using_event; static void (WINAPI *__TBB_destroy_condvar)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_using_event; //! Table describing how to link the handlers. static const dynamic_link_descriptor CondVarLinkTable[] = { DLD(InitializeConditionVariable, __TBB_init_condvar), DLD(SleepConditionVariableCS, __TBB_condvar_wait), DLD(WakeConditionVariable, __TBB_condvar_notify_one), DLD(WakeAllConditionVariable, __TBB_condvar_notify_all) }; void init_condvar_module() { __TBB_ASSERT( (uintptr_t)__TBB_init_condvar==(uintptr_t)&init_condvar_using_event, NULL ); if( dynamic_link( "Kernel32.dll", CondVarLinkTable, 4 ) ) __TBB_destroy_condvar = (void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_noop; } #endif /* _WIN32||_WIN64 */ } // namespace internal #if _WIN32||_WIN64 namespace interface5 { namespace internal { using tbb::internal::condvar_api_state; using tbb::internal::__TBB_init_condvar; using tbb::internal::__TBB_condvar_wait; using tbb::internal::__TBB_condvar_notify_one; using tbb::internal::__TBB_condvar_notify_all; using tbb::internal::__TBB_destroy_condvar; using tbb::internal::init_condvar_module; void internal_initialize_condition_variable( condvar_impl_t& cv ) { atomic_do_once( &init_condvar_module, condvar_api_state ); __TBB_init_condvar( &cv.cv_native ); } void internal_destroy_condition_variable( condvar_impl_t& cv ) { __TBB_destroy_condvar( &cv.cv_native ); } void internal_condition_variable_notify_one( condvar_impl_t& cv ) { __TBB_condvar_notify_one ( &cv.cv_native ); } void internal_condition_variable_notify_all( condvar_impl_t& cv ) { __TBB_condvar_notify_all( &cv.cv_native ); } bool internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx, const tick_count::interval_t* i ) { DWORD duration = i ? DWORD((i->seconds()*1000)) : INFINITE; mtx->set_state( mutex::INITIALIZED ); BOOL res = __TBB_condvar_wait( &cv.cv_native, mtx->native_handle(), duration ); mtx->set_state( mutex::HELD ); return res?true:false; } } // namespace internal } // nameespace interface5 #endif /* _WIN32||_WIN64 */ } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/critical_section.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/critical_section.h" #include "itt_notify.h" namespace tbb { namespace internal { void critical_section_v4::internal_construct() { ITT_SYNC_CREATE(&my_impl, _T("ppl::critical_section"), _T("")); } } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/critical_section.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_CRITICAL_SECTION_H_ #define _TBB_CRITICAL_SECTION_H_ #if _WIN32||_WIN64 #include "machine/windows_api.h" #else #include #include #endif // _WIN32||WIN64 #include "tbb_stddef.h" #include "tbb_thread.h" #include "tbb_exception.h" #include "tbb_profiling.h" namespace tbb { namespace internal { class critical_section_v4 : internal::no_copy { #if _WIN32||_WIN64 CRITICAL_SECTION my_impl; #else pthread_mutex_t my_impl; #endif tbb_thread::id my_tid; public: void __TBB_EXPORTED_METHOD internal_construct(); critical_section_v4() { #if _WIN32||_WIN64 InitializeCriticalSectionEx( &my_impl, 4000, 0 ); #else pthread_mutex_init(&my_impl, NULL); #endif internal_construct(); } ~critical_section_v4() { __TBB_ASSERT(my_tid == tbb_thread::id(), "Destroying a still-held critical section"); #if _WIN32||_WIN64 DeleteCriticalSection(&my_impl); #else pthread_mutex_destroy(&my_impl); #endif } class scoped_lock : internal::no_copy { private: critical_section_v4 &my_crit; public: scoped_lock( critical_section_v4& lock_me) :my_crit(lock_me) { my_crit.lock(); } ~scoped_lock() { my_crit.unlock(); } }; void lock() { tbb_thread::id local_tid = this_tbb_thread::get_id(); if(local_tid == my_tid) throw_exception( eid_improper_lock ); #if _WIN32||_WIN64 EnterCriticalSection( &my_impl ); #else int rval = pthread_mutex_lock(&my_impl); __TBB_ASSERT_EX(!rval, "critical_section::lock: pthread_mutex_lock failed"); #endif __TBB_ASSERT(my_tid == tbb_thread::id(), NULL); my_tid = local_tid; } bool try_lock() { bool gotlock; tbb_thread::id local_tid = this_tbb_thread::get_id(); if(local_tid == my_tid) return false; #if _WIN32||_WIN64 gotlock = TryEnterCriticalSection( &my_impl ) != 0; #else int rval = pthread_mutex_trylock(&my_impl); // valid returns are 0 (locked) and [EBUSY] __TBB_ASSERT(rval == 0 || rval == EBUSY, "critical_section::trylock: pthread_mutex_trylock failed"); gotlock = rval == 0; #endif if(gotlock) { my_tid = local_tid; } return gotlock; } void unlock() { __TBB_ASSERT(this_tbb_thread::get_id() == my_tid, "thread unlocking critical_section is not thread that locked it"); my_tid = tbb_thread::id(); #if _WIN32||_WIN64 LeaveCriticalSection( &my_impl ); #else int rval = pthread_mutex_unlock(&my_impl); __TBB_ASSERT_EX(!rval, "critical_section::unlock: pthread_mutex_unlock failed"); #endif } static const bool is_rw_mutex = false; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = true; }; // critical_section_v4 } // namespace internal typedef internal::critical_section_v4 critical_section; __TBB_DEFINE_PROFILING_SET_NAME(critical_section) } // namespace tbb #endif // _TBB_CRITICAL_SECTION_H_ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/custom_scheduler.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_custom_scheduler_H #define _TBB_custom_scheduler_H #include "scheduler.h" #include "observer_proxy.h" #include "itt_notify.h" namespace tbb { namespace internal { //! Amount of time to pause between steals. /** The default values below were found to be best empirically for K-Means on the 32-way Altix and 4-way (*2 for HT) fxqlin04. */ #ifdef __TBB_STEALING_PAUSE static const long PauseTime = __TBB_STEALING_PAUSE; #elif __TBB_ipf static const long PauseTime = 1500; #else static const long PauseTime = 80; #endif //------------------------------------------------------------------------ //! Traits classes for scheduler //------------------------------------------------------------------------ struct DefaultSchedulerTraits { static const bool itt_possible = true; static const bool has_slow_atomic = false; }; struct IntelSchedulerTraits { static const bool itt_possible = false; #if __TBB_x86_32||__TBB_x86_64 static const bool has_slow_atomic = true; #else static const bool has_slow_atomic = false; #endif /* __TBB_x86_32||__TBB_x86_64 */ }; //------------------------------------------------------------------------ // custom_scheduler //------------------------------------------------------------------------ //! A scheduler with a customized evaluation loop. /** The customization can use SchedulerTraits to make decisions without needing a run-time check. */ template class custom_scheduler: private generic_scheduler { typedef custom_scheduler scheduler_type; //! Scheduler loop that dispatches tasks. /** If child is non-NULL, it is dispatched first. Then, until "parent" has a reference count of 1, other task are dispatched or stolen. */ /*override*/ void local_wait_for_all( task& parent, task* child ); //! Entry point from client code to the scheduler loop that dispatches tasks. /** The method is virtual, but the *this object is used only for sake of dispatching on the correct vtable, not necessarily the correct *this object. The correct *this object is looked up in TLS. */ /*override*/ void wait_for_all( task& parent, task* child ) { static_cast(governor::local_scheduler())->scheduler_type::local_wait_for_all( parent, child ); } //! Construct a custom_scheduler custom_scheduler( arena* a, size_t index ) : generic_scheduler(a, index) {} //! Decrements ref_count of a predecessor. /** If it achieves 0, the predecessor is scheduled for execution. When changing, remember that this is a hot path function. */ void tally_completion_of_predecessor( task& s, task*& bypass_slot ) { task_prefix& p = s.prefix(); if( SchedulerTraits::itt_possible ) ITT_NOTIFY(sync_releasing, &p.ref_count); if( SchedulerTraits::has_slow_atomic && p.ref_count==1 ) p.ref_count=0; else if( __TBB_FetchAndDecrementWrelease(&p.ref_count) > 1 ) {// more references exist // '__TBB_cl_evict(&p)' degraded performance of parallel_preorder example return; } // Ordering on p.ref_count (superfluous if SchedulerTraits::has_slow_atomic) __TBB_control_consistency_helper(); __TBB_ASSERT(p.ref_count==0, "completion of task caused predecessor's reference count to underflow"); if( SchedulerTraits::itt_possible ) ITT_NOTIFY(sync_acquired, &p.ref_count); #if TBB_USE_ASSERT p.extra_state &= ~es_ref_count_active; #endif /* TBB_USE_ASSERT */ #if __TBB_RECYCLE_TO_ENQUEUE if (p.state==task::to_enqueue) { // related to __TBB_TASK_ARENA TODO: try keep priority of the task // e.g. rework task_prefix to remember priority of received task and use here my_arena->enqueue_task(s, 0, my_random ); } else #endif /*__TBB_RECYCLE_TO_ENQUEUE*/ if( bypass_slot==NULL ) bypass_slot = &s; else local_spawn( s, s.prefix().next ); } public: static generic_scheduler* allocate_scheduler( arena* a, size_t index ) { scheduler_type* s = (scheduler_type*)NFS_Allocate(1,sizeof(scheduler_type),NULL); new( s ) scheduler_type( a, index ); s->assert_task_pool_valid(); ITT_SYNC_CREATE(s, SyncType_Scheduler, SyncObj_TaskPoolSpinning); return s; } //! Try getting a task from the mailbox or stealing from another scheduler. /** Returns the stolen task or NULL if all attempts fail. */ /* override */ task* receive_or_steal_task( __TBB_atomic reference_count& completion_ref_count, bool return_if_no_work ); }; // class custom_scheduler<> //------------------------------------------------------------------------ // custom_scheduler methods //------------------------------------------------------------------------ template task* custom_scheduler::receive_or_steal_task( __TBB_atomic reference_count& completion_ref_count, bool return_if_no_work ) { task* t = NULL; bool outermost_dispatch_level = return_if_no_work || master_outermost_level(); bool can_steal_here = can_steal(); my_inbox.set_is_idle( true ); #if __TBB_HOARD_NONLOCAL_TASKS __TBB_ASSERT(!my_nonlocal_free_list, NULL); #endif #if __TBB_TASK_PRIORITY if ( return_if_no_work && my_arena->my_skipped_fifo_priority ) { // This thread can dequeue FIFO tasks, and some priority levels of // FIFO tasks have been bypassed (to prevent deadlock caused by // dynamic priority changes in nested task group hierarchy). intptr_t skipped_priority = my_arena->my_skipped_fifo_priority; if ( my_arena->my_skipped_fifo_priority.compare_and_swap(0, skipped_priority) == skipped_priority && skipped_priority > my_arena->my_top_priority ) { my_market->update_arena_priority( *my_arena, skipped_priority ); } } task_stream *ts; #else /* !__TBB_TASK_PRIORITY */ task_stream *ts = &my_arena->my_task_stream; #endif /* !__TBB_TASK_PRIORITY */ // TODO: Try to find a place to reset my_limit (under market's lock) // The number of slots potentially used in the arena. Updated once in a while, as my_limit changes rarely. size_t n = my_arena->my_limit-1; int yield_count = 0; // The state "failure_count==-1" is used only when itt_possible is true, // and denotes that a sync_prepare has not yet been issued. for( int failure_count = -static_cast(SchedulerTraits::itt_possible);; ++failure_count) { __TBB_ASSERT( my_arena->my_limit > 0, NULL ); __TBB_ASSERT( my_arena_index <= n, NULL ); if( completion_ref_count==1 ) { if( SchedulerTraits::itt_possible ) { if( failure_count!=-1 ) { ITT_NOTIFY(sync_prepare, &completion_ref_count); // Notify Intel(R) Thread Profiler that thread has stopped spinning. ITT_NOTIFY(sync_acquired, this); } ITT_NOTIFY(sync_acquired, &completion_ref_count); } __TBB_ASSERT( !t, NULL ); __TBB_control_consistency_helper(); // on ref_count break; // exit stealing loop and return; } // Check if the resource manager requires our arena to relinquish some threads if ( return_if_no_work && my_arena->my_num_workers_allotted < my_arena->num_workers_active() ) { #if !__TBB_TASK_ARENA __TBB_ASSERT( is_worker(), NULL ); #endif if( SchedulerTraits::itt_possible && failure_count != -1 ) ITT_NOTIFY(sync_cancel, this); return NULL; } #if __TBB_TASK_PRIORITY ts = &my_arena->my_task_stream[my_arena->my_top_priority]; #endif // Check if there are tasks mailed to this thread via task-to-thread affinity mechanism. __TBB_ASSERT(my_affinity_id, NULL); if ( n && !my_inbox.empty() && (t = get_mailbox_task()) ) { GATHER_STATISTIC( ++my_counters.mails_received ); } // Check if there are tasks in starvation-resistant stream. // Only allowed for workers with empty stack, which is identified by return_if_no_work. else if ( outermost_dispatch_level && !ts->empty() && (t = ts->pop( my_arena_slot->hint_for_pop)) ) { ITT_NOTIFY(sync_acquired, ts); // just proceed with the obtained task } #if __TBB_TASK_PRIORITY // Check if any earlier offloaded non-top priority tasks become returned to the top level else if ( my_offloaded_tasks && (t=reload_tasks()) ) { // just proceed with the obtained task } #endif /* __TBB_TASK_PRIORITY */ else if ( can_steal_here && n ) { // Try to steal a task from a random victim. size_t k = my_random.get() % n; arena_slot* victim = &my_arena->my_slots[k]; // The following condition excludes the master that might have // already taken our previous place in the arena from the list . // of potential victims. But since such a situation can take // place only in case of significant oversubscription, keeping // the checks simple seems to be preferable to complicating the code. if( k >= my_arena_index ) ++victim; // Adjusts random distribution to exclude self task **pool = victim->task_pool; if( pool == EmptyTaskPool || !(t = steal_task( *victim )) ) goto fail; if( is_proxy(*t) ) { task_proxy &tp = *(task_proxy*)t; t = tp.extract_task(); if ( !t ) { // Proxy was empty, so it's our responsibility to free it free_task(tp); goto fail; } GATHER_STATISTIC( ++my_counters.proxies_stolen ); } t->prefix().extra_state |= es_task_is_stolen; if( is_version_3_task(*t) ) { my_innermost_running_task = t; t->prefix().owner = this; t->note_affinity( my_affinity_id ); } GATHER_STATISTIC( ++my_counters.steals_committed ); } // end of stealing branch else goto fail; // A task was successfully obtained somewhere __TBB_ASSERT(t,NULL); #if __TBB_SCHEDULER_OBSERVER my_arena->my_observers.notify_entry_observers( my_last_local_observer, is_worker() ); the_global_observer_list.notify_entry_observers( my_last_global_observer, is_worker() ); #endif /* __TBB_SCHEDULER_OBSERVER */ if ( SchedulerTraits::itt_possible && failure_count != -1 ) { // FIXME - might be victim, or might be selected from a mailbox // Notify Intel(R) Thread Profiler that thread has stopped spinning. ITT_NOTIFY(sync_acquired, this); } break; // exit stealing loop and return fail: GATHER_STATISTIC( ++my_counters.steals_failed ); if( SchedulerTraits::itt_possible && failure_count==-1 ) { // The first attempt to steal work failed, so notify Intel(R) Thread Profiler that // the thread has started spinning. Ideally, we would do this notification // *before* the first failed attempt to steal, but at that point we do not // know that the steal will fail. ITT_NOTIFY(sync_prepare, this); failure_count = 0; } // Pause, even if we are going to yield, because the yield might return immediately. __TBB_Pause(PauseTime); const int failure_threshold = 2*int(n+1); if( failure_count>=failure_threshold ) { #if __TBB_YIELD2P failure_count = 0; #else failure_count = failure_threshold; #endif __TBB_Yield(); #if __TBB_TASK_PRIORITY // Check if there are tasks abandoned by other workers if ( my_arena->my_orphaned_tasks ) { // Epoch must be advanced before seizing the list pointer ++my_arena->my_abandonment_epoch; task* orphans = (task*)__TBB_FetchAndStoreW( &my_arena->my_orphaned_tasks, 0 ); if ( orphans ) { task** link = NULL; // Get local counter out of the way (we've just brought in external tasks) my_local_reload_epoch--; t = reload_tasks( orphans, link, effective_reference_priority() ); if ( orphans ) { *link = my_offloaded_tasks; if ( !my_offloaded_tasks ) my_offloaded_task_list_tail_link = link; my_offloaded_tasks = orphans; } __TBB_ASSERT( !my_offloaded_tasks == !my_offloaded_task_list_tail_link, NULL ); if ( t ) { if( SchedulerTraits::itt_possible ) ITT_NOTIFY(sync_cancel, this); break; // exit stealing loop and return } } } #endif /* __TBB_TASK_PRIORITY */ const int yield_threshold = 100; if( yield_count++ >= yield_threshold ) { // When a worker thread has nothing to do, return it to RML. // For purposes of affinity support, the thread is considered idle while in RML. #if __TBB_TASK_PRIORITY if( return_if_no_work || my_arena->my_top_priority > my_arena->my_bottom_priority ) { if ( my_arena->is_out_of_work() && return_if_no_work ) { #else /* !__TBB_TASK_PRIORITY */ if ( return_if_no_work && my_arena->is_out_of_work() ) { #endif /* !__TBB_TASK_PRIORITY */ if( SchedulerTraits::itt_possible ) ITT_NOTIFY(sync_cancel, this); return NULL; } #if __TBB_TASK_PRIORITY } if ( my_offloaded_tasks ) { // Safeguard against any sloppiness in managing reload epoch // counter (e.g. on the hot path because of performance reasons). my_local_reload_epoch--; // Break the deadlock caused by a higher priority dispatch loop // stealing and offloading a lower priority task. Priority check // at the stealing moment cannot completely preclude such cases // because priorities can changes dynamically. if ( !return_if_no_work && *my_ref_top_priority > my_arena->my_top_priority ) { GATHER_STATISTIC( ++my_counters.prio_ref_fixups ); my_ref_top_priority = &my_arena->my_top_priority; // it's expected that only outermost workers can use global reload epoch __TBB_ASSERT(!worker_outermost_level(), NULL); __TBB_ASSERT(my_ref_reload_epoch == &my_arena->my_reload_epoch, NULL); } } #endif /* __TBB_TASK_PRIORITY */ } // end of arena snapshot branch // If several attempts did not find work, re-read the arena limit. n = my_arena->my_limit-1; } // end of yielding branch } // end of nonlocal task retrieval loop my_inbox.set_is_idle( false ); return t; } template void custom_scheduler::local_wait_for_all( task& parent, task* child ) { __TBB_ASSERT( governor::is_set(this), NULL ); __TBB_ASSERT( parent.ref_count() >= (child && child->parent() == &parent ? 2 : 1), "ref_count is too small" ); assert_task_pool_valid(); // Using parent's refcount in sync_prepare (in the stealing loop below) is // a workaround for TP. We need to name it here to display correctly in Ampl. if( SchedulerTraits::itt_possible ) ITT_SYNC_CREATE(&parent.prefix().ref_count, SyncType_Scheduler, SyncObj_TaskStealingLoop); #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT( parent.prefix().context || (is_worker() && &parent == my_dummy_task), "parent task does not have context" ); #endif /* __TBB_TASK_GROUP_CONTEXT */ task* t = child; // Constant all_local_work_done is an unreachable refcount value that prevents // early quitting the dispatch loop. It is defined to be in the middle of the range // of negative values representable by the reference_count type. static const reference_count // For normal dispatch loops parents_work_done = 1, // For termination dispatch loops in masters all_local_work_done = (reference_count)3 << (sizeof(reference_count) * 8 - 2); reference_count quit_point; #if __TBB_TASK_PRIORITY __TBB_ASSERT( (uintptr_t)*my_ref_top_priority < (uintptr_t)num_priority_levels, NULL ); volatile intptr_t *old_ref_top_priority = my_ref_top_priority; // When entering nested parallelism level market level counter // must be replaced with the one local to this arena. volatile uintptr_t *old_ref_reload_epoch = my_ref_reload_epoch; #endif /* __TBB_TASK_PRIORITY */ task* old_dispatching_task = my_dispatching_task; my_dispatching_task = my_innermost_running_task; if( master_outermost_level() ) { // We are in the outermost task dispatch loop of a master thread or a worker which mimics master __TBB_ASSERT( !is_worker() || my_dispatching_task != old_dispatching_task, NULL ); quit_point = &parent == my_dummy_task ? all_local_work_done : parents_work_done; } else { quit_point = parents_work_done; #if __TBB_TASK_PRIORITY if ( &parent != my_dummy_task ) { // We are in a nested dispatch loop. // Market or arena priority must not prevent child tasks from being // executed so that dynamic priority changes did not cause deadlock. my_ref_top_priority = &parent.prefix().context->my_priority; my_ref_reload_epoch = &my_arena->my_reload_epoch; if(my_ref_reload_epoch != old_ref_reload_epoch) my_local_reload_epoch = *my_ref_reload_epoch-1; } #endif /* __TBB_TASK_PRIORITY */ } cpu_ctl_env_helper cpu_ctl_helper; if ( t ) cpu_ctl_helper.set_env( __TBB_CONTEXT_ARG1(t->prefix().context) ); #if TBB_USE_EXCEPTIONS // Infinite safeguard EH loop for (;;) { try { #endif /* TBB_USE_EXCEPTIONS */ // Outer loop receives tasks from global environment (via mailbox, FIFO queue(s), // and by stealing from other threads' task pools). // All exit points from the dispatch loop are located in its immediate scope. for(;;) { // Middle loop retrieves tasks from the local task pool. for(;;) { // Inner loop evaluates tasks coming from nesting loops and those returned // by just executed tasks (bypassing spawn or enqueue calls). while(t) { __TBB_ASSERT( my_inbox.is_idle_state(false), NULL ); __TBB_ASSERT(!is_proxy(*t),"unexpected proxy"); __TBB_ASSERT( t->prefix().owner, NULL ); assert_task_valid(*t); #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_ASSERT assert_context_valid(t->prefix().context); if ( !t->prefix().context->my_cancellation_requested ) #endif __TBB_ASSERT( 1L<state() & (1L<prefix().extra_state & es_task_enqueued) == 0) { assert_priority_valid(p); if ( p != my_arena->my_top_priority ) { my_market->update_arena_priority( *my_arena, p ); } if ( p < effective_reference_priority() ) { if ( !my_offloaded_tasks ) { my_offloaded_task_list_tail_link = &t->prefix().next_offloaded; // Erase possible reference to the owner scheduler (next_offloaded is a union member) *my_offloaded_task_list_tail_link = NULL; } offload_task( *t, p ); if ( in_arena() ) { t = winnow_task_pool(); if ( t ) continue; } else { // Mark arena as full to unlock arena priority level adjustment // by arena::is_out_of_work(), and ensure worker's presence. my_arena->advertise_new_work(); } goto stealing_ground; } } #endif /* __TBB_TASK_PRIORITY */ task* t_next = NULL; my_innermost_running_task = t; t->prefix().owner = this; t->prefix().state = task::executing; #if __TBB_TASK_GROUP_CONTEXT if ( !t->prefix().context->my_cancellation_requested ) #endif { GATHER_STATISTIC( ++my_counters.tasks_executed ); GATHER_STATISTIC( my_counters.avg_arena_concurrency += my_arena->num_workers_active() ); GATHER_STATISTIC( my_counters.avg_assigned_workers += my_arena->my_num_workers_allotted ); #if __TBB_TASK_PRIORITY GATHER_STATISTIC( my_counters.avg_arena_prio += p ); GATHER_STATISTIC( my_counters.avg_market_prio += my_market->my_global_top_priority ); #endif /* __TBB_TASK_PRIORITY */ ITT_STACK(SchedulerTraits::itt_possible, callee_enter, t->prefix().context->itt_caller); t_next = t->execute(); ITT_STACK(SchedulerTraits::itt_possible, callee_leave, t->prefix().context->itt_caller); if (t_next) { __TBB_ASSERT( t_next->state()==task::allocated, "if task::execute() returns task, it must be marked as allocated" ); reset_extra_state(t_next); #if TBB_USE_ASSERT affinity_id next_affinity=t_next->prefix().affinity; if (next_affinity != 0 && next_affinity != my_affinity_id) GATHER_STATISTIC( ++my_counters.affinity_ignored ); #endif } } assert_task_pool_valid(); switch( t->state() ) { case task::executing: { task* s = t->parent(); __TBB_ASSERT( my_innermost_running_task==t, NULL ); __TBB_ASSERT( t->prefix().ref_count==0, "Task still has children after it has been executed" ); t->~task(); if( s ) tally_completion_of_predecessor(*s, t_next); free_task( *t ); assert_task_pool_valid(); break; } case task::recycle: // set by recycle_as_safe_continuation() t->prefix().state = task::allocated; #if __TBB_RECYCLE_TO_ENQUEUE case task::to_enqueue: // set by recycle_to_enqueue() #endif __TBB_ASSERT( t_next != t, "a task returned from method execute() can not be recycled in another way" ); reset_extra_state(t); // for safe continuation, need atomically decrement ref_count; tally_completion_of_predecessor(*t, t_next); assert_task_pool_valid(); break; case task::reexecute: // set by recycle_to_reexecute() __TBB_ASSERT( t_next, "reexecution requires that method execute() return another task" ); __TBB_ASSERT( t_next != t, "a task returned from method execute() can not be recycled in another way" ); t->prefix().state = task::allocated; reset_extra_state(t); local_spawn( *t, t->prefix().next ); assert_task_pool_valid(); break; case task::allocated: reset_extra_state(t); break; #if TBB_USE_ASSERT case task::ready: __TBB_ASSERT( false, "task is in READY state upon return from method execute()" ); break; default: __TBB_ASSERT( false, "illegal state" ); #else default: // just to shut up some compilation warnings break; #endif /* TBB_USE_ASSERT */ } GATHER_STATISTIC( t_next ? ++my_counters.spawns_bypassed : 0 ); t = t_next; } // end of scheduler bypass loop assert_task_pool_valid(); if ( parent.prefix().ref_count == quit_point ) { __TBB_ASSERT( quit_point != all_local_work_done, NULL ); __TBB_control_consistency_helper(); // on ref_count ITT_NOTIFY(sync_acquired, &parent.prefix().ref_count); goto done; } if ( in_arena() ) { t = get_task(); } else { __TBB_ASSERT( is_quiescent_local_task_pool_reset(), NULL ); break; } __TBB_ASSERT(!t || !is_proxy(*t),"unexpected proxy"); assert_task_pool_valid(); if ( !t ) break; cpu_ctl_helper.set_env( __TBB_CONTEXT_ARG1(t->prefix().context) ); }; // end of local task pool retrieval loop #if __TBB_TASK_PRIORITY stealing_ground: #endif /* __TBB_TASK_PRIORITY */ #if __TBB_HOARD_NONLOCAL_TASKS // before stealing, previously stolen task objects are returned for (; my_nonlocal_free_list; my_nonlocal_free_list = t ) { t = my_nonlocal_free_list->prefix().next; free_nonlocal_small_task( *my_nonlocal_free_list ); } #endif if ( quit_point == all_local_work_done ) { __TBB_ASSERT( !in_arena() && is_quiescent_local_task_pool_reset(), NULL ); __TBB_ASSERT( !worker_outermost_level(), NULL ); my_innermost_running_task = my_dispatching_task; my_dispatching_task = old_dispatching_task; #if __TBB_TASK_PRIORITY my_ref_top_priority = old_ref_top_priority; if(my_ref_reload_epoch != old_ref_reload_epoch) my_local_reload_epoch = *old_ref_reload_epoch-1; my_ref_reload_epoch = old_ref_reload_epoch; #endif /* __TBB_TASK_PRIORITY */ return; } // The following assertion may be falsely triggered in the presence of enqueued tasks //__TBB_ASSERT( my_arena->my_max_num_workers > 0 || my_market->my_ref_count > 1 // || parent.prefix().ref_count == 1, "deadlock detected" ); // Dispatching task pointer is NULL *iff* this is a worker thread in its outermost // dispatch loop (i.e. its execution stack is empty). In this case it should exit it // either when there is no more work in the current arena, or when revoked by the market. t = receive_or_steal_task( parent.prefix().ref_count, worker_outermost_level() ); if ( !t ) goto done; __TBB_ASSERT(!is_proxy(*t),"unexpected proxy"); // The user can capture another the FPU settings to the context so the // cached data in the helper can be out-of-date and we cannot do fast // check. cpu_ctl_helper.set_env( __TBB_CONTEXT_ARG1(t->prefix().context) ); } // end of infinite stealing loop #if TBB_USE_EXCEPTIONS __TBB_ASSERT( false, "Must never get here" ); } // end of try-block TbbCatchAll( t->prefix().context ); // Complete post-processing ... if( t->state() == task::recycle #if __TBB_RECYCLE_TO_ENQUEUE // TODO: the enqueue semantics gets lost below, consider reimplementing || t->state() == task::to_enqueue #endif ) { // ... for recycled tasks to atomically decrement ref_count t->prefix().state = task::allocated; if( SchedulerTraits::itt_possible ) ITT_NOTIFY(sync_releasing, &t->prefix().ref_count); if( __TBB_FetchAndDecrementWrelease(&t->prefix().ref_count)==1 ) { if( SchedulerTraits::itt_possible ) ITT_NOTIFY(sync_acquired, &t->prefix().ref_count); }else{ t = NULL; } } } // end of infinite EH loop __TBB_ASSERT( false, "Must never get here too" ); #endif /* TBB_USE_EXCEPTIONS */ done: my_innermost_running_task = my_dispatching_task; my_dispatching_task = old_dispatching_task; #if __TBB_TASK_PRIORITY my_ref_top_priority = old_ref_top_priority; if(my_ref_reload_epoch != old_ref_reload_epoch) my_local_reload_epoch = *old_ref_reload_epoch-1; my_ref_reload_epoch = old_ref_reload_epoch; #endif /* __TBB_TASK_PRIORITY */ if ( !ConcurrentWaitsEnabled(parent) ) { if ( parent.prefix().ref_count != parents_work_done ) { // This is a worker that was revoked by the market. #if __TBB_TASK_ARENA __TBB_ASSERT( worker_outermost_level(), "Worker thread exits nested dispatch loop prematurely" ); #else __TBB_ASSERT( is_worker() && worker_outermost_level(), "Worker thread exits nested dispatch loop prematurely" ); #endif return; } parent.prefix().ref_count = 0; } #if TBB_USE_ASSERT parent.prefix().extra_state &= ~es_ref_count_active; #endif /* TBB_USE_ASSERT */ #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT(parent.prefix().context && default_context(), NULL); task_group_context* parent_ctx = parent.prefix().context; if ( parent_ctx->my_cancellation_requested ) { task_group_context::exception_container_type *pe = parent_ctx->my_exception; if ( master_outermost_level() && parent_ctx == default_context() ) { // We are in the outermost task dispatch loop of a master thread, and // the whole task tree has been collapsed. So we may clear cancellation data. parent_ctx->my_cancellation_requested = 0; // TODO: Add assertion that master's dummy task context does not have children parent_ctx->my_state &= ~(uintptr_t)task_group_context::may_have_children; } if ( pe ) { // On Windows, FPU control settings changed in the helper destructor are not visible // outside a catch block. So restore the default settings manually before rethrowing // the exception. cpu_ctl_helper.restore_default(); pe->throw_self(); } } __TBB_ASSERT(!is_worker() || !CancellationInfoPresent(*my_dummy_task), "Worker's dummy task context modified"); __TBB_ASSERT(!master_outermost_level() || !CancellationInfoPresent(*my_dummy_task), "Unexpected exception or cancellation data in the master's dummy task"); #endif /* __TBB_TASK_GROUP_CONTEXT */ assert_task_pool_valid(); } } // namespace internal } // namespace tbb #endif /* _TBB_custom_scheduler_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/dynamic_link.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "dynamic_link.h" #include "tbb/tbb_config.h" /* This file is used by both TBB and OpenMP RTL. Do not use __TBB_ASSERT() macro and runtime_warning() function because they are not available in OpenMP. Use LIBRARY_ASSERT and DYNAMIC_LINK_WARNING instead. */ #include // va_list etc. #if _WIN32 #include // Unify system calls #define dlopen( name, flags ) LoadLibraryA( name ) #define dlsym( handle, name ) GetProcAddress( handle, name ) #define dlclose( handle ) ( ! FreeLibrary( handle ) ) #define dlerror() GetLastError() #ifndef PATH_MAX #define PATH_MAX MAX_PATH #endif #else /* _WIN32 */ #include #include #include #include #include #endif /* _WIN32 */ #if __TBB_WEAK_SYMBOLS_PRESENT //TODO: use function attribute for weak symbols instead of the pragma. #pragma weak dlopen #pragma weak dlsym #pragma weak dlclose #pragma weak dlerror #pragma weak dladdr #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ #include "tbb/tbb_misc.h" #define __USE_TBB_ATOMICS ( !(__linux__&&__ia64__) || __TBB_BUILD ) #define __USE_STATIC_DL_INIT (!__ANDROID__) #if !__USE_TBB_ATOMICS #include #endif /* dynamic_link is a common interface for searching for required symbols in an executable and dynamic libraries. dynamic_link provides certain guarantees: 1. Either all or none of the requested symbols are resolved. Moreover, if symbols are not resolved, the dynamic_link_descriptor table is not modified; 2. All returned symbols have secured life time: this means that none of them can be invalidated until dynamic_unlink is called; 3. Any loaded library is loaded only via the full path. The full path is that from which the runtime itself was loaded. (This is done to avoid security issues caused by loading libraries from insecure paths). dynamic_link searches for the requested symbols in three stages, stopping as soon as all of the symbols have been resolved. 1. Search the global scope: a. On Windows: dynamic_link tries to obtain the handle of the requested library and if it succeeds it resolves the symbols via that handle. b. On Linux: dynamic_link tries to search for the symbols in the global scope via the main program handle. If the symbols are present in the global scope their life time is not guaranteed (since dynamic_link does not know anything about the library from which they are exported). Therefore it tries to "pin" the symbols by obtaining the library name and reopening it. dlopen may fail to reopen the library in two cases: i. The symbols are exported from the executable. Currently dynamic _link cannot handle this situation, so it will not find these symbols in this step. ii. The necessary library has been unloaded and cannot be reloaded. It seems there is nothing that can be done in this case. No symbols are returned. 2. Dynamic load: an attempt is made to load the requested library via the full path. The full path used is that from which the runtime itself was loaded. If the library can be loaded, then an attempt is made to resolve the requested symbols in the newly loaded library. If the symbols are not found the library is unloaded. 3. Weak symbols: if weak symbols are available they are returned. */ OPEN_INTERNAL_NAMESPACE #if __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED #if !defined(DYNAMIC_LINK_WARNING) && !__TBB_WIN8UI_SUPPORT // Report runtime errors and continue. #define DYNAMIC_LINK_WARNING dynamic_link_warning static void dynamic_link_warning( dynamic_link_error_t code, ... ) { (void) code; } // library_warning #endif /* DYNAMIC_LINK_WARNING */ static bool resolve_symbols( dynamic_link_handle module, const dynamic_link_descriptor descriptors[], size_t required ) { LIBRARY_ASSERT( module != NULL, "Module handle is NULL" ); if ( module == NULL ) return false; #if __TBB_WEAK_SYMBOLS_PRESENT if ( !dlsym ) return false; #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ const size_t n_desc=20; // Usually we don't have more than 20 descriptors per library LIBRARY_ASSERT( required <= n_desc, "Too many descriptors is required" ); if ( required > n_desc ) return false; pointer_to_handler h[n_desc]; for ( size_t k = 0; k < required; ++k ) { dynamic_link_descriptor const & desc = descriptors[k]; pointer_to_handler addr = (pointer_to_handler)dlsym( module, desc.name ); if ( !addr ) { return false; } h[k] = addr; } // Commit the entry points. // Cannot use memset here, because the writes must be atomic. for( size_t k = 0; k < required; ++k ) *descriptors[k].handler = h[k]; return true; } #if __TBB_WIN8UI_SUPPORT bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required, dynamic_link_handle*, int flags ) { dynamic_link_handle tmp_handle = NULL; TCHAR wlibrary[256]; if ( MultiByteToWideChar(CP_UTF8, 0, library, -1, wlibrary, 255) == 0 ) return false; if ( flags & DYNAMIC_LINK_LOAD ) tmp_handle = LoadPackagedLibrary( wlibrary, 0 ); if (tmp_handle != NULL){ return resolve_symbols(tmp_handle, descriptors, required); }else{ return false; } } void dynamic_unlink( dynamic_link_handle ) { } void dynamic_unlink_all() { } #else /* There is a security issue on Windows: LoadLibrary() may load and execute malicious code. See http://www.microsoft.com/technet/security/advisory/2269637.mspx for details. To avoid the issue, we have to pass full path (not just library name) to LoadLibrary. This function constructs full path to the specified library (it is assumed the library located side-by-side with the tbb.dll. The function constructs absolute path for given relative path. Important: Base directory is not current one, it is the directory tbb.dll loaded from. Example: Let us assume "tbb.dll" is located in "c:\program files\common\intel\" directory, e. g. absolute path of tbb library is "c:\program files\common\intel\tbb.dll". Absolute path for "tbbmalloc.dll" would be "c:\program files\common\intel\tbbmalloc.dll". Absolute path for "malloc\tbbmalloc.dll" would be "c:\program files\common\intel\malloc\tbbmalloc.dll". */ // Struct handle_storage is used by dynamic_link routine to store handles of // all loaded or pinned dynamic libraries. When TBB is shut down, it calls // dynamic_unlink_all() that unloads modules referenced by handle_storage. // This struct should not have any constructors since it may be used before // the constructor is called. #define MAX_LOADED_MODULES 8 // The number of maximum possible modules which can be loaded struct handle_storage { #if __USE_TBB_ATOMICS ::tbb::atomic my_size; #else size_t my_size; pthread_spinlock_t my_lock; #endif dynamic_link_handle my_handles[MAX_LOADED_MODULES]; void add_handle(const dynamic_link_handle &handle) { #if !__USE_TBB_ATOMICS int res = pthread_spin_lock( &my_lock ); LIBRARY_ASSERT( res==0, "pthread_spin_lock failed" ); #endif const size_t ind = my_size++; #if !__USE_TBB_ATOMICS res = pthread_spin_unlock( &my_lock ); LIBRARY_ASSERT( res==0, "pthread_spin_unlock failed" ); #endif LIBRARY_ASSERT( ind < MAX_LOADED_MODULES, "Too many modules are loaded" ); my_handles[ind] = handle; } void free_handles() { const size_t size = my_size; for (size_t i=0; i &once_state ) { tbb::internal::atomic_do_once( func, once_state ); } #define ATOMIC_ONCE_DECL( var ) tbb::atomic< tbb::internal::do_once_state > var #else static void atomic_once ( void (*func) (), pthread_once_t &once_state ) { pthread_once( &once_state, func ); } #define ATOMIC_ONCE_DECL( var ) pthread_once_t var = PTHREAD_ONCE_INIT #endif ATOMIC_ONCE_DECL( init_dl_data_state ); static struct _ap_data { char _path[PATH_MAX+1]; size_t _len; } ap_data; static void init_ap_data() { #if _WIN32 // Get handle of our DLL first. HMODULE handle; BOOL brc = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPSTR)( & dynamic_link ), // any function inside the library can be used for the address & handle ); if ( !brc ) { // Error occurred. int err = GetLastError(); DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleHandleEx", err ); return; } // Now get path to our DLL. DWORD drc = GetModuleFileNameA( handle, ap_data._path, static_cast< DWORD >( PATH_MAX ) ); if ( drc == 0 ) { // Error occurred. int err = GetLastError(); DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleFileName", err ); return; } if ( drc >= PATH_MAX ) { // Buffer too short. DYNAMIC_LINK_WARNING( dl_buff_too_small ); return; } // Find the position of the last backslash. char *backslash = strrchr( ap_data._path, '\\' ); if ( !backslash ) { // Backslash not found. LIBRARY_ASSERT( backslash!=NULL, "Unbelievable."); return; } LIBRARY_ASSERT( backslash >= ap_data._path, "Unbelievable."); ap_data._len = (size_t)(backslash - ap_data._path) + 1; *(backslash+1) = 0; #else // Get the library path #if __TBB_WEAK_SYMBOLS_PRESENT if ( !dladdr || !dlerror ) return; #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ Dl_info dlinfo; int res = dladdr( (void*)&dynamic_link, &dlinfo ); // any function inside the library can be used for the address if ( !res ) { char const * err = dlerror(); DYNAMIC_LINK_WARNING( dl_sys_fail, "dladdr", err ); return; } else { LIBRARY_ASSERT( dlinfo.dli_fname!=NULL, "Unbelievable." ); } char const *slash = strrchr( dlinfo.dli_fname, '/' ); size_t fname_len=0; if ( slash ) { LIBRARY_ASSERT( slash >= dlinfo.dli_fname, "Unbelievable."); fname_len = (size_t)(slash - dlinfo.dli_fname) + 1; } size_t rc; if ( dlinfo.dli_fname[0]=='/' ) { // The library path is absolute rc = 0; ap_data._len = 0; } else { // The library path is relative so get the current working directory if ( !getcwd( ap_data._path, sizeof(ap_data._path)/sizeof(ap_data._path[0]) ) ) { DYNAMIC_LINK_WARNING( dl_buff_too_small ); return; } ap_data._len = strlen( ap_data._path ); ap_data._path[ap_data._len++]='/'; rc = ap_data._len; } if ( fname_len>0 ) { if ( ap_data._len>PATH_MAX ) { DYNAMIC_LINK_WARNING( dl_buff_too_small ); ap_data._len=0; return; } strncpy( ap_data._path+rc, dlinfo.dli_fname, fname_len ); ap_data._len += fname_len; ap_data._path[ap_data._len]=0; } #endif /* _WIN32 */ } static void init_dl_data() { init_ap_data(); #if !__USE_TBB_ATOMICS int res; res = pthread_spin_init( &handles.my_lock, PTHREAD_PROCESS_SHARED ); LIBRARY_ASSERT( res==0, "pthread_spin_init failed" ); #endif } // ap_data structure is initialized with current directory on Linux. // So it should be initialized as soon as possible since the current directory may be changed. // static_init_ap_data object provides this initialization during library loading. static class _static_init_dl_data { public: _static_init_dl_data() { #if __USE_STATIC_DL_INIT atomic_once( &init_dl_data, init_dl_data_state ); #endif } #if !__USE_TBB_ATOMICS ~_static_init_dl_data() { int res; res = pthread_spin_destroy( &handles.my_lock ); LIBRARY_ASSERT( res==0, "pthread_spin_destroy failed" ); } #endif } static_init_dl_data; /* The function constructs absolute path for given relative path. Important: Base directory is not current one, it is the directory libtbb.so loaded from. Arguments: in name -- Name of a file (may be with relative path; it must not be an absolute one). out path -- Buffer to save result (absolute path) to. in len -- Size of buffer. ret -- 0 -- Error occurred. > len -- Buffer too short, required size returned. otherwise -- Ok, number of characters (not counting terminating null) written to buffer. */ #if __TBB_DYNAMIC_LOAD_ENABLED static size_t abs_path( char const * name, char * path, size_t len ) { atomic_once( &init_dl_data, init_dl_data_state ); if ( !ap_data._len ) return 0; size_t name_len = strlen( name ); size_t full_len = name_len+ap_data._len; if ( full_len < len ) { strncpy( path, ap_data._path, ap_data._len ); strncpy( path+ap_data._len, name, name_len ); path[full_len] = 0; } return full_len; } #endif // __TBB_DYNAMIC_LOAD_ENABLED #if __TBB_WEAK_SYMBOLS_PRESENT static bool weak_symbol_link( const dynamic_link_descriptor descriptors[], size_t required ) { // Check if the required entries are present in what was loaded into our process. for ( size_t k = 0; k < required; ++k ) if ( !descriptors[k].ptr ) return false; // Commit the entry points. for ( size_t k = 0; k < required; ++k ) *descriptors[k].handler = (pointer_to_handler) descriptors[k].ptr; return true; } #else static bool weak_symbol_link( const dynamic_link_descriptor[], size_t ) { return false; } #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ void dynamic_unlink( dynamic_link_handle handle ) { if ( handle ) { #if __TBB_WEAK_SYMBOLS_PRESENT LIBRARY_ASSERT( dlclose != NULL, "dlopen is present but dlclose is NOT present!?" ); #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ #if __TBB_DYNAMIC_LOAD_ENABLED dlclose( handle ); #endif /* __TBB_DYNAMIC_LOAD_ENABLED */ } } void dynamic_unlink_all() { handles.free_handles(); } #if _WIN32 static dynamic_link_handle global_symbols_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required ) { dynamic_link_handle library_handle; if ( GetModuleHandleExA( 0, library, &library_handle ) ) { if ( resolve_symbols( library_handle, descriptors, required ) ) return library_handle; else FreeLibrary( library_handle ); } return 0; } #else /* _WIN32 */ // It is supposed that all symbols are from the only one library static dynamic_link_handle pin_symbols( dynamic_link_descriptor desc, const dynamic_link_descriptor descriptors[], size_t required ) { // The library has been loaded by another module and contains at least one requested symbol. // But after we obtained the symbol the library can be unloaded by another thread // invalidating our symbol. Therefore we need to pin the library in memory. dynamic_link_handle library_handle; Dl_info info; // Get library's name from earlier found symbol if ( dladdr( (void*)*desc.handler, &info ) ) { // Pin the library library_handle = dlopen( info.dli_fname, RTLD_LAZY ); if ( library_handle ) { // If original library was unloaded before we pinned it // and then another module loaded in its place, the earlier // found symbol would become invalid. So revalidate them. if ( !resolve_symbols( library_handle, descriptors, required ) ) { // Wrong library. dynamic_unlink(library_handle); library_handle = 0; } } else { char const * err = dlerror(); DYNAMIC_LINK_WARNING( dl_lib_not_found, info.dli_fname, err ); } } else { // The library have been unloaded by another thread library_handle = 0; } return library_handle; } static dynamic_link_handle global_symbols_link( const char*, const dynamic_link_descriptor descriptors[], size_t required ) { #if __TBB_WEAK_SYMBOLS_PRESENT if ( !dlopen ) return 0; #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ dynamic_link_handle library_handle = dlopen( NULL, RTLD_LAZY ); #if __ANDROID__ // On Android dlopen( NULL ) returns NULL if it is called during dynamic module initialization. if ( !library_handle ) return 0; #endif // Check existence of only the first symbol, then use it to find the library and load all necessary symbols pointer_to_handler handler; dynamic_link_descriptor desc = { descriptors[0].name, &handler }; if ( resolve_symbols( library_handle, &desc, 1 ) ) return pin_symbols( desc, descriptors, required ); return 0; } #endif /* _WIN32 */ static void save_library_handle( dynamic_link_handle src, dynamic_link_handle *dst ) { if ( dst ) *dst = src; else handles.add_handle( src ); } dynamic_link_handle dynamic_load( const char* library, const dynamic_link_descriptor descriptors[], size_t required ) { #if __TBB_DYNAMIC_LOAD_ENABLED #if _XBOX return LoadLibrary (library); #else /* _XBOX */ size_t const len = PATH_MAX + 1; char path[ len ]; size_t rc = abs_path( library, path, len ); if ( 0 < rc && rc < len ) { #if _WIN32 // Prevent Windows from displaying silly message boxes if it fails to load library // (e.g. because of MS runtime problems - one of those crazy manifest related ones) UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); #endif /* _WIN32 */ #if __TBB_WEAK_SYMBOLS_PRESENT if ( !dlopen ) return 0; #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ dynamic_link_handle library_handle = dlopen( path, RTLD_LAZY ); #if _WIN32 SetErrorMode (prev_mode); #endif /* _WIN32 */ if( library_handle ) { if( !resolve_symbols( library_handle, descriptors, required ) ) { // The loaded library does not contain all the expected entry points dynamic_unlink( library_handle ); library_handle = NULL; } } else DYNAMIC_LINK_WARNING( dl_lib_not_found, path, dlerror() ); return library_handle; } else if ( rc>=len ) DYNAMIC_LINK_WARNING( dl_buff_too_small ); // rc == 0 means failing of init_ap_data so the warning has already been issued. #endif /* _XBOX */ #endif /* __TBB_DYNAMIC_LOAD_ENABLED */ return 0; } bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required, dynamic_link_handle *handle, int flags ) { // TODO: May global_symbols_link find weak symbols? dynamic_link_handle library_handle = ( flags & DYNAMIC_LINK_GLOBAL ) ? global_symbols_link( library, descriptors, required ) : 0; if ( !library_handle && ( flags & DYNAMIC_LINK_LOAD ) ) library_handle = dynamic_load( library, descriptors, required ); if ( !library_handle && ( flags & DYNAMIC_LINK_WEAK ) ) return weak_symbol_link( descriptors, required ); save_library_handle( library_handle, handle ); return true; } #endif /*__TBB_WIN8UI_SUPPORT*/ #else /* __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED */ bool dynamic_link( const char*, const dynamic_link_descriptor*, size_t, dynamic_link_handle *handle, int ) { if ( handle ) *handle=0; return false; } void dynamic_unlink( dynamic_link_handle ) { } void dynamic_unlink_all() { } #endif /* __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED */ CLOSE_INTERNAL_NAMESPACE ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/dynamic_link.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_dynamic_link #define __TBB_dynamic_link // Support for dynamic loading entry points from other shared libraries. #include "tbb/tbb_stddef.h" #ifdef LIBRARY_ASSERT #undef __TBB_ASSERT #define __TBB_ASSERT(x,y) LIBRARY_ASSERT(x,y) #else #define LIBRARY_ASSERT(x,y) __TBB_ASSERT_EX(x,y) #endif /* !LIBRARY_ASSERT */ /** By default, symbols declared and defined here go into namespace tbb::internal. To put them in other namespace, define macros OPEN_INTERNAL_NAMESPACE and CLOSE_INTERNAL_NAMESPACE to override the following default definitions. **/ #ifndef OPEN_INTERNAL_NAMESPACE #define OPEN_INTERNAL_NAMESPACE namespace tbb { namespace internal { #define CLOSE_INTERNAL_NAMESPACE }} #endif /* OPEN_INTERNAL_NAMESPACE */ #include #if _WIN32 #include "tbb/machine/windows_api.h" #endif /* _WIN32 */ OPEN_INTERNAL_NAMESPACE //! Type definition for a pointer to a void somefunc(void) typedef void (*pointer_to_handler)(); //! The helper to construct dynamic_link_descriptor structure // Double cast through the void* in DLD macro is necessary to // prevent warnings from some compilers (g++ 4.1) #if __TBB_WEAK_SYMBOLS_PRESENT #define DLD(s,h) {#s, (pointer_to_handler*)(void*)(&h), (pointer_to_handler)&s} #else #define DLD(s,h) {#s, (pointer_to_handler*)(void*)(&h)} #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ //! Association between a handler name and location of pointer to it. struct dynamic_link_descriptor { //! Name of the handler const char* name; //! Pointer to the handler pointer_to_handler* handler; #if __TBB_WEAK_SYMBOLS_PRESENT //! Weak symbol pointer_to_handler ptr; #endif }; #if _WIN32 typedef HMODULE dynamic_link_handle; #else typedef void* dynamic_link_handle; #endif /* _WIN32 */ const int DYNAMIC_LINK_GLOBAL = 0x01; const int DYNAMIC_LINK_LOAD = 0x02; const int DYNAMIC_LINK_WEAK = 0x04; const int DYNAMIC_LINK_ALL = DYNAMIC_LINK_GLOBAL | DYNAMIC_LINK_LOAD | DYNAMIC_LINK_WEAK; //! Fill in dynamically linked handlers. /** 'library' is the name of the requested library. It should not contain a full path since dynamic_link adds the full path (from which the runtime itself was loaded) to the library name. 'required' is the number of the initial entries in the array descriptors[] that have to be found in order for the call to succeed. If the library and all the required handlers are found, then the corresponding handler pointers are set, and the return value is true. Otherwise the original array of descriptors is left untouched and the return value is false. 'required' is limited by 20 (exceeding of this value will result in failure to load the symbols and the return value will be false). 'handle' is the handle of the library if it is loaded. Otherwise it is left untouched. 'flags' is the set of DYNAMIC_LINK_* flags. Each of the DYNAMIC_LINK_* flags allows its corresponding linking stage. **/ bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required, dynamic_link_handle* handle = 0, int flags = DYNAMIC_LINK_ALL ); void dynamic_unlink( dynamic_link_handle handle ); void dynamic_unlink_all(); enum dynamic_link_error_t { dl_success = 0, dl_lib_not_found, // char const * lib, dlerr_t err dl_sym_not_found, // char const * sym, dlerr_t err // Note: dlerr_t depends on OS: it is char const * on Linux* and OS X*, int on Windows*. dl_sys_fail, // char const * func, int err dl_buff_too_small // none }; // dynamic_link_error_t CLOSE_INTERNAL_NAMESPACE #endif /* __TBB_dynamic_link */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/enumerable_thread_specific.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_enumerable_thread_specific_H #define __TBB_enumerable_thread_specific_H #include "concurrent_vector.h" #include "tbb_thread.h" #include "tbb_allocator.h" #include "tbb_profiling.h" #include "cache_aligned_allocator.h" #include "aligned_space.h" #include // for memcpy #if _WIN32||_WIN64 #include "machine/windows_api.h" #else #include #endif namespace tbb { //! enum for selecting between single key and key-per-instance versions enum ets_key_usage_type { ets_key_per_instance, ets_no_key }; namespace interface6 { //! @cond namespace internal { using namespace tbb::internal; template class ets_base: tbb::internal::no_copy { protected: #if _WIN32||_WIN64 typedef DWORD key_type; #else typedef pthread_t key_type; #endif #if __TBB_PROTECTED_NESTED_CLASS_BROKEN public: #endif struct slot; struct array { array* next; size_t lg_size; slot& at( size_t k ) { return ((slot*)(void*)(this+1))[k]; } size_t size() const {return (size_t)1<>(8*sizeof(size_t)-lg_size); } }; struct slot { key_type key; void* ptr; bool empty() const {return !key;} bool match( key_type k ) const {return key==k;} bool claim( key_type k ) { __TBB_ASSERT(sizeof(tbb::atomic)==sizeof(key_type), NULL); return tbb::internal::punned_cast*>(&key)->compare_and_swap(k,0)==0; } }; #if __TBB_PROTECTED_NESTED_CLASS_BROKEN protected: #endif static key_type key_of_current_thread() { tbb::tbb_thread::id id = tbb::this_tbb_thread::get_id(); key_type k; memcpy( &k, &id, sizeof(k) ); return k; } //! Root of linked list of arrays of decreasing size. /** NULL if and only if my_count==0. Each array in the list is half the size of its predecessor. */ atomic my_root; atomic my_count; virtual void* create_local() = 0; virtual void* create_array(size_t _size) = 0; // _size in bytes virtual void free_array(void* ptr, size_t _size) = 0; // _size in bytes array* allocate( size_t lg_size ) { size_t n = 1<(create_array( sizeof(array)+n*sizeof(slot) )); a->lg_size = lg_size; std::memset( a+1, 0, n*sizeof(slot) ); return a; } void free(array* a) { size_t n = 1<<(a->lg_size); free_array( (void *)a, size_t(sizeof(array)+n*sizeof(slot)) ); } static size_t hash( key_type k ) { // Multiplicative hashing. Client should use *upper* bits. // casts required for Mac gcc4.* compiler return uintptr_t(k)*tbb::internal::select_size_t_constant<0x9E3779B9,0x9E3779B97F4A7C15ULL>::value; } ets_base() {my_root=NULL; my_count=0;} virtual ~ets_base(); // g++ complains if this is not virtual... void* table_lookup( bool& exists ); void table_clear(); // table_find is used in copying ETS, so is not used in concurrent context. So // we don't need itt annotations for it. slot& table_find( key_type k ) { size_t h = hash(k); array* r = my_root; size_t mask = r->mask(); for(size_t i = r->start(h);;i=(i+1)&mask) { slot& s = r->at(i); if( s.empty() || s.match(k) ) return s; } } void table_reserve_for_copy( const ets_base& other ) { __TBB_ASSERT(!my_root,NULL); __TBB_ASSERT(!my_count,NULL); if( other.my_root ) { array* a = allocate(other.my_root->lg_size); a->next = NULL; my_root = a; my_count = other.my_count; } } }; template ets_base::~ets_base() { __TBB_ASSERT(!my_root, NULL); } template void ets_base::table_clear() { while( array* r = my_root ) { my_root = r->next; free(r); } my_count = 0; } template void* ets_base::table_lookup( bool& exists ) { const key_type k = key_of_current_thread(); __TBB_ASSERT(k!=0,NULL); void* found; size_t h = hash(k); for( array* r=my_root; r; r=r->next ) { call_itt_notify(acquired,r); size_t mask=r->mask(); for(size_t i = r->start(h); ;i=(i+1)&mask) { slot& s = r->at(i); if( s.empty() ) break; if( s.match(k) ) { if( r==my_root ) { // Success at top level exists = true; return s.ptr; } else { // Success at some other level. Need to insert at top level. exists = true; found = s.ptr; goto insert; } } } } // Key does not yet exist. The density of slots in the table does not exceed 0.5, // for if this will occur a new table is allocated with double the current table // size, which is swapped in as the new root table. So an empty slot is guaranteed. exists = false; found = create_local(); { size_t c = ++my_count; array* r = my_root; call_itt_notify(acquired,r); if( !r || c>r->size()/2 ) { size_t s = r ? r->lg_size : 2; while( c>size_t(1)<<(s-1) ) ++s; array* a = allocate(s); for(;;) { a->next = r; call_itt_notify(releasing,a); array* new_r = my_root.compare_and_swap(a,r); if( new_r==r ) break; call_itt_notify(acquired, new_r); if( new_r->lg_size>=s ) { // Another thread inserted an equal or bigger array, so our array is superfluous. free(a); break; } r = new_r; } } } insert: // Whether a slot has been found in an older table, or if it has been inserted at this level, // it has already been accounted for in the total. Guaranteed to be room for it, and it is // not present, so search for empty slot and use it. array* ir = my_root; call_itt_notify(acquired, ir); size_t mask = ir->mask(); for(size_t i = ir->start(h);;i=(i+1)&mask) { slot& s = ir->at(i); if( s.empty() ) { if( s.claim(k) ) { s.ptr = found; return found; } } } } //! Specialization that exploits native TLS template <> class ets_base: protected ets_base { typedef ets_base super; #if _WIN32||_WIN64 #if __TBB_WIN8UI_SUPPORT typedef DWORD tls_key_t; void create_key() { my_key = FlsAlloc(NULL); } void destroy_key() { FlsFree(my_key); } void set_tls(void * value) { FlsSetValue(my_key, (LPVOID)value); } void* get_tls() { return (void *)FlsGetValue(my_key); } #else typedef DWORD tls_key_t; void create_key() { my_key = TlsAlloc(); } void destroy_key() { TlsFree(my_key); } void set_tls(void * value) { TlsSetValue(my_key, (LPVOID)value); } void* get_tls() { return (void *)TlsGetValue(my_key); } #endif #else typedef pthread_key_t tls_key_t; void create_key() { pthread_key_create(&my_key, NULL); } void destroy_key() { pthread_key_delete(my_key); } void set_tls( void * value ) const { pthread_setspecific(my_key, value); } void* get_tls() const { return pthread_getspecific(my_key); } #endif tls_key_t my_key; virtual void* create_local() = 0; virtual void* create_array(size_t _size) = 0; // _size in bytes virtual void free_array(void* ptr, size_t _size) = 0; // size in bytes public: ets_base() {create_key();} ~ets_base() {destroy_key();} void* table_lookup( bool& exists ) { void* found = get_tls(); if( found ) { exists=true; } else { found = super::table_lookup(exists); set_tls(found); } return found; } void table_clear() { destroy_key(); create_key(); super::table_clear(); } }; //! Random access iterator for traversing the thread local copies. template< typename Container, typename Value > class enumerable_thread_specific_iterator #if defined(_WIN64) && defined(_MSC_VER) // Ensure that Microsoft's internal template function _Val_type works correctly. : public std::iterator #endif /* defined(_WIN64) && defined(_MSC_VER) */ { //! current position in the concurrent_vector Container *my_container; typename Container::size_type my_index; mutable Value *my_value; template friend enumerable_thread_specific_iterator operator+( ptrdiff_t offset, const enumerable_thread_specific_iterator& v ); template friend bool operator==( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ); template friend bool operator<( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ); template friend ptrdiff_t operator-( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ); template friend class enumerable_thread_specific_iterator; public: enumerable_thread_specific_iterator( const Container &container, typename Container::size_type index ) : my_container(&const_cast(container)), my_index(index), my_value(NULL) {} //! Default constructor enumerable_thread_specific_iterator() : my_container(NULL), my_index(0), my_value(NULL) {} template enumerable_thread_specific_iterator( const enumerable_thread_specific_iterator& other ) : my_container( other.my_container ), my_index( other.my_index), my_value( const_cast(other.my_value) ) {} enumerable_thread_specific_iterator operator+( ptrdiff_t offset ) const { return enumerable_thread_specific_iterator(*my_container, my_index + offset); } enumerable_thread_specific_iterator &operator+=( ptrdiff_t offset ) { my_index += offset; my_value = NULL; return *this; } enumerable_thread_specific_iterator operator-( ptrdiff_t offset ) const { return enumerable_thread_specific_iterator( *my_container, my_index-offset ); } enumerable_thread_specific_iterator &operator-=( ptrdiff_t offset ) { my_index -= offset; my_value = NULL; return *this; } Value& operator*() const { Value* value = my_value; if( !value ) { value = my_value = reinterpret_cast(&(*my_container)[my_index].value); } __TBB_ASSERT( value==reinterpret_cast(&(*my_container)[my_index].value), "corrupt cache" ); return *value; } Value& operator[]( ptrdiff_t k ) const { return (*my_container)[my_index + k].value; } Value* operator->() const {return &operator*();} enumerable_thread_specific_iterator& operator++() { ++my_index; my_value = NULL; return *this; } enumerable_thread_specific_iterator& operator--() { --my_index; my_value = NULL; return *this; } //! Post increment enumerable_thread_specific_iterator operator++(int) { enumerable_thread_specific_iterator result = *this; ++my_index; my_value = NULL; return result; } //! Post decrement enumerable_thread_specific_iterator operator--(int) { enumerable_thread_specific_iterator result = *this; --my_index; my_value = NULL; return result; } // STL support typedef ptrdiff_t difference_type; typedef Value value_type; typedef Value* pointer; typedef Value& reference; typedef std::random_access_iterator_tag iterator_category; }; template enumerable_thread_specific_iterator operator+( ptrdiff_t offset, const enumerable_thread_specific_iterator& v ) { return enumerable_thread_specific_iterator( v.my_container, v.my_index + offset ); } template bool operator==( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ) { return i.my_index==j.my_index && i.my_container == j.my_container; } template bool operator!=( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ) { return !(i==j); } template bool operator<( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ) { return i.my_index bool operator>( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ) { return j bool operator>=( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ) { return !(i bool operator<=( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ) { return !(j ptrdiff_t operator-( const enumerable_thread_specific_iterator& i, const enumerable_thread_specific_iterator& j ) { return i.my_index-j.my_index; } template class segmented_iterator #if defined(_WIN64) && defined(_MSC_VER) : public std::iterator #endif { template friend bool operator==(const segmented_iterator& i, const segmented_iterator& j); template friend bool operator!=(const segmented_iterator& i, const segmented_iterator& j); template friend class segmented_iterator; public: segmented_iterator() {my_segcont = NULL;} segmented_iterator( const SegmentedContainer& _segmented_container ) : my_segcont(const_cast(&_segmented_container)), outer_iter(my_segcont->end()) { } ~segmented_iterator() {} typedef typename SegmentedContainer::iterator outer_iterator; typedef typename SegmentedContainer::value_type InnerContainer; typedef typename InnerContainer::iterator inner_iterator; // STL support typedef ptrdiff_t difference_type; typedef Value value_type; typedef typename SegmentedContainer::size_type size_type; typedef Value* pointer; typedef Value& reference; typedef std::input_iterator_tag iterator_category; // Copy Constructor template segmented_iterator(const segmented_iterator& other) : my_segcont(other.my_segcont), outer_iter(other.outer_iter), // can we assign a default-constructed iterator to inner if we're at the end? inner_iter(other.inner_iter) {} // assignment template segmented_iterator& operator=( const segmented_iterator& other) { if(this != &other) { my_segcont = other.my_segcont; outer_iter = other.outer_iter; if(outer_iter != my_segcont->end()) inner_iter = other.inner_iter; } return *this; } // allow assignment of outer iterator to segmented iterator. Once it is // assigned, move forward until a non-empty inner container is found or // the end of the outer container is reached. segmented_iterator& operator=(const outer_iterator& new_outer_iter) { __TBB_ASSERT(my_segcont != NULL, NULL); // check that this iterator points to something inside the segmented container for(outer_iter = new_outer_iter ;outer_iter!=my_segcont->end(); ++outer_iter) { if( !outer_iter->empty() ) { inner_iter = outer_iter->begin(); break; } } return *this; } // pre-increment segmented_iterator& operator++() { advance_me(); return *this; } // post-increment segmented_iterator operator++(int) { segmented_iterator tmp = *this; operator++(); return tmp; } bool operator==(const outer_iterator& other_outer) const { __TBB_ASSERT(my_segcont != NULL, NULL); return (outer_iter == other_outer && (outer_iter == my_segcont->end() || inner_iter == outer_iter->begin())); } bool operator!=(const outer_iterator& other_outer) const { return !operator==(other_outer); } // (i)* RHS reference operator*() const { __TBB_ASSERT(my_segcont != NULL, NULL); __TBB_ASSERT(outer_iter != my_segcont->end(), "Dereferencing a pointer at end of container"); __TBB_ASSERT(inner_iter != outer_iter->end(), NULL); // should never happen return *inner_iter; } // i-> pointer operator->() const { return &operator*();} private: SegmentedContainer* my_segcont; outer_iterator outer_iter; inner_iterator inner_iter; void advance_me() { __TBB_ASSERT(my_segcont != NULL, NULL); __TBB_ASSERT(outer_iter != my_segcont->end(), NULL); // not true if there are no inner containers __TBB_ASSERT(inner_iter != outer_iter->end(), NULL); // not true if the inner containers are all empty. ++inner_iter; while(inner_iter == outer_iter->end() && ++outer_iter != my_segcont->end()) { inner_iter = outer_iter->begin(); } } }; // segmented_iterator template bool operator==( const segmented_iterator& i, const segmented_iterator& j ) { if(i.my_segcont != j.my_segcont) return false; if(i.my_segcont == NULL) return true; if(i.outer_iter != j.outer_iter) return false; if(i.outer_iter == i.my_segcont->end()) return true; return i.inner_iter == j.inner_iter; } // != template bool operator!=( const segmented_iterator& i, const segmented_iterator& j ) { return !(i==j); } template struct destruct_only: tbb::internal::no_copy { tbb::aligned_space value; ~destruct_only() {value.begin()[0].~T();} }; template struct construct_by_default: tbb::internal::no_assign { void construct(void*where) {new(where) T();} // C++ note: the () in T() ensure zero initialization. construct_by_default( int ) {} }; template struct construct_by_exemplar: tbb::internal::no_assign { const T exemplar; void construct(void*where) {new(where) T(exemplar);} construct_by_exemplar( const T& t ) : exemplar(t) {} }; template struct construct_by_finit: tbb::internal::no_assign { Finit f; void construct(void* where) {new(where) T(f());} construct_by_finit( const Finit& f_ ) : f(f_) {} }; // storage for initialization function pointer template class callback_base { public: // Clone *this virtual callback_base* clone() = 0; // Destruct and free *this virtual void destroy() = 0; // Need virtual destructor to satisfy GCC compiler warning virtual ~callback_base() { } // Construct T at where virtual void construct(void* where) = 0; }; template class callback_leaf: public callback_base, Constructor { template callback_leaf( const X& x ) : Constructor(x) {} typedef typename tbb::tbb_allocator my_allocator_type; /*override*/ callback_base* clone() { void* where = my_allocator_type().allocate(1); return new(where) callback_leaf(*this); } /*override*/ void destroy() { my_allocator_type().destroy(this); my_allocator_type().deallocate(this,1); } /*override*/ void construct(void* where) { Constructor::construct(where); } public: template static callback_base* make( const X& x ) { void* where = my_allocator_type().allocate(1); return new(where) callback_leaf(x); } }; //! Template for adding padding in order to avoid false sharing /** ModularSize should be sizeof(U) modulo the cache line size. All maintenance of the space will be done explicitly on push_back, and all thread local copies must be destroyed before the concurrent vector is deleted. */ template struct ets_element { ets_element() { /* avoid cl warning C4345 about default initialization of POD types */ } char value[ModularSize==0 ? sizeof(U) : sizeof(U)+(tbb::internal::NFS_MaxLineSize-ModularSize)]; void unconstruct() { tbb::internal::punned_cast(&value)->~U(); } }; } // namespace internal //! @endcond //! The enumerable_thread_specific container /** enumerable_thread_specific has the following properties: - thread-local copies are lazily created, with default, exemplar or function initialization. - thread-local copies do not move (during lifetime, and excepting clear()) so the address of a copy is invariant. - the contained objects need not have operator=() defined if combine is not used. - enumerable_thread_specific containers may be copy-constructed or assigned. - thread-local copies can be managed by hash-table, or can be accessed via TLS storage for speed. - outside of parallel contexts, the contents of all thread-local copies are accessible by iterator or using combine or combine_each methods @par Segmented iterator When the thread-local objects are containers with input_iterators defined, a segmented iterator may be used to iterate over all the elements of all thread-local copies. @par combine and combine_each - Both methods are defined for enumerable_thread_specific. - combine() requires the the type T have operator=() defined. - neither method modifies the contents of the object (though there is no guarantee that the applied methods do not modify the object.) - Both are evaluated in serial context (the methods are assumed to be non-benign.) @ingroup containers */ template , ets_key_usage_type ETS_key_type=ets_no_key > class enumerable_thread_specific: internal::ets_base { template friend class enumerable_thread_specific; typedef internal::ets_element padded_element; //! A generic range, used to create range objects from the iterators template class generic_range_type: public blocked_range { public: typedef T value_type; typedef T& reference; typedef const T& const_reference; typedef I iterator; typedef ptrdiff_t difference_type; generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range(begin_,end_,grainsize_) {} template generic_range_type( const generic_range_type& r) : blocked_range(r.begin(),r.end(),r.grainsize()) {} generic_range_type( generic_range_type& r, split ) : blocked_range(r,split()) {} }; typedef typename Allocator::template rebind< padded_element >::other padded_allocator_type; typedef tbb::concurrent_vector< padded_element, padded_allocator_type > internal_collection_type; internal::callback_base *my_construct_callback; internal_collection_type my_locals; /*override*/ void* create_local() { void* lref = &*my_locals.grow_by(1); my_construct_callback->construct(lref); return lref; } void unconstruct_locals() { for(typename internal_collection_type::iterator cvi = my_locals.begin(); cvi != my_locals.end(); ++cvi) { cvi->unconstruct(); } } typedef typename Allocator::template rebind< uintptr_t >::other array_allocator_type; // _size is in bytes /*override*/ void* create_array(size_t _size) { size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t); return array_allocator_type().allocate(nelements); } /*override*/ void free_array( void* _ptr, size_t _size) { size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t); array_allocator_type().deallocate( reinterpret_cast(_ptr),nelements); } public: //! Basic types typedef Allocator allocator_type; typedef T value_type; typedef T& reference; typedef const T& const_reference; typedef T* pointer; typedef const T* const_pointer; typedef typename internal_collection_type::size_type size_type; typedef typename internal_collection_type::difference_type difference_type; // Iterator types typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, value_type > iterator; typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, const value_type > const_iterator; // Parallel range types typedef generic_range_type< iterator > range_type; typedef generic_range_type< const_iterator > const_range_type; //! Default constructor. Each local instance of T is default constructed. enumerable_thread_specific() : my_construct_callback( internal::callback_leaf >::make(/*dummy argument*/0) ) {} //! Constructor with initializer functor. Each local instance of T is constructed by T(finit()). template enumerable_thread_specific( Finit finit ) : my_construct_callback( internal::callback_leaf >::make( finit ) ) {} //! Constructor with exemplar. Each local instance of T is copied-constructed from the exemplar. enumerable_thread_specific(const T& exemplar) : my_construct_callback( internal::callback_leaf >::make( exemplar ) ) {} //! Destructor ~enumerable_thread_specific() { my_construct_callback->destroy(); this->clear(); // deallocation before the derived class is finished destructing // So free(array *) is still accessible } //! returns reference to local, discarding exists reference local() { bool exists; return local(exists); } //! Returns reference to calling thread's local copy, creating one if necessary reference local(bool& exists) { void* ptr = this->table_lookup(exists); return *(T*)ptr; } //! Get the number of local copies size_type size() const { return my_locals.size(); } //! true if there have been no local copies created bool empty() const { return my_locals.empty(); } //! begin iterator iterator begin() { return iterator( my_locals, 0 ); } //! end iterator iterator end() { return iterator(my_locals, my_locals.size() ); } //! begin const iterator const_iterator begin() const { return const_iterator(my_locals, 0); } //! end const iterator const_iterator end() const { return const_iterator(my_locals, my_locals.size()); } //! Get range for parallel algorithms range_type range( size_t grainsize=1 ) { return range_type( begin(), end(), grainsize ); } //! Get const range for parallel algorithms const_range_type range( size_t grainsize=1 ) const { return const_range_type( begin(), end(), grainsize ); } //! Destroys local copies void clear() { unconstruct_locals(); my_locals.clear(); this->table_clear(); // callback is not destroyed // exemplar is not destroyed } private: template void internal_copy( const enumerable_thread_specific& other); public: template enumerable_thread_specific( const enumerable_thread_specific& other ) : internal::ets_base () { internal_copy(other); } enumerable_thread_specific( const enumerable_thread_specific& other ) : internal::ets_base () { internal_copy(other); } private: template enumerable_thread_specific & internal_assign(const enumerable_thread_specific& other) { if(static_cast( this ) != static_cast( &other )) { this->clear(); my_construct_callback->destroy(); my_construct_callback = 0; internal_copy( other ); } return *this; } public: // assignment enumerable_thread_specific& operator=(const enumerable_thread_specific& other) { return internal_assign(other); } template enumerable_thread_specific& operator=(const enumerable_thread_specific& other) { return internal_assign(other); } // combine_func_t has signature T(T,T) or T(const T&, const T&) template T combine(combine_func_t f_combine) { if(begin() == end()) { internal::destruct_only location; my_construct_callback->construct(location.value.begin()); return *location.value.begin(); } const_iterator ci = begin(); T my_result = *ci; while(++ci != end()) my_result = f_combine( my_result, *ci ); return my_result; } // combine_func_t has signature void(T) or void(const T&) template void combine_each(combine_func_t f_combine) { for(const_iterator ci = begin(); ci != end(); ++ci) { f_combine( *ci ); } } }; // enumerable_thread_specific template template void enumerable_thread_specific::internal_copy( const enumerable_thread_specific& other) { // Initialize my_construct_callback first, so that it is valid even if rest of this routine throws an exception. my_construct_callback = other.my_construct_callback->clone(); typedef internal::ets_base base; __TBB_ASSERT(my_locals.size()==0,NULL); this->table_reserve_for_copy( other ); for( base::array* r=other.my_root; r; r=r->next ) { for( size_t i=0; isize(); ++i ) { base::slot& s1 = r->at(i); if( !s1.empty() ) { base::slot& s2 = this->table_find(s1.key); if( s2.empty() ) { void* lref = &*my_locals.grow_by(1); s2.ptr = new(lref) T(*(U*)s1.ptr); s2.key = s1.key; } else { // Skip the duplicate } } } } } template< typename Container > class flattened2d { // This intermediate typedef is to address issues with VC7.1 compilers typedef typename Container::value_type conval_type; public: //! Basic types typedef typename conval_type::size_type size_type; typedef typename conval_type::difference_type difference_type; typedef typename conval_type::allocator_type allocator_type; typedef typename conval_type::value_type value_type; typedef typename conval_type::reference reference; typedef typename conval_type::const_reference const_reference; typedef typename conval_type::pointer pointer; typedef typename conval_type::const_pointer const_pointer; typedef typename internal::segmented_iterator iterator; typedef typename internal::segmented_iterator const_iterator; flattened2d( const Container &c, typename Container::const_iterator b, typename Container::const_iterator e ) : my_container(const_cast(&c)), my_begin(b), my_end(e) { } flattened2d( const Container &c ) : my_container(const_cast(&c)), my_begin(c.begin()), my_end(c.end()) { } iterator begin() { return iterator(*my_container) = my_begin; } iterator end() { return iterator(*my_container) = my_end; } const_iterator begin() const { return const_iterator(*my_container) = my_begin; } const_iterator end() const { return const_iterator(*my_container) = my_end; } size_type size() const { size_type tot_size = 0; for(typename Container::const_iterator i = my_begin; i != my_end; ++i) { tot_size += i->size(); } return tot_size; } private: Container *my_container; typename Container::const_iterator my_begin; typename Container::const_iterator my_end; }; template flattened2d flatten2d(const Container &c, const typename Container::const_iterator b, const typename Container::const_iterator e) { return flattened2d(c, b, e); } template flattened2d flatten2d(const Container &c) { return flattened2d(c); } } // interface6 namespace internal { using interface6::internal::segmented_iterator; } using interface6::enumerable_thread_specific; using interface6::flattened2d; using interface6::flatten2d; } // namespace tbb #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/flow_graph.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_flow_graph_H #define __TBB_flow_graph_H #include "tbb_stddef.h" #include "atomic.h" #include "spin_mutex.h" #include "null_mutex.h" #include "spin_rw_mutex.h" #include "null_rw_mutex.h" #include "task.h" #include "cache_aligned_allocator.h" #include "tbb_exception.h" #include "internal/_aggregator_impl.h" #include "tbb_profiling.h" #if TBB_DEPRECATED_FLOW_ENQUEUE #define FLOW_SPAWN(a) tbb::task::enqueue((a)) #else #define FLOW_SPAWN(a) tbb::task::spawn((a)) #endif // use the VC10 or gcc version of tuple if it is available. #if __TBB_CPP11_TUPLE_PRESENT #include namespace tbb { namespace flow { using std::tuple; using std::tuple_size; using std::tuple_element; using std::get; } } #else #include "compat/tuple" #endif #include #include /** @file \brief The graph related classes and functions There are some applications that best express dependencies as messages passed between nodes in a graph. These messages may contain data or simply act as signals that a predecessors has completed. The graph class and its associated node classes can be used to express such applications. */ namespace tbb { namespace flow { //! An enumeration the provides the two most common concurrency levels: unlimited and serial enum concurrency { unlimited = 0, serial = 1 }; namespace interface7 { namespace internal { template class successor_cache; template class broadcast_cache; template class round_robin_cache; } //! An empty class used for messages that mean "I'm done" class continue_msg {}; template< typename T > class sender; template< typename T > class receiver; class continue_receiver; //! Pure virtual template class that defines a sender of messages of type T template< typename T > class sender { public: //! The output type of this sender typedef T output_type; //! The successor type for this node typedef receiver successor_type; virtual ~sender() {} //! Add a new successor to this node virtual bool register_successor( successor_type &r ) = 0; //! Removes a successor from this node virtual bool remove_successor( successor_type &r ) = 0; //! Request an item from the sender virtual bool try_get( T & ) { return false; } //! Reserves an item in the sender virtual bool try_reserve( T & ) { return false; } //! Releases the reserved item virtual bool try_release( ) { return false; } //! Consumes the reserved item virtual bool try_consume( ) { return false; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES //! interface to record edges for traversal & deletion virtual void internal_add_built_successor( successor_type & ) = 0; virtual void internal_delete_built_successor( successor_type & ) = 0; virtual void copy_successors( std::vector &) = 0; virtual size_t successor_count() = 0; #endif }; template< typename T > class limiter_node; // needed for resetting decrementer template< typename R, typename B > class run_and_put_task; static tbb::task * const SUCCESSFULLY_ENQUEUED = (task *)-1; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES // flags to modify the behavior of the graph reset(). Can be combined. enum reset_flags { rf_reset_protocol = 0, rf_reset_bodies = 1<<0, // delete the current node body, reset to a copy of the initial node body. rf_extract = 1<<1 // delete edges (extract() for single node, reset() for graph.) }; #define __TBB_PFG_RESET_ARG(exp) exp #define __TBB_COMMA , #else #define __TBB_PFG_RESET_ARG(exp) /* nothing */ #define __TBB_COMMA /* nothing */ #endif // enqueue left task if necessary. Returns the non-enqueued task if there is one. static inline tbb::task *combine_tasks( tbb::task * left, tbb::task * right) { // if no RHS task, don't change left. if(right == NULL) return left; // right != NULL if(left == NULL) return right; if(left == SUCCESSFULLY_ENQUEUED) return right; // left contains a task if(right != SUCCESSFULLY_ENQUEUED) { // both are valid tasks FLOW_SPAWN(*left); return right; } return left; } //! Pure virtual template class that defines a receiver of messages of type T template< typename T > class receiver { public: //! The input type of this receiver typedef T input_type; //! The predecessor type for this node typedef sender predecessor_type; //! Destructor virtual ~receiver() {} //! Put an item to the receiver bool try_put( const T& t ) { task *res = try_put_task(t); if(!res) return false; if (res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res); return true; } //! put item to successor; return task to run the successor if possible. protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; virtual task *try_put_task(const T& t) = 0; public: //! Add a predecessor to the node virtual bool register_predecessor( predecessor_type & ) { return false; } //! Remove a predecessor from the node virtual bool remove_predecessor( predecessor_type & ) { return false; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES virtual void internal_add_built_predecessor( predecessor_type & ) = 0; virtual void internal_delete_built_predecessor( predecessor_type & ) = 0; virtual void copy_predecessors( std::vector & ) = 0; virtual size_t predecessor_count() = 0; #endif protected: //! put receiver back in initial state template friend class limiter_node; virtual void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f = rf_reset_protocol ) ) = 0; template friend class internal::successor_cache; virtual bool is_continue_receiver() { return false; } }; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES //* holder of edges both for caches and for those nodes which do not have predecessor caches. // C == receiver< ... > or sender< ... >, depending. template class edge_container { public: typedef std::vector edge_vector; void add_edge( C &s) { built_edges.push_back( &s ); } void delete_edge( C &s) { for ( typename edge_vector::iterator i = built_edges.begin(); i != built_edges.end(); ++i ) { if ( *i == &s ) { (void)built_edges.erase(i); return; // only remove one predecessor per request } } } void copy_edges( edge_vector &v) { v = built_edges; } size_t edge_count() { return (size_t)(built_edges.size()); } void clear() { built_edges.clear(); } template< typename S > void sender_extract( S &s ); template< typename R > void receiver_extract( R &r ); private: edge_vector built_edges; }; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ //! Base class for receivers of completion messages /** These receivers automatically reset, but cannot be explicitly waited on */ class continue_receiver : public receiver< continue_msg > { public: //! The input type typedef continue_msg input_type; //! The predecessor type for this node typedef sender< continue_msg > predecessor_type; //! Constructor continue_receiver( int number_of_predecessors = 0 ) { my_predecessor_count = my_initial_predecessor_count = number_of_predecessors; my_current_count = 0; } //! Copy constructor continue_receiver( const continue_receiver& src ) : receiver() { my_predecessor_count = my_initial_predecessor_count = src.my_initial_predecessor_count; my_current_count = 0; } //! Destructor virtual ~continue_receiver() { } //! Increments the trigger threshold /* override */ bool register_predecessor( predecessor_type & ) { spin_mutex::scoped_lock l(my_mutex); ++my_predecessor_count; return true; } //! Decrements the trigger threshold /** Does not check to see if the removal of the predecessor now makes the current count exceed the new threshold. So removing a predecessor while the graph is active can cause unexpected results. */ /* override */ bool remove_predecessor( predecessor_type & ) { spin_mutex::scoped_lock l(my_mutex); --my_predecessor_count; return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; /*override*/ void internal_add_built_predecessor( predecessor_type &s) { spin_mutex::scoped_lock l(my_mutex); my_built_predecessors.add_edge( s ); } /*override*/ void internal_delete_built_predecessor( predecessor_type &s) { spin_mutex::scoped_lock l(my_mutex); my_built_predecessors.delete_edge(s); } /*override*/ void copy_predecessors( predecessor_vector_type &v) { spin_mutex::scoped_lock l(my_mutex); my_built_predecessors.copy_edges(v); } /*override*/ size_t predecessor_count() { spin_mutex::scoped_lock l(my_mutex); return my_built_predecessors.edge_count(); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; // execute body is supposed to be too small to create a task for. /* override */ task *try_put_task( const input_type & ) { { spin_mutex::scoped_lock l(my_mutex); if ( ++my_current_count < my_predecessor_count ) return SUCCESSFULLY_ENQUEUED; else my_current_count = 0; } task * res = execute(); if(!res) return SUCCESSFULLY_ENQUEUED; return res; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container my_built_predecessors; #endif spin_mutex my_mutex; int my_predecessor_count; int my_current_count; int my_initial_predecessor_count; // the friend declaration in the base class did not eliminate the "protected class" // error in gcc 4.1.2 template friend class limiter_node; /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f) ) { my_current_count = 0; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES if(f & rf_extract) { my_built_predecessors.receiver_extract(*this); my_predecessor_count = my_initial_predecessor_count; } #endif } //! Does whatever should happen when the threshold is reached /** This should be very fast or else spawn a task. This is called while the sender is blocked in the try_put(). */ virtual task * execute() = 0; template friend class internal::successor_cache; /*override*/ bool is_continue_receiver() { return true; } }; } // interface7 } // flow } // tbb #include "internal/_flow_graph_trace_impl.h" namespace tbb { namespace flow { namespace interface7 { #include "internal/_flow_graph_types_impl.h" #include "internal/_flow_graph_impl.h" using namespace internal::graph_policy_namespace; class graph; class graph_node; template class graph_iterator { friend class graph; friend class graph_node; public: typedef size_t size_type; typedef GraphNodeType value_type; typedef GraphNodeType* pointer; typedef GraphNodeType& reference; typedef const GraphNodeType& const_reference; typedef std::forward_iterator_tag iterator_category; //! Default constructor graph_iterator() : my_graph(NULL), current_node(NULL) {} //! Copy constructor graph_iterator(const graph_iterator& other) : my_graph(other.my_graph), current_node(other.current_node) {} //! Assignment graph_iterator& operator=(const graph_iterator& other) { if (this != &other) { my_graph = other.my_graph; current_node = other.current_node; } return *this; } //! Dereference reference operator*() const; //! Dereference pointer operator->() const; //! Equality bool operator==(const graph_iterator& other) const { return ((my_graph == other.my_graph) && (current_node == other.current_node)); } //! Inequality bool operator!=(const graph_iterator& other) const { return !(operator==(other)); } //! Pre-increment graph_iterator& operator++() { internal_forward(); return *this; } //! Post-increment graph_iterator operator++(int) { graph_iterator result = *this; operator++(); return result; } private: // the graph over which we are iterating GraphContainerType *my_graph; // pointer into my_graph's my_nodes list pointer current_node; //! Private initializing constructor for begin() and end() iterators graph_iterator(GraphContainerType *g, bool begin); void internal_forward(); }; //! The graph class /** This class serves as a handle to the graph */ class graph : tbb::internal::no_copy { friend class graph_node; template< typename Body > class run_task : public task { public: run_task( Body& body ) : my_body(body) {} task *execute() { my_body(); return NULL; } private: Body my_body; }; template< typename Receiver, typename Body > class run_and_put_task : public task { public: run_and_put_task( Receiver &r, Body& body ) : my_receiver(r), my_body(body) {} task *execute() { task *res = my_receiver.try_put_task( my_body() ); if(res == SUCCESSFULLY_ENQUEUED) res = NULL; return res; } private: Receiver &my_receiver; Body my_body; }; public: //! Constructs a graph with isolated task_group_context explicit graph() : my_nodes(NULL), my_nodes_last(NULL) { own_context = true; cancelled = false; caught_exception = false; my_context = new task_group_context(); my_root_task = ( new ( task::allocate_root(*my_context) ) empty_task ); my_root_task->set_ref_count(1); tbb::internal::fgt_graph( this ); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_is_active = true; #endif } //! Constructs a graph with use_this_context as context explicit graph(task_group_context& use_this_context) : my_context(&use_this_context), my_nodes(NULL), my_nodes_last(NULL) { own_context = false; my_root_task = ( new ( task::allocate_root(*my_context) ) empty_task ); my_root_task->set_ref_count(1); tbb::internal::fgt_graph( this ); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_is_active = true; #endif } //! Destroys the graph. /** Calls wait_for_all, then destroys the root task and context. */ ~graph() { wait_for_all(); my_root_task->set_ref_count(0); task::destroy( *my_root_task ); if (own_context) delete my_context; } #if TBB_PREVIEW_FLOW_GRAPH_TRACE void set_name( const char *name ) { tbb::internal::fgt_graph_desc( this, name ); } #endif //! Used to register that an external entity may still interact with the graph. /** The graph will not return from wait_for_all until a matching number of decrement_wait_count calls is made. */ void increment_wait_count() { if (my_root_task) my_root_task->increment_ref_count(); } //! Deregisters an external entity that may have interacted with the graph. /** The graph will not return from wait_for_all until all the number of decrement_wait_count calls matches the number of increment_wait_count calls. */ void decrement_wait_count() { if (my_root_task) my_root_task->decrement_ref_count(); } //! Spawns a task that runs a body and puts its output to a specific receiver /** The task is spawned as a child of the graph. This is useful for running tasks that need to block a wait_for_all() on the graph. For example a one-off source. */ template< typename Receiver, typename Body > void run( Receiver &r, Body body ) { FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *my_root_task ) ) run_and_put_task< Receiver, Body >( r, body )) ); } //! Spawns a task that runs a function object /** The task is spawned as a child of the graph. This is useful for running tasks that need to block a wait_for_all() on the graph. For example a one-off source. */ template< typename Body > void run( Body body ) { FLOW_SPAWN( * new ( task::allocate_additional_child_of( *my_root_task ) ) run_task< Body >( body ) ); } //! Wait until graph is idle and decrement_wait_count calls equals increment_wait_count calls. /** The waiting thread will go off and steal work while it is block in the wait_for_all. */ void wait_for_all() { cancelled = false; caught_exception = false; if (my_root_task) { #if TBB_USE_EXCEPTIONS try { #endif my_root_task->wait_for_all(); cancelled = my_context->is_group_execution_cancelled(); #if TBB_USE_EXCEPTIONS } catch(...) { my_root_task->set_ref_count(1); my_context->reset(); caught_exception = true; cancelled = true; throw; } #endif my_context->reset(); // consistent with behavior in catch() my_root_task->set_ref_count(1); } } //! Returns the root task of the graph task * root_task() { #if TBB_PREVIEW_FLOW_GRAPH_FEATURES if (!my_is_active) return NULL; else #endif return my_root_task; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES void set_active(bool a = true) { my_is_active = a; } bool is_active() { return my_is_active; } #endif // ITERATORS template friend class graph_iterator; // Graph iterator typedefs typedef graph_iterator iterator; typedef graph_iterator const_iterator; // Graph iterator constructors //! start iterator iterator begin() { return iterator(this, true); } //! end iterator iterator end() { return iterator(this, false); } //! start const iterator const_iterator begin() const { return const_iterator(this, true); } //! end const iterator const_iterator end() const { return const_iterator(this, false); } //! start const iterator const_iterator cbegin() const { return const_iterator(this, true); } //! end const iterator const_iterator cend() const { return const_iterator(this, false); } //! return status of graph execution bool is_cancelled() { return cancelled; } bool exception_thrown() { return caught_exception; } // thread-unsafe state reset. void reset(__TBB_PFG_RESET_ARG(reset_flags f = rf_reset_protocol)); private: task *my_root_task; task_group_context *my_context; bool own_context; bool cancelled; bool caught_exception; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES bool my_is_active; #endif graph_node *my_nodes, *my_nodes_last; spin_mutex nodelist_mutex; void register_node(graph_node *n); void remove_node(graph_node *n); }; // class graph template graph_iterator::graph_iterator(C *g, bool begin) : my_graph(g), current_node(NULL) { if (begin) current_node = my_graph->my_nodes; //else it is an end iterator by default } template typename graph_iterator::reference graph_iterator::operator*() const { __TBB_ASSERT(current_node, "graph_iterator at end"); return *operator->(); } template typename graph_iterator::pointer graph_iterator::operator->() const { return current_node; } template void graph_iterator::internal_forward() { if (current_node) current_node = current_node->next; } //! The base of all graph nodes. class graph_node : tbb::internal::no_assign { friend class graph; template friend class graph_iterator; protected: graph& my_graph; graph_node *next, *prev; public: graph_node(graph& g) : my_graph(g) { my_graph.register_node(this); } virtual ~graph_node() { my_graph.remove_node(this); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE virtual void set_name( const char *name ) = 0; #endif #if TBB_PREVIEW_FLOW_GRAPH_FEATURES virtual void extract( reset_flags f=rf_extract ) { bool a = my_graph.is_active(); my_graph.set_active(false); reset((reset_flags)(f|rf_extract)); my_graph.set_active(a); } #endif protected: virtual void reset(__TBB_PFG_RESET_ARG(reset_flags f=rf_reset_protocol)) = 0; }; inline void graph::register_node(graph_node *n) { n->next = NULL; { spin_mutex::scoped_lock lock(nodelist_mutex); n->prev = my_nodes_last; if (my_nodes_last) my_nodes_last->next = n; my_nodes_last = n; if (!my_nodes) my_nodes = n; } } inline void graph::remove_node(graph_node *n) { { spin_mutex::scoped_lock lock(nodelist_mutex); __TBB_ASSERT(my_nodes && my_nodes_last, "graph::remove_node: Error: no registered nodes"); if (n->prev) n->prev->next = n->next; if (n->next) n->next->prev = n->prev; if (my_nodes_last == n) my_nodes_last = n->prev; if (my_nodes == n) my_nodes = n->next; } n->prev = n->next = NULL; } inline void graph::reset( __TBB_PFG_RESET_ARG( reset_flags f )) { // reset context task *saved_my_root_task = my_root_task; my_root_task = NULL; if(my_context) my_context->reset(); cancelled = false; caught_exception = false; // reset all the nodes comprising the graph for(iterator ii = begin(); ii != end(); ++ii) { graph_node *my_p = &(*ii); my_p->reset(__TBB_PFG_RESET_ARG(f)); } my_root_task = saved_my_root_task; } #include "internal/_flow_graph_node_impl.h" //! An executable node that acts as a source, i.e. it has no predecessors template < typename Output > class source_node : public graph_node, public sender< Output > { protected: using graph_node::my_graph; public: //! The type of the output message, which is complete typedef Output output_type; //! The type of successors of this node typedef receiver< Output > successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector successor_vector_type; #endif //! Constructor for a node with a successor template< typename Body > source_node( graph &g, Body body, bool is_active = true ) : graph_node(g), my_active(is_active), init_my_active(is_active), my_body( new internal::source_body_leaf< output_type, Body>(body) ), my_reserved(false), my_has_cached_item(false) { my_successors.set_owner(this); tbb::internal::fgt_node_with_body( tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, static_cast *>(this), this->my_body ); } //! Copy constructor source_node( const source_node& src ) : graph_node(src.my_graph), sender(), my_active(src.init_my_active), init_my_active(src.init_my_active), my_body( src.my_body->clone() ), my_reserved(false), my_has_cached_item(false) { my_successors.set_owner(this); tbb::internal::fgt_node_with_body( tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, static_cast *>(this), this->my_body ); } //! The destructor ~source_node() { delete my_body; } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif //! Add a new successor to this node /* override */ bool register_successor( successor_type &r ) { spin_mutex::scoped_lock lock(my_mutex); my_successors.register_successor(r); if ( my_active ) spawn_put(); return true; } //! Removes a successor from this node /* override */ bool remove_successor( successor_type &r ) { spin_mutex::scoped_lock lock(my_mutex); my_successors.remove_successor(r); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void internal_add_built_successor( successor_type &r) { spin_mutex::scoped_lock lock(my_mutex); my_successors.internal_add_built_successor(r); } /*override*/void internal_delete_built_successor( successor_type &r) { spin_mutex::scoped_lock lock(my_mutex); my_successors.internal_delete_built_successor(r); } /*override*/size_t successor_count() { spin_mutex::scoped_lock lock(my_mutex); return my_successors.successor_count(); } /*override*/void copy_successors(successor_vector_type &v) { spin_mutex::scoped_lock l(my_mutex); my_successors.copy_successors(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ //! Request an item from the node /*override */ bool try_get( output_type &v ) { spin_mutex::scoped_lock lock(my_mutex); if ( my_reserved ) return false; if ( my_has_cached_item ) { v = my_cached_item; my_has_cached_item = false; return true; } // we've been asked to provide an item, but we have none. enqueue a task to // provide one. spawn_put(); return false; } //! Reserves an item. /* override */ bool try_reserve( output_type &v ) { spin_mutex::scoped_lock lock(my_mutex); if ( my_reserved ) { return false; } if ( my_has_cached_item ) { v = my_cached_item; my_reserved = true; return true; } else { return false; } } //! Release a reserved item. /** true = item has been released and so remains in sender, dest must request or reserve future items */ /* override */ bool try_release( ) { spin_mutex::scoped_lock lock(my_mutex); __TBB_ASSERT( my_reserved && my_has_cached_item, "releasing non-existent reservation" ); my_reserved = false; if(!my_successors.empty()) spawn_put(); return true; } //! Consumes a reserved item /* override */ bool try_consume( ) { spin_mutex::scoped_lock lock(my_mutex); __TBB_ASSERT( my_reserved && my_has_cached_item, "consuming non-existent reservation" ); my_reserved = false; my_has_cached_item = false; if ( !my_successors.empty() ) { spawn_put(); } return true; } //! Activates a node that was created in the inactive state void activate() { spin_mutex::scoped_lock lock(my_mutex); my_active = true; if ( !my_successors.empty() ) spawn_put(); } template Body copy_function_object() { internal::source_body &body_ref = *this->my_body; return dynamic_cast< internal::source_body_leaf & >(body_ref).get_body(); } protected: //! resets the source_node to its initial state void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { my_active = init_my_active; my_reserved =false; if(my_has_cached_item) { my_has_cached_item = false; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_successors.reset(f); if(f & rf_reset_bodies) my_body->reset_body(); #endif } private: spin_mutex my_mutex; bool my_active; bool init_my_active; internal::source_body *my_body; internal::broadcast_cache< output_type > my_successors; bool my_reserved; bool my_has_cached_item; output_type my_cached_item; // used by apply_body, can invoke body of node. bool try_reserve_apply_body(output_type &v) { spin_mutex::scoped_lock lock(my_mutex); if ( my_reserved ) { return false; } if ( !my_has_cached_item ) { tbb::internal::fgt_begin_body( my_body ); bool r = (*my_body)(my_cached_item); tbb::internal::fgt_end_body( my_body ); if (r) { my_has_cached_item = true; } } if ( my_has_cached_item ) { v = my_cached_item; my_reserved = true; return true; } else { return false; } } //! Spawns a task that applies the body /* override */ void spawn_put( ) { task* tp = this->my_graph.root_task(); if(tp) { FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *tp ) ) internal:: source_task_bypass < source_node< output_type > >( *this ) ) ); } } friend class internal::source_task_bypass< source_node< output_type > >; //! Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it. /* override */ task * apply_body_bypass( ) { output_type v; if ( !try_reserve_apply_body(v) ) return NULL; task *last_task = my_successors.try_put_task(v); if ( last_task ) try_consume(); else try_release(); return last_task; } }; // source_node //! Implements a function node that supports Input -> Output template < typename Input, typename Output = continue_msg, graph_buffer_policy = queueing, typename Allocator=cache_aligned_allocator > class function_node : public graph_node, public internal::function_input, public internal::function_output { protected: using graph_node::my_graph; public: typedef Input input_type; typedef Output output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; typedef internal::function_input fInput_type; typedef internal::function_output fOutput_type; #if TBB_PREVIEW_FLOW_GRAPH_FEAURES typedef std::vector predecessor_vector_type; typedef std::vector successor_vector_type; #endif //! Constructor template< typename Body > function_node( graph &g, size_t concurrency, Body body ) : graph_node(g), internal::function_input(g, concurrency, body) { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } //! Copy constructor function_node( const function_node& src ) : graph_node(src.my_graph), internal::function_input( src ), fOutput_type() { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; using fInput_type::try_put_task; // override of graph_node's reset. /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { fInput_type::reset_function_input(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES successors().reset(f); __TBB_ASSERT(!(f & rf_extract) || successors().empty(), "function_node successors not empty"); __TBB_ASSERT(this->my_predecessors.empty(), "function_node predecessors not empty"); #endif } /* override */ internal::broadcast_cache &successors () { return fOutput_type::my_successors; } }; //! Implements a function node that supports Input -> Output template < typename Input, typename Output, typename Allocator > class function_node : public graph_node, public internal::function_input, public internal::function_output { protected: using graph_node::my_graph; public: typedef Input input_type; typedef Output output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; typedef internal::function_input fInput_type; typedef internal::function_input_queue queue_type; typedef internal::function_output fOutput_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; typedef std::vector successor_vector_type; #endif //! Constructor template< typename Body > function_node( graph &g, size_t concurrency, Body body ) : graph_node(g), fInput_type( g, concurrency, body, new queue_type() ) { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } //! Copy constructor function_node( const function_node& src ) : graph_node(src.graph_node::my_graph), fInput_type( src, new queue_type() ), fOutput_type() { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; using fInput_type::try_put_task; /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { fInput_type::reset_function_input(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES successors().reset(f); __TBB_ASSERT(!(f & rf_extract) || successors().empty(), "function_node successors not empty"); __TBB_ASSERT(!(f & rf_extract) || this->my_predecessors.empty(), "function_node predecessors not empty"); #endif } /* override */ internal::broadcast_cache &successors () { return fOutput_type::my_successors; } }; //! implements a function node that supports Input -> (set of outputs) // Output is a tuple of output types. template < typename Input, typename Output, graph_buffer_policy = queueing, typename Allocator=cache_aligned_allocator > class multifunction_node : public graph_node, public internal::multifunction_input < Input, typename internal::wrap_tuple_elements< tbb::flow::tuple_size::value, // #elements in tuple internal::multifunction_output, // wrap this around each element Output // the tuple providing the types >::type, Allocator > { protected: using graph_node::my_graph; private: static const int N = tbb::flow::tuple_size::value; public: typedef Input input_type; typedef typename internal::wrap_tuple_elements::type output_ports_type; private: typedef typename internal::multifunction_input base_type; typedef typename internal::function_input_queue queue_type; public: template multifunction_node( graph &g, size_t concurrency, Body body ) : graph_node(g), base_type(g,concurrency, body) { tbb::internal::fgt_multioutput_node_with_body( tbb::internal::FLOW_MULTIFUNCTION_NODE, &this->graph_node::my_graph, static_cast *>(this), this->output_ports(), this->my_body ); } multifunction_node( const multifunction_node &other) : graph_node(other.graph_node::my_graph), base_type(other) { tbb::internal::fgt_multioutput_node_with_body( tbb::internal::FLOW_MULTIFUNCTION_NODE, &this->graph_node::my_graph, static_cast *>(this), this->output_ports(), this->my_body ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_multioutput_node_desc( this, name ); } #endif // all the guts are in multifunction_input... protected: /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { base_type::reset(__TBB_PFG_RESET_ARG(f)); } }; // multifunction_node template < typename Input, typename Output, typename Allocator > class multifunction_node : public graph_node, public internal::multifunction_input::value, internal::multifunction_output, Output>::type, Allocator> { protected: using graph_node::my_graph; static const int N = tbb::flow::tuple_size::value; public: typedef Input input_type; typedef typename internal::wrap_tuple_elements::type output_ports_type; private: typedef typename internal::multifunction_input base_type; typedef typename internal::function_input_queue queue_type; public: template multifunction_node( graph &g, size_t concurrency, Body body) : graph_node(g), base_type(g,concurrency, body, new queue_type()) { tbb::internal::fgt_multioutput_node_with_body( tbb::internal::FLOW_MULTIFUNCTION_NODE, &this->graph_node::my_graph, static_cast *>(this), this->output_ports(), this->my_body ); } multifunction_node( const multifunction_node &other) : graph_node(other.graph_node::my_graph), base_type(other, new queue_type()) { tbb::internal::fgt_multioutput_node_with_body( tbb::internal::FLOW_MULTIFUNCTION_NODE, &this->graph_node::my_graph, static_cast *>(this), this->output_ports(), this->my_body ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_multioutput_node_desc( this, name ); } #endif // all the guts are in multifunction_input... protected: /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { base_type::reset(__TBB_PFG_RESET_ARG(f)); } }; // multifunction_node //! split_node: accepts a tuple as input, forwards each element of the tuple to its // successors. The node has unlimited concurrency, so though it is marked as // "rejecting" it does not reject inputs. template > class split_node : public multifunction_node { static const int N = tbb::flow::tuple_size::value; typedef multifunction_node base_type; public: typedef typename base_type::output_ports_type output_ports_type; private: struct splitting_body { void operator()(const TupleType& t, output_ports_type &p) { internal::emit_element::emit_this(t, p); } }; public: typedef TupleType input_type; typedef Allocator allocator_type; split_node(graph &g) : base_type(g, unlimited, splitting_body()) { tbb::internal::fgt_multioutput_node( tbb::internal::FLOW_SPLIT_NODE, &this->graph_node::my_graph, static_cast *>(this), this->output_ports() ); } split_node( const split_node & other) : base_type(other) { tbb::internal::fgt_multioutput_node( tbb::internal::FLOW_SPLIT_NODE, &this->graph_node::my_graph, static_cast *>(this), this->output_ports() ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_multioutput_node_desc( this, name ); } #endif }; //! Implements an executable node that supports continue_msg -> Output template class continue_node : public graph_node, public internal::continue_input, public internal::function_output { protected: using graph_node::my_graph; public: typedef continue_msg input_type; typedef Output output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; typedef internal::continue_input fInput_type; typedef internal::function_output fOutput_type; //! Constructor for executable node with continue_msg -> Output template continue_node( graph &g, Body body ) : graph_node(g), internal::continue_input( g, body ) { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } //! Constructor for executable node with continue_msg -> Output template continue_node( graph &g, int number_of_predecessors, Body body ) : graph_node(g), internal::continue_input( g, number_of_predecessors, body ) { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } //! Copy constructor continue_node( const continue_node& src ) : graph_node(src.graph_node::my_graph), internal::continue_input(src), internal::function_output() { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; using fInput_type::try_put_task; /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { fInput_type::reset_receiver(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES successors().reset(f); __TBB_ASSERT(!(f & rf_extract) || successors().empty(), "continue_node not reset"); #endif } /* override */ internal::broadcast_cache &successors () { return fOutput_type::my_successors; } }; // continue_node template< typename T > class overwrite_node : public graph_node, public receiver, public sender { protected: using graph_node::my_graph; public: typedef T input_type; typedef T output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; typedef std::vector successor_vector_type; #endif overwrite_node(graph &g) : graph_node(g), my_buffer_is_valid(false) { my_successors.set_owner( this ); tbb::internal::fgt_node( tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); } // Copy constructor; doesn't take anything from src; default won't work overwrite_node( const overwrite_node& src ) : graph_node(src.my_graph), receiver(), sender(), my_buffer_is_valid(false) { my_successors.set_owner( this ); tbb::internal::fgt_node( tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); } ~overwrite_node() {} #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif /* override */ bool register_successor( successor_type &s ) { spin_mutex::scoped_lock l( my_mutex ); task* tp = this->my_graph.root_task(); // just to test if we are resetting if (my_buffer_is_valid && tp) { // We have a valid value that must be forwarded immediately. if ( s.try_put( my_buffer ) || !s.register_predecessor( *this ) ) { // We add the successor: it accepted our put or it rejected it but won't let us become a predecessor my_successors.register_successor( s ); } else { // We don't add the successor: it rejected our put and we became its predecessor instead return false; } } else { // No valid value yet, just add as successor my_successors.register_successor( s ); } return true; } /* override */ bool remove_successor( successor_type &s ) { spin_mutex::scoped_lock l( my_mutex ); my_successors.remove_successor(s); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void internal_add_built_successor( successor_type &s) { spin_mutex::scoped_lock l( my_mutex ); my_successors.internal_add_built_successor(s); } /*override*/void internal_delete_built_successor( successor_type &s) { spin_mutex::scoped_lock l( my_mutex ); my_successors.internal_delete_built_successor(s); } /*override*/size_t successor_count() { spin_mutex::scoped_lock l( my_mutex ); return my_successors.successor_count(); } /*override*/ void copy_successors(successor_vector_type &v) { spin_mutex::scoped_lock l( my_mutex ); my_successors.copy_successors(v); } /*override*/ void internal_add_built_predecessor( predecessor_type &p) { spin_mutex::scoped_lock l( my_mutex ); my_built_predecessors.add_edge(p); } /*override*/ void internal_delete_built_predecessor( predecessor_type &p) { spin_mutex::scoped_lock l( my_mutex ); my_built_predecessors.delete_edge(p); } /*override*/size_t predecessor_count() { spin_mutex::scoped_lock l( my_mutex ); return my_built_predecessors.edge_count(); } /*override*/void copy_predecessors(predecessor_vector_type &v) { spin_mutex::scoped_lock l( my_mutex ); my_built_predecessors.copy_edges(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ /* override */ bool try_get( input_type &v ) { spin_mutex::scoped_lock l( my_mutex ); if ( my_buffer_is_valid ) { v = my_buffer; return true; } return false; } bool is_valid() { spin_mutex::scoped_lock l( my_mutex ); return my_buffer_is_valid; } void clear() { spin_mutex::scoped_lock l( my_mutex ); my_buffer_is_valid = false; } protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; /* override */ task * try_put_task( const input_type &v ) { spin_mutex::scoped_lock l( my_mutex ); my_buffer = v; my_buffer_is_valid = true; task * rtask = my_successors.try_put_task(v); if(!rtask) rtask = SUCCESSFULLY_ENQUEUED; return rtask; } /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { my_buffer_is_valid = false; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_successors.reset(f); if (f&rf_extract) { my_built_predecessors.receiver_extract(*this); } #endif } spin_mutex my_mutex; internal::broadcast_cache< input_type, null_rw_mutex > my_successors; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container > my_built_predecessors; #endif input_type my_buffer; bool my_buffer_is_valid; /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) {} }; // overwrite_node template< typename T > class write_once_node : public overwrite_node { public: typedef T input_type; typedef T output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; //! Constructor write_once_node(graph& g) : overwrite_node(g) { tbb::internal::fgt_node( tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } //! Copy constructor: call base class copy constructor write_once_node( const write_once_node& src ) : overwrite_node(src) { tbb::internal::fgt_node( tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; /* override */ task *try_put_task( const T &v ) { spin_mutex::scoped_lock l( this->my_mutex ); if ( this->my_buffer_is_valid ) { return NULL; } else { this->my_buffer = v; this->my_buffer_is_valid = true; task *res = this->my_successors.try_put_task(v); if(!res) res = SUCCESSFULLY_ENQUEUED; return res; } } }; //! Forwards messages of type T to all successors template class broadcast_node : public graph_node, public receiver, public sender { protected: using graph_node::my_graph; public: typedef T input_type; typedef T output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; typedef std::vector successor_vector_type; #endif private: internal::broadcast_cache my_successors; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container my_built_predecessors; spin_mutex pred_mutex; #endif public: broadcast_node(graph& g) : graph_node(g) { my_successors.set_owner( this ); tbb::internal::fgt_node( tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); } // Copy constructor broadcast_node( const broadcast_node& src ) : graph_node(src.my_graph), receiver(), sender() { my_successors.set_owner( this ); tbb::internal::fgt_node( tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif //! Adds a successor virtual bool register_successor( receiver &r ) { my_successors.register_successor( r ); return true; } //! Removes s as a successor virtual bool remove_successor( receiver &r ) { my_successors.remove_successor( r ); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void internal_add_built_successor(successor_type &r) { my_successors.internal_add_built_successor(r); } /*override*/ void internal_delete_built_successor(successor_type &r) { my_successors.internal_delete_built_successor(r); } /*override*/ size_t successor_count() { return my_successors.successor_count(); } /*override*/ void copy_successors(successor_vector_type &v) { my_successors.copy_successors(v); } /*override*/ void internal_add_built_predecessor( predecessor_type &p) { my_built_predecessors.add_edge(p); } /*override*/ void internal_delete_built_predecessor( predecessor_type &p) { my_built_predecessors.delete_edge(p); } /*override*/ size_t predecessor_count() { return my_built_predecessors.edge_count(); } /*override*/ void copy_predecessors(predecessor_vector_type &v) { my_built_predecessors.copy_edges(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; //! build a task to run the successor if possible. Default is old behavior. /*override*/ task *try_put_task(const T& t) { task *new_task = my_successors.try_put_task(t); if(!new_task) new_task = SUCCESSFULLY_ENQUEUED; return new_task; } /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_successors.reset(f); if (f&rf_extract) { my_built_predecessors.receiver_extract(*this); } __TBB_ASSERT(!(f & rf_extract) || my_successors.empty(), "Error resetting broadcast_node"); #endif } /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) {} }; // broadcast_node //! Forwards messages in arbitrary order template > class buffer_node : public graph_node, public internal::reservable_item_buffer, public receiver, public sender { protected: using graph_node::my_graph; public: typedef T input_type; typedef T output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; typedef buffer_node my_class; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; typedef std::vector successor_vector_type; #endif protected: typedef size_t size_type; internal::round_robin_cache< T, null_rw_mutex > my_successors; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container my_built_predecessors; #endif friend class internal::forward_task_bypass< buffer_node< T, A > >; enum op_type {reg_succ, rem_succ, req_item, res_item, rel_res, con_res, put_item, try_fwd_task #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , add_blt_succ, del_blt_succ, add_blt_pred, del_blt_pred, blt_succ_cnt, blt_pred_cnt, blt_succ_cpy, blt_pred_cpy // create vector copies of preds and succs #endif }; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; // implements the aggregator_operation concept class buffer_operation : public internal::aggregated_operation< buffer_operation > { public: char type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES task * ltask; union { input_type *elem; successor_type *r; predecessor_type *p; size_t cnt_val; successor_vector_type *svec; predecessor_vector_type *pvec; }; #else T *elem; task * ltask; successor_type *r; #endif buffer_operation(const T& e, op_type t) : type(char(t)) #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , ltask(NULL), elem(const_cast(&e)) #else , elem(const_cast(&e)) , ltask(NULL) #endif {} buffer_operation(op_type t) : type(char(t)), ltask(NULL) {} }; bool forwarder_busy; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; internal::aggregator< my_handler, buffer_operation> my_aggregator; virtual void handle_operations(buffer_operation *op_list) { buffer_operation *tmp = NULL; bool try_forwarding=false; while (op_list) { tmp = op_list; op_list = op_list->next; switch (tmp->type) { case reg_succ: internal_reg_succ(tmp); try_forwarding = true; break; case rem_succ: internal_rem_succ(tmp); break; case req_item: internal_pop(tmp); break; case res_item: internal_reserve(tmp); break; case rel_res: internal_release(tmp); try_forwarding = true; break; case con_res: internal_consume(tmp); try_forwarding = true; break; case put_item: internal_push(tmp); try_forwarding = (tmp->status == SUCCEEDED); break; case try_fwd_task: internal_forward_task(tmp); break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES // edge recording case add_blt_succ: internal_add_built_succ(tmp); break; case del_blt_succ: internal_del_built_succ(tmp); break; case add_blt_pred: internal_add_built_pred(tmp); break; case del_blt_pred: internal_del_built_pred(tmp); break; case blt_succ_cnt: internal_succ_cnt(tmp); break; case blt_pred_cnt: internal_pred_cnt(tmp); break; case blt_succ_cpy: internal_copy_succs(tmp); break; case blt_pred_cpy: internal_copy_preds(tmp); break; #endif } } if (try_forwarding && !forwarder_busy) { task* tp = this->my_graph.root_task(); if(tp) { forwarder_busy = true; task *new_task = new(task::allocate_additional_child_of(*tp)) internal:: forward_task_bypass < buffer_node >(*this); // tmp should point to the last item handled by the aggregator. This is the operation // the handling thread enqueued. So modifying that record will be okay. tbb::task *z = tmp->ltask; tmp->ltask = combine_tasks(z, new_task); // in case the op generated a task } } } inline task *grab_forwarding_task( buffer_operation &op_data) { return op_data.ltask; } inline bool enqueue_forwarding_task(buffer_operation &op_data) { task *ft = grab_forwarding_task(op_data); if(ft) { FLOW_SPAWN(*ft); return true; } return false; } //! This is executed by an enqueued task, the "forwarder" virtual task *forward_task() { buffer_operation op_data(try_fwd_task); task *last_task = NULL; do { op_data.status = WAIT; op_data.ltask = NULL; my_aggregator.execute(&op_data); tbb::task *xtask = op_data.ltask; last_task = combine_tasks(last_task, xtask); } while (op_data.status == SUCCEEDED); return last_task; } //! Register successor virtual void internal_reg_succ(buffer_operation *op) { my_successors.register_successor(*(op->r)); __TBB_store_with_release(op->status, SUCCEEDED); } //! Remove successor virtual void internal_rem_succ(buffer_operation *op) { my_successors.remove_successor(*(op->r)); __TBB_store_with_release(op->status, SUCCEEDED); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES virtual void internal_add_built_succ(buffer_operation *op) { my_successors.internal_add_built_successor(*(op->r)); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_del_built_succ(buffer_operation *op) { my_successors.internal_delete_built_successor(*(op->r)); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_add_built_pred(buffer_operation *op) { my_built_predecessors.add_edge(*(op->p)); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_del_built_pred(buffer_operation *op) { my_built_predecessors.delete_edge(*(op->p)); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_succ_cnt(buffer_operation *op) { op->cnt_val = my_successors.successor_count(); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_pred_cnt(buffer_operation *op) { op->cnt_val = my_built_predecessors.edge_count(); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_copy_succs(buffer_operation *op) { my_successors.copy_successors(*(op->svec)); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_copy_preds(buffer_operation *op) { my_built_predecessors.copy_edges(*(op->pvec)); __TBB_store_with_release(op->status, SUCCEEDED); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ //! Tries to forward valid items to successors virtual void internal_forward_task(buffer_operation *op) { if (this->my_reserved || !this->my_item_valid(this->my_tail-1)) { __TBB_store_with_release(op->status, FAILED); this->forwarder_busy = false; return; } T i_copy; task * last_task = NULL; size_type counter = my_successors.size(); // Try forwarding, giving each successor a chance while (counter>0 && !this->buffer_empty() && this->my_item_valid(this->my_tail-1)) { this->copy_back(i_copy); task *new_task = my_successors.try_put_task(i_copy); if(new_task) { last_task = combine_tasks(last_task, new_task); this->destroy_back(); } --counter; } op->ltask = last_task; // return task if (last_task && !counter) { __TBB_store_with_release(op->status, SUCCEEDED); } else { __TBB_store_with_release(op->status, FAILED); forwarder_busy = false; } } virtual void internal_push(buffer_operation *op) { this->push_back(*(op->elem)); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_pop(buffer_operation *op) { if(this->pop_back(*(op->elem))) { __TBB_store_with_release(op->status, SUCCEEDED); } else { __TBB_store_with_release(op->status, FAILED); } } virtual void internal_reserve(buffer_operation *op) { if(this->reserve_front(*(op->elem))) { __TBB_store_with_release(op->status, SUCCEEDED); } else { __TBB_store_with_release(op->status, FAILED); } } virtual void internal_consume(buffer_operation *op) { this->consume_front(); __TBB_store_with_release(op->status, SUCCEEDED); } virtual void internal_release(buffer_operation *op) { this->release_front(); __TBB_store_with_release(op->status, SUCCEEDED); } public: //! Constructor buffer_node( graph &g ) : graph_node(g), internal::reservable_item_buffer(), forwarder_busy(false) { my_successors.set_owner(this); my_aggregator.initialize_handler(my_handler(this)); tbb::internal::fgt_node( tbb::internal::FLOW_BUFFER_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); } //! Copy constructor buffer_node( const buffer_node& src ) : graph_node(src.my_graph), internal::reservable_item_buffer(), receiver(), sender() { forwarder_busy = false; my_successors.set_owner(this); my_aggregator.initialize_handler(my_handler(this)); tbb::internal::fgt_node( tbb::internal::FLOW_BUFFER_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); } virtual ~buffer_node() {} #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif // // message sender implementation // //! Adds a new successor. /** Adds successor r to the list of successors; may forward tasks. */ /* override */ bool register_successor( successor_type &r ) { buffer_operation op_data(reg_succ); op_data.r = &r; my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void internal_add_built_successor( successor_type &r) { buffer_operation op_data(add_blt_succ); op_data.r = &r; my_aggregator.execute(&op_data); } /*override*/ void internal_delete_built_successor( successor_type &r) { buffer_operation op_data(del_blt_succ); op_data.r = &r; my_aggregator.execute(&op_data); } /*override*/ void internal_add_built_predecessor( predecessor_type &p) { buffer_operation op_data(add_blt_pred); op_data.p = &p; my_aggregator.execute(&op_data); } /*override*/ void internal_delete_built_predecessor( predecessor_type &p) { buffer_operation op_data(del_blt_pred); op_data.p = &p; my_aggregator.execute(&op_data); } /*override*/ size_t predecessor_count() { buffer_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } /*override*/ size_t successor_count() { buffer_operation op_data(blt_succ_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } /*override*/ void copy_predecessors( predecessor_vector_type &v ) { buffer_operation op_data(blt_pred_cpy); op_data.pvec = &v; my_aggregator.execute(&op_data); } /*override*/ void copy_successors( successor_vector_type &v ) { buffer_operation op_data(blt_succ_cpy); op_data.svec = &v; my_aggregator.execute(&op_data); } #endif //! Removes a successor. /** Removes successor r from the list of successors. It also calls r.remove_predecessor(*this) to remove this node as a predecessor. */ /* override */ bool remove_successor( successor_type &r ) { r.remove_predecessor(*this); buffer_operation op_data(rem_succ); op_data.r = &r; my_aggregator.execute(&op_data); // even though this operation does not cause a forward, if we are the handler, and // a forward is scheduled, we may be the first to reach this point after the aggregator, // and so should check for the task. (void)enqueue_forwarding_task(op_data); return true; } //! Request an item from the buffer_node /** true = v contains the returned item
false = no item has been returned */ /* override */ bool try_get( T &v ) { buffer_operation op_data(req_item); op_data.elem = &v; my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); return (op_data.status==SUCCEEDED); } //! Reserves an item. /** false = no item can be reserved
true = an item is reserved */ /* override */ bool try_reserve( T &v ) { buffer_operation op_data(res_item); op_data.elem = &v; my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); return (op_data.status==SUCCEEDED); } //! Release a reserved item. /** true = item has been released and so remains in sender */ /* override */ bool try_release() { buffer_operation op_data(rel_res); my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); return true; } //! Consumes a reserved item. /** true = item is removed from sender and reservation removed */ /* override */ bool try_consume() { buffer_operation op_data(con_res); my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); return true; } protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; //! receive an item, return a task *if possible /* override */ task *try_put_task(const T &t) { buffer_operation op_data(t, put_item); my_aggregator.execute(&op_data); task *ft = grab_forwarding_task(op_data); // sequencer_nodes can return failure (if an item has been previously inserted) // We have to spawn the returned task if our own operation fails. if(ft && op_data.status == FAILED) { // we haven't succeeded queueing the item, but for some reason the // call returned a task (if another request resulted in a successful // forward this could happen.) Queue the task and reset the pointer. FLOW_SPAWN(*ft); ft = NULL; } else if(!ft && op_data.status == SUCCEEDED) { ft = SUCCESSFULLY_ENQUEUED; } return ft; } /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { internal::reservable_item_buffer::reset(); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_successors.reset(f); if (f&rf_extract) { my_built_predecessors.receiver_extract(*this); } #endif forwarder_busy = false; } /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { } }; // buffer_node //! Forwards messages in FIFO order template > class queue_node : public buffer_node { protected: typedef buffer_node base_type; typedef typename base_type::size_type size_type; typedef typename base_type::buffer_operation queue_operation; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; /* override */ void internal_forward_task(queue_operation *op) { if (this->my_reserved || !this->my_item_valid(this->my_head)) { __TBB_store_with_release(op->status, FAILED); this->forwarder_busy = false; return; } T i_copy; task *last_task = NULL; size_type counter = this->my_successors.size(); // Keep trying to send items while there is at least one accepting successor while (counter>0 && this->my_item_valid(this->my_head)) { this->copy_front(i_copy); task *new_task = this->my_successors.try_put_task(i_copy); if(new_task) { this->destroy_front(); last_task = combine_tasks(last_task, new_task); } --counter; } op->ltask = last_task; if (last_task && !counter) __TBB_store_with_release(op->status, SUCCEEDED); else { __TBB_store_with_release(op->status, FAILED); this->forwarder_busy = false; } } /* override */ void internal_pop(queue_operation *op) { if ( this->my_reserved || !this->my_item_valid(this->my_head)){ __TBB_store_with_release(op->status, FAILED); } else { this->pop_front(*(op->elem)); __TBB_store_with_release(op->status, SUCCEEDED); } } /* override */ void internal_reserve(queue_operation *op) { if (this->my_reserved || !this->my_item_valid(this->my_head)) { __TBB_store_with_release(op->status, FAILED); } else { this->reserve_front(*(op->elem)); __TBB_store_with_release(op->status, SUCCEEDED); } } /* override */ void internal_consume(queue_operation *op) { this->consume_front(); __TBB_store_with_release(op->status, SUCCEEDED); } public: typedef T input_type; typedef T output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; //! Constructor queue_node( graph &g ) : base_type(g) { tbb::internal::fgt_node( tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } //! Copy constructor queue_node( const queue_node& src) : base_type(src) { tbb::internal::fgt_node( tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { base_type::reset(__TBB_PFG_RESET_ARG(f)); } }; // queue_node //! Forwards messages in sequence order template< typename T, typename A=cache_aligned_allocator > class sequencer_node : public queue_node { internal::function_body< T, size_t > *my_sequencer; // my_sequencer should be a benign function and must be callable // from a parallel context. Does this mean it needn't be reset? public: typedef T input_type; typedef T output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; //! Constructor template< typename Sequencer > sequencer_node( graph &g, const Sequencer& s ) : queue_node(g), my_sequencer(new internal::function_body_leaf< T, size_t, Sequencer>(s) ) { tbb::internal::fgt_node( tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } //! Copy constructor sequencer_node( const sequencer_node& src ) : queue_node(src), my_sequencer( src.my_sequencer->clone() ) { tbb::internal::fgt_node( tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } //! Destructor ~sequencer_node() { delete my_sequencer; } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif protected: typedef typename buffer_node::size_type size_type; typedef typename buffer_node::buffer_operation sequencer_operation; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; private: /* override */ void internal_push(sequencer_operation *op) { size_type tag = (*my_sequencer)(*(op->elem)); #if !TBB_DEPRECATED_SEQUENCER_DUPLICATES if(tag < this->my_head) { // have already emitted a message with this tag __TBB_store_with_release(op->status, FAILED); return; } #endif // cannot modify this->my_tail now; the buffer would be inconsistent. size_t new_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail; if(this->size(new_tail) > this->capacity()) { this->grow_my_array(this->size(new_tail)); } this->my_tail = new_tail; if(this->place_item(tag,*(op->elem))) { __TBB_store_with_release(op->status, SUCCEEDED); } else { // already have a message with this tag __TBB_store_with_release(op->status, FAILED); } } }; // sequencer_node //! Forwards messages in priority order template< typename T, typename Compare = std::less, typename A=cache_aligned_allocator > class priority_queue_node : public buffer_node { public: typedef T input_type; typedef T output_type; typedef buffer_node base_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; //! Constructor priority_queue_node( graph &g ) : buffer_node(g), mark(0) { tbb::internal::fgt_node( tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } //! Copy constructor priority_queue_node( const priority_queue_node &src ) : buffer_node(src), mark(0) { tbb::internal::fgt_node( tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif protected: /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { mark = 0; base_type::reset(__TBB_PFG_RESET_ARG(f)); } typedef typename buffer_node::size_type size_type; typedef typename buffer_node::item_type item_type; typedef typename buffer_node::buffer_operation prio_operation; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; /* override */ void handle_operations(prio_operation *op_list) { prio_operation *tmp = op_list /*, *pop_list*/ ; bool try_forwarding=false; while (op_list) { tmp = op_list; op_list = op_list->next; switch (tmp->type) { case buffer_node::reg_succ: this->internal_reg_succ(tmp); try_forwarding = true; break; case buffer_node::rem_succ: this->internal_rem_succ(tmp); break; case buffer_node::put_item: internal_push(tmp); try_forwarding = true; break; case buffer_node::try_fwd_task: internal_forward_task(tmp); break; case buffer_node::rel_res: internal_release(tmp); try_forwarding = true; break; case buffer_node::con_res: internal_consume(tmp); try_forwarding = true; break; case buffer_node::req_item: internal_pop(tmp); break; case buffer_node::res_item: internal_reserve(tmp); break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES case buffer_node::add_blt_succ: this->internal_add_built_succ(tmp); break; case buffer_node::del_blt_succ: this->internal_del_built_succ(tmp); break; case buffer_node::add_blt_pred: this->internal_add_built_pred(tmp); break; case buffer_node::del_blt_pred: this->internal_del_built_pred(tmp); break; case buffer_node::blt_succ_cnt: this->internal_succ_cnt(tmp); break; case buffer_node::blt_pred_cnt: this->internal_pred_cnt(tmp); break; case buffer_node::blt_succ_cpy: this->internal_copy_succs(tmp); break; case buffer_node::blt_pred_cpy: this->internal_copy_preds(tmp); break; #endif } } // process pops! for now, no special pop processing if (markmy_tail) heapify(); if (try_forwarding && !this->forwarder_busy) { task* tp = this->my_graph.root_task(); if(tp) { this->forwarder_busy = true; task *new_task = new(task::allocate_additional_child_of(*tp)) internal:: forward_task_bypass < buffer_node >(*this); // tmp should point to the last item handled by the aggregator. This is the operation // the handling thread enqueued. So modifying that record will be okay. tbb::task *tmp1 = tmp->ltask; tmp->ltask = combine_tasks(tmp1, new_task); } } } //! Tries to forward valid items to successors /* override */ void internal_forward_task(prio_operation *op) { T i_copy; task * last_task = NULL; // flagged when a successor accepts size_type counter = this->my_successors.size(); if (this->my_reserved || this->my_tail == 0) { __TBB_store_with_release(op->status, FAILED); this->forwarder_busy = false; return; } // Keep trying to send while there exists an accepting successor while (counter>0 && this->my_tail > 0) { i_copy = this->get_my_item(0); task * new_task = this->my_successors.try_put_task(i_copy); if ( new_task ) { last_task = combine_tasks(last_task, new_task); this->destroy_item(0); // we've forwarded this item if (mark == this->my_tail) --mark; if(--(this->my_tail)) { // didn't consume last item on heap this->move_item(0,this->my_tail); } if (this->my_tail > 1) // don't reheap for heap of size 1 reheap(); } --counter; } op->ltask = last_task; if (last_task && !counter) __TBB_store_with_release(op->status, SUCCEEDED); else { __TBB_store_with_release(op->status, FAILED); this->forwarder_busy = false; } } /* override */ void internal_push(prio_operation *op) { if ( this->my_tail >= this->my_array_size ) this->grow_my_array( this->my_tail + 1 ); (void) this->place_item(this->my_tail, *(op->elem)); ++(this->my_tail); __TBB_store_with_release(op->status, SUCCEEDED); } /* override */ void internal_pop(prio_operation *op) { // if empty or already reserved, don't pop if ( this->my_reserved == true || this->my_tail == 0 ) { __TBB_store_with_release(op->status, FAILED); return; } if (markmy_tail && // item pushed, no re-heap compare(this->get_my_item(0), this->get_my_item(this->my_tail-1))) { // there are newly pushed elems; last one higher than top // copy the data this->fetch_item(this->my_tail-1, *(op->elem)); __TBB_store_with_release(op->status, SUCCEEDED); --(this->my_tail); return; } // extract and push the last element down heap *(op->elem) = this->get_my_item(0); // copy the data, item 0 still valid __TBB_store_with_release(op->status, SUCCEEDED); if (mark == this->my_tail) --mark; __TBB_ASSERT(this->my_item_valid(this->my_tail - 1), NULL); if(--(this->my_tail)) { // there were two or more items in heap. Move the // last item to the top of the heap this->set_my_item(0,this->get_my_item(this->my_tail)); } this->destroy_item(this->my_tail); if (this->my_tail > 1) // don't reheap for heap of size 1 reheap(); } /* override */ void internal_reserve(prio_operation *op) { if (this->my_reserved == true || this->my_tail == 0) { __TBB_store_with_release(op->status, FAILED); return; } this->my_reserved = true; *(op->elem) = reserved_item = this->get_my_item(0); if (mark == this->my_tail) --mark; --(this->my_tail); __TBB_store_with_release(op->status, SUCCEEDED); this->set_my_item(0, this->get_my_item(this->my_tail)); this->destroy_item(this->my_tail); if (this->my_tail > 1) reheap(); } /* override */ void internal_consume(prio_operation *op) { this->my_reserved = false; __TBB_store_with_release(op->status, SUCCEEDED); } /* override */ void internal_release(prio_operation *op) { if (this->my_tail >= this->my_array_size) this->grow_my_array( this->my_tail + 1 ); this->set_my_item(this->my_tail, reserved_item); ++(this->my_tail); this->my_reserved = false; __TBB_store_with_release(op->status, SUCCEEDED); heapify(); } private: Compare compare; size_type mark; input_type reserved_item; // turn array into heap void heapify() { if (!mark) mark = 1; for (; markmy_tail; ++mark) { // for each unheaped element size_type cur_pos = mark; input_type to_place; this->fetch_item(mark,to_place); do { // push to_place up the heap size_type parent = (cur_pos-1)>>1; if (!compare(this->get_my_item(parent), to_place)) break; this->move_item(cur_pos, parent); cur_pos = parent; } while( cur_pos ); (void) this->place_item(cur_pos, to_place); } } // otherwise heapified array with new root element; rearrange to heap void reheap() { size_type cur_pos=0, child=1; while (child < mark) { size_type target = child; if (child+1get_my_item(child), this->get_my_item(child+1))) ++target; // target now has the higher priority child if (compare(this->get_my_item(target), this->get_my_item(cur_pos))) break; // swap this->swap_items(cur_pos, target); cur_pos = target; child = (cur_pos<<1)+1; } } }; // priority_queue_node //! Forwards messages only if the threshold has not been reached /** This node forwards items until its threshold is reached. It contains no buffering. If the downstream node rejects, the message is dropped. */ template< typename T > class limiter_node : public graph_node, public receiver< T >, public sender< T > { protected: using graph_node::my_graph; public: typedef T input_type; typedef T output_type; typedef sender< input_type > predecessor_type; typedef receiver< output_type > successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector successor_vector_type; typedef std::vector predecessor_vector_type; #endif private: size_t my_threshold; size_t my_count; //number of successful puts size_t my_tries; //number of active put attempts internal::reservable_predecessor_cache< T, spin_mutex > my_predecessors; spin_mutex my_mutex; internal::broadcast_cache< T > my_successors; int init_decrement_predecessors; friend class internal::forward_task_bypass< limiter_node >; // Let decrementer call decrement_counter() friend class internal::decrementer< limiter_node >; bool check_conditions() { // always called under lock return ( my_count + my_tries < my_threshold && !my_predecessors.empty() && !my_successors.empty() ); } // only returns a valid task pointer or NULL, never SUCCESSFULLY_ENQUEUED task *forward_task() { input_type v; task *rval = NULL; bool reserved = false; { spin_mutex::scoped_lock lock(my_mutex); if ( check_conditions() ) ++my_tries; else return NULL; } //SUCCESS // if we can reserve and can put, we consume the reservation // we increment the count and decrement the tries if ( (my_predecessors.try_reserve(v)) == true ){ reserved=true; if ( (rval = my_successors.try_put_task(v)) != NULL ){ { spin_mutex::scoped_lock lock(my_mutex); ++my_count; --my_tries; my_predecessors.try_consume(); if ( check_conditions() ) { task* tp = this->my_graph.root_task(); if ( tp ) { task *rtask = new ( task::allocate_additional_child_of( *tp ) ) internal::forward_task_bypass< limiter_node >( *this ); FLOW_SPAWN (*rtask); } } } return rval; } } //FAILURE //if we can't reserve, we decrement the tries //if we can reserve but can't put, we decrement the tries and release the reservation { spin_mutex::scoped_lock lock(my_mutex); --my_tries; if (reserved) my_predecessors.try_release(); if ( check_conditions() ) { task* tp = this->my_graph.root_task(); if ( tp ) { task *rtask = new ( task::allocate_additional_child_of( *tp ) ) internal::forward_task_bypass< limiter_node >( *this ); __TBB_ASSERT(!rval, "Have two tasks to handle"); return rtask; } } return rval; } } void forward() { __TBB_ASSERT(false, "Should never be called"); return; } task * decrement_counter() { { spin_mutex::scoped_lock lock(my_mutex); if(my_count) --my_count; } return forward_task(); } public: //! The internal receiver< continue_msg > that decrements the count internal::decrementer< limiter_node > decrement; //! Constructor limiter_node(graph &g, size_t threshold, int num_decrement_predecessors=0) : graph_node(g), my_threshold(threshold), my_count(0), my_tries(0), init_decrement_predecessors(num_decrement_predecessors), decrement(num_decrement_predecessors) { my_predecessors.set_owner(this); my_successors.set_owner(this); decrement.set_owner(this); tbb::internal::fgt_node( tbb::internal::FLOW_LIMITER_NODE, &this->my_graph, static_cast *>(this), static_cast *>(&decrement), static_cast *>(this) ); } //! Copy constructor limiter_node( const limiter_node& src ) : graph_node(src.my_graph), receiver(), sender(), my_threshold(src.my_threshold), my_count(0), my_tries(0), init_decrement_predecessors(src.init_decrement_predecessors), decrement(src.init_decrement_predecessors) { my_predecessors.set_owner(this); my_successors.set_owner(this); decrement.set_owner(this); tbb::internal::fgt_node( tbb::internal::FLOW_LIMITER_NODE, &this->my_graph, static_cast *>(this), static_cast *>(&decrement), static_cast *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif //! Replace the current successor with this new successor /* override */ bool register_successor( receiver &r ) { spin_mutex::scoped_lock lock(my_mutex); bool was_empty = my_successors.empty(); my_successors.register_successor(r); //spawn a forward task if this is the only successor if ( was_empty && !my_predecessors.empty() && my_count + my_tries < my_threshold ) { task* tp = this->my_graph.root_task(); if ( tp ) { FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *tp ) ) internal::forward_task_bypass < limiter_node >( *this ) ) ); } } return true; } //! Removes a successor from this node /** r.remove_predecessor(*this) is also called. */ /* override */ bool remove_successor( receiver &r ) { r.remove_predecessor(*this); my_successors.remove_successor(r); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void internal_add_built_successor(receiver &src) { my_successors.internal_add_built_successor(src); } /*override*/void internal_delete_built_successor(receiver &src) { my_successors.internal_delete_built_successor(src); } /*override*/size_t successor_count() { return my_successors.successor_count(); } /*override*/ void copy_successors(successor_vector_type &v) { my_successors.copy_successors(v); } /*override*/void internal_add_built_predecessor(sender &src) { my_predecessors.internal_add_built_predecessor(src); } /*override*/void internal_delete_built_predecessor(sender &src) { my_predecessors.internal_delete_built_predecessor(src); } /*override*/size_t predecessor_count() { return my_predecessors.predecessor_count(); } /*override*/ void copy_predecessors(predecessor_vector_type &v) { my_predecessors.copy_predecessors(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ //! Adds src to the list of cached predecessors. /* override */ bool register_predecessor( predecessor_type &src ) { spin_mutex::scoped_lock lock(my_mutex); my_predecessors.add( src ); task* tp = this->my_graph.root_task(); if ( my_count + my_tries < my_threshold && !my_successors.empty() && tp ) { FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *tp ) ) internal::forward_task_bypass < limiter_node >( *this ) ) ); } return true; } //! Removes src from the list of cached predecessors. /* override */ bool remove_predecessor( predecessor_type &src ) { my_predecessors.remove( src ); return true; } protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; //! Puts an item to this receiver /* override */ task *try_put_task( const T &t ) { { spin_mutex::scoped_lock lock(my_mutex); if ( my_count + my_tries >= my_threshold ) return NULL; else ++my_tries; } task * rtask = my_successors.try_put_task(t); if ( !rtask ) { // try_put_task failed. spin_mutex::scoped_lock lock(my_mutex); --my_tries; task* tp = this->my_graph.root_task(); if ( check_conditions() && tp ) { rtask = new ( task::allocate_additional_child_of( *tp ) ) internal::forward_task_bypass< limiter_node >( *this ); } } else { spin_mutex::scoped_lock lock(my_mutex); ++my_count; --my_tries; } return rtask; } /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { my_count = 0; my_predecessors.reset(__TBB_PFG_RESET_ARG(f)); decrement.reset_receiver(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_successors.reset(f); #endif } /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) { my_predecessors.reset(__TBB_PFG_RESET_ARG(f)); } }; // limiter_node #include "internal/_flow_graph_join_impl.h" using internal::reserving_port; using internal::queueing_port; using internal::tag_matching_port; using internal::input_port; using internal::tag_value; using internal::NO_TAG; template class join_node; template class join_node: public internal::unfolded_join_node::value, reserving_port, OutputTuple, reserving> { private: static const int N = tbb::flow::tuple_size::value; typedef typename internal::unfolded_join_node unfolded_type; public: typedef OutputTuple output_type; typedef typename unfolded_type::input_ports_type input_ports_type; join_node(graph &g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } join_node(const join_node &other) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; template class join_node: public internal::unfolded_join_node::value, queueing_port, OutputTuple, queueing> { private: static const int N = tbb::flow::tuple_size::value; typedef typename internal::unfolded_join_node unfolded_type; public: typedef OutputTuple output_type; typedef typename unfolded_type::input_ports_type input_ports_type; join_node(graph &g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } join_node(const join_node &other) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; // template for tag_matching join_node template class join_node : public internal::unfolded_join_node::value, tag_matching_port, OutputTuple, tag_matching> { private: static const int N = tbb::flow::tuple_size::value; typedef typename internal::unfolded_join_node unfolded_type; public: typedef OutputTuple output_type; typedef typename unfolded_type::input_ports_type input_ports_type; template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1) : unfolded_type(g, b0, b1) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2) : unfolded_type(g, b0, b1, b2) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3) : unfolded_type(g, b0, b1, b2, b3) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4) : unfolded_type(g, b0, b1, b2, b3, b4) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if __TBB_VARIADIC_MAX >= 6 template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5) : unfolded_type(g, b0, b1, b2, b3, b4, b5) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #endif #if __TBB_VARIADIC_MAX >= 7 template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #endif #if __TBB_VARIADIC_MAX >= 8 template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, __TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #endif #if __TBB_VARIADIC_MAX >= 9 template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, __TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #endif #if __TBB_VARIADIC_MAX >= 10 template join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #endif join_node(const join_node &other) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; // indexer node #include "internal/_flow_graph_indexer_impl.h" struct indexer_null_type {}; template class indexer_node; //indexer node specializations template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 1; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 2; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 3; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 4; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 5; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; #if __TBB_VARIADIC_MAX >= 6 template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 6; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; #endif //variadic max 6 #if __TBB_VARIADIC_MAX >= 7 template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 7; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; #endif //variadic max 7 #if __TBB_VARIADIC_MAX >= 8 template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 8; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; #endif //variadic max 8 #if __TBB_VARIADIC_MAX >= 9 template class indexer_node : public internal::unfolded_indexer_node > { private: static const int N = 9; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; #endif //variadic max 9 #if __TBB_VARIADIC_MAX >= 10 template class indexer_node/*default*/ : public internal::unfolded_indexer_node > { private: static const int N = 10; public: typedef tuple InputTuple; typedef typename internal::tagged_msg output_type; typedef typename internal::unfolded_indexer_node unfolded_type; indexer_node(graph& g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } // Copy constructor indexer_node( const indexer_node& other ) : unfolded_type(other) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE /* override */ void set_name( const char *name ) { tbb::internal::fgt_node_desc( this, name ); } #endif }; #endif //variadic max 10 //! Makes an edge between a single predecessor and a single successor template< typename T > inline void make_edge( sender &p, receiver &s ) { #if TBB_PREVIEW_FLOW_GRAPH_FEATURES s.internal_add_built_predecessor(p); p.internal_add_built_successor(s); #endif p.register_successor( s ); tbb::internal::fgt_make_edge( &p, &s ); } //! Makes an edge between a single predecessor and a single successor template< typename T > inline void remove_edge( sender &p, receiver &s ) { p.remove_successor( s ); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES // TODO: should we try to remove p from the predecessor list of s, in case the edge is reversed? p.internal_delete_built_successor(s); s.internal_delete_built_predecessor(p); #endif tbb::internal::fgt_remove_edge( &p, &s ); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES template template< typename S > void edge_container::sender_extract( S &s ) { edge_vector e = built_edges; for ( typename edge_vector::iterator i = e.begin(); i != e.end(); ++i ) { remove_edge(s, **i); } } template template< typename R > void edge_container::receiver_extract( R &r ) { edge_vector e = built_edges; for ( typename edge_vector::iterator i = e.begin(); i != e.end(); ++i ) { remove_edge(**i, r); } } #endif //! Returns a copy of the body from a function or continue node template< typename Body, typename Node > Body copy_body( Node &n ) { return n.template copy_function_object(); } } // interface7 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES using interface7::reset_flags; using interface7::rf_reset_protocol; using interface7::rf_reset_bodies; using interface7::rf_extract; #endif using interface7::graph; using interface7::graph_node; using interface7::continue_msg; using interface7::sender; using interface7::receiver; using interface7::continue_receiver; using interface7::source_node; using interface7::function_node; using interface7::multifunction_node; using interface7::split_node; using interface7::internal::output_port; using interface7::indexer_node; using interface7::internal::tagged_msg; using interface7::internal::cast_to; using interface7::internal::is_a; using interface7::continue_node; using interface7::overwrite_node; using interface7::write_once_node; using interface7::broadcast_node; using interface7::buffer_node; using interface7::queue_node; using interface7::sequencer_node; using interface7::priority_queue_node; using interface7::limiter_node; using namespace interface7::internal::graph_policy_namespace; using interface7::join_node; using interface7::input_port; using interface7::copy_body; using interface7::make_edge; using interface7::remove_edge; using interface7::internal::NO_TAG; using interface7::internal::tag_value; } // flow } // tbb #undef __TBB_PFG_RESET_ARG #undef __TBB_COMMA #endif // __TBB_flow_graph_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/governor.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include #include #include "governor.h" #include "tbb_main.h" #include "scheduler.h" #include "market.h" #include "arena.h" #include "tbb/task_scheduler_init.h" #include "dynamic_link.h" namespace tbb { namespace internal { //------------------------------------------------------------------------ // governor //------------------------------------------------------------------------ #if __TBB_SURVIVE_THREAD_SWITCH // Support for interoperability with Intel(R) Cilk(TM) Plus. #if _WIN32 #define CILKLIB_NAME "cilkrts20.dll" #else #define CILKLIB_NAME "libcilkrts.so" #endif //! Handler for interoperation with cilkrts library. static __cilk_tbb_retcode (*watch_stack_handler)(struct __cilk_tbb_unwatch_thunk* u, struct __cilk_tbb_stack_op_thunk o); //! Table describing how to link the handlers. static const dynamic_link_descriptor CilkLinkTable[] = { { "__cilkrts_watch_stack", (pointer_to_handler*)(void*)(&watch_stack_handler) } }; static atomic cilkrts_load_state; bool initialize_cilk_interop() { // Pinning can fail. This is a normal situation, and means that the current // thread does not use cilkrts and consequently does not need interop. return dynamic_link( CILKLIB_NAME, CilkLinkTable, 1, /*handle=*/0, DYNAMIC_LINK_GLOBAL ); } #endif /* __TBB_SURVIVE_THREAD_SWITCH */ namespace rml { tbb_server* make_private_server( tbb_client& client ); } void governor::acquire_resources () { #if USE_PTHREAD int status = theTLS.create(auto_terminate); #else int status = theTLS.create(); #endif if( status ) handle_perror(status, "TBB failed to initialize task scheduler TLS\n"); is_speculation_enabled = cpu_has_speculation(); } void governor::release_resources () { theRMLServerFactory.close(); #if TBB_USE_ASSERT if( __TBB_InitOnce::initialization_done() && theTLS.get() ) runtime_warning( "TBB is unloaded while tbb::task_scheduler_init object is alive?" ); #endif int status = theTLS.destroy(); if( status ) runtime_warning("failed to destroy task scheduler TLS: %s", strerror(status)); dynamic_unlink_all(); } rml::tbb_server* governor::create_rml_server ( rml::tbb_client& client ) { rml::tbb_server* server = NULL; if( !UsePrivateRML ) { ::rml::factory::status_type status = theRMLServerFactory.make_server( server, client ); if( status != ::rml::factory::st_success ) { UsePrivateRML = true; runtime_warning( "rml::tbb_factory::make_server failed with status %x, falling back on private rml", status ); } } if ( !server ) { __TBB_ASSERT( UsePrivateRML, NULL ); server = rml::make_private_server( client ); } __TBB_ASSERT( server, "Failed to create RML server" ); return server; } void governor::sign_on(generic_scheduler* s) { __TBB_ASSERT( !theTLS.get(), NULL ); theTLS.set(s); #if __TBB_SURVIVE_THREAD_SWITCH if( watch_stack_handler ) { __cilk_tbb_stack_op_thunk o; o.routine = &stack_op_handler; o.data = s; if( (*watch_stack_handler)(&s->my_cilk_unwatch_thunk, o) ) { // Failed to register with cilkrts, make sure we are clean s->my_cilk_unwatch_thunk.routine = NULL; } #if TBB_USE_ASSERT else s->my_cilk_state = generic_scheduler::cs_running; #endif /* TBB_USE_ASSERT */ } #endif /* __TBB_SURVIVE_THREAD_SWITCH */ } void governor::sign_off(generic_scheduler* s) { suppress_unused_warning(s); __TBB_ASSERT( theTLS.get()==s, "attempt to unregister a wrong scheduler instance" ); theTLS.set(NULL); #if __TBB_SURVIVE_THREAD_SWITCH __cilk_tbb_unwatch_thunk &ut = s->my_cilk_unwatch_thunk; if ( ut.routine ) (*ut.routine)(ut.data); #endif /* __TBB_SURVIVE_THREAD_SWITCH */ } void governor::setBlockingTerminate(const task_scheduler_init *tsi) { __TBB_ASSERT(!IsBlockingTerminationInProgress, "It's impossible to create task_scheduler_init while blocking termination is in progress."); if (BlockingTSI) throw_exception(eid_blocking_sch_init); BlockingTSI = tsi; } generic_scheduler* governor::init_scheduler( unsigned num_threads, stack_size_type stack_size, bool auto_init ) { if( !__TBB_InitOnce::initialization_done() ) DoOneTimeInitializations(); generic_scheduler* s = theTLS.get(); if( s ) { s->my_ref_count += 1; return s; } #if __TBB_SURVIVE_THREAD_SWITCH atomic_do_once( &initialize_cilk_interop, cilkrts_load_state ); #endif /* __TBB_SURVIVE_THREAD_SWITCH */ if( (int)num_threads == task_scheduler_init::automatic ) num_threads = default_num_threads(); s = generic_scheduler::create_master( market::create_arena( num_threads - 1, stack_size ? stack_size : ThreadStackSize ) ); __TBB_ASSERT(s, "Somehow a local scheduler creation for a master thread failed"); s->my_auto_initialized = auto_init; return s; } void governor::terminate_scheduler( generic_scheduler* s, const task_scheduler_init* tsi_ptr ) { __TBB_ASSERT( s == theTLS.get(), "Attempt to terminate non-local scheduler instance" ); if (--(s->my_ref_count)) { if (BlockingTSI && BlockingTSI==tsi_ptr) { // can't throw exception, because this is on dtor's call chain fprintf(stderr, "Attempt to terminate nested scheduler in blocking mode\n"); exit(1); } } else { #if TBB_USE_ASSERT if (BlockingTSI) { __TBB_ASSERT( BlockingTSI == tsi_ptr, "For blocking termination last terminate_scheduler must be blocking." ); IsBlockingTerminationInProgress = true; } #endif s->cleanup_master(); BlockingTSI = NULL; #if TBB_USE_ASSERT IsBlockingTerminationInProgress = false; #endif } } void governor::auto_terminate(void* arg){ generic_scheduler* s = static_cast(arg); if( s && s->my_auto_initialized ) { if( !--(s->my_ref_count) ) { __TBB_ASSERT( !BlockingTSI, "Blocking auto-terminate is not supported." ); // If the TLS slot is already cleared by OS or underlying concurrency // runtime, restore its value. if ( !theTLS.get() ) theTLS.set(s); else __TBB_ASSERT( s == theTLS.get(), NULL ); s->cleanup_master(); __TBB_ASSERT( !theTLS.get(), "cleanup_master has not cleared its TLS slot" ); } } } void governor::print_version_info () { if ( UsePrivateRML ) PrintExtraVersionInfo( "RML", "private" ); else { PrintExtraVersionInfo( "RML", "shared" ); theRMLServerFactory.call_with_server_info( PrintRMLVersionInfo, (void*)"" ); } #if __TBB_SURVIVE_THREAD_SWITCH if( watch_stack_handler ) PrintExtraVersionInfo( "CILK", CILKLIB_NAME ); #endif /* __TBB_SURVIVE_THREAD_SWITCH */ } void governor::initialize_rml_factory () { ::rml::factory::status_type res = theRMLServerFactory.open(); UsePrivateRML = res != ::rml::factory::st_success; } #if __TBB_SURVIVE_THREAD_SWITCH __cilk_tbb_retcode governor::stack_op_handler( __cilk_tbb_stack_op op, void* data ) { __TBB_ASSERT(data,NULL); generic_scheduler* s = static_cast(data); #if TBB_USE_ASSERT void* current = theTLS.get(); #if _WIN32||_WIN64 uintptr_t thread_id = GetCurrentThreadId(); #else uintptr_t thread_id = uintptr_t(pthread_self()); #endif #endif /* TBB_USE_ASSERT */ switch( op ) { default: __TBB_ASSERT( 0, "invalid op" ); case CILK_TBB_STACK_ADOPT: { __TBB_ASSERT( !current && s->my_cilk_state==generic_scheduler::cs_limbo || current==s && s->my_cilk_state==generic_scheduler::cs_running, "invalid adoption" ); #if TBB_USE_ASSERT if( current==s ) runtime_warning( "redundant adoption of %p by thread %p\n", s, (void*)thread_id ); s->my_cilk_state = generic_scheduler::cs_running; #endif /* TBB_USE_ASSERT */ theTLS.set(s); break; } case CILK_TBB_STACK_ORPHAN: { __TBB_ASSERT( current==s && s->my_cilk_state==generic_scheduler::cs_running, "invalid orphaning" ); #if TBB_USE_ASSERT s->my_cilk_state = generic_scheduler::cs_limbo; #endif /* TBB_USE_ASSERT */ theTLS.set(NULL); break; } case CILK_TBB_STACK_RELEASE: { __TBB_ASSERT( !current && s->my_cilk_state==generic_scheduler::cs_limbo || current==s && s->my_cilk_state==generic_scheduler::cs_running, "invalid release" ); #if TBB_USE_ASSERT s->my_cilk_state = generic_scheduler::cs_freed; #endif /* TBB_USE_ASSERT */ s->my_cilk_unwatch_thunk.routine = NULL; auto_terminate( s ); } } return 0; } #endif /* __TBB_SURVIVE_THREAD_SWITCH */ } // namespace internal //------------------------------------------------------------------------ // task_scheduler_init //------------------------------------------------------------------------ using namespace internal; /** Left out-of-line for the sake of the backward binary compatibility **/ void task_scheduler_init::initialize( int number_of_threads ) { initialize( number_of_threads, 0 ); } void task_scheduler_init::initialize( int number_of_threads, stack_size_type thread_stack_size ) { #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS uintptr_t new_mode = thread_stack_size & propagation_mode_mask; #endif thread_stack_size &= ~(stack_size_type)propagation_mode_mask; if( number_of_threads!=deferred ) { bool blocking_terminate = false; if (my_scheduler == (scheduler*)wait_workers_in_terminate_flag) { blocking_terminate = true; my_scheduler = NULL; } __TBB_ASSERT( !my_scheduler, "task_scheduler_init already initialized" ); __TBB_ASSERT( number_of_threads==-1 || number_of_threads>=1, "number_of_threads for task_scheduler_init must be -1 or positive" ); if (blocking_terminate) governor::setBlockingTerminate(this); internal::generic_scheduler *s = governor::init_scheduler( number_of_threads, thread_stack_size, /*auto_init=*/false ); #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS if ( s->master_outermost_level() ) { uintptr_t &vt = s->default_context()->my_version_and_traits; uintptr_t prev_mode = vt & task_group_context::exact_exception ? propagation_mode_exact : 0; vt = new_mode & propagation_mode_exact ? vt | task_group_context::exact_exception : new_mode & propagation_mode_captured ? vt & ~task_group_context::exact_exception : vt; // Use least significant bit of the scheduler pointer to store previous mode. // This is necessary when components compiled with different compilers and/or // TBB versions initialize the my_scheduler = static_cast((generic_scheduler*)((uintptr_t)s | prev_mode)); } else #endif /* __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS */ my_scheduler = s; } else { __TBB_ASSERT( !thread_stack_size, "deferred initialization ignores stack size setting" ); } } void task_scheduler_init::terminate() { #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS uintptr_t prev_mode = (uintptr_t)my_scheduler & propagation_mode_exact; my_scheduler = (scheduler*)((uintptr_t)my_scheduler & ~(uintptr_t)propagation_mode_exact); #endif /* __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS */ generic_scheduler* s = static_cast(my_scheduler); my_scheduler = NULL; __TBB_ASSERT( s, "task_scheduler_init::terminate without corresponding task_scheduler_init::initialize()"); #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS if ( s->master_outermost_level() ) { uintptr_t &vt = s->default_context()->my_version_and_traits; vt = prev_mode & propagation_mode_exact ? vt | task_group_context::exact_exception : vt & ~task_group_context::exact_exception; } #endif /* __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS */ governor::terminate_scheduler(s, this); } int task_scheduler_init::default_num_threads() { return governor::default_num_threads(); } } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/governor.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_governor_H #define _TBB_governor_H #include "tbb/task_scheduler_init.h" #include "../rml/include/rml_tbb.h" #include "tbb_misc.h" // for AvailableHwConcurrency and ThreadStackSize #include "tls.h" #if __TBB_SURVIVE_THREAD_SWITCH #include "cilk-tbb-interop.h" #endif /* __TBB_SURVIVE_THREAD_SWITCH */ namespace tbb { namespace internal { class market; class generic_scheduler; class __TBB_InitOnce; //------------------------------------------------------------------------ // Class governor //------------------------------------------------------------------------ //! The class handles access to the single instance of market, and to TLS to keep scheduler instances. /** It also supports automatic on-demand initialization of the TBB scheduler. The class contains only static data members and methods.*/ class governor { friend class __TBB_InitOnce; friend class market; //! TLS for scheduler instances associated with individual threads static basic_tls theTLS; //! Caches the maximal level of parallelism supported by the hardware static unsigned DefaultNumberOfThreads; static rml::tbb_factory theRMLServerFactory; static bool UsePrivateRML; //! Instance of task_scheduler_init that requested blocking termination. static const task_scheduler_init *BlockingTSI; #if TBB_USE_ASSERT static bool IsBlockingTerminationInProgress; #endif static bool is_speculation_enabled; //! Create key for thread-local storage and initialize RML. static void acquire_resources (); //! Destroy the thread-local storage key and deinitialize RML. static void release_resources (); static rml::tbb_server* create_rml_server ( rml::tbb_client& ); //! The internal routine to undo automatic initialization. /** The signature is written with void* so that the routine can be the destructor argument to pthread_key_create. */ static void auto_terminate(void* scheduler); public: static unsigned default_num_threads () { // No memory fence required, because at worst each invoking thread calls AvailableHwConcurrency once. return DefaultNumberOfThreads ? DefaultNumberOfThreads : DefaultNumberOfThreads = AvailableHwConcurrency(); } //! Processes scheduler initialization request (possibly nested) in a master thread /** If necessary creates new instance of arena and/or local scheduler. The auto_init argument specifies if the call is due to automatic initialization. **/ static generic_scheduler* init_scheduler( unsigned num_threads, stack_size_type stack_size, bool auto_init = false ); //! Processes scheduler termination request (possibly nested) in a master thread static void terminate_scheduler( generic_scheduler* s, const task_scheduler_init *tsi_ptr ); //! Register TBB scheduler instance in thread-local storage. static void sign_on(generic_scheduler* s); //! Unregister TBB scheduler instance from thread-local storage. static void sign_off(generic_scheduler* s); //! Used to check validity of the local scheduler TLS contents. static bool is_set ( generic_scheduler* s ) { return theTLS.get() == s; } //! Temporarily set TLS slot to the given scheduler static void assume_scheduler( generic_scheduler* s ) { theTLS.set( s ); } //! Obtain the thread-local instance of the TBB scheduler. /** If the scheduler has not been initialized yet, initialization is done automatically. Note that auto-initialized scheduler instance is destroyed only when its thread terminates. **/ static generic_scheduler* local_scheduler () { generic_scheduler* s = theTLS.get(); return s ? s : init_scheduler( (unsigned)task_scheduler_init::automatic, 0, true ); } static generic_scheduler* local_scheduler_if_initialized () { return theTLS.get(); } //! Undo automatic initialization if necessary; call when a thread exits. static void terminate_auto_initialized_scheduler() { auto_terminate( theTLS.get() ); } static void print_version_info (); static void initialize_rml_factory (); static bool needsWaitWorkers () { return BlockingTSI!=NULL; } //! Must be called before init_scheduler static void setBlockingTerminate(const task_scheduler_init *tsi); #if __TBB_SURVIVE_THREAD_SWITCH static __cilk_tbb_retcode stack_op_handler( __cilk_tbb_stack_op op, void* ); #endif /* __TBB_SURVIVE_THREAD_SWITCH */ static bool speculation_enabled() { return is_speculation_enabled; } }; // class governor } // namespace internal } // namespace tbb #endif /* _TBB_governor_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia32-masm/atomic_support.asm ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. .686 .model flat,c .code ALIGN 4 PUBLIC c __TBB_machine_fetchadd1 __TBB_machine_fetchadd1: mov edx,4[esp] mov eax,8[esp] lock xadd [edx],al ret .code ALIGN 4 PUBLIC c __TBB_machine_fetchstore1 __TBB_machine_fetchstore1: mov edx,4[esp] mov eax,8[esp] lock xchg [edx],al ret .code ALIGN 4 PUBLIC c __TBB_machine_cmpswp1 __TBB_machine_cmpswp1: mov edx,4[esp] mov ecx,8[esp] mov eax,12[esp] lock cmpxchg [edx],cl ret .code ALIGN 4 PUBLIC c __TBB_machine_fetchadd2 __TBB_machine_fetchadd2: mov edx,4[esp] mov eax,8[esp] lock xadd [edx],ax ret .code ALIGN 4 PUBLIC c __TBB_machine_fetchstore2 __TBB_machine_fetchstore2: mov edx,4[esp] mov eax,8[esp] lock xchg [edx],ax ret .code ALIGN 4 PUBLIC c __TBB_machine_cmpswp2 __TBB_machine_cmpswp2: mov edx,4[esp] mov ecx,8[esp] mov eax,12[esp] lock cmpxchg [edx],cx ret .code ALIGN 4 PUBLIC c __TBB_machine_fetchadd4 __TBB_machine_fetchadd4: mov edx,4[esp] mov eax,8[esp] lock xadd [edx],eax ret .code ALIGN 4 PUBLIC c __TBB_machine_fetchstore4 __TBB_machine_fetchstore4: mov edx,4[esp] mov eax,8[esp] lock xchg [edx],eax ret .code ALIGN 4 PUBLIC c __TBB_machine_cmpswp4 __TBB_machine_cmpswp4: mov edx,4[esp] mov ecx,8[esp] mov eax,12[esp] lock cmpxchg [edx],ecx ret .code ALIGN 4 PUBLIC c __TBB_machine_fetchadd8 __TBB_machine_fetchadd8: push ebx push edi mov edi,12[esp] mov eax,[edi] mov edx,4[edi] __TBB_machine_fetchadd8_loop: mov ebx,16[esp] mov ecx,20[esp] add ebx,eax adc ecx,edx lock cmpxchg8b qword ptr [edi] jnz __TBB_machine_fetchadd8_loop pop edi pop ebx ret .code ALIGN 4 PUBLIC c __TBB_machine_fetchstore8 __TBB_machine_fetchstore8: push ebx push edi mov edi,12[esp] mov ebx,16[esp] mov ecx,20[esp] mov eax,[edi] mov edx,4[edi] __TBB_machine_fetchstore8_loop: lock cmpxchg8b qword ptr [edi] jnz __TBB_machine_fetchstore8_loop pop edi pop ebx ret .code ALIGN 4 PUBLIC c __TBB_machine_cmpswp8 __TBB_machine_cmpswp8: push ebx push edi mov edi,12[esp] mov ebx,16[esp] mov ecx,20[esp] mov eax,24[esp] mov edx,28[esp] lock cmpxchg8b qword ptr [edi] pop edi pop ebx ret .code ALIGN 4 PUBLIC c __TBB_machine_load8 __TBB_machine_Load8: ; If location is on stack, compiler may have failed to align it correctly, so we do dynamic check. mov ecx,4[esp] test ecx,7 jne load_slow ; Load within a cache line sub esp,12 fild qword ptr [ecx] fistp qword ptr [esp] mov eax,[esp] mov edx,4[esp] add esp,12 ret load_slow: ; Load is misaligned. Use cmpxchg8b. push ebx push edi mov edi,ecx xor eax,eax xor ebx,ebx xor ecx,ecx xor edx,edx lock cmpxchg8b qword ptr [edi] pop edi pop ebx ret EXTRN __TBB_machine_store8_slow:PROC .code ALIGN 4 PUBLIC c __TBB_machine_store8 __TBB_machine_Store8: ; If location is on stack, compiler may have failed to align it correctly, so we do dynamic check. mov ecx,4[esp] test ecx,7 jne __TBB_machine_store8_slow ;; tail call to tbb_misc.cpp fild qword ptr 8[esp] fistp qword ptr [ecx] ret end ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia32-masm/itsx.asm ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. .686 .model flat,c .code ALIGN 4 PUBLIC c __TBB_machine_try_lock_elided __TBB_machine_try_lock_elided: mov ecx, 4[esp] xor eax, eax mov al, 1 BYTE 0F2H xchg al, byte ptr [ecx] xor al, 1 ret .code ALIGN 4 PUBLIC c __TBB_machine_unlock_elided __TBB_machine_unlock_elided: mov ecx, 4[esp] BYTE 0F3H mov byte ptr [ecx], 0 ret .code ALIGN 4 PUBLIC c __TBB_machine_begin_transaction __TBB_machine_begin_transaction: mov eax, -1 BYTE 0C7H BYTE 0F8H BYTE 000H BYTE 000H BYTE 000H BYTE 000H ret .code ALIGN 4 PUBLIC c __TBB_machine_end_transaction __TBB_machine_end_transaction: BYTE 00FH BYTE 001H BYTE 0D5H ret .code ALIGN 4 PUBLIC c __TBB_machine_transaction_conflict_abort __TBB_machine_transaction_conflict_abort: BYTE 0C6H BYTE 0F8H BYTE 0FFH ; 12.4.5 Abort argument: lock not free when tested ret .code ALIGN 4 PUBLIC c __TBB_machine_is_in_transaction __TBB_machine_is_in_transaction: xor eax, eax BYTE 00FH BYTE 001H BYTE 0D6H JZ rset MOV al,1 rset: RET end ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia32-masm/lock_byte.asm ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. ; DO NOT EDIT - AUTOMATICALLY GENERATED FROM .s FILE .686 .model flat,c .code ALIGN 4 PUBLIC c __TBB_machine_trylockbyte __TBB_machine_trylockbyte: mov edx,4[esp] mov al,[edx] mov cl,1 test al,1 jnz __TBB_machine_trylockbyte_contended lock cmpxchg [edx],cl jne __TBB_machine_trylockbyte_contended mov eax,1 ret __TBB_machine_trylockbyte_contended: xor eax,eax ret end ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia64-gas/atomic_support.s ================================================ // Copyright 2005-2014 Intel Corporation. All Rights Reserved. // // This file is part of Threading Building Blocks. Threading Building Blocks is free software; // you can redistribute it and/or modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. Threading Building Blocks is // distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. You should have received a copy of // the GNU General Public License along with Threading Building Blocks; if not, write to the // Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // As a special exception, you may use this file as part of a free software library without // restriction. Specifically, if other files instantiate templates or use macros or inline // functions from this file, or you compile this file and link it with other files to produce // an executable, this file does not by itself cause the resulting executable to be covered // by the GNU General Public License. This exception does not however invalidate any other // reasons why the executable file might be covered by the GNU General Public License. // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 .proc __TBB_machine_fetchadd1__TBB_full_fence# .global __TBB_machine_fetchadd1__TBB_full_fence# __TBB_machine_fetchadd1__TBB_full_fence: { mf br __TBB_machine_fetchadd1acquire } .endp __TBB_machine_fetchadd1__TBB_full_fence# .proc __TBB_machine_fetchadd1acquire# .global __TBB_machine_fetchadd1acquire# __TBB_machine_fetchadd1acquire: ld1 r9=[r32] ;; Retry_1acquire: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg1.acq r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_1acquire br.ret.sptk.many b0 # 49 "" .endp __TBB_machine_fetchadd1acquire# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore1__TBB_full_fence# .global __TBB_machine_fetchstore1__TBB_full_fence# __TBB_machine_fetchstore1__TBB_full_fence: mf ;; xchg1 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore1__TBB_full_fence# .proc __TBB_machine_fetchstore1acquire# .global __TBB_machine_fetchstore1acquire# __TBB_machine_fetchstore1acquire: xchg1 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore1acquire# # 88 "" .section .text .align 16 .proc __TBB_machine_cmpswp1__TBB_full_fence# .global __TBB_machine_cmpswp1__TBB_full_fence# __TBB_machine_cmpswp1__TBB_full_fence: { mf br __TBB_machine_cmpswp1acquire } .endp __TBB_machine_cmpswp1__TBB_full_fence# .proc __TBB_machine_cmpswp1acquire# .global __TBB_machine_cmpswp1acquire# __TBB_machine_cmpswp1acquire: zxt1 r34=r34 ;; mov ar.ccv=r34 ;; cmpxchg1.acq r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp1acquire# // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 .proc __TBB_machine_fetchadd2__TBB_full_fence# .global __TBB_machine_fetchadd2__TBB_full_fence# __TBB_machine_fetchadd2__TBB_full_fence: { mf br __TBB_machine_fetchadd2acquire } .endp __TBB_machine_fetchadd2__TBB_full_fence# .proc __TBB_machine_fetchadd2acquire# .global __TBB_machine_fetchadd2acquire# __TBB_machine_fetchadd2acquire: ld2 r9=[r32] ;; Retry_2acquire: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg2.acq r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_2acquire br.ret.sptk.many b0 # 49 "" .endp __TBB_machine_fetchadd2acquire# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore2__TBB_full_fence# .global __TBB_machine_fetchstore2__TBB_full_fence# __TBB_machine_fetchstore2__TBB_full_fence: mf ;; xchg2 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore2__TBB_full_fence# .proc __TBB_machine_fetchstore2acquire# .global __TBB_machine_fetchstore2acquire# __TBB_machine_fetchstore2acquire: xchg2 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore2acquire# # 88 "" .section .text .align 16 .proc __TBB_machine_cmpswp2__TBB_full_fence# .global __TBB_machine_cmpswp2__TBB_full_fence# __TBB_machine_cmpswp2__TBB_full_fence: { mf br __TBB_machine_cmpswp2acquire } .endp __TBB_machine_cmpswp2__TBB_full_fence# .proc __TBB_machine_cmpswp2acquire# .global __TBB_machine_cmpswp2acquire# __TBB_machine_cmpswp2acquire: zxt2 r34=r34 ;; mov ar.ccv=r34 ;; cmpxchg2.acq r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp2acquire# // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 .proc __TBB_machine_fetchadd4__TBB_full_fence# .global __TBB_machine_fetchadd4__TBB_full_fence# __TBB_machine_fetchadd4__TBB_full_fence: { mf br __TBB_machine_fetchadd4acquire } .endp __TBB_machine_fetchadd4__TBB_full_fence# .proc __TBB_machine_fetchadd4acquire# .global __TBB_machine_fetchadd4acquire# __TBB_machine_fetchadd4acquire: cmp.eq p6,p0=1,r33 cmp.eq p8,p0=-1,r33 (p6) br.cond.dptk Inc_4acquire (p8) br.cond.dpnt Dec_4acquire ;; ld4 r9=[r32] ;; Retry_4acquire: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg4.acq r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_4acquire br.ret.sptk.many b0 Inc_4acquire: fetchadd4.acq r8=[r32],1 br.ret.sptk.many b0 Dec_4acquire: fetchadd4.acq r8=[r32],-1 br.ret.sptk.many b0 .endp __TBB_machine_fetchadd4acquire# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore4__TBB_full_fence# .global __TBB_machine_fetchstore4__TBB_full_fence# __TBB_machine_fetchstore4__TBB_full_fence: mf ;; xchg4 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore4__TBB_full_fence# .proc __TBB_machine_fetchstore4acquire# .global __TBB_machine_fetchstore4acquire# __TBB_machine_fetchstore4acquire: xchg4 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore4acquire# # 88 "" .section .text .align 16 .proc __TBB_machine_cmpswp4__TBB_full_fence# .global __TBB_machine_cmpswp4__TBB_full_fence# __TBB_machine_cmpswp4__TBB_full_fence: { mf br __TBB_machine_cmpswp4acquire } .endp __TBB_machine_cmpswp4__TBB_full_fence# .proc __TBB_machine_cmpswp4acquire# .global __TBB_machine_cmpswp4acquire# __TBB_machine_cmpswp4acquire: zxt4 r34=r34 ;; mov ar.ccv=r34 ;; cmpxchg4.acq r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp4acquire# // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 .proc __TBB_machine_fetchadd8__TBB_full_fence# .global __TBB_machine_fetchadd8__TBB_full_fence# __TBB_machine_fetchadd8__TBB_full_fence: { mf br __TBB_machine_fetchadd8acquire } .endp __TBB_machine_fetchadd8__TBB_full_fence# .proc __TBB_machine_fetchadd8acquire# .global __TBB_machine_fetchadd8acquire# __TBB_machine_fetchadd8acquire: cmp.eq p6,p0=1,r33 cmp.eq p8,p0=-1,r33 (p6) br.cond.dptk Inc_8acquire (p8) br.cond.dpnt Dec_8acquire ;; ld8 r9=[r32] ;; Retry_8acquire: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg8.acq r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_8acquire br.ret.sptk.many b0 Inc_8acquire: fetchadd8.acq r8=[r32],1 br.ret.sptk.many b0 Dec_8acquire: fetchadd8.acq r8=[r32],-1 br.ret.sptk.many b0 .endp __TBB_machine_fetchadd8acquire# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore8__TBB_full_fence# .global __TBB_machine_fetchstore8__TBB_full_fence# __TBB_machine_fetchstore8__TBB_full_fence: mf ;; xchg8 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore8__TBB_full_fence# .proc __TBB_machine_fetchstore8acquire# .global __TBB_machine_fetchstore8acquire# __TBB_machine_fetchstore8acquire: xchg8 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore8acquire# # 88 "" .section .text .align 16 .proc __TBB_machine_cmpswp8__TBB_full_fence# .global __TBB_machine_cmpswp8__TBB_full_fence# __TBB_machine_cmpswp8__TBB_full_fence: { mf br __TBB_machine_cmpswp8acquire } .endp __TBB_machine_cmpswp8__TBB_full_fence# .proc __TBB_machine_cmpswp8acquire# .global __TBB_machine_cmpswp8acquire# __TBB_machine_cmpswp8acquire: mov ar.ccv=r34 ;; cmpxchg8.acq r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp8acquire# // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 # 19 "" .proc __TBB_machine_fetchadd1release# .global __TBB_machine_fetchadd1release# __TBB_machine_fetchadd1release: ld1 r9=[r32] ;; Retry_1release: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg1.rel r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_1release br.ret.sptk.many b0 # 49 "" .endp __TBB_machine_fetchadd1release# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore1release# .global __TBB_machine_fetchstore1release# __TBB_machine_fetchstore1release: mf ;; xchg1 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore1release# # 88 "" .section .text .align 16 # 101 "" .proc __TBB_machine_cmpswp1release# .global __TBB_machine_cmpswp1release# __TBB_machine_cmpswp1release: zxt1 r34=r34 ;; mov ar.ccv=r34 ;; cmpxchg1.rel r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp1release# // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 # 19 "" .proc __TBB_machine_fetchadd2release# .global __TBB_machine_fetchadd2release# __TBB_machine_fetchadd2release: ld2 r9=[r32] ;; Retry_2release: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg2.rel r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_2release br.ret.sptk.many b0 # 49 "" .endp __TBB_machine_fetchadd2release# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore2release# .global __TBB_machine_fetchstore2release# __TBB_machine_fetchstore2release: mf ;; xchg2 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore2release# # 88 "" .section .text .align 16 # 101 "" .proc __TBB_machine_cmpswp2release# .global __TBB_machine_cmpswp2release# __TBB_machine_cmpswp2release: zxt2 r34=r34 ;; mov ar.ccv=r34 ;; cmpxchg2.rel r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp2release# // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 # 19 "" .proc __TBB_machine_fetchadd4release# .global __TBB_machine_fetchadd4release# __TBB_machine_fetchadd4release: cmp.eq p6,p0=1,r33 cmp.eq p8,p0=-1,r33 (p6) br.cond.dptk Inc_4release (p8) br.cond.dpnt Dec_4release ;; ld4 r9=[r32] ;; Retry_4release: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg4.rel r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_4release br.ret.sptk.many b0 Inc_4release: fetchadd4.rel r8=[r32],1 br.ret.sptk.many b0 Dec_4release: fetchadd4.rel r8=[r32],-1 br.ret.sptk.many b0 .endp __TBB_machine_fetchadd4release# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore4release# .global __TBB_machine_fetchstore4release# __TBB_machine_fetchstore4release: mf ;; xchg4 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore4release# # 88 "" .section .text .align 16 # 101 "" .proc __TBB_machine_cmpswp4release# .global __TBB_machine_cmpswp4release# __TBB_machine_cmpswp4release: zxt4 r34=r34 ;; mov ar.ccv=r34 ;; cmpxchg4.rel r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp4release# // DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh # 1 "" # 1 "" # 1 "" # 1 "" .section .text .align 16 # 19 "" .proc __TBB_machine_fetchadd8release# .global __TBB_machine_fetchadd8release# __TBB_machine_fetchadd8release: cmp.eq p6,p0=1,r33 cmp.eq p8,p0=-1,r33 (p6) br.cond.dptk Inc_8release (p8) br.cond.dpnt Dec_8release ;; ld8 r9=[r32] ;; Retry_8release: mov ar.ccv=r9 mov r8=r9; add r10=r9,r33 ;; cmpxchg8.rel r9=[r32],r10,ar.ccv ;; cmp.ne p7,p0=r8,r9 (p7) br.cond.dpnt Retry_8release br.ret.sptk.many b0 Inc_8release: fetchadd8.rel r8=[r32],1 br.ret.sptk.many b0 Dec_8release: fetchadd8.rel r8=[r32],-1 br.ret.sptk.many b0 .endp __TBB_machine_fetchadd8release# # 62 "" .section .text .align 16 .proc __TBB_machine_fetchstore8release# .global __TBB_machine_fetchstore8release# __TBB_machine_fetchstore8release: mf ;; xchg8 r8=[r32],r33 br.ret.sptk.many b0 .endp __TBB_machine_fetchstore8release# # 88 "" .section .text .align 16 # 101 "" .proc __TBB_machine_cmpswp8release# .global __TBB_machine_cmpswp8release# __TBB_machine_cmpswp8release: mov ar.ccv=r34 ;; cmpxchg8.rel r8=[r32],r33,ar.ccv br.ret.sptk.many b0 .endp __TBB_machine_cmpswp8release# ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia64-gas/ia64_misc.s ================================================ // Copyright 2005-2014 Intel Corporation. All Rights Reserved. // // This file is part of Threading Building Blocks. Threading Building Blocks is free software; // you can redistribute it and/or modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. Threading Building Blocks is // distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. You should have received a copy of // the GNU General Public License along with Threading Building Blocks; if not, write to the // Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // As a special exception, you may use this file as part of a free software library without // restriction. Specifically, if other files instantiate templates or use macros or inline // functions from this file, or you compile this file and link it with other files to produce // an executable, this file does not by itself cause the resulting executable to be covered // by the GNU General Public License. This exception does not however invalidate any other // reasons why the executable file might be covered by the GNU General Public License. // RSE backing store pointer retrieval .section .text .align 16 .proc __TBB_get_bsp# .global __TBB_get_bsp# __TBB_get_bsp: mov r8=ar.bsp br.ret.sptk.many b0 .endp __TBB_get_bsp# .section .text .align 16 .proc __TBB_machine_load8_relaxed# .global __TBB_machine_load8_relaxed# __TBB_machine_load8_relaxed: ld8 r8=[r32] br.ret.sptk.many b0 .endp __TBB_machine_load8_relaxed# .section .text .align 16 .proc __TBB_machine_store8_relaxed# .global __TBB_machine_store8_relaxed# __TBB_machine_store8_relaxed: st8 [r32]=r33 br.ret.sptk.many b0 .endp __TBB_machine_store8_relaxed# .section .text .align 16 .proc __TBB_machine_load4_relaxed# .global __TBB_machine_load4_relaxed# __TBB_machine_load4_relaxed: ld4 r8=[r32] br.ret.sptk.many b0 .endp __TBB_machine_load4_relaxed# .section .text .align 16 .proc __TBB_machine_store4_relaxed# .global __TBB_machine_store4_relaxed# __TBB_machine_store4_relaxed: st4 [r32]=r33 br.ret.sptk.many b0 .endp __TBB_machine_store4_relaxed# .section .text .align 16 .proc __TBB_machine_load2_relaxed# .global __TBB_machine_load2_relaxed# __TBB_machine_load2_relaxed: ld2 r8=[r32] br.ret.sptk.many b0 .endp __TBB_machine_load2_relaxed# .section .text .align 16 .proc __TBB_machine_store2_relaxed# .global __TBB_machine_store2_relaxed# __TBB_machine_store2_relaxed: st2 [r32]=r33 br.ret.sptk.many b0 .endp __TBB_machine_store2_relaxed# .section .text .align 16 .proc __TBB_machine_load1_relaxed# .global __TBB_machine_load1_relaxed# __TBB_machine_load1_relaxed: ld1 r8=[r32] br.ret.sptk.many b0 .endp __TBB_machine_load1_relaxed# .section .text .align 16 .proc __TBB_machine_store1_relaxed# .global __TBB_machine_store1_relaxed# __TBB_machine_store1_relaxed: st1 [r32]=r33 br.ret.sptk.many b0 .endp __TBB_machine_store1_relaxed# ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia64-gas/lock_byte.s ================================================ // Copyright 2005-2014 Intel Corporation. All Rights Reserved. // // This file is part of Threading Building Blocks. Threading Building Blocks is free software; // you can redistribute it and/or modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. Threading Building Blocks is // distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. You should have received a copy of // the GNU General Public License along with Threading Building Blocks; if not, write to the // Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // As a special exception, you may use this file as part of a free software library without // restriction. Specifically, if other files instantiate templates or use macros or inline // functions from this file, or you compile this file and link it with other files to produce // an executable, this file does not by itself cause the resulting executable to be covered // by the GNU General Public License. This exception does not however invalidate any other // reasons why the executable file might be covered by the GNU General Public License. // Support for class TinyLock .section .text .align 16 // unsigned int __TBB_machine_trylockbyte( byte& flag ); // r32 = address of flag .proc __TBB_machine_trylockbyte# .global __TBB_machine_trylockbyte# ADDRESS_OF_FLAG=r32 RETCODE=r8 FLAG=r9 BUSY=r10 SCRATCH=r11 __TBB_machine_trylockbyte: ld1.acq FLAG=[ADDRESS_OF_FLAG] mov BUSY=1 mov RETCODE=0 ;; cmp.ne p6,p0=0,FLAG mov ar.ccv=r0 (p6) br.ret.sptk.many b0 ;; cmpxchg1.acq SCRATCH=[ADDRESS_OF_FLAG],BUSY,ar.ccv // Try to acquire lock ;; cmp.eq p6,p0=0,SCRATCH ;; (p6) mov RETCODE=1 br.ret.sptk.many b0 .endp __TBB_machine_trylockbyte# ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia64-gas/log2.s ================================================ // Copyright 2005-2014 Intel Corporation. All Rights Reserved. // // This file is part of Threading Building Blocks. Threading Building Blocks is free software; // you can redistribute it and/or modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. Threading Building Blocks is // distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. You should have received a copy of // the GNU General Public License along with Threading Building Blocks; if not, write to the // Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // As a special exception, you may use this file as part of a free software library without // restriction. Specifically, if other files instantiate templates or use macros or inline // functions from this file, or you compile this file and link it with other files to produce // an executable, this file does not by itself cause the resulting executable to be covered // by the GNU General Public License. This exception does not however invalidate any other // reasons why the executable file might be covered by the GNU General Public License. .section .text .align 16 // unsigned long __TBB_machine_lg( unsigned long x ); // r32 = x .proc __TBB_machine_lg# .global __TBB_machine_lg# __TBB_machine_lg: shr r16=r32,1 // .x ;; shr r17=r32,2 // ..x or r32=r32,r16 // xx ;; shr r16=r32,3 // ...xx or r32=r32,r17 // xxx ;; shr r17=r32,5 // .....xxx or r32=r32,r16 // xxxxx ;; shr r16=r32,8 // ........xxxxx or r32=r32,r17 // xxxxxxxx ;; shr r17=r32,13 or r32=r32,r16 // 13x ;; shr r16=r32,21 or r32=r32,r17 // 21x ;; shr r17=r32,34 or r32=r32,r16 // 34x ;; shr r16=r32,55 or r32=r32,r17 // 55x ;; or r32=r32,r16 // 64x ;; popcnt r8=r32 ;; add r8=-1,r8 br.ret.sptk.many b0 .endp __TBB_machine_lg# ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ia64-gas/pause.s ================================================ // Copyright 2005-2014 Intel Corporation. All Rights Reserved. // // This file is part of Threading Building Blocks. Threading Building Blocks is free software; // you can redistribute it and/or modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. Threading Building Blocks is // distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. You should have received a copy of // the GNU General Public License along with Threading Building Blocks; if not, write to the // Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // As a special exception, you may use this file as part of a free software library without // restriction. Specifically, if other files instantiate templates or use macros or inline // functions from this file, or you compile this file and link it with other files to produce // an executable, this file does not by itself cause the resulting executable to be covered // by the GNU General Public License. This exception does not however invalidate any other // reasons why the executable file might be covered by the GNU General Public License. .section .text .align 16 // void __TBB_machine_pause( long count ); // r32 = count .proc __TBB_machine_pause# .global __TBB_machine_pause# count = r32 __TBB_machine_pause: hint.m 0 add count=-1,count ;; cmp.eq p6,p7=0,count (p7) br.cond.dpnt __TBB_machine_pause (p6) br.ret.sptk.many b0 .endp __TBB_machine_pause# ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/ibm_aix51/atomic_support.c ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include #include /* This file must be compiled with gcc. The IBM compiler doesn't seem to support inline assembly statements (October 2007). */ #ifdef __GNUC__ int32_t __TBB_machine_cas_32 (volatile void* ptr, int32_t value, int32_t comparand) { __asm__ __volatile__ ("sync\n"); /* memory release operation */ compare_and_swap ((atomic_p) ptr, &comparand, value); __asm__ __volatile__ ("isync\n"); /* memory acquire operation */ return comparand; } int64_t __TBB_machine_cas_64 (volatile void* ptr, int64_t value, int64_t comparand) { __asm__ __volatile__ ("sync\n"); /* memory release operation */ compare_and_swaplp ((atomic_l) ptr, &comparand, value); __asm__ __volatile__ ("isync\n"); /* memory acquire operation */ return comparand; } void __TBB_machine_flush () { __asm__ __volatile__ ("sync\n"); } void __TBB_machine_lwsync () { __asm__ __volatile__ ("lwsync\n"); } void __TBB_machine_isync () { __asm__ __volatile__ ("isync\n"); } #endif /* __GNUC__ */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/intel64-masm/atomic_support.asm ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. ; DO NOT EDIT - AUTOMATICALLY GENERATED FROM .s FILE .code ALIGN 8 PUBLIC __TBB_machine_fetchadd1 __TBB_machine_fetchadd1: mov rax,rdx lock xadd [rcx],al ret .code ALIGN 8 PUBLIC __TBB_machine_fetchstore1 __TBB_machine_fetchstore1: mov rax,rdx lock xchg [rcx],al ret .code ALIGN 8 PUBLIC __TBB_machine_cmpswp1 __TBB_machine_cmpswp1: mov rax,r8 lock cmpxchg [rcx],dl ret .code ALIGN 8 PUBLIC __TBB_machine_fetchadd2 __TBB_machine_fetchadd2: mov rax,rdx lock xadd [rcx],ax ret .code ALIGN 8 PUBLIC __TBB_machine_fetchstore2 __TBB_machine_fetchstore2: mov rax,rdx lock xchg [rcx],ax ret .code ALIGN 8 PUBLIC __TBB_machine_cmpswp2 __TBB_machine_cmpswp2: mov rax,r8 lock cmpxchg [rcx],dx ret .code ALIGN 8 PUBLIC __TBB_machine_pause __TBB_machine_pause: L1: dw 090f3H; pause add ecx,-1 jne L1 ret end ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/intel64-masm/intel64_misc.asm ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. .code ALIGN 8 PUBLIC __TBB_get_cpu_ctl_env __TBB_get_cpu_ctl_env: stmxcsr [rcx] fstcw [rcx+4] ret .code ALIGN 8 PUBLIC __TBB_set_cpu_ctl_env __TBB_set_cpu_ctl_env: ldmxcsr [rcx] fldcw [rcx+4] ret end ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/intel64-masm/itsx.asm ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. .code ALIGN 8 PUBLIC __TBB_machine_try_lock_elided __TBB_machine_try_lock_elided: xor rax, rax mov al, 1 BYTE 0F2H xchg al, byte ptr [rcx] xor al, 1 ret .code ALIGN 8 PUBLIC __TBB_machine_unlock_elided __TBB_machine_unlock_elided: BYTE 0F3H mov byte ptr [rcx], 0 ret .code ALIGN 8 PUBLIC __TBB_machine_begin_transaction __TBB_machine_begin_transaction: mov eax, -1 BYTE 0C7H BYTE 0F8H BYTE 000H BYTE 000H BYTE 000H BYTE 000H ret .code ALIGN 8 PUBLIC __TBB_machine_end_transaction __TBB_machine_end_transaction: BYTE 00FH BYTE 001H BYTE 0D5H ret .code ALIGN 8 PUBLIC __TBB_machine_transaction_conflict_abort __TBB_machine_transaction_conflict_abort: BYTE 0C6H BYTE 0F8H BYTE 0FFH ; 12.4.5 Abort argument: lock not free when tested ret .code ALIGN 8 PUBLIC __TBB_machine_is_in_transaction __TBB_machine_is_in_transaction: xor eax, eax BYTE 00FH ; _xtest sets or clears ZF BYTE 001H BYTE 0D6H jz rset mov al,1 rset: ret end ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_aggregator_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__aggregator_impl_H #define __TBB__aggregator_impl_H #include "../atomic.h" #if !__TBBMALLOC_BUILD #include "../tbb_profiling.h" #endif namespace tbb { namespace interface6 { namespace internal { using namespace tbb::internal; //! aggregated_operation base class template class aggregated_operation { public: uintptr_t status; Derived *next; aggregated_operation() : status(0), next(NULL) {} }; //! Aggregator base class /** An aggregator for collecting operations coming from multiple sources and executing them serially on a single thread. operation_type must be derived from aggregated_operation. The parameter handler_type is a functor that will be passed the list of operations and is expected to handle each operation appropriately, setting the status of each operation to non-zero.*/ template < typename operation_type > class aggregator_generic { public: aggregator_generic() : handler_busy(false) { pending_operations = NULL; } //! Place operation in list /** Place operation in list and either handle list or wait for operation to complete. long_life_time specifies life time of an operation inserting in an aggregator. "Long" (long_life_time == true) life time operation can be accessed even after executing it. "Short" (long_life_time == false) life time operations can be destroyed during executing so any access to it after executing is invalid.*/ template < typename handler_type > void execute(operation_type *op, handler_type &handle_operations, bool long_life_time = true) { operation_type *res; // op->status should be read before inserting the operation in the // aggregator queue since it can become invalid after executing a // handler (if the operation has 'short' life time.) const uintptr_t status = op->status; // ITT note: &(op->status) tag is used to cover accesses to this op node. This // thread has created the operation, and now releases it so that the handler // thread may handle the associated operation w/o triggering a race condition; // thus this tag will be acquired just before the operation is handled in the // handle_operations functor. call_itt_notify(releasing, &(op->status)); // insert the operation in the queue. do { // ITT may flag the following line as a race; it is a false positive: // This is an atomic read; we don't provide itt_hide_load_word for atomics op->next = res = pending_operations; // NOT A RACE } while (pending_operations.compare_and_swap(op, res) != res); if (!res) { // first in the list; handle the operations. // ITT note: &pending_operations tag covers access to the handler_busy flag, // which this waiting handler thread will try to set before entering // handle_operations. call_itt_notify(acquired, &pending_operations); start_handle_operations(handle_operations); // The operation with 'short' life time can already be destroyed. if (long_life_time) __TBB_ASSERT(op->status, NULL); } // not first; wait for op to be ready. else if (!status) { // operation is blocking here. __TBB_ASSERT(long_life_time, "The blocking operation cannot have 'short' life time. Since it can already be destroyed."); call_itt_notify(prepare, &(op->status)); spin_wait_while_eq(op->status, uintptr_t(0)); itt_load_word_with_acquire(op->status); } } private: //! An atomically updated list (aka mailbox) of pending operations atomic pending_operations; //! Controls thread access to handle_operations uintptr_t handler_busy; //! Trigger the handling of operations when the handler is free template < typename handler_type > void start_handle_operations( handler_type &handle_operations ) { operation_type *op_list; // ITT note: &handler_busy tag covers access to pending_operations as it is passed // between active and waiting handlers. Below, the waiting handler waits until // the active handler releases, and the waiting handler acquires &handler_busy as // it becomes the active_handler. The release point is at the end of this // function, when all operations in pending_operations have been handled by the // owner of this aggregator. call_itt_notify(prepare, &handler_busy); // get the handler_busy: // only one thread can possibly spin here at a time spin_wait_until_eq(handler_busy, uintptr_t(0)); call_itt_notify(acquired, &handler_busy); // acquire fence not necessary here due to causality rule and surrounding atomics __TBB_store_with_release(handler_busy, uintptr_t(1)); // ITT note: &pending_operations tag covers access to the handler_busy flag // itself. Capturing the state of the pending_operations signifies that // handler_busy has been set and a new active handler will now process that list's // operations. call_itt_notify(releasing, &pending_operations); // grab pending_operations op_list = pending_operations.fetch_and_store(NULL); // handle all the operations handle_operations(op_list); // release the handler itt_store_word_with_release(handler_busy, uintptr_t(0)); } }; template < typename handler_type, typename operation_type > class aggregator : public aggregator_generic { handler_type handle_operations; public: aggregator() {} explicit aggregator(handler_type h) : handle_operations(h) {} void initialize_handler(handler_type h) { handle_operations = h; } void execute(operation_type *op) { aggregator_generic::execute(op, handle_operations); } }; // the most-compatible friend declaration (vs, gcc, icc) is // template friend class aggregating_functor; template class aggregating_functor { aggregating_class *fi; public: aggregating_functor() {} aggregating_functor(aggregating_class *fi_) : fi(fi_) {} void operator()(operation_list* op_list) { fi->handle_operations(op_list); } }; } // namespace internal } // namespace interface6 namespace internal { using interface6::internal::aggregated_operation; using interface6::internal::aggregator_generic; using interface6::internal::aggregator; using interface6::internal::aggregating_functor; } // namespace internal } // namespace tbb #endif // __TBB__aggregator_impl_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_concurrent_queue_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__concurrent_queue_impl_H #define __TBB__concurrent_queue_impl_H #ifndef __TBB_concurrent_queue_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #include "../tbb_stddef.h" #include "../tbb_machine.h" #include "../atomic.h" #include "../spin_mutex.h" #include "../cache_aligned_allocator.h" #include "../tbb_exception.h" #include "../tbb_profiling.h" #include #include #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif namespace tbb { #if !__TBB_TEMPLATE_FRIENDS_BROKEN // forward declaration namespace strict_ppl { template class concurrent_queue; } template class concurrent_bounded_queue; #endif //! For internal use only. namespace strict_ppl { //! @cond INTERNAL namespace internal { using namespace tbb::internal; typedef size_t ticket; template class micro_queue ; template class micro_queue_pop_finalizer ; template class concurrent_queue_base_v3; template struct concurrent_queue_rep; //! parts of concurrent_queue_rep that do not have references to micro_queue /** * For internal use only. */ struct concurrent_queue_rep_base : no_copy { template friend class micro_queue; template friend class concurrent_queue_base_v3; protected: //! Approximately n_queue/golden ratio static const size_t phi = 3; public: // must be power of 2 static const size_t n_queue = 8; //! Prefix on a page struct page { page* next; uintptr_t mask; }; atomic head_counter; char pad1[NFS_MaxLineSize-sizeof(atomic)]; atomic tail_counter; char pad2[NFS_MaxLineSize-sizeof(atomic)]; //! Always a power of 2 size_t items_per_page; //! Size of an item size_t item_size; //! number of invalid entries in the queue atomic n_invalid_entries; char pad3[NFS_MaxLineSize-sizeof(size_t)-sizeof(size_t)-sizeof(atomic)]; } ; inline bool is_valid_page(const concurrent_queue_rep_base::page* p) { return uintptr_t(p)>1; } //! Abstract class to define interface for page allocation/deallocation /** * For internal use only. */ class concurrent_queue_page_allocator { template friend class micro_queue ; template friend class micro_queue_pop_finalizer ; protected: virtual ~concurrent_queue_page_allocator() {} private: virtual concurrent_queue_rep_base::page* allocate_page() = 0; virtual void deallocate_page( concurrent_queue_rep_base::page* p ) = 0; } ; #if _MSC_VER && !defined(__INTEL_COMPILER) // unary minus operator applied to unsigned type, result still unsigned #pragma warning( push ) #pragma warning( disable: 4146 ) #endif //! A queue using simple locking. /** For efficiency, this class has no constructor. The caller is expected to zero-initialize it. */ template class micro_queue : no_copy { public: typedef void (*item_constructor_t)(T* location, const void* src); private: typedef concurrent_queue_rep_base::page page; //! Class used to ensure exception-safety of method "pop" class destroyer: no_copy { T& my_value; public: destroyer( T& value ) : my_value(value) {} ~destroyer() {my_value.~T();} }; void copy_item( page& dst, size_t dindex, const void* src, item_constructor_t construct_item ) { construct_item( &get_ref(dst, dindex), src ); } void copy_item( page& dst, size_t dindex, const page& src, size_t sindex, item_constructor_t construct_item ) { T& src_item = get_ref( const_cast(src), sindex ); construct_item( &get_ref(dst, dindex), static_cast(&src_item) ); } void assign_and_destroy_item( void* dst, page& src, size_t index ) { T& from = get_ref(src,index); destroyer d(from); *static_cast(dst) = tbb::internal::move( from ); } void spin_wait_until_my_turn( atomic& counter, ticket k, concurrent_queue_rep_base& rb ) const ; public: friend class micro_queue_pop_finalizer; struct padded_page: page { //! Not defined anywhere - exists to quiet warnings. padded_page(); //! Not defined anywhere - exists to quiet warnings. void operator=( const padded_page& ); //! Must be last field. T last; }; static T& get_ref( page& p, size_t index ) { return (&static_cast(static_cast(&p))->last)[index]; } atomic head_page; atomic head_counter; atomic tail_page; atomic tail_counter; spin_mutex page_mutex; void push( const void* item, ticket k, concurrent_queue_base_v3& base, item_constructor_t construct_item ) ; bool pop( void* dst, ticket k, concurrent_queue_base_v3& base ) ; micro_queue& assign( const micro_queue& src, concurrent_queue_base_v3& base, item_constructor_t construct_item ) ; page* make_copy( concurrent_queue_base_v3& base, const page* src_page, size_t begin_in_page, size_t end_in_page, ticket& g_index, item_constructor_t construct_item ) ; void invalidate_page_and_rethrow( ticket k ) ; }; template void micro_queue::spin_wait_until_my_turn( atomic& counter, ticket k, concurrent_queue_rep_base& rb ) const { for( atomic_backoff b(true);;b.pause() ) { ticket c = counter; if( c==k ) return; else if( c&1 ) { ++rb.n_invalid_entries; throw_exception( eid_bad_last_alloc ); } } } template void micro_queue::push( const void* item, ticket k, concurrent_queue_base_v3& base, item_constructor_t construct_item ) { k &= -concurrent_queue_rep_base::n_queue; page* p = NULL; size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page); if( !index ) { __TBB_TRY { concurrent_queue_page_allocator& pa = base; p = pa.allocate_page(); } __TBB_CATCH (...) { ++base.my_rep->n_invalid_entries; invalidate_page_and_rethrow( k ); } p->mask = 0; p->next = NULL; } if( tail_counter != k ) spin_wait_until_my_turn( tail_counter, k, *base.my_rep ); call_itt_notify(acquired, &tail_counter); if( p ) { spin_mutex::scoped_lock lock( page_mutex ); page* q = tail_page; if( is_valid_page(q) ) q->next = p; else head_page = p; tail_page = p; } else { p = tail_page; } __TBB_TRY { copy_item( *p, index, item, construct_item ); // If no exception was thrown, mark item as present. itt_hide_store_word(p->mask, p->mask | uintptr_t(1)<n_invalid_entries; call_itt_notify(releasing, &tail_counter); tail_counter += concurrent_queue_rep_base::n_queue; __TBB_RETHROW(); } } template bool micro_queue::pop( void* dst, ticket k, concurrent_queue_base_v3& base ) { k &= -concurrent_queue_rep_base::n_queue; if( head_counter!=k ) spin_wait_until_eq( head_counter, k ); call_itt_notify(acquired, &head_counter); if( tail_counter==k ) spin_wait_while_eq( tail_counter, k ); call_itt_notify(acquired, &tail_counter); page& p = *head_page; __TBB_ASSERT( &p, NULL ); size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); bool success = false; { micro_queue_pop_finalizer finalizer( *this, base, k+concurrent_queue_rep_base::n_queue, index==base.my_rep->items_per_page-1 ? &p : NULL ); if( p.mask & uintptr_t(1)<n_invalid_entries; } } return success; } template micro_queue& micro_queue::assign( const micro_queue& src, concurrent_queue_base_v3& base, item_constructor_t construct_item ) { head_counter = src.head_counter; tail_counter = src.tail_counter; const page* srcp = src.head_page; if( is_valid_page(srcp) ) { ticket g_index = head_counter; __TBB_TRY { size_t n_items = (tail_counter-head_counter)/concurrent_queue_rep_base::n_queue; size_t index = modulo_power_of_two( head_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); size_t end_in_first_page = (index+n_itemsitems_per_page)?(index+n_items):base.my_rep->items_per_page; head_page = make_copy( base, srcp, index, end_in_first_page, g_index, construct_item ); page* cur_page = head_page; if( srcp != src.tail_page ) { for( srcp = srcp->next; srcp!=src.tail_page; srcp=srcp->next ) { cur_page->next = make_copy( base, srcp, 0, base.my_rep->items_per_page, g_index, construct_item ); cur_page = cur_page->next; } __TBB_ASSERT( srcp==src.tail_page, NULL ); size_t last_index = modulo_power_of_two( tail_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); if( last_index==0 ) last_index = base.my_rep->items_per_page; cur_page->next = make_copy( base, srcp, 0, last_index, g_index, construct_item ); cur_page = cur_page->next; } tail_page = cur_page; } __TBB_CATCH (...) { invalidate_page_and_rethrow( g_index ); } } else { head_page = tail_page = NULL; } return *this; } template void micro_queue::invalidate_page_and_rethrow( ticket k ) { // Append an invalid page at address 1 so that no more pushes are allowed. page* invalid_page = (page*)uintptr_t(1); { spin_mutex::scoped_lock lock( page_mutex ); itt_store_word_with_release(tail_counter, k+concurrent_queue_rep_base::n_queue+1); page* q = tail_page; if( is_valid_page(q) ) q->next = invalid_page; else head_page = invalid_page; tail_page = invalid_page; } __TBB_RETHROW(); } template concurrent_queue_rep_base::page* micro_queue::make_copy( concurrent_queue_base_v3& base, const concurrent_queue_rep_base::page* src_page, size_t begin_in_page, size_t end_in_page, ticket& g_index, item_constructor_t construct_item ) { concurrent_queue_page_allocator& pa = base; page* new_page = pa.allocate_page(); new_page->next = NULL; new_page->mask = src_page->mask; for( ; begin_in_page!=end_in_page; ++begin_in_page, ++g_index ) if( new_page->mask & uintptr_t(1)< class micro_queue_pop_finalizer: no_copy { typedef concurrent_queue_rep_base::page page; ticket my_ticket; micro_queue& my_queue; page* my_page; concurrent_queue_page_allocator& allocator; public: micro_queue_pop_finalizer( micro_queue& queue, concurrent_queue_base_v3& b, ticket k, page* p ) : my_ticket(k), my_queue(queue), my_page(p), allocator(b) {} ~micro_queue_pop_finalizer() ; }; template micro_queue_pop_finalizer::~micro_queue_pop_finalizer() { page* p = my_page; if( is_valid_page(p) ) { spin_mutex::scoped_lock lock( my_queue.page_mutex ); page* q = p->next; my_queue.head_page = q; if( !is_valid_page(q) ) { my_queue.tail_page = NULL; } } itt_store_word_with_release(my_queue.head_counter, my_ticket); if( is_valid_page(p) ) { allocator.deallocate_page( p ); } } #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning( pop ) #endif // warning 4146 is back template class concurrent_queue_iterator_rep ; template class concurrent_queue_iterator_base_v3; //! representation of concurrent_queue_base /** * the class inherits from concurrent_queue_rep_base and defines an array of micro_queue's */ template struct concurrent_queue_rep : public concurrent_queue_rep_base { micro_queue array[n_queue]; //! Map ticket to an array index static size_t index( ticket k ) { return k*phi%n_queue; } micro_queue& choose( ticket k ) { // The formula here approximates LRU in a cache-oblivious way. return array[index(k)]; } }; //! base class of concurrent_queue /** * The class implements the interface defined by concurrent_queue_page_allocator * and has a pointer to an instance of concurrent_queue_rep. */ template class concurrent_queue_base_v3: public concurrent_queue_page_allocator { //! Internal representation concurrent_queue_rep* my_rep; friend struct concurrent_queue_rep; friend class micro_queue; friend class concurrent_queue_iterator_rep; friend class concurrent_queue_iterator_base_v3; protected: typedef typename concurrent_queue_rep::page page; private: typedef typename micro_queue::padded_page padded_page; typedef typename micro_queue::item_constructor_t item_constructor_t; /* override */ virtual page *allocate_page() { concurrent_queue_rep& r = *my_rep; size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); return reinterpret_cast(allocate_block ( n )); } /* override */ virtual void deallocate_page( concurrent_queue_rep_base::page *p ) { concurrent_queue_rep& r = *my_rep; size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); deallocate_block( reinterpret_cast(p), n ); } //! custom allocator virtual void *allocate_block( size_t n ) = 0; //! custom de-allocator virtual void deallocate_block( void *p, size_t n ) = 0; protected: concurrent_queue_base_v3(); /* override */ virtual ~concurrent_queue_base_v3() { #if TBB_USE_ASSERT size_t nq = my_rep->n_queue; for( size_t i=0; iarray[i].tail_page==NULL, "pages were not freed properly" ); #endif /* TBB_USE_ASSERT */ cache_aligned_allocator >().deallocate(my_rep,1); } //! Enqueue item at tail of queue void internal_push( const void* src, item_constructor_t construct_item ) { concurrent_queue_rep& r = *my_rep; ticket k = r.tail_counter++; r.choose(k).push( src, k, *this, construct_item ); } //! Attempt to dequeue item from queue. /** NULL if there was no item to dequeue. */ bool internal_try_pop( void* dst ) ; //! Get size of queue; result may be invalid if queue is modified concurrently size_t internal_size() const ; //! check if the queue is empty; thread safe bool internal_empty() const ; //! free any remaining pages /* note that the name may be misleading, but it remains so due to a historical accident. */ void internal_finish_clear() ; //! Obsolete void internal_throw_exception() const { throw_exception( eid_bad_alloc ); } //! copy or move internal representation void assign( const concurrent_queue_base_v3& src, item_constructor_t construct_item ) ; #if __TBB_CPP11_RVALUE_REF_PRESENT //! swap internal representation void internal_swap( concurrent_queue_base_v3& src ) { std::swap( my_rep, src.my_rep ); } #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ }; template concurrent_queue_base_v3::concurrent_queue_base_v3() { const size_t item_size = sizeof(T); my_rep = cache_aligned_allocator >().allocate(1); __TBB_ASSERT( (size_t)my_rep % NFS_GetLineSize()==0, "alignment error" ); __TBB_ASSERT( (size_t)&my_rep->head_counter % NFS_GetLineSize()==0, "alignment error" ); __TBB_ASSERT( (size_t)&my_rep->tail_counter % NFS_GetLineSize()==0, "alignment error" ); __TBB_ASSERT( (size_t)&my_rep->array % NFS_GetLineSize()==0, "alignment error" ); memset(my_rep,0,sizeof(concurrent_queue_rep)); my_rep->item_size = item_size; my_rep->items_per_page = item_size<= 8 ? 32 : item_size<= 16 ? 16 : item_size<= 32 ? 8 : item_size<= 64 ? 4 : item_size<=128 ? 2 : 1; } template bool concurrent_queue_base_v3::internal_try_pop( void* dst ) { concurrent_queue_rep& r = *my_rep; ticket k; do { k = r.head_counter; for(;;) { if( (ptrdiff_t)(r.tail_counter-k)<=0 ) { // Queue is empty return false; } // Queue had item with ticket k when we looked. Attempt to get that item. ticket tk=k; #if defined(_MSC_VER) && defined(_Wp64) #pragma warning (push) #pragma warning (disable: 4267) #endif k = r.head_counter.compare_and_swap( tk+1, tk ); #if defined(_MSC_VER) && defined(_Wp64) #pragma warning (pop) #endif if( k==tk ) break; // Another thread snatched the item, retry. } } while( !r.choose( k ).pop( dst, k, *this ) ); return true; } template size_t concurrent_queue_base_v3::internal_size() const { concurrent_queue_rep& r = *my_rep; __TBB_ASSERT( sizeof(ptrdiff_t)<=sizeof(size_t), NULL ); ticket hc = r.head_counter; size_t nie = r.n_invalid_entries; ticket tc = r.tail_counter; __TBB_ASSERT( hc!=tc || !nie, NULL ); ptrdiff_t sz = tc-hc-nie; return sz<0 ? 0 : size_t(sz); } template bool concurrent_queue_base_v3::internal_empty() const { concurrent_queue_rep& r = *my_rep; ticket tc = r.tail_counter; ticket hc = r.head_counter; // if tc!=r.tail_counter, the queue was not empty at some point between the two reads. return tc==r.tail_counter && tc==hc+r.n_invalid_entries ; } template void concurrent_queue_base_v3::internal_finish_clear() { concurrent_queue_rep& r = *my_rep; size_t nq = r.n_queue; for( size_t i=0; i void concurrent_queue_base_v3::assign( const concurrent_queue_base_v3& src, item_constructor_t construct_item ) { concurrent_queue_rep& r = *my_rep; r.items_per_page = src.my_rep->items_per_page; // copy concurrent_queue_rep data r.head_counter = src.my_rep->head_counter; r.tail_counter = src.my_rep->tail_counter; r.n_invalid_entries = src.my_rep->n_invalid_entries; // copy or move micro_queues for( size_t i = 0; i < r.n_queue; ++i ) r.array[i].assign( src.my_rep->array[i], *this, construct_item); __TBB_ASSERT( r.head_counter==src.my_rep->head_counter && r.tail_counter==src.my_rep->tail_counter, "the source concurrent queue should not be concurrently modified." ); } template class concurrent_queue_iterator; template class concurrent_queue_iterator_rep: no_assign { typedef typename micro_queue::padded_page padded_page; public: ticket head_counter; const concurrent_queue_base_v3& my_queue; typename concurrent_queue_base_v3::page* array[concurrent_queue_rep::n_queue]; concurrent_queue_iterator_rep( const concurrent_queue_base_v3& queue ) : head_counter(queue.my_rep->head_counter), my_queue(queue) { for( size_t k=0; k::n_queue; ++k ) array[k] = queue.my_rep->array[k].head_page; } //! Set item to point to kth element. Return true if at end of queue or item is marked valid; false otherwise. bool get_item( T*& item, size_t k ) ; }; template bool concurrent_queue_iterator_rep::get_item( T*& item, size_t k ) { if( k==my_queue.my_rep->tail_counter ) { item = NULL; return true; } else { typename concurrent_queue_base_v3::page* p = array[concurrent_queue_rep::index(k)]; __TBB_ASSERT(p,NULL); size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, my_queue.my_rep->items_per_page ); item = µ_queue::get_ref(*p,i); return (p->mask & uintptr_t(1)< class concurrent_queue_iterator_base_v3 : no_assign { //! Represents concurrent_queue over which we are iterating. /** NULL if one past last element in queue. */ concurrent_queue_iterator_rep* my_rep; template friend bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); template friend bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); protected: //! Pointer to current item Value* my_item; //! Default constructor concurrent_queue_iterator_base_v3() : my_rep(NULL), my_item(NULL) { #if __TBB_GCC_OPTIMIZER_ORDERING_BROKEN __TBB_compiler_fence(); #endif } //! Copy constructor concurrent_queue_iterator_base_v3( const concurrent_queue_iterator_base_v3& i ) : no_assign(), my_rep(NULL), my_item(NULL) { assign(i); } //! Construct iterator pointing to head of queue. concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ) ; //! Assignment void assign( const concurrent_queue_iterator_base_v3& other ) ; //! Advance iterator one step towards tail of queue. void advance() ; //! Destructor ~concurrent_queue_iterator_base_v3() { cache_aligned_allocator >().deallocate(my_rep, 1); my_rep = NULL; } }; template concurrent_queue_iterator_base_v3::concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ) { my_rep = cache_aligned_allocator >().allocate(1); new( my_rep ) concurrent_queue_iterator_rep(queue); size_t k = my_rep->head_counter; if( !my_rep->get_item(my_item, k) ) advance(); } template void concurrent_queue_iterator_base_v3::assign( const concurrent_queue_iterator_base_v3& other ) { if( my_rep!=other.my_rep ) { if( my_rep ) { cache_aligned_allocator >().deallocate(my_rep, 1); my_rep = NULL; } if( other.my_rep ) { my_rep = cache_aligned_allocator >().allocate(1); new( my_rep ) concurrent_queue_iterator_rep( *other.my_rep ); } } my_item = other.my_item; } template void concurrent_queue_iterator_base_v3::advance() { __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" ); size_t k = my_rep->head_counter; const concurrent_queue_base_v3& queue = my_rep->my_queue; #if TBB_USE_ASSERT Value* tmp; my_rep->get_item(tmp,k); __TBB_ASSERT( my_item==tmp, NULL ); #endif /* TBB_USE_ASSERT */ size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, queue.my_rep->items_per_page ); if( i==queue.my_rep->items_per_page-1 ) { typename concurrent_queue_base_v3::page*& root = my_rep->array[concurrent_queue_rep::index(k)]; root = root->next; } // advance k my_rep->head_counter = ++k; if( !my_rep->get_item(my_item, k) ) advance(); } //! Similar to C++0x std::remove_cv /** "tbb_" prefix added to avoid overload confusion with C++0x implementations. */ template struct tbb_remove_cv {typedef T type;}; template struct tbb_remove_cv {typedef T type;}; template struct tbb_remove_cv {typedef T type;}; template struct tbb_remove_cv {typedef T type;}; //! Meets requirements of a forward iterator for STL. /** Value is either the T or const T type of the container. @ingroup containers */ template class concurrent_queue_iterator: public concurrent_queue_iterator_base_v3::type>, public std::iterator { #if !__TBB_TEMPLATE_FRIENDS_BROKEN template friend class ::tbb::strict_ppl::concurrent_queue; #else public: // workaround for MSVC #endif //! Construct iterator pointing to head of queue. concurrent_queue_iterator( const concurrent_queue_base_v3& queue ) : concurrent_queue_iterator_base_v3::type>(queue) { } public: concurrent_queue_iterator() {} concurrent_queue_iterator( const concurrent_queue_iterator& other ) : concurrent_queue_iterator_base_v3::type>(other) {} //! Iterator assignment concurrent_queue_iterator& operator=( const concurrent_queue_iterator& other ) { this->assign(other); return *this; } //! Reference to current item Value& operator*() const { return *static_cast(this->my_item); } Value* operator->() const {return &operator*();} //! Advance to next item in queue concurrent_queue_iterator& operator++() { this->advance(); return *this; } //! Post increment Value* operator++(int) { Value* result = &operator*(); operator++(); return result; } }; // concurrent_queue_iterator template bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { return i.my_item==j.my_item; } template bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { return i.my_item!=j.my_item; } } // namespace internal //! @endcond } // namespace strict_ppl //! @cond INTERNAL namespace internal { class concurrent_queue_rep; class concurrent_queue_iterator_rep; class concurrent_queue_iterator_base_v3; template class concurrent_queue_iterator; //! For internal use only. /** Type-independent portion of concurrent_queue. @ingroup containers */ class concurrent_queue_base_v3: no_copy { //! Internal representation concurrent_queue_rep* my_rep; friend class concurrent_queue_rep; friend struct micro_queue; friend class micro_queue_pop_finalizer; friend class concurrent_queue_iterator_rep; friend class concurrent_queue_iterator_base_v3; protected: //! Prefix on a page struct page { page* next; uintptr_t mask; }; //! Capacity of the queue ptrdiff_t my_capacity; //! Always a power of 2 size_t items_per_page; //! Size of an item size_t item_size; enum copy_specifics { copy, move }; #if __TBB_PROTECTED_NESTED_CLASS_BROKEN public: #endif template struct padded_page: page { //! Not defined anywhere - exists to quiet warnings. padded_page(); //! Not defined anywhere - exists to quiet warnings. void operator=( const padded_page& ); //! Must be last field. T last; }; private: virtual void copy_item( page& dst, size_t index, const void* src ) = 0; virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) = 0; protected: __TBB_EXPORTED_METHOD concurrent_queue_base_v3( size_t item_size ); virtual __TBB_EXPORTED_METHOD ~concurrent_queue_base_v3(); //! Enqueue item at tail of queue using copy operation void __TBB_EXPORTED_METHOD internal_push( const void* src ); //! Dequeue item from head of queue void __TBB_EXPORTED_METHOD internal_pop( void* dst ); //! Abort all pending queue operations void __TBB_EXPORTED_METHOD internal_abort(); //! Attempt to enqueue item onto queue using copy operation bool __TBB_EXPORTED_METHOD internal_push_if_not_full( const void* src ); //! Attempt to dequeue item from queue. /** NULL if there was no item to dequeue. */ bool __TBB_EXPORTED_METHOD internal_pop_if_present( void* dst ); //! Get size of queue ptrdiff_t __TBB_EXPORTED_METHOD internal_size() const; //! Check if the queue is emtpy bool __TBB_EXPORTED_METHOD internal_empty() const; //! Set the queue capacity void __TBB_EXPORTED_METHOD internal_set_capacity( ptrdiff_t capacity, size_t element_size ); //! custom allocator virtual page *allocate_page() = 0; //! custom de-allocator virtual void deallocate_page( page *p ) = 0; //! free any remaining pages /* note that the name may be misleading, but it remains so due to a historical accident. */ void __TBB_EXPORTED_METHOD internal_finish_clear() ; //! throw an exception void __TBB_EXPORTED_METHOD internal_throw_exception() const; //! copy internal representation void __TBB_EXPORTED_METHOD assign( const concurrent_queue_base_v3& src ) ; #if __TBB_CPP11_RVALUE_REF_PRESENT //! swap queues void internal_swap( concurrent_queue_base_v3& src ) { std::swap( my_capacity, src.my_capacity ); std::swap( items_per_page, src.items_per_page ); std::swap( item_size, src.item_size ); std::swap( my_rep, src.my_rep ); } #endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ //! Enqueues item at tail of queue using specified operation (copy or move) void internal_insert_item( const void* src, copy_specifics op_type ); //! Attempts to enqueue at tail of queue using specified operation (copy or move) bool internal_insert_if_not_full( const void* src, copy_specifics op_type ); //! Assigns one queue to another using specified operation (copy or move) void internal_assign( const concurrent_queue_base_v3& src, copy_specifics op_type ); private: virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0; }; //! For internal use only. /** Backward compatible modification of concurrent_queue_base_v3 @ingroup containers */ class concurrent_queue_base_v8: public concurrent_queue_base_v3 { protected: concurrent_queue_base_v8( size_t item_sz ) : concurrent_queue_base_v3( item_sz ) {} //! move items void __TBB_EXPORTED_METHOD move_content( concurrent_queue_base_v8& src ) ; //! Attempt to enqueue item onto queue using move operation bool __TBB_EXPORTED_METHOD internal_push_move_if_not_full( const void* src ); //! Enqueue item at tail of queue using move operation void __TBB_EXPORTED_METHOD internal_push_move( const void* src ); private: friend struct micro_queue; virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0; virtual void move_item( page& dst, size_t index, const void* src ) = 0; }; //! Type-independent portion of concurrent_queue_iterator. /** @ingroup containers */ class concurrent_queue_iterator_base_v3 { //! concurrent_queue over which we are iterating. /** NULL if one past last element in queue. */ concurrent_queue_iterator_rep* my_rep; template friend bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); template friend bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); void initialize( const concurrent_queue_base_v3& queue, size_t offset_of_data ); protected: //! Pointer to current item void* my_item; //! Default constructor concurrent_queue_iterator_base_v3() : my_rep(NULL), my_item(NULL) {} //! Copy constructor concurrent_queue_iterator_base_v3( const concurrent_queue_iterator_base_v3& i ) : my_rep(NULL), my_item(NULL) { assign(i); } //! Obsolete entry point for constructing iterator pointing to head of queue. /** Does not work correctly for SSE types. */ __TBB_EXPORTED_METHOD concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ); //! Construct iterator pointing to head of queue. __TBB_EXPORTED_METHOD concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue, size_t offset_of_data ); //! Assignment void __TBB_EXPORTED_METHOD assign( const concurrent_queue_iterator_base_v3& i ); //! Advance iterator one step towards tail of queue. void __TBB_EXPORTED_METHOD advance(); //! Destructor __TBB_EXPORTED_METHOD ~concurrent_queue_iterator_base_v3(); }; typedef concurrent_queue_iterator_base_v3 concurrent_queue_iterator_base; //! Meets requirements of a forward iterator for STL. /** Value is either the T or const T type of the container. @ingroup containers */ template class concurrent_queue_iterator: public concurrent_queue_iterator_base, public std::iterator { #if !defined(_MSC_VER) || defined(__INTEL_COMPILER) template friend class ::tbb::concurrent_bounded_queue; #else public: // workaround for MSVC #endif //! Construct iterator pointing to head of queue. concurrent_queue_iterator( const concurrent_queue_base_v3& queue ) : concurrent_queue_iterator_base_v3(queue,__TBB_offsetof(concurrent_queue_base_v3::padded_page,last)) { } public: concurrent_queue_iterator() {} /** If Value==Container::value_type, then this routine is the copy constructor. If Value==const Container::value_type, then this routine is a conversion constructor. */ concurrent_queue_iterator( const concurrent_queue_iterator& other ) : concurrent_queue_iterator_base_v3(other) {} //! Iterator assignment concurrent_queue_iterator& operator=( const concurrent_queue_iterator& other ) { assign(other); return *this; } //! Reference to current item Value& operator*() const { return *static_cast(my_item); } Value* operator->() const {return &operator*();} //! Advance to next item in queue concurrent_queue_iterator& operator++() { advance(); return *this; } //! Post increment Value* operator++(int) { Value* result = &operator*(); operator++(); return result; } }; // concurrent_queue_iterator template bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { return i.my_item==j.my_item; } template bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { return i.my_item!=j.my_item; } } // namespace internal; //! @endcond } // namespace tbb #endif /* __TBB__concurrent_queue_impl_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_concurrent_unordered_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Container implementations in this header are based on PPL implementations provided by Microsoft. */ #ifndef __TBB__concurrent_unordered_impl_H #define __TBB__concurrent_unordered_impl_H #if !defined(__TBB_concurrent_unordered_map_H) && !defined(__TBB_concurrent_unordered_set_H) && !defined(__TBB_concurrent_hash_map_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #include "../tbb_stddef.h" #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #include // Need std::pair #include // Need std::equal_to (in ../concurrent_unordered_*.h) #include // For tbb_hasher #include // Need std::memset #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif #include "../atomic.h" #include "../tbb_exception.h" #include "../tbb_allocator.h" #if __TBB_INITIALIZER_LISTS_PRESENT #include #endif namespace tbb { namespace interface5 { //! @cond INTERNAL namespace internal { template class split_ordered_list; template class concurrent_unordered_base; // Forward list iterators (without skipping dummy elements) template class flist_iterator : public std::iterator { template friend class split_ordered_list; template friend class concurrent_unordered_base; template friend class flist_iterator; typedef typename Solist::nodeptr_t nodeptr_t; public: typedef typename Solist::value_type value_type; typedef typename Solist::difference_type difference_type; typedef typename Solist::pointer pointer; typedef typename Solist::reference reference; flist_iterator() : my_node_ptr(0) {} flist_iterator( const flist_iterator &other ) : my_node_ptr(other.my_node_ptr) {} reference operator*() const { return my_node_ptr->my_element; } pointer operator->() const { return &**this; } flist_iterator& operator++() { my_node_ptr = my_node_ptr->my_next; return *this; } flist_iterator operator++(int) { flist_iterator tmp = *this; ++*this; return tmp; } protected: flist_iterator(nodeptr_t pnode) : my_node_ptr(pnode) {} nodeptr_t get_node_ptr() const { return my_node_ptr; } nodeptr_t my_node_ptr; template friend bool operator==( const flist_iterator &i, const flist_iterator &j ); template friend bool operator!=( const flist_iterator& i, const flist_iterator& j ); }; template bool operator==( const flist_iterator &i, const flist_iterator &j ) { return i.my_node_ptr == j.my_node_ptr; } template bool operator!=( const flist_iterator& i, const flist_iterator& j ) { return i.my_node_ptr != j.my_node_ptr; } // Split-order list iterators, needed to skip dummy elements template class solist_iterator : public flist_iterator { typedef flist_iterator base_type; typedef typename Solist::nodeptr_t nodeptr_t; using base_type::get_node_ptr; template friend class split_ordered_list; template friend class solist_iterator; template friend bool operator==( const solist_iterator &i, const solist_iterator &j ); template friend bool operator!=( const solist_iterator& i, const solist_iterator& j ); const Solist *my_list_ptr; solist_iterator(nodeptr_t pnode, const Solist *plist) : base_type(pnode), my_list_ptr(plist) {} public: typedef typename Solist::value_type value_type; typedef typename Solist::difference_type difference_type; typedef typename Solist::pointer pointer; typedef typename Solist::reference reference; solist_iterator() {} solist_iterator(const solist_iterator &other ) : base_type(other), my_list_ptr(other.my_list_ptr) {} reference operator*() const { return this->base_type::operator*(); } pointer operator->() const { return (&**this); } solist_iterator& operator++() { do ++(*(base_type *)this); while (get_node_ptr() != NULL && get_node_ptr()->is_dummy()); return (*this); } solist_iterator operator++(int) { solist_iterator tmp = *this; do ++*this; while (get_node_ptr() != NULL && get_node_ptr()->is_dummy()); return (tmp); } }; template bool operator==( const solist_iterator &i, const solist_iterator &j ) { return i.my_node_ptr == j.my_node_ptr && i.my_list_ptr == j.my_list_ptr; } template bool operator!=( const solist_iterator& i, const solist_iterator& j ) { return i.my_node_ptr != j.my_node_ptr || i.my_list_ptr != j.my_list_ptr; } // Forward type and class definitions typedef size_t sokey_t; // Forward list in which elements are sorted in a split-order template class split_ordered_list { public: typedef split_ordered_list self_type; typedef typename Allocator::template rebind::other allocator_type; struct node; typedef node *nodeptr_t; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::difference_type difference_type; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference; typedef typename allocator_type::value_type value_type; typedef solist_iterator const_iterator; typedef solist_iterator iterator; typedef flist_iterator raw_const_iterator; typedef flist_iterator raw_iterator; // Node that holds the element in a split-ordered list struct node : tbb::internal::no_assign { private: // for compilers that try to generate default constructors though they are not needed. node(); // VS 2008, 2010, 2012 public: // Initialize the node with the given order key void init(sokey_t order_key) { my_order_key = order_key; my_next = NULL; } // Return the order key (needed for hashing) sokey_t get_order_key() const { // TODO: remove return my_order_key; } // Inserts the new element in the list in an atomic fashion nodeptr_t atomic_set_next(nodeptr_t new_node, nodeptr_t current_node) { // Try to change the next pointer on the current element to a new element, only if it still points to the cached next nodeptr_t exchange_node = tbb::internal::as_atomic(my_next).compare_and_swap(new_node, current_node); if (exchange_node == current_node) // TODO: why this branch? { // Operation succeeded, return the new node return new_node; } else { // Operation failed, return the "interfering" node return exchange_node; } } // Checks if this element in the list is a dummy, order enforcing node. Dummy nodes are used by buckets // in the hash table to quickly index into the right subsection of the split-ordered list. bool is_dummy() const { return (my_order_key & 0x1) == 0; } nodeptr_t my_next; // Next element in the list value_type my_element; // Element storage sokey_t my_order_key; // Order key for this element }; // Allocate a new node with the given order key and value nodeptr_t create_node(sokey_t order_key, const T &value) { nodeptr_t pnode = my_node_allocator.allocate(1); __TBB_TRY { new(static_cast(&pnode->my_element)) T(value); pnode->init(order_key); } __TBB_CATCH(...) { my_node_allocator.deallocate(pnode, 1); __TBB_RETHROW(); } return (pnode); } #if __TBB_CPP11_RVALUE_REF_PRESENT //TODO: try to combine both implementations using poor man forward //TODO: use RAII scoped guard instead of explicit catch // Allocate a new node with the given order key and value nodeptr_t create_node(sokey_t order_key, T &&value) { nodeptr_t pnode = my_node_allocator.allocate(1); __TBB_TRY { new(static_cast(&pnode->my_element)) T(std::move(value)); pnode->init(order_key); } __TBB_CATCH(...) { my_node_allocator.deallocate(pnode, 1); __TBB_RETHROW(); } return (pnode); } #endif //__TBB_CPP11_RVALUE_REF_PRESENT // Allocate a new node with the given order key; used to allocate dummy nodes nodeptr_t create_node(sokey_t order_key) { nodeptr_t pnode = my_node_allocator.allocate(1); pnode->init(order_key); return (pnode); } split_ordered_list(allocator_type a = allocator_type()) : my_node_allocator(a), my_element_count(0) { // Immediately allocate a dummy node with order key of 0. This node // will always be the head of the list. my_head = create_node(0); } ~split_ordered_list() { // Clear the list clear(); // Remove the head element which is not cleared by clear() nodeptr_t pnode = my_head; my_head = NULL; __TBB_ASSERT(pnode != NULL && pnode->my_next == NULL, "Invalid head list node"); destroy_node(pnode); } // Common forward list functions allocator_type get_allocator() const { return (my_node_allocator); } void clear() { nodeptr_t pnext; nodeptr_t pnode = my_head; __TBB_ASSERT(my_head != NULL, "Invalid head list node"); pnext = pnode->my_next; pnode->my_next = NULL; pnode = pnext; while (pnode != NULL) { pnext = pnode->my_next; destroy_node(pnode); pnode = pnext; } my_element_count = 0; } // Returns a first non-dummy element in the SOL iterator begin() { return first_real_iterator(raw_begin()); } // Returns a first non-dummy element in the SOL const_iterator begin() const { return first_real_iterator(raw_begin()); } iterator end() { return (iterator(0, this)); } const_iterator end() const { return (const_iterator(0, this)); } const_iterator cbegin() const { return (((const self_type *)this)->begin()); } const_iterator cend() const { return (((const self_type *)this)->end()); } // Checks if the number of elements (non-dummy) is 0 bool empty() const { return (my_element_count == 0); } // Returns the number of non-dummy elements in the list size_type size() const { return my_element_count; } // Returns the maximum size of the list, determined by the allocator size_type max_size() const { return my_node_allocator.max_size(); } // Swaps 'this' list with the passed in one void swap(self_type& other) { if (this == &other) { // Nothing to do return; } std::swap(my_element_count, other.my_element_count); std::swap(my_head, other.my_head); } // Split-order list functions // Returns a first element in the SOL, which is always a dummy raw_iterator raw_begin() { return raw_iterator(my_head); } // Returns a first element in the SOL, which is always a dummy raw_const_iterator raw_begin() const { return raw_const_iterator(my_head); } raw_iterator raw_end() { return raw_iterator(0); } raw_const_iterator raw_end() const { return raw_const_iterator(0); } static sokey_t get_order_key(const raw_const_iterator& it) { return it.get_node_ptr()->get_order_key(); } static sokey_t get_safe_order_key(const raw_const_iterator& it) { if( !it.get_node_ptr() ) return ~sokey_t(0); return it.get_node_ptr()->get_order_key(); } // Returns a public iterator version of the internal iterator. Public iterator must not // be a dummy private iterator. iterator get_iterator(raw_iterator it) { __TBB_ASSERT(it.get_node_ptr() == NULL || !it.get_node_ptr()->is_dummy(), "Invalid user node (dummy)"); return iterator(it.get_node_ptr(), this); } // Returns a public iterator version of the internal iterator. Public iterator must not // be a dummy private iterator. const_iterator get_iterator(raw_const_iterator it) const { __TBB_ASSERT(it.get_node_ptr() == NULL || !it.get_node_ptr()->is_dummy(), "Invalid user node (dummy)"); return const_iterator(it.get_node_ptr(), this); } // Returns a non-const version of the raw_iterator raw_iterator get_iterator(raw_const_iterator it) { return raw_iterator(it.get_node_ptr()); } // Returns a non-const version of the iterator static iterator get_iterator(const_iterator it) { return iterator(it.my_node_ptr, it.my_list_ptr); } // Returns a public iterator version of a first non-dummy internal iterator at or after // the passed in internal iterator. iterator first_real_iterator(raw_iterator it) { // Skip all dummy, internal only iterators while (it != raw_end() && it.get_node_ptr()->is_dummy()) ++it; return iterator(it.get_node_ptr(), this); } // Returns a public iterator version of a first non-dummy internal iterator at or after // the passed in internal iterator. const_iterator first_real_iterator(raw_const_iterator it) const { // Skip all dummy, internal only iterators while (it != raw_end() && it.get_node_ptr()->is_dummy()) ++it; return const_iterator(it.get_node_ptr(), this); } // Erase an element using the allocator void destroy_node(nodeptr_t pnode) { if (!pnode->is_dummy()) my_node_allocator.destroy(pnode); my_node_allocator.deallocate(pnode, 1); } // Try to insert a new element in the list. If insert fails, return the node that // was inserted instead. nodeptr_t try_insert(nodeptr_t previous, nodeptr_t new_node, nodeptr_t current_node) { new_node->my_next = current_node; return previous->atomic_set_next(new_node, current_node); } // Insert a new element between passed in iterators std::pair try_insert(raw_iterator it, raw_iterator next, const value_type &value, sokey_t order_key, size_type *new_count) { nodeptr_t pnode = create_node(order_key, value); nodeptr_t inserted_node = try_insert(it.get_node_ptr(), pnode, next.get_node_ptr()); if (inserted_node == pnode) { // If the insert succeeded, check that the order is correct and increment the element count check_range(); *new_count = __TBB_FetchAndAddW((uintptr_t*)&my_element_count, uintptr_t(1)); return std::pair(iterator(pnode, this), true); } else { // If the insert failed (element already there), then delete the new one destroy_node(pnode); return std::pair(end(), false); } } // Insert a new dummy element, starting search at a parent dummy element raw_iterator insert_dummy(raw_iterator it, sokey_t order_key) { raw_iterator last = raw_end(); raw_iterator where = it; __TBB_ASSERT(where != last, "Invalid head node"); ++where; // Create a dummy element up front, even though it may be discarded (due to concurrent insertion) nodeptr_t dummy_node = create_node(order_key); for (;;) { __TBB_ASSERT(it != last, "Invalid head list node"); // If the head iterator is at the end of the list, or past the point where this dummy // node needs to be inserted, then try to insert it. if (where == last || get_order_key(where) > order_key) { __TBB_ASSERT(get_order_key(it) < order_key, "Invalid node order in the list"); // Try to insert it in the right place nodeptr_t inserted_node = try_insert(it.get_node_ptr(), dummy_node, where.get_node_ptr()); if (inserted_node == dummy_node) { // Insertion succeeded, check the list for order violations check_range(); return raw_iterator(dummy_node); } else { // Insertion failed: either dummy node was inserted by another thread, or // a real element was inserted at exactly the same place as dummy node. // Proceed with the search from the previous location where order key was // known to be larger (note: this is legal only because there is no safe // concurrent erase operation supported). where = it; ++where; continue; } } else if (get_order_key(where) == order_key) { // Another dummy node with the same value found, discard the new one. destroy_node(dummy_node); return where; } // Move the iterator forward it = where; ++where; } } // This erase function can handle both real and dummy nodes void erase_node(raw_iterator previous, raw_const_iterator& where) { nodeptr_t pnode = (where++).get_node_ptr(); nodeptr_t prevnode = previous.get_node_ptr(); __TBB_ASSERT(prevnode->my_next == pnode, "Erase must take consecutive iterators"); prevnode->my_next = pnode->my_next; destroy_node(pnode); } // Erase the element (previous node needs to be passed because this is a forward only list) iterator erase_node(raw_iterator previous, const_iterator where) { raw_const_iterator it = where; erase_node(previous, it); my_element_count--; return get_iterator(first_real_iterator(it)); } // Move all elements from the passed in split-ordered list to this one void move_all(self_type& source) { raw_const_iterator first = source.raw_begin(); raw_const_iterator last = source.raw_end(); if (first == last) return; nodeptr_t previous_node = my_head; raw_const_iterator begin_iterator = first++; // Move all elements one by one, including dummy ones for (raw_const_iterator it = first; it != last;) { nodeptr_t pnode = it.get_node_ptr(); nodeptr_t dummy_node = pnode->is_dummy() ? create_node(pnode->get_order_key()) : create_node(pnode->get_order_key(), pnode->my_element); previous_node = try_insert(previous_node, dummy_node, NULL); __TBB_ASSERT(previous_node != NULL, "Insertion must succeed"); raw_const_iterator where = it++; source.erase_node(get_iterator(begin_iterator), where); } check_range(); } private: //Need to setup private fields of split_ordered_list in move constructor and assignment of concurrent_unordered_base template friend class concurrent_unordered_base; // Check the list for order violations void check_range() { #if TBB_USE_ASSERT for (raw_iterator it = raw_begin(); it != raw_end(); ++it) { raw_iterator next_iterator = it; ++next_iterator; __TBB_ASSERT(next_iterator == end() || next_iterator.get_node_ptr()->get_order_key() >= it.get_node_ptr()->get_order_key(), "!!! List order inconsistency !!!"); } #endif } typename allocator_type::template rebind::other my_node_allocator; // allocator object for nodes size_type my_element_count; // Total item count, not counting dummy nodes nodeptr_t my_head; // pointer to head node }; // Template class for hash compare template class hash_compare { public: typedef Hasher hasher; typedef Key_equality key_equal; hash_compare() {} hash_compare(Hasher a_hasher) : my_hash_object(a_hasher) {} hash_compare(Hasher a_hasher, Key_equality a_keyeq) : my_hash_object(a_hasher), my_key_compare_object(a_keyeq) {} size_t operator()(const Key& key) const { return ((size_t)my_hash_object(key)); } bool operator()(const Key& key1, const Key& key2) const { return (!my_key_compare_object(key1, key2)); } Hasher my_hash_object; // The hash object Key_equality my_key_compare_object; // The equality comparator object }; #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning(push) #pragma warning(disable: 4127) // warning C4127: conditional expression is constant #endif template class concurrent_unordered_base : public Traits { protected: // Type definitions typedef concurrent_unordered_base self_type; typedef typename Traits::value_type value_type; typedef typename Traits::key_type key_type; typedef typename Traits::hash_compare hash_compare; typedef typename Traits::value_compare value_compare; typedef typename Traits::allocator_type allocator_type; typedef typename hash_compare::hasher hasher; typedef typename hash_compare::key_equal key_equal; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::difference_type difference_type; typedef split_ordered_list solist_t; typedef typename solist_t::nodeptr_t nodeptr_t; // Iterators that walk the entire split-order list, including dummy nodes typedef typename solist_t::raw_iterator raw_iterator; typedef typename solist_t::raw_const_iterator raw_const_iterator; typedef typename solist_t::iterator iterator; // TODO: restore const iterator for unordered_sets typedef typename solist_t::const_iterator const_iterator; typedef iterator local_iterator; typedef const_iterator const_local_iterator; using Traits::my_hash_compare; using Traits::get_key; using Traits::allow_multimapping; static const size_type initial_bucket_number = 8; // Initial number of buckets private: typedef std::pair pairii_t; typedef std::pair paircc_t; static size_type const pointers_per_table = sizeof(size_type) * 8; // One bucket segment per bit static const size_type initial_bucket_load = 4; // Initial maximum number of elements per bucket struct call_internal_clear_on_exit{ concurrent_unordered_base* my_instance; call_internal_clear_on_exit(concurrent_unordered_base* instance) : my_instance(instance) {} void dismiss(){ my_instance = NULL;} ~call_internal_clear_on_exit(){ if (my_instance){ my_instance->internal_clear(); } } }; protected: // Constructors/Destructors concurrent_unordered_base(size_type n_of_buckets = initial_bucket_number, const hash_compare& hc = hash_compare(), const allocator_type& a = allocator_type()) : Traits(hc), my_solist(a), my_allocator(a), my_maximum_bucket_size((float) initial_bucket_load) { if( n_of_buckets == 0) ++n_of_buckets; my_number_of_buckets = 1<<__TBB_Log2((uintptr_t)n_of_buckets*2-1); // round up to power of 2 internal_init(); } concurrent_unordered_base(const concurrent_unordered_base& right, const allocator_type& a) : Traits(right.my_hash_compare), my_solist(a), my_allocator(a) { internal_init(); internal_copy(right); } concurrent_unordered_base(const concurrent_unordered_base& right) : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator()) { //FIXME:exception safety seems to be broken here internal_init(); internal_copy(right); } #if __TBB_CPP11_RVALUE_REF_PRESENT concurrent_unordered_base(concurrent_unordered_base&& right) : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator()) { internal_init(); swap(right); } concurrent_unordered_base(concurrent_unordered_base&& right, const allocator_type& a) : Traits(right.my_hash_compare), my_solist(a), my_allocator(a) { call_internal_clear_on_exit clear_buckets_on_exception(this); internal_init(); if (a == right.get_allocator()){ this->swap(right); }else{ my_maximum_bucket_size = right.my_maximum_bucket_size; my_number_of_buckets = right.my_number_of_buckets; my_solist.my_element_count = right.my_solist.my_element_count; if (! right.my_solist.empty()){ nodeptr_t previous_node = my_solist.my_head; // Move all elements one by one, including dummy ones for (raw_const_iterator it = ++(right.my_solist.raw_begin()), last = right.my_solist.raw_end(); it != last; ++it) { const nodeptr_t pnode = it.get_node_ptr(); nodeptr_t node; if (pnode->is_dummy()) { node = my_solist.create_node(pnode->get_order_key()); size_type bucket = __TBB_ReverseBits(pnode->get_order_key()) % my_number_of_buckets; set_bucket(bucket, node); }else{ node = my_solist.create_node(pnode->get_order_key(), std::move(pnode->my_element)); } previous_node = my_solist.try_insert(previous_node, node, NULL); __TBB_ASSERT(previous_node != NULL, "Insertion of node failed. Concurrent inserts in constructor ?"); } my_solist.check_range(); } } clear_buckets_on_exception.dismiss(); } #endif //__TBB_CPP11_RVALUE_REF_PRESENT concurrent_unordered_base& operator=(const concurrent_unordered_base& right) { if (this != &right) internal_copy(right); return (*this); } #if __TBB_CPP11_RVALUE_REF_PRESENT concurrent_unordered_base& operator=(concurrent_unordered_base&& other) { if(this != &other){ typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; if(pocma_t::value || this->my_allocator == other.my_allocator) { concurrent_unordered_base trash (std::move(*this)); swap(other); if (pocma_t::value) { using std::swap; //TODO: swapping allocators here may be a problem, replace with single direction moving swap(this->my_solist.my_node_allocator, other.my_solist.my_node_allocator); swap(this->my_allocator, other.my_allocator); } } else { concurrent_unordered_base moved_copy(std::move(other),this->my_allocator); this->swap(moved_copy); } } return *this; } #endif //__TBB_CPP11_RVALUE_REF_PRESENT #if __TBB_INITIALIZER_LISTS_PRESENT //! assignment operator from initializer_list concurrent_unordered_base& operator=(std::initializer_list il) { this->clear(); this->insert(il.begin(),il.end()); return (*this); } #endif //# __TBB_INITIALIZER_LISTS_PRESENT ~concurrent_unordered_base() { // Delete all node segments internal_clear(); } public: allocator_type get_allocator() const { return my_solist.get_allocator(); } // Size and capacity function bool empty() const { return my_solist.empty(); } size_type size() const { return my_solist.size(); } size_type max_size() const { return my_solist.max_size(); } // Iterators iterator begin() { return my_solist.begin(); } const_iterator begin() const { return my_solist.begin(); } iterator end() { return my_solist.end(); } const_iterator end() const { return my_solist.end(); } const_iterator cbegin() const { return my_solist.cbegin(); } const_iterator cend() const { return my_solist.cend(); } // Parallel traversal support class const_range_type : tbb::internal::no_assign { const concurrent_unordered_base &my_table; raw_const_iterator my_begin_node; raw_const_iterator my_end_node; mutable raw_const_iterator my_midpoint_node; public: //! Type for size of a range typedef typename concurrent_unordered_base::size_type size_type; typedef typename concurrent_unordered_base::value_type value_type; typedef typename concurrent_unordered_base::reference reference; typedef typename concurrent_unordered_base::difference_type difference_type; typedef typename concurrent_unordered_base::const_iterator iterator; //! True if range is empty. bool empty() const {return my_begin_node == my_end_node;} //! True if range can be partitioned into two subranges. bool is_divisible() const { return my_midpoint_node != my_end_node; } //! Split range. const_range_type( const_range_type &r, split ) : my_table(r.my_table), my_end_node(r.my_end_node) { r.my_end_node = my_begin_node = r.my_midpoint_node; __TBB_ASSERT( !empty(), "Splitting despite the range is not divisible" ); __TBB_ASSERT( !r.empty(), "Splitting despite the range is not divisible" ); set_midpoint(); r.set_midpoint(); } //! Init range with container and grainsize specified const_range_type( const concurrent_unordered_base &a_table ) : my_table(a_table), my_begin_node(a_table.my_solist.begin()), my_end_node(a_table.my_solist.end()) { set_midpoint(); } iterator begin() const { return my_table.my_solist.get_iterator(my_begin_node); } iterator end() const { return my_table.my_solist.get_iterator(my_end_node); } //! The grain size for this range. size_type grainsize() const { return 1; } //! Set my_midpoint_node to point approximately half way between my_begin_node and my_end_node. void set_midpoint() const { if( my_begin_node == my_end_node ) // not divisible my_midpoint_node = my_end_node; else { sokey_t begin_key = solist_t::get_safe_order_key(my_begin_node); sokey_t end_key = solist_t::get_safe_order_key(my_end_node); size_t mid_bucket = __TBB_ReverseBits( begin_key + (end_key-begin_key)/2 ) % my_table.my_number_of_buckets; while ( !my_table.is_initialized(mid_bucket) ) mid_bucket = my_table.get_parent(mid_bucket); if(__TBB_ReverseBits(mid_bucket) > begin_key) { // found a dummy_node between begin and end my_midpoint_node = my_table.my_solist.first_real_iterator(my_table.get_bucket( mid_bucket )); } else { // didn't find a dummy node between begin and end. my_midpoint_node = my_end_node; } #if TBB_USE_ASSERT { sokey_t mid_key = solist_t::get_safe_order_key(my_midpoint_node); __TBB_ASSERT( begin_key < mid_key, "my_begin_node is after my_midpoint_node" ); __TBB_ASSERT( mid_key <= end_key, "my_midpoint_node is after my_end_node" ); } #endif // TBB_USE_ASSERT } } }; class range_type : public const_range_type { public: typedef typename concurrent_unordered_base::iterator iterator; //! Split range. range_type( range_type &r, split ) : const_range_type( r, split() ) {} //! Init range with container and grainsize specified range_type( const concurrent_unordered_base &a_table ) : const_range_type(a_table) {} iterator begin() const { return solist_t::get_iterator( const_range_type::begin() ); } iterator end() const { return solist_t::get_iterator( const_range_type::end() ); } }; range_type range() { return range_type( *this ); } const_range_type range() const { return const_range_type( *this ); } // Modifiers std::pair insert(const value_type& value) { return internal_insert(value); } iterator insert(const_iterator, const value_type& value) { // Ignore hint return insert(value).first; } template void insert(Iterator first, Iterator last) { for (Iterator it = first; it != last; ++it) insert(*it); } #if __TBB_INITIALIZER_LISTS_PRESENT //! Insert initializer list void insert(std::initializer_list il) { insert(il.begin(), il.end()); } #endif iterator unsafe_erase(const_iterator where) { return internal_erase(where); } iterator unsafe_erase(const_iterator first, const_iterator last) { while (first != last) unsafe_erase(first++); return my_solist.get_iterator(first); } size_type unsafe_erase(const key_type& key) { pairii_t where = equal_range(key); size_type item_count = internal_distance(where.first, where.second); unsafe_erase(where.first, where.second); return item_count; } void swap(concurrent_unordered_base& right) { if (this != &right) { std::swap(my_hash_compare, right.my_hash_compare); // TODO: check what ADL meant here my_solist.swap(right.my_solist); internal_swap_buckets(right); std::swap(my_number_of_buckets, right.my_number_of_buckets); std::swap(my_maximum_bucket_size, right.my_maximum_bucket_size); } } // Observers hasher hash_function() const { return my_hash_compare.my_hash_object; } key_equal key_eq() const { return my_hash_compare.my_key_compare_object; } void clear() { // Clear list my_solist.clear(); // Clear buckets internal_clear(); // Initialize bucket 0 __TBB_ASSERT(my_buckets[0] == NULL, NULL); raw_iterator dummy_node = my_solist.raw_begin(); set_bucket(0, dummy_node); } // Lookup iterator find(const key_type& key) { return internal_find(key); } const_iterator find(const key_type& key) const { return const_cast(this)->internal_find(key); } size_type count(const key_type& key) const { if(allow_multimapping) { paircc_t answer = equal_range(key); size_type item_count = internal_distance(answer.first, answer.second); return item_count; } else { return const_cast(this)->internal_find(key) == end()?0:1; } } std::pair equal_range(const key_type& key) { return internal_equal_range(key); } std::pair equal_range(const key_type& key) const { return const_cast(this)->internal_equal_range(key); } // Bucket interface - for debugging size_type unsafe_bucket_count() const { return my_number_of_buckets; } size_type unsafe_max_bucket_count() const { return segment_size(pointers_per_table-1); } size_type unsafe_bucket_size(size_type bucket) { size_type item_count = 0; if (is_initialized(bucket)) { raw_iterator it = get_bucket(bucket); ++it; for (; it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy(); ++it) ++item_count; } return item_count; } size_type unsafe_bucket(const key_type& key) const { sokey_t order_key = (sokey_t) my_hash_compare(key); size_type bucket = order_key % my_number_of_buckets; return bucket; } // If the bucket is initialized, return a first non-dummy element in it local_iterator unsafe_begin(size_type bucket) { if (!is_initialized(bucket)) return end(); raw_iterator it = get_bucket(bucket); return my_solist.first_real_iterator(it); } // If the bucket is initialized, return a first non-dummy element in it const_local_iterator unsafe_begin(size_type bucket) const { if (!is_initialized(bucket)) return end(); raw_const_iterator it = get_bucket(bucket); return my_solist.first_real_iterator(it); } // @REVIEW: Takes O(n) // Returns the iterator after the last non-dummy element in the bucket local_iterator unsafe_end(size_type bucket) { if (!is_initialized(bucket)) return end(); raw_iterator it = get_bucket(bucket); // Find the end of the bucket, denoted by the dummy element do ++it; while(it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy()); // Return the first real element past the end of the bucket return my_solist.first_real_iterator(it); } // @REVIEW: Takes O(n) // Returns the iterator after the last non-dummy element in the bucket const_local_iterator unsafe_end(size_type bucket) const { if (!is_initialized(bucket)) return end(); raw_const_iterator it = get_bucket(bucket); // Find the end of the bucket, denoted by the dummy element do ++it; while(it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy()); // Return the first real element past the end of the bucket return my_solist.first_real_iterator(it); } const_local_iterator unsafe_cbegin(size_type bucket) const { return ((const self_type *) this)->unsafe_begin(bucket); } const_local_iterator unsafe_cend(size_type bucket) const { return ((const self_type *) this)->unsafe_end(bucket); } // Hash policy float load_factor() const { return (float) size() / (float) unsafe_bucket_count(); } float max_load_factor() const { return my_maximum_bucket_size; } void max_load_factor(float newmax) { if (newmax != newmax || newmax < 0) tbb::internal::throw_exception(tbb::internal::eid_invalid_load_factor); my_maximum_bucket_size = newmax; } // This function is a noop, because the underlying split-ordered list // is already sorted, so an increase in the bucket number will be // reflected next time this bucket is touched. void rehash(size_type buckets) { size_type current_buckets = my_number_of_buckets; if (current_buckets >= buckets) return; my_number_of_buckets = 1<<__TBB_Log2((uintptr_t)buckets*2-1); // round up to power of 2 } private: // Initialize the hash and keep the first bucket open void internal_init() { // Allocate an array of segment pointers memset(my_buckets, 0, pointers_per_table * sizeof(void *)); // Initialize bucket 0 raw_iterator dummy_node = my_solist.raw_begin(); set_bucket(0, dummy_node); } void internal_clear() { for (size_type index = 0; index < pointers_per_table; ++index) { if (my_buckets[index] != NULL) { size_type sz = segment_size(index); for (size_type index2 = 0; index2 < sz; ++index2) my_allocator.destroy(&my_buckets[index][index2]); my_allocator.deallocate(my_buckets[index], sz); my_buckets[index] = 0; } } } void internal_copy(const self_type& right) { clear(); my_maximum_bucket_size = right.my_maximum_bucket_size; my_number_of_buckets = right.my_number_of_buckets; __TBB_TRY { insert(right.begin(), right.end()); my_hash_compare = right.my_hash_compare; } __TBB_CATCH(...) { my_solist.clear(); __TBB_RETHROW(); } } void internal_swap_buckets(concurrent_unordered_base& right) { // Swap all node segments for (size_type index = 0; index < pointers_per_table; ++index) { raw_iterator * iterator_pointer = my_buckets[index]; my_buckets[index] = right.my_buckets[index]; right.my_buckets[index] = iterator_pointer; } } //TODO: why not use std::distance? // Hash APIs size_type internal_distance(const_iterator first, const_iterator last) const { size_type num = 0; for (const_iterator it = first; it != last; ++it) ++num; return num; } // Insert an element in the hash given its value std::pair internal_insert(const value_type& value) { sokey_t order_key = (sokey_t) my_hash_compare(get_key(value)); size_type bucket = order_key % my_number_of_buckets; // If bucket is empty, initialize it first if (!is_initialized(bucket)) init_bucket(bucket); size_type new_count = 0; order_key = split_order_key_regular(order_key); raw_iterator it = get_bucket(bucket); raw_iterator last = my_solist.raw_end(); raw_iterator where = it; __TBB_ASSERT(where != last, "Invalid head node"); // First node is a dummy node ++where; for (;;) { if (where == last || solist_t::get_order_key(where) > order_key) { // Try to insert it in the right place std::pair result = my_solist.try_insert(it, where, value, order_key, &new_count); if (result.second) { // Insertion succeeded, adjust the table size, if needed adjust_table_size(new_count, my_number_of_buckets); return result; } else { // Insertion failed: either the same node was inserted by another thread, or // another element was inserted at exactly the same place as this node. // Proceed with the search from the previous location where order key was // known to be larger (note: this is legal only because there is no safe // concurrent erase operation supported). where = it; ++where; continue; } } else if (!allow_multimapping && solist_t::get_order_key(where) == order_key && my_hash_compare(get_key(*where), get_key(value)) == 0) { // Element already in the list, return it return std::pair(my_solist.get_iterator(where), false); } // Move the iterator forward it = where; ++where; } } // Find the element in the split-ordered list iterator internal_find(const key_type& key) { sokey_t order_key = (sokey_t) my_hash_compare(key); size_type bucket = order_key % my_number_of_buckets; // If bucket is empty, initialize it first if (!is_initialized(bucket)) init_bucket(bucket); order_key = split_order_key_regular(order_key); raw_iterator last = my_solist.raw_end(); for (raw_iterator it = get_bucket(bucket); it != last; ++it) { if (solist_t::get_order_key(it) > order_key) { // If the order key is smaller than the current order key, the element // is not in the hash. return end(); } else if (solist_t::get_order_key(it) == order_key) { // The fact that order keys match does not mean that the element is found. // Key function comparison has to be performed to check whether this is the // right element. If not, keep searching while order key is the same. if (!my_hash_compare(get_key(*it), key)) return my_solist.get_iterator(it); } } return end(); } // Erase an element from the list. This is not a concurrency safe function. iterator internal_erase(const_iterator it) { key_type key = get_key(*it); sokey_t order_key = (sokey_t) my_hash_compare(key); size_type bucket = order_key % my_number_of_buckets; // If bucket is empty, initialize it first if (!is_initialized(bucket)) init_bucket(bucket); order_key = split_order_key_regular(order_key); raw_iterator previous = get_bucket(bucket); raw_iterator last = my_solist.raw_end(); raw_iterator where = previous; __TBB_ASSERT(where != last, "Invalid head node"); // First node is a dummy node ++where; for (;;) { if (where == last) return end(); else if (my_solist.get_iterator(where) == it) return my_solist.erase_node(previous, it); // Move the iterator forward previous = where; ++where; } } // Return the [begin, end) pair of iterators with the same key values. // This operation makes sense only if mapping is many-to-one. pairii_t internal_equal_range(const key_type& key) { sokey_t order_key = (sokey_t) my_hash_compare(key); size_type bucket = order_key % my_number_of_buckets; // If bucket is empty, initialize it first if (!is_initialized(bucket)) init_bucket(bucket); order_key = split_order_key_regular(order_key); raw_iterator end_it = my_solist.raw_end(); for (raw_iterator it = get_bucket(bucket); it != end_it; ++it) { if (solist_t::get_order_key(it) > order_key) { // There is no element with the given key return pairii_t(end(), end()); } else if (solist_t::get_order_key(it) == order_key && !my_hash_compare(get_key(*it), key)) { iterator first = my_solist.get_iterator(it); iterator last = first; do ++last; while( allow_multimapping && last != end() && !my_hash_compare(get_key(*last), key) ); return pairii_t(first, last); } } return pairii_t(end(), end()); } // Bucket APIs void init_bucket(size_type bucket) { // Bucket 0 has no parent. __TBB_ASSERT( bucket != 0, "The first bucket must always be initialized"); size_type parent_bucket = get_parent(bucket); // All parent_bucket buckets have to be initialized before this bucket is if (!is_initialized(parent_bucket)) init_bucket(parent_bucket); raw_iterator parent = get_bucket(parent_bucket); // Create a dummy first node in this bucket raw_iterator dummy_node = my_solist.insert_dummy(parent, split_order_key_dummy(bucket)); set_bucket(bucket, dummy_node); } void adjust_table_size(size_type total_elements, size_type current_size) { // Grow the table by a factor of 2 if possible and needed if ( ((float) total_elements / (float) current_size) > my_maximum_bucket_size ) { // Double the size of the hash only if size has not changed in between loads my_number_of_buckets.compare_and_swap(2u*current_size, current_size); //Simple "my_number_of_buckets.compare_and_swap( current_size<<1, current_size );" does not work for VC8 //due to overzealous compiler warnings in /Wp64 mode } } size_type get_parent(size_type bucket) const { // Unsets bucket's most significant turned-on bit size_type msb = __TBB_Log2((uintptr_t)bucket); return bucket & ~(size_type(1) << msb); } // Dynamic sized array (segments) //! @return segment index of given index in the array static size_type segment_index_of( size_type index ) { return size_type( __TBB_Log2( uintptr_t(index|1) ) ); } //! @return the first array index of given segment static size_type segment_base( size_type k ) { return (size_type(1)< my_number_of_buckets; // Current table size solist_t my_solist; // List where all the elements are kept typename allocator_type::template rebind::other my_allocator; // Allocator object for segments float my_maximum_bucket_size; // Maximum size of the bucket atomic my_buckets[pointers_per_table]; // The segment table }; #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning(pop) // warning 4127 is back #endif //! Hash multiplier static const size_t hash_multiplier = tbb::internal::select_size_t_constant<2654435769U, 11400714819323198485ULL>::value; } // namespace internal //! @endcond //! Hasher functions template inline size_t tbb_hasher( const T& t ) { return static_cast( t ) * internal::hash_multiplier; } template inline size_t tbb_hasher( P* ptr ) { size_t const h = reinterpret_cast( ptr ); return (h >> 3) ^ h; } template inline size_t tbb_hasher( const std::basic_string& s ) { size_t h = 0; for( const E* c = s.c_str(); *c; ++c ) h = static_cast(*c) ^ (h * internal::hash_multiplier); return h; } template inline size_t tbb_hasher( const std::pair& p ) { return tbb_hasher(p.first) ^ tbb_hasher(p.second); } } // namespace interface5 using interface5::tbb_hasher; // Template class for hash compare template class tbb_hash { public: tbb_hash() {} size_t operator()(const Key& key) const { return tbb_hasher(key); } }; } // namespace tbb #endif// __TBB__concurrent_unordered_impl_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__flow_graph_impl_H #define __TBB__flow_graph_impl_H #ifndef __TBB_flow_graph_H #error Do not #include this internal file directly; use public TBB headers instead. #endif namespace internal { namespace graph_policy_namespace { enum graph_buffer_policy { rejecting, reserving, queueing, tag_matching }; } // -------------- function_body containers ---------------------- //! A functor that takes no input and generates a value of type Output template< typename Output > class source_body : tbb::internal::no_assign { public: virtual ~source_body() {} virtual bool operator()(Output &output) = 0; virtual source_body* clone() = 0; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES virtual void reset_body() = 0; #endif }; //! The leaf for source_body template< typename Output, typename Body> class source_body_leaf : public source_body { public: source_body_leaf( const Body &_body ) : body(_body), init_body(_body) { } /*override*/ bool operator()(Output &output) { return body( output ); } /*override*/ source_body_leaf* clone() { return new source_body_leaf< Output, Body >(init_body); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void reset_body() { body = init_body; } #endif Body get_body() { return body; } private: Body body; Body init_body; }; //! A functor that takes an Input and generates an Output template< typename Input, typename Output > class function_body : tbb::internal::no_assign { public: virtual ~function_body() {} virtual Output operator()(const Input &input) = 0; virtual function_body* clone() = 0; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES virtual void reset_body() = 0; #endif }; //! the leaf for function_body template class function_body_leaf : public function_body< Input, Output > { public: function_body_leaf( const B &_body ) : body(_body), init_body(_body) { } Output operator()(const Input &i) { return body(i); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void reset_body() { body = init_body; } #endif B get_body() { return body; } /*override*/ function_body_leaf* clone() { return new function_body_leaf< Input, Output, B >(init_body); } private: B body; B init_body; }; //! the leaf for function_body specialized for Input and output of continue_msg template class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > { public: function_body_leaf( const B &_body ) : body(_body), init_body(_body) { } continue_msg operator()( const continue_msg &i ) { body(i); return i; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void reset_body() { body = init_body; } #endif B get_body() { return body; } /*override*/ function_body_leaf* clone() { return new function_body_leaf< continue_msg, continue_msg, B >(init_body); } private: B body; B init_body; }; //! the leaf for function_body specialized for Output of continue_msg template class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > { public: function_body_leaf( const B &_body ) : body(_body), init_body(_body) { } continue_msg operator()(const Input &i) { body(i); return continue_msg(); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void reset_body() { body = init_body; } #endif B get_body() { return body; } /*override*/ function_body_leaf* clone() { return new function_body_leaf< Input, continue_msg, B >(init_body); } private: B body; B init_body; }; //! the leaf for function_body specialized for Input of continue_msg template class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > { public: function_body_leaf( const B &_body ) : body(_body), init_body(_body) { } Output operator()(const continue_msg &i) { return body(i); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void reset_body() { body = init_body; } #endif B get_body() { return body; } /*override*/ function_body_leaf* clone() { return new function_body_leaf< continue_msg, Output, B >(init_body); } private: B body; B init_body; }; //! function_body that takes an Input and a set of output ports template class multifunction_body : tbb::internal::no_assign { public: virtual ~multifunction_body () {} virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0; virtual multifunction_body* clone() = 0; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES virtual void reset_body() = 0; #endif }; //! leaf for multifunction. OutputSet can be a std::tuple or a vector. template class multifunction_body_leaf : public multifunction_body { public: multifunction_body_leaf(const B &_body) : body(_body), init_body(_body) { } void operator()(const Input &input, OutputSet &oset) { body(input, oset); // body may explicitly put() to one or more of oset. } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void reset_body() { body = init_body; } #endif B get_body() { return body; } /*override*/ multifunction_body_leaf* clone() { return new multifunction_body_leaf(init_body); } private: B body; B init_body; }; // --------------------------- end of function_body containers ------------------------ // --------------------------- node task bodies --------------------------------------- //! A task that calls a node's forward_task function template< typename NodeType > class forward_task_bypass : public task { NodeType &my_node; public: forward_task_bypass( NodeType &n ) : my_node(n) {} task *execute() { task * new_task = my_node.forward_task(); if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL; return new_task; } }; //! A task that calls a node's apply_body_bypass function, passing in an input of type Input // return the task* unless it is SUCCESSFULLY_ENQUEUED, in which case return NULL template< typename NodeType, typename Input > class apply_body_task_bypass : public task { NodeType &my_node; Input my_input; public: apply_body_task_bypass( NodeType &n, const Input &i ) : my_node(n), my_input(i) {} task *execute() { task * next_task = my_node.apply_body_bypass( my_input ); if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL; return next_task; } }; //! A task that calls a node's apply_body function with no input template< typename NodeType > class source_task_bypass : public task { NodeType &my_node; public: source_task_bypass( NodeType &n ) : my_node(n) {} task *execute() { task *new_task = my_node.apply_body_bypass( ); if(new_task == SUCCESSFULLY_ENQUEUED) return NULL; return new_task; } }; // ------------------------ end of node task bodies ----------------------------------- //! An empty functor that takes an Input and returns a default constructed Output template< typename Input, typename Output > struct empty_body { Output operator()( const Input & ) const { return Output(); } }; //! A node_cache maintains a std::queue of elements of type T. Each operation is protected by a lock. template< typename T, typename M=spin_mutex > class node_cache { public: typedef size_t size_type; bool empty() { typename my_mutex_type::scoped_lock lock( my_mutex ); return internal_empty(); } void add( T &n ) { typename my_mutex_type::scoped_lock lock( my_mutex ); internal_push(n); } void remove( T &n ) { typename my_mutex_type::scoped_lock lock( my_mutex ); for ( size_t i = internal_size(); i != 0; --i ) { T &s = internal_pop(); if ( &s == &n ) return; // only remove one predecessor per request internal_push(s); } } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; void internal_add_built_predecessor( T &n ) { typename my_mutex_type::scoped_lock lock( my_mutex ); my_built_predecessors.add_edge(n); } void internal_delete_built_predecessor( T &n ) { typename my_mutex_type::scoped_lock lock( my_mutex ); my_built_predecessors.delete_edge(n); } void copy_predecessors( predecessor_vector_type &v) { typename my_mutex_type::scoped_lock lock( my_mutex ); my_built_predecessors.copy_edges(v); } size_t predecessor_count() { typename my_mutex_type::scoped_lock lock(my_mutex); return (size_t)(my_built_predecessors.edge_count()); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: typedef M my_mutex_type; my_mutex_type my_mutex; std::queue< T * > my_q; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container my_built_predecessors; #endif // Assumes lock is held inline bool internal_empty( ) { return my_q.empty(); } // Assumes lock is held inline size_type internal_size( ) { return my_q.size(); } // Assumes lock is held inline void internal_push( T &n ) { my_q.push(&n); } // Assumes lock is held inline T &internal_pop() { T *v = my_q.front(); my_q.pop(); return *v; } }; //! A cache of predecessors that only supports try_get template< typename T, typename M=spin_mutex > class predecessor_cache : public node_cache< sender, M > { public: typedef M my_mutex_type; typedef T output_type; typedef sender predecessor_type; typedef receiver successor_type; predecessor_cache( ) : my_owner( NULL ) { } void set_owner( successor_type *owner ) { my_owner = owner; } bool get_item( output_type &v ) { bool msg = false; do { predecessor_type *src; { typename my_mutex_type::scoped_lock lock(this->my_mutex); if ( this->internal_empty() ) { break; } src = &this->internal_pop(); } // Try to get from this sender msg = src->try_get( v ); if (msg == false) { // Relinquish ownership of the edge if ( my_owner) src->register_successor( *my_owner ); } else { // Retain ownership of the edge this->add(*src); } } while ( msg == false ); return msg; } void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { if(my_owner) { for(;;) { predecessor_type *src; { if(this->internal_empty()) break; src = &this->internal_pop(); } src->register_successor( *my_owner); } } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES if (f&rf_extract && my_owner) my_built_predecessors.receiver_extract(*my_owner); __TBB_ASSERT(!(f&rf_extract) || this->internal_empty(), "predecessor cache not empty"); #endif } protected: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES using node_cache< sender, M >::my_built_predecessors; #endif successor_type *my_owner; }; //! An cache of predecessors that supports requests and reservations template< typename T, typename M=spin_mutex > class reservable_predecessor_cache : public predecessor_cache< T, M > { public: typedef M my_mutex_type; typedef T output_type; typedef sender predecessor_type; typedef receiver successor_type; reservable_predecessor_cache( ) : reserved_src(NULL) { } bool try_reserve( output_type &v ) { bool msg = false; do { { typename my_mutex_type::scoped_lock lock(this->my_mutex); if ( reserved_src || this->internal_empty() ) return false; reserved_src = &this->internal_pop(); } // Try to get from this sender msg = reserved_src->try_reserve( v ); if (msg == false) { typename my_mutex_type::scoped_lock lock(this->my_mutex); // Relinquish ownership of the edge reserved_src->register_successor( *this->my_owner ); reserved_src = NULL; } else { // Retain ownership of the edge this->add( *reserved_src ); } } while ( msg == false ); return msg; } bool try_release( ) { reserved_src->try_release( ); reserved_src = NULL; return true; } bool try_consume( ) { reserved_src->try_consume( ); reserved_src = NULL; return true; } void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { reserved_src = NULL; predecessor_cache::reset(__TBB_PFG_RESET_ARG(f)); } private: predecessor_type *reserved_src; }; //! An abstract cache of successors template class successor_cache : tbb::internal::no_copy { protected: typedef M my_mutex_type; my_mutex_type my_mutex; typedef receiver *pointer_type; typedef std::list< pointer_type > my_successors_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container > my_built_successors; #endif my_successors_type my_successors; sender *my_owner; public: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector successor_vector_type; void internal_add_built_successor( receiver &r) { typename my_mutex_type::scoped_lock l(my_mutex, true); my_built_successors.add_edge( r ); } void internal_delete_built_successor( receiver &r) { typename my_mutex_type::scoped_lock l(my_mutex, true); my_built_successors.delete_edge(r); } void copy_successors( successor_vector_type &v) { typename my_mutex_type::scoped_lock l(my_mutex, false); my_built_successors.copy_edges(v); } size_t successor_count() { typename my_mutex_type::scoped_lock l(my_mutex,false); return my_built_successors.edge_count(); } void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { if (f&rf_extract && my_owner) my_built_successors.sender_extract(*my_owner); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ successor_cache( ) : my_owner(NULL) {} void set_owner( sender *owner ) { my_owner = owner; } virtual ~successor_cache() {} void register_successor( receiver &r ) { typename my_mutex_type::scoped_lock l(my_mutex, true); my_successors.push_back( &r ); } void remove_successor( receiver &r ) { typename my_mutex_type::scoped_lock l(my_mutex, true); for ( typename my_successors_type::iterator i = my_successors.begin(); i != my_successors.end(); ++i ) { if ( *i == & r ) { my_successors.erase(i); break; } } } bool empty() { typename my_mutex_type::scoped_lock l(my_mutex, false); return my_successors.empty(); } void clear() { my_successors.clear(); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_built_successors.clear(); #endif } virtual task * try_put_task( const T &t ) = 0; }; //! An abstract cache of successors, specialized to continue_msg template<> class successor_cache< continue_msg > : tbb::internal::no_copy { protected: typedef spin_rw_mutex my_mutex_type; my_mutex_type my_mutex; typedef receiver *pointer_type; typedef std::list< pointer_type > my_successors_type; my_successors_type my_successors; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container > my_built_successors; #endif sender *my_owner; public: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector successor_vector_type; void internal_add_built_successor( receiver &r) { my_mutex_type::scoped_lock l(my_mutex, true); my_built_successors.add_edge( r ); } void internal_delete_built_successor( receiver &r) { my_mutex_type::scoped_lock l(my_mutex, true); my_built_successors.delete_edge(r); } void copy_successors( successor_vector_type &v) { my_mutex_type::scoped_lock l(my_mutex, false); my_built_successors.copy_edges(v); } size_t successor_count() { my_mutex_type::scoped_lock l(my_mutex,false); return my_built_successors.edge_count(); } void reset( __TBB_PFG_RESET_ARG(reset_flags f)) { if (f&rf_extract && my_owner) my_built_successors.sender_extract(*my_owner); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ successor_cache( ) : my_owner(NULL) {} void set_owner( sender *owner ) { my_owner = owner; } virtual ~successor_cache() {} void register_successor( receiver &r ) { my_mutex_type::scoped_lock l(my_mutex, true); my_successors.push_back( &r ); if ( my_owner && r.is_continue_receiver() ) { r.register_predecessor( *my_owner ); } } void remove_successor( receiver &r ) { my_mutex_type::scoped_lock l(my_mutex, true); for ( my_successors_type::iterator i = my_successors.begin(); i != my_successors.end(); ++i ) { if ( *i == & r ) { // TODO: Check if we need to test for continue_receiver before // removing from r. if ( my_owner ) r.remove_predecessor( *my_owner ); my_successors.erase(i); break; } } } bool empty() { my_mutex_type::scoped_lock l(my_mutex, false); return my_successors.empty(); } void clear() { my_successors.clear(); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_built_successors.clear(); #endif } virtual task * try_put_task( const continue_msg &t ) = 0; }; //! A cache of successors that are broadcast to template class broadcast_cache : public successor_cache { typedef M my_mutex_type; typedef std::list< receiver * > my_successors_type; public: broadcast_cache( ) {} // as above, but call try_put_task instead, and return the last task we received (if any) /*override*/ task * try_put_task( const T &t ) { task * last_task = NULL; bool upgraded = true; typename my_mutex_type::scoped_lock l(this->my_mutex, upgraded); typename my_successors_type::iterator i = this->my_successors.begin(); while ( i != this->my_successors.end() ) { task *new_task = (*i)->try_put_task(t); last_task = combine_tasks(last_task, new_task); // enqueue if necessary if(new_task) { ++i; } else { // failed if ( (*i)->register_predecessor(*this->my_owner) ) { if (!upgraded) { l.upgrade_to_writer(); upgraded = true; } i = this->my_successors.erase(i); } else { ++i; } } } return last_task; } }; //! A cache of successors that are put in a round-robin fashion template class round_robin_cache : public successor_cache { typedef size_t size_type; typedef M my_mutex_type; typedef std::list< receiver * > my_successors_type; public: round_robin_cache( ) {} size_type size() { typename my_mutex_type::scoped_lock l(this->my_mutex, false); return this->my_successors.size(); } /*override*/task *try_put_task( const T &t ) { bool upgraded = true; typename my_mutex_type::scoped_lock l(this->my_mutex, upgraded); typename my_successors_type::iterator i = this->my_successors.begin(); while ( i != this->my_successors.end() ) { task *new_task = (*i)->try_put_task(t); if ( new_task ) { return new_task; } else { if ( (*i)->register_predecessor(*this->my_owner) ) { if (!upgraded) { l.upgrade_to_writer(); upgraded = true; } i = this->my_successors.erase(i); } else { ++i; } } } return NULL; } }; template class decrementer : public continue_receiver, tbb::internal::no_copy { T *my_node; task *execute() { return my_node->decrement_counter(); } public: typedef continue_msg input_type; typedef continue_msg output_type; decrementer( int number_of_predecessors = 0 ) : continue_receiver( number_of_predecessors ) { } void set_owner( T *node ) { my_node = node; } }; } #endif // __TBB__flow_graph_impl_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_indexer_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__flow_graph_indexer_impl_H #define __TBB__flow_graph_indexer_impl_H #ifndef __TBB_flow_graph_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #include "tbb/internal/_flow_graph_types_impl.h" namespace internal { // Output of the indexer_node is a tbb::flow::tagged_msg, and will be of // the form tagged_msg // where the value of tag will indicate which result was put to the // successor. template task* do_try_put(const T &v, void *p) { typename IndexerNodeBaseType::output_type o(K, v); return reinterpret_cast(p)->try_put_task(&o); } template struct indexer_helper { template static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) { typedef typename tuple_element::type T; task *(*indexer_node_put_task)(const T&, void *) = do_try_put; tbb::flow::get(my_input).set_up(p, indexer_node_put_task); indexer_helper::template set_indexer_node_pointer(my_input, p); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES template static inline void reset_inputs(InputTuple &my_input, reset_flags f) { join_helper::reset_inputs(my_input, f); tbb::flow::get(my_input).reset_receiver(f); } #endif }; template struct indexer_helper { template static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) { typedef typename tuple_element<0, TupleTypes>::type T; task *(*indexer_node_put_task)(const T&, void *) = do_try_put; tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES template static inline void reset_inputs(InputTuple &my_input, reset_flags f) { tbb::flow::get<0>(my_input).reset_receiver(f); } #endif }; template class indexer_input_port : public receiver { private: void* my_indexer_ptr; typedef task* (* forward_function_ptr)(T const &, void* ); forward_function_ptr my_try_put_task; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES spin_mutex my_pred_mutex; edge_container > my_built_predecessors; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ public: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES indexer_input_port() : my_pred_mutex() {} indexer_input_port( const indexer_input_port & /*other*/ ) : receiver(), my_pred_mutex() { } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ void set_up(void *p, forward_function_ptr f) { my_indexer_ptr = p; my_try_put_task = f; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector *> predecessor_vector_type; /*override*/size_t predecessor_count() { spin_mutex::scoped_lock l(my_pred_mutex); return my_built_predecessors.edge_count(); } /*override*/void internal_add_built_predecessor(sender &p) { spin_mutex::scoped_lock l(my_pred_mutex); my_built_predecessors.add_edge(p); } /*override*/void internal_delete_built_predecessor(sender &p) { spin_mutex::scoped_lock l(my_pred_mutex); my_built_predecessors.delete_edge(p); } /*override*/void copy_predecessors( predecessor_vector_type &v) { spin_mutex::scoped_lock l(my_pred_mutex); return my_built_predecessors.copy_edges(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; task *try_put_task(const T &v) { return my_try_put_task(v, my_indexer_ptr); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES public: /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) { if(f&rf_extract) my_built_predecessors.receiver_extract(*this); } #else /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { } #endif }; template class indexer_node_FE { public: static const int N = tbb::flow::tuple_size::value; typedef OutputType output_type; typedef InputTuple input_type; input_type &input_ports() { return my_inputs; } protected: input_type my_inputs; }; //! indexer_node_base template class indexer_node_base : public graph_node, public indexer_node_FE, public sender { protected: using graph_node::my_graph; public: static const size_t N = tbb::flow::tuple_size::value; typedef OutputType output_type; typedef StructTypes tuple_types; typedef receiver successor_type; typedef indexer_node_FE input_ports_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector successor_vector_type; #endif private: // ----------- Aggregator ------------ enum op_type { reg_succ, rem_succ, try__put_task #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , add_blt_succ, del_blt_succ, blt_succ_cnt, blt_succ_cpy #endif }; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; typedef indexer_node_base my_class; class indexer_node_base_operation : public aggregated_operation { public: char type; union { output_type const *my_arg; successor_type *my_succ; task *bypass_t; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES size_t cnt_val; successor_vector_type *succv; #endif }; indexer_node_base_operation(const output_type* e, op_type t) : type(char(t)), my_arg(e) {} indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)), my_succ(const_cast(&s)) {} indexer_node_base_operation(op_type t) : type(char(t)) {} }; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; aggregator my_aggregator; void handle_operations(indexer_node_base_operation* op_list) { indexer_node_base_operation *current; while(op_list) { current = op_list; op_list = op_list->next; switch(current->type) { case reg_succ: my_successors.register_successor(*(current->my_succ)); __TBB_store_with_release(current->status, SUCCEEDED); break; case rem_succ: my_successors.remove_successor(*(current->my_succ)); __TBB_store_with_release(current->status, SUCCEEDED); break; case try__put_task: { current->bypass_t = my_successors.try_put_task(*(current->my_arg)); __TBB_store_with_release(current->status, SUCCEEDED); // return of try_put_task actual return value } break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES case add_blt_succ: my_successors.internal_add_built_successor(*(current->my_succ)); __TBB_store_with_release(current->status, SUCCEEDED); break; case del_blt_succ: my_successors.internal_delete_built_successor(*(current->my_succ)); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_succ_cnt: current->cnt_val = my_successors.successor_count(); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_succ_cpy: my_successors.copy_successors(*(current->succv)); __TBB_store_with_release(current->status, SUCCEEDED); break; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ } } } // ---------- end aggregator ----------- public: indexer_node_base(graph& g) : graph_node(g), input_ports_type() { indexer_helper::set_indexer_node_pointer(this->my_inputs, this); my_successors.set_owner(this); my_aggregator.initialize_handler(my_handler(this)); } indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender() { indexer_helper::set_indexer_node_pointer(this->my_inputs, this); my_successors.set_owner(this); my_aggregator.initialize_handler(my_handler(this)); } bool register_successor(successor_type &r) { indexer_node_base_operation op_data(r, reg_succ); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } bool remove_successor( successor_type &r) { indexer_node_base_operation op_data(r, rem_succ); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } task * try_put_task(output_type const *v) { indexer_node_base_operation op_data(v, try__put_task); my_aggregator.execute(&op_data); return op_data.bypass_t; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES void internal_add_built_successor( successor_type &r) { indexer_node_base_operation op_data(r, add_blt_succ); my_aggregator.execute(&op_data); } void internal_delete_built_successor( successor_type &r) { indexer_node_base_operation op_data(r, del_blt_succ); my_aggregator.execute(&op_data); } size_t successor_count() { indexer_node_base_operation op_data(blt_succ_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } void copy_successors( successor_vector_type &v) { indexer_node_base_operation op_data(blt_succ_cpy); op_data.succv = &v; my_aggregator.execute(&op_data); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_successors.reset(f); indexer_helper::reset_inputs(this->my_inputs, f); #endif } private: broadcast_cache my_successors; }; //indexer_node_base template struct input_types; template struct input_types<1, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename internal::tagged_msg type; }; template struct input_types<2, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename internal::tagged_msg type; }; template struct input_types<3, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename internal::tagged_msg type; }; template struct input_types<4, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename tuple_element<3, InputTuple>::type fourth_type; typedef typename internal::tagged_msg type; }; template struct input_types<5, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename tuple_element<3, InputTuple>::type fourth_type; typedef typename tuple_element<4, InputTuple>::type fifth_type; typedef typename internal::tagged_msg type; }; template struct input_types<6, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename tuple_element<3, InputTuple>::type fourth_type; typedef typename tuple_element<4, InputTuple>::type fifth_type; typedef typename tuple_element<5, InputTuple>::type sixth_type; typedef typename internal::tagged_msg type; }; template struct input_types<7, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename tuple_element<3, InputTuple>::type fourth_type; typedef typename tuple_element<4, InputTuple>::type fifth_type; typedef typename tuple_element<5, InputTuple>::type sixth_type; typedef typename tuple_element<6, InputTuple>::type seventh_type; typedef typename internal::tagged_msg type; }; template struct input_types<8, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename tuple_element<3, InputTuple>::type fourth_type; typedef typename tuple_element<4, InputTuple>::type fifth_type; typedef typename tuple_element<5, InputTuple>::type sixth_type; typedef typename tuple_element<6, InputTuple>::type seventh_type; typedef typename tuple_element<7, InputTuple>::type eighth_type; typedef typename internal::tagged_msg type; }; template struct input_types<9, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename tuple_element<3, InputTuple>::type fourth_type; typedef typename tuple_element<4, InputTuple>::type fifth_type; typedef typename tuple_element<5, InputTuple>::type sixth_type; typedef typename tuple_element<6, InputTuple>::type seventh_type; typedef typename tuple_element<7, InputTuple>::type eighth_type; typedef typename tuple_element<8, InputTuple>::type nineth_type; typedef typename internal::tagged_msg type; }; template struct input_types<10, InputTuple> { typedef typename tuple_element<0, InputTuple>::type first_type; typedef typename tuple_element<1, InputTuple>::type second_type; typedef typename tuple_element<2, InputTuple>::type third_type; typedef typename tuple_element<3, InputTuple>::type fourth_type; typedef typename tuple_element<4, InputTuple>::type fifth_type; typedef typename tuple_element<5, InputTuple>::type sixth_type; typedef typename tuple_element<6, InputTuple>::type seventh_type; typedef typename tuple_element<7, InputTuple>::type eighth_type; typedef typename tuple_element<8, InputTuple>::type nineth_type; typedef typename tuple_element<9, InputTuple>::type tenth_type; typedef typename internal::tagged_msg type; }; // type generators template struct indexer_types : public input_types::value, OutputTuple> { static const int N = tbb::flow::tuple_size::value; typedef typename input_types::type output_type; typedef typename wrap_tuple_elements::type input_ports_type; typedef internal::indexer_node_FE indexer_FE_type; typedef internal::indexer_node_base indexer_base_type; }; template class unfolded_indexer_node : public indexer_types::indexer_base_type { public: typedef typename indexer_types::input_ports_type input_ports_type; typedef OutputTuple tuple_types; typedef typename indexer_types::output_type output_type; private: typedef typename indexer_types::indexer_base_type base_type; public: unfolded_indexer_node(graph& g) : base_type(g) {} unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {} }; } /* namespace internal */ #endif /* __TBB__flow_graph_indexer_impl_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_item_buffer_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__flow_graph_item_buffer_impl_H #define __TBB__flow_graph_item_buffer_impl_H #ifndef __TBB_flow_graph_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #include "tbb/internal/_flow_graph_types_impl.h" // for aligned_pair // in namespace tbb::flow::interface7 (included in _flow_graph_node_impl.h) //! Expandable buffer of items. The possible operations are push, pop, //* tests for empty and so forth. No mutual exclusion is built in. //* objects are constructed into and explicitly-destroyed. get_my_item gives // a read-only reference to the item in the buffer. set_my_item may be called // with either an empty or occupied slot. using internal::aligned_pair; using internal::alignment_of; namespace internal { template > class item_buffer { public: typedef T item_type; enum buffer_item_state { no_item=0, has_item=1, reserved_item=2 }; protected: typedef size_t size_type; typedef typename aligned_pair::type buffer_item_type; typedef typename A::template rebind::other allocator_type; buffer_item_type *my_array; size_type my_array_size; static const size_type initial_buffer_size = 4; size_type my_head; size_type my_tail; bool buffer_empty() { return my_head == my_tail; } buffer_item_type &item(size_type i) { __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of::value),NULL); __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].first))%alignment_of::value), NULL); return my_array[i & (my_array_size - 1) ]; } bool my_item_valid(size_type i) { return item(i).second != no_item; } bool my_item_reserved(size_type i) { return item(i).second == reserved_item; } // object management in buffer const item_type &get_my_item(size_t i) { __TBB_ASSERT(my_item_valid(i),"attempt to get invalid item"); item_type *itm = (tbb::internal::punned_cast(&(item(i).first))); return *(const item_type *)itm; } // may be called with an empty slot or a slot that has already been constructed into. void set_my_item(size_t i, const item_type &o) { if(item(i).second != no_item) { destroy_item(i); } new(&(item(i).first)) item_type(o); item(i).second = has_item; } // destructively-fetch an object from the buffer void fetch_item(size_t i, item_type &o) { __TBB_ASSERT(my_item_valid(i), "Trying to fetch an empty slot"); o = get_my_item(i); // could have std::move assign semantics destroy_item(i); } // move an existing item from one slot to another. The moved-to slot must be unoccupied, // the moved-from slot must exist and not be reserved. The after, from will be empty, // to will be occupied but not reserved void move_item(size_t to, size_t from) { __TBB_ASSERT(!my_item_valid(to), "Trying to move to a non-empty slot"); __TBB_ASSERT(my_item_valid(from), "Trying to move from an empty slot"); set_my_item(to, get_my_item(from)); // could have std::move semantics destroy_item(from); } // put an item in an empty slot. Return true if successful, else false bool place_item(size_t here, const item_type &me) { #if !TBB_DEPRECATED_SEQUENCER_DUPLICATES if(my_item_valid(here)) return false; #endif set_my_item(here, me); return true; } // could be implemented with std::move semantics void swap_items(size_t i, size_t j) { __TBB_ASSERT(my_item_valid(i) && my_item_valid(j), "attempt to swap invalid item(s)"); item_type temp = get_my_item(i); set_my_item(i, get_my_item(j)); set_my_item(j, temp); } void destroy_item(size_type i) { __TBB_ASSERT(my_item_valid(i), "destruction of invalid item"); (tbb::internal::punned_cast(&(item(i).first)))->~item_type(); item(i).second = no_item; } // returns a copy of the front void copy_front(item_type &v) { __TBB_ASSERT(my_item_valid(my_head), "attempt to fetch head non-item"); v = get_my_item(my_head); } // returns a copy of the back void copy_back(item_type &v) { __TBB_ASSERT(my_item_valid(my_tail-1), "attempt to fetch head non-item"); v = get_my_item(my_tail-1); } // following methods are for reservation of the front of a bufffer. void reserve_item(size_type i) { __TBB_ASSERT(my_item_valid(i) && !my_item_reserved(i), "item cannot be reserved"); item(i).second = reserved_item; } void release_item(size_type i) { __TBB_ASSERT(my_item_reserved(i), "item is not reserved"); item(i).second = has_item; } void destroy_front() { destroy_item(my_head); ++my_head; } void destroy_back() { destroy_item(my_tail-1); --my_tail; } // we have to be able to test against a new tail value without changing my_tail // grow_array doesn't work if we change my_tail when the old array is too small size_type size(size_t new_tail = 0) { return (new_tail ? new_tail : my_tail) - my_head; } size_type capacity() { return my_array_size; } // sequencer_node does not use this method, so we don't // need a version that passes in the new_tail value. bool buffer_full() { return size() >= capacity(); } //! Grows the internal array. void grow_my_array( size_t minimum_size ) { // test that we haven't made the structure inconsistent. __TBB_ASSERT(capacity() >= my_tail - my_head, "total items exceed capacity"); size_type new_size = my_array_size ? 2*my_array_size : initial_buffer_size; while( new_size > class reservable_item_buffer : public item_buffer { protected: using item_buffer::my_item_valid; using item_buffer::my_head; public: reservable_item_buffer() : item_buffer(), my_reserved(false) {} void reset() {my_reserved = false; item_buffer::reset(); } protected: bool reserve_front(T &v) { if(my_reserved || !my_item_valid(my_head)) return false; my_reserved = true; // reserving the head this->copy_front(v); this->reserve_item(this->my_head); return true; } void consume_front() { __TBB_ASSERT(my_reserved, "Attempt to consume a non-reserved item"); this->destroy_front(); my_reserved = false; } void release_front() { __TBB_ASSERT(my_reserved, "Attempt to release a non-reserved item"); this->release_item(this->my_head); my_reserved = false; } bool my_reserved; }; } // namespace internal #endif // __TBB__flow_graph_item_buffer_impl_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_join_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__flow_graph_join_impl_H #define __TBB__flow_graph_join_impl_H #ifndef __TBB_flow_graph_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #include "_flow_graph_types_impl.h" namespace internal { typedef size_t tag_value; static const tag_value NO_TAG = tag_value(-1); struct forwarding_base { forwarding_base(graph &g) : my_graph_ptr(&g), current_tag(NO_TAG) {} virtual ~forwarding_base() {} // decrement_port_count may create a forwarding task. If we cannot handle the task // ourselves, ask decrement_port_count to deal with it. virtual task * decrement_port_count(bool handle_task) = 0; virtual void increment_port_count() = 0; virtual task * increment_tag_count(tag_value /*t*/, bool /*handle_task*/) {return NULL;} // moved here so input ports can queue tasks graph* my_graph_ptr; tag_value current_tag; // so ports can refer to FE's desired items }; template< int N > struct join_helper { template< typename TupleType, typename PortType > static inline void set_join_node_pointer(TupleType &my_input, PortType *port) { tbb::flow::get( my_input ).set_join_node_pointer(port); join_helper::set_join_node_pointer( my_input, port ); } template< typename TupleType > static inline void consume_reservations( TupleType &my_input ) { tbb::flow::get( my_input ).consume(); join_helper::consume_reservations( my_input ); } template< typename TupleType > static inline void release_my_reservation( TupleType &my_input ) { tbb::flow::get( my_input ).release(); } template static inline void release_reservations( TupleType &my_input) { join_helper::release_reservations(my_input); release_my_reservation(my_input); } template< typename InputTuple, typename OutputTuple > static inline bool reserve( InputTuple &my_input, OutputTuple &out) { if ( !tbb::flow::get( my_input ).reserve( tbb::flow::get( out ) ) ) return false; if ( !join_helper::reserve( my_input, out ) ) { release_my_reservation( my_input ); return false; } return true; } template static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) { bool res = tbb::flow::get(my_input).get_item(tbb::flow::get(out) ); // may fail return join_helper::get_my_item(my_input, out) && res; // do get on other inputs before returning } template static inline bool get_items(InputTuple &my_input, OutputTuple &out) { return get_my_item(my_input, out); } template static inline void reset_my_port(InputTuple &my_input) { join_helper::reset_my_port(my_input); tbb::flow::get(my_input).reset_port(); } template static inline void reset_ports(InputTuple& my_input) { reset_my_port(my_input); } template static inline void set_tag_func(InputTuple &my_input, TagFuncTuple &my_tag_funcs) { tbb::flow::get(my_input).set_my_original_tag_func(tbb::flow::get(my_tag_funcs)); tbb::flow::get(my_input).set_my_tag_func(tbb::flow::get(my_input).my_original_func()->clone()); tbb::flow::get(my_tag_funcs) = NULL; join_helper::set_tag_func(my_input, my_tag_funcs); } template< typename TagFuncTuple1, typename TagFuncTuple2> static inline void copy_tag_functors(TagFuncTuple1 &my_inputs, TagFuncTuple2 &other_inputs) { if(tbb::flow::get(other_inputs).my_original_func()) { tbb::flow::get(my_inputs).set_my_tag_func(tbb::flow::get(other_inputs).my_original_func()->clone()); tbb::flow::get(my_inputs).set_my_original_tag_func(tbb::flow::get(other_inputs).my_original_func()->clone()); } join_helper::copy_tag_functors(my_inputs, other_inputs); } template static inline void reset_inputs(InputTuple &my_input __TBB_PFG_RESET_ARG(__TBB_COMMA reset_flags f)) { join_helper::reset_inputs(my_input __TBB_PFG_RESET_ARG(__TBB_COMMA f)); tbb::flow::get(my_input).reset_receiver(__TBB_PFG_RESET_ARG(f)); } }; template< > struct join_helper<1> { template< typename TupleType, typename PortType > static inline void set_join_node_pointer(TupleType &my_input, PortType *port) { tbb::flow::get<0>( my_input ).set_join_node_pointer(port); } template< typename TupleType > static inline void consume_reservations( TupleType &my_input ) { tbb::flow::get<0>( my_input ).consume(); } template< typename TupleType > static inline void release_my_reservation( TupleType &my_input ) { tbb::flow::get<0>( my_input ).release(); } template static inline void release_reservations( TupleType &my_input) { release_my_reservation(my_input); } template< typename InputTuple, typename OutputTuple > static inline bool reserve( InputTuple &my_input, OutputTuple &out) { return tbb::flow::get<0>( my_input ).reserve( tbb::flow::get<0>( out ) ); } template static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) { return tbb::flow::get<0>(my_input).get_item(tbb::flow::get<0>(out)); } template static inline bool get_items(InputTuple &my_input, OutputTuple &out) { return get_my_item(my_input, out); } template static inline void reset_my_port(InputTuple &my_input) { tbb::flow::get<0>(my_input).reset_port(); } template static inline void reset_ports(InputTuple& my_input) { reset_my_port(my_input); } template static inline void set_tag_func(InputTuple &my_input, TagFuncTuple &my_tag_funcs) { tbb::flow::get<0>(my_input).set_my_original_tag_func(tbb::flow::get<0>(my_tag_funcs)); tbb::flow::get<0>(my_input).set_my_tag_func(tbb::flow::get<0>(my_input).my_original_func()->clone()); tbb::flow::get<0>(my_tag_funcs) = NULL; } template< typename TagFuncTuple1, typename TagFuncTuple2> static inline void copy_tag_functors(TagFuncTuple1 &my_inputs, TagFuncTuple2 &other_inputs) { if(tbb::flow::get<0>(other_inputs).my_original_func()) { tbb::flow::get<0>(my_inputs).set_my_tag_func(tbb::flow::get<0>(other_inputs).my_original_func()->clone()); tbb::flow::get<0>(my_inputs).set_my_original_tag_func(tbb::flow::get<0>(other_inputs).my_original_func()->clone()); } } template static inline void reset_inputs(InputTuple &my_input __TBB_PFG_RESET_ARG(__TBB_COMMA reset_flags f)) { tbb::flow::get<0>(my_input).reset_receiver(__TBB_PFG_RESET_ARG(f)); } }; //! The two-phase join port template< typename T > class reserving_port : public receiver { public: typedef T input_type; typedef sender predecessor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; #endif private: // ----------- Aggregator ------------ enum op_type { reg_pred, rem_pred, res_item, rel_res, con_res #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy #endif }; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; typedef reserving_port my_class; class reserving_port_operation : public aggregated_operation { public: char type; union { T *my_arg; predecessor_type *my_pred; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES size_t cnt_val; predecessor_vector_type *pvec; #endif }; reserving_port_operation(const T& e, op_type t) : type(char(t)), my_arg(const_cast(&e)) {} reserving_port_operation(const predecessor_type &s, op_type t) : type(char(t)), my_pred(const_cast(&s)) {} reserving_port_operation(op_type t) : type(char(t)) {} }; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; aggregator my_aggregator; void handle_operations(reserving_port_operation* op_list) { reserving_port_operation *current; bool no_predecessors; while(op_list) { current = op_list; op_list = op_list->next; switch(current->type) { case reg_pred: no_predecessors = my_predecessors.empty(); my_predecessors.add(*(current->my_pred)); if ( no_predecessors ) { (void) my_join->decrement_port_count(true); // may try to forward } __TBB_store_with_release(current->status, SUCCEEDED); break; case rem_pred: my_predecessors.remove(*(current->my_pred)); if(my_predecessors.empty()) my_join->increment_port_count(); __TBB_store_with_release(current->status, SUCCEEDED); break; case res_item: if ( reserved ) { __TBB_store_with_release(current->status, FAILED); } else if ( my_predecessors.try_reserve( *(current->my_arg) ) ) { reserved = true; __TBB_store_with_release(current->status, SUCCEEDED); } else { if ( my_predecessors.empty() ) { my_join->increment_port_count(); } __TBB_store_with_release(current->status, FAILED); } break; case rel_res: reserved = false; my_predecessors.try_release( ); __TBB_store_with_release(current->status, SUCCEEDED); break; case con_res: reserved = false; my_predecessors.try_consume( ); __TBB_store_with_release(current->status, SUCCEEDED); break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES case add_blt_pred: my_predecessors.internal_add_built_predecessor(*(current->my_pred)); __TBB_store_with_release(current->status, SUCCEEDED); break; case del_blt_pred: my_predecessors.internal_delete_built_predecessor(*(current->my_pred)); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_pred_cnt: current->cnt_val = my_predecessors.predecessor_count(); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_pred_cpy: my_predecessors.copy_predecessors(*(current->pvec)); __TBB_store_with_release(current->status, SUCCEEDED); break; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ } } } protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; task *try_put_task( const T & ) { return NULL; } public: //! Constructor reserving_port() : reserved(false) { my_join = NULL; my_predecessors.set_owner( this ); my_aggregator.initialize_handler(my_handler(this)); } // copy constructor reserving_port(const reserving_port& /* other */) : receiver() { reserved = false; my_join = NULL; my_predecessors.set_owner( this ); my_aggregator.initialize_handler(my_handler(this)); } void set_join_node_pointer(forwarding_base *join) { my_join = join; } //! Add a predecessor bool register_predecessor( sender &src ) { reserving_port_operation op_data(src, reg_pred); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } //! Remove a predecessor bool remove_predecessor( sender &src ) { reserving_port_operation op_data(src, rem_pred); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } //! Reserve an item from the port bool reserve( T &v ) { reserving_port_operation op_data(v, res_item); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } //! Release the port void release( ) { reserving_port_operation op_data(rel_res); my_aggregator.execute(&op_data); } //! Complete use of the port void consume( ) { reserving_port_operation op_data(con_res); my_aggregator.execute(&op_data); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void internal_add_built_predecessor(predecessor_type &src) { reserving_port_operation op_data(src, add_blt_pred); my_aggregator.execute(&op_data); } /*override*/void internal_delete_built_predecessor(predecessor_type &src) { reserving_port_operation op_data(src, del_blt_pred); my_aggregator.execute(&op_data); } /*override*/size_t predecessor_count() { reserving_port_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } /*override*/void copy_predecessors(predecessor_vector_type &v) { reserving_port_operation op_data(blt_pred_cpy); op_data.pvec = &v; my_aggregator.execute(&op_data); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f)) { my_predecessors.reset(__TBB_PFG_RESET_ARG(f)); reserved = false; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES __TBB_ASSERT(!(f&rf_extract) || my_predecessors.empty(), "port edges not removed"); #endif } private: forwarding_base *my_join; reservable_predecessor_cache< T, null_mutex > my_predecessors; bool reserved; }; //! queueing join_port template class queueing_port : public receiver, public item_buffer { public: typedef T input_type; typedef sender predecessor_type; typedef queueing_port my_node_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; #endif // ----------- Aggregator ------------ private: enum op_type { get__item, res_port, try__put_task #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy #endif }; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; typedef queueing_port my_class; class queueing_port_operation : public aggregated_operation { public: char type; T my_val; T *my_arg; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES sender *pred; size_t cnt_val; predecessor_vector_type *pvec; #endif task * bypass_t; // constructor for value parameter queueing_port_operation(const T& e, op_type t) : type(char(t)), my_val(e) , bypass_t(NULL) {} // constructor for pointer parameter queueing_port_operation(const T* p, op_type t) : type(char(t)), my_arg(const_cast(p)) , bypass_t(NULL) {} // constructor with no parameter queueing_port_operation(op_type t) : type(char(t)) , bypass_t(NULL) {} }; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; aggregator my_aggregator; void handle_operations(queueing_port_operation* op_list) { queueing_port_operation *current; bool was_empty; while(op_list) { current = op_list; op_list = op_list->next; switch(current->type) { case try__put_task: { task *rtask = NULL; was_empty = this->buffer_empty(); this->push_back(current->my_val); if (was_empty) rtask = my_join->decrement_port_count(false); else rtask = SUCCESSFULLY_ENQUEUED; current->bypass_t = rtask; __TBB_store_with_release(current->status, SUCCEEDED); } break; case get__item: if(!this->buffer_empty()) { this->copy_front(*(current->my_arg)); __TBB_store_with_release(current->status, SUCCEEDED); } else { __TBB_store_with_release(current->status, FAILED); } break; case res_port: __TBB_ASSERT(this->my_item_valid(this->my_head), "No item to reset"); this->destroy_front(); if(this->my_item_valid(this->my_head)) { (void)my_join->decrement_port_count(true); } __TBB_store_with_release(current->status, SUCCEEDED); break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES case add_blt_pred: my_built_predecessors.add_edge(*(current->pred)); __TBB_store_with_release(current->status, SUCCEEDED); break; case del_blt_pred: my_built_predecessors.delete_edge(*(current->pred)); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_pred_cnt: current->cnt_val = my_built_predecessors.edge_count(); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_pred_cpy: my_built_predecessors.copy_edges(*(current->pvec)); __TBB_store_with_release(current->status, SUCCEEDED); break; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ } } } // ------------ End Aggregator --------------- protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; /*override*/task *try_put_task(const T &v) { queueing_port_operation op_data(v, try__put_task); my_aggregator.execute(&op_data); __TBB_ASSERT(op_data.status == SUCCEEDED || !op_data.bypass_t, "inconsistent return from aggregator"); if(!op_data.bypass_t) return SUCCESSFULLY_ENQUEUED; return op_data.bypass_t; } public: //! Constructor queueing_port() : item_buffer() { my_join = NULL; my_aggregator.initialize_handler(my_handler(this)); } //! copy constructor queueing_port(const queueing_port& /* other */) : receiver(), item_buffer() { my_join = NULL; my_aggregator.initialize_handler(my_handler(this)); } //! record parent for tallying available items void set_join_node_pointer(forwarding_base *join) { my_join = join; } bool get_item( T &v ) { queueing_port_operation op_data(&v, get__item); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } // reset_port is called when item is accepted by successor, but // is initiated by join_node. void reset_port() { queueing_port_operation op_data(res_port); my_aggregator.execute(&op_data); return; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void internal_add_built_predecessor(sender &p) { queueing_port_operation op_data(add_blt_pred); op_data.pred = &p; my_aggregator.execute(&op_data); } /*override*/void internal_delete_built_predecessor(sender &p) { queueing_port_operation op_data(del_blt_pred); op_data.pred = &p; my_aggregator.execute(&op_data); } /*override*/size_t predecessor_count() { queueing_port_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } /*override*/void copy_predecessors(predecessor_vector_type &v) { queueing_port_operation op_data(blt_pred_cpy); op_data.pvec = &v; my_aggregator.execute(&op_data); } /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) { item_buffer::reset(); if (f & rf_extract) my_built_predecessors.receiver_extract(*this); } #else /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { item_buffer::reset(); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ private: forwarding_base *my_join; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container > my_built_predecessors; #endif }; #include "_flow_graph_tagged_buffer_impl.h" template< typename T > class tag_matching_port : public receiver, public tagged_buffer< tag_value, T, NO_TAG > { public: typedef T input_type; typedef sender predecessor_type; typedef tag_matching_port my_node_type; // for forwarding, if needed typedef function_body my_tag_func_type; typedef tagged_buffer my_buffer_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; #endif private: // ----------- Aggregator ------------ private: enum op_type { try__put, get__item, res_port, add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy }; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; typedef tag_matching_port my_class; class tag_matching_port_operation : public aggregated_operation { public: char type; T my_val; T *my_arg; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES predecessor_type *pred; size_t cnt_val; predecessor_vector_type *pvec; #endif tag_value my_tag_value; // constructor for value parameter tag_matching_port_operation(const T& e, op_type t) : type(char(t)), my_val(e) {} // constructor for pointer parameter tag_matching_port_operation(const T* p, op_type t) : type(char(t)), my_arg(const_cast(p)) {} // constructor with no parameter tag_matching_port_operation(op_type t) : type(char(t)) {} }; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; aggregator my_aggregator; void handle_operations(tag_matching_port_operation* op_list) { tag_matching_port_operation *current; while(op_list) { current = op_list; op_list = op_list->next; switch(current->type) { case try__put: { bool was_inserted = this->tagged_insert(current->my_tag_value, current->my_val); // return failure if a duplicate insertion occurs __TBB_store_with_release(current->status, was_inserted ? SUCCEEDED : FAILED); } break; case get__item: // use current_tag from FE for item if(!this->tagged_find(my_join->current_tag, *(current->my_arg))) { __TBB_ASSERT(false, "Failed to find item corresponding to current_tag."); } __TBB_store_with_release(current->status, SUCCEEDED); break; case res_port: // use current_tag from FE for item this->tagged_delete(my_join->current_tag); __TBB_store_with_release(current->status, SUCCEEDED); break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES case add_blt_pred: my_built_predecessors.add_edge(*(current->pred)); __TBB_store_with_release(current->status, SUCCEEDED); break; case del_blt_pred: my_built_predecessors.delete_edge(*(current->pred)); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_pred_cnt: current->cnt_val = my_built_predecessors.edge_count(); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_pred_cpy: my_built_predecessors.copy_edges(*(current->pvec)); __TBB_store_with_release(current->status, SUCCEEDED); break; #endif } } } // ------------ End Aggregator --------------- protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; /*override*/task *try_put_task(const T& v) { tag_matching_port_operation op_data(v, try__put); op_data.my_tag_value = (*my_tag_func)(v); task *rtask = NULL; my_aggregator.execute(&op_data); if(op_data.status == SUCCEEDED) { rtask = my_join->increment_tag_count(op_data.my_tag_value, false); // may spawn // rtask has to reflect the return status of the try_put if(!rtask) rtask = SUCCESSFULLY_ENQUEUED; } return rtask; } public: tag_matching_port() : receiver(), tagged_buffer() { my_join = NULL; my_tag_func = NULL; my_original_tag_func = NULL; my_aggregator.initialize_handler(my_handler(this)); } // copy constructor tag_matching_port(const tag_matching_port& /*other*/) : receiver(), tagged_buffer() { my_join = NULL; // setting the tag methods is done in the copy-constructor for the front-end. my_tag_func = NULL; my_original_tag_func = NULL; my_aggregator.initialize_handler(my_handler(this)); } ~tag_matching_port() { if (my_tag_func) delete my_tag_func; if (my_original_tag_func) delete my_original_tag_func; } void set_join_node_pointer(forwarding_base *join) { my_join = join; } void set_my_original_tag_func(my_tag_func_type *f) { my_original_tag_func = f; } void set_my_tag_func(my_tag_func_type *f) { my_tag_func = f; } bool get_item( T &v ) { tag_matching_port_operation op_data(&v, get__item); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void internal_add_built_predecessor(sender &p) { tag_matching_port_operation op_data(add_blt_pred); op_data.pred = &p; my_aggregator.execute(&op_data); } /*override*/void internal_delete_built_predecessor(sender &p) { tag_matching_port_operation op_data(del_blt_pred); op_data.pred = &p; my_aggregator.execute(&op_data); } /*override*/size_t predecessor_count() { tag_matching_port_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } /*override*/void copy_predecessors(predecessor_vector_type &v) { tag_matching_port_operation op_data(blt_pred_cpy); op_data.pvec = &v; my_aggregator.execute(&op_data); } #endif // reset_port is called when item is accepted by successor, but // is initiated by join_node. void reset_port() { tag_matching_port_operation op_data(res_port); my_aggregator.execute(&op_data); return; } my_tag_func_type *my_func() { return my_tag_func; } my_tag_func_type *my_original_func() { return my_original_tag_func; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) { my_buffer_type::reset(); if (f & rf_extract) my_built_predecessors.receiver_extract(*this); } #else /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { my_buffer_type::reset(); } #endif private: // need map of tags to values forwarding_base *my_join; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container my_built_predecessors; #endif my_tag_func_type *my_tag_func; my_tag_func_type *my_original_tag_func; }; // tag_matching_port using namespace graph_policy_namespace; template class join_node_base; //! join_node_FE : implements input port policy template class join_node_FE; template class join_node_FE : public forwarding_base { public: static const int N = tbb::flow::tuple_size::value; typedef OutputTuple output_type; typedef InputTuple input_type; typedef join_node_base my_node_type; // for forwarding join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) { ports_with_no_inputs = N; join_helper::set_join_node_pointer(my_inputs, this); } join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::my_graph_ptr)), my_node(NULL) { ports_with_no_inputs = N; join_helper::set_join_node_pointer(my_inputs, this); } void set_my_node(my_node_type *new_my_node) { my_node = new_my_node; } void increment_port_count() { ++ports_with_no_inputs; } // if all input_ports have predecessors, spawn forward to try and consume tuples task * decrement_port_count(bool handle_task) { if(ports_with_no_inputs.fetch_and_decrement() == 1) { task* tp = this->my_graph_ptr->root_task(); if(tp) { task *rtask = new ( task::allocate_additional_child_of( *tp ) ) forward_task_bypass(*my_node); if(!handle_task) return rtask; FLOW_SPAWN(*rtask); } } return NULL; } input_type &input_ports() { return my_inputs; } protected: void reset( __TBB_PFG_RESET_ARG( reset_flags f)) { // called outside of parallel contexts ports_with_no_inputs = N; join_helper::reset_inputs(my_inputs __TBB_PFG_RESET_ARG( __TBB_COMMA f)); } // all methods on input ports should be called under mutual exclusion from join_node_base. bool tuple_build_may_succeed() { return !ports_with_no_inputs; } bool try_to_make_tuple(output_type &out) { if(ports_with_no_inputs) return false; return join_helper::reserve(my_inputs, out); } void tuple_accepted() { join_helper::consume_reservations(my_inputs); } void tuple_rejected() { join_helper::release_reservations(my_inputs); } input_type my_inputs; my_node_type *my_node; atomic ports_with_no_inputs; }; template class join_node_FE : public forwarding_base { public: static const int N = tbb::flow::tuple_size::value; typedef OutputTuple output_type; typedef InputTuple input_type; typedef join_node_base my_node_type; // for forwarding join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) { ports_with_no_items = N; join_helper::set_join_node_pointer(my_inputs, this); } join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::my_graph_ptr)), my_node(NULL) { ports_with_no_items = N; join_helper::set_join_node_pointer(my_inputs, this); } // needed for forwarding void set_my_node(my_node_type *new_my_node) { my_node = new_my_node; } void reset_port_count() { ports_with_no_items = N; } // if all input_ports have items, spawn forward to try and consume tuples task * decrement_port_count(bool handle_task) { if(ports_with_no_items.fetch_and_decrement() == 1) { task* tp = this->my_graph_ptr->root_task(); if(tp) { task *rtask = new ( task::allocate_additional_child_of( *tp ) ) forward_task_bypass (*my_node); if(!handle_task) return rtask; FLOW_SPAWN( *rtask); } } return NULL; } void increment_port_count() { __TBB_ASSERT(false, NULL); } // should never be called input_type &input_ports() { return my_inputs; } protected: void reset( __TBB_PFG_RESET_ARG( reset_flags f)) { reset_port_count(); join_helper::reset_inputs(my_inputs __TBB_PFG_RESET_ARG( __TBB_COMMA f) ); } // all methods on input ports should be called under mutual exclusion from join_node_base. bool tuple_build_may_succeed() { return !ports_with_no_items; } bool try_to_make_tuple(output_type &out) { if(ports_with_no_items) return false; return join_helper::get_items(my_inputs, out); } void tuple_accepted() { reset_port_count(); join_helper::reset_ports(my_inputs); } void tuple_rejected() { // nothing to do. } input_type my_inputs; my_node_type *my_node; atomic ports_with_no_items; }; // tag_matching join input port. template class join_node_FE : public forwarding_base, // buffer of tag value counts buffer of output items public tagged_buffer, public item_buffer { public: static const int N = tbb::flow::tuple_size::value; typedef OutputTuple output_type; typedef InputTuple input_type; typedef tagged_buffer my_tag_buffer; typedef item_buffer output_buffer_type; typedef join_node_base my_node_type; // for forwarding // ----------- Aggregator ------------ // the aggregator is only needed to serialize the access to the hash table. // and the output_buffer_type base class private: enum op_type { res_count, inc_count, may_succeed, try_make }; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; typedef join_node_FE my_class; class tag_matching_FE_operation : public aggregated_operation { public: char type; union { tag_value my_val; output_type* my_output; }; task *bypass_t; bool enqueue_task; // constructor for value parameter tag_matching_FE_operation(const tag_value& e , bool q_task , op_type t) : type(char(t)), my_val(e), bypass_t(NULL), enqueue_task(q_task) {} tag_matching_FE_operation(output_type *p, op_type t) : type(char(t)), my_output(p), bypass_t(NULL), enqueue_task(true) {} // constructor with no parameter tag_matching_FE_operation(op_type t) : type(char(t)), bypass_t(NULL), enqueue_task(true) {} }; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; aggregator my_aggregator; // called from aggregator, so serialized // construct as many output objects as possible. // returns a task pointer if the a task would have been enqueued but we asked that // it be returned. Otherwise returns NULL. task * fill_output_buffer(tag_value t, bool should_enqueue, bool handle_task) { output_type l_out; task *rtask = NULL; task* tp = this->my_graph_ptr->root_task(); bool do_fwd = should_enqueue && this->buffer_empty() && tp; this->current_tag = t; this->tagged_delete(this->current_tag); // remove the tag if(join_helper::get_items(my_inputs, l_out)) { // <== call back this->push_back(l_out); if(do_fwd) { // we enqueue if receiving an item from predecessor, not if successor asks for item rtask = new ( task::allocate_additional_child_of( *tp ) ) forward_task_bypass(*my_node); if(handle_task) { FLOW_SPAWN(*rtask); rtask = NULL; } do_fwd = false; } // retire the input values join_helper::reset_ports(my_inputs); // <== call back this->current_tag = NO_TAG; } else { __TBB_ASSERT(false, "should have had something to push"); } return rtask; } void handle_operations(tag_matching_FE_operation* op_list) { tag_matching_FE_operation *current; while(op_list) { current = op_list; op_list = op_list->next; switch(current->type) { case res_count: // called from BE { this->destroy_front(); __TBB_store_with_release(current->status, SUCCEEDED); } break; case inc_count: { // called from input ports size_t *p = 0; tag_value t = current->my_val; bool do_enqueue = current->enqueue_task; if(!(this->tagged_find_ref(t,p))) { this->tagged_insert(t, 0); if(!(this->tagged_find_ref(t,p))) { __TBB_ASSERT(false, "should find tag after inserting it"); } } if(++(*p) == size_t(N)) { task *rtask = fill_output_buffer(t, true, do_enqueue); __TBB_ASSERT(!rtask || !do_enqueue, "task should not be returned"); current->bypass_t = rtask; } } __TBB_store_with_release(current->status, SUCCEEDED); break; case may_succeed: // called from BE __TBB_store_with_release(current->status, this->buffer_empty() ? FAILED : SUCCEEDED); break; case try_make: // called from BE if(this->buffer_empty()) { __TBB_store_with_release(current->status, FAILED); } else { this->copy_front(*(current->my_output)); __TBB_store_with_release(current->status, SUCCEEDED); } break; } } } // ------------ End Aggregator --------------- public: template join_node_FE(graph &g, FunctionTuple tag_funcs) : forwarding_base(g), my_node(NULL) { join_helper::set_join_node_pointer(my_inputs, this); join_helper::set_tag_func(my_inputs, tag_funcs); my_aggregator.initialize_handler(my_handler(this)); } join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::my_graph_ptr)), my_tag_buffer(), output_buffer_type() { my_node = NULL; join_helper::set_join_node_pointer(my_inputs, this); join_helper::copy_tag_functors(my_inputs, const_cast(other.my_inputs)); my_aggregator.initialize_handler(my_handler(this)); } // needed for forwarding void set_my_node(my_node_type *new_my_node) { my_node = new_my_node; } void reset_port_count() { // called from BE tag_matching_FE_operation op_data(res_count); my_aggregator.execute(&op_data); return; } // if all input_ports have items, spawn forward to try and consume tuples // return a task if we are asked and did create one. task *increment_tag_count(tag_value t, bool handle_task) { // called from input_ports tag_matching_FE_operation op_data(t, handle_task, inc_count); my_aggregator.execute(&op_data); return op_data.bypass_t; } /*override*/ task *decrement_port_count(bool /*handle_task*/) { __TBB_ASSERT(false, NULL); return NULL; } void increment_port_count() { __TBB_ASSERT(false, NULL); } // should never be called input_type &input_ports() { return my_inputs; } protected: void reset( __TBB_PFG_RESET_ARG( reset_flags f )) { // called outside of parallel contexts join_helper::reset_inputs(my_inputs __TBB_PFG_RESET_ARG( __TBB_COMMA f)); my_tag_buffer::reset(); // have to reset the tag counts output_buffer_type::reset(); // also the queue of outputs my_node->current_tag = NO_TAG; } // all methods on input ports should be called under mutual exclusion from join_node_base. bool tuple_build_may_succeed() { // called from back-end tag_matching_FE_operation op_data(may_succeed); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } // cannot lock while calling back to input_ports. current_tag will only be set // and reset under the aggregator, so it will remain consistent. bool try_to_make_tuple(output_type &out) { tag_matching_FE_operation op_data(&out,try_make); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } void tuple_accepted() { reset_port_count(); // reset current_tag after ports reset. } void tuple_rejected() { // nothing to do. } input_type my_inputs; // input ports my_node_type *my_node; }; // join_node_FE //! join_node_base template class join_node_base : public graph_node, public join_node_FE, public sender { protected: using graph_node::my_graph; public: typedef OutputTuple output_type; typedef receiver successor_type; typedef join_node_FE input_ports_type; using input_ports_type::tuple_build_may_succeed; using input_ports_type::try_to_make_tuple; using input_ports_type::tuple_accepted; using input_ports_type::tuple_rejected; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector successor_vector_type; #endif private: // ----------- Aggregator ------------ enum op_type { reg_succ, rem_succ, try__get, do_fwrd, do_fwrd_bypass #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , add_blt_succ, del_blt_succ, blt_succ_cnt, blt_succ_cpy #endif }; enum op_stat {WAIT=0, SUCCEEDED, FAILED}; typedef join_node_base my_class; class join_node_base_operation : public aggregated_operation { public: char type; union { output_type *my_arg; successor_type *my_succ; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES size_t cnt_val; successor_vector_type *svec; #endif }; task *bypass_t; join_node_base_operation(const output_type& e, op_type t) : type(char(t)), my_arg(const_cast(&e)), bypass_t(NULL) {} join_node_base_operation(const successor_type &s, op_type t) : type(char(t)), my_succ(const_cast(&s)), bypass_t(NULL) {} join_node_base_operation(op_type t) : type(char(t)), bypass_t(NULL) {} }; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; bool forwarder_busy; aggregator my_aggregator; void handle_operations(join_node_base_operation* op_list) { join_node_base_operation *current; while(op_list) { current = op_list; op_list = op_list->next; switch(current->type) { case reg_succ: { my_successors.register_successor(*(current->my_succ)); task* tp = this->graph_node::my_graph.root_task(); if(tuple_build_may_succeed() && !forwarder_busy && tp) { task *rtask = new ( task::allocate_additional_child_of(*tp) ) forward_task_bypass >(*this); FLOW_SPAWN(*rtask); forwarder_busy = true; } __TBB_store_with_release(current->status, SUCCEEDED); } break; case rem_succ: my_successors.remove_successor(*(current->my_succ)); __TBB_store_with_release(current->status, SUCCEEDED); break; case try__get: if(tuple_build_may_succeed()) { if(try_to_make_tuple(*(current->my_arg))) { tuple_accepted(); __TBB_store_with_release(current->status, SUCCEEDED); } else __TBB_store_with_release(current->status, FAILED); } else __TBB_store_with_release(current->status, FAILED); break; case do_fwrd_bypass: { bool build_succeeded; task *last_task = NULL; output_type out; if(tuple_build_may_succeed()) { do { build_succeeded = try_to_make_tuple(out); if(build_succeeded) { task *new_task = my_successors.try_put_task(out); last_task = combine_tasks(last_task, new_task); if(new_task) { tuple_accepted(); } else { tuple_rejected(); build_succeeded = false; } } } while(build_succeeded); } current->bypass_t = last_task; __TBB_store_with_release(current->status, SUCCEEDED); forwarder_busy = false; } break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES case add_blt_succ: my_successors.internal_add_built_successor(*(current->my_succ)); __TBB_store_with_release(current->status, SUCCEEDED); break; case del_blt_succ: my_successors.internal_delete_built_successor(*(current->my_succ)); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_succ_cnt: current->cnt_val = my_successors.successor_count(); __TBB_store_with_release(current->status, SUCCEEDED); break; case blt_succ_cpy: my_successors.copy_successors(*(current->svec)); __TBB_store_with_release(current->status, SUCCEEDED); break; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ } } } // ---------- end aggregator ----------- public: join_node_base(graph &g) : graph_node(g), input_ports_type(g), forwarder_busy(false) { my_successors.set_owner(this); input_ports_type::set_my_node(this); my_aggregator.initialize_handler(my_handler(this)); } join_node_base(const join_node_base& other) : graph_node(other.graph_node::my_graph), input_ports_type(other), sender(), forwarder_busy(false), my_successors() { my_successors.set_owner(this); input_ports_type::set_my_node(this); my_aggregator.initialize_handler(my_handler(this)); } template join_node_base(graph &g, FunctionTuple f) : graph_node(g), input_ports_type(g, f), forwarder_busy(false) { my_successors.set_owner(this); input_ports_type::set_my_node(this); my_aggregator.initialize_handler(my_handler(this)); } bool register_successor(successor_type &r) { join_node_base_operation op_data(r, reg_succ); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } bool remove_successor( successor_type &r) { join_node_base_operation op_data(r, rem_succ); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } bool try_get( output_type &v) { join_node_base_operation op_data(v, try__get); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/void internal_add_built_successor( successor_type &r) { join_node_base_operation op_data(r, add_blt_succ); my_aggregator.execute(&op_data); } /*override*/void internal_delete_built_successor( successor_type &r) { join_node_base_operation op_data(r, del_blt_succ); my_aggregator.execute(&op_data); } /*override*/size_t successor_count() { join_node_base_operation op_data(blt_succ_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } /*override*/ void copy_successors(successor_vector_type &v) { join_node_base_operation op_data(blt_succ_cpy); op_data.svec = &v; my_aggregator.execute(&op_data); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { input_ports_type::reset(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES my_successors.reset(f); #endif } private: broadcast_cache my_successors; friend class forward_task_bypass< join_node_base >; task *forward_task() { join_node_base_operation op_data(do_fwrd_bypass); my_aggregator.execute(&op_data); return op_data.bypass_t; } }; // join base class type generator template class PT, typename OutputTuple, graph_buffer_policy JP> struct join_base { typedef typename internal::join_node_base::type, OutputTuple> type; }; //! unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type // using tuple_element. The class PT is the port type (reserving_port, queueing_port, tag_matching_port) // and should match the graph_buffer_policy. template class PT, typename OutputTuple, graph_buffer_policy JP> class unfolded_join_node : public join_base::type { public: typedef typename wrap_tuple_elements::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; public: unfolded_join_node(graph &g) : base_type(g) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; // tag_matching unfolded_join_node. This must be a separate specialization because the constructors // differ. template class unfolded_join_node<2,tag_matching_port,OutputTuple,tag_matching> : public join_base<2,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; public: typedef typename wrap_tuple_elements<2,tag_matching_port,OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename tbb::flow::tuple< f0_p, f1_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; template class unfolded_join_node<3,tag_matching_port,OutputTuple,tag_matching> : public join_base<3,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; public: typedef typename wrap_tuple_elements<3, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; template class unfolded_join_node<4,tag_matching_port,OutputTuple,tag_matching> : public join_base<4,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; public: typedef typename wrap_tuple_elements<4, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename internal::function_body *f3_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2), new internal::function_body_leaf(b3) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; template class unfolded_join_node<5,tag_matching_port,OutputTuple,tag_matching> : public join_base<5,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; public: typedef typename wrap_tuple_elements<5, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename internal::function_body *f3_p; typedef typename internal::function_body *f4_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2), new internal::function_body_leaf(b3), new internal::function_body_leaf(b4) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; #if __TBB_VARIADIC_MAX >= 6 template class unfolded_join_node<6,tag_matching_port,OutputTuple,tag_matching> : public join_base<6,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; public: typedef typename wrap_tuple_elements<6, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename internal::function_body *f3_p; typedef typename internal::function_body *f4_p; typedef typename internal::function_body *f5_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2), new internal::function_body_leaf(b3), new internal::function_body_leaf(b4), new internal::function_body_leaf(b5) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; #endif #if __TBB_VARIADIC_MAX >= 7 template class unfolded_join_node<7,tag_matching_port,OutputTuple,tag_matching> : public join_base<7,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; public: typedef typename wrap_tuple_elements<7, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename internal::function_body *f3_p; typedef typename internal::function_body *f4_p; typedef typename internal::function_body *f5_p; typedef typename internal::function_body *f6_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2), new internal::function_body_leaf(b3), new internal::function_body_leaf(b4), new internal::function_body_leaf(b5), new internal::function_body_leaf(b6) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; #endif #if __TBB_VARIADIC_MAX >= 8 template class unfolded_join_node<8,tag_matching_port,OutputTuple,tag_matching> : public join_base<8,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; public: typedef typename wrap_tuple_elements<8, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename internal::function_body *f3_p; typedef typename internal::function_body *f4_p; typedef typename internal::function_body *f5_p; typedef typename internal::function_body *f6_p; typedef typename internal::function_body *f7_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2), new internal::function_body_leaf(b3), new internal::function_body_leaf(b4), new internal::function_body_leaf(b5), new internal::function_body_leaf(b6), new internal::function_body_leaf(b7) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; #endif #if __TBB_VARIADIC_MAX >= 9 template class unfolded_join_node<9,tag_matching_port,OutputTuple,tag_matching> : public join_base<9,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8; public: typedef typename wrap_tuple_elements<9, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename internal::function_body *f3_p; typedef typename internal::function_body *f4_p; typedef typename internal::function_body *f5_p; typedef typename internal::function_body *f6_p; typedef typename internal::function_body *f7_p; typedef typename internal::function_body *f8_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7, B8 b8) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2), new internal::function_body_leaf(b3), new internal::function_body_leaf(b4), new internal::function_body_leaf(b5), new internal::function_body_leaf(b6), new internal::function_body_leaf(b7), new internal::function_body_leaf(b8) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; #endif #if __TBB_VARIADIC_MAX >= 10 template class unfolded_join_node<10,tag_matching_port,OutputTuple,tag_matching> : public join_base<10,tag_matching_port,OutputTuple,tag_matching>::type { typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8; typedef typename tbb::flow::tuple_element<9, OutputTuple>::type T9; public: typedef typename wrap_tuple_elements<10, tag_matching_port, OutputTuple>::type input_ports_type; typedef OutputTuple output_type; private: typedef join_node_base base_type; typedef typename internal::function_body *f0_p; typedef typename internal::function_body *f1_p; typedef typename internal::function_body *f2_p; typedef typename internal::function_body *f3_p; typedef typename internal::function_body *f4_p; typedef typename internal::function_body *f5_p; typedef typename internal::function_body *f6_p; typedef typename internal::function_body *f7_p; typedef typename internal::function_body *f8_p; typedef typename internal::function_body *f9_p; typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p, f9_p > func_initializer_type; public: template unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7, B8 b8, B9 b9) : base_type(g, func_initializer_type( new internal::function_body_leaf(b0), new internal::function_body_leaf(b1), new internal::function_body_leaf(b2), new internal::function_body_leaf(b3), new internal::function_body_leaf(b4), new internal::function_body_leaf(b5), new internal::function_body_leaf(b6), new internal::function_body_leaf(b7), new internal::function_body_leaf(b8), new internal::function_body_leaf(b9) ) ) {} unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} }; #endif //! templated function to refer to input ports of the join node template typename tbb::flow::tuple_element::type &input_port(JNT &jn) { return tbb::flow::get(jn.input_ports()); } } #endif // __TBB__flow_graph_join_impl_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_node_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__flow_graph_node_impl_H #define __TBB__flow_graph_node_impl_H #ifndef __TBB_flow_graph_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #include "_flow_graph_item_buffer_impl.h" //! @cond INTERNAL namespace internal { using tbb::internal::aggregated_operation; using tbb::internal::aggregating_functor; using tbb::internal::aggregator; template< typename T, typename A > class function_input_queue : public item_buffer { public: bool pop( T& t ) { return this->pop_front( t ); } bool push( T& t ) { return this->push_back( t ); } }; //! Input and scheduling for a function node that takes a type Input as input // The only up-ref is apply_body_impl, which should implement the function // call and any handling of the result. template< typename Input, typename A, typename ImplType > class function_input_base : public receiver, tbb::internal::no_assign { enum op_stat {WAIT=0, SUCCEEDED, FAILED}; enum op_type {reg_pred, rem_pred, app_body, try_fwd, tryput_bypass, app_body_bypass #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy // create vector copies of preds and succs #endif }; typedef function_input_base my_class; public: //! The input type of this receiver typedef Input input_type; typedef sender predecessor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector predecessor_vector_type; #endif //! Constructor for function_input_base function_input_base( graph &g, size_t max_concurrency, function_input_queue *q = NULL ) : my_graph(g), my_max_concurrency(max_concurrency), my_concurrency(0), my_queue(q), forwarder_busy(false) { my_predecessors.set_owner(this); my_aggregator.initialize_handler(my_handler(this)); } //! Copy constructor function_input_base( const function_input_base& src, function_input_queue *q = NULL ) : receiver(), tbb::internal::no_assign(), my_graph(src.my_graph), my_max_concurrency(src.my_max_concurrency), my_concurrency(0), my_queue(q), forwarder_busy(false) { my_predecessors.set_owner(this); my_aggregator.initialize_handler(my_handler(this)); } //! Destructor virtual ~function_input_base() { if ( my_queue ) delete my_queue; } //! Put to the node, returning a task if available virtual task * try_put_task( const input_type &t ) { if ( my_max_concurrency == 0 ) { return create_body_task( t ); } else { my_operation op_data(t, tryput_bypass); my_aggregator.execute(&op_data); if(op_data.status == SUCCEEDED ) { return op_data.bypass_t; } return NULL; } } //! Adds src to the list of cached predecessors. /* override */ bool register_predecessor( predecessor_type &src ) { my_operation op_data(reg_pred); op_data.r = &src; my_aggregator.execute(&op_data); return true; } //! Removes src from the list of cached predecessors. /* override */ bool remove_predecessor( predecessor_type &src ) { my_operation op_data(rem_pred); op_data.r = &src; my_aggregator.execute(&op_data); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES //! Adds to list of predecessors added by make_edge /*override*/ void internal_add_built_predecessor( predecessor_type &src) { my_operation op_data(add_blt_pred); op_data.r = &src; my_aggregator.execute(&op_data); } //! removes from to list of predecessors (used by remove_edge) /*override*/ void internal_delete_built_predecessor( predecessor_type &src) { my_operation op_data(del_blt_pred); op_data.r = &src; my_aggregator.execute(&op_data); } /*override*/ size_t predecessor_count() { my_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } /*override*/ void copy_predecessors(predecessor_vector_type &v) { my_operation op_data(blt_pred_cpy); op_data.predv = &v; my_aggregator.execute(&op_data); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: void reset_function_input_base( __TBB_PFG_RESET_ARG(reset_flags f)) { my_concurrency = 0; if(my_queue) { my_queue->reset(); } reset_receiver(__TBB_PFG_RESET_ARG(f)); forwarder_busy = false; } graph& my_graph; const size_t my_max_concurrency; size_t my_concurrency; function_input_queue *my_queue; predecessor_cache my_predecessors; /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f)) { my_predecessors.reset(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES __TBB_ASSERT(!(f & rf_extract) || my_predecessors.empty(), "function_input_base reset failed"); #endif } private: friend class apply_body_task_bypass< my_class, input_type >; friend class forward_task_bypass< my_class >; class my_operation : public aggregated_operation< my_operation > { public: char type; union { input_type *elem; predecessor_type *r; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES size_t cnt_val; predecessor_vector_type *predv; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ }; tbb::task *bypass_t; my_operation(const input_type& e, op_type t) : type(char(t)), elem(const_cast(&e)) {} my_operation(op_type t) : type(char(t)), r(NULL) {} }; bool forwarder_busy; typedef internal::aggregating_functor my_handler; friend class internal::aggregating_functor; aggregator< my_handler, my_operation > my_aggregator; void handle_operations(my_operation *op_list) { my_operation *tmp; while (op_list) { tmp = op_list; op_list = op_list->next; switch (tmp->type) { case reg_pred: my_predecessors.add(*(tmp->r)); __TBB_store_with_release(tmp->status, SUCCEEDED); if (!forwarder_busy) { forwarder_busy = true; spawn_forward_task(); } break; case rem_pred: my_predecessors.remove(*(tmp->r)); __TBB_store_with_release(tmp->status, SUCCEEDED); break; case app_body: __TBB_ASSERT(my_max_concurrency != 0, NULL); --my_concurrency; __TBB_store_with_release(tmp->status, SUCCEEDED); if (my_concurrencypop(i); else item_was_retrieved = my_predecessors.get_item(i); if (item_was_retrieved) { ++my_concurrency; spawn_body_task(i); } } break; case app_body_bypass: { task * new_task = NULL; __TBB_ASSERT(my_max_concurrency != 0, NULL); --my_concurrency; if (my_concurrencypop(i); else item_was_retrieved = my_predecessors.get_item(i); if (item_was_retrieved) { ++my_concurrency; new_task = create_body_task(i); } } tmp->bypass_t = new_task; __TBB_store_with_release(tmp->status, SUCCEEDED); } break; case tryput_bypass: internal_try_put_task(tmp); break; case try_fwd: internal_forward(tmp); break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES case add_blt_pred: { my_predecessors.internal_add_built_predecessor(*(tmp->r)); __TBB_store_with_release(tmp->status, SUCCEEDED); } break; case del_blt_pred: my_predecessors.internal_delete_built_predecessor(*(tmp->r)); __TBB_store_with_release(tmp->status, SUCCEEDED); break; case blt_pred_cnt: tmp->cnt_val = my_predecessors.predecessor_count(); __TBB_store_with_release(tmp->status, SUCCEEDED); break; case blt_pred_cpy: my_predecessors.copy_predecessors( *(tmp->predv) ); __TBB_store_with_release(tmp->status, SUCCEEDED); break; #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ } } } //! Put to the node, but return the task instead of enqueueing it void internal_try_put_task(my_operation *op) { __TBB_ASSERT(my_max_concurrency != 0, NULL); if (my_concurrency < my_max_concurrency) { ++my_concurrency; task * new_task = create_body_task(*(op->elem)); op->bypass_t = new_task; __TBB_store_with_release(op->status, SUCCEEDED); } else if ( my_queue && my_queue->push(*(op->elem)) ) { op->bypass_t = SUCCESSFULLY_ENQUEUED; __TBB_store_with_release(op->status, SUCCEEDED); } else { op->bypass_t = NULL; __TBB_store_with_release(op->status, FAILED); } } //! Tries to spawn bodies if available and if concurrency allows void internal_forward(my_operation *op) { op->bypass_t = NULL; if (my_concurrencypop(i); else item_was_retrieved = my_predecessors.get_item(i); if (item_was_retrieved) { ++my_concurrency; op->bypass_t = create_body_task(i); __TBB_store_with_release(op->status, SUCCEEDED); return; } } __TBB_store_with_release(op->status, FAILED); forwarder_busy = false; } //! Applies the body to the provided input // then decides if more work is available void apply_body( input_type &i ) { task *new_task = apply_body_bypass(i); if(!new_task) return; if(new_task == SUCCESSFULLY_ENQUEUED) return; FLOW_SPAWN(*new_task); return; } //! Applies the body to the provided input // then decides if more work is available task * apply_body_bypass( input_type &i ) { task * new_task = static_cast(this)->apply_body_impl_bypass(i); if ( my_max_concurrency != 0 ) { my_operation op_data(app_body_bypass); // tries to pop an item or get_item, enqueues another apply_body my_aggregator.execute(&op_data); tbb::task *ttask = op_data.bypass_t; new_task = combine_tasks(new_task, ttask); } return new_task; } //! allocates a task to call apply_body( input ) inline task * create_body_task( const input_type &input ) { task* tp = my_graph.root_task(); return (tp) ? new(task::allocate_additional_child_of(*tp)) apply_body_task_bypass < my_class, input_type >(*this, input) : NULL; } //! Spawns a task that calls apply_body( input ) inline void spawn_body_task( const input_type &input ) { task* tp = create_body_task(input); // tp == NULL => g.reset(), which shouldn't occur in concurrent context if(tp) { FLOW_SPAWN(*tp); } } //! This is executed by an enqueued task, the "forwarder" task *forward_task() { my_operation op_data(try_fwd); task *rval = NULL; do { op_data.status = WAIT; my_aggregator.execute(&op_data); if(op_data.status == SUCCEEDED) { tbb::task *ttask = op_data.bypass_t; rval = combine_tasks(rval, ttask); } } while (op_data.status == SUCCEEDED); return rval; } inline task *create_forward_task() { task* tp = my_graph.root_task(); return (tp) ? new(task::allocate_additional_child_of(*tp)) forward_task_bypass< my_class >(*this) : NULL; } //! Spawns a task that calls forward() inline void spawn_forward_task() { task* tp = create_forward_task(); if(tp) { FLOW_SPAWN(*tp); } } }; // function_input_base //! Implements methods for a function node that takes a type Input as input and sends // a type Output to its successors. template< typename Input, typename Output, typename A> class function_input : public function_input_base > { public: typedef Input input_type; typedef Output output_type; typedef function_input my_class; typedef function_input_base base_type; typedef function_input_queue input_queue_type; // constructor template function_input( graph &g, size_t max_concurrency, Body& body, function_input_queue *q = NULL ) : base_type(g, max_concurrency, q), my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { } //! Copy constructor function_input( const function_input& src, input_queue_type *q = NULL ) : base_type(src, q), my_body( src.my_body->clone() ) { } ~function_input() { delete my_body; } template< typename Body > Body copy_function_object() { internal::function_body &body_ref = *this->my_body; return dynamic_cast< internal::function_body_leaf & >(body_ref).get_body(); } task * apply_body_impl_bypass( const input_type &i) { #if TBB_PREVIEW_FLOW_GRAPH_TRACE // There is an extra copied needed to capture the // body execution without the try_put tbb::internal::fgt_begin_body( my_body ); output_type v = (*my_body)(i); tbb::internal::fgt_end_body( my_body ); task * new_task = successors().try_put_task( v ); #else task * new_task = successors().try_put_task( (*my_body)(i) ); #endif return new_task; } protected: void reset_function_input(__TBB_PFG_RESET_ARG(reset_flags f)) { base_type::reset_function_input_base(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES if(f & rf_reset_bodies) my_body->reset_body(); #endif } function_body *my_body; virtual broadcast_cache &successors() = 0; }; // function_input #if TBB_PREVIEW_FLOW_GRAPH_FEATURES // helper templates to reset the successor edges of the output ports of an multifunction_node template struct reset_element { template static void reset_this(P &p, reset_flags f) { (void)tbb::flow::get(p).successors().reset(f); reset_element::reset_this(p, f); } template static bool this_empty(P &p) { if(tbb::flow::get(p).successors().empty()) return reset_element::this_empty(p); return false; } }; template<> struct reset_element<1> { template static void reset_this(P &p, reset_flags f) { (void)tbb::flow::get<0>(p).successors().reset(f); } template static bool this_empty(P &p) { return tbb::flow::get<0>(p).successors().empty(); } }; #endif //! Implements methods for a function node that takes a type Input as input // and has a tuple of output ports specified. template< typename Input, typename OutputPortSet, typename A> class multifunction_input : public function_input_base > { public: static const int N = tbb::flow::tuple_size::value; typedef Input input_type; typedef OutputPortSet output_ports_type; typedef multifunction_input my_class; typedef function_input_base base_type; typedef function_input_queue input_queue_type; // constructor template multifunction_input( graph &g, size_t max_concurrency, Body& body, function_input_queue *q = NULL ) : base_type(g, max_concurrency, q), my_body( new internal::multifunction_body_leaf(body) ) { } //! Copy constructor multifunction_input( const multifunction_input& src, input_queue_type *q = NULL ) : base_type(src, q), my_body( src.my_body->clone() ) { } ~multifunction_input() { delete my_body; } template< typename Body > Body copy_function_object() { internal::multifunction_body &body_ref = *this->my_body; return dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body(); } // for multifunction nodes we do not have a single successor as such. So we just tell // the task we were successful. task * apply_body_impl_bypass( const input_type &i) { tbb::internal::fgt_begin_body( my_body ); (*my_body)(i, my_output_ports); tbb::internal::fgt_end_body( my_body ); task * new_task = SUCCESSFULLY_ENQUEUED; return new_task; } output_ports_type &output_ports(){ return my_output_ports; } protected: /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { base_type::reset_function_input_base(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES reset_element::reset_this(my_output_ports, f); if(f & rf_reset_bodies) my_body->reset_body(); __TBB_ASSERT(!(f & rf_extract) || reset_element::this_empty(my_output_ports), "multifunction_node reset failed"); #endif } multifunction_body *my_body; output_ports_type my_output_ports; }; // multifunction_input // template to refer to an output port of a multifunction_node template typename tbb::flow::tuple_element::type &output_port(MOP &op) { return tbb::flow::get(op.output_ports()); } // helper structs for split_node template struct emit_element { template static void emit_this(const T &t, P &p) { (void)tbb::flow::get(p).try_put(tbb::flow::get(t)); emit_element::emit_this(t,p); } }; template<> struct emit_element<1> { template static void emit_this(const T &t, P &p) { (void)tbb::flow::get<0>(p).try_put(tbb::flow::get<0>(t)); } }; //! Implements methods for an executable node that takes continue_msg as input template< typename Output > class continue_input : public continue_receiver { public: //! The input type of this receiver typedef continue_msg input_type; //! The output type of this receiver typedef Output output_type; template< typename Body > continue_input( graph &g, Body& body ) : my_graph_ptr(&g), my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { } template< typename Body > continue_input( graph &g, int number_of_predecessors, Body& body ) : continue_receiver( number_of_predecessors ), my_graph_ptr(&g), my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { } continue_input( const continue_input& src ) : continue_receiver(src), my_graph_ptr(src.my_graph_ptr), my_body( src.my_body->clone() ) {} ~continue_input() { delete my_body; } template< typename Body > Body copy_function_object() { internal::function_body &body_ref = *my_body; return dynamic_cast< internal::function_body_leaf & >(body_ref).get_body(); } /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f)) { continue_receiver::reset_receiver(__TBB_PFG_RESET_ARG(f)); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES if(f & rf_reset_bodies) my_body->reset_body(); #endif } protected: graph* my_graph_ptr; function_body *my_body; virtual broadcast_cache &successors() = 0; friend class apply_body_task_bypass< continue_input< Output >, continue_msg >; //! Applies the body to the provided input /* override */ task *apply_body_bypass( input_type ) { #if TBB_PREVIEW_FLOW_GRAPH_TRACE // There is an extra copied needed to capture the // body execution without the try_put tbb::internal::fgt_begin_body( my_body ); output_type v = (*my_body)( continue_msg() ); tbb::internal::fgt_end_body( my_body ); return successors().try_put_task( v ); #else return successors().try_put_task( (*my_body)( continue_msg() ) ); #endif } //! Spawns a task that applies the body /* override */ task *execute( ) { task* tp = my_graph_ptr->root_task(); return (tp) ? new ( task::allocate_additional_child_of( *tp ) ) apply_body_task_bypass< continue_input< Output >, continue_msg >( *this, continue_msg() ) : NULL; } }; // continue_input //! Implements methods for both executable and function nodes that puts Output to its successors template< typename Output > class function_output : public sender { public: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES template friend struct reset_element; #endif typedef Output output_type; typedef receiver successor_type; typedef broadcast_cache broadcast_cache_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef std::vector successor_vector_type; #endif function_output() { my_successors.set_owner(this); } function_output(const function_output & /*other*/) : sender() { my_successors.set_owner(this); } //! Adds a new successor to this node /* override */ bool register_successor( receiver &r ) { successors().register_successor( r ); return true; } //! Removes a successor from this node /* override */ bool remove_successor( receiver &r ) { successors().remove_successor( r ); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES /*override*/ void internal_add_built_successor( receiver &r) { successors().internal_add_built_successor( r ); } /*override*/ void internal_delete_built_successor( receiver &r) { successors().internal_delete_built_successor( r ); } /*override*/ size_t successor_count() { return successors().successor_count(); } /*override*/ void copy_successors( successor_vector_type &v) { successors().copy_successors(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ // for multifunction_node. The function_body that implements // the node will have an input and an output tuple of ports. To put // an item to a successor, the body should // // get(output_ports).try_put(output_value); // // return value will be bool returned from successors.try_put. task *try_put_task(const output_type &i) { return my_successors.try_put_task(i); } protected: broadcast_cache_type my_successors; broadcast_cache_type &successors() { return my_successors; } }; // function_output template< typename Output > class multifunction_output : public function_output { public: typedef Output output_type; typedef function_output base_type; using base_type::my_successors; multifunction_output() : base_type() {my_successors.set_owner(this);} multifunction_output( const multifunction_output &/*other*/) : base_type() { my_successors.set_owner(this); } bool try_put(const output_type &i) { task *res = my_successors.try_put_task(i); if(!res) return false; if(res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res); return true; } }; // multifunction_output } // internal #endif // __TBB__flow_graph_node_impl_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_tagged_buffer_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // tagged buffer that can expand, and can support as many deletions as additions // list-based, with elements of list held in array (for destruction management), // multiplicative hashing (like ets). No synchronization built-in. // #ifndef __TBB__flow_graph_tagged_buffer_impl_H #define __TBB__flow_graph_tagged_buffer_impl_H #ifndef __TBB_flow_graph_H #error Do not #include this internal file directly; use public TBB headers instead. #endif // included in namespace tbb::flow::interface7::internal template struct otherData { T t; U next; otherData() : t(NoTagMark), next(NULL) {} }; template struct buffer_element_type { // the second parameter below is void * because we can't forward-declare the type // itself, so we just reinterpret_cast below. typedef typename aligned_pair >::type type; }; template < typename TagType, typename ValueType, size_t NoTagMark = 0, typename Allocator=tbb::cache_aligned_allocator< typename buffer_element_type::type > > class tagged_buffer { public: static const size_t INITIAL_SIZE = 8; // initial size of the hash pointer table static const TagType NO_TAG = TagType(NoTagMark); typedef ValueType value_type; typedef typename buffer_element_type::type element_type; typedef value_type *pointer_type; typedef element_type *list_array_type; // array we manage manually typedef list_array_type *pointer_array_type; typedef typename Allocator::template rebind::other pointer_array_allocator_type; typedef typename Allocator::template rebind::other elements_array_allocator; private: size_t my_size; size_t nelements; pointer_array_type pointer_array; // pointer_array[my_size] list_array_type elements_array; // elements_array[my_size / 2] element_type* free_list; size_t mask() { return my_size - 1; } static size_t hash(TagType t) { return uintptr_t(t)*tbb::internal::select_size_t_constant<0x9E3779B9,0x9E3779B97F4A7C15ULL>::value; } void set_up_free_list( element_type **p_free_list, list_array_type la, size_t sz) { for(size_t i=0; i < sz - 1; ++i ) { // construct free list la[i].second.next = &(la[i+1]); la[i].second.t = NO_TAG; } la[sz-1].second.next = NULL; *p_free_list = &(la[0]); } // cleanup for exceptions struct DoCleanup { pointer_array_type *my_pa; list_array_type *my_elements; size_t my_size; DoCleanup(pointer_array_type &pa, list_array_type &my_els, size_t sz) : my_pa(&pa), my_elements(&my_els), my_size(sz) { } ~DoCleanup() { if(my_pa) { size_t dont_care = 0; internal_free_buffer(*my_pa, *my_elements, my_size, dont_care); } } }; // exception-safety requires we do all the potentially-throwing operations first void grow_array() { size_t new_size = my_size*2; size_t new_nelements = nelements; // internal_free_buffer zeroes this list_array_type new_elements_array = NULL; pointer_array_type new_pointer_array = NULL; list_array_type new_free_list = NULL; { DoCleanup my_cleanup(new_pointer_array, new_elements_array, new_size); new_elements_array = elements_array_allocator().allocate(my_size); new_pointer_array = pointer_array_allocator_type().allocate(new_size); for(size_t i=0; i < new_size; ++i) new_pointer_array[i] = NULL; set_up_free_list(&new_free_list, new_elements_array, my_size ); for(size_t i=0; i < my_size; ++i) { for( element_type* op = pointer_array[i]; op; op = (element_type *)(op->second.next)) { value_type *ov = reinterpret_cast(&(op->first)); // could have std::move semantics internal_tagged_insert(new_pointer_array, new_size, new_free_list, op->second.t, *ov); } } my_cleanup.my_pa = NULL; my_cleanup.my_elements = NULL; } internal_free_buffer(pointer_array, elements_array, my_size, nelements); free_list = new_free_list; pointer_array = new_pointer_array; elements_array = new_elements_array; my_size = new_size; nelements = new_nelements; } // v should have perfect forwarding if std::move implemented. // we use this method to move elements in grow_array, so can't use class fields void internal_tagged_insert( element_type **p_pointer_array, size_t p_sz, list_array_type &p_free_list, const TagType t, const value_type &v) { size_t l_mask = p_sz-1; size_t h = hash(t) & l_mask; __TBB_ASSERT(p_free_list, "Error: free list not set up."); element_type* my_elem = p_free_list; p_free_list = (element_type *)(p_free_list->second.next); my_elem->second.t = t; (void) new(&(my_elem->first)) value_type(v); my_elem->second.next = p_pointer_array[h]; p_pointer_array[h] = my_elem; } void internal_initialize_buffer() { pointer_array = pointer_array_allocator_type().allocate(my_size); for(size_t i = 0; i < my_size; ++i) pointer_array[i] = NULL; elements_array = elements_array_allocator().allocate(my_size / 2); set_up_free_list(&free_list, elements_array, my_size / 2); } // made static so an enclosed class can use to properly dispose of the internals static void internal_free_buffer( pointer_array_type &pa, list_array_type &el, size_t &sz, size_t &ne ) { if(pa) { for(size_t i = 0; i < sz; ++i ) { element_type *p_next; for( element_type *p = pa[i]; p; p = p_next) { p_next = (element_type *)p->second.next; value_type *vp = reinterpret_cast(&(p->first)); vp->~value_type(); } } pointer_array_allocator_type().deallocate(pa, sz); pa = NULL; } // Separate test (if allocation of pa throws, el may be allocated. // but no elements will be constructed.) if(el) { elements_array_allocator().deallocate(el, sz / 2); el = NULL; } sz = INITIAL_SIZE; ne = 0; } public: tagged_buffer() : my_size(INITIAL_SIZE), nelements(0) { internal_initialize_buffer(); } ~tagged_buffer() { internal_free_buffer(pointer_array, elements_array, my_size, nelements); } void reset() { internal_free_buffer(pointer_array, elements_array, my_size, nelements); internal_initialize_buffer(); } bool tagged_insert(const TagType t, const value_type &v) { pointer_type p; if(tagged_find_ref(t, p)) { p->~value_type(); (void) new(p) value_type(v); // copy-construct into the space return false; } ++nelements; if(nelements*2 > my_size) grow_array(); internal_tagged_insert(pointer_array, my_size, free_list, t, v); return true; } // returns reference to array element.v bool tagged_find_ref(const TagType t, pointer_type &v) { size_t i = hash(t) & mask(); for(element_type* p = pointer_array[i]; p; p = (element_type *)(p->second.next)) { if(p->second.t == t) { v = reinterpret_cast(&(p->first)); return true; } } return false; } bool tagged_find( const TagType t, value_type &v) { value_type *p; if(tagged_find_ref(t, p)) { v = *p; return true; } else return false; } void tagged_delete(const TagType t) { size_t h = hash(t) & mask(); element_type* prev = NULL; for(element_type* p = pointer_array[h]; p; prev = p, p = (element_type *)(p->second.next)) { if(p->second.t == t) { value_type *vp = reinterpret_cast(&(p->first)); vp->~value_type(); p->second.t = NO_TAG; if(prev) prev->second.next = p->second.next; else pointer_array[h] = (element_type *)(p->second.next); p->second.next = free_list; free_list = p; --nelements; return; } } __TBB_ASSERT(false, "tag not found for delete"); } }; #endif // __TBB__flow_graph_tagged_buffer_impl_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_trace_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _FGT_GRAPH_TRACE_IMPL_H #define _FGT_GRAPH_TRACE_IMPL_H #include "../tbb_profiling.h" namespace tbb { namespace internal { #if TBB_PREVIEW_FLOW_GRAPH_TRACE static inline void fgt_internal_create_input_port( void *node, void *p, string_index name_index ) { itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index ); } static inline void fgt_internal_create_output_port( void *node, void *p, string_index name_index ) { itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index ); } template < typename TypesTuple, typename PortsTuple, int N > struct fgt_internal_input_helper { static void register_port( void *node, PortsTuple &ports ) { fgt_internal_create_input_port( node, (void*)static_cast< tbb::flow::interface7::receiver< typename tbb::flow::tuple_element::type > * >(&(tbb::flow::get(ports))), static_cast(FLOW_INPUT_PORT_0 + N - 1) ); fgt_internal_input_helper::register_port( node, ports ); } }; template < typename TypesTuple, typename PortsTuple > struct fgt_internal_input_helper { static void register_port( void *node, PortsTuple &ports ) { fgt_internal_create_input_port( node, (void*)static_cast< tbb::flow::interface7::receiver< typename tbb::flow::tuple_element<0,TypesTuple>::type > * >(&(tbb::flow::get<0>(ports))), FLOW_INPUT_PORT_0 ); } }; template < typename TypesTuple, typename PortsTuple, int N > struct fgt_internal_output_helper { static void register_port( void *node, PortsTuple &ports ) { fgt_internal_create_output_port( node, (void*)static_cast< tbb::flow::interface7::sender< typename tbb::flow::tuple_element::type > * >(&(tbb::flow::get(ports))), static_cast(FLOW_OUTPUT_PORT_0 + N - 1) ); fgt_internal_output_helper::register_port( node, ports ); } }; template < typename TypesTuple, typename PortsTuple > struct fgt_internal_output_helper { static void register_port( void *node, PortsTuple &ports ) { fgt_internal_create_output_port( node, (void*)static_cast< tbb::flow::interface7::sender< typename tbb::flow::tuple_element<0,TypesTuple>::type > * >(&(tbb::flow::get<0>(ports))), FLOW_OUTPUT_PORT_0 ); } }; template< typename NodeType > void fgt_multioutput_node_desc( const NodeType *node, const char *desc ) { void *addr = (void *)( static_cast< tbb::flow::interface7::receiver< typename NodeType::input_type > * >(const_cast< NodeType *>(node)) ); itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); } template< typename NodeType > static inline void fgt_node_desc( const NodeType *node, const char *desc ) { void *addr = (void *)( static_cast< tbb::flow::interface7::sender< typename NodeType::output_type > * >(const_cast< NodeType *>(node)) ); itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); } static inline void fgt_graph_desc( void *g, const char *desc ) { itt_metadata_str_add( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, FLOW_OBJECT_NAME, desc ); } static inline void fgt_body( void *node, void *body ) { itt_relation_add( ITT_DOMAIN_FLOW, body, FLOW_BODY, __itt_relation_is_child_of, node, FLOW_NODE ); } template< typename OutputTuple, int N, typename PortsTuple > static inline void fgt_multioutput_node( string_index t, void *g, void *input_port, PortsTuple &ports ) { itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); fgt_internal_output_helper::register_port( input_port, ports ); } template< typename OutputTuple, int N, typename PortsTuple > static inline void fgt_multioutput_node_with_body( string_index t, void *g, void *input_port, PortsTuple &ports, void *body ) { itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); fgt_internal_output_helper::register_port( input_port, ports ); fgt_body( input_port, body ); } template< typename InputTuple, int N, typename PortsTuple > static inline void fgt_multiinput_node( string_index t, void *g, PortsTuple &ports, void *output_port) { itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); fgt_internal_input_helper::register_port( output_port, ports ); } static inline void fgt_node( string_index t, void *g, void *output_port ) { itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); } static inline void fgt_node_with_body( string_index t, void *g, void *output_port, void *body ) { itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); fgt_body( output_port, body ); } static inline void fgt_node( string_index t, void *g, void *input_port, void *output_port ) { fgt_node( t, g, output_port ); fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 ); } static inline void fgt_node_with_body( string_index t, void *g, void *input_port, void *output_port, void *body ) { fgt_node_with_body( t, g, output_port, body ); fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 ); } static inline void fgt_node( string_index t, void *g, void *input_port, void *decrement_port, void *output_port ) { fgt_node( t, g, input_port, output_port ); fgt_internal_create_input_port( output_port, decrement_port, FLOW_INPUT_PORT_1 ); } static inline void fgt_make_edge( void *output_port, void *input_port ) { itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_predecessor_to, input_port, FLOW_INPUT_PORT); } static inline void fgt_remove_edge( void *output_port, void *input_port ) { itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_sibling_of, input_port, FLOW_INPUT_PORT); } static inline void fgt_graph( void *g ) { itt_make_task_group( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, NULL, FLOW_NULL, FLOW_GRAPH ); } static inline void fgt_begin_body( void *body ) { itt_task_begin( ITT_DOMAIN_FLOW, body, FLOW_BODY, NULL, FLOW_NULL, FLOW_NULL ); } static inline void fgt_end_body( void * ) { itt_task_end( ITT_DOMAIN_FLOW ); } #else // TBB_PREVIEW_FLOW_GRAPH_TRACE static inline void fgt_graph( void * /*g*/ ) { } template< typename NodeType > static inline void fgt_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { } template< typename NodeType > static inline void fgt_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { } static inline void fgt_graph_desc( void * /*g*/, const char * /*desc*/ ) { } static inline void fgt_body( void * /*node*/, void * /*body*/ ) { } template< typename OutputTuple, int N, typename PortsTuple > static inline void fgt_multioutput_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/ ) { } template< typename OutputTuple, int N, typename PortsTuple > static inline void fgt_multioutput_node_with_body( string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/, void * /*body*/ ) { } template< typename InputTuple, int N, typename PortsTuple > static inline void fgt_multiinput_node( string_index /*t*/, void * /*g*/, PortsTuple & /*ports*/, void * /*output_port*/ ) { } static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*output_port*/ ) { } static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/ ) { } static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*decrement_port*/, void * /*output_port*/ ) { } static inline void fgt_node_with_body( string_index /*t*/, void * /*g*/, void * /*output_port*/, void * /*body*/ ) { } static inline void fgt_node_with_body( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/, void * /*body*/ ) { } static inline void fgt_make_edge( void * /*output_port*/, void * /*input_port*/ ) { } static inline void fgt_remove_edge( void * /*output_port*/, void * /*input_port*/ ) { } static inline void fgt_begin_body( void * /*body*/ ) { } static inline void fgt_end_body( void * /*body*/) { } #endif // TBB_PREVIEW_FLOW_GRAPH_TRACE } // namespace internal } // namespace tbb #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_flow_graph_types_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__flow_graph_types_impl_H #define __TBB__flow_graph_types_impl_H #ifndef __TBB_flow_graph_H #error Do not #include this internal file directly; use public TBB headers instead. #endif // included in namespace tbb::flow::interface7 namespace internal { // wrap each element of a tuple in a template, and make a tuple of the result. template class PT, typename TypeTuple> struct wrap_tuple_elements; template class PT, typename TypeTuple> struct wrap_tuple_elements<1, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type> > type; }; template class PT, typename TypeTuple> struct wrap_tuple_elements<2, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type> > type; }; template class PT, typename TypeTuple> struct wrap_tuple_elements<3, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type> > type; }; template class PT, typename TypeTuple> struct wrap_tuple_elements<4, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type>, PT::type> > type; }; template class PT, typename TypeTuple> struct wrap_tuple_elements<5, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type>, PT::type>, PT::type> > type; }; #if __TBB_VARIADIC_MAX >= 6 template class PT, typename TypeTuple> struct wrap_tuple_elements<6, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type> > type; }; #endif #if __TBB_VARIADIC_MAX >= 7 template class PT, typename TypeTuple> struct wrap_tuple_elements<7, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type> > type; }; #endif #if __TBB_VARIADIC_MAX >= 8 template class PT, typename TypeTuple> struct wrap_tuple_elements<8, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type> > type; }; #endif #if __TBB_VARIADIC_MAX >= 9 template class PT, typename TypeTuple> struct wrap_tuple_elements<9, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type> > type; }; #endif #if __TBB_VARIADIC_MAX >= 10 template class PT, typename TypeTuple> struct wrap_tuple_elements<10, PT, TypeTuple> { typedef typename tbb::flow::tuple< PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type>, PT::type> > type; }; #endif //! type mimicking std::pair but with trailing fill to ensure each element of an array //* will have the correct alignment template struct type_plus_align { char first[sizeof(T1)]; T2 second; char fill1[REM]; }; template struct type_plus_align { char first[sizeof(T1)]; T2 second; }; template struct alignment_of { typedef struct { char t; U padded; } test_alignment; static const size_t value = sizeof(test_alignment) - sizeof(U); }; // T1, T2 are actual types stored. The space defined for T1 in the type returned // is a char array of the correct size. Type T2 should be trivially-constructible, // T1 must be explicitly managed. template struct aligned_pair { static const size_t t1_align = alignment_of::value; static const size_t t2_align = alignment_of::value; typedef type_plus_align just_pair; static const size_t max_align = t1_align < t2_align ? t2_align : t1_align; static const size_t extra_bytes = sizeof(just_pair) % max_align; static const size_t remainder = extra_bytes ? max_align - extra_bytes : 0; public: typedef type_plus_align type; }; // aligned_pair // support for variant type // type we use when we're not storing a value struct default_constructed { }; // type which contains another type, tests for what type is contained, and references to it. // internal::Wrapper // void CopyTo( void *newSpace) : builds a Wrapper copy of itself in newSpace // struct to allow us to copy and test the type of objects struct WrapperBase { virtual ~WrapperBase() {} virtual void CopyTo(void* /*newSpace*/) const { } }; // Wrapper contains a T, with the ability to test what T is. The Wrapper can be // constructed from a T, can be copy-constructed from another Wrapper, and can be // examined via value(), but not modified. template struct Wrapper: public WrapperBase { typedef T value_type; typedef T* pointer_type; private: T value_space; public: const value_type &value() const { return value_space; } private: Wrapper(); // on exception will ensure the Wrapper will contain only a trivially-constructed object struct _unwind_space { pointer_type space; _unwind_space(pointer_type p) : space(p) {} ~_unwind_space() { if(space) (void) new (space) Wrapper(default_constructed()); } }; public: explicit Wrapper( const T& other ) : value_space(other) { } explicit Wrapper(const Wrapper& other) : value_space(other.value_space) { } /*override*/void CopyTo(void* newSpace) const { _unwind_space guard((pointer_type)newSpace); (void) new(newSpace) Wrapper(value_space); guard.space = NULL; } /*override*/~Wrapper() { } }; // specialization for array objects template struct Wrapper : public WrapperBase { typedef T value_type; typedef T* pointer_type; // space must be untyped. typedef T ArrayType[N]; private: // The space is not of type T[N] because when copy-constructing, it would be // default-initialized and then copied to in some fashion, resulting in two // constructions and one destruction per element. If the type is char[ ], we // placement new into each element, resulting in one construction per element. static const size_t space_size = sizeof(ArrayType) / sizeof(char); char value_space[space_size]; // on exception will ensure the already-built objects will be destructed // (the value_space is a char array, so it is already trivially-destructible.) struct _unwind_class { pointer_type space; int already_built; _unwind_class(pointer_type p) : space(p), already_built(0) {} ~_unwind_class() { if(space) { for(size_t i = already_built; i > 0 ; --i ) space[i-1].~value_type(); (void) new(space) Wrapper(default_constructed()); } } }; public: const ArrayType &value() const { char *vp = const_cast(value_space); return reinterpret_cast(*vp); } private: Wrapper(); public: // have to explicitly construct because other decays to a const value_type* explicit Wrapper(const ArrayType& other) { _unwind_class guard((pointer_type)value_space); pointer_type vp = reinterpret_cast(&value_space); for(size_t i = 0; i < N; ++i ) { (void) new(vp++) value_type(other[i]); ++(guard.already_built); } guard.space = NULL; } explicit Wrapper(const Wrapper& other) : WrapperBase() { // we have to do the heavy lifting to copy contents _unwind_class guard((pointer_type)value_space); pointer_type dp = reinterpret_cast(value_space); pointer_type sp = reinterpret_cast(const_cast(other.value_space)); for(size_t i = 0; i < N; ++i, ++dp, ++sp) { (void) new(dp) value_type(*sp); ++(guard.already_built); } guard.space = NULL; } /*override*/void CopyTo(void* newSpace) const { (void) new(newSpace) Wrapper(*this); // exceptions handled in copy constructor } /*override*/~Wrapper() { // have to destroy explicitly in reverse order pointer_type vp = reinterpret_cast(&value_space); for(size_t i = N; i > 0 ; --i ) vp[i-1].~value_type(); } }; // given a tuple, return the type of the element that has the maximum alignment requirement. // Given a tuple and that type, return the number of elements of the object with the max // alignment requirement that is at least as big as the largest object in the tuple. template struct pick_one; template struct pick_one { typedef T1 type; }; template struct pick_one { typedef T2 type; }; template< template class Selector, typename T1, typename T2 > struct pick_max { typedef typename pick_one< (Selector::value > Selector::value), T1, T2 >::type type; }; template struct size_of { static const int value = sizeof(T); }; template< size_t N, class Tuple, template class Selector > struct pick_tuple_max { typedef typename pick_tuple_max::type LeftMaxType; typedef typename tbb::flow::tuple_element::type ThisType; typedef typename pick_max::type type; }; template< class Tuple, template class Selector > struct pick_tuple_max<0, Tuple, Selector> { typedef typename tbb::flow::tuple_element<0, Tuple>::type type; }; // is the specified type included in a tuple? template struct is_same_type { static const bool value = false; }; template struct is_same_type { static const bool value = true; }; template struct is_element_of { typedef typename tbb::flow::tuple_element::type T_i; static const bool value = is_same_type::value || is_element_of::value; }; template struct is_element_of { typedef typename tbb::flow::tuple_element<0, Tuple>::type T_i; static const bool value = is_same_type::value; }; // allow the construction of types that are listed tuple. If a disallowed type // construction is written, a method involving this type is created. The // type has no definition, so a syntax error is generated. template struct ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple; template struct do_if; template struct do_if { static void construct(void *mySpace, const T& x) { (void) new(mySpace) Wrapper(x); } }; template struct do_if { static void construct(void * /*mySpace*/, const T& x) { // This method is instantiated when the type T does not match any of the // element types in the Tuple in variant. ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple::bad_type(x); } }; // Tuple tells us the allowed types that variant can hold. It determines the alignment of the space in // Wrapper, and how big Wrapper is. // // the object can only be tested for type, and a read-only reference can be fetched by cast_to(). using tbb::internal::punned_cast; struct tagged_null_type {}; template class tagged_msg { typedef tbb::flow::tuple= 6 , T5 #endif #if __TBB_VARIADIC_MAX >= 7 , T6 #endif #if __TBB_VARIADIC_MAX >= 8 , T7 #endif #if __TBB_VARIADIC_MAX >= 9 , T8 #endif #if __TBB_VARIADIC_MAX >= 10 , T9 #endif > Tuple; private: class variant { static const size_t N = tbb::flow::tuple_size::value; typedef typename pick_tuple_max::type AlignType; typedef typename pick_tuple_max::type MaxSizeType; static const size_t MaxNBytes = (sizeof(Wrapper)+sizeof(AlignType)-1); static const size_t MaxNElements = MaxNBytes/sizeof(AlignType); typedef typename tbb::aligned_space SpaceType; SpaceType my_space; static const size_t MaxSize = sizeof(SpaceType); public: variant() { (void) new(&my_space) Wrapper(default_constructed()); } template variant( const T& x ) { do_if::value>::construct(&my_space,x); } variant(const variant& other) { const WrapperBase * h = punned_cast(&(other.my_space)); h->CopyTo(&my_space); } // assignment must destroy and re-create the Wrapper type, as there is no way // to create a Wrapper-to-Wrapper assign even if we find they agree in type. void operator=( const variant& rhs ) { if(&rhs != this) { WrapperBase *h = punned_cast(&my_space); h->~WrapperBase(); const WrapperBase *ch = punned_cast(&(rhs.my_space)); ch->CopyTo(&my_space); } } template const U& variant_cast_to() const { const Wrapper *h = dynamic_cast*>(punned_cast(&my_space)); if(!h) { tbb::internal::throw_exception(tbb::internal::eid_bad_tagged_msg_cast); } return h->value(); } template bool variant_is_a() const { return dynamic_cast*>(punned_cast(&my_space)) != NULL; } bool variant_is_default_constructed() const {return variant_is_a();} ~variant() { WrapperBase *h = punned_cast(&my_space); h->~WrapperBase(); } }; //class variant TagType my_tag; variant my_msg; public: tagged_msg(): my_tag(TagType(~0)), my_msg(){} template tagged_msg(T const &index, R const &value) : my_tag(index), my_msg(value) {} #if __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN template tagged_msg(T const &index, R (&value)[N]) : my_tag(index), my_msg(value) {} #endif void set_tag(TagType const &index) {my_tag = index;} TagType tag() const {return my_tag;} template const V& cast_to() const {return my_msg.template variant_cast_to();} template bool is_a() const {return my_msg.template variant_is_a();} bool is_default_constructed() const {return my_msg.variant_is_default_constructed();} }; //class tagged_msg // template to simplify cast and test for tagged_msg in template contexts template const T& cast_to(V const &v) { return v.template cast_to(); } template bool is_a(V const &v) { return v.template is_a(); } } // namespace internal #endif /* __TBB__flow_graph_types_impl_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_mutex_padding.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_mutex_padding_H #define __TBB_mutex_padding_H // wrapper for padding mutexes to be alone on a cache line, without requiring they be allocated // from a pool. Because we allow them to be defined anywhere they must be two cache lines in size. namespace tbb { namespace interface7 { namespace internal { static const size_t cache_line_size = 64; // Pad a mutex to occupy a number of full cache lines sufficient to avoid false sharing // with other data; space overhead is up to 2*cache_line_size-1. template class padded_mutex; template class padded_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { typedef long pad_type; pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)]; Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);} public: static const bool is_rw_mutex = Mutex::is_rw_mutex; static const bool is_recursive_mutex = Mutex::is_recursive_mutex; static const bool is_fair_mutex = Mutex::is_fair_mutex; padded_mutex() { new(impl()) Mutex(); } ~padded_mutex() { impl()->~Mutex(); } //! Represents acquisition of a mutex. class scoped_lock : tbb::internal::no_copy { typename Mutex::scoped_lock my_scoped_lock; public: scoped_lock() : my_scoped_lock() {} scoped_lock( padded_mutex& m ) : my_scoped_lock(*m.impl()) { } ~scoped_lock() { } void acquire( padded_mutex& m ) { my_scoped_lock.acquire(*m.impl()); } bool try_acquire( padded_mutex& m ) { return my_scoped_lock.try_acquire(*m.impl()); } void release() { my_scoped_lock.release(); } }; }; template class padded_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { typedef long pad_type; pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)]; Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);} public: static const bool is_rw_mutex = Mutex::is_rw_mutex; static const bool is_recursive_mutex = Mutex::is_recursive_mutex; static const bool is_fair_mutex = Mutex::is_fair_mutex; padded_mutex() { new(impl()) Mutex(); } ~padded_mutex() { impl()->~Mutex(); } //! Represents acquisition of a mutex. class scoped_lock : tbb::internal::no_copy { typename Mutex::scoped_lock my_scoped_lock; public: scoped_lock() : my_scoped_lock() {} scoped_lock( padded_mutex& m, bool write = true ) : my_scoped_lock(*m.impl(),write) { } ~scoped_lock() { } void acquire( padded_mutex& m, bool write = true ) { my_scoped_lock.acquire(*m.impl(),write); } bool try_acquire( padded_mutex& m, bool write = true ) { return my_scoped_lock.try_acquire(*m.impl(),write); } bool upgrade_to_writer() { return my_scoped_lock.upgrade_to_writer(); } bool downgrade_to_reader() { return my_scoped_lock.downgrade_to_reader(); } void release() { my_scoped_lock.release(); } }; }; } // namespace internal } // namespace interface7 } // namespace tbb #endif /* __TBB_mutex_padding_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_range_iterator.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_range_iterator_H #define __TBB_range_iterator_H #include "../tbb_stddef.h" #if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT #include #endif namespace tbb { // iterators to first and last elements of container namespace internal { #if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT using std::begin; using std::end; template auto first(Container& c)-> decltype(begin(c)) {return begin(c);} template auto first(const Container& c)-> decltype(begin(c)) {return begin(c);} template auto last(Container& c)-> decltype(begin(c)) {return end(c);} template auto last(const Container& c)-> decltype(begin(c)) {return end(c);} #else template typename Container::iterator first(Container& c) {return c.begin();} template typename Container::const_iterator first(const Container& c) {return c.begin();} template typename Container::iterator last(Container& c) {return c.end();} template typename Container::const_iterator last(const Container& c) {return c.end();} #endif template T* first(T (&arr) [size]) {return arr;} template T* last(T (&arr) [size]) {return arr + size;} } //namespace internal } //namespace tbb #endif // __TBB_range_iterator_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_tbb_strings.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ TBB_STRING_RESOURCE(FLOW_BROADCAST_NODE, "broadcast_node") TBB_STRING_RESOURCE(FLOW_BUFFER_NODE, "buffer_node") TBB_STRING_RESOURCE(FLOW_CONTINUE_NODE, "continue_node") TBB_STRING_RESOURCE(FLOW_FUNCTION_NODE, "function_node") TBB_STRING_RESOURCE(FLOW_JOIN_NODE_QUEUEING, "join_node (queueing)") TBB_STRING_RESOURCE(FLOW_JOIN_NODE_RESERVING, "join_node (reserving)") TBB_STRING_RESOURCE(FLOW_JOIN_NODE_TAG_MATCHING, "join_node (tag_matching)") TBB_STRING_RESOURCE(FLOW_LIMITER_NODE, "limiter_node") TBB_STRING_RESOURCE(FLOW_MULTIFUNCTION_NODE, "multifunction_node") TBB_STRING_RESOURCE(FLOW_OR_NODE, "or_node") //no longer in use, kept for backward compatibilty TBB_STRING_RESOURCE(FLOW_OVERWRITE_NODE, "overwrite_node") TBB_STRING_RESOURCE(FLOW_PRIORITY_QUEUE_NODE, "priority_queue_node") TBB_STRING_RESOURCE(FLOW_QUEUE_NODE, "queue_node") TBB_STRING_RESOURCE(FLOW_SEQUENCER_NODE, "sequencer_node") TBB_STRING_RESOURCE(FLOW_SOURCE_NODE, "source_node") TBB_STRING_RESOURCE(FLOW_SPLIT_NODE, "split_node") TBB_STRING_RESOURCE(FLOW_WRITE_ONCE_NODE, "write_once_node") TBB_STRING_RESOURCE(FLOW_BODY, "body") TBB_STRING_RESOURCE(FLOW_GRAPH, "graph") TBB_STRING_RESOURCE(FLOW_NODE, "node") TBB_STRING_RESOURCE(FLOW_INPUT_PORT, "input_port") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_0, "input_port_0") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_1, "input_port_1") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_2, "input_port_2") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_3, "input_port_3") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_4, "input_port_4") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_5, "input_port_5") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_6, "input_port_6") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_7, "input_port_7") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_8, "input_port_8") TBB_STRING_RESOURCE(FLOW_INPUT_PORT_9, "input_port_9") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT, "output_port") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_0, "output_port_0") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_1, "output_port_1") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_2, "output_port_2") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_3, "output_port_3") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_4, "output_port_4") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_5, "output_port_5") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_6, "output_port_6") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_7, "output_port_7") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_8, "output_port_8") TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_9, "output_port_9") TBB_STRING_RESOURCE(FLOW_OBJECT_NAME, "object_name") TBB_STRING_RESOURCE(FLOW_NULL, "null") TBB_STRING_RESOURCE(FLOW_INDEXER_NODE, "indexer_node") ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_tbb_windef.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_windef_H #error Do not #include this internal file directly; use public TBB headers instead. #endif /* __TBB_tbb_windef_H */ // Check that the target Windows version has all API calls requried for TBB. // Do not increase the version in condition beyond 0x0500 without prior discussion! #if defined(_WIN32_WINNT) && _WIN32_WINNT<0x0501 #error TBB is unable to run on old Windows versions; _WIN32_WINNT must be 0x0501 or greater. #endif #if !defined(_MT) #error TBB requires linkage with multithreaded C/C++ runtime library. \ Choose multithreaded DLL runtime in project settings, or use /MD[d] compiler switch. #endif // Workaround for the problem with MVSC headers failing to define namespace std namespace std { using ::size_t; using ::ptrdiff_t; } #define __TBB_STRING_AUX(x) #x #define __TBB_STRING(x) __TBB_STRING_AUX(x) // Default setting of TBB_USE_DEBUG #ifdef TBB_USE_DEBUG # if TBB_USE_DEBUG # if !defined(_DEBUG) # pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MDd if compiling with TBB_USE_DEBUG!=0") # endif # else # if defined(_DEBUG) # pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MD if compiling with TBB_USE_DEBUG==0") # endif # endif #endif #if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBB_NO_IMPLICIT_LINKAGE) #define __TBB_NO_IMPLICIT_LINKAGE 1 #endif #if _MSC_VER #if !__TBB_NO_IMPLICIT_LINKAGE #ifdef __TBB_LIB_NAME #pragma comment(lib, __TBB_STRING(__TBB_LIB_NAME)) #else #ifdef _DEBUG #pragma comment(lib, "tbb_debug.lib") #else #pragma comment(lib, "tbb.lib") #endif #endif #endif #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_x86_eliding_mutex_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__x86_eliding_mutex_impl_H #define __TBB__x86_eliding_mutex_impl_H #ifndef __TBB_spin_mutex_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #if ( __TBB_x86_32 || __TBB_x86_64 ) namespace tbb { namespace interface7 { namespace internal { template class padded_mutex; //! An eliding lock that occupies a single byte. /** A x86_eliding_mutex is an HLE-enabled spin mutex. It is recommended to put the mutex on a cache line that is not shared by the data it protects. It should be used for locking short critical sections where the lock is contended but the data it protects are not. If zero-initialized, the mutex is considered unheld. @ingroup synchronization */ class x86_eliding_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { //! 0 if lock is released, 1 if lock is acquired. __TBB_atomic_flag flag; friend class padded_mutex; public: //! Construct unacquired lock. /** Equivalent to zero-initialization of *this. */ x86_eliding_mutex() : flag(0) {} // bug in gcc 3.x.x causes syntax error in spite of the friend declaration above. // Make the scoped_lock public in that case. #if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000 #else // by default we will not provide the scoped_lock interface. The user // should use the padded version of the mutex. scoped_lock is used in // padded_mutex template. private: #endif // scoped_lock in padded_mutex<> is the interface to use. //! Represents acquisition of a mutex. class scoped_lock : tbb::internal::no_copy { private: //! Points to currently held mutex, or NULL if no lock is held. x86_eliding_mutex* my_mutex; public: //! Construct without acquiring a mutex. scoped_lock() : my_mutex(NULL) {} //! Construct and acquire lock on a mutex. scoped_lock( x86_eliding_mutex& m ) : my_mutex(NULL) { acquire(m); } //! Acquire lock. void acquire( x86_eliding_mutex& m ) { __TBB_ASSERT( !my_mutex, "already holding a lock" ); my_mutex=&m; my_mutex->lock(); } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_acquire( x86_eliding_mutex& m ) { __TBB_ASSERT( !my_mutex, "already holding a lock" ); bool result = m.try_lock(); if( result ) { my_mutex = &m; } return result; } //! Release lock void release() { __TBB_ASSERT( my_mutex, "release on scoped_lock that is not holding a lock" ); my_mutex->unlock(); my_mutex = NULL; } //! Destroy lock. If holding a lock, releases the lock first. ~scoped_lock() { if( my_mutex ) { release(); } } }; #if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000 #else public: #endif /* __TBB_USE_X86_ELIDING_MUTEX */ // Mutex traits static const bool is_rw_mutex = false; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = false; // ISO C++0x compatibility methods //! Acquire lock void lock() { __TBB_LockByteElided(flag); } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_lock() { return __TBB_TryLockByteElided(flag); } //! Release lock void unlock() { __TBB_UnlockByteElided( flag ); } }; // end of x86_eliding_mutex } // namespace internal } // namespace interface7 } // namespace tbb #endif /* ( __TBB_x86_32 || __TBB_x86_64 ) */ #endif /* __TBB__x86_eliding_mutex_impl_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/internal/_x86_rtm_rw_mutex_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB__x86_rtm_rw_mutex_impl_H #define __TBB__x86_rtm_rw_mutex_impl_H #ifndef __TBB_spin_rw_mutex_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #if __TBB_TSX_AVAILABLE #include "../tbb_stddef.h" #include "../tbb_machine.h" #include "../tbb_profiling.h" #include "../spin_rw_mutex.h" namespace tbb { namespace interface8 { namespace internal { enum RTM_type { RTM_not_in_mutex, RTM_transacting_reader, RTM_transacting_writer, RTM_real_reader, RTM_real_writer }; static const unsigned long speculation_granularity = 64; //! Fast, unfair, spinning speculation-enabled reader-writer lock with backoff and // writer-preference /** @ingroup synchronization */ class x86_rtm_rw_mutex: private spin_rw_mutex { #if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000 // bug in gcc 3.x.x causes syntax error in spite of the friend declaration below. // Make the scoped_lock public in that case. public: #else private: #endif friend class interface7::internal::padded_mutex; class scoped_lock; // should be private friend class scoped_lock; private: //! @cond INTERNAL //! Internal construct unacquired mutex. void __TBB_EXPORTED_METHOD internal_construct(); //! Internal acquire write lock. // only_speculate == true if we're doing a try_lock, else false. void __TBB_EXPORTED_METHOD internal_acquire_writer(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false); //! Internal acquire read lock. // only_speculate == true if we're doing a try_lock, else false. void __TBB_EXPORTED_METHOD internal_acquire_reader(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false); //! Internal upgrade reader to become a writer. bool __TBB_EXPORTED_METHOD internal_upgrade( x86_rtm_rw_mutex::scoped_lock& ); //! Out of line code for downgrading a writer to a reader. bool __TBB_EXPORTED_METHOD internal_downgrade( x86_rtm_rw_mutex::scoped_lock& ); //! Internal try_acquire write lock. bool __TBB_EXPORTED_METHOD internal_try_acquire_writer( x86_rtm_rw_mutex::scoped_lock& ); //! Internal release lock. void __TBB_EXPORTED_METHOD internal_release( x86_rtm_rw_mutex::scoped_lock& ); static x86_rtm_rw_mutex* internal_get_mutex( const spin_rw_mutex::scoped_lock& lock ) { return static_cast( lock.internal_get_mutex() ); } static void internal_set_mutex( spin_rw_mutex::scoped_lock& lock, spin_rw_mutex* mtx ) { lock.internal_set_mutex( mtx ); } //! @endcond public: //! Construct unacquired mutex. x86_rtm_rw_mutex() { w_flag = false; #if TBB_USE_THREADING_TOOLS internal_construct(); #endif } #if TBB_USE_ASSERT //! Empty destructor. ~x86_rtm_rw_mutex() {} #endif /* TBB_USE_ASSERT */ // Mutex traits static const bool is_rw_mutex = true; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = false; #if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000 #else // by default we will not provide the scoped_lock interface. The user // should use the padded version of the mutex. scoped_lock is used in // padded_mutex template. private: #endif //! The scoped locking pattern /** It helps to avoid the common problem of forgetting to release lock. It also nicely provides the "node" for queuing locks. */ // Speculation-enabled scoped lock for spin_rw_mutex // The idea is to be able to reuse the acquire/release methods of spin_rw_mutex // and its scoped lock wherever possible. The only way to use a speculative lock is to use // a scoped_lock. (because transaction_state must be local) class scoped_lock : tbb::internal::no_copy { friend class x86_rtm_rw_mutex; spin_rw_mutex::scoped_lock my_scoped_lock; RTM_type transaction_state; public: //! Construct lock that has not acquired a mutex. /** Equivalent to zero-initialization of *this. */ scoped_lock() : my_scoped_lock(), transaction_state(RTM_not_in_mutex) { } //! Acquire lock on given mutex. scoped_lock( x86_rtm_rw_mutex& m, bool write = true ) : my_scoped_lock(), transaction_state(RTM_not_in_mutex) { acquire(m, write); } //! Release lock (if lock is held). ~scoped_lock() { if(transaction_state != RTM_not_in_mutex) release(); } //! Acquire lock on given mutex. void acquire( x86_rtm_rw_mutex& m, bool write = true ) { if( write ) m.internal_acquire_writer(*this); else m.internal_acquire_reader(*this); } //! Release lock void release() { x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); __TBB_ASSERT( mutex, "lock is not acquired" ); __TBB_ASSERT( transaction_state!=RTM_not_in_mutex, "lock is not acquired" ); return mutex->internal_release(*this); } //! Upgrade reader to become a writer. /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ bool upgrade_to_writer() { x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); __TBB_ASSERT( mutex, "lock is not acquired" ); __TBB_ASSERT( transaction_state==RTM_transacting_reader || transaction_state==RTM_real_reader, "Invalid state for upgrade" ); return mutex->internal_upgrade(*this); } //! Downgrade writer to become a reader. /** Returns whether the downgrade happened without releasing and re-acquiring the lock */ bool downgrade_to_reader() { x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); __TBB_ASSERT( mutex, "lock is not acquired" ); __TBB_ASSERT( transaction_state==RTM_transacting_writer || transaction_state==RTM_real_writer, "Invalid state for downgrade" ); return mutex->internal_downgrade(*this); } //! Attempt to acquire mutex. /** returns true if successful. */ bool try_acquire( x86_rtm_rw_mutex& m, bool write = true ) { #if TBB_USE_ASSERT x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); __TBB_ASSERT( !mutex, "lock is already acquired" ); #endif // have to assign m to our mutex. // cannot set the mutex, because try_acquire in spin_rw_mutex depends on it being NULL. if(write) return m.internal_try_acquire_writer(*this); // speculatively acquire the lock. If this fails, do try_acquire on the spin_rw_mutex. m.internal_acquire_reader(*this, /*only_speculate=*/true); if(transaction_state == RTM_transacting_reader) return true; if( my_scoped_lock.try_acquire(m, false)) { transaction_state = RTM_real_reader; return true; } return false; } }; // class x86_rtm_rw_mutex::scoped_lock // ISO C++0x compatibility methods not provided because we cannot maintain // state about whether a thread is in a transaction. private: char pad[speculation_granularity-sizeof(spin_rw_mutex)]; // padding // If true, writer holds the spin_rw_mutex. tbb::atomic w_flag; // want this on a separate cache line }; // x86_rtm_rw_mutex } // namespace internal } // namespace interface8 } // namespace tbb #endif /* __TBB_TSX_AVAILABLE */ #endif /* __TBB__x86_rtm_rw_mutex_impl_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/intrusive_list.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_intrusive_list_H #define _TBB_intrusive_list_H #include "tbb/tbb_stddef.h" namespace tbb { namespace internal { //! Data structure to be inherited by the types that can form intrusive lists. /** Intrusive list is formed by means of the member_intrusive_list template class. Note that type T must derive from intrusive_list_node either publicly or declare instantiation member_intrusive_list as a friend. This class implements a limited subset of std::list interface. **/ struct intrusive_list_node { intrusive_list_node *my_prev_node, *my_next_node; #if TBB_USE_ASSERT intrusive_list_node () { my_prev_node = my_next_node = this; } #endif /* TBB_USE_ASSERT */ }; //! List of element of type T, where T is derived from intrusive_list_node /** The class is not thread safe. **/ template class intrusive_list_base { //! Pointer to the head node intrusive_list_node my_head; //! Number of list elements size_t my_size; static intrusive_list_node& node ( T& item ) { return List::node(item); } static T& item ( intrusive_list_node* node ) { return List::item(node); } template class iterator_impl { Iterator& self () { return *static_cast(this); } //! Node the iterator points to at the moment intrusive_list_node *my_pos; protected: iterator_impl (intrusive_list_node* pos ) : my_pos(pos) {} T& item () const { return intrusive_list_base::item(my_pos); } public: iterator_impl () : my_pos(NULL) {} Iterator& operator = ( const Iterator& it ) { return my_pos = it.my_pos; } Iterator& operator = ( const T& val ) { return my_pos = &node(val); } bool operator == ( const Iterator& it ) const { return my_pos == it.my_pos; } bool operator != ( const Iterator& it ) const { return my_pos != it.my_pos; } Iterator& operator++ () { my_pos = my_pos->my_next_node; return self(); } Iterator& operator-- () { my_pos = my_pos->my_prev_node; return self(); } Iterator operator++ ( int ) { Iterator result = self(); ++(*this); return result; } Iterator operator-- ( int ) { Iterator result = self(); --(*this); return result; } }; // intrusive_list_base::iterator_impl void assert_ok () const { __TBB_ASSERT( (my_head.my_prev_node == &my_head && !my_size) || (my_head.my_next_node != &my_head && my_size >0), "intrusive_list_base corrupted" ); #if TBB_USE_ASSERT >= 2 size_t i = 0; for ( intrusive_list_node *n = my_head.my_next_node; n != &my_head; n = n->my_next_node ) ++i; __TBB_ASSERT( my_size == i, "Wrong size" ); #endif /* TBB_USE_ASSERT >= 2 */ } public: class iterator : public iterator_impl { template friend class intrusive_list_base; public: iterator (intrusive_list_node* pos ) : iterator_impl(pos ) {} iterator () {} T* operator-> () const { return &this->item(); } T& operator* () const { return this->item(); } }; // class iterator class const_iterator : public iterator_impl { template friend class intrusive_list_base; public: const_iterator (const intrusive_list_node* pos ) : iterator_impl(const_cast(pos) ) {} const_iterator () {} const T* operator-> () const { return &this->item(); } const T& operator* () const { return this->item(); } }; // class iterator intrusive_list_base () : my_size(0) { my_head.my_prev_node = &my_head; my_head.my_next_node = &my_head; } bool empty () const { return my_head.my_next_node == &my_head; } size_t size () const { return my_size; } iterator begin () { return iterator(my_head.my_next_node); } iterator end () { return iterator(&my_head); } const_iterator begin () const { return const_iterator(my_head.my_next_node); } const_iterator end () const { return const_iterator(&my_head); } void push_front ( T& val ) { __TBB_ASSERT( node(val).my_prev_node == &node(val) && node(val).my_next_node == &node(val), "Object with intrusive list node can be part of only one intrusive list simultaneously" ); // An object can be part of only one intrusive list at the given moment via the given node member node(val).my_prev_node = &my_head; node(val).my_next_node = my_head.my_next_node; my_head.my_next_node->my_prev_node = &node(val); my_head.my_next_node = &node(val); ++my_size; assert_ok(); } void remove( T& val ) { __TBB_ASSERT( node(val).my_prev_node != &node(val) && node(val).my_next_node != &node(val), "Element to remove is not in the list" ); __TBB_ASSERT( node(val).my_prev_node->my_next_node == &node(val) && node(val).my_next_node->my_prev_node == &node(val), "Element to remove is not in the list" ); --my_size; node(val).my_next_node->my_prev_node = node(val).my_prev_node; node(val).my_prev_node->my_next_node = node(val).my_next_node; #if TBB_USE_ASSERT node(val).my_prev_node = node(val).my_next_node = &node(val); #endif assert_ok(); } iterator erase ( iterator it ) { T& val = *it; ++it; remove( val ); return it; } }; // intrusive_list_base //! Double linked list of items of type T containing a member of type intrusive_list_node. /** NodePtr is a member pointer to the node data field. Class U is either T or a base class of T containing the node member. Default values exist for the sake of a partial specialization working with inheritance case. The list does not have ownership of its items. Its purpose is to avoid dynamic memory allocation when forming lists of existing objects. The class is not thread safe. **/ template class memptr_intrusive_list : public intrusive_list_base, T> { friend class intrusive_list_base, T>; static intrusive_list_node& node ( T& val ) { return val.*NodePtr; } static T& item ( intrusive_list_node* node ) { // Cannot use __TBB_offsetof (and consequently __TBB_get_object_ref) macro // with *NodePtr argument because gcc refuses to interpret pasted "->" and "*" // as member pointer dereferencing operator, and explicit usage of ## in // __TBB_offsetof implementation breaks operations with normal member names. return *reinterpret_cast((char*)node - ((ptrdiff_t)&(reinterpret_cast(0x1000)->*NodePtr) - 0x1000)); } }; // intrusive_list //! Double linked list of items of type T that is derived from intrusive_list_node class. /** The list does not have ownership of its items. Its purpose is to avoid dynamic memory allocation when forming lists of existing objects. The class is not thread safe. **/ template class intrusive_list : public intrusive_list_base, T> { friend class intrusive_list_base, T>; static intrusive_list_node& node ( T& val ) { return val; } static T& item ( intrusive_list_node* node ) { return *static_cast(node); } }; // intrusive_list } // namespace internal } // namespace tbb #endif /* _TBB_intrusive_list_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/itt_notify.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if DO_ITT_NOTIFY #if _WIN32||_WIN64 #ifndef UNICODE #define UNICODE #endif #else #pragma weak dlopen #pragma weak dlsym #pragma weak dlerror #endif /* WIN */ #if __TBB_BUILD extern "C" void ITT_DoOneTimeInitialization(); #define __itt_init_ittlib_name(x,y) (ITT_DoOneTimeInitialization(), true) #elif __TBBMALLOC_BUILD extern "C" void MallocInitializeITT(); #define __itt_init_ittlib_name(x,y) (MallocInitializeITT(), true) #else #error This file is expected to be used for either TBB or TBB allocator build. #endif // __TBB_BUILD #include "tools_api/ittnotify_static.c" namespace tbb { namespace internal { int __TBB_load_ittnotify() { return __itt_init_ittlib(NULL, // groups for: (__itt_group_id)(__itt_group_sync // prepare/cancel/acquired/releasing | __itt_group_thread // name threads | __itt_group_stitch // stack stitching #if __TBB_CPF_BUILD | __itt_group_structure #endif )); } }} // namespaces #endif /* DO_ITT_NOTIFY */ #define __TBB_NO_IMPLICIT_LINKAGE 1 #include "itt_notify.h" namespace tbb { #if DO_ITT_NOTIFY const tchar *SyncType_GlobalLock = _T("TbbGlobalLock"), *SyncType_Scheduler = _T("%Constant") ; const tchar *SyncObj_SchedulerInitialization = _T("TbbSchedulerInitialization"), *SyncObj_SchedulersList = _T("TbbSchedulersList"), *SyncObj_WorkerLifeCycleMgmt = _T("TBB Scheduler"), *SyncObj_TaskStealingLoop = _T("TBB Scheduler"), *SyncObj_WorkerTaskPool = _T("TBB Scheduler"), *SyncObj_MasterTaskPool = _T("TBB Scheduler"), *SyncObj_TaskPoolSpinning = _T("TBB Scheduler"), *SyncObj_Mailbox = _T("TBB Scheduler"), *SyncObj_TaskReturnList = _T("TBB Scheduler"), *SyncObj_TaskStream = _T("TBB Scheduler"), *SyncObj_ContextsList = _T("TBB Scheduler") ; #endif /* DO_ITT_NOTIFY */ } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/itt_notify.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_ITT_NOTIFY #define _TBB_ITT_NOTIFY #include "tbb/tbb_stddef.h" #if DO_ITT_NOTIFY #if _WIN32||_WIN64 #ifndef UNICODE #define UNICODE #endif #endif /* WIN */ #ifndef INTEL_ITTNOTIFY_API_PRIVATE #define INTEL_ITTNOTIFY_API_PRIVATE #endif #include "tools_api/ittnotify.h" #include "tools_api/legacy/ittnotify.h" extern "C" void __itt_fini_ittlib(void); #if _WIN32||_WIN64 #undef _T #undef __itt_event_create #define __itt_event_create __itt_event_createA #endif /* WIN */ #endif /* DO_ITT_NOTIFY */ #if !ITT_CALLER_NULL #define ITT_CALLER_NULL ((__itt_caller)0) #endif namespace tbb { //! Unicode support #if (_WIN32||_WIN64) && !__MINGW32__ //! Unicode character type. Always wchar_t on Windows. /** We do not use typedefs from Windows TCHAR family to keep consistence of TBB coding style. **/ typedef wchar_t tchar; //! Standard Windows macro to markup the string literals. #define _T(string_literal) L ## string_literal #else /* !WIN */ typedef char tchar; //! Standard Windows style macro to markup the string literals. #define _T(string_literal) string_literal #endif /* !WIN */ } // namespace tbb #if DO_ITT_NOTIFY namespace tbb { //! Display names of internal synchronization types extern const tchar *SyncType_GlobalLock, *SyncType_Scheduler; //! Display names of internal synchronization components/scenarios extern const tchar *SyncObj_SchedulerInitialization, *SyncObj_SchedulersList, *SyncObj_WorkerLifeCycleMgmt, *SyncObj_TaskStealingLoop, *SyncObj_WorkerTaskPool, *SyncObj_MasterTaskPool, *SyncObj_TaskPoolSpinning, *SyncObj_Mailbox, *SyncObj_TaskReturnList, *SyncObj_TaskStream, *SyncObj_ContextsList ; namespace internal { void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void* obj, const tchar* name); } // namespace internal } // namespace tbb // const_cast() is necessary to cast off volatility #define ITT_NOTIFY(name,obj) __itt_notify_##name(const_cast(static_cast(obj))) #define ITT_THREAD_SET_NAME(name) __itt_thread_set_name(name) #define ITT_FINI_ITTLIB() __itt_fini_ittlib() #define ITT_SYNC_CREATE(obj, type, name) __itt_sync_create((void*)(obj), type, name, 2) #define ITT_SYNC_RENAME(obj, name) __itt_sync_rename(obj, name) #define ITT_STACK_CREATE(obj) obj = __itt_stack_caller_create() #if __TBB_TASK_GROUP_CONTEXT #define ITT_STACK(precond, name, obj) (precond) ? __itt_stack_##name(obj) : ((void)0); #else #define ITT_STACK(precond, name, obj) ((void)0) #endif /* !__TBB_TASK_GROUP_CONTEXT */ #else /* !DO_ITT_NOTIFY */ #define ITT_NOTIFY(name,obj) ((void)0) #define ITT_THREAD_SET_NAME(name) ((void)0) #define ITT_FINI_ITTLIB() ((void)0) #define ITT_SYNC_CREATE(obj, type, name) ((void)0) #define ITT_SYNC_RENAME(obj, name) ((void)0) #define ITT_STACK_CREATE(obj) ((void)0) #define ITT_STACK(precond, name, obj) ((void)0) #endif /* !DO_ITT_NOTIFY */ namespace tbb { namespace internal { int __TBB_load_ittnotify(); }} #endif /* _TBB_ITT_NOTIFY */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/lin32-tbb-export.def ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ { global: #define __TBB_SYMBOL( sym ) sym; #include "lin32-tbb-export.lst" local: /* TBB symbols */ *3tbb*; *__TBB*; /* ITT symbols */ __itt_*; /* Intel Compiler (libirc) symbols */ __intel_*; _intel_*; get_memcpy_largest_cachelinesize; get_memcpy_largest_cache_size; get_mem_ops_method; init_mem_ops_method; irc__get_msg; irc__print; override_mem_ops_method; set_memcpy_largest_cachelinesize; set_memcpy_largest_cache_size; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/lin32-tbb-export.lst ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" /* cache_aligned_allocator.cpp */ __TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEjjPv ) __TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) __TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) __TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Ej ) __TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) /* task.cpp v3 */ __TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) __TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) __TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) __TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) __TBB_SYMBOL( _ZN3tbb4task4selfEv ) __TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEj ) __TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEj ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEj ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEj ) __TBB_SYMBOL( _ZTIN3tbb4taskE ) __TBB_SYMBOL( _ZTSN3tbb4taskE ) __TBB_SYMBOL( _ZTVN3tbb4taskE ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEij ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) #endif /* __TBB_SCHEDULER_OBSERVER */ __TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) __TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) __TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) __TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEi ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY /* task_v2.cpp */ __TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) #endif /* !TBB_NO_LEGACY */ /* Exception handling in task scheduler */ #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEj ) __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) __TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) #endif /* __TBB_TASK_GROUP_CONTEXT */ /* Symbols for exceptions thrown from TBB */ __TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) __TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) __TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) __TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) __TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) __TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) __TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) __TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) __TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) __TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) __TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) __TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) __TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) __TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) __TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) __TBB_SYMBOL( _ZTIN3tbb10user_abortE ) __TBB_SYMBOL( _ZTSN3tbb10user_abortE ) __TBB_SYMBOL( _ZTVN3tbb10user_abortE ) /* tbb_misc.cpp */ __TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) __TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) __TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) __TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) __TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) #if __TBB_x86_32 __TBB_SYMBOL( __TBB_machine_store8_slow_perf_warning ) __TBB_SYMBOL( __TBB_machine_store8_slow ) #endif __TBB_SYMBOL( TBB_runtime_interface_version ) /* tbb_main.cpp */ __TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) __TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) __TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) __TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) #if __TBB_ITT_STRUCTURE_API __TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) __TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) __TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) __TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) __TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) #endif /* pipeline.cpp */ __TBB_SYMBOL( _ZTIN3tbb6filterE ) __TBB_SYMBOL( _ZTSN3tbb6filterE ) __TBB_SYMBOL( _ZTVN3tbb6filterE ) __TBB_SYMBOL( _ZN3tbb6filterD2Ev ) __TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline3runEj ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZN3tbb8pipeline3runEjRNS_18task_group_contextE ) #endif __TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) __TBB_SYMBOL( _ZTIN3tbb8pipelineE ) __TBB_SYMBOL( _ZTSN3tbb8pipelineE ) __TBB_SYMBOL( _ZTVN3tbb8pipelineE ) __TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) __TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) /* queuing_rw_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) /* reader_writer_lock.cpp */ __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) #if !TBB_NO_LEGACY /* spin_rw_mutex.cpp v2 */ __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) #endif /* spin_rw_mutex v3 */ __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) // x86_rtm_rw_mutex.cpp __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) /* spin_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) /* mutex.cpp */ __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) /* recursive_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) /* QueuingMutex.cpp */ __TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) /* critical_section.cpp */ __TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) #if !TBB_NO_LEGACY /* concurrent_hash_map */ __TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) /* concurrent_queue.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityEij ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Ej ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) __TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) #endif /* concurrent_queue v3 */ /* constructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Ej ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Ej ) /* destructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) /* typeinfo */ __TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) /* vtable */ __TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) /* methods */ __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityEij ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) #if !TBB_NO_LEGACY /* concurrent_vector.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_jPFvPvPKvjE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvjEb ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_jPFvPvjEPFvS4_PKvjESA_ ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEjjPFvPvjE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEjjj ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEjRj ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEjjPFvPvjE ) __TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) #endif /* concurrent_vector v3 */ __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_jPFvPvPKvjE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvjE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_jPFvPvjEPFvS4_PKvjESA_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEjjPFvPvPKvjES4_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEjjj ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEjRj ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEjjPFvPvPKvjES4_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEjPvPFvS2_jEPFvS2_PKvjE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEj ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEjjjPKvPFvPvjEPFvS4_S3_jE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEjjPFvPvPKvjES4_ ) /* tbb_thread */ #if __MINGW32__ __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFjPvES2_ ) #else __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) #endif __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) __TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) __TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Ej ) __TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) #if __MINGW32__ /* condition_variable */ __TBB_SYMBOL( _ZN3tbb10interface58internal32internal_condition_variable_waitERNS1_14condvar_impl_tEPNS_5mutexEPKNS_10tick_count10interval_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal35internal_destroy_condition_variableERNS1_14condvar_impl_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_allERNS1_14condvar_impl_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_oneERNS1_14condvar_impl_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal38internal_initialize_condition_variableERNS1_14condvar_impl_tE ) #endif #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/lin64-tbb-export.def ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ { global: #define __TBB_SYMBOL( sym ) sym; #include "lin64-tbb-export.lst" local: /* TBB symbols */ *3tbb*; *__TBB*; /* ITT symbols */ __itt_*; /* Intel Compiler (libirc) symbols */ __intel_*; _intel_*; get_msg_buf; get_text_buf; message_catalog; print_buf; irc__get_msg; irc__print; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/lin64-tbb-export.lst ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" /* cache_aligned_allocator.cpp */ __TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) __TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) __TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) __TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) /* task.cpp v3 */ __TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) __TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) __TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) __TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) __TBB_SYMBOL( _ZN3tbb4task4selfEv ) __TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) __TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) __TBB_SYMBOL( _ZTIN3tbb4taskE ) __TBB_SYMBOL( _ZTSN3tbb4taskE ) __TBB_SYMBOL( _ZTVN3tbb4taskE ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) #endif /* __TBB_SCHEDULER_OBSERVER */ __TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) __TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) __TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) __TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY /* task_v2.cpp */ __TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) #endif /* !TBB_NO_LEGACY */ /* Exception handling in task scheduler */ #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) __TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) #endif /* __TBB_TASK_GROUP_CONTEXT */ /* Symbols for exceptions thrown from TBB */ __TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) __TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) __TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) __TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) __TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) __TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) __TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) __TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) __TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) __TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) __TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) __TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) __TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) __TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) __TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) __TBB_SYMBOL( _ZTIN3tbb10user_abortE ) __TBB_SYMBOL( _ZTSN3tbb10user_abortE ) __TBB_SYMBOL( _ZTVN3tbb10user_abortE ) /* tbb_misc.cpp */ __TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) __TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) __TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) __TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) __TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) __TBB_SYMBOL( TBB_runtime_interface_version ) /* tbb_main.cpp */ __TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) __TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) __TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) __TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) #if __TBB_ITT_STRUCTURE_API __TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) __TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) __TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) __TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) __TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) #endif /* pipeline.cpp */ __TBB_SYMBOL( _ZTIN3tbb6filterE ) __TBB_SYMBOL( _ZTSN3tbb6filterE ) __TBB_SYMBOL( _ZTVN3tbb6filterE ) __TBB_SYMBOL( _ZN3tbb6filterD2Ev ) __TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) #endif __TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) __TBB_SYMBOL( _ZTIN3tbb8pipelineE ) __TBB_SYMBOL( _ZTSN3tbb8pipelineE ) __TBB_SYMBOL( _ZTVN3tbb8pipelineE ) __TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) __TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) /* queuing_rw_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) /* reader_writer_lock.cpp */ __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) #if !TBB_NO_LEGACY /* spin_rw_mutex.cpp v2 */ __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) #endif // x86_rtm_rw_mutex.cpp __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) /* spin_rw_mutex v3 */ __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) /* spin_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) /* mutex.cpp */ __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) /* recursive_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) /* QueuingMutex.cpp */ __TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) /* critical_section.cpp */ __TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) #if !TBB_NO_LEGACY /* concurrent_hash_map */ __TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) /* concurrent_queue.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityElm ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) __TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) #endif /* concurrent_queue v3 */ /* constructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) /* destructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) /* typeinfo */ __TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) /* vtable */ __TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) /* methods */ __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityElm ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) #if !TBB_NO_LEGACY /* concurrent_vector.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) __TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) #endif /* concurrent_vector v3 */ __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) /* tbb_thread */ __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) __TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/lin64ipf-tbb-export.def ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ { global: #define __TBB_SYMBOL( sym ) sym; #include "lin64ipf-tbb-export.lst" local: /* TBB symbols */ *3tbb*; *__TBB*; /* ITT symbols */ __itt_*; /* Intel Compiler (libirc) symbols */ __intel_*; _intel_*; ?0_memcopyA; ?0_memcopyDu; ?0_memcpyD; ?1__memcpy; ?1__memmove; ?1__serial_memmove; memcpy; memset; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/lin64ipf-tbb-export.lst ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" /* cache_aligned_allocator.cpp */ __TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) __TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) __TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) __TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) /* task.cpp v3 */ __TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) __TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) __TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) __TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) __TBB_SYMBOL( _ZN3tbb4task4selfEv ) __TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) __TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) __TBB_SYMBOL( _ZTIN3tbb4taskE ) __TBB_SYMBOL( _ZTSN3tbb4taskE ) __TBB_SYMBOL( _ZTVN3tbb4taskE ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) #endif /* __TBB_SCHEDULER_OBSERVER */ __TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) __TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) __TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) __TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY /* task_v2.cpp */ __TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) #endif /* !TBB_NO_LEGACY */ /* Exception handling in task scheduler */ #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) __TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) #endif /* __TBB_TASK_GROUP_CONTEXT */ /* Symbols for exceptions thrown from TBB */ __TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) __TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) __TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) __TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) __TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) __TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) __TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) __TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) __TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) __TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) __TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) __TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) __TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) __TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) __TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) __TBB_SYMBOL( _ZTIN3tbb10user_abortE ) __TBB_SYMBOL( _ZTSN3tbb10user_abortE ) __TBB_SYMBOL( _ZTVN3tbb10user_abortE ) /* tbb_misc.cpp */ __TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) __TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) __TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) __TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) __TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) __TBB_SYMBOL( TBB_runtime_interface_version ) /* tbb_main.cpp */ __TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) __TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) __TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) __TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) /* pipeline.cpp */ __TBB_SYMBOL( _ZTIN3tbb6filterE ) __TBB_SYMBOL( _ZTSN3tbb6filterE ) __TBB_SYMBOL( _ZTVN3tbb6filterE ) __TBB_SYMBOL( _ZN3tbb6filterD2Ev ) __TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) #endif __TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) __TBB_SYMBOL( _ZTIN3tbb8pipelineE ) __TBB_SYMBOL( _ZTSN3tbb8pipelineE ) __TBB_SYMBOL( _ZTVN3tbb8pipelineE ) __TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) __TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) /* queuing_rw_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) /* reader_writer_lock.cpp */ __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) #if !TBB_NO_LEGACY /* spin_rw_mutex.cpp v2 */ __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) #endif /* spin_rw_mutex v3 */ __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) /* spin_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) /* mutex.cpp */ __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) /* recursive_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) /* QueuingMutex.cpp */ __TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) /* critical_section.cpp */ __TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) #if !TBB_NO_LEGACY /* concurrent_hash_map */ __TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) /* concurrent_queue.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityElm ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) __TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) #endif /* concurrent_queue v3 */ /* constructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) /* destructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) /* typeinfo */ __TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) /* vtable */ __TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) /* methods */ __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityElm ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) #if !TBB_NO_LEGACY /* concurrent_vector.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) __TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) #endif /* concurrent_vector v3 */ __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) /* tbb_thread */ __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) __TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) /* asm functions */ __TBB_SYMBOL( __TBB_machine_fetchadd1__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchadd2__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchadd4__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchadd8__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchstore1__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchstore2__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchstore4__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchstore8__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_fetchadd1acquire ) __TBB_SYMBOL( __TBB_machine_fetchadd1release ) __TBB_SYMBOL( __TBB_machine_fetchadd2acquire ) __TBB_SYMBOL( __TBB_machine_fetchadd2release ) __TBB_SYMBOL( __TBB_machine_fetchadd4acquire ) __TBB_SYMBOL( __TBB_machine_fetchadd4release ) __TBB_SYMBOL( __TBB_machine_fetchadd8acquire ) __TBB_SYMBOL( __TBB_machine_fetchadd8release ) __TBB_SYMBOL( __TBB_machine_fetchstore1acquire ) __TBB_SYMBOL( __TBB_machine_fetchstore1release ) __TBB_SYMBOL( __TBB_machine_fetchstore2acquire ) __TBB_SYMBOL( __TBB_machine_fetchstore2release ) __TBB_SYMBOL( __TBB_machine_fetchstore4acquire ) __TBB_SYMBOL( __TBB_machine_fetchstore4release ) __TBB_SYMBOL( __TBB_machine_fetchstore8acquire ) __TBB_SYMBOL( __TBB_machine_fetchstore8release ) __TBB_SYMBOL( __TBB_machine_cmpswp1acquire ) __TBB_SYMBOL( __TBB_machine_cmpswp1release ) __TBB_SYMBOL( __TBB_machine_cmpswp1__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_cmpswp2acquire ) __TBB_SYMBOL( __TBB_machine_cmpswp2release ) __TBB_SYMBOL( __TBB_machine_cmpswp2__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_cmpswp4acquire ) __TBB_SYMBOL( __TBB_machine_cmpswp4release ) __TBB_SYMBOL( __TBB_machine_cmpswp4__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_cmpswp8acquire ) __TBB_SYMBOL( __TBB_machine_cmpswp8release ) __TBB_SYMBOL( __TBB_machine_cmpswp8__TBB_full_fence ) __TBB_SYMBOL( __TBB_machine_lg ) __TBB_SYMBOL( __TBB_machine_lockbyte ) __TBB_SYMBOL( __TBB_machine_pause ) __TBB_SYMBOL( __TBB_machine_trylockbyte ) __TBB_SYMBOL( __TBB_machine_load8_relaxed ) __TBB_SYMBOL( __TBB_machine_store8_relaxed ) __TBB_SYMBOL( __TBB_machine_load4_relaxed ) __TBB_SYMBOL( __TBB_machine_store4_relaxed ) __TBB_SYMBOL( __TBB_machine_load2_relaxed ) __TBB_SYMBOL( __TBB_machine_store2_relaxed ) __TBB_SYMBOL( __TBB_machine_load1_relaxed ) __TBB_SYMBOL( __TBB_machine_store1_relaxed ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/mac32-tbb-export.def ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #define __TBB_SYMBOL( sym ) _##sym #include "mac32-tbb-export.lst" ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/mac32-tbb-export.lst ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" /* Sometimes OS X* requires leading underscore (e. g. in export list file), but sometimes not (e. g. when searching symbol in a dynamic library via dlsym()). Symbols in this file SHOULD be listed WITHOUT one leading underscore. __TBB_SYMBOL macro should add underscore when necessary, depending on the indended usage. */ // cache_aligned_allocator.cpp __TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) __TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) __TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) __TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) // task.cpp v3 __TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) __TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) __TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) __TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) __TBB_SYMBOL( _ZN3tbb4task4selfEv ) __TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) __TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) __TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) __TBB_SYMBOL( _ZTIN3tbb4taskE ) __TBB_SYMBOL( _ZTSN3tbb4taskE ) __TBB_SYMBOL( _ZTVN3tbb4taskE ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) #endif /* __TBB_SCHEDULER_OBSERVER */ __TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) __TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) __TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) __TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY // task_v2.cpp __TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) #endif // Exception handling in task scheduler #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) __TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) #endif /* __TBB_TASK_GROUP_CONTEXT */ // Symbols for exceptions thrown from TBB __TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) __TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) __TBB_SYMBOL( _ZNSt13runtime_errorD1Ev ) __TBB_SYMBOL( _ZTISt13runtime_error ) __TBB_SYMBOL( _ZTSSt13runtime_error ) __TBB_SYMBOL( _ZNSt16invalid_argumentD1Ev ) __TBB_SYMBOL( _ZTISt16invalid_argument ) __TBB_SYMBOL( _ZTSSt16invalid_argument ) __TBB_SYMBOL( _ZNSt11range_errorD1Ev ) __TBB_SYMBOL( _ZTISt11range_error ) __TBB_SYMBOL( _ZTSSt11range_error ) __TBB_SYMBOL( _ZNSt12length_errorD1Ev ) __TBB_SYMBOL( _ZTISt12length_error ) __TBB_SYMBOL( _ZTSSt12length_error ) __TBB_SYMBOL( _ZNSt12out_of_rangeD1Ev ) __TBB_SYMBOL( _ZTISt12out_of_range ) __TBB_SYMBOL( _ZTSSt12out_of_range ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) __TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) __TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) __TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) __TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) __TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) __TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) __TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) __TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) __TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) __TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) __TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) __TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) __TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) __TBB_SYMBOL( _ZTIN3tbb10user_abortE ) __TBB_SYMBOL( _ZTSN3tbb10user_abortE ) __TBB_SYMBOL( _ZTVN3tbb10user_abortE ) // tbb_misc.cpp __TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) __TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) __TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) __TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) #if __TBB_x86_32 __TBB_SYMBOL( __TBB_machine_store8_slow_perf_warning ) __TBB_SYMBOL( __TBB_machine_store8_slow ) #endif __TBB_SYMBOL( TBB_runtime_interface_version ) // tbb_main.cpp __TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) __TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) __TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) // pipeline.cpp __TBB_SYMBOL( _ZTIN3tbb6filterE ) __TBB_SYMBOL( _ZTSN3tbb6filterE ) __TBB_SYMBOL( _ZTVN3tbb6filterE ) __TBB_SYMBOL( _ZN3tbb6filterD2Ev ) __TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) #endif __TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) __TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8pipelineE ) __TBB_SYMBOL( _ZTSN3tbb8pipelineE ) __TBB_SYMBOL( _ZTVN3tbb8pipelineE ) __TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) // queuing_rw_mutex.cpp __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) // reader_writer_lock.cpp __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) #if !TBB_NO_LEGACY // spin_rw_mutex.cpp v2 __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) #endif // spin_rw_mutex v3 __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) // x86_rtm_rw_mutex.cpp __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) // spin_mutex.cpp __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) // mutex.cpp __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) // recursive_mutex.cpp __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) // queuing_mutex.cpp __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) // critical_section.cpp __TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) #if !TBB_NO_LEGACY // concurrent_hash_map __TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) // concurrent_queue.cpp v2 __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityEim ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) __TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) #endif // concurrent_queue v3 // constructors __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) // destructors __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) // typeinfo __TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) // vtable __TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) // methods __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityEim ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) #if !TBB_NO_LEGACY // concurrent_vector.cpp v2 __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) __TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) #endif // concurrent_vector v3 __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) // tbb_thread __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) __TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) __TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/mac64-tbb-export.def ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #define __TBB_SYMBOL( sym ) _##sym #include "mac64-tbb-export.lst" ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/mac64-tbb-export.lst ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" /* Sometimes OS X* requires leading underscore (e. g. in export list file), but sometimes not (e. g. when searching symbol in a dynamic library via dlsym()). Symbols in this file SHOULD be listed WITHOUT one leading underscore. __TBB_SYMBOL macro should add underscore when necessary, depending on the indended usage. */ // cache_aligned_allocator.cpp __TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) __TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) __TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) __TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) // task.cpp v3 __TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) __TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) __TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) __TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) __TBB_SYMBOL( _ZN3tbb4task4selfEv ) __TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) __TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) __TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) __TBB_SYMBOL( _ZTIN3tbb4taskE ) __TBB_SYMBOL( _ZTSN3tbb4taskE ) __TBB_SYMBOL( _ZTVN3tbb4taskE ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) #endif /* __TBB_SCHEDULER_OBSERVER */ __TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) __TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) __TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) __TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY // task_v2.cpp __TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) #endif // Exception handling in task scheduler #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) __TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) #endif /* __TBB_TASK_GROUP_CONTEXT */ // Symbols for exceptions thrown from TBB __TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) __TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) __TBB_SYMBOL( _ZNSt13runtime_errorD1Ev ) __TBB_SYMBOL( _ZTISt13runtime_error ) __TBB_SYMBOL( _ZTSSt13runtime_error ) __TBB_SYMBOL( _ZNSt16invalid_argumentD1Ev ) __TBB_SYMBOL( _ZTISt16invalid_argument ) __TBB_SYMBOL( _ZTSSt16invalid_argument ) __TBB_SYMBOL( _ZNSt11range_errorD1Ev ) __TBB_SYMBOL( _ZTISt11range_error ) __TBB_SYMBOL( _ZTSSt11range_error ) __TBB_SYMBOL( _ZNSt12length_errorD1Ev ) __TBB_SYMBOL( _ZTISt12length_error ) __TBB_SYMBOL( _ZTSSt12length_error ) __TBB_SYMBOL( _ZNSt12out_of_rangeD1Ev ) __TBB_SYMBOL( _ZTISt12out_of_range ) __TBB_SYMBOL( _ZTSSt12out_of_range ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) __TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) __TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) __TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) __TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) __TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) __TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) __TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) __TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) __TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) __TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) __TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) __TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) __TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) __TBB_SYMBOL( _ZTIN3tbb10user_abortE ) __TBB_SYMBOL( _ZTSN3tbb10user_abortE ) __TBB_SYMBOL( _ZTVN3tbb10user_abortE ) // tbb_misc.cpp __TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) __TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) __TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) __TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) __TBB_SYMBOL( TBB_runtime_interface_version ) // tbb_main.cpp __TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) __TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) __TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) // pipeline.cpp __TBB_SYMBOL( _ZTIN3tbb6filterE ) __TBB_SYMBOL( _ZTSN3tbb6filterE ) __TBB_SYMBOL( _ZTVN3tbb6filterE ) __TBB_SYMBOL( _ZN3tbb6filterD2Ev ) __TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) #endif __TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) __TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8pipelineE ) __TBB_SYMBOL( _ZTSN3tbb8pipelineE ) __TBB_SYMBOL( _ZTVN3tbb8pipelineE ) __TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) // queuing_rw_mutex.cpp __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) // reader_writer_lock.cpp __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) #if !TBB_NO_LEGACY // spin_rw_mutex.cpp v2 __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) #endif // spin_rw_mutex v3 __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) // x86_rtm_rw_mutex.cpp __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) // spin_mutex.cpp __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) // mutex.cpp __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) // recursive_mutex.cpp __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) // queuing_mutex.cpp __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) // critical_section.cpp __TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) #if !TBB_NO_LEGACY // concurrent_hash_map __TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) // concurrent_queue.cpp v2 __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityElm ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) __TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) #endif // concurrent_queue v3 // constructors __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) // destructors __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) // typeinfo __TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) // vtable __TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) // methods __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityElm ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) #if !TBB_NO_LEGACY // concurrent_vector.cpp v2 __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) __TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) #endif // concurrent_vector v3 __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) // tbb_thread __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) __TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) __TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/gcc_armv7.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Platform isolation layer for the ARMv7-a architecture. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif //TODO: is ARMv7 is the only version ever to support? #if !(__ARM_ARCH_7A__) #error compilation requires an ARMv7-a architecture. #endif #include #include #define __TBB_WORDSIZE 4 // Traditionally ARM is little-endian. // Note that, since only the layout of aligned 32-bit words is of interest, // any apparent PDP-endianness of 32-bit words at half-word alignment or // any little-endian ordering of big-endian 32-bit words in 64-bit quantities // may be disregarded for this setting. #if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG #elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #elif defined(__BYTE_ORDER__) #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED #else #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT #endif #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") #define __TBB_full_memory_fence() __asm__ __volatile__("dmb ish": : :"memory") #define __TBB_control_consistency_helper() __TBB_full_memory_fence() #define __TBB_acquire_consistency_helper() __TBB_full_memory_fence() #define __TBB_release_consistency_helper() __TBB_full_memory_fence() //-------------------------------------------------- // Compare and swap //-------------------------------------------------- /** * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand * @param value value to assign *ptr to if *ptr==comparand * @param comparand value to compare with *ptr * @return value originally in memory at ptr, regardless of success */ static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand ) { int32_t oldval, res; __TBB_full_memory_fence(); do { __asm__ __volatile__( "ldrex %1, [%3]\n" "mov %0, #0\n" "cmp %1, %4\n" "it eq\n" "strexeq %0, %5, [%3]\n" : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int32_t*)ptr) : "r" ((int32_t *)ptr), "Ir" (comparand), "r" (value) : "cc"); } while (res); __TBB_full_memory_fence(); return oldval; } /** * Atomic CAS for 64 bit values, if *ptr==comparand, then *ptr=value, returns *ptr * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand * @param value value to assign *ptr to if *ptr==comparand * @param comparand value to compare with *ptr * @return value originally in memory at ptr, regardless of success */ static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, int64_t comparand ) { int64_t oldval; int32_t res; __TBB_full_memory_fence(); do { __asm__ __volatile__( "mov %0, #0\n" "ldrexd %1, %H1, [%3]\n" "cmp %1, %4\n" "it eq\n" "cmpeq %H1, %H4\n" "it eq\n" "strexdeq %0, %5, %H5, [%3]" : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int64_t*)ptr) : "r" ((int64_t *)ptr), "r" (comparand), "r" (value) : "cc"); } while (res); __TBB_full_memory_fence(); return oldval; } static inline int32_t __TBB_machine_fetchadd4(volatile void* ptr, int32_t addend) { unsigned long tmp; int32_t result, tmp2; __TBB_full_memory_fence(); __asm__ __volatile__( "1: ldrex %0, [%4]\n" " add %3, %0, %5\n" " strex %1, %3, [%4]\n" " cmp %1, #0\n" " bne 1b\n" : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int32_t*)ptr), "=&r"(tmp2) : "r" ((int32_t *)ptr), "Ir" (addend) : "cc"); __TBB_full_memory_fence(); return result; } static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend) { unsigned long tmp; int64_t result, tmp2; __TBB_full_memory_fence(); __asm__ __volatile__( "1: ldrexd %0, %H0, [%4]\n" " adds %3, %0, %5\n" " adc %H3, %H0, %H5\n" " strexd %1, %3, %H3, [%4]\n" " cmp %1, #0\n" " bne 1b" : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int64_t*)ptr), "=&r"(tmp2) : "r" ((int64_t *)ptr), "r" (addend) : "cc"); __TBB_full_memory_fence(); return result; } inline void __TBB_machine_pause (int32_t delay ) { while(delay>0) { __TBB_compiler_fence(); delay--; } } namespace tbb { namespace internal { template struct machine_load_store_relaxed { static inline T load ( const volatile T& location ) { const T value = location; /* * An extra memory barrier is required for errata #761319 * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a */ __TBB_acquire_consistency_helper(); return value; } static inline void store ( volatile T& location, T value ) { location = value; } }; }} // namespaces internal, tbb // Machine specific atomic operations #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_Pause(V) __TBB_machine_pause(V) // Use generics for some things #define __TBB_USE_GENERIC_PART_WORD_CAS 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 1 #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/gcc_generic.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_generic_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_gcc_generic_H #include #include #define __TBB_WORDSIZE __SIZEOF_POINTER__ #if __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN #define __TBB_64BIT_ATOMICS 0 #endif /** FPU control setting not available for non-Intel architectures on Android **/ #if __ANDROID__ && __TBB_generic_arch #define __TBB_CPU_CTL_ENV_PRESENT 0 #endif // __BYTE_ORDER__ is used in accordance with http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html, // but __BIG_ENDIAN__ or __LITTLE_ENDIAN__ may be more commonly found instead. #if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG #elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #elif defined(__BYTE_ORDER__) #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED #else #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT #endif /** As this generic implementation has absolutely no information about underlying hardware, its performance most likely will be sub-optimal because of full memory fence usages where a more lightweight synchronization means (or none at all) could suffice. Thus if you use this header to enable TBB on a new platform, consider forking it and relaxing below helpers as appropriate. **/ #define __TBB_acquire_consistency_helper() __sync_synchronize() #define __TBB_release_consistency_helper() __sync_synchronize() #define __TBB_full_memory_fence() __sync_synchronize() #define __TBB_control_consistency_helper() __sync_synchronize() #define __TBB_MACHINE_DEFINE_ATOMICS(S,T) \ inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ return __sync_val_compare_and_swap(reinterpret_cast(ptr),comparand,value); \ } \ \ inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ return __sync_fetch_and_add(reinterpret_cast(ptr),value); \ } \ __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t) __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t) __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t) __TBB_MACHINE_DEFINE_ATOMICS(8,int64_t) #undef __TBB_MACHINE_DEFINE_ATOMICS namespace tbb{ namespace internal { namespace gcc_builtins { inline int clz(unsigned int x){ return __builtin_clz(x);}; inline int clz(unsigned long int x){ return __builtin_clzl(x);}; inline int clz(unsigned long long int x){ return __builtin_clzll(x);}; }}} //gcc __builtin_clz builtin count _number_ of leading zeroes static inline intptr_t __TBB_machine_lg( uintptr_t x ) { return sizeof(x)*8 - tbb::internal::gcc_builtins::clz(x) -1 ; } static inline void __TBB_machine_or( volatile void *ptr, uintptr_t addend ) { __sync_fetch_and_or(reinterpret_cast(ptr),addend); } static inline void __TBB_machine_and( volatile void *ptr, uintptr_t addend ) { __sync_fetch_and_and(reinterpret_cast(ptr),addend); } typedef unsigned char __TBB_Flag; typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag; inline bool __TBB_machine_try_lock_byte( __TBB_atomic_flag &flag ) { return __sync_lock_test_and_set(&flag,1)==0; } inline void __TBB_machine_unlock_byte( __TBB_atomic_flag &flag ) { __sync_lock_release(&flag); } // Machine specific atomic operations #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) #define __TBB_TryLockByte __TBB_machine_try_lock_byte #define __TBB_UnlockByte __TBB_machine_unlock_byte // Definition of other functions #define __TBB_Log2(V) __TBB_machine_lg(V) #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #if __TBB_WORDSIZE==4 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 #endif #if __TBB_x86_32 || __TBB_x86_64 #include "gcc_itsx.h" #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/gcc_ia32_common.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_gcc_ia32_common_H #define __TBB_machine_gcc_ia32_common_H //TODO: Add a higher-level function, e.g. tbb::interal::log2(), into tbb_stddef.h, which //uses __TBB_Log2 and contains the assert and remove the assert from here and all other //platform-specific headers. //TODO: Check if use of gcc intrinsic gives a better chance for cross call optimizations template static inline intptr_t __TBB_machine_lg( T x ) { __TBB_ASSERT(x>0, "The logarithm of a non-positive value is undefined."); uintptr_t j; __asm__("bsr %1,%0" : "=r"(j) : "r"((uintptr_t)x)); return j; } #define __TBB_Log2(V) __TBB_machine_lg(V) #ifndef __TBB_Pause //TODO: check if raising a ratio of pause instructions to loop control instructions //(via e.g. loop unrolling) gives any benefit for HT. E.g, the current implementation //does about 2 CPU-consuming instructions for every pause instruction. Perhaps for //high pause counts it should use an unrolled loop to raise the ratio, and thus free //up more integer cycles for the other hyperthread. On the other hand, if the loop is //unrolled too far, it won't fit in the core's loop cache, and thus take away //instruction decode slots from the other hyperthread. //TODO: check if use of gcc __builtin_ia32_pause intrinsic gives a "some how" better performing code static inline void __TBB_machine_pause( int32_t delay ) { for (int32_t i = 0; i < delay; i++) { __asm__ __volatile__("pause;"); } return; } #define __TBB_Pause(V) __TBB_machine_pause(V) #endif /* !__TBB_Pause */ // API to retrieve/update FPU control setting #ifndef __TBB_CPU_CTL_ENV_PRESENT #define __TBB_CPU_CTL_ENV_PRESENT 1 namespace tbb { namespace internal { class cpu_ctl_env { private: int mxcsr; short x87cw; static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */ public: bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; } void get_env() { #if __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN cpu_ctl_env loc_ctl; __asm__ __volatile__ ( "stmxcsr %0\n\t" "fstcw %1" : "=m"(loc_ctl.mxcsr), "=m"(loc_ctl.x87cw) ); *this = loc_ctl; #else __asm__ __volatile__ ( "stmxcsr %0\n\t" "fstcw %1" : "=m"(mxcsr), "=m"(x87cw) ); #endif mxcsr &= MXCSR_CONTROL_MASK; } void set_env() const { __asm__ __volatile__ ( "ldmxcsr %0\n\t" "fldcw %1" : : "m"(mxcsr), "m"(x87cw) ); } }; } // namespace internal } // namespace tbb #endif /* !__TBB_CPU_CTL_ENV_PRESENT */ #include "gcc_itsx.h" #endif /* __TBB_machine_gcc_ia32_common_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/gcc_itsx.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_itsx_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_gcc_itsx_H #define __TBB_OP_XACQUIRE 0xF2 #define __TBB_OP_XRELEASE 0xF3 #define __TBB_OP_LOCK 0xF0 #define __TBB_STRINGIZE_INTERNAL(arg) #arg #define __TBB_STRINGIZE(arg) __TBB_STRINGIZE_INTERNAL(arg) #ifdef __TBB_x86_64 #define __TBB_r_out "=r" #else #define __TBB_r_out "=q" #endif inline static uint8_t __TBB_machine_try_lock_elided( volatile uint8_t* lk ) { uint8_t value = 1; __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XACQUIRE)"; lock; xchgb %0, %1;" : __TBB_r_out(value), "=m"(*lk) : "0"(value), "m"(*lk) : "memory" ); return uint8_t(value^1); } inline static void __TBB_machine_try_lock_elided_cancel() { // 'pause' instruction aborts HLE/RTM transactions __asm__ volatile ("pause\n" : : : "memory" ); } inline static void __TBB_machine_unlock_elided( volatile uint8_t* lk ) { __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XRELEASE)"; movb $0, %0" : "=m"(*lk) : "m"(*lk) : "memory" ); } #if __TBB_TSX_INTRINSICS_PRESENT #include #define __TBB_machine_is_in_transaction _xtest #define __TBB_machine_begin_transaction _xbegin #define __TBB_machine_end_transaction _xend #define __TBB_machine_transaction_conflict_abort() _xabort(0xff) #else /*! * Check if the instruction is executed in a transaction or not */ inline static bool __TBB_machine_is_in_transaction() { int8_t res = 0; #if __TBB_x86_32 __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n" "setz %0" : "=q"(res) : : "memory" ); #else __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n" "setz %0" : "=r"(res) : : "memory" ); #endif return res==0; } /*! * Enter speculative execution mode. * @return -1 on success * abort cause ( or 0 ) on abort */ inline static uint32_t __TBB_machine_begin_transaction() { uint32_t res = ~uint32_t(0); // success value __asm__ volatile ("1: .byte 0xC7; .byte 0xF8;\n" // XBEGIN " .long 2f-1b-6\n" // 2f-1b == difference in addresses of start // of XBEGIN and the MOVL // 2f - 1b - 6 == that difference minus the size of the // XBEGIN instruction. This is the abort offset to // 2: below. " jmp 3f\n" // success (leave -1 in res) "2: movl %%eax,%0\n" // store failure code in res "3:" :"=r"(res):"0"(res):"memory","%eax"); return res; } /*! * Attempt to commit/end transaction */ inline static void __TBB_machine_end_transaction() { __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD5" :::"memory"); // XEND } /* * aborts with code 0xFF (lock already held) */ inline static void __TBB_machine_transaction_conflict_abort() { __asm__ volatile (".byte 0xC6; .byte 0xF8; .byte 0xFF" :::"memory"); } #endif /* __TBB_TSX_INTRINSICS_PRESENT */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/ibm_aix51.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // TODO: revise by comparing with mac_ppc.h #if !defined(__TBB_machine_H) || defined(__TBB_machine_ibm_aix51_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_ibm_aix51_H #define __TBB_WORDSIZE 8 #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG // assumption based on operating system #include #include #include extern "C" { int32_t __TBB_machine_cas_32 (volatile void* ptr, int32_t value, int32_t comparand); int64_t __TBB_machine_cas_64 (volatile void* ptr, int64_t value, int64_t comparand); void __TBB_machine_flush (); void __TBB_machine_lwsync (); void __TBB_machine_isync (); } // Mapping of old entry point names retained for the sake of backward binary compatibility #define __TBB_machine_cmpswp4 __TBB_machine_cas_32 #define __TBB_machine_cmpswp8 __TBB_machine_cas_64 #define __TBB_Yield() sched_yield() #define __TBB_USE_GENERIC_PART_WORD_CAS 1 #define __TBB_USE_GENERIC_FETCH_ADD 1 #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #if __GNUC__ #define __TBB_control_consistency_helper() __asm__ __volatile__( "isync": : :"memory") #define __TBB_acquire_consistency_helper() __asm__ __volatile__("lwsync": : :"memory") #define __TBB_release_consistency_helper() __asm__ __volatile__("lwsync": : :"memory") #define __TBB_full_memory_fence() __asm__ __volatile__( "sync": : :"memory") #else // IBM C++ Compiler does not support inline assembly // TODO: Since XL 9.0 or earlier GCC syntax is supported. Replace with more // lightweight implementation (like in mac_ppc.h) #define __TBB_control_consistency_helper() __TBB_machine_isync () #define __TBB_acquire_consistency_helper() __TBB_machine_lwsync () #define __TBB_release_consistency_helper() __TBB_machine_lwsync () #define __TBB_full_memory_fence() __TBB_machine_flush () #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/icc_generic.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #if ! __TBB_ICC_BUILTIN_ATOMICS_PRESENT #error "Intel C++ Compiler of at least 12.0 version is needed to use ICC intrinsics port" #endif #define __TBB_machine_icc_generic_H //ICC mimics the "native" target compiler #if _MSC_VER #include "msvc_ia32_common.h" #else #include "gcc_ia32_common.h" #endif //TODO: Make __TBB_WORDSIZE macro optional for ICC intrinsics port. //As compiler intrinsics are used for all the operations it is possible to do. #if __TBB_x86_32 #define __TBB_WORDSIZE 4 #else #define __TBB_WORDSIZE 8 #endif #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE //__TBB_compiler_fence() defined just in case, as it seems not to be used on its own anywhere else #if _MSC_VER //TODO: any way to use same intrinsics on windows and linux? #pragma intrinsic(_ReadWriteBarrier) #define __TBB_compiler_fence() _ReadWriteBarrier() #else #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") #endif #ifndef __TBB_full_memory_fence #if _MSC_VER //TODO: any way to use same intrinsics on windows and linux? #pragma intrinsic(_mm_mfence) #define __TBB_full_memory_fence() _mm_mfence() #else #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") #endif #endif #define __TBB_control_consistency_helper() __TBB_compiler_fence() namespace tbb { namespace internal { //TODO: is there any way to reuse definition of memory_order enum from ICC instead of copy paste. //however it seems unlikely that ICC will silently change exact enum values, as they are defined //in the ISO exactly like this. //TODO: add test that exact values of the enum are same as in the ISO C++11 typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst } memory_order; namespace icc_intrinsics_port { template T convert_argument(T value){ return value; } //The overload below is needed to have explicit conversion of pointer to void* in argument list. //compiler bug? //TODO: add according broken macro and recheck with ICC 13.0 if the overload is still needed template void* convert_argument(T* value){ return (void*)value; } } //TODO: code below is a bit repetitive, consider simplifying it template struct machine_load_store { static T load_with_acquire ( const volatile T& location ) { return __atomic_load_explicit(&location, memory_order_acquire); } static void store_with_release ( volatile T &location, T value ) { __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release); } }; template struct machine_load_store_relaxed { static inline T load ( const T& location ) { return __atomic_load_explicit(&location, memory_order_relaxed); } static inline void store ( T& location, T value ) { __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed); } }; template struct machine_load_store_seq_cst { static T load ( const volatile T& location ) { return __atomic_load_explicit(&location, memory_order_seq_cst); } static void store ( volatile T &location, T value ) { __atomic_store_explicit(&location, value, memory_order_seq_cst); } }; }} // namespace tbb::internal namespace tbb{ namespace internal { namespace icc_intrinsics_port{ typedef enum memory_order_map { relaxed = memory_order_relaxed, acquire = memory_order_acquire, release = memory_order_release, full_fence= memory_order_seq_cst } memory_order_map; }}}// namespace tbb::internal #define __TBB_MACHINE_DEFINE_ATOMICS(S,T,M) \ inline T __TBB_machine_cmpswp##S##M( volatile void *ptr, T value, T comparand ) { \ __atomic_compare_exchange_strong_explicit( \ (T*)ptr \ ,&comparand \ ,value \ , tbb::internal::icc_intrinsics_port::M \ , tbb::internal::icc_intrinsics_port::M); \ return comparand; \ } \ \ inline T __TBB_machine_fetchstore##S##M(volatile void *ptr, T value) { \ return __atomic_exchange_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \ } \ \ inline T __TBB_machine_fetchadd##S##M(volatile void *ptr, T value) { \ return __atomic_fetch_add_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \ } \ __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, full_fence) __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, acquire) __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, release) __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, relaxed) __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, full_fence) __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, acquire) __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, release) __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, relaxed) __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, full_fence) __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, acquire) __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, release) __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, relaxed) __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, full_fence) __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, acquire) __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, release) __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, relaxed) #undef __TBB_MACHINE_DEFINE_ATOMICS #define __TBB_USE_FENCED_ATOMICS 1 namespace tbb { namespace internal { #if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence) __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence) __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(acquire) __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(release) __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(relaxed) __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(relaxed) template struct machine_load_store { static T load_with_acquire ( const volatile T& location ) { if( tbb::internal::is_aligned(&location,8)) { return __atomic_load_explicit(&location, memory_order_acquire); } else { return __TBB_machine_generic_load8acquire(&location); } } static void store_with_release ( volatile T &location, T value ) { if( tbb::internal::is_aligned(&location,8)) { __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release); } else { return __TBB_machine_generic_store8release(&location,value); } } }; template struct machine_load_store_relaxed { static T load( const volatile T& location ) { if( tbb::internal::is_aligned(&location,8)) { return __atomic_load_explicit(&location, memory_order_relaxed); } else { return __TBB_machine_generic_load8relaxed(&location); } } static void store( volatile T &location, T value ) { if( tbb::internal::is_aligned(&location,8)) { __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed); } else { return __TBB_machine_generic_store8relaxed(&location,value); } } }; template struct machine_load_store_seq_cst { static T load ( const volatile T& location ) { if( tbb::internal::is_aligned(&location,8)) { return __atomic_load_explicit(&location, memory_order_seq_cst); } else { return __TBB_machine_generic_load8full_fence(&location); } } static void store ( volatile T &location, T value ) { if( tbb::internal::is_aligned(&location,8)) { __atomic_store_explicit(&location, value, memory_order_seq_cst); } else { return __TBB_machine_generic_store8full_fence(&location,value); } } }; #endif }} // namespace tbb::internal template inline void __TBB_machine_OR( T *operand, T addend ) { __atomic_fetch_or_explicit(operand, addend, tbb::internal::memory_order_seq_cst); } template inline void __TBB_machine_AND( T *operand, T addend ) { __atomic_fetch_and_explicit(operand, addend, tbb::internal::memory_order_seq_cst); } ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/linux_common.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #include #define __TBB_Yield() sched_yield() #include /* Futex definitions */ #include #if defined(SYS_futex) #define __TBB_USE_FUTEX 1 #include #include // Unfortunately, some versions of Linux do not have a header that defines FUTEX_WAIT and FUTEX_WAKE. #ifdef FUTEX_WAIT #define __TBB_FUTEX_WAIT FUTEX_WAIT #else #define __TBB_FUTEX_WAIT 0 #endif #ifdef FUTEX_WAKE #define __TBB_FUTEX_WAKE FUTEX_WAKE #else #define __TBB_FUTEX_WAKE 1 #endif #ifndef __TBB_ASSERT #error machine specific headers must be included after tbb_stddef.h #endif namespace tbb { namespace internal { inline int futex_wait( void *futex, int comparand ) { int r = syscall( SYS_futex,futex,__TBB_FUTEX_WAIT,comparand,NULL,NULL,0 ); #if TBB_USE_ASSERT int e = errno; __TBB_ASSERT( r==0||r==EWOULDBLOCK||(r==-1&&(e==EAGAIN||e==EINTR)), "futex_wait failed." ); #endif /* TBB_USE_ASSERT */ return r; } inline int futex_wakeup_one( void *futex ) { int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,1,NULL,NULL,0 ); __TBB_ASSERT( r==0||r==1, "futex_wakeup_one: more than one thread woken up?" ); return r; } inline int futex_wakeup_all( void *futex ) { int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,INT_MAX,NULL,NULL,0 ); __TBB_ASSERT( r>=0, "futex_wakeup_all: error in waking up threads" ); return r; } } /* namespace internal */ } /* namespace tbb */ #endif /* SYS_futex */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/linux_ia32.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia32_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_linux_ia32_H #include #include "gcc_ia32_common.h" #define __TBB_WORDSIZE 4 #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() #define __TBB_release_consistency_helper() __TBB_compiler_fence() #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") #if __TBB_ICC_ASM_VOLATILE_BROKEN #define __TBB_VOLATILE #else #define __TBB_VOLATILE volatile #endif #define __TBB_MACHINE_DEFINE_ATOMICS(S,T,X,R) \ static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ { \ T result; \ \ __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ : "=a"(result), "=m"(*(__TBB_VOLATILE T*)ptr) \ : "q"(value), "0"(comparand), "m"(*(__TBB_VOLATILE T*)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ { \ T result; \ __asm__ __volatile__("lock\nxadd" X " %0,%1" \ : R (result), "=m"(*(__TBB_VOLATILE T*)ptr) \ : "0"(addend), "m"(*(__TBB_VOLATILE T*)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ { \ T result; \ __asm__ __volatile__("lock\nxchg" X " %0,%1" \ : R (result), "=m"(*(__TBB_VOLATILE T*)ptr) \ : "0"(value), "m"(*(__TBB_VOLATILE T*)ptr) \ : "memory"); \ return result; \ } \ __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t,"","=q") __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"","=r") __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"l","=r") #if __INTEL_COMPILER #pragma warning( push ) // reference to EBX in a function requiring stack alignment #pragma warning( disable: 998 ) #endif #if __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN #define __TBB_IA32_CAS8_NOINLINE __attribute__ ((noinline)) #else #define __TBB_IA32_CAS8_NOINLINE #endif static inline __TBB_IA32_CAS8_NOINLINE int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) { //TODO: remove the extra part of condition once __TBB_GCC_BUILTIN_ATOMICS_PRESENT is lowered to gcc version 4.1.2 #if (__TBB_GCC_BUILTIN_ATOMICS_PRESENT || (__TBB_GCC_VERSION >= 40102)) && !__TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN return __sync_val_compare_and_swap( reinterpret_cast(ptr), comparand, value ); #else /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */ //TODO: look like ICC 13.0 has some issues with this code, investigate it more deeply int64_t result; union { int64_t i64; int32_t i32[2]; }; i64 = value; #if __PIC__ /* compiling position-independent code */ // EBX register preserved for compliance with position-independent code rules on IA32 int32_t tmp; __asm__ __volatile__ ( "movl %%ebx,%2\n\t" "movl %5,%%ebx\n\t" #if __GNUC__==3 "lock\n\t cmpxchg8b %1\n\t" #else "lock\n\t cmpxchg8b (%3)\n\t" #endif "movl %2,%%ebx" : "=A"(result) , "=m"(*(__TBB_VOLATILE int64_t *)ptr) , "=m"(tmp) #if __GNUC__==3 : "m"(*(__TBB_VOLATILE int64_t *)ptr) #else : "SD"(ptr) #endif , "0"(comparand) , "m"(i32[0]), "c"(i32[1]) : "memory" #if __INTEL_COMPILER ,"ebx" #endif ); #else /* !__PIC__ */ __asm__ __volatile__ ( "lock\n\t cmpxchg8b %1\n\t" : "=A"(result), "=m"(*(__TBB_VOLATILE int64_t *)ptr) : "m"(*(__TBB_VOLATILE int64_t *)ptr) , "0"(comparand) , "b"(i32[0]), "c"(i32[1]) : "memory" ); #endif /* __PIC__ */ return result; #endif /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */ } #undef __TBB_IA32_CAS8_NOINLINE #if __INTEL_COMPILER #pragma warning( pop ) #endif // warning 998 is back static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) { __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); } static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) { __asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); } //TODO: Check if it possible and profitable for IA-32 architecture on (Linux* and Windows*) //to use of 64-bit load/store via floating point registers together with full fence //for sequentially consistent load/store, instead of CAS. #if __clang__ #define __TBB_fildq "fildll" #define __TBB_fistpq "fistpll" #else #define __TBB_fildq "fildq" #define __TBB_fistpq "fistpq" #endif static inline int64_t __TBB_machine_aligned_load8 (const volatile void *ptr) { __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_load8 should be used with 8 byte aligned locations only \n"); int64_t result; __asm__ __volatile__ ( __TBB_fildq " %1\n\t" __TBB_fistpq " %0" : "=m"(result) : "m"(*(const __TBB_VOLATILE uint64_t*)ptr) : "memory" ); return result; } static inline void __TBB_machine_aligned_store8 (volatile void *ptr, int64_t value ) { __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_store8 should be used with 8 byte aligned locations only \n"); // Aligned store __asm__ __volatile__ ( __TBB_fildq " %1\n\t" __TBB_fistpq " %0" : "=m"(*(__TBB_VOLATILE int64_t*)ptr) : "m"(value) : "memory" ); } static inline int64_t __TBB_machine_load8 (const volatile void *ptr) { #if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN if( tbb::internal::is_aligned(ptr,8)) { #endif return __TBB_machine_aligned_load8(ptr); #if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN } else { // Unaligned load return __TBB_machine_cmpswp8(const_cast(ptr),0,0); } #endif } //! Handles misaligned 8-byte store /** Defined in tbb_misc.cpp */ extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value ); extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr ); static inline void __TBB_machine_store8(volatile void *ptr, int64_t value) { #if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN if( tbb::internal::is_aligned(ptr,8)) { #endif __TBB_machine_aligned_store8(ptr,value); #if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN } else { // Unaligned store #if TBB_USE_PERFORMANCE_WARNINGS __TBB_machine_store8_slow_perf_warning(ptr); #endif /* TBB_USE_PERFORMANCE_WARNINGS */ __TBB_machine_store8_slow(ptr,value); } #endif } // Machine specific atomic operations #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) #define __TBB_USE_GENERIC_DWORD_FETCH_ADD 1 #define __TBB_USE_GENERIC_DWORD_FETCH_STORE 1 #define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/linux_ia64.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia64_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_linux_ia64_H #include #include #define __TBB_WORDSIZE 8 #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #if __INTEL_COMPILER #define __TBB_compiler_fence() #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() #define __TBB_release_consistency_helper() #define __TBB_full_memory_fence() __mf() #else #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") #define __TBB_control_consistency_helper() __TBB_compiler_fence() // Even though GCC imbues volatile loads with acquire semantics, it sometimes moves // loads over the acquire fence. The following helpers stop such incorrect code motion. #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() #define __TBB_release_consistency_helper() __TBB_compiler_fence() #define __TBB_full_memory_fence() __asm__ __volatile__("mf": : :"memory") #endif /* !__INTEL_COMPILER */ // Most of the functions will be in a .s file // TODO: revise dynamic_link, memory pools and etc. if the library dependency is removed. extern "C" { int8_t __TBB_machine_fetchadd1__TBB_full_fence (volatile void *ptr, int8_t addend); int8_t __TBB_machine_fetchadd1acquire(volatile void *ptr, int8_t addend); int8_t __TBB_machine_fetchadd1release(volatile void *ptr, int8_t addend); int16_t __TBB_machine_fetchadd2__TBB_full_fence (volatile void *ptr, int16_t addend); int16_t __TBB_machine_fetchadd2acquire(volatile void *ptr, int16_t addend); int16_t __TBB_machine_fetchadd2release(volatile void *ptr, int16_t addend); int32_t __TBB_machine_fetchadd4__TBB_full_fence (volatile void *ptr, int32_t value); int32_t __TBB_machine_fetchadd4acquire(volatile void *ptr, int32_t addend); int32_t __TBB_machine_fetchadd4release(volatile void *ptr, int32_t addend); int64_t __TBB_machine_fetchadd8__TBB_full_fence (volatile void *ptr, int64_t value); int64_t __TBB_machine_fetchadd8acquire(volatile void *ptr, int64_t addend); int64_t __TBB_machine_fetchadd8release(volatile void *ptr, int64_t addend); int8_t __TBB_machine_fetchstore1__TBB_full_fence (volatile void *ptr, int8_t value); int8_t __TBB_machine_fetchstore1acquire(volatile void *ptr, int8_t value); int8_t __TBB_machine_fetchstore1release(volatile void *ptr, int8_t value); int16_t __TBB_machine_fetchstore2__TBB_full_fence (volatile void *ptr, int16_t value); int16_t __TBB_machine_fetchstore2acquire(volatile void *ptr, int16_t value); int16_t __TBB_machine_fetchstore2release(volatile void *ptr, int16_t value); int32_t __TBB_machine_fetchstore4__TBB_full_fence (volatile void *ptr, int32_t value); int32_t __TBB_machine_fetchstore4acquire(volatile void *ptr, int32_t value); int32_t __TBB_machine_fetchstore4release(volatile void *ptr, int32_t value); int64_t __TBB_machine_fetchstore8__TBB_full_fence (volatile void *ptr, int64_t value); int64_t __TBB_machine_fetchstore8acquire(volatile void *ptr, int64_t value); int64_t __TBB_machine_fetchstore8release(volatile void *ptr, int64_t value); int8_t __TBB_machine_cmpswp1__TBB_full_fence (volatile void *ptr, int8_t value, int8_t comparand); int8_t __TBB_machine_cmpswp1acquire(volatile void *ptr, int8_t value, int8_t comparand); int8_t __TBB_machine_cmpswp1release(volatile void *ptr, int8_t value, int8_t comparand); int16_t __TBB_machine_cmpswp2__TBB_full_fence (volatile void *ptr, int16_t value, int16_t comparand); int16_t __TBB_machine_cmpswp2acquire(volatile void *ptr, int16_t value, int16_t comparand); int16_t __TBB_machine_cmpswp2release(volatile void *ptr, int16_t value, int16_t comparand); int32_t __TBB_machine_cmpswp4__TBB_full_fence (volatile void *ptr, int32_t value, int32_t comparand); int32_t __TBB_machine_cmpswp4acquire(volatile void *ptr, int32_t value, int32_t comparand); int32_t __TBB_machine_cmpswp4release(volatile void *ptr, int32_t value, int32_t comparand); int64_t __TBB_machine_cmpswp8__TBB_full_fence (volatile void *ptr, int64_t value, int64_t comparand); int64_t __TBB_machine_cmpswp8acquire(volatile void *ptr, int64_t value, int64_t comparand); int64_t __TBB_machine_cmpswp8release(volatile void *ptr, int64_t value, int64_t comparand); int64_t __TBB_machine_lg(uint64_t value); void __TBB_machine_pause(int32_t delay); bool __TBB_machine_trylockbyte( volatile unsigned char &ptr ); int64_t __TBB_machine_lockbyte( volatile unsigned char &ptr ); //! Retrieves the current RSE backing store pointer. IA64 specific. void* __TBB_get_bsp(); int32_t __TBB_machine_load1_relaxed(const void *ptr); int32_t __TBB_machine_load2_relaxed(const void *ptr); int32_t __TBB_machine_load4_relaxed(const void *ptr); int64_t __TBB_machine_load8_relaxed(const void *ptr); void __TBB_machine_store1_relaxed(void *ptr, int32_t value); void __TBB_machine_store2_relaxed(void *ptr, int32_t value); void __TBB_machine_store4_relaxed(void *ptr, int32_t value); void __TBB_machine_store8_relaxed(void *ptr, int64_t value); } // extern "C" // Mapping old entry points to the names corresponding to the new full_fence identifier. #define __TBB_machine_fetchadd1full_fence __TBB_machine_fetchadd1__TBB_full_fence #define __TBB_machine_fetchadd2full_fence __TBB_machine_fetchadd2__TBB_full_fence #define __TBB_machine_fetchadd4full_fence __TBB_machine_fetchadd4__TBB_full_fence #define __TBB_machine_fetchadd8full_fence __TBB_machine_fetchadd8__TBB_full_fence #define __TBB_machine_fetchstore1full_fence __TBB_machine_fetchstore1__TBB_full_fence #define __TBB_machine_fetchstore2full_fence __TBB_machine_fetchstore2__TBB_full_fence #define __TBB_machine_fetchstore4full_fence __TBB_machine_fetchstore4__TBB_full_fence #define __TBB_machine_fetchstore8full_fence __TBB_machine_fetchstore8__TBB_full_fence #define __TBB_machine_cmpswp1full_fence __TBB_machine_cmpswp1__TBB_full_fence #define __TBB_machine_cmpswp2full_fence __TBB_machine_cmpswp2__TBB_full_fence #define __TBB_machine_cmpswp4full_fence __TBB_machine_cmpswp4__TBB_full_fence #define __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8__TBB_full_fence // Mapping relaxed operations to the entry points implementing them. /** On IA64 RMW operations implicitly have acquire semantics. Thus one cannot actually have completely relaxed RMW operation here. **/ #define __TBB_machine_fetchadd1relaxed __TBB_machine_fetchadd1acquire #define __TBB_machine_fetchadd2relaxed __TBB_machine_fetchadd2acquire #define __TBB_machine_fetchadd4relaxed __TBB_machine_fetchadd4acquire #define __TBB_machine_fetchadd8relaxed __TBB_machine_fetchadd8acquire #define __TBB_machine_fetchstore1relaxed __TBB_machine_fetchstore1acquire #define __TBB_machine_fetchstore2relaxed __TBB_machine_fetchstore2acquire #define __TBB_machine_fetchstore4relaxed __TBB_machine_fetchstore4acquire #define __TBB_machine_fetchstore8relaxed __TBB_machine_fetchstore8acquire #define __TBB_machine_cmpswp1relaxed __TBB_machine_cmpswp1acquire #define __TBB_machine_cmpswp2relaxed __TBB_machine_cmpswp2acquire #define __TBB_machine_cmpswp4relaxed __TBB_machine_cmpswp4acquire #define __TBB_machine_cmpswp8relaxed __TBB_machine_cmpswp8acquire #define __TBB_MACHINE_DEFINE_ATOMICS(S,V) \ template \ struct machine_load_store_relaxed { \ static inline T load ( const T& location ) { \ return (T)__TBB_machine_load##S##_relaxed(&location); \ } \ static inline void store ( T& location, T value ) { \ __TBB_machine_store##S##_relaxed(&location, (V)value); \ } \ } namespace tbb { namespace internal { __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t); __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t); __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t); __TBB_MACHINE_DEFINE_ATOMICS(8,int64_t); }} // namespaces internal, tbb #undef __TBB_MACHINE_DEFINE_ATOMICS #define __TBB_USE_FENCED_ATOMICS 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 // Definition of Lock functions #define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) #define __TBB_LockByte(P) __TBB_machine_lockbyte(P) // Definition of other utility functions #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/linux_intel64.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_intel64_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_linux_intel64_H #include #include "gcc_ia32_common.h" #define __TBB_WORDSIZE 8 #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() #define __TBB_release_consistency_helper() __TBB_compiler_fence() #ifndef __TBB_full_memory_fence #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") #endif #define __TBB_MACHINE_DEFINE_ATOMICS(S,T,X) \ static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ { \ T result; \ \ __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ : "=a"(result), "=m"(*(volatile T*)ptr) \ : "q"(value), "0"(comparand), "m"(*(volatile T*)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ { \ T result; \ __asm__ __volatile__("lock\nxadd" X " %0,%1" \ : "=r"(result),"=m"(*(volatile T*)ptr) \ : "0"(addend), "m"(*(volatile T*)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ { \ T result; \ __asm__ __volatile__("lock\nxchg" X " %0,%1" \ : "=r"(result),"=m"(*(volatile T*)ptr) \ : "0"(value), "m"(*(volatile T*)ptr) \ : "memory"); \ return result; \ } \ __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t,"") __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"") __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"") __TBB_MACHINE_DEFINE_ATOMICS(8,int64_t,"q") #undef __TBB_MACHINE_DEFINE_ATOMICS static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) { __asm__ __volatile__("lock\norq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory"); } static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) { __asm__ __volatile__("lock\nandq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory"); } #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) #define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/mac_ppc.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_power_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_gcc_power_H #include #include // TODO: rename to gcc_power.h? // This file is for Power Architecture with compilers supporting GNU inline-assembler syntax (currently GNU g++ and IBM XL). // Note that XL V9.0 (sometimes?) has trouble dealing with empty input and/or clobber lists, so they should be avoided. #if __powerpc64__ || __ppc64__ // IBM XL documents __powerpc64__ (and __PPC64__). // Apple documents __ppc64__ (with __ppc__ only on 32-bit). #define __TBB_WORDSIZE 8 #else #define __TBB_WORDSIZE 4 #endif // Traditionally Power Architecture is big-endian. // Little-endian could be just an address manipulation (compatibility with TBB not verified), // or normal little-endian (on more recent systems). Embedded PowerPC systems may support // page-specific endianness, but then one endianness must be hidden from TBB so that it still sees only one. #if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG #elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #elif defined(__BYTE_ORDER__) #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED #else #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT #endif // On Power Architecture, (lock-free) 64-bit atomics require 64-bit hardware: #if __TBB_WORDSIZE==8 // Do not change the following definition, because TBB itself will use 64-bit atomics in 64-bit builds. #define __TBB_64BIT_ATOMICS 1 #elif __bgp__ // Do not change the following definition, because this is known 32-bit hardware. #define __TBB_64BIT_ATOMICS 0 #else // To enable 64-bit atomics in 32-bit builds, set the value below to 1 instead of 0. // You must make certain that the program will only use them on actual 64-bit hardware // (which typically means that the entire program is only executed on such hardware), // because their implementation involves machine instructions that are illegal elsewhere. // The setting can be chosen independently per compilation unit, // which also means that TBB itself does not need to be rebuilt. // Alternatively (but only for the current architecture and TBB version), // override the default as a predefined macro when invoking the compiler. #ifndef __TBB_64BIT_ATOMICS #define __TBB_64BIT_ATOMICS 0 #endif #endif inline int32_t __TBB_machine_cmpswp4 (volatile void *ptr, int32_t value, int32_t comparand ) { int32_t result; __asm__ __volatile__("sync\n" "0:\n\t" "lwarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ "cmpw %[res],%[cmp]\n\t" /* compare against comparand */ "bne- 1f\n\t" /* exit if not same */ "stwcx. %[val],0,%[ptr]\n\t" /* store new value */ "bne- 0b\n" /* retry if reservation lost */ "1:\n\t" /* the exit */ "isync" : [res]"=&r"(result) , "+m"(* (int32_t*) ptr) /* redundant with "memory" */ : [ptr]"r"(ptr) , [val]"r"(value) , [cmp]"r"(comparand) : "memory" /* compiler full fence */ , "cr0" /* clobbered by cmp and/or stwcx. */ ); return result; } #if __TBB_WORDSIZE==8 inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) { int64_t result; __asm__ __volatile__("sync\n" "0:\n\t" "ldarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ "cmpd %[res],%[cmp]\n\t" /* compare against comparand */ "bne- 1f\n\t" /* exit if not same */ "stdcx. %[val],0,%[ptr]\n\t" /* store new value */ "bne- 0b\n" /* retry if reservation lost */ "1:\n\t" /* the exit */ "isync" : [res]"=&r"(result) , "+m"(* (int64_t*) ptr) /* redundant with "memory" */ : [ptr]"r"(ptr) , [val]"r"(value) , [cmp]"r"(comparand) : "memory" /* compiler full fence */ , "cr0" /* clobbered by cmp and/or stdcx. */ ); return result; } #elif __TBB_64BIT_ATOMICS /* && __TBB_WORDSIZE==4 */ inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) { int64_t result; int64_t value_register, comparand_register, result_register; // dummy variables to allocate registers __asm__ __volatile__("sync\n\t" "ld %[val],%[valm]\n\t" "ld %[cmp],%[cmpm]\n" "0:\n\t" "ldarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ "cmpd %[res],%[cmp]\n\t" /* compare against comparand */ "bne- 1f\n\t" /* exit if not same */ "stdcx. %[val],0,%[ptr]\n\t" /* store new value */ "bne- 0b\n" /* retry if reservation lost */ "1:\n\t" /* the exit */ "std %[res],%[resm]\n\t" "isync" : [resm]"=m"(result) , [res] "=&r"( result_register) , [val] "=&r"( value_register) , [cmp] "=&r"(comparand_register) , "+m"(* (int64_t*) ptr) /* redundant with "memory" */ : [ptr] "r"(ptr) , [valm]"m"(value) , [cmpm]"m"(comparand) : "memory" /* compiler full fence */ , "cr0" /* clobbered by cmpd and/or stdcx. */ ); return result; } #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ #define __TBB_MACHINE_DEFINE_LOAD_STORE(S,ldx,stx,cmpx) \ template \ struct machine_load_store { \ static inline T load_with_acquire(const volatile T& location) { \ T result; \ __asm__ __volatile__(ldx " %[res],0(%[ptr])\n" \ "0:\n\t" \ cmpx " %[res],%[res]\n\t" \ "bne- 0b\n\t" \ "isync" \ : [res]"=r"(result) \ : [ptr]"b"(&location) /* cannot use register 0 here */ \ , "m"(location) /* redundant with "memory" */ \ : "memory" /* compiler acquire fence */ \ , "cr0" /* clobbered by cmpw/cmpd */); \ return result; \ } \ static inline void store_with_release(volatile T &location, T value) { \ __asm__ __volatile__("lwsync\n\t" \ stx " %[val],0(%[ptr])" \ : "=m"(location) /* redundant with "memory" */ \ : [ptr]"b"(&location) /* cannot use register 0 here */ \ , [val]"r"(value) \ : "memory"/*compiler release fence*/ /*(cr0 not affected)*/); \ } \ }; \ \ template \ struct machine_load_store_relaxed { \ static inline T load (const __TBB_atomic T& location) { \ T result; \ __asm__ __volatile__(ldx " %[res],0(%[ptr])" \ : [res]"=r"(result) \ : [ptr]"b"(&location) /* cannot use register 0 here */ \ , "m"(location) \ ); /*(no compiler fence)*/ /*(cr0 not affected)*/ \ return result; \ } \ static inline void store (__TBB_atomic T &location, T value) { \ __asm__ __volatile__(stx " %[val],0(%[ptr])" \ : "=m"(location) \ : [ptr]"b"(&location) /* cannot use register 0 here */ \ , [val]"r"(value) \ ); /*(no compiler fence)*/ /*(cr0 not affected)*/ \ } \ }; namespace tbb { namespace internal { __TBB_MACHINE_DEFINE_LOAD_STORE(1,"lbz","stb","cmpw") __TBB_MACHINE_DEFINE_LOAD_STORE(2,"lhz","sth","cmpw") __TBB_MACHINE_DEFINE_LOAD_STORE(4,"lwz","stw","cmpw") #if __TBB_WORDSIZE==8 __TBB_MACHINE_DEFINE_LOAD_STORE(8,"ld" ,"std","cmpd") #elif __TBB_64BIT_ATOMICS /* && __TBB_WORDSIZE==4 */ template struct machine_load_store { static inline T load_with_acquire(const volatile T& location) { T result; T result_register; // dummy variable to allocate a register __asm__ __volatile__("ld %[res],0(%[ptr])\n\t" "std %[res],%[resm]\n" "0:\n\t" "cmpd %[res],%[res]\n\t" "bne- 0b\n\t" "isync" : [resm]"=m"(result) , [res]"=&r"(result_register) : [ptr]"b"(&location) /* cannot use register 0 here */ , "m"(location) /* redundant with "memory" */ : "memory" /* compiler acquire fence */ , "cr0" /* clobbered by cmpd */); return result; } static inline void store_with_release(volatile T &location, T value) { T value_register; // dummy variable to allocate a register __asm__ __volatile__("lwsync\n\t" "ld %[val],%[valm]\n\t" "std %[val],0(%[ptr])" : "=m"(location) /* redundant with "memory" */ , [val]"=&r"(value_register) : [ptr]"b"(&location) /* cannot use register 0 here */ , [valm]"m"(value) : "memory"/*compiler release fence*/ /*(cr0 not affected)*/); } }; struct machine_load_store_relaxed { static inline T load (const volatile T& location) { T result; T result_register; // dummy variable to allocate a register __asm__ __volatile__("ld %[res],0(%[ptr])\n\t" "std %[res],%[resm]" : [resm]"=m"(result) , [res]"=&r"(result_register) : [ptr]"b"(&location) /* cannot use register 0 here */ , "m"(location) ); /*(no compiler fence)*/ /*(cr0 not affected)*/ return result; } static inline void store (volatile T &location, T value) { T value_register; // dummy variable to allocate a register __asm__ __volatile__("ld %[val],%[valm]\n\t" "std %[val],0(%[ptr])" : "=m"(location) , [val]"=&r"(value_register) : [ptr]"b"(&location) /* cannot use register 0 here */ , [valm]"m"(value) ); /*(no compiler fence)*/ /*(cr0 not affected)*/ } }; #define __TBB_machine_load_store_relaxed_8 #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ }} // namespaces internal, tbb #undef __TBB_MACHINE_DEFINE_LOAD_STORE #define __TBB_USE_GENERIC_PART_WORD_CAS 1 #define __TBB_USE_GENERIC_FETCH_ADD 1 #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #define __TBB_control_consistency_helper() __asm__ __volatile__("isync": : :"memory") #define __TBB_full_memory_fence() __asm__ __volatile__( "sync": : :"memory") static inline intptr_t __TBB_machine_lg( uintptr_t x ) { __TBB_ASSERT(x, "__TBB_Log2(0) undefined"); // cntlzd/cntlzw starts counting at 2^63/2^31 (ignoring any higher-order bits), and does not affect cr0 #if __TBB_WORDSIZE==8 __asm__ __volatile__ ("cntlzd %0,%0" : "+r"(x)); return 63-static_cast(x); #else __asm__ __volatile__ ("cntlzw %0,%0" : "+r"(x)); return 31-static_cast(x); #endif } #define __TBB_Log2(V) __TBB_machine_lg(V) // Assumes implicit alignment for any 32-bit value typedef uint32_t __TBB_Flag; #define __TBB_Flag __TBB_Flag inline bool __TBB_machine_trylockbyte( __TBB_atomic __TBB_Flag &flag ) { return __TBB_machine_cmpswp4(&flag,1,0)==0; } #define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/macos_common.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_macos_common_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_macos_common_H #include #define __TBB_Yield() sched_yield() // __TBB_HardwareConcurrency #include #include static inline int __TBB_macos_available_cpu() { int name[2] = {CTL_HW, HW_AVAILCPU}; int ncpu; size_t size = sizeof(ncpu); sysctl( name, 2, &ncpu, &size, NULL, 0 ); return ncpu; } #define __TBB_HardwareConcurrency() __TBB_macos_available_cpu() #ifndef __TBB_full_memory_fence // TBB has not recognized the architecture (none of the architecture abstraction // headers was included). #define __TBB_UnknownArchitecture 1 #endif #if __TBB_UnknownArchitecture // Implementation of atomic operations based on OS provided primitives #include static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t value, int64_t comparand) { __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for OS X* atomics"); int64_t* address = (int64_t*)ptr; while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){ #if __TBB_WORDSIZE==8 int64_t snapshot = *address; #else int64_t snapshot = OSAtomicAdd64( 0, address ); #endif if( snapshot!=comparand ) return snapshot; } return comparand; } #define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8_OsX #endif /* __TBB_UnknownArchitecture */ #if __TBB_UnknownArchitecture #ifndef __TBB_WORDSIZE #define __TBB_WORDSIZE 4 #endif #ifdef __TBB_ENDIANNESS // Already determined based on hardware architecture. #elif __BIG_ENDIAN__ #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG #elif __LITTLE_ENDIAN__ #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #else #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED #endif /** As this generic implementation has absolutely no information about underlying hardware, its performance most likely will be sub-optimal because of full memory fence usages where a more lightweight synchronization means (or none at all) could suffice. Thus if you use this header to enable TBB on a new platform, consider forking it and relaxing below helpers as appropriate. **/ #define __TBB_control_consistency_helper() OSMemoryBarrier() #define __TBB_acquire_consistency_helper() OSMemoryBarrier() #define __TBB_release_consistency_helper() OSMemoryBarrier() #define __TBB_full_memory_fence() OSMemoryBarrier() static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand) { __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for OS X* atomics"); int32_t* address = (int32_t*)ptr; while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){ int32_t snapshot = *address; if( snapshot!=comparand ) return snapshot; } return comparand; } static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend) { __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for OS X* atomics"); return OSAtomicAdd32Barrier(addend, (int32_t*)ptr) - addend; } static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend) { __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for OS X* atomics"); return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend; } #define __TBB_USE_GENERIC_PART_WORD_CAS 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #if __TBB_WORDSIZE == 4 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 #endif #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #endif /* __TBB_UnknownArchitecture */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/mic_common.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_mic_common_H #define __TBB_mic_common_H #ifndef __TBB_machine_H #error Do not #include this internal file directly; use public TBB headers instead. #endif #if ! __TBB_DEFINE_MIC #error mic_common.h should be included only when building for Intel(R) Many Integrated Core Architecture #endif #ifndef __TBB_PREFETCHING #define __TBB_PREFETCHING 1 #endif #if __TBB_PREFETCHING #include #define __TBB_cl_prefetch(p) _mm_prefetch((const char*)p, _MM_HINT_T1) #define __TBB_cl_evict(p) _mm_clevict(p, _MM_HINT_T1) #endif /** Intel(R) Many Integrated Core Architecture does not support mfence and pause instructions **/ #define __TBB_full_memory_fence() __asm__ __volatile__("lock; addl $0,(%%rsp)":::"memory") #define __TBB_Pause(x) _mm_delay_32(16*(x)) #define __TBB_STEALING_PAUSE 1500/16 #include #define __TBB_Yield() sched_yield() // low-level timing intrinsic and its type #define __TBB_machine_time_stamp() _rdtsc() typedef uint64_t machine_tsc_t; /** Specifics **/ #define __TBB_STEALING_ABORT_ON_CONTENTION 1 #define __TBB_YIELD2P 1 #define __TBB_HOARD_NONLOCAL_TASKS 1 #if ! ( __FreeBSD__ || __linux__ ) #error Intel(R) Many Integrated Core Compiler does not define __FreeBSD__ or __linux__ anymore. Check for the __TBB_XXX_BROKEN defined under __FreeBSD__ or __linux__. #endif /* ! ( __FreeBSD__ || __linux__ ) */ #endif /* __TBB_mic_common_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/msvc_armv7.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_msvc_armv7_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_msvc_armv7_H #include #include #define __TBB_WORDSIZE 4 #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED #if defined(TBB_WIN32_USE_CL_BUILTINS) // We can test this on _M_IX86 #pragma intrinsic(_ReadWriteBarrier) #pragma intrinsic(_mm_mfence) #define __TBB_compiler_fence() _ReadWriteBarrier() #define __TBB_full_memory_fence() _mm_mfence() #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() #define __TBB_release_consistency_helper() __TBB_compiler_fence() #else //Now __dmb(_ARM_BARRIER_SY) is used for both compiler and memory fences //This might be changed later after testing #define __TBB_compiler_fence() __dmb(_ARM_BARRIER_SY) #define __TBB_full_memory_fence() __dmb(_ARM_BARRIER_SY) #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() __TBB_full_memory_fence() #define __TBB_release_consistency_helper() __TBB_full_memory_fence() #endif //-------------------------------------------------- // Compare and swap //-------------------------------------------------- /** * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand * @param value value to assign *ptr to if *ptr==comparand * @param comparand value to compare with *ptr * @return value originally in memory at ptr, regardless of success */ #define __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(S,T,F) \ inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ return _InterlockedCompareExchange##F(reinterpret_cast(ptr),value,comparand); \ } \ #define __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(S,T,F) \ inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ return _InterlockedExchangeAdd##F(reinterpret_cast(ptr),value); \ } \ __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(1,char,8) __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(2,short,16) __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(4,long,) __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(8,__int64,64) __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(4,long,) #if defined(TBB_WIN32_USE_CL_BUILTINS) // No _InterlockedExchangeAdd64 intrinsic on _M_IX86 #define __TBB_64BIT_ATOMICS 0 #else __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(8,__int64,64) #endif inline void __TBB_machine_pause (int32_t delay ) { while(delay>0) { __TBB_compiler_fence(); delay--; } } // API to retrieve/update FPU control setting #define __TBB_CPU_CTL_ENV_PRESENT 1 namespace tbb { namespace internal { template struct machine_load_store_relaxed { static inline T load ( const volatile T& location ) { const T value = location; /* * An extra memory barrier is required for errata #761319 * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a */ __TBB_acquire_consistency_helper(); return value; } static inline void store ( volatile T& location, T value ) { location = value; } }; class cpu_ctl_env { private: unsigned int my_ctl; public: bool operator!=( const cpu_ctl_env& ctl ) const { return my_ctl != ctl.my_ctl; } void get_env() { my_ctl = _control87(0, 0); } void set_env() const { _control87( my_ctl, ~0U ); } }; } // namespace internal } // namespaces tbb // Machine specific atomic operations #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_Pause(V) __TBB_machine_pause(V) // Use generics for some things #define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 1 #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #if defined(TBB_WIN32_USE_CL_BUILTINS) #if !__TBB_WIN8UI_SUPPORT extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); #define __TBB_Yield() SwitchToThread() #else #include #define __TBB_Yield() std::this_thread::yield() #endif #else #define __TBB_Yield() __yield() #endif // Machine specific atomic operations #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) template inline void __TBB_machine_OR( T1 *operand, T2 addend ) { _InterlockedOr((long volatile *)operand, (long)addend); } template inline void __TBB_machine_AND( T1 *operand, T2 addend ) { _InterlockedAnd((long volatile *)operand, (long)addend); } ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/msvc_ia32_common.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_msvc_ia32_common_H #define __TBB_machine_msvc_ia32_common_H #include //TODO: consider moving this macro to tbb_config.h and used there MSVC asm is used #if !_M_X64 || __INTEL_COMPILER #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 1 #if _M_X64 #define __TBB_r(reg_name) r##reg_name #else #define __TBB_r(reg_name) e##reg_name #endif #else //MSVC in x64 mode does not accept inline assembler #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 0 #endif #define __TBB_NO_X86_MSVC_INLINE_ASM_MSG "The compiler being used is not supported (outdated?)" #if (_MSC_VER >= 1300) || (__INTEL_COMPILER) //Use compiler intrinsic when available #define __TBB_PAUSE_USE_INTRINSIC 1 #pragma intrinsic(_mm_pause) namespace tbb { namespace internal { namespace intrinsics { namespace msvc { static inline void __TBB_machine_pause (uintptr_t delay ) { for (;delay>0; --delay ) _mm_pause(); } }}}} #else #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG #endif namespace tbb { namespace internal { namespace inline_asm { namespace msvc { static inline void __TBB_machine_pause (uintptr_t delay ) { _asm { mov __TBB_r(ax), delay __TBB_L1: pause add __TBB_r(ax), -1 jne __TBB_L1 } return; } }}}} #endif static inline void __TBB_machine_pause (uintptr_t delay ){ #if __TBB_PAUSE_USE_INTRINSIC tbb::internal::intrinsics::msvc::__TBB_machine_pause(delay); #else tbb::internal::inline_asm::msvc::__TBB_machine_pause(delay); #endif } //TODO: move this function to windows_api.h or to place where it is used #if (_MSC_VER<1400) && (!_WIN64) && (__TBB_X86_MSVC_INLINE_ASM_AVAILABLE) static inline void* __TBB_machine_get_current_teb () { void* pteb; __asm mov eax, fs:[0x18] __asm mov pteb, eax return pteb; } #endif #if ( _MSC_VER>=1400 && !defined(__INTEL_COMPILER) ) || (__INTEL_COMPILER>=1200) // MSVC did not have this intrinsic prior to VC8. // ICL 11.1 fails to compile a TBB example if __TBB_Log2 uses the intrinsic. #define __TBB_LOG2_USE_BSR_INTRINSIC 1 #if _M_X64 #define __TBB_BSR_INTRINSIC _BitScanReverse64 #else #define __TBB_BSR_INTRINSIC _BitScanReverse #endif #pragma intrinsic(__TBB_BSR_INTRINSIC) namespace tbb { namespace internal { namespace intrinsics { namespace msvc { inline uintptr_t __TBB_machine_lg( uintptr_t i ){ unsigned long j; __TBB_BSR_INTRINSIC( &j, i ); return j; } }}}} #else #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG #endif namespace tbb { namespace internal { namespace inline_asm { namespace msvc { inline uintptr_t __TBB_machine_lg( uintptr_t i ){ uintptr_t j; __asm { bsr __TBB_r(ax), i mov j, __TBB_r(ax) } return j; } }}}} #endif static inline intptr_t __TBB_machine_lg( uintptr_t i ) { #if __TBB_LOG2_USE_BSR_INTRINSIC return tbb::internal::intrinsics::msvc::__TBB_machine_lg(i); #else return tbb::internal::inline_asm::msvc::__TBB_machine_lg(i); #endif } // API to retrieve/update FPU control setting #define __TBB_CPU_CTL_ENV_PRESENT 1 namespace tbb { namespace internal { class cpu_ctl_env; } } #if __TBB_X86_MSVC_INLINE_ASM_AVAILABLE inline void __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* ctl ) { __asm { __asm mov __TBB_r(ax), ctl __asm stmxcsr [__TBB_r(ax)] __asm fstcw [__TBB_r(ax)+4] } } inline void __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* ctl ) { __asm { __asm mov __TBB_r(ax), ctl __asm ldmxcsr [__TBB_r(ax)] __asm fldcw [__TBB_r(ax)+4] } } #else extern "C" { void __TBB_EXPORTED_FUNC __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* ); void __TBB_EXPORTED_FUNC __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* ); } #endif namespace tbb { namespace internal { class cpu_ctl_env { private: int mxcsr; short x87cw; static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */ public: bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; } void get_env() { __TBB_get_cpu_ctl_env( this ); mxcsr &= MXCSR_CONTROL_MASK; } void set_env() const { __TBB_set_cpu_ctl_env( this ); } }; } // namespace internal } // namespace tbb #if !__TBB_WIN8UI_SUPPORT extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); #define __TBB_Yield() SwitchToThread() #else #include #define __TBB_Yield() std::this_thread::yield() #endif #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) #undef __TBB_r extern "C" { __int8 __TBB_EXPORTED_FUNC __TBB_machine_try_lock_elided (volatile void* ptr); void __TBB_EXPORTED_FUNC __TBB_machine_unlock_elided (volatile void* ptr); // 'pause' instruction aborts HLE/RTM transactions #if __TBB_PAUSE_USE_INTRINSIC inline static void __TBB_machine_try_lock_elided_cancel() { _mm_pause(); } #else inline static void __TBB_machine_try_lock_elided_cancel() { _asm pause; } #endif #if __TBB_TSX_INTRINSICS_PRESENT #define __TBB_machine_is_in_transaction _xtest #define __TBB_machine_begin_transaction _xbegin #define __TBB_machine_end_transaction _xend // The value (0xFF) below comes from the // Intel(R) 64 and IA-32 Architectures Optimization Reference Manual 12.4.5 lock not free #define __TBB_machine_transaction_conflict_abort() _xabort(0xFF) #else __int8 __TBB_EXPORTED_FUNC __TBB_machine_is_in_transaction(); unsigned __int32 __TBB_EXPORTED_FUNC __TBB_machine_begin_transaction(); void __TBB_EXPORTED_FUNC __TBB_machine_end_transaction(); void __TBB_EXPORTED_FUNC __TBB_machine_transaction_conflict_abort(); #endif /* __TBB_TSX_INTRINSICS_PRESENT */ } #endif /* __TBB_machine_msvc_ia32_common_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/sunos_sparc.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_sunos_sparc_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_sunos_sparc_H #include #include #define __TBB_WORDSIZE 8 // Big endian is assumed for SPARC. // While hardware may support page-specific bi-endianness, only big endian pages may be exposed to TBB #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG /** To those working on SPARC hardware. Consider relaxing acquire and release consistency helpers to no-op (as this port covers TSO mode only). **/ #define __TBB_compiler_fence() __asm__ __volatile__ ("": : :"memory") #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() #define __TBB_release_consistency_helper() __TBB_compiler_fence() #define __TBB_full_memory_fence() __asm__ __volatile__("membar #LoadLoad|#LoadStore|#StoreStore|#StoreLoad": : : "memory") //-------------------------------------------------- // Compare and swap //-------------------------------------------------- /** * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand * @param value value to assign *ptr to if *ptr==comparand * @param comparand value to compare with *ptr ( @return value originally in memory at ptr, regardless of success */ static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand ){ int32_t result; __asm__ __volatile__( "cas\t[%5],%4,%1" : "=m"(*(int32_t *)ptr), "=r"(result) : "m"(*(int32_t *)ptr), "1"(value), "r"(comparand), "r"(ptr) : "memory"); return result; } /** * Atomic CAS for 64 bit values, if *ptr==comparand, then *ptr=value, returns *ptr * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand * @param value value to assign *ptr to if *ptr==comparand * @param comparand value to compare with *ptr ( @return value originally in memory at ptr, regardless of success */ static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, int64_t comparand ){ int64_t result; __asm__ __volatile__( "casx\t[%5],%4,%1" : "=m"(*(int64_t *)ptr), "=r"(result) : "m"(*(int64_t *)ptr), "1"(value), "r"(comparand), "r"(ptr) : "memory"); return result; } //--------------------------------------------------- // Fetch and add //--------------------------------------------------- /** * Atomic fetch and add for 32 bit values, in this case implemented by continuously checking success of atomicity * @param ptr pointer to value to add addend to * @param addened value to add to *ptr * @return value at ptr before addened was added */ static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend){ int32_t result; __asm__ __volatile__ ( "0:\t add\t %3, %4, %0\n" // do addition "\t cas\t [%2], %3, %0\n" // cas to store result in memory "\t cmp\t %3, %0\n" // check if value from memory is original "\t bne,a,pn\t %%icc, 0b\n" // if not try again "\t mov %0, %3\n" // use branch delay slot to move new value in memory to be added : "=&r"(result), "=m"(*(int32_t *)ptr) : "r"(ptr), "r"(*(int32_t *)ptr), "r"(addend), "m"(*(int32_t *)ptr) : "ccr", "memory"); return result; } /** * Atomic fetch and add for 64 bit values, in this case implemented by continuously checking success of atomicity * @param ptr pointer to value to add addend to * @param addened value to add to *ptr * @return value at ptr before addened was added */ static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend){ int64_t result; __asm__ __volatile__ ( "0:\t add\t %3, %4, %0\n" // do addition "\t casx\t [%2], %3, %0\n" // cas to store result in memory "\t cmp\t %3, %0\n" // check if value from memory is original "\t bne,a,pn\t %%xcc, 0b\n" // if not try again "\t mov %0, %3\n" // use branch delay slot to move new value in memory to be added : "=&r"(result), "=m"(*(int64_t *)ptr) : "r"(ptr), "r"(*(int64_t *)ptr), "r"(addend), "m"(*(int64_t *)ptr) : "ccr", "memory"); return result; } //-------------------------------------------------------- // Logarithm (base two, integer) //-------------------------------------------------------- static inline int64_t __TBB_machine_lg( uint64_t x ) { __TBB_ASSERT(x, "__TBB_Log2(0) undefined"); uint64_t count; // one hot encode x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); x |= (x >> 32); // count 1's __asm__ ("popc %1, %0" : "=r"(count) : "r"(x) ); return count-1; } //-------------------------------------------------------- static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) { __asm__ __volatile__ ( "0:\t or\t %2, %3, %%g1\n" // do operation "\t casx\t [%1], %2, %%g1\n" // cas to store result in memory "\t cmp\t %2, %%g1\n" // check if value from memory is original "\t bne,a,pn\t %%xcc, 0b\n" // if not try again "\t mov %%g1, %2\n" // use branch delay slot to move new value in memory to be added : "=m"(*(int64_t *)ptr) : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr) : "ccr", "g1", "memory"); } static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) { __asm__ __volatile__ ( "0:\t and\t %2, %3, %%g1\n" // do operation "\t casx\t [%1], %2, %%g1\n" // cas to store result in memory "\t cmp\t %2, %%g1\n" // check if value from memory is original "\t bne,a,pn\t %%xcc, 0b\n" // if not try again "\t mov %%g1, %2\n" // use branch delay slot to move new value in memory to be added : "=m"(*(int64_t *)ptr) : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr) : "ccr", "g1", "memory"); } static inline void __TBB_machine_pause( int32_t delay ) { // do nothing, inlined, doesn't matter } // put 0xff in memory location, return memory value, // generic trylockbyte puts 0x01, however this is fine // because all that matters is that 0 is unlocked static inline bool __TBB_machine_trylockbyte(unsigned char &flag){ unsigned char result; __asm__ __volatile__ ( "ldstub\t [%2], %0\n" : "=r"(result), "=m"(flag) : "r"(&flag), "m"(flag) : "memory"); return result == 0; } #define __TBB_USE_GENERIC_PART_WORD_CAS 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) // Definition of other functions #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) #define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/windows_api.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_windows_api_H #define __TBB_machine_windows_api_H #if _WIN32 || _WIN64 #if _XBOX #define NONET #define NOD3D #include #else // Assume "usual" Windows #include #endif // _XBOX #if _WIN32_WINNT < 0x0600 // The following Windows API function is declared explicitly; // otherwise it fails to compile by VS2005. #if !defined(WINBASEAPI) || (_WIN32_WINNT < 0x0501 && _MSC_VER == 1400) #define __TBB_WINBASEAPI extern "C" #else #define __TBB_WINBASEAPI WINBASEAPI #endif __TBB_WINBASEAPI BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION ); __TBB_WINBASEAPI BOOL WINAPI InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION, DWORD ); // Overloading WINBASEAPI macro and using local functions missing in Windows XP/2003 #define InitializeCriticalSectionEx inlineInitializeCriticalSectionEx #define CreateSemaphoreEx inlineCreateSemaphoreEx #define CreateEventEx inlineCreateEventEx inline BOOL WINAPI inlineInitializeCriticalSectionEx( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD ) { return InitializeCriticalSectionAndSpinCount( lpCriticalSection, dwSpinCount ); } inline HANDLE WINAPI inlineCreateSemaphoreEx( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName, DWORD, DWORD ) { return CreateSemaphore( lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName ); } inline HANDLE WINAPI inlineCreateEventEx( LPSECURITY_ATTRIBUTES lpEventAttributes, LPCTSTR lpName, DWORD dwFlags, DWORD ) { BOOL manual_reset = dwFlags&0x00000001 ? TRUE : FALSE; // CREATE_EVENT_MANUAL_RESET BOOL initial_set = dwFlags&0x00000002 ? TRUE : FALSE; // CREATE_EVENT_INITIAL_SET return CreateEvent( lpEventAttributes, manual_reset, initial_set, lpName ); } #endif #if defined(RTL_SRWLOCK_INIT) #ifndef __TBB_USE_SRWLOCK // TODO: turn it on when bug 1952 will be fixed #define __TBB_USE_SRWLOCK 0 #endif #endif #else #error tbb/machine/windows_api.h should only be used for Windows based platforms #endif // _WIN32 || _WIN64 #endif // __TBB_machine_windows_api_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/windows_ia32.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_ia32_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_windows_ia32_H #include "msvc_ia32_common.h" #define __TBB_WORDSIZE 4 #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #if __INTEL_COMPILER && (__INTEL_COMPILER < 1100) #define __TBB_compiler_fence() __asm { __asm nop } #define __TBB_full_memory_fence() __asm { __asm mfence } #elif _MSC_VER >= 1300 || __INTEL_COMPILER #pragma intrinsic(_ReadWriteBarrier) #pragma intrinsic(_mm_mfence) #define __TBB_compiler_fence() _ReadWriteBarrier() #define __TBB_full_memory_fence() _mm_mfence() #else #error Unsupported compiler - need to define __TBB_{control,acquire,release}_consistency_helper to support it #endif #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() #define __TBB_release_consistency_helper() __TBB_compiler_fence() #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (push) #pragma warning (disable: 4244 4267) #endif extern "C" { __int64 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp8 (volatile void *ptr, __int64 value, __int64 comparand ); __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd8 (volatile void *ptr, __int64 addend ); __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ); void __TBB_EXPORTED_FUNC __TBB_machine_store8 (volatile void *ptr, __int64 value ); __int64 __TBB_EXPORTED_FUNC __TBB_machine_load8 (const volatile void *ptr); } //TODO: use _InterlockedXXX intrinsics as they available since VC 2005 #define __TBB_MACHINE_DEFINE_ATOMICS(S,T,U,A,C) \ static inline T __TBB_machine_cmpswp##S ( volatile void * ptr, U value, U comparand ) { \ T result; \ volatile T *p = (T *)ptr; \ __asm \ { \ __asm mov edx, p \ __asm mov C , value \ __asm mov A , comparand \ __asm lock cmpxchg [edx], C \ __asm mov result, A \ } \ return result; \ } \ \ static inline T __TBB_machine_fetchadd##S ( volatile void * ptr, U addend ) { \ T result; \ volatile T *p = (T *)ptr; \ __asm \ { \ __asm mov edx, p \ __asm mov A, addend \ __asm lock xadd [edx], A \ __asm mov result, A \ } \ return result; \ }\ \ static inline T __TBB_machine_fetchstore##S ( volatile void * ptr, U value ) { \ T result; \ volatile T *p = (T *)ptr; \ __asm \ { \ __asm mov edx, p \ __asm mov A, value \ __asm lock xchg [edx], A \ __asm mov result, A \ } \ return result; \ } __TBB_MACHINE_DEFINE_ATOMICS(1, __int8, __int8, al, cl) __TBB_MACHINE_DEFINE_ATOMICS(2, __int16, __int16, ax, cx) __TBB_MACHINE_DEFINE_ATOMICS(4, ptrdiff_t, ptrdiff_t, eax, ecx) #undef __TBB_MACHINE_DEFINE_ATOMICS static inline void __TBB_machine_OR( volatile void *operand, __int32 addend ) { __asm { mov eax, addend mov edx, [operand] lock or [edx], eax } } static inline void __TBB_machine_AND( volatile void *operand, __int32 addend ) { __asm { mov eax, addend mov edx, [operand] lock and [edx], eax } } #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) //TODO: Check if it possible and profitable for IA-32 architecture on (Linux and Windows) //to use of 64-bit load/store via floating point registers together with full fence //for sequentially consistent load/store, instead of CAS. #define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warnings 4244, 4267 are back ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/windows_intel64.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_intel64_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_windows_intel64_H #define __TBB_WORDSIZE 8 #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #include #include "msvc_ia32_common.h" //TODO: Use _InterlockedXXX16 intrinsics for 2 byte operations #if !__INTEL_COMPILER #pragma intrinsic(_InterlockedOr64) #pragma intrinsic(_InterlockedAnd64) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedExchange64) #endif /* !(__INTEL_COMPILER) */ #if __INTEL_COMPILER && (__INTEL_COMPILER < 1100) #define __TBB_compiler_fence() __asm { __asm nop } #define __TBB_full_memory_fence() __asm { __asm mfence } #elif _MSC_VER >= 1300 || __INTEL_COMPILER #pragma intrinsic(_ReadWriteBarrier) #pragma intrinsic(_mm_mfence) #define __TBB_compiler_fence() _ReadWriteBarrier() #define __TBB_full_memory_fence() _mm_mfence() #endif #define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() #define __TBB_release_consistency_helper() __TBB_compiler_fence() // ATTENTION: if you ever change argument types in machine-specific primitives, // please take care of atomic_word<> specializations in tbb/atomic.h extern "C" { __int8 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp1 (volatile void *ptr, __int8 value, __int8 comparand ); __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd1 (volatile void *ptr, __int8 addend ); __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore1 (volatile void *ptr, __int8 value ); __int16 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp2 (volatile void *ptr, __int16 value, __int16 comparand ); __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd2 (volatile void *ptr, __int16 addend ); __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore2 (volatile void *ptr, __int16 value ); } inline long __TBB_machine_cmpswp4 (volatile void *ptr, __int32 value, __int32 comparand ) { return _InterlockedCompareExchange( (long*)ptr, value, comparand ); } inline long __TBB_machine_fetchadd4 (volatile void *ptr, __int32 addend ) { return _InterlockedExchangeAdd( (long*)ptr, addend ); } inline long __TBB_machine_fetchstore4 (volatile void *ptr, __int32 value ) { return _InterlockedExchange( (long*)ptr, value ); } inline __int64 __TBB_machine_cmpswp8 (volatile void *ptr, __int64 value, __int64 comparand ) { return _InterlockedCompareExchange64( (__int64*)ptr, value, comparand ); } inline __int64 __TBB_machine_fetchadd8 (volatile void *ptr, __int64 addend ) { return _InterlockedExchangeAdd64( (__int64*)ptr, addend ); } inline __int64 __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ) { return _InterlockedExchange64( (__int64*)ptr, value ); } #define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 inline void __TBB_machine_OR( volatile void *operand, intptr_t addend ) { _InterlockedOr64((__int64*)operand, addend); } inline void __TBB_machine_AND( volatile void *operand, intptr_t addend ) { _InterlockedAnd64((__int64*)operand, addend); } #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/machine/xbox360_ppc.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // TODO: revise by comparing with mac_ppc.h #if !defined(__TBB_machine_H) || defined(__TBB_machine_xbox360_ppc_H) #error Do not #include this internal file directly; use public TBB headers instead. #endif #define __TBB_machine_xbox360_ppc_H #define NONET #define NOD3D #include "xtl.h" #include "ppcintrinsics.h" #if _MSC_VER >= 1300 extern "C" void _MemoryBarrier(); #pragma intrinsic(_MemoryBarrier) #define __TBB_control_consistency_helper() __isync() #define __TBB_acquire_consistency_helper() _MemoryBarrier() #define __TBB_release_consistency_helper() _MemoryBarrier() #endif #define __TBB_full_memory_fence() __sync() #define __TBB_WORDSIZE 4 #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG //todo: define __TBB_USE_FENCED_ATOMICS and define acquire/release primitives to maximize performance inline __int32 __TBB_machine_cmpswp4(volatile void *ptr, __int32 value, __int32 comparand ) { __sync(); __int32 result = InterlockedCompareExchange((volatile LONG*)ptr, value, comparand); __isync(); return result; } inline __int64 __TBB_machine_cmpswp8(volatile void *ptr, __int64 value, __int64 comparand ) { __sync(); __int64 result = InterlockedCompareExchange64((volatile LONG64*)ptr, value, comparand); __isync(); return result; } #define __TBB_USE_GENERIC_PART_WORD_CAS 1 #define __TBB_USE_GENERIC_FETCH_ADD 1 #define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #pragma optimize( "", off ) inline void __TBB_machine_pause (__int32 delay ) { for (__int32 i=0; i> 0) & 1) + ((__TBB_XBOX360_HARDWARE_THREAD_MASK >> 1) & 1) + ((__TBB_XBOX360_HARDWARE_THREAD_MASK >> 2) & 1) + ((__TBB_XBOX360_HARDWARE_THREAD_MASK >> 3) & 1) + ((__TBB_XBOX360_HARDWARE_THREAD_MASK >> 4) & 1) + ((__TBB_XBOX360_HARDWARE_THREAD_MASK >> 5) & 1) + 1; // +1 accomodates for the master thread } static inline int __TBB_XBOX360_GetHardwareThreadIndex(int workerThreadIndex) { workerThreadIndex %= __TBB_XBOX360_DetectNumberOfWorkers()-1; int m = __TBB_XBOX360_HARDWARE_THREAD_MASK; int index = 0; int skipcount = workerThreadIndex; while (true) { if ((m & 1)!=0) { if (skipcount==0) break; skipcount--; } m >>= 1; index++; } return index; } #define __TBB_HardwareConcurrency() __TBB_XBOX360_DetectNumberOfWorkers() ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/mailbox.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_mailbox_H #define _TBB_mailbox_H #include "tbb/tbb_stddef.h" #include "tbb/cache_aligned_allocator.h" #include "scheduler_common.h" #include "tbb/atomic.h" namespace tbb { namespace internal { struct task_proxy : public task { static const intptr_t pool_bit = 1<<0; static const intptr_t mailbox_bit = 1<<1; static const intptr_t location_mask = pool_bit | mailbox_bit; /* All but two low-order bits represent a (task*). Two low-order bits mean: 1 = proxy is/was/will be in task pool 2 = proxy is/was/will be in mailbox */ intptr_t task_and_tag; //! Pointer to next task_proxy in a mailbox task_proxy *__TBB_atomic next_in_mailbox; //! Mailbox to which this was mailed. mail_outbox* outbox; //! True if the proxy is stored both in its sender's pool and in the destination mailbox. static bool is_shared ( intptr_t tat ) { return (tat & location_mask) == location_mask; } //! Returns a pointer to the encapsulated task or NULL. static task* task_ptr ( intptr_t tat ) { return (task*)(tat & ~location_mask); } //! Returns a pointer to the encapsulated task or NULL, and frees proxy if necessary. template inline task* extract_task () { __TBB_ASSERT( prefix().extra_state == es_task_proxy, "Normal task misinterpreted as a proxy?" ); intptr_t tat = __TBB_load_with_acquire(task_and_tag); __TBB_ASSERT( tat == from_bit || (is_shared(tat) && task_ptr(tat)), "Proxy's tag cannot specify both locations if the proxy " "was retrieved from one of its original locations" ); if ( tat != from_bit ) { const intptr_t cleaner_bit = location_mask & ~from_bit; // Attempt to transition the proxy to the "empty" state with // cleaner_bit specifying entity responsible for its eventual freeing. // Explicit cast to void* is to work around a seeming ICC 11.1 bug. if ( as_atomic(task_and_tag).compare_and_swap(cleaner_bit, tat) == tat ) { // Successfully grabbed the task, and left new owner with the job of freeing the proxy return task_ptr(tat); } } // Proxied task has already been claimed from another proxy location. __TBB_ASSERT( task_and_tag == from_bit, "Empty proxy cannot contain non-zero task pointer" ); poison_pointer(outbox); poison_pointer(next_in_mailbox); poison_value(task_and_tag); return NULL; } }; // struct task_proxy //! Internal representation of mail_outbox, without padding. class unpadded_mail_outbox { protected: typedef task_proxy*__TBB_atomic proxy_ptr; //! Pointer to first task_proxy in mailbox, or NULL if box is empty. proxy_ptr my_first; //! Pointer to pointer that will point to next item in the queue. Never NULL. proxy_ptr* __TBB_atomic my_last; //! Owner of mailbox is not executing a task, and has drained its own task pool. bool my_is_idle; }; //! Class representing where mail is put. /** Padded to occupy a cache line. */ class mail_outbox : padded { task_proxy* internal_pop() { task_proxy* const first = __TBB_load_relaxed(my_first); if( !first ) return NULL; __TBB_control_consistency_helper(); // on my_first // There is a first item in the mailbox. See if there is a second. if( task_proxy* second = first->next_in_mailbox ) { // There are at least two items, so first item can be popped easily. my_first = second; } else { // There is only one item. Some care is required to pop it. my_first = NULL; if( as_atomic(my_last).compare_and_swap(&my_first,&first->next_in_mailbox) == &first->next_in_mailbox ) { // Successfully transitioned mailbox from having one item to having none. __TBB_ASSERT(!first->next_in_mailbox,NULL); } else { // Some other thread updated my_last but has not filled in first->next_in_mailbox // Wait until first item points to second item. atomic_backoff backoff; while( !(second = first->next_in_mailbox) ) backoff.pause(); my_first = second; } } return first; } public: friend class mail_inbox; //! Push task_proxy onto the mailbox queue of another thread. /** Implementation is wait-free. */ void push( task_proxy& t ) { __TBB_ASSERT(&t, NULL); t.next_in_mailbox = NULL; proxy_ptr * const link = (proxy_ptr *)__TBB_FetchAndStoreW(&my_last,(intptr_t)&t.next_in_mailbox); // No release fence required for the next store, because there are no memory operations // between the previous fully fenced atomic operation and the store. __TBB_store_relaxed(*link, &t); } //! Return true if mailbox is empty bool empty() { return __TBB_load_relaxed(my_first) == NULL; } //! Construct *this as a mailbox from zeroed memory. /** Raise assertion if *this is not previously zeroed, or sizeof(this) is wrong. This method is provided instead of a full constructor since we know the object will be constructed in zeroed memory. */ void construct() { __TBB_ASSERT( sizeof(*this)==NFS_MaxLineSize, NULL ); __TBB_ASSERT( !my_first, NULL ); __TBB_ASSERT( !my_last, NULL ); __TBB_ASSERT( !my_is_idle, NULL ); my_last=&my_first; suppress_unused_warning(pad); } //! Drain the mailbox intptr_t drain() { intptr_t k = 0; // No fences here because other threads have already quit. for( ; task_proxy* t = my_first; ++k ) { my_first = t->next_in_mailbox; NFS_Free((char*)t - task_prefix_reservation_size); } return k; } //! True if thread that owns this mailbox is looking for work. bool recipient_is_idle() { return my_is_idle; } }; // class mail_outbox //! Class representing source of mail. class mail_inbox { //! Corresponding sink where mail that we receive will be put. mail_outbox* my_putter; public: //! Construct unattached inbox mail_inbox() : my_putter(NULL) {} //! Attach inbox to a corresponding outbox. void attach( mail_outbox& putter ) { __TBB_ASSERT(!my_putter,"already attached"); my_putter = &putter; } //! Detach inbox from its outbox void detach() { __TBB_ASSERT(my_putter,"not attached"); my_putter = NULL; } //! Get next piece of mail, or NULL if mailbox is empty. task_proxy* pop() { return my_putter->internal_pop(); } //! Return true if mailbox is empty bool empty() { return my_putter->empty(); } //! Indicate whether thread that reads this mailbox is idle. /** Raises assertion failure if mailbox is redundantly marked as not idle. */ void set_is_idle( bool value ) { if( my_putter ) { __TBB_ASSERT( my_putter->my_is_idle || value, "attempt to redundantly mark mailbox as not idle" ); my_putter->my_is_idle = value; } } //! Indicate whether thread that reads this mailbox is idle. bool is_idle_state ( bool value ) const { return !my_putter || my_putter->my_is_idle == value; } #if DO_ITT_NOTIFY //! Get pointer to corresponding outbox used for ITT_NOTIFY calls. void* outbox() const {return my_putter;} #endif /* DO_ITT_NOTIFY */ }; // class mail_inbox } // namespace internal } // namespace tbb #endif /* _TBB_mailbox_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/market.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_stddef.h" #include "market.h" #include "tbb_main.h" #include "governor.h" #include "scheduler.h" #include "itt_notify.h" namespace tbb { namespace internal { void market::insert_arena_into_list ( arena& a ) { #if __TBB_TASK_PRIORITY arena_list_type &arenas = my_priority_levels[a.my_top_priority].arenas; arena *&next = my_priority_levels[a.my_top_priority].next_arena; #else /* !__TBB_TASK_PRIORITY */ arena_list_type &arenas = my_arenas; arena *&next = my_next_arena; #endif /* !__TBB_TASK_PRIORITY */ arenas.push_front( a ); if ( arenas.size() == 1 ) next = &*arenas.begin(); } void market::remove_arena_from_list ( arena& a ) { #if __TBB_TASK_PRIORITY arena_list_type &arenas = my_priority_levels[a.my_top_priority].arenas; arena *&next = my_priority_levels[a.my_top_priority].next_arena; #else /* !__TBB_TASK_PRIORITY */ arena_list_type &arenas = my_arenas; arena *&next = my_next_arena; #endif /* !__TBB_TASK_PRIORITY */ arena_list_type::iterator it = next; __TBB_ASSERT( it != arenas.end(), NULL ); if ( next == &a ) { if ( ++it == arenas.end() && arenas.size() > 1 ) it = arenas.begin(); next = &*it; } arenas.remove( a ); } //------------------------------------------------------------------------ // market //------------------------------------------------------------------------ market::market ( unsigned max_num_workers, size_t stack_size ) : my_ref_count(1) , my_stack_size(stack_size) , my_max_num_workers(max_num_workers) #if __TBB_TASK_PRIORITY , my_global_top_priority(normalized_normal_priority) , my_global_bottom_priority(normalized_normal_priority) #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION , my_lowest_populated_level(normalized_normal_priority) #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ #endif /* __TBB_TASK_PRIORITY */ { #if __TBB_TASK_PRIORITY __TBB_ASSERT( my_global_reload_epoch == 0, NULL ); my_priority_levels[normalized_normal_priority].workers_available = max_num_workers; #endif /* __TBB_TASK_PRIORITY */ // Once created RML server will start initializing workers that will need // global market instance to get worker stack size my_server = governor::create_rml_server( *this ); __TBB_ASSERT( my_server, "Failed to create RML server" ); } market& market::global_market ( unsigned max_num_workers, size_t stack_size ) { global_market_mutex_type::scoped_lock lock( theMarketMutex ); market *m = theMarket; if ( m ) { ++m->my_ref_count; if ( m->my_stack_size < stack_size ) runtime_warning( "Newer master request for larger stack cannot be satisfied\n" ); } else { max_num_workers = max( governor::default_num_threads() - 1, max_num_workers ); // at least 1 worker is required to support starvation resistant tasks if( max_num_workers==0 ) max_num_workers = 1; // Create the global market instance size_t size = sizeof(market); #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT( __TBB_offsetof(market, my_workers) + sizeof(generic_scheduler*) == sizeof(market), "my_workers must be the last data field of the market class"); size += sizeof(generic_scheduler*) * (max_num_workers - 1); #endif /* __TBB_TASK_GROUP_CONTEXT */ __TBB_InitOnce::add_ref(); void* storage = NFS_Allocate(1, size, NULL); memset( storage, 0, size ); // Initialize and publish global market m = new (storage) market( max_num_workers, stack_size ); theMarket = m; } return *m; } void market::destroy () { #if __TBB_COUNT_TASK_NODES if ( my_task_node_count ) runtime_warning( "Leaked %ld task objects\n", (long)my_task_node_count ); #endif /* __TBB_COUNT_TASK_NODES */ this->~market(); NFS_Free( this ); __TBB_InitOnce::remove_ref(); } void market::release () { __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" ); bool do_release = false; { global_market_mutex_type::scoped_lock lock(theMarketMutex); if ( --my_ref_count == 0 ) { do_release = true; theMarket = NULL; } } if( do_release ) my_server->request_close_connection(); } void market::wait_workers () { // usable for this kind of scheduler only __TBB_ASSERT(governor::needsWaitWorkers(), NULL); // wait till terminating last worker decresed my_ref_count while (__TBB_load_with_acquire(my_ref_count) > 1) __TBB_Yield(); __TBB_ASSERT(1 == my_ref_count, NULL); release(); } arena& market::create_arena ( unsigned max_num_workers, size_t stack_size ) { market &m = global_market( max_num_workers, stack_size ); // increases market's ref count #if __TBB_TASK_ARENA // Prevent cutting an extra slot for task_arena(p,0) with default market (p-1 workers). // This is a temporary workaround for 1968 until (TODO:) master slot reservation is reworked arena& a = arena::allocate_arena( m, min(max_num_workers, m.my_max_num_workers+1) ); #else arena& a = arena::allocate_arena( m, min(max_num_workers, m.my_max_num_workers) ); #endif // Add newly created arena into the existing market's list. arenas_list_mutex_type::scoped_lock lock(m.my_arenas_list_mutex); m.insert_arena_into_list(a); return a; } /** This method must be invoked under my_arenas_list_mutex. **/ void market::detach_arena ( arena& a ) { __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" ); #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION __TBB_ASSERT( !a.my_num_workers_present, NULL ); #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ __TBB_ASSERT( !a.my_slots[0].my_scheduler, NULL ); remove_arena_from_list(a); if ( a.my_aba_epoch == my_arenas_aba_epoch ) ++my_arenas_aba_epoch; } void market::try_destroy_arena ( arena* a, uintptr_t aba_epoch ) { __TBB_ASSERT ( a, NULL ); arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); assert_market_valid(); #if __TBB_TASK_PRIORITY for ( int p = my_global_top_priority; p >= my_global_bottom_priority; --p ) { priority_level_info &pl = my_priority_levels[p]; arena_list_type &my_arenas = pl.arenas; #endif /* __TBB_TASK_PRIORITY */ arena_list_type::iterator it = my_arenas.begin(); for ( ; it != my_arenas.end(); ++it ) { if ( a == &*it ) { if ( it->my_aba_epoch == aba_epoch ) { // Arena is alive if ( !a->my_num_workers_requested && !a->my_references ) { __TBB_ASSERT( !a->my_num_workers_allotted && (a->my_pool_state == arena::SNAPSHOT_EMPTY || !a->my_max_num_workers), "Inconsistent arena state" ); // Arena is abandoned. Destroy it. detach_arena( *a ); lock.release(); a->free_arena(); } } return; } } #if __TBB_TASK_PRIORITY } #endif /* __TBB_TASK_PRIORITY */ } void market::try_destroy_arena ( market* m, arena* a, uintptr_t aba_epoch, bool master ) { // Arena may have been orphaned. Or it may have been destroyed. // Thus we cannot dereference the pointer to it until its liveness is verified. // Arena is alive if it is found in the market's list. if ( m != theMarket ) { // The market has already been emptied. return; } else if ( master ) { // If this is a master thread, market can be destroyed at any moment. // So protect it with an extra refcount. global_market_mutex_type::scoped_lock lock(theMarketMutex); if ( m != theMarket ) return; ++m->my_ref_count; } m->try_destroy_arena( a, aba_epoch ); if ( master ) m->release(); } /** This method must be invoked under my_arenas_list_mutex. **/ arena* market::arena_in_need ( arena_list_type &arenas, arena *&next ) { if ( arenas.empty() ) return NULL; arena_list_type::iterator it = next; __TBB_ASSERT( it != arenas.end(), NULL ); do { arena& a = *it; if ( ++it == arenas.end() ) it = arenas.begin(); if ( a.num_workers_active() < a.my_num_workers_allotted ) { a.my_references += 2; // add a worker #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION ++a.my_num_workers_present; ++my_priority_levels[a.my_top_priority].workers_present; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ as_atomic(next) = &*it; // a subject for innocent data race under the reader lock // TODO: rework global round robin policy to local or random to avoid this write return &a; } } while ( it != next ); return NULL; } void market::update_allotment ( arena_list_type& arenas, int workers_demand, int max_workers ) { __TBB_ASSERT( workers_demand, NULL ); max_workers = min(workers_demand, max_workers); int carry = 0; #if TBB_USE_ASSERT int assigned = 0; #endif /* TBB_USE_ASSERT */ arena_list_type::iterator it = arenas.begin(); for ( ; it != arenas.end(); ++it ) { arena& a = *it; if ( a.my_num_workers_requested <= 0 ) { __TBB_ASSERT( !a.my_num_workers_allotted, NULL ); continue; } int tmp = a.my_num_workers_requested * max_workers + carry; int allotted = tmp / workers_demand; carry = tmp % workers_demand; // a.my_num_workers_requested may temporarily exceed a.my_max_num_workers a.my_num_workers_allotted = min( allotted, (int)a.my_max_num_workers ); #if TBB_USE_ASSERT assigned += a.my_num_workers_allotted; #endif /* TBB_USE_ASSERT */ } __TBB_ASSERT( assigned <= workers_demand, NULL ); } #if __TBB_TASK_PRIORITY inline void market::update_global_top_priority ( intptr_t newPriority ) { GATHER_STATISTIC( ++governor::local_scheduler_if_initialized()->my_counters.market_prio_switches ); my_global_top_priority = newPriority; my_priority_levels[newPriority].workers_available = my_max_num_workers; advance_global_reload_epoch(); } inline void market::reset_global_priority () { my_global_bottom_priority = normalized_normal_priority; update_global_top_priority(normalized_normal_priority); #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION my_lowest_populated_level = normalized_normal_priority; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ } arena* market::arena_in_need ( arena* prev_arena ) { if( !has_any_demand() ) return NULL; arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex, /*is_writer=*/false); assert_market_valid(); #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION if ( prev_arena ) { priority_level_info &pl = my_priority_levels[prev_arena->my_top_priority]; --prev_arena->my_num_workers_present; --pl.workers_present; if ( !--prev_arena->my_references && !prev_arena->my_num_workers_requested ) { detach_arena( *a ); lock.release(); a->free_arena(); lock.acquire(); } } #else suppress_unused_warning(prev_arena); #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ int p = my_global_top_priority; arena *a = NULL; do { priority_level_info &pl = my_priority_levels[p]; #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION __TBB_ASSERT( p >= my_lowest_populated_level, NULL ); if ( pl.workers_present >= pl.workers_requested ) continue; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ a = arena_in_need( pl.arenas, pl.next_arena ); } while ( !a && --p >= my_global_bottom_priority ); return a; } void market::update_allotment ( intptr_t highest_affected_priority ) { intptr_t i = highest_affected_priority; int available = my_priority_levels[i].workers_available; #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION my_lowest_populated_level = my_global_bottom_priority; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ for ( ; i >= my_global_bottom_priority; --i ) { priority_level_info &pl = my_priority_levels[i]; pl.workers_available = available; if ( pl.workers_requested ) { update_allotment( pl.arenas, pl.workers_requested, available ); available -= pl.workers_requested; if ( available < 0 ) { available = 0; #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION my_lowest_populated_level = i; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ break; } } } __TBB_ASSERT( i <= my_global_bottom_priority || !available, NULL ); for ( --i; i >= my_global_bottom_priority; --i ) { priority_level_info &pl = my_priority_levels[i]; pl.workers_available = 0; arena_list_type::iterator it = pl.arenas.begin(); for ( ; it != pl.arenas.end(); ++it ) { __TBB_ASSERT( it->my_num_workers_requested || !it->my_num_workers_allotted, NULL ); it->my_num_workers_allotted = 0; } } } #endif /* __TBB_TASK_PRIORITY */ void market::adjust_demand ( arena& a, int delta ) { __TBB_ASSERT( theMarket, "market instance was destroyed prematurely?" ); if ( !delta ) return; my_arenas_list_mutex.lock(); int prev_req = a.my_num_workers_requested; a.my_num_workers_requested += delta; if ( a.my_num_workers_requested <= 0 ) { a.my_num_workers_allotted = 0; if ( prev_req <= 0 ) { my_arenas_list_mutex.unlock(); return; } delta = -prev_req; } #if __TBB_TASK_ARENA else if ( prev_req < 0 ) { delta = a.my_num_workers_requested; } #else /* __TBB_TASK_ARENA */ __TBB_ASSERT( prev_req >= 0, "Part-size request to RML?" ); #endif /* __TBB_TASK_ARENA */ #if __TBB_TASK_PRIORITY intptr_t p = a.my_top_priority; priority_level_info &pl = my_priority_levels[p]; pl.workers_requested += delta; __TBB_ASSERT( pl.workers_requested >= 0, NULL ); #if !__TBB_TASK_ARENA __TBB_ASSERT( a.my_num_workers_requested >= 0, NULL ); #else //TODO: understand the assertion and modify #endif if ( a.my_num_workers_requested <= 0 ) { if ( a.my_top_priority != normalized_normal_priority ) { GATHER_STATISTIC( ++governor::local_scheduler_if_initialized()->my_counters.arena_prio_resets ); update_arena_top_priority( a, normalized_normal_priority ); } a.my_bottom_priority = normalized_normal_priority; } if ( p == my_global_top_priority ) { if ( !pl.workers_requested ) { while ( --p >= my_global_bottom_priority && !my_priority_levels[p].workers_requested ) continue; if ( p < my_global_bottom_priority ) reset_global_priority(); else update_global_top_priority(p); } update_allotment( my_global_top_priority ); } else if ( p > my_global_top_priority ) { #if !__TBB_TASK_ARENA __TBB_ASSERT( pl.workers_requested > 0, NULL ); #else //TODO: understand the assertion and modify #endif update_global_top_priority(p); a.my_num_workers_allotted = min( (int)my_max_num_workers, a.my_num_workers_requested ); my_priority_levels[p - 1].workers_available = my_max_num_workers - a.my_num_workers_allotted; update_allotment( p - 1 ); } else if ( p == my_global_bottom_priority ) { if ( !pl.workers_requested ) { while ( ++p <= my_global_top_priority && !my_priority_levels[p].workers_requested ) continue; if ( p > my_global_top_priority ) reset_global_priority(); else { my_global_bottom_priority = p; #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION my_lowest_populated_level = max( my_lowest_populated_level, p ); #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ } } else update_allotment( p ); } else if ( p < my_global_bottom_priority ) { __TBB_ASSERT( a.my_num_workers_requested > 0, NULL ); int prev_bottom = my_global_bottom_priority; my_global_bottom_priority = p; update_allotment( prev_bottom ); } else { __TBB_ASSERT( my_global_bottom_priority < p && p < my_global_top_priority, NULL ); update_allotment( p ); } __TBB_ASSERT( my_global_top_priority >= a.my_top_priority || a.my_num_workers_requested<=0, NULL ); assert_market_valid(); #else /* !__TBB_TASK_PRIORITY */ my_total_demand += delta; update_allotment(); #endif /* !__TBB_TASK_PRIORITY */ my_arenas_list_mutex.unlock(); // Must be called outside of any locks my_server->adjust_job_count_estimate( delta ); GATHER_STATISTIC( governor::local_scheduler_if_initialized() ? ++governor::local_scheduler_if_initialized()->my_counters.gate_switches : 0 ); } void market::process( job& j ) { generic_scheduler& s = static_cast(j); arena *a = NULL; __TBB_ASSERT( governor::is_set(&s), NULL ); #if !__TBB_SLEEP_PERMISSION while ( (a = arena_in_need(a)) ) a->process(s); #else//__TBB_SLEEP_PERMISSION enum { query_interval = 1000, first_interval = 1, pause_time = 100 // similar to PauseTime used for the stealing loop }; for(int i = first_interval; ; i--) { while ( (a = arena_in_need(a)) ) { a->process(s); i = first_interval; } if( i == 0 ) { #if __TBB_TASK_PRIORITY arena_list_type &al = my_priority_levels[my_global_top_priority].arenas; #else /* __TBB_TASK_PRIORITY */ arena_list_type &al = my_arenas; #endif /* __TBB_TASK_PRIORITY */ if( al.empty() ) // races if any are innocent TODO: replace by an RML query interface break; // no arenas left, perhaps going to shut down if( the_global_observer_list.ask_permission_to_leave() ) break; // go sleep __TBB_Yield(); i = query_interval; } else __TBB_Pause(pause_time); } #endif//__TBB_SLEEP_PERMISSION GATHER_STATISTIC( ++s.my_counters.market_roundtrips ); } void market::cleanup( job& j ) { __TBB_ASSERT( theMarket != this, NULL ); generic_scheduler& s = static_cast(j); generic_scheduler* mine = governor::local_scheduler_if_initialized(); __TBB_ASSERT( !mine || mine->my_arena_index!=0, NULL ); if( mine!=&s ) { governor::assume_scheduler( &s ); generic_scheduler::cleanup_worker( &s, mine!=NULL ); governor::assume_scheduler( mine ); } else { generic_scheduler::cleanup_worker( &s, true ); } } void market::acknowledge_close_connection() { destroy(); } ::rml::job* market::create_one_job() { unsigned index = ++my_num_workers; __TBB_ASSERT( index > 0, NULL ); ITT_THREAD_SET_NAME(_T("TBB Worker Thread")); // index serves as a hint decreasing conflicts between workers when they migrate between arenas generic_scheduler* s = generic_scheduler::create_worker( *this, index ); #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT( index <= my_max_num_workers, NULL ); __TBB_ASSERT( !my_workers[index - 1], NULL ); my_workers[index - 1] = s; #endif /* __TBB_TASK_GROUP_CONTEXT */ governor::sign_on(s); return s; } #if __TBB_TASK_PRIORITY void market::update_arena_top_priority ( arena& a, intptr_t new_priority ) { GATHER_STATISTIC( ++governor::local_scheduler_if_initialized()->my_counters.arena_prio_switches ); __TBB_ASSERT( a.my_top_priority != new_priority, NULL ); priority_level_info &prev_level = my_priority_levels[a.my_top_priority], &new_level = my_priority_levels[new_priority]; remove_arena_from_list(a); a.my_top_priority = new_priority; insert_arena_into_list(a); ++a.my_reload_epoch; // TODO: synch with global reload epoch in order to optimize usage of local reload epoch #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION // Arena's my_num_workers_present may remain positive for some time after its // my_num_workers_requested becomes zero. Thus the following two lines are // executed unconditionally. prev_level.workers_present -= a.my_num_workers_present; new_level.workers_present += a.my_num_workers_present; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ prev_level.workers_requested -= a.my_num_workers_requested; new_level.workers_requested += a.my_num_workers_requested; __TBB_ASSERT( prev_level.workers_requested >= 0 && new_level.workers_requested >= 0, NULL ); } bool market::lower_arena_priority ( arena& a, intptr_t new_priority, uintptr_t old_reload_epoch ) { // TODO: replace the lock with a try_lock loop which performs a double check of the epoch arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); if ( a.my_reload_epoch != old_reload_epoch ) { assert_market_valid(); return false; } __TBB_ASSERT( a.my_top_priority > new_priority, NULL ); __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); intptr_t p = a.my_top_priority; update_arena_top_priority( a, new_priority ); if ( a.my_num_workers_requested > 0 ) { if ( my_global_bottom_priority > new_priority ) { my_global_bottom_priority = new_priority; } if ( p == my_global_top_priority && !my_priority_levels[p].workers_requested ) { // Global top level became empty for ( --p; !my_priority_levels[p].workers_requested; --p ) continue; __TBB_ASSERT( p >= my_global_bottom_priority, NULL ); update_global_top_priority(p); } update_allotment( p ); } __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); assert_market_valid(); return true; } bool market::update_arena_priority ( arena& a, intptr_t new_priority ) { arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); __TBB_ASSERT( my_global_top_priority >= a.my_top_priority || a.my_num_workers_requested <= 0, NULL ); assert_market_valid(); if ( a.my_top_priority == new_priority ) { return false; } else if ( a.my_top_priority > new_priority ) { if ( a.my_bottom_priority > new_priority ) a.my_bottom_priority = new_priority; return false; } else if ( a.my_num_workers_requested <= 0 ) { return false; } __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); intptr_t p = a.my_top_priority; intptr_t highest_affected_level = max(p, new_priority); update_arena_top_priority( a, new_priority ); if ( my_global_top_priority < new_priority ) { update_global_top_priority(new_priority); } else if ( my_global_top_priority == new_priority ) { advance_global_reload_epoch(); } else { __TBB_ASSERT( new_priority < my_global_top_priority, NULL ); __TBB_ASSERT( new_priority > my_global_bottom_priority, NULL ); if ( p == my_global_top_priority && !my_priority_levels[p].workers_requested ) { // Global top level became empty __TBB_ASSERT( my_global_bottom_priority < p, NULL ); for ( --p; !my_priority_levels[p].workers_requested; --p ) continue; __TBB_ASSERT( p >= new_priority, NULL ); update_global_top_priority(p); highest_affected_level = p; } } if ( p == my_global_bottom_priority ) { // Arena priority was increased from the global bottom level. __TBB_ASSERT( p < new_priority, NULL ); // n __TBB_ASSERT( new_priority <= my_global_top_priority, NULL ); while ( !my_priority_levels[my_global_bottom_priority].workers_requested ) ++my_global_bottom_priority; __TBB_ASSERT( my_global_bottom_priority <= new_priority, NULL ); __TBB_ASSERT( my_priority_levels[my_global_bottom_priority].workers_requested > 0, NULL ); } update_allotment( highest_affected_level ); __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); assert_market_valid(); return true; } #endif /* __TBB_TASK_PRIORITY */ #if __TBB_COUNT_TASK_NODES intptr_t market::workers_task_node_count() { intptr_t result = 0; ForEachArena(a) { result += a.workers_task_node_count(); } EndForEach(); return result; } #endif /* __TBB_COUNT_TASK_NODES */ } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/market.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_market_H #define _TBB_market_H #include "tbb/tbb_stddef.h" #include "scheduler_common.h" #include "tbb/atomic.h" #include "tbb/spin_rw_mutex.h" #include "../rml/include/rml_tbb.h" #include "intrusive_list.h" #if defined(_MSC_VER) && defined(_Wp64) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (push) #pragma warning (disable: 4244) #endif namespace tbb { class task_group_context; namespace internal { //------------------------------------------------------------------------ // Class market //------------------------------------------------------------------------ class market : no_copy, rml::tbb_client { friend class generic_scheduler; friend class arena; template friend class custom_scheduler; friend class tbb::task_group_context; private: friend void ITT_DoUnsafeOneTimeInitialization (); typedef intrusive_list arena_list_type; //! Currently active global market static market* theMarket; typedef scheduler_mutex_type global_market_mutex_type; //! Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation static global_market_mutex_type theMarketMutex; //! Reference count controlling market object lifetime intptr_t my_ref_count; //! Lightweight mutex guarding accounting operations with arenas list typedef spin_rw_mutex arenas_list_mutex_type; arenas_list_mutex_type my_arenas_list_mutex; //! Pointer to the RML server object that services this TBB instance. rml::tbb_server* my_server; //! Stack size of worker threads size_t my_stack_size; //! Number of workers requested from the underlying resource manager unsigned my_max_num_workers; //! Number of workers that have been delivered by RML /** Used to assign indices to the new workers coming from RML, and busy part of my_workers array. **/ atomic my_num_workers; #if __TBB_TASK_PRIORITY //! Highest priority among active arenas in the market. /** Arena priority level is its tasks highest priority (specified by arena's my_top_priority member). Arena is active when it has outstanding request for workers. Note that inactive arena may have workers lingering there for some time. **/ intptr_t my_global_top_priority; //! Lowest priority among active arenas in the market. /** See also my_global_top_priority **/ intptr_t my_global_bottom_priority; //! Tracks events that may bring tasks in offload areas to the top priority level. /** Incremented when global top priority is decremented or a task group priority is elevated to the current top level. **/ uintptr_t my_global_reload_epoch; //! Information about arenas at a particular priority level struct priority_level_info { //! List of arenas at this priority level arena_list_type arenas; //! The first arena to be checked when idle worker seeks for an arena to enter /** The check happens in round-robin fashion. **/ arena *next_arena; //! Total amount of workers requested by arenas at this priority level. int workers_requested; //! Maximal amount of workers the market can tell off to this priority level. int workers_available; #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION //! Total amount of workers that are in arenas at this priority level. int workers_present; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ }; // struct priority_level_info //! Information about arenas at different priority levels priority_level_info my_priority_levels[num_priority_levels]; #if __TBB_TRACK_PRIORITY_LEVEL_SATURATION //! Lowest priority level having workers available. intptr_t my_lowest_populated_level; #endif /* __TBB_TRACK_PRIORITY_LEVEL_SATURATION */ #else /* !__TBB_TASK_PRIORITY */ //! List of registered arenas arena_list_type my_arenas; //! The first arena to be checked when idle worker seeks for an arena to enter /** The check happens in round-robin fashion. **/ arena *my_next_arena; //! Number of workers that were requested by all arenas int my_total_demand; #endif /* !__TBB_TASK_PRIORITY */ //! ABA prevention marker to assign to newly created arenas uintptr_t my_arenas_aba_epoch; #if __TBB_COUNT_TASK_NODES //! Net number of nodes that have been allocated from heap. /** Updated each time a scheduler or arena is destroyed. */ atomic my_task_node_count; #endif /* __TBB_COUNT_TASK_NODES */ //! Constructor market ( unsigned max_num_workers, size_t stack_size ); //! Factory method creating new market object static market& global_market ( unsigned max_num_workers, size_t stack_size ); //! Destroys and deallocates market object created by market::create() void destroy (); void try_destroy_arena ( arena*, uintptr_t aba_epoch ); #if __TBB_TASK_PRIORITY //! Returns next arena that needs more workers, or NULL. arena* arena_in_need ( arena* prev_arena ); //! Recalculates the number of workers assigned to each arena at and below the specified priority. /** The actual number of workers servicing a particular arena may temporarily deviate from the calculated value. **/ void update_allotment ( intptr_t highest_affected_priority ); //! Changes arena's top priority and updates affected priority levels info in the market. void update_arena_top_priority ( arena& a, intptr_t newPriority ); //! Changes market's global top priority and related settings. inline void update_global_top_priority ( intptr_t newPriority ); //! Resets empty market's global top and bottom priority to the normal level. inline void reset_global_priority (); inline void advance_global_reload_epoch () { __TBB_store_with_release( my_global_reload_epoch, my_global_reload_epoch + 1 ); } void assert_market_valid () const { __TBB_ASSERT( (my_priority_levels[my_global_top_priority].workers_requested > 0 && !my_priority_levels[my_global_top_priority].arenas.empty()) || (my_global_top_priority == my_global_bottom_priority && my_global_top_priority == normalized_normal_priority), NULL ); } bool has_any_demand() const { for(int p = 0; p < num_priority_levels; p++) if( __TBB_load_with_acquire(my_priority_levels[p].workers_requested) > 0 ) // TODO: use as_atomic here and below return true; return false; } #else /* !__TBB_TASK_PRIORITY */ //! Recalculates the number of workers assigned to each arena in the list. /** The actual number of workers servicing a particular arena may temporarily deviate from the calculated value. **/ void update_allotment () { if ( my_total_demand ) update_allotment( my_arenas, my_total_demand, (int)my_max_num_workers ); } //! Returns next arena that needs more workers, or NULL. arena* arena_in_need (arena*) { if(__TBB_load_with_acquire(my_total_demand) <= 0) return NULL; arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex, /*is_writer=*/false); return arena_in_need(my_arenas, my_next_arena); } void assert_market_valid () const {} #endif /* !__TBB_TASK_PRIORITY */ //! Returns number of masters doing computational (CPU-intensive) work int num_active_masters () { return 1; } // APM TODO: replace with a real mechanism //////////////////////////////////////////////////////////////////////////////// // Helpers to unify code branches dependent on priority feature presence void insert_arena_into_list ( arena& a ); void remove_arena_from_list ( arena& a ); arena* arena_in_need ( arena_list_type &arenas, arena *&next ); static void update_allotment ( arena_list_type& arenas, int total_demand, int max_workers ); //////////////////////////////////////////////////////////////////////////////// // Implementation of rml::tbb_client interface methods /*override*/ version_type version () const { return 0; } /*override*/ unsigned max_job_count () const { return my_max_num_workers; } /*override*/ size_t min_stack_size () const { return worker_stack_size(); } /*override*/ policy_type policy () const { return throughput; } /*override*/ job* create_one_job (); /*override*/ void cleanup( job& j ); /*override*/ void acknowledge_close_connection (); /*override*/ void process( job& j ); public: //! Creates an arena object /** If necessary, also creates global market instance, and boosts its ref count. Each call to create_arena() must be matched by the call to arena::free_arena(). **/ static arena& create_arena ( unsigned max_num_workers, size_t stack_size ); //! Removes the arena from the market's list static void try_destroy_arena ( market*, arena*, uintptr_t aba_epoch, bool master ); //! Removes the arena from the market's list void detach_arena ( arena& ); //! Decrements market's refcount and destroys it in the end void release (); //! Request that arena's need in workers should be adjusted. /** Concurrent invocations are possible only on behalf of different arenas. **/ void adjust_demand ( arena&, int delta ); //! Guarantee that request_close_connection() is called by master, not some worker /** Must be called before arena::on_thread_leaving() **/ void prepare_wait_workers() { ++my_ref_count; } //! Wait workers termination void wait_workers (); //! Returns the requested stack size of worker threads. size_t worker_stack_size () const { return my_stack_size; } #if _WIN32||_WIN64 //! register master with the resource manager void register_master( ::rml::server::execution_resource_t& rsc_handle ) { __TBB_ASSERT( my_server, "RML server not defined?" ); // the server may ignore registration and set master_exec_resource to NULL. my_server->register_master( rsc_handle ); } //! unregister master with the resource manager void unregister_master( ::rml::server::execution_resource_t& rsc_handle ) const { my_server->unregister_master( rsc_handle ); } #endif /* WIN */ #if __TBB_TASK_GROUP_CONTEXT //! Finds all contexts affected by the state change and propagates the new state to them. template bool propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_TASK_PRIORITY //! Lowers arena's priority is not higher than newPriority /** Returns true if arena priority was actually elevated. **/ bool lower_arena_priority ( arena& a, intptr_t new_priority, uintptr_t old_reload_epoch ); //! Makes sure arena's priority is not lower than newPriority /** Returns true if arena priority was elevated. Also updates arena's bottom priority boundary if necessary. This method is called whenever a user changes priority, because whether it was hiked or sunk can be determined for sure only under the lock used by this function. **/ bool update_arena_priority ( arena& a, intptr_t new_priority ); #endif /* __TBB_TASK_PRIORITY */ #if __TBB_COUNT_TASK_NODES //! Returns the number of task objects "living" in worker threads intptr_t workers_task_node_count(); //! Net number of nodes that have been allocated from heap. /** Updated each time a scheduler or arena is destroyed. */ void update_task_node_count( intptr_t delta ) { my_task_node_count += delta; } #endif /* __TBB_COUNT_TASK_NODES */ #if __TBB_TASK_GROUP_CONTEXT //! Array of pointers to the registered workers /** Used by cancellation propagation mechanism. Must be the last data member of the class market. **/ generic_scheduler* my_workers[1]; #endif /* __TBB_TASK_GROUP_CONTEXT */ }; // class market #if __TBB_TASK_PRIORITY #define BeginForEachArena(a) \ arenas_list_mutex_type::scoped_lock arena_list_lock(my_arenas_list_mutex); \ for ( intptr_t i = my_global_top_priority; i >= my_global_bottom_priority; --i ) { \ /*arenas_list_mutex_type::scoped_lock arena_list_lock(my_priority_levels[i].my_arenas_list_mutex);*/ \ arena_list_type &arenas = my_priority_levels[i].arenas; #else /* !__TBB_TASK_PRIORITY */ #define BeginForEachArena(a) \ arena_list_type &arenas = my_arenas; { #endif /* !__TBB_TASK_PRIORITY */ #define ForEachArena(a) \ BeginForEachArena(a) \ arena_list_type::iterator it = arenas.begin(); \ for ( ; it != arenas.end(); ++it ) { \ arena &a = *it; #define EndForEach() }} } // namespace internal } // namespace tbb #if defined(_MSC_VER) && defined(_Wp64) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (pop) #endif // warning 4244 is back #endif /* _TBB_market_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/memory_pool.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_memory_pool_H #define __TBB_memory_pool_H #if !TBB_PREVIEW_MEMORY_POOL #error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h #endif /** @file */ #include "scalable_allocator.h" #include // std::bad_alloc #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #include // std::forward #endif #if __TBB_EXTRA_DEBUG #define __TBBMALLOC_ASSERT ASSERT #else #define __TBBMALLOC_ASSERT(a,b) ((void)0) #endif namespace tbb { namespace interface6 { //! @cond INTERNAL namespace internal { //! Base of thread-safe pool allocator for variable-size requests class pool_base : tbb::internal::no_copy { // Pool interface is separate from standard allocator classes because it has // to maintain internal state, no copy or assignment. Move and swap are possible. public: //! Reset pool to reuse its memory (free all objects at once) void recycle() { rml::pool_reset(my_pool); } //! The "malloc" analogue to allocate block of memory of size bytes void *malloc(size_t size) { return rml::pool_malloc(my_pool, size); } //! The "free" analogue to discard a previously allocated piece of memory. void free(void* ptr) { rml::pool_free(my_pool, ptr); } //! The "realloc" analogue complementing pool_malloc. // Enables some low-level optimization possibilities void *realloc(void* ptr, size_t size) { return rml::pool_realloc(my_pool, ptr, size); } protected: //! destroy pool - must be called in a child class void destroy() { rml::pool_destroy(my_pool); } rml::MemoryPool *my_pool; }; } // namespace internal //! @endcond #if _MSC_VER && !defined(__INTEL_COMPILER) // Workaround for erroneous "unreferenced parameter" warning in method destroy. #pragma warning (push) #pragma warning (disable: 4100) #endif //! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 /** @ingroup memory_allocation */ template class memory_pool_allocator { protected: typedef P pool_type; pool_type *my_pool; template friend class memory_pool_allocator; template friend bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b); template friend bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b); public: typedef typename tbb::internal::allocator_type::value_type value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef memory_pool_allocator other; }; memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {} memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} template memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } //! Allocate space for n objects. pointer allocate( size_type n, const void* /*hint*/ = 0) { return static_cast( my_pool->malloc( n*sizeof(value_type) ) ); } //! Free previously allocated block of memory. void deallocate( pointer p, size_type ) { my_pool->free(p); } //! Largest value for which method allocate might succeed. size_type max_size() const throw() { size_type max = static_cast(-1) / sizeof (value_type); return (max > 0 ? max : 1); } //! Copy-construct value at location pointed to by p. #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC template void construct(U *p, Args&&... args) { ::new((void *)p) U(std::forward(args)...); } #else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #if __TBB_CPP11_RVALUE_REF_PRESENT void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));} #endif void construct( pointer p, const value_type& value ) { ::new((void*)(p)) value_type(value); } #endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC //! Destroy value at location pointed to by p. void destroy( pointer p ) { p->~value_type(); } }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4100 is back //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ template class memory_pool_allocator { public: typedef P pool_type; typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef memory_pool_allocator other; }; memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {} memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} template memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} protected: pool_type *my_pool; template friend class memory_pool_allocator; template friend bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b); template friend bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b); }; template inline bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b) {return a.my_pool==b.my_pool;} template inline bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b) {return a.my_pool!=b.my_pool;} //! Thread-safe growable pool allocator for variable-size requests template class memory_pool : public internal::pool_base { Alloc my_alloc; // TODO: base-class optimization static void *allocate_request(intptr_t pool_id, size_t & bytes); static int deallocate_request(intptr_t pool_id, void*, size_t raw_bytes); public: //! construct pool with underlying allocator memory_pool(const Alloc &src = Alloc()); //! destroy pool ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter }; class fixed_pool : public internal::pool_base { void *my_buffer; size_t my_size; inline static void *allocate_request(intptr_t pool_id, size_t & bytes); public: //! construct pool with underlying allocator inline fixed_pool(void *buf, size_t size); //! destroy pool ~fixed_pool() { destroy(); } }; //////////////// Implementation /////////////// template memory_pool::memory_pool(const Alloc &src) : my_alloc(src) { rml::MemPoolPolicy args(allocate_request, deallocate_request, sizeof(typename Alloc::value_type)); rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool); if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc()); } template void *memory_pool::allocate_request(intptr_t pool_id, size_t & bytes) { memory_pool &self = *reinterpret_cast*>(pool_id); const size_t unit_size = sizeof(typename Alloc::value_type); __TBBMALLOC_ASSERT( 0 == bytes%unit_size, NULL); void *ptr; __TBB_TRY { ptr = self.my_alloc.allocate( bytes/unit_size ); } __TBB_CATCH(...) { return 0; } return ptr; } #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED // Workaround for erroneous "unreachable code" warning in the template below. // Specific for VC++ 17-18 compiler #pragma warning (push) #pragma warning (disable: 4702) #endif template int memory_pool::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) { memory_pool &self = *reinterpret_cast*>(pool_id); const size_t unit_size = sizeof(typename Alloc::value_type); __TBBMALLOC_ASSERT( 0 == raw_bytes%unit_size, NULL); self.my_alloc.deallocate( static_cast(raw_ptr), raw_bytes/unit_size ); return 0; } #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED #pragma warning (pop) #endif inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) { if( !buf || !size ) __TBB_THROW(std::bad_alloc()); rml::MemPoolPolicy args(allocate_request, 0, size, /*fixedPool=*/true); rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool); if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc()); } inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) { fixed_pool &self = *reinterpret_cast(pool_id); __TBBMALLOC_ASSERT(0 != self.my_size, "The buffer must not be used twice."); bytes = self.my_size; self.my_size = 0; // remember that buffer has been used return self.my_buffer; } } //namespace interface6 using interface6::memory_pool_allocator; using interface6::memory_pool; using interface6::fixed_pool; } //namespace tbb #undef __TBBMALLOC_ASSERT #endif// __TBB_memory_pool_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/mutex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if _WIN32||_WIN64 #include // EDEADLK #endif #include "tbb/mutex.h" #include "itt_notify.h" namespace tbb { void mutex::scoped_lock::internal_acquire( mutex& m ) { #if _WIN32||_WIN64 switch( m.state ) { case INITIALIZED: case HELD: EnterCriticalSection( &m.impl ); // If a thread comes here, and another thread holds the lock, it will block // in EnterCriticalSection. When it returns from EnterCriticalSection, // m.state must be set to INITIALIZED. If the same thread tries to acquire a lock it // aleady holds, the lock is in HELD state, thus will cause throwing the exception. if (m.state==HELD) tbb::internal::handle_perror(EDEADLK,"mutex::scoped_lock: deadlock caused by attempt to reacquire held mutex"); m.state = HELD; break; case DESTROYED: __TBB_ASSERT(false,"mutex::scoped_lock: mutex already destroyed"); break; default: __TBB_ASSERT(false,"mutex::scoped_lock: illegal mutex state"); break; } #else int error_code = pthread_mutex_lock(&m.impl); if( error_code ) tbb::internal::handle_perror(error_code,"mutex::scoped_lock: pthread_mutex_lock failed"); #endif /* _WIN32||_WIN64 */ my_mutex = &m; } void mutex::scoped_lock::internal_release() { __TBB_ASSERT( my_mutex, "mutex::scoped_lock: not holding a mutex" ); #if _WIN32||_WIN64 switch( my_mutex->state ) { case INITIALIZED: __TBB_ASSERT(false,"mutex::scoped_lock: try to release the lock without acquisition"); break; case HELD: my_mutex->state = INITIALIZED; LeaveCriticalSection(&my_mutex->impl); break; case DESTROYED: __TBB_ASSERT(false,"mutex::scoped_lock: mutex already destroyed"); break; default: __TBB_ASSERT(false,"mutex::scoped_lock: illegal mutex state"); break; } #else int error_code = pthread_mutex_unlock(&my_mutex->impl); __TBB_ASSERT_EX(!error_code, "mutex::scoped_lock: pthread_mutex_unlock failed"); #endif /* _WIN32||_WIN64 */ my_mutex = NULL; } bool mutex::scoped_lock::internal_try_acquire( mutex& m ) { #if _WIN32||_WIN64 switch( m.state ) { case INITIALIZED: case HELD: break; case DESTROYED: __TBB_ASSERT(false,"mutex::scoped_lock: mutex already destroyed"); break; default: __TBB_ASSERT(false,"mutex::scoped_lock: illegal mutex state"); break; } #endif /* _WIN32||_WIN64 */ bool result; #if _WIN32||_WIN64 result = TryEnterCriticalSection(&m.impl)!=0; if( result ) { __TBB_ASSERT(m.state!=HELD, "mutex::scoped_lock: deadlock caused by attempt to reacquire held mutex"); m.state = HELD; } #else result = pthread_mutex_trylock(&m.impl)==0; #endif /* _WIN32||_WIN64 */ if( result ) my_mutex = &m; return result; } void mutex::internal_construct() { #if _WIN32||_WIN64 InitializeCriticalSectionEx(&impl, 4000, 0); state = INITIALIZED; #else int error_code = pthread_mutex_init(&impl,NULL); if( error_code ) tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed"); #endif /* _WIN32||_WIN64*/ ITT_SYNC_CREATE(&impl, _T("tbb::mutex"), _T("")); } void mutex::internal_destroy() { #if _WIN32||_WIN64 switch( state ) { case INITIALIZED: DeleteCriticalSection(&impl); break; case DESTROYED: __TBB_ASSERT(false,"mutex: already destroyed"); break; default: __TBB_ASSERT(false,"mutex: illegal state for destruction"); break; } state = DESTROYED; #else int error_code = pthread_mutex_destroy(&impl); __TBB_ASSERT_EX(!error_code,"mutex: pthread_mutex_destroy failed"); #endif /* _WIN32||_WIN64 */ } } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_mutex_H #define __TBB_mutex_H #if _WIN32||_WIN64 #include "machine/windows_api.h" #else #include #endif /* _WIN32||_WIN64 */ #include #include "aligned_space.h" #include "tbb_stddef.h" #include "tbb_profiling.h" namespace tbb { //! Wrapper around the platform's native reader-writer lock. /** For testing purposes only. @ingroup synchronization */ class mutex : internal::mutex_copy_deprecated_and_disabled { public: //! Construct unacquired mutex. mutex() { #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS internal_construct(); #else #if _WIN32||_WIN64 InitializeCriticalSectionEx(&impl, 4000, 0); #else int error_code = pthread_mutex_init(&impl,NULL); if( error_code ) tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed"); #endif /* _WIN32||_WIN64*/ #endif /* TBB_USE_ASSERT */ }; ~mutex() { #if TBB_USE_ASSERT internal_destroy(); #else #if _WIN32||_WIN64 DeleteCriticalSection(&impl); #else pthread_mutex_destroy(&impl); #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ }; class scoped_lock; friend class scoped_lock; //! The scoped locking pattern /** It helps to avoid the common problem of forgetting to release lock. It also nicely provides the "node" for queuing locks. */ class scoped_lock : internal::no_copy { public: //! Construct lock that has not acquired a mutex. scoped_lock() : my_mutex(NULL) {}; //! Acquire lock on given mutex. scoped_lock( mutex& mutex ) { acquire( mutex ); } //! Release lock (if lock is held). ~scoped_lock() { if( my_mutex ) release(); } //! Acquire lock on given mutex. void acquire( mutex& mutex ) { #if TBB_USE_ASSERT internal_acquire(mutex); #else mutex.lock(); my_mutex = &mutex; #endif /* TBB_USE_ASSERT */ } //! Try acquire lock on given mutex. bool try_acquire( mutex& mutex ) { #if TBB_USE_ASSERT return internal_try_acquire (mutex); #else bool result = mutex.try_lock(); if( result ) my_mutex = &mutex; return result; #endif /* TBB_USE_ASSERT */ } //! Release lock void release() { #if TBB_USE_ASSERT internal_release (); #else my_mutex->unlock(); my_mutex = NULL; #endif /* TBB_USE_ASSERT */ } private: //! The pointer to the current mutex to work mutex* my_mutex; //! All checks from acquire using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_acquire( mutex& m ); //! All checks from try_acquire using mutex.state were moved here bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m ); //! All checks from release using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_release(); friend class mutex; }; // Mutex traits static const bool is_rw_mutex = false; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = false; // ISO C++0x compatibility methods //! Acquire lock void lock() { #if TBB_USE_ASSERT aligned_space tmp; new(tmp.begin()) scoped_lock(*this); #else #if _WIN32||_WIN64 EnterCriticalSection(&impl); #else int error_code = pthread_mutex_lock(&impl); if( error_code ) tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_lock failed"); #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_lock() { #if TBB_USE_ASSERT aligned_space tmp; scoped_lock& s = *tmp.begin(); s.my_mutex = NULL; return s.internal_try_acquire(*this); #else #if _WIN32||_WIN64 return TryEnterCriticalSection(&impl)!=0; #else return pthread_mutex_trylock(&impl)==0; #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ } //! Release lock void unlock() { #if TBB_USE_ASSERT aligned_space tmp; scoped_lock& s = *tmp.begin(); s.my_mutex = this; s.internal_release(); #else #if _WIN32||_WIN64 LeaveCriticalSection(&impl); #else pthread_mutex_unlock(&impl); #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ } //! Return native_handle #if _WIN32||_WIN64 typedef LPCRITICAL_SECTION native_handle_type; #else typedef pthread_mutex_t* native_handle_type; #endif native_handle_type native_handle() { return (native_handle_type) &impl; } enum state_t { INITIALIZED=0x1234, DESTROYED=0x789A, HELD=0x56CD }; private: #if _WIN32||_WIN64 CRITICAL_SECTION impl; enum state_t state; #else pthread_mutex_t impl; #endif /* _WIN32||_WIN64 */ //! All checks from mutex constructor using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_construct(); //! All checks from mutex destructor using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_destroy(); #if _WIN32||_WIN64 public: //! Set the internal state void set_state( state_t to ) { state = to; } #endif }; __TBB_DEFINE_PROFILING_SET_NAME(mutex) } // namespace tbb #endif /* __TBB_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/null_mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_null_mutex_H #define __TBB_null_mutex_H #include "tbb_stddef.h" namespace tbb { //! A mutex which does nothing /** A null_mutex does no operation and simulates success. @ingroup synchronization */ class null_mutex : internal::mutex_copy_deprecated_and_disabled { public: //! Represents acquisition of a mutex. class scoped_lock : internal::no_copy { public: scoped_lock() {} scoped_lock( null_mutex& ) {} ~scoped_lock() {} void acquire( null_mutex& ) {} bool try_acquire( null_mutex& ) { return true; } void release() {} }; null_mutex() {} // Mutex traits static const bool is_rw_mutex = false; static const bool is_recursive_mutex = true; static const bool is_fair_mutex = true; }; } #endif /* __TBB_null_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/null_rw_mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_null_rw_mutex_H #define __TBB_null_rw_mutex_H #include "tbb_stddef.h" namespace tbb { //! A rw mutex which does nothing /** A null_rw_mutex is a rw mutex that does nothing and simulates successful operation. @ingroup synchronization */ class null_rw_mutex : internal::mutex_copy_deprecated_and_disabled { public: //! Represents acquisition of a mutex. class scoped_lock : internal::no_copy { public: scoped_lock() {} scoped_lock( null_rw_mutex& , bool = true ) {} ~scoped_lock() {} void acquire( null_rw_mutex& , bool = true ) {} bool upgrade_to_writer() { return true; } bool downgrade_to_reader() { return true; } bool try_acquire( null_rw_mutex& , bool = true ) { return true; } void release() {} }; null_rw_mutex() {} // Mutex traits static const bool is_rw_mutex = true; static const bool is_recursive_mutex = true; static const bool is_fair_mutex = true; }; } #endif /* __TBB_null_rw_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/observer_proxy.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" #if !__TBB_ARENA_OBSERVER #error __TBB_ARENA_OBSERVER must be defined #endif #if __TBB_SCHEDULER_OBSERVER #include "observer_proxy.h" #include "tbb_main.h" #include "governor.h" #include "scheduler.h" #include "arena.h" namespace tbb { namespace internal { padded the_global_observer_list; #if TBB_USE_ASSERT static atomic observer_proxy_count; struct check_observer_proxy_count { ~check_observer_proxy_count() { if( observer_proxy_count!=0 ) { runtime_warning( "Leaked %ld observer_proxy objects\n", long(observer_proxy_count) ); } } }; static check_observer_proxy_count the_check_observer_proxy_count; #endif /* TBB_USE_ASSERT */ interface6::task_scheduler_observer* observer_proxy::get_v6_observer() { if(my_version != 6) return NULL; return static_cast(my_observer); } bool observer_proxy::is_global() { return !get_v6_observer() || get_v6_observer()->my_context_tag == interface6::task_scheduler_observer::global_tag; } observer_proxy::observer_proxy( task_scheduler_observer_v3& tso ) : my_list(NULL), my_next(NULL), my_prev(NULL), my_observer(&tso) { #if TBB_USE_ASSERT ++observer_proxy_count; #endif /* TBB_USE_ASSERT */ // 1 for observer my_ref_count = 1; my_version = load(my_observer->my_busy_count) == interface6::task_scheduler_observer::v6_trait ? 6 : 0; __TBB_ASSERT( my_version >= 6 || !load(my_observer->my_busy_count), NULL ); } #if TBB_USE_ASSERT observer_proxy::~observer_proxy () { __TBB_ASSERT( !my_ref_count, "Attempt to destroy proxy still in use" ); poison_value(my_ref_count); poison_pointer(my_prev); poison_pointer(my_next); --observer_proxy_count; } #endif /* TBB_USE_ASSERT */ template T atomic_fetch_and_store ( T* addr, const V& val ) { return (T)atomic_traits::fetch_and_store( addr, (T)val ); } void observer_list::clear () { __TBB_ASSERT( this != &the_global_observer_list, "Method clear() cannot be used on the list of global observers" ); // Though the method will work fine for the empty list, we require the caller // to check for the list emptiness before invoking it to avoid extra overhead. __TBB_ASSERT( !empty(), NULL ); { scoped_lock lock(mutex(), /*is_writer=*/true); observer_proxy *next = my_head; while ( observer_proxy *p = next ) { __TBB_ASSERT( p->my_version >= 6, NULL ); next = p->my_next; // Both proxy p and observer p->my_observer (if non-null) are guaranteed // to be alive while the list is locked. task_scheduler_observer_v3 *obs = p->my_observer; // Make sure that possible concurrent observer destruction does not // conflict with the proxy list cleanup. if ( !obs || !(p = (observer_proxy*)__TBB_FetchAndStoreW(&obs->my_proxy, 0)) ) continue; // accessing 'obs' after detaching of obs->my_proxy leads to the race with observer destruction __TBB_ASSERT( !next || p == next->my_prev, NULL ); __TBB_ASSERT( is_alive(p->my_ref_count), "Observer's proxy died prematurely" ); __TBB_ASSERT( p->my_ref_count == 1, "Reference for observer is missing" ); #if TBB_USE_ASSERT p->my_observer = NULL; p->my_ref_count = 0; #endif /* TBB_USE_ASSERT */ remove(p); delete p; } } while( my_head ) __TBB_Yield(); } void observer_list::insert ( observer_proxy* p ) { scoped_lock lock(mutex(), /*is_writer=*/true); if ( my_head ) { p->my_prev = my_tail; my_tail->my_next = p; } else my_head = p; my_tail = p; } void observer_list::remove ( observer_proxy* p ) { __TBB_ASSERT( my_head, "Attempt to remove an item from an empty list" ); __TBB_ASSERT( !my_tail->my_next, "Last item's my_next must be NULL" ); if( p == my_tail ) { __TBB_ASSERT( !p->my_next, NULL ); my_tail = p->my_prev; } else { __TBB_ASSERT( p->my_next, NULL ); p->my_next->my_prev = p->my_prev; } if ( p == my_head ) { __TBB_ASSERT( !p->my_prev, NULL ); my_head = p->my_next; } else { __TBB_ASSERT( p->my_prev, NULL ); p->my_prev->my_next = p->my_next; } __TBB_ASSERT( (my_head && my_tail) || (!my_head && !my_tail), NULL ); } void observer_list::remove_ref( observer_proxy* p ) { int r = p->my_ref_count; __TBB_ASSERT( is_alive(r), NULL ); while(r>1) { __TBB_ASSERT( r!=0, NULL ); int r_old = p->my_ref_count.compare_and_swap(r-1,r); if( r_old==r ) { // Successfully decremented count. return; } r = r_old; } __TBB_ASSERT( r==1, NULL ); // Reference count might go to zero { // Use lock to avoid resurrection by a thread concurrently walking the list observer_list::scoped_lock lock(mutex(), /*is_writer=*/true); r = --p->my_ref_count; if( !r ) remove(p); } __TBB_ASSERT( r || !p->my_ref_count, NULL ); if( !r ) delete p; } void observer_list::do_notify_entry_observers( observer_proxy*& last, bool worker ) { // Pointer p marches though the list from last (exclusively) to the end. observer_proxy *p = last, *prev = p; for(;;) { task_scheduler_observer_v3* tso=NULL; // Hold lock on list only long enough to advance to the next proxy in the list. { scoped_lock lock(mutex(), /*is_writer=*/false); do { if( p ) { // We were already processing the list. if( observer_proxy* q = p->my_next ) { if( p == prev ) remove_ref_fast(prev); // sets prev to NULL if successful p = q; } else { // Reached the end of the list. if( p == prev ) { // Keep the reference as we store the 'last' pointer in scheduler __TBB_ASSERT(p->my_ref_count >= 1 + (p->my_observer?1:0), NULL); } else { // The last few proxies were empty __TBB_ASSERT(p->my_ref_count, NULL); ++p->my_ref_count; if( prev ) { lock.release(); remove_ref(prev); } } last = p; return; } } else { // Starting pass through the list p = my_head; if( !p ) return; } tso = p->my_observer; } while( !tso ); ++p->my_ref_count; ++tso->my_busy_count; } __TBB_ASSERT( !prev || p!=prev, NULL ); // Release the proxy pinned before p if( prev ) remove_ref(prev); // Do not hold any locks on the list while calling user's code. // Do not intercept any exceptions that may escape the callback so that // they are either handled by the TBB scheduler or passed to the debugger. tso->on_scheduler_entry(worker); __TBB_ASSERT(p->my_ref_count, NULL); intptr_t bc = --tso->my_busy_count; __TBB_ASSERT_EX( bc>=0, "my_busy_count underflowed" ); prev = p; } } void observer_list::do_notify_exit_observers( observer_proxy* last, bool worker ) { // Pointer p marches though the list from the beginning to last (inclusively). observer_proxy *p = NULL, *prev = NULL; for(;;) { task_scheduler_observer_v3* tso=NULL; // Hold lock on list only long enough to advance to the next proxy in the list. { scoped_lock lock(mutex(), /*is_writer=*/false); do { if( p ) { // We were already processing the list. if( p != last ) { __TBB_ASSERT( p->my_next, "List items before 'last' must have valid my_next pointer" ); if( p == prev ) remove_ref_fast(prev); // sets prev to NULL if successful p = p->my_next; } else { // remove the reference from the last item remove_ref_fast(p); if( p ) { lock.release(); remove_ref(p); } return; } } else { // Starting pass through the list p = my_head; __TBB_ASSERT( p, "Nonzero 'last' must guarantee that the global list is non-empty" ); } tso = p->my_observer; } while( !tso ); // The item is already refcounted if ( p != last ) // the last is already referenced since entry notification ++p->my_ref_count; ++tso->my_busy_count; } __TBB_ASSERT( !prev || p!=prev, NULL ); if( prev ) remove_ref(prev); // Do not hold any locks on the list while calling user's code. // Do not intercept any exceptions that may escape the callback so that // they are either handled by the TBB scheduler or passed to the debugger. tso->on_scheduler_exit(worker); __TBB_ASSERT(p->my_ref_count || p == last, NULL); intptr_t bc = --tso->my_busy_count; __TBB_ASSERT_EX( bc>=0, "my_busy_count underflowed" ); prev = p; } } #if __TBB_SLEEP_PERMISSION bool observer_list::ask_permission_to_leave() { __TBB_ASSERT( this == &the_global_observer_list, "This method cannot be used on lists of arena observers" ); if( !my_head ) return true; // Pointer p marches though the list observer_proxy *p = NULL, *prev = NULL; bool result = true; while( result ) { task_scheduler_observer* tso = NULL; // Hold lock on list only long enough to advance to the next proxy in the list. { scoped_lock lock(mutex(), /*is_writer=*/false); do { if( p ) { // We were already processing the list. observer_proxy* q = p->my_next; // read next, remove the previous reference if( p == prev ) remove_ref_fast(prev); // sets prev to NULL if successful if( q ) p = q; else { // Reached the end of the list. if( prev ) { lock.release(); remove_ref(prev); } return result; } } else { // Starting pass through the list p = my_head; if( !p ) return result; } tso = p->get_v6_observer(); } while( !tso ); ++p->my_ref_count; ++tso->my_busy_count; } __TBB_ASSERT( !prev || p!=prev, NULL ); // Release the proxy pinned before p if( prev ) remove_ref(prev); // Do not hold any locks on the list while calling user's code. // Do not intercept any exceptions that may escape the callback so that // they are either handled by the TBB scheduler or passed to the debugger. result = tso->may_sleep(); __TBB_ASSERT(p->my_ref_count, NULL); intptr_t bc = --tso->my_busy_count; __TBB_ASSERT_EX( bc>=0, "my_busy_count underflowed" ); prev = p; } if( prev ) remove_ref(prev); return result; } #endif//__TBB_SLEEP_PERMISSION void task_scheduler_observer_v3::observe( bool enable ) { if( enable ) { if( !my_proxy ) { my_proxy = new observer_proxy( *this ); my_busy_count = 0; // proxy stores versioning information, clear it if ( !my_proxy->is_global() ) { // Local observer activation generic_scheduler* s = governor::local_scheduler_if_initialized(); #if __TBB_TASK_ARENA __TBB_ASSERT( my_proxy->get_v6_observer(), NULL ); intptr_t tag = my_proxy->get_v6_observer()->my_context_tag; if( tag != interface6::task_scheduler_observer::implicit_tag ) { // explicit arena task_arena *a = reinterpret_cast(tag); a->initialize(); my_proxy->my_list = &a->my_arena->my_observers; } else #endif { if( !s ) s = governor::init_scheduler( (unsigned)task_scheduler_init::automatic, 0, true ); __TBB_ASSERT( __TBB_InitOnce::initialization_done(), NULL ); __TBB_ASSERT( s && s->my_arena, NULL ); my_proxy->my_list = &s->my_arena->my_observers; } my_proxy->my_list->insert(my_proxy); // Notify newly activated observer and other pending ones if it belongs to current arena if(s && &s->my_arena->my_observers == my_proxy->my_list ) my_proxy->my_list->notify_entry_observers( s->my_last_local_observer, s->is_worker() ); } else { // Obsolete. Global observer activation if( !__TBB_InitOnce::initialization_done() ) DoOneTimeInitializations(); my_proxy->my_list = &the_global_observer_list; my_proxy->my_list->insert(my_proxy); if( generic_scheduler* s = governor::local_scheduler_if_initialized() ) { // Notify newly created observer of its own thread. // Any other pending observers are notified too. the_global_observer_list.notify_entry_observers( s->my_last_global_observer, s->is_worker() ); } } } } else { // Make sure that possible concurrent proxy list cleanup does not conflict // with the observer destruction here. if ( observer_proxy* proxy = (observer_proxy*)__TBB_FetchAndStoreW(&my_proxy, 0) ) { // List destruction should not touch this proxy after we've won the above interlocked exchange. __TBB_ASSERT( proxy->my_observer == this, NULL ); __TBB_ASSERT( is_alive(proxy->my_ref_count), "Observer's proxy died prematurely" ); __TBB_ASSERT( proxy->my_ref_count >= 1, "reference for observer missing" ); observer_list &list = *proxy->my_list; { // Ensure that none of the list walkers relies on observer pointer validity observer_list::scoped_lock lock(list.mutex(), /*is_writer=*/true); proxy->my_observer = NULL; // Proxy may still be held by other threads (to track the last notified observer) if( !--proxy->my_ref_count ) {// nobody can increase it under exclusive lock list.remove(proxy); __TBB_ASSERT( !proxy->my_ref_count, NULL ); delete proxy; } } while( my_busy_count ) // other threads are still accessing the callback __TBB_Yield(); } } } } // namespace internal } // namespace tbb #endif /* __TBB_SCHEDULER_OBSERVER */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/observer_proxy.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_observer_proxy_H #define _TBB_observer_proxy_H #if __TBB_SCHEDULER_OBSERVER #include "scheduler_common.h" // to include task.h #include "tbb/task_scheduler_observer.h" #include "tbb/spin_rw_mutex.h" #include "tbb/aligned_space.h" namespace tbb { namespace internal { class observer_list { friend class arena; // Mutex is wrapped with aligned_space to shut up warnings when its destructor // is called while threads are still using it. typedef aligned_space my_mutex_type; //! Pointer to the head of this list. observer_proxy* my_head; //! Pointer to the tail of this list. observer_proxy* my_tail; //! Mutex protecting this list. my_mutex_type my_mutex; //! Back-pointer to the arena this list belongs to. arena* my_arena; //! Decrement refcount of the proxy p if there are other outstanding references. /** In case of success sets p to NULL. Must be invoked from under the list lock. **/ inline static void remove_ref_fast( observer_proxy*& p ); //! Implements notify_entry_observers functionality. void do_notify_entry_observers( observer_proxy*& last, bool worker ); //! Implements notify_exit_observers functionality. void do_notify_exit_observers( observer_proxy* last, bool worker ); public: observer_list () : my_head(NULL), my_tail(NULL) {} //! Removes and destroys all observer proxies from the list. /** Cannot be used concurrently with other methods. **/ void clear (); //! Add observer proxy to the tail of the list. void insert ( observer_proxy* p ); //! Remove observer proxy from the list. void remove ( observer_proxy* p ); //! Decrement refcount of the proxy and destroy it if necessary. /** When refcount reaches zero removes the proxy from the list and destructs it. **/ void remove_ref( observer_proxy* p ); //! Type of the scoped lock for the reader-writer mutex associated with the list. typedef spin_rw_mutex::scoped_lock scoped_lock; //! Accessor to the reader-writer mutex associated with the list. spin_rw_mutex& mutex () { return my_mutex.begin()[0]; } bool empty () const { return my_head == NULL; } //! Call entry notifications on observers added after last was notified. /** Updates last to become the last notified observer proxy (in the global list) or leaves it to be NULL. The proxy has its refcount incremented. **/ inline void notify_entry_observers( observer_proxy*& last, bool worker ); //! Call exit notifications on last and observers added before it. inline void notify_exit_observers( observer_proxy*& last, bool worker ); //! Call may_sleep callbacks to ask for permission for a worker thread to leave market bool ask_permission_to_leave(); }; // class observer_list //! Wrapper for an observer object /** To maintain shared lists of observers the scheduler first wraps each observer object into a proxy so that a list item remained valid even after the corresponding proxy object is destroyed by the user code. **/ class observer_proxy { friend class task_scheduler_observer_v3; friend class observer_list; //! Reference count used for garbage collection. /** 1 for reference from my task_scheduler_observer. 1 for each task dispatcher's last observer pointer. No accounting for neighbors in the shared list. */ atomic my_ref_count; //! Reference to the list this observer belongs to. observer_list* my_list; //! Pointer to next observer in the list specified by my_head. /** NULL for the last item in the list. **/ observer_proxy* my_next; //! Pointer to the previous observer in the list specified by my_head. /** For the head of the list points to the last item. **/ observer_proxy* my_prev; //! Associated observer task_scheduler_observer_v3* my_observer; //! Version char my_version; interface6::task_scheduler_observer* get_v6_observer(); bool is_global(); //TODO: move them back inline when un-CPF'ing //! Constructs proxy for the given observer and adds it to the specified list. observer_proxy( task_scheduler_observer_v3& ); #if TBB_USE_ASSERT ~observer_proxy(); #endif /* TBB_USE_ASSERT */ //! Shut up the warning observer_proxy& operator = ( const observer_proxy& ); }; // class observer_proxy inline void observer_list::remove_ref_fast( observer_proxy*& p ) { if( p->my_observer ) { // Can decrement refcount quickly, as it cannot drop to zero while under the lock. int r = --p->my_ref_count; __TBB_ASSERT_EX( r, NULL ); p = NULL; } else { // Use slow form of refcount decrementing, after the lock is released. } } inline void observer_list::notify_entry_observers( observer_proxy*& last, bool worker ) { if ( last == my_tail ) return; do_notify_entry_observers( last, worker ); } inline void observer_list::notify_exit_observers( observer_proxy*& last, bool worker ) { if ( !last ) return; __TBB_ASSERT(is_alive((uintptr_t)last), NULL); do_notify_exit_observers( last, worker ); __TBB_ASSERT(last, NULL); poison_value(last); } extern padded the_global_observer_list; } // namespace internal } // namespace tbb #endif /* __TBB_SCHEDULER_OBSERVER */ #endif /* _TBB_observer_proxy_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_do.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_do_H #define __TBB_parallel_do_H #include "internal/_range_iterator.h" #include "task.h" #include "aligned_space.h" #include namespace tbb { //! @cond INTERNAL namespace internal { template class parallel_do_feeder_impl; template class do_group_task; //! Strips its template type argument from 'cv' and '&' qualifiers template struct strip { typedef T type; }; template struct strip { typedef T type; }; template struct strip { typedef T type; }; template struct strip { typedef T type; }; template struct strip { typedef T type; }; // Most of the compilers remove cv-qualifiers from non-reference function argument types. // But unfortunately there are those that don't. template struct strip { typedef T type; }; template struct strip { typedef T type; }; template struct strip { typedef T type; }; } // namespace internal //! @endcond //! Class the user supplied algorithm body uses to add new tasks /** \param Item Work item type **/ template class parallel_do_feeder: internal::no_copy { parallel_do_feeder() {} virtual ~parallel_do_feeder () {} virtual void internal_add( const Item& item ) = 0; template friend class internal::parallel_do_feeder_impl; public: //! Add a work item to a running parallel_do. void add( const Item& item ) {internal_add(item);} }; //! @cond INTERNAL namespace internal { //! For internal use only. /** Selects one of the two possible forms of function call member operator. @ingroup algorithms **/ template class parallel_do_operator_selector { typedef parallel_do_feeder Feeder; template static void internal_call( const Body& obj, A1& arg1, A2&, void (Body::*)(CvItem) const ) { obj(arg1); } template static void internal_call( const Body& obj, A1& arg1, A2& arg2, void (Body::*)(CvItem, parallel_do_feeder&) const ) { obj(arg1, arg2); } public: template static void call( const Body& obj, A1& arg1, A2& arg2 ) { internal_call( obj, arg1, arg2, &Body::operator() ); } }; //! For internal use only. /** Executes one iteration of a do. @ingroup algorithms */ template class do_iteration_task: public task { typedef parallel_do_feeder_impl feeder_type; Item my_value; feeder_type& my_feeder; do_iteration_task( const Item& value, feeder_type& feeder ) : my_value(value), my_feeder(feeder) {} /*override*/ task* execute() { parallel_do_operator_selector::call(*my_feeder.my_body, my_value, my_feeder); return NULL; } template friend class parallel_do_feeder_impl; }; // class do_iteration_task template class do_iteration_task_iter: public task { typedef parallel_do_feeder_impl feeder_type; Iterator my_iter; feeder_type& my_feeder; do_iteration_task_iter( const Iterator& iter, feeder_type& feeder ) : my_iter(iter), my_feeder(feeder) {} /*override*/ task* execute() { parallel_do_operator_selector::call(*my_feeder.my_body, *my_iter, my_feeder); return NULL; } template friend class do_group_task_forward; template friend class do_group_task_input; template friend class do_task_iter; }; // class do_iteration_task_iter //! For internal use only. /** Implements new task adding procedure. @ingroup algorithms **/ template class parallel_do_feeder_impl : public parallel_do_feeder { /*override*/ void internal_add( const Item& item ) { typedef do_iteration_task iteration_type; iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(item, *this); t.spawn( t ); } public: const Body* my_body; empty_task* my_barrier; parallel_do_feeder_impl() { my_barrier = new( task::allocate_root() ) empty_task(); __TBB_ASSERT(my_barrier, "root task allocation failed"); } #if __TBB_TASK_GROUP_CONTEXT parallel_do_feeder_impl(tbb::task_group_context &context) { my_barrier = new( task::allocate_root(context) ) empty_task(); __TBB_ASSERT(my_barrier, "root task allocation failed"); } #endif ~parallel_do_feeder_impl() { my_barrier->destroy(*my_barrier); } }; // class parallel_do_feeder_impl //! For internal use only /** Unpacks a block of iterations. @ingroup algorithms */ template class do_group_task_forward: public task { static const size_t max_arg_size = 4; typedef parallel_do_feeder_impl feeder_type; feeder_type& my_feeder; Iterator my_first; size_t my_size; do_group_task_forward( Iterator first, size_t size, feeder_type& feeder ) : my_feeder(feeder), my_first(first), my_size(size) {} /*override*/ task* execute() { typedef do_iteration_task_iter iteration_type; __TBB_ASSERT( my_size>0, NULL ); task_list list; task* t; size_t k=0; for(;;) { t = new( allocate_child() ) iteration_type( my_first, my_feeder ); ++my_first; if( ++k==my_size ) break; list.push_back(*t); } set_ref_count(int(k+1)); spawn(list); spawn_and_wait_for_all(*t); return NULL; } template friend class do_task_iter; }; // class do_group_task_forward template class do_group_task_input: public task { static const size_t max_arg_size = 4; typedef parallel_do_feeder_impl feeder_type; feeder_type& my_feeder; size_t my_size; aligned_space my_arg; do_group_task_input( feeder_type& feeder ) : my_feeder(feeder), my_size(0) {} /*override*/ task* execute() { typedef do_iteration_task_iter iteration_type; __TBB_ASSERT( my_size>0, NULL ); task_list list; task* t; size_t k=0; for(;;) { t = new( allocate_child() ) iteration_type( my_arg.begin() + k, my_feeder ); if( ++k==my_size ) break; list.push_back(*t); } set_ref_count(int(k+1)); spawn(list); spawn_and_wait_for_all(*t); return NULL; } ~do_group_task_input(){ for( size_t k=0; k~Item(); } template friend class do_task_iter; }; // class do_group_task_input //! For internal use only. /** Gets block of iterations and packages them into a do_group_task. @ingroup algorithms */ template class do_task_iter: public task { typedef parallel_do_feeder_impl feeder_type; public: do_task_iter( Iterator first, Iterator last , feeder_type& feeder ) : my_first(first), my_last(last), my_feeder(feeder) {} private: Iterator my_first; Iterator my_last; feeder_type& my_feeder; /* Do not merge run(xxx) and run_xxx() methods. They are separated in order to make sure that compilers will eliminate unused argument of type xxx (that is will not put it on stack). The sole purpose of this argument is overload resolution. An alternative could be using template functions, but explicit specialization of member function templates is not supported for non specialized class templates. Besides template functions would always fall back to the least efficient variant (the one for input iterators) in case of iterators having custom tags derived from basic ones. */ /*override*/ task* execute() { typedef typename std::iterator_traits::iterator_category iterator_tag; return run( (iterator_tag*)NULL ); } /** This is the most restricted variant that operates on input iterators or iterators with unknown tags (tags not derived from the standard ones). **/ inline task* run( void* ) { return run_for_input_iterator(); } task* run_for_input_iterator() { typedef do_group_task_input block_type; block_type& t = *new( allocate_additional_child_of(*my_feeder.my_barrier) ) block_type(my_feeder); size_t k=0; while( !(my_first == my_last) ) { new (t.my_arg.begin() + k) Item(*my_first); ++my_first; if( ++k==block_type::max_arg_size ) { if ( !(my_first == my_last) ) recycle_to_reexecute(); break; } } if( k==0 ) { destroy(t); return NULL; } else { t.my_size = k; return &t; } } inline task* run( std::forward_iterator_tag* ) { return run_for_forward_iterator(); } task* run_for_forward_iterator() { typedef do_group_task_forward block_type; Iterator first = my_first; size_t k=0; while( !(my_first==my_last) ) { ++my_first; if( ++k==block_type::max_arg_size ) { if ( !(my_first==my_last) ) recycle_to_reexecute(); break; } } return k==0 ? NULL : new( allocate_additional_child_of(*my_feeder.my_barrier) ) block_type(first, k, my_feeder); } inline task* run( std::random_access_iterator_tag* ) { return run_for_random_access_iterator(); } task* run_for_random_access_iterator() { typedef do_group_task_forward block_type; typedef do_iteration_task_iter iteration_type; size_t k = static_cast(my_last-my_first); if( k > block_type::max_arg_size ) { Iterator middle = my_first + k/2; empty_task& c = *new( allocate_continuation() ) empty_task; do_task_iter& b = *new( c.allocate_child() ) do_task_iter(middle, my_last, my_feeder); recycle_as_child_of(c); my_last = middle; c.set_ref_count(2); c.spawn(b); return this; }else if( k != 0 ) { task_list list; task* t; size_t k1=0; for(;;) { t = new( allocate_child() ) iteration_type(my_first, my_feeder); ++my_first; if( ++k1==k ) break; list.push_back(*t); } set_ref_count(int(k+1)); spawn(list); spawn_and_wait_for_all(*t); } return NULL; } }; // class do_task_iter //! For internal use only. /** Implements parallel iteration over a range. @ingroup algorithms */ template void run_parallel_do( Iterator first, Iterator last, const Body& body #if __TBB_TASK_GROUP_CONTEXT , task_group_context& context #endif ) { typedef do_task_iter root_iteration_task; #if __TBB_TASK_GROUP_CONTEXT parallel_do_feeder_impl feeder(context); #else parallel_do_feeder_impl feeder; #endif feeder.my_body = &body; root_iteration_task &t = *new( feeder.my_barrier->allocate_child() ) root_iteration_task(first, last, feeder); feeder.my_barrier->set_ref_count(2); feeder.my_barrier->spawn_and_wait_for_all(t); } //! For internal use only. /** Detects types of Body's operator function arguments. @ingroup algorithms **/ template void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item) const #if __TBB_TASK_GROUP_CONTEXT , task_group_context& context #endif // __TBB_TASK_GROUP_CONTEXT ) { run_parallel_do::type>( first, last, body #if __TBB_TASK_GROUP_CONTEXT , context #endif // __TBB_TASK_GROUP_CONTEXT ); } //! For internal use only. /** Detects types of Body's operator function arguments. @ingroup algorithms **/ template void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item, parallel_do_feeder<_Item>&) const #if __TBB_TASK_GROUP_CONTEXT , task_group_context& context #endif // __TBB_TASK_GROUP_CONTEXT ) { run_parallel_do::type>( first, last, body #if __TBB_TASK_GROUP_CONTEXT , context #endif // __TBB_TASK_GROUP_CONTEXT ); } } // namespace internal //! @endcond /** \page parallel_do_body_req Requirements on parallel_do body Class \c Body implementing the concept of parallel_do body must define: - \code B::operator()( cv_item_type item, parallel_do_feeder& feeder ) const OR B::operator()( cv_item_type& item ) const \endcode Process item. May be invoked concurrently for the same \c this but different \c item. - \code item_type( const item_type& ) \endcode Copy a work item. - \code ~item_type() \endcode Destroy a work item **/ /** \name parallel_do See also requirements on \ref parallel_do_body_req "parallel_do Body". **/ //@{ //! Parallel iteration over a range, with optional addition of more work. /** @ingroup algorithms */ template void parallel_do( Iterator first, Iterator last, const Body& body ) { if ( first == last ) return; #if __TBB_TASK_GROUP_CONTEXT task_group_context context; #endif // __TBB_TASK_GROUP_CONTEXT internal::select_parallel_do( first, last, body, &Body::operator() #if __TBB_TASK_GROUP_CONTEXT , context #endif // __TBB_TASK_GROUP_CONTEXT ); } template void parallel_do(Range& rng, const Body& body) { parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body); } template void parallel_do(const Range& rng, const Body& body) { parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body); } #if __TBB_TASK_GROUP_CONTEXT //! Parallel iteration over a range, with optional addition of more work and user-supplied context /** @ingroup algorithms */ template void parallel_do( Iterator first, Iterator last, const Body& body, task_group_context& context ) { if ( first == last ) return; internal::select_parallel_do( first, last, body, &Body::operator(), context ); } template void parallel_do(Range& rng, const Body& body, task_group_context& context) { parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context); } template void parallel_do(const Range& rng, const Body& body, task_group_context& context) { parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context); } #endif // __TBB_TASK_GROUP_CONTEXT //@} } // namespace #endif /* __TBB_parallel_do_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_for.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_for_H #define __TBB_parallel_for_H #include #include "task.h" #include "partitioner.h" #include "blocked_range.h" #include "tbb_exception.h" namespace tbb { namespace interface7 { //! @cond INTERNAL namespace internal { //! allocate right task with new parent void* allocate_sibling(task* start_for_task, size_t bytes); //! Task type used in parallel_for /** @ingroup algorithms */ template class start_for: public task { Range my_range; const Body my_body; typename Partitioner::task_partition_type my_partition; /*override*/ task* execute(); //! Update affinity info, if any. /*override*/ void note_affinity( affinity_id id ) { my_partition.note_affinity( id ); } public: //! Constructor for root task. start_for( const Range& range, const Body& body, Partitioner& partitioner ) : my_range(range), my_body(body), my_partition(partitioner) { } //! Splitting constructor used to generate children. /** parent_ becomes left child. Newly constructed object is right child. */ start_for( start_for& parent_, typename Partitioner::split_type& split_obj) : my_range(parent_.my_range, split_obj), my_body(parent_.my_body), my_partition(parent_.my_partition, split_obj) { my_partition.set_affinity(*this); } //! Construct right child from the given range as response to the demand. /** parent_ remains left child. Newly constructed object is right child. */ start_for( start_for& parent_, const Range& r, depth_t d ) : my_range(r), my_body(parent_.my_body), my_partition(parent_.my_partition, split()) { my_partition.set_affinity(*this); my_partition.align_depth( d ); } static void run( const Range& range, const Body& body, Partitioner& partitioner ) { if( !range.empty() ) { #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP start_for& a = *new(task::allocate_root()) start_for(range,body,partitioner); #else // Bound context prevents exceptions from body to affect nesting or sibling algorithms, // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. task_group_context context; start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner); #endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ task::spawn_root_and_wait(a); } } #if __TBB_TASK_GROUP_CONTEXT static void run( const Range& range, const Body& body, Partitioner& partitioner, task_group_context& context ) { if( !range.empty() ) { start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner); task::spawn_root_and_wait(a); } } #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Run body for range, serves as callback for partitioner void run_body( Range &r ) { my_body( r ); } //! spawn right task, serves as callback for partitioner void offer_work(typename Partitioner::split_type& split_obj) { spawn( *new( allocate_sibling(static_cast(this), sizeof(start_for)) ) start_for(*this, split_obj) ); } //! spawn right task, serves as callback for partitioner void offer_work(const Range& r, depth_t d = 0) { spawn( *new( allocate_sibling(static_cast(this), sizeof(start_for)) ) start_for(*this, r, d) ); } }; //! allocate right task with new parent // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined inline void* allocate_sibling(task* start_for_task, size_t bytes) { task* parent_ptr = new( start_for_task->allocate_continuation() ) flag_task(); start_for_task->set_parent(parent_ptr); parent_ptr->set_ref_count(2); return &parent_ptr->allocate_child().allocate(bytes); } //! execute task for parallel_for template task* start_for::execute() { my_partition.check_being_stolen( *this ); my_partition.execute(*this, my_range); return NULL; } } // namespace internal //! @endcond } // namespace interfaceX //! @cond INTERNAL namespace internal { using interface7::internal::start_for; //! Calls the function with values from range [begin, end) with a step provided template class parallel_for_body : internal::no_assign { const Function &my_func; const Index my_begin; const Index my_step; public: parallel_for_body( const Function& _func, Index& _begin, Index& _step ) : my_func(_func), my_begin(_begin), my_step(_step) {} void operator()( const tbb::blocked_range& r ) const { // A set of local variables to help the compiler with vectorization of the following loop. Index b = r.begin(); Index e = r.end(); Index ms = my_step; Index k = my_begin + b*ms; #if __INTEL_COMPILER #pragma ivdep #if __TBB_ASSERT_ON_VECTORIZATION_FAILURE #pragma vector always assert #endif #endif for ( Index i = b; i < e; ++i, k += ms ) { my_func( k ); } } }; } // namespace internal //! @endcond // Requirements on Range concept are documented in blocked_range.h /** \page parallel_for_body_req Requirements on parallel_for body Class \c Body implementing the concept of parallel_for body must define: - \code Body::Body( const Body& ); \endcode Copy constructor - \code Body::~Body(); \endcode Destructor - \code void Body::operator()( Range& r ) const; \endcode Function call operator applying the body to range \c r. **/ /** \name parallel_for See also requirements on \ref range_req "Range" and \ref parallel_for_body_req "parallel_for Body". **/ //@{ //! Parallel iteration over range with default partitioner. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body ) { internal::start_for::run(range,body,__TBB_DEFAULT_PARTITIONER()); } //! Parallel iteration over range with simple partitioner. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) { internal::start_for::run(range,body,partitioner); } //! Parallel iteration over range with auto_partitioner. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) { internal::start_for::run(range,body,partitioner); } //! Parallel iteration over range with affinity_partitioner. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) { internal::start_for::run(range,body,partitioner); } #if __TBB_TASK_GROUP_CONTEXT //! Parallel iteration over range with default partitioner and user-supplied context. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, task_group_context& context ) { internal::start_for::run(range, body, __TBB_DEFAULT_PARTITIONER(), context); } //! Parallel iteration over range with simple partitioner and user-supplied context. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner, task_group_context& context ) { internal::start_for::run(range, body, partitioner, context); } //! Parallel iteration over range with auto_partitioner and user-supplied context. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner, task_group_context& context ) { internal::start_for::run(range, body, partitioner, context); } //! Parallel iteration over range with affinity_partitioner and user-supplied context. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner, task_group_context& context ) { internal::start_for::run(range,body,partitioner, context); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //@} namespace strict_ppl { //@{ //! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner template void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner) { if (step <= 0 ) internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument else if (last > first) { // Above "else" avoids "potential divide by zero" warning on some platforms Index end = (last - first - Index(1)) / step + Index(1); tbb::blocked_range range(static_cast(0), end); internal::parallel_for_body body(f, first, step); tbb::parallel_for(range, body, partitioner); } } //! Parallel iteration over a range of integers with a step provided and default partitioner template void parallel_for(Index first, Index last, Index step, const Function& f) { parallel_for_impl(first, last, step, f, auto_partitioner()); } //! Parallel iteration over a range of integers with a step provided and simple partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner) { parallel_for_impl(first, last, step, f, partitioner); } //! Parallel iteration over a range of integers with a step provided and auto partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner) { parallel_for_impl(first, last, step, f, partitioner); } //! Parallel iteration over a range of integers with a step provided and affinity partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner) { parallel_for_impl(first, last, step, f, partitioner); } //! Parallel iteration over a range of integers with a default step value and default partitioner template void parallel_for(Index first, Index last, const Function& f) { parallel_for_impl(first, last, static_cast(1), f, auto_partitioner()); } //! Parallel iteration over a range of integers with a default step value and simple partitioner template void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner) { parallel_for_impl(first, last, static_cast(1), f, partitioner); } //! Parallel iteration over a range of integers with a default step value and auto partitioner template void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner) { parallel_for_impl(first, last, static_cast(1), f, partitioner); } //! Parallel iteration over a range of integers with a default step value and affinity partitioner template void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner) { parallel_for_impl(first, last, static_cast(1), f, partitioner); } #if __TBB_TASK_GROUP_CONTEXT //! Implementation of parallel iteration over stepped range of integers with explicit step, task group context, and partitioner template void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner, tbb::task_group_context &context) { if (step <= 0 ) internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument else if (last > first) { // Above "else" avoids "potential divide by zero" warning on some platforms Index end = (last - first - Index(1)) / step + Index(1); tbb::blocked_range range(static_cast(0), end); internal::parallel_for_body body(f, first, step); tbb::parallel_for(range, body, partitioner, context); } } //! Parallel iteration over a range of integers with explicit step, task group context, and default partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, tbb::task_group_context &context) { parallel_for_impl(first, last, step, f, auto_partitioner(), context); } //! Parallel iteration over a range of integers with explicit step, task group context, and simple partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, step, f, partitioner, context); } //! Parallel iteration over a range of integers with explicit step, task group context, and auto partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, step, f, partitioner, context); } //! Parallel iteration over a range of integers with explicit step, task group context, and affinity partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, step, f, partitioner, context); } //! Parallel iteration over a range of integers with a default step value, explicit task group context, and default partitioner template void parallel_for(Index first, Index last, const Function& f, tbb::task_group_context &context) { parallel_for_impl(first, last, static_cast(1), f, auto_partitioner(), context); } //! Parallel iteration over a range of integers with a default step value, explicit task group context, and simple partitioner template void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, static_cast(1), f, partitioner, context); } //! Parallel iteration over a range of integers with a default step value, explicit task group context, and auto partitioner template void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, static_cast(1), f, partitioner, context); } //! Parallel iteration over a range of integers with a default step value, explicit task group context, and affinity_partitioner template void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, static_cast(1), f, partitioner, context); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //@} } // namespace strict_ppl using strict_ppl::parallel_for; } // namespace tbb #if TBB_PREVIEW_SERIAL_SUBSET #define __TBB_NORMAL_EXECUTION #include "../serial/tbb/parallel_for.h" #undef __TBB_NORMAL_EXECUTION #endif #endif /* __TBB_parallel_for_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_for_each.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_for_each_H #define __TBB_parallel_for_each_H #include "parallel_do.h" namespace tbb { //! @cond INTERNAL namespace internal { // The class calls user function in operator() template class parallel_for_each_body : internal::no_assign { const Function &my_func; public: parallel_for_each_body(const Function &_func) : my_func(_func) {} parallel_for_each_body(const parallel_for_each_body &_caller) : my_func(_caller.my_func) {} void operator() ( typename std::iterator_traits::reference value ) const { my_func(value); } }; } // namespace internal //! @endcond /** \name parallel_for_each **/ //@{ //! Calls function f for all items from [first, last) interval using user-supplied context /** @ingroup algorithms */ #if __TBB_TASK_GROUP_CONTEXT template void parallel_for_each(InputIterator first, InputIterator last, const Function& f, task_group_context &context) { internal::parallel_for_each_body body(f); tbb::parallel_do (first, last, body, context); } //! Calls function f for all items from rng using user-supplied context /** @ingroup algorithms */ template void parallel_for_each(Range& rng, const Function& f, task_group_context& context) { parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); } //! Calls function f for all items from const rng user-supplied context /** @ingroup algorithms */ template void parallel_for_each(const Range& rng, const Function& f, task_group_context& context) { parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Uses default context template void parallel_for_each(InputIterator first, InputIterator last, const Function& f) { internal::parallel_for_each_body body(f); tbb::parallel_do (first, last, body); } //! Uses default context template void parallel_for_each(Range& rng, const Function& f) { parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); } //! Uses default context template void parallel_for_each(const Range& rng, const Function& f) { parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); } //@} } // namespace #endif /* __TBB_parallel_for_each_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_invoke.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_invoke_H #define __TBB_parallel_invoke_H #include "task.h" #if __TBB_VARIADIC_PARALLEL_INVOKE #include #endif namespace tbb { #if !__TBB_TASK_GROUP_CONTEXT /** Dummy to avoid cluttering the bulk of the header with enormous amount of ifdefs. **/ struct task_group_context {}; #endif /* __TBB_TASK_GROUP_CONTEXT */ //! @cond INTERNAL namespace internal { // Simple task object, executing user method template class function_invoker : public task{ public: function_invoker(const function& _function) : my_function(_function) {} private: const function &my_function; /*override*/ task* execute() { my_function(); return NULL; } }; // The class spawns two or three child tasks template class spawner : public task { private: const function1& my_func1; const function2& my_func2; const function3& my_func3; bool is_recycled; task* execute (){ if(is_recycled){ return NULL; }else{ __TBB_ASSERT(N==2 || N==3, "Number of arguments passed to spawner is wrong"); set_ref_count(N); recycle_as_safe_continuation(); internal::function_invoker* invoker2 = new (allocate_child()) internal::function_invoker(my_func2); __TBB_ASSERT(invoker2, "Child task allocation failed"); spawn(*invoker2); size_t n = N; // To prevent compiler warnings if (n>2) { internal::function_invoker* invoker3 = new (allocate_child()) internal::function_invoker(my_func3); __TBB_ASSERT(invoker3, "Child task allocation failed"); spawn(*invoker3); } my_func1(); is_recycled = true; return NULL; } } // execute public: spawner(const function1& _func1, const function2& _func2, const function3& _func3) : my_func1(_func1), my_func2(_func2), my_func3(_func3), is_recycled(false) {} }; // Creates and spawns child tasks class parallel_invoke_helper : public empty_task { public: // Dummy functor class class parallel_invoke_noop { public: void operator() () const {} }; // Creates a helper object with user-defined number of children expected parallel_invoke_helper(int number_of_children) { set_ref_count(number_of_children + 1); } #if __TBB_VARIADIC_PARALLEL_INVOKE void add_children() {} void add_children(tbb::task_group_context&) {} template void add_children(function&& _func) { internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(std::forward(_func)); __TBB_ASSERT(invoker, "Child task allocation failed"); spawn(*invoker); } template void add_children(function&& _func, tbb::task_group_context&) { add_children(std::forward(_func)); } // Adds child(ren) task(s) and spawns them template void add_children(function1&& _func1, function2&& _func2, function&&... _func) { // The third argument is dummy, it is ignored actually. parallel_invoke_noop noop; typedef internal::spawner<2, function1, function2, parallel_invoke_noop> spawner_type; spawner_type & sub_root = *new(allocate_child()) spawner_type(std::forward(_func1), std::forward(_func2), noop); spawn(sub_root); add_children(std::forward(_func)...); } #else // Adds child task and spawns it template void add_children (const function &_func) { internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(_func); __TBB_ASSERT(invoker, "Child task allocation failed"); spawn(*invoker); } // Adds a task with multiple child tasks and spawns it // two arguments template void add_children (const function1& _func1, const function2& _func2) { // The third argument is dummy, it is ignored actually. parallel_invoke_noop noop; internal::spawner<2, function1, function2, parallel_invoke_noop>& sub_root = *new(allocate_child())internal::spawner<2, function1, function2, parallel_invoke_noop>(_func1, _func2, noop); spawn(sub_root); } // three arguments template void add_children (const function1& _func1, const function2& _func2, const function3& _func3) { internal::spawner<3, function1, function2, function3>& sub_root = *new(allocate_child())internal::spawner<3, function1, function2, function3>(_func1, _func2, _func3); spawn(sub_root); } #endif // __TBB_VARIADIC_PARALLEL_INVOKE // Waits for all child tasks template void run_and_finish(const F0& f0) { internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(f0); __TBB_ASSERT(invoker, "Child task allocation failed"); spawn_and_wait_for_all(*invoker); } }; // The class destroys root if exception occurred as well as in normal case class parallel_invoke_cleaner: internal::no_copy { public: #if __TBB_TASK_GROUP_CONTEXT parallel_invoke_cleaner(int number_of_children, tbb::task_group_context& context) : root(*new(task::allocate_root(context)) internal::parallel_invoke_helper(number_of_children)) #else parallel_invoke_cleaner(int number_of_children, tbb::task_group_context&) : root(*new(task::allocate_root()) internal::parallel_invoke_helper(number_of_children)) #endif /* !__TBB_TASK_GROUP_CONTEXT */ {} ~parallel_invoke_cleaner(){ root.destroy(root); } internal::parallel_invoke_helper& root; }; #if __TBB_VARIADIC_PARALLEL_INVOKE // Determine whether the last parameter in a pack is task_group_context template struct impl_selector; // to workaround a GCC bug template struct impl_selector { typedef typename impl_selector::type type; }; template struct impl_selector { typedef false_type type; }; template<> struct impl_selector { typedef true_type type; }; // Select task_group_context parameter from the back of a pack task_group_context& get_context( task_group_context& tgc ) { return tgc; } template task_group_context& get_context( T1&& /*ignored*/, T&&... t ) { return get_context( std::forward(t)... ); } // task_group_context is known to be at the back of the parameter pack template void parallel_invoke_impl(true_type, F0&& f0, F1&& f1, F&&... f) { __TBB_STATIC_ASSERT(sizeof...(F)>0, "Variadic parallel_invoke implementation broken?"); // # of child tasks: f0, f1, and a task for each two elements of the pack except the last const size_t number_of_children = 2 + sizeof...(F)/2; parallel_invoke_cleaner cleaner(number_of_children, get_context(std::forward(f)...)); parallel_invoke_helper& root = cleaner.root; root.add_children(std::forward(f)...); root.add_children(std::forward(f1)); root.run_and_finish(std::forward(f0)); } // task_group_context is not in the pack, needs to be added template void parallel_invoke_impl(false_type, F0&& f0, F1&& f1, F&&... f) { tbb::task_group_context context; // Add context to the arguments, and redirect to the other overload parallel_invoke_impl(true_type(), std::forward(f0), std::forward(f1), std::forward(f)..., context); } #endif } // namespace internal //! @endcond /** \name parallel_invoke **/ //@{ //! Executes a list of tasks in parallel and waits for all tasks to complete. /** @ingroup algorithms */ #if __TBB_VARIADIC_PARALLEL_INVOKE // parallel_invoke for two or more arguments via variadic templates // presence of task_group_context is defined automatically template void parallel_invoke(F0&& f0, F1&& f1, F&&... f) { typedef typename internal::impl_selector::type selector_type; internal::parallel_invoke_impl(selector_type(), std::forward(f0), std::forward(f1), std::forward(f)...); } #else // parallel_invoke with user-defined context // two arguments template void parallel_invoke(const F0& f0, const F1& f1, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(2, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f1); root.run_and_finish(f0); } // three arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(3, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f2); root.add_children(f1); root.run_and_finish(f0); } // four arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(4, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f3); root.add_children(f2); root.add_children(f1); root.run_and_finish(f0); } // five arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(3, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f4, f3); root.add_children(f2, f1); root.run_and_finish(f0); } // six arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(3, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f5, f4, f3); root.add_children(f2, f1); root.run_and_finish(f0); } // seven arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(3, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f6, f5, f4); root.add_children(f3, f2, f1); root.run_and_finish(f0); } // eight arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6, const F7& f7, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(4, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f7, f6, f5); root.add_children(f4, f3); root.add_children(f2, f1); root.run_and_finish(f0); } // nine arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6, const F7& f7, const F8& f8, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(4, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f8, f7, f6); root.add_children(f5, f4, f3); root.add_children(f2, f1); root.run_and_finish(f0); } // ten arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6, const F7& f7, const F8& f8, const F9& f9, tbb::task_group_context& context) { internal::parallel_invoke_cleaner cleaner(4, context); internal::parallel_invoke_helper& root = cleaner.root; root.add_children(f9, f8, f7); root.add_children(f6, f5, f4); root.add_children(f3, f2, f1); root.run_and_finish(f0); } // two arguments template void parallel_invoke(const F0& f0, const F1& f1) { task_group_context context; parallel_invoke(f0, f1, context); } // three arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2) { task_group_context context; parallel_invoke(f0, f1, f2, context); } // four arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3) { task_group_context context; parallel_invoke(f0, f1, f2, f3, context); } // five arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4) { task_group_context context; parallel_invoke(f0, f1, f2, f3, f4, context); } // six arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5) { task_group_context context; parallel_invoke(f0, f1, f2, f3, f4, f5, context); } // seven arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6) { task_group_context context; parallel_invoke(f0, f1, f2, f3, f4, f5, f6, context); } // eight arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6, const F7& f7) { task_group_context context; parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, context); } // nine arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6, const F7& f7, const F8& f8) { task_group_context context; parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, f8, context); } // ten arguments template void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, const F6& f6, const F7& f7, const F8& f8, const F9& f9) { task_group_context context; parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, context); } #endif // __TBB_VARIADIC_PARALLEL_INVOKE //@} } // namespace #endif /* __TBB_parallel_invoke_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_reduce.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_reduce_H #define __TBB_parallel_reduce_H #include #include "task.h" #include "aligned_space.h" #include "partitioner.h" #include "tbb_profiling.h" namespace tbb { namespace interface7 { //! @cond INTERNAL namespace internal { using namespace tbb::internal; /** Values for reduction_context. */ enum { root_task, left_child, right_child }; /** Represented as a char, not enum, for compactness. */ typedef char reduction_context; //! Task type used to combine the partial results of parallel_reduce. /** @ingroup algorithms */ template class finish_reduce: public flag_task { //! Pointer to body, or NULL if the left child has not yet finished. bool has_right_zombie; const reduction_context my_context; Body* my_body; aligned_space zombie_space; finish_reduce( reduction_context context_ ) : has_right_zombie(false), // TODO: substitute by flag_task::child_stolen? my_context(context_), my_body(NULL) { } ~finish_reduce() { if( has_right_zombie ) zombie_space.begin()->~Body(); } task* execute() { if( has_right_zombie ) { // Right child was stolen. Body* s = zombie_space.begin(); my_body->join( *s ); // Body::join() won't be called if canceled. Defer destruction to destructor } if( my_context==left_child ) itt_store_word_with_release( static_cast(parent())->my_body, my_body ); return NULL; } template friend class start_reduce; }; //! allocate right task with new parent void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes); //! Task type used to split the work of parallel_reduce. /** @ingroup algorithms */ template class start_reduce: public task { typedef finish_reduce finish_type; Body* my_body; Range my_range; typename Partitioner::task_partition_type my_partition; reduction_context my_context; /*override*/ task* execute(); //! Update affinity info, if any /*override*/ void note_affinity( affinity_id id ) { my_partition.note_affinity( id ); } template friend class finish_reduce; public: //! Constructor used for root task start_reduce( const Range& range, Body* body, Partitioner& partitioner ) : my_body(body), my_range(range), my_partition(partitioner), my_context(root_task) { } //! Splitting constructor used to generate children. /** parent_ becomes left child. Newly constructed object is right child. */ start_reduce( start_reduce& parent_, typename Partitioner::split_type& split_obj ) : my_body(parent_.my_body), my_range(parent_.my_range, split_obj), my_partition(parent_.my_partition, split_obj), my_context(right_child) { my_partition.set_affinity(*this); parent_.my_context = left_child; } //! Construct right child from the given range as response to the demand. /** parent_ remains left child. Newly constructed object is right child. */ start_reduce( start_reduce& parent_, const Range& r, depth_t d ) : my_body(parent_.my_body), my_range(r), my_partition(parent_.my_partition, split()), my_context(right_child) { my_partition.set_affinity(*this); my_partition.align_depth( d ); // TODO: move into constructor of partitioner parent_.my_context = left_child; } static void run( const Range& range, Body& body, Partitioner& partitioner ) { if( !range.empty() ) { #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP task::spawn_root_and_wait( *new(task::allocate_root()) start_reduce(range,&body,partitioner) ); #else // Bound context prevents exceptions from body to affect nesting or sibling algorithms, // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. task_group_context context; task::spawn_root_and_wait( *new(task::allocate_root(context)) start_reduce(range,&body,partitioner) ); #endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ } } #if __TBB_TASK_GROUP_CONTEXT static void run( const Range& range, Body& body, Partitioner& partitioner, task_group_context& context ) { if( !range.empty() ) task::spawn_root_and_wait( *new(task::allocate_root(context)) start_reduce(range,&body,partitioner) ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Run body for range void run_body( Range &r ) { (*my_body)( r ); } //! spawn right task, serves as callback for partitioner // TODO: remove code duplication from 'offer_work' methods void offer_work(typename Partitioner::split_type& split_obj) { task *tasks[2]; allocate_sibling(static_cast(this), tasks, sizeof(start_reduce), sizeof(finish_type)); new((void*)tasks[0]) finish_type(my_context); new((void*)tasks[1]) start_reduce(*this, split_obj); spawn(*tasks[1]); } //! spawn right task, serves as callback for partitioner void offer_work(const Range& r, depth_t d = 0) { task *tasks[2]; allocate_sibling(static_cast(this), tasks, sizeof(start_reduce), sizeof(finish_type)); new((void*)tasks[0]) finish_type(my_context); new((void*)tasks[1]) start_reduce(*this, r, d); spawn(*tasks[1]); } }; //! allocate right task with new parent // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined inline void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes) { tasks[0] = &start_reduce_task->allocate_continuation().allocate(finish_bytes); start_reduce_task->set_parent(tasks[0]); tasks[0]->set_ref_count(2); tasks[1] = &tasks[0]->allocate_child().allocate(start_bytes); } template task* start_reduce::execute() { my_partition.check_being_stolen( *this ); if( my_context==right_child ) { finish_type* parent_ptr = static_cast(parent()); if( !itt_load_word_with_acquire(parent_ptr->my_body) ) { // TODO: replace by is_stolen_task() or by parent_ptr->ref_count() == 2??? my_body = new( parent_ptr->zombie_space.begin() ) Body(*my_body,split()); parent_ptr->has_right_zombie = true; } } else __TBB_ASSERT(my_context==root_task,NULL);// because left leaf spawns right leafs without recycling my_partition.execute(*this, my_range); if( my_context==left_child ) { finish_type* parent_ptr = static_cast(parent()); __TBB_ASSERT(my_body!=parent_ptr->zombie_space.begin(),NULL); itt_store_word_with_release(parent_ptr->my_body, my_body ); } return NULL; } //! Task type used to combine the partial results of parallel_deterministic_reduce. /** @ingroup algorithms */ template class finish_deterministic_reduce: public task { Body &my_left_body; Body my_right_body; finish_deterministic_reduce( Body &body ) : my_left_body( body ), my_right_body( body, split() ) { } task* execute() { my_left_body.join( my_right_body ); return NULL; } template friend class start_deterministic_reduce; }; //! Task type used to split the work of parallel_deterministic_reduce. /** @ingroup algorithms */ template class start_deterministic_reduce: public task { typedef finish_deterministic_reduce finish_type; Body &my_body; Range my_range; /*override*/ task* execute(); //! Constructor used for root task start_deterministic_reduce( const Range& range, Body& body ) : my_body( body ), my_range( range ) { } //! Splitting constructor used to generate children. /** parent_ becomes left child. Newly constructed object is right child. */ start_deterministic_reduce( start_deterministic_reduce& parent_, finish_type& c ) : my_body( c.my_right_body ), my_range( parent_.my_range, split() ) { } public: static void run( const Range& range, Body& body ) { if( !range.empty() ) { #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP task::spawn_root_and_wait( *new(task::allocate_root()) start_deterministic_reduce(range,&body) ); #else // Bound context prevents exceptions from body to affect nesting or sibling algorithms, // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. task_group_context context; task::spawn_root_and_wait( *new(task::allocate_root(context)) start_deterministic_reduce(range,body) ); #endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ } } #if __TBB_TASK_GROUP_CONTEXT static void run( const Range& range, Body& body, task_group_context& context ) { if( !range.empty() ) task::spawn_root_and_wait( *new(task::allocate_root(context)) start_deterministic_reduce(range,body) ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ }; template task* start_deterministic_reduce::execute() { if( !my_range.is_divisible() ) { my_body( my_range ); return NULL; } else { finish_type& c = *new( allocate_continuation() ) finish_type( my_body ); recycle_as_child_of(c); c.set_ref_count(2); start_deterministic_reduce& b = *new( c.allocate_child() ) start_deterministic_reduce( *this, c ); task::spawn(b); return this; } } } // namespace internal //! @endcond } //namespace interfaceX //! @cond INTERNAL namespace internal { using interface7::internal::start_reduce; using interface7::internal::start_deterministic_reduce; //! Auxiliary class for parallel_reduce; for internal use only. /** The adaptor class that implements \ref parallel_reduce_body_req "parallel_reduce Body" using given \ref parallel_reduce_lambda_req "anonymous function objects". **/ /** @ingroup algorithms */ template class lambda_reduce_body { //FIXME: decide if my_real_body, my_reduction, and identity_element should be copied or referenced // (might require some performance measurements) const Value& identity_element; const RealBody& my_real_body; const Reduction& my_reduction; Value my_value; lambda_reduce_body& operator= ( const lambda_reduce_body& other ); public: lambda_reduce_body( const Value& identity, const RealBody& body, const Reduction& reduction ) : identity_element(identity) , my_real_body(body) , my_reduction(reduction) , my_value(identity) { } lambda_reduce_body( const lambda_reduce_body& other ) : identity_element(other.identity_element) , my_real_body(other.my_real_body) , my_reduction(other.my_reduction) , my_value(other.my_value) { } lambda_reduce_body( lambda_reduce_body& other, tbb::split ) : identity_element(other.identity_element) , my_real_body(other.my_real_body) , my_reduction(other.my_reduction) , my_value(other.identity_element) { } void operator()(Range& range) { my_value = my_real_body(range, const_cast(my_value)); } void join( lambda_reduce_body& rhs ) { my_value = my_reduction(const_cast(my_value), const_cast(rhs.my_value)); } Value result() const { return my_value; } }; } // namespace internal //! @endcond // Requirements on Range concept are documented in blocked_range.h /** \page parallel_reduce_body_req Requirements on parallel_reduce body Class \c Body implementing the concept of parallel_reduce body must define: - \code Body::Body( Body&, split ); \endcode Splitting constructor. Must be able to run concurrently with operator() and method \c join - \code Body::~Body(); \endcode Destructor - \code void Body::operator()( Range& r ); \endcode Function call operator applying body to range \c r and accumulating the result - \code void Body::join( Body& b ); \endcode Join results. The result in \c b should be merged into the result of \c this **/ /** \page parallel_reduce_lambda_req Requirements on parallel_reduce anonymous function objects (lambda functions) TO BE DOCUMENTED **/ /** \name parallel_reduce See also requirements on \ref range_req "Range" and \ref parallel_reduce_body_req "parallel_reduce Body". **/ //@{ //! Parallel iteration with reduction and default partitioner. /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body ) { internal::start_reduce::run( range, body, __TBB_DEFAULT_PARTITIONER() ); } //! Parallel iteration with reduction and simple_partitioner /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, const simple_partitioner& partitioner ) { internal::start_reduce::run( range, body, partitioner ); } //! Parallel iteration with reduction and auto_partitioner /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, const auto_partitioner& partitioner ) { internal::start_reduce::run( range, body, partitioner ); } //! Parallel iteration with reduction and affinity_partitioner /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, affinity_partitioner& partitioner ) { internal::start_reduce::run( range, body, partitioner ); } #if __TBB_TASK_GROUP_CONTEXT //! Parallel iteration with reduction, simple partitioner and user-supplied context. /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, const simple_partitioner& partitioner, task_group_context& context ) { internal::start_reduce::run( range, body, partitioner, context ); } //! Parallel iteration with reduction, auto_partitioner and user-supplied context /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, const auto_partitioner& partitioner, task_group_context& context ) { internal::start_reduce::run( range, body, partitioner, context ); } //! Parallel iteration with reduction, affinity_partitioner and user-supplied context /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, affinity_partitioner& partitioner, task_group_context& context ) { internal::start_reduce::run( range, body, partitioner, context ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ /** parallel_reduce overloads that work with anonymous function objects (see also \ref parallel_reduce_lambda_req "requirements on parallel_reduce anonymous function objects"). **/ //! Parallel iteration with reduction and default partitioner. /** @ingroup algorithms **/ template Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_reduce,const __TBB_DEFAULT_PARTITIONER> ::run(range, body, __TBB_DEFAULT_PARTITIONER() ); return body.result(); } //! Parallel iteration with reduction and simple_partitioner. /** @ingroup algorithms **/ template Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, const simple_partitioner& partitioner ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_reduce,const simple_partitioner> ::run(range, body, partitioner ); return body.result(); } //! Parallel iteration with reduction and auto_partitioner /** @ingroup algorithms **/ template Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, const auto_partitioner& partitioner ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_reduce,const auto_partitioner> ::run( range, body, partitioner ); return body.result(); } //! Parallel iteration with reduction and affinity_partitioner /** @ingroup algorithms **/ template Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, affinity_partitioner& partitioner ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_reduce,affinity_partitioner> ::run( range, body, partitioner ); return body.result(); } #if __TBB_TASK_GROUP_CONTEXT //! Parallel iteration with reduction, simple partitioner and user-supplied context. /** @ingroup algorithms **/ template Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, const simple_partitioner& partitioner, task_group_context& context ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_reduce,const simple_partitioner> ::run( range, body, partitioner, context ); return body.result(); } //! Parallel iteration with reduction, auto_partitioner and user-supplied context /** @ingroup algorithms **/ template Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, const auto_partitioner& partitioner, task_group_context& context ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_reduce,const auto_partitioner> ::run( range, body, partitioner, context ); return body.result(); } //! Parallel iteration with reduction, affinity_partitioner and user-supplied context /** @ingroup algorithms **/ template Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, affinity_partitioner& partitioner, task_group_context& context ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_reduce,affinity_partitioner> ::run( range, body, partitioner, context ); return body.result(); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Parallel iteration with deterministic reduction and default partitioner. /** @ingroup algorithms **/ template void parallel_deterministic_reduce( const Range& range, Body& body ) { internal::start_deterministic_reduce::run( range, body ); } #if __TBB_TASK_GROUP_CONTEXT //! Parallel iteration with deterministic reduction, simple partitioner and user-supplied context. /** @ingroup algorithms **/ template void parallel_deterministic_reduce( const Range& range, Body& body, task_group_context& context ) { internal::start_deterministic_reduce::run( range, body, context ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ /** parallel_reduce overloads that work with anonymous function objects (see also \ref parallel_reduce_lambda_req "requirements on parallel_reduce anonymous function objects"). **/ //! Parallel iteration with deterministic reduction and default partitioner. /** @ingroup algorithms **/ template Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_deterministic_reduce > ::run(range, body); return body.result(); } #if __TBB_TASK_GROUP_CONTEXT //! Parallel iteration with deterministic reduction, simple partitioner and user-supplied context. /** @ingroup algorithms **/ template Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, task_group_context& context ) { internal::lambda_reduce_body body(identity, real_body, reduction); internal::start_deterministic_reduce > ::run( range, body, context ); return body.result(); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //@} } // namespace tbb #endif /* __TBB_parallel_reduce_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_scan.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_scan_H #define __TBB_parallel_scan_H #include "task.h" #include "aligned_space.h" #include #include "partitioner.h" namespace tbb { //! Used to indicate that the initial scan is being performed. /** @ingroup algorithms */ struct pre_scan_tag { static bool is_final_scan() {return false;} }; //! Used to indicate that the final scan is being performed. /** @ingroup algorithms */ struct final_scan_tag { static bool is_final_scan() {return true;} }; //! @cond INTERNAL namespace internal { //! Performs final scan for a leaf /** @ingroup algorithms */ template class final_sum: public task { public: Body my_body; private: aligned_space my_range; //! Where to put result of last subrange, or NULL if not last subrange. Body* my_stuff_last; public: final_sum( Body& body_ ) : my_body(body_,split()) { poison_pointer(my_stuff_last); } ~final_sum() { my_range.begin()->~Range(); } void finish_construction( const Range& range_, Body* stuff_last_ ) { new( my_range.begin() ) Range(range_); my_stuff_last = stuff_last_; } private: /*override*/ task* execute() { my_body( *my_range.begin(), final_scan_tag() ); if( my_stuff_last ) my_stuff_last->assign(my_body); return NULL; } }; //! Split work to be done in the scan. /** @ingroup algorithms */ template class sum_node: public task { typedef final_sum final_sum_type; public: final_sum_type *my_incoming; final_sum_type *my_body; Body *my_stuff_last; private: final_sum_type *my_left_sum; sum_node *my_left; sum_node *my_right; bool my_left_is_final; Range my_range; sum_node( const Range range_, bool left_is_final_ ) : my_left_sum(NULL), my_left(NULL), my_right(NULL), my_left_is_final(left_is_final_), my_range(range_) { // Poison fields that will be set by second pass. poison_pointer(my_body); poison_pointer(my_incoming); } task* create_child( const Range& range_, final_sum_type& f, sum_node* n, final_sum_type* incoming_, Body* stuff_last_ ) { if( !n ) { f.recycle_as_child_of( *this ); f.finish_construction( range_, stuff_last_ ); return &f; } else { n->my_body = &f; n->my_incoming = incoming_; n->my_stuff_last = stuff_last_; return n; } } /*override*/ task* execute() { if( my_body ) { if( my_incoming ) my_left_sum->my_body.reverse_join( my_incoming->my_body ); recycle_as_continuation(); sum_node& c = *this; task* b = c.create_child(Range(my_range,split()),*my_left_sum,my_right,my_left_sum,my_stuff_last); task* a = my_left_is_final ? NULL : c.create_child(my_range,*my_body,my_left,my_incoming,NULL); set_ref_count( (a!=NULL)+(b!=NULL) ); my_body = NULL; if( a ) spawn(*b); else a = b; return a; } else { return NULL; } } template friend class start_scan; template friend class finish_scan; }; //! Combine partial results /** @ingroup algorithms */ template class finish_scan: public task { typedef sum_node sum_node_type; typedef final_sum final_sum_type; final_sum_type** const my_sum; sum_node_type*& my_return_slot; public: final_sum_type* my_right_zombie; sum_node_type& my_result; /*override*/ task* execute() { __TBB_ASSERT( my_result.ref_count()==(my_result.my_left!=NULL)+(my_result.my_right!=NULL), NULL ); if( my_result.my_left ) my_result.my_left_is_final = false; if( my_right_zombie && my_sum ) ((*my_sum)->my_body).reverse_join(my_result.my_left_sum->my_body); __TBB_ASSERT( !my_return_slot, NULL ); if( my_right_zombie || my_result.my_right ) { my_return_slot = &my_result; } else { destroy( my_result ); } if( my_right_zombie && !my_sum && !my_result.my_right ) { destroy(*my_right_zombie); my_right_zombie = NULL; } return NULL; } finish_scan( sum_node_type*& return_slot_, final_sum_type** sum_, sum_node_type& result_ ) : my_sum(sum_), my_return_slot(return_slot_), my_right_zombie(NULL), my_result(result_) { __TBB_ASSERT( !my_return_slot, NULL ); } }; //! Initial task to split the work /** @ingroup algorithms */ template class start_scan: public task { typedef sum_node sum_node_type; typedef final_sum final_sum_type; final_sum_type* my_body; /** Non-null if caller is requesting total. */ final_sum_type** my_sum; sum_node_type** my_return_slot; /** Null if computing root. */ sum_node_type* my_parent_sum; bool my_is_final; bool my_is_right_child; Range my_range; typename Partitioner::partition_type my_partition; /*override*/ task* execute(); public: start_scan( sum_node_type*& return_slot_, start_scan& parent_, sum_node_type* parent_sum_ ) : my_body(parent_.my_body), my_sum(parent_.my_sum), my_return_slot(&return_slot_), my_parent_sum(parent_sum_), my_is_final(parent_.my_is_final), my_is_right_child(false), my_range(parent_.my_range,split()), my_partition(parent_.my_partition,split()) { __TBB_ASSERT( !*my_return_slot, NULL ); } start_scan( sum_node_type*& return_slot_, const Range& range_, final_sum_type& body_, const Partitioner& partitioner_) : my_body(&body_), my_sum(NULL), my_return_slot(&return_slot_), my_parent_sum(NULL), my_is_final(true), my_is_right_child(false), my_range(range_), my_partition(partitioner_) { __TBB_ASSERT( !*my_return_slot, NULL ); } static void run( const Range& range_, Body& body_, const Partitioner& partitioner_ ) { if( !range_.empty() ) { typedef internal::start_scan start_pass1_type; internal::sum_node* root = NULL; typedef internal::final_sum final_sum_type; final_sum_type* temp_body = new(task::allocate_root()) final_sum_type( body_ ); start_pass1_type& pass1 = *new(task::allocate_root()) start_pass1_type( /*my_return_slot=*/root, range_, *temp_body, partitioner_ ); task::spawn_root_and_wait( pass1 ); if( root ) { root->my_body = temp_body; root->my_incoming = NULL; root->my_stuff_last = &body_; task::spawn_root_and_wait( *root ); } else { body_.assign(temp_body->my_body); temp_body->finish_construction( range_, NULL ); temp_body->destroy(*temp_body); } } } }; template task* start_scan::execute() { typedef internal::finish_scan finish_pass1_type; finish_pass1_type* p = my_parent_sum ? static_cast( parent() ) : NULL; // Inspecting p->result.left_sum would ordinarily be a race condition. // But we inspect it only if we are not a stolen task, in which case we // know that task assigning to p->result.left_sum has completed. bool treat_as_stolen = my_is_right_child && (is_stolen_task() || my_body!=p->my_result.my_left_sum); if( treat_as_stolen ) { // Invocation is for right child that has been really stolen or needs to be virtually stolen p->my_right_zombie = my_body = new( allocate_root() ) final_sum_type(my_body->my_body); my_is_final = false; } task* next_task = NULL; if( (my_is_right_child && !treat_as_stolen) || !my_range.is_divisible() || my_partition.should_execute_range(*this) ) { if( my_is_final ) (my_body->my_body)( my_range, final_scan_tag() ); else if( my_sum ) (my_body->my_body)( my_range, pre_scan_tag() ); if( my_sum ) *my_sum = my_body; __TBB_ASSERT( !*my_return_slot, NULL ); } else { sum_node_type* result; if( my_parent_sum ) result = new(allocate_additional_child_of(*my_parent_sum)) sum_node_type(my_range,/*my_left_is_final=*/my_is_final); else result = new(task::allocate_root()) sum_node_type(my_range,/*my_left_is_final=*/my_is_final); finish_pass1_type& c = *new( allocate_continuation()) finish_pass1_type(*my_return_slot,my_sum,*result); // Split off right child start_scan& b = *new( c.allocate_child() ) start_scan( /*my_return_slot=*/result->my_right, *this, result ); b.my_is_right_child = true; // Left child is recycling of *this. Must recycle this before spawning b, // otherwise b might complete and decrement c.ref_count() to zero, which // would cause c.execute() to run prematurely. recycle_as_child_of(c); c.set_ref_count(2); c.spawn(b); my_sum = &result->my_left_sum; my_return_slot = &result->my_left; my_is_right_child = false; next_task = this; my_parent_sum = result; __TBB_ASSERT( !*my_return_slot, NULL ); } return next_task; } } // namespace internal //! @endcond // Requirements on Range concept are documented in blocked_range.h /** \page parallel_scan_body_req Requirements on parallel_scan body Class \c Body implementing the concept of parallel_scan body must define: - \code Body::Body( Body&, split ); \endcode Splitting constructor. Split \c b so that \c this and \c b can accumulate separately - \code Body::~Body(); \endcode Destructor - \code void Body::operator()( const Range& r, pre_scan_tag ); \endcode Preprocess iterations for range \c r - \code void Body::operator()( const Range& r, final_scan_tag ); \endcode Do final processing for iterations of range \c r - \code void Body::reverse_join( Body& a ); \endcode Merge preprocessing state of \c a into \c this, where \c a was created earlier from \c b by b's splitting constructor **/ /** \name parallel_scan See also requirements on \ref range_req "Range" and \ref parallel_scan_body_req "parallel_scan Body". **/ //@{ //! Parallel prefix with default partitioner /** @ingroup algorithms **/ template void parallel_scan( const Range& range, Body& body ) { internal::start_scan::run(range,body,__TBB_DEFAULT_PARTITIONER()); } //! Parallel prefix with simple_partitioner /** @ingroup algorithms **/ template void parallel_scan( const Range& range, Body& body, const simple_partitioner& partitioner ) { internal::start_scan::run(range,body,partitioner); } //! Parallel prefix with auto_partitioner /** @ingroup algorithms **/ template void parallel_scan( const Range& range, Body& body, const auto_partitioner& partitioner ) { internal::start_scan::run(range,body,partitioner); } //@} } // namespace tbb #endif /* __TBB_parallel_scan_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_sort.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_sort_H #define __TBB_parallel_sort_H #include "parallel_for.h" #include "blocked_range.h" #include "internal/_range_iterator.h" #include #include #include namespace tbb { //! @cond INTERNAL namespace internal { //! Range used in quicksort to split elements into subranges based on a value. /** The split operation selects a splitter and places all elements less than or equal to the value in the first range and the remaining elements in the second range. @ingroup algorithms */ template class quick_sort_range: private no_assign { inline size_t median_of_three(const RandomAccessIterator &array, size_t l, size_t m, size_t r) const { return comp(array[l], array[m]) ? ( comp(array[m], array[r]) ? m : ( comp( array[l], array[r]) ? r : l ) ) : ( comp(array[r], array[m]) ? m : ( comp( array[r], array[l] ) ? r : l ) ); } inline size_t pseudo_median_of_nine( const RandomAccessIterator &array, const quick_sort_range &range ) const { size_t offset = range.size/8u; return median_of_three(array, median_of_three(array, 0, offset, offset*2), median_of_three(array, offset*3, offset*4, offset*5), median_of_three(array, offset*6, offset*7, range.size - 1) ); } public: static const size_t grainsize = 500; const Compare ∁ RandomAccessIterator begin; size_t size; quick_sort_range( RandomAccessIterator begin_, size_t size_, const Compare &comp_ ) : comp(comp_), begin(begin_), size(size_) {} bool empty() const {return size==0;} bool is_divisible() const {return size>=grainsize;} quick_sort_range( quick_sort_range& range, split ) : comp(range.comp) { using std::swap; RandomAccessIterator array = range.begin; RandomAccessIterator key0 = range.begin; size_t m = pseudo_median_of_nine(array, range); if (m) swap ( array[0], array[m] ); size_t i=0; size_t j=range.size; // Partition interval [i+1,j-1] with key *key0. for(;;) { __TBB_ASSERT( i class quick_sort_pretest_body : internal::no_assign { const Compare ∁ public: quick_sort_pretest_body(const Compare &_comp) : comp(_comp) {} void operator()( const blocked_range& range ) const { task &my_task = task::self(); RandomAccessIterator my_end = range.end(); int i = 0; for (RandomAccessIterator k = range.begin(); k != my_end; ++k, ++i) { if ( i%64 == 0 && my_task.is_cancelled() ) break; // The k-1 is never out-of-range because the first chunk starts at begin+serial_cutoff+1 if ( comp( *(k), *(k-1) ) ) { my_task.cancel_group_execution(); break; } } } }; #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Body class used to sort elements in a range that is smaller than the grainsize. /** @ingroup algorithms */ template struct quick_sort_body { void operator()( const quick_sort_range& range ) const { //SerialQuickSort( range.begin, range.size, range.comp ); std::sort( range.begin, range.begin + range.size, range.comp ); } }; //! Wrapper method to initiate the sort by calling parallel_for. /** @ingroup algorithms */ template void parallel_quick_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp ) { #if __TBB_TASK_GROUP_CONTEXT task_group_context my_context; const int serial_cutoff = 9; __TBB_ASSERT( begin + serial_cutoff < end, "min_parallel_size is smaller than serial cutoff?" ); RandomAccessIterator k; for ( k = begin ; k != begin + serial_cutoff; ++k ) { if ( comp( *(k+1), *k ) ) { goto do_parallel_quick_sort; } } parallel_for( blocked_range(k+1, end), quick_sort_pretest_body(comp), auto_partitioner(), my_context); if (my_context.is_group_execution_cancelled()) do_parallel_quick_sort: #endif /* __TBB_TASK_GROUP_CONTEXT */ parallel_for( quick_sort_range(begin, end-begin, comp ), quick_sort_body(), auto_partitioner() ); } } // namespace internal //! @endcond /** \page parallel_sort_iter_req Requirements on iterators for parallel_sort Requirements on value type \c T of \c RandomAccessIterator for \c parallel_sort: - \code void swap( T& x, T& y ) \endcode Swaps \c x and \c y - \code bool Compare::operator()( const T& x, const T& y ) \endcode True if x comes before y; **/ /** \name parallel_sort See also requirements on \ref parallel_sort_iter_req "iterators for parallel_sort". **/ //@{ //! Sorts the data in [begin,end) using the given comparator /** The compare function object is used for all comparisons between elements during sorting. The compare object must define a bool operator() function. @ingroup algorithms **/ template void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp) { const int min_parallel_size = 500; if( end > begin ) { if (end - begin < min_parallel_size) { std::sort(begin, end, comp); } else { internal::parallel_quick_sort(begin, end, comp); } } } //! Sorts the data in [begin,end) with a default comparator \c std::less /** @ingroup algorithms **/ template inline void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end ) { parallel_sort( begin, end, std::less< typename std::iterator_traits::value_type >() ); } //! Sorts the data in rng using the given comparator /** @ingroup algorithms **/ template void parallel_sort(Range& rng, const Compare& comp) { parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng), comp); } //! Sorts the data in const rng using the given comparator /** @ingroup algorithms **/ template void parallel_sort(const Range& rng, const Compare& comp) { parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng), comp); } //! Sorts the data in rng with a default comparator \c std::less /** @ingroup algorithms **/ template void parallel_sort(Range& rng) { parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng)); } //! Sorts the data in const rng with a default comparator \c std::less /** @ingroup algorithms **/ template void parallel_sort(const Range& rng) { parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng)); } //! Sorts the data in the range \c [begin,end) with a default comparator \c std::less /** @ingroup algorithms **/ template inline void parallel_sort( T * begin, T * end ) { parallel_sort( begin, end, std::less< T >() ); } //@} } // namespace tbb #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/parallel_while.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_parallel_while #define __TBB_parallel_while #include "task.h" #include namespace tbb { template class parallel_while; //! @cond INTERNAL namespace internal { template class while_task; //! For internal use only. /** Executes one iteration of a while. @ingroup algorithms */ template class while_iteration_task: public task { const Body& my_body; typename Body::argument_type my_value; /*override*/ task* execute() { my_body(my_value); return NULL; } while_iteration_task( const typename Body::argument_type& value, const Body& body ) : my_body(body), my_value(value) {} template friend class while_group_task; friend class tbb::parallel_while; }; //! For internal use only /** Unpacks a block of iterations. @ingroup algorithms */ template class while_group_task: public task { static const size_t max_arg_size = 4; const Body& my_body; size_t size; typename Body::argument_type my_arg[max_arg_size]; while_group_task( const Body& body ) : my_body(body), size(0) {} /*override*/ task* execute() { typedef while_iteration_task iteration_type; __TBB_ASSERT( size>0, NULL ); task_list list; task* t; size_t k=0; for(;;) { t = new( allocate_child() ) iteration_type(my_arg[k],my_body); if( ++k==size ) break; list.push_back(*t); } set_ref_count(int(k+1)); spawn(list); spawn_and_wait_for_all(*t); return NULL; } template friend class while_task; }; //! For internal use only. /** Gets block of iterations from a stream and packages them into a while_group_task. @ingroup algorithms */ template class while_task: public task { Stream& my_stream; const Body& my_body; empty_task& my_barrier; /*override*/ task* execute() { typedef while_group_task block_type; block_type& t = *new( allocate_additional_child_of(my_barrier) ) block_type(my_body); size_t k=0; while( my_stream.pop_if_present(t.my_arg[k]) ) { if( ++k==block_type::max_arg_size ) { // There might be more iterations. recycle_to_reexecute(); break; } } if( k==0 ) { destroy(t); return NULL; } else { t.size = k; return &t; } } while_task( Stream& stream, const Body& body, empty_task& barrier ) : my_stream(stream), my_body(body), my_barrier(barrier) {} friend class tbb::parallel_while; }; } // namespace internal //! @endcond //! Parallel iteration over a stream, with optional addition of more work. /** The Body b has the requirement: \n "b(v)" \n "b.argument_type" \n where v is an argument_type @ingroup algorithms */ template class parallel_while: internal::no_copy { public: //! Construct empty non-running parallel while. parallel_while() : my_body(NULL), my_barrier(NULL) {} //! Destructor cleans up data members before returning. ~parallel_while() { if( my_barrier ) { my_barrier->destroy(*my_barrier); my_barrier = NULL; } } //! Type of items typedef typename Body::argument_type value_type; //! Apply body.apply to each item in the stream. /** A Stream s has the requirements \n "S::value_type" \n "s.pop_if_present(value) is convertible to bool */ template void run( Stream& stream, const Body& body ); //! Add a work item while running. /** Should be executed only by body.apply or a thread spawned therefrom. */ void add( const value_type& item ); private: const Body* my_body; empty_task* my_barrier; }; template template void parallel_while::run( Stream& stream, const Body& body ) { using namespace internal; empty_task& barrier = *new( task::allocate_root() ) empty_task(); my_body = &body; my_barrier = &barrier; my_barrier->set_ref_count(2); while_task& w = *new( my_barrier->allocate_child() ) while_task( stream, body, barrier ); my_barrier->spawn_and_wait_for_all(w); my_barrier->destroy(*my_barrier); my_barrier = NULL; my_body = NULL; } template void parallel_while::add( const value_type& item ) { __TBB_ASSERT(my_barrier,"attempt to add to parallel_while that is not running"); typedef internal::while_iteration_task iteration_type; iteration_type& i = *new( task::allocate_additional_child_of(*my_barrier) ) iteration_type(item,*my_body); task::self().spawn( i ); } } // namespace #endif /* __TBB_parallel_while */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/partitioner.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_partitioner_H #define __TBB_partitioner_H #ifndef __TBB_INITIAL_CHUNKS // initial task divisions per thread #define __TBB_INITIAL_CHUNKS 2 #endif #ifndef __TBB_RANGE_POOL_CAPACITY // maximum number of elements in range pool #define __TBB_RANGE_POOL_CAPACITY 8 #endif #ifndef __TBB_INIT_DEPTH // initial value for depth of range pool #define __TBB_INIT_DEPTH 5 #endif #ifndef __TBB_DEMAND_DEPTH_ADD // when imbalance is found range splits this value times more #define __TBB_DEMAND_DEPTH_ADD 2 #endif #ifndef __TBB_STATIC_THRESHOLD // necessary number of clocks for the work to be distributed among all tasks #define __TBB_STATIC_THRESHOLD 40000 #endif #if __TBB_DEFINE_MIC #define __TBB_NONUNIFORM_TASK_CREATION 1 #ifdef __TBB_machine_time_stamp #define __TBB_USE_MACHINE_TIME_STAMPS 1 #define __TBB_task_duration() __TBB_STATIC_THRESHOLD #endif // __TBB_machine_time_stamp #endif // __TBB_DEFINE_MIC #include "task.h" #include "aligned_space.h" #include "atomic.h" #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings #pragma warning (push) #pragma warning (disable: 4244) #endif namespace tbb { class auto_partitioner; class simple_partitioner; class affinity_partitioner; namespace interface7 { namespace internal { class affinity_partition_type; } } namespace internal { //< @cond INTERNAL size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor(); //! Defines entry point for affinity partitioner into tbb run-time library. class affinity_partitioner_base_v3: no_copy { friend class tbb::affinity_partitioner; friend class tbb::interface7::internal::affinity_partition_type; //! Array that remembers affinities of tree positions to affinity_id. /** NULL if my_size==0. */ affinity_id* my_array; //! Number of elements in my_array. size_t my_size; //! Zeros the fields. affinity_partitioner_base_v3() : my_array(NULL), my_size(0) {} //! Deallocates my_array. ~affinity_partitioner_base_v3() {resize(0);} //! Resize my_array. /** Retains values if resulting size is the same. */ void __TBB_EXPORTED_METHOD resize( unsigned factor ); }; //! Provides backward-compatible methods for partition objects without affinity. class partition_type_base { public: void set_affinity( task & ) {} void note_affinity( task::affinity_id ) {} task* continue_after_execute_range() {return NULL;} bool decide_whether_to_delay() {return false;} void spawn_or_delay( bool, task& b ) { task::spawn(b); } }; template class start_scan; } //< namespace internal @endcond namespace serial { namespace interface7 { template class start_for; } } namespace interface7 { //! @cond INTERNAL namespace internal { using namespace tbb::internal; template class start_for; template class start_reduce; //! Join task node that contains shared flag for stealing feedback class flag_task: public task { public: tbb::atomic my_child_stolen; flag_task() { my_child_stolen = false; } task* execute() { return NULL; } static void mark_task_stolen(task &t) { tbb::atomic &flag = static_cast(t.parent())->my_child_stolen; #if TBB_USE_THREADING_TOOLS // Threading tools respect lock prefix but report false-positive data-race via plain store flag.fetch_and_store(true); #else flag = true; #endif //TBB_USE_THREADING_TOOLS } static bool is_peer_stolen(task &t) { return static_cast(t.parent())->my_child_stolen; } }; //! Depth is a relative depth of recursive division inside a range pool. Relative depth allows //! infinite absolute depth of the recursion for heavily unbalanced workloads with range represented //! by a number that cannot fit into machine word. typedef unsigned char depth_t; //! Range pool stores ranges of type T in a circular buffer with MaxCapacity template class range_vector { depth_t my_head; depth_t my_tail; depth_t my_size; depth_t my_depth[MaxCapacity]; // relative depths of stored ranges tbb::aligned_space my_pool; public: //! initialize via first range in pool range_vector(const T& elem) : my_head(0), my_tail(0), my_size(1) { my_depth[0] = 0; new( static_cast(my_pool.begin()) ) T(elem);//TODO: std::move? } ~range_vector() { while( !empty() ) pop_back(); } bool empty() const { return my_size == 0; } depth_t size() const { return my_size; } //! Populates range pool via ranges up to max depth or while divisible //! max_depth starts from 0, e.g. value 2 makes 3 ranges in the pool up to two 1/4 pieces void split_to_fill(depth_t max_depth) { while( my_size < MaxCapacity && is_divisible(max_depth) ) { depth_t prev = my_head; my_head = (my_head + 1) % MaxCapacity; new(my_pool.begin()+my_head) T(my_pool.begin()[prev]); // copy TODO: std::move? my_pool.begin()[prev].~T(); // instead of assignment new(my_pool.begin()+prev) T(my_pool.begin()[my_head], split()); // do 'inverse' split my_depth[my_head] = ++my_depth[prev]; my_size++; } } void pop_back() { __TBB_ASSERT(my_size > 0, "range_vector::pop_back() with empty size"); my_pool.begin()[my_head].~T(); my_size--; my_head = (my_head + MaxCapacity - 1) % MaxCapacity; } void pop_front() { __TBB_ASSERT(my_size > 0, "range_vector::pop_front() with empty size"); my_pool.begin()[my_tail].~T(); my_size--; my_tail = (my_tail + 1) % MaxCapacity; } T& back() { __TBB_ASSERT(my_size > 0, "range_vector::back() with empty size"); return my_pool.begin()[my_head]; } T& front() { __TBB_ASSERT(my_size > 0, "range_vector::front() with empty size"); return my_pool.begin()[my_tail]; } //! similarly to front(), returns depth of the first range in the pool depth_t front_depth() { __TBB_ASSERT(my_size > 0, "range_vector::front_depth() with empty size"); return my_depth[my_tail]; } depth_t back_depth() { __TBB_ASSERT(my_size > 0, "range_vector::back_depth() with empty size"); return my_depth[my_head]; } bool is_divisible(depth_t max_depth) { return back_depth() < max_depth && back().is_divisible(); } }; //! Provides default methods for partition objects and common algorithm blocks. template struct partition_type_base { typedef split split_type; // decision makers void set_affinity( task & ) {} void note_affinity( task::affinity_id ) {} bool check_being_stolen(task &) { return false; } // part of old should_execute_range() bool check_for_demand(task &) { return false; } bool is_divisible() { return true; } // part of old should_execute_range() depth_t max_depth() { return 0; } void align_depth(depth_t) { } template split_type get_split() { return split(); } // common function blocks Partition& self() { return *static_cast(this); } // CRTP helper template void execute(StartType &start, Range &range) { // The algorithm in a few words ([]-denotes calls to decision methods of partitioner): // [If this task is stolen, adjust depth and divisions if necessary, set flag]. // If range is divisible { // Spread the work while [initial divisions left]; // Create trap task [if necessary]; // } // If not divisible or [max depth is reached], execute, else do the range pool part if ( range.is_divisible() ) { if ( self().is_divisible() ) { do { // split until is divisible typename Partition::split_type split_obj = self().template get_split(); start.offer_work( split_obj ); } while ( range.is_divisible() && self().is_divisible() ); } } if( !range.is_divisible() || !self().max_depth() ) start.run_body( range ); // simple partitioner goes always here else { // do range pool internal::range_vector range_pool(range); do { range_pool.split_to_fill(self().max_depth()); // fill range pool if( self().check_for_demand( start ) ) { if( range_pool.size() > 1 ) { start.offer_work( range_pool.front(), range_pool.front_depth() ); range_pool.pop_front(); continue; } if( range_pool.is_divisible(self().max_depth()) ) // was not enough depth to fork a task continue; // note: next split_to_fill() should split range at least once } start.run_body( range_pool.back() ); range_pool.pop_back(); } while( !range_pool.empty() && !start.is_cancelled() ); } } }; //! Provides default methods for auto (adaptive) partition objects. template struct adaptive_partition_type_base : partition_type_base { size_t my_divisor; depth_t my_max_depth; adaptive_partition_type_base() : my_max_depth(__TBB_INIT_DEPTH) { my_divisor = tbb::internal::get_initial_auto_partitioner_divisor() / 4; __TBB_ASSERT(my_divisor, "initial value of get_initial_auto_partitioner_divisor() is not valid"); } adaptive_partition_type_base(adaptive_partition_type_base &src, split) { my_max_depth = src.my_max_depth; #if TBB_USE_ASSERT size_t old_divisor = src.my_divisor; #endif #if __TBB_INITIAL_TASK_IMBALANCE if( src.my_divisor <= 1 ) my_divisor = 0; else my_divisor = src.my_divisor = (src.my_divisor + 1u) / 2u; #else my_divisor = src.my_divisor / 2u; src.my_divisor = src.my_divisor - my_divisor; // TODO: check the effect separately if (my_divisor) src.my_max_depth += static_cast(__TBB_Log2(src.my_divisor / my_divisor)); #endif // For affinity_partitioner, my_divisor indicates the number of affinity array indices the task reserves. // A task which has only one index must produce the right split without reserved index in order to avoid // it to be overwritten in note_affinity() of the created (right) task. // I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order) __TBB_ASSERT( (old_divisor <= 1 && my_divisor == 0) || (old_divisor > 1 && my_divisor != 0), NULL); } adaptive_partition_type_base(adaptive_partition_type_base &src, const proportional_split& split_obj) { my_max_depth = src.my_max_depth; my_divisor = size_t(float(src.my_divisor) * float(split_obj.right()) / float(split_obj.left() + split_obj.right())); src.my_divisor -= my_divisor; } bool check_being_stolen( task &t) { // part of old should_execute_range() if( !my_divisor ) { // if not from the top P tasks of binary tree my_divisor = 1; // TODO: replace by on-stack flag (partition_state's member)? if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // runs concurrently with the left task #if TBB_USE_EXCEPTIONS // RTTI is available, check whether the cast is valid __TBB_ASSERT(dynamic_cast(t.parent()), 0); // correctness of the cast relies on avoiding the root task for which: // - initial value of my_divisor != 0 (protected by separate assertion) // - is_stolen_task() always returns false for the root task. #endif flag_task::mark_task_stolen(t); if( !my_max_depth ) my_max_depth++; my_max_depth += __TBB_DEMAND_DEPTH_ADD; return true; } } return false; } void align_depth(depth_t base) { __TBB_ASSERT(base <= my_max_depth, 0); my_max_depth -= base; } depth_t max_depth() { return my_max_depth; } }; //! Helper that enables one or the other code branches (see example in is_range_divisible_in_proportion) template struct enable_if { typedef T type; }; template struct enable_if { }; //! Class determines whether template parameter has static boolean //! constant 'is_divisible_in_proportion' initialized with value of //! 'true' or not. /** If template parameter has such field that has been initialized * with non-zero value then class field will be set to 'true', * otherwise - 'false' */ template class is_range_divisible_in_proportion { private: typedef char yes[1]; typedef char no [2]; template static yes& decide(typename enable_if::type *); template static no& decide(...); public: // equals to 'true' if and only if static const variable 'is_divisible_in_proportion' of template parameter // initialized with the value of 'true' static const bool value = (sizeof(decide(0)) == sizeof(yes)); }; //! Provides default methods for affinity (adaptive) partition objects. class affinity_partition_type : public adaptive_partition_type_base { static const unsigned factor_power = 4; static const unsigned factor = 1<(), my_delay(start) #ifdef __TBB_USE_MACHINE_TIME_STAMPS , my_dst_tsc(0) #endif { __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" ); my_divisor *= factor; ap.resize(factor); my_array = ap.my_array; my_begin = 0; my_max_depth = factor_power + 1; // the first factor_power ranges will be spawned, and >=1 ranges should be left __TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 ); } affinity_partition_type(affinity_partition_type& p, split) : adaptive_partition_type_base(p, split()), my_delay(pass), #ifdef __TBB_USE_MACHINE_TIME_STAMPS my_dst_tsc(0), #endif my_array(p.my_array) { // the sum of the divisors represents original value of p.my_divisor before split __TBB_ASSERT(my_divisor + p.my_divisor <= factor, NULL); my_begin = p.my_begin + p.my_divisor; } affinity_partition_type(affinity_partition_type& p, const proportional_split& split_obj) : adaptive_partition_type_base(p, split_obj), my_delay(start), #ifdef __TBB_USE_MACHINE_TIME_STAMPS my_dst_tsc(0), #endif my_array(p.my_array) { size_t total_divisor = my_divisor + p.my_divisor; __TBB_ASSERT(total_divisor % factor == 0, NULL); my_divisor = (my_divisor + factor/2) & (0u - factor); if (!my_divisor) my_divisor = factor; else if (my_divisor == total_divisor) my_divisor = total_divisor - factor; p.my_divisor = total_divisor - my_divisor; __TBB_ASSERT(my_divisor && p.my_divisor, NULL); my_begin = p.my_begin + p.my_divisor; } void set_affinity( task &t ) { if( my_divisor ) { if( !my_array[my_begin] ) { // TODO: consider code reuse for static_paritioner my_array[my_begin] = affinity_id(my_begin / factor + 1); } t.set_affinity( my_array[my_begin] ); } } void note_affinity( task::affinity_id id ) { if( my_divisor ) my_array[my_begin] = id; } bool check_for_demand( task &t ) { if( pass == my_delay ) { if( my_divisor > 1 ) // produce affinitized tasks while they have slot in array return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more else if( my_divisor && my_max_depth ) { // make balancing task my_divisor = 0; // once for each task; depth will be decreased in align_depth() return true; } else if( flag_task::is_peer_stolen(t) ) { my_max_depth += __TBB_DEMAND_DEPTH_ADD; return true; } } else if( start == my_delay ) { #ifndef __TBB_USE_MACHINE_TIME_STAMPS my_delay = pass; #else my_dst_tsc = __TBB_machine_time_stamp() + __TBB_task_duration(); my_delay = run; } else if( run == my_delay ) { if( __TBB_machine_time_stamp() < my_dst_tsc ) { __TBB_ASSERT(my_max_depth > 0, NULL); return false; } my_delay = pass; return true; #endif // __TBB_USE_MACHINE_TIME_STAMPS } return false; } bool is_divisible() { // part of old should_execute_range() return my_divisor > factor; } #if _MSC_VER && !defined(__INTEL_COMPILER) // Suppress "conditional expression is constant" warning. #pragma warning( push ) #pragma warning( disable: 4127 ) #endif template split_type get_split() { if (is_range_divisible_in_proportion::value) { size_t size = my_divisor / factor; #if __TBB_NONUNIFORM_TASK_CREATION size_t right = (size + 2) / 3; #else size_t right = size / 2; #endif size_t left = size - right; return split_type(left, right); } else { return split_type(1, 1); } } #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning( pop ) #endif // warning 4127 is back static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY; }; class auto_partition_type: public adaptive_partition_type_base { public: auto_partition_type( const auto_partitioner& ) { my_divisor *= __TBB_INITIAL_CHUNKS; } auto_partition_type( auto_partition_type& src, split) : adaptive_partition_type_base(src, split()) {} bool is_divisible() { // part of old should_execute_range() if( my_divisor > 1 ) return true; if( my_divisor && my_max_depth ) { // can split the task. TODO: on-stack flag instead // keep same fragmentation while splitting for the local task pool my_max_depth--; my_divisor = 0; // decrease max_depth once per task return true; } else return false; } bool check_for_demand(task &t) { if( flag_task::is_peer_stolen(t) ) { my_max_depth += __TBB_DEMAND_DEPTH_ADD; return true; } else return false; } static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY; }; class simple_partition_type: public partition_type_base { public: simple_partition_type( const simple_partitioner& ) {} simple_partition_type( const simple_partition_type&, split ) {} //! simplified algorithm template void execute(StartType &start, Range &range) { split_type split_obj = split(); // start.offer_work accepts split_type as reference while( range.is_divisible() ) start.offer_work( split_obj ); start.run_body( range ); } //static const unsigned range_pool_size = 1; - not necessary because execute() is overridden }; //! Backward-compatible partition for auto and affinity partition objects. class old_auto_partition_type: public tbb::internal::partition_type_base { size_t num_chunks; static const size_t VICTIM_CHUNKS = 4; public: bool should_execute_range(const task &t) { if( num_chunks friend class serial::interface7::start_for; template friend class interface7::internal::start_for; template friend class interface7::internal::start_reduce; template friend class internal::start_scan; // backward compatibility class partition_type: public internal::partition_type_base { public: bool should_execute_range(const task& ) {return false;} partition_type( const simple_partitioner& ) {} partition_type( const partition_type&, split ) {} }; // new implementation just extends existing interface typedef interface7::internal::simple_partition_type task_partition_type; // TODO: consider to make split_type public typedef interface7::internal::simple_partition_type::split_type split_type; }; //! An auto partitioner /** The range is initial divided into several large chunks. Chunks are further subdivided into smaller pieces if demand detected and they are divisible. @ingroup algorithms */ class auto_partitioner { public: auto_partitioner() {} private: template friend class serial::interface7::start_for; template friend class interface7::internal::start_for; template friend class interface7::internal::start_reduce; template friend class internal::start_scan; // backward compatibility typedef interface7::internal::old_auto_partition_type partition_type; // new implementation just extends existing interface typedef interface7::internal::auto_partition_type task_partition_type; // TODO: consider to make split_type public typedef interface7::internal::auto_partition_type::split_type split_type; }; //! An affinity partitioner class affinity_partitioner: internal::affinity_partitioner_base_v3 { public: affinity_partitioner() {} private: template friend class serial::interface7::start_for; template friend class interface7::internal::start_for; template friend class interface7::internal::start_reduce; template friend class internal::start_scan; // backward compatibility - for parallel_scan only typedef interface7::internal::old_auto_partition_type partition_type; // new implementation just extends existing interface typedef interface7::internal::affinity_partition_type task_partition_type; // TODO: consider to make split_type public typedef interface7::internal::affinity_partition_type::split_type split_type; }; } // namespace tbb #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4244 is back #undef __TBB_INITIAL_CHUNKS #undef __TBB_RANGE_POOL_CAPACITY #undef __TBB_INIT_DEPTH #endif /* __TBB_partitioner_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/pipeline.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/pipeline.h" #include "tbb/spin_mutex.h" #include "tbb/cache_aligned_allocator.h" #include "itt_notify.h" #include "semaphore.h" #include "tls.h" // for parallel filters that do not use NULL as end_of_input namespace tbb { namespace internal { //! This structure is used to store task information in a input buffer struct task_info { void* my_object; //! Invalid unless a task went through an ordered stage. Token my_token; //! False until my_token is set. bool my_token_ready; //! True if my_object is valid. bool is_valid; //! Set to initial state (no object, no token) void reset() { my_object = NULL; my_token = 0; my_token_ready = false; is_valid = false; } }; //! A buffer of input items for a filter. /** Each item is a task_info, inserted into a position in the buffer corresponding to a Token. */ class input_buffer : no_copy { friend class tbb::internal::pipeline_root_task; friend class tbb::filter; friend class tbb::thread_bound_filter; friend class tbb::internal::stage_task; friend class tbb::pipeline; typedef Token size_type; //! Array of deferred tasks that cannot yet start executing. task_info* array; //! for thread-bound filter, semaphore for waiting, NULL otherwise. semaphore* my_sem; //! Size of array /** Always 0 or a power of 2 */ size_type array_size; //! Lowest token that can start executing. /** All prior Token have already been seen. */ Token low_token; //! Serializes updates. spin_mutex array_mutex; //! Resize "array". /** Caller is responsible to acquiring a lock on "array_mutex". */ void grow( size_type minimum_size ); //! Initial size for "array" /** Must be a power of 2 */ static const size_type initial_buffer_size = 4; //! Used for out of order buffer, and for assigning my_token if is_ordered and my_token not already assigned Token high_token; //! True for ordered filter, false otherwise. bool is_ordered; //! True for thread-bound filter, false otherwise. bool is_bound; //! for parallel filters that accepts NULLs, thread-local flag for reaching end_of_input typedef basic_tls end_of_input_tls_t; end_of_input_tls_t end_of_input_tls; bool end_of_input_tls_allocated; // no way to test pthread creation of TLS void create_sema(size_t initial_tokens) { __TBB_ASSERT(!my_sem,NULL); my_sem = new internal::semaphore(initial_tokens); } void free_sema() { __TBB_ASSERT(my_sem,NULL); delete my_sem; } void sema_P() { __TBB_ASSERT(my_sem,NULL); my_sem->P(); } void sema_V() { __TBB_ASSERT(my_sem,NULL); my_sem->V(); } public: //! Construct empty buffer. input_buffer( bool is_ordered_, bool is_bound_ ) : array(NULL), my_sem(NULL), array_size(0), low_token(0), high_token(0), is_ordered(is_ordered_), is_bound(is_bound_), end_of_input_tls_allocated(false) { grow(initial_buffer_size); __TBB_ASSERT( array, NULL ); if(is_bound) create_sema(0); } //! Destroy the buffer. ~input_buffer() { __TBB_ASSERT( array, NULL ); cache_aligned_allocator().deallocate(array,array_size); poison_pointer( array ); if(my_sem) { free_sema(); } if(end_of_input_tls_allocated) { destroy_my_tls(); } } //! Put a token into the buffer. /** If task information was placed into buffer, returns true; otherwise returns false, informing the caller to create and spawn a task. If input buffer owned by thread-bound filter and the item at low_token was not valid, issue a V() If the input_buffer is owned by a successor to a thread-bound filter, the force_put parameter should be true to ensure the token is inserted in the buffer. */ bool put_token( task_info& info_, bool force_put = false ) { { info_.is_valid = true; spin_mutex::scoped_lock lock( array_mutex ); Token token; bool was_empty = !array[low_token&(array_size-1)].is_valid; if( is_ordered ) { if( !info_.my_token_ready ) { info_.my_token = high_token++; info_.my_token_ready = true; } token = info_.my_token; } else token = high_token++; __TBB_ASSERT( (tokendiff_t)(token-low_token)>=0, NULL ); if( token!=low_token || is_bound || force_put ) { // Trying to put token that is beyond low_token. // Need to wait until low_token catches up before dispatching. if( token-low_token>=array_size ) grow( token-low_token+1 ); ITT_NOTIFY( sync_releasing, this ); array[token&(array_size-1)] = info_; if(was_empty && is_bound) { sema_V(); } return true; } } return false; } //! Note that processing of a token is finished. /** Fires up processing of the next token, if processing was deferred. */ // Using template to avoid explicit dependency on stage_task // this is only called for serial filters, and is the reason for the // advance parameter in return_item (we're incrementing low_token here.) // Non-TBF serial stages don't advance the token at the start because the presence // of the current token in the buffer keeps another stage from being spawned. template void note_done( Token token, StageTask& spawner ) { task_info wakee; wakee.reset(); { spin_mutex::scoped_lock lock( array_mutex ); if( !is_ordered || token==low_token ) { // Wake the next task task_info& item = array[++low_token & (array_size-1)]; ITT_NOTIFY( sync_acquired, this ); wakee = item; item.is_valid = false; } } if( wakee.is_valid ) spawner.spawn_stage_task(wakee); } #if __TBB_TASK_GROUP_CONTEXT //! The method destroys all data in filters to prevent memory leaks void clear( filter* my_filter ) { long t=low_token; for( size_type i=0; ifinalize(temp.my_object); temp.is_valid = false; } } } #endif //! return an item, invalidate the queued item, but only advance if advance // advance == true for parallel filters. If the filter is serial, leave the // item in the buffer to keep another stage from being spawned. bool return_item(task_info& info, bool advance) { spin_mutex::scoped_lock lock( array_mutex ); task_info& item = array[low_token&(array_size-1)]; ITT_NOTIFY( sync_acquired, this ); if( item.is_valid ) { info = item; item.is_valid = false; if (advance) low_token++; return true; } return false; } //! true if the current low_token is valid. bool has_item() { spin_mutex::scoped_lock lock(array_mutex); return array[low_token&(array_size -1)].is_valid; } // end_of_input signal for parallel_pipeline, parallel input filters with 0 tokens allowed. void create_my_tls() { int status = end_of_input_tls.create(); if(status) handle_perror(status, "TLS not allocated for filter"); end_of_input_tls_allocated = true; } void destroy_my_tls() { int status = end_of_input_tls.destroy(); if(status) handle_perror(status, "Failed to destroy filter TLS"); } bool my_tls_end_of_input() { return end_of_input_tls.get() != 0; } void set_my_tls_end_of_input() { end_of_input_tls.set(1); } }; void input_buffer::grow( size_type minimum_size ) { size_type old_size = array_size; size_type new_size = old_size ? 2*old_size : initial_buffer_size; while( new_size().allocate(new_size); task_info* old_array = array; for( size_type i=0; i().deallocate(old_array,old_size); } class stage_task: public task, public task_info { private: friend class tbb::pipeline; pipeline& my_pipeline; filter* my_filter; //! True if this task has not yet read the input. bool my_at_start; public: //! Construct stage_task for first stage in a pipeline. /** Such a stage has not read any input yet. */ stage_task( pipeline& pipeline ) : my_pipeline(pipeline), my_filter(pipeline.filter_list), my_at_start(true) { task_info::reset(); } //! Construct stage_task for a subsequent stage in a pipeline. stage_task( pipeline& pipeline, filter* filter_, const task_info& info ) : task_info(info), my_pipeline(pipeline), my_filter(filter_), my_at_start(false) {} //! Roughly equivalent to the constructor of input stage task void reset() { task_info::reset(); my_filter = my_pipeline.filter_list; my_at_start = true; } //! The virtual task execution method /*override*/ task* execute(); #if __TBB_TASK_GROUP_CONTEXT ~stage_task() { if (my_filter && my_object && (my_filter->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(4)) { __TBB_ASSERT(is_cancelled(), "Trying to finalize the task that wasn't cancelled"); my_filter->finalize(my_object); my_object = NULL; } } #endif // __TBB_TASK_GROUP_CONTEXT //! Creates and spawns stage_task from task_info void spawn_stage_task(const task_info& info) { stage_task* clone = new (allocate_additional_child_of(*parent())) stage_task( my_pipeline, my_filter, info ); spawn(*clone); } }; task* stage_task::execute() { __TBB_ASSERT( !my_at_start || !my_object, NULL ); __TBB_ASSERT( !my_filter->is_bound(), NULL ); if( my_at_start ) { if( my_filter->is_serial() ) { my_object = (*my_filter)(my_object); if( my_object || ( my_filter->object_may_be_null() && !my_pipeline.end_of_input) ) { if( my_filter->is_ordered() ) { my_token = my_pipeline.token_counter++; // ideally, with relaxed semantics my_token_ready = true; } else if( (my_filter->my_filter_mode & my_filter->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { if( my_pipeline.has_thread_bound_filters ) my_pipeline.token_counter++; // ideally, with relaxed semantics } if( !my_filter->next_filter_in_pipeline ) { // we're only filter in pipeline reset(); goto process_another_stage; } else { ITT_NOTIFY( sync_releasing, &my_pipeline.input_tokens ); if( --my_pipeline.input_tokens>0 ) spawn( *new( allocate_additional_child_of(*parent()) ) stage_task( my_pipeline ) ); } } else { my_pipeline.end_of_input = true; return NULL; } } else /*not is_serial*/ { if( my_pipeline.end_of_input ) return NULL; if( (my_filter->my_filter_mode & my_filter->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { if( my_pipeline.has_thread_bound_filters ) my_pipeline.token_counter++; } ITT_NOTIFY( sync_releasing, &my_pipeline.input_tokens ); if( --my_pipeline.input_tokens>0 ) spawn( *new( allocate_additional_child_of(*parent()) ) stage_task( my_pipeline ) ); my_object = (*my_filter)(my_object); if( !my_object && (!my_filter->object_may_be_null() || my_filter->my_input_buffer->my_tls_end_of_input()) ) { my_pipeline.end_of_input = true; if( (my_filter->my_filter_mode & my_filter->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { if( my_pipeline.has_thread_bound_filters ) my_pipeline.token_counter--; // fix token_counter } return NULL; } } my_at_start = false; } else { my_object = (*my_filter)(my_object); if( my_filter->is_serial() ) my_filter->my_input_buffer->note_done(my_token, *this); } my_filter = my_filter->next_filter_in_pipeline; if( my_filter ) { // There is another filter to execute. if( my_filter->is_serial() ) { // The next filter must execute tokens in order if( my_filter->my_input_buffer->put_token(*this) ){ // Can't proceed with the same item if( my_filter->is_bound() ) { // Find the next non-thread-bound filter do { my_filter = my_filter->next_filter_in_pipeline; } while( my_filter && my_filter->is_bound() ); // Check if there is an item ready to process if( my_filter && my_filter->my_input_buffer->return_item(*this, !my_filter->is_serial())) goto process_another_stage; } my_filter = NULL; // To prevent deleting my_object twice if exception occurs return NULL; } } } else { // Reached end of the pipe. size_t ntokens_avail = ++my_pipeline.input_tokens; if(my_pipeline.filter_list->is_bound() ) { if(ntokens_avail == 1) { my_pipeline.filter_list->my_input_buffer->sema_V(); } return NULL; } if( ntokens_avail>1 // Only recycle if there is one available token || my_pipeline.end_of_input ) { return NULL; // No need to recycle for new input } ITT_NOTIFY( sync_acquired, &my_pipeline.input_tokens ); // Recycle as an input stage task. reset(); } process_another_stage: /* A semi-hackish way to reexecute the same task object immediately without spawning. recycle_as_continuation marks the task for future execution, and then 'this' pointer is returned to bypass spawning. */ recycle_as_continuation(); return this; } class pipeline_root_task: public task { pipeline& my_pipeline; bool do_segment_scanning; /*override*/ task* execute() { if( !my_pipeline.end_of_input ) if( !my_pipeline.filter_list->is_bound() ) if( my_pipeline.input_tokens > 0 ) { recycle_as_continuation(); set_ref_count(1); return new( allocate_child() ) stage_task( my_pipeline ); } if( do_segment_scanning ) { filter* current_filter = my_pipeline.filter_list->next_segment; /* first non-thread-bound filter that follows thread-bound one and may have valid items to process */ filter* first_suitable_filter = current_filter; while( current_filter ) { __TBB_ASSERT( !current_filter->is_bound(), "filter is thread-bound?" ); __TBB_ASSERT( current_filter->prev_filter_in_pipeline->is_bound(), "previous filter is not thread-bound?" ); if( !my_pipeline.end_of_input || current_filter->has_more_work()) { task_info info; info.reset(); if( current_filter->my_input_buffer->return_item(info, !current_filter->is_serial()) ) { set_ref_count(1); recycle_as_continuation(); return new( allocate_child() ) stage_task( my_pipeline, current_filter, info); } current_filter = current_filter->next_segment; if( !current_filter ) { if( !my_pipeline.end_of_input ) { recycle_as_continuation(); return this; } current_filter = first_suitable_filter; __TBB_Yield(); } } else { /* The preceding pipeline segment is empty. Fast-forward to the next post-TBF segment. */ first_suitable_filter = first_suitable_filter->next_segment; current_filter = first_suitable_filter; } } /* while( current_filter ) */ return NULL; } else { if( !my_pipeline.end_of_input ) { recycle_as_continuation(); return this; } return NULL; } } public: pipeline_root_task( pipeline& pipeline ): my_pipeline(pipeline), do_segment_scanning(false) { __TBB_ASSERT( my_pipeline.filter_list, NULL ); filter* first = my_pipeline.filter_list; if( (first->my_filter_mode & first->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { // Scanning the pipeline for segments filter* head_of_previous_segment = first; for( filter* subfilter=first->next_filter_in_pipeline; subfilter!=NULL; subfilter=subfilter->next_filter_in_pipeline ) { if( subfilter->prev_filter_in_pipeline->is_bound() && !subfilter->is_bound() ) { do_segment_scanning = true; head_of_previous_segment->next_segment = subfilter; head_of_previous_segment = subfilter; } } } } }; #if _MSC_VER && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings // Suppress compiler warning about constant conditional expression #pragma warning (disable: 4127) #endif // The class destroys end_counter and clears all input buffers if pipeline was cancelled. class pipeline_cleaner: internal::no_copy { pipeline& my_pipeline; public: pipeline_cleaner(pipeline& _pipeline) : my_pipeline(_pipeline) {} ~pipeline_cleaner(){ #if __TBB_TASK_GROUP_CONTEXT if (my_pipeline.end_counter->is_cancelled()) // Pipeline was cancelled my_pipeline.clear_filters(); #endif my_pipeline.end_counter = NULL; } }; } // namespace internal void pipeline::inject_token( task& ) { __TBB_ASSERT(false,"illegal call to inject_token"); } #if __TBB_TASK_GROUP_CONTEXT void pipeline::clear_filters() { for( filter* f = filter_list; f; f = f->next_filter_in_pipeline ) { if ((f->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(4)) if( internal::input_buffer* b = f->my_input_buffer ) b->clear(f); } } #endif pipeline::pipeline() : filter_list(NULL), filter_end(NULL), end_counter(NULL), end_of_input(false), has_thread_bound_filters(false) { token_counter = 0; input_tokens = 0; } pipeline::~pipeline() { clear(); } void pipeline::clear() { filter* next; for( filter* f = filter_list; f; f=next ) { if( internal::input_buffer* b = f->my_input_buffer ) { delete b; f->my_input_buffer = NULL; } next=f->next_filter_in_pipeline; f->next_filter_in_pipeline = filter::not_in_pipeline(); if ( (f->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(3) ) { f->prev_filter_in_pipeline = filter::not_in_pipeline(); f->my_pipeline = NULL; } if ( (f->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(5) ) f->next_segment = NULL; } filter_list = filter_end = NULL; } void pipeline::add_filter( filter& filter_ ) { #if TBB_USE_ASSERT if ( (filter_.my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(3) ) __TBB_ASSERT( filter_.prev_filter_in_pipeline==filter::not_in_pipeline(), "filter already part of pipeline?" ); __TBB_ASSERT( filter_.next_filter_in_pipeline==filter::not_in_pipeline(), "filter already part of pipeline?" ); __TBB_ASSERT( !end_counter, "invocation of add_filter on running pipeline" ); #endif if ( (filter_.my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(3) ) { filter_.my_pipeline = this; filter_.prev_filter_in_pipeline = filter_end; if ( filter_list == NULL) filter_list = &filter_; else filter_end->next_filter_in_pipeline = &filter_; filter_.next_filter_in_pipeline = NULL; filter_end = &filter_; } else { if( !filter_end ) filter_end = reinterpret_cast(&filter_list); *reinterpret_cast(filter_end) = &filter_; filter_end = reinterpret_cast(&filter_.next_filter_in_pipeline); *reinterpret_cast(filter_end) = NULL; } if( (filter_.my_filter_mode & filter_.version_mask) >= __TBB_PIPELINE_VERSION(5) ) { if( filter_.is_serial() ) { if( filter_.is_bound() ) has_thread_bound_filters = true; filter_.my_input_buffer = new internal::input_buffer( filter_.is_ordered(), filter_.is_bound() ); } else { if(filter_.prev_filter_in_pipeline) { if(filter_.prev_filter_in_pipeline->is_bound()) { // successors to bound filters must have an input_buffer filter_.my_input_buffer = new internal::input_buffer( /*is_ordered*/false, false ); } } else { // input filter if(filter_.object_may_be_null() ) { //TODO: buffer only needed to hold TLS; could improve filter_.my_input_buffer = new internal::input_buffer( /*is_ordered*/false, false ); filter_.my_input_buffer->create_my_tls(); } } } } else { if( filter_.is_serial() ) { filter_.my_input_buffer = new internal::input_buffer( filter_.is_ordered(), false ); } } } void pipeline::remove_filter( filter& filter_ ) { __TBB_ASSERT( filter_.prev_filter_in_pipeline!=filter::not_in_pipeline(), "filter not part of pipeline" ); __TBB_ASSERT( filter_.next_filter_in_pipeline!=filter::not_in_pipeline(), "filter not part of pipeline" ); __TBB_ASSERT( !end_counter, "invocation of remove_filter on running pipeline" ); if (&filter_ == filter_list) filter_list = filter_.next_filter_in_pipeline; else { __TBB_ASSERT( filter_.prev_filter_in_pipeline, "filter list broken?" ); filter_.prev_filter_in_pipeline->next_filter_in_pipeline = filter_.next_filter_in_pipeline; } if (&filter_ == filter_end) filter_end = filter_.prev_filter_in_pipeline; else { __TBB_ASSERT( filter_.next_filter_in_pipeline, "filter list broken?" ); filter_.next_filter_in_pipeline->prev_filter_in_pipeline = filter_.prev_filter_in_pipeline; } if( internal::input_buffer* b = filter_.my_input_buffer ) { delete b; filter_.my_input_buffer = NULL; } filter_.next_filter_in_pipeline = filter_.prev_filter_in_pipeline = filter::not_in_pipeline(); if ( (filter_.my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(5) ) filter_.next_segment = NULL; filter_.my_pipeline = NULL; } void pipeline::run( size_t max_number_of_live_tokens #if __TBB_TASK_GROUP_CONTEXT , tbb::task_group_context& context #endif ) { __TBB_ASSERT( max_number_of_live_tokens>0, "pipeline::run must have at least one token" ); __TBB_ASSERT( !end_counter, "pipeline already running?" ); if( filter_list ) { internal::pipeline_cleaner my_pipeline_cleaner(*this); end_of_input = false; input_tokens = internal::Token(max_number_of_live_tokens); if(has_thread_bound_filters) { // release input filter if thread-bound if(filter_list->is_bound()) { filter_list->my_input_buffer->sema_V(); } } #if __TBB_TASK_GROUP_CONTEXT end_counter = new( task::allocate_root(context) ) internal::pipeline_root_task( *this ); #else end_counter = new( task::allocate_root() ) internal::pipeline_root_task( *this ); #endif // Start execution of tasks task::spawn_root_and_wait( *end_counter ); if(has_thread_bound_filters) { for(filter* f = filter_list->next_filter_in_pipeline; f; f=f->next_filter_in_pipeline) { if(f->is_bound()) { f->my_input_buffer->sema_V(); // wake to end } } } } } #if __TBB_TASK_GROUP_CONTEXT void pipeline::run( size_t max_number_of_live_tokens ) { if( filter_list ) { // Construct task group context with the exception propagation mode expected // by the pipeline caller. uintptr_t ctx_traits = filter_list->my_filter_mode & filter::exact_exception_propagation ? task_group_context::default_traits : task_group_context::default_traits & ~task_group_context::exact_exception; task_group_context context(task_group_context::bound, ctx_traits); run(max_number_of_live_tokens, context); } } #endif // __TBB_TASK_GROUP_CONTEXT bool filter::has_more_work() { __TBB_ASSERT(my_pipeline, NULL); __TBB_ASSERT(my_input_buffer, "has_more_work() called for filter with no input buffer"); return (internal::tokendiff_t)(my_pipeline->token_counter - my_input_buffer->low_token) != 0; } filter::~filter() { if ( (my_filter_mode & version_mask) >= __TBB_PIPELINE_VERSION(3) ) { if ( next_filter_in_pipeline != filter::not_in_pipeline() ) my_pipeline->remove_filter(*this); else __TBB_ASSERT( prev_filter_in_pipeline == filter::not_in_pipeline(), "probably filter list is broken" ); } else { __TBB_ASSERT( next_filter_in_pipeline==filter::not_in_pipeline(), "cannot destroy filter that is part of pipeline" ); } } void filter::set_end_of_input() { __TBB_ASSERT(my_input_buffer, NULL); __TBB_ASSERT(object_may_be_null(), NULL); if(is_serial()) { my_pipeline->end_of_input = true; } else { __TBB_ASSERT(my_input_buffer->end_of_input_tls_allocated, NULL); my_input_buffer->set_my_tls_end_of_input(); } } thread_bound_filter::result_type thread_bound_filter::process_item() { return internal_process_item(true); } thread_bound_filter::result_type thread_bound_filter::try_process_item() { return internal_process_item(false); } thread_bound_filter::result_type thread_bound_filter::internal_process_item(bool is_blocking) { __TBB_ASSERT(my_pipeline != NULL,"It's not supposed that process_item is called for a filter that is not in a pipeline."); internal::task_info info; info.reset(); if( my_pipeline->end_of_input && !has_more_work() ) return end_of_stream; if( !prev_filter_in_pipeline ) { if( my_pipeline->end_of_input ) return end_of_stream; while( my_pipeline->input_tokens == 0 ) { if( !is_blocking ) return item_not_available; my_input_buffer->sema_P(); } info.my_object = (*this)(info.my_object); if( info.my_object ) { __TBB_ASSERT(my_pipeline->input_tokens > 0, "Token failed in thread-bound filter"); my_pipeline->input_tokens--; if( is_ordered() ) { info.my_token = my_pipeline->token_counter; info.my_token_ready = true; } my_pipeline->token_counter++; // ideally, with relaxed semantics } else { my_pipeline->end_of_input = true; return end_of_stream; } } else { /* this is not an input filter */ while( !my_input_buffer->has_item() ) { if( !is_blocking ) { return item_not_available; } my_input_buffer->sema_P(); if( my_pipeline->end_of_input && !has_more_work() ) { return end_of_stream; } } if( !my_input_buffer->return_item(info, /*advance*/true) ) { __TBB_ASSERT(false,"return_item failed"); } info.my_object = (*this)(info.my_object); } if( next_filter_in_pipeline ) { if ( !next_filter_in_pipeline->my_input_buffer->put_token(info,/*force_put=*/true) ) { __TBB_ASSERT(false, "Couldn't put token after thread-bound buffer"); } } else { size_t ntokens_avail = ++(my_pipeline->input_tokens); if( my_pipeline->filter_list->is_bound() ) { if( ntokens_avail == 1 ) { my_pipeline->filter_list->my_input_buffer->sema_V(); } } } return success; } } // tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/pipeline.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_pipeline_H #define __TBB_pipeline_H #include "atomic.h" #include "task.h" #include "tbb_allocator.h" #include #if __TBB_CPP11_TYPE_PROPERTIES_PRESENT || __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT #include #endif namespace tbb { class pipeline; class filter; //! @cond INTERNAL namespace internal { // The argument for PIPELINE_VERSION should be an integer between 2 and 9 #define __TBB_PIPELINE_VERSION(x) ((unsigned char)(x-2)<<1) typedef unsigned long Token; typedef long tokendiff_t; class stage_task; class input_buffer; class pipeline_root_task; class pipeline_cleaner; } // namespace internal namespace interface6 { template class filter_t; namespace internal { class pipeline_proxy; } } //! @endcond //! A stage in a pipeline. /** @ingroup algorithms */ class filter: internal::no_copy { private: //! Value used to mark "not in pipeline" static filter* not_in_pipeline() {return reinterpret_cast(intptr_t(-1));} protected: //! The lowest bit 0 is for parallel vs. serial static const unsigned char filter_is_serial = 0x1; //! 4th bit distinguishes ordered vs unordered filters. /** The bit was not set for parallel filters in TBB 2.1 and earlier, but is_ordered() function always treats parallel filters as out of order. */ static const unsigned char filter_is_out_of_order = 0x1<<4; //! 5th bit distinguishes thread-bound and regular filters. static const unsigned char filter_is_bound = 0x1<<5; //! 6th bit marks input filters emitting small objects static const unsigned char filter_may_emit_null = 0x1<<6; //! 7th bit defines exception propagation mode expected by the application. static const unsigned char exact_exception_propagation = #if TBB_USE_CAPTURED_EXCEPTION 0x0; #else 0x1<<7; #endif /* TBB_USE_CAPTURED_EXCEPTION */ static const unsigned char current_version = __TBB_PIPELINE_VERSION(5); static const unsigned char version_mask = 0x7<<1; // bits 1-3 are for version public: enum mode { //! processes multiple items in parallel and in no particular order parallel = current_version | filter_is_out_of_order, //! processes items one at a time; all such filters process items in the same order serial_in_order = current_version | filter_is_serial, //! processes items one at a time and in no particular order serial_out_of_order = current_version | filter_is_serial | filter_is_out_of_order, //! @deprecated use serial_in_order instead serial = serial_in_order }; protected: filter( bool is_serial_ ) : next_filter_in_pipeline(not_in_pipeline()), my_input_buffer(NULL), my_filter_mode(static_cast((is_serial_ ? serial : parallel) | exact_exception_propagation)), prev_filter_in_pipeline(not_in_pipeline()), my_pipeline(NULL), next_segment(NULL) {} filter( mode filter_mode ) : next_filter_in_pipeline(not_in_pipeline()), my_input_buffer(NULL), my_filter_mode(static_cast(filter_mode | exact_exception_propagation)), prev_filter_in_pipeline(not_in_pipeline()), my_pipeline(NULL), next_segment(NULL) {} // signal end-of-input for concrete_filters void __TBB_EXPORTED_METHOD set_end_of_input(); public: //! True if filter is serial. bool is_serial() const { return bool( my_filter_mode & filter_is_serial ); } //! True if filter must receive stream in order. bool is_ordered() const { return (my_filter_mode & (filter_is_out_of_order|filter_is_serial))==filter_is_serial; } //! True if filter is thread-bound. bool is_bound() const { return ( my_filter_mode & filter_is_bound )==filter_is_bound; } //! true if an input filter can emit null bool object_may_be_null() { return ( my_filter_mode & filter_may_emit_null ) == filter_may_emit_null; } //! Operate on an item from the input stream, and return item for output stream. /** Returns NULL if filter is a sink. */ virtual void* operator()( void* item ) = 0; //! Destroy filter. /** If the filter was added to a pipeline, the pipeline must be destroyed first. */ virtual __TBB_EXPORTED_METHOD ~filter(); #if __TBB_TASK_GROUP_CONTEXT //! Destroys item if pipeline was cancelled. /** Required to prevent memory leaks. Note it can be called concurrently even for serial filters.*/ virtual void finalize( void* /*item*/ ) {}; #endif private: //! Pointer to next filter in the pipeline. filter* next_filter_in_pipeline; //! has the filter not yet processed all the tokens it will ever see? // (pipeline has not yet reached end_of_input or this filter has not yet // seen the last token produced by input_filter) bool has_more_work(); //! Buffer for incoming tokens, or NULL if not required. /** The buffer is required if the filter is serial or follows a thread-bound one. */ internal::input_buffer* my_input_buffer; friend class internal::stage_task; friend class internal::pipeline_root_task; friend class pipeline; friend class thread_bound_filter; //! Storage for filter mode and dynamically checked implementation version. const unsigned char my_filter_mode; //! Pointer to previous filter in the pipeline. filter* prev_filter_in_pipeline; //! Pointer to the pipeline. pipeline* my_pipeline; //! Pointer to the next "segment" of filters, or NULL if not required. /** In each segment, the first filter is not thread-bound but follows a thread-bound one. */ filter* next_segment; }; //! A stage in a pipeline served by a user thread. /** @ingroup algorithms */ class thread_bound_filter: public filter { public: enum result_type { // item was processed success, // item is currently not available item_not_available, // there are no more items to process end_of_stream }; protected: thread_bound_filter(mode filter_mode): filter(static_cast(filter_mode | filter::filter_is_bound)) { __TBB_ASSERT(filter_mode & filter::filter_is_serial, "thread-bound filters must be serial"); } public: //! If a data item is available, invoke operator() on that item. /** This interface is non-blocking. Returns 'success' if an item was processed. Returns 'item_not_available' if no item can be processed now but more may arrive in the future, or if token limit is reached. Returns 'end_of_stream' if there are no more items to process. */ result_type __TBB_EXPORTED_METHOD try_process_item(); //! Wait until a data item becomes available, and invoke operator() on that item. /** This interface is blocking. Returns 'success' if an item was processed. Returns 'end_of_stream' if there are no more items to process. Never returns 'item_not_available', as it blocks until another return condition applies. */ result_type __TBB_EXPORTED_METHOD process_item(); private: //! Internal routine for item processing result_type internal_process_item(bool is_blocking); }; //! A processing pipeline that applies filters to items. /** @ingroup algorithms */ class pipeline { public: //! Construct empty pipeline. __TBB_EXPORTED_METHOD pipeline(); /** Though the current implementation declares the destructor virtual, do not rely on this detail. The virtualness is deprecated and may disappear in future versions of TBB. */ virtual __TBB_EXPORTED_METHOD ~pipeline(); //! Add filter to end of pipeline. void __TBB_EXPORTED_METHOD add_filter( filter& filter_ ); //! Run the pipeline to completion. void __TBB_EXPORTED_METHOD run( size_t max_number_of_live_tokens ); #if __TBB_TASK_GROUP_CONTEXT //! Run the pipeline to completion with user-supplied context. void __TBB_EXPORTED_METHOD run( size_t max_number_of_live_tokens, tbb::task_group_context& context ); #endif //! Remove all filters from the pipeline. void __TBB_EXPORTED_METHOD clear(); private: friend class internal::stage_task; friend class internal::pipeline_root_task; friend class filter; friend class thread_bound_filter; friend class internal::pipeline_cleaner; friend class tbb::interface6::internal::pipeline_proxy; //! Pointer to first filter in the pipeline. filter* filter_list; //! Pointer to location where address of next filter to be added should be stored. filter* filter_end; //! task who's reference count is used to determine when all stages are done. task* end_counter; //! Number of idle tokens waiting for input stage. atomic input_tokens; //! Global counter of tokens atomic token_counter; //! False until fetch_input returns NULL. bool end_of_input; //! True if the pipeline contains a thread-bound filter; false otherwise. bool has_thread_bound_filters; //! Remove filter from pipeline. void remove_filter( filter& filter_ ); //! Not used, but retained to satisfy old export files. void __TBB_EXPORTED_METHOD inject_token( task& self ); #if __TBB_TASK_GROUP_CONTEXT //! Does clean up if pipeline is cancelled or exception occurred void clear_filters(); #endif }; //------------------------------------------------------------------------ // Support for lambda-friendly parallel_pipeline interface //------------------------------------------------------------------------ namespace interface6 { namespace internal { template class concrete_filter; } //! input_filter control to signal end-of-input for parallel_pipeline class flow_control { bool is_pipeline_stopped; flow_control() { is_pipeline_stopped = false; } template friend class internal::concrete_filter; public: void stop() { is_pipeline_stopped = true; } }; //! @cond INTERNAL namespace internal { template struct tbb_large_object {enum { value = sizeof(T) > sizeof(void *) }; }; // Obtain type properties in one or another way #if __TBB_CPP11_TYPE_PROPERTIES_PRESENT template struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable::value }; }; #elif __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT template struct tbb_trivially_copyable { enum { value = std::has_trivial_copy_constructor::value }; }; #else // Explicitly list the types we wish to be placed as-is in the pipeline input_buffers. template struct tbb_trivially_copyable { enum { value = false }; }; template struct tbb_trivially_copyable { enum { value = true }; }; template<> struct tbb_trivially_copyable { enum { value = true }; }; template<> struct tbb_trivially_copyable { enum { value = true }; }; template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; #endif // Obtaining type properties template struct is_large_object {enum { value = tbb_large_object::value || !tbb_trivially_copyable::value }; }; template class token_helper; // large object helper (uses tbb_allocator) template class token_helper { public: typedef typename tbb::tbb_allocator allocator; typedef T* pointer; typedef T value_type; static pointer create_token(const value_type & source) { pointer output_t = allocator().allocate(1); return new (output_t) T(source); } static value_type & token(pointer & t) { return *t;} static void * cast_to_void_ptr(pointer ref) { return (void *) ref; } static pointer cast_from_void_ptr(void * ref) { return (pointer)ref; } static void destroy_token(pointer token) { allocator().destroy(token); allocator().deallocate(token,1); } }; // pointer specialization template class token_helper { public: typedef T* pointer; typedef T* value_type; static pointer create_token(const value_type & source) { return source; } static value_type & token(pointer & t) { return t;} static void * cast_to_void_ptr(pointer ref) { return (void *)ref; } static pointer cast_from_void_ptr(void * ref) { return (pointer)ref; } static void destroy_token( pointer /*token*/) {} }; // small object specialization (converts void* to the correct type, passes objects directly.) template class token_helper { typedef union { T actual_value; void * void_overlay; } type_to_void_ptr_map; public: typedef T pointer; // not really a pointer in this case. typedef T value_type; static pointer create_token(const value_type & source) { return source; } static value_type & token(pointer & t) { return t;} static void * cast_to_void_ptr(pointer ref) { type_to_void_ptr_map mymap; mymap.void_overlay = NULL; mymap.actual_value = ref; return mymap.void_overlay; } static pointer cast_from_void_ptr(void * ref) { type_to_void_ptr_map mymap; mymap.void_overlay = ref; return mymap.actual_value; } static void destroy_token( pointer /*token*/) {} }; template class concrete_filter: public tbb::filter { const Body& my_body; typedef token_helper::value > t_helper; typedef typename t_helper::pointer t_pointer; typedef token_helper::value > u_helper; typedef typename u_helper::pointer u_pointer; /*override*/ void* operator()(void* input) { t_pointer temp_input = t_helper::cast_from_void_ptr(input); u_pointer output_u = u_helper::create_token(my_body(t_helper::token(temp_input))); t_helper::destroy_token(temp_input); return u_helper::cast_to_void_ptr(output_u); } /*override*/ void finalize(void * input) { t_pointer temp_input = t_helper::cast_from_void_ptr(input); t_helper::destroy_token(temp_input); } public: concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} }; // input template class concrete_filter: public filter { const Body& my_body; typedef token_helper::value > u_helper; typedef typename u_helper::pointer u_pointer; /*override*/void* operator()(void*) { flow_control control; u_pointer output_u = u_helper::create_token(my_body(control)); if(control.is_pipeline_stopped) { u_helper::destroy_token(output_u); set_end_of_input(); return NULL; } return u_helper::cast_to_void_ptr(output_u); } public: concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(static_cast(filter_mode | filter_may_emit_null)), my_body(body) {} }; template class concrete_filter: public filter { const Body& my_body; typedef token_helper::value > t_helper; typedef typename t_helper::pointer t_pointer; /*override*/ void* operator()(void* input) { t_pointer temp_input = t_helper::cast_from_void_ptr(input); my_body(t_helper::token(temp_input)); t_helper::destroy_token(temp_input); return NULL; } /*override*/ void finalize(void* input) { t_pointer temp_input = t_helper::cast_from_void_ptr(input); t_helper::destroy_token(temp_input); } public: concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} }; template class concrete_filter: public filter { const Body& my_body; /** Override privately because it is always called virtually */ /*override*/ void* operator()(void*) { flow_control control; my_body(control); void* output = control.is_pipeline_stopped ? NULL : (void*)(intptr_t)-1; return output; } public: concrete_filter(filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} }; //! The class that represents an object of the pipeline for parallel_pipeline(). /** It primarily serves as RAII class that deletes heap-allocated filter instances. */ class pipeline_proxy { tbb::pipeline my_pipe; public: pipeline_proxy( const filter_t& filter_chain ); ~pipeline_proxy() { while( filter* f = my_pipe.filter_list ) delete f; // filter destructor removes it from the pipeline } tbb::pipeline* operator->() { return &my_pipe; } }; //! Abstract base class that represents a node in a parse tree underlying a filter_t. /** These nodes are always heap-allocated and can be shared by filter_t objects. */ class filter_node: tbb::internal::no_copy { /** Count must be atomic because it is hidden state for user, but might be shared by threads. */ tbb::atomic ref_count; protected: filter_node() { ref_count = 0; #ifdef __TBB_TEST_FILTER_NODE_COUNT ++(__TBB_TEST_FILTER_NODE_COUNT); #endif } public: //! Add concrete_filter to pipeline virtual void add_to( pipeline& ) = 0; //! Increment reference count void add_ref() {++ref_count;} //! Decrement reference count and delete if it becomes zero. void remove_ref() { __TBB_ASSERT(ref_count>0,"ref_count underflow"); if( --ref_count==0 ) delete this; } virtual ~filter_node() { #ifdef __TBB_TEST_FILTER_NODE_COUNT --(__TBB_TEST_FILTER_NODE_COUNT); #endif } }; //! Node in parse tree representing result of make_filter. template class filter_node_leaf: public filter_node { const tbb::filter::mode mode; const Body body; /*override*/void add_to( pipeline& p ) { concrete_filter* f = new concrete_filter(mode,body); p.add_filter( *f ); } public: filter_node_leaf( tbb::filter::mode m, const Body& b ) : mode(m), body(b) {} }; //! Node in parse tree representing join of two filters. class filter_node_join: public filter_node { friend class filter_node; // to suppress GCC 3.2 warnings filter_node& left; filter_node& right; /*override*/~filter_node_join() { left.remove_ref(); right.remove_ref(); } /*override*/void add_to( pipeline& p ) { left.add_to(p); right.add_to(p); } public: filter_node_join( filter_node& x, filter_node& y ) : left(x), right(y) { left.add_ref(); right.add_ref(); } }; } // namespace internal //! @endcond //! Create a filter to participate in parallel_pipeline template filter_t make_filter(tbb::filter::mode mode, const Body& body) { return new internal::filter_node_leaf(mode, body); } template filter_t operator& (const filter_t& left, const filter_t& right) { __TBB_ASSERT(left.root,"cannot use default-constructed filter_t as left argument of '&'"); __TBB_ASSERT(right.root,"cannot use default-constructed filter_t as right argument of '&'"); return new internal::filter_node_join(*left.root,*right.root); } //! Class representing a chain of type-safe pipeline filters template class filter_t { typedef internal::filter_node filter_node; filter_node* root; filter_t( filter_node* root_ ) : root(root_) { root->add_ref(); } friend class internal::pipeline_proxy; template friend filter_t make_filter(tbb::filter::mode, const Body& ); template friend filter_t operator& (const filter_t& , const filter_t& ); public: filter_t() : root(NULL) {} filter_t( const filter_t& rhs ) : root(rhs.root) { if( root ) root->add_ref(); } template filter_t( tbb::filter::mode mode, const Body& body ) : root( new internal::filter_node_leaf(mode, body) ) { root->add_ref(); } void operator=( const filter_t& rhs ) { // Order of operations below carefully chosen so that reference counts remain correct // in unlikely event that remove_ref throws exception. filter_node* old = root; root = rhs.root; if( root ) root->add_ref(); if( old ) old->remove_ref(); } ~filter_t() { if( root ) root->remove_ref(); } void clear() { // Like operator= with filter_t() on right side. if( root ) { filter_node* old = root; root = NULL; old->remove_ref(); } } }; inline internal::pipeline_proxy::pipeline_proxy( const filter_t& filter_chain ) : my_pipe() { __TBB_ASSERT( filter_chain.root, "cannot apply parallel_pipeline to default-constructed filter_t" ); filter_chain.root->add_to(my_pipe); } inline void parallel_pipeline(size_t max_number_of_live_tokens, const filter_t& filter_chain #if __TBB_TASK_GROUP_CONTEXT , tbb::task_group_context& context #endif ) { internal::pipeline_proxy pipe(filter_chain); // tbb::pipeline::run() is called via the proxy pipe->run(max_number_of_live_tokens #if __TBB_TASK_GROUP_CONTEXT , context #endif ); } #if __TBB_TASK_GROUP_CONTEXT inline void parallel_pipeline(size_t max_number_of_live_tokens, const filter_t& filter_chain) { tbb::task_group_context context; parallel_pipeline(max_number_of_live_tokens, filter_chain, context); } #endif // __TBB_TASK_GROUP_CONTEXT } // interface6 using interface6::flow_control; using interface6::filter_t; using interface6::make_filter; using interface6::parallel_pipeline; } // tbb #endif /* __TBB_pipeline_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/private_server.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "rml_tbb.h" #include "../server/thread_monitor.h" #include "tbb/atomic.h" #include "tbb/cache_aligned_allocator.h" #include "scheduler_common.h" #include "governor.h" #include "tbb_misc.h" using rml::internal::thread_monitor; namespace tbb { namespace internal { namespace rml { typedef thread_monitor::handle_type thread_handle; class private_server; class private_worker: no_copy { //! State in finite-state machine that controls the worker. /** State diagram: init --> starting --> normal | | | | V | \------> quit <------/ */ enum state_t { //! *this is initialized st_init, //! *this has associated thread that is starting up. st_starting, //! Associated thread is doing normal life sequence. st_normal, //! Associated thread has ended normal life sequence and promises to never touch *this again. st_quit }; atomic my_state; //! Associated server private_server& my_server; //! Associated client tbb_client& my_client; //! index used for avoiding the 64K aliasing problem const size_t my_index; //! Monitor for sleeping when there is no work to do. /** The invariant that holds for sleeping workers is: "my_slack<=0 && my_state==st_normal && I am on server's list of asleep threads" */ thread_monitor my_thread_monitor; //! Handle of the OS thread associated with this worker thread_handle my_handle; //! Link for list of workers that are sleeping or have no associated thread. private_worker* my_next; friend class private_server; //! Actions executed by the associated thread void run(); //! Wake up associated thread (or launch a thread if there is none) void wake_or_launch(); //! Called by a thread (usually not the associated thread) to commence termination. void start_shutdown(); static __RML_DECL_THREAD_ROUTINE thread_routine( void* arg ); static void release_handle(thread_handle my_handle); protected: private_worker( private_server& server, tbb_client& client, const size_t i ) : my_server(server), my_client(client), my_index(i) { my_state = st_init; } }; static const size_t cache_line_size = tbb::internal::NFS_MaxLineSize; #if _MSC_VER && !defined(__INTEL_COMPILER) // Suppress overzealous compiler warnings about uninstantiable class #pragma warning(push) #pragma warning(disable:4510 4610) #endif class padded_private_worker: public private_worker { char pad[cache_line_size - sizeof(private_worker)%cache_line_size]; public: padded_private_worker( private_server& server, tbb_client& client, const size_t i ) : private_worker(server,client,i) { suppress_unused_warning(pad); } }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning(pop) #endif class private_server: public tbb_server, no_copy { tbb_client& my_client; //! Maximum number of threads to be created. /** Threads are created lazily, so maximum might not actually be reached. */ const tbb_client::size_type my_n_thread; //! Stack size for each thread. */ const size_t my_stack_size; //! Number of jobs that could use their associated thread minus number of active threads. /** If negative, indicates oversubscription. If positive, indicates that more threads should run. Can be lowered asynchronously, but must be raised only while holding my_asleep_list_mutex, because raising it impacts the invariant for sleeping threads. */ atomic my_slack; //! Counter used to determine when to delete this. atomic my_ref_count; padded_private_worker* my_thread_array; //! List of workers that are asleep or committed to sleeping until notified by another thread. tbb::atomic my_asleep_list_root; //! Protects my_asleep_list_root typedef scheduler_mutex_type asleep_list_mutex_type; asleep_list_mutex_type my_asleep_list_mutex; #if TBB_USE_ASSERT atomic my_net_slack_requests; #endif /* TBB_USE_ASSERT */ //! Wake up to two sleeping workers, if there are any sleeping. /** The call is used to propagate a chain reaction where each thread wakes up two threads, which in turn each wake up two threads, etc. */ void propagate_chain_reaction() { // First test of a double-check idiom. Second test is inside wake_some(0). if( my_asleep_list_root ) wake_some(0); } //! Try to add t to list of sleeping workers bool try_insert_in_asleep_list( private_worker& t ); //! Equivalent of adding additional_slack to my_slack and waking up to 2 threads if my_slack permits. void wake_some( int additional_slack ); virtual ~private_server(); void remove_server_ref() { if( --my_ref_count==0 ) { my_client.acknowledge_close_connection(); this->~private_server(); tbb::cache_aligned_allocator().deallocate( this, 1 ); } } friend class private_worker; public: private_server( tbb_client& client ); /*override*/ version_type version() const { return 0; } /*override*/ void request_close_connection( bool /*exiting*/ ) { for( size_t i=0; i=2 && !__MINGW64__ // ensure that stack is properly aligned for TBB threads __attribute__((force_align_arg_pointer)) #endif __RML_DECL_THREAD_ROUTINE private_worker::thread_routine( void* arg ) { private_worker* self = static_cast(arg); AVOID_64K_ALIASING( self->my_index ); #if _XBOX int HWThreadIndex = __TBB_XBOX360_GetHardwareThreadIndex(i); XSetThreadProcessor(GetCurrentThread(), HWThreadIndex); #endif self->run(); return 0; } #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning(pop) #endif void private_worker::release_handle(thread_handle handle) { if (governor::needsWaitWorkers()) thread_monitor::join(handle); else thread_monitor::detach_thread(handle); } void private_worker::start_shutdown() { state_t s; do { s = my_state; __TBB_ASSERT( s!=st_quit, NULL ); } while( my_state.compare_and_swap( st_quit, s )!=s ); if( s==st_normal || s==st_starting ) { // May have invalidated invariant for sleeping, so wake up the thread. // Note that the notify() here occurs without maintaining invariants for my_slack. // It does not matter, because my_state==st_quit overrides checking of my_slack. my_thread_monitor.notify(); // Do not need release handle in st_init state, // because in this case the thread wasn't started yet. // For st_starting release is done at launch site. if (s==st_normal) release_handle(my_handle); } else if( s==st_init ) { // Perform action that otherwise would be performed by associated thread when it quits. my_server.remove_server_ref(); } } void private_worker::run() { my_server.propagate_chain_reaction(); // Transiting to st_normal here would require setting my_handle, // which would create race with the launching thread and // complications in handle management on Windows. ::rml::job& j = *my_client.create_one_job(); while( my_state!=st_quit ) { if( my_server.my_slack>=0 ) { my_client.process(j); } else { thread_monitor::cookie c; // Prepare to wait my_thread_monitor.prepare_wait(c); // Check/set the invariant for sleeping if( my_state!=st_quit && my_server.try_insert_in_asleep_list(*this) ) { my_thread_monitor.commit_wait(c); my_server.propagate_chain_reaction(); } else { // Invariant broken my_thread_monitor.cancel_wait(); } } } my_client.cleanup(j); ++my_server.my_slack; my_server.remove_server_ref(); } inline void private_worker::wake_or_launch() { if( my_state==st_init && my_state.compare_and_swap( st_starting, st_init )==st_init ) { // after this point, remove_server_ref() must be done by created thread #if USE_WINTHREAD my_handle = thread_monitor::launch( thread_routine, this, my_server.my_stack_size, &this->my_index ); #elif USE_PTHREAD { affinity_helper fpa; fpa.protect_affinity_mask(); my_handle = thread_monitor::launch( thread_routine, this, my_server.my_stack_size ); // Implicit destruction of fpa resets original affinity mask. } #endif /* USE_PTHREAD */ state_t s = my_state.compare_and_swap( st_normal, st_starting ); if (st_starting != s) { // Do shutdown during startup. my_handle can't be released // by start_shutdown, because my_handle value might be not set yet // at time of transition from st_starting to st_quit. __TBB_ASSERT( s==st_quit, NULL ); release_handle(my_handle); } } else my_thread_monitor.notify(); } //------------------------------------------------------------------------ // Methods of private_server //------------------------------------------------------------------------ private_server::private_server( tbb_client& client ) : my_client(client), my_n_thread(client.max_job_count()), my_stack_size(client.min_stack_size()), my_thread_array(NULL) { my_ref_count = my_n_thread+1; my_slack = 0; #if TBB_USE_ASSERT my_net_slack_requests = 0; #endif /* TBB_USE_ASSERT */ my_asleep_list_root = NULL; my_thread_array = tbb::cache_aligned_allocator().allocate( my_n_thread ); memset( my_thread_array, 0, sizeof(private_worker)*my_n_thread ); for( size_t i=0; imy_next = my_asleep_list_root; my_asleep_list_root = t; } } private_server::~private_server() { __TBB_ASSERT( my_net_slack_requests==0, NULL ); for( size_t i=my_n_thread; i--; ) my_thread_array[i].~padded_private_worker(); tbb::cache_aligned_allocator().deallocate( my_thread_array, my_n_thread ); tbb::internal::poison_pointer( my_thread_array ); } inline bool private_server::try_insert_in_asleep_list( private_worker& t ) { asleep_list_mutex_type::scoped_lock lock; if( !lock.try_acquire(my_asleep_list_mutex) ) return false; // Contribute to slack under lock so that if another takes that unit of slack, // it sees us sleeping on the list and wakes us up. int k = ++my_slack; if( k<=0 ) { t.my_next = my_asleep_list_root; my_asleep_list_root = &t; return true; } else { --my_slack; return false; } } void private_server::wake_some( int additional_slack ) { __TBB_ASSERT( additional_slack>=0, NULL ); private_worker* wakee[2]; private_worker**w = wakee; { asleep_list_mutex_type::scoped_lock lock(my_asleep_list_mutex); while( my_asleep_list_root && w0 ) { if (additional_slack+my_slack<=0) // additional demand does not exceed surplus supply break; --additional_slack; } else { // Chain reaction; Try to claim unit of slack int old; do { old = my_slack; if( old<=0 ) goto done; } while( my_slack.compare_and_swap(old-1,old)!=old ); } // Pop sleeping worker to combine with claimed unit of slack my_asleep_list_root = (*w++ = my_asleep_list_root)->my_next; } if( additional_slack ) { // Contribute our unused slack to my_slack. my_slack += additional_slack; } } done: while( w>wakee ) (*--w)->wake_or_launch(); } void private_server::adjust_job_count_estimate( int delta ) { #if TBB_USE_ASSERT my_net_slack_requests+=delta; #endif /* TBB_USE_ASSERT */ if( delta<0 ) { my_slack+=delta; } else if( delta>0 ) { wake_some( delta ); } } //! Factory method called from task.cpp to create a private_server. tbb_server* make_private_server( tbb_client& client ) { return new( tbb::cache_aligned_allocator().allocate(1) ) private_server(client); } } // namespace rml } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/queuing_mutex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/queuing_mutex.h" #include "tbb/tbb_machine.h" #include "tbb/tbb_stddef.h" #include "tbb_misc.h" #include "itt_notify.h" namespace tbb { using namespace internal; //! A method to acquire queuing_mutex lock void queuing_mutex::scoped_lock::acquire( queuing_mutex& m ) { __TBB_ASSERT( !this->mutex, "scoped_lock is already holding a mutex"); // Must set all fields before the fetch_and_store, because once the // fetch_and_store executes, *this becomes accessible to other threads. mutex = &m; next = NULL; going = 0; // The fetch_and_store must have release semantics, because we are // "sending" the fields initialized above to other processors. scoped_lock* pred = m.q_tail.fetch_and_store(this); if( pred ) { ITT_NOTIFY(sync_prepare, mutex); #if TBB_USE_ASSERT __TBB_control_consistency_helper(); // on "m.q_tail" __TBB_ASSERT( !pred->next, "the predecessor has another successor!"); #endif pred->next = this; spin_wait_while_eq( going, 0ul ); } ITT_NOTIFY(sync_acquired, mutex); // Force acquire so that user's critical section receives correct values // from processor that was previously in the user's critical section. __TBB_load_with_acquire(going); } //! A method to acquire queuing_mutex if it is free bool queuing_mutex::scoped_lock::try_acquire( queuing_mutex& m ) { __TBB_ASSERT( !this->mutex, "scoped_lock is already holding a mutex"); // Must set all fields before the fetch_and_store, because once the // fetch_and_store executes, *this becomes accessible to other threads. next = NULL; going = 0; // The CAS must have release semantics, because we are // "sending" the fields initialized above to other processors. if( m.q_tail.compare_and_swap(this, NULL) ) return false; // Force acquire so that user's critical section receives correct values // from processor that was previously in the user's critical section. // try_acquire should always have acquire semantic, even if failed. __TBB_load_with_acquire(going); mutex = &m; ITT_NOTIFY(sync_acquired, mutex); return true; } //! A method to release queuing_mutex lock void queuing_mutex::scoped_lock::release( ) { __TBB_ASSERT(this->mutex!=NULL, "no lock acquired"); ITT_NOTIFY(sync_releasing, mutex); if( !next ) { if( this == mutex->q_tail.compare_and_swap(NULL, this) ) { // this was the only item in the queue, and the queue is now empty. goto done; } // Someone in the queue spin_wait_while_eq( next, (scoped_lock*)0 ); } __TBB_ASSERT(next,NULL); __TBB_store_with_release(next->going, 1); done: initialize(); } void queuing_mutex::internal_construct() { ITT_SYNC_CREATE(this, _T("tbb::queuing_mutex"), _T("")); } } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/queuing_mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_queuing_mutex_H #define __TBB_queuing_mutex_H #include "tbb_config.h" #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif #include "atomic.h" #include "tbb_profiling.h" namespace tbb { //! Queuing mutex with local-only spinning. /** @ingroup synchronization */ class queuing_mutex : internal::mutex_copy_deprecated_and_disabled { public: //! Construct unacquired mutex. queuing_mutex() { q_tail = NULL; #if TBB_USE_THREADING_TOOLS internal_construct(); #endif } //! The scoped locking pattern /** It helps to avoid the common problem of forgetting to release lock. It also nicely provides the "node" for queuing locks. */ class scoped_lock: internal::no_copy { //! Initialize fields to mean "no lock held". void initialize() { mutex = NULL; #if TBB_USE_ASSERT internal::poison_pointer(next); #endif /* TBB_USE_ASSERT */ } public: //! Construct lock that has not acquired a mutex. /** Equivalent to zero-initialization of *this. */ scoped_lock() {initialize();} //! Acquire lock on given mutex. scoped_lock( queuing_mutex& m ) { initialize(); acquire(m); } //! Release lock (if lock is held). ~scoped_lock() { if( mutex ) release(); } //! Acquire lock on given mutex. void __TBB_EXPORTED_METHOD acquire( queuing_mutex& m ); //! Acquire lock on given mutex if free (i.e. non-blocking) bool __TBB_EXPORTED_METHOD try_acquire( queuing_mutex& m ); //! Release lock. void __TBB_EXPORTED_METHOD release(); private: //! The pointer to the mutex owned, or NULL if not holding a mutex. queuing_mutex* mutex; //! The pointer to the next competitor for a mutex scoped_lock *next; //! The local spin-wait variable /** Inverted (0 - blocked, 1 - acquired the mutex) for the sake of zero-initialization. Defining it as an entire word instead of a byte seems to help performance slightly. */ uintptr_t going; }; void __TBB_EXPORTED_METHOD internal_construct(); // Mutex traits static const bool is_rw_mutex = false; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = true; private: //! The last competitor requesting the lock atomic q_tail; }; __TBB_DEFINE_PROFILING_SET_NAME(queuing_mutex) } // namespace tbb #endif /* __TBB_queuing_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/queuing_rw_mutex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /** Before making any changes in the implementation, please emulate algorithmic changes with SPIN tool using /tools/spin_models/ReaderWriterMutex.pml. There could be some code looking as "can be restructured" but its structure does matter! */ #include "tbb/queuing_rw_mutex.h" #include "tbb/tbb_machine.h" #include "tbb/tbb_stddef.h" #include "tbb/tbb_machine.h" #include "itt_notify.h" namespace tbb { using namespace internal; //! Flag bits in a state_t that specify information about a locking request. enum state_t_flags { STATE_NONE = 0, STATE_WRITER = 1<<0, STATE_READER = 1<<1, STATE_READER_UNBLOCKNEXT = 1<<2, STATE_ACTIVEREADER = 1<<3, STATE_UPGRADE_REQUESTED = 1<<4, STATE_UPGRADE_WAITING = 1<<5, STATE_UPGRADE_LOSER = 1<<6, STATE_COMBINED_WAITINGREADER = STATE_READER | STATE_READER_UNBLOCKNEXT, STATE_COMBINED_READER = STATE_COMBINED_WAITINGREADER | STATE_ACTIVEREADER, STATE_COMBINED_UPGRADING = STATE_UPGRADE_WAITING | STATE_UPGRADE_LOSER }; const unsigned char RELEASED = 0; const unsigned char ACQUIRED = 1; inline bool queuing_rw_mutex::scoped_lock::try_acquire_internal_lock() { return as_atomic(my_internal_lock).compare_and_swap(ACQUIRED,RELEASED) == RELEASED; } inline void queuing_rw_mutex::scoped_lock::acquire_internal_lock() { // Usually, we would use the test-test-and-set idiom here, with exponential backoff. // But so far, experiments indicate there is no value in doing so here. while( !try_acquire_internal_lock() ) { __TBB_Pause(1); } } inline void queuing_rw_mutex::scoped_lock::release_internal_lock() { __TBB_store_with_release(my_internal_lock,RELEASED); } inline void queuing_rw_mutex::scoped_lock::wait_for_release_of_internal_lock() { spin_wait_until_eq(my_internal_lock, RELEASED); } inline void queuing_rw_mutex::scoped_lock::unblock_or_wait_on_internal_lock( uintptr_t flag ) { if( flag ) wait_for_release_of_internal_lock(); else release_internal_lock(); } #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings #pragma warning (push) #pragma warning (disable: 4311 4312) #endif //! A view of a T* with additional functionality for twiddling low-order bits. template class tricky_atomic_pointer: no_copy { public: typedef typename atomic_selector::word word; template static T* fetch_and_add( T* volatile * location, word addend ) { return reinterpret_cast( atomic_traits::fetch_and_add(location, addend) ); } template static T* fetch_and_store( T* volatile * location, T* value ) { return reinterpret_cast( atomic_traits::fetch_and_store(location, reinterpret_cast(value)) ); } template static T* compare_and_swap( T* volatile * location, T* value, T* comparand ) { return reinterpret_cast( atomic_traits::compare_and_swap(location, reinterpret_cast(value), reinterpret_cast(comparand)) ); } T* & ref; tricky_atomic_pointer( T*& original ) : ref(original) {}; tricky_atomic_pointer( T* volatile & original ) : ref(original) {}; T* operator&( word operand2 ) const { return reinterpret_cast( reinterpret_cast(ref) & operand2 ); } T* operator|( word operand2 ) const { return reinterpret_cast( reinterpret_cast(ref) | operand2 ); } }; typedef tricky_atomic_pointer tricky_pointer; #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings #pragma warning (pop) #endif //! Mask for low order bit of a pointer. static const tricky_pointer::word FLAG = 0x1; inline uintptr_t get_flag( queuing_rw_mutex::scoped_lock* ptr ) { return uintptr_t(ptr) & FLAG; } //------------------------------------------------------------------------ // Methods of queuing_rw_mutex::scoped_lock //------------------------------------------------------------------------ //! A method to acquire queuing_rw_mutex lock void queuing_rw_mutex::scoped_lock::acquire( queuing_rw_mutex& m, bool write ) { __TBB_ASSERT( !my_mutex, "scoped_lock is already holding a mutex"); // Must set all fields before the fetch_and_store, because once the // fetch_and_store executes, *this becomes accessible to other threads. my_mutex = &m; __TBB_store_relaxed(my_prev , (scoped_lock*)0); __TBB_store_relaxed(my_next , (scoped_lock*)0); __TBB_store_relaxed(my_going, 0); my_state = state_t(write ? STATE_WRITER : STATE_READER); my_internal_lock = RELEASED; queuing_rw_mutex::scoped_lock* pred = m.q_tail.fetch_and_store(this); if( write ) { // Acquiring for write if( pred ) { ITT_NOTIFY(sync_prepare, my_mutex); pred = tricky_pointer(pred) & ~FLAG; __TBB_ASSERT( !( uintptr_t(pred) & FLAG ), "use of corrupted pointer!" ); #if TBB_USE_ASSERT __TBB_control_consistency_helper(); // on "m.q_tail" __TBB_ASSERT( !__TBB_load_relaxed(pred->my_next), "the predecessor has another successor!"); #endif __TBB_store_with_release(pred->my_next,this); spin_wait_until_eq(my_going, 1); } } else { // Acquiring for read #if DO_ITT_NOTIFY bool sync_prepare_done = false; #endif if( pred ) { unsigned short pred_state; __TBB_ASSERT( !__TBB_load_relaxed(my_prev), "the predecessor is already set" ); if( uintptr_t(pred) & FLAG ) { /* this is only possible if pred is an upgrading reader and it signals us to wait */ pred_state = STATE_UPGRADE_WAITING; pred = tricky_pointer(pred) & ~FLAG; } else { // Load pred->my_state now, because once pred->my_next becomes // non-NULL, we must assume that *pred might be destroyed. pred_state = pred->my_state.compare_and_swap(STATE_READER_UNBLOCKNEXT, STATE_READER); } __TBB_store_relaxed(my_prev, pred); __TBB_ASSERT( !( uintptr_t(pred) & FLAG ), "use of corrupted pointer!" ); #if TBB_USE_ASSERT __TBB_control_consistency_helper(); // on "m.q_tail" __TBB_ASSERT( !__TBB_load_relaxed(pred->my_next), "the predecessor has another successor!"); #endif __TBB_store_with_release(pred->my_next,this); if( pred_state != STATE_ACTIVEREADER ) { #if DO_ITT_NOTIFY sync_prepare_done = true; ITT_NOTIFY(sync_prepare, my_mutex); #endif spin_wait_until_eq(my_going, 1); } } // The protected state must have been acquired here before it can be further released to any other reader(s): unsigned short old_state = my_state.compare_and_swap(STATE_ACTIVEREADER, STATE_READER); if( old_state!=STATE_READER ) { #if DO_ITT_NOTIFY if( !sync_prepare_done ) ITT_NOTIFY(sync_prepare, my_mutex); #endif // Failed to become active reader -> need to unblock the next waiting reader first __TBB_ASSERT( my_state==STATE_READER_UNBLOCKNEXT, "unexpected state" ); spin_wait_while_eq(my_next, (scoped_lock*)NULL); /* my_state should be changed before unblocking the next otherwise it might finish and another thread can get our old state and left blocked */ my_state = STATE_ACTIVEREADER; __TBB_store_with_release(my_next->my_going,1); } } ITT_NOTIFY(sync_acquired, my_mutex); // Force acquire so that user's critical section receives correct values // from processor that was previously in the user's critical section. __TBB_load_with_acquire(my_going); } //! A method to acquire queuing_rw_mutex if it is free bool queuing_rw_mutex::scoped_lock::try_acquire( queuing_rw_mutex& m, bool write ) { __TBB_ASSERT( !my_mutex, "scoped_lock is already holding a mutex"); if( load(m.q_tail) ) return false; // Someone already took the lock // Must set all fields before the fetch_and_store, because once the // fetch_and_store executes, *this becomes accessible to other threads. __TBB_store_relaxed(my_prev, (scoped_lock*)0); __TBB_store_relaxed(my_next, (scoped_lock*)0); __TBB_store_relaxed(my_going, 0); // TODO: remove dead assignment? my_state = state_t(write ? STATE_WRITER : STATE_ACTIVEREADER); my_internal_lock = RELEASED; // The CAS must have release semantics, because we are // "sending" the fields initialized above to other processors. if( m.q_tail.compare_and_swap(this, NULL) ) return false; // Someone already took the lock // Force acquire so that user's critical section receives correct values // from processor that was previously in the user's critical section. // try_acquire should always have acquire semantic, even if failed. __TBB_load_with_acquire(my_going); my_mutex = &m; ITT_NOTIFY(sync_acquired, my_mutex); return true; } //! A method to release queuing_rw_mutex lock void queuing_rw_mutex::scoped_lock::release( ) { __TBB_ASSERT(my_mutex!=NULL, "no lock acquired"); ITT_NOTIFY(sync_releasing, my_mutex); if( my_state == STATE_WRITER ) { // Acquired for write // The logic below is the same as "writerUnlock", but elides // "return" from the middle of the routine. // In the statement below, acquire semantics of reading my_next is required // so that following operations with fields of my_next are safe. scoped_lock* n = __TBB_load_with_acquire(my_next); if( !n ) { if( this == my_mutex->q_tail.compare_and_swap(NULL, this) ) { // this was the only item in the queue, and the queue is now empty. goto done; } spin_wait_while_eq( my_next, (scoped_lock*)NULL ); n = __TBB_load_with_acquire(my_next); } __TBB_store_relaxed(n->my_going, 2); // protect next queue node from being destroyed too early if( n->my_state==STATE_UPGRADE_WAITING ) { // the next waiting for upgrade means this writer was upgraded before. acquire_internal_lock(); queuing_rw_mutex::scoped_lock* tmp = tricky_pointer::fetch_and_store(&(n->my_prev), NULL); n->my_state = STATE_UPGRADE_LOSER; __TBB_store_with_release(n->my_going,1); unblock_or_wait_on_internal_lock(get_flag(tmp)); } else { __TBB_ASSERT( my_state & (STATE_COMBINED_WAITINGREADER | STATE_WRITER), "unexpected state" ); __TBB_ASSERT( !( uintptr_t(__TBB_load_relaxed(n->my_prev)) & FLAG ), "use of corrupted pointer!" ); __TBB_store_relaxed(n->my_prev, (scoped_lock*)0); __TBB_store_with_release(n->my_going,1); } } else { // Acquired for read queuing_rw_mutex::scoped_lock *tmp = NULL; retry: // Addition to the original paper: Mark my_prev as in use queuing_rw_mutex::scoped_lock *pred = tricky_pointer::fetch_and_add(&my_prev, FLAG); if( pred ) { if( !(pred->try_acquire_internal_lock()) ) { // Failed to acquire the lock on pred. The predecessor either unlinks or upgrades. // In the second case, it could or could not know my "in use" flag - need to check tmp = tricky_pointer::compare_and_swap(&my_prev, pred, tricky_pointer(pred) | FLAG ); if( !(uintptr_t(tmp) & FLAG) ) { // Wait for the predecessor to change my_prev (e.g. during unlink) spin_wait_while_eq( my_prev, tricky_pointer(pred)|FLAG ); // Now owner of pred is waiting for _us_ to release its lock pred->release_internal_lock(); } // else the "in use" flag is back -> the predecessor didn't get it and will release itself; nothing to do tmp = NULL; goto retry; } __TBB_ASSERT(pred && pred->my_internal_lock==ACQUIRED, "predecessor's lock is not acquired"); __TBB_store_relaxed(my_prev, pred); acquire_internal_lock(); __TBB_store_with_release(pred->my_next,reinterpret_cast(NULL)); if( !__TBB_load_relaxed(my_next) && this != my_mutex->q_tail.compare_and_swap(pred, this) ) { spin_wait_while_eq( my_next, (void*)NULL ); } __TBB_ASSERT( !get_flag(__TBB_load_relaxed(my_next)), "use of corrupted pointer" ); // ensure acquire semantics of reading 'my_next' if( scoped_lock *const l_next = __TBB_load_with_acquire(my_next) ) { // I->next != nil, TODO: rename to n after clearing up and adapting the n in the comment two lines below // Equivalent to I->next->prev = I->prev but protected against (prev[n]&FLAG)!=0 tmp = tricky_pointer::fetch_and_store(&(l_next->my_prev), pred); // I->prev->next = I->next; __TBB_ASSERT(__TBB_load_relaxed(my_prev)==pred, NULL); __TBB_store_with_release(pred->my_next, my_next); } // Safe to release in the order opposite to acquiring which makes the code simpler pred->release_internal_lock(); } else { // No predecessor when we looked acquire_internal_lock(); // "exclusiveLock(&I->EL)" scoped_lock* n = __TBB_load_with_acquire(my_next); if( !n ) { if( this != my_mutex->q_tail.compare_and_swap(NULL, this) ) { spin_wait_while_eq( my_next, (scoped_lock*)NULL ); n = __TBB_load_relaxed(my_next); } else { goto unlock_self; } } __TBB_store_relaxed(n->my_going, 2); // protect next queue node from being destroyed too early tmp = tricky_pointer::fetch_and_store(&(n->my_prev), NULL); __TBB_store_with_release(n->my_going,1); } unlock_self: unblock_or_wait_on_internal_lock(get_flag(tmp)); } done: spin_wait_while_eq( my_going, 2 ); initialize(); } bool queuing_rw_mutex::scoped_lock::downgrade_to_reader() { __TBB_ASSERT( my_state==STATE_WRITER, "no sense to downgrade a reader" ); ITT_NOTIFY(sync_releasing, my_mutex); if( ! __TBB_load_with_acquire(my_next) ) { my_state = STATE_READER; if( this==my_mutex->q_tail ) { unsigned short old_state = my_state.compare_and_swap(STATE_ACTIVEREADER, STATE_READER); if( old_state==STATE_READER ) { // Downgrade completed return true; } } /* wait for the next to register */ spin_wait_while_eq( my_next, (void*)NULL ); } scoped_lock *const n = __TBB_load_relaxed(my_next); __TBB_ASSERT( n, "still no successor at this point!" ); if( n->my_state & STATE_COMBINED_WAITINGREADER ) __TBB_store_with_release(n->my_going,1); else if( n->my_state==STATE_UPGRADE_WAITING ) // the next waiting for upgrade means this writer was upgraded before. n->my_state = STATE_UPGRADE_LOSER; my_state = STATE_ACTIVEREADER; return true; } bool queuing_rw_mutex::scoped_lock::upgrade_to_writer() { __TBB_ASSERT( my_state==STATE_ACTIVEREADER, "only active reader can be upgraded" ); queuing_rw_mutex::scoped_lock * tmp; queuing_rw_mutex::scoped_lock * me = this; ITT_NOTIFY(sync_releasing, my_mutex); my_state = STATE_UPGRADE_REQUESTED; requested: __TBB_ASSERT( !(uintptr_t(__TBB_load_relaxed(my_next)) & FLAG), "use of corrupted pointer!" ); acquire_internal_lock(); if( this != my_mutex->q_tail.compare_and_swap(tricky_pointer(me)|FLAG, this) ) { spin_wait_while_eq( my_next, (void*)NULL ); queuing_rw_mutex::scoped_lock * n; n = tricky_pointer::fetch_and_add(&my_next, FLAG); unsigned short n_state = n->my_state; /* the next reader can be blocked by our state. the best thing to do is to unblock it */ if( n_state & STATE_COMBINED_WAITINGREADER ) __TBB_store_with_release(n->my_going,1); tmp = tricky_pointer::fetch_and_store(&(n->my_prev), this); unblock_or_wait_on_internal_lock(get_flag(tmp)); if( n_state & (STATE_COMBINED_READER | STATE_UPGRADE_REQUESTED) ) { // save n|FLAG for simplicity of following comparisons tmp = tricky_pointer(n)|FLAG; for( atomic_backoff b; __TBB_load_relaxed(my_next)==tmp; b.pause() ) { if( my_state & STATE_COMBINED_UPGRADING ) { if( __TBB_load_with_acquire(my_next)==tmp ) __TBB_store_relaxed(my_next, n); goto waiting; } } __TBB_ASSERT(__TBB_load_relaxed(my_next) != (tricky_pointer(n)|FLAG), NULL); goto requested; } else { __TBB_ASSERT( n_state & (STATE_WRITER | STATE_UPGRADE_WAITING), "unexpected state"); __TBB_ASSERT( (tricky_pointer(n)|FLAG) == __TBB_load_relaxed(my_next), NULL); __TBB_store_relaxed(my_next, n); } } else { /* We are in the tail; whoever comes next is blocked by q_tail&FLAG */ release_internal_lock(); } // if( this != my_mutex->q_tail... ) my_state.compare_and_swap(STATE_UPGRADE_WAITING, STATE_UPGRADE_REQUESTED); waiting: __TBB_ASSERT( !( intptr_t(__TBB_load_relaxed(my_next)) & FLAG ), "use of corrupted pointer!" ); __TBB_ASSERT( my_state & STATE_COMBINED_UPGRADING, "wrong state at upgrade waiting_retry" ); __TBB_ASSERT( me==this, NULL ); ITT_NOTIFY(sync_prepare, my_mutex); /* if no one was blocked by the "corrupted" q_tail, turn it back */ my_mutex->q_tail.compare_and_swap( this, tricky_pointer(me)|FLAG ); queuing_rw_mutex::scoped_lock * pred; pred = tricky_pointer::fetch_and_add(&my_prev, FLAG); if( pred ) { bool success = pred->try_acquire_internal_lock(); pred->my_state.compare_and_swap(STATE_UPGRADE_WAITING, STATE_UPGRADE_REQUESTED); if( !success ) { tmp = tricky_pointer::compare_and_swap(&my_prev, pred, tricky_pointer(pred)|FLAG ); if( uintptr_t(tmp) & FLAG ) { spin_wait_while_eq(my_prev, pred); pred = __TBB_load_relaxed(my_prev); } else { spin_wait_while_eq( my_prev, tricky_pointer(pred)|FLAG ); pred->release_internal_lock(); } } else { __TBB_store_relaxed(my_prev, pred); pred->release_internal_lock(); spin_wait_while_eq(my_prev, pred); pred = __TBB_load_relaxed(my_prev); } if( pred ) goto waiting; } else { // restore the corrupted my_prev field for possible further use (e.g. if downgrade back to reader) __TBB_store_relaxed(my_prev, pred); } __TBB_ASSERT( !pred && !__TBB_load_relaxed(my_prev), NULL ); // additional lifetime issue prevention checks // wait for the successor to finish working with my fields wait_for_release_of_internal_lock(); // now wait for the predecessor to finish working with my fields spin_wait_while_eq( my_going, 2 ); // Acquire critical section indirectly from previous owner or directly from predecessor (TODO: not clear). __TBB_control_consistency_helper(); // on either "my_mutex->q_tail" or "my_going" (TODO: not clear) bool result = ( my_state != STATE_UPGRADE_LOSER ); my_state = STATE_WRITER; __TBB_store_relaxed(my_going, 1); ITT_NOTIFY(sync_acquired, my_mutex); return result; } void queuing_rw_mutex::internal_construct() { ITT_SYNC_CREATE(this, _T("tbb::queuing_rw_mutex"), _T("")); } } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/queuing_rw_mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_queuing_rw_mutex_H #define __TBB_queuing_rw_mutex_H #include "tbb_config.h" #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif #include "atomic.h" #include "tbb_profiling.h" namespace tbb { //! Queuing reader-writer mutex with local-only spinning. /** Adapted from Krieger, Stumm, et al. pseudocode at http://www.eecg.toronto.edu/parallel/pubs_abs.html#Krieger_etal_ICPP93 @ingroup synchronization */ class queuing_rw_mutex : internal::mutex_copy_deprecated_and_disabled { public: //! Construct unacquired mutex. queuing_rw_mutex() { q_tail = NULL; #if TBB_USE_THREADING_TOOLS internal_construct(); #endif } //! Destructor asserts if the mutex is acquired, i.e. q_tail is non-NULL ~queuing_rw_mutex() { #if TBB_USE_ASSERT __TBB_ASSERT( !q_tail, "destruction of an acquired mutex"); #endif } //! The scoped locking pattern /** It helps to avoid the common problem of forgetting to release lock. It also nicely provides the "node" for queuing locks. */ class scoped_lock: internal::no_copy { //! Initialize fields to mean "no lock held". void initialize() { my_mutex = NULL; #if TBB_USE_ASSERT my_state = 0xFF; // Set to invalid state internal::poison_pointer(my_next); internal::poison_pointer(my_prev); #endif /* TBB_USE_ASSERT */ } public: //! Construct lock that has not acquired a mutex. /** Equivalent to zero-initialization of *this. */ scoped_lock() {initialize();} //! Acquire lock on given mutex. scoped_lock( queuing_rw_mutex& m, bool write=true ) { initialize(); acquire(m,write); } //! Release lock (if lock is held). ~scoped_lock() { if( my_mutex ) release(); } //! Acquire lock on given mutex. void acquire( queuing_rw_mutex& m, bool write=true ); //! Acquire lock on given mutex if free (i.e. non-blocking) bool try_acquire( queuing_rw_mutex& m, bool write=true ); //! Release lock. void release(); //! Upgrade reader to become a writer. /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ bool upgrade_to_writer(); //! Downgrade writer to become a reader. bool downgrade_to_reader(); private: //! The pointer to the mutex owned, or NULL if not holding a mutex. queuing_rw_mutex* my_mutex; //! The pointer to the previous and next competitors for a mutex scoped_lock *__TBB_atomic my_prev, *__TBB_atomic my_next; typedef unsigned char state_t; //! State of the request: reader, writer, active reader, other service states atomic my_state; //! The local spin-wait variable /** Corresponds to "spin" in the pseudocode but inverted for the sake of zero-initialization */ unsigned char __TBB_atomic my_going; //! A tiny internal lock unsigned char my_internal_lock; //! Acquire the internal lock void acquire_internal_lock(); //! Try to acquire the internal lock /** Returns true if lock was successfully acquired. */ bool try_acquire_internal_lock(); //! Release the internal lock void release_internal_lock(); //! Wait for internal lock to be released void wait_for_release_of_internal_lock(); //! A helper function void unblock_or_wait_on_internal_lock( uintptr_t ); }; void __TBB_EXPORTED_METHOD internal_construct(); // Mutex traits static const bool is_rw_mutex = true; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = true; private: //! The last competitor requesting the lock atomic q_tail; }; __TBB_DEFINE_PROFILING_SET_NAME(queuing_rw_mutex) } // namespace tbb #endif /* __TBB_queuing_rw_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/reader_writer_lock.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/reader_writer_lock.h" #include "tbb/tbb_machine.h" #include "tbb/tbb_exception.h" #include "itt_notify.h" #if defined(_MSC_VER) && defined(_Wp64) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (disable: 4244) #endif namespace tbb { namespace interface5 { const uintptr_t WFLAG1 = 0x1; // writer interested or active const uintptr_t WFLAG2 = 0x2; // writers interested, no entering readers const uintptr_t RFLAG = 0x4; // reader interested but not active const uintptr_t RC_INCR = 0x8; // to adjust reader count // Perform an atomic bitwise-OR on the operand, and return its previous value. inline uintptr_t fetch_and_or(atomic& operand, uintptr_t value) { for (tbb::internal::atomic_backoff b;;b.pause()) { uintptr_t old = operand; uintptr_t result = operand.compare_and_swap(old|value, old); if (result==old) return result; } } // Perform an atomic bitwise-AND on the operand, and return its previous value. inline uintptr_t fetch_and_and(atomic& operand, uintptr_t value) { for (tbb::internal::atomic_backoff b;;b.pause()) { uintptr_t old = operand; uintptr_t result = operand.compare_and_swap(old&value, old); if (result==old) return result; } } //! Spin WHILE the value at the location is greater than or equal to a given value /** T and U should be comparable types. */ template void spin_wait_while_geq( const volatile T& location, U value ) { tbb::internal::atomic_backoff backoff; while( location>=value ) backoff.pause(); } //! Spin UNTIL (location & value) is true. /** T and U should be comparable types. */ template void spin_wait_until_and( const volatile T& location, U value ) { tbb::internal::atomic_backoff backoff; while( !(location & value) ) backoff.pause(); } void reader_writer_lock::internal_construct() { reader_head = NULL; writer_head = NULL; writer_tail = NULL; rdr_count_and_flags = 0; my_current_writer = tbb_thread::id(); #if TBB_USE_THREADING_TOOLS ITT_SYNC_CREATE(this, _T("tbb::reader_writer_lock"), _T("")); #endif /* TBB_USE_THREADING_TOOLS */ } void reader_writer_lock::internal_destroy() { __TBB_ASSERT(rdr_count_and_flags==0, "reader_writer_lock destroyed with pending readers/writers."); __TBB_ASSERT(reader_head==NULL, "reader_writer_lock destroyed with pending readers."); __TBB_ASSERT(writer_tail==NULL, "reader_writer_lock destroyed with pending writers."); __TBB_ASSERT(writer_head==NULL, "reader_writer_lock destroyed with pending/active writers."); } // Acquires the reader_writer_lock for write. If the lock is currently held in write // mode by another context, the writer will block by spinning on a local variable. // Throws exception improper_lock if the context tries to acquire a // reader_writer_lock that it already has write ownership of. void reader_writer_lock::lock() { if (is_current_writer()) { // recursive lock attempt // we don't support recursive writer locks; throw exception tbb::internal::throw_exception(tbb::internal::eid_improper_lock); } else { scoped_lock *a_writer_lock = new scoped_lock(); (void) start_write(a_writer_lock); } } // Tries to acquire the reader_writer_lock for write. This function does not block. // Return Value: True or false, depending on whether the lock is acquired or not. // If the lock is already held by this acquiring context, try_lock() returns false. bool reader_writer_lock::try_lock() { if (is_current_writer()) { // recursive lock attempt return false; } else { scoped_lock *a_writer_lock = new scoped_lock(); a_writer_lock->status = waiting_nonblocking; return start_write(a_writer_lock); } } bool reader_writer_lock::start_write(scoped_lock *I) { tbb_thread::id id = this_tbb_thread::get_id(); scoped_lock *pred = NULL; if (I->status == waiting_nonblocking) { if ((pred = writer_tail.compare_and_swap(I, NULL)) != NULL) { delete I; return false; } } else { ITT_NOTIFY(sync_prepare, this); pred = writer_tail.fetch_and_store(I); } if (pred) pred->next = I; else { set_next_writer(I); if (I->status == waiting_nonblocking) { if (I->next) { // potentially more writers set_next_writer(I->next); } else { // no more writers writer_head.fetch_and_store(NULL); if (I != writer_tail.compare_and_swap(NULL, I)) { // an incoming writer is in the process of being added spin_wait_while_eq(I->next, (scoped_lock *)NULL); // wait for new writer to be added __TBB_ASSERT(I->next, "There should be a node following the last writer."); set_next_writer(I->next); } } delete I; return false; } } spin_wait_while_eq(I->status, waiting); ITT_NOTIFY(sync_acquired, this); my_current_writer = id; return true; } void reader_writer_lock::set_next_writer(scoped_lock *W) { writer_head = W; if (W->status == waiting_nonblocking) { if (rdr_count_and_flags.compare_and_swap(WFLAG1+WFLAG2, 0) == 0) { W->status = active; } } else { if (fetch_and_or(rdr_count_and_flags, WFLAG1) & RFLAG) { // reader present spin_wait_until_and(rdr_count_and_flags, WFLAG2); // block until readers set WFLAG2 } else { // no reader in timing window __TBB_AtomicOR(&rdr_count_and_flags, WFLAG2); } spin_wait_while_geq(rdr_count_and_flags, RC_INCR); // block until readers finish W->status = active; } } // Acquires the reader_writer_lock for read. If the lock is currently held by a writer, // this reader will block and wait until the writers are done. // Throws exception improper_lock when the context tries to acquire a reader_writer_lock // that it already has write ownership of. void reader_writer_lock::lock_read() { if (is_current_writer()) { // recursive lock attempt // we don't support writer->reader downgrade; throw exception tbb::internal::throw_exception(tbb::internal::eid_improper_lock); } else { scoped_lock_read a_reader_lock; start_read(&a_reader_lock); } } // Tries to acquire the reader_writer_lock for read. This function does not block. // Return Value: True or false, depending on whether the lock is acquired or not. bool reader_writer_lock::try_lock_read() { if (is_current_writer()) { // recursive lock attempt return false; } else { if (rdr_count_and_flags.fetch_and_add(RC_INCR) & (WFLAG1+WFLAG2)) { // writers present rdr_count_and_flags -= RC_INCR; return false; } else { // no writers ITT_NOTIFY(sync_acquired, this); return true; } } } void reader_writer_lock::start_read(scoped_lock_read *I) { ITT_NOTIFY(sync_prepare, this); I->next = reader_head.fetch_and_store(I); if (!I->next) { // first arriving reader in my group; set RFLAG, test writer flags // unblock and/or update statuses of non-blocking readers if (!(fetch_and_or(rdr_count_and_flags, RFLAG) & (WFLAG1+WFLAG2))) { // no writers unblock_readers(); } } __TBB_ASSERT(I->status == waiting || I->status == active, "Lock requests should be waiting or active before blocking."); spin_wait_while_eq(I->status, waiting); // block if (I->next) { __TBB_ASSERT(I->next->status == waiting, NULL); rdr_count_and_flags += RC_INCR; I->next->status = active; // wake successor } ITT_NOTIFY(sync_acquired, this); } void reader_writer_lock::unblock_readers() { // clear rdr interest flag, increment rdr count __TBB_ASSERT(rdr_count_and_flags&RFLAG, NULL); rdr_count_and_flags += RC_INCR-RFLAG; __TBB_ASSERT(rdr_count_and_flags >= RC_INCR, NULL); // indicate clear of window if (rdr_count_and_flags & WFLAG1 && !(rdr_count_and_flags & WFLAG2)) { __TBB_AtomicOR(&rdr_count_and_flags, WFLAG2); } // unblock waiting readers scoped_lock_read *head = reader_head.fetch_and_store(NULL); __TBB_ASSERT(head, NULL); __TBB_ASSERT(head->status == waiting, NULL); head->status = active; } // Releases the reader_writer_lock void reader_writer_lock::unlock() { if( my_current_writer!=tbb_thread::id() ) { // A writer owns the lock __TBB_ASSERT(is_current_writer(), "caller of reader_writer_lock::unlock() does not own the lock."); __TBB_ASSERT(writer_head, NULL); __TBB_ASSERT(writer_head->status==active, NULL); scoped_lock *a_writer_lock = writer_head; end_write(a_writer_lock); __TBB_ASSERT(a_writer_lock != writer_head, "Internal error: About to turn writer_head into dangling reference."); delete a_writer_lock; } else { end_read(); } } void reader_writer_lock::end_write(scoped_lock *I) { __TBB_ASSERT(I==writer_head, "Internal error: can't unlock a thread that is not holding the lock."); my_current_writer = tbb_thread::id(); ITT_NOTIFY(sync_releasing, this); if (I->next) { // potentially more writers writer_head = I->next; writer_head->status = active; } else { // No more writers; clear writer flag, test reader interest flag __TBB_ASSERT(writer_head, NULL); if (fetch_and_and(rdr_count_and_flags, ~(WFLAG1+WFLAG2)) & RFLAG) { unblock_readers(); } writer_head.fetch_and_store(NULL); if (I != writer_tail.compare_and_swap(NULL, I)) { // an incoming writer is in the process of being added spin_wait_while_eq(I->next, (scoped_lock *)NULL); // wait for new writer to be added __TBB_ASSERT(I->next, "There should be a node following the last writer."); set_next_writer(I->next); } } } void reader_writer_lock::end_read() { ITT_NOTIFY(sync_releasing, this); __TBB_ASSERT(rdr_count_and_flags >= RC_INCR, "unlock() called but no readers hold the lock."); rdr_count_and_flags -= RC_INCR; } inline bool reader_writer_lock::is_current_writer() { return my_current_writer==this_tbb_thread::get_id(); } // Construct with a blocking attempt to acquire a write lock on the passed reader_writer_lock void reader_writer_lock::scoped_lock::internal_construct (reader_writer_lock& lock) { mutex = &lock; next = NULL; status = waiting; if (mutex->is_current_writer()) { // recursive lock attempt // we don't support recursive writer locks; throw exception tbb::internal::throw_exception(tbb::internal::eid_improper_lock); } else { // this thread holds no locks (void) mutex->start_write(this); } } inline reader_writer_lock::scoped_lock::scoped_lock() : mutex(NULL), next(NULL) { status = waiting; } // Construct with a blocking attempt to acquire a write lock on the passed reader_writer_lock void reader_writer_lock::scoped_lock_read::internal_construct (reader_writer_lock& lock) { mutex = &lock; next = NULL; status = waiting; if (mutex->is_current_writer()) { // recursive lock attempt // we don't support writer->reader downgrade; throw exception tbb::internal::throw_exception(tbb::internal::eid_improper_lock); } else { // this thread holds no locks mutex->start_read(this); } } inline reader_writer_lock::scoped_lock_read::scoped_lock_read() : mutex(NULL), next(NULL) { status = waiting; } void reader_writer_lock::scoped_lock::internal_destroy() { if (mutex) { __TBB_ASSERT(mutex->is_current_writer(), "~scoped_lock() destroyed by thread different than thread that holds lock."); mutex->end_write(this); } status = invalid; } void reader_writer_lock::scoped_lock_read::internal_destroy() { if (mutex) mutex->end_read(); status = invalid; } } // namespace interface5 } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/reader_writer_lock.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_reader_writer_lock_H #define __TBB_reader_writer_lock_H #include "tbb_thread.h" #include "tbb_allocator.h" #include "atomic.h" namespace tbb { namespace interface5 { //! Writer-preference reader-writer lock with local-only spinning on readers. /** Loosely adapted from Mellor-Crummey and Scott pseudocode at http://www.cs.rochester.edu/research/synchronization/pseudocode/rw.html#s_wp @ingroup synchronization */ class reader_writer_lock : tbb::internal::no_copy { public: friend class scoped_lock; friend class scoped_lock_read; //! Status type for nodes associated with lock instances /** waiting_nonblocking: the wait state for nonblocking lock instances; for writes, these transition straight to active states; for reads, these are unused. waiting: the start and spin state for all lock instances; these will transition to active state when appropriate. Non-blocking write locks transition from this state to waiting_nonblocking immediately. active: the active state means that the lock instance holds the lock; it will transition to invalid state during node deletion invalid: the end state for all nodes; this is set in the destructor so if we encounter this state, we are looking at memory that has already been freed The state diagrams below describe the status transitions. Single arrows indicate that the thread that owns the node is responsible for the transition; double arrows indicate that any thread could make the transition. State diagram for scoped_lock status: waiting ----------> waiting_nonblocking | _____________/ | V V V active -----------------> invalid State diagram for scoped_lock_read status: waiting | V active ----------------->invalid */ enum status_t { waiting_nonblocking, waiting, active, invalid }; //! Constructs a new reader_writer_lock reader_writer_lock() { internal_construct(); } //! Destructs a reader_writer_lock object ~reader_writer_lock() { internal_destroy(); } //! The scoped lock pattern for write locks /** Scoped locks help avoid the common problem of forgetting to release the lock. This type also serves as the node for queuing locks. */ class scoped_lock : tbb::internal::no_copy { public: friend class reader_writer_lock; //! Construct with blocking attempt to acquire write lock on the passed-in lock scoped_lock(reader_writer_lock& lock) { internal_construct(lock); } //! Destructor, releases the write lock ~scoped_lock() { internal_destroy(); } void* operator new(size_t s) { return tbb::internal::allocate_via_handler_v3(s); } void operator delete(void* p) { tbb::internal::deallocate_via_handler_v3(p); } private: //! The pointer to the mutex to lock reader_writer_lock *mutex; //! The next queued competitor for the mutex scoped_lock* next; //! Status flag of the thread associated with this node atomic status; //! Construct scoped_lock that is not holding lock scoped_lock(); void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&); void __TBB_EXPORTED_METHOD internal_destroy(); }; //! The scoped lock pattern for read locks class scoped_lock_read : tbb::internal::no_copy { public: friend class reader_writer_lock; //! Construct with blocking attempt to acquire read lock on the passed-in lock scoped_lock_read(reader_writer_lock& lock) { internal_construct(lock); } //! Destructor, releases the read lock ~scoped_lock_read() { internal_destroy(); } void* operator new(size_t s) { return tbb::internal::allocate_via_handler_v3(s); } void operator delete(void* p) { tbb::internal::deallocate_via_handler_v3(p); } private: //! The pointer to the mutex to lock reader_writer_lock *mutex; //! The next queued competitor for the mutex scoped_lock_read *next; //! Status flag of the thread associated with this node atomic status; //! Construct scoped_lock_read that is not holding lock scoped_lock_read(); void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&); void __TBB_EXPORTED_METHOD internal_destroy(); }; //! Acquires the reader_writer_lock for write. /** If the lock is currently held in write mode by another context, the writer will block by spinning on a local variable. Exceptions thrown: improper_lock The context tries to acquire a reader_writer_lock that it already has write ownership of.*/ void __TBB_EXPORTED_METHOD lock(); //! Tries to acquire the reader_writer_lock for write. /** This function does not block. Return Value: True or false, depending on whether the lock is acquired or not. If the lock is already held by this acquiring context, try_lock() returns false. */ bool __TBB_EXPORTED_METHOD try_lock(); //! Acquires the reader_writer_lock for read. /** If the lock is currently held by a writer, this reader will block and wait until the writers are done. Exceptions thrown: improper_lock The context tries to acquire a reader_writer_lock that it already has write ownership of. */ void __TBB_EXPORTED_METHOD lock_read(); //! Tries to acquire the reader_writer_lock for read. /** This function does not block. Return Value: True or false, depending on whether the lock is acquired or not. */ bool __TBB_EXPORTED_METHOD try_lock_read(); //! Releases the reader_writer_lock void __TBB_EXPORTED_METHOD unlock(); private: void __TBB_EXPORTED_METHOD internal_construct(); void __TBB_EXPORTED_METHOD internal_destroy(); //! Attempts to acquire write lock /** If unavailable, spins in blocking case, returns false in non-blocking case. */ bool start_write(scoped_lock *); //! Sets writer_head to w and attempts to unblock void set_next_writer(scoped_lock *w); //! Relinquishes write lock to next waiting writer or group of readers void end_write(scoped_lock *); //! Checks if current thread holds write lock bool is_current_writer(); //! Attempts to acquire read lock /** If unavailable, spins in blocking case, returns false in non-blocking case. */ void start_read(scoped_lock_read *); //! Unblocks pending readers void unblock_readers(); //! Relinquishes read lock by decrementing counter; last reader wakes pending writer void end_read(); //! The list of pending readers atomic reader_head; //! The list of pending writers atomic writer_head; //! The last node in the list of pending writers atomic writer_tail; //! Writer that owns the mutex; tbb_thread::id() otherwise. tbb_thread::id my_current_writer; //! Status of mutex atomic rdr_count_and_flags; // used with __TBB_AtomicOR, which assumes uintptr_t }; } // namespace interface5 using interface5::reader_writer_lock; } // namespace tbb #endif /* __TBB_reader_writer_lock_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/recursive_mutex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/recursive_mutex.h" #include "itt_notify.h" namespace tbb { void recursive_mutex::scoped_lock::internal_acquire( recursive_mutex& m ) { #if _WIN32||_WIN64 switch( m.state ) { case INITIALIZED: // since we cannot look into the internal of the CriticalSection object // we won't know how many times the lock has been acquired, and thus // we won't know when we may safely set the state back to INITIALIZED // if we change the state to HELD as in mutex.cpp. thus, we won't change // the state for recursive_mutex EnterCriticalSection( &m.impl ); break; case DESTROYED: __TBB_ASSERT(false,"recursive_mutex::scoped_lock: mutex already destroyed"); break; default: __TBB_ASSERT(false,"recursive_mutex::scoped_lock: illegal mutex state"); break; } #else int error_code = pthread_mutex_lock(&m.impl); if( error_code ) tbb::internal::handle_perror(error_code,"recursive_mutex::scoped_lock: pthread_mutex_lock failed"); #endif /* _WIN32||_WIN64 */ my_mutex = &m; } void recursive_mutex::scoped_lock::internal_release() { __TBB_ASSERT( my_mutex, "recursive_mutex::scoped_lock: not holding a mutex" ); #if _WIN32||_WIN64 switch( my_mutex->state ) { case INITIALIZED: LeaveCriticalSection( &my_mutex->impl ); break; case DESTROYED: __TBB_ASSERT(false,"recursive_mutex::scoped_lock: mutex already destroyed"); break; default: __TBB_ASSERT(false,"recursive_mutex::scoped_lock: illegal mutex state"); break; } #else int error_code = pthread_mutex_unlock(&my_mutex->impl); __TBB_ASSERT_EX(!error_code, "recursive_mutex::scoped_lock: pthread_mutex_unlock failed"); #endif /* _WIN32||_WIN64 */ my_mutex = NULL; } bool recursive_mutex::scoped_lock::internal_try_acquire( recursive_mutex& m ) { #if _WIN32||_WIN64 switch( m.state ) { case INITIALIZED: break; case DESTROYED: __TBB_ASSERT(false,"recursive_mutex::scoped_lock: mutex already destroyed"); break; default: __TBB_ASSERT(false,"recursive_mutex::scoped_lock: illegal mutex state"); break; } #endif /* _WIN32||_WIN64 */ bool result; #if _WIN32||_WIN64 result = TryEnterCriticalSection(&m.impl)!=0; #else result = pthread_mutex_trylock(&m.impl)==0; #endif /* _WIN32||_WIN64 */ if( result ) my_mutex = &m; return result; } void recursive_mutex::internal_construct() { #if _WIN32||_WIN64 InitializeCriticalSectionEx(&impl, 4000, 0); state = INITIALIZED; #else pthread_mutexattr_t mtx_attr; int error_code = pthread_mutexattr_init( &mtx_attr ); if( error_code ) tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutexattr_init failed"); pthread_mutexattr_settype( &mtx_attr, PTHREAD_MUTEX_RECURSIVE ); error_code = pthread_mutex_init( &impl, &mtx_attr ); if( error_code ) tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_init failed"); pthread_mutexattr_destroy( &mtx_attr ); #endif /* _WIN32||_WIN64*/ ITT_SYNC_CREATE(&impl, _T("tbb::recursive_mutex"), _T("")); } void recursive_mutex::internal_destroy() { #if _WIN32||_WIN64 switch( state ) { case INITIALIZED: DeleteCriticalSection(&impl); break; case DESTROYED: __TBB_ASSERT(false,"recursive_mutex: already destroyed"); break; default: __TBB_ASSERT(false,"recursive_mutex: illegal state for destruction"); break; } state = DESTROYED; #else int error_code = pthread_mutex_destroy(&impl); __TBB_ASSERT_EX(!error_code,"recursive_mutex: pthread_mutex_destroy failed"); #endif /* _WIN32||_WIN64 */ } } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/recursive_mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_recursive_mutex_H #define __TBB_recursive_mutex_H #if _WIN32||_WIN64 #include "machine/windows_api.h" #else #include #endif /* _WIN32||_WIN64 */ #include #include "aligned_space.h" #include "tbb_stddef.h" #include "tbb_profiling.h" namespace tbb { //! Mutex that allows recursive mutex acquisition. /** Mutex that allows recursive mutex acquisition. @ingroup synchronization */ class recursive_mutex : internal::mutex_copy_deprecated_and_disabled { public: //! Construct unacquired recursive_mutex. recursive_mutex() { #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS internal_construct(); #else #if _WIN32||_WIN64 InitializeCriticalSectionEx(&impl, 4000, 0); #else pthread_mutexattr_t mtx_attr; int error_code = pthread_mutexattr_init( &mtx_attr ); if( error_code ) tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutexattr_init failed"); pthread_mutexattr_settype( &mtx_attr, PTHREAD_MUTEX_RECURSIVE ); error_code = pthread_mutex_init( &impl, &mtx_attr ); if( error_code ) tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_init failed"); pthread_mutexattr_destroy( &mtx_attr ); #endif /* _WIN32||_WIN64*/ #endif /* TBB_USE_ASSERT */ }; ~recursive_mutex() { #if TBB_USE_ASSERT internal_destroy(); #else #if _WIN32||_WIN64 DeleteCriticalSection(&impl); #else pthread_mutex_destroy(&impl); #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ }; class scoped_lock; friend class scoped_lock; //! The scoped locking pattern /** It helps to avoid the common problem of forgetting to release lock. It also nicely provides the "node" for queuing locks. */ class scoped_lock: internal::no_copy { public: //! Construct lock that has not acquired a recursive_mutex. scoped_lock() : my_mutex(NULL) {}; //! Acquire lock on given mutex. scoped_lock( recursive_mutex& mutex ) { #if TBB_USE_ASSERT my_mutex = &mutex; #endif /* TBB_USE_ASSERT */ acquire( mutex ); } //! Release lock (if lock is held). ~scoped_lock() { if( my_mutex ) release(); } //! Acquire lock on given mutex. void acquire( recursive_mutex& mutex ) { #if TBB_USE_ASSERT internal_acquire( mutex ); #else my_mutex = &mutex; mutex.lock(); #endif /* TBB_USE_ASSERT */ } //! Try acquire lock on given recursive_mutex. bool try_acquire( recursive_mutex& mutex ) { #if TBB_USE_ASSERT return internal_try_acquire( mutex ); #else bool result = mutex.try_lock(); if( result ) my_mutex = &mutex; return result; #endif /* TBB_USE_ASSERT */ } //! Release lock void release() { #if TBB_USE_ASSERT internal_release(); #else my_mutex->unlock(); my_mutex = NULL; #endif /* TBB_USE_ASSERT */ } private: //! The pointer to the current recursive_mutex to work recursive_mutex* my_mutex; //! All checks from acquire using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_acquire( recursive_mutex& m ); //! All checks from try_acquire using mutex.state were moved here bool __TBB_EXPORTED_METHOD internal_try_acquire( recursive_mutex& m ); //! All checks from release using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_release(); friend class recursive_mutex; }; // Mutex traits static const bool is_rw_mutex = false; static const bool is_recursive_mutex = true; static const bool is_fair_mutex = false; // C++0x compatibility interface //! Acquire lock void lock() { #if TBB_USE_ASSERT aligned_space tmp; new(tmp.begin()) scoped_lock(*this); #else #if _WIN32||_WIN64 EnterCriticalSection(&impl); #else int error_code = pthread_mutex_lock(&impl); if( error_code ) tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_lock failed"); #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_lock() { #if TBB_USE_ASSERT aligned_space tmp; return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); #else #if _WIN32||_WIN64 return TryEnterCriticalSection(&impl)!=0; #else return pthread_mutex_trylock(&impl)==0; #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ } //! Release lock void unlock() { #if TBB_USE_ASSERT aligned_space tmp; scoped_lock& s = *tmp.begin(); s.my_mutex = this; s.internal_release(); #else #if _WIN32||_WIN64 LeaveCriticalSection(&impl); #else pthread_mutex_unlock(&impl); #endif /* _WIN32||_WIN64 */ #endif /* TBB_USE_ASSERT */ } //! Return native_handle #if _WIN32||_WIN64 typedef LPCRITICAL_SECTION native_handle_type; #else typedef pthread_mutex_t* native_handle_type; #endif native_handle_type native_handle() { return (native_handle_type) &impl; } private: #if _WIN32||_WIN64 CRITICAL_SECTION impl; enum state_t { INITIALIZED=0x1234, DESTROYED=0x789A, } state; #else pthread_mutex_t impl; #endif /* _WIN32||_WIN64 */ //! All checks from mutex constructor using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_construct(); //! All checks from mutex destructor using mutex.state were moved here void __TBB_EXPORTED_METHOD internal_destroy(); }; __TBB_DEFINE_PROFILING_SET_NAME(recursive_mutex) } // namespace tbb #endif /* __TBB_recursive_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/runtime_loader.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_runtime_loader_H #define __TBB_runtime_loader_H #if ! TBB_PREVIEW_RUNTIME_LOADER #error Set TBB_PREVIEW_RUNTIME_LOADER to include runtime_loader.h #endif #include "tbb_stddef.h" #include #if _MSC_VER #if ! __TBB_NO_IMPLICIT_LINKAGE #ifdef _DEBUG #pragma comment( linker, "/nodefaultlib:tbb_debug.lib" ) #pragma comment( linker, "/defaultlib:tbbproxy_debug.lib" ) #else #pragma comment( linker, "/nodefaultlib:tbb.lib" ) #pragma comment( linker, "/defaultlib:tbbproxy.lib" ) #endif #endif #endif namespace tbb { namespace interface6 { //! Load TBB at runtime. /*! \b Usage: In source code: \code #include "tbb/runtime_loader.h" char const * path[] = { "/lib/ia32", NULL }; tbb::runtime_loader loader( path ); // Now use TBB. \endcode Link with \c tbbproxy.lib (or \c libtbbproxy.a) instead of \c tbb.lib (\c libtbb.dylib, \c libtbb.so). TBB library will be loaded at runtime from \c /lib/ia32 directory. \b Attention: All \c runtime_loader objects (in the same module, i.e. exe or dll) share some global state. The most noticeable piece of global state is loaded TBB library. There are some implications: - Only one TBB library can be loaded per module. - If one object has already loaded TBB library, another object will not load TBB. If the loaded TBB library is suitable for the second object, both will use TBB cooperatively, otherwise the second object will report an error. - \c runtime_loader objects will not work (correctly) in parallel due to absence of synchronization. */ class runtime_loader : tbb::internal::no_copy { public: //! Error mode constants. enum error_mode { em_status, //!< Save status of operation and continue. em_throw, //!< Throw an exception of tbb::runtime_loader::error_code type. em_abort //!< Print message to \c stderr and call \c abort(). }; // error_mode //! Error codes. enum error_code { ec_ok, //!< No errors. ec_bad_call, //!< Invalid function call (e. g. load() called when TBB is already loaded). ec_bad_arg, //!< Invalid argument passed. ec_bad_lib, //!< Invalid library found (e. g. \c TBB_runtime_version symbol not found). ec_bad_ver, //!< TBB found but version is not suitable. ec_no_lib //!< No suitable TBB library found. }; // error_code //! Initialize object but do not load TBB. runtime_loader( error_mode mode = em_abort ); //! Initialize object and load TBB. /*! See load() for details. If error mode is \c em_status, call status() to check whether TBB was loaded or not. */ runtime_loader( char const * path[], //!< List of directories to search TBB in. int min_ver = TBB_INTERFACE_VERSION, //!< Minimal suitable version of TBB. int max_ver = INT_MAX, //!< Maximal suitable version of TBB. error_mode mode = em_abort //!< Error mode for this object. ); //! Destroy object. ~runtime_loader(); //! Load TBB. /*! The method searches the directories specified in \c path[] array for the TBB library. When the library is found, it is loaded and its version is checked. If the version is not suitable, the library is unloaded, and the search continues. \b Note: For security reasons, avoid using relative directory names. For example, never load TBB from current (\c "."), parent (\c "..") or any other relative directory (like \c "lib" ). Use only absolute directory names (e. g. "/usr/local/lib"). For the same security reasons, avoid using system default directories (\c "") on Windows. (See http://www.microsoft.com/technet/security/advisory/2269637.mspx for details.) Neglecting these rules may cause your program to execute 3-rd party malicious code. \b Errors: - \c ec_bad_call - TBB already loaded by this object. - \c ec_bad_arg - \p min_ver and/or \p max_ver negative or zero, or \p min_ver > \p max_ver. - \c ec_bad_ver - TBB of unsuitable version already loaded by another object. - \c ec_no_lib - No suitable library found. */ error_code load( char const * path[], //!< List of directories to search TBB in. int min_ver = TBB_INTERFACE_VERSION, //!< Minimal suitable version of TBB. int max_ver = INT_MAX //!< Maximal suitable version of TBB. ); //! Report status. /*! If error mode is \c em_status, the function returns status of the last operation. */ error_code status(); private: error_mode const my_mode; error_code my_status; bool my_loaded; }; // class runtime_loader } // namespace interface6 using interface6::runtime_loader; } // namespace tbb #endif /* __TBB_runtime_loader_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/scalable_allocator.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_scalable_allocator_H #define __TBB_scalable_allocator_H /** @file */ #include /* Need ptrdiff_t and size_t from here. */ #if !_MSC_VER #include /* Need intptr_t from here. */ #endif #if !defined(__cplusplus) && __ICC==1100 #pragma warning (push) #pragma warning (disable: 991) #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if _MSC_VER >= 1400 #define __TBB_EXPORTED_FUNC __cdecl #else #define __TBB_EXPORTED_FUNC #endif /** The "malloc" analogue to allocate block of memory of size bytes. * @ingroup memory_allocation */ void * __TBB_EXPORTED_FUNC scalable_malloc (size_t size); /** The "free" analogue to discard a previously allocated piece of memory. @ingroup memory_allocation */ void __TBB_EXPORTED_FUNC scalable_free (void* ptr); /** The "realloc" analogue complementing scalable_malloc. @ingroup memory_allocation */ void * __TBB_EXPORTED_FUNC scalable_realloc (void* ptr, size_t size); /** The "calloc" analogue complementing scalable_malloc. @ingroup memory_allocation */ void * __TBB_EXPORTED_FUNC scalable_calloc (size_t nobj, size_t size); /** The "posix_memalign" analogue. @ingroup memory_allocation */ int __TBB_EXPORTED_FUNC scalable_posix_memalign (void** memptr, size_t alignment, size_t size); /** The "_aligned_malloc" analogue. @ingroup memory_allocation */ void * __TBB_EXPORTED_FUNC scalable_aligned_malloc (size_t size, size_t alignment); /** The "_aligned_realloc" analogue. @ingroup memory_allocation */ void * __TBB_EXPORTED_FUNC scalable_aligned_realloc (void* ptr, size_t size, size_t alignment); /** The "_aligned_free" analogue. @ingroup memory_allocation */ void __TBB_EXPORTED_FUNC scalable_aligned_free (void* ptr); /** The analogue of _msize/malloc_size/malloc_usable_size. Returns the usable size of a memory block previously allocated by scalable_*, or 0 (zero) if ptr does not point to such a block. @ingroup memory_allocation */ size_t __TBB_EXPORTED_FUNC scalable_msize (void* ptr); /* Results for scalable_allocation_* functions */ typedef enum { TBBMALLOC_OK, TBBMALLOC_INVALID_PARAM, TBBMALLOC_UNSUPPORTED, TBBMALLOC_NO_MEMORY, TBBMALLOC_NO_EFFECT } ScalableAllocationResult; /* Setting TBB_MALLOC_USE_HUGE_PAGES environment variable to 1 enables huge pages. scalable_allocation_mode call has priority over environment variable. */ typedef enum { TBBMALLOC_USE_HUGE_PAGES, /* value turns using huge pages on and off */ /* deprecated, kept for backward compatibility only */ USE_HUGE_PAGES = TBBMALLOC_USE_HUGE_PAGES, /* try to limit memory consumption value Bytes, clean internal buffers if limit is exceeded, but not prevents from requesting memory from OS */ TBBMALLOC_SET_SOFT_HEAP_LIMIT } AllocationModeParam; /** Set TBB allocator-specific allocation modes. @ingroup memory_allocation */ int __TBB_EXPORTED_FUNC scalable_allocation_mode(int param, intptr_t value); typedef enum { /* Clean internal allocator buffers for all threads. Returns TBBMALLOC_NO_EFFECT if no buffers cleaned, TBBMALLOC_OK if some memory released from buffers. */ TBBMALLOC_CLEAN_ALL_BUFFERS, /* Clean internal allocator buffer for current thread only. Return values same as for TBBMALLOC_CLEAN_ALL_BUFFERS. */ TBBMALLOC_CLEAN_THREAD_BUFFERS } ScalableAllocationCmd; /** Call TBB allocator-specific commands. @ingroup memory_allocation */ int __TBB_EXPORTED_FUNC scalable_allocation_command(int cmd, void *param); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #ifdef __cplusplus //! The namespace rml contains components of low-level memory pool interface. namespace rml { class MemoryPool; typedef void *(*rawAllocType)(intptr_t pool_id, size_t &bytes); typedef int (*rawFreeType)(intptr_t pool_id, void* raw_ptr, size_t raw_bytes); /* MemPoolPolicy extension must be compatible with such structure fields layout struct MemPoolPolicy { rawAllocType pAlloc; rawFreeType pFree; size_t granularity; // granularity of pAlloc allocations }; */ struct MemPoolPolicy { enum { TBBMALLOC_POOL_VERSION = 1 }; rawAllocType pAlloc; rawFreeType pFree; // granularity of pAlloc allocations. 0 means default used. size_t granularity; int version; // all memory consumed at 1st pAlloc call and never returned, // no more pAlloc calls after 1st unsigned fixedPool : 1, // memory consumed but returned only at pool termination keepAllMemory : 1, reserved : 30; MemPoolPolicy(rawAllocType pAlloc_, rawFreeType pFree_, size_t granularity_ = 0, bool fixedPool_ = false, bool keepAllMemory_ = false) : pAlloc(pAlloc_), pFree(pFree_), granularity(granularity_), version(TBBMALLOC_POOL_VERSION), fixedPool(fixedPool_), keepAllMemory(keepAllMemory_), reserved(0) {} }; // enums have same values as appropriate enums from ScalableAllocationResult // TODO: use ScalableAllocationResult in pool_create directly enum MemPoolError { // pool created successfully POOL_OK = TBBMALLOC_OK, // invalid policy parameters found INVALID_POLICY = TBBMALLOC_INVALID_PARAM, // requested pool policy is not supported by allocator library UNSUPPORTED_POLICY = TBBMALLOC_UNSUPPORTED, // lack of memory during pool creation NO_MEMORY = TBBMALLOC_NO_MEMORY, // action takes no effect NO_EFFECT = TBBMALLOC_NO_EFFECT }; MemPoolError pool_create_v1(intptr_t pool_id, const MemPoolPolicy *policy, rml::MemoryPool **pool); bool pool_destroy(MemoryPool* memPool); void *pool_malloc(MemoryPool* memPool, size_t size); void *pool_realloc(MemoryPool* memPool, void *object, size_t size); void *pool_aligned_malloc(MemoryPool* mPool, size_t size, size_t alignment); void *pool_aligned_realloc(MemoryPool* mPool, void *ptr, size_t size, size_t alignment); bool pool_reset(MemoryPool* memPool); bool pool_free(MemoryPool *memPool, void *object); } #include /* To use new with the placement argument */ /* Ensure that including this header does not cause implicit linkage with TBB */ #ifndef __TBB_NO_IMPLICIT_LINKAGE #define __TBB_NO_IMPLICIT_LINKAGE 1 #include "tbb_stddef.h" #undef __TBB_NO_IMPLICIT_LINKAGE #else #include "tbb_stddef.h" #endif #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #include // std::forward #endif namespace tbb { #if _MSC_VER && !defined(__INTEL_COMPILER) // Workaround for erroneous "unreferenced parameter" warning in method destroy. #pragma warning (push) #pragma warning (disable: 4100) #endif //! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 /** The members are ordered the same way they are in section 20.4.1 of the ISO C++ standard. @ingroup memory_allocation */ template class scalable_allocator { public: typedef typename internal::allocator_type::value_type value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef scalable_allocator other; }; scalable_allocator() throw() {} scalable_allocator( const scalable_allocator& ) throw() {} template scalable_allocator(const scalable_allocator&) throw() {} pointer address(reference x) const {return &x;} const_pointer address(const_reference x) const {return &x;} //! Allocate space for n objects. pointer allocate( size_type n, const void* /*hint*/ =0 ) { return static_cast( scalable_malloc( n * sizeof(value_type) ) ); } //! Free previously allocated block of memory void deallocate( pointer p, size_type ) { scalable_free( p ); } //! Largest value for which method allocate might succeed. size_type max_size() const throw() { size_type absolutemax = static_cast(-1) / sizeof (value_type); return (absolutemax > 0 ? absolutemax : 1); } #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC template void construct(U *p, Args&&... args) { ::new((void *)p) U(std::forward(args)...); } #else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #if __TBB_CPP11_RVALUE_REF_PRESENT void construct( pointer p, value_type&& value ) { ::new((void*)(p)) value_type( std::move( value ) ); } #endif void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} #endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC void destroy( pointer p ) {p->~value_type();} }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4100 is back //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ template<> class scalable_allocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef scalable_allocator other; }; }; template inline bool operator==( const scalable_allocator&, const scalable_allocator& ) {return true;} template inline bool operator!=( const scalable_allocator&, const scalable_allocator& ) {return false;} } // namespace tbb #if _MSC_VER #if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBBMALLOC_NO_IMPLICIT_LINKAGE) #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1 #endif #if !__TBBMALLOC_NO_IMPLICIT_LINKAGE #ifdef _DEBUG #pragma comment(lib, "tbbmalloc_debug.lib") #else #pragma comment(lib, "tbbmalloc.lib") #endif #endif #endif #endif /* __cplusplus */ #if !defined(__cplusplus) && __ICC==1100 #pragma warning (pop) #endif // ICC 11.0 warning 991 is back #endif /* __TBB_scalable_allocator_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/scheduler.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "custom_scheduler.h" #include "scheduler_utility.h" #include "governor.h" #include "market.h" #include "arena.h" #include "mailbox.h" #include "observer_proxy.h" #include "tbb/tbb_machine.h" #include "tbb/atomic.h" namespace tbb { namespace internal { //------------------------------------------------------------------------ // Library initialization //------------------------------------------------------------------------ /** Defined in tbb_main.cpp **/ extern generic_scheduler* (*AllocateSchedulerPtr)( arena*, size_t index ); inline generic_scheduler* allocate_scheduler ( arena* a, size_t index ) { return AllocateSchedulerPtr(a, index); } #if __TBB_TASK_GROUP_CONTEXT context_state_propagation_mutex_type the_context_state_propagation_mutex; uintptr_t the_context_state_propagation_epoch = 0; //! Context to be associated with dummy tasks of worker threads schedulers. /** It is never used for its direct purpose, and is introduced solely for the sake of avoiding one extra conditional branch in the end of wait_for_all method. **/ static task_group_context the_dummy_context(task_group_context::isolated); #endif /* __TBB_TASK_GROUP_CONTEXT */ void Scheduler_OneTimeInitialization ( bool itt_present ) { AllocateSchedulerPtr = itt_present ? &custom_scheduler::allocate_scheduler : &custom_scheduler::allocate_scheduler; #if __TBB_TASK_GROUP_CONTEXT // There must be no tasks belonging to this fake task group. Mark invalid for the assert __TBB_ASSERT(!(task_group_context::low_unused_state_bit & (task_group_context::low_unused_state_bit-1)), NULL); the_dummy_context.my_state = task_group_context::low_unused_state_bit; #if __TBB_TASK_PRIORITY // It should never prevent tasks from being passed to execution. the_dummy_context.my_priority = num_priority_levels - 1; #endif /* __TBB_TASK_PRIORITY */ #endif /* __TBB_TASK_GROUP_CONTEXT */ } //------------------------------------------------------------------------ // scheduler interface //------------------------------------------------------------------------ // A pure virtual destructor should still have a body // so the one for tbb::internal::scheduler::~scheduler() is provided here scheduler::~scheduler( ) {} //------------------------------------------------------------------------ // generic_scheduler //------------------------------------------------------------------------ #if _MSC_VER && !defined(__INTEL_COMPILER) // Suppress overzealous compiler warning about using 'this' in base initializer list. #pragma warning(push) #pragma warning(disable:4355) #endif generic_scheduler::generic_scheduler( arena* a, size_t index ) : my_stealing_threshold(0) , my_market(NULL) , my_random( this ) , my_free_list(NULL) #if __TBB_HOARD_NONLOCAL_TASKS , my_nonlocal_free_list(NULL) #endif , my_dummy_task(NULL) , my_ref_count(1) , my_auto_initialized(false) #if __TBB_COUNT_TASK_NODES , my_task_node_count(0) #endif /* __TBB_COUNT_TASK_NODES */ , my_small_task_count(1) // Extra 1 is a guard reference , my_return_list(NULL) #if __TBB_TASK_GROUP_CONTEXT , my_local_ctx_list_update(make_atomic(uintptr_t(0))) #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_TASK_PRIORITY , my_offloaded_tasks(NULL) , my_offloaded_task_list_tail_link(NULL) , my_local_reload_epoch(0) , my_pool_reshuffling_pending(false) #endif /* __TBB_TASK_PRIORITY */ #if __TBB_TASK_GROUP_CONTEXT , my_nonlocal_ctx_list_update(make_atomic(uintptr_t(0))) #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_SURVIVE_THREAD_SWITCH && TBB_USE_ASSERT , my_cilk_state(cs_none) #endif /* __TBB_SURVIVE_THREAD_SWITCH && TBB_USE_ASSERT */ { my_arena_index = index; my_arena_slot = 0; my_arena = a; my_innermost_running_task = NULL; my_dispatching_task = NULL; my_affinity_id = 0; #if __TBB_SCHEDULER_OBSERVER my_last_global_observer = NULL; my_last_local_observer = NULL; #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_PRIORITY my_ref_top_priority = NULL; my_ref_reload_epoch = NULL; #endif /* __TBB_TASK_PRIORITY */ my_dummy_task = &allocate_task( sizeof(task), __TBB_CONTEXT_ARG(NULL, NULL) ); #if __TBB_TASK_GROUP_CONTEXT my_context_list_head.my_prev = &my_context_list_head; my_context_list_head.my_next = &my_context_list_head; ITT_SYNC_CREATE(&my_context_list_mutex, SyncType_Scheduler, SyncObj_ContextsList); #endif /* __TBB_TASK_GROUP_CONTEXT */ my_dummy_task->prefix().ref_count = 2; ITT_SYNC_CREATE(&my_dummy_task->prefix().ref_count, SyncType_Scheduler, SyncObj_WorkerLifeCycleMgmt); ITT_SYNC_CREATE(&my_return_list, SyncType_Scheduler, SyncObj_TaskReturnList); assert_task_pool_valid(); #if __TBB_SURVIVE_THREAD_SWITCH my_cilk_unwatch_thunk.routine = NULL; #endif /* __TBB_SURVIVE_THREAD_SWITCH */ } #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning(pop) #endif // warning 4355 is back #if TBB_USE_ASSERT > 1 void generic_scheduler::assert_task_pool_valid() const { acquire_task_pool(); task** tp = my_arena_slot->task_pool_ptr; __TBB_ASSERT( my_arena_slot->my_task_pool_size >= min_task_pool_size, NULL ); const size_t H = __TBB_load_relaxed(my_arena_slot->head); // mirror const size_t T = __TBB_load_relaxed(my_arena_slot->tail); // mirror __TBB_ASSERT( H <= T, NULL ); for ( size_t i = 0; i < H; ++i ) __TBB_ASSERT( tp[i] == poisoned_ptr, "Task pool corrupted" ); for ( size_t i = H; i < T; ++i ) { __TBB_ASSERT( (uintptr_t)tp[i] + 1 > 1u, "nil or invalid task pointer in the deque" ); __TBB_ASSERT( tp[i]->prefix().state == task::ready || tp[i]->prefix().extra_state == es_task_proxy, "task in the deque has invalid state" ); } for ( size_t i = T; i < my_arena_slot->my_task_pool_size; ++i ) __TBB_ASSERT( tp[i] == poisoned_ptr, "Task pool corrupted" ); release_task_pool(); } #endif /* TBB_USE_ASSERT > 1 */ void generic_scheduler::init_stack_info () { // Stacks are growing top-down. Highest address is called "stack base", // and the lowest is "stack limit". __TBB_ASSERT( !my_stealing_threshold, "Stealing threshold has already been calculated" ); size_t stack_size = my_market->worker_stack_size(); #if USE_WINTHREAD #if defined(_MSC_VER)&&_MSC_VER<1400 && !_WIN64 NT_TIB *pteb = (NT_TIB*)__TBB_machine_get_current_teb(); #else NT_TIB *pteb = (NT_TIB*)NtCurrentTeb(); #endif __TBB_ASSERT( &pteb < pteb->StackBase && &pteb > pteb->StackLimit, "invalid stack info in TEB" ); __TBB_ASSERT( stack_size >0, "stack_size not initialized?" ); // When a thread is created with the attribute STACK_SIZE_PARAM_IS_A_RESERVATION, stack limit // in the TIB points to the committed part of the stack only. This renders the expression // "(uintptr_t)pteb->StackBase / 2 + (uintptr_t)pteb->StackLimit / 2" virtually useless. // Thus for worker threads we use the explicit stack size we used while creating them. // And for master threads we rely on the following fact and assumption: // - the default stack size of a master thread on Windows is 1M; // - if it was explicitly set by the application it is at least as large as the size of a worker stack. if ( is_worker() || stack_size < MByte ) my_stealing_threshold = (uintptr_t)pteb->StackBase - stack_size / 2; else my_stealing_threshold = (uintptr_t)pteb->StackBase - MByte / 2; #else /* USE_PTHREAD */ // There is no portable way to get stack base address in Posix, so we use // non-portable method (on all modern Linux) or the simplified approach // based on the common sense assumptions. The most important assumption // is that the main thread's stack size is not less than that of other threads. // See also comment 3 at the end of this file void *stack_base = &stack_size; #if __linux__ && !__bg__ #if __TBB_ipf void *rsb_base = __TBB_get_bsp(); #endif size_t np_stack_size = 0; void *stack_limit = NULL; pthread_attr_t np_attr_stack; if( 0 == pthread_getattr_np(pthread_self(), &np_attr_stack) ) { if ( 0 == pthread_attr_getstack(&np_attr_stack, &stack_limit, &np_stack_size) ) { #if __TBB_ipf pthread_attr_t attr_stack; if ( 0 == pthread_attr_init(&attr_stack) ) { if ( 0 == pthread_attr_getstacksize(&attr_stack, &stack_size) ) { if ( np_stack_size < stack_size ) { // We are in a secondary thread. Use reliable data. // IA-64 architecture stack is split into RSE backup and memory parts rsb_base = stack_limit; stack_size = np_stack_size/2; // Limit of the memory part of the stack stack_limit = (char*)stack_limit + stack_size; } // We are either in the main thread or this thread stack // is bigger that that of the main one. As we cannot discern // these cases we fall back to the default (heuristic) values. } pthread_attr_destroy(&attr_stack); } // IA-64 architecture stack is split into RSE backup and memory parts my_rsb_stealing_threshold = (uintptr_t)((char*)rsb_base + stack_size/2); #endif /* __TBB_ipf */ // Size of the stack free part stack_size = size_t((char*)stack_base - (char*)stack_limit); } pthread_attr_destroy(&np_attr_stack); } #endif /* __linux__ */ __TBB_ASSERT( stack_size>0, "stack size must be positive" ); my_stealing_threshold = (uintptr_t)((char*)stack_base - stack_size/2); #endif /* USE_PTHREAD */ } #if __TBB_TASK_GROUP_CONTEXT /** The function uses synchronization scheme similar to the one in the destructor of task_group_context augmented with interlocked state change of each context object. The purpose of this algo is to prevent threads doing nonlocal context destruction from accessing destroyed owner-scheduler instance still pointed to by the context object. **/ void generic_scheduler::cleanup_local_context_list () { // Detach contexts remaining in the local list bool wait_for_concurrent_destroyers_to_leave = false; uintptr_t local_count_snapshot = my_context_state_propagation_epoch; my_local_ctx_list_update.store(1); { // This is just a definition. Actual lock is acquired only in case of conflict. spin_mutex::scoped_lock lock; // Full fence prevents reordering of store to my_local_ctx_list_update with // load from my_nonlocal_ctx_list_update. atomic_fence(); // Check for the conflict with concurrent destroyer or cancellation propagator if ( my_nonlocal_ctx_list_update.load() || local_count_snapshot != the_context_state_propagation_epoch ) lock.acquire(my_context_list_mutex); // No acquire fence is necessary for loading my_context_list_head.my_next, // as the list can be updated by this thread only. context_list_node_t *node = my_context_list_head.my_next; while ( node != &my_context_list_head ) { task_group_context &ctx = __TBB_get_object_ref(task_group_context, my_node, node); __TBB_ASSERT( __TBB_load_relaxed(ctx.my_kind) != task_group_context::binding_required, "Only a context bound to a root task can be detached" ); node = node->my_next; __TBB_ASSERT( is_alive(ctx.my_version_and_traits), "Walked into a destroyed context while detaching contexts from the local list" ); // Synchronizes with ~task_group_context(). TODO: evaluate and perhaps relax if ( internal::as_atomic(ctx.my_kind).fetch_and_store(task_group_context::detached) == task_group_context::dying ) wait_for_concurrent_destroyers_to_leave = true; } } my_local_ctx_list_update.store(0); // Wait until other threads referencing this scheduler object finish with it if ( wait_for_concurrent_destroyers_to_leave ) spin_wait_until_eq( my_nonlocal_ctx_list_update, 0u ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ void generic_scheduler::free_scheduler() { __TBB_ASSERT( !my_arena_slot, NULL ); #if __TBB_TASK_GROUP_CONTEXT cleanup_local_context_list(); #endif /* __TBB_TASK_GROUP_CONTEXT */ free_task( *my_dummy_task ); #if __TBB_HOARD_NONLOCAL_TASKS while( task* t = my_nonlocal_free_list ) { task_prefix& p = t->prefix(); my_nonlocal_free_list = p.next; __TBB_ASSERT( p.origin && p.origin!=this, NULL ); free_nonlocal_small_task(*t); } #endif // k accounts for a guard reference and each task that we deallocate. intptr_t k = 1; for(;;) { while( task* t = my_free_list ) { my_free_list = t->prefix().next; deallocate_task(*t); ++k; } if( my_return_list==plugged_return_list() ) break; my_free_list = (task*)__TBB_FetchAndStoreW( &my_return_list, (intptr_t)plugged_return_list() ); } #if __TBB_COUNT_TASK_NODES my_market->update_task_node_count( my_task_node_count ); #endif /* __TBB_COUNT_TASK_NODES */ // Update my_small_task_count last. Doing so sooner might cause another thread to free *this. __TBB_ASSERT( my_small_task_count>=k, "my_small_task_count corrupted" ); governor::sign_off(this); if( __TBB_FetchAndAddW( &my_small_task_count, -k )==k ) NFS_Free( this ); } task& generic_scheduler::allocate_task( size_t number_of_bytes, __TBB_CONTEXT_ARG(task* parent, task_group_context* context) ) { GATHER_STATISTIC(++my_counters.active_tasks); task *t; if( number_of_bytes<=quick_task_size ) { #if __TBB_HOARD_NONLOCAL_TASKS if( (t = my_nonlocal_free_list) ) { GATHER_STATISTIC(--my_counters.free_list_length); __TBB_ASSERT( t->state()==task::freed, "free list of tasks is corrupted" ); my_nonlocal_free_list = t->prefix().next; } else #endif if( (t = my_free_list) ) { GATHER_STATISTIC(--my_counters.free_list_length); __TBB_ASSERT( t->state()==task::freed, "free list of tasks is corrupted" ); my_free_list = t->prefix().next; } else if( my_return_list ) { // No fence required for read of my_return_list above, because __TBB_FetchAndStoreW has a fence. t = (task*)__TBB_FetchAndStoreW( &my_return_list, 0 ); // with acquire __TBB_ASSERT( t, "another thread emptied the my_return_list" ); __TBB_ASSERT( t->prefix().origin==this, "task returned to wrong my_return_list" ); ITT_NOTIFY( sync_acquired, &my_return_list ); my_free_list = t->prefix().next; } else { t = (task*)((char*)NFS_Allocate( 1, task_prefix_reservation_size+quick_task_size, NULL ) + task_prefix_reservation_size ); #if __TBB_COUNT_TASK_NODES ++my_task_node_count; #endif /* __TBB_COUNT_TASK_NODES */ t->prefix().origin = this; t->prefix().next = 0; ++my_small_task_count; } #if __TBB_PREFETCHING task *t_next = t->prefix().next; if( !t_next ) { // the task was last in the list #if __TBB_HOARD_NONLOCAL_TASKS if( my_free_list ) t_next = my_free_list; else #endif if( my_return_list ) // enable prefetching, gives speedup t_next = my_free_list = (task*)__TBB_FetchAndStoreW( &my_return_list, 0 ); } if( t_next ) { // gives speedup for both cache lines __TBB_cl_prefetch(t_next); __TBB_cl_prefetch(&t_next->prefix()); } #endif /* __TBB_PREFETCHING */ } else { GATHER_STATISTIC(++my_counters.big_tasks); t = (task*)((char*)NFS_Allocate( 1, task_prefix_reservation_size+number_of_bytes, NULL ) + task_prefix_reservation_size ); #if __TBB_COUNT_TASK_NODES ++my_task_node_count; #endif /* __TBB_COUNT_TASK_NODES */ t->prefix().origin = NULL; } task_prefix& p = t->prefix(); #if __TBB_TASK_GROUP_CONTEXT p.context = context; #endif /* __TBB_TASK_GROUP_CONTEXT */ // Obsolete. But still in use, so has to be assigned correct value here. p.owner = this; p.ref_count = 0; // Obsolete. Assign some not outrageously out-of-place value for a while. p.depth = 0; p.parent = parent; // In TBB 2.1 and later, the constructor for task sets extra_state to indicate the version of the tbb/task.h header. // In TBB 2.0 and earlier, the constructor leaves extra_state as zero. p.extra_state = 0; p.affinity = 0; p.state = task::allocated; return *t; } void generic_scheduler::free_nonlocal_small_task( task& t ) { __TBB_ASSERT( t.state()==task::freed, NULL ); generic_scheduler& s = *static_cast(t.prefix().origin); __TBB_ASSERT( &s!=this, NULL ); for(;;) { task* old = s.my_return_list; if( old==plugged_return_list() ) break; // Atomically insert t at head of s.my_return_list t.prefix().next = old; ITT_NOTIFY( sync_releasing, &s.my_return_list ); if( as_atomic(s.my_return_list).compare_and_swap(&t, old )==old ) { #if __TBB_PREFETCHING __TBB_cl_evict(&t.prefix()); __TBB_cl_evict(&t); #endif return; } } deallocate_task(t); if( __TBB_FetchAndDecrementWrelease( &s.my_small_task_count )==1 ) { // We freed the last task allocated by scheduler s, so it's our responsibility // to free the scheduler. NFS_Free( &s ); } } size_t generic_scheduler::prepare_task_pool ( size_t num_tasks ) { size_t T = __TBB_load_relaxed(my_arena_slot->tail); // mirror if ( T + num_tasks <= my_arena_slot->my_task_pool_size ) return T; acquire_task_pool(); size_t H = __TBB_load_relaxed(my_arena_slot->head); // mirror T -= H; size_t new_size = T + num_tasks; __TBB_ASSERT(!my_arena_slot->my_task_pool_size || my_arena_slot->my_task_pool_size >= min_task_pool_size, NULL); if( !my_arena_slot->my_task_pool_size ) { __TBB_ASSERT( !in_arena() && !my_arena_slot->task_pool_ptr, NULL ); if( new_size < min_task_pool_size ) new_size = min_task_pool_size; my_arena_slot->allocate_task_pool( new_size ); } // If the free space at the beginning of the task pool is too short, we // are likely facing a pathological single-producer-multiple-consumers // scenario, and thus it's better to expand the task pool else if ( new_size <= my_arena_slot->my_task_pool_size - min_task_pool_size/4 ) { // Relocate the busy part to the beginning of the deque memmove( my_arena_slot->task_pool_ptr, my_arena_slot->task_pool_ptr + H, T * sizeof(task*) ); my_arena_slot->fill_with_canary_pattern( T, my_arena_slot->tail ); commit_relocated_tasks(T); } else { // Grow task pool. As this operation is rare, and its cost is asymptotically // amortizable, we can tolerate new task pool allocation done under the lock. if ( new_size < 2 * my_arena_slot->my_task_pool_size ) new_size = 2 * my_arena_slot->my_task_pool_size; task** old_pool = my_arena_slot->task_pool_ptr; my_arena_slot->allocate_task_pool( new_size ); // updates my_task_pool_size __TBB_ASSERT( T <= my_arena_slot->my_task_pool_size, "new task pool is too short" ); memcpy( my_arena_slot->task_pool_ptr, old_pool + H, T * sizeof(task*) ); commit_relocated_tasks(T); __TBB_ASSERT( old_pool, "attempt to free NULL TaskPool" ); NFS_Free( old_pool ); } assert_task_pool_valid(); return T; } /** ATTENTION: This method is mostly the same as generic_scheduler::lock_task_pool(), with a little different logic of slot state checks (slot is either locked or points to our task pool). Thus if either of them is changed, consider changing the counterpart as well. **/ inline void generic_scheduler::acquire_task_pool() const { if ( !in_arena() ) return; // we are not in arena - nothing to lock bool sync_prepare_done = false; for( atomic_backoff b;;b.pause() ) { #if TBB_USE_ASSERT __TBB_ASSERT( my_arena_slot == my_arena->my_slots + my_arena_index, "invalid arena slot index" ); // Local copy of the arena slot task pool pointer is necessary for the next // assertion to work correctly to exclude asynchronous state transition effect. task** tp = my_arena_slot->task_pool; __TBB_ASSERT( tp == LockedTaskPool || tp == my_arena_slot->task_pool_ptr, "slot ownership corrupt?" ); #endif if( my_arena_slot->task_pool != LockedTaskPool && as_atomic(my_arena_slot->task_pool).compare_and_swap(LockedTaskPool, my_arena_slot->task_pool_ptr ) == my_arena_slot->task_pool_ptr ) { // We acquired our own slot ITT_NOTIFY(sync_acquired, my_arena_slot); break; } else if( !sync_prepare_done ) { // Start waiting ITT_NOTIFY(sync_prepare, my_arena_slot); sync_prepare_done = true; } // Someone else acquired a lock, so pause and do exponential backoff. } __TBB_ASSERT( my_arena_slot->task_pool == LockedTaskPool, "not really acquired task pool" ); } // generic_scheduler::acquire_task_pool inline void generic_scheduler::release_task_pool() const { if ( !in_arena() ) return; // we are not in arena - nothing to unlock __TBB_ASSERT( my_arena_slot, "we are not in arena" ); __TBB_ASSERT( my_arena_slot->task_pool == LockedTaskPool, "arena slot is not locked" ); ITT_NOTIFY(sync_releasing, my_arena_slot); __TBB_store_with_release( my_arena_slot->task_pool, my_arena_slot->task_pool_ptr ); } /** ATTENTION: This method is mostly the same as generic_scheduler::acquire_task_pool(), with a little different logic of slot state checks (slot can be empty, locked or point to any task pool other than ours, and asynchronous transitions between all these states are possible). Thus if any of them is changed, consider changing the counterpart as well **/ inline task** generic_scheduler::lock_task_pool( arena_slot* victim_arena_slot ) const { task** victim_task_pool; bool sync_prepare_done = false; for( atomic_backoff backoff;; /*backoff pause embedded in the loop*/) { victim_task_pool = victim_arena_slot->task_pool; // NOTE: Do not use comparison of head and tail indices to check for // the presence of work in the victim's task pool, as they may give // incorrect indication because of task pool relocations and resizes. if ( victim_task_pool == EmptyTaskPool ) { // The victim thread emptied its task pool - nothing to lock if( sync_prepare_done ) ITT_NOTIFY(sync_cancel, victim_arena_slot); break; } if( victim_task_pool != LockedTaskPool && as_atomic(victim_arena_slot->task_pool).compare_and_swap(LockedTaskPool, victim_task_pool ) == victim_task_pool ) { // We've locked victim's task pool ITT_NOTIFY(sync_acquired, victim_arena_slot); break; } else if( !sync_prepare_done ) { // Start waiting ITT_NOTIFY(sync_prepare, victim_arena_slot); sync_prepare_done = true; } GATHER_STATISTIC( ++my_counters.thieves_conflicts ); // Someone else acquired a lock, so pause and do exponential backoff. #if __TBB_STEALING_ABORT_ON_CONTENTION if(!backoff.bounded_pause()) { // the 16 was acquired empirically and a theory behind it supposes // that number of threads becomes much bigger than number of // tasks which can be spawned by one thread causing excessive contention. // TODO: However even small arenas can benefit from the abort on contention // if preemption of a thief is a problem if(my_arena->my_limit >= 16) return EmptyTaskPool; __TBB_Yield(); } #else backoff.pause(); #endif } __TBB_ASSERT( victim_task_pool == EmptyTaskPool || (victim_arena_slot->task_pool == LockedTaskPool && victim_task_pool != LockedTaskPool), "not really locked victim's task pool?" ); return victim_task_pool; } // generic_scheduler::lock_task_pool inline void generic_scheduler::unlock_task_pool( arena_slot* victim_arena_slot, task** victim_task_pool ) const { __TBB_ASSERT( victim_arena_slot, "empty victim arena slot pointer" ); __TBB_ASSERT( victim_arena_slot->task_pool == LockedTaskPool, "victim arena slot is not locked" ); ITT_NOTIFY(sync_releasing, victim_arena_slot); __TBB_store_with_release( victim_arena_slot->task_pool, victim_task_pool ); } inline task* generic_scheduler::prepare_for_spawning( task* t ) { __TBB_ASSERT( t->state()==task::allocated, "attempt to spawn task that is not in 'allocated' state" ); t->prefix().state = task::ready; #if TBB_USE_ASSERT if( task* parent = t->parent() ) { internal::reference_count ref_count = parent->prefix().ref_count; __TBB_ASSERT( ref_count>=0, "attempt to spawn task whose parent has a ref_count<0" ); __TBB_ASSERT( ref_count!=0, "attempt to spawn task whose parent has a ref_count==0 (forgot to set_ref_count?)" ); parent->prefix().extra_state |= es_ref_count_active; } #endif /* TBB_USE_ASSERT */ affinity_id dst_thread = t->prefix().affinity; __TBB_ASSERT( dst_thread == 0 || is_version_3_task(*t), "backwards compatibility to TBB 2.0 tasks is broken" ); if( dst_thread != 0 && dst_thread != my_affinity_id ) { task_proxy& proxy = (task_proxy&)allocate_task( sizeof(task_proxy), __TBB_CONTEXT_ARG(NULL, NULL) ); // Mark as a proxy proxy.prefix().extra_state = es_task_proxy; proxy.outbox = &my_arena->mailbox(dst_thread); // Mark proxy as present in both locations (sender's task pool and destination mailbox) proxy.task_and_tag = intptr_t(t) | task_proxy::location_mask; #if __TBB_TASK_PRIORITY proxy.prefix().context = t->prefix().context; #endif /* __TBB_TASK_PRIORITY */ ITT_NOTIFY( sync_releasing, proxy.outbox ); // Mail the proxy - after this point t may be destroyed by another thread at any moment. proxy.outbox->push(proxy); return &proxy; } return t; } /** Conceptually, this method should be a member of class scheduler. But doing so would force us to publish class scheduler in the headers. */ void generic_scheduler::local_spawn( task& first, task*& next ) { __TBB_ASSERT( governor::is_set(this), NULL ); if ( &first.prefix().next == &next ) { // Single task is being spawned size_t T = prepare_task_pool( 1 ); my_arena_slot->task_pool_ptr[T] = prepare_for_spawning( &first ); commit_spawned_tasks( T + 1 ); } else { // Task list is being spawned task *arr[min_task_pool_size]; fast_reverse_vector tasks(arr, min_task_pool_size); task *t_next = NULL; for( task* t = &first; ; t = t_next ) { // If t is affinitized to another thread, it may already be executed // and destroyed by the time prepare_for_spawning returns. // So milk it while it is alive. bool end = &t->prefix().next == &next; t_next = t->prefix().next; tasks.push_back( prepare_for_spawning(t) ); if( end ) break; } size_t num_tasks = tasks.size(); size_t T = prepare_task_pool( num_tasks ); tasks.copy_memory( my_arena_slot->task_pool_ptr + T ); commit_spawned_tasks( T + num_tasks ); } if ( !in_arena() ) enter_arena(); my_arena->advertise_new_work(); assert_task_pool_valid(); } void generic_scheduler::local_spawn_root_and_wait( task& first, task*& next ) { __TBB_ASSERT( governor::is_set(this), NULL ); __TBB_ASSERT( &first, NULL ); auto_empty_task dummy( __TBB_CONTEXT_ARG(this, first.prefix().context) ); internal::reference_count n = 0; for( task* t=&first; ; t=t->prefix().next ) { ++n; __TBB_ASSERT( !t->prefix().parent, "not a root task, or already running" ); t->prefix().parent = &dummy; if( &t->prefix().next==&next ) break; #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT( t->prefix().context == t->prefix().next->prefix().context, "all the root tasks in list must share the same context"); #endif /* __TBB_TASK_GROUP_CONTEXT */ } dummy.prefix().ref_count = n+1; if( n>1 ) local_spawn( *first.prefix().next, next ); local_wait_for_all( dummy, &first ); } void tbb::internal::generic_scheduler::spawn( task& first, task*& next ) { governor::local_scheduler()->local_spawn( first, next ); } void tbb::internal::generic_scheduler::spawn_root_and_wait( task& first, task*& next ) { governor::local_scheduler()->local_spawn_root_and_wait( first, next ); } void tbb::internal::generic_scheduler::enqueue( task& t, void* prio ) { generic_scheduler *s = governor::local_scheduler(); // these redirections are due to bw-compatibility, consider reworking some day __TBB_ASSERT( s->my_arena, "thread is not in any arena" ); s->my_arena->enqueue_task(t, (intptr_t)prio, s->my_random ); } #if __TBB_TASK_PRIORITY class auto_indicator : no_copy { volatile bool& my_indicator; public: auto_indicator ( volatile bool& indicator ) : my_indicator(indicator) { my_indicator = true ;} ~auto_indicator () { my_indicator = false; } }; task* generic_scheduler::winnow_task_pool () { GATHER_STATISTIC( ++my_counters.prio_winnowings ); __TBB_ASSERT( in_arena(), NULL ); __TBB_ASSERT( my_offloaded_tasks, "At least one task is expected to be already offloaded" ); // To eliminate possible sinking of the store to the indicator below the subsequent // store to my_arena_slot->tail, the stores should have either been separated // by full fence or both use release fences. And resetting indicator should have // been done with release fence. But since this is just an optimization, and // the corresponding checking sequence in arena::is_out_of_work() is not atomic // anyway, fences aren't used, so that not to penalize warmer path. auto_indicator indicator(my_pool_reshuffling_pending); // The purpose of the synchronization algorithm here is for the owner thread // to avoid locking task pool most of the time. size_t T0 = __TBB_load_relaxed(my_arena_slot->tail); __TBB_store_relaxed( my_arena_slot->tail, __TBB_load_relaxed(my_arena_slot->head) - 1 ); atomic_fence(); size_t H = __TBB_load_relaxed(my_arena_slot->head); size_t T = __TBB_load_relaxed(my_arena_slot->tail); __TBB_ASSERT( (intptr_t)T <= (intptr_t)T0, NULL); __TBB_ASSERT( (intptr_t)H >= (intptr_t)T || (H == T0 && T == T0), NULL ); bool acquired = false; if ( H == T ) { // Either no contention with thieves during arbitration protocol execution or ... if ( H >= T0 ) { // ... the task pool got empty reset_deque_and_leave_arena( /*locked=*/false ); return NULL; } } else { // Contention with thieves detected. Now without taking lock it is impossible // to define the current head value because of its jitter caused by continuing // stealing attempts (the pool is not locked so far). acquired = true; acquire_task_pool(); H = __TBB_load_relaxed(my_arena_slot->head); if ( H >= T0 ) { reset_deque_and_leave_arena( /*locked=*/true ); return NULL; } } size_t src, dst = T0; // Find the first task to offload. for ( src = H; src < T0; ++src ) { task &t = *my_arena_slot->task_pool_ptr[src]; intptr_t p = priority(t); if ( p < *my_ref_top_priority ) { // Position of the first offloaded task will be the starting point // for relocation of subsequent tasks that survive winnowing. dst = src; offload_task( t, p ); break; } } for ( ++src; src < T0; ++src ) { task &t = *my_arena_slot->task_pool_ptr[src]; intptr_t p = priority(t); if ( p < *my_ref_top_priority ) offload_task( t, p ); else my_arena_slot->task_pool_ptr[dst++] = &t; } __TBB_ASSERT( T0 >= dst, NULL ); task *t = H < dst ? my_arena_slot->task_pool_ptr[--dst] : NULL; if ( H == dst ) { // No tasks remain the primary pool reset_deque_and_leave_arena( acquired ); } else if ( acquired ) { __TBB_ASSERT( !is_poisoned(my_arena_slot->task_pool_ptr[H]), NULL ); __TBB_store_relaxed( my_arena_slot->tail, dst ); release_task_pool(); } else { __TBB_ASSERT( !is_poisoned(my_arena_slot->task_pool_ptr[H]), NULL ); // Release fence is necessary to make sure possibly relocated task pointers // become visible to potential thieves __TBB_store_with_release( my_arena_slot->tail, dst ); } my_arena_slot->fill_with_canary_pattern( dst, T0 ); assert_task_pool_valid(); return t; } task* generic_scheduler::reload_tasks ( task*& offloaded_tasks, task**& offloaded_task_list_link, intptr_t top_priority ) { GATHER_STATISTIC( ++my_counters.prio_reloads ); __TBB_ASSERT( !in_arena(), NULL ); task *arr[min_task_pool_size]; fast_reverse_vector tasks(arr, min_task_pool_size); task **link = &offloaded_tasks; task *t; while ( (t = *link) ) { task** next_ptr = &t->prefix().next_offloaded; if ( priority(*t) >= top_priority ) { tasks.push_back( t ); // Note that owner is an alias of next_offloaded. Thus the following // assignment overwrites *next_ptr task* next = *next_ptr; t->prefix().owner = this; __TBB_ASSERT( t->prefix().state == task::ready || t->prefix().extra_state == es_task_proxy, NULL ); *link = next; } else { link = next_ptr; } } if ( link == &offloaded_tasks ) { offloaded_tasks = NULL; #if TBB_USE_ASSERT offloaded_task_list_link = NULL; #endif /* TBB_USE_ASSERT */ } else { __TBB_ASSERT( link, NULL ); // Mark end of list *link = NULL; offloaded_task_list_link = link; } __TBB_ASSERT( link, NULL ); size_t num_tasks = tasks.size(); if ( num_tasks ) { GATHER_STATISTIC( ++my_counters.prio_tasks_reloaded ); size_t T = prepare_task_pool( num_tasks ); tasks.copy_memory( my_arena_slot->task_pool_ptr + T ); if ( --num_tasks ) { commit_spawned_tasks( T += num_tasks ); enter_arena(); my_arena->advertise_new_work(); } __TBB_ASSERT( T == __TBB_load_relaxed(my_arena_slot->tail), NULL ); __TBB_ASSERT( T < my_arena_slot->my_task_pool_size, NULL ); t = my_arena_slot->task_pool_ptr[T]; poison_pointer(my_arena_slot->task_pool_ptr[T]); assert_task_pool_valid(); } return t; } task* generic_scheduler::reload_tasks () { uintptr_t reload_epoch = *my_ref_reload_epoch; __TBB_ASSERT( my_offloaded_tasks, NULL ); __TBB_ASSERT( my_local_reload_epoch <= reload_epoch || my_local_reload_epoch - reload_epoch > uintptr_t(-1)/2, "Reload epoch counter overflow?" ); if ( my_local_reload_epoch == reload_epoch ) return NULL; __TBB_ASSERT( my_offloaded_tasks, NULL ); intptr_t top_priority = effective_reference_priority(); __TBB_ASSERT( (uintptr_t)top_priority < (uintptr_t)num_priority_levels, NULL ); task *t = reload_tasks( my_offloaded_tasks, my_offloaded_task_list_tail_link, top_priority ); if ( my_offloaded_tasks && (my_arena->my_bottom_priority >= top_priority || !my_arena->my_num_workers_requested) ) { // Safeguard against deliberately relaxed synchronization while checking // for the presence of work in arena (so that not to impact hot paths). // Arena may be reset to empty state when offloaded low priority tasks // are still present. This results in both bottom and top priority bounds // becoming 'normal', which makes offloaded low priority tasks unreachable. // Update arena's bottom priority to accommodate them. // First indicate the presence of lower-priority tasks my_market->update_arena_priority( *my_arena, priority(*my_offloaded_tasks) ); // Then mark arena as full to unlock arena priority level adjustment // by arena::is_out_of_work(), and ensure worker's presence my_arena->advertise_new_work(); } my_local_reload_epoch = reload_epoch; return t; } #endif /* __TBB_TASK_PRIORITY */ inline task* generic_scheduler::get_task() { __TBB_ASSERT( in_arena(), NULL ); task* result = NULL; size_t T = __TBB_load_relaxed(my_arena_slot->tail); // mirror retry: __TBB_store_relaxed(my_arena_slot->tail, --T); atomic_fence(); if ( (intptr_t)__TBB_load_relaxed(my_arena_slot->head) > (intptr_t)T ) { acquire_task_pool(); size_t H = __TBB_load_relaxed(my_arena_slot->head); // mirror if ( (intptr_t)H <= (intptr_t)T ) { // The thief backed off - grab the task result = my_arena_slot->task_pool_ptr[T]; __TBB_ASSERT( !is_poisoned(result), NULL ); poison_pointer( my_arena_slot->task_pool_ptr[T] ); } else { __TBB_ASSERT ( H == __TBB_load_relaxed(my_arena_slot->head) && T == __TBB_load_relaxed(my_arena_slot->tail) && H == T + 1, "victim/thief arbitration algorithm failure" ); } if ( (intptr_t)H < (intptr_t)T ) release_task_pool(); else reset_deque_and_leave_arena( /*locked=*/true ); } else { __TBB_control_consistency_helper(); // on my_arena_slot->head result = my_arena_slot->task_pool_ptr[T]; __TBB_ASSERT( !is_poisoned(result), NULL ); poison_pointer( my_arena_slot->task_pool_ptr[T] ); } if( result && is_proxy(*result) ) { task_proxy &tp = *(task_proxy*)result; result = tp.extract_task(); if( !result ) { // Proxy was empty, so it's our responsibility to free it free_task(tp); if ( in_arena() ) goto retry; __TBB_ASSERT( is_quiescent_local_task_pool_reset(), NULL ); return NULL; } GATHER_STATISTIC( ++my_counters.proxies_executed ); // Following assertion should be true because TBB 2.0 tasks never specify affinity, and hence are not proxied. __TBB_ASSERT( is_version_3_task(*result), "backwards compatibility with TBB 2.0 broken" ); // Task affinity has changed. my_innermost_running_task = result; result->note_affinity(my_affinity_id); } __TBB_ASSERT( result || is_quiescent_local_task_pool_reset(), NULL ); return result; } // generic_scheduler::get_task task* generic_scheduler::steal_task( arena_slot& victim_slot ) { task** victim_pool = lock_task_pool( &victim_slot ); if ( !victim_pool ) return NULL; task* result = NULL; size_t H = __TBB_load_relaxed(victim_slot.head); // mirror const size_t H0 = H; int skip_and_bump = 0; // +1 for skipped task and +1 for bumped head&tail retry: __TBB_store_relaxed( victim_slot.head, ++H ); atomic_fence(); if ( (intptr_t)H > (intptr_t)__TBB_load_relaxed(victim_slot.tail) ) { // Stealing attempt failed, deque contents has not been changed by us GATHER_STATISTIC( ++my_counters.thief_backoffs ); __TBB_store_relaxed( victim_slot.head, /*dead: H = */ H0 ); skip_and_bump++; // trigger that we bumped head and tail __TBB_ASSERT ( !result, NULL ); } else { __TBB_control_consistency_helper(); // on victim_slot.tail result = victim_pool[H-1]; __TBB_ASSERT( !is_poisoned(result), NULL ); if( is_proxy(*result) ) { task_proxy& tp = *static_cast(result); // If mailed task is likely to be grabbed by its destination thread, skip it. if ( task_proxy::is_shared(tp.task_and_tag) && tp.outbox->recipient_is_idle() ) { GATHER_STATISTIC( ++my_counters.proxies_bypassed ); result = NULL; __TBB_ASSERT( skip_and_bump < 2, NULL ); skip_and_bump = 1; // note we skipped a task goto retry; } } __TBB_ASSERT( result, NULL ); // emit "task was consumed" signal ITT_NOTIFY(sync_acquired, (void*)((uintptr_t)&victim_slot+sizeof(uintptr_t))); const size_t H1 = H0 + 1; if ( H1 < H ) { // Some proxies in the task pool have been bypassed. Need to close // the hole left by the stolen task. The following variant: // victim_pool[H-1] = victim_pool[H0]; // is of constant time, but creates a potential for degrading stealing // mechanism efficiency and growing owner's stack size too much because // of moving earlier split off (and thus larger) chunks closer to owner's // end of the deque (tail). // So we use linear time variant that is likely to be amortized to be // near-constant time, though, and preserves stealing efficiency premises. // These changes in the deque must be released to the owner. memmove( victim_pool + H1, victim_pool + H0, (H - H1) * sizeof(task*) ); __TBB_store_with_release( victim_slot.head, /*dead: H = */ H1 ); if ( (intptr_t)H >= (intptr_t)__TBB_load_relaxed(victim_slot.tail) ) skip_and_bump++; // trigger that we bumped head and tail } poison_pointer( victim_pool[H0] ); } unlock_task_pool( &victim_slot, victim_pool ); __TBB_ASSERT( skip_and_bump <= 2, NULL ); #if __TBB_PREFETCHING __TBB_cl_evict(&victim_slot.head); __TBB_cl_evict(&victim_slot.tail); #endif if( --skip_and_bump > 0 ) { // if both: task skipped and head&tail bumped // Synchronize with snapshot as we bumped head and tail which can falsely trigger EMPTY state atomic_fence(); my_arena->advertise_new_work(); } return result; } task* generic_scheduler::get_mailbox_task() { __TBB_ASSERT( my_affinity_id>0, "not in arena" ); while ( task_proxy* const tp = my_inbox.pop() ) { if ( task* result = tp->extract_task() ) { ITT_NOTIFY( sync_acquired, my_inbox.outbox() ); result->prefix().extra_state |= es_task_is_stolen; return result; } // We have exclusive access to the proxy, and can destroy it. free_task(*tp); } return NULL; } // TODO: Rename to publish_task_pool void generic_scheduler::enter_arena() { __TBB_ASSERT ( my_arena, "no arena: initialization not completed?" ); __TBB_ASSERT ( my_arena_index < my_arena->my_num_slots, "arena slot index is out-of-bound" ); __TBB_ASSERT ( my_arena_slot == &my_arena->my_slots[my_arena_index], NULL); __TBB_ASSERT ( my_arena_slot->task_pool == EmptyTaskPool, "someone else grabbed my arena slot?" ); __TBB_ASSERT ( __TBB_load_relaxed(my_arena_slot->head) < __TBB_load_relaxed(my_arena_slot->tail), "entering arena without tasks to share" ); // Release signal on behalf of previously spawned tasks (when this thread was not in arena yet) ITT_NOTIFY(sync_releasing, my_arena_slot); __TBB_store_with_release( my_arena_slot->task_pool, my_arena_slot->task_pool_ptr ); } void generic_scheduler::leave_arena() { __TBB_ASSERT( in_arena(), "Not in arena" ); // Do not reset my_arena_index. It will be used to (attempt to) re-acquire the slot next time __TBB_ASSERT( &my_arena->my_slots[my_arena_index] == my_arena_slot, "arena slot and slot index mismatch" ); __TBB_ASSERT ( my_arena_slot->task_pool == LockedTaskPool, "Task pool must be locked when leaving arena" ); __TBB_ASSERT ( is_quiescent_local_task_pool_empty(), "Cannot leave arena when the task pool is not empty" ); ITT_NOTIFY(sync_releasing, &my_arena->my_slots[my_arena_index]); // No release fence is necessary here as this assignment precludes external // accesses to the local task pool when becomes visible. Thus it is harmless // if it gets hoisted above preceding local bookkeeping manipulations. __TBB_store_relaxed( my_arena_slot->task_pool, EmptyTaskPool ); } generic_scheduler* generic_scheduler::create_worker( market& m, size_t index ) { generic_scheduler* s = allocate_scheduler( NULL, index ); // index is not a real slot in arena #if __TBB_TASK_GROUP_CONTEXT s->my_dummy_task->prefix().context = &the_dummy_context; // Sync up the local cancellation state with the global one. No need for fence here. s->my_context_state_propagation_epoch = the_context_state_propagation_epoch; #endif /* __TBB_TASK_GROUP_CONTEXT */ s->my_market = &m; s->init_stack_info(); #if __TBB_TASK_PRIORITY s->my_ref_top_priority = &s->my_market->my_global_top_priority; s->my_ref_reload_epoch = &s->my_market->my_global_reload_epoch; #endif /* __TBB_TASK_PRIORITY */ return s; } // TODO: make it a member method generic_scheduler* generic_scheduler::create_master( arena& a ) { generic_scheduler* s = allocate_scheduler( &a, 0 /*Master thread always occupies the first slot*/ ); task& t = *s->my_dummy_task; s->my_innermost_running_task = &t; s->my_dispatching_task = &t; t.prefix().ref_count = 1; governor::sign_on(s); __TBB_ASSERT( &task::self()==&t, "governor::sign_on failed?" ); #if __TBB_TASK_GROUP_CONTEXT // Context to be used by root tasks by default (if the user has not specified one). // Allocation is done by NFS allocator because we cannot reuse memory allocated // for task objects since the free list is empty at the moment. t.prefix().context = a.my_default_ctx; #endif /* __TBB_TASK_GROUP_CONTEXT */ s->my_market = a.my_market; __TBB_ASSERT( s->my_arena_index == 0, "Master thread must occupy the first slot in its arena" ); s->attach_mailbox(1); s->my_arena_slot = a.my_slots + 0; s->my_arena_slot->my_scheduler = s; #if _WIN32||_WIN64 __TBB_ASSERT( s->my_market, NULL ); s->my_market->register_master( s->master_exec_resource ); #endif /* _WIN32||_WIN64 */ s->init_stack_info(); #if __TBB_TASK_GROUP_CONTEXT // Sync up the local cancellation state with the global one. No need for fence here. s->my_context_state_propagation_epoch = the_context_state_propagation_epoch; #endif #if __TBB_TASK_PRIORITY // In the current implementation master threads continue processing even when // there are other masters with higher priority. Only TBB worker threads are // redistributed between arenas based on the latters' priority. Thus master // threads use arena's top priority as a reference point (in contrast to workers // that use my_market->my_global_top_priority). s->my_ref_top_priority = &s->my_arena->my_top_priority; s->my_ref_reload_epoch = &s->my_arena->my_reload_epoch; #endif /* __TBB_TASK_PRIORITY */ #if __TBB_SCHEDULER_OBSERVER // Process any existing observers. __TBB_ASSERT( a.my_observers.empty(), "Just created arena cannot have any observers associated with it" ); the_global_observer_list.notify_entry_observers( s->my_last_global_observer, /*worker=*/false ); #endif /* __TBB_SCHEDULER_OBSERVER */ return s; } void generic_scheduler::cleanup_worker( void* arg, bool worker ) { generic_scheduler& s = *(generic_scheduler*)arg; __TBB_ASSERT( !s.my_arena_slot, "cleaning up attached worker" ); #if __TBB_SCHEDULER_OBSERVER if ( worker ) // can be called by master for worker, do not notify master twice the_global_observer_list.notify_exit_observers( s.my_last_global_observer, /*worker=*/true ); #endif /* __TBB_SCHEDULER_OBSERVER */ s.free_scheduler(); } void generic_scheduler::cleanup_master() { generic_scheduler& s = *this; // for similarity with cleanup_worker __TBB_ASSERT( s.my_arena_slot, NULL); #if __TBB_SCHEDULER_OBSERVER s.my_arena->my_observers.notify_exit_observers( s.my_last_local_observer, /*worker=*/false ); the_global_observer_list.notify_exit_observers( s.my_last_global_observer, /*worker=*/false ); #endif /* __TBB_SCHEDULER_OBSERVER */ if( in_arena() ) { acquire_task_pool(); if ( my_arena_slot->task_pool == EmptyTaskPool || __TBB_load_relaxed(my_arena_slot->head) >= __TBB_load_relaxed(my_arena_slot->tail) ) { // Local task pool is empty leave_arena(); } else { // Master's local task pool may e.g. contain proxies of affinitized tasks. release_task_pool(); __TBB_ASSERT ( governor::is_set(this), "TLS slot is cleared before the task pool cleanup" ); s.local_wait_for_all( *s.my_dummy_task, NULL ); __TBB_ASSERT( !in_arena(), NULL ); __TBB_ASSERT ( governor::is_set(this), "Other thread reused our TLS key during the task pool cleanup" ); } } __TBB_ASSERT( s.my_market, NULL ); market *my_market = s.my_market; #if _WIN32||_WIN64 s.my_market->unregister_master( s.master_exec_resource ); #endif /* _WIN32||_WIN64 */ arena* a = s.my_arena; __TBB_ASSERT(a->my_slots+0 == my_arena_slot, NULL); #if __TBB_STATISTICS *my_arena_slot->my_counters += s.my_counters; #endif /* __TBB_STATISTICS */ #if __TBB_TASK_PRIORITY __TBB_ASSERT( my_arena_slot->my_scheduler, NULL ); // Master's scheduler may be locked by a worker taking arena snapshot or by // a thread propagating task group state change across the context tree. while ( as_atomic(my_arena_slot->my_scheduler).compare_and_swap(NULL, this) != this ) __TBB_Yield(); __TBB_ASSERT( !my_arena_slot->my_scheduler, NULL ); #else /* !__TBB_TASK_PRIORITY */ __TBB_store_with_release(my_arena_slot->my_scheduler, (generic_scheduler*)NULL); #endif /* __TBB_TASK_PRIORITY */ my_arena_slot = NULL; // detached from slot s.free_scheduler(); // Resetting arena to EMPTY state (as earlier TBB versions did) should not be // done here (or anywhere else in the master thread to that matter) because // after introducing arena-per-master logic and fire-and-forget tasks doing // so can result either in arena's premature destruction (at least without // additional costly checks in workers) or in unnecessary arena state changes // (and ensuing workers migration). #if __TBB_STATISTICS_EARLY_DUMP GATHER_STATISTIC( a->dump_arena_statistics() ); #endif if (governor::needsWaitWorkers()) my_market->prepare_wait_workers(); a->on_thread_leaving(); if (governor::needsWaitWorkers()) my_market->wait_workers(); } } // namespace internal } // namespace tbb /* Comments: 1. The premise of the cancellation support implementation is that cancellations are not part of the hot path of the program execution. Therefore all changes in its implementation in order to reduce the overhead of the cancellation control flow should be done only in ways that do not increase overhead of the normal execution. In general contexts are used by all threads and their descendants are created in different threads as well. In order to minimize impact of the cross-thread tree maintenance (first of all because of the synchronization), the tree of contexts is split into pieces, each of which is handled by the only thread. Such pieces are represented as lists of contexts, members of which are contexts that were bound to their parents in the given thread. The context tree maintenance and cancellation propagation algorithms is designed in such a manner that cross-thread access to a context list will take place only when cancellation signal is sent (by user or when an exception happens), and synchronization is necessary only then. Thus the normal execution flow (without exceptions and cancellation) remains free from any synchronization done on behalf of exception handling and cancellation support. 2. Consider parallel cancellations at the different levels of the context tree: Ctx1 <- Cancelled by Thread1 |- Thread2 started processing | | Ctx2 |- Thread1 started processing | T1 |- Thread2 finishes and syncs up local counters Ctx3 <- Cancelled by Thread2 | | |- Ctx5 is bound to Ctx2 Ctx4 | T2 |- Thread1 reaches Ctx2 Thread-propagator of each cancellation increments global counter. However the thread propagating the cancellation from the outermost context (Thread1) may be the last to finish. Which means that the local counters may be synchronized earlier (by Thread2, at Time1) than it propagated cancellation into Ctx2 (at time Time2). If a new context (Ctx5) is created and bound to Ctx2 between Time1 and Time2, checking its parent only (Ctx2) may result in cancellation request being lost. This issue is solved by doing the whole propagation under the lock. If we need more concurrency while processing parallel cancellations, we could try the following modification of the propagation algorithm: advance global counter and remember it for each thread: scan thread's list of contexts for each thread: sync up its local counter only if the global counter has not been changed However this version of the algorithm requires more analysis and verification. 3. There is no portable way to get stack base address in Posix, however the modern Linux versions provide pthread_attr_np API that can be used to obtain thread's stack size and base address. Unfortunately even this function does not provide enough information for the main thread on IA-64 architecture (RSE spill area and memory stack are allocated as two separate discontinuous chunks of memory), and there is no portable way to discern the main and the secondary threads. Thus for OS X* and IA-64 Linux architecture we use the TBB worker stack size for all threads and use the current stack top as the stack base. This simplified approach is based on the following assumptions: 1) If the default stack size is insufficient for the user app needs, the required amount will be explicitly specified by the user at the point of the TBB scheduler initialization (as an argument to tbb::task_scheduler_init constructor). 2) When a master thread initializes the scheduler, it has enough space on its stack. Here "enough" means "at least as much as worker threads have". 3) If the user app strives to conserve the memory by cutting stack size, it should do this for TBB workers too (as in the #1). */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/scheduler.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_scheduler_H #define _TBB_scheduler_H #include "scheduler_common.h" #include "tbb/spin_mutex.h" #include "mailbox.h" #include "tbb_misc.h" // for FastRandom #include "itt_notify.h" #include "../rml/include/rml_tbb.h" #if __TBB_SURVIVE_THREAD_SWITCH #include "cilk-tbb-interop.h" #endif /* __TBB_SURVIVE_THREAD_SWITCH */ namespace tbb { namespace internal { template class custom_scheduler; struct nested_arena_context; //------------------------------------------------------------------------ // generic_scheduler //------------------------------------------------------------------------ #if __TBB_TASK_GROUP_CONTEXT struct scheduler_list_node_t { scheduler_list_node_t *my_prev, *my_next; }; #endif /* __TBB_TASK_GROUP_CONTEXT */ #define EmptyTaskPool ((task**)0) #define LockedTaskPool ((task**)~(intptr_t)0) #define LockedMaster ((generic_scheduler*)~(intptr_t)0) struct scheduler_state { //! Index of the arena slot the scheduler occupies now, or occupied last time. size_t my_arena_index; // TODO: make it unsigned and pair with my_affinity_id to fit into cache line //! Pointer to the slot in the arena we own at the moment. arena_slot* my_arena_slot; //! The arena that I own (if master) or am servicing at the moment (if worker) arena* my_arena; //! Innermost task whose task::execute() is running. task* my_innermost_running_task; //! Task, in the context of which the current TBB dispatch loop is running. /** Outside of or in the outermost dispatch loop (not in a nested call to wait_for_all) it is my_dummy_task for master threads, and NULL for workers. **/ task* my_dispatching_task; mail_inbox my_inbox; //! The mailbox id assigned to this scheduler. /** The id is assigned upon first entry into the arena. TODO: how are id's being garbage collected? TODO: master thread may enter arena and leave and then reenter. We want to give it the same affinity_id upon reentry, if practical. */ affinity_id my_affinity_id; #if __TBB_SCHEDULER_OBSERVER //! Last observer in the global observers list processed by this scheduler observer_proxy* my_last_global_observer; //! Last observer in the local observers list processed by this scheduler observer_proxy* my_last_local_observer; #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_PRIORITY //! Latest known highest priority of tasks in the market or arena. /** Master threads currently tracks only tasks in their arenas, while workers take into account global top priority (among all arenas in the market). **/ volatile intptr_t *my_ref_top_priority; //! Pointer to market's (for workers) or current arena's (for the master) reload epoch counter. volatile uintptr_t *my_ref_reload_epoch; #endif /* __TBB_TASK_PRIORITY */ }; //! Work stealing task scheduler. /** None of the fields here are ever read or written by threads other than the thread that creates the instance. Class generic_scheduler is an abstract base class that contains most of the scheduler, except for tweaks specific to processors and tools (e.g. VTune). The derived template class custom_scheduler fills in the tweaks. */ class generic_scheduler: public scheduler, public ::rml::job, public scheduler_state { public: // almost every class in TBB uses generic_scheduler //! If sizeof(task) is <=quick_task_size, it is handled on a free list instead of malloc'd. static const size_t quick_task_size = 256-task_prefix_reservation_size; static bool is_version_3_task( task& t ) { return (t.prefix().extra_state & 0x0F)>=0x1; } //! Position in the call stack specifying its maximal filling when stealing is still allowed uintptr_t my_stealing_threshold; #if __TBB_ipf //! Position in the RSE backup area specifying its maximal filling when stealing is still allowed uintptr_t my_rsb_stealing_threshold; #endif static const size_t null_arena_index = ~size_t(0); // TODO: Rename into is_task_pool_published() inline bool in_arena () const; inline bool is_local_task_pool_quiescent () const; inline bool is_quiescent_local_task_pool_empty () const; inline bool is_quiescent_local_task_pool_reset () const; //! The market I am in market* my_market; //! Random number generator used for picking a random victim from which to steal. FastRandom my_random; //! Free list of small tasks that can be reused. task* my_free_list; #if __TBB_HOARD_NONLOCAL_TASKS //! Free list of small non-local tasks that should be returned or can be reused. task* my_nonlocal_free_list; #endif //! Fake root task created by slave threads. /** The task is used as the "parent" argument to method wait_for_all. */ task* my_dummy_task; //! Reference count for scheduler /** Number of task_scheduler_init objects that point to this scheduler */ long my_ref_count; inline void attach_mailbox( affinity_id id ); /* A couple of bools can be located here because space is otherwise just padding after my_affinity_id. */ //! True if *this was created by automatic TBB initialization bool my_auto_initialized; #if __TBB_COUNT_TASK_NODES //! Net number of big task objects that have been allocated but not yet freed. intptr_t my_task_node_count; #endif /* __TBB_COUNT_TASK_NODES */ //! Sets up the data necessary for the stealing limiting heuristics void init_stack_info (); //! Returns true if stealing is allowed bool can_steal () { int anchor; // TODO IDEA: Add performance warning? #if __TBB_ipf return my_stealing_threshold < (uintptr_t)&anchor && (uintptr_t)__TBB_get_bsp() < my_rsb_stealing_threshold; #else return my_stealing_threshold < (uintptr_t)&anchor; #endif } //! Actions common to enter_arena and try_enter_arena void do_enter_arena(); //! Used by workers to enter the arena /** Does not lock the task pool in case if arena slot has been successfully grabbed. **/ void enter_arena(); //! Leave the arena /** Leaving arena automatically releases the task pool if it is locked. **/ void leave_arena(); //! Resets head and tail indices to 0, and leaves arena /** Argument specifies whether the task pool is currently locked by the owner (via acquire_task_pool).**/ inline void reset_deque_and_leave_arena ( bool locked ); //! Locks victim's task pool, and returns pointer to it. The pointer can be NULL. /** Garbles victim_arena_slot->task_pool for the duration of the lock. **/ task** lock_task_pool( arena_slot* victim_arena_slot ) const; //! Unlocks victim's task pool /** Restores victim_arena_slot->task_pool munged by lock_task_pool. **/ void unlock_task_pool( arena_slot* victim_arena_slot, task** victim_task_pool ) const; //! Locks the local task pool /** Garbles my_arena_slot->task_pool for the duration of the lock. Requires correctly set my_arena_slot->task_pool_ptr. **/ void acquire_task_pool() const; //! Unlocks the local task pool /** Restores my_arena_slot->task_pool munged by acquire_task_pool. Requires correctly set my_arena_slot->task_pool_ptr. **/ void release_task_pool() const; //! Checks if t is affinitized to another thread, and if so, bundles it as proxy. /** Returns either t or proxy containing t. **/ task* prepare_for_spawning( task* t ); //! Makes newly spawned tasks visible to thieves inline void commit_spawned_tasks( size_t new_tail ); //! Makes relocated tasks visible to thieves and releases the local task pool. /** Obviously, the task pool must be locked when calling this method. **/ inline void commit_relocated_tasks( size_t new_tail ); //! Get a task from the local pool. /** Called only by the pool owner. Returns the pointer to the task or NULL if the pool is empty. In the latter case compacts the pool. **/ task* get_task(); //! Attempt to get a task from the mailbox. /** Gets a task only if it has not been executed by its sender or a thief that has stolen it from the sender's task pool. Otherwise returns NULL. This method is intended to be used only by the thread extracting the proxy from its mailbox. (In contrast to local task pool, mailbox can be read only by its owner). **/ task* get_mailbox_task(); //! True if t is a task_proxy static bool is_proxy( const task& t ) { return t.prefix().extra_state==es_task_proxy; } //! Steal task from another scheduler's ready pool. task* steal_task( arena_slot& victim_arena_slot ); /** Initial size of the task deque sufficient to serve without reallocation 4 nested parallel_for calls with iteration space of 65535 grains each. **/ static const size_t min_task_pool_size = 64; //! Makes sure that the task pool can accommodate at least n more elements /** If necessary relocates existing task pointers or grows the ready task deque. Returns (possible updated) tail index (not accounting for n). **/ size_t prepare_task_pool( size_t n ); //! Initialize a scheduler for a master thread. static generic_scheduler* create_master( arena& a ); //! Perform necessary cleanup when a master thread stops using TBB. void cleanup_master(); //! Initialize a scheduler for a worker thread. static generic_scheduler* create_worker( market& m, size_t index ); //! Perform necessary cleanup when a worker thread finishes. static void cleanup_worker( void* arg, bool worker ); protected: template friend class custom_scheduler; generic_scheduler( arena*, size_t index ); public: #if TBB_USE_ASSERT > 1 //! Check that internal data structures are in consistent state. /** Raises __TBB_ASSERT failure if inconsistency is found. */ void assert_task_pool_valid () const; #else void assert_task_pool_valid() const {} #endif /* TBB_USE_ASSERT <= 1 */ #if __TBB_TASK_ARENA void nested_arena_entry(arena*, nested_arena_context &, bool); void nested_arena_exit(nested_arena_context &); void wait_until_empty(); #endif /*override*/ void spawn( task& first, task*& next ); /*override*/ void spawn_root_and_wait( task& first, task*& next ); /*override*/ void enqueue( task&, void* reserved ); void local_spawn( task& first, task*& next ); void local_spawn_root_and_wait( task& first, task*& next ); virtual void local_wait_for_all( task& parent, task* child ) = 0; //! Destroy and deallocate this scheduler object void free_scheduler(); //! Allocate task object, either from the heap or a free list. /** Returns uninitialized task object with initialized prefix. */ task& allocate_task( size_t number_of_bytes, __TBB_CONTEXT_ARG(task* parent, task_group_context* context) ); //! Put task on free list. /** Does not call destructor. */ template void free_task( task& t ); //! Return task object to the memory allocator. inline void deallocate_task( task& t ); //! True if running on a worker thread, false otherwise. inline bool is_worker(); //! True if the scheduler is on the outermost dispatch level in a master thread. /** Returns true when this scheduler instance is associated with an application thread, and is not executing any TBB task. This includes being in a TBB dispatch loop (one of wait_for_all methods) invoked directly from that thread. **/ inline bool master_outermost_level () const; //! True if the scheduler is on the outermost dispatch level in a worker thread. inline bool worker_outermost_level () const; #if __TBB_TASK_GROUP_CONTEXT //! Returns task group context used by this scheduler instance. /** This context is associated with root tasks created by a master thread without explicitly specified context object outside of any running task. Note that the default context of a worker thread is never accessed by user code (directly or indirectly). **/ inline task_group_context* default_context (); #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Returns number of worker threads in the arena this thread belongs to. unsigned number_of_workers_in_my_arena(); #if __TBB_COUNT_TASK_NODES intptr_t get_task_node_count( bool count_arena_workers = false ); #endif /* __TBB_COUNT_TASK_NODES */ //! Special value used to mark my_return_list as not taking any more entries. static task* plugged_return_list() {return (task*)(intptr_t)(-1);} //! Number of small tasks that have been allocated by this scheduler. intptr_t my_small_task_count; //! List of small tasks that have been returned to this scheduler by other schedulers. task* my_return_list; //! Try getting a task from other threads (via mailbox, stealing, FIFO queue, orphans adoption). /** Returns obtained task or NULL if all attempts fail. */ virtual task* receive_or_steal_task( __TBB_atomic reference_count& completion_ref_count, bool return_if_no_work ) = 0; //! Free a small task t that that was allocated by a different scheduler void free_nonlocal_small_task( task& t ); #if __TBB_TASK_GROUP_CONTEXT //! Padding isolating thread-local members from members that can be written to by other threads. char _padding1[NFS_MaxLineSize - sizeof(context_list_node_t)]; //! Head of the thread specific list of task group contexts. context_list_node_t my_context_list_head; //! Mutex protecting access to the list of task group contexts. // TODO: check whether it can be deadly preempted and replace by spinning/sleeping mutex spin_mutex my_context_list_mutex; //! Last state propagation epoch known to this thread /** Together with the_context_state_propagation_epoch constitute synchronization protocol that keeps hot path of task group context construction destruction mostly lock-free. When local epoch equals the global one, the state of task group contexts registered with this thread is consistent with that of the task group trees they belong to. **/ uintptr_t my_context_state_propagation_epoch; //! Flag indicating that a context is being destructed by its owner thread /** Together with my_nonlocal_ctx_list_update constitute synchronization protocol that keeps hot path of context destruction (by the owner thread) mostly lock-free. **/ tbb::atomic my_local_ctx_list_update; #if __TBB_TASK_PRIORITY //! Returns reference priority used to decide whether a task should be offloaded. inline intptr_t effective_reference_priority () const; // TODO: move into slots and fix is_out_of_work //! Task pool for offloading tasks with priorities lower than the current top priority. task* my_offloaded_tasks; //! Points to the last offloaded task in the my_offloaded_tasks list. task** my_offloaded_task_list_tail_link; //! Indicator of how recently the offload area was checked for the presence of top priority tasks. uintptr_t my_local_reload_epoch; //! Indicates that the pool is likely non-empty even if appears so from outside volatile bool my_pool_reshuffling_pending; //! Searches offload area for top priority tasks and reloads found ones into primary task pool. /** Returns one of the found tasks or NULL. **/ task* reload_tasks (); task* reload_tasks ( task*& offloaded_tasks, task**& offloaded_task_list_link, intptr_t top_priority ); //! Moves tasks with priority below the top one from primary task pool into offload area. /** Returns the next execution candidate task or NULL. **/ task* winnow_task_pool (); //! Unconditionally moves the task into offload area. inline void offload_task ( task& t, intptr_t task_priority ); #endif /* __TBB_TASK_PRIORITY */ //! Detaches abandoned contexts /** These contexts must be destroyed by other threads. **/ void cleanup_local_context_list (); //! Finds all contexts registered by this scheduler affected by the state change //! and propagates the new state to them. template void propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); // check consistency static void assert_context_valid(const task_group_context *tgc) { suppress_unused_warning(tgc); #if TBB_USE_ASSERT __TBB_ASSERT(tgc, NULL); uintptr_t ctx = tgc->my_version_and_traits; __TBB_ASSERT(is_alive(ctx), "referenced task_group_context was destroyed"); static const char *msg = "task_group_context is invalid"; __TBB_ASSERT(!(ctx&~(3|(7<my_kind < task_group_context::dying, msg); __TBB_ASSERT(tgc->my_cancellation_requested == 0 || tgc->my_cancellation_requested == 1, msg); __TBB_ASSERT(tgc->my_state < task_group_context::low_unused_state_bit, msg); if(tgc->my_kind != task_group_context::isolated) { __TBB_ASSERT(tgc->my_owner, msg); __TBB_ASSERT(tgc->my_node.my_next && tgc->my_node.my_prev, msg); } #if __TBB_TASK_PRIORITY assert_priority_valid(tgc->my_priority); #endif if(tgc->my_parent) #if TBB_USE_ASSERT > 1 assert_context_valid(tgc->my_parent); #else __TBB_ASSERT(is_alive(tgc->my_parent->my_version_and_traits), msg); #endif #endif } #endif /* __TBB_TASK_GROUP_CONTEXT */ #if _WIN32||_WIN64 private: //! Handle returned by RML when registering a master with RML ::rml::server::execution_resource_t master_exec_resource; public: #endif /* _WIN32||_WIN64 */ #if __TBB_TASK_GROUP_CONTEXT //! Flag indicating that a context is being destructed by non-owner thread. /** See also my_local_ctx_list_update. **/ tbb::atomic my_nonlocal_ctx_list_update; #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_SURVIVE_THREAD_SWITCH __cilk_tbb_unwatch_thunk my_cilk_unwatch_thunk; #if TBB_USE_ASSERT //! State values used to check interface contract with cilkrts. /** Names of cs_running...cs_freed derived from state machine diagram in cilk-tbb-interop.h */ enum cilk_state_t { cs_none=0xF000, // Start at nonzero value so that we can detect use of zeroed memory. cs_running, cs_limbo, cs_freed }; cilk_state_t my_cilk_state; #endif /* TBB_USE_ASSERT */ #endif /* __TBB_SURVIVE_THREAD_SWITCH */ #if __TBB_STATISTICS //! Set of counters to track internal statistics on per thread basis /** Placed at the end of the class definition to minimize the disturbance of the core logic memory operations. **/ mutable statistics_counters my_counters; #endif /* __TBB_STATISTICS */ }; // class generic_scheduler } // namespace internal } // namespace tbb #include "arena.h" #include "governor.h" namespace tbb { namespace internal { inline bool generic_scheduler::in_arena () const { __TBB_ASSERT(my_arena_slot, 0); return my_arena_slot->task_pool != EmptyTaskPool; } inline bool generic_scheduler::is_local_task_pool_quiescent () const { __TBB_ASSERT(my_arena_slot, 0); task** tp = my_arena_slot->task_pool; return tp == EmptyTaskPool || tp == LockedTaskPool; } inline bool generic_scheduler::is_quiescent_local_task_pool_empty () const { __TBB_ASSERT( is_local_task_pool_quiescent(), "Task pool is not quiescent" ); return __TBB_load_relaxed(my_arena_slot->head) == __TBB_load_relaxed(my_arena_slot->tail); } inline bool generic_scheduler::is_quiescent_local_task_pool_reset () const { __TBB_ASSERT( is_local_task_pool_quiescent(), "Task pool is not quiescent" ); return __TBB_load_relaxed(my_arena_slot->head) == 0 && __TBB_load_relaxed(my_arena_slot->tail) == 0; } inline bool generic_scheduler::master_outermost_level () const { return my_dispatching_task == my_dummy_task; } inline bool generic_scheduler::worker_outermost_level () const { return !my_dispatching_task; } #if __TBB_TASK_GROUP_CONTEXT inline task_group_context* generic_scheduler::default_context () { return my_dummy_task->prefix().context; } #endif /* __TBB_TASK_GROUP_CONTEXT */ inline void generic_scheduler::attach_mailbox( affinity_id id ) { __TBB_ASSERT(id>0,NULL); my_inbox.attach( my_arena->mailbox(id) ); my_affinity_id = id; } inline bool generic_scheduler::is_worker() { return my_arena_index != 0; //TODO: rework for multiple master } inline unsigned generic_scheduler::number_of_workers_in_my_arena() { return my_arena->my_max_num_workers; } //! Return task object to the memory allocator. inline void generic_scheduler::deallocate_task( task& t ) { #if TBB_USE_ASSERT task_prefix& p = t.prefix(); p.state = 0xFF; p.extra_state = 0xFF; poison_pointer(p.next); #endif /* TBB_USE_ASSERT */ NFS_Free((char*)&t-task_prefix_reservation_size); #if __TBB_COUNT_TASK_NODES --my_task_node_count; #endif /* __TBB_COUNT_TASK_NODES */ } #if __TBB_COUNT_TASK_NODES inline intptr_t generic_scheduler::get_task_node_count( bool count_arena_workers ) { return my_task_node_count + (count_arena_workers? my_arena->workers_task_node_count(): 0); } #endif /* __TBB_COUNT_TASK_NODES */ inline void generic_scheduler::reset_deque_and_leave_arena ( bool locked ) { if ( !locked ) acquire_task_pool(); __TBB_store_relaxed( my_arena_slot->tail, 0 ); __TBB_store_relaxed( my_arena_slot->head, 0 ); leave_arena(); } //TODO: move to arena_slot inline void generic_scheduler::commit_spawned_tasks( size_t new_tail ) { __TBB_ASSERT ( new_tail <= my_arena_slot->my_task_pool_size, "task deque end was overwritten" ); // emit "task was released" signal ITT_NOTIFY(sync_releasing, (void*)((uintptr_t)my_arena_slot+sizeof(uintptr_t))); // Release fence is necessary to make sure that previously stored task pointers // are visible to thieves. __TBB_store_with_release( my_arena_slot->tail, new_tail ); } void generic_scheduler::commit_relocated_tasks ( size_t new_tail ) { __TBB_ASSERT( is_local_task_pool_quiescent(), "Task pool must be locked when calling commit_relocated_tasks()" ); __TBB_store_relaxed( my_arena_slot->head, 0 ); // Tail is updated last to minimize probability of a thread making arena // snapshot being misguided into thinking that this task pool is empty. __TBB_store_relaxed( my_arena_slot->tail, new_tail ); release_task_pool(); } template void generic_scheduler::free_task( task& t ) { #if __TBB_HOARD_NONLOCAL_TASKS static const int h = hint&(~local_task); #else static const free_task_hint h = hint; #endif GATHER_STATISTIC(--my_counters.active_tasks); task_prefix& p = t.prefix(); // Verify that optimization hints are correct. __TBB_ASSERT( h!=small_local_task || p.origin==this, NULL ); __TBB_ASSERT( !(h&small_task) || p.origin, NULL ); __TBB_ASSERT( !(h&local_task) || (!p.origin || uintptr_t(p.origin) > uintptr_t(4096)), "local_task means allocated"); poison_value(p.depth); poison_value(p.ref_count); poison_pointer(p.owner); __TBB_ASSERT( 1L<my_num_workers_allotted < my_arena->num_workers_active() ? *my_ref_top_priority : my_arena->my_top_priority; } inline void generic_scheduler::offload_task ( task& t, intptr_t /*priority*/ ) { GATHER_STATISTIC( ++my_counters.prio_tasks_offloaded ); __TBB_ASSERT( my_offloaded_task_list_tail_link && !*my_offloaded_task_list_tail_link, NULL ); #if TBB_USE_ASSERT t.prefix().state = task::ready; #endif /* TBB_USE_ASSERT */ t.prefix().next_offloaded = my_offloaded_tasks; my_offloaded_tasks = &t; } #endif /* __TBB_TASK_PRIORITY */ #if __TBB_FP_CONTEXT class cpu_ctl_env_helper { cpu_ctl_env guard_cpu_ctl_env; cpu_ctl_env curr_cpu_ctl_env; public: cpu_ctl_env_helper() { guard_cpu_ctl_env.get_env(); curr_cpu_ctl_env = guard_cpu_ctl_env; } ~cpu_ctl_env_helper() { if ( curr_cpu_ctl_env != guard_cpu_ctl_env ) guard_cpu_ctl_env.set_env(); } void set_env( const task_group_context *ctx ) { generic_scheduler::assert_context_valid(ctx); const cpu_ctl_env &ctl = *punned_cast(&ctx->my_cpu_ctl_env); if ( ctl != curr_cpu_ctl_env ) { curr_cpu_ctl_env = ctl; curr_cpu_ctl_env.set_env(); } } void restore_default() { if ( curr_cpu_ctl_env != guard_cpu_ctl_env ) { guard_cpu_ctl_env.set_env(); curr_cpu_ctl_env = guard_cpu_ctl_env; } } }; #else struct cpu_ctl_env_helper { void set_env( __TBB_CONTEXT_ARG1(task_group_context *) ) {} void restore_default() {} }; #endif /* __TBB_FP_CONTEXT */ } // namespace internal } // namespace tbb #endif /* _TBB_scheduler_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/scheduler_common.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_scheduler_common_H #define _TBB_scheduler_common_H #include "tbb/tbb_machine.h" #include "tbb/cache_aligned_allocator.h" #include // for memset, memcpy, memmove #include "tbb_statistics.h" #if TBB_USE_ASSERT > 1 #include #endif /* TBB_USE_ASSERT > 1 */ /* Temporarily change "private" to "public" while including "tbb/task.h". This hack allows us to avoid publishing internal types and methods in the public header files just for sake of friend declarations. */ #ifndef private #define private public #define undef_private #endif #include "tbb/task.h" #include "tbb/tbb_exception.h" #ifdef undef_private #undef private #endif #ifndef __TBB_SCHEDULER_MUTEX_TYPE #define __TBB_SCHEDULER_MUTEX_TYPE tbb::spin_mutex #endif // TODO: add conditional inclusion based on specified type #include "tbb/spin_mutex.h" // This macro is an attempt to get rid of ugly ifdefs in the shared parts of the code. // It drops the second argument depending on whether the controlling macro is defined. // The first argument is just a convenience allowing to keep comma before the macro usage. #if __TBB_TASK_GROUP_CONTEXT #define __TBB_CONTEXT_ARG1(context) context #define __TBB_CONTEXT_ARG(arg1, context) arg1, context #else /* !__TBB_TASK_GROUP_CONTEXT */ #define __TBB_CONTEXT_ARG1(context) #define __TBB_CONTEXT_ARG(arg1, context) arg1 #endif /* !__TBB_TASK_GROUP_CONTEXT */ #if DO_TBB_TRACE #include #define TBB_TRACE(x) ((void)std::printf x) #else #define TBB_TRACE(x) ((void)(0)) #endif /* DO_TBB_TRACE */ #if !__TBB_CPU_CTL_ENV_PRESENT #include #endif #if _MSC_VER && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings // These particular warnings are so ubiquitous that no attempt is made to narrow // the scope of the warnings. #pragma warning (disable: 4100 4127 4312 4244 4267 4706) #endif namespace tbb { namespace interface7 { namespace internal { class task_arena_base; class delegated_task; class wait_task; }} namespace internal { using namespace interface7::internal; class arena; template class custom_scheduler; class generic_scheduler; class governor; class mail_outbox; class market; class observer_proxy; class task_scheduler_observer_v3; #if __TBB_TASK_PRIORITY static const intptr_t num_priority_levels = 3; static const intptr_t normalized_normal_priority = (num_priority_levels - 1) / 2; inline intptr_t normalize_priority ( priority_t p ) { return intptr_t(p - priority_low) / priority_stride_v4; } static const priority_t priority_from_normalized_rep[num_priority_levels] = { priority_low, priority_normal, priority_high }; inline void assert_priority_valid ( intptr_t p ) { __TBB_ASSERT_EX( p >= 0 && p < num_priority_levels, NULL ); } inline intptr_t& priority ( task& t ) { return t.prefix().context->my_priority; } #endif /* __TBB_TASK_PRIORITY */ //! Mutex type for global locks in the scheduler typedef __TBB_SCHEDULER_MUTEX_TYPE scheduler_mutex_type; #if __TBB_TASK_GROUP_CONTEXT //! Task group state change propagation global epoch /** Together with generic_scheduler::my_context_state_propagation_epoch forms cross-thread signaling mechanism that allows to avoid locking at the hot path of normal execution flow. When a descendant task group context is registered or unregistered, the global and local epochs are compared. If they differ, a state change is being propagated, and thus registration/deregistration routines take slower branch that may block (at most one thread of the pool can be blocked at any moment). Otherwise the control path is lock-free and fast. **/ extern uintptr_t the_context_state_propagation_epoch; //! Mutex guarding state change propagation across task groups forest. /** Also protects modification of related data structures. **/ typedef scheduler_mutex_type context_state_propagation_mutex_type; extern context_state_propagation_mutex_type the_context_state_propagation_mutex; #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Alignment for a task object const size_t task_alignment = 32; //! Number of bytes reserved for a task prefix /** If not exactly sizeof(task_prefix), the extra bytes *precede* the task_prefix. */ const size_t task_prefix_reservation_size = ((sizeof(internal::task_prefix)-1)/task_alignment+1)*task_alignment; //! Definitions for bits in task_prefix::extra_state enum task_extra_state { //! Tag for v1 tasks (i.e. tasks in TBB 1.0 and 2.0) es_version_1_task = 0, //! Tag for v3 tasks (i.e. tasks in TBB 2.1-2.2) es_version_3_task = 1, //! Tag for enqueued tasks es_task_enqueued = 0x10, //! Tag for v3 task_proxy. es_task_proxy = 0x20, //! Set if ref_count might be changed by another thread. Used for debugging. es_ref_count_active = 0x40, //! Set if the task has been stolen es_task_is_stolen = 0x80 }; inline void reset_extra_state ( task *t ) { t->prefix().extra_state &= ~(es_task_is_stolen | es_task_enqueued); } //! Optimization hint to free_task that enables it omit unnecessary tests and code. enum free_task_hint { //! No hint no_hint=0, //! Task is known to have been allocated by this scheduler local_task=1, //! Task is known to be a small task. /** Task should be returned to the free list of *some* scheduler, possibly not this scheduler. */ small_task=2, //! Bitwise-OR of local_task and small_task. /** Task should be returned to free list of this scheduler. */ small_local_task=3, //! Disable caching for a small task. no_cache = 4, //! Task is known to be a small task and must not be cached. no_cache_small_task = no_cache | small_task }; //------------------------------------------------------------------------ // Debugging support //------------------------------------------------------------------------ #if TBB_USE_ASSERT static const uintptr_t venom = tbb::internal::select_size_t_constant<0xDEADBEEFU,0xDDEEAADDDEADBEEFULL>::value; template void poison_value ( T& val ) { val = * punned_cast(&venom); } /** Expected to be used in assertions only, thus no empty form is defined. **/ inline bool is_alive( uintptr_t v ) { return v != venom; } /** Logically, this method should be a member of class task. But we do not want to publish it, so it is here instead. */ inline void assert_task_valid( const task& task ) { __TBB_ASSERT( &task!=NULL, NULL ); __TBB_ASSERT( !is_poisoned(&task), NULL ); __TBB_ASSERT( (uintptr_t)&task % task_alignment == 0, "misaligned task" ); #if __TBB_RECYCLE_TO_ENQUEUE __TBB_ASSERT( (unsigned)task.state()<=(unsigned)task::to_enqueue, "corrupt task (invalid state)" ); #else __TBB_ASSERT( (unsigned)task.state()<=(unsigned)task::recycle, "corrupt task (invalid state)" ); #endif } #else /* !TBB_USE_ASSERT */ /** In contrast to debug version poison_value() is a macro here because the variable used as its argument may be undefined in release builds. **/ #define poison_value(g) ((void)0) inline void assert_task_valid( const task& ) {} #endif /* !TBB_USE_ASSERT */ //------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------ #if __TBB_TASK_GROUP_CONTEXT inline bool ConcurrentWaitsEnabled ( task& t ) { return (t.prefix().context->my_version_and_traits & task_group_context::concurrent_wait) != 0; } inline bool CancellationInfoPresent ( task& t ) { return t.prefix().context->my_cancellation_requested != 0; } #if TBB_USE_CAPTURED_EXCEPTION inline tbb_exception* TbbCurrentException( task_group_context*, tbb_exception* src) { return src->move(); } inline tbb_exception* TbbCurrentException( task_group_context*, captured_exception* src) { return src; } #else // Using macro instead of an inline function here allows to avoid evaluation of the // TbbCapturedException expression when exact propagation is enabled for the context. #define TbbCurrentException(context, TbbCapturedException) \ context->my_version_and_traits & task_group_context::exact_exception \ ? tbb_exception_ptr::allocate() \ : tbb_exception_ptr::allocate( *(TbbCapturedException) ); #endif /* !TBB_USE_CAPTURED_EXCEPTION */ #define TbbRegisterCurrentException(context, TbbCapturedException) \ if ( context->cancel_group_execution() ) { \ /* We are the first to signal cancellation, so store the exception that caused it. */ \ context->my_exception = TbbCurrentException( context, TbbCapturedException ); \ } #define TbbCatchAll(context) \ catch ( tbb_exception& exc ) { \ TbbRegisterCurrentException( context, &exc ); \ } catch ( std::exception& exc ) { \ TbbRegisterCurrentException( context, captured_exception::allocate(typeid(exc).name(), exc.what()) ); \ } catch ( ... ) { \ TbbRegisterCurrentException( context, captured_exception::allocate("...", "Unidentified exception") );\ } #else /* !__TBB_TASK_GROUP_CONTEXT */ inline bool ConcurrentWaitsEnabled ( task& t ) { return false; } #endif /* __TBB_TASK_GROUP_CONTEXT */ //------------------------------------------------------------------------ // arena_slot //------------------------------------------------------------------------ struct arena_slot_line1 { //TODO: make this tbb:atomic<>. //! Scheduler of the thread attached to the slot /** Marks the slot as busy, and is used to iterate through the schedulers belonging to this arena **/ generic_scheduler* my_scheduler; // Synchronization of access to Task pool /** Also is used to specify if the slot is empty or locked: 0 - empty -1 - locked **/ task* *__TBB_atomic task_pool; //! Index of the first ready task in the deque. /** Modified by thieves, and by the owner during compaction/reallocation **/ __TBB_atomic size_t head; }; struct arena_slot_line2 { //! Hint provided for operations with the container of starvation-resistant tasks. /** Modified by the owner thread (during these operations). **/ unsigned hint_for_pop; //! Index of the element following the last ready task in the deque. /** Modified by the owner thread. **/ __TBB_atomic size_t tail; //! Capacity of the primary task pool (number of elements - pointers to task). size_t my_task_pool_size; // Task pool of the scheduler that owns this slot task* *__TBB_atomic task_pool_ptr; #if __TBB_STATISTICS //! Set of counters to accumulate internal statistics related to this arena statistics_counters *my_counters; #endif /* __TBB_STATISTICS */ }; struct arena_slot : padded, padded { #if TBB_USE_ASSERT void fill_with_canary_pattern ( size_t first, size_t last ) { for ( size_t i = first; i < last; ++i ) poison_pointer(task_pool_ptr[i]); } #else void fill_with_canary_pattern ( size_t, size_t ) {} #endif /* TBB_USE_ASSERT */ void allocate_task_pool( size_t n ) { size_t byte_size = ((n * sizeof(task*) + NFS_MaxLineSize - 1) / NFS_MaxLineSize) * NFS_MaxLineSize; my_task_pool_size = byte_size / sizeof(task*); task_pool_ptr = (task**)NFS_Allocate( 1, byte_size, NULL ); // No need to clear the fresh deque since valid items are designated by the head and tail members. // But fill it with a canary pattern in the high vigilance debug mode. fill_with_canary_pattern( 0, my_task_pool_size ); } //! Deallocate task pool that was allocated by means of allocate_task_pool. void free_task_pool( ) { #if !__TBB_TASK_ARENA __TBB_ASSERT( !task_pool /*TODO: == EmptyTaskPool*/, NULL); #else //TODO: understand the assertion and modify #endif if( task_pool_ptr ) { __TBB_ASSERT( my_task_pool_size, NULL); NFS_Free( task_pool_ptr ); task_pool_ptr = NULL; my_task_pool_size = 0; } } }; #if !__TBB_CPU_CTL_ENV_PRESENT class cpu_ctl_env { fenv_t *my_fenv_ptr; public: cpu_ctl_env() : my_fenv_ptr(NULL) {} ~cpu_ctl_env() { if ( my_fenv_ptr ) tbb::internal::NFS_Free( (void*)my_fenv_ptr ); } // It is possible not to copy memory but just to copy pointers but the following issues should be addressed: // 1. The arena lifetime and the context lifetime are independent; // 2. The user is allowed to recapture different FPU settings to context so 'current FPU settings' inside // dispatch loop may become invalid. // But do we really want to improve the fenv implementation? It seems to be better to replace the fenv implementation // with a platform specific implementation. cpu_ctl_env( const cpu_ctl_env &src ) : my_fenv_ptr(NULL) { *this = src; } cpu_ctl_env& operator=( const cpu_ctl_env &src ) { __TBB_ASSERT( src.my_fenv_ptr, NULL ); if ( !my_fenv_ptr ) my_fenv_ptr = (fenv_t*)tbb::internal::NFS_Allocate(1, sizeof(fenv_t), NULL); *my_fenv_ptr = *src.my_fenv_ptr; return *this; } bool operator!=( const cpu_ctl_env &ctl ) const { __TBB_ASSERT( my_fenv_ptr, "cpu_ctl_env is not initialized." ); __TBB_ASSERT( ctl.my_fenv_ptr, "cpu_ctl_env is not initialized." ); return memcmp( (void*)my_fenv_ptr, (void*)ctl.my_fenv_ptr, sizeof(fenv_t) ); } void get_env () { if ( !my_fenv_ptr ) my_fenv_ptr = (fenv_t*)tbb::internal::NFS_Allocate(1, sizeof(fenv_t), NULL); fegetenv( my_fenv_ptr ); } const cpu_ctl_env& set_env () const { __TBB_ASSERT( my_fenv_ptr, "cpu_ctl_env is not initialized." ); fesetenv( my_fenv_ptr ); return *this; } }; #endif /* !__TBB_CPU_CTL_ENV_PRESENT */ } // namespace internal } // namespace tbb #endif /* _TBB_scheduler_common_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/scheduler_utility.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_scheduler_utility_H #define _TBB_scheduler_utility_H #include "scheduler.h" namespace tbb { namespace internal { //------------------------------------------------------------------------ // auto_empty_task //------------------------------------------------------------------------ //! Smart holder for the empty task class with automatic destruction class auto_empty_task { task* my_task; generic_scheduler* my_scheduler; public: auto_empty_task ( __TBB_CONTEXT_ARG(generic_scheduler *s, task_group_context* context) ) : my_task( new(&s->allocate_task(sizeof(empty_task), __TBB_CONTEXT_ARG(NULL, context))) empty_task ) , my_scheduler(s) {} // empty_task has trivial destructor, so there's no need to call it. ~auto_empty_task () { my_scheduler->free_task(*my_task); } operator task& () { return *my_task; } task* operator & () { return my_task; } task_prefix& prefix () { return my_task->prefix(); } }; // class auto_empty_task //------------------------------------------------------------------------ // fast_reverse_vector //------------------------------------------------------------------------ //! Vector that grows without reallocations, and stores items in the reverse order. /** Requires to initialize its first segment with a preallocated memory chunk (usually it is static array or an array allocated on the stack). The second template parameter specifies maximal number of segments. Each next segment is twice as large as the previous one. **/ template class fast_reverse_vector { public: fast_reverse_vector ( T* initial_segment, size_t segment_size ) : m_cur_segment(initial_segment) , m_cur_segment_size(segment_size) , m_pos(segment_size) , m_num_segments(0) , m_size(0) { __TBB_ASSERT ( initial_segment && segment_size, "Nonempty initial segment must be supplied"); } ~fast_reverse_vector () { for ( size_t i = 1; i < m_num_segments; ++i ) NFS_Free( m_segments[i] ); } size_t size () const { return m_size + m_cur_segment_size - m_pos; } void push_back ( const T& val ) { if ( !m_pos ) { if ( !m_num_segments ) m_segments[m_num_segments++] = m_cur_segment; m_size += m_cur_segment_size; m_cur_segment_size *= 2; m_pos = m_cur_segment_size; m_segments[m_num_segments++] = m_cur_segment = (T*)NFS_Allocate( m_cur_segment_size, sizeof(T), NULL ); __TBB_ASSERT ( m_num_segments < max_segments, "Maximal capacity exceeded" ); } m_cur_segment[--m_pos] = val; } //! Copies the contents of the vector into the dst array. /** Can only be used when T is a POD type, as copying does not invoke copy constructors. **/ void copy_memory ( T* dst ) const { size_t sz = m_cur_segment_size - m_pos; memcpy( dst, m_cur_segment + m_pos, sz * sizeof(T) ); dst += sz; sz = m_cur_segment_size / 2; for ( long i = (long)m_num_segments - 2; i >= 0; --i ) { memcpy( dst, m_segments[i], sz * sizeof(T) ); dst += sz; sz /= 2; } } protected: //! The current (not completely filled) segment T *m_cur_segment; //! Capacity of m_cur_segment size_t m_cur_segment_size; //! Insertion position in m_cur_segment size_t m_pos; //! Array of segments (has fixed size specified by the second template parameter) T *m_segments[max_segments]; //! Number of segments (the size of m_segments) size_t m_num_segments; //! Number of items in the segments in m_segments size_t m_size; }; // class fast_reverse_vector } // namespace internal } // namespace tbb #endif /* _TBB_scheduler_utility_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/semaphore.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "semaphore.h" #if __TBB_USE_SRWLOCK #include "dynamic_link.h" // Refers to src/tbb, not include/tbb #include "tbb_misc.h" #endif namespace tbb { namespace internal { // TODO: For new win UI port, we can use SRWLock API without dynamic_link etc. #if __TBB_USE_SRWLOCK static atomic concmon_module_inited; void WINAPI init_binsem_using_event( SRWLOCK* h_ ) { srwl_or_handle* shptr = (srwl_or_handle*) h_; shptr->h = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS|SEMAPHORE_ALL_ACCESS ); } void WINAPI acquire_binsem_using_event( SRWLOCK* h_ ) { srwl_or_handle* shptr = (srwl_or_handle*) h_; WaitForSingleObjectEx( shptr->h, INFINITE, FALSE ); } void WINAPI release_binsem_using_event( SRWLOCK* h_ ) { srwl_or_handle* shptr = (srwl_or_handle*) h_; SetEvent( shptr->h ); } static void (WINAPI *__TBB_init_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&init_binsem_using_event; static void (WINAPI *__TBB_acquire_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&acquire_binsem_using_event; static void (WINAPI *__TBB_release_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&release_binsem_using_event; //! Table describing the how to link the handlers. static const dynamic_link_descriptor SRWLLinkTable[] = { DLD(InitializeSRWLock, __TBB_init_binsem), DLD(AcquireSRWLockExclusive, __TBB_acquire_binsem), DLD(ReleaseSRWLockExclusive, __TBB_release_binsem) }; inline void init_concmon_module() { __TBB_ASSERT( (uintptr_t)__TBB_init_binsem==(uintptr_t)&init_binsem_using_event, NULL ); if( dynamic_link( "Kernel32.dll", SRWLLinkTable, sizeof(SRWLLinkTable)/sizeof(dynamic_link_descriptor) ) ) { __TBB_ASSERT( (uintptr_t)__TBB_init_binsem!=(uintptr_t)&init_binsem_using_event, NULL ); __TBB_ASSERT( (uintptr_t)__TBB_acquire_binsem!=(uintptr_t)&acquire_binsem_using_event, NULL ); __TBB_ASSERT( (uintptr_t)__TBB_release_binsem!=(uintptr_t)&release_binsem_using_event, NULL ); } } binary_semaphore::binary_semaphore() { atomic_do_once( &init_concmon_module, concmon_module_inited ); __TBB_init_binsem( &my_sem.lock ); if( (uintptr_t)__TBB_init_binsem!=(uintptr_t)&init_binsem_using_event ) P(); } binary_semaphore::~binary_semaphore() { if( (uintptr_t)__TBB_init_binsem==(uintptr_t)&init_binsem_using_event ) CloseHandle( my_sem.h ); } void binary_semaphore::P() { __TBB_acquire_binsem( &my_sem.lock ); } void binary_semaphore::V() { __TBB_release_binsem( &my_sem.lock ); } #endif /* __TBB_USE_SRWLOCK */ } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/semaphore.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_semaphore_H #define __TBB_tbb_semaphore_H #include "tbb/tbb_stddef.h" #if _WIN32||_WIN64 #include "tbb/machine/windows_api.h" #elif __APPLE__ #include #include #include #include #else #include #ifdef TBB_USE_DEBUG #include #endif #endif /*_WIN32||_WIN64*/ namespace tbb { namespace internal { #if _WIN32||_WIN64 typedef LONG sem_count_t; //! Edsger Dijkstra's counting semaphore class semaphore : no_copy { static const int max_semaphore_cnt = MAXLONG; public: //! ctor semaphore(size_t start_cnt_ = 0) {init_semaphore(start_cnt_);} //! dtor ~semaphore() {CloseHandle( sem );} //! wait/acquire void P() {WaitForSingleObjectEx( sem, INFINITE, FALSE );} //! post/release void V() {ReleaseSemaphore( sem, 1, NULL );} private: HANDLE sem; void init_semaphore(size_t start_cnt_) { sem = CreateSemaphoreEx( NULL, LONG(start_cnt_), max_semaphore_cnt, NULL, 0, SEMAPHORE_ALL_ACCESS ); } }; #elif __APPLE__ //! Edsger Dijkstra's counting semaphore class semaphore : no_copy { public: //! ctor semaphore(int start_cnt_ = 0) : sem(start_cnt_) { init_semaphore(start_cnt_); } //! dtor ~semaphore() { kern_return_t ret = semaphore_destroy( mach_task_self(), sem ); __TBB_ASSERT_EX( ret==err_none, NULL ); } //! wait/acquire void P() { int ret; do { ret = semaphore_wait( sem ); } while( ret==KERN_ABORTED ); __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" ); } //! post/release void V() { semaphore_signal( sem ); } private: semaphore_t sem; void init_semaphore(int start_cnt_) { kern_return_t ret = semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, start_cnt_ ); __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" ); } }; #else /* Linux/Unix */ typedef uint32_t sem_count_t; //! Edsger Dijkstra's counting semaphore class semaphore : no_copy { public: //! ctor semaphore(int start_cnt_ = 0 ) { init_semaphore( start_cnt_ ); } //! dtor ~semaphore() { int ret = sem_destroy( &sem ); __TBB_ASSERT_EX( !ret, NULL ); } //! wait/acquire void P() { while( sem_wait( &sem )!=0 ) __TBB_ASSERT( errno==EINTR, NULL ); } //! post/release void V() { sem_post( &sem ); } private: sem_t sem; void init_semaphore(int start_cnt_) { int ret = sem_init( &sem, /*shared among threads*/ 0, start_cnt_ ); __TBB_ASSERT_EX( !ret, NULL ); } }; #endif /* _WIN32||_WIN64 */ //! for performance reasons, we want specialized binary_semaphore #if _WIN32||_WIN64 #if !__TBB_USE_SRWLOCK //! binary_semaphore for concurrent_monitor class binary_semaphore : no_copy { public: //! ctor binary_semaphore() { my_sem = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS ); } //! dtor ~binary_semaphore() { CloseHandle( my_sem ); } //! wait/acquire void P() { WaitForSingleObjectEx( my_sem, INFINITE, FALSE ); } //! post/release void V() { SetEvent( my_sem ); } private: HANDLE my_sem; }; #else /* __TBB_USE_SRWLOCK */ union srwl_or_handle { SRWLOCK lock; HANDLE h; }; //! binary_semaphore for concurrent_monitor class binary_semaphore : no_copy { public: //! ctor binary_semaphore(); //! dtor ~binary_semaphore(); //! wait/acquire void P(); //! post/release void V(); private: srwl_or_handle my_sem; }; #endif /* !__TBB_USE_SRWLOCK */ #elif __APPLE__ //! binary_semaphore for concurrent monitor class binary_semaphore : no_copy { public: //! ctor binary_semaphore() : my_sem(0) { kern_return_t ret = semaphore_create( mach_task_self(), &my_sem, SYNC_POLICY_FIFO, 0 ); __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" ); } //! dtor ~binary_semaphore() { kern_return_t ret = semaphore_destroy( mach_task_self(), my_sem ); __TBB_ASSERT_EX( ret==err_none, NULL ); } //! wait/acquire void P() { int ret; do { ret = semaphore_wait( my_sem ); } while( ret==KERN_ABORTED ); __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" ); } //! post/release void V() { semaphore_signal( my_sem ); } private: semaphore_t my_sem; }; #else /* Linux/Unix */ #if __TBB_USE_FUTEX class binary_semaphore : no_copy { public: //! ctor binary_semaphore() { my_sem = 1; } //! dtor ~binary_semaphore() {} //! wait/acquire void P() { int s; if( (s = my_sem.compare_and_swap( 1, 0 ))!=0 ) { if( s!=2 ) s = my_sem.fetch_and_store( 2 ); while( s!=0 ) { futex_wait( &my_sem, 2 ); s = my_sem.fetch_and_store( 2 ); } } } //! post/release void V() { __TBB_ASSERT( my_sem>=1, "multiple V()'s in a row?" ); if( my_sem--!=1 ) { //if old value was 2 my_sem = 0; futex_wakeup_one( &my_sem ); } } private: atomic my_sem; }; #else typedef uint32_t sem_count_t; //! binary_semaphore for concurrent monitor class binary_semaphore : no_copy { public: //! ctor binary_semaphore() { int ret = sem_init( &my_sem, /*shared among threads*/ 0, 0 ); __TBB_ASSERT_EX( !ret, NULL ); } //! dtor ~binary_semaphore() { int ret = sem_destroy( &my_sem ); __TBB_ASSERT_EX( !ret, NULL ); } //! wait/acquire void P() { while( sem_wait( &my_sem )!=0 ) __TBB_ASSERT( errno==EINTR, NULL ); } //! post/release void V() { sem_post( &my_sem ); } private: sem_t my_sem; }; #endif /* __TBB_USE_FUTEX */ #endif /* _WIN32||_WIN64 */ } // namespace internal } // namespace tbb #endif /* __TBB_tbb_semaphore_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/spin_mutex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_machine.h" #include "tbb/spin_mutex.h" #include "itt_notify.h" #include "tbb_misc.h" namespace tbb { void spin_mutex::scoped_lock::internal_acquire( spin_mutex& m ) { __TBB_ASSERT( !my_mutex, "already holding a lock on a spin_mutex" ); ITT_NOTIFY(sync_prepare, &m); __TBB_LockByte(m.flag); my_mutex = &m; ITT_NOTIFY(sync_acquired, &m); } void spin_mutex::scoped_lock::internal_release() { __TBB_ASSERT( my_mutex, "release on spin_mutex::scoped_lock that is not holding a lock" ); ITT_NOTIFY(sync_releasing, my_mutex); __TBB_UnlockByte(my_mutex->flag); my_mutex = NULL; } bool spin_mutex::scoped_lock::internal_try_acquire( spin_mutex& m ) { __TBB_ASSERT( !my_mutex, "already holding a lock on a spin_mutex" ); bool result = bool( __TBB_TryLockByte(m.flag) ); if( result ) { my_mutex = &m; ITT_NOTIFY(sync_acquired, &m); } return result; } void spin_mutex::internal_construct() { ITT_SYNC_CREATE(this, _T("tbb::spin_mutex"), _T("")); } } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/spin_mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_spin_mutex_H #define __TBB_spin_mutex_H #include #include #include "aligned_space.h" #include "tbb_stddef.h" #include "tbb_machine.h" #include "tbb_profiling.h" #include "internal/_mutex_padding.h" namespace tbb { //! A lock that occupies a single byte. /** A spin_mutex is a spin mutex that fits in a single byte. It should be used only for locking short critical sections (typically less than 20 instructions) when fairness is not an issue. If zero-initialized, the mutex is considered unheld. @ingroup synchronization */ class spin_mutex : internal::mutex_copy_deprecated_and_disabled { //! 0 if lock is released, 1 if lock is acquired. __TBB_atomic_flag flag; public: //! Construct unacquired lock. /** Equivalent to zero-initialization of *this. */ spin_mutex() : flag(0) { #if TBB_USE_THREADING_TOOLS internal_construct(); #endif } //! Represents acquisition of a mutex. class scoped_lock : internal::no_copy { private: //! Points to currently held mutex, or NULL if no lock is held. spin_mutex* my_mutex; //! Value to store into spin_mutex::flag to unlock the mutex. /** This variable is no longer used. Instead, 0 and 1 are used to represent that the lock is free and acquired, respectively. We keep the member variable here to ensure backward compatibility */ __TBB_Flag my_unlock_value; //! Like acquire, but with ITT instrumentation. void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m ); //! Like try_acquire, but with ITT instrumentation. bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m ); //! Like release, but with ITT instrumentation. void __TBB_EXPORTED_METHOD internal_release(); friend class spin_mutex; public: //! Construct without acquiring a mutex. scoped_lock() : my_mutex(NULL), my_unlock_value(0) {} //! Construct and acquire lock on a mutex. scoped_lock( spin_mutex& m ) : my_unlock_value(0) { internal::suppress_unused_warning(my_unlock_value); #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT my_mutex=NULL; internal_acquire(m); #else my_mutex=&m; __TBB_LockByte(m.flag); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ } //! Acquire lock. void acquire( spin_mutex& m ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT internal_acquire(m); #else my_mutex = &m; __TBB_LockByte(m.flag); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_acquire( spin_mutex& m ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT return internal_try_acquire(m); #else bool result = __TBB_TryLockByte(m.flag); if( result ) my_mutex = &m; return result; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ } //! Release lock void release() { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT internal_release(); #else __TBB_UnlockByte(my_mutex->flag); my_mutex = NULL; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } //! Destroy lock. If holding a lock, releases the lock first. ~scoped_lock() { if( my_mutex ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT internal_release(); #else __TBB_UnlockByte(my_mutex->flag); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } } }; //! Internal constructor with ITT instrumentation. void __TBB_EXPORTED_METHOD internal_construct(); // Mutex traits static const bool is_rw_mutex = false; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = false; // ISO C++0x compatibility methods //! Acquire lock void lock() { #if TBB_USE_THREADING_TOOLS aligned_space tmp; new(tmp.begin()) scoped_lock(*this); #else __TBB_LockByte(flag); #endif /* TBB_USE_THREADING_TOOLS*/ } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_lock() { #if TBB_USE_THREADING_TOOLS aligned_space tmp; return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); #else return __TBB_TryLockByte(flag); #endif /* TBB_USE_THREADING_TOOLS*/ } //! Release lock void unlock() { #if TBB_USE_THREADING_TOOLS aligned_space tmp; scoped_lock& s = *tmp.begin(); s.my_mutex = this; s.internal_release(); #else __TBB_store_with_release(flag, 0); #endif /* TBB_USE_THREADING_TOOLS */ } friend class scoped_lock; }; // end of spin_mutex __TBB_DEFINE_PROFILING_SET_NAME(spin_mutex) } // namespace tbb #if ( __TBB_x86_32 || __TBB_x86_64 ) #include "internal/_x86_eliding_mutex_impl.h" #endif namespace tbb { //! A cross-platform spin mutex with speculative lock acquisition. /** On platforms with proper HW support, this lock may speculatively execute its critical sections, using HW mechanisms to detect real data races and ensure atomicity of the critical sections. In particular, it uses Intel(R) Transactional Synchronization Extensions (Intel(R) TSX). Without such HW support, it behaves like a spin_mutex. It should be used for locking short critical sections where the lock is contended but the data it protects are not. If zero-initialized, the mutex is considered unheld. @ingroup synchronization */ #if ( __TBB_x86_32 || __TBB_x86_64 ) typedef interface7::internal::padded_mutex speculative_spin_mutex; #else typedef interface7::internal::padded_mutex speculative_spin_mutex; #endif __TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_mutex) } // namespace tbb #endif /* __TBB_spin_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/spin_rw_mutex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/spin_rw_mutex.h" #include "tbb/tbb_machine.h" #include "tbb/atomic.h" #include "itt_notify.h" #if defined(_MSC_VER) && defined(_Wp64) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (disable: 4244) #endif namespace tbb { template // a template can work with private spin_rw_mutex::state_t static inline T CAS(volatile T &addr, T newv, T oldv) { // ICC (9.1 and 10.1 tried) unable to do implicit conversion // from "volatile T*" to "volatile void*", so explicit cast added. return tbb::internal::as_atomic(addr).compare_and_swap( newv, oldv ); } //! Acquire write lock on the given mutex. bool spin_rw_mutex_v3::internal_acquire_writer() { ITT_NOTIFY(sync_prepare, this); for( internal::atomic_backoff backoff;;backoff.pause() ){ state_t s = const_cast(state); // ensure reloading if( !(s & BUSY) ) { // no readers, no writers if( CAS(state, WRITER, s)==s ) break; // successfully stored writer flag backoff.reset(); // we could be very close to complete op. } else if( !(s & WRITER_PENDING) ) { // no pending writers __TBB_AtomicOR(&state, WRITER_PENDING); } } ITT_NOTIFY(sync_acquired, this); return false; } //! Release writer lock on the given mutex void spin_rw_mutex_v3::internal_release_writer() { ITT_NOTIFY(sync_releasing, this); __TBB_AtomicAND( &state, READERS ); } //! Acquire read lock on given mutex. void spin_rw_mutex_v3::internal_acquire_reader() { ITT_NOTIFY(sync_prepare, this); for( internal::atomic_backoff b;;b.pause() ){ state_t s = const_cast(state); // ensure reloading if( !(s & (WRITER|WRITER_PENDING)) ) { // no writer or write requests state_t t = (state_t)__TBB_FetchAndAddW( &state, (intptr_t) ONE_READER ); if( !( t&WRITER )) break; // successfully stored increased number of readers // writer got there first, undo the increment __TBB_FetchAndAddW( &state, -(intptr_t)ONE_READER ); } } ITT_NOTIFY(sync_acquired, this); __TBB_ASSERT( state & READERS, "invalid state of a read lock: no readers" ); } //! Upgrade reader to become a writer. /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ bool spin_rw_mutex_v3::internal_upgrade() { state_t s = state; __TBB_ASSERT( s & READERS, "invalid state before upgrade: no readers " ); // check and set writer-pending flag // required conditions: either no pending writers, or we are the only reader // (with multiple readers and pending writer, another upgrade could have been requested) while( (s & READERS)==ONE_READER || !(s & WRITER_PENDING) ) { state_t old_s = s; if( (s=CAS(state, s | WRITER | WRITER_PENDING, s))==old_s ) { ITT_NOTIFY(sync_prepare, this); internal::atomic_backoff backoff; while( (state & READERS) != ONE_READER ) backoff.pause(); __TBB_ASSERT((state&(WRITER_PENDING|WRITER))==(WRITER_PENDING|WRITER),"invalid state when upgrading to writer"); // both new readers and writers are blocked at this time __TBB_FetchAndAddW( &state, - (intptr_t)(ONE_READER+WRITER_PENDING)); ITT_NOTIFY(sync_acquired, this); return true; // successfully upgraded } } // slow reacquire internal_release_reader(); return internal_acquire_writer(); // always returns false } //! Downgrade writer to a reader void spin_rw_mutex_v3::internal_downgrade() { ITT_NOTIFY(sync_releasing, this); __TBB_FetchAndAddW( &state, (intptr_t)(ONE_READER-WRITER)); __TBB_ASSERT( state & READERS, "invalid state after downgrade: no readers" ); } //! Release read lock on the given mutex void spin_rw_mutex_v3::internal_release_reader() { __TBB_ASSERT( state & READERS, "invalid state of a read lock: no readers" ); ITT_NOTIFY(sync_releasing, this); // release reader __TBB_FetchAndAddWrelease( &state,-(intptr_t)ONE_READER); } //! Try to acquire write lock on the given mutex bool spin_rw_mutex_v3::internal_try_acquire_writer() { // for a writer: only possible to acquire if no active readers or writers state_t s = state; if( !(s & BUSY) ) // no readers, no writers; mask is 1..1101 if( CAS(state, WRITER, s)==s ) { ITT_NOTIFY(sync_acquired, this); return true; // successfully stored writer flag } return false; } //! Try to acquire read lock on the given mutex bool spin_rw_mutex_v3::internal_try_acquire_reader() { // for a reader: acquire if no active or waiting writers state_t s = state; if( !(s & (WRITER|WRITER_PENDING)) ) { // no writers state_t t = (state_t)__TBB_FetchAndAddW( &state, (intptr_t) ONE_READER ); if( !( t&WRITER )) { // got the lock ITT_NOTIFY(sync_acquired, this); return true; // successfully stored increased number of readers } // writer got there first, undo the increment __TBB_FetchAndAddW( &state, -(intptr_t)ONE_READER ); } return false; } void spin_rw_mutex_v3::internal_construct() { ITT_SYNC_CREATE(this, _T("tbb::spin_rw_mutex"), _T("")); } } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/spin_rw_mutex.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_spin_rw_mutex_H #define __TBB_spin_rw_mutex_H #include "tbb_stddef.h" #include "tbb_machine.h" #include "tbb_profiling.h" #include "internal/_mutex_padding.h" namespace tbb { #if __TBB_TSX_AVAILABLE namespace interface8 { namespace internal { class x86_rtm_rw_mutex; }} #endif class spin_rw_mutex_v3; typedef spin_rw_mutex_v3 spin_rw_mutex; //! Fast, unfair, spinning reader-writer lock with backoff and writer-preference /** @ingroup synchronization */ class spin_rw_mutex_v3 : internal::mutex_copy_deprecated_and_disabled { //! @cond INTERNAL //! Internal acquire write lock. bool __TBB_EXPORTED_METHOD internal_acquire_writer(); //! Out of line code for releasing a write lock. /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ void __TBB_EXPORTED_METHOD internal_release_writer(); //! Internal acquire read lock. void __TBB_EXPORTED_METHOD internal_acquire_reader(); //! Internal upgrade reader to become a writer. bool __TBB_EXPORTED_METHOD internal_upgrade(); //! Out of line code for downgrading a writer to a reader. /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ void __TBB_EXPORTED_METHOD internal_downgrade(); //! Internal release read lock. void __TBB_EXPORTED_METHOD internal_release_reader(); //! Internal try_acquire write lock. bool __TBB_EXPORTED_METHOD internal_try_acquire_writer(); //! Internal try_acquire read lock. bool __TBB_EXPORTED_METHOD internal_try_acquire_reader(); //! @endcond public: //! Construct unacquired mutex. spin_rw_mutex_v3() : state(0) { #if TBB_USE_THREADING_TOOLS internal_construct(); #endif } #if TBB_USE_ASSERT //! Destructor asserts if the mutex is acquired, i.e. state is zero. ~spin_rw_mutex_v3() { __TBB_ASSERT( !state, "destruction of an acquired mutex"); }; #endif /* TBB_USE_ASSERT */ //! The scoped locking pattern /** It helps to avoid the common problem of forgetting to release lock. It also nicely provides the "node" for queuing locks. */ class scoped_lock : internal::no_copy { #if __TBB_TSX_AVAILABLE friend class tbb::interface8::internal::x86_rtm_rw_mutex; // helper methods for x86_rtm_rw_mutex spin_rw_mutex *internal_get_mutex() const { return mutex; } void internal_set_mutex(spin_rw_mutex* m) { mutex = m; } #endif public: //! Construct lock that has not acquired a mutex. /** Equivalent to zero-initialization of *this. */ scoped_lock() : mutex(NULL), is_writer(false) {} //! Acquire lock on given mutex. scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) { acquire(m, write); } //! Release lock (if lock is held). ~scoped_lock() { if( mutex ) release(); } //! Acquire lock on given mutex. void acquire( spin_rw_mutex& m, bool write = true ) { __TBB_ASSERT( !mutex, "holding mutex already" ); is_writer = write; mutex = &m; if( write ) mutex->internal_acquire_writer(); else mutex->internal_acquire_reader(); } //! Upgrade reader to become a writer. /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ bool upgrade_to_writer() { __TBB_ASSERT( mutex, "lock is not acquired" ); __TBB_ASSERT( !is_writer, "not a reader" ); is_writer = true; return mutex->internal_upgrade(); } //! Release lock. void release() { __TBB_ASSERT( mutex, "lock is not acquired" ); spin_rw_mutex *m = mutex; mutex = NULL; #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT if( is_writer ) m->internal_release_writer(); else m->internal_release_reader(); #else if( is_writer ) __TBB_AtomicAND( &m->state, READERS ); else __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } //! Downgrade writer to become a reader. bool downgrade_to_reader() { __TBB_ASSERT( mutex, "lock is not acquired" ); __TBB_ASSERT( is_writer, "not a writer" ); #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT mutex->internal_downgrade(); #else __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER)); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ is_writer = false; return true; } //! Try acquire lock on given mutex. bool try_acquire( spin_rw_mutex& m, bool write = true ) { __TBB_ASSERT( !mutex, "holding mutex already" ); bool result; is_writer = write; result = write? m.internal_try_acquire_writer() : m.internal_try_acquire_reader(); if( result ) mutex = &m; return result; } protected: //! The pointer to the current mutex that is held, or NULL if no mutex is held. spin_rw_mutex* mutex; //! If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock. /** Not defined if not holding a lock. */ bool is_writer; }; // Mutex traits static const bool is_rw_mutex = true; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = false; // ISO C++0x compatibility methods //! Acquire writer lock void lock() {internal_acquire_writer();} //! Try acquiring writer lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_lock() {return internal_try_acquire_writer();} //! Release lock void unlock() { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT if( state&WRITER ) internal_release_writer(); else internal_release_reader(); #else if( state&WRITER ) __TBB_AtomicAND( &state, READERS ); else __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } // Methods for reader locks that resemble ISO C++0x compatibility methods. //! Acquire reader lock void lock_read() {internal_acquire_reader();} //! Try acquiring reader lock (non-blocking) /** Return true if reader lock acquired; false otherwise. */ bool try_lock_read() {return internal_try_acquire_reader();} protected: typedef intptr_t state_t; static const state_t WRITER = 1; static const state_t WRITER_PENDING = 2; static const state_t READERS = ~(WRITER | WRITER_PENDING); static const state_t ONE_READER = 4; static const state_t BUSY = WRITER | READERS; //! State of lock /** Bit 0 = writer is holding lock Bit 1 = request by a writer to acquire lock (hint to readers to wait) Bit 2..N = number of readers holding lock */ state_t state; private: void __TBB_EXPORTED_METHOD internal_construct(); }; __TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex) } // namespace tbb #if __TBB_TSX_AVAILABLE #include "internal/_x86_rtm_rw_mutex_impl.h" #endif namespace tbb { namespace interface8 { //! A cross-platform spin reader/writer mutex with speculative lock acquisition. /** On platforms with proper HW support, this lock may speculatively execute its critical sections, using HW mechanisms to detect real data races and ensure atomicity of the critical sections. In particular, it uses Intel(R) Transactional Synchronization Extensions (Intel(R) TSX). Without such HW support, it behaves like a spin_rw_mutex. It should be used for locking short critical sections where the lock is contended but the data it protects are not. @ingroup synchronization */ #if __TBB_TSX_AVAILABLE typedef interface7::internal::padded_mutex speculative_spin_rw_mutex; #else typedef interface7::internal::padded_mutex speculative_spin_rw_mutex; #endif } // namespace interface8 using interface8::speculative_spin_rw_mutex; __TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_rw_mutex) } // namespace tbb #endif /* __TBB_spin_rw_mutex_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // Do not include task.h directly. Use scheduler_common.h instead #include "scheduler_common.h" #include "governor.h" #include "scheduler.h" #include "itt_notify.h" #include "tbb/cache_aligned_allocator.h" #include "tbb/partitioner.h" #include namespace tbb { using namespace std; namespace internal { //------------------------------------------------------------------------ // Methods of allocate_root_proxy //------------------------------------------------------------------------ task& allocate_root_proxy::allocate( size_t size ) { internal::generic_scheduler* v = governor::local_scheduler(); __TBB_ASSERT( v, "thread did not activate a task_scheduler_init object?" ); #if __TBB_TASK_GROUP_CONTEXT task_prefix& p = v->my_innermost_running_task->prefix(); ITT_STACK_CREATE(p.context->itt_caller); #endif // New root task becomes part of the currently running task's cancellation context return v->allocate_task( size, __TBB_CONTEXT_ARG(NULL, p.context) ); } void allocate_root_proxy::free( task& task ) { internal::generic_scheduler* v = governor::local_scheduler(); __TBB_ASSERT( v, "thread does not have initialized task_scheduler_init object?" ); #if __TBB_TASK_GROUP_CONTEXT // No need to do anything here as long as there is no context -> task connection #endif /* __TBB_TASK_GROUP_CONTEXT */ v->free_task( task ); } #if __TBB_TASK_GROUP_CONTEXT //------------------------------------------------------------------------ // Methods of allocate_root_with_context_proxy //------------------------------------------------------------------------ task& allocate_root_with_context_proxy::allocate( size_t size ) const { internal::generic_scheduler* s = governor::local_scheduler(); __TBB_ASSERT( s, "Scheduler auto-initialization failed?" ); task& t = s->allocate_task( size, NULL, &my_context ); // Supported usage model prohibits concurrent initial binding. Thus we do not // need interlocked operations or fences to manipulate with my_context.my_kind if ( __TBB_load_relaxed(my_context.my_kind) == task_group_context::binding_required ) { // If we are in the outermost task dispatch loop of a master thread, then // there is nothing to bind this context to, and we skip the binding part // treating the context as isolated. if ( s->my_innermost_running_task == s->my_dummy_task ) __TBB_store_relaxed(my_context.my_kind, task_group_context::isolated); else my_context.bind_to( s ); } #if __TBB_FP_CONTEXT if ( __TBB_load_relaxed(my_context.my_kind) == task_group_context::isolated && !(my_context.my_version_and_traits & task_group_context::fp_settings) ) my_context.copy_fp_settings( *s->my_arena->my_default_ctx ); #endif ITT_STACK_CREATE(my_context.itt_caller); return t; } void allocate_root_with_context_proxy::free( task& task ) const { internal::generic_scheduler* v = governor::local_scheduler(); __TBB_ASSERT( v, "thread does not have initialized task_scheduler_init object?" ); // No need to do anything here as long as unbinding is performed by context destructor only. v->free_task( task ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //------------------------------------------------------------------------ // Methods of allocate_continuation_proxy //------------------------------------------------------------------------ task& allocate_continuation_proxy::allocate( size_t size ) const { task& t = *((task*)this); assert_task_valid(t); generic_scheduler* s = governor::local_scheduler(); task* parent = t.parent(); t.prefix().parent = NULL; return s->allocate_task( size, __TBB_CONTEXT_ARG(parent, t.prefix().context) ); } void allocate_continuation_proxy::free( task& mytask ) const { // Restore the parent as it was before the corresponding allocate was called. ((task*)this)->prefix().parent = mytask.parent(); governor::local_scheduler()->free_task(mytask); } //------------------------------------------------------------------------ // Methods of allocate_child_proxy //------------------------------------------------------------------------ task& allocate_child_proxy::allocate( size_t size ) const { task& t = *((task*)this); assert_task_valid(t); generic_scheduler* s = governor::local_scheduler(); return s->allocate_task( size, __TBB_CONTEXT_ARG(&t, t.prefix().context) ); } void allocate_child_proxy::free( task& mytask ) const { governor::local_scheduler()->free_task(mytask); } //------------------------------------------------------------------------ // Methods of allocate_additional_child_of_proxy //------------------------------------------------------------------------ task& allocate_additional_child_of_proxy::allocate( size_t size ) const { parent.increment_ref_count(); generic_scheduler* s = governor::local_scheduler(); return s->allocate_task( size, __TBB_CONTEXT_ARG(&parent, parent.prefix().context) ); } void allocate_additional_child_of_proxy::free( task& task ) const { // Undo the increment. We do not check the result of the fetch-and-decrement. // We could consider be spawning the task if the fetch-and-decrement returns 1. // But we do not know that was the programmer's intention. // Furthermore, if it was the programmer's intention, the program has a fundamental // race condition (that we warn about in Reference manual), because the // reference count might have become zero before the corresponding call to // allocate_additional_child_of_proxy::allocate. parent.internal_decrement_ref_count(); governor::local_scheduler()->free_task(task); } //------------------------------------------------------------------------ // Support for auto_partitioner //------------------------------------------------------------------------ size_t get_initial_auto_partitioner_divisor() { const size_t X_FACTOR = 4; return X_FACTOR * (1+governor::local_scheduler()->number_of_workers_in_my_arena()); } //------------------------------------------------------------------------ // Methods of affinity_partitioner_base_v3 //------------------------------------------------------------------------ void affinity_partitioner_base_v3::resize( unsigned factor ) { // Check factor to avoid asking for number of workers while there might be no arena. size_t new_size = factor ? factor*(1+governor::local_scheduler()->number_of_workers_in_my_arena()) : 0; if( new_size!=my_size ) { if( my_array ) { NFS_Free( my_array ); // Following two assignments must be done here for sake of exception safety. my_array = NULL; my_size = 0; } if( new_size ) { my_array = static_cast(NFS_Allocate(new_size,sizeof(affinity_id), NULL )); memset( my_array, 0, sizeof(affinity_id)*new_size ); my_size = new_size; } } } } // namespace internal using namespace tbb::internal; //------------------------------------------------------------------------ // task //------------------------------------------------------------------------ void task::internal_set_ref_count( int count ) { __TBB_ASSERT( count>=0, "count must not be negative" ); task_prefix &p = prefix(); __TBB_ASSERT(p.ref_count==1 && p.state==allocated && self().parent()==this || !(p.extra_state & es_ref_count_active), "ref_count race detected"); ITT_NOTIFY(sync_releasing, &p.ref_count); p.ref_count = count; } internal::reference_count task::internal_decrement_ref_count() { ITT_NOTIFY( sync_releasing, &prefix().ref_count ); internal::reference_count k = __TBB_FetchAndDecrementWrelease( &prefix().ref_count ); __TBB_ASSERT( k>=1, "task's reference count underflowed" ); if( k==1 ) ITT_NOTIFY( sync_acquired, &prefix().ref_count ); return k-1; } task& task::self() { generic_scheduler *v = governor::local_scheduler(); v->assert_task_pool_valid(); __TBB_ASSERT( v->my_innermost_running_task, NULL ); return *v->my_innermost_running_task; } bool task::is_owned_by_current_thread() const { return true; } void interface5::internal::task_base::destroy( task& victim ) { // 1 may be a guard reference for wait_for_all, which was not reset because // of concurrent_wait mode or because prepared root task was not actually used // for spawning tasks (as in structured_task_group). __TBB_ASSERT( (intptr_t)victim.prefix().ref_count <= 1, "Task being destroyed must not have children" ); __TBB_ASSERT( victim.state()==task::allocated, "illegal state for victim task" ); task* parent = victim.parent(); victim.~task(); if( parent ) { __TBB_ASSERT( parent->state()!=task::freed && parent->state()!=task::ready, "attempt to destroy child of running or corrupted parent?" ); // 'reexecute' and 'executing' are also signs of a race condition, since most tasks // set their ref_count upon entry but "es_ref_count_active" should detect this parent->internal_decrement_ref_count(); // Even if the last reference to *parent is removed, it should not be spawned (documented behavior). } governor::local_scheduler()->free_task( victim ); } void task::spawn_and_wait_for_all( task_list& list ) { generic_scheduler* s = governor::local_scheduler(); task* t = list.first; if( t ) { if( &t->prefix().next!=list.next_ptr ) s->local_spawn( *t->prefix().next, *list.next_ptr ); list.clear(); } s->local_wait_for_all( *this, t ); } /** Defined out of line so that compiler does not replicate task's vtable. It's pointless to define it inline anyway, because all call sites to it are virtual calls that the compiler is unlikely to optimize. */ void task::note_affinity( affinity_id ) { } #if __TBB_TASK_GROUP_CONTEXT void task::change_group ( task_group_context& ctx ) { prefix().context = &ctx; internal::generic_scheduler* s = governor::local_scheduler(); if ( __TBB_load_relaxed(ctx.my_kind) == task_group_context::binding_required ) { // If we are in the outermost task dispatch loop of a master thread, then // there is nothing to bind this context to, and we skip the binding part // treating the context as isolated. if ( s->my_innermost_running_task == s->my_dummy_task ) __TBB_store_relaxed(ctx.my_kind, task_group_context::isolated); else ctx.bind_to( s ); } #if __TBB_FP_CONTEXT if ( __TBB_load_relaxed(ctx.my_kind) == task_group_context::isolated && !(ctx.my_version_and_traits & task_group_context::fp_settings) ) ctx.copy_fp_settings( *s->my_arena->my_default_ctx ); #endif ITT_STACK_CREATE(ctx.itt_caller); } #endif /* __TBB_TASK_GROUP_CONTEXT */ } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_task_H #define __TBB_task_H #include "tbb_stddef.h" #include "tbb_machine.h" #include typedef struct ___itt_caller *__itt_caller; namespace tbb { class task; class task_list; class task_group_context; // MSVC does not allow taking the address of a member that was defined // privately in task_base and made public in class task via a using declaration. #if _MSC_VER || (__GNUC__==3 && __GNUC_MINOR__<3) #define __TBB_TASK_BASE_ACCESS public #else #define __TBB_TASK_BASE_ACCESS private #endif namespace internal { //< @cond INTERNAL class allocate_additional_child_of_proxy: no_assign { //! No longer used, but retained for binary layout compatibility. Always NULL. task* self; task& parent; public: explicit allocate_additional_child_of_proxy( task& parent_ ) : self(NULL), parent(parent_) {} task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; void __TBB_EXPORTED_METHOD free( task& ) const; }; struct cpu_ctl_env_space { int space[sizeof(internal::uint64_t)/sizeof(int)]; }; } //< namespace internal @endcond namespace interface5 { namespace internal { //! Base class for methods that became static in TBB 3.0. /** TBB's evolution caused the "this" argument for several methods to become obsolete. However, for backwards binary compatibility, the new methods need distinct names, otherwise the One Definition Rule would be broken. Hence the new methods are defined in this private base class, and then exposed in class task via using declarations. */ class task_base: tbb::internal::no_copy { __TBB_TASK_BASE_ACCESS: friend class tbb::task; //! Schedule task for execution when a worker becomes available. static void spawn( task& t ); //! Spawn multiple tasks and clear list. static void spawn( task_list& list ); //! Like allocate_child, except that task's parent becomes "t", not this. /** Typically used in conjunction with schedule_to_reexecute to implement while loops. Atomically increments the reference count of t.parent() */ static tbb::internal::allocate_additional_child_of_proxy allocate_additional_child_of( task& t ) { return tbb::internal::allocate_additional_child_of_proxy(t); } //! Destroy a task. /** Usually, calling this method is unnecessary, because a task is implicitly deleted after its execute() method runs. However, sometimes a task needs to be explicitly deallocated, such as when a root task is used as the parent in spawn_and_wait_for_all. */ static void __TBB_EXPORTED_FUNC destroy( task& victim ); }; } // internal } // interface5 //! @cond INTERNAL namespace internal { class scheduler: no_copy { public: //! For internal use only virtual void spawn( task& first, task*& next ) = 0; //! For internal use only virtual void wait_for_all( task& parent, task* child ) = 0; //! For internal use only virtual void spawn_root_and_wait( task& first, task*& next ) = 0; //! Pure virtual destructor; // Have to have it just to shut up overzealous compilation warnings virtual ~scheduler() = 0; //! For internal use only virtual void enqueue( task& t, void* reserved ) = 0; }; //! A reference count /** Should always be non-negative. A signed type is used so that underflow can be detected. */ typedef intptr_t reference_count; //! An id as used for specifying affinity. typedef unsigned short affinity_id; #if __TBB_TASK_GROUP_CONTEXT class generic_scheduler; struct context_list_node_t { context_list_node_t *my_prev, *my_next; }; class allocate_root_with_context_proxy: no_assign { task_group_context& my_context; public: allocate_root_with_context_proxy ( task_group_context& ctx ) : my_context(ctx) {} task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; void __TBB_EXPORTED_METHOD free( task& ) const; }; #endif /* __TBB_TASK_GROUP_CONTEXT */ class allocate_root_proxy: no_assign { public: static task& __TBB_EXPORTED_FUNC allocate( size_t size ); static void __TBB_EXPORTED_FUNC free( task& ); }; class allocate_continuation_proxy: no_assign { public: task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; void __TBB_EXPORTED_METHOD free( task& ) const; }; class allocate_child_proxy: no_assign { public: task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; void __TBB_EXPORTED_METHOD free( task& ) const; }; //! Memory prefix to a task object. /** This class is internal to the library. Do not reference it directly, except within the library itself. Fields are ordered in way that preserves backwards compatibility and yields good packing on typical 32-bit and 64-bit platforms. In case task prefix size exceeds 32 or 64 bytes on IA32 and Intel64 architectures correspondingly, consider dynamic setting of task_alignment and task_prefix_reservation_size based on the maximal operand size supported by the current CPU. @ingroup task_scheduling */ class task_prefix { private: friend class tbb::task; friend class tbb::interface5::internal::task_base; friend class tbb::task_list; friend class internal::scheduler; friend class internal::allocate_root_proxy; friend class internal::allocate_child_proxy; friend class internal::allocate_continuation_proxy; friend class internal::allocate_additional_child_of_proxy; #if __TBB_TASK_GROUP_CONTEXT //! Shared context that is used to communicate asynchronous state changes /** Currently it is used to broadcast cancellation requests generated both by users and as the result of unhandled exceptions in the task::execute() methods. */ task_group_context *context; #endif /* __TBB_TASK_GROUP_CONTEXT */ //! The scheduler that allocated the task, or NULL if the task is big. /** Small tasks are pooled by the scheduler that allocated the task. If a scheduler needs to free a small task allocated by another scheduler, it returns the task to that other scheduler. This policy avoids memory space blowup issues for memory allocators that allocate from thread-specific pools. */ scheduler* origin; #if __TBB_TASK_PRIORITY union { #endif /* __TBB_TASK_PRIORITY */ //! Obsolete. The scheduler that owns the task. /** Retained only for the sake of backward binary compatibility. Still used by inline methods in the task.h header. **/ scheduler* owner; #if __TBB_TASK_PRIORITY //! Pointer to the next offloaded lower priority task. /** Used to maintain a list of offloaded tasks inside the scheduler. **/ task* next_offloaded; }; #endif /* __TBB_TASK_PRIORITY */ //! The task whose reference count includes me. /** In the "blocking style" of programming, this field points to the parent task. In the "continuation-passing style" of programming, this field points to the continuation of the parent. */ tbb::task* parent; //! Reference count used for synchronization. /** In the "continuation-passing style" of programming, this field is the difference of the number of allocated children minus the number of children that have completed. In the "blocking style" of programming, this field is one more than the difference. */ __TBB_atomic reference_count ref_count; //! Obsolete. Used to be scheduling depth before TBB 2.2 /** Retained only for the sake of backward binary compatibility. Not used by TBB anymore. **/ int depth; //! A task::state_type, stored as a byte for compactness. /** This state is exposed to users via method task::state(). */ unsigned char state; //! Miscellaneous state that is not directly visible to users, stored as a byte for compactness. /** 0x0 -> version 1.0 task 0x1 -> version >=2.1 task 0x10 -> task was enqueued 0x20 -> task_proxy 0x40 -> task has live ref_count 0x80 -> a stolen task */ unsigned char extra_state; affinity_id affinity; //! "next" field for list of task tbb::task* next; //! The task corresponding to this task_prefix. tbb::task& task() {return *reinterpret_cast(this+1);} }; } // namespace internal //! @endcond #if __TBB_TASK_GROUP_CONTEXT #if __TBB_TASK_PRIORITY namespace internal { static const int priority_stride_v4 = INT_MAX / 4; } enum priority_t { priority_normal = internal::priority_stride_v4 * 2, priority_low = priority_normal - internal::priority_stride_v4, priority_high = priority_normal + internal::priority_stride_v4 }; #endif /* __TBB_TASK_PRIORITY */ #if TBB_USE_CAPTURED_EXCEPTION class tbb_exception; #else namespace internal { class tbb_exception_ptr; } #endif /* !TBB_USE_CAPTURED_EXCEPTION */ class task_scheduler_init; namespace interface7 { class task_arena; } //! Used to form groups of tasks /** @ingroup task_scheduling The context services explicit cancellation requests from user code, and unhandled exceptions intercepted during tasks execution. Intercepting an exception results in generating internal cancellation requests (which is processed in exactly the same way as external ones). The context is associated with one or more root tasks and defines the cancellation group that includes all the descendants of the corresponding root task(s). Association is established when a context object is passed as an argument to the task::allocate_root() method. See task_group_context::task_group_context for more details. The context can be bound to another one, and other contexts can be bound to it, forming a tree-like structure: parent -> this -> children. Arrows here designate cancellation propagation direction. If a task in a cancellation group is cancelled all the other tasks in this group and groups bound to it (as children) get cancelled too. IMPLEMENTATION NOTE: When adding new members to task_group_context or changing types of existing ones, update the size of both padding buffers (_leading_padding and _trailing_padding) appropriately. See also VERSIONING NOTE at the constructor definition below. **/ class task_group_context : internal::no_copy { private: friend class internal::generic_scheduler; friend class task_scheduler_init; friend class interface7::task_arena; #if TBB_USE_CAPTURED_EXCEPTION typedef tbb_exception exception_container_type; #else typedef internal::tbb_exception_ptr exception_container_type; #endif enum version_traits_word_layout { traits_offset = 16, version_mask = 0xFFFF, traits_mask = 0xFFFFul << traits_offset }; public: enum kind_type { isolated, bound }; enum traits_type { exact_exception = 0x0001ul << traits_offset, #if __TBB_FP_CONTEXT fp_settings = 0x0002ul << traits_offset, #endif concurrent_wait = 0x0004ul << traits_offset, #if TBB_USE_CAPTURED_EXCEPTION default_traits = 0 #else default_traits = exact_exception #endif /* !TBB_USE_CAPTURED_EXCEPTION */ }; private: enum state { may_have_children = 1, // the following enumerations must be the last, new 2^x values must go above next_state_value, low_unused_state_bit = (next_state_value-1)*2 }; union { //! Flavor of this context: bound or isolated. // TODO: describe asynchronous use, and whether any memory semantics are needed __TBB_atomic kind_type my_kind; uintptr_t _my_kind_aligner; }; //! Pointer to the context of the parent cancellation group. NULL for isolated contexts. task_group_context *my_parent; //! Used to form the thread specific list of contexts without additional memory allocation. /** A context is included into the list of the current thread when its binding to its parent happens. Any context can be present in the list of one thread only. **/ internal::context_list_node_t my_node; //! Used to set and maintain stack stitching point for Intel Performance Tools. __itt_caller itt_caller; //! Leading padding protecting accesses to frequently used members from false sharing. /** Read accesses to the field my_cancellation_requested are on the hot path inside the scheduler. This padding ensures that this field never shares the same cache line with a local variable that is frequently written to. **/ char _leading_padding[internal::NFS_MaxLineSize - 2 * sizeof(uintptr_t)- sizeof(void*) - sizeof(internal::context_list_node_t) - sizeof(__itt_caller) #if __TBB_FP_CONTEXT - sizeof(internal::cpu_ctl_env_space) #endif ]; #if __TBB_FP_CONTEXT //! Space for platform-specific FPU settings. /** Must only be accessed inside TBB binaries, and never directly in user code or inline methods. */ internal::cpu_ctl_env_space my_cpu_ctl_env; #endif //! Specifies whether cancellation was requested for this task group. uintptr_t my_cancellation_requested; //! Version for run-time checks and behavioral traits of the context. /** Version occupies low 16 bits, and traits (zero or more ORed enumerators from the traits_type enumerations) take the next 16 bits. Original (zeroth) version of the context did not support any traits. **/ uintptr_t my_version_and_traits; //! Pointer to the container storing exception being propagated across this task group. exception_container_type *my_exception; //! Scheduler instance that registered this context in its thread specific list. internal::generic_scheduler *my_owner; //! Internal state (combination of state flags, currently only may_have_children). uintptr_t my_state; #if __TBB_TASK_PRIORITY //! Priority level of the task group (in normalized representation) intptr_t my_priority; #endif /* __TBB_TASK_PRIORITY */ //! Trailing padding protecting accesses to frequently used members from false sharing /** \sa _leading_padding **/ char _trailing_padding[internal::NFS_MaxLineSize - 2 * sizeof(uintptr_t) - 2 * sizeof(void*) #if __TBB_TASK_PRIORITY - sizeof(intptr_t) #endif /* __TBB_TASK_PRIORITY */ ]; public: //! Default & binding constructor. /** By default a bound context is created. That is this context will be bound (as child) to the context of the task calling task::allocate_root(this_context) method. Cancellation requests passed to the parent context are propagated to all the contexts bound to it. Similarly priority change is propagated from the parent context to its children. If task_group_context::isolated is used as the argument, then the tasks associated with this context will never be affected by events in any other context. Creating isolated contexts involve much less overhead, but they have limited utility. Normally when an exception occurs in an algorithm that has nested ones running, it is desirably to have all the nested algorithms cancelled as well. Such a behavior requires nested algorithms to use bound contexts. There is one good place where using isolated algorithms is beneficial. It is a master thread. That is if a particular algorithm is invoked directly from the master thread (not from a TBB task), supplying it with explicitly created isolated context will result in a faster algorithm startup. VERSIONING NOTE: Implementation(s) of task_group_context constructor(s) cannot be made entirely out-of-line because the run-time version must be set by the user code. This will become critically important for binary compatibility, if we ever have to change the size of the context object. Boosting the runtime version will also be necessary if new data fields are introduced in the currently unused padding areas and these fields are updated by inline methods. **/ task_group_context ( kind_type relation_with_parent = bound, uintptr_t traits = default_traits ) : my_kind(relation_with_parent) , my_version_and_traits(2 | traits) { init(); } // Do not introduce standalone unbind method since it will break state propagation assumptions __TBB_EXPORTED_METHOD ~task_group_context (); //! Forcefully reinitializes the context after the task tree it was associated with is completed. /** Because the method assumes that all the tasks that used to be associated with this context have already finished, calling it while the context is still in use somewhere in the task hierarchy leads to undefined behavior. IMPORTANT: This method is not thread safe! The method does not change the context's parent if it is set. **/ void __TBB_EXPORTED_METHOD reset (); //! Initiates cancellation of all tasks in this cancellation group and its subordinate groups. /** \return false if cancellation has already been requested, true otherwise. Note that canceling never fails. When false is returned, it just means that another thread (or this one) has already sent cancellation request to this context or to one of its ancestors (if this context is bound). It is guaranteed that when this method is concurrently called on the same not yet cancelled context, true will be returned by one and only one invocation. **/ bool __TBB_EXPORTED_METHOD cancel_group_execution (); //! Returns true if the context received cancellation request. bool __TBB_EXPORTED_METHOD is_group_execution_cancelled () const; //! Records the pending exception, and cancels the task group. /** May be called only from inside a catch-block. If the context is already cancelled, does nothing. The method brings the task group associated with this context exactly into the state it would be in, if one of its tasks threw the currently pending exception during its execution. In other words, it emulates the actions of the scheduler's dispatch loop exception handler. **/ void __TBB_EXPORTED_METHOD register_pending_exception (); #if __TBB_FP_CONTEXT //! Captures the current FPU control settings to the context. /** Because the method assumes that all the tasks that used to be associated with this context have already finished, calling it while the context is still in use somewhere in the task hierarchy leads to undefined behavior. IMPORTANT: This method is not thread safe! The method does not change the FPU control settings of the context's parent. **/ void __TBB_EXPORTED_METHOD capture_fp_settings (); #endif #if __TBB_TASK_PRIORITY //! Changes priority of the task group void set_priority ( priority_t ); //! Retrieves current priority of the current task group priority_t priority () const; #endif /* __TBB_TASK_PRIORITY */ protected: //! Out-of-line part of the constructor. /** Singled out to ensure backward binary compatibility of the future versions. **/ void __TBB_EXPORTED_METHOD init (); private: friend class task; friend class internal::allocate_root_with_context_proxy; static const kind_type binding_required = bound; static const kind_type binding_completed = kind_type(bound+1); static const kind_type detached = kind_type(binding_completed+1); static const kind_type dying = kind_type(detached+1); //! Propagates any state change detected to *this, and as an optimisation possibly also upward along the heritage line. template void propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); //! Registers this context with the local scheduler and binds it to its parent context void bind_to ( internal::generic_scheduler *local_sched ); //! Registers this context with the local scheduler void register_with ( internal::generic_scheduler *local_sched ); #if __TBB_FP_CONTEXT //! Copies FPU control setting from another context // TODO: Consider adding #else stub in order to omit #if sections in other code void copy_fp_settings( const task_group_context &src ); #endif /* __TBB_FP_CONTEXT */ }; // class task_group_context #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Base class for user-defined tasks. /** @ingroup task_scheduling */ class task: __TBB_TASK_BASE_ACCESS interface5::internal::task_base { //! Set reference count void __TBB_EXPORTED_METHOD internal_set_ref_count( int count ); //! Decrement reference count and return its new value. internal::reference_count __TBB_EXPORTED_METHOD internal_decrement_ref_count(); protected: //! Default constructor. task() {prefix().extra_state=1;} public: //! Destructor. virtual ~task() {} //! Should be overridden by derived classes. virtual task* execute() = 0; //! Enumeration of task states that the scheduler considers. enum state_type { //! task is running, and will be destroyed after method execute() completes. executing, //! task to be rescheduled. reexecute, //! task is in ready pool, or is going to be put there, or was just taken off. ready, //! task object is freshly allocated or recycled. allocated, //! task object is on free list, or is going to be put there, or was just taken off. freed, //! task to be recycled as continuation recycle #if __TBB_RECYCLE_TO_ENQUEUE //! task to be scheduled for starvation-resistant execution ,to_enqueue #endif }; //------------------------------------------------------------------------ // Allocating tasks //------------------------------------------------------------------------ //! Returns proxy for overloaded new that allocates a root task. static internal::allocate_root_proxy allocate_root() { return internal::allocate_root_proxy(); } #if __TBB_TASK_GROUP_CONTEXT //! Returns proxy for overloaded new that allocates a root task associated with user supplied context. static internal::allocate_root_with_context_proxy allocate_root( task_group_context& ctx ) { return internal::allocate_root_with_context_proxy(ctx); } #endif /* __TBB_TASK_GROUP_CONTEXT */ //! Returns proxy for overloaded new that allocates a continuation task of *this. /** The continuation's parent becomes the parent of *this. */ internal::allocate_continuation_proxy& allocate_continuation() { return *reinterpret_cast(this); } //! Returns proxy for overloaded new that allocates a child task of *this. internal::allocate_child_proxy& allocate_child() { return *reinterpret_cast(this); } //! Define recommended static form via import from base class. using task_base::allocate_additional_child_of; #if __TBB_DEPRECATED_TASK_INTERFACE //! Destroy a task. /** Usually, calling this method is unnecessary, because a task is implicitly deleted after its execute() method runs. However, sometimes a task needs to be explicitly deallocated, such as when a root task is used as the parent in spawn_and_wait_for_all. */ void __TBB_EXPORTED_METHOD destroy( task& t ); #else /* !__TBB_DEPRECATED_TASK_INTERFACE */ //! Define recommended static form via import from base class. using task_base::destroy; #endif /* !__TBB_DEPRECATED_TASK_INTERFACE */ //------------------------------------------------------------------------ // Recycling of tasks //------------------------------------------------------------------------ //! Change this to be a continuation of its former self. /** The caller must guarantee that the task's refcount does not become zero until after the method execute() returns. Typically, this is done by having method execute() return a pointer to a child of the task. If the guarantee cannot be made, use method recycle_as_safe_continuation instead. Because of the hazard, this method may be deprecated in the future. */ void recycle_as_continuation() { __TBB_ASSERT( prefix().state==executing, "execute not running?" ); prefix().state = allocated; } //! Recommended to use, safe variant of recycle_as_continuation /** For safety, it requires additional increment of ref_count. With no descendants and ref_count of 1, it has the semantics of recycle_to_reexecute. */ void recycle_as_safe_continuation() { __TBB_ASSERT( prefix().state==executing, "execute not running?" ); prefix().state = recycle; } //! Change this to be a child of new_parent. void recycle_as_child_of( task& new_parent ) { internal::task_prefix& p = prefix(); __TBB_ASSERT( prefix().state==executing||prefix().state==allocated, "execute not running, or already recycled" ); __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled as a child" ); __TBB_ASSERT( p.parent==NULL, "parent must be null" ); __TBB_ASSERT( new_parent.prefix().state<=recycle, "corrupt parent's state" ); __TBB_ASSERT( new_parent.prefix().state!=freed, "parent already freed" ); p.state = allocated; p.parent = &new_parent; #if __TBB_TASK_GROUP_CONTEXT p.context = new_parent.prefix().context; #endif /* __TBB_TASK_GROUP_CONTEXT */ } //! Schedule this for reexecution after current execute() returns. /** Made obsolete by recycle_as_safe_continuation; may become deprecated. */ void recycle_to_reexecute() { __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" ); __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled for reexecution" ); prefix().state = reexecute; } #if __TBB_RECYCLE_TO_ENQUEUE //! Schedule this to enqueue after descendant tasks complete. /** Save enqueue/spawn difference, it has the semantics of recycle_as_safe_continuation. */ void recycle_to_enqueue() { __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" ); prefix().state = to_enqueue; } #endif /* __TBB_RECYCLE_TO_ENQUEUE */ //------------------------------------------------------------------------ // Spawning and blocking //------------------------------------------------------------------------ //! Set reference count void set_ref_count( int count ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT internal_set_ref_count(count); #else prefix().ref_count = count; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } //! Atomically increment reference count and returns its old value. /** Has acquire semantics */ void increment_ref_count() { __TBB_FetchAndIncrementWacquire( &prefix().ref_count ); } //! Atomically decrement reference count and returns its new value. /** Has release semantics. */ int decrement_ref_count() { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT return int(internal_decrement_ref_count()); #else return int(__TBB_FetchAndDecrementWrelease( &prefix().ref_count ))-1; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } //! Define recommended static forms via import from base class. using task_base::spawn; //! Similar to spawn followed by wait_for_all, but more efficient. void spawn_and_wait_for_all( task& child ) { prefix().owner->wait_for_all( *this, &child ); } //! Similar to spawn followed by wait_for_all, but more efficient. void __TBB_EXPORTED_METHOD spawn_and_wait_for_all( task_list& list ); //! Spawn task allocated by allocate_root, wait for it to complete, and deallocate it. static void spawn_root_and_wait( task& root ) { root.prefix().owner->spawn_root_and_wait( root, root.prefix().next ); } //! Spawn root tasks on list and wait for all of them to finish. /** If there are more tasks than worker threads, the tasks are spawned in order of front to back. */ static void spawn_root_and_wait( task_list& root_list ); //! Wait for reference count to become one, and set reference count to zero. /** Works on tasks while waiting. */ void wait_for_all() { prefix().owner->wait_for_all( *this, NULL ); } //! Enqueue task for starvation-resistant execution. #if __TBB_TASK_PRIORITY /** The task will be enqueued on the normal priority level disregarding the priority of its task group. The rationale of such semantics is that priority of an enqueued task is statically fixed at the moment of its enqueuing, while task group priority is dynamic. Thus automatic priority inheritance would be generally a subject to the race, which may result in unexpected behavior. Use enqueue() overload with explicit priority value and task::group_priority() method to implement such priority inheritance when it is really necessary. **/ #endif /* __TBB_TASK_PRIORITY */ static void enqueue( task& t ) { t.prefix().owner->enqueue( t, NULL ); } #if __TBB_TASK_PRIORITY //! Enqueue task for starvation-resistant execution on the specified priority level. static void enqueue( task& t, priority_t p ) { __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" ); t.prefix().owner->enqueue( t, (void*)p ); } #endif /* __TBB_TASK_PRIORITY */ //! The innermost task being executed or destroyed by the current thread at the moment. static task& __TBB_EXPORTED_FUNC self(); //! task on whose behalf this task is working, or NULL if this is a root. task* parent() const {return prefix().parent;} //! sets parent task pointer to specified value void set_parent(task* p) { #if __TBB_TASK_GROUP_CONTEXT __TBB_ASSERT(prefix().context == p->prefix().context, "The tasks must be in the same context"); #endif prefix().parent = p; } #if __TBB_TASK_GROUP_CONTEXT //! This method is deprecated and will be removed in the future. /** Use method group() instead. **/ task_group_context* context() {return prefix().context;} //! Pointer to the task group descriptor. task_group_context* group () { return prefix().context; } #endif /* __TBB_TASK_GROUP_CONTEXT */ //! True if task was stolen from the task pool of another thread. bool is_stolen_task() const { return (prefix().extra_state & 0x80)!=0; } //------------------------------------------------------------------------ // Debugging //------------------------------------------------------------------------ //! Current execution state state_type state() const {return state_type(prefix().state);} //! The internal reference count. int ref_count() const { #if TBB_USE_ASSERT internal::reference_count ref_count_ = prefix().ref_count; __TBB_ASSERT( ref_count_==int(ref_count_), "integer overflow error"); #endif return int(prefix().ref_count); } //! Obsolete, and only retained for the sake of backward compatibility. Always returns true. bool __TBB_EXPORTED_METHOD is_owned_by_current_thread() const; //------------------------------------------------------------------------ // Affinity //------------------------------------------------------------------------ //! An id as used for specifying affinity. /** Guaranteed to be integral type. Value of 0 means no affinity. */ typedef internal::affinity_id affinity_id; //! Set affinity for this task. void set_affinity( affinity_id id ) {prefix().affinity = id;} //! Current affinity of this task affinity_id affinity() const {return prefix().affinity;} //! Invoked by scheduler to notify task that it ran on unexpected thread. /** Invoked before method execute() runs, if task is stolen, or task has affinity but will be executed on another thread. The default action does nothing. */ virtual void __TBB_EXPORTED_METHOD note_affinity( affinity_id id ); #if __TBB_TASK_GROUP_CONTEXT //! Moves this task from its current group into another one. /** Argument ctx specifies the new group. The primary purpose of this method is to associate unique task group context with a task allocated for subsequent enqueuing. In contrast to spawned tasks enqueued ones normally outlive the scope where they were created. This makes traditional usage model where task group context are allocated locally on the stack inapplicable. Dynamic allocation of context objects is performance inefficient. Method change_group() allows to make task group context object a member of the task class, and then associate it with its containing task object in the latter's constructor. **/ void __TBB_EXPORTED_METHOD change_group ( task_group_context& ctx ); //! Initiates cancellation of all tasks in this cancellation group and its subordinate groups. /** \return false if cancellation has already been requested, true otherwise. **/ bool cancel_group_execution () { return prefix().context->cancel_group_execution(); } //! Returns true if the context has received cancellation request. bool is_cancelled () const { return prefix().context->is_group_execution_cancelled(); } #else bool is_cancelled () const { return false; } #endif /* __TBB_TASK_GROUP_CONTEXT */ #if __TBB_TASK_PRIORITY //! Changes priority of the task group this task belongs to. void set_group_priority ( priority_t p ) { prefix().context->set_priority(p); } //! Retrieves current priority of the task group this task belongs to. priority_t group_priority () const { return prefix().context->priority(); } #endif /* __TBB_TASK_PRIORITY */ private: friend class interface5::internal::task_base; friend class task_list; friend class internal::scheduler; friend class internal::allocate_root_proxy; #if __TBB_TASK_GROUP_CONTEXT friend class internal::allocate_root_with_context_proxy; #endif /* __TBB_TASK_GROUP_CONTEXT */ friend class internal::allocate_continuation_proxy; friend class internal::allocate_child_proxy; friend class internal::allocate_additional_child_of_proxy; //! Get reference to corresponding task_prefix. /** Version tag prevents loader on Linux from using the wrong symbol in debug builds. **/ internal::task_prefix& prefix( internal::version_tag* = NULL ) const { return reinterpret_cast(const_cast(this))[-1]; } }; // class task //! task that does nothing. Useful for synchronization. /** @ingroup task_scheduling */ class empty_task: public task { /*override*/ task* execute() { return NULL; } }; //! @cond INTERNAL namespace internal { template class function_task : public task { F my_func; /*override*/ task* execute() { my_func(); return NULL; } public: function_task( const F& f ) : my_func(f) {} }; } // namespace internal //! @endcond //! A list of children. /** Used for method task::spawn_children @ingroup task_scheduling */ class task_list: internal::no_copy { private: task* first; task** next_ptr; friend class task; friend class interface5::internal::task_base; public: //! Construct empty list task_list() : first(NULL), next_ptr(&first) {} //! Destroys the list, but does not destroy the task objects. ~task_list() {} //! True if list if empty; false otherwise. bool empty() const {return !first;} //! Push task onto back of list. void push_back( task& task ) { task.prefix().next = NULL; *next_ptr = &task; next_ptr = &task.prefix().next; } //! Pop the front task from the list. task& pop_front() { __TBB_ASSERT( !empty(), "attempt to pop item from empty task_list" ); task* result = first; first = result->prefix().next; if( !first ) next_ptr = &first; return *result; } //! Clear the list void clear() { first=NULL; next_ptr=&first; } }; inline void interface5::internal::task_base::spawn( task& t ) { t.prefix().owner->spawn( t, t.prefix().next ); } inline void interface5::internal::task_base::spawn( task_list& list ) { if( task* t = list.first ) { t->prefix().owner->spawn( *t, *list.next_ptr ); list.clear(); } } inline void task::spawn_root_and_wait( task_list& root_list ) { if( task* t = root_list.first ) { t->prefix().owner->spawn_root_and_wait( *t, *root_list.next_ptr ); root_list.clear(); } } } // namespace tbb inline void *operator new( size_t bytes, const tbb::internal::allocate_root_proxy& ) { return &tbb::internal::allocate_root_proxy::allocate(bytes); } inline void operator delete( void* task, const tbb::internal::allocate_root_proxy& ) { tbb::internal::allocate_root_proxy::free( *static_cast(task) ); } #if __TBB_TASK_GROUP_CONTEXT inline void *operator new( size_t bytes, const tbb::internal::allocate_root_with_context_proxy& p ) { return &p.allocate(bytes); } inline void operator delete( void* task, const tbb::internal::allocate_root_with_context_proxy& p ) { p.free( *static_cast(task) ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ inline void *operator new( size_t bytes, const tbb::internal::allocate_continuation_proxy& p ) { return &p.allocate(bytes); } inline void operator delete( void* task, const tbb::internal::allocate_continuation_proxy& p ) { p.free( *static_cast(task) ); } inline void *operator new( size_t bytes, const tbb::internal::allocate_child_proxy& p ) { return &p.allocate(bytes); } inline void operator delete( void* task, const tbb::internal::allocate_child_proxy& p ) { p.free( *static_cast(task) ); } inline void *operator new( size_t bytes, const tbb::internal::allocate_additional_child_of_proxy& p ) { return &p.allocate(bytes); } inline void operator delete( void* task, const tbb::internal::allocate_additional_child_of_proxy& p ) { p.free( *static_cast(task) ); } #endif /* __TBB_task_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task_arena.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_task_arena_H #define __TBB_task_arena_H #include "task.h" #include "tbb_exception.h" #if TBB_USE_THREADING_TOOLS #include "atomic.h" // for as_atomic #endif #if __TBB_TASK_ARENA namespace tbb { //! @cond INTERNAL namespace internal { //! Internal to library. Should not be used by clients. /** @ingroup task_scheduling */ class arena; class task_scheduler_observer_v3; } // namespace internal //! @endcond namespace interface7 { //! @cond INTERNAL namespace internal { using namespace tbb::internal; //e.g. function_task from task.h class delegate_base : no_assign { public: virtual void operator()() const = 0; virtual ~delegate_base() {} }; template class delegated_function : public delegate_base { F &my_func; /*override*/ void operator()() const { my_func(); } public: delegated_function ( F& f ) : my_func(f) {} }; class task_arena_base { protected: //! NULL if not currently initialized. internal::arena* my_arena; #if __TBB_TASK_GROUP_CONTEXT //! default context of the arena task_group_context *my_context; #endif //! Concurrency level for deferred initialization int my_max_concurrency; //! Reserved master slots unsigned my_master_slots; //! Special settings intptr_t my_version_and_traits; enum { default_flags = 0 #if __TBB_TASK_GROUP_CONTEXT | (task_group_context::default_traits & task_group_context::exact_exception) // 0 or 1 << 16 , exact_exception_flag = task_group_context::exact_exception // used to specify flag for context directly #endif }; task_arena_base(int max_concurrency, unsigned reserved_for_masters) : my_arena(0) #if __TBB_TASK_GROUP_CONTEXT , my_context(0) #endif , my_max_concurrency(max_concurrency) , my_master_slots(reserved_for_masters) , my_version_and_traits(default_flags) {} void __TBB_EXPORTED_METHOD internal_initialize( ); void __TBB_EXPORTED_METHOD internal_terminate( ); void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const; void __TBB_EXPORTED_METHOD internal_execute( delegate_base& ) const; void __TBB_EXPORTED_METHOD internal_wait() const; static int __TBB_EXPORTED_FUNC internal_current_slot(); public: //! Typedef for number of threads that is automatic. static const int automatic = -1; // any value < 1 means 'automatic' }; } // namespace internal //! @endcond /** 1-to-1 proxy representation class of scheduler's arena * Constructors set up settings only, real construction is deferred till the first method invocation * Destructor only removes one of the references to the inner arena representation. * Final destruction happens when all the references (and the work) are gone. */ class task_arena : public internal::task_arena_base { friend class tbb::internal::task_scheduler_observer_v3; bool my_initialized; public: //! Creates task_arena with certain concurrency limits /** Sets up settings only, real construction is deferred till the first method invocation * @arg max_concurrency specifies total number of slots in arena where threads work * @arg reserved_for_masters specifies number of slots to be used by master threads only. * Value of 1 is default and reflects behavior of implicit arenas. **/ task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1) : task_arena_base(max_concurrency, reserved_for_masters) , my_initialized(false) {} //! Copies settings from another task_arena task_arena(const task_arena &s) // copy settings but not the reference or instance : task_arena_base(s.my_max_concurrency, s.my_master_slots) , my_initialized(false) {} //! Forces allocation of the resources for the task_arena as specified in constructor arguments inline void initialize() { if( !my_initialized ) { internal_initialize(); #if TBB_USE_THREADING_TOOLS // Threading tools respect lock prefix but report false-positive data-race via plain store internal::as_atomic(my_initialized).fetch_and_store(true); #else my_initialized = true; #endif //TBB_USE_THREADING_TOOLS } } //! Overrides concurrency level and forces initialization of internal representation inline void initialize(int max_concurrency, unsigned reserved_for_masters = 1) { __TBB_ASSERT( !my_arena, "Impossible to modify settings of an already initialized task_arena"); if( !my_initialized ) { my_max_concurrency = max_concurrency; my_master_slots = reserved_for_masters; initialize(); } } //! Removes the reference to the internal arena representation. //! Not thread safe wrt concurrent invocations of other methods. inline void terminate() { if( my_initialized ) { internal_terminate(); my_initialized = false; } } //! Removes the reference to the internal arena representation, and destroys the external object. //! Not thread safe wrt concurrent invocations of other methods. ~task_arena() { terminate(); } //! Returns true if the arena is active (initialized); false otherwise. //! The name was chosen to match a task_scheduler_init method with the same semantics. bool is_active() const { return my_initialized; } //! Enqueues a task into the arena to process a functor, and immediately returns. //! Does not require the calling thread to join the arena template void enqueue( const F& f ) { initialize(); #if __TBB_TASK_GROUP_CONTEXT internal_enqueue( *new( task::allocate_root(*my_context) ) internal::function_task(f), 0 ); #else internal_enqueue( *new( task::allocate_root() ) internal::function_task(f), 0 ); #endif } #if __TBB_TASK_PRIORITY //! Enqueues a task with priority p into the arena to process a functor f, and immediately returns. //! Does not require the calling thread to join the arena template void enqueue( const F& f, priority_t p ) { __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" ); initialize(); #if __TBB_TASK_GROUP_CONTEXT internal_enqueue( *new( task::allocate_root(*my_context) ) internal::function_task(f), (intptr_t)p ); #else internal_enqueue( *new( task::allocate_root() ) internal::function_task(f), (intptr_t)p ); #endif } #endif// __TBB_TASK_PRIORITY //! Joins the arena and executes a functor, then returns //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread template void execute(F& f) { initialize(); internal::delegated_function d(f); internal_execute( d ); } //! Joins the arena and executes a functor, then returns //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread template void execute(const F& f) { initialize(); internal::delegated_function d(f); internal_execute( d ); } #if __TBB_EXTRA_DEBUG //! Wait for all work in the arena to be completed //! Even submitted by other application threads //! Joins arena if/when possible (in the same way as execute()) void debug_wait_until_empty() { initialize(); internal_wait(); } #endif //__TBB_EXTRA_DEBUG //! Returns the index, aka slot number, of the calling thread in its current arena inline static int current_thread_index() { return internal_current_slot(); } }; } // namespace interfaceX using interface7::task_arena; } // namespace tbb #endif /* __TBB_TASK_ARENA */ #endif /* __TBB_task_arena_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task_group.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_task_group_H #define __TBB_task_group_H #include "task.h" #include "tbb_exception.h" #if __TBB_TASK_GROUP_CONTEXT namespace tbb { namespace internal { template class task_handle_task; } class task_group; class structured_task_group; template class task_handle : internal::no_assign { template friend class internal::task_handle_task; friend class task_group; friend class structured_task_group; static const intptr_t scheduled = 0x1; F my_func; intptr_t my_state; void mark_scheduled () { // The check here is intentionally lax to avoid the impact of interlocked operation if ( my_state & scheduled ) internal::throw_exception( internal::eid_invalid_multiple_scheduling ); my_state |= scheduled; } public: task_handle( const F& f ) : my_func(f), my_state(0) {} void operator() () const { my_func(); } }; enum task_group_status { not_complete, complete, canceled }; namespace internal { template class task_handle_task : public task { task_handle& my_handle; /*override*/ task* execute() { my_handle(); return NULL; } public: task_handle_task( task_handle& h ) : my_handle(h) { h.mark_scheduled(); } }; class task_group_base : internal::no_copy { protected: empty_task* my_root; task_group_context my_context; task& owner () { return *my_root; } template task_group_status internal_run_and_wait( F& f ) { __TBB_TRY { if ( !my_context.is_group_execution_cancelled() ) f(); } __TBB_CATCH( ... ) { my_context.register_pending_exception(); } return wait(); } template void internal_run( F& f ) { owner().spawn( *new( owner().allocate_additional_child_of(*my_root) ) Task(f) ); } public: task_group_base( uintptr_t traits = 0 ) : my_context(task_group_context::bound, task_group_context::default_traits | traits) { my_root = new( task::allocate_root(my_context) ) empty_task; my_root->set_ref_count(1); } ~task_group_base() __TBB_NOEXCEPT(false) { if( my_root->ref_count() > 1 ) { bool stack_unwinding_in_progress = std::uncaught_exception(); // Always attempt to do proper cleanup to avoid inevitable memory corruption // in case of missing wait (for the sake of better testability & debuggability) if ( !is_canceling() ) cancel(); __TBB_TRY { my_root->wait_for_all(); } __TBB_CATCH (...) { task::destroy(*my_root); __TBB_RETHROW(); } task::destroy(*my_root); if ( !stack_unwinding_in_progress ) internal::throw_exception( internal::eid_missing_wait ); } else { task::destroy(*my_root); } } template void run( task_handle& h ) { internal_run< task_handle, internal::task_handle_task >( h ); } task_group_status wait() { __TBB_TRY { my_root->wait_for_all(); } __TBB_CATCH( ... ) { my_context.reset(); __TBB_RETHROW(); } if ( my_context.is_group_execution_cancelled() ) { my_context.reset(); return canceled; } return complete; } bool is_canceling() { return my_context.is_group_execution_cancelled(); } void cancel() { my_context.cancel_group_execution(); } }; // class task_group_base } // namespace internal class task_group : public internal::task_group_base { public: task_group () : task_group_base( task_group_context::concurrent_wait ) {} #if __SUNPRO_CC template void run( task_handle& h ) { internal_run< task_handle, internal::task_handle_task >( h ); } #else using task_group_base::run; #endif template void run( const F& f ) { internal_run< const F, internal::function_task >( f ); } template task_group_status run_and_wait( const F& f ) { return internal_run_and_wait( f ); } template task_group_status run_and_wait( task_handle& h ) { h.mark_scheduled(); return internal_run_and_wait< task_handle >( h ); } }; // class task_group class structured_task_group : public internal::task_group_base { public: template task_group_status run_and_wait ( task_handle& h ) { h.mark_scheduled(); return internal_run_and_wait< task_handle >( h ); } task_group_status wait() { task_group_status res = task_group_base::wait(); my_root->set_ref_count(1); return res; } }; // class structured_task_group inline bool is_current_task_group_canceling() { return task::self().is_cancelled(); } template task_handle make_task( const F& f ) { return task_handle( f ); } } // namespace tbb #endif /* __TBB_TASK_GROUP_CONTEXT */ #endif /* __TBB_task_group_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task_group_context.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "scheduler.h" #include "itt_notify.h" namespace tbb { #if __TBB_TASK_GROUP_CONTEXT using namespace internal; //------------------------------------------------------------------------ // captured_exception //------------------------------------------------------------------------ inline char* duplicate_string ( const char* src ) { char* dst = NULL; if ( src ) { size_t len = strlen(src) + 1; dst = (char*)allocate_via_handler_v3(len); strncpy (dst, src, len); } return dst; } captured_exception::~captured_exception () throw() { clear(); } void captured_exception::set ( const char* a_name, const char* info ) throw() { my_exception_name = duplicate_string( a_name ); my_exception_info = duplicate_string( info ); } void captured_exception::clear () throw() { deallocate_via_handler_v3 (const_cast(my_exception_name)); deallocate_via_handler_v3 (const_cast(my_exception_info)); } captured_exception* captured_exception::move () throw() { captured_exception *e = (captured_exception*)allocate_via_handler_v3(sizeof(captured_exception)); if ( e ) { ::new (e) captured_exception(); e->my_exception_name = my_exception_name; e->my_exception_info = my_exception_info; e->my_dynamic = true; my_exception_name = my_exception_info = NULL; } return e; } void captured_exception::destroy () throw() { __TBB_ASSERT ( my_dynamic, "Method destroy can be used only on objects created by clone or allocate" ); if ( my_dynamic ) { this->captured_exception::~captured_exception(); deallocate_via_handler_v3 (this); } } captured_exception* captured_exception::allocate ( const char* a_name, const char* info ) { captured_exception *e = (captured_exception*)allocate_via_handler_v3( sizeof(captured_exception) ); if ( e ) { ::new (e) captured_exception(a_name, info); e->my_dynamic = true; } return e; } const char* captured_exception::name() const throw() { return my_exception_name; } const char* captured_exception::what() const throw() { return my_exception_info; } //------------------------------------------------------------------------ // tbb_exception_ptr //------------------------------------------------------------------------ #if !TBB_USE_CAPTURED_EXCEPTION namespace internal { template tbb_exception_ptr* AllocateExceptionContainer( const T& src ) { tbb_exception_ptr *eptr = (tbb_exception_ptr*)allocate_via_handler_v3( sizeof(tbb_exception_ptr) ); if ( eptr ) new (eptr) tbb_exception_ptr(src); return eptr; } tbb_exception_ptr* tbb_exception_ptr::allocate () { return AllocateExceptionContainer( std::current_exception() ); } tbb_exception_ptr* tbb_exception_ptr::allocate ( const tbb_exception& ) { return AllocateExceptionContainer( std::current_exception() ); } tbb_exception_ptr* tbb_exception_ptr::allocate ( captured_exception& src ) { tbb_exception_ptr *res = AllocateExceptionContainer( src ); src.destroy(); return res; } void tbb_exception_ptr::destroy () throw() { this->tbb_exception_ptr::~tbb_exception_ptr(); deallocate_via_handler_v3 (this); } } // namespace internal #endif /* !TBB_USE_CAPTURED_EXCEPTION */ //------------------------------------------------------------------------ // task_group_context //------------------------------------------------------------------------ task_group_context::~task_group_context () { if ( __TBB_load_relaxed(my_kind) == binding_completed ) { if ( governor::is_set(my_owner) ) { // Local update of the context list uintptr_t local_count_snapshot = my_owner->my_context_state_propagation_epoch; my_owner->my_local_ctx_list_update.store(1); // Prevent load of nonlocal update flag from being hoisted before the // store to local update flag. atomic_fence(); if ( my_owner->my_nonlocal_ctx_list_update.load() ) { spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex); my_node.my_prev->my_next = my_node.my_next; my_node.my_next->my_prev = my_node.my_prev; my_owner->my_local_ctx_list_update.store(0); } else { my_node.my_prev->my_next = my_node.my_next; my_node.my_next->my_prev = my_node.my_prev; // Release fence is necessary so that update of our neighbors in // the context list was committed when possible concurrent destroyer // proceeds after local update flag is reset by the following store. my_owner->my_local_ctx_list_update.store(0); if ( local_count_snapshot != the_context_state_propagation_epoch ) { // Another thread was propagating cancellation request when we removed // ourselves from the list. We must ensure that it is not accessing us // when this destructor finishes. We'll be able to acquire the lock // below only after the other thread finishes with us. spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex); } } } else { // Nonlocal update of the context list // Synchronizes with generic_scheduler::cleanup_local_context_list() // TODO: evaluate and perhaps relax, or add some lock instead if ( internal::as_atomic(my_kind).fetch_and_store(dying) == detached ) { my_node.my_prev->my_next = my_node.my_next; my_node.my_next->my_prev = my_node.my_prev; } else { //TODO: evaluate and perhaps relax my_owner->my_nonlocal_ctx_list_update.fetch_and_increment(); //TODO: evaluate and perhaps remove spin_wait_until_eq( my_owner->my_local_ctx_list_update, 0u ); my_owner->my_context_list_mutex.lock(); my_node.my_prev->my_next = my_node.my_next; my_node.my_next->my_prev = my_node.my_prev; my_owner->my_context_list_mutex.unlock(); //TODO: evaluate and perhaps relax my_owner->my_nonlocal_ctx_list_update.fetch_and_decrement(); } } } #if __TBB_FP_CONTEXT internal::punned_cast(&my_cpu_ctl_env)->~cpu_ctl_env(); #endif poison_value(my_version_and_traits); if ( my_exception ) my_exception->destroy(); ITT_STACK(itt_caller != ITT_CALLER_NULL, caller_destroy, itt_caller); } void task_group_context::init () { __TBB_STATIC_ASSERT ( sizeof(my_version_and_traits) >= 4, "Layout of my_version_and_traits must be reconsidered on this platform" ); __TBB_STATIC_ASSERT ( sizeof(task_group_context) == 2 * NFS_MaxLineSize, "Context class has wrong size - check padding and members alignment" ); __TBB_ASSERT ( (uintptr_t(this) & (sizeof(my_cancellation_requested) - 1)) == 0, "Context is improperly aligned" ); __TBB_ASSERT ( __TBB_load_relaxed(my_kind) == isolated || __TBB_load_relaxed(my_kind) == bound, "Context can be created only as isolated or bound" ); my_parent = NULL; my_cancellation_requested = 0; my_exception = NULL; my_owner = NULL; my_state = 0; itt_caller = ITT_CALLER_NULL; #if __TBB_TASK_PRIORITY my_priority = normalized_normal_priority; #endif /* __TBB_TASK_PRIORITY */ #if __TBB_FP_CONTEXT __TBB_STATIC_ASSERT( sizeof(my_cpu_ctl_env) == sizeof(internal::uint64_t), "The reserved space for FPU settings are not equal sizeof(uint64_t)" ); __TBB_STATIC_ASSERT( sizeof(cpu_ctl_env) <= sizeof(my_cpu_ctl_env), "FPU settings storage does not fit to uint64_t" ); suppress_unused_warning( my_cpu_ctl_env.space ); cpu_ctl_env &ctl = *internal::punned_cast(&my_cpu_ctl_env); new ( &ctl ) cpu_ctl_env; if ( my_version_and_traits & fp_settings ) ctl.get_env(); #endif } void task_group_context::register_with ( generic_scheduler *local_sched ) { __TBB_ASSERT( local_sched, NULL ); my_owner = local_sched; // state propagation logic assumes new contexts are bound to head of the list my_node.my_prev = &local_sched->my_context_list_head; // Notify threads that may be concurrently destroying contexts registered // in this scheduler's list that local list update is underway. local_sched->my_local_ctx_list_update.store(1); // Prevent load of global propagation epoch counter from being hoisted before // speculative stores above, as well as load of nonlocal update flag from // being hoisted before the store to local update flag. atomic_fence(); // Finalize local context list update if ( local_sched->my_nonlocal_ctx_list_update.load() ) { spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex); local_sched->my_context_list_head.my_next->my_prev = &my_node; my_node.my_next = local_sched->my_context_list_head.my_next; my_owner->my_local_ctx_list_update.store(0); local_sched->my_context_list_head.my_next = &my_node; } else { local_sched->my_context_list_head.my_next->my_prev = &my_node; my_node.my_next = local_sched->my_context_list_head.my_next; my_owner->my_local_ctx_list_update.store(0); // Thread-local list of contexts allows concurrent traversal by another thread // while propagating state change. To ensure visibility of my_node's members // to the concurrently traversing thread, the list's head is updated by means // of store-with-release. __TBB_store_with_release(local_sched->my_context_list_head.my_next, &my_node); } } void task_group_context::bind_to ( generic_scheduler *local_sched ) { __TBB_ASSERT ( __TBB_load_relaxed(my_kind) == binding_required, "Already bound or isolated?" ); __TBB_ASSERT ( !my_parent, "Parent is set before initial binding" ); my_parent = local_sched->my_innermost_running_task->prefix().context; #if __TBB_FP_CONTEXT // Inherit FPU settings only if the context has not captured FPU settings yet. if ( !(my_version_and_traits & fp_settings) ) copy_fp_settings(*my_parent); #endif // Condition below prevents unnecessary thrashing parent context's cache line if ( !(my_parent->my_state & may_have_children) ) my_parent->my_state |= may_have_children; // full fence is below if ( my_parent->my_parent ) { // Even if this context were made accessible for state change propagation // (by placing __TBB_store_with_release(s->my_context_list_head.my_next, &my_node) // above), it still could be missed if state propagation from a grand-ancestor // was underway concurrently with binding. // Speculative propagation from the parent together with epoch counters // detecting possibility of such a race allow to avoid taking locks when // there is no contention. // Acquire fence is necessary to prevent reordering subsequent speculative // loads of parent state data out of the scope where epoch counters comparison // can reliably validate it. uintptr_t local_count_snapshot = __TBB_load_with_acquire( my_parent->my_owner->my_context_state_propagation_epoch ); // Speculative propagation of parent's state. The speculation will be // validated by the epoch counters check further on. my_cancellation_requested = my_parent->my_cancellation_requested; #if __TBB_TASK_PRIORITY my_priority = my_parent->my_priority; #endif /* __TBB_TASK_PRIORITY */ register_with( local_sched ); // Issues full fence // If no state propagation was detected by the following condition, the above // full fence guarantees that the parent had correct state during speculative // propagation before the fence. Otherwise the propagation from parent is // repeated under the lock. if ( local_count_snapshot != the_context_state_propagation_epoch ) { // Another thread may be propagating state change right now. So resort to lock. context_state_propagation_mutex_type::scoped_lock lock(the_context_state_propagation_mutex); my_cancellation_requested = my_parent->my_cancellation_requested; #if __TBB_TASK_PRIORITY my_priority = my_parent->my_priority; #endif /* __TBB_TASK_PRIORITY */ } } else { register_with( local_sched ); // Issues full fence // As we do not have grand-ancestors, concurrent state propagation (if any) // may originate only from the parent context, and thus it is safe to directly // copy the state from it. my_cancellation_requested = my_parent->my_cancellation_requested; #if __TBB_TASK_PRIORITY my_priority = my_parent->my_priority; #endif /* __TBB_TASK_PRIORITY */ } __TBB_store_relaxed(my_kind, binding_completed); } #if __TBB_TASK_GROUP_CONTEXT template void task_group_context::propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ) { if (this->*mptr_state == new_state) { // Nothing to do, whether descending from "src" or not, so no need to scan. // Hopefully this happens often thanks to earlier invocations. // This optimization is enabled by LIFO order in the context lists: // - new contexts are bound to the beginning of lists; // - descendants are newer than ancestors; // - earlier invocations are therefore likely to "paint" long chains. } else if (this == &src) { // This clause is disjunct from the traversal below, which skips src entirely. // Note that src.*mptr_state is not necessarily still equal to new_state (another thread may have changed it again). // Such interference is probably not frequent enough to aim for optimisation by writing new_state again (to make the other thread back down). // Letting the other thread prevail may also be fairer. } else { for ( task_group_context *ancestor = my_parent; ancestor != NULL; ancestor = ancestor->my_parent ) { __TBB_ASSERT(internal::is_alive(ancestor->my_version_and_traits), "context tree was corrupted"); if ( ancestor == &src ) { for ( task_group_context *ctx = this; ctx != ancestor; ctx = ctx->my_parent ) ctx->*mptr_state = new_state; break; } } } } template void generic_scheduler::propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ) { spin_mutex::scoped_lock lock(my_context_list_mutex); // Acquire fence is necessary to ensure that the subsequent node->my_next load // returned the correct value in case it was just inserted in another thread. // The fence also ensures visibility of the correct my_parent value. context_list_node_t *node = __TBB_load_with_acquire(my_context_list_head.my_next); while ( node != &my_context_list_head ) { task_group_context &ctx = __TBB_get_object_ref(task_group_context, my_node, node); if ( ctx.*mptr_state != new_state ) ctx.propagate_task_group_state( mptr_state, src, new_state ); node = node->my_next; __TBB_ASSERT( is_alive(ctx.my_version_and_traits), "Local context list contains destroyed object" ); } // Sync up local propagation epoch with the global one. Release fence prevents // reordering of possible store to *mptr_state after the sync point. __TBB_store_with_release(my_context_state_propagation_epoch, the_context_state_propagation_epoch); } template bool market::propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ) { if ( !(src.my_state & task_group_context::may_have_children) ) return true; // The whole propagation algorithm is under the lock in order to ensure correctness // in case of concurrent state changes at the different levels of the context tree. // See comment at the bottom of scheduler.cpp context_state_propagation_mutex_type::scoped_lock lock(the_context_state_propagation_mutex); if ( src.*mptr_state != new_state ) // Another thread has concurrently changed the state. Back down. return false; // Advance global state propagation epoch __TBB_FetchAndAddWrelease(&the_context_state_propagation_epoch, 1); // Propagate to all workers and masters and sync up their local epochs with the global one unsigned num_workers = my_num_workers; for ( unsigned i = 0; i < num_workers; ++i ) { generic_scheduler *s = my_workers[i]; // If the worker is only about to be registered, skip it. if ( s ) s->propagate_task_group_state( mptr_state, src, new_state ); } // Propagate to all master threads (under my_arenas_list_mutex lock) ForEachArena(a) { // uses lock on my_arenas_list_mutex arena_slot &slot = a.my_slots[0]; generic_scheduler *s = slot.my_scheduler; // If the master is under construction, skip it. Otherwise make sure that it does not // leave its arena and its scheduler get destroyed while we accessing its data. if ( s && as_atomic(slot.my_scheduler).compare_and_swap(LockedMaster, s) == s ) { //TODO: remove need in lock __TBB_ASSERT( slot.my_scheduler == LockedMaster, NULL ); // The whole propagation sequence is locked, thus no contention is expected __TBB_ASSERT( s != LockedMaster, NULL ); s->propagate_task_group_state( mptr_state, src, new_state ); __TBB_store_with_release( slot.my_scheduler, s ); } } EndForEach(); return true; } template bool arena::propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ) { return my_market->propagate_task_group_state( mptr_state, src, new_state ); } #endif /* __TBB_TASK_GROUP_CONTEXT */ bool task_group_context::cancel_group_execution () { __TBB_ASSERT ( my_cancellation_requested == 0 || my_cancellation_requested == 1, "Invalid cancellation state"); if ( my_cancellation_requested || as_atomic(my_cancellation_requested).compare_and_swap(1, 0) ) { // This task group and any descendants have already been canceled. // (A newly added descendant would inherit its parent's my_cancellation_requested, // not missing out on any cancellation still being propagated, and a context cannot be uncanceled.) return false; } governor::local_scheduler()->my_arena->propagate_task_group_state( &task_group_context::my_cancellation_requested, *this, (uintptr_t)1 ); return true; } bool task_group_context::is_group_execution_cancelled () const { return my_cancellation_requested != 0; } // IMPORTANT: It is assumed that this method is not used concurrently! void task_group_context::reset () { //! TODO: Add assertion that this context does not have children // No fences are necessary since this context can be accessed from another thread // only after stealing happened (which means necessary fences were used). if ( my_exception ) { my_exception->destroy(); my_exception = NULL; } my_cancellation_requested = 0; } #if __TBB_FP_CONTEXT // IMPORTANT: It is assumed that this method is not used concurrently! void task_group_context::capture_fp_settings () { //! TODO: Add assertion that this context does not have children // No fences are necessary since this context can be accessed from another thread // only after stealing happened (which means necessary fences were used). cpu_ctl_env &ctl = *internal::punned_cast(&my_cpu_ctl_env); if ( !(my_version_and_traits & fp_settings) ) { new ( &ctl ) cpu_ctl_env; my_version_and_traits |= fp_settings; } ctl.get_env(); } void task_group_context::copy_fp_settings( const task_group_context &src ) { __TBB_ASSERT( !(my_version_and_traits & fp_settings), "The context already has FPU settings." ); __TBB_ASSERT( src.my_version_and_traits & fp_settings, "The source context does not have FPU settings." ); cpu_ctl_env &ctl = *internal::punned_cast(&my_cpu_ctl_env); cpu_ctl_env &src_ctl = *internal::punned_cast(&src.my_cpu_ctl_env); new (&ctl) cpu_ctl_env( src_ctl ); my_version_and_traits |= fp_settings; } #endif /* __TBB_FP_CONTEXT */ void task_group_context::register_pending_exception () { if ( my_cancellation_requested ) return; #if TBB_USE_EXCEPTIONS try { throw; } TbbCatchAll( this ); #endif /* TBB_USE_EXCEPTIONS */ } #if __TBB_TASK_PRIORITY void task_group_context::set_priority ( priority_t prio ) { __TBB_ASSERT( prio == priority_low || prio == priority_normal || prio == priority_high, "Invalid priority level value" ); intptr_t p = normalize_priority(prio); if ( my_priority == p && !(my_state & task_group_context::may_have_children)) return; my_priority = p; internal::generic_scheduler* s = governor::local_scheduler_if_initialized(); if ( !s || !s->my_arena->propagate_task_group_state(&task_group_context::my_priority, *this, p) ) return; // Updating arena priority here does not eliminate necessity of checking each // task priority and updating arena priority if necessary before the task execution. // These checks will be necessary because: // a) set_priority() may be invoked before any tasks from this task group are spawned; // b) all spawned tasks from this task group are retrieved from the task pools. // These cases create a time window when arena priority may be lowered. s->my_market->update_arena_priority( *s->my_arena, p ); } priority_t task_group_context::priority () const { return static_cast(priority_from_normalized_rep[my_priority]); } #endif /* __TBB_TASK_PRIORITY */ #endif /* __TBB_TASK_GROUP_CONTEXT */ } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task_scheduler_init.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_task_scheduler_init_H #define __TBB_task_scheduler_init_H #include "tbb_stddef.h" #include "limits.h" namespace tbb { typedef std::size_t stack_size_type; //! @cond INTERNAL namespace internal { //! Internal to library. Should not be used by clients. /** @ingroup task_scheduling */ class scheduler; } // namespace internal //! @endcond //! Class delimiting the scope of task scheduler activity. /** A thread can construct a task_scheduler_init object and keep it alive while it uses TBB's tasking subsystem (including parallel algorithms). This class allows to customize properties of the TBB task pool to some extent. For example it can limit concurrency level of parallel work initiated by the given thread. It also can be used to specify stack size of the TBB worker threads, though this setting is not effective if the thread pool has already been created. If a parallel construct is used without task_scheduler_init object previously created, the scheduler will be initialized automatically with default settings, and will persist until this thread exits. Default concurrency level is defined as described in task_scheduler_init::initialize(). @ingroup task_scheduling */ class task_scheduler_init: internal::no_copy { enum ExceptionPropagationMode { propagation_mode_exact = 1u, propagation_mode_captured = 2u, propagation_mode_mask = propagation_mode_exact | propagation_mode_captured }; #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE enum { wait_workers_in_terminate_flag = 128u }; #endif /** NULL if not currently initialized. */ internal::scheduler* my_scheduler; public: //! Typedef for number of threads that is automatic. static const int automatic = -1; //! Argument to initialize() or constructor that causes initialization to be deferred. static const int deferred = -2; //! Ensure that scheduler exists for this thread /** A value of -1 lets TBB decide on the number of threads, which is usually maximal hardware concurrency for this process, that is the number of logical CPUs on the machine (possibly limited by the processor affinity mask of this process (Windows) or of this thread (Linux, FreeBSD). It is preferable option for production code because it helps to avoid nasty surprises when several TBB based components run side-by-side or in a nested fashion inside the same process. The number_of_threads is ignored if any other task_scheduler_inits currently exist. A thread may construct multiple task_scheduler_inits. Doing so does no harm because the underlying scheduler is reference counted. */ void __TBB_EXPORTED_METHOD initialize( int number_of_threads=automatic ); //! The overloaded method with stack size parameter /** Overloading is necessary to preserve ABI compatibility */ void __TBB_EXPORTED_METHOD initialize( int number_of_threads, stack_size_type thread_stack_size ); //! Inverse of method initialize. void __TBB_EXPORTED_METHOD terminate(); //! Shorthand for default constructor followed by call to initialize(number_of_threads). #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0, bool wait_workers_in_terminate = false ) : my_scheduler(NULL) #else task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0 ) : my_scheduler(NULL) #endif { // Two lowest order bits of the stack size argument may be taken to communicate // default exception propagation mode of the client to be used when the // client manually creates tasks in the master thread and does not use // explicit task group context object. This is necessary because newer // TBB binaries with exact propagation enabled by default may be used // by older clients that expect tbb::captured_exception wrapper. // All zeros mean old client - no preference. __TBB_ASSERT( !(thread_stack_size & propagation_mode_mask), "Requested stack size is not aligned" ); #if TBB_USE_EXCEPTIONS thread_stack_size |= TBB_USE_CAPTURED_EXCEPTION ? propagation_mode_captured : propagation_mode_exact; #endif /* TBB_USE_EXCEPTIONS */ #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE if (wait_workers_in_terminate) my_scheduler = (internal::scheduler*)wait_workers_in_terminate_flag; #endif initialize( number_of_threads, thread_stack_size ); } //! Destroy scheduler for this thread if thread has no other live task_scheduler_inits. ~task_scheduler_init() { if( my_scheduler ) terminate(); internal::poison_pointer( my_scheduler ); } //! Returns the number of threads TBB scheduler would create if initialized by default. /** Result returned by this method does not depend on whether the scheduler has already been initialized. Because tbb 2.0 does not support blocking tasks yet, you may use this method to boost the number of threads in the tbb's internal pool, if your tasks are doing I/O operations. The optimal number of additional threads depends on how much time your tasks spend in the blocked state. Before TBB 3.0 U4 this method returned the number of logical CPU in the system. Currently on Windows, Linux and FreeBSD it returns the number of logical CPUs available to the current process in accordance with its affinity mask. NOTE: The return value of this method never changes after its first invocation. This means that changes in the process affinity mask that took place after this method was first invoked will not affect the number of worker threads in the TBB worker threads pool. */ static int __TBB_EXPORTED_FUNC default_num_threads (); //! Returns true if scheduler is active (initialized); false otherwise bool is_active() const { return my_scheduler != NULL; } }; } // namespace tbb #endif /* __TBB_task_scheduler_init_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task_scheduler_observer.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_task_scheduler_observer_H #define __TBB_task_scheduler_observer_H #include "atomic.h" #if __TBB_TASK_ARENA #include "task_arena.h" #endif //__TBB_TASK_ARENA #if __TBB_SCHEDULER_OBSERVER namespace tbb { namespace interface6 { class task_scheduler_observer; } namespace internal { class observer_proxy; class observer_list; class task_scheduler_observer_v3 { friend class observer_proxy; friend class observer_list; friend class interface6::task_scheduler_observer; //! Pointer to the proxy holding this observer. /** Observers are proxied by the scheduler to maintain persistent lists of them. **/ observer_proxy* my_proxy; //! Counter preventing the observer from being destroyed while in use by the scheduler. /** Valid only when observation is on. **/ atomic my_busy_count; public: //! Enable or disable observation /** For local observers the method can be used only when the current thread has the task scheduler initialized or is attached to an arena. Repeated calls with the same state are no-ops. **/ void __TBB_EXPORTED_METHOD observe( bool state=true ); //! Returns true if observation is enabled, false otherwise. bool is_observing() const {return my_proxy!=NULL;} //! Construct observer with observation disabled. task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store(0); } //! Entry notification /** Invoked from inside observe(true) call and whenever a worker enters the arena this observer is associated with. If a thread is already in the arena when the observer is activated, the entry notification is called before it executes the first stolen task. Obsolete semantics. For global observers it is called by a thread before the first steal since observation became enabled. **/ virtual void on_scheduler_entry( bool /*is_worker*/ ) {} //! Exit notification /** Invoked from inside observe(false) call and whenever a worker leaves the arena this observer is associated with. Obsolete semantics. For global observers it is called by a thread before the first steal since observation became enabled. **/ virtual void on_scheduler_exit( bool /*is_worker*/ ) {} //! Destructor automatically switches observation off if it is enabled. virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);} }; } // namespace internal #if __TBB_ARENA_OBSERVER namespace interface6 { class task_scheduler_observer : public internal::task_scheduler_observer_v3 { friend class internal::task_scheduler_observer_v3; friend class internal::observer_proxy; friend class internal::observer_list; /** Negative numbers with the largest absolute value to minimize probability of coincidence in case of a bug in busy count usage. **/ // TODO: take more high bits for version number static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1); //! contains task_arena pointer or tag indicating local or global semantics of the observer intptr_t my_context_tag; enum { global_tag = 0, implicit_tag = 1 }; public: //! Construct local or global observer in inactive state (observation disabled). /** For a local observer entry/exit notifications are invoked whenever a worker thread joins/leaves the arena of the observer's owner thread. If a thread is already in the arena when the observer is activated, the entry notification is called before it executes the first stolen task. **/ /** TODO: Obsolete. Global observer semantics is obsolete as it violates master thread isolation guarantees and is not composable. Thus the current default behavior of the constructor is obsolete too and will be changed in one of the future versions of the library. **/ task_scheduler_observer( bool local = false ) { my_context_tag = local? implicit_tag : global_tag; } #if __TBB_TASK_ARENA //! Construct local observer for a given arena in inactive state (observation disabled). /** entry/exit notifications are invoked whenever a thread joins/leaves arena. If a thread is already in the arena when the observer is activated, the entry notification is called before it executes the first stolen task. **/ task_scheduler_observer( task_arena & a) { my_context_tag = (intptr_t)&a; } #endif //__TBB_TASK_ARENA /** Destructor protects instance of the observer from concurrent notification. It is recommended to disable observation before destructor of a derived class starts, otherwise it can lead to concurrent notification callback on partly destroyed object **/ virtual ~task_scheduler_observer() { if(my_proxy) observe(false); } //! Enable or disable observation /** Warning: concurrent invocations of this method are not safe. Repeated calls with the same state are no-ops. **/ void observe( bool state=true ) { if( state && !my_proxy ) { __TBB_ASSERT( !my_busy_count, "Inconsistent state of task_scheduler_observer instance"); my_busy_count.store(v6_trait); } internal::task_scheduler_observer_v3::observe(state); } //! Return commands for may_sleep() enum { keep_awake = false, allow_sleep = true }; //! The callback can be invoked by a worker thread before it goes to sleep. /** If it returns false ('keep_awake'), the thread will keep spinning and looking for work. It will not be called for master threads. **/ virtual bool may_sleep() { return allow_sleep; } }; } //namespace interface6 using interface6::task_scheduler_observer; #else /*__TBB_ARENA_OBSERVER*/ typedef tbb::internal::task_scheduler_observer_v3 task_scheduler_observer; #endif /*__TBB_ARENA_OBSERVER*/ } // namespace tbb #endif /* __TBB_SCHEDULER_OBSERVER */ #endif /* __TBB_task_scheduler_observer_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/task_stream.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_task_stream_H #define _TBB_task_stream_H #include "tbb/tbb_stddef.h" #include #include #include "tbb/atomic.h" // for __TBB_Atomic* #include "tbb/spin_mutex.h" #include "tbb/tbb_allocator.h" #include "scheduler_common.h" #include "tbb_misc.h" // for FastRandom namespace tbb { namespace internal { //! Essentially, this is just a pair of a queue and a mutex to protect the queue. /** The reason std::pair is not used is that the code would look less clean if field names were replaced with 'first' and 'second'. **/ template< typename T, typename mutex_t > struct queue_and_mutex { typedef std::deque< T, tbb_allocator > queue_base_t; queue_base_t my_queue; mutex_t my_mutex; queue_and_mutex () : my_queue(), my_mutex() {} ~queue_and_mutex () {} }; const uintptr_t one = 1; inline void set_one_bit( uintptr_t& dest, int pos ) { __TBB_ASSERT( pos>=0, NULL ); __TBB_ASSERT( pos<32, NULL ); __TBB_AtomicOR( &dest, one<=0, NULL ); __TBB_ASSERT( pos<32, NULL ); __TBB_AtomicAND( &dest, ~(one<=0, NULL ); __TBB_ASSERT( pos<32, NULL ); return (val & (one< lane_t; uintptr_t population; padded* lanes; unsigned N; public: task_stream() : population(), lanes() { } void initialize( unsigned n_lanes ) { const unsigned max_lanes = #if __TBB_MORE_FIFO_LANES sizeof(population) * CHAR_BIT; #else 32; #endif N = n_lanes>=max_lanes ? max_lanes : n_lanes>2 ? 1<<(__TBB_Log2(n_lanes-1)+1) : 2; __TBB_ASSERT( N==max_lanes || N>=n_lanes && ((N-1)&N)==0, "number of lanes miscalculated"); __TBB_ASSERT( N <= sizeof(population) * CHAR_BIT, NULL ); lanes = new padded[N]; __TBB_ASSERT( !population, NULL ); } ~task_stream() { if (lanes) delete[] lanes; } //! Push a task into a lane. void push( task* source, FastRandom& random ) { // Lane selection is random. Each thread should keep a separate seed value. unsigned idx; for( ; ; ) { idx = random.get() & (N-1); spin_mutex::scoped_lock lock; if( lock.try_acquire(lanes[idx].my_mutex) ) { lanes[idx].my_queue.push_back(source); set_one_bit( population, idx ); //TODO: avoid atomic op if the bit is already set break; } } } //! Try finding and popping a task. task* pop( unsigned& last_used_lane ) { task* result = NULL; // Lane selection is round-robin. Each thread should keep its last used lane. unsigned idx = (last_used_lane+1)&(N-1); for( ; population; idx=(idx+1)&(N-1) ) { if( is_bit_set( population, idx ) ) { lane_t& lane = lanes[idx]; spin_mutex::scoped_lock lock; if( lock.try_acquire(lane.my_mutex) && !lane.my_queue.empty() ) { result = lane.my_queue.front(); lane.my_queue.pop_front(); if( lane.my_queue.empty() ) clear_one_bit( population, idx ); break; } } } last_used_lane = idx; return result; } //! Checks existence of a task. bool empty() { return !population; } //! Destroys all remaining tasks in every lane. Returns the number of destroyed tasks. /** Tasks are not executed, because it would potentially create more tasks at a late stage. The scheduler is really expected to execute all tasks before task_stream destruction. */ intptr_t drain() { intptr_t result = 0; for(unsigned i=0; i #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #include // std::forward #endif #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif namespace tbb { //! @cond INTERNAL namespace internal { //! Deallocates memory using FreeHandler /** The function uses scalable_free if scalable allocator is available and free if not*/ void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p ); //! Allocates memory using MallocHandler /** The function uses scalable_malloc if scalable allocator is available and malloc if not*/ void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n ); //! Returns true if standard malloc/free are used to work with memory. bool __TBB_EXPORTED_FUNC is_malloc_used_v3(); } //! @endcond #if _MSC_VER && !defined(__INTEL_COMPILER) // Workaround for erroneous "unreferenced parameter" warning in method destroy. #pragma warning (push) #pragma warning (disable: 4100) #endif //! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 /** The class selects the best memory allocation mechanism available from scalable_malloc and standard malloc. The members are ordered the same way they are in section 20.4.1 of the ISO C++ standard. @ingroup memory_allocation */ template class tbb_allocator { public: typedef typename internal::allocator_type::value_type value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef tbb_allocator other; }; //! Specifies current allocator enum malloc_type { scalable, standard }; tbb_allocator() throw() {} tbb_allocator( const tbb_allocator& ) throw() {} template tbb_allocator(const tbb_allocator&) throw() {} pointer address(reference x) const {return &x;} const_pointer address(const_reference x) const {return &x;} //! Allocate space for n objects. pointer allocate( size_type n, const void* /*hint*/ = 0) { return pointer(internal::allocate_via_handler_v3( n * sizeof(value_type) )); } //! Free previously allocated block of memory. void deallocate( pointer p, size_type ) { internal::deallocate_via_handler_v3(p); } //! Largest value for which method allocate might succeed. size_type max_size() const throw() { size_type max = static_cast(-1) / sizeof (value_type); return (max > 0 ? max : 1); } //! Copy-construct value at location pointed to by p. #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC template void construct(U *p, Args&&... args) { ::new((void *)p) U(std::forward(args)...); } #else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC #if __TBB_CPP11_RVALUE_REF_PRESENT void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));} #endif void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} #endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC //! Destroy value at location pointed to by p. void destroy( pointer p ) {p->~value_type();} //! Returns current allocator static malloc_type allocator_type() { return internal::is_malloc_used_v3() ? standard : scalable; } }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4100 is back //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ template<> class tbb_allocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef tbb_allocator other; }; }; template inline bool operator==( const tbb_allocator&, const tbb_allocator& ) {return true;} template inline bool operator!=( const tbb_allocator&, const tbb_allocator& ) {return false;} //! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 /** The class is an adapter over an actual allocator that fills the allocation using memset function with template argument C as the value. The members are ordered the same way they are in section 20.4.1 of the ISO C++ standard. @ingroup memory_allocation */ template class Allocator = tbb_allocator> class zero_allocator : public Allocator { public: typedef Allocator base_allocator_type; typedef typename base_allocator_type::value_type value_type; typedef typename base_allocator_type::pointer pointer; typedef typename base_allocator_type::const_pointer const_pointer; typedef typename base_allocator_type::reference reference; typedef typename base_allocator_type::const_reference const_reference; typedef typename base_allocator_type::size_type size_type; typedef typename base_allocator_type::difference_type difference_type; template struct rebind { typedef zero_allocator other; }; zero_allocator() throw() { } zero_allocator(const zero_allocator &a) throw() : base_allocator_type( a ) { } template zero_allocator(const zero_allocator &a) throw() : base_allocator_type( Allocator( a ) ) { } pointer allocate(const size_type n, const void *hint = 0 ) { pointer ptr = base_allocator_type::allocate( n, hint ); std::memset( ptr, 0, n * sizeof(value_type) ); return ptr; } }; //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ template class Allocator> class zero_allocator : public Allocator { public: typedef Allocator base_allocator_type; typedef typename base_allocator_type::value_type value_type; typedef typename base_allocator_type::pointer pointer; typedef typename base_allocator_type::const_pointer const_pointer; template struct rebind { typedef zero_allocator other; }; }; template class B1, typename T2, template class B2> inline bool operator==( const zero_allocator &a, const zero_allocator &b) { return static_cast< B1 >(a) == static_cast< B2 >(b); } template class B1, typename T2, template class B2> inline bool operator!=( const zero_allocator &a, const zero_allocator &b) { return static_cast< B1 >(a) != static_cast< B2 >(b); } } // namespace tbb #endif /* __TBB_tbb_allocator_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_assert_impl.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // IMPORTANT: To use assertion handling in TBB, exactly one of the TBB source files // should #include tbb_assert_impl.h thus instantiating assertion handling routines. // The intent of putting it to a separate file is to allow some tests to use it // as well in order to avoid dependency on the library. // include headers for required function declarations #include #include #include #include #if _MSC_VER #include #endif #if _MSC_VER >= 1400 #define __TBB_EXPORTED_FUNC __cdecl #else #define __TBB_EXPORTED_FUNC #endif using namespace std; #if __TBBMALLOC_BUILD namespace rml { namespace internal { #else namespace tbb { #endif //! Type for an assertion handler typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment ); static assertion_handler_type assertion_handler; assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler ) { assertion_handler_type old_handler = assertion_handler; assertion_handler = new_handler; return old_handler; } void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment ) { if( assertion_handler_type a = assertion_handler ) { (*a)(filename,line,expression,comment); } else { static bool already_failed; if( !already_failed ) { already_failed = true; fprintf( stderr, "Assertion %s failed on line %d of file %s\n", expression, line, filename ); if( comment ) fprintf( stderr, "Detailed description: %s\n", comment ); #if _MSC_VER && _DEBUG if(1 == _CrtDbgReport(_CRT_ASSERT, filename, line, "tbb_debug.dll", "%s\r\n%s", expression, comment?comment:"")) _CrtDbgBreak(); #else fflush(stderr); abort(); #endif } } } #if defined(_MSC_VER)&&_MSC_VER<1400 # define vsnprintf _vsnprintf #endif #if !__TBBMALLOC_BUILD namespace internal { //! Report a runtime warning. void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... ) { char str[1024]; memset(str, 0, 1024); va_list args; va_start(args, format); vsnprintf( str, 1024-1, format, args); va_end(args); fprintf( stderr, "TBB Warning: %s\n", str); } } // namespace internal #endif #if __TBBMALLOC_BUILD }} // namespaces rml::internal #else } // namespace tbb #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_config.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_config_H #define __TBB_tbb_config_H /** This header is supposed to contain macro definitions and C style comments only. The macros defined here are intended to control such aspects of TBB build as - presence of compiler features - compilation modes - feature sets - known compiler/platform issues **/ /*Check which standard library we use on OS X.*/ /*__TBB_SYMBOL is defined only while processing exported symbols list where C++ is not allowed.*/ #if !defined(__TBB_SYMBOL) && __APPLE__ #include #endif // note that when ICC is in use __TBB_GCC_VERSION might not closely match GCC version on the machine #define __TBB_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #if __clang__ /**according to clang documentation version can be vendor specific **/ #define __TBB_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #endif /** Preprocessor symbols to determine HW architecture **/ #if _WIN32||_WIN64 # if defined(_M_X64)||defined(__x86_64__) // the latter for MinGW support # define __TBB_x86_64 1 # elif defined(_M_IA64) # define __TBB_ipf 1 # elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support # define __TBB_x86_32 1 # else # define __TBB_generic_arch 1 # endif #else /* Assume generic Unix */ # if !__linux__ && !__APPLE__ # define __TBB_generic_os 1 # endif # if __x86_64__ # define __TBB_x86_64 1 # elif __ia64__ # define __TBB_ipf 1 # elif __i386__||__i386 // __i386 is for Sun OS # define __TBB_x86_32 1 # else # define __TBB_generic_arch 1 # endif #endif #if __MIC__ || __MIC2__ #define __TBB_DEFINE_MIC 1 #endif #define __TBB_TSX_AVAILABLE (__TBB_x86_32 || __TBB_x86_64) && !__TBB_DEFINE_MIC /** Presence of compiler features **/ #if __INTEL_COMPILER == 9999 && __INTEL_COMPILER_BUILD_DATE == 20110811 /* Intel(R) Composer XE 2011 Update 6 incorrectly sets __INTEL_COMPILER. Fix it. */ #undef __INTEL_COMPILER #define __INTEL_COMPILER 1210 #endif #if __TBB_GCC_VERSION >= 40400 && !defined(__INTEL_COMPILER) /** warning suppression pragmas available in GCC since 4.4 **/ #define __TBB_GCC_WARNING_SUPPRESSION_PRESENT 1 #endif /* Select particular features of C++11 based on compiler version. ICC 12.1 (Linux), GCC 4.3 and higher, clang 2.9 and higher set __GXX_EXPERIMENTAL_CXX0X__ in c++11 mode. Compilers that mimics other compilers (ICC, clang) must be processed before compilers they mimic (GCC, MSVC). TODO: The following conditions should be extended when new compilers/runtimes support added. */ #if __INTEL_COMPILER /** C++11 mode detection macros for Intel C++ compiler (enabled by -std=c++0x option): __INTEL_CXX11_MODE__ for version >=13.0 __STDC_HOSTED__ for version >=12.0 on Windows, __GXX_EXPERIMENTAL_CXX0X__ for version >=12.0 on Linux and OS X. **/ // On Windows, C++11 features supported by Visual Studio 2010 and higher are enabled by default #ifndef __INTEL_CXX11_MODE__ #define __INTEL_CXX11_MODE__ ((_MSC_VER && __STDC_HOSTED__) || __GXX_EXPERIMENTAL_CXX0X__) // TODO: check if more conditions can be simplified with the above macro #endif #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (__INTEL_CXX11_MODE__ && __VARIADIC_TEMPLATES) // Both r-value reference support in compiler and std::move/std::forward // presence in C++ standard library is checked. #define __TBB_CPP11_RVALUE_REF_PRESENT ((__GXX_EXPERIMENTAL_CXX0X__ && (__TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION) || _MSC_VER >= 1600) && __INTEL_COMPILER >= 1200) #if _MSC_VER >= 1600 #define __TBB_EXCEPTION_PTR_PRESENT ( __INTEL_COMPILER > 1300 \ /*ICC 12.1 Upd 10 and 13 beta Upd 2 fixed exception_ptr linking issue*/ \ || (__INTEL_COMPILER == 1300 && __INTEL_COMPILER_BUILD_DATE >= 20120530) \ || (__INTEL_COMPILER == 1210 && __INTEL_COMPILER_BUILD_DATE >= 20120410) ) /** libstdc++ that comes with GCC 4.6 use C++11 features not supported by ICC 12.1. * Because of that ICC 12.1 does not support C++11 mode with with gcc 4.6 (or higher), * and therefore does not define __GXX_EXPERIMENTAL_CXX0X__ macro **/ #elif __TBB_GCC_VERSION >= 40404 && __TBB_GCC_VERSION < 40600 #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1200) #elif __TBB_GCC_VERSION >= 40600 #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1300) #else #define __TBB_EXCEPTION_PTR_PRESENT 0 #endif #define __TBB_MAKE_EXCEPTION_PTR_PRESENT (_MSC_VER >= 1700 || (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600)) #define __TBB_STATIC_ASSERT_PRESENT (__INTEL_CXX11_MODE__ || _MSC_VER >= 1600) #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600 || (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300)) /**Intel C++ compiler 14.0 crashes on using __has_include. When it fixed, condition will need to be updated. **/ #if (__clang__ && __INTEL_COMPILER > 1400) #if (__has_feature(__cxx_generalized_initializers__) && __has_include()) #define __TBB_INITIALIZER_LISTS_PRESENT 1 #endif #else /** TODO: when MSVC2013 is supported by Intel C++ compiler, it will be enabled silently by compiler, so rule will need to be updated.**/ #define __TBB_INITIALIZER_LISTS_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 && (_MSC_VER >= 1800 || __TBB_GCC_VERSION >= 40400 || _LIBCPP_VERSION) #endif #define __TBB_CONSTEXPR_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200 /** ICC seems to disable support of noexcept event in c++11 when compiling in compatibility mode for gcc <4.6 **/ #define __TBB_NOEXCEPT_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1300 && (__TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION || _MSC_VER) #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1310 && (__TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION)) #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) #elif __clang__ //TODO: these options need to be rechecked /** on OS X* the only way to get C++11 is to use clang. For library features (e.g. exception_ptr) libc++ is also * required. So there is no need to check GCC version for clang**/ #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (__has_feature(__cxx_variadic_templates__)) #define __TBB_CPP11_RVALUE_REF_PRESENT (__has_feature(__cxx_rvalue_references__) && (__TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION)) /** TODO: extend exception_ptr related conditions to cover libstdc++ **/ #define __TBB_EXCEPTION_PTR_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION) #define __TBB_MAKE_EXCEPTION_PTR_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION) #define __TBB_STATIC_ASSERT_PRESENT __has_feature(__cxx_static_assert__) /**Clang (preprocessor) has problems with dealing with expression having __has_include in #ifs * used inside C++ code. (At least version that comes with OS X 10.8 : Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)) **/ #if (__GXX_EXPERIMENTAL_CXX0X__ && __has_include()) #define __TBB_CPP11_TUPLE_PRESENT 1 #endif #if (__has_feature(__cxx_generalized_initializers__) && __has_include()) #define __TBB_INITIALIZER_LISTS_PRESENT 1 #endif #define __TBB_CONSTEXPR_PRESENT __has_feature(__cxx_constexpr__) #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__has_feature(__cxx_defaulted_functions__) && __has_feature(__cxx_deleted_functions__)) /**For some unknown reason __has_feature(__cxx_noexcept) does not yield true for all cases. Compiler bug ? **/ #define __TBB_NOEXCEPT_PRESENT (__cplusplus >= 201103L) #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__has_feature(__cxx_range_for__) && _LIBCPP_VERSION) #define __TBB_CPP11_AUTO_PRESENT __has_feature(__cxx_auto_type__) #define __TBB_CPP11_DECLTYPE_PRESENT __has_feature(__cxx_decltype__) #elif __GNUC__ #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT __GXX_EXPERIMENTAL_CXX0X__ #define __TBB_CPP11_RVALUE_REF_PRESENT __GXX_EXPERIMENTAL_CXX0X__ /** __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 here is a substitution for _GLIBCXX_ATOMIC_BUILTINS_4, which is a prerequisite for exception_ptr but cannot be used in this file because it is defined in a header, not by the compiler. If the compiler has no atomic intrinsics, the C++ library should not expect those as well. **/ #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40404 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) #define __TBB_MAKE_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) #define __TBB_STATIC_ASSERT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) #define __TBB_CPP11_TUPLE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) #define __TBB_INITIALIZER_LISTS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) /** gcc seems have to support constexpr from 4.4 but tests in (test_atomic) seeming reasonable fail to compile prior 4.6**/ #define __TBB_CONSTEXPR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) #define __TBB_NOEXCEPT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) #define __TBB_CPP11_AUTO_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) #define __TBB_CPP11_DECLTYPE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) #elif _MSC_VER #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (_MSC_VER >= 1800) #define __TBB_CPP11_RVALUE_REF_PRESENT (_MSC_VER >= 1600) #define __TBB_EXCEPTION_PTR_PRESENT (_MSC_VER >= 1600) #define __TBB_STATIC_ASSERT_PRESENT (_MSC_VER >= 1600) #define __TBB_MAKE_EXCEPTION_PTR_PRESENT (_MSC_VER >= 1700) #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600) #define __TBB_INITIALIZER_LISTS_PRESENT (_MSC_VER >= 1800) #define __TBB_CONSTEXPR_PRESENT 0 #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (_MSC_VER >= 1800) #define __TBB_NOEXCEPT_PRESENT 0 /*for _MSC_VER == 1800*/ #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700) #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600) #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600) #else #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT 0 #define __TBB_CPP11_RVALUE_REF_PRESENT 0 #define __TBB_EXCEPTION_PTR_PRESENT 0 #define __TBB_STATIC_ASSERT_PRESENT 0 #define __TBB_MAKE_EXCEPTION_PTR_PRESENT 0 #define __TBB_CPP11_TUPLE_PRESENT 0 #define __TBB_INITIALIZER_LISTS_PRESENT 0 #define __TBB_CONSTEXPR_PRESENT 0 #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT 0 #define __TBB_NOEXCEPT_PRESENT 0 #define __TBB_CPP11_STD_BEGIN_END_PRESENT 0 #define __TBB_CPP11_AUTO_PRESENT 0 #define __TBB_CPP11_DECLTYPE_PRESENT 0 #endif // C++11 standard library features #define __TBB_CPP11_TYPE_PROPERTIES_PRESENT (_LIBCPP_VERSION || _MSC_VER >= 1700) #define __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300 || _MSC_VER >= 1600) //TODO: Probably more accurate way is to analyze version of stdlibc++ via__GLIBCXX__ instead of __TBB_GCC_VERSION #define __TBB_ALLOCATOR_TRAITS_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION || _MSC_VER >= 1700 || \ __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 && !(__TBB_GCC_VERSION == 40700 && __TBB_DEFINE_MIC) \ ) //TODO: not clear how exactly this macro affects exception_ptr - investigate // On linux ICC fails to find existing std::exception_ptr in libstdc++ without this define #if __INTEL_COMPILER && __GNUC__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 #endif // Work around a bug in MinGW32 #if __MINGW32__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(_GLIBCXX_ATOMIC_BUILTINS_4) #define _GLIBCXX_ATOMIC_BUILTINS_4 #endif #if __GNUC__ || __SUNPRO_CC || __IBMCPP__ /* ICC defines __GNUC__ and so is covered */ #define __TBB_ATTRIBUTE_ALIGNED_PRESENT 1 #elif _MSC_VER && (_MSC_VER >= 1300 || __INTEL_COMPILER) #define __TBB_DECLSPEC_ALIGN_PRESENT 1 #endif /* Actually ICC supports gcc __sync_* intrinsics starting 11.1, * but 64 bit support for 32 bit target comes in later ones*/ /* TODO: change the version back to 4.1.2 once macro __TBB_WORD_SIZE become optional */ #if __TBB_GCC_VERSION >= 40306 || __INTEL_COMPILER >= 1200 /** built-in atomics available in GCC since 4.1.2 **/ #define __TBB_GCC_BUILTIN_ATOMICS_PRESENT 1 #endif #if __INTEL_COMPILER >= 1200 /** built-in C++11 style atomics available in ICC since 12.0 **/ #define __TBB_ICC_BUILTIN_ATOMICS_PRESENT 1 #endif #define __TBB_TSX_INTRINSICS_PRESENT ((__RTM__ || _MSC_VER>=1700 || __INTEL_COMPILER>=1300) && !__TBB_DEFINE_MIC && !__ANDROID__) /** User controlled TBB features & modes **/ #ifndef TBB_USE_DEBUG #ifdef _DEBUG #define TBB_USE_DEBUG _DEBUG #else #define TBB_USE_DEBUG 0 #endif #endif /* TBB_USE_DEBUG */ #ifndef TBB_USE_ASSERT #define TBB_USE_ASSERT TBB_USE_DEBUG #endif /* TBB_USE_ASSERT */ #ifndef TBB_USE_THREADING_TOOLS #define TBB_USE_THREADING_TOOLS TBB_USE_DEBUG #endif /* TBB_USE_THREADING_TOOLS */ #ifndef TBB_USE_PERFORMANCE_WARNINGS #ifdef TBB_PERFORMANCE_WARNINGS #define TBB_USE_PERFORMANCE_WARNINGS TBB_PERFORMANCE_WARNINGS #else #define TBB_USE_PERFORMANCE_WARNINGS TBB_USE_DEBUG #endif /* TBB_PEFORMANCE_WARNINGS */ #endif /* TBB_USE_PERFORMANCE_WARNINGS */ #if !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) && !defined(__SUNPRO_CC) || defined(_XBOX) #if TBB_USE_EXCEPTIONS #error Compilation settings do not support exception handling. Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. #elif !defined(TBB_USE_EXCEPTIONS) #define TBB_USE_EXCEPTIONS 0 #endif #elif !defined(TBB_USE_EXCEPTIONS) #if __TBB_DEFINE_MIC #define TBB_USE_EXCEPTIONS 0 #else #define TBB_USE_EXCEPTIONS 1 #endif #elif TBB_USE_EXCEPTIONS && __TBB_DEFINE_MIC #error Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. #endif #ifndef TBB_IMPLEMENT_CPP0X /** By default, use C++11 classes if available **/ #if __GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__ #define TBB_IMPLEMENT_CPP0X 0 #elif __clang__ && __cplusplus >= 201103L //TODO: consider introducing separate macros for each file? //prevent injection of corresponding tbb names into std:: namespace if native headers are present #if __has_include() || __has_include() #define TBB_IMPLEMENT_CPP0X 0 #else #define TBB_IMPLEMENT_CPP0X 1 #endif #elif _MSC_VER>=1700 #define TBB_IMPLEMENT_CPP0X 0 #elif __STDCPP_THREADS__ #define TBB_IMPLEMENT_CPP0X 0 #else #define TBB_IMPLEMENT_CPP0X 1 #endif #endif /* TBB_IMPLEMENT_CPP0X */ /* TBB_USE_CAPTURED_EXCEPTION should be explicitly set to either 0 or 1, as it is used as C++ const */ #ifndef TBB_USE_CAPTURED_EXCEPTION /** IA-64 architecture pre-built TBB binaries do not support exception_ptr. **/ #if __TBB_EXCEPTION_PTR_PRESENT && !defined(__ia64__) #define TBB_USE_CAPTURED_EXCEPTION 0 #else #define TBB_USE_CAPTURED_EXCEPTION 1 #endif #else /* defined TBB_USE_CAPTURED_EXCEPTION */ #if !TBB_USE_CAPTURED_EXCEPTION && !__TBB_EXCEPTION_PTR_PRESENT #error Current runtime does not support std::exception_ptr. Set TBB_USE_CAPTURED_EXCEPTION and make sure that your code is ready to catch tbb::captured_exception. #endif #endif /* defined TBB_USE_CAPTURED_EXCEPTION */ /** Check whether the request to use GCC atomics can be satisfied **/ #if TBB_USE_GCC_BUILTINS && !__TBB_GCC_BUILTIN_ATOMICS_PRESENT #error "GCC atomic built-ins are not supported." #endif /** Internal TBB features & modes **/ /** __TBB_WEAK_SYMBOLS_PRESENT denotes that the system supports the weak symbol mechanism **/ #ifndef __TBB_WEAK_SYMBOLS_PRESENT #define __TBB_WEAK_SYMBOLS_PRESENT ( !_WIN32 && !__APPLE__ && !__sun && (__TBB_GCC_VERSION >= 40000 || __INTEL_COMPILER ) ) #endif /** __TBB_DYNAMIC_LOAD_ENABLED describes the system possibility to load shared libraries at run time **/ #ifndef __TBB_DYNAMIC_LOAD_ENABLED #define __TBB_DYNAMIC_LOAD_ENABLED 1 #endif /** __TBB_SOURCE_DIRECTLY_INCLUDED is a mode used in whitebox testing when it's necessary to test internal functions not exported from TBB DLLs **/ #if (_WIN32||_WIN64) && (__TBB_SOURCE_DIRECTLY_INCLUDED || TBB_USE_PREVIEW_BINARY) #define __TBB_NO_IMPLICIT_LINKAGE 1 #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1 #endif #ifndef __TBB_COUNT_TASK_NODES #define __TBB_COUNT_TASK_NODES TBB_USE_ASSERT #endif #ifndef __TBB_TASK_GROUP_CONTEXT #define __TBB_TASK_GROUP_CONTEXT 1 #endif /* __TBB_TASK_GROUP_CONTEXT */ #ifndef __TBB_SCHEDULER_OBSERVER #define __TBB_SCHEDULER_OBSERVER 1 #endif /* __TBB_SCHEDULER_OBSERVER */ #ifndef __TBB_FP_CONTEXT #define __TBB_FP_CONTEXT __TBB_TASK_GROUP_CONTEXT #endif /* __TBB_FP_CONTEXT */ #if __TBB_FP_CONTEXT && !__TBB_TASK_GROUP_CONTEXT #error __TBB_FP_CONTEXT requires __TBB_TASK_GROUP_CONTEXT to be enabled #endif #ifndef __TBB_TASK_ARENA #define __TBB_TASK_ARENA 1 #endif /* __TBB_TASK_ARENA */ #if __TBB_TASK_ARENA #define __TBB_RECYCLE_TO_ENQUEUE __TBB_BUILD // keep non-official #if !__TBB_SCHEDULER_OBSERVER #error __TBB_TASK_ARENA requires __TBB_SCHEDULER_OBSERVER to be enabled #endif #endif /* __TBB_TASK_ARENA */ #ifndef __TBB_ARENA_OBSERVER #define __TBB_ARENA_OBSERVER ((__TBB_BUILD||TBB_PREVIEW_LOCAL_OBSERVER)&& __TBB_SCHEDULER_OBSERVER) #endif /* __TBB_ARENA_OBSERVER */ #ifndef __TBB_SLEEP_PERMISSION #define __TBB_SLEEP_PERMISSION ((__TBB_CPF_BUILD||TBB_PREVIEW_LOCAL_OBSERVER)&& __TBB_SCHEDULER_OBSERVER) #endif /* __TBB_SLEEP_PERMISSION */ #if TBB_PREVIEW_FLOW_GRAPH_TRACE #define __TBB_NO_IMPLICIT_LINKAGE 1 #endif /* TBB_PREVIEW_FLOW_GRAPH_TRACE */ #ifndef __TBB_ITT_STRUCTURE_API #define __TBB_ITT_STRUCTURE_API ( !__TBB_DEFINE_MIC && (__TBB_CPF_BUILD || TBB_PREVIEW_FLOW_GRAPH_TRACE) ) #endif #if TBB_USE_EXCEPTIONS && !__TBB_TASK_GROUP_CONTEXT #error TBB_USE_EXCEPTIONS requires __TBB_TASK_GROUP_CONTEXT to be enabled #endif #ifndef __TBB_TASK_PRIORITY #define __TBB_TASK_PRIORITY (!(__TBB_CPF_BUILD||TBB_USE_PREVIEW_BINARY)&&__TBB_TASK_GROUP_CONTEXT) // TODO: it will be enabled for CPF in the next versions #endif /* __TBB_TASK_PRIORITY */ #if __TBB_TASK_PRIORITY && !__TBB_TASK_GROUP_CONTEXT #error __TBB_TASK_PRIORITY requires __TBB_TASK_GROUP_CONTEXT to be enabled #endif #if TBB_PREVIEW_WAITING_FOR_WORKERS || __TBB_BUILD #define __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE 1 #endif #if !defined(__TBB_SURVIVE_THREAD_SWITCH) && \ (_WIN32 || _WIN64 || __APPLE__ || (__linux__ && !__ANDROID__)) #define __TBB_SURVIVE_THREAD_SWITCH 1 #endif /* __TBB_SURVIVE_THREAD_SWITCH */ #ifndef __TBB_DEFAULT_PARTITIONER #if TBB_DEPRECATED /** Default partitioner for parallel loop templates in TBB 1.0-2.1 */ #define __TBB_DEFAULT_PARTITIONER tbb::simple_partitioner #else /** Default partitioner for parallel loop templates since TBB 2.2 */ #define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner #endif /* TBB_DEPRECATED */ #endif /* !defined(__TBB_DEFAULT_PARTITIONER */ #ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES #define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1 #endif #ifdef _VARIADIC_MAX #define __TBB_VARIADIC_MAX _VARIADIC_MAX #else #if _MSC_VER >= 1700 #define __TBB_VARIADIC_MAX 5 /* current VS11 setting, may change. */ #else #define __TBB_VARIADIC_MAX 10 #endif #endif /** __TBB_WIN8UI_SUPPORT enables support of New Windows*8 Store Apps and limit a possibility to load shared libraries at run time only from application container **/ #if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP #define __TBB_WIN8UI_SUPPORT 1 #else #define __TBB_WIN8UI_SUPPORT 0 #endif /** Macros of the form __TBB_XXX_BROKEN denote known issues that are caused by the bugs in compilers, standard or OS specific libraries. They should be removed as soon as the corresponding bugs are fixed or the buggy OS/compiler versions go out of the support list. **/ #if __ANDROID__ && __TBB_GCC_VERSION <= 40403 && !__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 /** Necessary because on Android 8-byte CAS and F&A are not available for some processor architectures, but no mandatory warning message appears from GCC 4.4.3. Instead, only a linkage error occurs when these atomic operations are used (such as in unit test test_atomic.exe). **/ #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1 #elif __TBB_x86_32 && __TBB_GCC_VERSION == 40102 && ! __GNUC_RH_RELEASE__ /** GCC 4.1.2 erroneously emit call to external function for 64 bit sync_ intrinsics. However these functions are not defined anywhere. It seems that this problem was fixed later on and RHEL got an updated version of gcc 4.1.2. **/ #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1 #endif #if __GNUC__ && __TBB_x86_64 && __INTEL_COMPILER == 1200 #define __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN 1 #endif #if _MSC_VER && __INTEL_COMPILER && (__INTEL_COMPILER<1110 || __INTEL_COMPILER==1110 && __INTEL_COMPILER_BUILD_DATE < 20091012) /** Necessary to avoid ICL error (or warning in non-strict mode): "exception specification for implicitly declared virtual destructor is incompatible with that of overridden one". **/ #define __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN 1 #endif #if defined(_MSC_VER) && _MSC_VER < 1500 && !defined(__INTEL_COMPILER) /** VS2005 and earlier do not allow declaring template class as a friend of classes defined in other namespaces. **/ #define __TBB_TEMPLATE_FRIENDS_BROKEN 1 #endif //TODO: recheck for different clang versions #if __GLIBC__==2 && __GLIBC_MINOR__==3 || (__APPLE__ && ( __INTEL_COMPILER==1200 && !TBB_USE_DEBUG)) /** Macro controlling EH usages in TBB tests. Some older versions of glibc crash when exception handling happens concurrently. **/ #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 1 #else #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 0 #endif #if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110 /** That's a bug in Intel compiler 11.1.044/IA-32/Windows, that leads to a worker thread crash on the thread's startup. **/ #define __TBB_ICL_11_1_CODE_GEN_BROKEN 1 #endif #if __clang__ || (__GNUC__==3 && __GNUC_MINOR__==3 && !defined(__INTEL_COMPILER)) /** Bugs with access to nested classes declared in protected area */ #define __TBB_PROTECTED_NESTED_CLASS_BROKEN 1 #endif #if __MINGW32__ && __TBB_GCC_VERSION < 40200 /** MinGW has a bug with stack alignment for routines invoked from MS RTLs. Since GCC 4.2, the bug can be worked around via a special attribute. **/ #define __TBB_SSE_STACK_ALIGNMENT_BROKEN 1 #else #define __TBB_SSE_STACK_ALIGNMENT_BROKEN 0 #endif #if __GNUC__==4 && __GNUC_MINOR__==3 && __GNUC_PATCHLEVEL__==0 /* GCC of this version may rashly ignore control dependencies */ #define __TBB_GCC_OPTIMIZER_ORDERING_BROKEN 1 #endif #if __FreeBSD__ /** A bug in FreeBSD 8.0 results in kernel panic when there is contention on a mutex created with this attribute. **/ #define __TBB_PRIO_INHERIT_BROKEN 1 /** A bug in FreeBSD 8.0 results in test hanging when an exception occurs during (concurrent?) object construction by means of placement new operator. **/ #define __TBB_PLACEMENT_NEW_EXCEPTION_SAFETY_BROKEN 1 #endif /* __FreeBSD__ */ #if (__linux__ || __APPLE__) && __i386__ && defined(__INTEL_COMPILER) /** The Intel compiler for IA-32 (Linux|OS X) crashes or generates incorrect code when __asm__ arguments have a cast to volatile. **/ #define __TBB_ICC_ASM_VOLATILE_BROKEN 1 #endif #if !__INTEL_COMPILER && (_MSC_VER || __GNUC__==3 && __GNUC_MINOR__<=2) /** Bug in GCC 3.2 and MSVC compilers that sometimes return 0 for __alignof(T) when T has not yet been instantiated. **/ #define __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN 1 #endif #if __TBB_DEFINE_MIC /** Main thread and user's thread have different default thread affinity masks. **/ #define __TBB_MAIN_THREAD_AFFINITY_BROKEN 1 #endif #if __GXX_EXPERIMENTAL_CXX0X__ && !defined(__EXCEPTIONS) && \ ((!__INTEL_COMPILER && !__clang__ && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<40600)) || \ (__INTEL_COMPILER<=1400 && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<=40801))) /* There is an issue for specific GCC toolchain when C++11 is enabled and exceptions are disabled: exceprion_ptr.h/nested_exception.h use throw unconditionally. GCC can ignore 'throw' since 4.6; but with ICC the issue still exists. */ #define __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN 1 #else #define __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN 0 #endif #if __INTEL_COMPILER==1300 && __TBB_GCC_VERSION>=40700 && defined(__GXX_EXPERIMENTAL_CXX0X__) /* Some C++11 features used inside libstdc++ are not supported by Intel compiler. * Checking version of gcc instead of libstdc++ because * - they are directly connected, * - for now it is not possible to check version of any standard library in this file */ #define __TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN 1 #else #define __TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN 0 #endif #if (__GNUC__==4 && __GNUC_MINOR__==4 ) && !defined(__INTEL_COMPILER) && !defined(__clang__) /** excessive warnings related to strict aliasing rules in GCC 4.4 **/ #define __TBB_GCC_STRICT_ALIASING_BROKEN 1 /* topical remedy: #pragma GCC diagnostic ignored "-Wstrict-aliasing" */ #if !__TBB_GCC_WARNING_SUPPRESSION_PRESENT #error Warning suppression is not supported, while should. #endif #endif /*In a PIC mode some versions of GCC 4.1.2 generate incorrect inlined code for 8 byte __sync_val_compare_and_swap intrinsic */ #if __TBB_GCC_VERSION == 40102 && __PIC__ && !defined(__INTEL_COMPILER) && !defined(__clang__) #define __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN 1 #endif #if __TBB_x86_32 && (__linux__ || __APPLE__ || _WIN32 || __sun || __ANDROID__) && (__INTEL_COMPILER || (__GNUC__==3 && __GNUC_MINOR__==3 ) || __SUNPRO_CC) // Some compilers for IA-32 fail to provide 8-byte alignment of objects on the stack, // even if the object specifies 8-byte alignment. On such platforms, the IA-32 implementation // of 64 bit atomics (e.g. atomic) use different tactics depending upon // whether the object is properly aligned or not. #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 1 #else #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 0 #endif #if __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && __TBB_GCC_VERSION < 40700 && !defined(__INTEL_COMPILER) && !defined (__clang__) #define __TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN 1 #endif #if _MSC_VER && _MSC_VER <= 1800 && !__INTEL_COMPILER // With MSVC, when an array is passed by const reference to a template function, // constness from the function parameter may get propagated to the template parameter. #define __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN 1 #endif // A compiler bug: a disabled copy constructor prevents use of the moving constructor #define __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN (_MSC_VER && (__INTEL_COMPILER >= 1300 && __INTEL_COMPILER <= 1310) && !__INTEL_CXX11_MODE__) // MSVC 2013 and ICC 15 seems do not generate implicit move constructor for empty derived class while should #define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN (__TBB_CPP11_RVALUE_REF_PRESENT && \ ( !__INTEL_COMPILER && _MSC_VER && _MSC_VER <=1800 || __INTEL_COMPILER && __INTEL_COMPILER <= 1500 )) /** End of __TBB_XXX_BROKEN macro section **/ #if defined(_MSC_VER) && _MSC_VER>=1500 && !defined(__INTEL_COMPILER) // A macro to suppress erroneous or benign "unreachable code" MSVC warning (4702) #define __TBB_MSVC_UNREACHABLE_CODE_IGNORED 1 #endif #define __TBB_ATOMIC_CTORS (__TBB_CONSTEXPR_PRESENT && __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && (!__TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN)) #define __TBB_ALLOCATOR_CONSTRUCT_VARIADIC (__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT) #define __TBB_VARIADIC_PARALLEL_INVOKE (TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT) #endif /* __TBB_tbb_config_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_exception.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_exception_H #define __TBB_exception_H #include "tbb_stddef.h" #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #include //required for bad_alloc definition, operators new #include // required to construct std exception classes #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif namespace tbb { //! Exception for concurrent containers class bad_last_alloc : public std::bad_alloc { public: /*override*/ const char* what() const throw(); #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN /*override*/ ~bad_last_alloc() throw() {} #endif }; //! Exception for PPL locks class improper_lock : public std::exception { public: /*override*/ const char* what() const throw(); }; //! Exception for user-initiated abort class user_abort : public std::exception { public: /*override*/ const char* what() const throw(); }; //! Exception for missing wait on structured_task_group class missing_wait : public std::exception { public: /*override*/ const char* what() const throw(); }; //! Exception for repeated scheduling of the same task_handle class invalid_multiple_scheduling : public std::exception { public: /*override*/ const char* what() const throw(); }; namespace internal { //! Obsolete void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4(); enum exception_id { eid_bad_alloc = 1, eid_bad_last_alloc, eid_nonpositive_step, eid_out_of_range, eid_segment_range_error, eid_index_range_error, eid_missing_wait, eid_invalid_multiple_scheduling, eid_improper_lock, eid_possible_deadlock, eid_operation_not_permitted, eid_condvar_wait_failed, eid_invalid_load_factor, eid_reserved, // free slot for backward compatibility, can be reused. eid_invalid_swap, eid_reservation_length_error, eid_invalid_key, eid_user_abort, eid_reserved1, #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE // This id is used only inside library and only for support of CPF functionality. // So, if we drop the functionality, eid_reserved1 can be safely renamed and reused. eid_blocking_sch_init = eid_reserved1, #endif eid_bad_tagged_msg_cast, //! The last enumerator tracks the number of defined IDs. It must remain the last one. /** When adding new IDs, place them immediately _before_ this comment (that is _after_ all the existing IDs. NEVER insert new IDs between the existing ones. **/ eid_max }; //! Gathers all throw operators in one place. /** Its purpose is to minimize code bloat that can be caused by throw operators scattered in multiple places, especially in templates. **/ void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id ); //! Versionless convenience wrapper for throw_exception_v4() inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); } } // namespace internal } // namespace tbb #if __TBB_TASK_GROUP_CONTEXT #include "tbb_allocator.h" #include //for typeid namespace tbb { //! Interface to be implemented by all exceptions TBB recognizes and propagates across the threads. /** If an unhandled exception of the type derived from tbb::tbb_exception is intercepted by the TBB scheduler in one of the worker threads, it is delivered to and re-thrown in the root thread. The root thread is the thread that has started the outermost algorithm or root task sharing the same task_group_context with the guilty algorithm/task (the one that threw the exception first). Note: when documentation mentions workers with respect to exception handling, masters are implied as well, because they are completely equivalent in this context. Consequently a root thread can be master or worker thread. NOTE: In case of nested algorithms or complex task hierarchies when the nested levels share (explicitly or by means of implicit inheritance) the task group context of the outermost level, the exception may be (re-)thrown multiple times (ultimately - in each worker on each nesting level) before reaching the root thread at the outermost level. IMPORTANT: if you intercept an exception derived from this class on a nested level, you must re-throw it in the catch block by means of the "throw;" operator. TBB provides two implementations of this interface: tbb::captured_exception and template class tbb::movable_exception. See their declarations for more info. **/ class tbb_exception : public std::exception { /** No operator new is provided because the TBB usage model assumes dynamic creation of the TBB exception objects only by means of applying move() operation on an exception thrown out of TBB scheduler. **/ void* operator new ( size_t ); public: #if __clang__ // At -O3 or even -O2 optimization level, Clang may fully throw away an empty destructor // of tbb_exception from destructors of derived classes. As a result, it does not create // vtable for tbb_exception, which is a required part of TBB binary interface. // Making the destructor non-empty (with just a semicolon) prevents that optimization. ~tbb_exception() throw() { /* keep the semicolon! */ ; } #endif //! Creates and returns pointer to the deep copy of this exception object. /** Move semantics is allowed. **/ virtual tbb_exception* move () throw() = 0; //! Destroys objects created by the move() method. /** Frees memory and calls destructor for this exception object. Can and must be used only on objects created by the move method. **/ virtual void destroy () throw() = 0; //! Throws this exception object. /** Make sure that if you have several levels of derivation from this interface you implement or override this method on the most derived level. The implementation is as simple as "throw *this;". Failure to do this will result in exception of a base class type being thrown. **/ virtual void throw_self () = 0; //! Returns RTTI name of the originally intercepted exception virtual const char* name() const throw() = 0; //! Returns the result of originally intercepted exception's what() method. virtual const char* what() const throw() = 0; /** Operator delete is provided only to allow using existing smart pointers with TBB exception objects obtained as the result of applying move() operation on an exception thrown out of TBB scheduler. When overriding method move() make sure to override operator delete as well if memory is allocated not by TBB's scalable allocator. **/ void operator delete ( void* p ) { internal::deallocate_via_handler_v3(p); } }; //! This class is used by TBB to propagate information about unhandled exceptions into the root thread. /** Exception of this type is thrown by TBB in the root thread (thread that started a parallel algorithm ) if an unhandled exception was intercepted during the algorithm execution in one of the workers. \sa tbb::tbb_exception **/ class captured_exception : public tbb_exception { public: captured_exception ( const captured_exception& src ) : tbb_exception(src), my_dynamic(false) { set(src.my_exception_name, src.my_exception_info); } captured_exception ( const char* name_, const char* info ) : my_dynamic(false) { set(name_, info); } __TBB_EXPORTED_METHOD ~captured_exception () throw(); captured_exception& operator= ( const captured_exception& src ) { if ( this != &src ) { clear(); set(src.my_exception_name, src.my_exception_info); } return *this; } /*override*/ captured_exception* __TBB_EXPORTED_METHOD move () throw(); /*override*/ void __TBB_EXPORTED_METHOD destroy () throw(); /*override*/ void throw_self () { __TBB_THROW(*this); } /*override*/ const char* __TBB_EXPORTED_METHOD name() const throw(); /*override*/ const char* __TBB_EXPORTED_METHOD what() const throw(); void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw(); void __TBB_EXPORTED_METHOD clear () throw(); private: //! Used only by method clone(). captured_exception() {} //! Functionally equivalent to {captured_exception e(name,info); return e.clone();} static captured_exception* allocate ( const char* name, const char* info ); bool my_dynamic; const char* my_exception_name; const char* my_exception_info; }; //! Template that can be used to implement exception that transfers arbitrary ExceptionData to the root thread /** Code using TBB can instantiate this template with an arbitrary ExceptionData type and throw this exception object. Such exceptions are intercepted by the TBB scheduler and delivered to the root thread (). \sa tbb::tbb_exception **/ template class movable_exception : public tbb_exception { typedef movable_exception self_type; public: movable_exception ( const ExceptionData& data_ ) : my_exception_data(data_) , my_dynamic(false) , my_exception_name( #if TBB_USE_EXCEPTIONS typeid(self_type).name() #else /* !TBB_USE_EXCEPTIONS */ "movable_exception" #endif /* !TBB_USE_EXCEPTIONS */ ) {} movable_exception ( const movable_exception& src ) throw () : tbb_exception(src) , my_exception_data(src.my_exception_data) , my_dynamic(false) , my_exception_name(src.my_exception_name) {} ~movable_exception () throw() {} const movable_exception& operator= ( const movable_exception& src ) { if ( this != &src ) { my_exception_data = src.my_exception_data; my_exception_name = src.my_exception_name; } return *this; } ExceptionData& data () throw() { return my_exception_data; } const ExceptionData& data () const throw() { return my_exception_data; } /*override*/ const char* name () const throw() { return my_exception_name; } /*override*/ const char* what () const throw() { return "tbb::movable_exception"; } /*override*/ movable_exception* move () throw() { void* e = internal::allocate_via_handler_v3(sizeof(movable_exception)); if ( e ) { ::new (e) movable_exception(*this); ((movable_exception*)e)->my_dynamic = true; } return (movable_exception*)e; } /*override*/ void destroy () throw() { __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" ); if ( my_dynamic ) { this->~movable_exception(); internal::deallocate_via_handler_v3(this); } } /*override*/ void throw_self () { __TBB_THROW( *this ); } protected: //! User data ExceptionData my_exception_data; private: //! Flag specifying whether this object has been dynamically allocated (by the move method) bool my_dynamic; //! RTTI name of this class /** We rely on the fact that RTTI names are static string constants. **/ const char* my_exception_name; }; #if !TBB_USE_CAPTURED_EXCEPTION namespace internal { //! Exception container that preserves the exact copy of the original exception /** This class can be used only when the appropriate runtime support (mandated by C++0x) is present **/ class tbb_exception_ptr { std::exception_ptr my_ptr; public: static tbb_exception_ptr* allocate (); static tbb_exception_ptr* allocate ( const tbb_exception& tag ); //! This overload uses move semantics (i.e. it empties src) static tbb_exception_ptr* allocate ( captured_exception& src ); //! Destroys this objects /** Note that objects of this type can be created only by the allocate() method. **/ void destroy () throw(); //! Throws the contained exception . void throw_self () { std::rethrow_exception(my_ptr); } private: tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {} tbb_exception_ptr ( const captured_exception& src ) : #if __TBB_MAKE_EXCEPTION_PTR_PRESENT my_ptr(std::make_exception_ptr(src)) // the final function name in C++11 #else my_ptr(std::copy_exception(src)) // early C++0x drafts name #endif {} }; // class tbb::internal::tbb_exception_ptr } // namespace internal #endif /* !TBB_USE_CAPTURED_EXCEPTION */ } // namespace tbb #endif /* __TBB_TASK_GROUP_CONTEXT */ #endif /* __TBB_exception_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_machine.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #define __TBB_machine_H /** This header provides basic platform abstraction layer by hooking up appropriate architecture/OS/compiler specific headers from the /include/tbb/machine directory. If a plug-in header does not implement all the required APIs, it must specify the missing ones by setting one or more of the following macros: __TBB_USE_GENERIC_PART_WORD_CAS __TBB_USE_GENERIC_PART_WORD_FETCH_ADD __TBB_USE_GENERIC_PART_WORD_FETCH_STORE __TBB_USE_GENERIC_FETCH_ADD __TBB_USE_GENERIC_FETCH_STORE __TBB_USE_GENERIC_DWORD_FETCH_ADD __TBB_USE_GENERIC_DWORD_FETCH_STORE __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE __TBB_USE_GENERIC_FULL_FENCED_LOAD_STORE __TBB_USE_GENERIC_RELAXED_LOAD_STORE __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE In this case tbb_machine.h will add missing functionality based on a minimal set of APIs that are required to be implemented by all plug-n headers as described further. Note that these generic implementations may be sub-optimal for a particular architecture, and thus should be relied upon only after careful evaluation or as the last resort. Additionally __TBB_64BIT_ATOMICS can be set to 0 on a 32-bit architecture to indicate that the port is not going to support double word atomics. It may also be set to 1 explicitly, though normally this is not necessary as tbb_machine.h will set it automatically. __TBB_ENDIANNESS macro can be defined by the implementation as well. It is used only if __TBB_USE_GENERIC_PART_WORD_CAS is set (or for testing), and must specify the layout of aligned 16-bit and 32-bit data anywhere within a process (while the details of unaligned 16-bit or 32-bit data or of 64-bit data are irrelevant). The layout must be the same at all relevant memory locations within the current process; in case of page-specific endianness, one endianness must be kept "out of sight". Possible settings, reflecting hardware and possibly O.S. convention, are: - __TBB_ENDIAN_BIG for big-endian data, - __TBB_ENDIAN_LITTLE for little-endian data, - __TBB_ENDIAN_DETECT for run-time detection iff exactly one of the above, - __TBB_ENDIAN_UNSUPPORTED to prevent undefined behavior if none of the above. Prerequisites for each architecture port ---------------------------------------- The following functions and macros have no generic implementation. Therefore they must be implemented in each machine architecture specific header either as a conventional function or as a functional macro. __TBB_WORDSIZE This is the size of machine word in bytes, i.e. for 32 bit systems it should be defined to 4. __TBB_Yield() Signals OS that the current thread is willing to relinquish the remainder of its time quantum. __TBB_full_memory_fence() Must prevent all memory operations from being reordered across it (both by hardware and compiler). All such fences must be totally ordered (or sequentially consistent). __TBB_machine_cmpswp4( volatile void *ptr, int32_t value, int32_t comparand ) Must be provided if __TBB_USE_FENCED_ATOMICS is not set. __TBB_machine_cmpswp8( volatile void *ptr, int32_t value, int64_t comparand ) Must be provided for 64-bit architectures if __TBB_USE_FENCED_ATOMICS is not set, and for 32-bit architectures if __TBB_64BIT_ATOMICS is set __TBB_machine_(...), where = {cmpswp, fetchadd, fetchstore} = {1, 2, 4, 8} = {full_fence, acquire, release, relaxed} Must be provided if __TBB_USE_FENCED_ATOMICS is set. __TBB_control_consistency_helper() Bridges the memory-semantics gap between architectures providing only implicit C++0x "consume" semantics (like Power Architecture) and those also implicitly obeying control dependencies (like IA-64 architecture). It must be used only in conditional code where the condition is itself data-dependent, and will then make subsequent code behave as if the original data dependency were acquired. It needs only a compiler fence where implied by the architecture either specifically (like IA-64 architecture) or because generally stronger "acquire" semantics are enforced (like x86). It is always valid, though potentially suboptimal, to replace control with acquire on the load and then remove the helper. __TBB_acquire_consistency_helper(), __TBB_release_consistency_helper() Must be provided if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE is set. Enforce acquire and release semantics in generic implementations of fenced store and load operations. Depending on the particular architecture/compiler combination they may be a hardware fence, a compiler fence, both or nothing. **/ #include "tbb_stddef.h" namespace tbb { namespace internal { //< @cond INTERNAL //////////////////////////////////////////////////////////////////////////////// // Overridable helpers declarations // // A machine/*.h file may choose to define these templates, otherwise it must // request default implementation by setting appropriate __TBB_USE_GENERIC_XXX macro(s). // template struct machine_load_store; template struct machine_load_store_relaxed; template struct machine_load_store_seq_cst; // // End of overridable helpers declarations //////////////////////////////////////////////////////////////////////////////// template struct atomic_selector; template<> struct atomic_selector<1> { typedef int8_t word; inline static word fetch_store ( volatile void* location, word value ); }; template<> struct atomic_selector<2> { typedef int16_t word; inline static word fetch_store ( volatile void* location, word value ); }; template<> struct atomic_selector<4> { #if _MSC_VER && !_WIN64 // Work-around that avoids spurious /Wp64 warnings typedef intptr_t word; #else typedef int32_t word; #endif inline static word fetch_store ( volatile void* location, word value ); }; template<> struct atomic_selector<8> { typedef int64_t word; inline static word fetch_store ( volatile void* location, word value ); }; }} //< namespaces internal @endcond, tbb #define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M) \ inline void __TBB_machine_generic_store8##M(volatile void *ptr, int64_t value) { \ for(;;) { \ int64_t result = *(volatile int64_t *)ptr; \ if( __TBB_machine_cmpswp8##M(ptr,value,result)==result ) break; \ } \ } \ #define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M) \ inline int64_t __TBB_machine_generic_load8##M(const volatile void *ptr) { \ /* Comparand and new value may be anything, they only must be equal, and */ \ /* the value should have a low probability to be actually found in 'location'.*/ \ const int64_t anyvalue = 2305843009213693951LL; \ return __TBB_machine_cmpswp8##M(const_cast(ptr),anyvalue,anyvalue); \ } \ // The set of allowed values for __TBB_ENDIANNESS (see above for details) #define __TBB_ENDIAN_UNSUPPORTED -1 #define __TBB_ENDIAN_LITTLE 0 #define __TBB_ENDIAN_BIG 1 #define __TBB_ENDIAN_DETECT 2 #if _WIN32||_WIN64 #ifdef _MANAGED #pragma managed(push, off) #endif #if __MINGW64__ || __MINGW32__ extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); #define __TBB_Yield() SwitchToThread() #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) #include "machine/gcc_generic.h" #elif __MINGW64__ #include "machine/linux_intel64.h" #elif __MINGW32__ #include "machine/linux_ia32.h" #endif #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) #include "machine/icc_generic.h" #elif defined(_M_IX86) && !defined(__TBB_WIN32_USE_CL_BUILTINS) #include "machine/windows_ia32.h" #elif defined(_M_X64) #include "machine/windows_intel64.h" #elif defined(_XBOX) #include "machine/xbox360_ppc.h" #elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS) #include "machine/msvc_armv7.h" #endif #ifdef _MANAGED #pragma managed(pop) #endif #elif __TBB_DEFINE_MIC #include "machine/mic_common.h" #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) #include "machine/icc_generic.h" #else #include "machine/linux_intel64.h" #endif #elif __linux__ || __FreeBSD__ || __NetBSD__ #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) #include "machine/gcc_generic.h" #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) #include "machine/icc_generic.h" #elif __i386__ #include "machine/linux_ia32.h" #elif __x86_64__ #include "machine/linux_intel64.h" #elif __ia64__ #include "machine/linux_ia64.h" #elif __powerpc__ #include "machine/mac_ppc.h" #elif __arm__ #include "machine/gcc_armv7.h" #elif __TBB_GCC_BUILTIN_ATOMICS_PRESENT #include "machine/gcc_generic.h" #endif #include "machine/linux_common.h" #elif __APPLE__ //TODO: TBB_USE_GCC_BUILTINS is not used for Mac, Sun, Aix #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) #include "machine/icc_generic.h" #elif __i386__ #include "machine/linux_ia32.h" #elif __x86_64__ #include "machine/linux_intel64.h" #elif __POWERPC__ #include "machine/mac_ppc.h" #endif #include "machine/macos_common.h" #elif _AIX #include "machine/ibm_aix51.h" #elif __sun || __SUNPRO_CC #define __asm__ asm #define __volatile__ volatile #if __i386 || __i386__ #include "machine/linux_ia32.h" #elif __x86_64__ #include "machine/linux_intel64.h" #elif __sparc #include "machine/sunos_sparc.h" #endif #include #define __TBB_Yield() sched_yield() #endif /* OS selection */ #ifndef __TBB_64BIT_ATOMICS #define __TBB_64BIT_ATOMICS 1 #endif //TODO: replace usage of these functions with usage of tbb::atomic, and then remove them //TODO: map functions with W suffix to use cast to tbb::atomic and according op, i.e. as_atomic().op() // Special atomic functions #if __TBB_USE_FENCED_ATOMICS #define __TBB_machine_cmpswp1 __TBB_machine_cmpswp1full_fence #define __TBB_machine_cmpswp2 __TBB_machine_cmpswp2full_fence #define __TBB_machine_cmpswp4 __TBB_machine_cmpswp4full_fence #define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8full_fence #if __TBB_WORDSIZE==8 #define __TBB_machine_fetchadd8 __TBB_machine_fetchadd8full_fence #define __TBB_machine_fetchstore8 __TBB_machine_fetchstore8full_fence #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd8release(P,V) #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd8acquire(P,1) #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd8release(P,(-1)) #else #define __TBB_machine_fetchadd4 __TBB_machine_fetchadd4full_fence #define __TBB_machine_fetchstore4 __TBB_machine_fetchstore4full_fence #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd4release(P,V) #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd4acquire(P,1) #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd4release(P,(-1)) #endif /* __TBB_WORDSIZE==4 */ #else /* !__TBB_USE_FENCED_ATOMICS */ #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V) #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1) #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,(-1)) #endif /* !__TBB_USE_FENCED_ATOMICS */ #if __TBB_WORDSIZE==4 #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd4(P,V) #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore4(P,V) #elif __TBB_WORDSIZE==8 #if __TBB_USE_GENERIC_DWORD_LOAD_STORE || __TBB_USE_GENERIC_DWORD_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_STORE #error These macros should only be used on 32-bit platforms. #endif #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd8(P,V) #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore8(P,V) #else /* __TBB_WORDSIZE != 8 */ #error Unsupported machine word size. #endif /* __TBB_WORDSIZE */ #ifndef __TBB_Pause inline void __TBB_Pause(int32_t) { __TBB_Yield(); } #endif namespace tbb { //! Sequentially consistent full memory fence. inline void atomic_fence () { __TBB_full_memory_fence(); } namespace internal { //< @cond INTERNAL //! Class that implements exponential backoff. /** See implementation of spin_wait_while_eq for an example. */ class atomic_backoff : no_copy { //! Time delay, in units of "pause" instructions. /** Should be equal to approximately the number of "pause" instructions that take the same time as an context switch. */ static const int32_t LOOPS_BEFORE_YIELD = 16; int32_t count; public: // In many cases, an object of this type is initialized eagerly on hot path, // as in for(atomic_backoff b; ; b.pause()) { /*loop body*/ } // For this reason, the construction cost must be very small! atomic_backoff() : count(1) {} // This constructor pauses immediately; do not use on hot paths! atomic_backoff( bool ) : count(1) { pause(); } //! Pause for a while. void pause() { if( count<=LOOPS_BEFORE_YIELD ) { __TBB_Pause(count); // Pause twice as long the next time. count*=2; } else { // Pause is so long that we might as well yield CPU to scheduler. __TBB_Yield(); } } // pause for a few times and then return false immediately. bool bounded_pause() { if( count<=LOOPS_BEFORE_YIELD ) { __TBB_Pause(count); // Pause twice as long the next time. count*=2; return true; } else { return false; } } void reset() { count = 1; } }; //! Spin WHILE the value of the variable is equal to a given value /** T and U should be comparable types. */ template void spin_wait_while_eq( const volatile T& location, U value ) { atomic_backoff backoff; while( location==value ) backoff.pause(); } //! Spin UNTIL the value of the variable is equal to a given value /** T and U should be comparable types. */ template void spin_wait_until_eq( const volatile T& location, const U value ) { atomic_backoff backoff; while( location!=value ) backoff.pause(); } template void spin_wait_while(predicate_type condition){ atomic_backoff backoff; while( condition() ) backoff.pause(); } //////////////////////////////////////////////////////////////////////////////// // Generic compare-and-swap applied to only a part of a machine word. // #ifndef __TBB_ENDIANNESS #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT #endif #if __TBB_USE_GENERIC_PART_WORD_CAS && __TBB_ENDIANNESS==__TBB_ENDIAN_UNSUPPORTED #error Generic implementation of part-word CAS may not be used with __TBB_ENDIAN_UNSUPPORTED #endif #if __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED // // This function is the only use of __TBB_ENDIANNESS. // The following restrictions/limitations apply for this operation: // - T must be an integer type of at most 4 bytes for the casts and calculations to work // - T must also be less than 4 bytes to avoid compiler warnings when computing mask // (and for the operation to be useful at all, so no workaround is applied) // - the architecture must consistently use either little-endian or big-endian (same for all locations) // // TODO: static_assert for the type requirements stated above template inline T __TBB_MaskedCompareAndSwap (volatile T * const ptr, const T value, const T comparand ) { struct endianness{ static bool is_big_endian(){ #if __TBB_ENDIANNESS==__TBB_ENDIAN_DETECT const uint32_t probe = 0x03020100; return (((const char*)(&probe))[0]==0x03); #elif __TBB_ENDIANNESS==__TBB_ENDIAN_BIG || __TBB_ENDIANNESS==__TBB_ENDIAN_LITTLE return __TBB_ENDIANNESS==__TBB_ENDIAN_BIG; #else #error Unexpected value of __TBB_ENDIANNESS #endif }}; const uint32_t byte_offset = (uint32_t) ((uintptr_t)ptr & 0x3); volatile uint32_t * const aligned_ptr = (uint32_t*)((uintptr_t)ptr - byte_offset ); // location of T within uint32_t for a C++ shift operation const uint32_t bits_to_shift = 8*(endianness::is_big_endian() ? (4 - sizeof(T) - (byte_offset)) : byte_offset); const uint32_t mask = (((uint32_t)1<<(sizeof(T)*8)) - 1 )<> bits_to_shift); } else continue; // CAS failed but the bits of interest were not changed } } #endif // __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED //////////////////////////////////////////////////////////////////////////////// template inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T comparand ); template<> inline int8_t __TBB_CompareAndSwapGeneric <1,int8_t> (volatile void *ptr, int8_t value, int8_t comparand ) { #if __TBB_USE_GENERIC_PART_WORD_CAS return __TBB_MaskedCompareAndSwap((volatile int8_t *)ptr,value,comparand); #else return __TBB_machine_cmpswp1(ptr,value,comparand); #endif } template<> inline int16_t __TBB_CompareAndSwapGeneric <2,int16_t> (volatile void *ptr, int16_t value, int16_t comparand ) { #if __TBB_USE_GENERIC_PART_WORD_CAS return __TBB_MaskedCompareAndSwap((volatile int16_t *)ptr,value,comparand); #else return __TBB_machine_cmpswp2(ptr,value,comparand); #endif } template<> inline int32_t __TBB_CompareAndSwapGeneric <4,int32_t> (volatile void *ptr, int32_t value, int32_t comparand ) { // Cast shuts up /Wp64 warning return (int32_t)__TBB_machine_cmpswp4(ptr,value,comparand); } #if __TBB_64BIT_ATOMICS template<> inline int64_t __TBB_CompareAndSwapGeneric <8,int64_t> (volatile void *ptr, int64_t value, int64_t comparand ) { return __TBB_machine_cmpswp8(ptr,value,comparand); } #endif template inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) { T result; for( atomic_backoff b;;b.pause() ) { result = *reinterpret_cast(ptr); // __TBB_CompareAndSwapGeneric presumed to have full fence. if( __TBB_CompareAndSwapGeneric ( ptr, result+addend, result )==result ) break; } return result; } template inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) { T result; for( atomic_backoff b;;b.pause() ) { result = *reinterpret_cast(ptr); // __TBB_CompareAndSwapGeneric presumed to have full fence. if( __TBB_CompareAndSwapGeneric ( ptr, value, result )==result ) break; } return result; } #if __TBB_USE_GENERIC_PART_WORD_CAS #define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1,int8_t> #define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2,int16_t> #endif #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_PART_WORD_FETCH_ADD #define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,int8_t> #define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,int16_t> #endif #if __TBB_USE_GENERIC_FETCH_ADD #define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,int32_t> #endif #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_ADD #define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,int64_t> #endif #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_PART_WORD_FETCH_STORE #define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,int8_t> #define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,int16_t> #endif #if __TBB_USE_GENERIC_FETCH_STORE #define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,int32_t> #endif #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_DWORD_FETCH_STORE #define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,int64_t> #endif #if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE #define __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(S) \ atomic_selector::word atomic_selector::fetch_store ( volatile void* location, word value ) { \ return __TBB_machine_fetchstore##S( location, value ); \ } __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(1) __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(2) __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(4) __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(8) #undef __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE #endif /* __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ #if __TBB_USE_GENERIC_DWORD_LOAD_STORE /*TODO: find a more elegant way to handle function names difference*/ #if ! __TBB_USE_FENCED_ATOMICS /* This name forwarding is needed for generic implementation of * load8/store8 defined below (via macro) to pick the right CAS function*/ #define __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8 #endif __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence) __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence) #if ! __TBB_USE_FENCED_ATOMICS #undef __TBB_machine_cmpswp8full_fence #endif #define __TBB_machine_store8 tbb::internal::__TBB_machine_generic_store8full_fence #define __TBB_machine_load8 tbb::internal::__TBB_machine_generic_load8full_fence #endif /* __TBB_USE_GENERIC_DWORD_LOAD_STORE */ #if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE /** Fenced operations use volatile qualifier to prevent compiler from optimizing them out, and on architectures with weak memory ordering to induce compiler to generate code with appropriate acquire/release semantics. On architectures like IA32, Intel64 (and likely Sparc TSO) volatile has no effect on code gen, and consistency helpers serve as a compiler fence (the latter being true for IA64/gcc as well to fix a bug in some gcc versions). This code assumes that the generated instructions will operate atomically, which typically requires a type that can be moved in a single instruction, cooperation from the compiler for effective use of such an instruction, and appropriate alignment of the data. **/ template struct machine_load_store { static T load_with_acquire ( const volatile T& location ) { T to_return = location; __TBB_acquire_consistency_helper(); return to_return; } static void store_with_release ( volatile T &location, T value ) { __TBB_release_consistency_helper(); location = value; } }; //in general, plain load and store of 32bit compiler is not atomic for 64bit types #if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS template struct machine_load_store { static T load_with_acquire ( const volatile T& location ) { return (T)__TBB_machine_load8( (const volatile void*)&location ); } static void store_with_release ( volatile T& location, T value ) { __TBB_machine_store8( (volatile void*)&location, (int64_t)value ); } }; #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ #endif /* __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE */ #if __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE template struct machine_load_store_seq_cst { static T load ( const volatile T& location ) { __TBB_full_memory_fence(); return machine_load_store::load_with_acquire( location ); } #if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE static void store ( volatile T &location, T value ) { atomic_selector::fetch_store( (volatile void*)&location, (typename atomic_selector::word)value ); } #else /* !__TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ static void store ( volatile T &location, T value ) { machine_load_store::store_with_release( location, value ); __TBB_full_memory_fence(); } #endif /* !__TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ }; #if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS /** The implementation does not use functions __TBB_machine_load8/store8 as they are not required to be sequentially consistent. **/ template struct machine_load_store_seq_cst { static T load ( const volatile T& location ) { // Comparand and new value may be anything, they only must be equal, and // the value should have a low probability to be actually found in 'location'. const int64_t anyvalue = 2305843009213693951LL; return __TBB_machine_cmpswp8( (volatile void*)const_cast(&location), anyvalue, anyvalue ); } static void store ( volatile T &location, T value ) { int64_t result = (volatile int64_t&)location; while ( __TBB_machine_cmpswp8((volatile void*)&location, (int64_t)value, result) != result ) result = (volatile int64_t&)location; } }; #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ #endif /*__TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE */ #if __TBB_USE_GENERIC_RELAXED_LOAD_STORE // Relaxed operations add volatile qualifier to prevent compiler from optimizing them out. /** Volatile should not incur any additional cost on IA32, Intel64, and Sparc TSO architectures. However on architectures with weak memory ordering compiler may generate code with acquire/release semantics for operations on volatile data. **/ template struct machine_load_store_relaxed { static inline T load ( const volatile T& location ) { return location; } static inline void store ( volatile T& location, T value ) { location = value; } }; #if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS template struct machine_load_store_relaxed { static inline T load ( const volatile T& location ) { return (T)__TBB_machine_load8( (const volatile void*)&location ); } static inline void store ( volatile T& location, T value ) { __TBB_machine_store8( (volatile void*)&location, (int64_t)value ); } }; #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ #endif /* __TBB_USE_GENERIC_RELAXED_LOAD_STORE */ #undef __TBB_WORDSIZE //this macro is forbidden to use outside of atomic machinery template inline T __TBB_load_with_acquire(const volatile T &location) { return machine_load_store::load_with_acquire( location ); } template inline void __TBB_store_with_release(volatile T& location, V value) { machine_load_store::store_with_release( location, T(value) ); } //! Overload that exists solely to avoid /Wp64 warnings. inline void __TBB_store_with_release(volatile size_t& location, size_t value) { machine_load_store::store_with_release( location, value ); } template inline T __TBB_load_full_fence(const volatile T &location) { return machine_load_store_seq_cst::load( location ); } template inline void __TBB_store_full_fence(volatile T& location, V value) { machine_load_store_seq_cst::store( location, T(value) ); } //! Overload that exists solely to avoid /Wp64 warnings. inline void __TBB_store_full_fence(volatile size_t& location, size_t value) { machine_load_store_seq_cst::store( location, value ); } template inline T __TBB_load_relaxed (const volatile T& location) { return machine_load_store_relaxed::load( const_cast(location) ); } template inline void __TBB_store_relaxed ( volatile T& location, V value ) { machine_load_store_relaxed::store( const_cast(location), T(value) ); } //! Overload that exists solely to avoid /Wp64 warnings. inline void __TBB_store_relaxed ( volatile size_t& location, size_t value ) { machine_load_store_relaxed::store( const_cast(location), value ); } // Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as // strict as type T. The type should have a trivial default constructor and destructor, so that // arrays of that type can be declared without initializers. // It is correct (but perhaps a waste of space) if __TBB_TypeWithAlignmentAtLeastAsStrict(T) expands // to a type bigger than T. // The default definition here works on machines where integers are naturally aligned and the // strictest alignment is 64. #ifndef __TBB_TypeWithAlignmentAtLeastAsStrict #if __TBB_ATTRIBUTE_ALIGNED_PRESENT #define __TBB_DefineTypeWithAlignment(PowerOf2) \ struct __TBB_machine_type_with_alignment_##PowerOf2 { \ uint32_t member[PowerOf2/sizeof(uint32_t)]; \ } __attribute__((aligned(PowerOf2))); #define __TBB_alignof(T) __alignof__(T) #elif __TBB_DECLSPEC_ALIGN_PRESENT #define __TBB_DefineTypeWithAlignment(PowerOf2) \ __declspec(align(PowerOf2)) \ struct __TBB_machine_type_with_alignment_##PowerOf2 { \ uint32_t member[PowerOf2/sizeof(uint32_t)]; \ }; #define __TBB_alignof(T) __alignof(T) #else /* A compiler with unknown syntax for data alignment */ #error Must define __TBB_TypeWithAlignmentAtLeastAsStrict(T) #endif /* Now declare types aligned to useful powers of two */ // TODO: Is __TBB_DefineTypeWithAlignment(8) needed on 32 bit platforms? __TBB_DefineTypeWithAlignment(16) __TBB_DefineTypeWithAlignment(32) __TBB_DefineTypeWithAlignment(64) typedef __TBB_machine_type_with_alignment_64 __TBB_machine_type_with_strictest_alignment; // Primary template is a declaration of incomplete type so that it fails with unknown alignments template struct type_with_alignment; // Specializations for allowed alignments template<> struct type_with_alignment<1> { char member; }; template<> struct type_with_alignment<2> { uint16_t member; }; template<> struct type_with_alignment<4> { uint32_t member; }; template<> struct type_with_alignment<8> { uint64_t member; }; template<> struct type_with_alignment<16> {__TBB_machine_type_with_alignment_16 member; }; template<> struct type_with_alignment<32> {__TBB_machine_type_with_alignment_32 member; }; template<> struct type_with_alignment<64> {__TBB_machine_type_with_alignment_64 member; }; #if __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN //! Work around for bug in GNU 3.2 and MSVC compilers. /** Bug is that compiler sometimes returns 0 for __alignof(T) when T has not yet been instantiated. The work-around forces instantiation by forcing computation of sizeof(T) before __alignof(T). */ template struct work_around_alignment_bug { static const size_t alignment = __TBB_alignof(T); }; #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment::alignment> #else #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<__TBB_alignof(T)> #endif /* __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN */ #endif /* __TBB_TypeWithAlignmentAtLeastAsStrict */ // Template class here is to avoid instantiation of the static data for modules that don't use it template struct reverse { static const T byte_table[256]; }; // An efficient implementation of the reverse function utilizes a 2^8 lookup table holding the bit-reversed // values of [0..2^8 - 1]. Those values can also be computed on the fly at a slightly higher cost. template const T reverse::byte_table[256] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; } // namespace internal @endcond } // namespace tbb // Preserving access to legacy APIs using tbb::internal::__TBB_load_with_acquire; using tbb::internal::__TBB_store_with_release; // Mapping historically used names to the ones expected by atomic_load_store_traits #define __TBB_load_acquire __TBB_load_with_acquire #define __TBB_store_release __TBB_store_with_release #ifndef __TBB_Log2 inline intptr_t __TBB_Log2( uintptr_t x ) { if( x==0 ) return -1; intptr_t result = 0; #if !defined(_M_ARM) uintptr_t tmp; if( sizeof(x)>4 && (tmp = ((uint64_t)x)>>32) ) { x=tmp; result += 32; } #endif if( uintptr_t tmp = x>>16 ) { x=tmp; result += 16; } if( uintptr_t tmp = x>>8 ) { x=tmp; result += 8; } if( uintptr_t tmp = x>>4 ) { x=tmp; result += 4; } if( uintptr_t tmp = x>>2 ) { x=tmp; result += 2; } return (x&2)? result+1: result; } #endif #ifndef __TBB_AtomicOR inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) { for( tbb::internal::atomic_backoff b;;b.pause() ) { uintptr_t tmp = *(volatile uintptr_t *)operand; uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp); if( result==tmp ) break; } } #endif #ifndef __TBB_AtomicAND inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) { for( tbb::internal::atomic_backoff b;;b.pause() ) { uintptr_t tmp = *(volatile uintptr_t *)operand; uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp); if( result==tmp ) break; } } #endif #if __TBB_PREFETCHING #ifndef __TBB_cl_prefetch #error This platform does not define cache management primitives required for __TBB_PREFETCHING #endif #ifndef __TBB_cl_evict #define __TBB_cl_evict(p) #endif #endif #ifndef __TBB_Flag typedef unsigned char __TBB_Flag; #endif typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag; #ifndef __TBB_TryLockByte inline bool __TBB_TryLockByte( __TBB_atomic_flag &flag ) { return __TBB_machine_cmpswp1(&flag,1,0)==0; } #endif #ifndef __TBB_LockByte inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) { tbb::internal::atomic_backoff backoff; while( !__TBB_TryLockByte(flag) ) backoff.pause(); return 0; } #endif #ifndef __TBB_UnlockByte #define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0) #endif // lock primitives with TSX #if ( __TBB_x86_32 || __TBB_x86_64 ) /* only on ia32/intel64 */ inline void __TBB_TryLockByteElidedCancel() { __TBB_machine_try_lock_elided_cancel(); } inline bool __TBB_TryLockByteElided( __TBB_atomic_flag& flag ) { bool res = __TBB_machine_try_lock_elided( &flag )!=0; // to avoid the "lemming" effect, we need to abort the transaction // if __TBB_machine_try_lock_elided returns false (i.e., someone else // has acquired the mutex non-speculatively). if( !res ) __TBB_TryLockByteElidedCancel(); return res; } inline void __TBB_LockByteElided( __TBB_atomic_flag& flag ) { for(;;) { tbb::internal::spin_wait_while_eq( flag, 1 ); if( __TBB_machine_try_lock_elided( &flag ) ) return; // Another thread acquired the lock "for real". // To avoid the "lemming" effect, we abort the transaction. __TBB_TryLockByteElidedCancel(); } } inline void __TBB_UnlockByteElided( __TBB_atomic_flag& flag ) { __TBB_machine_unlock_elided( &flag ); } #endif #ifndef __TBB_ReverseByte inline unsigned char __TBB_ReverseByte(unsigned char src) { return tbb::internal::reverse::byte_table[src]; } #endif template T __TBB_ReverseBits(T src) { T dst; unsigned char *original = (unsigned char *) &src; unsigned char *reversed = (unsigned char *) &dst; for( int i = sizeof(T)-1; i >= 0; i-- ) reversed[i] = __TBB_ReverseByte( original[sizeof(T)-i-1] ); return dst; } #endif /* __TBB_machine_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_main.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" #include "tbb_main.h" #include "governor.h" #include "market.h" #include "tbb_misc.h" #include "itt_notify.h" namespace tbb { namespace internal { //------------------------------------------------------------------------ // Begin shared data layout. // The following global data items are mostly read-only after initialization. //------------------------------------------------------------------------ //! Padding in order to prevent false sharing. static const char _pad[NFS_MaxLineSize - sizeof(int)] = {}; //------------------------------------------------------------------------ // governor data basic_tls governor::theTLS; unsigned governor::DefaultNumberOfThreads; rml::tbb_factory governor::theRMLServerFactory; bool governor::UsePrivateRML; const task_scheduler_init *governor::BlockingTSI; #if TBB_USE_ASSERT bool governor::IsBlockingTerminationInProgress; #endif bool governor::is_speculation_enabled; //------------------------------------------------------------------------ // market data market* market::theMarket; market::global_market_mutex_type market::theMarketMutex; //------------------------------------------------------------------------ // One time initialization data //! Counter of references to global shared resources such as TLS. atomic __TBB_InitOnce::count; __TBB_atomic_flag __TBB_InitOnce::InitializationLock; //! Flag that is set to true after one-time initializations are done. bool __TBB_InitOnce::InitializationDone; #if DO_ITT_NOTIFY static bool ITT_Present; static bool ITT_InitializationDone; #endif #if !(_WIN32||_WIN64) || __TBB_SOURCE_DIRECTLY_INCLUDED static __TBB_InitOnce __TBB_InitOnceHiddenInstance; #endif //------------------------------------------------------------------------ // generic_scheduler data //! Pointer to the scheduler factory function generic_scheduler* (*AllocateSchedulerPtr)( arena*, size_t index ); #if __TBB_OLD_PRIMES_RNG //! Table of primes used by fast random-number generator (FastRandom). /** Also serves to keep anything else from being placed in the same cache line as the global data items preceding it. */ static const unsigned Primes[] = { 0x9e3779b1, 0xffe6cc59, 0x2109f6dd, 0x43977ab5, 0xba5703f5, 0xb495a877, 0xe1626741, 0x79695e6b, 0xbc98c09f, 0xd5bee2b3, 0x287488f9, 0x3af18231, 0x9677cd4d, 0xbe3a6929, 0xadc6a877, 0xdcf0674b, 0xbe4d6fe9, 0x5f15e201, 0x99afc3fd, 0xf3f16801, 0xe222cfff, 0x24ba5fdb, 0x0620452d, 0x79f149e3, 0xc8b93f49, 0x972702cd, 0xb07dd827, 0x6c97d5ed, 0x085a3d61, 0x46eb5ea7, 0x3d9910ed, 0x2e687b5b, 0x29609227, 0x6eb081f1, 0x0954c4e1, 0x9d114db9, 0x542acfa9, 0xb3e6bd7b, 0x0742d917, 0xe9f3ffa7, 0x54581edb, 0xf2480f45, 0x0bb9288f, 0xef1affc7, 0x85fa0ca7, 0x3ccc14db, 0xe6baf34b, 0x343377f7, 0x5ca19031, 0xe6d9293b, 0xf0a9f391, 0x5d2e980b, 0xfc411073, 0xc3749363, 0xb892d829, 0x3549366b, 0x629750ad, 0xb98294e5, 0x892d9483, 0xc235baf3, 0x3d2402a3, 0x6bdef3c9, 0xbec333cd, 0x40c9520f }; //------------------------------------------------------------------------ // End of shared data layout //------------------------------------------------------------------------ //------------------------------------------------------------------------ // Shared data accessors //------------------------------------------------------------------------ unsigned GetPrime ( unsigned seed ) { return Primes[seed%(sizeof(Primes)/sizeof(Primes[0]))]; } #endif //__TBB_OLD_PRIMES_RNG //------------------------------------------------------------------------ // __TBB_InitOnce //------------------------------------------------------------------------ void __TBB_InitOnce::add_ref() { if( ++count==1 ) governor::acquire_resources(); } void __TBB_InitOnce::remove_ref() { int k = --count; __TBB_ASSERT(k>=0,"removed __TBB_InitOnce ref that was not added?"); if( k==0 ) { governor::release_resources(); ITT_FINI_ITTLIB(); } } //------------------------------------------------------------------------ // One-time Initializations //------------------------------------------------------------------------ //! Defined in cache_aligned_allocator.cpp void initialize_cache_aligned_allocator(); //! Defined in scheduler.cpp void Scheduler_OneTimeInitialization ( bool itt_present ); #if DO_ITT_NOTIFY #if __TBB_ITT_STRUCTURE_API static __itt_domain *fgt_domain = NULL; struct resource_string { const char *str; __itt_string_handle *itt_str_handle; }; // // populate resource strings // #define TBB_STRING_RESOURCE( index_name, str ) { str, NULL }, static resource_string strings_for_itt[] = { #include "tbb/internal/_tbb_strings.h" { "num_resource_strings", NULL } }; #undef TBB_STRING_RESOURCE static __itt_string_handle *ITT_get_string_handle(int idx) { __TBB_ASSERT(idx >= 0, NULL); return idx < NUM_STRINGS ? strings_for_itt[idx].itt_str_handle : NULL; } static void ITT_init_domains() { fgt_domain = __itt_domain_create( _T("tbb.flow") ); fgt_domain->flags = 1; } static void ITT_init_strings() { for ( int i = 0; i < NUM_STRINGS; ++i ) { #if _WIN32||_WIN64 strings_for_itt[i].itt_str_handle = __itt_string_handle_createA( strings_for_itt[i].str ); #else strings_for_itt[i].itt_str_handle = __itt_string_handle_create( strings_for_itt[i].str ); #endif } } static void ITT_init() { ITT_init_domains(); ITT_init_strings(); } #endif // __TBB_ITT_STRUCTURE_API /** Thread-unsafe lazy one-time initialization of tools interop. Used by both dummy handlers and general TBB one-time initialization routine. **/ void ITT_DoUnsafeOneTimeInitialization () { if ( !ITT_InitializationDone ) { ITT_Present = (__TBB_load_ittnotify()!=0); #if __TBB_ITT_STRUCTURE_API if (ITT_Present) ITT_init(); #endif ITT_InitializationDone = true; ITT_SYNC_CREATE(&market::theMarketMutex, SyncType_GlobalLock, SyncObj_SchedulerInitialization); } } /** Thread-safe lazy one-time initialization of tools interop. Used by dummy handlers only. **/ extern "C" void ITT_DoOneTimeInitialization() { __TBB_InitOnce::lock(); ITT_DoUnsafeOneTimeInitialization(); __TBB_InitOnce::unlock(); } #endif /* DO_ITT_NOTIFY */ //! Performs thread-safe lazy one-time general TBB initialization. void DoOneTimeInitializations() { suppress_unused_warning(_pad); __TBB_InitOnce::lock(); // No fence required for load of InitializationDone, because we are inside a critical section. if( !__TBB_InitOnce::InitializationDone ) { __TBB_InitOnce::add_ref(); if( GetBoolEnvironmentVariable("TBB_VERSION") ) PrintVersion(); bool itt_present = false; #if DO_ITT_NOTIFY ITT_DoUnsafeOneTimeInitialization(); itt_present = ITT_Present; #endif /* DO_ITT_NOTIFY */ initialize_cache_aligned_allocator(); governor::initialize_rml_factory(); Scheduler_OneTimeInitialization( itt_present ); // Force processor groups support detection governor::default_num_threads(); // Dump version data governor::print_version_info(); PrintExtraVersionInfo( "Tools support", itt_present ? "enabled" : "disabled" ); __TBB_InitOnce::InitializationDone = true; } __TBB_InitOnce::unlock(); } #if (_WIN32||_WIN64) && !__TBB_SOURCE_DIRECTLY_INCLUDED //! Windows "DllMain" that handles startup and shutdown of dynamic library. extern "C" bool WINAPI DllMain( HANDLE /*hinstDLL*/, DWORD reason, LPVOID /*lpvReserved*/ ) { switch( reason ) { case DLL_PROCESS_ATTACH: __TBB_InitOnce::add_ref(); break; case DLL_PROCESS_DETACH: __TBB_InitOnce::remove_ref(); // It is assumed that InitializationDone is not set after DLL_PROCESS_DETACH, // and thus no race on InitializationDone is possible. if( __TBB_InitOnce::initialization_done() ) { // Remove reference that we added in DoOneTimeInitializations. __TBB_InitOnce::remove_ref(); } break; case DLL_THREAD_DETACH: governor::terminate_auto_initialized_scheduler(); break; } return true; } #endif /* (_WIN32||_WIN64) && !__TBB_SOURCE_DIRECTLY_INCLUDED */ void itt_store_pointer_with_release_v3( void* dst, void* src ) { ITT_NOTIFY(sync_releasing, dst); __TBB_store_with_release(*static_cast(dst),src); } void* itt_load_pointer_with_acquire_v3( const void* src ) { void* result = __TBB_load_with_acquire(*static_cast(src)); ITT_NOTIFY(sync_acquired, const_cast(src)); return result; } #if DO_ITT_NOTIFY void call_itt_notify_v5(int t, void *ptr) { switch (t) { case 0: ITT_NOTIFY(sync_prepare, ptr); break; case 1: ITT_NOTIFY(sync_cancel, ptr); break; case 2: ITT_NOTIFY(sync_acquired, ptr); break; case 3: ITT_NOTIFY(sync_releasing, ptr); break; } } #else void call_itt_notify_v5(int /*t*/, void* /*ptr*/) {} #endif #if __TBB_ITT_STRUCTURE_API #if DO_ITT_NOTIFY const __itt_id itt_null_id = {0, 0, 0}; static inline __itt_domain* get_itt_domain( itt_domain_enum idx ) { return ( idx == ITT_DOMAIN_FLOW ) ? fgt_domain : NULL; } static inline void itt_id_make(__itt_id *id, void* addr, unsigned long long extra) { *id = __itt_id_make(addr, extra); } static inline void itt_id_create(const __itt_domain *domain, __itt_id id) { ITTNOTIFY_VOID_D1(id_create, domain, id); } void itt_make_task_group_v7( itt_domain_enum domain, void *group, unsigned long long group_extra, void *parent, unsigned long long parent_extra, string_index name_index ) { if ( __itt_domain *d = get_itt_domain( domain ) ) { __itt_id group_id = itt_null_id; __itt_id parent_id = itt_null_id; itt_id_make( &group_id, group, group_extra ); itt_id_create( d, group_id ); if ( parent ) { itt_id_make( &parent_id, parent, parent_extra ); } __itt_string_handle *n = ITT_get_string_handle(name_index); ITTNOTIFY_VOID_D3(task_group, d, group_id, parent_id, n); } } void itt_metadata_str_add_v7( itt_domain_enum domain, void *addr, unsigned long long addr_extra, string_index key, const char *value ) { if ( __itt_domain *d = get_itt_domain( domain ) ) { __itt_id id = itt_null_id; itt_id_make( &id, addr, addr_extra ); __itt_string_handle *k = ITT_get_string_handle(key); size_t value_length = strlen( value ); #if _WIN32||_WIN64 ITTNOTIFY_VOID_D4(metadata_str_addA, d, id, k, value, value_length); #else ITTNOTIFY_VOID_D4(metadata_str_add, d, id, k, value, value_length); #endif } } void itt_relation_add_v7( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, itt_relation relation, void *addr1, unsigned long long addr1_extra ) { if ( __itt_domain *d = get_itt_domain( domain ) ) { __itt_id id0 = itt_null_id; __itt_id id1 = itt_null_id; itt_id_make( &id0, addr0, addr0_extra ); itt_id_make( &id1, addr1, addr1_extra ); ITTNOTIFY_VOID_D3(relation_add, d, id0, (__itt_relation)relation, id1); } } void itt_task_begin_v7( itt_domain_enum domain, void *task, unsigned long long task_extra, void *parent, unsigned long long parent_extra, string_index /* name_index */ ) { if ( __itt_domain *d = get_itt_domain( domain ) ) { __itt_id task_id = itt_null_id; __itt_id parent_id = itt_null_id; itt_id_make( &task_id, task, task_extra ); if ( parent ) { itt_id_make( &parent_id, parent, parent_extra ); } ITTNOTIFY_VOID_D3(task_begin, d, task_id, parent_id, NULL ); } } void itt_task_end_v7( itt_domain_enum domain ) { if ( __itt_domain *d = get_itt_domain( domain ) ) { ITTNOTIFY_VOID_D0(task_end, d); } } #else // DO_ITT_NOTIFY void itt_make_task_group_v7( itt_domain_enum domain, void *group, unsigned long long group_extra, void *parent, unsigned long long parent_extra, string_index name_index ) { } void itt_metadata_str_add_v7( itt_domain_enum domain, void *addr, unsigned long long addr_extra, string_index key, const char *value ) { } void itt_relation_add_v7( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, itt_relation relation, void *addr1, unsigned long long addr1_extra ) { } void itt_task_begin_v7( itt_domain_enum domain, void *task, unsigned long long task_extra, void * /*parent*/, unsigned long long /* parent_extra */, string_index /* name_index */ ) { } void itt_task_end_v7( itt_domain_enum domain ) { } #endif // DO_ITT_NOTIFY #endif // __TBB_ITT_STRUCTURE_API void* itt_load_pointer_v3( const void* src ) { //TODO: replace this with __TBB_load_relaxed void* result = *static_cast(src); return result; } void itt_set_sync_name_v3( void* obj, const tchar* name) { ITT_SYNC_RENAME(obj, name); suppress_unused_warning(obj && name); } } // namespace internal } // namespace tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_main.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_tbb_main_H #define _TBB_tbb_main_H #include "tbb/atomic.h" namespace tbb { namespace internal { void DoOneTimeInitializations (); //------------------------------------------------------------------------ // __TBB_InitOnce //------------------------------------------------------------------------ //! Class that supports TBB initialization. /** It handles acquisition and release of global resources (e.g. TLS) during startup and shutdown, as well as synchronization for DoOneTimeInitializations. */ class __TBB_InitOnce { friend void DoOneTimeInitializations(); friend void ITT_DoUnsafeOneTimeInitialization (); static atomic count; //! Platform specific code to acquire resources. static void acquire_resources(); //! Platform specific code to release resources. static void release_resources(); //! Specifies if the one-time initializations has been done. static bool InitializationDone; //! Global initialization lock /** Scenarios are possible when tools interop has to be initialized before the TBB itself. This imposes a requirement that the global initialization lock has to support valid static initialization, and does not issue any tool notifications in any build mode. **/ static __TBB_atomic_flag InitializationLock; public: static void lock() { __TBB_LockByte( InitializationLock ); } static void unlock() { __TBB_UnlockByte( InitializationLock ); } static bool initialization_done() { return __TBB_load_with_acquire(InitializationDone); } //! Add initial reference to resources. /** We assume that dynamic loading of the library prevents any other threads from entering the library until this constructor has finished running. **/ __TBB_InitOnce() { add_ref(); } //! Remove the initial reference to resources. /** This is not necessarily the last reference if other threads are still running. **/ ~__TBB_InitOnce() { remove_ref(); // We assume that InitializationDone is not set after file-scope destructors // start running, and thus no race on InitializationDone is possible. if( initialization_done() ) { // Remove an extra reference that was added in DoOneTimeInitializations. remove_ref(); } } //! Add reference to resources. If first reference added, acquire the resources. static void add_ref(); //! Remove reference to resources. If last reference removed, release the resources. static void remove_ref(); }; // class __TBB_InitOnce } // namespace internal } // namespace tbb #endif /* _TBB_tbb_main_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_misc.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // Source file for miscellaneous entities that are infrequently referenced by // an executing program. #include "tbb/tbb_stddef.h" #include "tbb_assert_impl.h" // Out-of-line TBB assertion handling routines are instantiated here. #include "tbb/tbb_exception.h" #include "tbb/tbb_machine.h" #include "tbb_misc.h" #include #include #include #if _WIN32||_WIN64 #include "tbb/machine/windows_api.h" #endif #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif using namespace std; namespace tbb { const char* bad_last_alloc::what() const throw() { return "bad allocation in previous or concurrent attempt"; } const char* improper_lock::what() const throw() { return "attempted recursive lock on critical section or non-recursive mutex"; } const char* user_abort::what() const throw() { return "User-initiated abort has terminated this operation"; } const char* invalid_multiple_scheduling::what() const throw() { return "The same task_handle object cannot be executed more than once"; } const char* missing_wait::what() const throw() { return "wait() was not called on the structured_task_group"; } namespace internal { #if TBB_USE_EXCEPTIONS #define DO_THROW(exc, init_args) throw exc init_args; #else /* !TBB_USE_EXCEPTIONS */ #define PRINT_ERROR_AND_ABORT(exc_name, msg) \ fprintf (stderr, "Exception %s with message %s would've been thrown, " \ "if exception handling were not disabled. Aborting.\n", exc_name, msg); \ fflush(stderr); \ abort(); #define DO_THROW(exc, init_args) PRINT_ERROR_AND_ABORT(#exc, #init_args) #endif /* !TBB_USE_EXCEPTIONS */ /* The "what" should be fairly short, not more than about 128 characters. Because we control all the call sites to handle_perror, it is pointless to bullet-proof it for very long strings. Design note: ADR put this routine off to the side in tbb_misc.cpp instead of Task.cpp because the throw generates a pathetic lot of code, and ADR wanted this large chunk of code to be placed on a cold page. */ void handle_perror( int error_code, const char* what ) { char buf[256]; #if _MSC_VER #define snprintf _snprintf #endif int written = snprintf(buf, sizeof(buf), "%s: %s", what, strerror( error_code )); // On overflow, the returned value exceeds sizeof(buf) (for GLIBC) or is negative (for MSVC). __TBB_ASSERT_EX( written>0 && written<(int)sizeof(buf), "Error description is too long" ); // Ensure that buffer ends in terminator. buf[sizeof(buf)-1] = 0; #if TBB_USE_EXCEPTIONS throw runtime_error(buf); #else PRINT_ERROR_AND_ABORT( "runtime_error", buf); #endif /* !TBB_USE_EXCEPTIONS */ } #if _WIN32||_WIN64 void handle_win_error( int error_code ) { char buf[512]; #if !__TBB_WIN8UI_SUPPORT FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error_code, 0, buf, sizeof(buf), NULL ); #else //TODO: update with right replacement for FormatMessageA sprintf_s((char*)&buf, 512, "error code %d", error_code); #endif #if TBB_USE_EXCEPTIONS throw runtime_error(buf); #else PRINT_ERROR_AND_ABORT( "runtime_error", buf); #endif /* !TBB_USE_EXCEPTIONS */ } #endif // _WIN32||_WIN64 void throw_bad_last_alloc_exception_v4() { throw_exception_v4(eid_bad_last_alloc); } void throw_exception_v4 ( exception_id eid ) { __TBB_ASSERT ( eid > 0 && eid < eid_max, "Unknown exception ID" ); switch ( eid ) { case eid_bad_alloc: DO_THROW( bad_alloc, () ); case eid_bad_last_alloc: DO_THROW( bad_last_alloc, () ); case eid_nonpositive_step: DO_THROW( invalid_argument, ("Step must be positive") ); case eid_out_of_range: DO_THROW( out_of_range, ("Index out of requested size range") ); case eid_segment_range_error: DO_THROW( range_error, ("Index out of allocated segment slots") ); case eid_index_range_error: DO_THROW( range_error, ("Index is not allocated") ); case eid_missing_wait: DO_THROW( missing_wait, () ); case eid_invalid_multiple_scheduling: DO_THROW( invalid_multiple_scheduling, () ); case eid_improper_lock: DO_THROW( improper_lock, () ); case eid_possible_deadlock: DO_THROW( runtime_error, ("Resource deadlock would occur") ); case eid_operation_not_permitted: DO_THROW( runtime_error, ("Operation not permitted") ); case eid_condvar_wait_failed: DO_THROW( runtime_error, ("Wait on condition variable failed") ); case eid_invalid_load_factor: DO_THROW( out_of_range, ("Invalid hash load factor") ); case eid_reserved: DO_THROW( out_of_range, ("[backward compatibility] Invalid number of buckets") ); case eid_invalid_swap: DO_THROW( invalid_argument, ("swap() is invalid on non-equal allocators") ); case eid_reservation_length_error: DO_THROW( length_error, ("reservation size exceeds permitted max size") ); case eid_invalid_key: DO_THROW( out_of_range, ("invalid key") ); case eid_user_abort: DO_THROW( user_abort, () ); case eid_bad_tagged_msg_cast: DO_THROW( runtime_error, ("Illegal tagged_msg cast") ); #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE case eid_blocking_sch_init: DO_THROW( runtime_error, ("Nesting of blocking termination is impossible") ); #endif default: break; } #if !TBB_USE_EXCEPTIONS && __APPLE__ out_of_range e1(""); length_error e2(""); range_error e3(""); invalid_argument e4(""); #endif /* !TBB_USE_EXCEPTIONS && __APPLE__ */ } #if _XBOX || __TBB_WIN8UI_SUPPORT bool GetBoolEnvironmentVariable( const char * ) { return false;} #else /* _XBOX || __TBB_WIN8UI_SUPPORT */ bool GetBoolEnvironmentVariable( const char * name ) { if( const char* s = getenv(name) ) return strcmp(s,"0") != 0; return false; } #endif /* _XBOX || __TBB_WIN8UI_SUPPORT */ #include "tbb_version.h" /** The leading "\0" is here so that applying "strings" to the binary delivers a clean result. */ static const char VersionString[] = "\0" TBB_VERSION_STRINGS; static bool PrintVersionFlag = false; void PrintVersion() { PrintVersionFlag = true; fputs(VersionString+1,stderr); } void PrintExtraVersionInfo( const char* category, const char* format, ... ) { if( PrintVersionFlag ) { char str[1024]; memset(str, 0, 1024); va_list args; va_start(args, format); // Note: correct vsnprintf definition obtained from tbb_assert_impl.h vsnprintf( str, 1024-1, format, args); va_end(args); fprintf(stderr, "TBB: %s\t%s\n", category, str ); } } void PrintRMLVersionInfo( void* arg, const char* server_info ) { PrintExtraVersionInfo( server_info, (const char *)arg ); } //! check for transaction support. #if _MSC_VER #include // for __cpuid #endif bool cpu_has_speculation() { #if __TBB_TSX_AVAILABLE #if (__INTEL_COMPILER || __GNUC__ || _MSC_VER || __SUNPRO_CC) bool result = false; const int hle_ebx_mask = 1<<4; #if _MSC_VER int info[4] = {0,0,0,0}; const int reg_ebx = 1; __cpuidex(info, 7, 0); result = (info[reg_ebx] & hle_ebx_mask)!=0; #elif __GNUC__ || __SUNPRO_CC int32_t reg_ebx = 0; int32_t reg_eax = 7; int32_t reg_ecx = 0; __asm__ __volatile__ ( "movl %%ebx, %%esi\n" "cpuid\n" "movl %%ebx, %0\n" "movl %%esi, %%ebx\n" : "=a"(reg_ebx) : "0" (reg_eax), "c" (reg_ecx) : "esi", #if __TBB_x86_64 "ebx", #endif "edx" ); result = (reg_ebx & hle_ebx_mask)!=0 ; #endif return result; #else #error Speculation detection not enabled for compiler #endif /* __INTEL_COMPILER || __GNUC__ || _MSC_VER */ #else /* __TBB_TSX_AVAILABLE */ return false; #endif /* __TBB_TSX_AVAILABLE */ } } // namespace internal extern "C" int TBB_runtime_interface_version() { return TBB_INTERFACE_VERSION; } } // namespace tbb #if !__TBB_RML_STATIC #if __TBB_x86_32 #include "tbb/atomic.h" // in MSVC environment, int64_t defined in tbb::internal namespace only (see tbb_stddef.h) #if _MSC_VER using tbb::internal::int64_t; #endif //! Warn about 8-byte store that crosses a cache line. extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr ) { // Report run-time warning unless we have already recently reported warning for that address. const unsigned n = 4; static tbb::atomic cache[n]; static tbb::atomic k; for( unsigned i=0; i(ptr); tbb::internal::runtime_warning( "atomic store on misaligned 8-byte location %p is slow", ptr ); done:; } //! Handle 8-byte store that crosses a cache line. extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value ) { for( tbb::internal::atomic_backoff b;;b.pause() ) { int64_t tmp = *(int64_t*)ptr; if( __TBB_machine_cmpswp8(ptr,value,tmp)==tmp ) break; } } #endif /* __TBB_x86_32 */ #endif /* !__TBB_RML_STATIC */ #if __TBB_ipf /* It was found that on IA-64 architecture inlining of __TBB_machine_lockbyte leads to serious performance regression with ICC. So keep it out-of-line. */ extern "C" intptr_t __TBB_machine_lockbyte( volatile unsigned char& flag ) { tbb::internal::atomic_backoff backoff; while( !__TBB_TryLockByte(flag) ) backoff.pause(); return 0; } #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_misc.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_tbb_misc_H #define _TBB_tbb_misc_H #include "tbb/tbb_stddef.h" #include "tbb/tbb_machine.h" #include "tbb/atomic.h" // For atomic_xxx definitions #if __linux__ || __FreeBSD__ #include // __FreeBSD_version #if __FreeBSD_version >= 701000 #include #endif #endif // Does the operating system have a system call to pin a thread to a set of OS processors? #define __TBB_OS_AFFINITY_SYSCALL_PRESENT ((__linux__ && !__ANDROID__) || (__FreeBSD_version >= 701000)) // On IBM* Blue Gene* CNK nodes, the affinity API has restrictions that prevent its usability for TBB, // and also sysconf(_SC_NPROCESSORS_ONLN) already takes process affinity into account. #define __TBB_USE_OS_AFFINITY_SYSCALL (__TBB_OS_AFFINITY_SYSCALL_PRESENT && !__bg__) namespace tbb { namespace internal { const size_t MByte = 1024*1024; #if __TBB_WIN8UI_SUPPORT // In Win8UI mode, TBB uses a thread creation API that does not allow to specify the stack size. // Still, the thread stack size value, either explicit or default, is used by the scheduler. // So here we set the default value to match the platform's default of 1MB. const size_t ThreadStackSize = 1*MByte; #else const size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte; #endif #ifndef __TBB_HardwareConcurrency //! Returns maximal parallelism level supported by the current OS configuration. int AvailableHwConcurrency(); #else inline int AvailableHwConcurrency() { int n = __TBB_HardwareConcurrency(); return n > 0 ? n : 1; // Fail safety strap } #endif /* __TBB_HardwareConcurrency */ #if _WIN32||_WIN64 //! Returns number of processor groups in the current OS configuration. /** AvailableHwConcurrency must be called at least once before calling this method. **/ int NumberOfProcessorGroups(); //! Retrieves index of processor group containing processor with the given index int FindProcessorGroupIndex ( int processorIndex ); //! Affinitizes the thread to the specified processor group void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex ); #endif /* _WIN32||_WIN64 */ //! Throws std::runtime_error with what() returning error_code description prefixed with aux_info void handle_win_error( int error_code ); //! True if environment variable with given name is set and not 0; otherwise false. bool GetBoolEnvironmentVariable( const char * name ); //! Prints TBB version information on stderr void PrintVersion(); //! Prints arbitrary extra TBB version information on stderr void PrintExtraVersionInfo( const char* category, const char* format, ... ); //! A callback routine to print RML version information on stderr void PrintRMLVersionInfo( void* arg, const char* server_info ); // For TBB compilation only; not to be used in public headers #if defined(min) || defined(max) #undef min #undef max #endif //! Utility template function returning lesser of the two values. /** Provided here to avoid including not strict safe .\n In case operands cause signed/unsigned or size mismatch warnings it is caller's responsibility to do the appropriate cast before calling the function. **/ template T1 min ( const T1& val1, const T2& val2 ) { return val1 < val2 ? val1 : val2; } //! Utility template function returning greater of the two values. /** Provided here to avoid including not strict safe .\n In case operands cause signed/unsigned or size mismatch warnings it is caller's responsibility to do the appropriate cast before calling the function. **/ template T1 max ( const T1& val1, const T2& val2 ) { return val1 < val2 ? val2 : val1; } //! Utility helper structure to ease overload resolution template struct int_to_type {}; //------------------------------------------------------------------------ // FastRandom //------------------------------------------------------------------------ /** Defined in tbb_main.cpp **/ unsigned GetPrime ( unsigned seed ); //! A fast random number generator. /** Uses linear congruential method. */ class FastRandom { private: #if __TBB_OLD_PRIMES_RNG unsigned x, a; static const unsigned c = 1; #else unsigned x, c; static const unsigned a = 0x9e3779b1; // a big prime number #endif //__TBB_OLD_PRIMES_RNG public: //! Get a random number. unsigned short get() { return get(x); } //! Get a random number for the given seed; update the seed for next use. unsigned short get( unsigned& seed ) { unsigned short r = (unsigned short)(seed>>16); __TBB_ASSERT(c&1, "c must be odd for big rng period"); seed = seed*a+c; return r; } //! Construct a random number generator. FastRandom( void* unique_ptr ) { init(uintptr_t(unique_ptr)); } FastRandom( uint32_t seed) { init(seed); } FastRandom( uint64_t seed) { init(seed); } template void init( T seed ) { init(seed,int_to_type()); } void init( uint64_t seed , int_to_type<8> ) { init(uint32_t((seed>>32)+seed), int_to_type<4>()); } void init( uint32_t seed, int_to_type<4> ) { #if __TBB_OLD_PRIMES_RNG x = seed; a = GetPrime( seed ); #else // threads use different seeds for unique sequences c = (seed|1)*0xba5703f5; // c must be odd, shuffle by a prime number x = c^(seed>>1); // also shuffle x for the first get() invocation #endif } }; //------------------------------------------------------------------------ // Atomic extensions //------------------------------------------------------------------------ //! Atomically replaces value of dst with newValue if they satisfy condition of compare predicate /** Return value semantics is the same as for CAS. **/ template T1 atomic_update ( tbb::atomic& dst, T2 newValue, Pred compare ) { T1 oldValue = dst; while ( compare(oldValue, newValue) ) { if ( dst.compare_and_swap((T1)newValue, oldValue) == oldValue ) break; oldValue = dst; } return oldValue; } //! One-time initialization states enum do_once_state { do_once_uninitialized = 0, ///< No execution attempts have been undertaken yet do_once_pending, ///< A thread is executing associated do-once routine do_once_executed, ///< Do-once routine has been executed initialization_complete = do_once_executed ///< Convenience alias }; //! One-time initialization function /** /param initializer Pointer to function without arguments The variant that returns bool is used for cases when initialization can fail and it is OK to continue execution, but the state should be reset so that the initialization attempt was repeated the next time. /param state Shared state associated with initializer that specifies its initialization state. Must be initially set to #uninitialized value (e.g. by means of default static zero initialization). **/ template void atomic_do_once ( const F& initializer, atomic& state ) { // tbb::atomic provides necessary acquire and release fences. // The loop in the implementation is necessary to avoid race when thread T2 // that arrived in the middle of initialization attempt by another thread T1 // has just made initialization possible. // In such a case T2 has to rely on T1 to initialize, but T1 may already be past // the point where it can recognize the changed conditions. while ( state != do_once_executed ) { if( state == do_once_uninitialized ) { if( state.compare_and_swap( do_once_pending, do_once_uninitialized ) == do_once_uninitialized ) { run_initializer( initializer, state ); break; } } spin_wait_while_eq( state, do_once_pending ); } } // Run the initializer which can not fail inline void run_initializer( void (*f)(), atomic& state ) { f(); state = do_once_executed; } // Run the initializer which can require repeated call inline void run_initializer( bool (*f)(), atomic& state ) { state = f() ? do_once_executed : do_once_uninitialized; } #if __TBB_USE_OS_AFFINITY_SYSCALL #if __linux__ typedef cpu_set_t basic_mask_t; #elif __FreeBSD_version >= 701000 typedef cpuset_t basic_mask_t; #else #error affinity_helper is not implemented in this OS #endif class affinity_helper : no_copy { basic_mask_t* threadMask; int is_changed; public: affinity_helper() : threadMask(NULL), is_changed(0) {} ~affinity_helper(); void protect_affinity_mask(); }; #else class affinity_helper : no_copy { public: void protect_affinity_mask() {} }; #endif /* __TBB_USE_OS_AFFINITY_SYSCALL */ extern bool cpu_has_speculation(); } // namespace internal } // namespace tbb #endif /* _TBB_tbb_misc_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_misc_ex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // Source file for miscellaneous entities that are infrequently referenced by // an executing program, and implementation of which requires dynamic linking. #include "tbb_misc.h" #if !defined(__TBB_HardwareConcurrency) #include "dynamic_link.h" #include #include #if _WIN32||_WIN64 #include "tbb/machine/windows_api.h" #if __TBB_WIN8UI_SUPPORT #include #endif #else #include #if __linux__ #include #include #include #include #elif __sun #include #elif __FreeBSD__ #include #include #include // Required by #include #endif #endif namespace tbb { namespace internal { #if __TBB_USE_OS_AFFINITY_SYSCALL static void set_affinity_mask( size_t maskSize, const basic_mask_t* threadMask ) { #if __linux__ if( sched_setaffinity( 0, maskSize, threadMask ) ) #else /* FreeBSD */ if( cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, maskSize, threadMask ) ) #endif runtime_warning( "setaffinity syscall failed" ); } static void get_affinity_mask( size_t maskSize, basic_mask_t* threadMask ) { #if __linux__ if( sched_getaffinity( 0, maskSize, threadMask ) ) #else /* FreeBSD */ if( cpuset_getaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, maskSize, threadMask ) ) #endif runtime_warning( "getaffinity syscall failed" ); } static basic_mask_t* process_mask; static int num_masks; struct process_mask_cleanup_helper { ~process_mask_cleanup_helper() { if( process_mask ) { delete [] process_mask; } } }; static process_mask_cleanup_helper process_mask_cleanup; #define curMaskSize sizeof(basic_mask_t) * num_masks affinity_helper::~affinity_helper() { if( threadMask ) { if( is_changed ) { set_affinity_mask( curMaskSize, threadMask ); } delete [] threadMask; } } void affinity_helper::protect_affinity_mask() { if( threadMask == NULL && num_masks && process_mask ) { threadMask = new basic_mask_t [num_masks]; memset( threadMask, 0, curMaskSize ); get_affinity_mask( curMaskSize, threadMask ); is_changed = memcmp( process_mask, threadMask, curMaskSize ); if( is_changed ) { set_affinity_mask( curMaskSize, process_mask ); } } } #undef curMaskSize static atomic hardware_concurrency_info; static int theNumProcs; static void initialize_hardware_concurrency_info () { int err; int availableProcs = 0; int numMasks = 1; #if __linux__ #if __TBB_MAIN_THREAD_AFFINITY_BROKEN int maxProcs = INT_MAX; // To check the entire mask. int pid = 0; // Get the mask of the calling thread. #else int maxProcs = sysconf(_SC_NPROCESSORS_ONLN); int pid = getpid(); #endif cpu_set_t *processMask; const size_t BasicMaskSize = sizeof(cpu_set_t); for (;;) { int curMaskSize = BasicMaskSize * numMasks; processMask = new cpu_set_t[numMasks]; memset( processMask, 0, curMaskSize ); err = sched_getaffinity( pid, curMaskSize, processMask ); if ( !err || errno != EINVAL || curMaskSize * CHAR_BIT >= 256 * 1024 ) break; delete[] processMask; numMasks <<= 1; } #else /* FreeBSD >= 7.1 */ int maxProcs = sysconf(_SC_NPROCESSORS_ONLN); cpuset_t *processMask; const size_t BasicMaskSize = sizeof(cpuset_t); for (;;) { int curMaskSize = BasicMaskSize * numMasks; processMask = new cpuset_t[numMasks]; memset( processMask, 0, curMaskSize ); // CPU_LEVEL_WHICH - anonymous (current) mask, CPU_LEVEL_CPUSET - assigned mask #if __TBB_MAIN_THREAD_AFFINITY_BROKEN err = cpuset_getaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, curMaskSize, processMask ); #else err = cpuset_getaffinity( CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, curMaskSize, processMask ); #endif if ( !err || errno != ERANGE || curMaskSize * CHAR_BIT >= 16 * 1024 ) break; delete[] processMask; numMasks <<= 1; } #endif /* FreeBSD >= 7.1 */ if ( !err ) { for ( int m = 0; availableProcs < maxProcs && m < numMasks; ++m ) { for ( size_t i = 0; (availableProcs < maxProcs) && (i < BasicMaskSize * CHAR_BIT); ++i ) { if ( CPU_ISSET( i, processMask + m ) ) ++availableProcs; } } num_masks = numMasks; process_mask = processMask; } else { availableProcs = (maxProcs == INT_MAX) ? sysconf(_SC_NPROCESSORS_ONLN) : maxProcs; delete[] processMask; } theNumProcs = availableProcs > 0 ? availableProcs : 1; // Fail safety strap __TBB_ASSERT( theNumProcs <= sysconf(_SC_NPROCESSORS_ONLN), NULL ); } int AvailableHwConcurrency() { atomic_do_once( &initialize_hardware_concurrency_info, hardware_concurrency_info ); return theNumProcs; } #elif __ANDROID__ // Work-around for Android that reads the correct number of available CPUs since system calls are unreliable. // Format of "present" file is: ([-|],)+ int AvailableHwConcurrency() { FILE *fp = fopen("/sys/devices/system/cpu/present", "r"); if (fp == NULL) return 1; int num_args, lower, upper, num_cpus=0; while ((num_args = fscanf(fp, "%u-%u", &lower, &upper)) != EOF) { switch(num_args) { case 2: num_cpus += upper - lower + 1; break; case 1: num_cpus += 1; break; } fscanf(fp, ","); } return (num_cpus > 0) ? num_cpus : 1; } #elif defined(_SC_NPROCESSORS_ONLN) int AvailableHwConcurrency() { int n = sysconf(_SC_NPROCESSORS_ONLN); return (n > 0) ? n : 1; } #elif _WIN32||_WIN64 static atomic hardware_concurrency_info; static const WORD TBB_ALL_PROCESSOR_GROUPS = 0xffff; // Statically allocate an array for processor group information. // Windows 7 supports maximum 4 groups, but let's look ahead a little. static const WORD MaxProcessorGroups = 64; struct ProcessorGroupInfo { DWORD_PTR mask; ///< Affinity mask covering the whole group int numProcs; ///< Number of processors in the group int numProcsRunningTotal; ///< Subtotal of processors in this and preceding groups //! Total number of processor groups in the system static int NumGroups; //! Index of the group with a slot reserved for the first master thread /** In the context of multiple processor groups support current implementation defines "the first master thread" as the first thread to invoke AvailableHwConcurrency(). TODO: Implement a dynamic scheme remapping workers depending on the pending master threads affinity. **/ static int HoleIndex; }; int ProcessorGroupInfo::NumGroups = 1; int ProcessorGroupInfo::HoleIndex = 0; ProcessorGroupInfo theProcessorGroups[MaxProcessorGroups]; struct TBB_GROUP_AFFINITY { DWORD_PTR Mask; WORD Group; WORD Reserved[3]; }; static DWORD (WINAPI *TBB_GetActiveProcessorCount)( WORD groupIndex ) = NULL; static WORD (WINAPI *TBB_GetActiveProcessorGroupCount)() = NULL; static BOOL (WINAPI *TBB_SetThreadGroupAffinity)( HANDLE hThread, const TBB_GROUP_AFFINITY* newAff, TBB_GROUP_AFFINITY *prevAff ); static BOOL (WINAPI *TBB_GetThreadGroupAffinity)( HANDLE hThread, TBB_GROUP_AFFINITY* ); static const dynamic_link_descriptor ProcessorGroupsApiLinkTable[] = { DLD(GetActiveProcessorCount, TBB_GetActiveProcessorCount) , DLD(GetActiveProcessorGroupCount, TBB_GetActiveProcessorGroupCount) , DLD(SetThreadGroupAffinity, TBB_SetThreadGroupAffinity) , DLD(GetThreadGroupAffinity, TBB_GetThreadGroupAffinity) }; static void initialize_hardware_concurrency_info () { #if __TBB_WIN8UI_SUPPORT // For these applications processor groups info is unavailable // Setting up a number of processors for one processor group theProcessorGroups[0].numProcs = theProcessorGroups[0].numProcsRunningTotal = std::thread::hardware_concurrency(); #else /* __TBB_WIN8UI_SUPPORT */ dynamic_link( "Kernel32.dll", ProcessorGroupsApiLinkTable, sizeof(ProcessorGroupsApiLinkTable)/sizeof(dynamic_link_descriptor) ); SYSTEM_INFO si; GetNativeSystemInfo(&si); DWORD_PTR pam, sam, m = 1; GetProcessAffinityMask( GetCurrentProcess(), &pam, &sam ); int nproc = 0; for ( size_t i = 0; i < sizeof(DWORD_PTR) * CHAR_BIT; ++i, m <<= 1 ) { if ( pam & m ) ++nproc; } __TBB_ASSERT( nproc <= (int)si.dwNumberOfProcessors, NULL ); // By default setting up a number of processors for one processor group theProcessorGroups[0].numProcs = theProcessorGroups[0].numProcsRunningTotal = nproc; // Setting up processor groups in case the process does not restrict affinity mask and more than one processor group is present if ( nproc == (int)si.dwNumberOfProcessors && TBB_GetActiveProcessorCount ) { // The process does not have restricting affinity mask and multiple processor groups are possible ProcessorGroupInfo::NumGroups = (int)TBB_GetActiveProcessorGroupCount(); __TBB_ASSERT( ProcessorGroupInfo::NumGroups <= MaxProcessorGroups, NULL ); // Fail safety bootstrap. Release versions will limit available concurrency // level, while debug ones would assert. if ( ProcessorGroupInfo::NumGroups > MaxProcessorGroups ) ProcessorGroupInfo::NumGroups = MaxProcessorGroups; if ( ProcessorGroupInfo::NumGroups > 1 ) { TBB_GROUP_AFFINITY ga; if ( TBB_GetThreadGroupAffinity( GetCurrentThread(), &ga ) ) ProcessorGroupInfo::HoleIndex = ga.Group; int nprocs = 0; for ( WORD i = 0; i < ProcessorGroupInfo::NumGroups; ++i ) { ProcessorGroupInfo &pgi = theProcessorGroups[i]; pgi.numProcs = (int)TBB_GetActiveProcessorCount(i); __TBB_ASSERT( pgi.numProcs <= (int)sizeof(DWORD_PTR) * CHAR_BIT, NULL ); pgi.mask = pgi.numProcs == sizeof(DWORD_PTR) * CHAR_BIT ? ~(DWORD_PTR)0 : (DWORD_PTR(1) << pgi.numProcs) - 1; pgi.numProcsRunningTotal = nprocs += pgi.numProcs; } __TBB_ASSERT( nprocs == (int)TBB_GetActiveProcessorCount( TBB_ALL_PROCESSOR_GROUPS ), NULL ); } } #endif /* __TBB_WIN8UI_SUPPORT */ PrintExtraVersionInfo("Processor groups", "%d", ProcessorGroupInfo::NumGroups); if (ProcessorGroupInfo::NumGroups>1) for (int i=0; i= numProcs - 1 ) { holeIdx = INT_MAX; procIdx = (procIdx - numProcs + 1) % numProcs; } else holeIdx = ProcessorGroupInfo::HoleIndex; __TBB_ASSERT( hardware_concurrency_info == initialization_complete, "FindProcessorGroupIndex is used before AvailableHwConcurrency" ); // Approximate the likely group index assuming all groups are of the same size int i = procIdx / theProcessorGroups[0].numProcs; // Make sure the approximation is a valid group index if (i >= ProcessorGroupInfo::NumGroups) i = ProcessorGroupInfo::NumGroups-1; // Now adjust the approximation up or down if ( theProcessorGroups[i].numProcsRunningTotal > HoleAdjusted(procIdx, i) ) { while ( theProcessorGroups[i].numProcsRunningTotal - theProcessorGroups[i].numProcs > HoleAdjusted(procIdx, i) ) { __TBB_ASSERT( i > 0, NULL ); --i; } } else { do { ++i; } while ( theProcessorGroups[i].numProcsRunningTotal <= HoleAdjusted(procIdx, i) ); } __TBB_ASSERT( i < ProcessorGroupInfo::NumGroups, NULL ); return i; } void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex ) { __TBB_ASSERT( hardware_concurrency_info == initialization_complete, "MoveThreadIntoProcessorGroup is used before AvailableHwConcurrency" ); if ( !TBB_SetThreadGroupAffinity ) return; TBB_GROUP_AFFINITY ga = { theProcessorGroups[groupIndex].mask, (WORD)groupIndex, {0,0,0} }; TBB_SetThreadGroupAffinity( hThread, &ga, NULL ); } #else #error AvailableHwConcurrency is not implemented in this OS #endif /* OS */ } // namespace internal } // namespace tbb #endif /* !__TBB_HardwareConcurrency */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_profiling.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_profiling_H #define __TBB_profiling_H namespace tbb { namespace internal { // // This is not under __TBB_ITT_STRUCTURE_API because these values are used directly in flow_graph.h. // // include list of index names #define TBB_STRING_RESOURCE(index_name,str) index_name, enum string_index { #include "internal/_tbb_strings.h" NUM_STRINGS }; #undef TBB_STRING_RESOURCE enum itt_relation { __itt_relation_is_unknown = 0, __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */ __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */ __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */ __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */ __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */ __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */ __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */ }; } } // Check if the tools support is enabled #if (_WIN32||_WIN64||__linux__) && !__MINGW32__ && TBB_USE_THREADING_TOOLS #if _WIN32||_WIN64 #include /* mbstowcs_s */ #endif #include "tbb_stddef.h" namespace tbb { namespace internal { #if _WIN32||_WIN64 void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const wchar_t* name ); inline size_t multibyte_to_widechar( wchar_t* wcs, const char* mbs, size_t bufsize) { #if _MSC_VER>=1400 size_t len; mbstowcs_s( &len, wcs, bufsize, mbs, _TRUNCATE ); return len; // mbstowcs_s counts null terminator #else size_t len = mbstowcs( wcs, mbs, bufsize ); if(wcs && len!=size_t(-1) ) wcs[len inline void itt_store_word_with_release(tbb::atomic& dst, U src) { #if TBB_USE_THREADING_TOOLS // This assertion should be replaced with static_assert __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); itt_store_pointer_with_release_v3(&dst, (void *)uintptr_t(src)); #else dst = src; #endif // TBB_USE_THREADING_TOOLS } template inline T itt_load_word_with_acquire(const tbb::atomic& src) { #if TBB_USE_THREADING_TOOLS // This assertion should be replaced with static_assert __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings #pragma warning (push) #pragma warning (disable: 4311) #endif T result = (T)itt_load_pointer_with_acquire_v3(&src); #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif return result; #else return src; #endif // TBB_USE_THREADING_TOOLS } template inline void itt_store_word_with_release(T& dst, T src) { #if TBB_USE_THREADING_TOOLS // This assertion should be replaced with static_assert __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); itt_store_pointer_with_release_v3(&dst, (void *)src); #else __TBB_store_with_release(dst, src); #endif // TBB_USE_THREADING_TOOLS } template inline T itt_load_word_with_acquire(const T& src) { #if TBB_USE_THREADING_TOOLS // This assertion should be replaced with static_assert __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized"); return (T)itt_load_pointer_with_acquire_v3(&src); #else return __TBB_load_with_acquire(src); #endif // TBB_USE_THREADING_TOOLS } template inline void itt_hide_store_word(T& dst, T src) { #if TBB_USE_THREADING_TOOLS //TODO: This assertion should be replaced with static_assert __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized"); itt_store_pointer_with_release_v3(&dst, (void *)src); #else dst = src; #endif } //TODO: rename to itt_hide_load_word_relaxed template inline T itt_hide_load_word(const T& src) { #if TBB_USE_THREADING_TOOLS //TODO: This assertion should be replaced with static_assert __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); return (T)itt_load_pointer_v3(&src); #else return src; #endif } #if TBB_USE_THREADING_TOOLS inline void call_itt_notify(notify_type t, void *ptr) { call_itt_notify_v5((int)t, ptr); } #else inline void call_itt_notify(notify_type /*t*/, void * /*ptr*/) {} #endif // TBB_USE_THREADING_TOOLS #if __TBB_ITT_STRUCTURE_API inline void itt_make_task_group( itt_domain_enum domain, void *group, unsigned long long group_extra, void *parent, unsigned long long parent_extra, string_index name_index ) { itt_make_task_group_v7( domain, group, group_extra, parent, parent_extra, name_index ); } inline void itt_metadata_str_add( itt_domain_enum domain, void *addr, unsigned long long addr_extra, string_index key, const char *value ) { itt_metadata_str_add_v7( domain, addr, addr_extra, key, value ); } inline void itt_relation_add( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, itt_relation relation, void *addr1, unsigned long long addr1_extra ) { itt_relation_add_v7( domain, addr0, addr0_extra, relation, addr1, addr1_extra ); } inline void itt_task_begin( itt_domain_enum domain, void *task, unsigned long long task_extra, void *parent, unsigned long long parent_extra, string_index name_index ) { itt_task_begin_v7( domain, task, task_extra, parent, parent_extra, name_index ); } inline void itt_task_end( itt_domain_enum domain ) { itt_task_end_v7( domain ); } #endif // __TBB_ITT_STRUCTURE_API } // namespace internal } // namespace tbb #endif /* __TBB_profiling_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_resource.rc ================================================ // Copyright 2005-2014 Intel Corporation. All Rights Reserved. // // This file is part of Threading Building Blocks. Threading Building Blocks is free software; // you can redistribute it and/or modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. Threading Building Blocks is // distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. You should have received a copy of // the GNU General Public License along with Threading Building Blocks; if not, write to the // Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // As a special exception, you may use this file as part of a free software library without // restriction. Specifically, if other files instantiate templates or use macros or inline // functions from this file, or you compile this file and link it with other files to produce // an executable, this file does not by itself cause the resulting executable to be covered // by the GNU General Public License. This exception does not however invalidate any other // reasons why the executable file might be covered by the GNU General Public License. // Microsoft Visual C++ generated resource script. // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include #define ENDL "\r\n" #include "tbb_version.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // Neutral resources //#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) #ifdef _WIN32 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // manifest integration #ifdef TBB_MANIFEST #include "winuser.h" 2 RT_MANIFEST tbbmanifest.exe.manifest #endif ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION TBB_VERNUMBERS PRODUCTVERSION TBB_VERNUMBERS FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "000004b0" BEGIN VALUE "CompanyName", "Intel Corporation\0" VALUE "FileDescription", "Intel(R) Threading Building Blocks library\0" VALUE "FileVersion", TBB_VERSION "\0" VALUE "LegalCopyright", "Copyright 2005-2014 Intel Corporation. All Rights Reserved.\0" VALUE "LegalTrademarks", "\0" #ifndef TBB_USE_DEBUG VALUE "OriginalFilename", "tbb.dll\0" #else VALUE "OriginalFilename", "tbb_debug.dll\0" #endif VALUE "ProductName", "Intel(R) Threading Building Blocks for Windows\0" VALUE "ProductVersion", TBB_VERSION "\0" VALUE "PrivateBuild", "\0" VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0, 1200 END END //#endif // Neutral resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_statistics.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb_statistics.h" #if __TBB_STATISTICS #include #include #if __TBB_STATISTICS_STDOUT #include #endif #include "tbb/spin_mutex.h" namespace tbb { namespace internal { //! Human readable titles of statistics groups defined by statistics_groups enum. /** The order of this vector elements must correspond to the statistics_counters structure layout. **/ const char* StatGroupTitles[] = { "task objects", "tasks executed", "stealing attempts", "task proxies", "arena", "market", "priority ops", "prio ops details" }; //! Human readable titles of statistics elements defined by statistics_counters struct. /** The order of this vector elements must correspond to the statistics_counters structure layout (with NULLs interspersed to separate groups). **/ const char* StatFieldTitles[] = { /*task objects*/ "active", "freed", "big", NULL, /*tasks executed*/ "total", "w/o spawn", NULL, /*stealing attempts*/ "succeeded", "failed", "conflicts", "backoffs", NULL, /*task proxies*/ "mailed", "revoked", "stolen", "bypassed", "ignored", NULL, /*arena*/ "switches", "roundtrips", "avg.conc", "avg.allot", NULL, /*market*/ "roundtrips", NULL, /*priority ops*/ "ar.switch", "mkt.switch", "ar.reset", "ref.fixup", "avg.ar.pr", "avg.mkt.pr", NULL, /*prio ops details*/ "winnows", "reloads", "orphaned", "winnowed", "reloaded", NULL }; //! Class for logging statistics /** There should be only one instance of this class. Results are written to a file "statistics.txt" in tab-separated format. */ class statistics_logger { public: statistics_logger () { __TBB_ASSERT( sg_end - 1 == 1 << (sizeof(StatGroupTitles)/sizeof(*StatGroupTitles) - 1), NULL ); my_file = fopen("statistics.txt","w"); if( !my_file ) perror("fopen(\"statistics.txt\"\")"); // Initialize groups dump layout info group_start_field[0] = 0; for ( size_t i = 0, j = 0; i < NumGroups; ++i, ++j ) { __TBB_ASSERT( StatFieldTitles[j], "Empty group occurred" ); while ( StatFieldTitles[j] ) ++j; group_start_field[i + 1] = j - i; // -i accounts for preceding NULL separators } __TBB_ASSERT( group_start_field[NumGroups] == statistics_counters::size(), "Wrong number of elements in StatFieldTitles" ); dump( "%-*s", IDColumnWidth, ""); process_groups( &statistics_logger::print_group_title ); dump( "%-*s", IDColumnWidth, "ID"); process_groups( &statistics_logger::print_field_titles ); } ~statistics_logger () { fclose(my_file); } void record( const statistics_counters& c, size_t id ) { spin_mutex::scoped_lock lock(my_mutex); counters_to_dump = &c; #if __TBB_STATISTICS_TOTALS_ONLY if ( id == arena_counters_total ) { dump( "%-*s", IDColumnWidth, "Tot" ); process_groups( &statistics_logger::print_field_values ); } #else /* !__TBB_STATISTICS_TOTALS_ONLY */ const char* idString = NULL; switch ( id ) { case 0: idString = "M"; break; case workers_counters_total: idString = "Wtot"; break; case arena_counters_total: idString = "Tot"; break; default: dump( "W%-*u", IDColumnWidth - 1, id ); } if ( idString ) dump( "%-*s", IDColumnWidth, idString ); process_groups( &statistics_logger::print_field_values ); #endif /* !__TBB_STATISTICS_TOTALS_ONLY */ } private: static const size_t IDColumnWidth = 5; static const size_t StatisticsColumnWidth = 10; static const size_t NumGroups = sizeof(StatGroupTitles)/sizeof(char*); //! File into which statistics are written. FILE* my_file; //! Mutex that serializes accesses to my_file spin_mutex my_mutex; //! Indices of the each group's first field in statistics_counters struct. /** An extra element is used to track the total number of statistics fields. **/ size_t group_start_field[NumGroups + 1]; //! Currently processed set of counters. const statistics_counters* counters_to_dump; static const size_t NumFields = sizeof(StatFieldTitles)/sizeof(*StatFieldTitles) - NumGroups; bool averages_fields[NumFields]; void dump ( char const* fmt, ... ) { va_list args; if ( my_file ) { va_start( args, fmt ); vfprintf( my_file, fmt, args ); va_end( args ); } #if __TBB_STATISTICS_STDOUT va_start( args, fmt ); vprintf( fmt, args ); va_end( args ); #endif } void process_groups ( void (statistics_logger::*per_group_action)(size_t group_idx) ) { for ( size_t i = 0, group_flag = 1; i < NumGroups; ++i, group_flag <<= 1 ) { __TBB_ASSERT( group_flag < sg_end, "StatGroupTitles contents is incompatible with statistics_groups definition" ); if ( __TBB_ActiveStatisticsGroups & group_flag ) (this->*per_group_action)( i ); } dump( "\n" ); } void print_group_title ( size_t group_idx ) { dump( "%-*s", (group_start_field[group_idx + 1] - group_start_field[group_idx]) * (StatisticsColumnWidth + 1), StatGroupTitles[group_idx] ); } void print_field_titles ( size_t group_idx ) { // +group_idx accounts for preceding NULL separators size_t i = group_start_field[group_idx] + group_idx; while ( StatFieldTitles[i] ) { averages_fields[i - group_idx] = strncmp(StatFieldTitles[i], "avg.", 4) == 0; dump( "%-*s ", StatisticsColumnWidth, StatFieldTitles[i++] ); } } void print_field_values ( size_t group_idx ) { size_t begin = group_start_field[group_idx], end = group_start_field[group_idx + 1]; for ( size_t i = begin; i < end; ++i ) { if ( averages_fields[i] ) dump( "%-*.2f ", StatisticsColumnWidth, (double)counters_to_dump->field(i)/counters_to_dump->tasks_executed ); else dump( "%-*ld ", StatisticsColumnWidth, counters_to_dump->field(i) ); } } }; // class statistics_logger static statistics_logger the_statistics; void dump_statistics ( const statistics_counters& c, size_t id ) { the_statistics.record(c, id); } } // namespace internal } // namespace tbb #endif /* __TBB_STATISTICS */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_statistics.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_tbb_statistics_H #define _TBB_tbb_statistics_H /** This file defines parameters of the internal statistics collected by the TBB library (currently by the task scheduler only). Statistics is accumulated separately in each thread and is dumped when the scheduler instance associated with the given thread is destroyed. For apps with multiple master threads or with the same master repeatedly initializing and then deinitializing task scheduler this results in TBB workers statistics getting inseparably mixed. Therefore statistics is accumulated in arena slots, and should be dumped when arena is destroyed. This separates statistics collected for each scheduler activity region in each master thread. With the current RML implementation (TBB 2.2, 3.0) to avoid complete loss of statistics data during app shutdown (because of lazy workers deinitialization logic) set __TBB_STATISTICS_EARLY_DUMP macro to write the statistics at the moment a master thread deinitializes its scheduler. This may happen a little earlier than the moment of arena destruction resulting in the following undesired (though usually tolerable) effects: - a few events related to unsuccessful stealing or thread pool activity may be lost, - statistics may be substantially incomplete in case of FIFO tasks used in the FAF mode. Macro __TBB_STATISTICS_STDOUT and global variable __TBB_ActiveStatisticsGroups defined below can be used to configure the statistics output. To add new counter: 1) Insert it into the appropriate group range in statistics_counters; 2) Insert the corresponding field title into StatFieldTitles (preserving relative order of the fields). To add new counters group: 1) Insert new group bit flag into statistics_groups; 2) Insert the new group title into StatGroupTitles (preserving relative order of the groups). 3) Add counter belonging to the new group as described above **/ #include "tbb/tbb_stddef.h" #ifndef __TBB_STATISTICS #define __TBB_STATISTICS 0 #endif /* __TBB_STATISTICS */ #if __TBB_STATISTICS #include // for memset //! Dump counters into stdout as well. /** By default statistics counters are written to the file "statistics.txt" only. **/ #define __TBB_STATISTICS_STDOUT 1 //! Dump only totals for all threads in the given arena /** By default statistics counters for each arena slot are dumped separately, as well as the subtotal for workers. **/ #define __TBB_STATISTICS_TOTALS_ONLY 1 //! Dump statistics for an arena when its master completes /** By default (when this macro is not set) the statistics is sent to output when arena object is destroyed. But with the current lazy workers termination logic default behavior may result in loosing all statistics output. **/ #define __TBB_STATISTICS_EARLY_DUMP 1 #define GATHER_STATISTIC(x) (x) namespace tbb { namespace internal { //! Groups of statistics counters. /** The order of enumerators must be the same as the order of the corresponding field groups in the statistics_counters structure. **/ enum statistics_groups { sg_task_allocation = 0x01, sg_task_execution = 0x02, sg_stealing = 0x04, sg_affinity = 0x08, sg_arena = 0x10, sg_market = 0x20, sg_prio = 0x40, sg_prio_ex = 0x80, // List end marker. Insert new groups only before it. sg_end }; //! Groups of counters to output const uintptr_t __TBB_ActiveStatisticsGroups = sg_task_execution | sg_stealing | sg_affinity | sg_arena | sg_market; //! A set of various statistics counters that are updated by the library on per thread basis. /** All the fields must be of the same type (statistics_counters::counter_type). This is necessary to allow reinterpreting this structure as an array. **/ struct statistics_counters { typedef long counter_type; // Group: sg_task_allocation // Counters in this group can have negative values as the tasks migrate across // threads while the associated counters are updated in the current thread only // to avoid data races //! Number of tasks allocated and not yet destroyed counter_type active_tasks; //! Number of task corpses stored for future reuse counter_type free_list_length; //! Number of big tasks allocated during the run /** To find total number of tasks malloc'd, compute (big_tasks+my_small_task_count) */ counter_type big_tasks; // Group: sg_task_execution //! Number of tasks executed counter_type tasks_executed; //! Number of elided spawns counter_type spawns_bypassed; // Group: sg_stealing //! Number of tasks successfully stolen counter_type steals_committed; //! Number of failed stealing attempts counter_type steals_failed; //! Number of failed attempts to lock victim's task pool counter_type thieves_conflicts; //! Number of times thief backed off because of the collision with the owner counter_type thief_backoffs; // Group: sg_affinity //! Number of tasks received from mailbox counter_type mails_received; //! Number of affinitized tasks executed by the owner /** Goes as "revoked" in statistics printout. **/ counter_type proxies_executed; //! Number of affinitized tasks intercepted by thieves counter_type proxies_stolen; //! Number of proxy bypasses by thieves during stealing counter_type proxies_bypassed; //! Number of affinitized tasks executed by the owner via scheduler bypass mechanism counter_type affinity_ignored; // Group: sg_arena //! Number of times the state of arena switched between "full" and "empty" counter_type gate_switches; //! Number of times workers left an arena and returned into the market counter_type arena_roundtrips; // !Average concurrency level of this arena counter_type avg_arena_concurrency; //! Average assigned priority counter_type avg_assigned_workers; // Group: sg_market //! Number of times workers left the market and returned into RML counter_type market_roundtrips; // Group; sg_prio //! Number of arena priority switches counter_type arena_prio_switches; //! Number of market priority switches counter_type market_prio_switches; //! Number of arena priority switches counter_type arena_prio_resets; //! Number of reference priority source fixups to avoid deadlock counter_type prio_ref_fixups; //! Average arena priority counter_type avg_arena_prio; //! Average market priority counter_type avg_market_prio; // Group; sg_prio_ex //! Number of times local task pools were winnowed counter_type prio_winnowings; //! Number of times secondary task pools were searched for top priority tasks counter_type prio_reloads; //! Number of times secondary task pools were abandoned by quitting workers counter_type prio_orphanings; //! Number of tasks offloaded into secondary task pools counter_type prio_tasks_offloaded; //! Number of tasks reloaded from secondary task pools counter_type prio_tasks_reloaded; // Constructor and helpers statistics_counters() { reset(); } void reset () { memset( this, 0, sizeof(statistics_counters) ); } counter_type& field ( size_t index ) { return reinterpret_cast(this)[index]; } const counter_type& field ( size_t index ) const { return reinterpret_cast(this)[index]; } static size_t size () { return sizeof(statistics_counters) / sizeof(counter_type); } const statistics_counters& operator += ( const statistics_counters& rhs ) { for ( size_t i = 0; i < size(); ++i ) field(i) += rhs.field(i); return *this; } }; // statistics_counters static const size_t workers_counters_total = (size_t)-1; static const size_t arena_counters_total = (size_t)-2; void dump_statistics ( const statistics_counters& c, size_t id ); } // namespace internal } // namespace tbb #else /* !__TBB_STATISTICS */ #define GATHER_STATISTIC(x) ((void)0) #endif /* !__TBB_STATISTICS */ #endif /* _TBB_tbb_statistics_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_stddef.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_stddef_H #define __TBB_tbb_stddef_H // Marketing-driven product version #define TBB_VERSION_MAJOR 4 #define TBB_VERSION_MINOR 3 // Engineering-focused interface version #define TBB_INTERFACE_VERSION 8000 #define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 // The oldest major interface version still supported // To be used in SONAME, manifests, etc. #define TBB_COMPATIBLE_INTERFACE_VERSION 2 #define __TBB_STRING_AUX(x) #x #define __TBB_STRING(x) __TBB_STRING_AUX(x) // We do not need defines below for resource processing on windows #if !defined RC_INVOKED // Define groups for Doxygen documentation /** * @defgroup algorithms Algorithms * @defgroup containers Containers * @defgroup memory_allocation Memory Allocation * @defgroup synchronization Synchronization * @defgroup timing Timing * @defgroup task_scheduling Task Scheduling */ // Simple text that is displayed on the main page of Doxygen documentation. /** * \mainpage Main Page * * Click the tabs above for information about the * -
Modules (groups of functionality) implemented by the library * - Classes provided by the library * - Files constituting the library. * . * Please note that significant part of TBB functionality is implemented in the form of * template functions, descriptions of which are not accessible on the Classes * tab. Use Modules or Namespace/Namespace Members * tabs to find them. * * Additional pieces of information can be found here * - \subpage concepts * . */ /** \page concepts TBB concepts A concept is a set of requirements to a type, which are necessary and sufficient for the type to model a particular behavior or a set of behaviors. Some concepts are specific to a particular algorithm (e.g. algorithm body), while other ones are common to several algorithms (e.g. range concept). All TBB algorithms make use of different classes implementing various concepts. Implementation classes are supplied by the user as type arguments of template parameters and/or as objects passed as function call arguments. The library provides predefined implementations of some concepts (e.g. several kinds of \ref range_req "ranges"), while other ones must always be implemented by the user. TBB defines a set of minimal requirements each concept must conform to. Here is the list of different concepts hyperlinked to the corresponding requirements specifications: - \subpage range_req - \subpage parallel_do_body_req - \subpage parallel_for_body_req - \subpage parallel_reduce_body_req - \subpage parallel_scan_body_req - \subpage parallel_sort_iter_req **/ // tbb_config.h should be included the first since it contains macro definitions used in other headers #include "tbb_config.h" #if _MSC_VER >=1400 #define __TBB_EXPORTED_FUNC __cdecl #define __TBB_EXPORTED_METHOD __thiscall #else #define __TBB_EXPORTED_FUNC #define __TBB_EXPORTED_METHOD #endif #if __INTEL_COMPILER || _MSC_VER #define __TBB_NOINLINE(decl) __declspec(noinline) decl #elif __GNUC__ #define __TBB_NOINLINE(decl) decl __attribute__ ((noinline)) #else #define __TBB_NOINLINE(decl) decl #endif #if __TBB_NOEXCEPT_PRESENT #define __TBB_NOEXCEPT(expression) noexcept(expression) #else #define __TBB_NOEXCEPT(expression) #endif #include /* Need size_t and ptrdiff_t */ #if _MSC_VER #define __TBB_tbb_windef_H #include "internal/_tbb_windef.h" #undef __TBB_tbb_windef_H #endif #if !defined(_MSC_VER) || _MSC_VER>=1600 #include #endif //! Type for an assertion handler typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment ); #if TBB_USE_ASSERT #define __TBB_ASSERT_NS(predicate,message,ns) ((predicate)?((void)0) : ns::assertion_failure(__FILE__,__LINE__,#predicate,message)) //! Assert that x is true. /** If x is false, print assertion failure message. If the comment argument is not NULL, it is printed as part of the failure message. The comment argument has no other effect. */ #if __TBBMALLOC_BUILD namespace rml { namespace internal { #define __TBB_ASSERT(predicate,message) __TBB_ASSERT_NS(predicate,message,rml::internal) #else namespace tbb { #define __TBB_ASSERT(predicate,message) __TBB_ASSERT_NS(predicate,message,tbb) #endif #define __TBB_ASSERT_EX __TBB_ASSERT //! Set assertion handler and return previous value of it. assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler ); //! Process an assertion failure. /** Normally called from __TBB_ASSERT macro. If assertion handler is null, print message for assertion failure and abort. Otherwise call the assertion handler. */ void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment ); #if __TBBMALLOC_BUILD }} // namespace rml::internal #else } // namespace tbb #endif #else /* !TBB_USE_ASSERT */ //! No-op version of __TBB_ASSERT. #define __TBB_ASSERT(predicate,comment) ((void)0) //! "Extended" version is useful to suppress warnings if a variable is only used with an assert #define __TBB_ASSERT_EX(predicate,comment) ((void)(1 && (predicate))) #endif /* !TBB_USE_ASSERT */ //! The namespace tbb contains all components of the library. namespace tbb { #if _MSC_VER && _MSC_VER<1600 namespace internal { typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; } // namespace internal #else /* Posix */ namespace internal { using ::int8_t; using ::int16_t; using ::int32_t; using ::int64_t; using ::uint8_t; using ::uint16_t; using ::uint32_t; using ::uint64_t; } // namespace internal #endif /* Posix */ using std::size_t; using std::ptrdiff_t; //! The function returns the interface version of the TBB shared library being used. /** * The version it returns is determined at runtime, not at compile/link time. * So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time. */ extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version(); //! Dummy type that distinguishes splitting constructor from copy constructor. /** * See description of parallel_for and parallel_reduce for example usages. * @ingroup algorithms */ class split { }; //! Type enables transmission of splitting proportion from partitioners to range objects /** * In order to make use of such facility Range objects must implement * splitting constructor with this type passed and initialize static * constant boolean field 'is_divisible_in_proportion' with the value * of 'true' */ class proportional_split { public: proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left), my_right(_right) { } proportional_split(split) : my_left(1), my_right(1) { } size_t left() const { return my_left; } size_t right() const { return my_right; } void set_proportion(size_t _left, size_t _right) { my_left = _left; my_right = _right; } // used when range does not support proportional split operator split() const { return split(); } private: size_t my_left, my_right; }; /** * @cond INTERNAL * @brief Identifiers declared inside namespace internal should never be used directly by client code. */ namespace internal { //! Compile-time constant that is upper bound on cache line/sector size. /** It should be used only in situations where having a compile-time upper bound is more useful than a run-time exact answer. @ingroup memory_allocation */ const size_t NFS_MaxLineSize = 128; /** Label for data that may be accessed from different threads, and that may eventually become wrapped in a formal atomic type. Note that no problems have yet been observed relating to the definition currently being empty, even if at least "volatile" would seem to be in order to avoid data sometimes temporarily hiding in a register (although "volatile" as a "poor man's atomic" lacks several other features of a proper atomic, some of which are now provided instead through specialized functions). Note that usage is intentionally compatible with a definition as qualifier "volatile", both as a way to have the compiler help enforce use of the label and to quickly rule out one potential issue. Note however that, with some architecture/compiler combinations, e.g. on IA-64 architecture, "volatile" also has non-portable memory semantics that are needlessly expensive for "relaxed" operations. Note that this must only be applied to data that will not change bit patterns when cast to/from an integral type of the same length; tbb::atomic must be used instead for, e.g., floating-point types. TODO: apply wherever relevant **/ #define __TBB_atomic // intentionally empty, see above template struct padded_base : T { char pad[S - R]; }; template struct padded_base : T {}; //! Pads type T to fill out to a multiple of cache line size. template struct padded : padded_base {}; //! Extended variant of the standard offsetof macro /** The standard offsetof macro is not sufficient for TBB as it can be used for POD-types only. The constant 0x1000 (not NULL) is necessary to appease GCC. **/ #define __TBB_offsetof(class_name, member_name) \ ((ptrdiff_t)&(reinterpret_cast(0x1000)->member_name) - 0x1000) //! Returns address of the object containing a member with the given name and address #define __TBB_get_object_ref(class_name, member_name, member_addr) \ (*reinterpret_cast((char*)member_addr - __TBB_offsetof(class_name, member_name))) //! Throws std::runtime_error with what() returning error_code description prefixed with aux_info void __TBB_EXPORTED_FUNC handle_perror( int error_code, const char* aux_info ); #if TBB_USE_EXCEPTIONS #define __TBB_TRY try #define __TBB_CATCH(e) catch(e) #define __TBB_THROW(e) throw e #define __TBB_RETHROW() throw #else /* !TBB_USE_EXCEPTIONS */ inline bool __TBB_false() { return false; } #define __TBB_TRY #define __TBB_CATCH(e) if ( tbb::internal::__TBB_false() ) #define __TBB_THROW(e) ((void)0) #define __TBB_RETHROW() ((void)0) #endif /* !TBB_USE_EXCEPTIONS */ //! Report a runtime warning. void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... ); #if TBB_USE_ASSERT static void* const poisoned_ptr = reinterpret_cast(-1); //! Set p to invalid pointer value. // Also works for regular (non-__TBB_atomic) pointers. template inline void poison_pointer( T* __TBB_atomic & p ) { p = reinterpret_cast(poisoned_ptr); } /** Expected to be used in assertions only, thus no empty form is defined. **/ template inline bool is_poisoned( T* p ) { return p == reinterpret_cast(poisoned_ptr); } #else template inline void poison_pointer( T* __TBB_atomic & ) {/*do nothing*/} #endif /* !TBB_USE_ASSERT */ //! Cast between unrelated pointer types. /** This method should be used sparingly as a last resort for dealing with situations that inherently break strict ISO C++ aliasing rules. */ // T is a pointer type because it will be explicitly provided by the programmer as a template argument; // U is a referent type to enable the compiler to check that "ptr" is a pointer, deducing U in the process. template inline T punned_cast( U* ptr ) { uintptr_t x = reinterpret_cast(ptr); return reinterpret_cast(x); } //! Base class for types that should not be assigned. class no_assign { // Deny assignment void operator=( const no_assign& ); public: #if __GNUC__ //! Explicitly define default construction, because otherwise gcc issues gratuitous warning. no_assign() {} #endif /* __GNUC__ */ }; //! Base class for types that should not be copied or assigned. class no_copy: no_assign { //! Deny copy construction no_copy( const no_copy& ); public: //! Allow default construction no_copy() {} }; #if TBB_DEPRECATED_MUTEX_COPYING class mutex_copy_deprecated_and_disabled {}; #else // By default various implementations of mutexes are not copy constructible // and not copy assignable. class mutex_copy_deprecated_and_disabled : no_copy {}; #endif //! A function to check if passed in pointer is aligned on a specific border template inline bool is_aligned(T* pointer, uintptr_t alignment) { return 0==((uintptr_t)pointer & (alignment-1)); } //! A function to check if passed integer is a power of 2 template inline bool is_power_of_two(integer_type arg) { return arg && (0 == (arg & (arg - 1))); } //! A function to compute arg modulo divisor where divisor is a power of 2. template inline argument_integer_type modulo_power_of_two(argument_integer_type arg, divisor_integer_type divisor) { // Divisor is assumed to be a power of two (which is valid for current uses). __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of two" ); return (arg & (divisor - 1)); } //! A function to determine if "arg is a multiplication of a number and a power of 2". // i.e. for strictly positive i and j, with j a power of 2, // determines whether i==j< inline bool is_power_of_two_factor(argument_integer_type arg, divisor_integer_type divisor) { // Divisor is assumed to be a power of two (which is valid for current uses). __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of two" ); return 0 == (arg & (arg - divisor)); } //! Utility template function to prevent "unused" warnings by various compilers. template void suppress_unused_warning( const T& ) {} // Struct to be used as a version tag for inline functions. /** Version tag can be necessary to prevent loader on Linux from using the wrong symbol in debug builds (when inline functions are compiled as out-of-line). **/ struct version_tag_v3 {}; typedef version_tag_v3 version_tag; } // internal } // tbb // Following is a set of classes and functions typically used in compile-time "metaprogramming". // TODO: move all that to a separate header #if __TBB_ALLOCATOR_TRAITS_PRESENT #include //for allocator_traits #endif #if __TBB_CPP11_RVALUE_REF_PRESENT || _LIBCPP_VERSION #include // for std::move #endif namespace tbb { namespace internal { //! Class for determining type of std::allocator::value_type. template struct allocator_type { typedef T value_type; }; #if _MSC_VER //! Microsoft std::allocator has non-standard extension that strips const from a type. template struct allocator_type { typedef T value_type; }; #endif // Ad-hoc implementation of true_type & false_type // Intended strictly for internal use! For public APIs (traits etc), use C++11 analogues. template struct bool_constant { static /*constexpr*/ const bool value = v; }; typedef bool_constant true_type; typedef bool_constant false_type; #if __TBB_ALLOCATOR_TRAITS_PRESENT using std::allocator_traits; #else template struct allocator_traits{ typedef tbb::internal::false_type propagate_on_container_move_assignment; }; #endif //! A template to select either 32-bit or 64-bit constant as compile time, depending on machine word size. template struct select_size_t_constant { //Explicit cast is needed to avoid compiler warnings about possible truncation. //The value of the right size, which is selected by ?:, is anyway not truncated or promoted. static const size_t value = (size_t)((sizeof(size_t)==sizeof(u)) ? u : ull); }; #if __TBB_CPP11_RVALUE_REF_PRESENT using std::move; #elif defined(_LIBCPP_NAMESPACE) // libc++ defines "pre-C++11 move" similarly to our; use it to avoid name conflicts in some cases. using std::_LIBCPP_NAMESPACE::move; #else template T& move( T& x ) { return x; } #endif template struct STATIC_ASSERTION_FAILED; template <> struct STATIC_ASSERTION_FAILED { enum {value=1};}; template<> struct STATIC_ASSERTION_FAILED; //intentionally left undefined to cause compile time error //! @endcond }} // namespace tbb::internal #if __TBB_STATIC_ASSERT_PRESENT #define __TBB_STATIC_ASSERT(condition,msg) static_assert(condition,msg) #else //please note condition is intentionally inverted to get a bit more understandable error msg #define __TBB_STATIC_ASSERT_IMPL1(condition,msg,line) \ enum {static_assert_on_line_##line = tbb::internal::STATIC_ASSERTION_FAILED::value} #define __TBB_STATIC_ASSERT_IMPL(condition,msg,line) __TBB_STATIC_ASSERT_IMPL1(condition,msg,line) //! Verify at compile time that passed in condition is hold #define __TBB_STATIC_ASSERT(condition,msg) __TBB_STATIC_ASSERT_IMPL(condition,msg,__LINE__) #endif #endif /* RC_INVOKED */ #endif /* __TBB_tbb_stddef_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_thread.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #if _WIN32||_WIN64 #include // _beginthreadex() #endif #include #include "tbb_misc.h" // handle_win_error(), ThreadStackSize #include "tbb/tbb_stddef.h" #include "tbb/tbb_thread.h" #include "tbb/tbb_allocator.h" #include "governor.h" // default_num_threads() #if __TBB_WIN8UI_SUPPORT #include #endif namespace tbb { namespace internal { //! Allocate a closure void* allocate_closure_v3( size_t size ) { return allocate_via_handler_v3( size ); } //! Free a closure allocated by allocate_closure_v3 void free_closure_v3( void *ptr ) { deallocate_via_handler_v3( ptr ); } void tbb_thread_v3::join() { if (!joinable()) handle_perror( EINVAL, "tbb_thread::join" ); // Invalid argument if (this_tbb_thread::get_id() == get_id()) handle_perror( EDEADLK, "tbb_thread::join" ); // Resource deadlock avoided #if _WIN32||_WIN64 #if __TBB_WIN8UI_SUPPORT std::thread* thread_tmp=(std::thread*)my_thread_id; thread_tmp->join(); delete thread_tmp; #else // __TBB_WIN8UI_SUPPORT DWORD status = WaitForSingleObjectEx( my_handle, INFINITE, FALSE ); if ( status == WAIT_FAILED ) handle_win_error( GetLastError() ); BOOL close_stat = CloseHandle( my_handle ); if ( close_stat == 0 ) handle_win_error( GetLastError() ); my_thread_id = 0; #endif // __TBB_WIN8UI_SUPPORT #else int status = pthread_join( my_handle, NULL ); if( status ) handle_perror( status, "pthread_join" ); #endif // _WIN32||_WIN64 my_handle = 0; } void tbb_thread_v3::detach() { if (!joinable()) handle_perror( EINVAL, "tbb_thread::detach" ); // Invalid argument #if _WIN32||_WIN64 BOOL status = CloseHandle( my_handle ); if ( status == 0 ) handle_win_error( GetLastError() ); my_thread_id = 0; #else int status = pthread_detach( my_handle ); if( status ) handle_perror( status, "pthread_detach" ); #endif // _WIN32||_WIN64 my_handle = 0; } void tbb_thread_v3::internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), void* closure ) { #if _WIN32||_WIN64 #if __TBB_WIN8UI_SUPPORT std::thread* thread_tmp=new std::thread(start_routine, closure); my_handle = thread_tmp->native_handle(); // TODO: to find out the way to find thread_id without GetThreadId and other // desktop functions. // Now tbb_thread does have its own thread_id that stores std::thread object my_thread_id = (size_t)thread_tmp; #else unsigned thread_id; // The return type of _beginthreadex is "uintptr_t" on new MS compilers, // and 'unsigned long' on old MS compilers. uintptr_t works for both. uintptr_t status = _beginthreadex( NULL, ThreadStackSize, start_routine, closure, 0, &thread_id ); if( status==0 ) handle_perror(errno,"__beginthreadex"); else { my_handle = (HANDLE)status; my_thread_id = thread_id; } #endif #else pthread_t thread_handle; int status; pthread_attr_t stack_size; status = pthread_attr_init( &stack_size ); if( status ) handle_perror( status, "pthread_attr_init" ); status = pthread_attr_setstacksize( &stack_size, ThreadStackSize ); if( status ) handle_perror( status, "pthread_attr_setstacksize" ); status = pthread_create( &thread_handle, &stack_size, start_routine, closure ); if( status ) handle_perror( status, "pthread_create" ); status = pthread_attr_destroy( &stack_size ); if( status ) handle_perror( status, "pthread_attr_destroy" ); my_handle = thread_handle; #endif // _WIN32||_WIN64 } unsigned tbb_thread_v3::hardware_concurrency() __TBB_NOEXCEPT(true) { return governor::default_num_threads(); } tbb_thread_v3::id thread_get_id_v3() { #if _WIN32||_WIN64 return tbb_thread_v3::id( GetCurrentThreadId() ); #else return tbb_thread_v3::id( pthread_self() ); #endif // _WIN32||_WIN64 } void move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ) { if (t1.joinable()) t1.detach(); t1.my_handle = t2.my_handle; t2.my_handle = 0; #if _WIN32||_WIN64 t1.my_thread_id = t2.my_thread_id; t2.my_thread_id = 0; #endif // _WIN32||_WIN64 } void thread_yield_v3() { __TBB_Yield(); } void thread_sleep_v3(const tick_count::interval_t &i) { #if _WIN32||_WIN64 tick_count t0 = tick_count::now(); tick_count t1 = t0; for(;;) { double remainder = (i-(t1-t0)).seconds()*1e3; // milliseconds remaining to sleep if( remainder<=0 ) break; DWORD t = remainder>=INFINITE ? INFINITE-1 : DWORD(remainder); #if !__TBB_WIN8UI_SUPPORT Sleep( t ); #else std::chrono::milliseconds sleep_time( t ); std::this_thread::sleep_for( sleep_time ); #endif t1 = tick_count::now(); } #else struct timespec req; double sec = i.seconds(); req.tv_sec = static_cast(sec); req.tv_nsec = static_cast( (sec - req.tv_sec)*1e9 ); nanosleep(&req, NULL); #endif // _WIN32||_WIN64 } } // internal } // tbb ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_thread.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_thread_H #define __TBB_tbb_thread_H #include "tbb_stddef.h" #if _WIN32||_WIN64 #include "machine/windows_api.h" #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* ) #if __TBB_WIN8UI_SUPPORT typedef size_t thread_id_type; #else // __TBB_WIN8UI_SUPPORT typedef DWORD thread_id_type; #endif // __TBB_WIN8UI_SUPPORT #else #define __TBB_NATIVE_THREAD_ROUTINE void* #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* ) #include #endif // _WIN32||_WIN64 #include "tick_count.h" #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers #pragma warning (push) #pragma warning (disable: 4530) #endif #include #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) #endif namespace tbb { namespace internal { class tbb_thread_v3; } inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true); namespace internal { //! Allocate a closure void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size ); //! Free a closure allocated by allocate_closure_v3 void __TBB_EXPORTED_FUNC free_closure_v3( void* ); struct thread_closure_base { void* operator new( size_t size ) {return allocate_closure_v3(size);} void operator delete( void* ptr ) {free_closure_v3(ptr);} }; template struct thread_closure_0: thread_closure_base { F function; static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { thread_closure_0 *self = static_cast(c); self->function(); delete self; return 0; } thread_closure_0( const F& f ) : function(f) {} }; //! Structure used to pass user function with 1 argument to thread. template struct thread_closure_1: thread_closure_base { F function; X arg1; //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { thread_closure_1 *self = static_cast(c); self->function(self->arg1); delete self; return 0; } thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {} }; template struct thread_closure_2: thread_closure_base { F function; X arg1; Y arg2; //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { thread_closure_2 *self = static_cast(c); self->function(self->arg1, self->arg2); delete self; return 0; } thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {} }; //! Versioned thread class. class tbb_thread_v3 { #if __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN // Workaround for a compiler bug: declaring the copy constructor as public // enables use of the moving constructor. // The definition is not provided in order to prohibit copying. public: #endif tbb_thread_v3(const tbb_thread_v3&); // = delete; // Deny access public: #if _WIN32||_WIN64 typedef HANDLE native_handle_type; #else typedef pthread_t native_handle_type; #endif // _WIN32||_WIN64 class id; //! Constructs a thread object that does not represent a thread of execution. tbb_thread_v3() __TBB_NOEXCEPT(true) : my_handle(0) #if _WIN32||_WIN64 , my_thread_id(0) #endif // _WIN32||_WIN64 {} //! Constructs an object and executes f() in a new thread template explicit tbb_thread_v3(F f) { typedef internal::thread_closure_0 closure_type; internal_start(closure_type::start_routine, new closure_type(f)); } //! Constructs an object and executes f(x) in a new thread template tbb_thread_v3(F f, X x) { typedef internal::thread_closure_1 closure_type; internal_start(closure_type::start_routine, new closure_type(f,x)); } //! Constructs an object and executes f(x,y) in a new thread template tbb_thread_v3(F f, X x, Y y) { typedef internal::thread_closure_2 closure_type; internal_start(closure_type::start_routine, new closure_type(f,x,y)); } #if __TBB_CPP11_RVALUE_REF_PRESENT tbb_thread_v3(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) : my_handle(x.my_handle) #if _WIN32||_WIN64 , my_thread_id(x.my_thread_id) #endif { x.internal_wipe(); } tbb_thread_v3& operator=(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) { internal_move(x); return *this; } private: tbb_thread_v3& operator=(const tbb_thread_v3& x); // = delete; public: #else // __TBB_CPP11_RVALUE_REF_PRESENT tbb_thread_v3& operator=(tbb_thread_v3& x) { internal_move(x); return *this; } #endif // __TBB_CPP11_RVALUE_REF_PRESENT void swap( tbb_thread_v3& t ) __TBB_NOEXCEPT(true) {tbb::swap( *this, t );} bool joinable() const __TBB_NOEXCEPT(true) {return my_handle!=0; } //! The completion of the thread represented by *this happens before join() returns. void __TBB_EXPORTED_METHOD join(); //! When detach() returns, *this no longer represents the possibly continuing thread of execution. void __TBB_EXPORTED_METHOD detach(); ~tbb_thread_v3() {if( joinable() ) detach();} inline id get_id() const __TBB_NOEXCEPT(true); native_handle_type native_handle() { return my_handle; } //! The number of hardware thread contexts. /** Before TBB 3.0 U4 this methods returned the number of logical CPU in the system. Currently on Windows, Linux and FreeBSD it returns the number of logical CPUs available to the current process in accordance with its affinity mask. NOTE: The return value of this method never changes after its first invocation. This means that changes in the process affinity mask that took place after this method was first invoked will not affect the number of worker threads in the TBB worker threads pool. **/ static unsigned __TBB_EXPORTED_FUNC hardware_concurrency() __TBB_NOEXCEPT(true); private: native_handle_type my_handle; #if _WIN32||_WIN64 thread_id_type my_thread_id; #endif // _WIN32||_WIN64 void internal_wipe() __TBB_NOEXCEPT(true) { my_handle = 0; #if _WIN32||_WIN64 my_thread_id = 0; #endif } void internal_move(tbb_thread_v3& x) __TBB_NOEXCEPT(true) { if (joinable()) detach(); my_handle = x.my_handle; #if _WIN32||_WIN64 my_thread_id = x.my_thread_id; #endif // _WIN32||_WIN64 x.internal_wipe(); } /** Runs start_routine(closure) on another thread and sets my_handle to the handle of the created thread. */ void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), void* closure ); friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true); }; class tbb_thread_v3::id { #if _WIN32||_WIN64 thread_id_type my_id; id( thread_id_type id_ ) : my_id(id_) {} #else pthread_t my_id; id( pthread_t id_ ) : my_id(id_) {} #endif // _WIN32||_WIN64 friend class tbb_thread_v3; public: id() __TBB_NOEXCEPT(true) : my_id(0) {} friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); template friend std::basic_ostream& operator<< (std::basic_ostream &out, tbb_thread_v3::id id) { out << id.my_id; return out; } friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); }; // tbb_thread_v3::id tbb_thread_v3::id tbb_thread_v3::get_id() const __TBB_NOEXCEPT(true) { #if _WIN32||_WIN64 return id(my_thread_id); #else return id(my_handle); #endif // _WIN32||_WIN64 } void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); void __TBB_EXPORTED_FUNC thread_yield_v3(); void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i); inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) { return x.my_id == y.my_id; } inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) { return x.my_id != y.my_id; } inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) { return x.my_id < y.my_id; } inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) { return x.my_id <= y.my_id; } inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) { return x.my_id > y.my_id; } inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) { return x.my_id >= y.my_id; } } // namespace internal; //! Users reference thread class by name tbb_thread typedef internal::tbb_thread_v3 tbb_thread; using internal::operator==; using internal::operator!=; using internal::operator<; using internal::operator>; using internal::operator<=; using internal::operator>=; inline void move( tbb_thread& t1, tbb_thread& t2 ) { internal::move_v3(t1, t2); } inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true) { tbb::tbb_thread::native_handle_type h = t1.my_handle; t1.my_handle = t2.my_handle; t2.my_handle = h; #if _WIN32||_WIN64 thread_id_type i = t1.my_thread_id; t1.my_thread_id = t2.my_thread_id; t2.my_thread_id = i; #endif /* _WIN32||_WIN64 */ } namespace this_tbb_thread { inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); } //! Offers the operating system the opportunity to schedule another thread. inline void yield() { internal::thread_yield_v3(); } //! The current thread blocks at least until the time specified. inline void sleep(const tick_count::interval_t &i) { internal::thread_sleep_v3(i); } } // namespace this_tbb_thread } // namespace tbb #endif /* __TBB_tbb_thread_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbb_version.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // Please define version number in the file: #include "tbb/tbb_stddef.h" // And don't touch anything below #ifndef ENDL #define ENDL "\n" #endif #include "version_string.ver" #ifndef __TBB_VERSION_STRINGS #pragma message("Warning: version_string.ver isn't generated properly by version_info.sh script!") // here is an example of macros value: #define __TBB_VERSION_STRINGS \ "TBB: BUILD_HOST\tUnknown\n" \ "TBB: BUILD_ARCH\tUnknown\n" \ "TBB: BUILD_OS\t\tUnknown\n" \ "TBB: BUILD_CL\t\tUnknown\n" \ "TBB: BUILD_COMPILER\tUnknown\n" \ "TBB: BUILD_COMMAND\tUnknown\n" #endif #ifndef __TBB_DATETIME #ifdef RC_INVOKED #define __TBB_DATETIME "Unknown" #else #define __TBB_DATETIME __DATE__ __TIME__ #endif #endif #define __TBB_VERSION_NUMBER(N) #N ": VERSION\t\t" __TBB_STRING(TBB_VERSION_MAJOR.TBB_VERSION_MINOR) ENDL #define __TBB_INTERFACE_VERSION_NUMBER(N) #N ": INTERFACE VERSION\t" __TBB_STRING(TBB_INTERFACE_VERSION) ENDL #define __TBB_VERSION_DATETIME(N) #N ": BUILD_DATE\t\t" __TBB_DATETIME ENDL #ifndef TBB_USE_DEBUG #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\tundefined" ENDL #elif TBB_USE_DEBUG==0 #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\t0" ENDL #elif TBB_USE_DEBUG==1 #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\t1" ENDL #elif TBB_USE_DEBUG==2 #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\t2" ENDL #else #error Unexpected value for TBB_USE_DEBUG #endif /* Make __TBB_VERSION_USE_ASSERT and __TBB_VERSION_DO_NOTIFY empty for rc * because rc from VS2005 crashed with fatal error RC10056 for too complex * macros (for example, when __TBB_CPF_BUILD is enabled). * All information is available in BUILD_COMMAND anyway. */ #ifdef RC_INVOKED #define __TBB_VERSION_USE_ASSERT(N) #else // RC_INVOKED #ifndef TBB_USE_ASSERT #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\tundefined" ENDL #elif TBB_USE_ASSERT==0 #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\t0" ENDL #elif TBB_USE_ASSERT==1 #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\t1" ENDL #elif TBB_USE_ASSERT==2 #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\t2" ENDL #else #error Unexpected value for TBB_USE_ASSERT #endif #endif // RC_INVOKED #ifndef __TBB_CPF_BUILD #define __TBB_VERSION_TBB_PREVIEW_BINARY(N) #else #define __TBB_VERSION_TBB_PREVIEW_BINARY(N) #N ": TBB_PREVIEW_BINARY\t1" ENDL #endif #ifdef RC_INVOKED #define __TBB_VERSION_DO_NOTIFY(N) #else #ifndef DO_ITT_NOTIFY #define __TBB_VERSION_DO_NOTIFY(N) #N ": DO_ITT_NOTIFY\tundefined" ENDL #elif DO_ITT_NOTIFY==1 #define __TBB_VERSION_DO_NOTIFY(N) #N ": DO_ITT_NOTIFY\t1" ENDL #elif DO_ITT_NOTIFY==0 #define __TBB_VERSION_DO_NOTIFY(N) #else #error Unexpected value for DO_ITT_NOTIFY #endif #endif // RC_INVOKED #define TBB_VERSION_STRINGS_P(N) __TBB_VERSION_NUMBER(N) __TBB_INTERFACE_VERSION_NUMBER(N) __TBB_VERSION_DATETIME(N) __TBB_VERSION_STRINGS(N) __TBB_VERSION_USE_DEBUG(N) __TBB_VERSION_USE_ASSERT(N) __TBB_VERSION_TBB_PREVIEW_BINARY(N) __TBB_VERSION_DO_NOTIFY(N) #define TBB_VERSION_STRINGS TBB_VERSION_STRINGS_P(TBB) #define TBBMALLOC_VERSION_STRINGS TBB_VERSION_STRINGS_P(TBBmalloc) // numbers #ifndef __TBB_VERSION_YMD #define __TBB_VERSION_YMD 0, 0 #endif #define TBB_VERNUMBERS TBB_VERSION_MAJOR, TBB_VERSION_MINOR, __TBB_VERSION_YMD #define TBB_VERSION __TBB_STRING(TBB_VERNUMBERS) ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tbbmalloc_proxy.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Replacing the standard memory allocation routines in Microsoft* C/C++ RTL (malloc/free, global new/delete, etc.) with the TBB memory allocator. Include the following header to a source of any binary which is loaded during application startup #include "tbb/tbbmalloc_proxy.h" or add following parameters to the linker options for the binary which is loaded during application startup. It can be either exe-file or dll. For win32 tbbmalloc_proxy.lib /INCLUDE:"___TBB_malloc_proxy" win64 tbbmalloc_proxy.lib /INCLUDE:"__TBB_malloc_proxy" */ #ifndef __TBB_tbbmalloc_proxy_H #define __TBB_tbbmalloc_proxy_H #if _MSC_VER #ifdef _DEBUG #pragma comment(lib, "tbbmalloc_proxy_debug.lib") #else #pragma comment(lib, "tbbmalloc_proxy.lib") #endif #if defined(_WIN64) #pragma comment(linker, "/include:__TBB_malloc_proxy") #else #pragma comment(linker, "/include:___TBB_malloc_proxy") #endif #else /* Primarily to support MinGW */ extern "C" void __TBB_malloc_proxy(); struct __TBB_malloc_proxy_caller { __TBB_malloc_proxy_caller() { __TBB_malloc_proxy(); } } volatile __TBB_malloc_proxy_helper_object; #endif // _MSC_VER #endif //__TBB_tbbmalloc_proxy_H ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tick_count.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tick_count_H #define __TBB_tick_count_H #include "tbb_stddef.h" #if _WIN32||_WIN64 #include "machine/windows_api.h" #elif __linux__ #include #else /* generic Unix */ #include #endif /* (choice of OS) */ namespace tbb { //! Absolute timestamp /** @ingroup timing */ class tick_count { public: //! Relative time interval. class interval_t { long long value; explicit interval_t( long long value_ ) : value(value_) {} public: //! Construct a time interval representing zero time duration interval_t() : value(0) {}; //! Construct a time interval representing sec seconds time duration explicit interval_t( double sec ); //! Return the length of a time interval in seconds double seconds() const; friend class tbb::tick_count; //! Extract the intervals from the tick_counts and subtract them. friend interval_t operator-( const tick_count& t1, const tick_count& t0 ); //! Add two intervals. friend interval_t operator+( const interval_t& i, const interval_t& j ) { return interval_t(i.value+j.value); } //! Subtract two intervals. friend interval_t operator-( const interval_t& i, const interval_t& j ) { return interval_t(i.value-j.value); } //! Accumulation operator interval_t& operator+=( const interval_t& i ) {value += i.value; return *this;} //! Subtraction operator interval_t& operator-=( const interval_t& i ) {value -= i.value; return *this;} private: static long long ticks_per_second(){ #if _WIN32||_WIN64 LARGE_INTEGER qpfreq; int rval = QueryPerformanceFrequency(&qpfreq); __TBB_ASSERT_EX(rval, "QueryPerformanceFrequency returned zero"); return static_cast(qpfreq.QuadPart); #elif __linux__ return static_cast(1E9); #else /* generic Unix */ return static_cast(1E6); #endif /* (choice of OS) */ } }; //! Construct an absolute timestamp initialized to zero. tick_count() : my_count(0) {}; //! Return current time. static tick_count now(); //! Subtract two timestamps to get the time interval between friend interval_t operator-( const tick_count& t1, const tick_count& t0 ); //! Return the resolution of the clock in seconds per tick. static double resolution() { return 1.0 / interval_t::ticks_per_second(); } private: long long my_count; }; inline tick_count tick_count::now() { tick_count result; #if _WIN32||_WIN64 LARGE_INTEGER qpcnt; int rval = QueryPerformanceCounter(&qpcnt); __TBB_ASSERT_EX(rval, "QueryPerformanceCounter failed"); result.my_count = qpcnt.QuadPart; #elif __linux__ struct timespec ts; int status = clock_gettime( CLOCK_REALTIME, &ts ); __TBB_ASSERT_EX( status==0, "CLOCK_REALTIME not supported" ); result.my_count = static_cast(1000000000UL)*static_cast(ts.tv_sec) + static_cast(ts.tv_nsec); #else /* generic Unix */ struct timeval tv; int status = gettimeofday(&tv, NULL); __TBB_ASSERT_EX( status==0, "gettimeofday failed" ); result.my_count = static_cast(1000000)*static_cast(tv.tv_sec) + static_cast(tv.tv_usec); #endif /*(choice of OS) */ return result; } inline tick_count::interval_t::interval_t( double sec ) { value = static_cast(sec*interval_t::ticks_per_second()); } inline tick_count::interval_t operator-( const tick_count& t1, const tick_count& t0 ) { return tick_count::interval_t( t1.my_count-t0.my_count ); } inline double tick_count::interval_t::seconds() const { return value*tick_count::resolution(); } } // namespace tbb #endif /* __TBB_tick_count_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tls.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_tls_H #define _TBB_tls_H #if USE_PTHREAD #include #else /* assume USE_WINTHREAD */ #include "tbb/machine/windows_api.h" #endif namespace tbb { namespace internal { typedef void (*tls_dtor_t)(void*); //! Basic cross-platform wrapper class for TLS operations. template class basic_tls { #if USE_PTHREAD typedef pthread_key_t tls_key_t; public: int create( tls_dtor_t dtor = NULL ) { return pthread_key_create(&my_key, dtor); } int destroy() { return pthread_key_delete(my_key); } void set( T value ) { pthread_setspecific(my_key, (void*)value); } T get() { return (T)pthread_getspecific(my_key); } #else /* USE_WINTHREAD */ typedef DWORD tls_key_t; public: #if !__TBB_WIN8UI_SUPPORT int create() { tls_key_t tmp = TlsAlloc(); if( tmp==TLS_OUT_OF_INDEXES ) return TLS_OUT_OF_INDEXES; my_key = tmp; return 0; } int destroy() { TlsFree(my_key); my_key=0; return 0; } void set( T value ) { TlsSetValue(my_key, (LPVOID)value); } T get() { return (T)TlsGetValue(my_key); } #else /*!__TBB_WIN8UI_SUPPORT*/ int create() { tls_key_t tmp = FlsAlloc(NULL); if( tmp== (DWORD)0xFFFFFFFF ) return (DWORD)0xFFFFFFFF; my_key = tmp; return 0; } int destroy() { FlsFree(my_key); my_key=0; return 0; } void set( T value ) { FlsSetValue(my_key, (LPVOID)value); } T get() { return (T)FlsGetValue(my_key); } #endif /* !__TBB_WIN8UI_SUPPORT */ #endif /* USE_WINTHREAD */ private: tls_key_t my_key; }; //! More advanced TLS support template class. /** It supports RAII and to some extent mimic __declspec(thread) variables. */ template class tls : public basic_tls { typedef basic_tls base; public: tls() { base::create(); } ~tls() { base::destroy(); } T operator=(T value) { base::set(value); return value; } operator T() { return base::get(); } }; template class tls : basic_tls { typedef basic_tls base; static void internal_dtor(void* ptr) { if (ptr) delete (T*)ptr; } T* internal_get() { T* result = base::get(); if (!result) { result = new T; base::set(result); } return result; } public: tls() { #if USE_PTHREAD base::create( internal_dtor ); #else base::create(); #endif } ~tls() { base::destroy(); } T* operator=(T* value) { base::set(value); return value; } operator T*() { return internal_get(); } T* operator->() { return internal_get(); } T& operator*() { return *internal_get(); } }; } // namespace internal } // namespace tbb #endif /* _TBB_tls_H */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/disable_warnings.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "ittnotify_config.h" #if ITT_PLATFORM==ITT_PLATFORM_WIN #pragma warning (disable: 593) /* parameter "XXXX" was set but never used */ #pragma warning (disable: 344) /* typedef name has already been declared (with same type) */ #pragma warning (disable: 174) /* expression has no effect */ #pragma warning (disable: 4127) /* conditional expression is constant */ #pragma warning (disable: 4306) /* conversion from '?' to '?' of greater size */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if defined __INTEL_COMPILER #pragma warning (disable: 869) /* parameter "XXXXX" was never referenced */ #pragma warning (disable: 1418) /* external function definition with no prior declaration */ #pragma warning (disable: 1419) /* external declaration in primary source file */ #endif /* __INTEL_COMPILER */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/internal/ittnotify.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _INTERNAL_ITTNOTIFY_H_ #define _INTERNAL_ITTNOTIFY_H_ /** * @file * @brief Internal User API functions and types */ /** @cond exclude_from_documentation */ #ifndef ITT_OS_WIN # define ITT_OS_WIN 1 #endif /* ITT_OS_WIN */ #ifndef ITT_OS_LINUX # define ITT_OS_LINUX 2 #endif /* ITT_OS_LINUX */ #ifndef ITT_OS_MAC # define ITT_OS_MAC 3 #endif /* ITT_OS_MAC */ #ifndef ITT_OS # if defined WIN32 || defined _WIN32 # define ITT_OS ITT_OS_WIN # elif defined( __APPLE__ ) && defined( __MACH__ ) # define ITT_OS ITT_OS_MAC # else # define ITT_OS ITT_OS_LINUX # endif #endif /* ITT_OS */ #ifndef ITT_PLATFORM_WIN # define ITT_PLATFORM_WIN 1 #endif /* ITT_PLATFORM_WIN */ #ifndef ITT_PLATFORM_POSIX # define ITT_PLATFORM_POSIX 2 #endif /* ITT_PLATFORM_POSIX */ #ifndef ITT_PLATFORM_MAC # define ITT_PLATFORM_MAC 3 #endif /* ITT_PLATFORM_MAC */ #ifndef ITT_PLATFORM # if ITT_OS==ITT_OS_WIN # define ITT_PLATFORM ITT_PLATFORM_WIN # elif ITT_OS==ITT_OS_MAC # define ITT_PLATFORM ITT_PLATFORM_MAC # else # define ITT_PLATFORM ITT_PLATFORM_POSIX # endif #endif /* ITT_PLATFORM */ #if defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif #include #if ITT_PLATFORM==ITT_PLATFORM_WIN #include #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #include #if defined(UNICODE) || defined(_UNICODE) #include #endif /* UNICODE || _UNICODE */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #ifndef CDECL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define CDECL __cdecl # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define CDECL __attribute__ ((cdecl)) # else /* _M_IX86 || __i386__ */ # define CDECL /* actual only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* CDECL */ #ifndef STDCALL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define STDCALL __stdcall # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define STDCALL __attribute__ ((stdcall)) # else /* _M_IX86 || __i386__ */ # define STDCALL /* supported only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* STDCALL */ #define ITTAPI CDECL #define LIBITTAPI CDECL /* TODO: Temporary for compatibility! */ #define ITTAPI_CALL CDECL #define LIBITTAPI_CALL CDECL #if ITT_PLATFORM==ITT_PLATFORM_WIN /* use __forceinline (VC++ specific) */ #define ITT_INLINE __forceinline #define ITT_INLINE_ATTRIBUTE /* nothing */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /* * Generally, functions are not inlined unless optimization is specified. * For functions declared inline, this attribute inlines the function even * if no optimization level was specified. */ #ifdef __STRICT_ANSI__ #define ITT_INLINE static #else /* __STRICT_ANSI__ */ #define ITT_INLINE static inline #endif /* __STRICT_ANSI__ */ #define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline, unused)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @endcond */ /** @cond exclude_from_documentation */ /* Helper macro for joining tokens */ #define ITT_JOIN_AUX(p,n) p##n #define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) #ifdef ITT_MAJOR #undef ITT_MAJOR #endif #ifdef ITT_MINOR #undef ITT_MINOR #endif #define ITT_MAJOR 3 #define ITT_MINOR 0 /* Standard versioning of a token with major and minor version numbers */ #define ITT_VERSIONIZE(x) \ ITT_JOIN(x, \ ITT_JOIN(_, \ ITT_JOIN(ITT_MAJOR, \ ITT_JOIN(_, ITT_MINOR)))) #ifndef INTEL_ITTNOTIFY_PREFIX # define INTEL_ITTNOTIFY_PREFIX __itt_ #endif /* INTEL_ITTNOTIFY_PREFIX */ #ifndef INTEL_ITTNOTIFY_POSTFIX # define INTEL_ITTNOTIFY_POSTFIX _ptr_ #endif /* INTEL_ITTNOTIFY_POSTFIX */ #define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) #define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) #define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_VOID_D0(n,d) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_VOID_D1(n,d,x) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_VOID_D2(n,d,x,y) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_VOID_D3(n,d,x,y,z) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #define ITTNOTIFY_DATA_D0(n,d) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_DATA_D1(n,d,x) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_DATA_D2(n,d,x,y) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_DATA_D3(n,d,x,y,z) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #ifdef ITT_STUB #undef ITT_STUB #endif #ifdef ITT_STUBV #undef ITT_STUBV #endif #define ITT_STUBV(api,type,name,args) \ typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); #define ITT_STUB ITT_STUBV /** @endcond */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define INTEL_ITTNOTIFY_API_PRIVATE #include "../ittnotify.h" #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _INTERNAL_ITTNOTIFY_H_ */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/ittnotify.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _ITTNOTIFY_H_ #define _ITTNOTIFY_H_ /** @file @brief Public User API functions and types @mainpage The ITT API is used to annotate a user's program with additional information that can be used by correctness and performance tools. The user inserts calls in their program. Those calls generate information that is collected at runtime, and used by tools such as Intel(R) Parallel Amplifier and Intel(R) Parallel Inspector. @section API Concepts The following general concepts are used throughout the API. @subsection Unicode Support Many API functions take character string arguments. On Windows, there are two versions of each such function. The function name is suffixed by W if Unicode support is enabled, and by A otherwise. Any API function that takes a character string argument adheres to this convention. @subsection Conditional Compilation Many users prefer having an option to modify ITT API code when linking it inside their runtimes. ITT API header file provides a mechanism to replace ITT API function names inside your code with empty strings. To do this, define the macros INTEL_NO_ITTNOTIFY_API during compilation and remove the static library from the linker script. @subsection Domains [see domains] Domains provide a way to separate notification for different modules or libraries in a program. Domains are specified by dotted character strings, e.g. TBB.Internal.Control. A mechanism (to be specified) is provided to enable and disable domains. By default, all domains are enabled. @subsection Named Entities and Instances Named entities (frames, regions, tasks, and markers) communicate information about the program to the analysis tools. A named entity often refers to a section of program code, or to some set of logical concepts that the programmer wants to group together. Named entities relate to the programmer's static view of the program. When the program actually executes, many instances of a given named entity may be created. The API annotations denote instances of named entities. The actual named entities are displayed using the analysis tools. In other words, the named entities come into existence when instances are created. Instances of named entities may have instance identifiers (IDs). Some API calls use instance identifiers to create relationships between different instances of named entities. Other API calls associate data with instances of named entities. Some named entities must always have instance IDs. In particular, regions and frames always have IDs. Task and markers need IDs only if the ID is needed in another API call (such as adding a relation or metadata). The lifetime of instance IDs is distinct from the lifetime of instances. This allows various relationships to be specified separate from the actual execution of instances. This flexibility comes at the expense of extra API calls. The same ID may not be reused for different instances, unless a previous [ref] __itt_id_destroy call for that ID has been issued. */ /** @cond exclude_from_documentation */ #ifndef ITT_OS_WIN # define ITT_OS_WIN 1 #endif /* ITT_OS_WIN */ #ifndef ITT_OS_LINUX # define ITT_OS_LINUX 2 #endif /* ITT_OS_LINUX */ #ifndef ITT_OS_MAC # define ITT_OS_MAC 3 #endif /* ITT_OS_MAC */ #ifndef ITT_OS # if defined WIN32 || defined _WIN32 # define ITT_OS ITT_OS_WIN # elif defined( __APPLE__ ) && defined( __MACH__ ) # define ITT_OS ITT_OS_MAC # else # define ITT_OS ITT_OS_LINUX # endif #endif /* ITT_OS */ #ifndef ITT_PLATFORM_WIN # define ITT_PLATFORM_WIN 1 #endif /* ITT_PLATFORM_WIN */ #ifndef ITT_PLATFORM_POSIX # define ITT_PLATFORM_POSIX 2 #endif /* ITT_PLATFORM_POSIX */ #ifndef ITT_PLATFORM_MAC # define ITT_PLATFORM_MAC 3 #endif /* ITT_PLATFORM_MAC */ #ifndef ITT_PLATFORM # if ITT_OS==ITT_OS_WIN # define ITT_PLATFORM ITT_PLATFORM_WIN # elif ITT_OS==ITT_OS_MAC # define ITT_PLATFORM ITT_PLATFORM_MAC # else # define ITT_PLATFORM ITT_PLATFORM_POSIX # endif #endif /* ITT_PLATFORM */ #if defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif #include #if ITT_PLATFORM==ITT_PLATFORM_WIN #include #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #include #if defined(UNICODE) || defined(_UNICODE) #include #endif /* UNICODE || _UNICODE */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #ifndef CDECL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define CDECL __cdecl # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define CDECL __attribute__ ((cdecl)) # else /* _M_IX86 || __i386__ */ # define CDECL /* actual only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* CDECL */ #ifndef STDCALL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define STDCALL __stdcall # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define STDCALL __attribute__ ((stdcall)) # else /* _M_IX86 || __i386__ */ # define STDCALL /* supported only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* STDCALL */ #define ITTAPI CDECL #define LIBITTAPI CDECL /* TODO: Temporary for compatibility! */ #define ITTAPI_CALL CDECL #define LIBITTAPI_CALL CDECL #if ITT_PLATFORM==ITT_PLATFORM_WIN /* use __forceinline (VC++ specific) */ #define ITT_INLINE __forceinline #define ITT_INLINE_ATTRIBUTE /* nothing */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /* * Generally, functions are not inlined unless optimization is specified. * For functions declared inline, this attribute inlines the function even * if no optimization level was specified. */ #ifdef __STRICT_ANSI__ #define ITT_INLINE static inline #else /* __STRICT_ANSI__ */ #define ITT_INLINE static inline #endif /* __STRICT_ANSI__ */ #define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline, unused)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @endcond */ #ifdef INTEL_ITTNOTIFY_ENABLE_LEGACY # if ITT_PLATFORM==ITT_PLATFORM_WIN # pragma message("WARNING!!! Deprecated API is used. Please undefine INTEL_ITTNOTIFY_ENABLE_LEGACY macro") # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ // #warning usage leads to ICC's compilation error // # warning "Deprecated API is used. Please undefine INTEL_ITTNOTIFY_ENABLE_LEGACY macro" # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # include "legacy/ittnotify.h" #endif /* INTEL_ITTNOTIFY_ENABLE_LEGACY */ /** @cond exclude_from_documentation */ /* Helper macro for joining tokens */ #define ITT_JOIN_AUX(p,n) p##n #define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) #ifdef ITT_MAJOR #undef ITT_MAJOR #endif #ifdef ITT_MINOR #undef ITT_MINOR #endif #define ITT_MAJOR 3 #define ITT_MINOR 0 /* Standard versioning of a token with major and minor version numbers */ #define ITT_VERSIONIZE(x) \ ITT_JOIN(x, \ ITT_JOIN(_, \ ITT_JOIN(ITT_MAJOR, \ ITT_JOIN(_, ITT_MINOR)))) #ifndef INTEL_ITTNOTIFY_PREFIX # define INTEL_ITTNOTIFY_PREFIX __itt_ #endif /* INTEL_ITTNOTIFY_PREFIX */ #ifndef INTEL_ITTNOTIFY_POSTFIX # define INTEL_ITTNOTIFY_POSTFIX _ptr_ #endif /* INTEL_ITTNOTIFY_POSTFIX */ #define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) #define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) #define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_VOID_D0(n,d) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_VOID_D1(n,d,x) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_VOID_D2(n,d,x,y) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_VOID_D3(n,d,x,y,z) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #define ITTNOTIFY_DATA_D0(n,d) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_DATA_D1(n,d,x) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_DATA_D2(n,d,x,y) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_DATA_D3(n,d,x,y,z) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #ifdef ITT_STUB #undef ITT_STUB #endif #ifdef ITT_STUBV #undef ITT_STUBV #endif #define ITT_STUBV(api,type,name,args) \ typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); #define ITT_STUB ITT_STUBV /** @endcond */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @cond exclude_from_gpa_documentation */ /** * @defgroup public Public API * @{ * @} */ /** * @defgroup control Collection Control * @ingroup public * General behavior: application continues to run, but no profiling information is being collected * * Pausing occurs not only for the current thread but for all process as well as spawned processes * - Intel(R) Parallel Inspector and Intel(R) Inspector XE: * - Does not analyze or report errors that involve memory access. * - Other errors are reported as usual. Pausing data collection in * Intel(R) Parallel Inspector and Intel(R) Inspector XE * only pauses tracing and analyzing memory access. * It does not pause tracing or analyzing threading APIs. * . * - Intel(R) Parallel Amplifier and Intel(R) VTune(TM) Amplifier XE: * - Does continue to record when new threads are started. * . * - Other effects: * - Possible reduction of runtime overhead. * . * @{ */ /** @brief Pause collection */ void ITTAPI __itt_pause(void); /** @brief Resume collection */ void ITTAPI __itt_resume(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, pause, (void)) ITT_STUBV(ITTAPI, void, resume, (void)) #define __itt_pause ITTNOTIFY_VOID(pause) #define __itt_pause_ptr ITTNOTIFY_NAME(pause) #define __itt_resume ITTNOTIFY_VOID(resume) #define __itt_resume_ptr ITTNOTIFY_NAME(resume) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_pause() #define __itt_pause_ptr 0 #define __itt_resume() #define __itt_resume_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_pause_ptr 0 #define __itt_resume_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} control group */ /** @endcond */ /** * @defgroup threads Threads * @ingroup public * Give names to threads * @{ */ /** * @brief Sets thread name of calling thread * @param[in] name - name of thread */ #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_thread_set_nameA(const char *name); void ITTAPI __itt_thread_set_nameW(const wchar_t *name); #if defined(UNICODE) || defined(_UNICODE) # define __itt_thread_set_name __itt_thread_set_nameW # define __itt_thread_set_name_ptr __itt_thread_set_nameW_ptr #else /* UNICODE */ # define __itt_thread_set_name __itt_thread_set_nameA # define __itt_thread_set_name_ptr __itt_thread_set_nameA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ void ITTAPI __itt_thread_set_name(const char *name); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, thread_set_nameA, (const char *name)) ITT_STUBV(ITTAPI, void, thread_set_nameW, (const wchar_t *name)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, thread_set_name, (const char *name)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_thread_set_nameA ITTNOTIFY_VOID(thread_set_nameA) #define __itt_thread_set_nameA_ptr ITTNOTIFY_NAME(thread_set_nameA) #define __itt_thread_set_nameW ITTNOTIFY_VOID(thread_set_nameW) #define __itt_thread_set_nameW_ptr ITTNOTIFY_NAME(thread_set_nameW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_thread_set_name ITTNOTIFY_VOID(thread_set_name) #define __itt_thread_set_name_ptr ITTNOTIFY_NAME(thread_set_name) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_thread_set_nameA(name) #define __itt_thread_set_nameA_ptr 0 #define __itt_thread_set_nameW(name) #define __itt_thread_set_nameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_thread_set_name(name) #define __itt_thread_set_name_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_thread_set_nameA_ptr 0 #define __itt_thread_set_nameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_thread_set_name_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @cond exclude_from_gpa_documentation */ /** * @brief Mark current thread as ignored from this point on, for the duration of its existence. */ void ITTAPI __itt_thread_ignore(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, thread_ignore, (void)) #define __itt_thread_ignore ITTNOTIFY_VOID(thread_ignore) #define __itt_thread_ignore_ptr ITTNOTIFY_NAME(thread_ignore) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_thread_ignore() #define __itt_thread_ignore_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_thread_ignore_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} threads group */ /** * @defgroup suppress Error suppression * @ingroup public * General behavior: application continues to run, but errors are suppressed * * @{ */ /*****************************************************************//** * @name group of functions used for error suppression in correctness tools *********************************************************************/ /** @{ */ /** * @hideinitializer * @brief possible value for suppression mask */ #define __itt_suppress_all_errors 0x7fffffff /** * @hideinitializer * @brief possible value for suppression mask (suppresses errors from threading analysis) */ #define __itt_suppress_threading_errors 0x000000ff /** * @hideinitializer * @brief possible value for suppression mask (suppresses errors from memory analysis) */ #define __itt_suppress_memory_errors 0x0000ff00 /** * @brief Start suppressing errors identified in mask on this thread */ void ITTAPI __itt_suppress_push(unsigned int mask); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, suppress_push, (unsigned int mask)) #define __itt_suppress_push ITTNOTIFY_VOID(suppress_push) #define __itt_suppress_push_ptr ITTNOTIFY_NAME(suppress_push) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_suppress_push(mask) #define __itt_suppress_push_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_suppress_push_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Undo the effects of the matching call to __itt_suppress_push */ void ITTAPI __itt_suppress_pop(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, suppress_pop, (void)) #define __itt_suppress_pop ITTNOTIFY_VOID(suppress_pop) #define __itt_suppress_pop_ptr ITTNOTIFY_NAME(suppress_pop) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_suppress_pop() #define __itt_suppress_pop_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_suppress_pop_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @enum __itt_model_disable * @brief Enumerator for the disable methods */ typedef enum __itt_suppress_mode { __itt_unsuppress_range, __itt_suppress_range } __itt_suppress_mode_t; /** * @brief Mark a range of memory for error suppression or unsuppression for error types included in mask */ void ITTAPI __itt_suppress_mark_range(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, suppress_mark_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size)) #define __itt_suppress_mark_range ITTNOTIFY_VOID(suppress_mark_range) #define __itt_suppress_mark_range_ptr ITTNOTIFY_NAME(suppress_mark_range) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_suppress_mark_range(mask) #define __itt_suppress_mark_range_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_suppress_mark_range_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Undo the effect of a matching call to __itt_suppress_mark_range. If not matching * call is found, nothing is changed. */ void ITTAPI __itt_suppress_clear_range(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, suppress_clear_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size)) #define __itt_suppress_clear_range ITTNOTIFY_VOID(suppress_clear_range) #define __itt_suppress_clear_range_ptr ITTNOTIFY_NAME(suppress_clear_range) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_suppress_clear_range(mask) #define __itt_suppress_clear_range_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_suppress_clear_range_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} */ /** @} suppress group */ /** * @defgroup sync Synchronization * @ingroup public * Indicate user-written synchronization code * @{ */ /** * @hideinitializer * @brief possible value of attribute argument for sync object type */ #define __itt_attr_barrier 1 /** * @hideinitializer * @brief possible value of attribute argument for sync object type */ #define __itt_attr_mutex 2 /** @brief Name a synchronization object @param[in] addr Handle for the synchronization object. You should use a real address to uniquely identify the synchronization object. @param[in] objtype null-terminated object type string. If NULL is passed, the name will be "User Synchronization". @param[in] objname null-terminated object name string. If NULL, no name will be assigned to the object. @param[in] attribute one of [#__itt_attr_barrier, #__itt_attr_mutex] */ #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_sync_createA(void *addr, const char *objtype, const char *objname, int attribute); void ITTAPI __itt_sync_createW(void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute); #if defined(UNICODE) || defined(_UNICODE) # define __itt_sync_create __itt_sync_createW # define __itt_sync_create_ptr __itt_sync_createW_ptr #else /* UNICODE */ # define __itt_sync_create __itt_sync_createA # define __itt_sync_create_ptr __itt_sync_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ void ITTAPI __itt_sync_create (void *addr, const char *objtype, const char *objname, int attribute); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, sync_createA, (void *addr, const char *objtype, const char *objname, int attribute)) ITT_STUBV(ITTAPI, void, sync_createW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, sync_create, (void *addr, const char* objtype, const char* objname, int attribute)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_createA ITTNOTIFY_VOID(sync_createA) #define __itt_sync_createA_ptr ITTNOTIFY_NAME(sync_createA) #define __itt_sync_createW ITTNOTIFY_VOID(sync_createW) #define __itt_sync_createW_ptr ITTNOTIFY_NAME(sync_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_create ITTNOTIFY_VOID(sync_create) #define __itt_sync_create_ptr ITTNOTIFY_NAME(sync_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_createA(addr, objtype, objname, attribute) #define __itt_sync_createA_ptr 0 #define __itt_sync_createW(addr, objtype, objname, attribute) #define __itt_sync_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_create(addr, objtype, objname, attribute) #define __itt_sync_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_createA_ptr 0 #define __itt_sync_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief Rename a synchronization object You can use the rename call to assign or reassign a name to a given synchronization object. @param[in] addr handle for the synchronization object. @param[in] name null-terminated object name string. */ #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_sync_renameA(void *addr, const char *name); void ITTAPI __itt_sync_renameW(void *addr, const wchar_t *name); #if defined(UNICODE) || defined(_UNICODE) # define __itt_sync_rename __itt_sync_renameW # define __itt_sync_rename_ptr __itt_sync_renameW_ptr #else /* UNICODE */ # define __itt_sync_rename __itt_sync_renameA # define __itt_sync_rename_ptr __itt_sync_renameA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ void ITTAPI __itt_sync_rename(void *addr, const char *name); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, sync_renameA, (void *addr, const char *name)) ITT_STUBV(ITTAPI, void, sync_renameW, (void *addr, const wchar_t *name)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, sync_rename, (void *addr, const char *name)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_renameA ITTNOTIFY_VOID(sync_renameA) #define __itt_sync_renameA_ptr ITTNOTIFY_NAME(sync_renameA) #define __itt_sync_renameW ITTNOTIFY_VOID(sync_renameW) #define __itt_sync_renameW_ptr ITTNOTIFY_NAME(sync_renameW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_rename ITTNOTIFY_VOID(sync_rename) #define __itt_sync_rename_ptr ITTNOTIFY_NAME(sync_rename) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_renameA(addr, name) #define __itt_sync_renameA_ptr 0 #define __itt_sync_renameW(addr, name) #define __itt_sync_renameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_rename(addr, name) #define __itt_sync_rename_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_renameA_ptr 0 #define __itt_sync_renameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_rename_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief Destroy a synchronization object. @param addr Handle for the synchronization object. */ void ITTAPI __itt_sync_destroy(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, sync_destroy, (void *addr)) #define __itt_sync_destroy ITTNOTIFY_VOID(sync_destroy) #define __itt_sync_destroy_ptr ITTNOTIFY_NAME(sync_destroy) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_sync_destroy(addr) #define __itt_sync_destroy_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_sync_destroy_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /*****************************************************************//** * @name group of functions is used for performance measurement tools *********************************************************************/ /** @{ */ /** * @brief Enter spin loop on user-defined sync object */ void ITTAPI __itt_sync_prepare(void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, sync_prepare, (void *addr)) #define __itt_sync_prepare ITTNOTIFY_VOID(sync_prepare) #define __itt_sync_prepare_ptr ITTNOTIFY_NAME(sync_prepare) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_sync_prepare(addr) #define __itt_sync_prepare_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_sync_prepare_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Quit spin loop without acquiring spin object */ void ITTAPI __itt_sync_cancel(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, sync_cancel, (void *addr)) #define __itt_sync_cancel ITTNOTIFY_VOID(sync_cancel) #define __itt_sync_cancel_ptr ITTNOTIFY_NAME(sync_cancel) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_sync_cancel(addr) #define __itt_sync_cancel_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_sync_cancel_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Successful spin loop completion (sync object acquired) */ void ITTAPI __itt_sync_acquired(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, sync_acquired, (void *addr)) #define __itt_sync_acquired ITTNOTIFY_VOID(sync_acquired) #define __itt_sync_acquired_ptr ITTNOTIFY_NAME(sync_acquired) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_sync_acquired(addr) #define __itt_sync_acquired_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_sync_acquired_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Start sync object releasing code. Is called before the lock release call. */ void ITTAPI __itt_sync_releasing(void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, sync_releasing, (void *addr)) #define __itt_sync_releasing ITTNOTIFY_VOID(sync_releasing) #define __itt_sync_releasing_ptr ITTNOTIFY_NAME(sync_releasing) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_sync_releasing(addr) #define __itt_sync_releasing_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_sync_releasing_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} */ /** @} sync group */ /**************************************************************//** * @name group of functions is used for correctness checking tools ******************************************************************/ /** @{ */ /** * @ingroup legacy * @deprecated Legacy API * @brief Fast synchronization which does no require spinning. * - This special function is to be used by TBB and OpenMP libraries only when they know * there is no spin but they need to suppress TC warnings about shared variable modifications. * - It only has corresponding pointers in static library and does not have corresponding function * in dynamic library. * @see void __itt_sync_prepare(void* addr); */ void ITTAPI __itt_fsync_prepare(void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, fsync_prepare, (void *addr)) #define __itt_fsync_prepare ITTNOTIFY_VOID(fsync_prepare) #define __itt_fsync_prepare_ptr ITTNOTIFY_NAME(fsync_prepare) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_fsync_prepare(addr) #define __itt_fsync_prepare_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_fsync_prepare_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup legacy * @deprecated Legacy API * @brief Fast synchronization which does no require spinning. * - This special function is to be used by TBB and OpenMP libraries only when they know * there is no spin but they need to suppress TC warnings about shared variable modifications. * - It only has corresponding pointers in static library and does not have corresponding function * in dynamic library. * @see void __itt_sync_cancel(void *addr); */ void ITTAPI __itt_fsync_cancel(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, fsync_cancel, (void *addr)) #define __itt_fsync_cancel ITTNOTIFY_VOID(fsync_cancel) #define __itt_fsync_cancel_ptr ITTNOTIFY_NAME(fsync_cancel) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_fsync_cancel(addr) #define __itt_fsync_cancel_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_fsync_cancel_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup legacy * @deprecated Legacy API * @brief Fast synchronization which does no require spinning. * - This special function is to be used by TBB and OpenMP libraries only when they know * there is no spin but they need to suppress TC warnings about shared variable modifications. * - It only has corresponding pointers in static library and does not have corresponding function * in dynamic library. * @see void __itt_sync_acquired(void *addr); */ void ITTAPI __itt_fsync_acquired(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, fsync_acquired, (void *addr)) #define __itt_fsync_acquired ITTNOTIFY_VOID(fsync_acquired) #define __itt_fsync_acquired_ptr ITTNOTIFY_NAME(fsync_acquired) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_fsync_acquired(addr) #define __itt_fsync_acquired_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_fsync_acquired_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup legacy * @deprecated Legacy API * @brief Fast synchronization which does no require spinning. * - This special function is to be used by TBB and OpenMP libraries only when they know * there is no spin but they need to suppress TC warnings about shared variable modifications. * - It only has corresponding pointers in static library and does not have corresponding function * in dynamic library. * @see void __itt_sync_releasing(void* addr); */ void ITTAPI __itt_fsync_releasing(void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, fsync_releasing, (void *addr)) #define __itt_fsync_releasing ITTNOTIFY_VOID(fsync_releasing) #define __itt_fsync_releasing_ptr ITTNOTIFY_NAME(fsync_releasing) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_fsync_releasing(addr) #define __itt_fsync_releasing_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_fsync_releasing_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} */ /** * @defgroup model Modeling by Intel(R) Parallel Advisor * @ingroup public * This is the subset of itt used for modeling by Intel(R) Parallel Advisor. * This API is called ONLY using annotate.h, by "Annotation" macros * the user places in their sources during the parallelism modeling steps. * * site_begin/end and task_begin/end take the address of handle variables, * which are writeable by the API. Handles must be 0 initialized prior * to the first call to begin, or may cause a run-time failure. * The handles are initialized in a multi-thread safe way by the API if * the handle is 0. The commonly expected idiom is one static handle to * identify a site or task. If a site or task of the same name has already * been started during this collection, the same handle MAY be returned, * but is not required to be - it is unspecified if data merging is done * based on name. These routines also take an instance variable. Like * the lexical instance, these must be 0 initialized. Unlike the lexical * instance, this is used to track a single dynamic instance. * * API used by the Intel(R) Parallel Advisor to describe potential concurrency * and related activities. User-added source annotations expand to calls * to these procedures to enable modeling of a hypothetical concurrent * execution serially. * @{ */ #if !defined(_ADVISOR_ANNOTATE_H_) || defined(ANNOTATE_EXPAND_NULL) typedef void* __itt_model_site; /*!< @brief handle for lexical site */ typedef void* __itt_model_site_instance; /*!< @brief handle for dynamic instance */ typedef void* __itt_model_task; /*!< @brief handle for lexical site */ typedef void* __itt_model_task_instance; /*!< @brief handle for dynamic instance */ /** * @enum __itt_model_disable * @brief Enumerator for the disable methods */ typedef enum { __itt_model_disable_observation, __itt_model_disable_collection } __itt_model_disable; #endif /* !_ADVISOR_ANNOTATE_H_ || ANNOTATE_EXPAND_NULL */ /** * @brief ANNOTATE_SITE_BEGIN/ANNOTATE_SITE_END support. * * site_begin/end model a potential concurrency site. * site instances may be recursively nested with themselves. * site_end exits the most recently started but unended site for the current * thread. The handle passed to end may be used to validate structure. * Instances of a site encountered on different threads concurrently * are considered completely distinct. If the site name for two different * lexical sites match, it is unspecified whether they are treated as the * same or different for data presentation. */ void ITTAPI __itt_model_site_begin(__itt_model_site *site, __itt_model_site_instance *instance, const char *name); #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_model_site_beginW(const wchar_t *name); #endif void ITTAPI __itt_model_site_beginA(const char *name); void ITTAPI __itt_model_site_beginAL(const char *name, size_t siteNameLen); void ITTAPI __itt_model_site_end (__itt_model_site *site, __itt_model_site_instance *instance); void ITTAPI __itt_model_site_end_2(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_site_begin, (__itt_model_site *site, __itt_model_site_instance *instance, const char *name)) #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, model_site_beginW, (const wchar_t *name)) #endif ITT_STUBV(ITTAPI, void, model_site_beginA, (const char *name)) ITT_STUBV(ITTAPI, void, model_site_beginAL, (const char *name, size_t siteNameLen)) ITT_STUBV(ITTAPI, void, model_site_end, (__itt_model_site *site, __itt_model_site_instance *instance)) ITT_STUBV(ITTAPI, void, model_site_end_2, (void)) #define __itt_model_site_begin ITTNOTIFY_VOID(model_site_begin) #define __itt_model_site_begin_ptr ITTNOTIFY_NAME(model_site_begin) #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_model_site_beginW ITTNOTIFY_VOID(model_site_beginW) #define __itt_model_site_beginW_ptr ITTNOTIFY_NAME(model_site_beginW) #endif #define __itt_model_site_beginA ITTNOTIFY_VOID(model_site_beginA) #define __itt_model_site_beginA_ptr ITTNOTIFY_NAME(model_site_beginA) #define __itt_model_site_beginAL ITTNOTIFY_VOID(model_site_beginAL) #define __itt_model_site_beginAL_ptr ITTNOTIFY_NAME(model_site_beginAL) #define __itt_model_site_end ITTNOTIFY_VOID(model_site_end) #define __itt_model_site_end_ptr ITTNOTIFY_NAME(model_site_end) #define __itt_model_site_end_2 ITTNOTIFY_VOID(model_site_end_2) #define __itt_model_site_end_2_ptr ITTNOTIFY_NAME(model_site_end_2) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_site_begin(site, instance, name) #define __itt_model_site_begin_ptr 0 #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_model_site_beginW(name) #define __itt_model_site_beginW_ptr 0 #endif #define __itt_model_site_beginA(name) #define __itt_model_site_beginA_ptr 0 #define __itt_model_site_beginAL(name, siteNameLen) #define __itt_model_site_beginAL_ptr 0 #define __itt_model_site_end(site, instance) #define __itt_model_site_end_ptr 0 #define __itt_model_site_end_2() #define __itt_model_site_end_2_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_site_begin_ptr 0 #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_model_site_beginW_ptr 0 #endif #define __itt_model_site_beginA_ptr 0 #define __itt_model_site_beginAL_ptr 0 #define __itt_model_site_end_ptr 0 #define __itt_model_site_end_2_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_TASK_BEGIN/ANNOTATE_TASK_END support * * task_begin/end model a potential task, which is contained within the most * closely enclosing dynamic site. task_end exits the most recently started * but unended task. The handle passed to end may be used to validate * structure. It is unspecified if bad dynamic nesting is detected. If it * is, it should be encoded in the resulting data collection. The collector * should not fail due to construct nesting issues, nor attempt to directly * indicate the problem. */ void ITTAPI __itt_model_task_begin(__itt_model_task *task, __itt_model_task_instance *instance, const char *name); #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_model_task_beginW(const wchar_t *name); void ITTAPI __itt_model_iteration_taskW(const wchar_t *name); #endif void ITTAPI __itt_model_task_beginA(const char *name); void ITTAPI __itt_model_task_beginAL(const char *name, size_t taskNameLen); void ITTAPI __itt_model_iteration_taskA(const char *name); void ITTAPI __itt_model_iteration_taskAL(const char *name, size_t taskNameLen); void ITTAPI __itt_model_task_end (__itt_model_task *task, __itt_model_task_instance *instance); void ITTAPI __itt_model_task_end_2(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_task_begin, (__itt_model_task *task, __itt_model_task_instance *instance, const char *name)) #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, model_task_beginW, (const wchar_t *name)) ITT_STUBV(ITTAPI, void, model_iteration_taskW, (const wchar_t *name)) #endif ITT_STUBV(ITTAPI, void, model_task_beginA, (const char *name)) ITT_STUBV(ITTAPI, void, model_task_beginAL, (const char *name, size_t taskNameLen)) ITT_STUBV(ITTAPI, void, model_iteration_taskA, (const char *name)) ITT_STUBV(ITTAPI, void, model_iteration_taskAL, (const char *name, size_t taskNameLen)) ITT_STUBV(ITTAPI, void, model_task_end, (__itt_model_task *task, __itt_model_task_instance *instance)) ITT_STUBV(ITTAPI, void, model_task_end_2, (void)) #define __itt_model_task_begin ITTNOTIFY_VOID(model_task_begin) #define __itt_model_task_begin_ptr ITTNOTIFY_NAME(model_task_begin) #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_model_task_beginW ITTNOTIFY_VOID(model_task_beginW) #define __itt_model_task_beginW_ptr ITTNOTIFY_NAME(model_task_beginW) #define __itt_model_iteration_taskW ITTNOTIFY_VOID(model_iteration_taskW) #define __itt_model_iteration_taskW_ptr ITTNOTIFY_NAME(model_iteration_taskW) #endif #define __itt_model_task_beginA ITTNOTIFY_VOID(model_task_beginA) #define __itt_model_task_beginA_ptr ITTNOTIFY_NAME(model_task_beginA) #define __itt_model_task_beginAL ITTNOTIFY_VOID(model_task_beginAL) #define __itt_model_task_beginAL_ptr ITTNOTIFY_NAME(model_task_beginAL) #define __itt_model_iteration_taskA ITTNOTIFY_VOID(model_iteration_taskA) #define __itt_model_iteration_taskA_ptr ITTNOTIFY_NAME(model_iteration_taskA) #define __itt_model_iteration_taskAL ITTNOTIFY_VOID(model_iteration_taskAL) #define __itt_model_iteration_taskAL_ptr ITTNOTIFY_NAME(model_iteration_taskAL) #define __itt_model_task_end ITTNOTIFY_VOID(model_task_end) #define __itt_model_task_end_ptr ITTNOTIFY_NAME(model_task_end) #define __itt_model_task_end_2 ITTNOTIFY_VOID(model_task_end_2) #define __itt_model_task_end_2_ptr ITTNOTIFY_NAME(model_task_end_2) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_task_begin(task, instance, name) #define __itt_model_task_begin_ptr 0 #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_model_task_beginW(name) #define __itt_model_task_beginW_ptr 0 #endif #define __itt_model_task_beginA(name) #define __itt_model_task_beginA_ptr 0 #define __itt_model_task_beginAL(name, siteNameLen) #define __itt_model_task_beginAL_ptr 0 #define __itt_model_iteration_taskA(name) #define __itt_model_iteration_taskA_ptr 0 #define __itt_model_iteration_taskAL(name, siteNameLen) #define __itt_model_iteration_taskAL_ptr 0 #define __itt_model_task_end(task, instance) #define __itt_model_task_end_ptr 0 #define __itt_model_task_end_2() #define __itt_model_task_end_2_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_task_begin_ptr 0 #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_model_task_beginW_ptr 0 #endif #define __itt_model_task_beginA_ptr 0 #define __itt_model_task_beginAL_ptr 0 #define __itt_model_iteration_taskA_ptr 0 #define __itt_model_iteration_taskAL_ptr 0 #define __itt_model_task_end_ptr 0 #define __itt_model_task_end_2_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_LOCK_ACQUIRE/ANNOTATE_LOCK_RELEASE support * * lock_acquire/release model a potential lock for both lockset and * performance modeling. Each unique address is modeled as a separate * lock, with invalid addresses being valid lock IDs. Specifically: * no storage is accessed by the API at the specified address - it is only * used for lock identification. Lock acquires may be self-nested and are * unlocked by a corresponding number of releases. * (These closely correspond to __itt_sync_acquired/__itt_sync_releasing, * but may not have identical semantics.) */ void ITTAPI __itt_model_lock_acquire(void *lock); void ITTAPI __itt_model_lock_acquire_2(void *lock); void ITTAPI __itt_model_lock_release(void *lock); void ITTAPI __itt_model_lock_release_2(void *lock); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_lock_acquire, (void *lock)) ITT_STUBV(ITTAPI, void, model_lock_acquire_2, (void *lock)) ITT_STUBV(ITTAPI, void, model_lock_release, (void *lock)) ITT_STUBV(ITTAPI, void, model_lock_release_2, (void *lock)) #define __itt_model_lock_acquire ITTNOTIFY_VOID(model_lock_acquire) #define __itt_model_lock_acquire_ptr ITTNOTIFY_NAME(model_lock_acquire) #define __itt_model_lock_acquire_2 ITTNOTIFY_VOID(model_lock_acquire_2) #define __itt_model_lock_acquire_2_ptr ITTNOTIFY_NAME(model_lock_acquire_2) #define __itt_model_lock_release ITTNOTIFY_VOID(model_lock_release) #define __itt_model_lock_release_ptr ITTNOTIFY_NAME(model_lock_release) #define __itt_model_lock_release_2 ITTNOTIFY_VOID(model_lock_release_2) #define __itt_model_lock_release_2_ptr ITTNOTIFY_NAME(model_lock_release_2) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_lock_acquire(lock) #define __itt_model_lock_acquire_ptr 0 #define __itt_model_lock_acquire_2(lock) #define __itt_model_lock_acquire_2_ptr 0 #define __itt_model_lock_release(lock) #define __itt_model_lock_release_ptr 0 #define __itt_model_lock_release_2(lock) #define __itt_model_lock_release_2_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_lock_acquire_ptr 0 #define __itt_model_lock_acquire_2_ptr 0 #define __itt_model_lock_release_ptr 0 #define __itt_model_lock_release_2_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_RECORD_ALLOCATION/ANNOTATE_RECORD_DEALLOCATION support * * record_allocation/deallocation describe user-defined memory allocator * behavior, which may be required for correctness modeling to understand * when storage is not expected to be actually reused across threads. */ void ITTAPI __itt_model_record_allocation (void *addr, size_t size); void ITTAPI __itt_model_record_deallocation(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_record_allocation, (void *addr, size_t size)) ITT_STUBV(ITTAPI, void, model_record_deallocation, (void *addr)) #define __itt_model_record_allocation ITTNOTIFY_VOID(model_record_allocation) #define __itt_model_record_allocation_ptr ITTNOTIFY_NAME(model_record_allocation) #define __itt_model_record_deallocation ITTNOTIFY_VOID(model_record_deallocation) #define __itt_model_record_deallocation_ptr ITTNOTIFY_NAME(model_record_deallocation) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_record_allocation(addr, size) #define __itt_model_record_allocation_ptr 0 #define __itt_model_record_deallocation(addr) #define __itt_model_record_deallocation_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_record_allocation_ptr 0 #define __itt_model_record_deallocation_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_INDUCTION_USES support * * Note particular storage is inductive through the end of the current site */ void ITTAPI __itt_model_induction_uses(void* addr, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_induction_uses, (void *addr, size_t size)) #define __itt_model_induction_uses ITTNOTIFY_VOID(model_induction_uses) #define __itt_model_induction_uses_ptr ITTNOTIFY_NAME(model_induction_uses) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_induction_uses(addr, size) #define __itt_model_induction_uses_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_induction_uses_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_REDUCTION_USES support * * Note particular storage is used for reduction through the end * of the current site */ void ITTAPI __itt_model_reduction_uses(void* addr, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_reduction_uses, (void *addr, size_t size)) #define __itt_model_reduction_uses ITTNOTIFY_VOID(model_reduction_uses) #define __itt_model_reduction_uses_ptr ITTNOTIFY_NAME(model_reduction_uses) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_reduction_uses(addr, size) #define __itt_model_reduction_uses_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_reduction_uses_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_OBSERVE_USES support * * Have correctness modeling record observations about uses of storage * through the end of the current site */ void ITTAPI __itt_model_observe_uses(void* addr, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_observe_uses, (void *addr, size_t size)) #define __itt_model_observe_uses ITTNOTIFY_VOID(model_observe_uses) #define __itt_model_observe_uses_ptr ITTNOTIFY_NAME(model_observe_uses) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_observe_uses(addr, size) #define __itt_model_observe_uses_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_observe_uses_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_CLEAR_USES support * * Clear the special handling of a piece of storage related to induction, * reduction or observe_uses */ void ITTAPI __itt_model_clear_uses(void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_clear_uses, (void *addr)) #define __itt_model_clear_uses ITTNOTIFY_VOID(model_clear_uses) #define __itt_model_clear_uses_ptr ITTNOTIFY_NAME(model_clear_uses) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_clear_uses(addr) #define __itt_model_clear_uses_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_clear_uses_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief ANNOTATE_DISABLE_*_PUSH/ANNOTATE_DISABLE_*_POP support * * disable_push/disable_pop push and pop disabling based on a parameter. * Disabling observations stops processing of memory references during * correctness modeling, and all annotations that occur in the disabled * region. This allows description of code that is expected to be handled * specially during conversion to parallelism or that is not recognized * by tools (e.g. some kinds of synchronization operations.) * This mechanism causes all annotations in the disabled region, other * than disable_push and disable_pop, to be ignored. (For example, this * might validly be used to disable an entire parallel site and the contained * tasks and locking in it for data collection purposes.) * The disable for collection is a more expensive operation, but reduces * collector overhead significantly. This applies to BOTH correctness data * collection and performance data collection. For example, a site * containing a task might only enable data collection for the first 10 * iterations. Both performance and correctness data should reflect this, * and the program should run as close to full speed as possible when * collection is disabled. */ void ITTAPI __itt_model_disable_push(__itt_model_disable x); void ITTAPI __itt_model_disable_pop(void); void ITTAPI __itt_model_aggregate_task(size_t x); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, model_disable_push, (__itt_model_disable x)) ITT_STUBV(ITTAPI, void, model_disable_pop, (void)) ITT_STUBV(ITTAPI, void, model_aggregate_task, (size_t x)) #define __itt_model_disable_push ITTNOTIFY_VOID(model_disable_push) #define __itt_model_disable_push_ptr ITTNOTIFY_NAME(model_disable_push) #define __itt_model_disable_pop ITTNOTIFY_VOID(model_disable_pop) #define __itt_model_disable_pop_ptr ITTNOTIFY_NAME(model_disable_pop) #define __itt_model_aggregate_task ITTNOTIFY_VOID(model_aggregate_task) #define __itt_model_aggregate_task_ptr ITTNOTIFY_NAME(model_aggregate_task) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_model_disable_push(x) #define __itt_model_disable_push_ptr 0 #define __itt_model_disable_pop() #define __itt_model_disable_pop_ptr 0 #define __itt_model_aggregate_task(x) #define __itt_model_aggregate_task_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_model_disable_push_ptr 0 #define __itt_model_disable_pop_ptr 0 #define __itt_model_aggregate_task_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} model group */ /** * @defgroup heap Heap * @ingroup public * Heap group * @{ */ typedef void* __itt_heap_function; /** * @brief Create an identification for heap function * @return non-zero identifier or NULL */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_heap_function ITTAPI __itt_heap_function_createA(const char* name, const char* domain); __itt_heap_function ITTAPI __itt_heap_function_createW(const wchar_t* name, const wchar_t* domain); #if defined(UNICODE) || defined(_UNICODE) # define __itt_heap_function_create __itt_heap_function_createW # define __itt_heap_function_create_ptr __itt_heap_function_createW_ptr #else # define __itt_heap_function_create __itt_heap_function_createA # define __itt_heap_function_create_ptr __itt_heap_function_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_heap_function ITTAPI __itt_heap_function_create(const char* name, const char* domain); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createA, (const char* name, const char* domain)) ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createW, (const wchar_t* name, const wchar_t* domain)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_heap_function, heap_function_create, (const char* name, const char* domain)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_heap_function_createA ITTNOTIFY_DATA(heap_function_createA) #define __itt_heap_function_createA_ptr ITTNOTIFY_NAME(heap_function_createA) #define __itt_heap_function_createW ITTNOTIFY_DATA(heap_function_createW) #define __itt_heap_function_createW_ptr ITTNOTIFY_NAME(heap_function_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_heap_function_create ITTNOTIFY_DATA(heap_function_create) #define __itt_heap_function_create_ptr ITTNOTIFY_NAME(heap_function_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_heap_function_createA(name, domain) (__itt_heap_function)0 #define __itt_heap_function_createA_ptr 0 #define __itt_heap_function_createW(name, domain) (__itt_heap_function)0 #define __itt_heap_function_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_heap_function_create(name, domain) (__itt_heap_function)0 #define __itt_heap_function_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_heap_function_createA_ptr 0 #define __itt_heap_function_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_heap_function_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an allocation begin occurrence. */ void ITTAPI __itt_heap_allocate_begin(__itt_heap_function h, size_t size, int initialized); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_allocate_begin, (__itt_heap_function h, size_t size, int initialized)) #define __itt_heap_allocate_begin ITTNOTIFY_VOID(heap_allocate_begin) #define __itt_heap_allocate_begin_ptr ITTNOTIFY_NAME(heap_allocate_begin) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_allocate_begin(h, size, initialized) #define __itt_heap_allocate_begin_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_allocate_begin_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an allocation end occurrence. */ void ITTAPI __itt_heap_allocate_end(__itt_heap_function h, void** addr, size_t size, int initialized); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_allocate_end, (__itt_heap_function h, void** addr, size_t size, int initialized)) #define __itt_heap_allocate_end ITTNOTIFY_VOID(heap_allocate_end) #define __itt_heap_allocate_end_ptr ITTNOTIFY_NAME(heap_allocate_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_allocate_end(h, addr, size, initialized) #define __itt_heap_allocate_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_allocate_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an free begin occurrence. */ void ITTAPI __itt_heap_free_begin(__itt_heap_function h, void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_free_begin, (__itt_heap_function h, void* addr)) #define __itt_heap_free_begin ITTNOTIFY_VOID(heap_free_begin) #define __itt_heap_free_begin_ptr ITTNOTIFY_NAME(heap_free_begin) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_free_begin(h, addr) #define __itt_heap_free_begin_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_free_begin_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an free end occurrence. */ void ITTAPI __itt_heap_free_end(__itt_heap_function h, void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_free_end, (__itt_heap_function h, void* addr)) #define __itt_heap_free_end ITTNOTIFY_VOID(heap_free_end) #define __itt_heap_free_end_ptr ITTNOTIFY_NAME(heap_free_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_free_end(h, addr) #define __itt_heap_free_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_free_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an reallocation begin occurrence. */ void ITTAPI __itt_heap_reallocate_begin(__itt_heap_function h, void* addr, size_t new_size, int initialized); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_reallocate_begin, (__itt_heap_function h, void* addr, size_t new_size, int initialized)) #define __itt_heap_reallocate_begin ITTNOTIFY_VOID(heap_reallocate_begin) #define __itt_heap_reallocate_begin_ptr ITTNOTIFY_NAME(heap_reallocate_begin) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_reallocate_begin(h, addr, new_size, initialized) #define __itt_heap_reallocate_begin_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_reallocate_begin_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an reallocation end occurrence. */ void ITTAPI __itt_heap_reallocate_end(__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_reallocate_end, (__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized)) #define __itt_heap_reallocate_end ITTNOTIFY_VOID(heap_reallocate_end) #define __itt_heap_reallocate_end_ptr ITTNOTIFY_NAME(heap_reallocate_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_reallocate_end(h, addr, new_addr, new_size, initialized) #define __itt_heap_reallocate_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_reallocate_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief internal access begin */ void ITTAPI __itt_heap_internal_access_begin(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_internal_access_begin, (void)) #define __itt_heap_internal_access_begin ITTNOTIFY_VOID(heap_internal_access_begin) #define __itt_heap_internal_access_begin_ptr ITTNOTIFY_NAME(heap_internal_access_begin) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_internal_access_begin() #define __itt_heap_internal_access_begin_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_internal_access_begin_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief internal access end */ void ITTAPI __itt_heap_internal_access_end(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_internal_access_end, (void)) #define __itt_heap_internal_access_end ITTNOTIFY_VOID(heap_internal_access_end) #define __itt_heap_internal_access_end_ptr ITTNOTIFY_NAME(heap_internal_access_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_internal_access_end() #define __itt_heap_internal_access_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_internal_access_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief record memory growth begin */ void ITTAPI __itt_heap_record_memory_growth_begin(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_record_memory_growth_begin, (void)) #define __itt_heap_record_memory_growth_begin ITTNOTIFY_VOID(heap_record_memory_growth_begin) #define __itt_heap_record_memory_growth_begin_ptr ITTNOTIFY_NAME(heap_record_memory_growth_begin) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_record_memory_growth_begin() #define __itt_heap_record_memory_growth_begin_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_record_memory_growth_begin_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief record memory growth end */ void ITTAPI __itt_heap_record_memory_growth_end(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_record_memory_growth_end, (void)) #define __itt_heap_record_memory_growth_end ITTNOTIFY_VOID(heap_record_memory_growth_end) #define __itt_heap_record_memory_growth_end_ptr ITTNOTIFY_NAME(heap_record_memory_growth_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_record_memory_growth_end() #define __itt_heap_record_memory_growth_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_record_memory_growth_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Specify the type of heap detection/reporting to modify. */ /** * @hideinitializer * @brief Report on memory leaks. */ #define __itt_heap_leaks 0x00000001 /** * @hideinitializer * @brief Report on memory growth. */ #define __itt_heap_growth 0x00000002 /** @brief heap reset detection */ void ITTAPI __itt_heap_reset_detection(unsigned int reset_mask); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_reset_detection, (unsigned int reset_mask)) #define __itt_heap_reset_detection ITTNOTIFY_VOID(heap_reset_detection) #define __itt_heap_reset_detection_ptr ITTNOTIFY_NAME(heap_reset_detection) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_reset_detection() #define __itt_heap_reset_detection_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_reset_detection_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief report */ void ITTAPI __itt_heap_record(unsigned int record_mask); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, heap_record, (unsigned int record_mask)) #define __itt_heap_record ITTNOTIFY_VOID(heap_record) #define __itt_heap_record_ptr ITTNOTIFY_NAME(heap_record) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_heap_record() #define __itt_heap_record_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_heap_record_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} heap group */ /** @endcond */ /* ========================================================================== */ /** * @defgroup domains Domains * @ingroup public * Domains group * @{ */ /** @cond exclude_from_documentation */ #pragma pack(push, 8) typedef struct ___itt_domain { volatile int flags; /*!< Zero if disabled, non-zero if enabled. The meaning of different non-zero values is reserved to the runtime */ const char* nameA; /*!< Copy of original name in ASCII. */ #if defined(UNICODE) || defined(_UNICODE) const wchar_t* nameW; /*!< Copy of original name in UNICODE. */ #else /* UNICODE || _UNICODE */ void* nameW; #endif /* UNICODE || _UNICODE */ int extra1; /*!< Reserved to the runtime */ void* extra2; /*!< Reserved to the runtime */ struct ___itt_domain* next; } __itt_domain; #pragma pack(pop) /** @endcond */ /** * @ingroup domains * @brief Create a domain. * Create domain using some domain name: the URI naming style is recommended. * Because the set of domains is expected to be static over the application's * execution time, there is no mechanism to destroy a domain. * Any domain can be accessed by any thread in the process, regardless of * which thread created the domain. This call is thread-safe. * @param[in] name name of domain */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_domain* ITTAPI __itt_domain_createA(const char *name); __itt_domain* ITTAPI __itt_domain_createW(const wchar_t *name); #if defined(UNICODE) || defined(_UNICODE) # define __itt_domain_create __itt_domain_createW # define __itt_domain_create_ptr __itt_domain_createW_ptr #else /* UNICODE */ # define __itt_domain_create __itt_domain_createA # define __itt_domain_create_ptr __itt_domain_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_domain* ITTAPI __itt_domain_create(const char *name); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_domain*, domain_createA, (const char *name)) ITT_STUB(ITTAPI, __itt_domain*, domain_createW, (const wchar_t *name)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_domain*, domain_create, (const char *name)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_domain_createA ITTNOTIFY_DATA(domain_createA) #define __itt_domain_createA_ptr ITTNOTIFY_NAME(domain_createA) #define __itt_domain_createW ITTNOTIFY_DATA(domain_createW) #define __itt_domain_createW_ptr ITTNOTIFY_NAME(domain_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_domain_create ITTNOTIFY_DATA(domain_create) #define __itt_domain_create_ptr ITTNOTIFY_NAME(domain_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_domain_createA(name) (__itt_domain*)0 #define __itt_domain_createA_ptr 0 #define __itt_domain_createW(name) (__itt_domain*)0 #define __itt_domain_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_domain_create(name) (__itt_domain*)0 #define __itt_domain_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_domain_createA_ptr 0 #define __itt_domain_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_domain_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} domains group */ /** * @defgroup ids IDs * @ingroup public * IDs group * @{ */ /** @cond exclude_from_documentation */ #pragma pack(push, 8) typedef struct ___itt_id { unsigned long long d1, d2, d3; } __itt_id; #pragma pack(pop) /** @endcond */ static const __itt_id __itt_null = { 0, 0, 0 }; /** * @ingroup ids * @brief A convenience function is provided to create an ID without domain control. * @brief This is a convenience function to initialize an __itt_id structure. This function * does not affect the trace collector runtime in any way. After you make the ID with this * function, you still must create it with the __itt_id_create function before using the ID * to identify a named entity. * @param[in] addr The address of object; high QWORD of the ID value. * @param[in] extra The extra data to unique identify object; low QWORD of the ID value. */ ITT_INLINE __itt_id ITTAPI __itt_id_make(void* addr, unsigned long long extra) ITT_INLINE_ATTRIBUTE; ITT_INLINE __itt_id ITTAPI __itt_id_make(void* addr, unsigned long long extra) { __itt_id id = __itt_null; id.d1 = (unsigned long long)((uintptr_t)addr); id.d2 = (unsigned long long)extra; id.d3 = (unsigned long long)0; /* Reserved. Must be zero */ return id; } /** * @ingroup ids * @brief Create an instance of identifier. * This establishes the beginning of the lifetime of an instance of * the given ID in the trace. Once this lifetime starts, the ID * can be used to tag named entity instances in calls such as * __itt_task_begin, and to specify relationships among * identified named entity instances, using the \ref relations APIs. * Instance IDs are not domain specific! * @param[in] domain The domain controlling the execution of this call. * @param[in] id The ID to create. */ void ITTAPI __itt_id_create(const __itt_domain *domain, __itt_id id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, id_create, (const __itt_domain *domain, __itt_id id)) #define __itt_id_create(d,x) ITTNOTIFY_VOID_D1(id_create,d,x) #define __itt_id_create_ptr ITTNOTIFY_NAME(id_create) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_id_create(domain,id) #define __itt_id_create_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_id_create_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup ids * @brief Destroy an instance of identifier. * This ends the lifetime of the current instance of the given ID value in the trace. * Any relationships that are established after this lifetime ends are invalid. * This call must be performed before the given ID value can be reused for a different * named entity instance. * @param[in] domain The domain controlling the execution of this call. * @param[in] id The ID to destroy. */ void ITTAPI __itt_id_destroy(const __itt_domain *domain, __itt_id id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, id_destroy, (const __itt_domain *domain, __itt_id id)) #define __itt_id_destroy(d,x) ITTNOTIFY_VOID_D1(id_destroy,d,x) #define __itt_id_destroy_ptr ITTNOTIFY_NAME(id_destroy) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_id_destroy(domain,id) #define __itt_id_destroy_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_id_destroy_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} ids group */ /** * @defgroup handless String Handles * @ingroup public * String Handles group * @{ */ /** @cond exclude_from_documentation */ #pragma pack(push, 8) typedef struct ___itt_string_handle { const char* strA; /*!< Copy of original string in ASCII. */ #if defined(UNICODE) || defined(_UNICODE) const wchar_t* strW; /*!< Copy of original string in UNICODE. */ #else /* UNICODE || _UNICODE */ void* strW; #endif /* UNICODE || _UNICODE */ int extra1; /*!< Reserved. Must be zero */ void* extra2; /*!< Reserved. Must be zero */ struct ___itt_string_handle* next; } __itt_string_handle; #pragma pack(pop) /** @endcond */ /** * @ingroup handles * @brief Create a string handle. * Create and return handle value that can be associated with a string. * Consecutive calls to __itt_string_handle_create with the same name * return the same value. Because the set of string handles is expected to remain * static during the application's execution time, there is no mechanism to destroy a string handle. * Any string handle can be accessed by any thread in the process, regardless of which thread created * the string handle. This call is thread-safe. * @param[in] name The input string */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_string_handle* ITTAPI __itt_string_handle_createA(const char *name); __itt_string_handle* ITTAPI __itt_string_handle_createW(const wchar_t *name); #if defined(UNICODE) || defined(_UNICODE) # define __itt_string_handle_create __itt_string_handle_createW # define __itt_string_handle_create_ptr __itt_string_handle_createW_ptr #else /* UNICODE */ # define __itt_string_handle_create __itt_string_handle_createA # define __itt_string_handle_create_ptr __itt_string_handle_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_string_handle* ITTAPI __itt_string_handle_create(const char *name); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createA, (const char *name)) ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createW, (const wchar_t *name)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_create, (const char *name)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_string_handle_createA ITTNOTIFY_DATA(string_handle_createA) #define __itt_string_handle_createA_ptr ITTNOTIFY_NAME(string_handle_createA) #define __itt_string_handle_createW ITTNOTIFY_DATA(string_handle_createW) #define __itt_string_handle_createW_ptr ITTNOTIFY_NAME(string_handle_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_string_handle_create ITTNOTIFY_DATA(string_handle_create) #define __itt_string_handle_create_ptr ITTNOTIFY_NAME(string_handle_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_string_handle_createA(name) (__itt_string_handle*)0 #define __itt_string_handle_createA_ptr 0 #define __itt_string_handle_createW(name) (__itt_string_handle*)0 #define __itt_string_handle_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_string_handle_create(name) (__itt_string_handle*)0 #define __itt_string_handle_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_string_handle_createA_ptr 0 #define __itt_string_handle_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_string_handle_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} handles group */ /** @cond exclude_from_documentation */ typedef unsigned long long __itt_timestamp; /** @endcond */ static const __itt_timestamp __itt_timestamp_none = (__itt_timestamp)-1LL; /** @cond exclude_from_gpa_documentation */ /** * @ingroup timestamps * @brief Return timestamp corresponding to the current moment. * This returns the timestamp in the format that is the most relevant for the current * host or platform (RDTSC, QPC, and others). You can use the "<" operator to * compare __itt_timestamp values. */ __itt_timestamp ITTAPI __itt_get_timestamp(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_timestamp, get_timestamp, (void)) #define __itt_get_timestamp ITTNOTIFY_DATA(get_timestamp) #define __itt_get_timestamp_ptr ITTNOTIFY_NAME(get_timestamp) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_get_timestamp() #define __itt_get_timestamp_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_get_timestamp_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} timestamps */ /** @endcond */ /** @cond exclude_from_gpa_documentation */ /** * @defgroup regions Regions * @ingroup public * Regions group * @{ */ /** * @ingroup regions * @brief Begin of region instance. * Successive calls to __itt_region_begin with the same ID are ignored * until a call to __itt_region_end with the same ID * @param[in] domain The domain for this region instance * @param[in] id The instance ID for this region instance. Must not be __itt_null * @param[in] parentid The instance ID for the parent of this region instance, or __itt_null * @param[in] name The name of this region */ void ITTAPI __itt_region_begin(const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name); /** * @ingroup regions * @brief End of region instance. * The first call to __itt_region_end with a given ID ends the * region. Successive calls with the same ID are ignored, as are * calls that do not have a matching __itt_region_begin call. * @param[in] domain The domain for this region instance * @param[in] id The instance ID for this region instance */ void ITTAPI __itt_region_end(const __itt_domain *domain, __itt_id id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, region_begin, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) ITT_STUBV(ITTAPI, void, region_end, (const __itt_domain *domain, __itt_id id)) #define __itt_region_begin(d,x,y,z) ITTNOTIFY_VOID_D3(region_begin,d,x,y,z) #define __itt_region_begin_ptr ITTNOTIFY_NAME(region_begin) #define __itt_region_end(d,x) ITTNOTIFY_VOID_D1(region_end,d,x) #define __itt_region_end_ptr ITTNOTIFY_NAME(region_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_region_begin(d,x,y,z) #define __itt_region_begin_ptr 0 #define __itt_region_end(d,x) #define __itt_region_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_region_begin_ptr 0 #define __itt_region_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} regions group */ /** * @defgroup frames Frames * @ingroup public * Frames are similar to regions, but are intended to be easier to use and to implement. * In particular: * - Frames always represent periods of elapsed time * - By default, frames have no nesting relationships * @{ */ /** * @ingroup frames * @brief Begin a frame instance. * Successive calls to __itt_frame_begin with the * same ID are ignored until a call to __itt_frame_end with the same ID. * @param[in] domain The domain for this frame instance * @param[in] id The instance ID for this frame instance or NULL */ void ITTAPI __itt_frame_begin_v3(const __itt_domain *domain, __itt_id *id); /** * @ingroup frames * @brief End a frame instance. * The first call to __itt_frame_end with a given ID * ends the frame. Successive calls with the same ID are ignored, as are * calls that do not have a matching __itt_frame_begin call. * @param[in] domain The domain for this frame instance * @param[in] id The instance ID for this frame instance or NULL for current */ void ITTAPI __itt_frame_end_v3(const __itt_domain *domain, __itt_id *id); /** * @ingroup frames * @brief Submits a frame instance. * Successive calls to __itt_frame_begin or __itt_frame_submit with the * same ID are ignored until a call to __itt_frame_end or __itt_frame_submit * with the same ID. * Passing special __itt_timestamp_none value as "end" argument means * take the current timestamp as the end timestamp. * @param[in] domain The domain for this frame instance * @param[in] id The instance ID for this frame instance or NULL * @param[in] begin Timestamp of the beggining of the frame * @param[in] end Timestamp of the end of the frame */ void ITTAPI __itt_frame_submit_v3(const __itt_domain *domain, __itt_id *id, __itt_timestamp begin, __itt_timestamp end); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, frame_begin_v3, (const __itt_domain *domain, __itt_id *id)) ITT_STUBV(ITTAPI, void, frame_end_v3, (const __itt_domain *domain, __itt_id *id)) ITT_STUBV(ITTAPI, void, frame_submit_v3, (const __itt_domain *domain, __itt_id *id, __itt_timestamp begin, __itt_timestamp end)) #define __itt_frame_begin_v3(d,x) ITTNOTIFY_VOID_D1(frame_begin_v3,d,x) #define __itt_frame_begin_v3_ptr ITTNOTIFY_NAME(frame_begin_v3) #define __itt_frame_end_v3(d,x) ITTNOTIFY_VOID_D1(frame_end_v3,d,x) #define __itt_frame_end_v3_ptr ITTNOTIFY_NAME(frame_end_v3) #define __itt_frame_submit_v3(d,x,b,e) ITTNOTIFY_VOID_D3(frame_submit_v3,d,x,b,e) #define __itt_frame_submit_v3_ptr ITTNOTIFY_NAME(frame_submit_v3) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_frame_begin_v3(domain,id) #define __itt_frame_begin_v3_ptr 0 #define __itt_frame_end_v3(domain,id) #define __itt_frame_end_v3_ptr 0 #define __itt_frame_submit_v3(domain,id,begin,end) #define __itt_frame_submit_v3_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_frame_begin_v3_ptr 0 #define __itt_frame_end_v3_ptr 0 #define __itt_frame_submit_v3_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} frames group */ /** @endcond */ /** * @defgroup taskgroup Task Group * @ingroup public * Task Group * @{ */ /** * @ingroup task_groups * @brief Denotes a task_group instance. * Successive calls to __itt_task_group with the same ID are ignored. * @param[in] domain The domain for this task_group instance * @param[in] id The instance ID for this task_group instance. Must not be __itt_null. * @param[in] parentid The instance ID for the parent of this task_group instance, or __itt_null. * @param[in] name The name of this task_group */ void ITTAPI __itt_task_group(const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, task_group, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) #define __itt_task_group(d,x,y,z) ITTNOTIFY_VOID_D3(task_group,d,x,y,z) #define __itt_task_group_ptr ITTNOTIFY_NAME(task_group) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_task_group(d,x,y,z) #define __itt_task_group_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_task_group_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} taskgroup group */ /** * @defgroup tasks Tasks * @ingroup public * A task instance represents a piece of work performed by a particular * thread for a period of time. A call to __itt_task_begin creates a * task instance. This becomes the current instance for that task on that * thread. A following call to __itt_task_end on the same thread ends the * instance. There may be multiple simultaneous instances of tasks with the * same name on different threads. If an ID is specified, the task instance * receives that ID. Nested tasks are allowed. * * Note: The task is defined by the bracketing of __itt_task_begin and * __itt_task_end on the same thread. If some scheduling mechanism causes * task switching (the thread executes a different user task) or task * switching (the user task switches to a different thread) then this breaks * the notion of current instance. Additional API calls are required to * deal with that possibility. * @{ */ /** * @ingroup tasks * @brief Begin a task instance. * @param[in] domain The domain for this task * @param[in] taskid The instance ID for this task instance, or __itt_null * @param[in] parentid The parent instance to which this task instance belongs, or __itt_null * @param[in] name The name of this task */ void ITTAPI __itt_task_begin(const __itt_domain *domain, __itt_id taskid, __itt_id parentid, __itt_string_handle *name); /** * @ingroup tasks * @brief Begin a task instance. * @param[in] domain The domain for this task * @param[in] taskid The identifier for this task instance (may be 0) * @param[in] parentid The parent of this task (may be 0) * @param[in] fn The pointer to the function you are tracing */ void ITTAPI __itt_task_begin_fn(const __itt_domain *domain, __itt_id taskid, __itt_id parentid, void* fn); /** * @ingroup tasks * @brief End the current task instance. * @param[in] domain The domain for this task */ void ITTAPI __itt_task_end(const __itt_domain *domain); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, task_begin, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) ITT_STUBV(ITTAPI, void, task_begin_fn, (const __itt_domain *domain, __itt_id id, __itt_id parentid, void* fn)) ITT_STUBV(ITTAPI, void, task_end, (const __itt_domain *domain)) #define __itt_task_begin(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin,d,x,y,z) #define __itt_task_begin_ptr ITTNOTIFY_NAME(task_begin) #define __itt_task_begin_fn(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin_fn,d,x,y,z) #define __itt_task_begin_fn_ptr ITTNOTIFY_NAME(task_begin_fn) #define __itt_task_end(d) ITTNOTIFY_VOID_D0(task_end,d) #define __itt_task_end_ptr ITTNOTIFY_NAME(task_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_task_begin(domain,id,parentid,name) #define __itt_task_begin_ptr 0 #define __itt_task_begin_fn(domain,id,parentid,fn) #define __itt_task_begin_fn_ptr 0 #define __itt_task_end(domain) #define __itt_task_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_task_begin_ptr 0 #define __itt_task_begin_fn_ptr 0 #define __itt_task_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} tasks group */ /** * @defgroup counters Counters * @ingroup public * Counters are user-defined objects with a monotonically increasing * value. Counter values are 64-bit unsigned integers. Counter values * are tracked per-thread. Counters have names that can be displayed in * the tools. * @{ */ /** * @ingroup counters * @brief Increment a counter by one. * The first call with a given name creates a counter by that name and sets its * value to zero on every thread. Successive calls increment the counter value * on the thread on which the call is issued. * @param[in] domain The domain controlling the call. Counter names are not domain specific. * The domain argument is used only to enable or disable the API calls. * @param[in] name The name of the counter */ void ITTAPI __itt_counter_inc_v3(const __itt_domain *domain, __itt_string_handle *name); /** * @ingroup counters * @brief Increment a counter by the value specified in delta. * @param[in] domain The domain controlling the call. Counter names are not domain specific. * The domain argument is used only to enable or disable the API calls. * @param[in] name The name of the counter * @param[in] delta The amount by which to increment the counter */ void ITTAPI __itt_counter_inc_delta_v3(const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, counter_inc_v3, (const __itt_domain *domain, __itt_string_handle *name)) ITT_STUBV(ITTAPI, void, counter_inc_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta)) #define __itt_counter_inc_v3(d,x) ITTNOTIFY_VOID_D1(counter_inc_v3,d,x) #define __itt_counter_inc_v3_ptr ITTNOTIFY_NAME(counter_inc_v3) #define __itt_counter_inc_delta_v3(d,x,y) ITTNOTIFY_VOID_D2(counter_inc_delta_v3,d,x,y) #define __itt_counter_inc_delta_v3_ptr ITTNOTIFY_NAME(counter_inc_delta_v3) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_counter_inc_v3(domain,name) #define __itt_counter_inc_v3_ptr 0 #define __itt_counter_inc_delta_v3(domain,name,delta) #define __itt_counter_inc_delta_v3_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_counter_inc_v3_ptr 0 #define __itt_counter_inc_delta_v3_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} counters group */ /** * @defgroup markers Markers * Markers represent a single discreet event in time. Markers have a scope, * described by an enumerated type __itt_scope. Markers are created by * the API call __itt_marker. A marker instance can be given an ID for use in * adding metadata. * @{ */ /** * @brief Describes the scope of an event object in the trace. */ typedef enum { __itt_scope_unknown = 0, __itt_scope_global, __itt_scope_track_group, __itt_scope_track, __itt_scope_task, __itt_scope_marker } __itt_scope; /** @cond exclude_from_documentation */ #define __itt_marker_scope_unknown __itt_scope_unknown #define __itt_marker_scope_global __itt_scope_global #define __itt_marker_scope_process __itt_scope_track_group #define __itt_marker_scope_thread __itt_scope_track #define __itt_marker_scope_task __itt_scope_task /** @endcond */ /** * @ingroup markers * @brief Create a marker instance * @param[in] domain The domain for this marker * @param[in] id The instance ID for this marker or __itt_null * @param[in] name The name for this marker * @param[in] scope The scope for this marker */ void ITTAPI __itt_marker(const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, marker, (const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope)) #define __itt_marker(d,x,y,z) ITTNOTIFY_VOID_D3(marker,d,x,y,z) #define __itt_marker_ptr ITTNOTIFY_NAME(marker) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_marker(domain,id,name,scope) #define __itt_marker_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_marker_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} markers group */ /** * @defgroup metadata Metadata * The metadata API is used to attach extra information to named * entities. Metadata can be attached to an identified named entity by ID, * or to the current entity (which is always a task). * * Conceptually metadata has a type (what kind of metadata), a key (the * name of the metadata), and a value (the actual data). The encoding of * the value depends on the type of the metadata. * * The type of metadata is specified by an enumerated type __itt_metdata_type. * @{ */ /** * @ingroup parameters * @brief describes the type of metadata */ typedef enum { __itt_metadata_unknown = 0, __itt_metadata_u64, /**< Unsigned 64-bit integer */ __itt_metadata_s64, /**< Signed 64-bit integer */ __itt_metadata_u32, /**< Unsigned 32-bit integer */ __itt_metadata_s32, /**< Signed 32-bit integer */ __itt_metadata_u16, /**< Unsigned 16-bit integer */ __itt_metadata_s16, /**< Signed 16-bit integer */ __itt_metadata_float, /**< Signed 32-bit floating-point */ __itt_metadata_double /**< SIgned 64-bit floating-point */ } __itt_metadata_type; /** * @ingroup parameters * @brief Add metadata to an instance of a named entity. * @param[in] domain The domain controlling the call * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task * @param[in] key The name of the metadata * @param[in] type The type of the metadata * @param[in] count The number of elements of the given type. If count == 0, no metadata will be added. * @param[in] data The metadata itself */ void ITTAPI __itt_metadata_add(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, metadata_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data)) #define __itt_metadata_add(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(metadata_add,d,x,y,z,a,b) #define __itt_metadata_add_ptr ITTNOTIFY_NAME(metadata_add) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_metadata_add(d,x,y,z,a,b) #define __itt_metadata_add_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_metadata_add_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup parameters * @brief Add string metadata to an instance of a named entity. * @param[in] domain The domain controlling the call * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task * @param[in] key The name of the metadata * @param[in] data The metadata itself * @param[in] length The number of characters in the string, or -1 if the length is unknown but the string is null-terminated */ #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_metadata_str_addA(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length); void ITTAPI __itt_metadata_str_addW(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t *data, size_t length); #if defined(UNICODE) || defined(_UNICODE) # define __itt_metadata_str_add __itt_metadata_str_addW # define __itt_metadata_str_add_ptr __itt_metadata_str_addW_ptr #else /* UNICODE */ # define __itt_metadata_str_add __itt_metadata_str_addA # define __itt_metadata_str_add_ptr __itt_metadata_str_addA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ void ITTAPI __itt_metadata_str_add(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length); #endif /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, metadata_str_addA, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length)) ITT_STUBV(ITTAPI, void, metadata_str_addW, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t *data, size_t length)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, metadata_str_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_metadata_str_addA(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_addA,d,x,y,z,a) #define __itt_metadata_str_addA_ptr ITTNOTIFY_NAME(metadata_str_addA) #define __itt_metadata_str_addW(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_addW,d,x,y,z,a) #define __itt_metadata_str_addW_ptr ITTNOTIFY_NAME(metadata_str_addW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_metadata_str_add(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add,d,x,y,z,a) #define __itt_metadata_str_add_ptr ITTNOTIFY_NAME(metadata_str_add) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_metadata_str_addA(d,x,y,z,a) #define __itt_metadata_str_addA_ptr 0 #define __itt_metadata_str_addW(d,x,y,z,a) #define __itt_metadata_str_addW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_metadata_str_add(d,x,y,z,a) #define __itt_metadata_str_add_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_metadata_str_addA_ptr 0 #define __itt_metadata_str_addW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_metadata_str_add_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup parameters * @brief Add metadata to an instance of a named entity. * @param[in] domain The domain controlling the call * @param[in] scope The scope of the instance to which the metadata is to be added * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task * @param[in] key The name of the metadata * @param[in] type The type of the metadata * @param[in] count The number of elements of the given type. If count == 0, no metadata will be added. * @param[in] data The metadata itself */ void ITTAPI __itt_metadata_add_with_scope(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, metadata_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data)) #define __itt_metadata_add_with_scope(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(metadata_add_with_scope,d,x,y,z,a,b) #define __itt_metadata_add_with_scope_ptr ITTNOTIFY_NAME(metadata_add_with_scope) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_metadata_add_with_scope(d,x,y,z,a,b) #define __itt_metadata_add_with_scope_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_metadata_add_with_scope_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup parameters * @brief Add string metadata to an instance of a named entity. * @param[in] domain The domain controlling the call * @param[in] scope The scope of the instance to which the metadata is to be added * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task * @param[in] key The name of the metadata * @param[in] data The metadata itself * @param[in] length The number of characters in the string, or -1 if the length is unknown but the string is null-terminated */ #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_metadata_str_add_with_scopeA(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length); void ITTAPI __itt_metadata_str_add_with_scopeW(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length); #if defined(UNICODE) || defined(_UNICODE) # define __itt_metadata_str_add_with_scope __itt_metadata_str_add_with_scopeW # define __itt_metadata_str_add_with_scope_ptr __itt_metadata_str_add_with_scopeW_ptr #else /* UNICODE */ # define __itt_metadata_str_add_with_scope __itt_metadata_str_add_with_scopeA # define __itt_metadata_str_add_with_scope_ptr __itt_metadata_str_add_with_scopeA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ void ITTAPI __itt_metadata_str_add_with_scope(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length); #endif /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeA, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length)) ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeW, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, metadata_str_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_metadata_str_add_with_scopeA(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scopeA,d,x,y,z,a) #define __itt_metadata_str_add_with_scopeA_ptr ITTNOTIFY_NAME(metadata_str_add_with_scopeA) #define __itt_metadata_str_add_with_scopeW(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scopeW,d,x,y,z,a) #define __itt_metadata_str_add_with_scopeW_ptr ITTNOTIFY_NAME(metadata_str_add_with_scopeW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_metadata_str_add_with_scope(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scope,d,x,y,z,a) #define __itt_metadata_str_add_with_scope_ptr ITTNOTIFY_NAME(metadata_str_add_with_scope) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_metadata_str_add_with_scopeA(d,x,y,z,a) #define __itt_metadata_str_add_with_scopeA_ptr 0 #define __itt_metadata_str_add_with_scopeW(d,x,y,z,a) #define __itt_metadata_str_add_with_scopeW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_metadata_str_add_with_scope(d,x,y,z,a) #define __itt_metadata_str_add_with_scope_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_metadata_str_add_with_scopeA_ptr 0 #define __itt_metadata_str_add_with_scopeW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_metadata_str_add_with_scope_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} metadata group */ /** * @defgroup relations Relations * Instances of named entities can be explicitly associated with other * instances using instance IDs and the relationship API calls. * * @{ */ /** * @ingroup relations * @brief The kind of relation between two instances is specified by the enumerated type __itt_relation. * Relations between instances can be added with an API call. The relation * API uses instance IDs. Relations can be added before or after the actual * instances are created and persist independently of the instances. This * is the motivation for having different lifetimes for instance IDs and * the actual instances. */ typedef enum { __itt_relation_is_unknown = 0, __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */ __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */ __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */ __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */ __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */ __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */ __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */ } __itt_relation; /** * @ingroup relations * @brief Add a relation to the current task instance. * The current task instance is the head of the relation. * @param[in] domain The domain controlling this call * @param[in] relation The kind of relation * @param[in] tail The ID for the tail of the relation */ void ITTAPI __itt_relation_add_to_current(const __itt_domain *domain, __itt_relation relation, __itt_id tail); /** * @ingroup relations * @brief Add a relation between two instance identifiers. * @param[in] domain The domain controlling this call * @param[in] head The ID for the head of the relation * @param[in] relation The kind of relation * @param[in] tail The ID for the tail of the relation */ void ITTAPI __itt_relation_add(const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, relation_add_to_current, (const __itt_domain *domain, __itt_relation relation, __itt_id tail)) ITT_STUBV(ITTAPI, void, relation_add, (const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail)) #define __itt_relation_add_to_current(d,x,y) ITTNOTIFY_VOID_D2(relation_add_to_current,d,x,y) #define __itt_relation_add_to_current_ptr ITTNOTIFY_NAME(relation_add_to_current) #define __itt_relation_add(d,x,y,z) ITTNOTIFY_VOID_D3(relation_add,d,x,y,z) #define __itt_relation_add_ptr ITTNOTIFY_NAME(relation_add) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_relation_add_to_current(d,x,y) #define __itt_relation_add_to_current_ptr 0 #define __itt_relation_add(d,x,y,z) #define __itt_relation_add_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_relation_add_to_current_ptr 0 #define __itt_relation_add_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} relations group */ /** @cond exclude_from_documentation */ #pragma pack(push, 8) typedef struct ___itt_clock_info { unsigned long long clock_freq; /*!< Clock domain frequency */ unsigned long long clock_base; /*!< Clock domain base timestamp */ } __itt_clock_info; #pragma pack(pop) /** @endcond */ /** @cond exclude_from_documentation */ typedef void (ITTAPI *__itt_get_clock_info_fn)(__itt_clock_info* clock_info, void* data); /** @endcond */ /** @cond exclude_from_documentation */ #pragma pack(push, 8) typedef struct ___itt_clock_domain { __itt_clock_info info; /*!< Most recent clock domain info */ __itt_get_clock_info_fn fn; /*!< Callback function pointer */ void* fn_data; /*!< Input argument for the callback function */ int extra1; /*!< Reserved. Must be zero */ void* extra2; /*!< Reserved. Must be zero */ struct ___itt_clock_domain* next; } __itt_clock_domain; #pragma pack(pop) /** @endcond */ /** * @ingroup clockdomains * @brief Create a clock domain. * Certain applications require the capability to trace their application using * a clock domain different than the CPU, for instance the instrumentation of events * that occur on a GPU. * Because the set of domains is expected to be static over the application's execution time, * there is no mechanism to destroy a domain. * Any domain can be accessed by any thread in the process, regardless of which thread created * the domain. This call is thread-safe. * @param[in] fn A pointer to a callback function which retrieves alternative CPU timestamps * @param[in] fn_data Argument for a callback function; may be NULL */ __itt_clock_domain* ITTAPI __itt_clock_domain_create(__itt_get_clock_info_fn fn, void* fn_data); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_clock_domain*, clock_domain_create, (__itt_get_clock_info_fn fn, void* fn_data)) #define __itt_clock_domain_create ITTNOTIFY_DATA(clock_domain_create) #define __itt_clock_domain_create_ptr ITTNOTIFY_NAME(clock_domain_create) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_clock_domain_create(fn,fn_data) (__itt_clock_domain*)0 #define __itt_clock_domain_create_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_clock_domain_create_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup clockdomains * @brief Recalculate clock domains frequences and clock base timestamps. */ void ITTAPI __itt_clock_domain_reset(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, clock_domain_reset, (void)) #define __itt_clock_domain_reset ITTNOTIFY_VOID(clock_domain_reset) #define __itt_clock_domain_reset_ptr ITTNOTIFY_NAME(clock_domain_reset) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_clock_domain_reset() #define __itt_clock_domain_reset_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_clock_domain_reset_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup clockdomain * @brief Create an instance of identifier. This establishes the beginning of the lifetime of * an instance of the given ID in the trace. Once this lifetime starts, the ID can be used to * tag named entity instances in calls such as __itt_task_begin, and to specify relationships among * identified named entity instances, using the \ref relations APIs. * @param[in] domain The domain controlling the execution of this call. * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] id The ID to create. */ void ITTAPI __itt_id_create_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id); /** * @ingroup clockdomain * @brief Destroy an instance of identifier. This ends the lifetime of the current instance of the * given ID value in the trace. Any relationships that are established after this lifetime ends are * invalid. This call must be performed before the given ID value can be reused for a different * named entity instance. * @param[in] domain The domain controlling the execution of this call. * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] id The ID to destroy. */ void ITTAPI __itt_id_destroy_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, id_create_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id)) ITT_STUBV(ITTAPI, void, id_destroy_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id)) #define __itt_id_create_ex(d,x,y,z) ITTNOTIFY_VOID_D3(id_create_ex,d,x,y,z) #define __itt_id_create_ex_ptr ITTNOTIFY_NAME(id_create_ex) #define __itt_id_destroy_ex(d,x,y,z) ITTNOTIFY_VOID_D3(id_destroy_ex,d,x,y,z) #define __itt_id_destroy_ex_ptr ITTNOTIFY_NAME(id_destroy_ex) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_id_create_ex(domain,clock_domain,timestamp,id) #define __itt_id_create_ex_ptr 0 #define __itt_id_destroy_ex(domain,clock_domain,timestamp,id) #define __itt_id_destroy_ex_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_id_create_ex_ptr 0 #define __itt_id_destroy_ex_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup clockdomain * @brief Begin a task instance. * @param[in] domain The domain for this task * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] taskid The instance ID for this task instance, or __itt_null * @param[in] parentid The parent instance to which this task instance belongs, or __itt_null * @param[in] name The name of this task */ void ITTAPI __itt_task_begin_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); /** * @ingroup clockdomain * @brief Begin a task instance. * @param[in] domain The domain for this task * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] taskid The identifier for this task instance, or __itt_null * @param[in] parentid The parent of this task, or __itt_null * @param[in] fn The pointer to the function you are tracing */ void ITTAPI __itt_task_begin_fn_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, void* fn); /** * @ingroup clockdomain * @brief End the current task instance. * @param[in] domain The domain for this task * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. */ void ITTAPI __itt_task_end_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, task_begin_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, __itt_string_handle *name)) ITT_STUBV(ITTAPI, void, task_begin_fn_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, void* fn)) ITT_STUBV(ITTAPI, void, task_end_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp)) #define __itt_task_begin_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_ex,d,x,y,z,a,b) #define __itt_task_begin_ex_ptr ITTNOTIFY_NAME(task_begin_ex) #define __itt_task_begin_fn_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_fn_ex,d,x,y,z,a,b) #define __itt_task_begin_fn_ex_ptr ITTNOTIFY_NAME(task_begin_fn_ex) #define __itt_task_end_ex(d,x,y) ITTNOTIFY_VOID_D2(task_end_ex,d,x,y) #define __itt_task_end_ex_ptr ITTNOTIFY_NAME(task_end_ex) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_task_begin_ex(domain,clock_domain,timestamp,id,parentid,name) #define __itt_task_begin_ex_ptr 0 #define __itt_task_begin_fn_ex(domain,clock_domain,timestamp,id,parentid,fn) #define __itt_task_begin_fn_ex_ptr 0 #define __itt_task_end_ex(domain,clock_domain,timestamp) #define __itt_task_end_ex_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_task_begin_ex_ptr 0 #define __itt_task_begin_fn_ex_ptr 0 #define __itt_task_end_ex_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup markers * @brief Create a marker instance. * @param[in] domain The domain for this marker * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] id The instance ID for this marker, or __itt_null * @param[in] name The name for this marker * @param[in] scope The scope for this marker */ void ITTAPI __itt_marker_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, marker_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope)) #define __itt_marker_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(marker_ex,d,x,y,z,a,b) #define __itt_marker_ex_ptr ITTNOTIFY_NAME(marker_ex) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_marker_ex(domain,clock_domain,timestamp,id,name,scope) #define __itt_marker_ex_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_marker_ex_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @ingroup clockdomain * @brief Add a relation to the current task instance. * The current task instance is the head of the relation. * @param[in] domain The domain controlling this call * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] relation The kind of relation * @param[in] tail The ID for the tail of the relation */ void ITTAPI __itt_relation_add_to_current_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail); /** * @ingroup clockdomain * @brief Add a relation between two instance identifiers. * @param[in] domain The domain controlling this call * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] head The ID for the head of the relation * @param[in] relation The kind of relation * @param[in] tail The ID for the tail of the relation */ void ITTAPI __itt_relation_add_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, relation_add_to_current_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail)) ITT_STUBV(ITTAPI, void, relation_add_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail)) #define __itt_relation_add_to_current_ex(d,x,y,z,a) ITTNOTIFY_VOID_D4(relation_add_to_current_ex,d,x,y,z,a) #define __itt_relation_add_to_current_ex_ptr ITTNOTIFY_NAME(relation_add_to_current_ex) #define __itt_relation_add_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(relation_add_ex,d,x,y,z,a,b) #define __itt_relation_add_ex_ptr ITTNOTIFY_NAME(relation_add_ex) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_relation_add_to_current_ex(domain,clock_domain,timestame,relation,tail) #define __itt_relation_add_to_current_ex_ptr 0 #define __itt_relation_add_ex(domain,clock_domain,timestamp,head,relation,tail) #define __itt_relation_add_ex_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_relation_add_to_current_ex_ptr 0 #define __itt_relation_add_ex_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @cond exclude_from_documentation */ typedef enum ___itt_track_group_type { __itt_track_group_type_normal = 0 } __itt_track_group_type; /** @endcond */ /** @cond exclude_from_documentation */ #pragma pack(push, 8) typedef struct ___itt_track_group { __itt_string_handle* name; /*!< Name of the track group */ struct ___itt_track* track; /*!< List of child tracks */ __itt_track_group_type tgtype; /*!< Type of the track group */ int extra1; /*!< Reserved. Must be zero */ void* extra2; /*!< Reserved. Must be zero */ struct ___itt_track_group* next; } __itt_track_group; #pragma pack(pop) /** @endcond */ /** * @brief Placeholder for custom track types. Currently, "normal" custom track * is the only available track type. */ typedef enum ___itt_track_type { __itt_track_type_normal = 0 #ifdef INTEL_ITTNOTIFY_API_PRIVATE , __itt_track_type_queue #endif /* INTEL_ITTNOTIFY_API_PRIVATE */ } __itt_track_type; /** @cond exclude_from_documentation */ #pragma pack(push, 8) typedef struct ___itt_track { __itt_string_handle* name; /*!< Name of the track group */ __itt_track_group* group; /*!< Parent group to a track */ __itt_track_type ttype; /*!< Type of the track */ int extra1; /*!< Reserved. Must be zero */ void* extra2; /*!< Reserved. Must be zero */ struct ___itt_track* next; } __itt_track; #pragma pack(pop) /** @endcond */ /** * @brief Create logical track group. */ __itt_track_group* ITTAPI __itt_track_group_create(__itt_string_handle* name, __itt_track_group_type track_group_type); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_track_group*, track_group_create, (__itt_string_handle* name, __itt_track_group_type track_group_type)) #define __itt_track_group_create ITTNOTIFY_DATA(track_group_create) #define __itt_track_group_create_ptr ITTNOTIFY_NAME(track_group_create) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_track_group_create(name) (__itt_track_group*)0 #define __itt_track_group_create_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_track_group_create_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Create logical track. */ __itt_track* ITTAPI __itt_track_create(__itt_track_group* track_group, __itt_string_handle* name, __itt_track_type track_type); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_track*, track_create, (__itt_track_group* track_group,__itt_string_handle* name, __itt_track_type track_type)) #define __itt_track_create ITTNOTIFY_DATA(track_create) #define __itt_track_create_ptr ITTNOTIFY_NAME(track_create) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_track_create(track_group,name,track_type) (__itt_track*)0 #define __itt_track_create_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_track_create_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Set the logical track. */ void ITTAPI __itt_set_track(__itt_track* track); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, set_track, (__itt_track *track)) #define __itt_set_track ITTNOTIFY_VOID(set_track) #define __itt_set_track_ptr ITTNOTIFY_NAME(set_track) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_set_track(track) #define __itt_set_track_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_set_track_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /* ========================================================================== */ /** @cond exclude_from_gpa_documentation */ /** * @defgroup events Events * @ingroup public * Events group * @{ */ /** @brief user event type */ typedef int __itt_event; /** * @brief Create an event notification * @note name or namelen being null/name and namelen not matching, user event feature not enabled * @return non-zero event identifier upon success and __itt_err otherwise */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_event LIBITTAPI __itt_event_createA(const char *name, int namelen); __itt_event LIBITTAPI __itt_event_createW(const wchar_t *name, int namelen); #if defined(UNICODE) || defined(_UNICODE) # define __itt_event_create __itt_event_createW # define __itt_event_create_ptr __itt_event_createW_ptr #else # define __itt_event_create __itt_event_createA # define __itt_event_create_ptr __itt_event_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_event LIBITTAPI __itt_event_create(const char *name, int namelen); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen)) ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_event_createA ITTNOTIFY_DATA(event_createA) #define __itt_event_createA_ptr ITTNOTIFY_NAME(event_createA) #define __itt_event_createW ITTNOTIFY_DATA(event_createW) #define __itt_event_createW_ptr ITTNOTIFY_NAME(event_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_event_create ITTNOTIFY_DATA(event_create) #define __itt_event_create_ptr ITTNOTIFY_NAME(event_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_event_createA(name, namelen) (__itt_event)0 #define __itt_event_createA_ptr 0 #define __itt_event_createW(name, namelen) (__itt_event)0 #define __itt_event_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_event_create(name, namelen) (__itt_event)0 #define __itt_event_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_event_createA_ptr 0 #define __itt_event_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_event_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an event occurrence. * @return __itt_err upon failure (invalid event id/user event feature not enabled) */ int LIBITTAPI __itt_event_start(__itt_event event); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event)) #define __itt_event_start ITTNOTIFY_DATA(event_start) #define __itt_event_start_ptr ITTNOTIFY_NAME(event_start) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_event_start(event) (int)0 #define __itt_event_start_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_event_start_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an event end occurrence. * @note It is optional if events do not have durations. * @return __itt_err upon failure (invalid event id/user event feature not enabled) */ int LIBITTAPI __itt_event_end(__itt_event event); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event)) #define __itt_event_end ITTNOTIFY_DATA(event_end) #define __itt_event_end_ptr ITTNOTIFY_NAME(event_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_event_end(event) (int)0 #define __itt_event_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_event_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} events group */ /** * @defgroup arrays Arrays Visualizer * @ingroup public * Visualize arrays * @{ */ /** * @enum __itt_av_data_type * @brief Defines types of arrays data (for C/C++ intrinsic types) */ typedef enum { __itt_e_first = 0, __itt_e_char = 0, /* 1-byte integer */ __itt_e_uchar, /* 1-byte unsigned integer */ __itt_e_int16, /* 2-byte integer */ __itt_e_uint16, /* 2-byte unsigned integer */ __itt_e_int32, /* 4-byte integer */ __itt_e_uint32, /* 4-byte unsigned integer */ __itt_e_int64, /* 8-byte integer */ __itt_e_uint64, /* 8-byte unsigned integer */ __itt_e_float, /* 4-byte floating */ __itt_e_double, /* 8-byte floating */ __itt_e_last = __itt_e_double } __itt_av_data_type; /** * @brief Save an array data to a file. * Output format is defined by the file extension. The csv and bmp formats are supported (bmp - for 2-dimensional array only). * @param[in] data - pointer to the array data * @param[in] rank - the rank of the array * @param[in] dimensions - pointer to an array of integers, which specifies the array dimensions. * The size of dimensions must be equal to the rank * @param[in] type - the type of the array, specified as one of the __itt_av_data_type values (for intrinsic types) * @param[in] filePath - the file path; the output format is defined by the file extension * @param[in] columnOrder - defines how the array is stored in the linear memory. * It should be 1 for column-major order (e.g. in FORTRAN) or 0 - for row-major order (e.g. in C). */ #if ITT_PLATFORM==ITT_PLATFORM_WIN int ITTAPI __itt_av_saveA(void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder); int ITTAPI __itt_av_saveW(void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder); #if defined(UNICODE) || defined(_UNICODE) # define __itt_av_save __itt_av_saveW # define __itt_av_save_ptr __itt_av_saveW_ptr #else /* UNICODE */ # define __itt_av_save __itt_av_saveA # define __itt_av_save_ptr __itt_av_saveA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ int ITTAPI __itt_av_save(void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, int, av_saveA, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder)) ITT_STUB(ITTAPI, int, av_saveW, (void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, av_save, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_av_saveA ITTNOTIFY_DATA(av_saveA) #define __itt_av_saveA_ptr ITTNOTIFY_NAME(av_saveA) #define __itt_av_saveW ITTNOTIFY_DATA(av_saveW) #define __itt_av_saveW_ptr ITTNOTIFY_NAME(av_saveW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_av_save ITTNOTIFY_DATA(av_save) #define __itt_av_save_ptr ITTNOTIFY_NAME(av_save) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_av_saveA(name) #define __itt_av_saveA_ptr 0 #define __itt_av_saveW(name) #define __itt_av_saveW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_av_save(name) #define __itt_av_save_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_av_saveA_ptr 0 #define __itt_av_saveW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_av_save_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ void ITTAPI __itt_enable_attach(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, enable_attach, (void)) #define __itt_enable_attach ITTNOTIFY_VOID(enable_attach) #define __itt_enable_attach_ptr ITTNOTIFY_NAME(enable_attach) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_enable_attach() #define __itt_enable_attach_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_enable_attach_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @cond exclude_from_gpa_documentation */ /** @} arrays group */ /** @endcond */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _ITTNOTIFY_H_ */ #ifdef INTEL_ITTNOTIFY_API_PRIVATE #ifndef _ITTNOTIFY_PRIVATE_ #define _ITTNOTIFY_PRIVATE_ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * @ingroup tasks * @brief Begin an overlapped task instance. * @param[in] domain The domain for this task. * @param[in] taskid The identifier for this task instance, *cannot* be __itt_null. * @param[in] parentid The parent of this task, or __itt_null. * @param[in] name The name of this task. */ void ITTAPI __itt_task_begin_overlapped(const __itt_domain* domain, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); /** * @ingroup clockdomain * @brief Begin an overlapped task instance. * @param[in] domain The domain for this task * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] taskid The identifier for this task instance, *cannot* be __itt_null. * @param[in] parentid The parent of this task, or __itt_null. * @param[in] name The name of this task. */ void ITTAPI __itt_task_begin_overlapped_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); /** * @ingroup tasks * @brief End an overlapped task instance. * @param[in] domain The domain for this task * @param[in] taskid Explicit ID of finished task */ void ITTAPI __itt_task_end_overlapped(const __itt_domain *domain, __itt_id taskid); /** * @ingroup clockdomain * @brief End an overlapped task instance. * @param[in] domain The domain for this task * @param[in] clock_domain The clock domain controlling the execution of this call. * @param[in] timestamp The user defined timestamp. * @param[in] taskid Explicit ID of finished task */ void ITTAPI __itt_task_end_overlapped_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, task_begin_overlapped, (const __itt_domain *domain, __itt_id taskid, __itt_id parentid, __itt_string_handle *name)) ITT_STUBV(ITTAPI, void, task_begin_overlapped_ex, (const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name)) ITT_STUBV(ITTAPI, void, task_end_overlapped, (const __itt_domain *domain, __itt_id taskid)) ITT_STUBV(ITTAPI, void, task_end_overlapped_ex, (const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid)) #define __itt_task_begin_overlapped(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin_overlapped,d,x,y,z) #define __itt_task_begin_overlapped_ptr ITTNOTIFY_NAME(task_begin_overlapped) #define __itt_task_begin_overlapped_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_overlapped_ex,d,x,y,z,a,b) #define __itt_task_begin_overlapped_ex_ptr ITTNOTIFY_NAME(task_begin_overlapped_ex) #define __itt_task_end_overlapped(d,x) ITTNOTIFY_VOID_D1(task_end_overlapped,d,x) #define __itt_task_end_overlapped_ptr ITTNOTIFY_NAME(task_end_overlapped) #define __itt_task_end_overlapped_ex(d,x,y,z) ITTNOTIFY_VOID_D3(task_end_overlapped_ex,d,x,y,z) #define __itt_task_end_overlapped_ex_ptr ITTNOTIFY_NAME(task_end_overlapped_ex) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_task_begin_overlapped(domain,taskid,parentid,name) #define __itt_task_begin_overlapped_ptr 0 #define __itt_task_begin_overlapped_ex(domain,clock_domain,timestamp,taskid,parentid,name) #define __itt_task_begin_overlapped_ex_ptr 0 #define __itt_task_end_overlapped(domain,taskid) #define __itt_task_end_overlapped_ptr 0 #define __itt_task_end_overlapped_ex(domain,clock_domain,timestamp,taskid) #define __itt_task_end_overlapped_ex_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_task_begin_overlapped_ptr 0 #define __itt_task_begin_overlapped_ex_ptr 0 #define __itt_task_end_overlapped_ptr 0 #define __itt_task_end_overlapped_ex_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @defgroup makrs_internal Marks * @ingroup internal * Marks group * @warning Internal API: * - It is not shipped to outside of Intel * - It is delivered to internal Intel teams using e-mail or SVN access only * @{ */ /** @brief user mark type */ typedef int __itt_mark_type; /** * @brief Creates a user mark type with the specified name using char or Unicode string. * @param[in] name - name of mark to create * @return Returns a handle to the mark type */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_mark_type ITTAPI __itt_mark_createA(const char *name); __itt_mark_type ITTAPI __itt_mark_createW(const wchar_t *name); #if defined(UNICODE) || defined(_UNICODE) # define __itt_mark_create __itt_mark_createW # define __itt_mark_create_ptr __itt_mark_createW_ptr #else /* UNICODE */ # define __itt_mark_create __itt_mark_createA # define __itt_mark_create_ptr __itt_mark_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_mark_type ITTAPI __itt_mark_create(const char *name); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_mark_type, mark_createA, (const char *name)) ITT_STUB(ITTAPI, __itt_mark_type, mark_createW, (const wchar_t *name)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_mark_type, mark_create, (const char *name)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_mark_createA ITTNOTIFY_DATA(mark_createA) #define __itt_mark_createA_ptr ITTNOTIFY_NAME(mark_createA) #define __itt_mark_createW ITTNOTIFY_DATA(mark_createW) #define __itt_mark_createW_ptr ITTNOTIFY_NAME(mark_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark_create ITTNOTIFY_DATA(mark_create) #define __itt_mark_create_ptr ITTNOTIFY_NAME(mark_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_mark_createA(name) (__itt_mark_type)0 #define __itt_mark_createA_ptr 0 #define __itt_mark_createW(name) (__itt_mark_type)0 #define __itt_mark_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark_create(name) (__itt_mark_type)0 #define __itt_mark_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_mark_createA_ptr 0 #define __itt_mark_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Creates a "discrete" user mark type of the specified type and an optional parameter using char or Unicode string. * * - The mark of "discrete" type is placed to collection results in case of success. It appears in overtime view(s) as a special tick sign. * - The call is "synchronous" - function returns after mark is actually added to results. * - This function is useful, for example, to mark different phases of application * (beginning of the next mark automatically meand end of current region). * - Can be used together with "continuous" marks (see below) at the same collection session * @param[in] mt - mark, created by __itt_mark_create(const char* name) function * @param[in] parameter - string parameter of mark * @return Returns zero value in case of success, non-zero value otherwise. */ #if ITT_PLATFORM==ITT_PLATFORM_WIN int ITTAPI __itt_markA(__itt_mark_type mt, const char *parameter); int ITTAPI __itt_markW(__itt_mark_type mt, const wchar_t *parameter); #if defined(UNICODE) || defined(_UNICODE) # define __itt_mark __itt_markW # define __itt_mark_ptr __itt_markW_ptr #else /* UNICODE */ # define __itt_mark __itt_markA # define __itt_mark_ptr __itt_markA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ int ITTAPI __itt_mark(__itt_mark_type mt, const char *parameter); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, int, markA, (__itt_mark_type mt, const char *parameter)) ITT_STUB(ITTAPI, int, markW, (__itt_mark_type mt, const wchar_t *parameter)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, mark, (__itt_mark_type mt, const char *parameter)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_markA ITTNOTIFY_DATA(markA) #define __itt_markA_ptr ITTNOTIFY_NAME(markA) #define __itt_markW ITTNOTIFY_DATA(markW) #define __itt_markW_ptr ITTNOTIFY_NAME(markW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark ITTNOTIFY_DATA(mark) #define __itt_mark_ptr ITTNOTIFY_NAME(mark) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_markA(mt, parameter) (int)0 #define __itt_markA_ptr 0 #define __itt_markW(mt, parameter) (int)0 #define __itt_markW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark(mt, parameter) (int)0 #define __itt_mark_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_markA_ptr 0 #define __itt_markW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Use this if necessary to create a "discrete" user event type (mark) for process * rather then for one thread * @see int __itt_mark(__itt_mark_type mt, const char* parameter); */ #if ITT_PLATFORM==ITT_PLATFORM_WIN int ITTAPI __itt_mark_globalA(__itt_mark_type mt, const char *parameter); int ITTAPI __itt_mark_globalW(__itt_mark_type mt, const wchar_t *parameter); #if defined(UNICODE) || defined(_UNICODE) # define __itt_mark_global __itt_mark_globalW # define __itt_mark_global_ptr __itt_mark_globalW_ptr #else /* UNICODE */ # define __itt_mark_global __itt_mark_globalA # define __itt_mark_global_ptr __itt_mark_globalA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ int ITTAPI __itt_mark_global(__itt_mark_type mt, const char *parameter); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, int, mark_globalA, (__itt_mark_type mt, const char *parameter)) ITT_STUB(ITTAPI, int, mark_globalW, (__itt_mark_type mt, const wchar_t *parameter)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, mark_global, (__itt_mark_type mt, const char *parameter)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_mark_globalA ITTNOTIFY_DATA(mark_globalA) #define __itt_mark_globalA_ptr ITTNOTIFY_NAME(mark_globalA) #define __itt_mark_globalW ITTNOTIFY_DATA(mark_globalW) #define __itt_mark_globalW_ptr ITTNOTIFY_NAME(mark_globalW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark_global ITTNOTIFY_DATA(mark_global) #define __itt_mark_global_ptr ITTNOTIFY_NAME(mark_global) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_mark_globalA(mt, parameter) (int)0 #define __itt_mark_globalA_ptr 0 #define __itt_mark_globalW(mt, parameter) (int)0 #define __itt_mark_globalW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark_global(mt, parameter) (int)0 #define __itt_mark_global_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_mark_globalA_ptr 0 #define __itt_mark_globalW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_mark_global_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Creates an "end" point for "continuous" mark with specified name. * * - Returns zero value in case of success, non-zero value otherwise. * Also returns non-zero value when preceding "begin" point for the * mark with the same name failed to be created or not created. * - The mark of "continuous" type is placed to collection results in * case of success. It appears in overtime view(s) as a special tick * sign (different from "discrete" mark) together with line from * corresponding "begin" mark to "end" mark. * @note Continuous marks can overlap and be nested inside each other. * Discrete mark can be nested inside marked region * @param[in] mt - mark, created by __itt_mark_create(const char* name) function * @return Returns zero value in case of success, non-zero value otherwise. */ int ITTAPI __itt_mark_off(__itt_mark_type mt); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, int, mark_off, (__itt_mark_type mt)) #define __itt_mark_off ITTNOTIFY_DATA(mark_off) #define __itt_mark_off_ptr ITTNOTIFY_NAME(mark_off) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_mark_off(mt) (int)0 #define __itt_mark_off_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_mark_off_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Use this if necessary to create an "end" point for mark of process * @see int __itt_mark_off(__itt_mark_type mt); */ int ITTAPI __itt_mark_global_off(__itt_mark_type mt); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, int, mark_global_off, (__itt_mark_type mt)) #define __itt_mark_global_off ITTNOTIFY_DATA(mark_global_off) #define __itt_mark_global_off_ptr ITTNOTIFY_NAME(mark_global_off) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_mark_global_off(mt) (int)0 #define __itt_mark_global_off_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_mark_global_off_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} marks group */ /** * @defgroup counters_internal Counters * @ingroup internal * Counters group * @{ */ /** * @brief opaque structure for counter identification */ typedef struct ___itt_counter *__itt_counter; /** * @brief Create a counter with given name/domain for the calling thread * * After __itt_counter_create() is called, __itt_counter_inc() / __itt_counter_inc_delta() can be used * to increment the counter on any thread */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_counter ITTAPI __itt_counter_createA(const char *name, const char *domain); __itt_counter ITTAPI __itt_counter_createW(const wchar_t *name, const wchar_t *domain); #if defined(UNICODE) || defined(_UNICODE) # define __itt_counter_create __itt_counter_createW # define __itt_counter_create_ptr __itt_counter_createW_ptr #else /* UNICODE */ # define __itt_counter_create __itt_counter_createA # define __itt_counter_create_ptr __itt_counter_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_counter ITTAPI __itt_counter_create(const char *name, const char *domain); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_counter, counter_createA, (const char *name, const char *domain)) ITT_STUB(ITTAPI, __itt_counter, counter_createW, (const wchar_t *name, const wchar_t *domain)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_counter, counter_create, (const char *name, const char *domain)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_counter_createA ITTNOTIFY_DATA(counter_createA) #define __itt_counter_createA_ptr ITTNOTIFY_NAME(counter_createA) #define __itt_counter_createW ITTNOTIFY_DATA(counter_createW) #define __itt_counter_createW_ptr ITTNOTIFY_NAME(counter_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_counter_create ITTNOTIFY_DATA(counter_create) #define __itt_counter_create_ptr ITTNOTIFY_NAME(counter_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_counter_createA(name, domain) #define __itt_counter_createA_ptr 0 #define __itt_counter_createW(name, domain) #define __itt_counter_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_counter_create(name, domain) #define __itt_counter_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_counter_createA_ptr 0 #define __itt_counter_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_counter_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Destroy the counter identified by the pointer previously returned by __itt_counter_create() */ void ITTAPI __itt_counter_destroy(__itt_counter id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, counter_destroy, (__itt_counter id)) #define __itt_counter_destroy ITTNOTIFY_VOID(counter_destroy) #define __itt_counter_destroy_ptr ITTNOTIFY_NAME(counter_destroy) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_counter_destroy(id) #define __itt_counter_destroy_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_counter_destroy_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Increment the counter value */ void ITTAPI __itt_counter_inc(__itt_counter id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, counter_inc, (__itt_counter id)) #define __itt_counter_inc ITTNOTIFY_VOID(counter_inc) #define __itt_counter_inc_ptr ITTNOTIFY_NAME(counter_inc) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_counter_inc(id) #define __itt_counter_inc_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_counter_inc_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Increment the counter value with x */ void ITTAPI __itt_counter_inc_delta(__itt_counter id, unsigned long long value); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, counter_inc_delta, (__itt_counter id, unsigned long long value)) #define __itt_counter_inc_delta ITTNOTIFY_VOID(counter_inc_delta) #define __itt_counter_inc_delta_ptr ITTNOTIFY_NAME(counter_inc_delta) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_counter_inc_delta(id, value) #define __itt_counter_inc_delta_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_counter_inc_delta_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} counters group */ /** * @defgroup stitch Stack Stitching * @ingroup internal * Stack Stitching group * @{ */ /** * @brief opaque structure for counter identification */ typedef struct ___itt_caller *__itt_caller; /** * @brief Create the stitch point e.g. a point in call stack where other stacks should be stitched to. * The function returns a unique identifier which is used to match the cut points with corresponding stitch points. */ __itt_caller ITTAPI __itt_stack_caller_create(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_caller, stack_caller_create, (void)) #define __itt_stack_caller_create ITTNOTIFY_DATA(stack_caller_create) #define __itt_stack_caller_create_ptr ITTNOTIFY_NAME(stack_caller_create) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_stack_caller_create() (__itt_caller)0 #define __itt_stack_caller_create_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_stack_caller_create_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Destroy the inforamtion about stitch point identified by the pointer previously returned by __itt_stack_caller_create() */ void ITTAPI __itt_stack_caller_destroy(__itt_caller id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, stack_caller_destroy, (__itt_caller id)) #define __itt_stack_caller_destroy ITTNOTIFY_VOID(stack_caller_destroy) #define __itt_stack_caller_destroy_ptr ITTNOTIFY_NAME(stack_caller_destroy) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_stack_caller_destroy(id) #define __itt_stack_caller_destroy_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_stack_caller_destroy_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Sets the cut point. Stack from each event which occurs after this call will be cut * at the same stack level the function was called and stitched to the corresponding stitch point. */ void ITTAPI __itt_stack_callee_enter(__itt_caller id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, stack_callee_enter, (__itt_caller id)) #define __itt_stack_callee_enter ITTNOTIFY_VOID(stack_callee_enter) #define __itt_stack_callee_enter_ptr ITTNOTIFY_NAME(stack_callee_enter) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_stack_callee_enter(id) #define __itt_stack_callee_enter_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_stack_callee_enter_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief This function eliminates the cut point which was set by latest __itt_stack_callee_enter(). */ void ITTAPI __itt_stack_callee_leave(__itt_caller id); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, stack_callee_leave, (__itt_caller id)) #define __itt_stack_callee_leave ITTNOTIFY_VOID(stack_callee_leave) #define __itt_stack_callee_leave_ptr ITTNOTIFY_NAME(stack_callee_leave) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_stack_callee_leave(id) #define __itt_stack_callee_leave_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_stack_callee_leave_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} stitch group */ /* ***************************************************************************************************************************** */ #include /** @cond exclude_from_documentation */ typedef enum __itt_error_code { __itt_error_success = 0, /*!< no error */ __itt_error_no_module = 1, /*!< module can't be loaded */ /* %1$s -- library name; win: %2$d -- system error code; unx: %2$s -- system error message. */ __itt_error_no_symbol = 2, /*!< symbol not found */ /* %1$s -- library name, %2$s -- symbol name. */ __itt_error_unknown_group = 3, /*!< unknown group specified */ /* %1$s -- env var name, %2$s -- group name. */ __itt_error_cant_read_env = 4, /*!< GetEnvironmentVariable() failed */ /* %1$s -- env var name, %2$d -- system error. */ __itt_error_env_too_long = 5, /*!< variable value too long */ /* %1$s -- env var name, %2$d -- actual length of the var, %3$d -- max allowed length. */ __itt_error_system = 6 /*!< pthread_mutexattr_init or pthread_mutex_init failed */ /* %1$s -- function name, %2$d -- errno. */ } __itt_error_code; typedef void (__itt_error_handler_t)(__itt_error_code code, va_list); __itt_error_handler_t* __itt_set_error_handler(__itt_error_handler_t*); const char* ITTAPI __itt_api_version(void); /** @endcond */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #define __itt_error_handler ITT_JOIN(INTEL_ITTNOTIFY_PREFIX, error_handler) void __itt_error_handler(__itt_error_code code, va_list args); extern const int ITTNOTIFY_NAME(err); #define __itt_err ITTNOTIFY_NAME(err) ITT_STUB(ITTAPI, const char*, api_version, (void)) #define __itt_api_version ITTNOTIFY_DATA(api_version) #define __itt_api_version_ptr ITTNOTIFY_NAME(api_version) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_api_version() (const char*)0 #define __itt_api_version_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_api_version_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _ITTNOTIFY_PRIVATE_ */ #endif /* INTEL_ITTNOTIFY_API_PRIVATE */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/ittnotify_config.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _ITTNOTIFY_CONFIG_H_ #define _ITTNOTIFY_CONFIG_H_ /** @cond exclude_from_documentation */ #ifndef ITT_OS_WIN # define ITT_OS_WIN 1 #endif /* ITT_OS_WIN */ #ifndef ITT_OS_LINUX # define ITT_OS_LINUX 2 #endif /* ITT_OS_LINUX */ #ifndef ITT_OS_MAC # define ITT_OS_MAC 3 #endif /* ITT_OS_MAC */ #ifndef ITT_OS # if defined WIN32 || defined _WIN32 # define ITT_OS ITT_OS_WIN # elif defined( __APPLE__ ) && defined( __MACH__ ) # define ITT_OS ITT_OS_MAC # else # define ITT_OS ITT_OS_LINUX # endif #endif /* ITT_OS */ #ifndef ITT_PLATFORM_WIN # define ITT_PLATFORM_WIN 1 #endif /* ITT_PLATFORM_WIN */ #ifndef ITT_PLATFORM_POSIX # define ITT_PLATFORM_POSIX 2 #endif /* ITT_PLATFORM_POSIX */ #ifndef ITT_PLATFORM_MAC # define ITT_PLATFORM_MAC 3 #endif /* ITT_PLATFORM_MAC */ #ifndef ITT_PLATFORM # if ITT_OS==ITT_OS_WIN # define ITT_PLATFORM ITT_PLATFORM_WIN # elif ITT_OS==ITT_OS_MAC # define ITT_PLATFORM ITT_PLATFORM_MAC # else # define ITT_PLATFORM ITT_PLATFORM_POSIX # endif #endif /* ITT_PLATFORM */ #if defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif #include #if ITT_PLATFORM==ITT_PLATFORM_WIN #include #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #include #if defined(UNICODE) || defined(_UNICODE) #include #endif /* UNICODE || _UNICODE */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #ifndef CDECL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define CDECL __cdecl # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define CDECL __attribute__ ((cdecl)) # else /* _M_IX86 || __i386__ */ # define CDECL /* actual only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* CDECL */ #ifndef STDCALL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define STDCALL __stdcall # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define STDCALL __attribute__ ((stdcall)) # else /* _M_IX86 || __i386__ */ # define STDCALL /* supported only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* STDCALL */ #define ITTAPI CDECL #define LIBITTAPI CDECL /* TODO: Temporary for compatibility! */ #define ITTAPI_CALL CDECL #define LIBITTAPI_CALL CDECL #if ITT_PLATFORM==ITT_PLATFORM_WIN /* use __forceinline (VC++ specific) */ #define ITT_INLINE __forceinline #define ITT_INLINE_ATTRIBUTE /* nothing */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /* * Generally, functions are not inlined unless optimization is specified. * For functions declared inline, this attribute inlines the function even * if no optimization level was specified. */ #ifdef __STRICT_ANSI__ #define ITT_INLINE static inline #else /* __STRICT_ANSI__ */ #define ITT_INLINE static inline #endif /* __STRICT_ANSI__ */ #define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline, unused)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @endcond */ #ifndef ITT_ARCH_IA32 # define ITT_ARCH_IA32 1 #endif /* ITT_ARCH_IA32 */ #ifndef ITT_ARCH_IA32E # define ITT_ARCH_IA32E 2 #endif /* ITT_ARCH_IA32E */ #ifndef ITT_ARCH_ARM # define ITT_ARCH_ARM 4 #endif /* ITT_ARCH_ARM */ #ifndef ITT_ARCH # if defined _M_IX86 || defined __i386__ # define ITT_ARCH ITT_ARCH_IA32 # elif defined _M_X64 || defined _M_AMD64 || defined __x86_64__ # define ITT_ARCH ITT_ARCH_IA32E # elif defined _M_IA64 || defined __ia64__ # define ITT_ARCH ITT_ARCH_IA64 # elif defined _M_ARM || __arm__ # define ITT_ARCH ITT_ARCH_ARM # endif #endif #ifdef __cplusplus # define ITT_EXTERN_C extern "C" #else # define ITT_EXTERN_C /* nothing */ #endif /* __cplusplus */ #define ITT_TO_STR_AUX(x) #x #define ITT_TO_STR(x) ITT_TO_STR_AUX(x) #define __ITT_BUILD_ASSERT(expr, suffix) do { \ static char __itt_build_check_##suffix[(expr) ? 1 : -1]; \ __itt_build_check_##suffix[0] = 0; \ } while(0) #define _ITT_BUILD_ASSERT(expr, suffix) __ITT_BUILD_ASSERT((expr), suffix) #define ITT_BUILD_ASSERT(expr) _ITT_BUILD_ASSERT((expr), __LINE__) #define ITT_MAGIC { 0xED, 0xAB, 0xAB, 0xEC, 0x0D, 0xEE, 0xDA, 0x30 } /* Replace with snapshot date YYYYMMDD for promotion build. */ #define API_VERSION_BUILD 20111111 #ifndef API_VERSION_NUM #define API_VERSION_NUM 0.0.0 #endif /* API_VERSION_NUM */ #define API_VERSION "ITT-API-Version " ITT_TO_STR(API_VERSION_NUM) \ " (" ITT_TO_STR(API_VERSION_BUILD) ")" /* OS communication functions */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #include typedef HMODULE lib_t; typedef DWORD TIDT; typedef CRITICAL_SECTION mutex_t; #define MUTEX_INITIALIZER { 0 } #define strong_alias(name, aliasname) /* empty for Windows */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #include #if defined(UNICODE) || defined(_UNICODE) #include #endif /* UNICODE */ #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 /* need for PTHREAD_MUTEX_RECURSIVE */ #endif /* _GNU_SOURCE */ #ifndef __USE_UNIX98 #define __USE_UNIX98 1 /* need for PTHREAD_MUTEX_RECURSIVE, on SLES11.1 with gcc 4.3.4 wherein pthread.h missing dependency on __USE_XOPEN2K8 */ #endif /*__USE_UNIX98*/ #include typedef void* lib_t; typedef pthread_t TIDT; typedef pthread_mutex_t mutex_t; #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define _strong_alias(name, aliasname) \ extern __typeof (name) aliasname __attribute__ ((alias (#name))); #define strong_alias(name, aliasname) _strong_alias(name, aliasname) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_get_proc(lib, name) GetProcAddress(lib, name) #define __itt_mutex_init(mutex) InitializeCriticalSection(mutex) #define __itt_mutex_lock(mutex) EnterCriticalSection(mutex) #define __itt_mutex_unlock(mutex) LeaveCriticalSection(mutex) #define __itt_load_lib(name) LoadLibraryA(name) #define __itt_unload_lib(handle) FreeLibrary(handle) #define __itt_system_error() (int)GetLastError() #define __itt_fstrcmp(s1, s2) lstrcmpA(s1, s2) #define __itt_fstrlen(s) lstrlenA(s) #define __itt_fstrcpyn(s1, s2, l) lstrcpynA(s1, s2, l) #define __itt_fstrdup(s) _strdup(s) #define __itt_thread_id() GetCurrentThreadId() #define __itt_thread_yield() SwitchToThread() #ifndef ITT_SIMPLE_INIT ITT_INLINE long __itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE; ITT_INLINE long __itt_interlocked_increment(volatile long* ptr) { return InterlockedIncrement(ptr); } #endif /* ITT_SIMPLE_INIT */ #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ #define __itt_get_proc(lib, name) dlsym(lib, name) #define __itt_mutex_init(mutex) {\ pthread_mutexattr_t mutex_attr; \ int error_code = pthread_mutexattr_init(&mutex_attr); \ if (error_code) \ __itt_report_error(__itt_error_system, "pthread_mutexattr_init", \ error_code); \ error_code = pthread_mutexattr_settype(&mutex_attr, \ PTHREAD_MUTEX_RECURSIVE); \ if (error_code) \ __itt_report_error(__itt_error_system, "pthread_mutexattr_settype", \ error_code); \ error_code = pthread_mutex_init(mutex, &mutex_attr); \ if (error_code) \ __itt_report_error(__itt_error_system, "pthread_mutex_init", \ error_code); \ error_code = pthread_mutexattr_destroy(&mutex_attr); \ if (error_code) \ __itt_report_error(__itt_error_system, "pthread_mutexattr_destroy", \ error_code); \ } #define __itt_mutex_lock(mutex) pthread_mutex_lock(mutex) #define __itt_mutex_unlock(mutex) pthread_mutex_unlock(mutex) #define __itt_load_lib(name) dlopen(name, RTLD_LAZY) #define __itt_unload_lib(handle) dlclose(handle) #define __itt_system_error() errno #define __itt_fstrcmp(s1, s2) strcmp(s1, s2) #define __itt_fstrlen(s) strlen(s) #define __itt_fstrcpyn(s1, s2, l) strncpy(s1, s2, l) #define __itt_fstrdup(s) strdup(s) #define __itt_thread_id() pthread_self() #define __itt_thread_yield() sched_yield() #if ITT_ARCH==ITT_ARCH_IA64 #ifdef __INTEL_COMPILER #define __TBB_machine_fetchadd4(addr, val) __fetchadd4_acq((void *)addr, val) #else /* __INTEL_COMPILER */ /* TODO: Add Support for not Intel compilers for IA-64 architecture */ #endif /* __INTEL_COMPILER */ #elif ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_IA32E /* ITT_ARCH!=ITT_ARCH_IA64 */ ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend) ITT_INLINE_ATTRIBUTE; ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend) { long result; __asm__ __volatile__("lock\nxadd %0,%1" : "=r"(result),"=m"(*(int*)ptr) : "0"(addend), "m"(*(int*)ptr) : "memory"); return result; } #elif ITT_ARCH==ITT_ARCH_ARM #define __TBB_machine_fetchadd4(addr, val) __sync_fetch_and_add(addr, val) #endif /* ITT_ARCH==ITT_ARCH_IA64 */ #ifndef ITT_SIMPLE_INIT ITT_INLINE long __itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE; ITT_INLINE long __itt_interlocked_increment(volatile long* ptr) { return __TBB_machine_fetchadd4(ptr, 1) + 1L; } #endif /* ITT_SIMPLE_INIT */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ typedef enum { __itt_collection_normal = 0, __itt_collection_paused = 1 } __itt_collection_state; typedef enum { __itt_thread_normal = 0, __itt_thread_ignored = 1 } __itt_thread_state; #pragma pack(push, 8) typedef struct ___itt_thread_info { const char* nameA; /*!< Copy of original name in ASCII. */ #if defined(UNICODE) || defined(_UNICODE) const wchar_t* nameW; /*!< Copy of original name in UNICODE. */ #else /* UNICODE || _UNICODE */ void* nameW; #endif /* UNICODE || _UNICODE */ TIDT tid; __itt_thread_state state; /*!< Thread state (paused or normal) */ int extra1; /*!< Reserved to the runtime */ void* extra2; /*!< Reserved to the runtime */ struct ___itt_thread_info* next; } __itt_thread_info; #include "ittnotify_types.h" /* For __itt_group_id definition */ typedef struct ___itt_api_info_20101001 { const char* name; void** func_ptr; void* init_func; __itt_group_id group; } __itt_api_info_20101001; typedef struct ___itt_api_info { const char* name; void** func_ptr; void* init_func; void* null_func; __itt_group_id group; } __itt_api_info; struct ___itt_domain; struct ___itt_string_handle; typedef struct ___itt_global { unsigned char magic[8]; unsigned long version_major; unsigned long version_minor; unsigned long version_build; volatile long api_initialized; volatile long mutex_initialized; volatile long atomic_counter; mutex_t mutex; lib_t lib; void* error_handler; const char** dll_path_ptr; __itt_api_info* api_list_ptr; struct ___itt_global* next; /* Joinable structures below */ __itt_thread_info* thread_list; struct ___itt_domain* domain_list; struct ___itt_string_handle* string_list; __itt_collection_state state; } __itt_global; #pragma pack(pop) #define NEW_THREAD_INFO_W(gptr,h,h_tail,t,s,n) { \ h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \ if (h != NULL) { \ h->tid = t; \ h->nameA = NULL; \ h->nameW = n ? _wcsdup(n) : NULL; \ h->state = s; \ h->extra1 = 0; /* reserved */ \ h->extra2 = NULL; /* reserved */ \ h->next = NULL; \ if (h_tail == NULL) \ (gptr)->thread_list = h; \ else \ h_tail->next = h; \ } \ } #define NEW_THREAD_INFO_A(gptr,h,h_tail,t,s,n) { \ h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \ if (h != NULL) { \ h->tid = t; \ h->nameA = n ? __itt_fstrdup(n) : NULL; \ h->nameW = NULL; \ h->state = s; \ h->extra1 = 0; /* reserved */ \ h->extra2 = NULL; /* reserved */ \ h->next = NULL; \ if (h_tail == NULL) \ (gptr)->thread_list = h; \ else \ h_tail->next = h; \ } \ } #define NEW_DOMAIN_W(gptr,h,h_tail,name) { \ h = (__itt_domain*)malloc(sizeof(__itt_domain)); \ if (h != NULL) { \ h->flags = 0; /* domain is disabled by default */ \ h->nameA = NULL; \ h->nameW = name ? _wcsdup(name) : NULL; \ h->extra1 = 0; /* reserved */ \ h->extra2 = NULL; /* reserved */ \ h->next = NULL; \ if (h_tail == NULL) \ (gptr)->domain_list = h; \ else \ h_tail->next = h; \ } \ } #define NEW_DOMAIN_A(gptr,h,h_tail,name) { \ h = (__itt_domain*)malloc(sizeof(__itt_domain)); \ if (h != NULL) { \ h->flags = 0; /* domain is disabled by default */ \ h->nameA = name ? __itt_fstrdup(name) : NULL; \ h->nameW = NULL; \ h->extra1 = 0; /* reserved */ \ h->extra2 = NULL; /* reserved */ \ h->next = NULL; \ if (h_tail == NULL) \ (gptr)->domain_list = h; \ else \ h_tail->next = h; \ } \ } #define NEW_STRING_HANDLE_W(gptr,h,h_tail,name) { \ h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \ if (h != NULL) { \ h->strA = NULL; \ h->strW = name ? _wcsdup(name) : NULL; \ h->extra1 = 0; /* reserved */ \ h->extra2 = NULL; /* reserved */ \ h->next = NULL; \ if (h_tail == NULL) \ (gptr)->string_list = h; \ else \ h_tail->next = h; \ } \ } #define NEW_STRING_HANDLE_A(gptr,h,h_tail,name) { \ h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \ if (h != NULL) { \ h->strA = name ? __itt_fstrdup(name) : NULL; \ h->strW = NULL; \ h->extra1 = 0; /* reserved */ \ h->extra2 = NULL; /* reserved */ \ h->next = NULL; \ if (h_tail == NULL) \ (gptr)->string_list = h; \ else \ h_tail->next = h; \ } \ } #endif /* _ITTNOTIFY_CONFIG_H_ */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/ittnotify_static.c ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "ittnotify_config.h" #if ITT_PLATFORM==ITT_PLATFORM_WIN #define PATH_MAX 512 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ #include #include #include #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #include #include #include #include #define INTEL_NO_MACRO_BODY #define INTEL_ITTNOTIFY_API_PRIVATE #include "ittnotify.h" #include "legacy/ittnotify.h" #include "disable_warnings.h" static const char api_version[] = API_VERSION "\0\n@(#) $Revision: 336044 $\n"; #define _N_(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) #if ITT_OS==ITT_OS_WIN static const char* ittnotify_lib_name = "libittnotify.dll"; #elif ITT_OS==ITT_OS_LINUX static const char* ittnotify_lib_name = "libittnotify.so"; #elif ITT_OS==ITT_OS_MAC static const char* ittnotify_lib_name = "libittnotify.dylib"; #else #error Unsupported or unknown OS. #endif #ifdef __ANDROID__ #include #include #include #include #include #include #include #ifdef ITT_ANDROID_LOG #define ITT_ANDROID_LOG_TAG "INTEL_VTUNE_USERAPI" #define ITT_ANDROID_LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) #define ITT_ANDROID_LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) #define ITT_ANDROID_LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) #define ITT_ANDROID_LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) #else #define ITT_ANDROID_LOGI(...) #define ITT_ANDROID_LOGW(...) #define ITT_ANDROID_LOGE(...) #define ITT_ANDROID_LOGD(...) #endif /* default location of userapi collector on Android */ #define ANDROID_ITTNOTIFY_DEFAULT_PATH "/data/data/com.intel.vtune/intel/libittnotify.so" #endif #ifndef LIB_VAR_NAME #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM #define LIB_VAR_NAME INTEL_LIBITTNOTIFY32 #else #define LIB_VAR_NAME INTEL_LIBITTNOTIFY64 #endif #endif /* LIB_VAR_NAME */ #define ITT_MUTEX_INIT_AND_LOCK(p) { \ if (!p.mutex_initialized) \ { \ if (__itt_interlocked_increment(&p.atomic_counter) == 1) \ { \ __itt_mutex_init(&p.mutex); \ p.mutex_initialized = 1; \ } \ else \ while (!p.mutex_initialized) \ __itt_thread_yield(); \ } \ __itt_mutex_lock(&p.mutex); \ } const int _N_(err) = 0; typedef int (__itt_init_ittlib_t)(const char*, __itt_group_id); /* this define used to control initialization function name. */ #ifndef __itt_init_ittlib_name ITT_EXTERN_C int _N_(init_ittlib)(const char*, __itt_group_id); static __itt_init_ittlib_t* __itt_init_ittlib_ptr = _N_(init_ittlib); #define __itt_init_ittlib_name __itt_init_ittlib_ptr #endif /* __itt_init_ittlib_name */ typedef void (__itt_fini_ittlib_t)(void); /* this define used to control finalization function name. */ #ifndef __itt_fini_ittlib_name ITT_EXTERN_C void _N_(fini_ittlib)(void); static __itt_fini_ittlib_t* __itt_fini_ittlib_ptr = _N_(fini_ittlib); #define __itt_fini_ittlib_name __itt_fini_ittlib_ptr #endif /* __itt_fini_ittlib_name */ /* building pointers to imported funcs */ #undef ITT_STUBV #undef ITT_STUB #define ITT_STUB(api,type,name,args,params,ptr,group,format) \ static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ typedef type api ITT_JOIN(_N_(name),_t) args; \ ITT_EXTERN_C { ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); } \ static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ { \ __itt_init_ittlib_name(NULL, __itt_group_all); \ if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ return ITTNOTIFY_NAME(name) params; \ else \ return (type)0; \ } #define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ typedef type api ITT_JOIN(_N_(name),_t) args; \ ITT_EXTERN_C { ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); } \ static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ { \ __itt_init_ittlib_name(NULL, __itt_group_all); \ if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ ITTNOTIFY_NAME(name) params; \ else \ return; \ } #undef __ITT_INTERNAL_INIT #include "ittnotify_static.h" #undef ITT_STUB #undef ITT_STUBV #define ITT_STUB(api,type,name,args,params,ptr,group,format) \ static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ typedef type api ITT_JOIN(_N_(name),_t) args; \ ITT_EXTERN_C { ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); } #define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ typedef type api ITT_JOIN(_N_(name),_t) args; \ ITT_EXTERN_C { ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); } #define __ITT_INTERNAL_INIT #include "ittnotify_static.h" #undef __ITT_INTERNAL_INIT ITT_GROUP_LIST(group_list); #pragma pack(push, 8) typedef struct ___itt_group_alias { const char* env_var; __itt_group_id groups; } __itt_group_alias; static __itt_group_alias group_alias[] = { { "KMP_FOR_TPROFILE", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_mark) }, { "KMP_FOR_TCHECK", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_fsync | __itt_group_mark | __itt_group_suppress) }, { NULL, (__itt_group_none) }, { api_version, (__itt_group_none) } /* !!! Just to avoid unused code elimination !!! */ }; #pragma pack(pop) #if ITT_PLATFORM==ITT_PLATFORM_WIN #pragma warning(push) #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ static __itt_api_info api_list[] = { /* Define functions with static implementation */ #undef ITT_STUB #undef ITT_STUBV #define ITT_STUB(api,type,name,args,params,nameindll,group,format) { ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (__itt_group_id)(group)}, #define ITT_STUBV ITT_STUB #define __ITT_INTERNAL_INIT #include "ittnotify_static.h" #undef __ITT_INTERNAL_INIT /* Define functions without static implementation */ #undef ITT_STUB #undef ITT_STUBV #define ITT_STUB(api,type,name,args,params,nameindll,group,format) {ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), NULL, (__itt_group_id)(group)}, #define ITT_STUBV ITT_STUB #include "ittnotify_static.h" {NULL, NULL, NULL, NULL, __itt_group_none} }; #if ITT_PLATFORM==ITT_PLATFORM_WIN #pragma warning(pop) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /* private, init thread info item. used for internal purposes */ static __itt_thread_info init_thread_info = { (const char*)NULL, /* nameA */ #if defined(UNICODE) || defined(_UNICODE) (const wchar_t*)NULL, /* nameW */ #else (void*)NULL, /* nameW */ #endif 0, /* tid */ __itt_thread_normal, /* state */ 0, /* extra1 */ (void*)NULL, /* extra2 */ (__itt_thread_info*)NULL /* next */ }; /* private, NULL domain item. used for internal purposes */ static __itt_domain null_domain = { 0, /* flags: disabled by default */ (const char*)NULL, /* nameA */ #if defined(UNICODE) || defined(_UNICODE) (const wchar_t*)NULL, /* nameW */ #else (void*)NULL, /* nameW */ #endif 0, /* extra1 */ (void*)NULL, /* extra2 */ (__itt_domain*)NULL /* next */ }; /* private, NULL string handle item. used for internal purposes */ static __itt_string_handle null_string_handle = { (const char*)NULL, /* strA */ #if defined(UNICODE) || defined(_UNICODE) (const wchar_t*)NULL, /* strW */ #else (void*)NULL, /* strW */ #endif 0, /* extra1 */ (void*)NULL, /* extra2 */ (__itt_string_handle*)NULL /* next */ }; static const char dll_path[PATH_MAX] = { 0 }; /* static part descriptor which handles. all notification api attributes. */ __itt_global _N_(_ittapi_global) = { ITT_MAGIC, /* identification info */ ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD, /* version info */ 0, /* api_initialized */ 0, /* mutex_initialized */ 0, /* atomic_counter */ MUTEX_INITIALIZER, /* mutex */ NULL, /* dynamic library handle */ NULL, /* error_handler */ (const char**)&dll_path, /* dll_path_ptr */ (__itt_api_info*)&api_list, /* api_list_ptr */ NULL, /* next __itt_global */ (__itt_thread_info*)&init_thread_info, /* thread_list */ (__itt_domain*)&null_domain, /* domain_list */ (__itt_string_handle*)&null_string_handle, /* string_list */ __itt_collection_normal /* collection state */ }; typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id); typedef void (__itt_api_fini_t)(__itt_global*); /* ========================================================================= */ #ifdef ITT_NOTIFY_EXT_REPORT ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args); #endif /* ITT_NOTIFY_EXT_REPORT */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #pragma warning(push) #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ static void __itt_report_error(__itt_error_code code, ...) { va_list args; va_start(args, code); if (_N_(_ittapi_global).error_handler != NULL) { __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; handler(code, args); } #ifdef ITT_NOTIFY_EXT_REPORT _N_(error_handler)(code, args); #endif /* ITT_NOTIFY_EXT_REPORT */ va_end(args); } #if ITT_PLATFORM==ITT_PLATFORM_WIN #pragma warning(pop) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name) { __itt_domain *h_tail, *h; if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))) return ITTNOTIFY_NAME(domain_createW)(name); } if (name == NULL) return _N_(_ittapi_global).domain_list; ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) if (h->nameW != NULL && !wcscmp(h->nameW, name)) break; if (h == NULL) { NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name); } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); return h; } static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name) #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ { __itt_domain *h_tail, *h; if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); #if ITT_PLATFORM==ITT_PLATFORM_WIN if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))) return ITTNOTIFY_NAME(domain_createA)(name); #else if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))) return ITTNOTIFY_NAME(domain_create)(name); #endif } if (name == NULL) return _N_(_ittapi_global).domain_list; ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break; if (h == NULL) { NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name); } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); return h; } #if ITT_PLATFORM==ITT_PLATFORM_WIN static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name) { __itt_string_handle *h_tail, *h; if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))) return ITTNOTIFY_NAME(string_handle_createW)(name); } if (name == NULL) return _N_(_ittapi_global).string_list; ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) if (h->strW != NULL && !wcscmp(h->strW, name)) break; if (h == NULL) { NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name); } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); return h; } static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name) #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ { __itt_string_handle *h_tail, *h; if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); #if ITT_PLATFORM==ITT_PLATFORM_WIN if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))) return ITTNOTIFY_NAME(string_handle_createA)(name); #else if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))) return ITTNOTIFY_NAME(string_handle_create)(name); #endif } if (name == NULL) return _N_(_ittapi_global).string_list; ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break; if (h == NULL) { NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name); } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); return h; } /* -------------------------------------------------------------------------- */ static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void) { if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))) { ITTNOTIFY_NAME(pause)(); return; } } _N_(_ittapi_global).state = __itt_collection_paused; } static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void) { if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))) { ITTNOTIFY_NAME(resume)(); return; } } _N_(_ittapi_global).state = __itt_collection_normal; } #if ITT_PLATFORM==ITT_PLATFORM_WIN static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name) { TIDT tid = __itt_thread_id(); __itt_thread_info *h_tail, *h; if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))) { ITTNOTIFY_NAME(thread_set_nameW)(name); return; } } __itt_mutex_lock(&_N_(_ittapi_global).mutex); for (h_tail = NULL, h = _N_(_ittapi_global).thread_list; h != NULL; h_tail = h, h = h->next) if (h->tid == tid) break; if (h == NULL) { NEW_THREAD_INFO_W(&_N_(_ittapi_global), h, h_tail, tid, __itt_thread_normal, name); } else { h->nameW = name ? _wcsdup(name) : NULL; } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); } static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen) { namelen = namelen; ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name); return 0; } static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ { TIDT tid = __itt_thread_id(); __itt_thread_info *h_tail, *h; if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); #if ITT_PLATFORM==ITT_PLATFORM_WIN if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))) { ITTNOTIFY_NAME(thread_set_nameA)(name); return; } #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))) { ITTNOTIFY_NAME(thread_set_name)(name); return; } #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ } __itt_mutex_lock(&_N_(_ittapi_global).mutex); for (h_tail = NULL, h = _N_(_ittapi_global).thread_list; h != NULL; h_tail = h, h = h->next) if (h->tid == tid) break; if (h == NULL) { NEW_THREAD_INFO_A(&_N_(_ittapi_global), h, h_tail, tid, __itt_thread_normal, name); } else { h->nameA = name ? __itt_fstrdup(name) : NULL; } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); } #if ITT_PLATFORM==ITT_PLATFORM_WIN static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen) { namelen = namelen; ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name); return 0; } #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen) { ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name); return 0; } #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void) { TIDT tid = __itt_thread_id(); __itt_thread_info *h_tail, *h; if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) { __itt_init_ittlib_name(NULL, __itt_group_all); if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))) { ITTNOTIFY_NAME(thread_ignore)(); return; } } __itt_mutex_lock(&_N_(_ittapi_global).mutex); for (h_tail = NULL, h = _N_(_ittapi_global).thread_list; h != NULL; h_tail = h, h = h->next) if (h->tid == tid) break; if (h == NULL) { static const char* name = "unknown"; NEW_THREAD_INFO_A(&_N_(_ittapi_global), h, h_tail, tid, __itt_thread_ignored, name); } else { h->state = __itt_thread_ignored; } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); } static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void) { ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(); } static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void) { #ifdef __ANDROID__ /* * if LIB_VAR_NAME env variable were set before then stay previous value * else set default path */ setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0); #endif } /* -------------------------------------------------------------------------- */ static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len) { int i; int j; if (!s || !sep || !out || !len) return NULL; for (i = 0; s[i]; i++) { int b = 0; for (j = 0; sep[j]; j++) if (s[i] == sep[j]) { b = 1; break; } if (!b) break; } if (!s[i]) return NULL; *len = 0; *out = &s[i]; for (; s[i]; i++, (*len)++) { int b = 0; for (j = 0; sep[j]; j++) if (s[i] == sep[j]) { b = 1; break; } if (b) break; } for (; s[i]; i++) { int b = 0; for (j = 0; sep[j]; j++) if (s[i] == sep[j]) { b = 1; break; } if (!b) break; } return &s[i]; } /* This function return value of env variable that placed into static buffer. * !!! The same static buffer is used for subsequent calls. !!! * This was done to aviod dynamic allocation for few calls. * Actually we need this function only four times. */ static const char* __itt_get_env_var(const char* name) { #define MAX_ENV_VALUE_SIZE 4086 static char env_buff[MAX_ENV_VALUE_SIZE]; static char* env_value = (char*)env_buff; if (name != NULL) { #if ITT_PLATFORM==ITT_PLATFORM_WIN size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len); if (rc >= max_len) __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1)); else if (rc > 0) { const char* ret = (const char*)env_value; env_value += rc + 1; return ret; } else { /* If environment variable is empty, GetEnvirornmentVariables() * returns zero (number of characters (not including terminating null), * and GetLastError() returns ERROR_SUCCESS. */ DWORD err = GetLastError(); if (err == ERROR_SUCCESS) return env_value; if (err != ERROR_ENVVAR_NOT_FOUND) __itt_report_error(__itt_error_cant_read_env, name, (int)err); } #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ char* env = getenv(name); if (env != NULL) { size_t len = strlen(env); size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); if (len < max_len) { const char* ret = (const char*)env_value; strncpy(env_value, env, len + 1); env_value += len + 1; return ret; } else __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1)); } #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ } return NULL; } static const char* __itt_get_lib_name(void) { const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); #ifdef __ANDROID__ if (lib_name == NULL) { const char* const system_wide_marker_filename = "/data/local/tmp/com.intel.itt.collector_lib"; int itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY); ssize_t res = 0; if (itt_marker_file_fd == -1) { const pid_t my_pid = getpid(); char cmdline_path[PATH_MAX] = {0}; char package_name[PATH_MAX] = {0}; char app_sandbox_file[PATH_MAX] = {0}; int cmdline_fd = 0; ITT_ANDROID_LOGI("Unable to open system-wide marker file."); snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid); ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path); cmdline_fd = open(cmdline_path, O_RDONLY); if (cmdline_fd == -1) { ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path); return lib_name; } res = read(cmdline_fd, package_name, PATH_MAX - 1); if (res == -1) { ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path); res = close(cmdline_fd); if (res == -1) { ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); } return lib_name; } res = close(cmdline_fd); if (res == -1) { ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); return lib_name; } ITT_ANDROID_LOGI("Package name: %s\n", package_name); snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/com.intel.itt.collector_lib", package_name); ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file); itt_marker_file_fd = open(app_sandbox_file, O_RDONLY); if (itt_marker_file_fd == -1) { ITT_ANDROID_LOGE("Unable to open app marker file!"); return lib_name; } } { char itt_lib_name[PATH_MAX] = {0}; res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1); if (res == -1) { ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd); res = close(itt_marker_file_fd); if (res == -1) { ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); } return lib_name; } ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name); res = close(itt_marker_file_fd); if (res == -1) { ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); return lib_name; } ITT_ANDROID_LOGI("Set env"); res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0); if (res == -1) { ITT_ANDROID_LOGE("Unable to set env var!"); return lib_name; } lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); ITT_ANDROID_LOGI("ITT Lib path from env: %s", itt_lib_name); } } #endif return lib_name; } #ifndef min #define min(a,b) (a) < (b) ? (a) : (b) #endif /* min */ static __itt_group_id __itt_get_groups(void) { int i; __itt_group_id res = __itt_group_none; const char* var_name = "INTEL_ITTNOTIFY_GROUPS"; const char* group_str = __itt_get_env_var(var_name); if (group_str != NULL) { int len; char gr[255]; const char* chunk; while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL) { __itt_fstrcpyn(gr, chunk, sizeof(gr) - 1); gr[min(len, (int)(sizeof(gr) - 1))] = 0; for (i = 0; group_list[i].name != NULL; i++) { if (!__itt_fstrcmp(gr, group_list[i].name)) { res = (__itt_group_id)(res | group_list[i].id); break; } } } /* TODO: !!! Workaround for bug with warning for unknown group !!! * Should be fixed in new initialization scheme. * Now the following groups should be set always. */ for (i = 0; group_list[i].id != __itt_group_none; i++) if (group_list[i].id != __itt_group_all && group_list[i].id > __itt_group_splitter_min && group_list[i].id < __itt_group_splitter_max) res = (__itt_group_id)(res | group_list[i].id); return res; } else { for (i = 0; group_alias[i].env_var != NULL; i++) if (__itt_get_env_var(group_alias[i].env_var) != NULL) return group_alias[i].groups; } return res; } static int __itt_lib_version(lib_t lib) { if (lib == NULL) return 0; if (__itt_get_proc(lib, "__itt_api_init")) return 2; if (__itt_get_proc(lib, "__itt_api_version")) return 1; return 0; } /* It's not used right now! Comment it out to avoid warnings. static void __itt_reinit_all_pointers(void) { register int i; // Fill all pointers with initial stubs for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func; } */ static void __itt_nullify_all_pointers(void) { int i; /* Nulify all pointers except domain_create and string_handle_create */ for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; } #if ITT_PLATFORM==ITT_PLATFORM_WIN #pragma warning(push) #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_EXTERN_C void _N_(fini_ittlib)(void) { __itt_api_fini_t* __itt_api_fini_ptr; static volatile TIDT current_thread = 0; if (_N_(_ittapi_global).api_initialized) { __itt_mutex_lock(&_N_(_ittapi_global).mutex); if (_N_(_ittapi_global).api_initialized) { if (current_thread == 0) { current_thread = __itt_thread_id(); __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini"); if (__itt_api_fini_ptr) __itt_api_fini_ptr(&_N_(_ittapi_global)); __itt_nullify_all_pointers(); /* TODO: !!! not safe !!! don't support unload so far. * if (_N_(_ittapi_global).lib != NULL) * __itt_unload_lib(_N_(_ittapi_global).lib); * _N_(_ittapi_global).lib = NULL; */ _N_(_ittapi_global).api_initialized = 0; current_thread = 0; } } __itt_mutex_unlock(&_N_(_ittapi_global).mutex); } } ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups) { int i; __itt_group_id groups; #ifdef ITT_COMPLETE_GROUP __itt_group_id zero_group = __itt_group_none; #endif /* ITT_COMPLETE_GROUP */ static volatile TIDT current_thread = 0; if (!_N_(_ittapi_global).api_initialized) { #ifndef ITT_SIMPLE_INIT ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); #endif /* ITT_SIMPLE_INIT */ if (!_N_(_ittapi_global).api_initialized) { if (current_thread == 0) { current_thread = __itt_thread_id(); _N_(_ittapi_global).thread_list->tid = current_thread; if (lib_name == NULL) lib_name = __itt_get_lib_name(); groups = __itt_get_groups(); if (groups != __itt_group_none || lib_name != NULL) { _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name); if (_N_(_ittapi_global).lib != NULL) { __itt_api_init_t* __itt_api_init_ptr; int lib_version = __itt_lib_version(_N_(_ittapi_global).lib); switch (lib_version) { case 0: groups = __itt_group_legacy; case 1: /* Fill all pointers from dynamic library */ for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) { if (_N_(_ittapi_global).api_list_ptr[i].group & groups & init_groups) { *_N_(_ittapi_global).api_list_ptr[i].func_ptr = (void*)__itt_get_proc(_N_(_ittapi_global).lib, _N_(_ittapi_global).api_list_ptr[i].name); if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr == NULL) { /* Restore pointers for function with static implementation */ *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; __itt_report_error(__itt_error_no_symbol, lib_name, _N_(_ittapi_global).api_list_ptr[i].name); #ifdef ITT_COMPLETE_GROUP zero_group = (__itt_group_id)(zero_group | _N_(_ittapi_global).api_list_ptr[i].group); #endif /* ITT_COMPLETE_GROUP */ } } else *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; } if (groups == __itt_group_legacy) { /* Compatibility with legacy tools */ ITTNOTIFY_NAME(thread_ignore) = ITTNOTIFY_NAME(thr_ignore); #if ITT_PLATFORM==ITT_PLATFORM_WIN ITTNOTIFY_NAME(sync_createA) = ITTNOTIFY_NAME(sync_set_nameA); ITTNOTIFY_NAME(sync_createW) = ITTNOTIFY_NAME(sync_set_nameW); #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITTNOTIFY_NAME(sync_create) = ITTNOTIFY_NAME(sync_set_name); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITTNOTIFY_NAME(sync_prepare) = ITTNOTIFY_NAME(notify_sync_prepare); ITTNOTIFY_NAME(sync_cancel) = ITTNOTIFY_NAME(notify_sync_cancel); ITTNOTIFY_NAME(sync_acquired) = ITTNOTIFY_NAME(notify_sync_acquired); ITTNOTIFY_NAME(sync_releasing) = ITTNOTIFY_NAME(notify_sync_releasing); } #ifdef ITT_COMPLETE_GROUP for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) if (_N_(_ittapi_global).api_list_ptr[i].group & zero_group) *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; #endif /* ITT_COMPLETE_GROUP */ break; case 2: __itt_api_init_ptr = (__itt_api_init_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_init"); if (__itt_api_init_ptr) __itt_api_init_ptr(&_N_(_ittapi_global), init_groups); break; } } else { __itt_nullify_all_pointers(); __itt_report_error(__itt_error_no_module, lib_name, #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_system_error() #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ dlerror() #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ); } } else { __itt_nullify_all_pointers(); } _N_(_ittapi_global).api_initialized = 1; current_thread = 0; /* !!! Just to avoid unused code elimination !!! */ if (__itt_fini_ittlib_ptr == _N_(fini_ittlib)) current_thread = 0; } } #ifndef ITT_SIMPLE_INIT __itt_mutex_unlock(&_N_(_ittapi_global).mutex); #endif /* ITT_SIMPLE_INIT */ } /* Evaluating if any function ptr is non empty and it's in init_groups */ for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr != _N_(_ittapi_global).api_list_ptr[i].null_func && _N_(_ittapi_global).api_list_ptr[i].group & init_groups) return 1; return 0; } ITT_EXTERN_C __itt_error_handler_t* _N_(set_error_handler)(__itt_error_handler_t* handler) { __itt_error_handler_t* prev = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; _N_(_ittapi_global).error_handler = (void*)(size_t)handler; return prev; } #if ITT_PLATFORM==ITT_PLATFORM_WIN #pragma warning(pop) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/ittnotify_static.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "ittnotify_config.h" #ifndef ITT_FORMAT_DEFINED # ifndef ITT_FORMAT # define ITT_FORMAT # endif /* ITT_FORMAT */ # ifndef ITT_NO_PARAMS # define ITT_NO_PARAMS # endif /* ITT_NO_PARAMS */ #endif /* ITT_FORMAT_DEFINED */ /* * parameters for macro expected: * ITT_STUB(api, type, func_name, arguments, params, func_name_in_dll, group, printf_fmt) */ #ifdef __ITT_INTERNAL_INIT #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_domain*, domain_createA, (const char *name), (ITT_FORMAT name), domain_createA, __itt_group_structure, "\"%s\"") ITT_STUB(ITTAPI, __itt_domain*, domain_createW, (const wchar_t *name), (ITT_FORMAT name), domain_createW, __itt_group_structure, "\"%S\"") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_domain*, domain_create, (const char *name), (ITT_FORMAT name), domain_create, __itt_group_structure, "\"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createA, (const char *name), (ITT_FORMAT name), string_handle_createA, __itt_group_structure, "\"%s\"") ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createW, (const wchar_t *name), (ITT_FORMAT name), string_handle_createW, __itt_group_structure, "\"%S\"") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_create, (const char *name), (ITT_FORMAT name), string_handle_create, __itt_group_structure, "\"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, pause, (void), (ITT_NO_PARAMS), pause, __itt_group_control | __itt_group_legacy, "no args") ITT_STUBV(ITTAPI, void, resume, (void), (ITT_NO_PARAMS), resume, __itt_group_control | __itt_group_legacy, "no args") #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, thread_set_nameA, (const char *name), (ITT_FORMAT name), thread_set_nameA, __itt_group_thread, "\"%s\"") ITT_STUBV(ITTAPI, void, thread_set_nameW, (const wchar_t *name), (ITT_FORMAT name), thread_set_nameW, __itt_group_thread, "\"%S\"") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, thread_set_name, (const char *name), (ITT_FORMAT name), thread_set_name, __itt_group_thread, "\"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, thread_ignore, (void), (ITT_NO_PARAMS), thread_ignore, __itt_group_thread, "no args") #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(LIBITTAPI, int, thr_name_setA, (const char *name, int namelen), (ITT_FORMAT name, namelen), thr_name_setA, __itt_group_thread | __itt_group_legacy, "\"%s\", %d") ITT_STUB(LIBITTAPI, int, thr_name_setW, (const wchar_t *name, int namelen), (ITT_FORMAT name, namelen), thr_name_setW, __itt_group_thread | __itt_group_legacy, "\"%S\", %d") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, int, thr_name_set, (const char *name, int namelen), (ITT_FORMAT name, namelen), thr_name_set, __itt_group_thread | __itt_group_legacy, "\"%s\", %d") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(LIBITTAPI, void, thr_ignore, (void), (ITT_NO_PARAMS), thr_ignore, __itt_group_thread | __itt_group_legacy, "no args") #endif /* __ITT_INTERNAL_BODY */ ITT_STUBV(ITTAPI, void, enable_attach, (void), (ITT_NO_PARAMS), enable_attach, __itt_group_all, "no args") #else /* __ITT_INTERNAL_INIT */ #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, sync_createA, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_createA, __itt_group_sync | __itt_group_fsync, "%p, \"%s\", \"%s\", %x") ITT_STUBV(ITTAPI, void, sync_createW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_createW, __itt_group_sync | __itt_group_fsync, "%p, \"%S\", \"%S\", %x") ITT_STUBV(ITTAPI, void, sync_renameA, (void *addr, const char *name), (ITT_FORMAT addr, name), sync_renameA, __itt_group_sync | __itt_group_fsync, "%p, \"%s\"") ITT_STUBV(ITTAPI, void, sync_renameW, (void *addr, const wchar_t *name), (ITT_FORMAT addr, name), sync_renameW, __itt_group_sync | __itt_group_fsync, "%p, \"%S\"") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, sync_create, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_create, __itt_group_sync | __itt_group_fsync, "%p, \"%s\", \"%s\", %x") ITT_STUBV(ITTAPI, void, sync_rename, (void *addr, const char *name), (ITT_FORMAT addr, name), sync_rename, __itt_group_sync | __itt_group_fsync, "%p, \"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, sync_destroy, (void *addr), (ITT_FORMAT addr), sync_destroy, __itt_group_sync | __itt_group_fsync, "%p") ITT_STUBV(ITTAPI, void, sync_prepare, (void* addr), (ITT_FORMAT addr), sync_prepare, __itt_group_sync, "%p") ITT_STUBV(ITTAPI, void, sync_cancel, (void *addr), (ITT_FORMAT addr), sync_cancel, __itt_group_sync, "%p") ITT_STUBV(ITTAPI, void, sync_acquired, (void *addr), (ITT_FORMAT addr), sync_acquired, __itt_group_sync, "%p") ITT_STUBV(ITTAPI, void, sync_releasing, (void* addr), (ITT_FORMAT addr), sync_releasing, __itt_group_sync, "%p") ITT_STUBV(ITTAPI, void, suppress_push, (unsigned int mask), (ITT_FORMAT mask), suppress_push, __itt_group_suppress, "%p") ITT_STUBV(ITTAPI, void, suppress_pop, (void), (ITT_NO_PARAMS), suppress_pop, __itt_group_suppress, "no args") ITT_STUBV(ITTAPI, void, suppress_mark_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size),(ITT_FORMAT mode, mask, address, size), suppress_mark_range, __itt_group_suppress, "%d, %p, %p, %d") ITT_STUBV(ITTAPI, void, suppress_clear_range,(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size),(ITT_FORMAT mode, mask, address, size), suppress_clear_range,__itt_group_suppress, "%d, %p, %p, %d") ITT_STUBV(ITTAPI, void, fsync_prepare, (void* addr), (ITT_FORMAT addr), sync_prepare, __itt_group_fsync, "%p") ITT_STUBV(ITTAPI, void, fsync_cancel, (void *addr), (ITT_FORMAT addr), sync_cancel, __itt_group_fsync, "%p") ITT_STUBV(ITTAPI, void, fsync_acquired, (void *addr), (ITT_FORMAT addr), sync_acquired, __itt_group_fsync, "%p") ITT_STUBV(ITTAPI, void, fsync_releasing, (void* addr), (ITT_FORMAT addr), sync_releasing, __itt_group_fsync, "%p") ITT_STUBV(ITTAPI, void, model_site_begin, (__itt_model_site *site, __itt_model_site_instance *instance, const char *name), (ITT_FORMAT site, instance, name), model_site_begin, __itt_group_model, "%p, %p, \"%s\"") ITT_STUBV(ITTAPI, void, model_site_end, (__itt_model_site *site, __itt_model_site_instance *instance), (ITT_FORMAT site, instance), model_site_end, __itt_group_model, "%p, %p") ITT_STUBV(ITTAPI, void, model_task_begin, (__itt_model_task *task, __itt_model_task_instance *instance, const char *name), (ITT_FORMAT task, instance, name), model_task_begin, __itt_group_model, "%p, %p, \"%s\"") ITT_STUBV(ITTAPI, void, model_task_end, (__itt_model_task *task, __itt_model_task_instance *instance), (ITT_FORMAT task, instance), model_task_end, __itt_group_model, "%p, %p") ITT_STUBV(ITTAPI, void, model_lock_acquire, (void *lock), (ITT_FORMAT lock), model_lock_acquire, __itt_group_model, "%p") ITT_STUBV(ITTAPI, void, model_lock_release, (void *lock), (ITT_FORMAT lock), model_lock_release, __itt_group_model, "%p") ITT_STUBV(ITTAPI, void, model_record_allocation, (void *addr, size_t size), (ITT_FORMAT addr, size), model_record_allocation, __itt_group_model, "%p, %d") ITT_STUBV(ITTAPI, void, model_record_deallocation, (void *addr), (ITT_FORMAT addr), model_record_deallocation, __itt_group_model, "%p") ITT_STUBV(ITTAPI, void, model_induction_uses, (void* addr, size_t size), (ITT_FORMAT addr, size), model_induction_uses, __itt_group_model, "%p, %d") ITT_STUBV(ITTAPI, void, model_reduction_uses, (void* addr, size_t size), (ITT_FORMAT addr, size), model_reduction_uses, __itt_group_model, "%p, %d") ITT_STUBV(ITTAPI, void, model_observe_uses, (void* addr, size_t size), (ITT_FORMAT addr, size), model_observe_uses, __itt_group_model, "%p, %d") ITT_STUBV(ITTAPI, void, model_clear_uses, (void* addr), (ITT_FORMAT addr), model_clear_uses, __itt_group_model, "%p") #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, model_site_beginW, (const wchar_t *name), (ITT_FORMAT name), model_site_beginW, __itt_group_model, "\"%s\"") ITT_STUBV(ITTAPI, void, model_task_beginW, (const wchar_t *name), (ITT_FORMAT name), model_task_beginW, __itt_group_model, "\"%s\"") ITT_STUBV(ITTAPI, void, model_iteration_taskW, (const wchar_t *name), (ITT_FORMAT name), model_iteration_taskW, __itt_group_model, "\"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, model_site_beginA, (const char *name), (ITT_FORMAT name), model_site_beginA, __itt_group_model, "\"%s\"") ITT_STUBV(ITTAPI, void, model_site_beginAL, (const char *name, size_t len), (ITT_FORMAT name, len), model_site_beginAL, __itt_group_model, "\"%s\", %d") ITT_STUBV(ITTAPI, void, model_task_beginA, (const char *name), (ITT_FORMAT name), model_task_beginA, __itt_group_model, "\"%s\"") ITT_STUBV(ITTAPI, void, model_task_beginAL, (const char *name, size_t len), (ITT_FORMAT name, len), model_task_beginAL, __itt_group_model, "\"%s\", %d") ITT_STUBV(ITTAPI, void, model_iteration_taskA, (const char *name), (ITT_FORMAT name), model_iteration_taskA, __itt_group_model, "\"%s\"") ITT_STUBV(ITTAPI, void, model_iteration_taskAL, (const char *name, size_t len), (ITT_FORMAT name, len), model_iteration_taskAL, __itt_group_model, "\"%s\", %d") ITT_STUBV(ITTAPI, void, model_site_end_2, (void), (ITT_NO_PARAMS), model_site_end_2, __itt_group_model, "no args") ITT_STUBV(ITTAPI, void, model_task_end_2, (void), (ITT_NO_PARAMS), model_task_end_2, __itt_group_model, "no args") ITT_STUBV(ITTAPI, void, model_lock_acquire_2, (void *lock), (ITT_FORMAT lock), model_lock_acquire_2, __itt_group_model, "%p") ITT_STUBV(ITTAPI, void, model_lock_release_2, (void *lock), (ITT_FORMAT lock), model_lock_release_2, __itt_group_model, "%p") ITT_STUBV(ITTAPI, void, model_aggregate_task, (size_t count), (ITT_FORMAT count), model_aggregate_task, __itt_group_model, "%d") ITT_STUBV(ITTAPI, void, model_disable_push, (__itt_model_disable x), (ITT_FORMAT x), model_disable_push, __itt_group_model, "%p") ITT_STUBV(ITTAPI, void, model_disable_pop, (void), (ITT_NO_PARAMS), model_disable_pop, __itt_group_model, "no args") #endif /* __ITT_INTERNAL_BODY */ #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createA, (const char *name, const char *domain), (ITT_FORMAT name, domain), heap_function_createA, __itt_group_heap, "\"%s\", \"%s\"") ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createW, (const wchar_t *name, const wchar_t *domain), (ITT_FORMAT name, domain), heap_function_createW, __itt_group_heap, "\"%s\", \"%s\"") #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_heap_function, heap_function_create, (const char *name, const char *domain), (ITT_FORMAT name, domain), heap_function_create, __itt_group_heap, "\"%s\", \"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* __ITT_INTERNAL_BODY */ ITT_STUBV(ITTAPI, void, heap_allocate_begin, (__itt_heap_function h, size_t size, int initialized), (ITT_FORMAT h, size, initialized), heap_allocate_begin, __itt_group_heap, "%p, %lu, %d") ITT_STUBV(ITTAPI, void, heap_allocate_end, (__itt_heap_function h, void** addr, size_t size, int initialized), (ITT_FORMAT h, addr, size, initialized), heap_allocate_end, __itt_group_heap, "%p, %p, %lu, %d") ITT_STUBV(ITTAPI, void, heap_free_begin, (__itt_heap_function h, void* addr), (ITT_FORMAT h, addr), heap_free_begin, __itt_group_heap, "%p, %p") ITT_STUBV(ITTAPI, void, heap_free_end, (__itt_heap_function h, void* addr), (ITT_FORMAT h, addr), heap_free_end, __itt_group_heap, "%p, %p") ITT_STUBV(ITTAPI, void, heap_reallocate_begin, (__itt_heap_function h, void* addr, size_t new_size, int initialized), (ITT_FORMAT h, addr, new_size, initialized), heap_reallocate_begin, __itt_group_heap, "%p, %p, %lu, %d") ITT_STUBV(ITTAPI, void, heap_reallocate_end, (__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized), (ITT_FORMAT h, addr, new_addr, new_size, initialized), heap_reallocate_end, __itt_group_heap, "%p, %p, %p, %lu, %d") ITT_STUBV(ITTAPI, void, heap_internal_access_begin, (void), (ITT_NO_PARAMS), heap_internal_access_begin, __itt_group_heap, "no args") ITT_STUBV(ITTAPI, void, heap_internal_access_end, (void), (ITT_NO_PARAMS), heap_internal_access_end, __itt_group_heap, "no args") ITT_STUBV(ITTAPI, void, heap_record_memory_growth_begin, (void), (ITT_NO_PARAMS), heap_record_memory_growth_begin, __itt_group_heap, "no args") ITT_STUBV(ITTAPI, void, heap_record_memory_growth_end, (void), (ITT_NO_PARAMS), heap_record_memory_growth_end, __itt_group_heap, "no args") ITT_STUBV(ITTAPI, void, heap_reset_detection, (unsigned int reset_mask), (ITT_FORMAT reset_mask), heap_reset_detection, __itt_group_heap, "%u") ITT_STUBV(ITTAPI, void, heap_record, (unsigned int record_mask), (ITT_FORMAT record_mask), heap_record, __itt_group_heap, "%u") ITT_STUBV(ITTAPI, void, id_create, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), id_create, __itt_group_structure, "%p, %lu") ITT_STUBV(ITTAPI, void, id_destroy, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), id_destroy, __itt_group_structure, "%p, %lu") ITT_STUB(ITTAPI, __itt_timestamp, get_timestamp, (void), (ITT_NO_PARAMS), get_timestamp, __itt_group_structure, "no args") ITT_STUBV(ITTAPI, void, region_begin, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), region_begin, __itt_group_structure, "%p, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, region_end, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), region_end, __itt_group_structure, "%p, %lu") #ifndef __ITT_INTERNAL_BODY ITT_STUBV(ITTAPI, void, frame_begin_v3, (const __itt_domain *domain, __itt_id *id), (ITT_FORMAT domain, id), frame_begin_v3, __itt_group_structure, "%p, %p") ITT_STUBV(ITTAPI, void, frame_end_v3, (const __itt_domain *domain, __itt_id *id), (ITT_FORMAT domain, id), frame_end_v3, __itt_group_structure, "%p, %p") ITT_STUBV(ITTAPI, void, frame_submit_v3, (const __itt_domain *domain, __itt_id *id, __itt_timestamp begin, __itt_timestamp end), (ITT_FORMAT domain, id, begin, end), frame_submit_v3, __itt_group_structure, "%p, %p, %lu, %lu") #endif /* __ITT_INTERNAL_BODY */ ITT_STUBV(ITTAPI, void, task_group, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), task_group, __itt_group_structure, "%p, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, task_begin, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), task_begin, __itt_group_structure, "%p, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, task_begin_fn, (const __itt_domain *domain, __itt_id id, __itt_id parent, void* fn), (ITT_FORMAT domain, id, parent, fn), task_begin_fn, __itt_group_structure, "%p, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, task_end, (const __itt_domain *domain), (ITT_FORMAT domain), task_end, __itt_group_structure, "%p") ITT_STUBV(ITTAPI, void, counter_inc_v3, (const __itt_domain *domain, __itt_string_handle *name), (ITT_FORMAT domain, name), counter_inc_v3, __itt_group_structure, "%p, %p") ITT_STUBV(ITTAPI, void, counter_inc_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long value), (ITT_FORMAT domain, name, value), counter_inc_delta_v3, __itt_group_structure, "%p, %p, %lu") ITT_STUBV(ITTAPI, void, marker, (const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope), (ITT_FORMAT domain, id, name, scope), marker, __itt_group_structure, "%p, %lu, %p, %d") ITT_STUBV(ITTAPI, void, metadata_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data), (ITT_FORMAT domain, id, key, type, count, data), metadata_add, __itt_group_structure, "%p, %lu, %p, %d, %lu, %p") #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, metadata_str_addA, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char* data, size_t length), (ITT_FORMAT domain, id, key, data, length), metadata_str_addA, __itt_group_structure, "%p, %lu, %p, %p, %lu") ITT_STUBV(ITTAPI, void, metadata_str_addW, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t* data, size_t length), (ITT_FORMAT domain, id, key, data, length), metadata_str_addW, __itt_group_structure, "%p, %lu, %p, %p, %lu") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, metadata_str_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char* data, size_t length), (ITT_FORMAT domain, id, key, data, length), metadata_str_add, __itt_group_structure, "%p, %lu, %p, %p, %lu") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, relation_add_to_current, (const __itt_domain *domain, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, relation, tail), relation_add_to_current, __itt_group_structure, "%p, %lu, %p") ITT_STUBV(ITTAPI, void, relation_add, (const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, head, relation, tail), relation_add, __itt_group_structure, "%p, %p, %lu, %p") #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen), (ITT_FORMAT name, namelen), event_createA, __itt_group_mark | __itt_group_legacy, "\"%s\", %d") ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen), (ITT_FORMAT name, namelen), event_createW, __itt_group_mark | __itt_group_legacy, "\"%S\", %d") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen), (ITT_FORMAT name, namelen), event_create, __itt_group_mark | __itt_group_legacy, "\"%s\", %d") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event), (ITT_FORMAT event), event_start, __itt_group_mark | __itt_group_legacy, "%d") ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event), (ITT_FORMAT event), event_end, __itt_group_mark | __itt_group_legacy, "%d") #endif /* __ITT_INTERNAL_BODY */ #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, sync_set_nameA, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_set_nameA, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%s\", \"%s\", %x") ITT_STUBV(ITTAPI, void, sync_set_nameW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_set_nameW, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%S\", \"%S\", %x") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, sync_set_name, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_set_name, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "p, \"%s\", \"%s\", %x") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(LIBITTAPI, int, notify_sync_nameA, (void *p, const char *objtype, int typelen, const char *objname, int namelen, int attribute), (ITT_FORMAT p, objtype, typelen, objname, namelen, attribute), notify_sync_nameA, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%s\", %d, \"%s\", %d, %x") ITT_STUB(LIBITTAPI, int, notify_sync_nameW, (void *p, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute), (ITT_FORMAT p, objtype, typelen, objname, namelen, attribute), notify_sync_nameW, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%S\", %d, \"%S\", %d, %x") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, int, notify_sync_name, (void *p, const char *objtype, int typelen, const char *objname, int namelen, int attribute), (ITT_FORMAT p, objtype, typelen, objname, namelen, attribute), notify_sync_name, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%s\", %d, \"%s\", %d, %x") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(LIBITTAPI, void, notify_sync_prepare, (void *p), (ITT_FORMAT p), notify_sync_prepare, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") ITT_STUBV(LIBITTAPI, void, notify_sync_cancel, (void *p), (ITT_FORMAT p), notify_sync_cancel, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") ITT_STUBV(LIBITTAPI, void, notify_sync_acquired, (void *p), (ITT_FORMAT p), notify_sync_acquired, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") ITT_STUBV(LIBITTAPI, void, notify_sync_releasing, (void *p), (ITT_FORMAT p), notify_sync_releasing, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") #endif /* __ITT_INTERNAL_BODY */ ITT_STUBV(LIBITTAPI, void, memory_read, (void *addr, size_t size), (ITT_FORMAT addr, size), memory_read, __itt_group_legacy, "%p, %lu") ITT_STUBV(LIBITTAPI, void, memory_write, (void *addr, size_t size), (ITT_FORMAT addr, size), memory_write, __itt_group_legacy, "%p, %lu") ITT_STUBV(LIBITTAPI, void, memory_update, (void *addr, size_t size), (ITT_FORMAT addr, size), memory_update, __itt_group_legacy, "%p, %lu") ITT_STUB(LIBITTAPI, __itt_state_t, state_get, (void), (ITT_NO_PARAMS), state_get, __itt_group_legacy, "no args") ITT_STUB(LIBITTAPI, __itt_state_t, state_set, (__itt_state_t s), (ITT_FORMAT s), state_set, __itt_group_legacy, "%d") ITT_STUB(LIBITTAPI, __itt_obj_state_t, obj_mode_set, (__itt_obj_prop_t p, __itt_obj_state_t s), (ITT_FORMAT p, s), obj_mode_set, __itt_group_legacy, "%d, %d") ITT_STUB(LIBITTAPI, __itt_thr_state_t, thr_mode_set, (__itt_thr_prop_t p, __itt_thr_state_t s), (ITT_FORMAT p, s), thr_mode_set, __itt_group_legacy, "%d, %d") #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_frame, frame_createA, (const char *domain), (ITT_FORMAT domain), frame_createA, __itt_group_frame, "\"%s\"") ITT_STUB(ITTAPI, __itt_frame, frame_createW, (const wchar_t *domain), (ITT_FORMAT domain), frame_createW, __itt_group_frame, "\"%s\"") #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_frame, frame_create, (const char *domain), (ITT_FORMAT domain), frame_create, __itt_group_frame, "\"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* __ITT_INTERNAL_BODY */ ITT_STUBV(ITTAPI, void, frame_begin, (__itt_frame frame), (ITT_FORMAT frame), frame_begin, __itt_group_frame, "%p") ITT_STUBV(ITTAPI, void, frame_end, (__itt_frame frame), (ITT_FORMAT frame), frame_end, __itt_group_frame, "%p") #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_counter, counter_createA, (const char *name, const char *domain), (ITT_FORMAT name, domain), counter_createA, __itt_group_counter, "\"%s\", \"%s\"") ITT_STUB(ITTAPI, __itt_counter, counter_createW, (const wchar_t *name, const wchar_t *domain), (ITT_FORMAT name, domain), counter_createW, __itt_group_counter, "\"%s\", \"%s\"") #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_counter, counter_create, (const char *name, const char *domain), (ITT_FORMAT name, domain), counter_create, __itt_group_counter, "\"%s\", \"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* __ITT_INTERNAL_BODY */ ITT_STUBV(ITTAPI, void, counter_destroy, (__itt_counter id), (ITT_FORMAT id), counter_destroy, __itt_group_counter, "%p") ITT_STUBV(ITTAPI, void, counter_inc, (__itt_counter id), (ITT_FORMAT id), counter_inc, __itt_group_counter, "%p") ITT_STUBV(ITTAPI, void, counter_inc_delta, (__itt_counter id, unsigned long long value), (ITT_FORMAT id, value), counter_inc_delta, __itt_group_counter, "%p, %lu") #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_mark_type, mark_createA, (const char *name), (ITT_FORMAT name), mark_createA, __itt_group_mark, "\"%s\"") ITT_STUB(ITTAPI, __itt_mark_type, mark_createW, (const wchar_t *name), (ITT_FORMAT name), mark_createW, __itt_group_mark, "\"%S\"") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_mark_type, mark_create, (const char *name), (ITT_FORMAT name), mark_create, __itt_group_mark, "\"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* __ITT_INTERNAL_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, int, markA, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), markA, __itt_group_mark, "%d, \"%s\"") ITT_STUB(ITTAPI, int, markW, (__itt_mark_type mt, const wchar_t *parameter), (ITT_FORMAT mt, parameter), markW, __itt_group_mark, "%d, \"%S\"") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, mark, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), mark, __itt_group_mark, "%d, \"%s\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, mark_off, (__itt_mark_type mt), (ITT_FORMAT mt), mark_off, __itt_group_mark, "%d") #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, int, mark_globalA, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), mark_globalA, __itt_group_mark, "%d, \"%s\"") ITT_STUB(ITTAPI, int, mark_globalW, (__itt_mark_type mt, const wchar_t *parameter), (ITT_FORMAT mt, parameter), mark_globalW, __itt_group_mark, "%d, \"%S\"") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, mark_global, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), mark_global, __itt_group_mark, "%d, \"%S\"") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, mark_global_off, (__itt_mark_type mt), (ITT_FORMAT mt), mark_global_off, __itt_group_mark, "%d") #ifndef __ITT_INTERNAL_BODY ITT_STUB(ITTAPI, __itt_caller, stack_caller_create, (void), (ITT_NO_PARAMS), stack_caller_create, __itt_group_stitch, "no args") #endif /* __ITT_INTERNAL_BODY */ ITT_STUBV(ITTAPI, void, stack_caller_destroy, (__itt_caller id), (ITT_FORMAT id), stack_caller_destroy, __itt_group_stitch, "%p") ITT_STUBV(ITTAPI, void, stack_callee_enter, (__itt_caller id), (ITT_FORMAT id), stack_callee_enter, __itt_group_stitch, "%p") ITT_STUBV(ITTAPI, void, stack_callee_leave, (__itt_caller id), (ITT_FORMAT id), stack_callee_leave, __itt_group_stitch, "%p") ITT_STUB(ITTAPI, __itt_clock_domain*, clock_domain_create, (__itt_get_clock_info_fn fn, void* fn_data), (ITT_FORMAT fn, fn_data), clock_domain_create, __itt_group_structure, "%p, %p") ITT_STUBV(ITTAPI, void, clock_domain_reset, (void), (ITT_NO_PARAMS), clock_domain_reset, __itt_group_structure, "no args") ITT_STUBV(ITTAPI, void, id_create_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id), (ITT_FORMAT domain, clock_domain, timestamp, id), id_create_ex, __itt_group_structure, "%p, %p, %lu, %lu") ITT_STUBV(ITTAPI, void, id_destroy_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id), (ITT_FORMAT domain, clock_domain, timestamp, id), id_destroy_ex, __itt_group_structure, "%p, %p, %lu, %lu") ITT_STUBV(ITTAPI, void, task_begin_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, __itt_string_handle *name), (ITT_FORMAT domain, clock_domain, timestamp, id, parentid, name), task_begin_ex, __itt_group_structure, "%p, %p, %lu, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, task_begin_fn_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, void* fn), (ITT_FORMAT domain, clock_domain, timestamp, id, parentid, fn), task_begin_fn_ex, __itt_group_structure, "%p, %p, %lu, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, task_end_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp), (ITT_FORMAT domain, clock_domain, timestamp), task_end_ex, __itt_group_structure, "%p, %p, %lu") ITT_STUBV(ITTAPI, void, task_begin_overlapped, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), task_begin_overlapped, __itt_group_structure, "%p, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, task_begin_overlapped_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, __itt_string_handle *name), (ITT_FORMAT domain, clock_domain, timestamp, id, parentid, name), task_begin_overlapped_ex, __itt_group_structure, "%p, %p, %lu, %lu, %lu, %p") ITT_STUBV(ITTAPI, void, task_end_overlapped, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), task_end_overlapped, __itt_group_structure, "%p, %lu") ITT_STUBV(ITTAPI, void, task_end_overlapped_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id), (ITT_FORMAT domain, clock_domain, timestamp, id), task_end_overlapped_ex, __itt_group_structure, "%p, %p, %lu, %lu") ITT_STUBV(ITTAPI, void, marker_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope), (ITT_FORMAT domain, clock_domain, timestamp, id, name, scope), marker_ex, __itt_group_structure, "%p, %p, %lu, %lu, %p, %d") ITT_STUBV(ITTAPI, void, metadata_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data), (ITT_FORMAT domain, scope, key, type, count, data), metadata_add_with_scope, __itt_group_structure, "%p, %d, %p, %d, %lu, %p") #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeA, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length), (ITT_FORMAT domain, scope, key, data, length), metadata_str_add_with_scopeA, __itt_group_structure, "%p, %d, %p, %p, %lu") ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeW, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length), (ITT_FORMAT domain, scope, key, data, length), metadata_str_add_with_scopeW, __itt_group_structure, "%p, %d, %p, %p, %lu") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, metadata_str_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length), (ITT_FORMAT domain, scope, key, data, length), metadata_str_add_with_scope, __itt_group_structure, "%p, %d, %p, %p, %lu") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, relation_add_to_current_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, clock_domain, timestamp, relation, tail), relation_add_to_current_ex, __itt_group_structure, "%p, %p, %lu, %d, %lu") ITT_STUBV(ITTAPI, void, relation_add_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, clock_domain, timestamp, head, relation, tail), relation_add_ex, __itt_group_structure, "%p, %p, %lu, %lu, %d, %lu") ITT_STUB(ITTAPI, __itt_track_group*, track_group_create, (__itt_string_handle* name, __itt_track_group_type track_group_type), (ITT_FORMAT name, track_group_type), track_group_create, __itt_group_structure, "%p, %d") ITT_STUB(ITTAPI, __itt_track*, track_create, (__itt_track_group* track_group,__itt_string_handle* name, __itt_track_type track_type), (ITT_FORMAT track_group, name, track_type), track_create, __itt_group_structure, "%p, %p, %d") ITT_STUBV(ITTAPI, void, set_track, (__itt_track *track), (ITT_FORMAT track), set_track, __itt_group_structure, "%p") #ifndef __ITT_INTERNAL_BODY ITT_STUB(ITTAPI, const char*, api_version, (void), (ITT_NO_PARAMS), api_version, __itt_group_all & ~__itt_group_legacy, "no args") #endif /* __ITT_INTERNAL_BODY */ #ifndef __ITT_INTERNAL_BODY #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, int, av_saveA, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder), (ITT_FORMAT data, rank, dimensions, type, filePath, columnOrder), av_saveA, __itt_group_arrays, "%p, %d, %p, %d, \"%s\", %d") ITT_STUB(ITTAPI, int, av_saveW, (void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder), (ITT_FORMAT data, rank, dimensions, type, filePath, columnOrder), av_saveW, __itt_group_arrays, "%p, %d, %p, %d, \"%S\", %d") #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, int, av_save, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder), (ITT_FORMAT data, rank, dimensions, type, filePath, columnOrder), av_save, __itt_group_arrays, "%p, %d, %p, %d, \"%s\", %d") #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* __ITT_INTERNAL_BODY */ #endif /* __ITT_INTERNAL_INIT */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/ittnotify_types.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _ITTNOTIFY_TYPES_H_ #define _ITTNOTIFY_TYPES_H_ typedef enum ___itt_group_id { __itt_group_none = 0, __itt_group_legacy = 1<<0, __itt_group_control = 1<<1, __itt_group_thread = 1<<2, __itt_group_mark = 1<<3, __itt_group_sync = 1<<4, __itt_group_fsync = 1<<5, __itt_group_jit = 1<<6, __itt_group_model = 1<<7, __itt_group_splitter_min = 1<<7, __itt_group_counter = 1<<8, __itt_group_frame = 1<<9, __itt_group_stitch = 1<<10, __itt_group_heap = 1<<11, __itt_group_splitter_max = 1<<12, __itt_group_structure = 1<<12, __itt_group_suppress = 1<<13, __itt_group_arrays = 1<<14, __itt_group_all = -1 } __itt_group_id; #pragma pack(push, 8) typedef struct ___itt_group_list { __itt_group_id id; const char* name; } __itt_group_list; #pragma pack(pop) #define ITT_GROUP_LIST(varname) \ static __itt_group_list varname[] = { \ { __itt_group_all, "all" }, \ { __itt_group_control, "control" }, \ { __itt_group_thread, "thread" }, \ { __itt_group_mark, "mark" }, \ { __itt_group_sync, "sync" }, \ { __itt_group_fsync, "fsync" }, \ { __itt_group_jit, "jit" }, \ { __itt_group_model, "model" }, \ { __itt_group_counter, "counter" }, \ { __itt_group_frame, "frame" }, \ { __itt_group_stitch, "stitch" }, \ { __itt_group_heap, "heap" }, \ { __itt_group_structure, "structure" }, \ { __itt_group_suppress, "suppress" }, \ { __itt_group_arrays, "arrays" }, \ { __itt_group_none, NULL } \ } #endif /* _ITTNOTIFY_TYPES_H_ */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/legacy/ittnotify.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _LEGACY_ITTNOTIFY_H_ #define _LEGACY_ITTNOTIFY_H_ /** * @file * @brief Legacy User API functions and types */ /** @cond exclude_from_documentation */ #ifndef ITT_OS_WIN # define ITT_OS_WIN 1 #endif /* ITT_OS_WIN */ #ifndef ITT_OS_LINUX # define ITT_OS_LINUX 2 #endif /* ITT_OS_LINUX */ #ifndef ITT_OS_MAC # define ITT_OS_MAC 3 #endif /* ITT_OS_MAC */ #ifndef ITT_OS # if defined WIN32 || defined _WIN32 # define ITT_OS ITT_OS_WIN # elif defined( __APPLE__ ) && defined( __MACH__ ) # define ITT_OS ITT_OS_MAC # else # define ITT_OS ITT_OS_LINUX # endif #endif /* ITT_OS */ #ifndef ITT_PLATFORM_WIN # define ITT_PLATFORM_WIN 1 #endif /* ITT_PLATFORM_WIN */ #ifndef ITT_PLATFORM_POSIX # define ITT_PLATFORM_POSIX 2 #endif /* ITT_PLATFORM_POSIX */ #ifndef ITT_PLATFORM_MAC # define ITT_PLATFORM_MAC 3 #endif /* ITT_PLATFORM_MAC */ #ifndef ITT_PLATFORM # if ITT_OS==ITT_OS_WIN # define ITT_PLATFORM ITT_PLATFORM_WIN # elif ITT_OS==ITT_OS_MAC # define ITT_PLATFORM ITT_PLATFORM_MAC # else # define ITT_PLATFORM ITT_PLATFORM_POSIX # endif #endif /* ITT_PLATFORM */ #if defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif #include #if ITT_PLATFORM==ITT_PLATFORM_WIN #include #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #include #if defined(UNICODE) || defined(_UNICODE) #include #endif /* UNICODE || _UNICODE */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #ifndef CDECL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define CDECL __cdecl # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define CDECL __attribute__ ((cdecl)) # else /* _M_IX86 || __i386__ */ # define CDECL /* actual only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* CDECL */ #ifndef STDCALL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define STDCALL __stdcall # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define STDCALL __attribute__ ((stdcall)) # else /* _M_IX86 || __i386__ */ # define STDCALL /* supported only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* STDCALL */ #define ITTAPI CDECL #define LIBITTAPI CDECL /* TODO: Temporary for compatibility! */ #define ITTAPI_CALL CDECL #define LIBITTAPI_CALL CDECL #if ITT_PLATFORM==ITT_PLATFORM_WIN /* use __forceinline (VC++ specific) */ #define ITT_INLINE __forceinline #define ITT_INLINE_ATTRIBUTE /* nothing */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /* * Generally, functions are not inlined unless optimization is specified. * For functions declared inline, this attribute inlines the function even * if no optimization level was specified. */ #ifdef __STRICT_ANSI__ #define ITT_INLINE static inline #else /* __STRICT_ANSI__ */ #define ITT_INLINE static inline #endif /* __STRICT_ANSI__ */ #define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline, unused)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @endcond */ /** @cond exclude_from_documentation */ /* Helper macro for joining tokens */ #define ITT_JOIN_AUX(p,n) p##n #define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) #ifdef ITT_MAJOR #undef ITT_MAJOR #endif #ifdef ITT_MINOR #undef ITT_MINOR #endif #define ITT_MAJOR 3 #define ITT_MINOR 0 /* Standard versioning of a token with major and minor version numbers */ #define ITT_VERSIONIZE(x) \ ITT_JOIN(x, \ ITT_JOIN(_, \ ITT_JOIN(ITT_MAJOR, \ ITT_JOIN(_, ITT_MINOR)))) #ifndef INTEL_ITTNOTIFY_PREFIX # define INTEL_ITTNOTIFY_PREFIX __itt_ #endif /* INTEL_ITTNOTIFY_PREFIX */ #ifndef INTEL_ITTNOTIFY_POSTFIX # define INTEL_ITTNOTIFY_POSTFIX _ptr_ #endif /* INTEL_ITTNOTIFY_POSTFIX */ #define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) #define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) #define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_VOID_D0(n,d) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_VOID_D1(n,d,x) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_VOID_D2(n,d,x,y) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_VOID_D3(n,d,x,y,z) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #define ITTNOTIFY_DATA_D0(n,d) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_DATA_D1(n,d,x) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_DATA_D2(n,d,x,y) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_DATA_D3(n,d,x,y,z) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #ifdef ITT_STUB #undef ITT_STUB #endif #ifdef ITT_STUBV #undef ITT_STUBV #endif #define ITT_STUBV(api,type,name,args) \ typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); #define ITT_STUB ITT_STUBV /** @endcond */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * @defgroup legacy Legacy API * @{ * @} */ /** * @defgroup legacy_control Collection Control * @ingroup legacy * General behavior: application continues to run, but no profiling information is being collected * * Pausing occurs not only for the current thread but for all process as well as spawned processes * - Intel(R) Parallel Inspector and Intel(R) Inspector XE: * - Does not analyze or report errors that involve memory access. * - Other errors are reported as usual. Pausing data collection in * Intel(R) Parallel Inspector and Intel(R) Inspector XE * only pauses tracing and analyzing memory access. * It does not pause tracing or analyzing threading APIs. * . * - Intel(R) Parallel Amplifier and Intel(R) VTune(TM) Amplifier XE: * - Does continue to record when new threads are started. * . * - Other effects: * - Possible reduction of runtime overhead. * . * @{ */ #ifndef _ITTNOTIFY_H_ /** @brief Pause collection */ void ITTAPI __itt_pause(void); /** @brief Resume collection */ void ITTAPI __itt_resume(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, pause, (void)) ITT_STUBV(ITTAPI, void, resume, (void)) #define __itt_pause ITTNOTIFY_VOID(pause) #define __itt_pause_ptr ITTNOTIFY_NAME(pause) #define __itt_resume ITTNOTIFY_VOID(resume) #define __itt_resume_ptr ITTNOTIFY_NAME(resume) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_pause() #define __itt_pause_ptr 0 #define __itt_resume() #define __itt_resume_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_pause_ptr 0 #define __itt_resume_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ #endif /* _ITTNOTIFY_H_ */ /** @} legacy_control group */ /** * @defgroup legacy_threads Threads * @ingroup legacy * Threads group * @warning Legacy API * @{ */ /** * @deprecated Legacy API * @brief Set name to be associated with thread in analysis GUI. * @return __itt_err upon failure (name or namelen being null,name and namelen mismatched) */ #if ITT_PLATFORM==ITT_PLATFORM_WIN int LIBITTAPI __itt_thr_name_setA(const char *name, int namelen); int LIBITTAPI __itt_thr_name_setW(const wchar_t *name, int namelen); #if defined(UNICODE) || defined(_UNICODE) # define __itt_thr_name_set __itt_thr_name_setW # define __itt_thr_name_set_ptr __itt_thr_name_setW_ptr #else # define __itt_thr_name_set __itt_thr_name_setA # define __itt_thr_name_set_ptr __itt_thr_name_setA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ int LIBITTAPI __itt_thr_name_set(const char *name, int namelen); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(LIBITTAPI, int, thr_name_setA, (const char *name, int namelen)) ITT_STUB(LIBITTAPI, int, thr_name_setW, (const wchar_t *name, int namelen)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, int, thr_name_set, (const char *name, int namelen)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_thr_name_setA ITTNOTIFY_DATA(thr_name_setA) #define __itt_thr_name_setA_ptr ITTNOTIFY_NAME(thr_name_setA) #define __itt_thr_name_setW ITTNOTIFY_DATA(thr_name_setW) #define __itt_thr_name_setW_ptr ITTNOTIFY_NAME(thr_name_setW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_thr_name_set ITTNOTIFY_DATA(thr_name_set) #define __itt_thr_name_set_ptr ITTNOTIFY_NAME(thr_name_set) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_thr_name_setA(name, namelen) #define __itt_thr_name_setA_ptr 0 #define __itt_thr_name_setW(name, namelen) #define __itt_thr_name_setW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_thr_name_set(name, namelen) #define __itt_thr_name_set_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_thr_name_setA_ptr 0 #define __itt_thr_name_setW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_thr_name_set_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Mark current thread as ignored from this point on, for the duration of its existence. */ void LIBITTAPI __itt_thr_ignore(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, thr_ignore, (void)) #define __itt_thr_ignore ITTNOTIFY_VOID(thr_ignore) #define __itt_thr_ignore_ptr ITTNOTIFY_NAME(thr_ignore) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_thr_ignore() #define __itt_thr_ignore_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_thr_ignore_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} legacy_threads group */ /** * @defgroup legacy_sync Synchronization * @ingroup legacy * Synchronization group * @warning Legacy API * @{ */ /** * @hideinitializer * @brief possible value of attribute argument for sync object type */ #define __itt_attr_barrier 1 /** * @hideinitializer * @brief possible value of attribute argument for sync object type */ #define __itt_attr_mutex 2 /** * @deprecated Legacy API * @brief Assign a name to a sync object using char or Unicode string * @param[in] addr - pointer to the sync object. You should use a real pointer to your object * to make sure that the values don't clash with other object addresses * @param[in] objtype - null-terminated object type string. If NULL is passed, the object will * be assumed to be of generic "User Synchronization" type * @param[in] objname - null-terminated object name string. If NULL, no name will be assigned * to the object -- you can use the __itt_sync_rename call later to assign * the name * @param[in] attribute - one of [#__itt_attr_barrier, #__itt_attr_mutex] values which defines the * exact semantics of how prepare/acquired/releasing calls work. */ #if ITT_PLATFORM==ITT_PLATFORM_WIN void ITTAPI __itt_sync_set_nameA(void *addr, const char *objtype, const char *objname, int attribute); void ITTAPI __itt_sync_set_nameW(void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute); #if defined(UNICODE) || defined(_UNICODE) # define __itt_sync_set_name __itt_sync_set_nameW # define __itt_sync_set_name_ptr __itt_sync_set_nameW_ptr #else /* UNICODE */ # define __itt_sync_set_name __itt_sync_set_nameA # define __itt_sync_set_name_ptr __itt_sync_set_nameA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ void ITTAPI __itt_sync_set_name(void *addr, const char* objtype, const char* objname, int attribute); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUBV(ITTAPI, void, sync_set_nameA, (void *addr, const char *objtype, const char *objname, int attribute)) ITT_STUBV(ITTAPI, void, sync_set_nameW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUBV(ITTAPI, void, sync_set_name, (void *addr, const char *objtype, const char *objname, int attribute)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_set_nameA ITTNOTIFY_VOID(sync_set_nameA) #define __itt_sync_set_nameA_ptr ITTNOTIFY_NAME(sync_set_nameA) #define __itt_sync_set_nameW ITTNOTIFY_VOID(sync_set_nameW) #define __itt_sync_set_nameW_ptr ITTNOTIFY_NAME(sync_set_nameW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_set_name ITTNOTIFY_VOID(sync_set_name) #define __itt_sync_set_name_ptr ITTNOTIFY_NAME(sync_set_name) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_set_nameA(addr, objtype, objname, attribute) #define __itt_sync_set_nameA_ptr 0 #define __itt_sync_set_nameW(addr, objtype, objname, attribute) #define __itt_sync_set_nameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_set_name(addr, objtype, objname, attribute) #define __itt_sync_set_name_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_sync_set_nameA_ptr 0 #define __itt_sync_set_nameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_sync_set_name_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Assign a name and type to a sync object using char or Unicode string * @param[in] addr - pointer to the sync object. You should use a real pointer to your object * to make sure that the values don't clash with other object addresses * @param[in] objtype - null-terminated object type string. If NULL is passed, the object will * be assumed to be of generic "User Synchronization" type * @param[in] objname - null-terminated object name string. If NULL, no name will be assigned * to the object -- you can use the __itt_sync_rename call later to assign * the name * @param[in] typelen, namelen - a lenght of string for appropriate objtype and objname parameter * @param[in] attribute - one of [#__itt_attr_barrier, #__itt_attr_mutex] values which defines the * exact semantics of how prepare/acquired/releasing calls work. * @return __itt_err upon failure (name or namelen being null,name and namelen mismatched) */ #if ITT_PLATFORM==ITT_PLATFORM_WIN int LIBITTAPI __itt_notify_sync_nameA(void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute); int LIBITTAPI __itt_notify_sync_nameW(void *addr, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute); #if defined(UNICODE) || defined(_UNICODE) # define __itt_notify_sync_name __itt_notify_sync_nameW #else # define __itt_notify_sync_name __itt_notify_sync_nameA #endif #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ int LIBITTAPI __itt_notify_sync_name(void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(LIBITTAPI, int, notify_sync_nameA, (void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute)) ITT_STUB(LIBITTAPI, int, notify_sync_nameW, (void *addr, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, int, notify_sync_name, (void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_notify_sync_nameA ITTNOTIFY_DATA(notify_sync_nameA) #define __itt_notify_sync_nameA_ptr ITTNOTIFY_NAME(notify_sync_nameA) #define __itt_notify_sync_nameW ITTNOTIFY_DATA(notify_sync_nameW) #define __itt_notify_sync_nameW_ptr ITTNOTIFY_NAME(notify_sync_nameW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_notify_sync_name ITTNOTIFY_DATA(notify_sync_name) #define __itt_notify_sync_name_ptr ITTNOTIFY_NAME(notify_sync_name) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_notify_sync_nameA(addr, objtype, typelen, objname, namelen, attribute) #define __itt_notify_sync_nameA_ptr 0 #define __itt_notify_sync_nameW(addr, objtype, typelen, objname, namelen, attribute) #define __itt_notify_sync_nameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_notify_sync_name(addr, objtype, typelen, objname, namelen, attribute) #define __itt_notify_sync_name_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_notify_sync_nameA_ptr 0 #define __itt_notify_sync_nameW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_notify_sync_name_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Enter spin loop on user-defined sync object */ void LIBITTAPI __itt_notify_sync_prepare(void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, notify_sync_prepare, (void *addr)) #define __itt_notify_sync_prepare ITTNOTIFY_VOID(notify_sync_prepare) #define __itt_notify_sync_prepare_ptr ITTNOTIFY_NAME(notify_sync_prepare) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_notify_sync_prepare(addr) #define __itt_notify_sync_prepare_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_notify_sync_prepare_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Quit spin loop without acquiring spin object */ void LIBITTAPI __itt_notify_sync_cancel(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, notify_sync_cancel, (void *addr)) #define __itt_notify_sync_cancel ITTNOTIFY_VOID(notify_sync_cancel) #define __itt_notify_sync_cancel_ptr ITTNOTIFY_NAME(notify_sync_cancel) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_notify_sync_cancel(addr) #define __itt_notify_sync_cancel_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_notify_sync_cancel_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Successful spin loop completion (sync object acquired) */ void LIBITTAPI __itt_notify_sync_acquired(void *addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, notify_sync_acquired, (void *addr)) #define __itt_notify_sync_acquired ITTNOTIFY_VOID(notify_sync_acquired) #define __itt_notify_sync_acquired_ptr ITTNOTIFY_NAME(notify_sync_acquired) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_notify_sync_acquired(addr) #define __itt_notify_sync_acquired_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_notify_sync_acquired_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Start sync object releasing code. Is called before the lock release call. */ void LIBITTAPI __itt_notify_sync_releasing(void* addr); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, notify_sync_releasing, (void *addr)) #define __itt_notify_sync_releasing ITTNOTIFY_VOID(notify_sync_releasing) #define __itt_notify_sync_releasing_ptr ITTNOTIFY_NAME(notify_sync_releasing) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_notify_sync_releasing(addr) #define __itt_notify_sync_releasing_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_notify_sync_releasing_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} legacy_sync group */ #ifndef _ITTNOTIFY_H_ /** * @defgroup legacy_events Events * @ingroup legacy * Events group * @{ */ /** @brief user event type */ typedef int __itt_event; /** * @brief Create an event notification * @note name or namelen being null/name and namelen not matching, user event feature not enabled * @return non-zero event identifier upon success and __itt_err otherwise */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_event LIBITTAPI __itt_event_createA(const char *name, int namelen); __itt_event LIBITTAPI __itt_event_createW(const wchar_t *name, int namelen); #if defined(UNICODE) || defined(_UNICODE) # define __itt_event_create __itt_event_createW # define __itt_event_create_ptr __itt_event_createW_ptr #else # define __itt_event_create __itt_event_createA # define __itt_event_create_ptr __itt_event_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_event LIBITTAPI __itt_event_create(const char *name, int namelen); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen)) ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_event_createA ITTNOTIFY_DATA(event_createA) #define __itt_event_createA_ptr ITTNOTIFY_NAME(event_createA) #define __itt_event_createW ITTNOTIFY_DATA(event_createW) #define __itt_event_createW_ptr ITTNOTIFY_NAME(event_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_event_create ITTNOTIFY_DATA(event_create) #define __itt_event_create_ptr ITTNOTIFY_NAME(event_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_event_createA(name, namelen) (__itt_event)0 #define __itt_event_createA_ptr 0 #define __itt_event_createW(name, namelen) (__itt_event)0 #define __itt_event_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_event_create(name, namelen) (__itt_event)0 #define __itt_event_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_event_createA_ptr 0 #define __itt_event_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_event_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an event occurrence. * @return __itt_err upon failure (invalid event id/user event feature not enabled) */ int LIBITTAPI __itt_event_start(__itt_event event); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event)) #define __itt_event_start ITTNOTIFY_DATA(event_start) #define __itt_event_start_ptr ITTNOTIFY_NAME(event_start) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_event_start(event) (int)0 #define __itt_event_start_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_event_start_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @brief Record an event end occurrence. * @note It is optional if events do not have durations. * @return __itt_err upon failure (invalid event id/user event feature not enabled) */ int LIBITTAPI __itt_event_end(__itt_event event); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event)) #define __itt_event_end ITTNOTIFY_DATA(event_end) #define __itt_event_end_ptr ITTNOTIFY_NAME(event_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_event_end(event) (int)0 #define __itt_event_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_event_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} legacy_events group */ #endif /* _ITTNOTIFY_H_ */ /** * @defgroup legacy_memory Memory Accesses * @ingroup legacy */ /** * @deprecated Legacy API * @brief Inform the tool of memory accesses on reading */ void LIBITTAPI __itt_memory_read(void *addr, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, memory_read, (void *addr, size_t size)) #define __itt_memory_read ITTNOTIFY_VOID(memory_read) #define __itt_memory_read_ptr ITTNOTIFY_NAME(memory_read) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_memory_read(addr, size) #define __itt_memory_read_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_memory_read_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Inform the tool of memory accesses on writing */ void LIBITTAPI __itt_memory_write(void *addr, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, memory_write, (void *addr, size_t size)) #define __itt_memory_write ITTNOTIFY_VOID(memory_write) #define __itt_memory_write_ptr ITTNOTIFY_NAME(memory_write) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_memory_write(addr, size) #define __itt_memory_write_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_memory_write_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief Inform the tool of memory accesses on updating */ void LIBITTAPI __itt_memory_update(void *address, size_t size); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(LIBITTAPI, void, memory_update, (void *addr, size_t size)) #define __itt_memory_update ITTNOTIFY_VOID(memory_update) #define __itt_memory_update_ptr ITTNOTIFY_NAME(memory_update) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_memory_update(addr, size) #define __itt_memory_update_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_memory_update_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} legacy_memory group */ /** * @defgroup legacy_state Thread and Object States * @ingroup legacy */ /** @brief state type */ typedef int __itt_state_t; /** @cond exclude_from_documentation */ typedef enum __itt_obj_state { __itt_obj_state_err = 0, __itt_obj_state_clr = 1, __itt_obj_state_set = 2, __itt_obj_state_use = 3 } __itt_obj_state_t; typedef enum __itt_thr_state { __itt_thr_state_err = 0, __itt_thr_state_clr = 1, __itt_thr_state_set = 2 } __itt_thr_state_t; typedef enum __itt_obj_prop { __itt_obj_prop_watch = 1, __itt_obj_prop_ignore = 2, __itt_obj_prop_sharable = 3 } __itt_obj_prop_t; typedef enum __itt_thr_prop { __itt_thr_prop_quiet = 1 } __itt_thr_prop_t; /** @endcond */ /** * @deprecated Legacy API * @brief managing thread and object states */ __itt_state_t LIBITTAPI __itt_state_get(void); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_state_t, state_get, (void)) #define __itt_state_get ITTNOTIFY_DATA(state_get) #define __itt_state_get_ptr ITTNOTIFY_NAME(state_get) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_state_get(void) (__itt_state_t)0 #define __itt_state_get_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_state_get_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief managing thread and object states */ __itt_state_t LIBITTAPI __itt_state_set(__itt_state_t s); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_state_t, state_set, (__itt_state_t s)) #define __itt_state_set ITTNOTIFY_DATA(state_set) #define __itt_state_set_ptr ITTNOTIFY_NAME(state_set) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_state_set(s) (__itt_state_t)0 #define __itt_state_set_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_state_set_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief managing thread and object modes */ __itt_thr_state_t LIBITTAPI __itt_thr_mode_set(__itt_thr_prop_t p, __itt_thr_state_t s); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_thr_state_t, thr_mode_set, (__itt_thr_prop_t p, __itt_thr_state_t s)) #define __itt_thr_mode_set ITTNOTIFY_DATA(thr_mode_set) #define __itt_thr_mode_set_ptr ITTNOTIFY_NAME(thr_mode_set) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_thr_mode_set(p, s) (__itt_thr_state_t)0 #define __itt_thr_mode_set_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_thr_mode_set_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** * @deprecated Legacy API * @brief managing thread and object modes */ __itt_obj_state_t LIBITTAPI __itt_obj_mode_set(__itt_obj_prop_t p, __itt_obj_state_t s); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUB(ITTAPI, __itt_obj_state_t, obj_mode_set, (__itt_obj_prop_t p, __itt_obj_state_t s)) #define __itt_obj_mode_set ITTNOTIFY_DATA(obj_mode_set) #define __itt_obj_mode_set_ptr ITTNOTIFY_NAME(obj_mode_set) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_obj_mode_set(p, s) (__itt_obj_state_t)0 #define __itt_obj_mode_set_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_obj_mode_set_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} legacy_state group */ /** * @defgroup frames Frames * @ingroup legacy * Frames group * @{ */ /** * @brief opaque structure for frame identification */ typedef struct __itt_frame_t *__itt_frame; /** * @brief Create a global frame with given domain */ #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_frame ITTAPI __itt_frame_createA(const char *domain); __itt_frame ITTAPI __itt_frame_createW(const wchar_t *domain); #if defined(UNICODE) || defined(_UNICODE) # define __itt_frame_create __itt_frame_createW # define __itt_frame_create_ptr __itt_frame_createW_ptr #else /* UNICODE */ # define __itt_frame_create __itt_frame_createA # define __itt_frame_create_ptr __itt_frame_createA_ptr #endif /* UNICODE */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ __itt_frame ITTAPI __itt_frame_create(const char *domain); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API #if ITT_PLATFORM==ITT_PLATFORM_WIN ITT_STUB(ITTAPI, __itt_frame, frame_createA, (const char *domain)) ITT_STUB(ITTAPI, __itt_frame, frame_createW, (const wchar_t *domain)) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITT_STUB(ITTAPI, __itt_frame, frame_create, (const char *domain)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_frame_createA ITTNOTIFY_DATA(frame_createA) #define __itt_frame_createA_ptr ITTNOTIFY_NAME(frame_createA) #define __itt_frame_createW ITTNOTIFY_DATA(frame_createW) #define __itt_frame_createW_ptr ITTNOTIFY_NAME(frame_createW) #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_frame_create ITTNOTIFY_DATA(frame_create) #define __itt_frame_create_ptr ITTNOTIFY_NAME(frame_create) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #else /* INTEL_NO_ITTNOTIFY_API */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_frame_createA(domain) #define __itt_frame_createA_ptr 0 #define __itt_frame_createW(domain) #define __itt_frame_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_frame_create(domain) #define __itt_frame_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #if ITT_PLATFORM==ITT_PLATFORM_WIN #define __itt_frame_createA_ptr 0 #define __itt_frame_createW_ptr 0 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #define __itt_frame_create_ptr 0 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @brief Record an frame begin occurrence. */ void ITTAPI __itt_frame_begin(__itt_frame frame); /** @brief Record an frame end occurrence. */ void ITTAPI __itt_frame_end (__itt_frame frame); /** @cond exclude_from_documentation */ #ifndef INTEL_NO_MACRO_BODY #ifndef INTEL_NO_ITTNOTIFY_API ITT_STUBV(ITTAPI, void, frame_begin, (__itt_frame frame)) ITT_STUBV(ITTAPI, void, frame_end, (__itt_frame frame)) #define __itt_frame_begin ITTNOTIFY_VOID(frame_begin) #define __itt_frame_begin_ptr ITTNOTIFY_NAME(frame_begin) #define __itt_frame_end ITTNOTIFY_VOID(frame_end) #define __itt_frame_end_ptr ITTNOTIFY_NAME(frame_end) #else /* INTEL_NO_ITTNOTIFY_API */ #define __itt_frame_begin(frame) #define __itt_frame_begin_ptr 0 #define __itt_frame_end(frame) #define __itt_frame_end_ptr 0 #endif /* INTEL_NO_ITTNOTIFY_API */ #else /* INTEL_NO_MACRO_BODY */ #define __itt_frame_begin_ptr 0 #define __itt_frame_end_ptr 0 #endif /* INTEL_NO_MACRO_BODY */ /** @endcond */ /** @} frames group */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _LEGACY_ITTNOTIFY_H_ */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/tools_api/prototype/ittnotify.h ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _PROTOTYPE_ITTNOTIFY_H_ #define _PROTOTYPE_ITTNOTIFY_H_ /** * @file * @brief Prototype User API functions and types */ /** @cond exclude_from_documentation */ #ifndef ITT_OS_WIN # define ITT_OS_WIN 1 #endif /* ITT_OS_WIN */ #ifndef ITT_OS_LINUX # define ITT_OS_LINUX 2 #endif /* ITT_OS_LINUX */ #ifndef ITT_OS_MAC # define ITT_OS_MAC 3 #endif /* ITT_OS_MAC */ #ifndef ITT_OS # if defined WIN32 || defined _WIN32 # define ITT_OS ITT_OS_WIN # elif defined( __APPLE__ ) && defined( __MACH__ ) # define ITT_OS ITT_OS_MAC # else # define ITT_OS ITT_OS_LINUX # endif #endif /* ITT_OS */ #ifndef ITT_PLATFORM_WIN # define ITT_PLATFORM_WIN 1 #endif /* ITT_PLATFORM_WIN */ #ifndef ITT_PLATFORM_POSIX # define ITT_PLATFORM_POSIX 2 #endif /* ITT_PLATFORM_POSIX */ #ifndef ITT_PLATFORM_MAC # define ITT_PLATFORM_MAC 3 #endif /* ITT_PLATFORM_MAC */ #ifndef ITT_PLATFORM # if ITT_OS==ITT_OS_WIN # define ITT_PLATFORM ITT_PLATFORM_WIN # elif ITT_OS==ITT_OS_MAC # define ITT_PLATFORM ITT_PLATFORM_MAC # else # define ITT_PLATFORM ITT_PLATFORM_POSIX # endif #endif /* ITT_PLATFORM */ #if defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif #include #if ITT_PLATFORM==ITT_PLATFORM_WIN #include #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #include #if defined(UNICODE) || defined(_UNICODE) #include #endif /* UNICODE || _UNICODE */ #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #ifndef CDECL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define CDECL __cdecl # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define CDECL __attribute__ ((cdecl)) # else /* _M_IX86 || __i386__ */ # define CDECL /* actual only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* CDECL */ #ifndef STDCALL # if ITT_PLATFORM==ITT_PLATFORM_WIN # define STDCALL __stdcall # else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ # if defined _M_IX86 || defined __i386__ # define STDCALL __attribute__ ((stdcall)) # else /* _M_IX86 || __i386__ */ # define STDCALL /* supported only on x86 platform */ # endif /* _M_IX86 || __i386__ */ # endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ #endif /* STDCALL */ #define ITTAPI CDECL #define LIBITTAPI CDECL /* TODO: Temporary for compatibility! */ #define ITTAPI_CALL CDECL #define LIBITTAPI_CALL CDECL #if ITT_PLATFORM==ITT_PLATFORM_WIN /* use __forceinline (VC++ specific) */ #define ITT_INLINE __forceinline #define ITT_INLINE_ATTRIBUTE /* nothing */ #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /* * Generally, functions are not inlined unless optimization is specified. * For functions declared inline, this attribute inlines the function even * if no optimization level was specified. */ #ifdef __STRICT_ANSI__ #define ITT_INLINE static #else /* __STRICT_ANSI__ */ #define ITT_INLINE static inline #endif /* __STRICT_ANSI__ */ #define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline, unused)) #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ /** @endcond */ /** @cond exclude_from_documentation */ /* Helper macro for joining tokens */ #define ITT_JOIN_AUX(p,n) p##n #define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) #ifdef ITT_MAJOR #undef ITT_MAJOR #endif #ifdef ITT_MINOR #undef ITT_MINOR #endif #define ITT_MAJOR 3 #define ITT_MINOR 0 /* Standard versioning of a token with major and minor version numbers */ #define ITT_VERSIONIZE(x) \ ITT_JOIN(x, \ ITT_JOIN(_, \ ITT_JOIN(ITT_MAJOR, \ ITT_JOIN(_, ITT_MINOR)))) #ifndef INTEL_ITTNOTIFY_PREFIX # define INTEL_ITTNOTIFY_PREFIX __itt_ #endif /* INTEL_ITTNOTIFY_PREFIX */ #ifndef INTEL_ITTNOTIFY_POSTFIX # define INTEL_ITTNOTIFY_POSTFIX _ptr_ #endif /* INTEL_ITTNOTIFY_POSTFIX */ #define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) #define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) #define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) #define ITTNOTIFY_VOID_D0(n,d) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_VOID_D1(n,d,x) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_VOID_D2(n,d,x,y) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_VOID_D3(n,d,x,y,z) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #define ITTNOTIFY_DATA_D0(n,d) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) #define ITTNOTIFY_DATA_D1(n,d,x) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) #define ITTNOTIFY_DATA_D2(n,d,x,y) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) #define ITTNOTIFY_DATA_D3(n,d,x,y,z) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) #define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) #define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) #define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) #ifdef ITT_STUB #undef ITT_STUB #endif #ifdef ITT_STUBV #undef ITT_STUBV #endif #define ITT_STUBV(api,type,name,args) \ typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); #define ITT_STUB ITT_STUBV /** @endcond */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * @defgroup prototype Prototype API * @{ * @} */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _PROTOTYPE_ITTNOTIFY_H_ */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/version_string.ver ================================================ #define __TBB_VERSION_STRINGS(N) "Empty" ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/win32-tbb-export.def ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. EXPORTS #define __TBB_SYMBOL( sym ) sym #if _M_ARM #include "winrt-tbb-export.lst" #else #include "win32-tbb-export.lst" #endif ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/win32-tbb-export.lst ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. #include "tbb/tbb_config.h" // Assembly-language support that is called directly by clients // __TBB_SYMBOL( __TBB_machine_cmpswp1 ) // __TBB_SYMBOL( __TBB_machine_cmpswp2 ) // __TBB_SYMBOL( __TBB_machine_cmpswp4 ) __TBB_SYMBOL( __TBB_machine_cmpswp8 ) // __TBB_SYMBOL( __TBB_machine_fetchadd1 ) // __TBB_SYMBOL( __TBB_machine_fetchadd2 ) // __TBB_SYMBOL( __TBB_machine_fetchadd4 ) __TBB_SYMBOL( __TBB_machine_fetchadd8 ) // __TBB_SYMBOL( __TBB_machine_fetchstore1 ) // __TBB_SYMBOL( __TBB_machine_fetchstore2 ) // __TBB_SYMBOL( __TBB_machine_fetchstore4 ) __TBB_SYMBOL( __TBB_machine_fetchstore8 ) __TBB_SYMBOL( __TBB_machine_store8 ) __TBB_SYMBOL( __TBB_machine_load8 ) __TBB_SYMBOL( __TBB_machine_trylockbyte ) __TBB_SYMBOL( __TBB_machine_try_lock_elided ) __TBB_SYMBOL( __TBB_machine_unlock_elided ) __TBB_SYMBOL( __TBB_machine_is_in_transaction ) // cache_aligned_allocator.cpp __TBB_SYMBOL( ?NFS_Allocate@internal@tbb@@YAPAXIIPAX@Z ) __TBB_SYMBOL( ?NFS_GetLineSize@internal@tbb@@YAIXZ ) __TBB_SYMBOL( ?NFS_Free@internal@tbb@@YAXPAX@Z ) __TBB_SYMBOL( ?allocate_via_handler_v3@internal@tbb@@YAPAXI@Z ) __TBB_SYMBOL( ?deallocate_via_handler_v3@internal@tbb@@YAXPAX@Z ) __TBB_SYMBOL( ?is_malloc_used_v3@internal@tbb@@YA_NXZ ) // task.cpp v3 __TBB_SYMBOL( ?allocate@allocate_additional_child_of_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) __TBB_SYMBOL( ?allocate@allocate_child_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) __TBB_SYMBOL( ?allocate@allocate_continuation_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) __TBB_SYMBOL( ?allocate@allocate_root_proxy@internal@tbb@@SAAAVtask@3@I@Z ) __TBB_SYMBOL( ?destroy@task_base@internal@interface5@tbb@@SAXAAVtask@4@@Z ) __TBB_SYMBOL( ?free@allocate_additional_child_of_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_child_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_continuation_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_root_proxy@internal@tbb@@SAXAAVtask@3@@Z ) __TBB_SYMBOL( ?internal_set_ref_count@task@tbb@@AAEXH@Z ) __TBB_SYMBOL( ?internal_decrement_ref_count@task@tbb@@AAEHXZ ) __TBB_SYMBOL( ?is_owned_by_current_thread@task@tbb@@QBE_NXZ ) __TBB_SYMBOL( ?note_affinity@task@tbb@@UAEXG@Z ) __TBB_SYMBOL( ?resize@affinity_partitioner_base_v3@internal@tbb@@AAEXI@Z ) __TBB_SYMBOL( ?self@task@tbb@@SAAAV12@XZ ) __TBB_SYMBOL( ?spawn_and_wait_for_all@task@tbb@@QAEXAAVtask_list@2@@Z ) __TBB_SYMBOL( ?default_num_threads@task_scheduler_init@tbb@@SAHXZ ) __TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAEXHI@Z ) __TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAEXH@Z ) __TBB_SYMBOL( ?terminate@task_scheduler_init@tbb@@QAEXXZ ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( ?observe@task_scheduler_observer_v3@internal@tbb@@QAEX_N@Z ) #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ) __TBB_SYMBOL( ?internal_initialize@task_arena_base@internal@interface7@tbb@@IAEXXZ ) __TBB_SYMBOL( ?internal_terminate@task_arena_base@internal@interface7@tbb@@IAEXXZ ) __TBB_SYMBOL( ?internal_enqueue@task_arena_base@internal@interface7@tbb@@IBEXAAVtask@4@H@Z ) __TBB_SYMBOL( ?internal_execute@task_arena_base@internal@interface7@tbb@@IBEXAAVdelegate_base@234@@Z ) __TBB_SYMBOL( ?internal_wait@task_arena_base@internal@interface7@tbb@@IBEXXZ ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY // task_v2.cpp __TBB_SYMBOL( ?destroy@task@tbb@@QAEXAAV12@@Z ) #endif // exception handling support #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( ?allocate@allocate_root_with_context_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) __TBB_SYMBOL( ?free@allocate_root_with_context_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) __TBB_SYMBOL( ?change_group@task@tbb@@QAEXAAVtask_group_context@2@@Z ) __TBB_SYMBOL( ?is_group_execution_cancelled@task_group_context@tbb@@QBE_NXZ ) __TBB_SYMBOL( ?cancel_group_execution@task_group_context@tbb@@QAE_NXZ ) __TBB_SYMBOL( ?reset@task_group_context@tbb@@QAEXXZ ) __TBB_SYMBOL( ?capture_fp_settings@task_group_context@tbb@@QAEXXZ ) __TBB_SYMBOL( ?init@task_group_context@tbb@@IAEXXZ ) __TBB_SYMBOL( ?register_pending_exception@task_group_context@tbb@@QAEXXZ ) __TBB_SYMBOL( ??1task_group_context@tbb@@QAE@XZ ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( ?set_priority@task_group_context@tbb@@QAEXW4priority_t@2@@Z ) __TBB_SYMBOL( ?priority@task_group_context@tbb@@QBE?AW4priority_t@2@XZ ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( ?name@captured_exception@tbb@@UBEPBDXZ ) __TBB_SYMBOL( ?what@captured_exception@tbb@@UBEPBDXZ ) __TBB_SYMBOL( ??1captured_exception@tbb@@UAE@XZ ) __TBB_SYMBOL( ?move@captured_exception@tbb@@UAEPAV12@XZ ) __TBB_SYMBOL( ?destroy@captured_exception@tbb@@UAEXXZ ) __TBB_SYMBOL( ?set@captured_exception@tbb@@QAEXPBD0@Z ) __TBB_SYMBOL( ?clear@captured_exception@tbb@@QAEXXZ ) #endif /* __TBB_TASK_GROUP_CONTEXT */ // Symbols for exceptions thrown from TBB __TBB_SYMBOL( ?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ ) __TBB_SYMBOL( ?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z ) __TBB_SYMBOL( ?what@bad_last_alloc@tbb@@UBEPBDXZ ) __TBB_SYMBOL( ?what@missing_wait@tbb@@UBEPBDXZ ) __TBB_SYMBOL( ?what@invalid_multiple_scheduling@tbb@@UBEPBDXZ ) __TBB_SYMBOL( ?what@improper_lock@tbb@@UBEPBDXZ ) __TBB_SYMBOL( ?what@user_abort@tbb@@UBEPBDXZ ) // tbb_misc.cpp __TBB_SYMBOL( ?assertion_failure@tbb@@YAXPBDH00@Z ) __TBB_SYMBOL( ?get_initial_auto_partitioner_divisor@internal@tbb@@YAIXZ ) __TBB_SYMBOL( ?handle_perror@internal@tbb@@YAXHPBD@Z ) __TBB_SYMBOL( ?set_assertion_handler@tbb@@YAP6AXPBDH00@ZP6AX0H00@Z@Z ) __TBB_SYMBOL( ?runtime_warning@internal@tbb@@YAXPBDZZ ) __TBB_SYMBOL( TBB_runtime_interface_version ) // tbb_main.cpp __TBB_SYMBOL( ?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPAXPBX@Z ) __TBB_SYMBOL( ?itt_store_pointer_with_release_v3@internal@tbb@@YAXPAX0@Z ) __TBB_SYMBOL( ?call_itt_notify_v5@internal@tbb@@YAXHPAX@Z ) __TBB_SYMBOL( ?itt_set_sync_name_v3@internal@tbb@@YAXPAXPB_W@Z ) __TBB_SYMBOL( ?itt_load_pointer_v3@internal@tbb@@YAPAXPBX@Z ) #if __TBB_ITT_STRUCTURE_API __TBB_SYMBOL( ?itt_make_task_group_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_K12W4string_index@12@@Z ) __TBB_SYMBOL( ?itt_metadata_str_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_KW4string_index@12@PBD@Z ) __TBB_SYMBOL( ?itt_relation_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_KW4itt_relation@12@12@Z ) __TBB_SYMBOL( ?itt_task_begin_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_K12W4string_index@12@@Z ) __TBB_SYMBOL( ?itt_task_end_v7@internal@tbb@@YAXW4itt_domain_enum@12@@Z ) #endif // pipeline.cpp __TBB_SYMBOL( ??0pipeline@tbb@@QAE@XZ ) __TBB_SYMBOL( ??1filter@tbb@@UAE@XZ ) __TBB_SYMBOL( ??1pipeline@tbb@@UAE@XZ ) __TBB_SYMBOL( ??_7pipeline@tbb@@6B@ ) __TBB_SYMBOL( ?add_filter@pipeline@tbb@@QAEXAAVfilter@2@@Z ) __TBB_SYMBOL( ?clear@pipeline@tbb@@QAEXXZ ) __TBB_SYMBOL( ?inject_token@pipeline@tbb@@AAEXAAVtask@2@@Z ) __TBB_SYMBOL( ?run@pipeline@tbb@@QAEXI@Z ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( ?run@pipeline@tbb@@QAEXIAAVtask_group_context@2@@Z ) #endif __TBB_SYMBOL( ?process_item@thread_bound_filter@tbb@@QAE?AW4result_type@12@XZ ) __TBB_SYMBOL( ?try_process_item@thread_bound_filter@tbb@@QAE?AW4result_type@12@XZ ) __TBB_SYMBOL( ?set_end_of_input@filter@tbb@@IAEXXZ ) // queuing_rw_mutex.cpp __TBB_SYMBOL( ?internal_construct@queuing_rw_mutex@tbb@@QAEXXZ ) __TBB_SYMBOL( ?acquire@scoped_lock@queuing_rw_mutex@tbb@@QAEXAAV23@_N@Z ) __TBB_SYMBOL( ?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QAE_NXZ ) __TBB_SYMBOL( ?release@scoped_lock@queuing_rw_mutex@tbb@@QAEXXZ ) __TBB_SYMBOL( ?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QAE_NXZ ) __TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QAE_NAAV23@_N@Z ) // reader_writer_lock.cpp __TBB_SYMBOL( ?try_lock_read@reader_writer_lock@interface5@tbb@@QAE_NXZ ) __TBB_SYMBOL( ?try_lock@reader_writer_lock@interface5@tbb@@QAE_NXZ ) __TBB_SYMBOL( ?unlock@reader_writer_lock@interface5@tbb@@QAEXXZ ) __TBB_SYMBOL( ?lock_read@reader_writer_lock@interface5@tbb@@QAEXXZ ) __TBB_SYMBOL( ?lock@reader_writer_lock@interface5@tbb@@QAEXXZ ) __TBB_SYMBOL( ?internal_construct@reader_writer_lock@interface5@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_destroy@reader_writer_lock@interface5@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AAEXAAV234@@Z ) __TBB_SYMBOL( ?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAEXAAV234@@Z ) __TBB_SYMBOL( ?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAEXXZ ) #if !TBB_NO_LEGACY // spin_rw_mutex.cpp v2 __TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) __TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) __TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) __TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) #endif // spin_rw_mutex v3 __TBB_SYMBOL( ?internal_construct@spin_rw_mutex_v3@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex_v3@tbb@@AAE_NXZ ) __TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex_v3@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AAE_NXZ ) __TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex_v3@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex_v3@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AAE_NXZ ) __TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AAE_NXZ ) // x86_rtm_rw_mutex.cpp __TBB_SYMBOL( ?internal_construct@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_release@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@@Z ) __TBB_SYMBOL( ?internal_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@_N@Z ) __TBB_SYMBOL( ?internal_acquire_reader@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@_N@Z ) __TBB_SYMBOL( ?internal_upgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z ) __TBB_SYMBOL( ?internal_downgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z ) __TBB_SYMBOL( ?internal_try_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z ) // spin_mutex.cpp __TBB_SYMBOL( ?internal_construct@spin_mutex@tbb@@QAEXXZ ) __TBB_SYMBOL( ?internal_acquire@scoped_lock@spin_mutex@tbb@@AAEXAAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@spin_mutex@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AAE_NAAV23@@Z ) // mutex.cpp __TBB_SYMBOL( ?internal_acquire@scoped_lock@mutex@tbb@@AAEXAAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@mutex@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@mutex@tbb@@AAE_NAAV23@@Z ) __TBB_SYMBOL( ?internal_construct@mutex@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_destroy@mutex@tbb@@AAEXXZ ) // recursive_mutex.cpp __TBB_SYMBOL( ?internal_acquire@scoped_lock@recursive_mutex@tbb@@AAEXAAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@recursive_mutex@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AAE_NAAV23@@Z ) __TBB_SYMBOL( ?internal_construct@recursive_mutex@tbb@@AAEXXZ ) __TBB_SYMBOL( ?internal_destroy@recursive_mutex@tbb@@AAEXXZ ) // queuing_mutex.cpp __TBB_SYMBOL( ?internal_construct@queuing_mutex@tbb@@QAEXXZ ) __TBB_SYMBOL( ?acquire@scoped_lock@queuing_mutex@tbb@@QAEXAAV23@@Z ) __TBB_SYMBOL( ?release@scoped_lock@queuing_mutex@tbb@@QAEXXZ ) __TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_mutex@tbb@@QAE_NAAV23@@Z ) // critical_section.cpp __TBB_SYMBOL( ?internal_construct@critical_section_v4@internal@tbb@@QAEXXZ ) #if !TBB_NO_LEGACY // concurrent_hash_map.cpp __TBB_SYMBOL( ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QBE_NXZ ) // concurrent_queue.cpp v2 __TBB_SYMBOL( ?advance@concurrent_queue_iterator_base@internal@tbb@@IAEXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_iterator_base@internal@tbb@@IAEXABV123@@Z ) __TBB_SYMBOL( ?internal_size@concurrent_queue_base@internal@tbb@@IBEHXZ ) __TBB_SYMBOL( ??0concurrent_queue_base@internal@tbb@@IAE@I@Z ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base@internal@tbb@@IAE@ABVconcurrent_queue_base@12@@Z ) __TBB_SYMBOL( ??1concurrent_queue_base@internal@tbb@@MAE@XZ ) __TBB_SYMBOL( ??1concurrent_queue_iterator_base@internal@tbb@@IAE@XZ ) __TBB_SYMBOL( ?internal_pop@concurrent_queue_base@internal@tbb@@IAEXPAX@Z ) __TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IAE_NPAX@Z ) __TBB_SYMBOL( ?internal_push@concurrent_queue_base@internal@tbb@@IAEXPBX@Z ) __TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IAE_NPBX@Z ) __TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base@internal@tbb@@IAEXHI@Z ) #endif // concurrent_queue v3 __TBB_SYMBOL( ??1concurrent_queue_iterator_base_v3@internal@tbb@@IAE@XZ ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAE@ABVconcurrent_queue_base_v3@12@@Z ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAE@ABVconcurrent_queue_base_v3@12@I@Z ) __TBB_SYMBOL( ?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IAEXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IAEXABV123@@Z ) __TBB_SYMBOL( ??0concurrent_queue_base_v3@internal@tbb@@IAE@I@Z ) __TBB_SYMBOL( ??1concurrent_queue_base_v3@internal@tbb@@MAE@XZ ) __TBB_SYMBOL( ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IAEXPAX@Z ) __TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IAE_NPAX@Z ) __TBB_SYMBOL( ?internal_abort@concurrent_queue_base_v3@internal@tbb@@IAEXXZ ) __TBB_SYMBOL( ?internal_push@concurrent_queue_base_v3@internal@tbb@@IAEXPBX@Z ) __TBB_SYMBOL( ?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IAEXPBX@Z ) __TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IAE_NPBX@Z ) __TBB_SYMBOL( ?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IAE_NPBX@Z ) __TBB_SYMBOL( ?internal_size@concurrent_queue_base_v3@internal@tbb@@IBEHXZ ) __TBB_SYMBOL( ?internal_empty@concurrent_queue_base_v3@internal@tbb@@IBE_NXZ ) __TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IAEXHI@Z ) __TBB_SYMBOL( ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IAEXXZ ) __TBB_SYMBOL( ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IBEXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_base_v3@internal@tbb@@IAEXABV123@@Z ) __TBB_SYMBOL( ?move_content@concurrent_queue_base_v8@internal@tbb@@IAEXAAV123@@Z ) #if !TBB_NO_LEGACY // concurrent_vector.cpp v2 __TBB_SYMBOL( ?internal_assign@concurrent_vector_base@internal@tbb@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) __TBB_SYMBOL( ?internal_capacity@concurrent_vector_base@internal@tbb@@IBEIXZ ) __TBB_SYMBOL( ?internal_clear@concurrent_vector_base@internal@tbb@@IAEXP6AXPAXI@Z_N@Z ) __TBB_SYMBOL( ?internal_copy@concurrent_vector_base@internal@tbb@@IAEXABV123@IP6AXPAXPBXI@Z@Z ) __TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base@internal@tbb@@IAEIIIP6AXPAXI@Z@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IAEXIIP6AXPAXI@Z@Z ) __TBB_SYMBOL( ?internal_push_back@concurrent_vector_base@internal@tbb@@IAEPAXIAAI@Z ) __TBB_SYMBOL( ?internal_reserve@concurrent_vector_base@internal@tbb@@IAEXIII@Z ) #endif // concurrent_vector v3 __TBB_SYMBOL( ??1concurrent_vector_base_v3@internal@tbb@@IAE@XZ ) __TBB_SYMBOL( ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) __TBB_SYMBOL( ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IBEIXZ ) __TBB_SYMBOL( ?internal_clear@concurrent_vector_base_v3@internal@tbb@@IAEIP6AXPAXI@Z@Z ) __TBB_SYMBOL( ?internal_copy@concurrent_vector_base_v3@internal@tbb@@IAEXABV123@IP6AXPAXPBXI@Z@Z ) __TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IAEIIIP6AXPAXPBXI@Z1@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IAEXIIP6AXPAXPBXI@Z1@Z ) __TBB_SYMBOL( ?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IAEPAXIAAI@Z ) __TBB_SYMBOL( ?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IAEXIII@Z ) __TBB_SYMBOL( ?internal_compact@concurrent_vector_base_v3@internal@tbb@@IAEPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z ) __TBB_SYMBOL( ?internal_swap@concurrent_vector_base_v3@internal@tbb@@IAEXAAV123@@Z ) __TBB_SYMBOL( ?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IBEXI@Z ) __TBB_SYMBOL( ?internal_resize@concurrent_vector_base_v3@internal@tbb@@IAEXIIIPBXP6AXPAXI@ZP6AX10I@Z@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IAEIIIP6AXPAXPBXI@Z1@Z ) // tbb_thread __TBB_SYMBOL( ?join@tbb_thread_v3@internal@tbb@@QAEXXZ ) __TBB_SYMBOL( ?detach@tbb_thread_v3@internal@tbb@@QAEXXZ ) __TBB_SYMBOL( ?internal_start@tbb_thread_v3@internal@tbb@@AAEXP6GIPAX@Z0@Z ) __TBB_SYMBOL( ?allocate_closure_v3@internal@tbb@@YAPAXI@Z ) __TBB_SYMBOL( ?free_closure_v3@internal@tbb@@YAXPAX@Z ) __TBB_SYMBOL( ?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ ) __TBB_SYMBOL( ?thread_yield_v3@internal@tbb@@YAXXZ ) __TBB_SYMBOL( ?thread_sleep_v3@internal@tbb@@YAXABVinterval_t@tick_count@2@@Z ) __TBB_SYMBOL( ?move_v3@internal@tbb@@YAXAAVtbb_thread_v3@12@0@Z ) __TBB_SYMBOL( ?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ ) // condition_variable __TBB_SYMBOL( ?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAATcondvar_impl_t@123@PAVmutex@3@PBVinterval_t@tick_count@3@@Z ) __TBB_SYMBOL( ?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/win64-gcc-tbb-export.def ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ { global: #define __TBB_SYMBOL( sym ) sym; #include "win64-gcc-tbb-export.lst" local: /* TBB symbols */ *3tbb*; *__TBB*; /* Intel Compiler (libirc) symbols */ __intel_*; _intel_*; get_msg_buf; get_text_buf; message_catalog; print_buf; irc__get_msg; irc__print; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/win64-gcc-tbb-export.lst ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" /* cache_aligned_allocator.cpp */ __TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEyyPv ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) __TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) __TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Ey ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) /* task.cpp v3 */ __TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) __TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) __TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) __TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) __TBB_SYMBOL( _ZN3tbb4task4selfEv ) __TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZTIN3tbb4taskE ) __TBB_SYMBOL( _ZTSN3tbb4taskE ) __TBB_SYMBOL( _ZTVN3tbb4taskE ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEiy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) __TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) #endif /* __TBB_SCHEDULER_OBSERVER */ __TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) __TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) __TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) __TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) __TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEx ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) __TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) __TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY /* task_v2.cpp */ __TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) #endif /* !TBB_NO_LEGACY */ /* Exception handling in task scheduler */ #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) __TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) __TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) __TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) __TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) __TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) __TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) __TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) __TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) __TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) #endif /* __TBB_TASK_GROUP_CONTEXT */ /* Symbols for exceptions thrown from TBB */ __TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) __TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) __TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) __TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) __TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) __TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) __TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) __TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) __TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) __TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) __TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) __TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) __TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) __TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) __TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) __TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) __TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) __TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) __TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) __TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) __TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) __TBB_SYMBOL( _ZTIN3tbb10user_abortE ) __TBB_SYMBOL( _ZTSN3tbb10user_abortE ) __TBB_SYMBOL( _ZTVN3tbb10user_abortE ) /* tbb_misc.cpp */ __TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) __TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) __TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) __TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) __TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) __TBB_SYMBOL( TBB_runtime_interface_version ) /* tbb_main.cpp */ __TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) __TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) __TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) __TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) __TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) /* pipeline.cpp */ __TBB_SYMBOL( _ZTIN3tbb6filterE ) __TBB_SYMBOL( _ZTSN3tbb6filterE ) __TBB_SYMBOL( _ZTVN3tbb6filterE ) __TBB_SYMBOL( _ZN3tbb6filterD2Ev ) __TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) __TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) __TBB_SYMBOL( _ZN3tbb8pipeline3runEy ) // MODIFIED LINUX ENTRY #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( _ZN3tbb8pipeline3runEyRNS_18task_group_contextE ) // MODIFIED LINUX ENTRY #endif __TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) __TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) __TBB_SYMBOL( _ZTIN3tbb8pipelineE ) __TBB_SYMBOL( _ZTSN3tbb8pipelineE ) __TBB_SYMBOL( _ZTVN3tbb8pipelineE ) __TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) __TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) __TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) /* queuing_rw_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) /* reader_writer_lock.cpp */ __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) __TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) #if !TBB_NO_LEGACY /* spin_rw_mutex.cpp v2 */ __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) __TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) #endif // x86_rtm_rw_mutex.cpp __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) __TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) /* spin_rw_mutex v3 */ __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) __TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) /* spin_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) /* mutex.cpp */ __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) /* recursive_mutex.cpp */ __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) __TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) /* QueuingMutex.cpp */ __TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) __TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) /* critical_section.cpp */ __TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) #if !TBB_NO_LEGACY /* concurrent_hash_map */ __TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) /* concurrent_queue.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityExy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Ey ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) __TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) __TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) __TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) #endif /* concurrent_queue v3 */ /* constructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Ey ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Ey ) // MODIFIED LINUX ENTRY /* destructors */ __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) /* typeinfo */ __TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) __TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) /* vtable */ __TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) /* methods */ __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityExy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) __TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) __TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) #if !TBB_NO_LEGACY /* concurrent_vector.cpp v2 */ __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_yPFvPvPKvyE ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvyEb ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_yPFvPvyEPFvS4_PKvyESA_ ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEyyPFvPvyE ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEyyy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEyRy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEyyPFvPvyE ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) #endif /* concurrent_vector v3 */ __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_yPFvPvPKvyE ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvyE ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_yPFvPvyEPFvS4_PKvyESA_ ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEyyPFvPvPKvyES4_ ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEyyy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEyRy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEyyPFvPvPKvyES4_ ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEyPvPFvS2_yEPFvS2_PKvyE ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) __TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEy ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEyyyPKvPFvPvyEPFvS4_S3_yE ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEyyPFvPvPKvyES4_ ) // MODIFIED LINUX ENTRY /* tbb_thread */ __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) __TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) __TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFjPvES2_ ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Ey ) // MODIFIED LINUX ENTRY __TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) __TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) __TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) /* condition_variable */ __TBB_SYMBOL( _ZN3tbb10interface58internal32internal_condition_variable_waitERNS1_14condvar_impl_tEPNS_5mutexEPKNS_10tick_count10interval_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal35internal_destroy_condition_variableERNS1_14condvar_impl_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_allERNS1_14condvar_impl_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_oneERNS1_14condvar_impl_tE ) __TBB_SYMBOL( _ZN3tbb10interface58internal38internal_initialize_condition_variableERNS1_14condvar_impl_tE ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/win64-tbb-export.def ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. ; This file is organized with a section for each .cpp file. ; Each of these sections is in alphabetical order. EXPORTS #define __TBB_SYMBOL( sym ) sym #include "win64-tbb-export.lst" ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/win64-tbb-export.lst ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. // This file is organized with a section for each .cpp file. // Each of these sections is in alphabetical order. #include "tbb/tbb_config.h" // Assembly-language support that is called directly by clients __TBB_SYMBOL( __TBB_machine_cmpswp1 ) __TBB_SYMBOL( __TBB_machine_fetchadd1 ) __TBB_SYMBOL( __TBB_machine_fetchstore1 ) __TBB_SYMBOL( __TBB_machine_cmpswp2 ) __TBB_SYMBOL( __TBB_machine_fetchadd2 ) __TBB_SYMBOL( __TBB_machine_fetchstore2 ) __TBB_SYMBOL( __TBB_machine_pause ) __TBB_SYMBOL( __TBB_machine_try_lock_elided ) __TBB_SYMBOL( __TBB_machine_unlock_elided ) __TBB_SYMBOL( __TBB_machine_is_in_transaction ) // cache_aligned_allocator.cpp __TBB_SYMBOL( ?NFS_Allocate@internal@tbb@@YAPEAX_K0PEAX@Z ) __TBB_SYMBOL( ?NFS_GetLineSize@internal@tbb@@YA_KXZ ) __TBB_SYMBOL( ?NFS_Free@internal@tbb@@YAXPEAX@Z ) __TBB_SYMBOL( ?allocate_via_handler_v3@internal@tbb@@YAPEAX_K@Z ) __TBB_SYMBOL( ?deallocate_via_handler_v3@internal@tbb@@YAXPEAX@Z ) __TBB_SYMBOL( ?is_malloc_used_v3@internal@tbb@@YA_NXZ ) // task.cpp v3 __TBB_SYMBOL( ?resize@affinity_partitioner_base_v3@internal@tbb@@AEAAXI@Z ) __TBB_SYMBOL( ?allocate@allocate_additional_child_of_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) __TBB_SYMBOL( ?allocate@allocate_child_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) __TBB_SYMBOL( ?allocate@allocate_continuation_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) __TBB_SYMBOL( ?allocate@allocate_root_proxy@internal@tbb@@SAAEAVtask@3@_K@Z ) __TBB_SYMBOL( ?destroy@task_base@internal@interface5@tbb@@SAXAEAVtask@4@@Z ) __TBB_SYMBOL( ?free@allocate_additional_child_of_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_child_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_continuation_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_root_proxy@internal@tbb@@SAXAEAVtask@3@@Z ) __TBB_SYMBOL( ?internal_set_ref_count@task@tbb@@AEAAXH@Z ) __TBB_SYMBOL( ?internal_decrement_ref_count@task@tbb@@AEAA_JXZ ) __TBB_SYMBOL( ?is_owned_by_current_thread@task@tbb@@QEBA_NXZ ) __TBB_SYMBOL( ?note_affinity@task@tbb@@UEAAXG@Z ) __TBB_SYMBOL( ?self@task@tbb@@SAAEAV12@XZ ) __TBB_SYMBOL( ?spawn_and_wait_for_all@task@tbb@@QEAAXAEAVtask_list@2@@Z ) __TBB_SYMBOL( ?default_num_threads@task_scheduler_init@tbb@@SAHXZ ) __TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QEAAXH_K@Z ) __TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QEAAXH@Z ) __TBB_SYMBOL( ?terminate@task_scheduler_init@tbb@@QEAAXXZ ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( ?observe@task_scheduler_observer_v3@internal@tbb@@QEAAX_N@Z ) #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ) __TBB_SYMBOL( ?internal_initialize@task_arena_base@internal@interface7@tbb@@IEAAXXZ ) __TBB_SYMBOL( ?internal_terminate@task_arena_base@internal@interface7@tbb@@IEAAXXZ ) __TBB_SYMBOL( ?internal_enqueue@task_arena_base@internal@interface7@tbb@@IEBAXAEAVtask@4@_J@Z ) __TBB_SYMBOL( ?internal_execute@task_arena_base@internal@interface7@tbb@@IEBAXAEAVdelegate_base@234@@Z ) __TBB_SYMBOL( ?internal_wait@task_arena_base@internal@interface7@tbb@@IEBAXXZ ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY // task_v2.cpp __TBB_SYMBOL( ?destroy@task@tbb@@QEAAXAEAV12@@Z ) #endif // Exception handling in task scheduler #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( ?allocate@allocate_root_with_context_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) __TBB_SYMBOL( ?free@allocate_root_with_context_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) __TBB_SYMBOL( ?change_group@task@tbb@@QEAAXAEAVtask_group_context@2@@Z ) __TBB_SYMBOL( ?is_group_execution_cancelled@task_group_context@tbb@@QEBA_NXZ ) __TBB_SYMBOL( ?cancel_group_execution@task_group_context@tbb@@QEAA_NXZ ) __TBB_SYMBOL( ?reset@task_group_context@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?capture_fp_settings@task_group_context@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?init@task_group_context@tbb@@IEAAXXZ ) __TBB_SYMBOL( ?register_pending_exception@task_group_context@tbb@@QEAAXXZ ) __TBB_SYMBOL( ??1task_group_context@tbb@@QEAA@XZ ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( ?set_priority@task_group_context@tbb@@QEAAXW4priority_t@2@@Z ) __TBB_SYMBOL( ?priority@task_group_context@tbb@@QEBA?AW4priority_t@2@XZ ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( ?name@captured_exception@tbb@@UEBAPEBDXZ ) __TBB_SYMBOL( ?what@captured_exception@tbb@@UEBAPEBDXZ ) __TBB_SYMBOL( ??1captured_exception@tbb@@UEAA@XZ ) __TBB_SYMBOL( ?move@captured_exception@tbb@@UEAAPEAV12@XZ ) __TBB_SYMBOL( ?destroy@captured_exception@tbb@@UEAAXXZ ) __TBB_SYMBOL( ?set@captured_exception@tbb@@QEAAXPEBD0@Z ) __TBB_SYMBOL( ?clear@captured_exception@tbb@@QEAAXXZ ) #endif /* __TBB_TASK_GROUP_CONTEXT */ // Symbols for exceptions thrown from TBB __TBB_SYMBOL( ?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ ) __TBB_SYMBOL( ?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z ) __TBB_SYMBOL( ?what@bad_last_alloc@tbb@@UEBAPEBDXZ ) __TBB_SYMBOL( ?what@missing_wait@tbb@@UEBAPEBDXZ ) __TBB_SYMBOL( ?what@invalid_multiple_scheduling@tbb@@UEBAPEBDXZ ) __TBB_SYMBOL( ?what@improper_lock@tbb@@UEBAPEBDXZ ) __TBB_SYMBOL( ?what@user_abort@tbb@@UEBAPEBDXZ ) // tbb_misc.cpp __TBB_SYMBOL( ?assertion_failure@tbb@@YAXPEBDH00@Z ) __TBB_SYMBOL( ?get_initial_auto_partitioner_divisor@internal@tbb@@YA_KXZ ) __TBB_SYMBOL( ?handle_perror@internal@tbb@@YAXHPEBD@Z ) __TBB_SYMBOL( ?set_assertion_handler@tbb@@YAP6AXPEBDH00@ZP6AX0H00@Z@Z ) __TBB_SYMBOL( ?runtime_warning@internal@tbb@@YAXPEBDZZ ) __TBB_SYMBOL( TBB_runtime_interface_version ) // tbb_main.cpp __TBB_SYMBOL( ?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPEAXPEBX@Z ) __TBB_SYMBOL( ?itt_store_pointer_with_release_v3@internal@tbb@@YAXPEAX0@Z ) __TBB_SYMBOL( ?call_itt_notify_v5@internal@tbb@@YAXHPEAX@Z ) __TBB_SYMBOL( ?itt_load_pointer_v3@internal@tbb@@YAPEAXPEBX@Z ) __TBB_SYMBOL( ?itt_set_sync_name_v3@internal@tbb@@YAXPEAXPEB_W@Z ) #if __TBB_ITT_STRUCTURE_API __TBB_SYMBOL( ?itt_make_task_group_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_K12W4string_index@12@@Z ) __TBB_SYMBOL( ?itt_metadata_str_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_KW4string_index@12@PEBD@Z ) __TBB_SYMBOL( ?itt_relation_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_KW4itt_relation@12@12@Z ) __TBB_SYMBOL( ?itt_task_begin_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_K12W4string_index@12@@Z ) __TBB_SYMBOL( ?itt_task_end_v7@internal@tbb@@YAXW4itt_domain_enum@12@@Z ) #endif // pipeline.cpp __TBB_SYMBOL( ??_7pipeline@tbb@@6B@ ) __TBB_SYMBOL( ??0pipeline@tbb@@QEAA@XZ ) __TBB_SYMBOL( ??1filter@tbb@@UEAA@XZ ) __TBB_SYMBOL( ??1pipeline@tbb@@UEAA@XZ ) __TBB_SYMBOL( ?add_filter@pipeline@tbb@@QEAAXAEAVfilter@2@@Z ) __TBB_SYMBOL( ?clear@pipeline@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?inject_token@pipeline@tbb@@AEAAXAEAVtask@2@@Z ) __TBB_SYMBOL( ?run@pipeline@tbb@@QEAAX_K@Z ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( ?run@pipeline@tbb@@QEAAX_KAEAVtask_group_context@2@@Z ) #endif __TBB_SYMBOL( ?process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ ) __TBB_SYMBOL( ?try_process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ ) __TBB_SYMBOL( ?set_end_of_input@filter@tbb@@IEAAXXZ ) // queuing_rw_mutex.cpp __TBB_SYMBOL( ?internal_construct@queuing_rw_mutex@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?acquire@scoped_lock@queuing_rw_mutex@tbb@@QEAAXAEAV23@_N@Z ) __TBB_SYMBOL( ?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NXZ ) __TBB_SYMBOL( ?release@scoped_lock@queuing_rw_mutex@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NXZ ) __TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NAEAV23@_N@Z ) // reader_writer_lock.cpp __TBB_SYMBOL( ?try_lock_read@reader_writer_lock@interface5@tbb@@QEAA_NXZ ) __TBB_SYMBOL( ?try_lock@reader_writer_lock@interface5@tbb@@QEAA_NXZ ) __TBB_SYMBOL( ?unlock@reader_writer_lock@interface5@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?lock_read@reader_writer_lock@interface5@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?lock@reader_writer_lock@interface5@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?internal_construct@reader_writer_lock@interface5@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_destroy@reader_writer_lock@interface5@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AEAAXAEAV234@@Z ) __TBB_SYMBOL( ?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AEAAXAEAV234@@Z ) __TBB_SYMBOL( ?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AEAAXXZ ) #if !TBB_NO_LEGACY // spin_rw_mutex.cpp v2 __TBB_SYMBOL( ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) __TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) __TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) __TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) __TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) __TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) __TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) __TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) __TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) #endif // spin_rw_mutex v3 __TBB_SYMBOL( ?internal_construct@spin_rw_mutex_v3@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) __TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex_v3@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) __TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex_v3@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex_v3@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) __TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) // x86_rtm_rw_mutex.cpp __TBB_SYMBOL( ?internal_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z ) __TBB_SYMBOL( ?internal_acquire_reader@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z ) __TBB_SYMBOL( ?internal_upgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z ) __TBB_SYMBOL( ?internal_downgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z ) __TBB_SYMBOL( ?internal_try_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z ) __TBB_SYMBOL( ?internal_release@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@@Z ) __TBB_SYMBOL( ?internal_construct@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXXZ ) // spin_mutex.cpp __TBB_SYMBOL( ?internal_construct@spin_mutex@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?internal_acquire@scoped_lock@spin_mutex@tbb@@AEAAXAEAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@spin_mutex@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AEAA_NAEAV23@@Z ) // mutex.cpp __TBB_SYMBOL( ?internal_acquire@scoped_lock@mutex@tbb@@AEAAXAEAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@mutex@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@mutex@tbb@@AEAA_NAEAV23@@Z ) __TBB_SYMBOL( ?internal_construct@mutex@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_destroy@mutex@tbb@@AEAAXXZ ) // recursive_mutex.cpp __TBB_SYMBOL( ?internal_construct@recursive_mutex@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_destroy@recursive_mutex@tbb@@AEAAXXZ ) __TBB_SYMBOL( ?internal_acquire@scoped_lock@recursive_mutex@tbb@@AEAAXAEAV23@@Z ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AEAA_NAEAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@recursive_mutex@tbb@@AEAAXXZ ) // queuing_mutex.cpp __TBB_SYMBOL( ?internal_construct@queuing_mutex@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?acquire@scoped_lock@queuing_mutex@tbb@@QEAAXAEAV23@@Z ) __TBB_SYMBOL( ?release@scoped_lock@queuing_mutex@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_mutex@tbb@@QEAA_NAEAV23@@Z ) //critical_section.cpp __TBB_SYMBOL( ?internal_construct@critical_section_v4@internal@tbb@@QEAAXXZ ) #if !TBB_NO_LEGACY // concurrent_hash_map.cpp __TBB_SYMBOL( ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QEBA_NXZ ) // concurrent_queue.cpp v2 __TBB_SYMBOL( ??0concurrent_queue_base@internal@tbb@@IEAA@_K@Z ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base@internal@tbb@@IEAA@AEBVconcurrent_queue_base@12@@Z ) __TBB_SYMBOL( ??1concurrent_queue_base@internal@tbb@@MEAA@XZ ) __TBB_SYMBOL( ??1concurrent_queue_iterator_base@internal@tbb@@IEAA@XZ ) __TBB_SYMBOL( ?advance@concurrent_queue_iterator_base@internal@tbb@@IEAAXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_iterator_base@internal@tbb@@IEAAXAEBV123@@Z ) __TBB_SYMBOL( ?internal_pop@concurrent_queue_base@internal@tbb@@IEAAXPEAX@Z ) __TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IEAA_NPEAX@Z ) __TBB_SYMBOL( ?internal_push@concurrent_queue_base@internal@tbb@@IEAAXPEBX@Z ) __TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IEAA_NPEBX@Z ) __TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base@internal@tbb@@IEAAX_J_K@Z ) __TBB_SYMBOL( ?internal_size@concurrent_queue_base@internal@tbb@@IEBA_JXZ ) #endif // concurrent_queue v3 __TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@@Z ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@_K@Z ) __TBB_SYMBOL( ??1concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@XZ ) __TBB_SYMBOL( ?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IEAAXAEBV123@@Z ) __TBB_SYMBOL( ?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IEAAXXZ ) __TBB_SYMBOL( ??0concurrent_queue_base_v3@internal@tbb@@IEAA@_K@Z ) __TBB_SYMBOL( ??1concurrent_queue_base_v3@internal@tbb@@MEAA@XZ ) __TBB_SYMBOL( ?internal_push@concurrent_queue_base_v3@internal@tbb@@IEAAXPEBX@Z ) __TBB_SYMBOL( ?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IEAAXPEBX@Z ) __TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEBX@Z ) __TBB_SYMBOL( ?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IEAA_NPEBX@Z ) __TBB_SYMBOL( ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IEAAXPEAX@Z ) __TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEAX@Z ) __TBB_SYMBOL( ?internal_abort@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ ) __TBB_SYMBOL( ?internal_size@concurrent_queue_base_v3@internal@tbb@@IEBA_JXZ ) __TBB_SYMBOL( ?internal_empty@concurrent_queue_base_v3@internal@tbb@@IEBA_NXZ ) __TBB_SYMBOL( ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ ) __TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IEAAX_J_K@Z ) __TBB_SYMBOL( ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IEBAXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_base_v3@internal@tbb@@IEAAXAEBV123@@Z ) __TBB_SYMBOL( ?move_content@concurrent_queue_base_v8@internal@tbb@@IEAAXAEAV123@@Z ) #if !TBB_NO_LEGACY // concurrent_vector.cpp v2 __TBB_SYMBOL( ?internal_assign@concurrent_vector_base@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z ) __TBB_SYMBOL( ?internal_capacity@concurrent_vector_base@internal@tbb@@IEBA_KXZ ) __TBB_SYMBOL( ?internal_clear@concurrent_vector_base@internal@tbb@@IEAAXP6AXPEAX_K@Z_N@Z ) __TBB_SYMBOL( ?internal_copy@concurrent_vector_base@internal@tbb@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z ) __TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base@internal@tbb@@IEAA_K_K0P6AXPEAX0@Z@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IEAAX_K0P6AXPEAX0@Z@Z ) __TBB_SYMBOL( ?internal_push_back@concurrent_vector_base@internal@tbb@@IEAAPEAX_KAEA_K@Z ) __TBB_SYMBOL( ?internal_reserve@concurrent_vector_base@internal@tbb@@IEAAX_K00@Z ) #endif // concurrent_vector v3 __TBB_SYMBOL( ??1concurrent_vector_base_v3@internal@tbb@@IEAA@XZ ) __TBB_SYMBOL( ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z ) __TBB_SYMBOL( ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IEBA_KXZ ) __TBB_SYMBOL( ?internal_clear@concurrent_vector_base_v3@internal@tbb@@IEAA_KP6AXPEAX_K@Z@Z ) __TBB_SYMBOL( ?internal_copy@concurrent_vector_base_v3@internal@tbb@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z ) __TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IEAAX_K0P6AXPEAXPEBX0@Z2@Z ) __TBB_SYMBOL( ?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IEAAPEAX_KAEA_K@Z ) __TBB_SYMBOL( ?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IEAAX_K00@Z ) __TBB_SYMBOL( ?internal_compact@concurrent_vector_base_v3@internal@tbb@@IEAAPEAX_KPEAXP6AX10@ZP6AX1PEBX0@Z@Z ) __TBB_SYMBOL( ?internal_swap@concurrent_vector_base_v3@internal@tbb@@IEAAXAEAV123@@Z ) __TBB_SYMBOL( ?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IEBAX_K@Z ) __TBB_SYMBOL( ?internal_resize@concurrent_vector_base_v3@internal@tbb@@IEAAX_K00PEBXP6AXPEAX0@ZP6AX210@Z@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z ) // tbb_thread __TBB_SYMBOL( ?allocate_closure_v3@internal@tbb@@YAPEAX_K@Z ) __TBB_SYMBOL( ?detach@tbb_thread_v3@internal@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?free_closure_v3@internal@tbb@@YAXPEAX@Z ) __TBB_SYMBOL( ?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ ) __TBB_SYMBOL( ?internal_start@tbb_thread_v3@internal@tbb@@AEAAXP6AIPEAX@Z0@Z ) __TBB_SYMBOL( ?join@tbb_thread_v3@internal@tbb@@QEAAXXZ ) __TBB_SYMBOL( ?move_v3@internal@tbb@@YAXAEAVtbb_thread_v3@12@0@Z ) __TBB_SYMBOL( ?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ ) __TBB_SYMBOL( ?thread_sleep_v3@internal@tbb@@YAXAEBVinterval_t@tick_count@2@@Z ) __TBB_SYMBOL( ?thread_yield_v3@internal@tbb@@YAXXZ ) // condition_variable __TBB_SYMBOL( ?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAEATcondvar_impl_t@123@PEAVmutex@3@PEBVinterval_t@tick_count@3@@Z ) __TBB_SYMBOL( ?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/winrt-tbb-export.lst ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. #include "tbb/tbb_config.h" // cache_aligned_allocator.cpp __TBB_SYMBOL( ?NFS_Allocate@internal@tbb@@YAPAXIIPAX@Z ) __TBB_SYMBOL( ?NFS_GetLineSize@internal@tbb@@YAIXZ ) __TBB_SYMBOL( ?NFS_Free@internal@tbb@@YAXPAX@Z ) __TBB_SYMBOL( ?allocate_via_handler_v3@internal@tbb@@YAPAXI@Z ) __TBB_SYMBOL( ?deallocate_via_handler_v3@internal@tbb@@YAXPAX@Z ) __TBB_SYMBOL( ?is_malloc_used_v3@internal@tbb@@YA_NXZ ) // task.cpp v3 __TBB_SYMBOL( ?allocate@allocate_additional_child_of_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) __TBB_SYMBOL( ?allocate@allocate_child_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) __TBB_SYMBOL( ?allocate@allocate_continuation_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) __TBB_SYMBOL( ?allocate@allocate_root_proxy@internal@tbb@@SAAAVtask@3@I@Z ) __TBB_SYMBOL( ?destroy@task_base@internal@interface5@tbb@@SAXAAVtask@4@@Z ) __TBB_SYMBOL( ?free@allocate_additional_child_of_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_child_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_continuation_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) __TBB_SYMBOL( ?free@allocate_root_proxy@internal@tbb@@SAXAAVtask@3@@Z ) __TBB_SYMBOL( ?internal_set_ref_count@task@tbb@@AAAXH@Z ) __TBB_SYMBOL( ?internal_decrement_ref_count@task@tbb@@AAAHXZ ) __TBB_SYMBOL( ?is_owned_by_current_thread@task@tbb@@QBA_NXZ ) __TBB_SYMBOL( ?note_affinity@task@tbb@@UAAXG@Z ) __TBB_SYMBOL( ?resize@affinity_partitioner_base_v3@internal@tbb@@AAAXI@Z ) __TBB_SYMBOL( ?self@task@tbb@@SAAAV12@XZ ) __TBB_SYMBOL( ?spawn_and_wait_for_all@task@tbb@@QAAXAAVtask_list@2@@Z ) __TBB_SYMBOL( ?default_num_threads@task_scheduler_init@tbb@@SAHXZ ) __TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAAXHI@Z ) __TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAAXH@Z ) __TBB_SYMBOL( ?terminate@task_scheduler_init@tbb@@QAAXXZ ) #if __TBB_SCHEDULER_OBSERVER __TBB_SYMBOL( ?observe@task_scheduler_observer_v3@internal@tbb@@QAAX_N@Z ) #endif /* __TBB_SCHEDULER_OBSERVER */ #if __TBB_TASK_ARENA /* arena.cpp */ __TBB_SYMBOL( ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ) __TBB_SYMBOL( ?internal_initialize@task_arena_base@internal@interface7@tbb@@IAAXXZ ) __TBB_SYMBOL( ?internal_terminate@task_arena_base@internal@interface7@tbb@@IAAXXZ ) __TBB_SYMBOL( ?internal_enqueue@task_arena_base@internal@interface7@tbb@@IBAXAAVtask@4@H@Z ) __TBB_SYMBOL( ?internal_execute@task_arena_base@internal@interface7@tbb@@IBAXAAVdelegate_base@234@@Z ) __TBB_SYMBOL( ?internal_wait@task_arena_base@internal@interface7@tbb@@IBAXXZ ) #endif /* __TBB_TASK_ARENA */ #if !TBB_NO_LEGACY // task_v2.cpp __TBB_SYMBOL( ?destroy@task@tbb@@QAAXAAV12@@Z ) #endif // exception handling support #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( ?allocate@allocate_root_with_context_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) __TBB_SYMBOL( ?free@allocate_root_with_context_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) __TBB_SYMBOL( ?change_group@task@tbb@@QAAXAAVtask_group_context@2@@Z ) __TBB_SYMBOL( ?is_group_execution_cancelled@task_group_context@tbb@@QBA_NXZ ) __TBB_SYMBOL( ?cancel_group_execution@task_group_context@tbb@@QAA_NXZ ) __TBB_SYMBOL( ?reset@task_group_context@tbb@@QAAXXZ ) __TBB_SYMBOL( ?capture_fp_settings@task_group_context@tbb@@QAAXXZ ) __TBB_SYMBOL( ?init@task_group_context@tbb@@IAAXXZ ) __TBB_SYMBOL( ?register_pending_exception@task_group_context@tbb@@QAAXXZ ) __TBB_SYMBOL( ??1task_group_context@tbb@@QAA@XZ ) #if __TBB_TASK_PRIORITY __TBB_SYMBOL( ?set_priority@task_group_context@tbb@@QAAXW4priority_t@2@@Z ) __TBB_SYMBOL( ?priority@task_group_context@tbb@@QBA?AW4priority_t@2@XZ ) #endif /* __TBB_TASK_PRIORITY */ __TBB_SYMBOL( ?name@captured_exception@tbb@@UBAPBDXZ ) __TBB_SYMBOL( ?what@captured_exception@tbb@@UBAPBDXZ ) __TBB_SYMBOL( ??1captured_exception@tbb@@UAA@XZ ) __TBB_SYMBOL( ?move@captured_exception@tbb@@UAAPAV12@XZ ) __TBB_SYMBOL( ?destroy@captured_exception@tbb@@UAAXXZ ) __TBB_SYMBOL( ?set@captured_exception@tbb@@QAAXPBD0@Z ) __TBB_SYMBOL( ?clear@captured_exception@tbb@@QAAXXZ ) #endif /* __TBB_TASK_GROUP_CONTEXT */ // Symbols for exceptions thrown from TBB __TBB_SYMBOL( ?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ ) __TBB_SYMBOL( ?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z ) __TBB_SYMBOL( ?what@bad_last_alloc@tbb@@UBAPBDXZ ) __TBB_SYMBOL( ?what@missing_wait@tbb@@UBAPBDXZ ) __TBB_SYMBOL( ?what@invalid_multiple_scheduling@tbb@@UBAPBDXZ ) __TBB_SYMBOL( ?what@improper_lock@tbb@@UBAPBDXZ ) __TBB_SYMBOL( ?what@user_abort@tbb@@UBAPBDXZ ) // tbb_misc.cpp __TBB_SYMBOL( ?assertion_failure@tbb@@YAXPBDH00@Z ) __TBB_SYMBOL( ?get_initial_auto_partitioner_divisor@internal@tbb@@YAIXZ ) __TBB_SYMBOL( ?handle_perror@internal@tbb@@YAXHPBD@Z ) __TBB_SYMBOL( ?set_assertion_handler@tbb@@YAP6AXPBDH00@ZP6AX0H00@Z@Z ) __TBB_SYMBOL( ?runtime_warning@internal@tbb@@YAXPBDZZ ) __TBB_SYMBOL( TBB_runtime_interface_version ) // tbb_main.cpp __TBB_SYMBOL( ?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPAXPBX@Z ) __TBB_SYMBOL( ?itt_store_pointer_with_release_v3@internal@tbb@@YAXPAX0@Z ) __TBB_SYMBOL( ?call_itt_notify_v5@internal@tbb@@YAXHPAX@Z ) __TBB_SYMBOL( ?itt_set_sync_name_v3@internal@tbb@@YAXPAXPB_W@Z ) __TBB_SYMBOL( ?itt_load_pointer_v3@internal@tbb@@YAPAXPBX@Z ) // pipeline.cpp __TBB_SYMBOL( ??0pipeline@tbb@@QAA@XZ ) __TBB_SYMBOL( ??1filter@tbb@@UAA@XZ ) __TBB_SYMBOL( ??1pipeline@tbb@@UAA@XZ ) __TBB_SYMBOL( ??_7pipeline@tbb@@6B@ ) __TBB_SYMBOL( ?add_filter@pipeline@tbb@@QAAXAAVfilter@2@@Z ) __TBB_SYMBOL( ?clear@pipeline@tbb@@QAAXXZ ) __TBB_SYMBOL( ?inject_token@pipeline@tbb@@AAAXAAVtask@2@@Z ) __TBB_SYMBOL( ?run@pipeline@tbb@@QAAXI@Z ) #if __TBB_TASK_GROUP_CONTEXT __TBB_SYMBOL( ?run@pipeline@tbb@@QAAXIAAVtask_group_context@2@@Z ) #endif __TBB_SYMBOL( ?process_item@thread_bound_filter@tbb@@QAA?AW4result_type@12@XZ ) __TBB_SYMBOL( ?try_process_item@thread_bound_filter@tbb@@QAA?AW4result_type@12@XZ ) __TBB_SYMBOL( ?set_end_of_input@filter@tbb@@IAAXXZ ) // queuing_rw_mutex.cpp __TBB_SYMBOL( ?internal_construct@queuing_rw_mutex@tbb@@QAAXXZ ) __TBB_SYMBOL( ?acquire@scoped_lock@queuing_rw_mutex@tbb@@QAAXAAV23@_N@Z ) __TBB_SYMBOL( ?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QAA_NXZ ) __TBB_SYMBOL( ?release@scoped_lock@queuing_rw_mutex@tbb@@QAAXXZ ) __TBB_SYMBOL( ?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QAA_NXZ ) __TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QAA_NAAV23@_N@Z ) // reader_writer_lock.cpp __TBB_SYMBOL( ?try_lock_read@reader_writer_lock@interface5@tbb@@QAA_NXZ ) __TBB_SYMBOL( ?try_lock@reader_writer_lock@interface5@tbb@@QAA_NXZ ) __TBB_SYMBOL( ?unlock@reader_writer_lock@interface5@tbb@@QAAXXZ ) __TBB_SYMBOL( ?lock_read@reader_writer_lock@interface5@tbb@@QAAXXZ ) __TBB_SYMBOL( ?lock@reader_writer_lock@interface5@tbb@@QAAXXZ ) __TBB_SYMBOL( ?internal_construct@reader_writer_lock@interface5@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_destroy@reader_writer_lock@interface5@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AAAXAAV234@@Z ) __TBB_SYMBOL( ?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAAXAAV234@@Z ) __TBB_SYMBOL( ?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAAXXZ ) #if !TBB_NO_LEGACY // spin_rw_mutex.cpp v2 __TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) __TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex@tbb@@CAXPAV12@@Z ) __TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) __TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) __TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) #endif // spin_rw_mutex v3 __TBB_SYMBOL( ?internal_construct@spin_rw_mutex_v3@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex_v3@tbb@@AAA_NXZ ) __TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex_v3@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AAA_NXZ ) __TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex_v3@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex_v3@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AAA_NXZ ) __TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AAA_NXZ ) // spin_mutex.cpp __TBB_SYMBOL( ?internal_construct@spin_mutex@tbb@@QAAXXZ ) __TBB_SYMBOL( ?internal_acquire@scoped_lock@spin_mutex@tbb@@AAAXAAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@spin_mutex@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AAA_NAAV23@@Z ) // mutex.cpp __TBB_SYMBOL( ?internal_acquire@scoped_lock@mutex@tbb@@AAAXAAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@mutex@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@mutex@tbb@@AAA_NAAV23@@Z ) __TBB_SYMBOL( ?internal_construct@mutex@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_destroy@mutex@tbb@@AAAXXZ ) // recursive_mutex.cpp __TBB_SYMBOL( ?internal_acquire@scoped_lock@recursive_mutex@tbb@@AAAXAAV23@@Z ) __TBB_SYMBOL( ?internal_release@scoped_lock@recursive_mutex@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AAA_NAAV23@@Z ) __TBB_SYMBOL( ?internal_construct@recursive_mutex@tbb@@AAAXXZ ) __TBB_SYMBOL( ?internal_destroy@recursive_mutex@tbb@@AAAXXZ ) // queuing_mutex.cpp __TBB_SYMBOL( ?internal_construct@queuing_mutex@tbb@@QAAXXZ ) __TBB_SYMBOL( ?acquire@scoped_lock@queuing_mutex@tbb@@QAAXAAV23@@Z ) __TBB_SYMBOL( ?release@scoped_lock@queuing_mutex@tbb@@QAAXXZ ) __TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_mutex@tbb@@QAA_NAAV23@@Z ) // critical_section.cpp __TBB_SYMBOL( ?internal_construct@critical_section_v4@internal@tbb@@QAAXXZ ) #if !TBB_NO_LEGACY // concurrent_hash_map.cpp __TBB_SYMBOL( ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QBA_NXZ ) // concurrent_queue.cpp v2 __TBB_SYMBOL( ?advance@concurrent_queue_iterator_base@internal@tbb@@IAAXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_iterator_base@internal@tbb@@IAAXABV123@@Z ) __TBB_SYMBOL( ?internal_size@concurrent_queue_base@internal@tbb@@IBAHXZ ) __TBB_SYMBOL( ??0concurrent_queue_base@internal@tbb@@IAA@I@Z ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base@internal@tbb@@IAA@ABVconcurrent_queue_base@12@@Z ) __TBB_SYMBOL( ??1concurrent_queue_base@internal@tbb@@MAA@XZ ) __TBB_SYMBOL( ??1concurrent_queue_iterator_base@internal@tbb@@IAA@XZ ) __TBB_SYMBOL( ?internal_pop@concurrent_queue_base@internal@tbb@@IAAXPAX@Z ) __TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IAA_NPAX@Z ) __TBB_SYMBOL( ?internal_push@concurrent_queue_base@internal@tbb@@IAAXPBX@Z ) __TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IAA_NPBX@Z ) __TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base@internal@tbb@@IAAXHI@Z ) #endif // concurrent_queue v3 __TBB_SYMBOL( ??1concurrent_queue_iterator_base_v3@internal@tbb@@IAA@XZ ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAA@ABVconcurrent_queue_base_v3@12@@Z ) __TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAA@ABVconcurrent_queue_base_v3@12@I@Z ) __TBB_SYMBOL( ?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IAAXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IAAXABV123@@Z ) __TBB_SYMBOL( ??0concurrent_queue_base_v3@internal@tbb@@IAA@I@Z ) __TBB_SYMBOL( ??1concurrent_queue_base_v3@internal@tbb@@MAA@XZ ) __TBB_SYMBOL( ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IAAXPAX@Z ) __TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IAA_NPAX@Z ) __TBB_SYMBOL( ?internal_abort@concurrent_queue_base_v3@internal@tbb@@IAAXXZ ) __TBB_SYMBOL( ?internal_push@concurrent_queue_base_v3@internal@tbb@@IAAXPBX@Z ) __TBB_SYMBOL( ?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IAAXPBX@Z ) __TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IAA_NPBX@Z ) __TBB_SYMBOL( ?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IAA_NPBX@Z ) __TBB_SYMBOL( ?internal_size@concurrent_queue_base_v3@internal@tbb@@IBAHXZ ) __TBB_SYMBOL( ?internal_empty@concurrent_queue_base_v3@internal@tbb@@IBA_NXZ ) __TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IAAXHI@Z ) __TBB_SYMBOL( ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IAAXXZ ) __TBB_SYMBOL( ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IBAXXZ ) __TBB_SYMBOL( ?assign@concurrent_queue_base_v3@internal@tbb@@IAAXABV123@@Z ) __TBB_SYMBOL( ?move_content@concurrent_queue_base_v8@internal@tbb@@IAAXAAV123@@Z ) #if !TBB_NO_LEGACY // concurrent_vector.cpp v2 __TBB_SYMBOL( ?internal_assign@concurrent_vector_base@internal@tbb@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) __TBB_SYMBOL( ?internal_capacity@concurrent_vector_base@internal@tbb@@IBAIXZ ) __TBB_SYMBOL( ?internal_clear@concurrent_vector_base@internal@tbb@@IAAXP6AXPAXI@Z_N@Z ) __TBB_SYMBOL( ?internal_copy@concurrent_vector_base@internal@tbb@@IAAXABV123@IP6AXPAXPBXI@Z@Z ) __TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base@internal@tbb@@IAAIIIP6AXPAXI@Z@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IAAXIIP6AXPAXI@Z@Z ) __TBB_SYMBOL( ?internal_push_back@concurrent_vector_base@internal@tbb@@IAAPAXIAAI@Z ) __TBB_SYMBOL( ?internal_reserve@concurrent_vector_base@internal@tbb@@IAAXIII@Z ) #endif // concurrent_vector v3 __TBB_SYMBOL( ??1concurrent_vector_base_v3@internal@tbb@@IAA@XZ ) __TBB_SYMBOL( ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) __TBB_SYMBOL( ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IBAIXZ ) __TBB_SYMBOL( ?internal_clear@concurrent_vector_base_v3@internal@tbb@@IAAIP6AXPAXI@Z@Z ) __TBB_SYMBOL( ?internal_copy@concurrent_vector_base_v3@internal@tbb@@IAAXABV123@IP6AXPAXPBXI@Z@Z ) __TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IAAIIIP6AXPAXPBXI@Z1@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IAAXIIP6AXPAXPBXI@Z1@Z ) __TBB_SYMBOL( ?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IAAPAXIAAI@Z ) __TBB_SYMBOL( ?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IAAXIII@Z ) __TBB_SYMBOL( ?internal_compact@concurrent_vector_base_v3@internal@tbb@@IAAPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z ) __TBB_SYMBOL( ?internal_swap@concurrent_vector_base_v3@internal@tbb@@IAAXAAV123@@Z ) __TBB_SYMBOL( ?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IBAXI@Z ) __TBB_SYMBOL( ?internal_resize@concurrent_vector_base_v3@internal@tbb@@IAAXIIIPBXP6AXPAXI@ZP6AX10I@Z@Z ) __TBB_SYMBOL( ?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IAAIIIP6AXPAXPBXI@Z1@Z ) // tbb_thread __TBB_SYMBOL( ?join@tbb_thread_v3@internal@tbb@@QAAXXZ ) __TBB_SYMBOL( ?detach@tbb_thread_v3@internal@tbb@@QAAXXZ ) __TBB_SYMBOL( ?internal_start@tbb_thread_v3@internal@tbb@@AAAXP6AIPAX@Z0@Z ) __TBB_SYMBOL( ?allocate_closure_v3@internal@tbb@@YAPAXI@Z ) __TBB_SYMBOL( ?free_closure_v3@internal@tbb@@YAXPAX@Z ) __TBB_SYMBOL( ?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ ) __TBB_SYMBOL( ?thread_yield_v3@internal@tbb@@YAXXZ ) __TBB_SYMBOL( ?thread_sleep_v3@internal@tbb@@YAXABVinterval_t@tick_count@2@@Z ) __TBB_SYMBOL( ?move_v3@internal@tbb@@YAXAAVtbb_thread_v3@12@0@Z ) __TBB_SYMBOL( ?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ ) // condition_variable __TBB_SYMBOL( ?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAATcondvar_impl_t@123@PAVmutex@3@PBVinterval_t@tick_count@3@@Z ) __TBB_SYMBOL( ?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) __TBB_SYMBOL( ?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) #undef __TBB_SYMBOL ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/x86_rtm_rw_mutex.cpp ================================================ /* Copyright 2005-2014 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "tbb/tbb_config.h" #if __TBB_TSX_AVAILABLE #include "tbb/spin_rw_mutex.h" #include "tbb/tbb_machine.h" #include "itt_notify.h" #include "governor.h" #include "tbb/atomic.h" // __TBB_RW_MUTEX_DELAY_TEST shifts the point where flags aborting speculation are // added to the read-set of the operation. If 1, will add the test just before // the transaction is ended. #ifndef __TBB_RW_MUTEX_DELAY_TEST #define __TBB_RW_MUTEX_DELAY_TEST 1 #endif #if defined(_MSC_VER) && defined(_Wp64) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (disable: 4244) #endif namespace tbb { namespace interface8 { namespace internal { // abort code for mutexes that detect a conflict with another thread. // value is hexadecimal enum { speculation_transaction_aborted = 0x01, speculation_can_retry = 0x02, speculation_memadd_conflict = 0x04, speculation_buffer_overflow = 0x08, speculation_breakpoint_hit = 0x10, speculation_nested_abort = 0x20, speculation_xabort_mask = 0xFF000000, speculation_xabort_shift = 24, speculation_retry = speculation_transaction_aborted | speculation_can_retry | speculation_memadd_conflict }; // maximum number of times to retry static const int retry_threshold_read = 10; static const int retry_threshold_write = 10; //! Release speculative mutex void x86_rtm_rw_mutex::internal_release(x86_rtm_rw_mutex::scoped_lock& s) { switch(s.transaction_state) { case RTM_transacting_writer: case RTM_transacting_reader: { __TBB_ASSERT(__TBB_machine_is_in_transaction(), "transaction_state && not speculating"); #if __TBB_RW_MUTEX_DELAY_TEST if(s.transaction_state == RTM_transacting_reader) { if(this->w_flag) __TBB_machine_transaction_conflict_abort(); } else { if(this->state) __TBB_machine_transaction_conflict_abort(); } #endif __TBB_machine_end_transaction(); s.my_scoped_lock.internal_set_mutex(NULL); } break; case RTM_real_reader: __TBB_ASSERT(!this->w_flag, "w_flag set but read lock acquired"); s.my_scoped_lock.release(); break; case RTM_real_writer: __TBB_ASSERT(this->w_flag, "w_flag unset but write lock acquired"); this->w_flag = false; s.my_scoped_lock.release(); break; case RTM_not_in_mutex: __TBB_ASSERT(false, "RTM_not_in_mutex, but in release"); default: __TBB_ASSERT(false, "invalid transaction_state"); } s.transaction_state = RTM_not_in_mutex; } //! Acquire write lock on the given mutex. void x86_rtm_rw_mutex::internal_acquire_writer(x86_rtm_rw_mutex::scoped_lock& s, bool only_speculate) { __TBB_ASSERT(s.transaction_state == RTM_not_in_mutex, "scoped_lock already in transaction"); if(tbb::internal::governor::speculation_enabled()) { int num_retries = 0; unsigned int abort_code; do { tbb::internal::atomic_backoff backoff; if(this->state) { if(only_speculate) return; do { backoff.pause(); // test the spin_rw_mutex (real readers or writers) } while(this->state); } // _xbegin returns -1 on success or the abort code, so capture it if(( abort_code = __TBB_machine_begin_transaction()) == ~(unsigned int)(0) ) { // started speculation #if !__TBB_RW_MUTEX_DELAY_TEST if(this->state) { // add spin_rw_mutex to read-set. // reader or writer grabbed the lock, so abort. __TBB_machine_transaction_conflict_abort(); } #endif s.transaction_state = RTM_transacting_writer; s.my_scoped_lock.internal_set_mutex(this); // need mutex for release() return; // successfully started speculation } ++num_retries; } while( (abort_code & speculation_retry) != 0 && (num_retries < retry_threshold_write) ); } if(only_speculate) return; // should apply a real try_lock... s.my_scoped_lock.acquire(*this, true); // kill transactional writers __TBB_ASSERT(!w_flag, "After acquire for write, w_flag already true"); w_flag = true; // kill transactional readers s.transaction_state = RTM_real_writer; return; } //! Acquire read lock on given mutex. // only_speculate : true if we are doing a try_acquire. If true and we fail to speculate, don't // really acquire the lock, return and do a try_acquire on the contained spin_rw_mutex. If // the lock is already held by a writer, just return. void x86_rtm_rw_mutex::internal_acquire_reader(x86_rtm_rw_mutex::scoped_lock& s, bool only_speculate) { __TBB_ASSERT(s.transaction_state == RTM_not_in_mutex, "scoped_lock already in transaction"); if(tbb::internal::governor::speculation_enabled()) { int num_retries = 0; unsigned int abort_code; do { tbb::internal::atomic_backoff backoff; // if in try_acquire, and lock is held as writer, don't attempt to speculate. if(w_flag) { if(only_speculate) return; do { backoff.pause(); // test the spin_rw_mutex (real readers or writers) } while(w_flag); } // _xbegin returns -1 on success or the abort code, so capture it if((abort_code = __TBB_machine_begin_transaction()) == ~(unsigned int)(0) ) { // started speculation #if !__TBB_RW_MUTEX_DELAY_TEST if(w_flag) { // add w_flag to read-set. __TBB_machine_transaction_conflict_abort(); // writer grabbed the lock, so abort. } #endif s.transaction_state = RTM_transacting_reader; s.my_scoped_lock.internal_set_mutex(this); // need mutex for release() return; // successfully started speculation } // fallback path // retry only if there is any hope of getting into a transaction soon // Retry in the following cases (from Section 8.3.5 of Intel(R) // Architecture Instruction Set Extensions Programming Reference): // 1. abort caused by XABORT instruction (bit 0 of EAX register is set) // 2. the transaction may succeed on a retry (bit 1 of EAX register is set) // 3. if another logical processor conflicted with a memory address // that was part of the transaction that aborted (bit 2 of EAX register is set) // That is, retry if (abort_code & 0x7) is non-zero ++num_retries; } while( (abort_code & speculation_retry) != 0 && (num_retries < retry_threshold_read) ); } if(only_speculate) return; s.my_scoped_lock.acquire( *this, false ); s.transaction_state = RTM_real_reader; } //! Upgrade reader to become a writer. /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ bool x86_rtm_rw_mutex::internal_upgrade(x86_rtm_rw_mutex::scoped_lock& s) { switch(s.transaction_state) { case RTM_real_reader: { s.transaction_state = RTM_real_writer; bool no_release = s.my_scoped_lock.upgrade_to_writer(); __TBB_ASSERT(!w_flag, "After upgrade_to_writer, w_flag already true"); w_flag = true; return no_release; } case RTM_transacting_reader: s.transaction_state = RTM_transacting_writer; // don't need to add w_flag to read_set even if __TBB_RW_MUTEX_DELAY_TEST // because the this pointer (the spin_rw_mutex) will be sufficient on release. return true; default: __TBB_ASSERT(false, "Invalid state for upgrade"); return false; } } //! Downgrade writer to a reader. bool x86_rtm_rw_mutex::internal_downgrade(x86_rtm_rw_mutex::scoped_lock& s) { switch(s.transaction_state) { case RTM_real_writer: s.transaction_state = RTM_real_reader; __TBB_ASSERT(w_flag, "Before downgrade_to_reader w_flag not true"); w_flag = false; return s.my_scoped_lock.downgrade_to_reader(); case RTM_transacting_writer: #if __TBB_RW_MUTEX_DELAY_TEST if(this->state) { // a reader or writer has acquired mutex for real. __TBB_machine_transaction_conflict_abort(); } #endif s.transaction_state = RTM_transacting_reader; return true; default: __TBB_ASSERT(false, "Invalid state for downgrade"); return false; } } //! Try to acquire write lock on the given mutex. // There may be reader(s) which acquired the spin_rw_mutex, as well as possibly // transactional reader(s). If this is the case, the acquire will fail, and assigning // w_flag will kill the transactors. So we only assign w_flag if we have successfully // acquired the lock. bool x86_rtm_rw_mutex::internal_try_acquire_writer(x86_rtm_rw_mutex::scoped_lock& s) { internal_acquire_writer(s, /*only_speculate=*/true); if(s.transaction_state == RTM_transacting_writer) { return true; } __TBB_ASSERT(s.transaction_state == RTM_not_in_mutex, "Trying to acquire writer which is already allocated"); // transacting write acquire failed. try_acquire the real mutex bool result = s.my_scoped_lock.try_acquire(*this, true); if(result) { // only shoot down readers if we're not transacting ourselves __TBB_ASSERT(!w_flag, "After try_acquire_writer, w_flag already true"); w_flag = true; s.transaction_state = RTM_real_writer; } return result; } void x86_rtm_rw_mutex::internal_construct() { ITT_SYNC_CREATE(this, _T("tbb::x86_rtm_rw_mutex"), _T("")); } } // namespace internal } // namespace interface8 } // namespace tbb #endif /* __TBB_TSX_AVAILABLE */ ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbb/xbox360-tbb-export.def ================================================ ; Copyright 2005-2014 Intel Corporation. All Rights Reserved. ; ; This file is part of Threading Building Blocks. Threading Building Blocks is free software; ; you can redistribute it and/or modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. Threading Building Blocks is ; distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the ; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; See the GNU General Public License for more details. You should have received a copy of ; the GNU General Public License along with Threading Building Blocks; if not, write to the ; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ; ; As a special exception, you may use this file as part of a free software library without ; restriction. Specifically, if other files instantiate templates or use macros or inline ; functions from this file, or you compile this file and link it with other files to produce ; an executable, this file does not by itself cause the resulting executable to be covered ; by the GNU General Public License. This exception does not however invalidate any other ; reasons why the executable file might be covered by the GNU General Public License. EXPORTS ; Assembly-language support that is called directly by clients ;__TBB_machine_cmpswp1 ;__TBB_machine_cmpswp2 ;__TBB_machine_cmpswp4 ;__TBB_machine_cmpswp8 ;__TBB_machine_fetchadd1 ;__TBB_machine_fetchadd2 ;__TBB_machine_fetchadd4 ;__TBB_machine_fetchadd8 ;__TBB_machine_fetchstore1 ;__TBB_machine_fetchstore2 ;__TBB_machine_fetchstore4 ;__TBB_machine_fetchstore8 ;__TBB_machine_store8 ;__TBB_machine_load8 ;__TBB_machine_trylockbyte ; cache_aligned_allocator.cpp ?NFS_Allocate@internal@tbb@@YAPAXIIPAX@Z @1 ?NFS_GetLineSize@internal@tbb@@YAIXZ @2 ?NFS_Free@internal@tbb@@YAXPAX@Z @3 ?allocate_via_handler_v3@internal@tbb@@YAPAXI@Z @4 ?deallocate_via_handler_v3@internal@tbb@@YAXPAX@Z @5 ?is_malloc_used_v3@internal@tbb@@YA_NXZ @6 ; task.cpp v3 ?allocate@allocate_additional_child_of_proxy@internal@tbb@@QBAAAVtask@3@I@Z @7 ?allocate@allocate_child_proxy@internal@tbb@@QBAAAVtask@3@I@Z @8 ?allocate@allocate_continuation_proxy@internal@tbb@@QBAAAVtask@3@I@Z @9 ?allocate@allocate_root_proxy@internal@tbb@@SAAAVtask@3@I@Z @10 ?destroy@task@tbb@@QAAXAAV12@@Z @11 ?free@allocate_additional_child_of_proxy@internal@tbb@@QBAXAAVtask@3@@Z @12 ?free@allocate_child_proxy@internal@tbb@@QBAXAAVtask@3@@Z @13 ?free@allocate_continuation_proxy@internal@tbb@@QBAXAAVtask@3@@Z @14 ?free@allocate_root_proxy@internal@tbb@@SAXAAVtask@3@@Z @15 ?internal_set_ref_count@task@tbb@@AAAXH@Z @16 ?is_owned_by_current_thread@task@tbb@@QBA_NXZ @17 ?note_affinity@task@tbb@@UAAXG@Z @18 ?resize@affinity_partitioner_base_v3@internal@tbb@@AAAXI@Z @19 ?self@task@tbb@@SAAAV12@XZ @20 ?spawn_and_wait_for_all@task@tbb@@QAAXAAVtask_list@2@@Z @21 ?default_num_threads@task_scheduler_init@tbb@@SAHXZ @22 ?initialize@task_scheduler_init@tbb@@QAAXHI@Z @23 ?initialize@task_scheduler_init@tbb@@QAAXH@Z @24 ?terminate@task_scheduler_init@tbb@@QAAXXZ @25 ?observe@task_scheduler_observer_v3@internal@tbb@@QAAX_N@Z @26 ; exception handling support ?allocate@allocate_root_with_context_proxy@internal@tbb@@QBAAAVtask@3@I@Z @27 ?free@allocate_root_with_context_proxy@internal@tbb@@QBAXAAVtask@3@@Z @28 ?is_group_execution_cancelled@task_group_context@tbb@@QBA_NXZ @29 ?cancel_group_execution@task_group_context@tbb@@QAA_NXZ @30 ?reset@task_group_context@tbb@@QAAXXZ @31 ?init@task_group_context@tbb@@IAAXXZ @32 ??1task_group_context@tbb@@QAA@XZ @33 ?name@captured_exception@tbb@@UBAPBDXZ @34 ?what@captured_exception@tbb@@UBAPBDXZ @35 ??1captured_exception@tbb@@UAA@XZ @36 ; tbb_misc.cpp ?assertion_failure@tbb@@YAXPBDH00@Z @37 ?get_initial_auto_partitioner_divisor@internal@tbb@@YAIXZ @38 ?handle_perror@internal@tbb@@YAXHPBD@Z @39 ?set_assertion_handler@tbb@@YAP6AXPBDH00@ZP6AX0H00@Z@Z @40 ?runtime_warning@internal@tbb@@YAXPBDZZ @41 ; tbb_main.cpp ?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPAXPBX@Z @42 ?itt_store_pointer_with_release_v3@internal@tbb@@YAXPAX0@Z @43 ; pipeline.cpp ??0pipeline@tbb@@QAA@XZ @44 ??1filter@tbb@@UAA@XZ @45 ??1pipeline@tbb@@UAA@XZ @46 ??_7pipeline@tbb@@6B@ @47 ?add_filter@pipeline@tbb@@QAAXAAVfilter@2@@Z @48 ?clear@pipeline@tbb@@QAAXXZ @49 ?inject_token@pipeline@tbb@@AAAXAAVtask@2@@Z @50 ?run@pipeline@tbb@@QAAXI@Z @51 ; queuing_rw_mutex.cpp ?acquire@scoped_lock@queuing_rw_mutex@tbb@@QAAXAAV23@_N@Z @52 ?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QAA_NXZ @53 ?release@scoped_lock@queuing_rw_mutex@tbb@@QAAXXZ @54 ?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QAA_NXZ @55 ?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QAA_NAAV23@_N@Z @56 #if !TBB_NO_LEGACY ; spin_rw_mutex.cpp v2 ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z @57 ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z @58 ?internal_downgrade@spin_rw_mutex@tbb@@CAXPAV12@@Z @59 ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPAV12@@Z @60 ?internal_release_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z @61 ?internal_release_writer@spin_rw_mutex@tbb@@CAXPAV12@@Z @62 ?internal_upgrade@spin_rw_mutex@tbb@@CA_NPAV12@@Z @63 ?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z @64 ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPAV12@@Z @65 #endif ; spin_rw_mutex v3 ?internal_upgrade@spin_rw_mutex_v3@tbb@@AAA_NXZ @66 ?internal_downgrade@spin_rw_mutex_v3@tbb@@AAAXXZ @67 ?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AAAXXZ @68 ?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AAA_NXZ @69 ?internal_release_reader@spin_rw_mutex_v3@tbb@@AAAXXZ @70 ?internal_release_writer@spin_rw_mutex_v3@tbb@@AAAXXZ @71 ?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AAA_NXZ @72 ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AAA_NXZ @73 ; spin_mutex.cpp ?internal_acquire@scoped_lock@spin_mutex@tbb@@AAAXAAV23@@Z @74 ?internal_release@scoped_lock@spin_mutex@tbb@@AAAXXZ @75 ?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AAA_NAAV23@@Z @76 ; mutex.cpp ?internal_acquire@scoped_lock@mutex@tbb@@AAAXAAV23@@Z @77 ?internal_release@scoped_lock@mutex@tbb@@AAAXXZ @78 ?internal_try_acquire@scoped_lock@mutex@tbb@@AAA_NAAV23@@Z @79 ?internal_construct@mutex@tbb@@AAAXXZ @80 ?internal_destroy@mutex@tbb@@AAAXXZ @81 ; recursive_mutex.cpp ?internal_acquire@scoped_lock@recursive_mutex@tbb@@AAAXAAV23@@Z @82 ?internal_release@scoped_lock@recursive_mutex@tbb@@AAAXXZ @83 ?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AAA_NAAV23@@Z @84 ?internal_construct@recursive_mutex@tbb@@AAAXXZ @85 ?internal_destroy@recursive_mutex@tbb@@AAAXXZ @86 ; queuing_mutex.cpp ?acquire@scoped_lock@queuing_mutex@tbb@@QAAXAAV23@@Z @87 ?release@scoped_lock@queuing_mutex@tbb@@QAAXXZ @88 ?try_acquire@scoped_lock@queuing_mutex@tbb@@QAA_NAAV23@@Z @89 ; concurrent_hash_map.cpp ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QBA_NXZ @90 #if !TBB_NO_LEGACY ; concurrent_queue.cpp v2 ?advance@concurrent_queue_iterator_base@internal@tbb@@IAAXXZ @91 ?assign@concurrent_queue_iterator_base@internal@tbb@@IAAXABV123@@Z @92 ?internal_size@concurrent_queue_base@internal@tbb@@IBAHXZ @93 ??0concurrent_queue_base@internal@tbb@@IAA@I@Z @94 ??0concurrent_queue_iterator_base@internal@tbb@@IAA@ABVconcurrent_queue_base@12@@Z @95 ??1concurrent_queue_base@internal@tbb@@MAA@XZ @96 ??1concurrent_queue_iterator_base@internal@tbb@@IAA@XZ @97 ?internal_pop@concurrent_queue_base@internal@tbb@@IAAXPAX@Z @98 ?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IAA_NPAX@Z @99 ?internal_push@concurrent_queue_base@internal@tbb@@IAAXPBX@Z @100 ?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IAA_NPBX@Z @101 ?internal_set_capacity@concurrent_queue_base@internal@tbb@@IAAXHI@Z @102 #endif ; concurrent_queue v3 ??1concurrent_queue_iterator_base_v3@internal@tbb@@IAA@XZ @103 ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAA@ABVconcurrent_queue_base_v3@12@@Z @104 ?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IAAXXZ @105 ?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IAAXABV123@@Z @106 ??0concurrent_queue_base_v3@internal@tbb@@IAA@I@Z @107 ??1concurrent_queue_base_v3@internal@tbb@@MAA@XZ @108 ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IAAXPAX@Z @109 ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IAA_NPAX@Z @110 ?internal_push@concurrent_queue_base_v3@internal@tbb@@IAAXPBX@Z @111 ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IAA_NPBX@Z @112 ?internal_size@concurrent_queue_base_v3@internal@tbb@@IBAHXZ @113 ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IAAXHI@Z @114 ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IAAXXZ @115 ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IBAXXZ @116 #if !TBB_NO_LEGACY ; concurrent_vector.cpp v2 ?internal_assign@concurrent_vector_base@internal@tbb@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z @117 ?internal_capacity@concurrent_vector_base@internal@tbb@@IBAIXZ @118 ?internal_clear@concurrent_vector_base@internal@tbb@@IAAXP6AXPAXI@Z_N@Z @119 ?internal_copy@concurrent_vector_base@internal@tbb@@IAAXABV123@IP6AXPAXPBXI@Z@Z @120 ?internal_grow_by@concurrent_vector_base@internal@tbb@@IAAIIIP6AXPAXI@Z@Z @121 ?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IAAXIIP6AXPAXI@Z@Z @122 ?internal_push_back@concurrent_vector_base@internal@tbb@@IAAPAXIAAI@Z @123 ?internal_reserve@concurrent_vector_base@internal@tbb@@IAAXIII@Z @124 #endif ; concurrent_vector v3 ??1concurrent_vector_base_v3@internal@tbb@@IAA@XZ @125 ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z @126 ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IBAIXZ @127 ?internal_clear@concurrent_vector_base_v3@internal@tbb@@IAAIP6AXPAXI@Z@Z @128 ?internal_copy@concurrent_vector_base_v3@internal@tbb@@IAAXABV123@IP6AXPAXPBXI@Z@Z @129 ?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IAAIIIP6AXPAXPBXI@Z1@Z @130 ?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IAAXIIP6AXPAXPBXI@Z1@Z @131 ?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IAAPAXIAAI@Z @132 ?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IAAXIII@Z @133 ?internal_compact@concurrent_vector_base_v3@internal@tbb@@IAAPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z @134 ?internal_swap@concurrent_vector_base_v3@internal@tbb@@IAAXAAV123@@Z @135 ?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IBAXI@Z @136 ; tbb_thread ?join@tbb_thread_v3@internal@tbb@@QAAXXZ @137 ?detach@tbb_thread_v3@internal@tbb@@QAAXXZ @138 ?internal_start@tbb_thread_v3@internal@tbb@@AAAXP6AIPAX@Z0@Z @139 ?allocate_closure_v3@internal@tbb@@YAPAXI@Z @140 ?free_closure_v3@internal@tbb@@YAXPAX@Z @141 ?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ @142 ?thread_yield_v3@internal@tbb@@YAXXZ @143 ?thread_sleep_v3@internal@tbb@@YAXABVinterval_t@tick_count@2@@Z @144 ?move_v3@internal@tbb@@YAXAAVtbb_thread_v3@12@0@Z @145 ?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ @146 ================================================ FILE: src/third_party/concurrentqueue/benchmarks/tbbqueue.h ================================================ #pragma once #include #include "tbb/concurrent_queue.h" #include "wrappers.h" template struct TbbQueueWrapper { public: typedef DummyToken producer_token_t; typedef DummyToken consumer_token_t; public: template inline bool enqueue(U&& item) { q.push(std::forward(item)); return true; // assume successful allocation for the sake of the benchmarks } inline bool try_dequeue(T& item) { return q.try_pop(item); } // Dummy token methods (not used) bool enqueue(producer_token_t const&, T const&) { return false; } bool try_enqueue(producer_token_t, T const&) { return false; } bool try_dequeue(consumer_token_t, T& item) { return false; } template bool enqueue_bulk(It, size_t) { return false; } template bool enqueue_bulk(producer_token_t const&, It, size_t) { return false; } template size_t try_dequeue_bulk(It, size_t) { return 0; } template size_t try_dequeue_bulk(consumer_token_t, It, size_t) { return 0; } private: tbb::concurrent_queue q; }; ================================================ FILE: src/third_party/concurrentqueue/benchmarks/wrappers.h ================================================ #pragma once struct DummyToken { template DummyToken(TQueue const&) { } }; ================================================ FILE: src/third_party/concurrentqueue/blockingconcurrentqueue.h ================================================ // Provides an efficient blocking version of moodycamel::ConcurrentQueue. // ©2015-2016 Cameron Desrochers. Distributed under the terms of the simplified // BSD license, available at the top of concurrentqueue.h. // Uses Jeff Preshing's semaphore implementation (under the terms of its // separate zlib license, embedded below). #pragma once #include "concurrentqueue.h" #include #include #include #include #include #if defined(_WIN32) // Avoid including windows.h in a header; we only need a handful of // items, so we'll redeclare them here (this is relatively safe since // the API generally has to remain stable between Windows versions). // I know this is an ugly hack but it still beats polluting the global // namespace with thousands of generic names or adding a .cpp for nothing. extern "C" { struct _SECURITY_ATTRIBUTES; __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes, long lInitialCount, long lMaximumCount, const wchar_t* lpName); __declspec(dllimport) int __stdcall CloseHandle(void* hObject); __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void* hHandle, unsigned long dwMilliseconds); __declspec(dllimport) int __stdcall ReleaseSemaphore(void* hSemaphore, long lReleaseCount, long* lpPreviousCount); } #elif defined(__MACH__) #include #elif defined(__unix__) #include #endif namespace moodycamel { namespace details { // Code in the mpmc_sema namespace below is an adaptation of Jeff Preshing's // portable + lightweight semaphore implementations, originally from // https://github.com/preshing/cpp11-on-multicore/blob/master/common/sema.h // LICENSE: // Copyright (c) 2015 Jeff Preshing // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software // in a product, an acknowledgement in the product documentation would be // appreciated but is not required. // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // 3. This notice may not be removed or altered from any source distribution. namespace mpmc_sema { #if defined(_WIN32) class Semaphore { private: void* m_hSema; Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; public: Semaphore(int initialCount = 0) { assert(initialCount >= 0); const long maxLong = 0x7fffffff; m_hSema = CreateSemaphoreW(nullptr, initialCount, maxLong, nullptr); } ~Semaphore() { CloseHandle(m_hSema); } void wait() { const unsigned long infinite = 0xffffffff; WaitForSingleObject(m_hSema, infinite); } bool try_wait() { const unsigned long RC_WAIT_TIMEOUT = 0x00000102; return WaitForSingleObject(m_hSema, 0) != RC_WAIT_TIMEOUT; } bool timed_wait(std::uint64_t usecs) { const unsigned long RC_WAIT_TIMEOUT = 0x00000102; return WaitForSingleObject(m_hSema, (unsigned long)(usecs / 1000)) != RC_WAIT_TIMEOUT; } void signal(int count = 1) { ReleaseSemaphore(m_hSema, count, nullptr); } }; #elif defined(__MACH__) //--------------------------------------------------------- // Semaphore (Apple iOS and OSX) // Can't use POSIX semaphores due to http://lists.apple.com/archives/darwin-kernel/2009/Apr/msg00010.html //--------------------------------------------------------- class Semaphore { private: semaphore_t m_sema; Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; public: Semaphore(int initialCount = 0) { assert(initialCount >= 0); semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount); } ~Semaphore() { semaphore_destroy(mach_task_self(), m_sema); } void wait() { semaphore_wait(m_sema); } bool try_wait() { return timed_wait(0); } bool timed_wait(std::uint64_t timeout_usecs) { mach_timespec_t ts; ts.tv_sec = static_cast(timeout_usecs / 1000000); ts.tv_nsec = (timeout_usecs % 1000000) * 1000; // added in OSX 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/modules/Darwin.html kern_return_t rc = semaphore_timedwait(m_sema, ts); return rc != KERN_OPERATION_TIMED_OUT && rc != KERN_ABORTED; } void signal() { semaphore_signal(m_sema); } void signal(int count) { while (count-- > 0) { semaphore_signal(m_sema); } } }; #elif defined(__unix__) //--------------------------------------------------------- // Semaphore (POSIX, Linux) //--------------------------------------------------------- class Semaphore { private: sem_t m_sema; Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; public: Semaphore(int initialCount = 0) { assert(initialCount >= 0); sem_init(&m_sema, 0, initialCount); } ~Semaphore() { sem_destroy(&m_sema); } void wait() { // http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error int rc; do { rc = sem_wait(&m_sema); } while (rc == -1 && errno == EINTR); } bool try_wait() { int rc; do { rc = sem_trywait(&m_sema); } while (rc == -1 && errno == EINTR); return !(rc == -1 && errno == EAGAIN); } bool timed_wait(std::uint64_t usecs) { struct timespec ts; const int usecs_in_1_sec = 1000000; const int nsecs_in_1_sec = 1000000000; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += usecs / usecs_in_1_sec; ts.tv_nsec += (usecs % usecs_in_1_sec) * 1000; // sem_timedwait bombs if you have more than 1e9 in tv_nsec // so we have to clean things up before passing it in if (ts.tv_nsec >= nsecs_in_1_sec) { ts.tv_nsec -= nsecs_in_1_sec; ++ts.tv_sec; } int rc; do { rc = sem_timedwait(&m_sema, &ts); } while (rc == -1 && errno == EINTR); return !(rc == -1 && errno == ETIMEDOUT); } void signal() { sem_post(&m_sema); } void signal(int count) { while (count-- > 0) { sem_post(&m_sema); } } }; #else #error Unsupported platform! (No semaphore wrapper available) #endif //--------------------------------------------------------- // LightweightSemaphore //--------------------------------------------------------- class LightweightSemaphore { public: typedef std::make_signed::type ssize_t; private: std::atomic m_count; Semaphore m_sema; bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1) { ssize_t oldCount; // Is there a better way to set the initial spin count? // If we lower it to 1000, testBenaphore becomes 15x slower on my Core i7-5930K Windows PC, // as threads start hitting the kernel semaphore. int spin = 10000; while (--spin >= 0) { oldCount = m_count.load(std::memory_order_relaxed); if ((oldCount > 0) && m_count.compare_exchange_strong(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed)) return true; std::atomic_signal_fence(std::memory_order_acquire); // Prevent the compiler from collapsing the loop. } oldCount = m_count.fetch_sub(1, std::memory_order_acquire); if (oldCount > 0) return true; if (timeout_usecs < 0) { m_sema.wait(); return true; } if (m_sema.timed_wait((std::uint64_t)timeout_usecs)) return true; // At this point, we've timed out waiting for the semaphore, but the // count is still decremented indicating we may still be waiting on // it. So we have to re-adjust the count, but only if the semaphore // wasn't signaled enough times for us too since then. If it was, we // need to release the semaphore too. while (true) { oldCount = m_count.load(std::memory_order_acquire); if (oldCount >= 0 && m_sema.try_wait()) return true; if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed)) return false; } } ssize_t waitManyWithPartialSpinning(ssize_t max, std::int64_t timeout_usecs = -1) { assert(max > 0); ssize_t oldCount; int spin = 10000; while (--spin >= 0) { oldCount = m_count.load(std::memory_order_relaxed); if (oldCount > 0) { ssize_t newCount = oldCount > max ? oldCount - max : 0; if (m_count.compare_exchange_strong(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed)) return oldCount - newCount; } std::atomic_signal_fence(std::memory_order_acquire); } oldCount = m_count.fetch_sub(1, std::memory_order_acquire); if (oldCount <= 0) { if (timeout_usecs < 0) m_sema.wait(); else if (!m_sema.timed_wait((std::uint64_t)timeout_usecs)) { while (true) { oldCount = m_count.load(std::memory_order_acquire); if (oldCount >= 0 && m_sema.try_wait()) break; if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed)) return 0; } } } if (max > 1) return 1 + tryWaitMany(max - 1); return 1; } public: LightweightSemaphore(ssize_t initialCount = 0) : m_count(initialCount) { assert(initialCount >= 0); } bool tryWait() { ssize_t oldCount = m_count.load(std::memory_order_relaxed); while (oldCount > 0) { if (m_count.compare_exchange_weak(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed)) return true; } return false; } void wait() { if (!tryWait()) waitWithPartialSpinning(); } bool wait(std::int64_t timeout_usecs) { return tryWait() || waitWithPartialSpinning(timeout_usecs); } // Acquires between 0 and (greedily) max, inclusive ssize_t tryWaitMany(ssize_t max) { assert(max >= 0); ssize_t oldCount = m_count.load(std::memory_order_relaxed); while (oldCount > 0) { ssize_t newCount = oldCount > max ? oldCount - max : 0; if (m_count.compare_exchange_weak(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed)) return oldCount - newCount; } return 0; } // Acquires at least one, and (greedily) at most max ssize_t waitMany(ssize_t max, std::int64_t timeout_usecs) { assert(max >= 0); ssize_t result = tryWaitMany(max); if (result == 0 && max > 0) result = waitManyWithPartialSpinning(max, timeout_usecs); return result; } ssize_t waitMany(ssize_t max) { ssize_t result = waitMany(max, -1); assert(result > 0); return result; } void signal(ssize_t count = 1) { assert(count >= 0); ssize_t oldCount = m_count.fetch_add(count, std::memory_order_release); ssize_t toRelease = -oldCount < count ? -oldCount : count; if (toRelease > 0) { m_sema.signal((int)toRelease); } } ssize_t availableApprox() const { ssize_t count = m_count.load(std::memory_order_relaxed); return count > 0 ? count : 0; } }; } // end namespace mpmc_sema } // end namespace details // This is a blocking version of the queue. It has an almost identical interface to // the normal non-blocking version, with the addition of various wait_dequeue() methods // and the removal of producer-specific dequeue methods. template class BlockingConcurrentQueue { private: typedef ::moodycamel::ConcurrentQueue ConcurrentQueue; typedef details::mpmc_sema::LightweightSemaphore LightweightSemaphore; public: typedef typename ConcurrentQueue::producer_token_t producer_token_t; typedef typename ConcurrentQueue::consumer_token_t consumer_token_t; typedef typename ConcurrentQueue::index_t index_t; typedef typename ConcurrentQueue::size_t size_t; typedef typename std::make_signed::type ssize_t; static const size_t BLOCK_SIZE = ConcurrentQueue::BLOCK_SIZE; static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = ConcurrentQueue::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD; static const size_t EXPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::EXPLICIT_INITIAL_INDEX_SIZE; static const size_t IMPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::IMPLICIT_INITIAL_INDEX_SIZE; static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = ConcurrentQueue::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE; static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = ConcurrentQueue::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE; static const size_t MAX_SUBQUEUE_SIZE = ConcurrentQueue::MAX_SUBQUEUE_SIZE; public: // Creates a queue with at least `capacity` element slots; note that the // actual number of elements that can be inserted without additional memory // allocation depends on the number of producers and the block size (e.g. if // the block size is equal to `capacity`, only a single block will be allocated // up-front, which means only a single producer will be able to enqueue elements // without an extra allocation -- blocks aren't shared between producers). // This method is not thread safe -- it is up to the user to ensure that the // queue is fully constructed before it starts being used by other threads (this // includes making the memory effects of construction visible, possibly with a // memory barrier). explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE) : inner(capacity), sema(create(), &BlockingConcurrentQueue::template destroy) { assert(reinterpret_cast((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member"); if (!sema) { MOODYCAMEL_THROW(std::bad_alloc()); } } BlockingConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers) : inner(minCapacity, maxExplicitProducers, maxImplicitProducers), sema(create(), &BlockingConcurrentQueue::template destroy) { assert(reinterpret_cast((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member"); if (!sema) { MOODYCAMEL_THROW(std::bad_alloc()); } } // Disable copying and copy assignment BlockingConcurrentQueue(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; BlockingConcurrentQueue& operator=(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; // Moving is supported, but note that it is *not* a thread-safe operation. // Nobody can use the queue while it's being moved, and the memory effects // of that move must be propagated to other threads before they can use it. // Note: When a queue is moved, its tokens are still valid but can only be // used with the destination queue (i.e. semantically they are moved along // with the queue itself). BlockingConcurrentQueue(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT : inner(std::move(other.inner)), sema(std::move(other.sema)) { } inline BlockingConcurrentQueue& operator=(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT { return swap_internal(other); } // Swaps this queue's state with the other's. Not thread-safe. // Swapping two queues does not invalidate their tokens, however // the tokens that were created for one queue must be used with // only the swapped queue (i.e. the tokens are tied to the // queue's movable state, not the object itself). inline void swap(BlockingConcurrentQueue& other) MOODYCAMEL_NOEXCEPT { swap_internal(other); } private: BlockingConcurrentQueue& swap_internal(BlockingConcurrentQueue& other) { if (this == &other) { return *this; } inner.swap(other.inner); sema.swap(other.sema); return *this; } public: // Enqueues a single item (by copying it). // Allocates memory if required. Only fails if memory allocation fails (or implicit // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(T const& item) { if ((details::likely)(inner.enqueue(item))) { sema->signal(); return true; } return false; } // Enqueues a single item (by moving it, if possible). // Allocates memory if required. Only fails if memory allocation fails (or implicit // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(T&& item) { if ((details::likely)(inner.enqueue(std::move(item)))) { sema->signal(); return true; } return false; } // Enqueues a single item (by copying it) using an explicit producer token. // Allocates memory if required. Only fails if memory allocation fails (or // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(producer_token_t const& token, T const& item) { if ((details::likely)(inner.enqueue(token, item))) { sema->signal(); return true; } return false; } // Enqueues a single item (by moving it, if possible) using an explicit producer token. // Allocates memory if required. Only fails if memory allocation fails (or // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(producer_token_t const& token, T&& item) { if ((details::likely)(inner.enqueue(token, std::move(item)))) { sema->signal(); return true; } return false; } // Enqueues several items. // Allocates memory if required. Only fails if memory allocation fails (or // implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE // is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Note: Use std::make_move_iterator if the elements should be moved instead of copied. // Thread-safe. template inline bool enqueue_bulk(It itemFirst, size_t count) { if ((details::likely)(inner.enqueue_bulk(std::forward(itemFirst), count))) { sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count); return true; } return false; } // Enqueues several items using an explicit producer token. // Allocates memory if required. Only fails if memory allocation fails // (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Note: Use std::make_move_iterator if the elements should be moved // instead of copied. // Thread-safe. template inline bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) { if ((details::likely)(inner.enqueue_bulk(token, std::forward(itemFirst), count))) { sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count); return true; } return false; } // Enqueues a single item (by copying it). // Does not allocate memory. Fails if not enough room to enqueue (or implicit // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE // is 0). // Thread-safe. inline bool try_enqueue(T const& item) { if (inner.try_enqueue(item)) { sema->signal(); return true; } return false; } // Enqueues a single item (by moving it, if possible). // Does not allocate memory (except for one-time implicit producer). // Fails if not enough room to enqueue (or implicit production is // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0). // Thread-safe. inline bool try_enqueue(T&& item) { if (inner.try_enqueue(std::move(item))) { sema->signal(); return true; } return false; } // Enqueues a single item (by copying it) using an explicit producer token. // Does not allocate memory. Fails if not enough room to enqueue. // Thread-safe. inline bool try_enqueue(producer_token_t const& token, T const& item) { if (inner.try_enqueue(token, item)) { sema->signal(); return true; } return false; } // Enqueues a single item (by moving it, if possible) using an explicit producer token. // Does not allocate memory. Fails if not enough room to enqueue. // Thread-safe. inline bool try_enqueue(producer_token_t const& token, T&& item) { if (inner.try_enqueue(token, std::move(item))) { sema->signal(); return true; } return false; } // Enqueues several items. // Does not allocate memory (except for one-time implicit producer). // Fails if not enough room to enqueue (or implicit production is // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0). // Note: Use std::make_move_iterator if the elements should be moved // instead of copied. // Thread-safe. template inline bool try_enqueue_bulk(It itemFirst, size_t count) { if (inner.try_enqueue_bulk(std::forward(itemFirst), count)) { sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count); return true; } return false; } // Enqueues several items using an explicit producer token. // Does not allocate memory. Fails if not enough room to enqueue. // Note: Use std::make_move_iterator if the elements should be moved // instead of copied. // Thread-safe. template inline bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) { if (inner.try_enqueue_bulk(token, std::forward(itemFirst), count)) { sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count); return true; } return false; } // Attempts to dequeue from the queue. // Returns false if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template inline bool try_dequeue(U& item) { if (sema->tryWait()) { while (!inner.try_dequeue(item)) { continue; } return true; } return false; } // Attempts to dequeue from the queue using an explicit consumer token. // Returns false if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template inline bool try_dequeue(consumer_token_t& token, U& item) { if (sema->tryWait()) { while (!inner.try_dequeue(token, item)) { continue; } return true; } return false; } // Attempts to dequeue several elements from the queue. // Returns the number of items actually dequeued. // Returns 0 if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template inline size_t try_dequeue_bulk(It itemFirst, size_t max) { size_t count = 0; max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max); while (count != max) { count += inner.template try_dequeue_bulk(itemFirst, max - count); } return count; } // Attempts to dequeue several elements from the queue using an explicit consumer token. // Returns the number of items actually dequeued. // Returns 0 if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template inline size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max) { size_t count = 0; max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max); while (count != max) { count += inner.template try_dequeue_bulk(token, itemFirst, max - count); } return count; } // Blocks the current thread until there's something to dequeue, then // dequeues it. // Never allocates. Thread-safe. template inline void wait_dequeue(U& item) { sema->wait(); while (!inner.try_dequeue(item)) { continue; } } // Blocks the current thread until either there's something to dequeue // or the timeout (specified in microseconds) expires. Returns false // without setting `item` if the timeout expires, otherwise assigns // to `item` and returns true. // Using a negative timeout indicates an indefinite timeout, // and is thus functionally equivalent to calling wait_dequeue. // Never allocates. Thread-safe. template inline bool wait_dequeue_timed(U& item, std::int64_t timeout_usecs) { if (!sema->wait(timeout_usecs)) { return false; } while (!inner.try_dequeue(item)) { continue; } return true; } // Blocks the current thread until either there's something to dequeue // or the timeout expires. Returns false without setting `item` if the // timeout expires, otherwise assigns to `item` and returns true. // Never allocates. Thread-safe. template inline bool wait_dequeue_timed(U& item, std::chrono::duration const& timeout) { return wait_dequeue_timed(item, std::chrono::duration_cast(timeout).count()); } // Blocks the current thread until there's something to dequeue, then // dequeues it using an explicit consumer token. // Never allocates. Thread-safe. template inline void wait_dequeue(consumer_token_t& token, U& item) { sema->wait(); while (!inner.try_dequeue(token, item)) { continue; } } // Blocks the current thread until either there's something to dequeue // or the timeout (specified in microseconds) expires. Returns false // without setting `item` if the timeout expires, otherwise assigns // to `item` and returns true. // Using a negative timeout indicates an indefinite timeout, // and is thus functionally equivalent to calling wait_dequeue. // Never allocates. Thread-safe. template inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::int64_t timeout_usecs) { if (!sema->wait(timeout_usecs)) { return false; } while (!inner.try_dequeue(token, item)) { continue; } return true; } // Blocks the current thread until either there's something to dequeue // or the timeout expires. Returns false without setting `item` if the // timeout expires, otherwise assigns to `item` and returns true. // Never allocates. Thread-safe. template inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::chrono::duration const& timeout) { return wait_dequeue_timed(token, item, std::chrono::duration_cast(timeout).count()); } // Attempts to dequeue several elements from the queue. // Returns the number of items actually dequeued, which will // always be at least one (this method blocks until the queue // is non-empty) and at most max. // Never allocates. Thread-safe. template inline size_t wait_dequeue_bulk(It itemFirst, size_t max) { size_t count = 0; max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max); while (count != max) { count += inner.template try_dequeue_bulk(itemFirst, max - count); } return count; } // Attempts to dequeue several elements from the queue. // Returns the number of items actually dequeued, which can // be 0 if the timeout expires while waiting for elements, // and at most max. // Using a negative timeout indicates an indefinite timeout, // and is thus functionally equivalent to calling wait_dequeue_bulk. // Never allocates. Thread-safe. template inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::int64_t timeout_usecs) { size_t count = 0; max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs); while (count != max) { count += inner.template try_dequeue_bulk(itemFirst, max - count); } return count; } // Attempts to dequeue several elements from the queue. // Returns the number of items actually dequeued, which can // be 0 if the timeout expires while waiting for elements, // and at most max. // Never allocates. Thread-safe. template inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::chrono::duration const& timeout) { return wait_dequeue_bulk_timed(itemFirst, max, std::chrono::duration_cast(timeout).count()); } // Attempts to dequeue several elements from the queue using an explicit consumer token. // Returns the number of items actually dequeued, which will // always be at least one (this method blocks until the queue // is non-empty) and at most max. // Never allocates. Thread-safe. template inline size_t wait_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max) { size_t count = 0; max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max); while (count != max) { count += inner.template try_dequeue_bulk(token, itemFirst, max - count); } return count; } // Attempts to dequeue several elements from the queue using an explicit consumer token. // Returns the number of items actually dequeued, which can // be 0 if the timeout expires while waiting for elements, // and at most max. // Using a negative timeout indicates an indefinite timeout, // and is thus functionally equivalent to calling wait_dequeue_bulk. // Never allocates. Thread-safe. template inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::int64_t timeout_usecs) { size_t count = 0; max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs); while (count != max) { count += inner.template try_dequeue_bulk(token, itemFirst, max - count); } return count; } // Attempts to dequeue several elements from the queue using an explicit consumer token. // Returns the number of items actually dequeued, which can // be 0 if the timeout expires while waiting for elements, // and at most max. // Never allocates. Thread-safe. template inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::chrono::duration const& timeout) { return wait_dequeue_bulk_timed(token, itemFirst, max, std::chrono::duration_cast(timeout).count()); } // Returns an estimate of the total number of elements currently in the queue. This // estimate is only accurate if the queue has completely stabilized before it is called // (i.e. all enqueue and dequeue operations have completed and their memory effects are // visible on the calling thread, and no further operations start while this method is // being called). // Thread-safe. inline size_t size_approx() const { return (size_t)sema->availableApprox(); } // Returns true if the underlying atomic variables used by // the queue are lock-free (they should be on most platforms). // Thread-safe. static bool is_lock_free() { return ConcurrentQueue::is_lock_free(); } private: template static inline U* create() { auto p = (Traits::malloc)(sizeof(U)); return p != nullptr ? new (p) U : nullptr; } template static inline U* create(A1&& a1) { auto p = (Traits::malloc)(sizeof(U)); return p != nullptr ? new (p) U(std::forward(a1)) : nullptr; } template static inline void destroy(U* p) { if (p != nullptr) { p->~U(); } (Traits::free)(p); } private: ConcurrentQueue inner; std::unique_ptr sema; }; template inline void swap(BlockingConcurrentQueue& a, BlockingConcurrentQueue& b) MOODYCAMEL_NOEXCEPT { a.swap(b); } } // end namespace moodycamel ================================================ FILE: src/third_party/concurrentqueue/concurrentqueue.h ================================================ // Provides a C++11 implementation of a multi-producer, multi-consumer lock-free queue. // An overview, including benchmark results, is provided here: // http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++ // The full design is also described in excruciating detail at: // http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue // Simplified BSD license: // Copyright (c) 2013-2016, Cameron Desrochers. // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // - Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma once #if defined(__GNUC__) // Disable -Wconversion warnings (spuriously triggered when Traits::size_t and // Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings // upon assigning any computed values) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #ifdef MCDBGQ_USE_RELACY #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" #endif #endif #if defined(__APPLE__) #include "TargetConditionals.h" #endif #ifdef MCDBGQ_USE_RELACY #include "relacy/relacy_std.hpp" #include "relacy_shims.h" // We only use malloc/free anyway, and the delete macro messes up `= delete` method declarations. // We'll override the default trait malloc ourselves without a macro. #undef new #undef delete #undef malloc #undef free #else #include // Requires C++11. Sorry VS2010. #include #endif #include // for max_align_t #include #include #include #include #include #include #include // for CHAR_BIT #include #include // partly for __WINPTHREADS_VERSION if on MinGW-w64 w/ POSIX threading // Platform-specific definitions of a numeric thread ID type and an invalid value namespace moodycamel { namespace details { template struct thread_id_converter { typedef thread_id_t thread_id_numeric_size_t; typedef thread_id_t thread_id_hash_t; static thread_id_hash_t prehash(thread_id_t const& x) { return x; } }; } } #if defined(MCDBGQ_USE_RELACY) namespace moodycamel { namespace details { typedef std::uint32_t thread_id_t; static const thread_id_t invalid_thread_id = 0xFFFFFFFFU; static const thread_id_t invalid_thread_id2 = 0xFFFFFFFEU; static inline thread_id_t thread_id() { return rl::thread_index(); } } } #elif defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__) // No sense pulling in windows.h in a header, we'll manually declare the function // we use and rely on backwards-compatibility for this not to break extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); namespace moodycamel { namespace details { static_assert(sizeof(unsigned long) == sizeof(std::uint32_t), "Expected size of unsigned long to be 32 bits on Windows"); typedef std::uint32_t thread_id_t; static const thread_id_t invalid_thread_id = 0; // See http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx static const thread_id_t invalid_thread_id2 = 0xFFFFFFFFU; // Not technically guaranteed to be invalid, but is never used in practice. Note that all Win32 thread IDs are presently multiples of 4. static inline thread_id_t thread_id() { return static_cast(::GetCurrentThreadId()); } } } #elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE) namespace moodycamel { namespace details { static_assert(sizeof(std::thread::id) == 4 || sizeof(std::thread::id) == 8, "std::thread::id is expected to be either 4 or 8 bytes"); typedef std::thread::id thread_id_t; static const thread_id_t invalid_thread_id; // Default ctor creates invalid ID // Note we don't define a invalid_thread_id2 since std::thread::id doesn't have one; it's // only used if MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is defined anyway, which it won't // be. static inline thread_id_t thread_id() { return std::this_thread::get_id(); } template struct thread_id_size { }; template<> struct thread_id_size<4> { typedef std::uint32_t numeric_t; }; template<> struct thread_id_size<8> { typedef std::uint64_t numeric_t; }; template<> struct thread_id_converter { typedef thread_id_size::numeric_t thread_id_numeric_size_t; #ifndef __APPLE__ typedef std::size_t thread_id_hash_t; #else typedef thread_id_numeric_size_t thread_id_hash_t; #endif static thread_id_hash_t prehash(thread_id_t const& x) { #ifndef __APPLE__ return std::hash()(x); #else return *reinterpret_cast(&x); #endif } }; } } #else // Use a nice trick from this answer: http://stackoverflow.com/a/8438730/21475 // In order to get a numeric thread ID in a platform-independent way, we use a thread-local // static variable's address as a thread identifier :-) #if defined(__GNUC__) || defined(__INTEL_COMPILER) #define MOODYCAMEL_THREADLOCAL __thread #elif defined(_MSC_VER) #define MOODYCAMEL_THREADLOCAL __declspec(thread) #else // Assume C++11 compliant compiler #define MOODYCAMEL_THREADLOCAL thread_local #endif namespace moodycamel { namespace details { typedef std::uintptr_t thread_id_t; static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr static const thread_id_t invalid_thread_id2 = 1; // Member accesses off a null pointer are also generally invalid. Plus it's not aligned. static inline thread_id_t thread_id() { static MOODYCAMEL_THREADLOCAL int x; return reinterpret_cast(&x); } } } #endif // Exceptions #ifndef MOODYCAMEL_EXCEPTIONS_ENABLED #if (defined(_MSC_VER) && defined(_CPPUNWIND)) || (defined(__GNUC__) && defined(__EXCEPTIONS)) || (!defined(_MSC_VER) && !defined(__GNUC__)) #define MOODYCAMEL_EXCEPTIONS_ENABLED #endif #endif #ifdef MOODYCAMEL_EXCEPTIONS_ENABLED #define MOODYCAMEL_TRY try #define MOODYCAMEL_CATCH(...) catch(__VA_ARGS__) #define MOODYCAMEL_RETHROW throw #define MOODYCAMEL_THROW(expr) throw (expr) #else #define MOODYCAMEL_TRY if (true) #define MOODYCAMEL_CATCH(...) else if (false) #define MOODYCAMEL_RETHROW #define MOODYCAMEL_THROW(expr) #endif #ifndef MOODYCAMEL_NOEXCEPT #if !defined(MOODYCAMEL_EXCEPTIONS_ENABLED) #define MOODYCAMEL_NOEXCEPT #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) true #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) true #elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1800 // VS2012's std::is_nothrow_[move_]constructible is broken and returns true when it shouldn't :-( // We have to assume *all* non-trivial constructors may throw on VS2012! #define MOODYCAMEL_NOEXCEPT _NOEXCEPT #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value : std::is_trivially_copy_constructible::value) #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) #elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1900 #define MOODYCAMEL_NOEXCEPT _NOEXCEPT #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value || std::is_nothrow_move_constructible::value : std::is_trivially_copy_constructible::value || std::is_nothrow_copy_constructible::value) #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) #else #define MOODYCAMEL_NOEXCEPT noexcept #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) noexcept(expr) #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) noexcept(expr) #endif #endif #ifndef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED #ifdef MCDBGQ_USE_RELACY #define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED #else // VS2013 doesn't support `thread_local`, and MinGW-w64 w/ POSIX threading has a crippling bug: http://sourceforge.net/p/mingw-w64/bugs/445 // g++ <=4.7 doesn't support thread_local either. // Finally, iOS/ARM doesn't have support for it either, and g++/ARM allows it to compile but it's unconfirmed to actually work #if (!defined(_MSC_VER) || _MSC_VER >= 1900) && (!defined(__MINGW32__) && !defined(__MINGW64__) || !defined(__WINPTHREADS_VERSION)) && (!defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && (!defined(__APPLE__) || !TARGET_OS_IPHONE) && !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__) // Assume `thread_local` is fully supported in all other C++11 compilers/platforms //#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED // always disabled for now since several users report having problems with it on #endif #endif #endif // VS2012 doesn't support deleted functions. // In this case, we declare the function normally but don't define it. A link error will be generated if the function is called. #ifndef MOODYCAMEL_DELETE_FUNCTION #if defined(_MSC_VER) && _MSC_VER < 1800 #define MOODYCAMEL_DELETE_FUNCTION #else #define MOODYCAMEL_DELETE_FUNCTION = delete #endif #endif // Compiler-specific likely/unlikely hints namespace moodycamel { namespace details { #if defined(__GNUC__) static inline bool (likely)(bool x) { return __builtin_expect((x), true); } static inline bool (unlikely)(bool x) { return __builtin_expect((x), false); } #else static inline bool (likely)(bool x) { return x; } static inline bool (unlikely)(bool x) { return x; } #endif } } #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG #include "internal/concurrentqueue_internal_debug.h" #endif namespace moodycamel { namespace details { template struct const_numeric_max { static_assert(std::is_integral::value, "const_numeric_max can only be used with integers"); static const T value = std::numeric_limits::is_signed ? (static_cast(1) << (sizeof(T) * CHAR_BIT - 1)) - static_cast(1) : static_cast(-1); }; #if defined(__GLIBCXX__) typedef ::max_align_t std_max_align_t; // libstdc++ forgot to add it to std:: for a while #else typedef std::max_align_t std_max_align_t; // Others (e.g. MSVC) insist it can *only* be accessed via std:: #endif // Some platforms have incorrectly set max_align_t to a type with <8 bytes alignment even while supporting // 8-byte aligned scalar values (*cough* 32-bit iOS). Work around this with our own union. See issue #64. typedef union { std_max_align_t x; long long y; void* z; } max_align_t; } // Default traits for the ConcurrentQueue. To change some of the // traits without re-implementing all of them, inherit from this // struct and shadow the declarations you wish to be different; // since the traits are used as a template type parameter, the // shadowed declarations will be used where defined, and the defaults // otherwise. struct ConcurrentQueueDefaultTraits { // General-purpose size type. std::size_t is strongly recommended. typedef std::size_t size_t; // The type used for the enqueue and dequeue indices. Must be at least as // large as size_t. Should be significantly larger than the number of elements // you expect to hold at once, especially if you have a high turnover rate; // for example, on 32-bit x86, if you expect to have over a hundred million // elements or pump several million elements through your queue in a very // short space of time, using a 32-bit type *may* trigger a race condition. // A 64-bit int type is recommended in that case, and in practice will // prevent a race condition no matter the usage of the queue. Note that // whether the queue is lock-free with a 64-int type depends on the whether // std::atomic is lock-free, which is platform-specific. typedef std::size_t index_t; // Internally, all elements are enqueued and dequeued from multi-element // blocks; this is the smallest controllable unit. If you expect few elements // but many producers, a smaller block size should be favoured. For few producers // and/or many elements, a larger block size is preferred. A sane default // is provided. Must be a power of 2. static const size_t BLOCK_SIZE = 32; // For explicit producers (i.e. when using a producer token), the block is // checked for being empty by iterating through a list of flags, one per element. // For large block sizes, this is too inefficient, and switching to an atomic // counter-based approach is faster. The switch is made for block sizes strictly // larger than this threshold. static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 32; // How many full blocks can be expected for a single explicit producer? This should // reflect that number's maximum for optimal performance. Must be a power of 2. static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 32; // How many full blocks can be expected for a single implicit producer? This should // reflect that number's maximum for optimal performance. Must be a power of 2. static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 32; // The initial size of the hash table mapping thread IDs to implicit producers. // Note that the hash is resized every time it becomes half full. // Must be a power of two, and either 0 or at least 1. If 0, implicit production // (using the enqueue methods without an explicit producer token) is disabled. static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 32; // Controls the number of items that an explicit consumer (i.e. one with a token) // must consume before it causes all consumers to rotate and move on to the next // internal queue. static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256; // The maximum number of elements (inclusive) that can be enqueued to a sub-queue. // Enqueue operations that would cause this limit to be surpassed will fail. Note // that this limit is enforced at the block level (for performance reasons), i.e. // it's rounded up to the nearest block size. static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max::value; #ifndef MCDBGQ_USE_RELACY // Memory allocation can be customized if needed. // malloc should return nullptr on failure, and handle alignment like std::malloc. #if defined(malloc) || defined(free) // Gah, this is 2015, stop defining macros that break standard code already! // Work around malloc/free being special macros: static inline void* WORKAROUND_malloc(size_t size) { return malloc(size); } static inline void WORKAROUND_free(void* ptr) { return free(ptr); } static inline void* (malloc)(size_t size) { return WORKAROUND_malloc(size); } static inline void (free)(void* ptr) { return WORKAROUND_free(ptr); } #else static inline void* malloc(size_t size) { return std::malloc(size); } static inline void free(void* ptr) { return std::free(ptr); } #endif #else // Debug versions when running under the Relacy race detector (ignore // these in user code) static inline void* malloc(size_t size) { return rl::rl_malloc(size, $); } static inline void free(void* ptr) { return rl::rl_free(ptr, $); } #endif }; // When producing or consuming many elements, the most efficient way is to: // 1) Use one of the bulk-operation methods of the queue with a token // 2) Failing that, use the bulk-operation methods without a token // 3) Failing that, create a token and use that with the single-item methods // 4) Failing that, use the single-parameter methods of the queue // Having said that, don't create tokens willy-nilly -- ideally there should be // a maximum of one token per thread (of each kind). struct ProducerToken; struct ConsumerToken; template class ConcurrentQueue; template class BlockingConcurrentQueue; class ConcurrentQueueTests; namespace details { struct ConcurrentQueueProducerTypelessBase { ConcurrentQueueProducerTypelessBase* next; std::atomic inactive; ProducerToken* token; ConcurrentQueueProducerTypelessBase() : next(nullptr), inactive(false), token(nullptr) { } }; template struct _hash_32_or_64 { static inline std::uint32_t hash(std::uint32_t h) { // MurmurHash3 finalizer -- see https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp // Since the thread ID is already unique, all we really want to do is propagate that // uniqueness evenly across all the bits, so that we can use a subset of the bits while // reducing collisions significantly h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; return h ^ (h >> 16); } }; template<> struct _hash_32_or_64<1> { static inline std::uint64_t hash(std::uint64_t h) { h ^= h >> 33; h *= 0xff51afd7ed558ccd; h ^= h >> 33; h *= 0xc4ceb9fe1a85ec53; return h ^ (h >> 33); } }; template struct hash_32_or_64 : public _hash_32_or_64<(size > 4)> { }; static inline size_t hash_thread_id(thread_id_t id) { static_assert(sizeof(thread_id_t) <= 8, "Expected a platform where thread IDs are at most 64-bit values"); return static_cast(hash_32_or_64::thread_id_hash_t)>::hash( thread_id_converter::prehash(id))); } template static inline bool circular_less_than(T a, T b) { #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4554) #endif static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "circular_less_than is intended to be used only with unsigned integer types"); return static_cast(a - b) > static_cast(static_cast(1) << static_cast(sizeof(T) * CHAR_BIT - 1)); #ifdef _MSC_VER #pragma warning(pop) #endif } template static inline char* align_for(char* ptr) { const std::size_t alignment = std::alignment_of::value; return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment; } template static inline T ceil_to_pow_2(T x) { static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "ceil_to_pow_2 is intended to be used only with unsigned integer types"); // Adapted from http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 --x; x |= x >> 1; x |= x >> 2; x |= x >> 4; for (std::size_t i = 1; i < sizeof(T); i <<= 1) { x |= x >> (i << 3); } ++x; return x; } template static inline void swap_relaxed(std::atomic& left, std::atomic& right) { T temp = std::move(left.load(std::memory_order_relaxed)); left.store(std::move(right.load(std::memory_order_relaxed)), std::memory_order_relaxed); right.store(std::move(temp), std::memory_order_relaxed); } template static inline T const& nomove(T const& x) { return x; } template struct nomove_if { template static inline T const& eval(T const& x) { return x; } }; template<> struct nomove_if { template static inline auto eval(U&& x) -> decltype(std::forward(x)) { return std::forward(x); } }; template static inline auto deref_noexcept(It& it) MOODYCAMEL_NOEXCEPT -> decltype(*it) { return *it; } #if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) template struct is_trivially_destructible : std::is_trivially_destructible { }; #else template struct is_trivially_destructible : std::has_trivial_destructor { }; #endif #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED #ifdef MCDBGQ_USE_RELACY typedef RelacyThreadExitListener ThreadExitListener; typedef RelacyThreadExitNotifier ThreadExitNotifier; #else struct ThreadExitListener { typedef void (*callback_t)(void*); callback_t callback; void* userData; ThreadExitListener* next; // reserved for use by the ThreadExitNotifier }; class ThreadExitNotifier { public: static void subscribe(ThreadExitListener* listener) { auto& tlsInst = instance(); listener->next = tlsInst.tail; tlsInst.tail = listener; } static void unsubscribe(ThreadExitListener* listener) { auto& tlsInst = instance(); ThreadExitListener** prev = &tlsInst.tail; for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) { if (ptr == listener) { *prev = ptr->next; break; } prev = &ptr->next; } } private: ThreadExitNotifier() : tail(nullptr) { } ThreadExitNotifier(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; ThreadExitNotifier& operator=(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; ~ThreadExitNotifier() { // This thread is about to exit, let everyone know! assert(this == &instance() && "If this assert fails, you likely have a buggy compiler! Change the preprocessor conditions such that MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is no longer defined."); for (auto ptr = tail; ptr != nullptr; ptr = ptr->next) { ptr->callback(ptr->userData); } } // Thread-local static inline ThreadExitNotifier& instance() { static thread_local ThreadExitNotifier notifier; return notifier; } private: ThreadExitListener* tail; }; #endif #endif template struct static_is_lock_free_num { enum { value = 0 }; }; template<> struct static_is_lock_free_num { enum { value = ATOMIC_CHAR_LOCK_FREE }; }; template<> struct static_is_lock_free_num { enum { value = ATOMIC_SHORT_LOCK_FREE }; }; template<> struct static_is_lock_free_num { enum { value = ATOMIC_INT_LOCK_FREE }; }; template<> struct static_is_lock_free_num { enum { value = ATOMIC_LONG_LOCK_FREE }; }; template<> struct static_is_lock_free_num { enum { value = ATOMIC_LLONG_LOCK_FREE }; }; template struct static_is_lock_free : static_is_lock_free_num::type> { }; template<> struct static_is_lock_free { enum { value = ATOMIC_BOOL_LOCK_FREE }; }; template struct static_is_lock_free { enum { value = ATOMIC_POINTER_LOCK_FREE }; }; } struct ProducerToken { template explicit ProducerToken(ConcurrentQueue& queue); template explicit ProducerToken(BlockingConcurrentQueue& queue); ProducerToken(ProducerToken&& other) MOODYCAMEL_NOEXCEPT : producer(other.producer) { other.producer = nullptr; if (producer != nullptr) { producer->token = this; } } inline ProducerToken& operator=(ProducerToken&& other) MOODYCAMEL_NOEXCEPT { swap(other); return *this; } void swap(ProducerToken& other) MOODYCAMEL_NOEXCEPT { std::swap(producer, other.producer); if (producer != nullptr) { producer->token = this; } if (other.producer != nullptr) { other.producer->token = &other; } } // A token is always valid unless: // 1) Memory allocation failed during construction // 2) It was moved via the move constructor // (Note: assignment does a swap, leaving both potentially valid) // 3) The associated queue was destroyed // Note that if valid() returns true, that only indicates // that the token is valid for use with a specific queue, // but not which one; that's up to the user to track. inline bool valid() const { return producer != nullptr; } ~ProducerToken() { if (producer != nullptr) { producer->token = nullptr; producer->inactive.store(true, std::memory_order_release); } } // Disable copying and assignment ProducerToken(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; ProducerToken& operator=(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; private: template friend class ConcurrentQueue; friend class ConcurrentQueueTests; protected: details::ConcurrentQueueProducerTypelessBase* producer; }; struct ConsumerToken { template explicit ConsumerToken(ConcurrentQueue& q); template explicit ConsumerToken(BlockingConcurrentQueue& q); ConsumerToken(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT : initialOffset(other.initialOffset), lastKnownGlobalOffset(other.lastKnownGlobalOffset), itemsConsumedFromCurrent(other.itemsConsumedFromCurrent), currentProducer(other.currentProducer), desiredProducer(other.desiredProducer) { } inline ConsumerToken& operator=(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT { swap(other); return *this; } void swap(ConsumerToken& other) MOODYCAMEL_NOEXCEPT { std::swap(initialOffset, other.initialOffset); std::swap(lastKnownGlobalOffset, other.lastKnownGlobalOffset); std::swap(itemsConsumedFromCurrent, other.itemsConsumedFromCurrent); std::swap(currentProducer, other.currentProducer); std::swap(desiredProducer, other.desiredProducer); } // Disable copying and assignment ConsumerToken(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; ConsumerToken& operator=(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; private: template friend class ConcurrentQueue; friend class ConcurrentQueueTests; private: // but shared with ConcurrentQueue std::uint32_t initialOffset; std::uint32_t lastKnownGlobalOffset; std::uint32_t itemsConsumedFromCurrent; details::ConcurrentQueueProducerTypelessBase* currentProducer; details::ConcurrentQueueProducerTypelessBase* desiredProducer; }; // Need to forward-declare this swap because it's in a namespace. // See http://stackoverflow.com/questions/4492062/why-does-a-c-friend-class-need-a-forward-declaration-only-in-other-namespaces template inline void swap(typename ConcurrentQueue::ImplicitProducerKVP& a, typename ConcurrentQueue::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT; template class ConcurrentQueue { public: typedef ::moodycamel::ProducerToken producer_token_t; typedef ::moodycamel::ConsumerToken consumer_token_t; typedef typename Traits::index_t index_t; typedef typename Traits::size_t size_t; static const size_t BLOCK_SIZE = static_cast(Traits::BLOCK_SIZE); static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = static_cast(Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD); static const size_t EXPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::EXPLICIT_INITIAL_INDEX_SIZE); static const size_t IMPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::IMPLICIT_INITIAL_INDEX_SIZE); static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = static_cast(Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE); static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = static_cast(Traits::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE); #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4307) // + integral constant overflow (that's what the ternary expression is for!) #pragma warning(disable: 4309) // static_cast: Truncation of constant value #endif static const size_t MAX_SUBQUEUE_SIZE = (details::const_numeric_max::value - static_cast(Traits::MAX_SUBQUEUE_SIZE) < BLOCK_SIZE) ? details::const_numeric_max::value : ((static_cast(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE - 1)) / BLOCK_SIZE * BLOCK_SIZE); #ifdef _MSC_VER #pragma warning(pop) #endif static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::size_t must be an unsigned integral type"); static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::index_t must be an unsigned integral type"); static_assert(sizeof(index_t) >= sizeof(size_t), "Traits::index_t must be at least as wide as Traits::size_t"); static_assert((BLOCK_SIZE > 1) && !(BLOCK_SIZE & (BLOCK_SIZE - 1)), "Traits::BLOCK_SIZE must be a power of 2 (and at least 2)"); static_assert((EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD > 1) && !(EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD & (EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD - 1)), "Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD must be a power of 2 (and greater than 1)"); static_assert((EXPLICIT_INITIAL_INDEX_SIZE > 1) && !(EXPLICIT_INITIAL_INDEX_SIZE & (EXPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::EXPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); static_assert((IMPLICIT_INITIAL_INDEX_SIZE > 1) && !(IMPLICIT_INITIAL_INDEX_SIZE & (IMPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::IMPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); static_assert((INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) || !(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE & (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE - 1)), "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be a power of 2"); static_assert(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0 || INITIAL_IMPLICIT_PRODUCER_HASH_SIZE >= 1, "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be at least 1 (or 0 to disable implicit enqueueing)"); public: // Creates a queue with at least `capacity` element slots; note that the // actual number of elements that can be inserted without additional memory // allocation depends on the number of producers and the block size (e.g. if // the block size is equal to `capacity`, only a single block will be allocated // up-front, which means only a single producer will be able to enqueue elements // without an extra allocation -- blocks aren't shared between producers). // This method is not thread safe -- it is up to the user to ensure that the // queue is fully constructed before it starts being used by other threads (this // includes making the memory effects of construction visible, possibly with a // memory barrier). explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE) : producerListTail(nullptr), producerCount(0), initialBlockPoolIndex(0), nextExplicitConsumerId(0), globalExplicitConsumerOffset(0) { implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); populate_initial_implicit_producer_hash(); populate_initial_block_list(capacity / BLOCK_SIZE + ((capacity & (BLOCK_SIZE - 1)) == 0 ? 0 : 1)); #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG // Track all the producers using a fully-resolved typed list for // each kind; this makes it possible to debug them starting from // the root queue object (otherwise wacky casts are needed that // don't compile in the debugger's expression evaluator). explicitProducers.store(nullptr, std::memory_order_relaxed); implicitProducers.store(nullptr, std::memory_order_relaxed); #endif } // Computes the correct amount of pre-allocated blocks for you based // on the minimum number of elements you want available at any given // time, and the maximum concurrent number of each type of producer. ConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers) : producerListTail(nullptr), producerCount(0), initialBlockPoolIndex(0), nextExplicitConsumerId(0), globalExplicitConsumerOffset(0) { implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); populate_initial_implicit_producer_hash(); size_t blocks = (((minCapacity + BLOCK_SIZE - 1) / BLOCK_SIZE) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers + maxImplicitProducers); populate_initial_block_list(blocks); #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG explicitProducers.store(nullptr, std::memory_order_relaxed); implicitProducers.store(nullptr, std::memory_order_relaxed); #endif } // Note: The queue should not be accessed concurrently while it's // being deleted. It's up to the user to synchronize this. // This method is not thread safe. ~ConcurrentQueue() { // Destroy producers auto ptr = producerListTail.load(std::memory_order_relaxed); while (ptr != nullptr) { auto next = ptr->next_prod(); if (ptr->token != nullptr) { ptr->token->producer = nullptr; } destroy(ptr); ptr = next; } // Destroy implicit producer hash tables if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE != 0) { auto hash = implicitProducerHash.load(std::memory_order_relaxed); while (hash != nullptr) { auto prev = hash->prev; if (prev != nullptr) { // The last hash is part of this object and was not allocated dynamically for (size_t i = 0; i != hash->capacity; ++i) { hash->entries[i].~ImplicitProducerKVP(); } hash->~ImplicitProducerHash(); (Traits::free)(hash); } hash = prev; } } // Destroy global free list auto block = freeList.head_unsafe(); while (block != nullptr) { auto next = block->freeListNext.load(std::memory_order_relaxed); if (block->dynamicallyAllocated) { destroy(block); } block = next; } // Destroy initial free list destroy_array(initialBlockPool, initialBlockPoolSize); } // Disable copying and copy assignment ConcurrentQueue(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; ConcurrentQueue& operator=(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; // Moving is supported, but note that it is *not* a thread-safe operation. // Nobody can use the queue while it's being moved, and the memory effects // of that move must be propagated to other threads before they can use it. // Note: When a queue is moved, its tokens are still valid but can only be // used with the destination queue (i.e. semantically they are moved along // with the queue itself). ConcurrentQueue(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT : producerListTail(other.producerListTail.load(std::memory_order_relaxed)), producerCount(other.producerCount.load(std::memory_order_relaxed)), initialBlockPoolIndex(other.initialBlockPoolIndex.load(std::memory_order_relaxed)), initialBlockPool(other.initialBlockPool), initialBlockPoolSize(other.initialBlockPoolSize), freeList(std::move(other.freeList)), nextExplicitConsumerId(other.nextExplicitConsumerId.load(std::memory_order_relaxed)), globalExplicitConsumerOffset(other.globalExplicitConsumerOffset.load(std::memory_order_relaxed)) { // Move the other one into this, and leave the other one as an empty queue implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); populate_initial_implicit_producer_hash(); swap_implicit_producer_hashes(other); other.producerListTail.store(nullptr, std::memory_order_relaxed); other.producerCount.store(0, std::memory_order_relaxed); other.nextExplicitConsumerId.store(0, std::memory_order_relaxed); other.globalExplicitConsumerOffset.store(0, std::memory_order_relaxed); #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG explicitProducers.store(other.explicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); other.explicitProducers.store(nullptr, std::memory_order_relaxed); implicitProducers.store(other.implicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); other.implicitProducers.store(nullptr, std::memory_order_relaxed); #endif other.initialBlockPoolIndex.store(0, std::memory_order_relaxed); other.initialBlockPoolSize = 0; other.initialBlockPool = nullptr; reown_producers(); } inline ConcurrentQueue& operator=(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT { return swap_internal(other); } // Swaps this queue's state with the other's. Not thread-safe. // Swapping two queues does not invalidate their tokens, however // the tokens that were created for one queue must be used with // only the swapped queue (i.e. the tokens are tied to the // queue's movable state, not the object itself). inline void swap(ConcurrentQueue& other) MOODYCAMEL_NOEXCEPT { swap_internal(other); } private: ConcurrentQueue& swap_internal(ConcurrentQueue& other) { if (this == &other) { return *this; } details::swap_relaxed(producerListTail, other.producerListTail); details::swap_relaxed(producerCount, other.producerCount); details::swap_relaxed(initialBlockPoolIndex, other.initialBlockPoolIndex); std::swap(initialBlockPool, other.initialBlockPool); std::swap(initialBlockPoolSize, other.initialBlockPoolSize); freeList.swap(other.freeList); details::swap_relaxed(nextExplicitConsumerId, other.nextExplicitConsumerId); details::swap_relaxed(globalExplicitConsumerOffset, other.globalExplicitConsumerOffset); swap_implicit_producer_hashes(other); reown_producers(); other.reown_producers(); #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG details::swap_relaxed(explicitProducers, other.explicitProducers); details::swap_relaxed(implicitProducers, other.implicitProducers); #endif return *this; } public: // Enqueues a single item (by copying it). // Allocates memory if required. Only fails if memory allocation fails (or implicit // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(T const& item) { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; return inner_enqueue(item); } // Enqueues a single item (by moving it, if possible). // Allocates memory if required. Only fails if memory allocation fails (or implicit // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(T&& item) { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; return inner_enqueue(std::move(item)); } // Enqueues a single item (by copying it) using an explicit producer token. // Allocates memory if required. Only fails if memory allocation fails (or // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(producer_token_t const& token, T const& item) { return inner_enqueue(token, item); } // Enqueues a single item (by moving it, if possible) using an explicit producer token. // Allocates memory if required. Only fails if memory allocation fails (or // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Thread-safe. inline bool enqueue(producer_token_t const& token, T&& item) { return inner_enqueue(token, std::move(item)); } // Enqueues several items. // Allocates memory if required. Only fails if memory allocation fails (or // implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE // is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Note: Use std::make_move_iterator if the elements should be moved instead of copied. // Thread-safe. template bool enqueue_bulk(It itemFirst, size_t count) { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; return inner_enqueue_bulk(itemFirst, count); } // Enqueues several items using an explicit producer token. // Allocates memory if required. Only fails if memory allocation fails // (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). // Note: Use std::make_move_iterator if the elements should be moved // instead of copied. // Thread-safe. template bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) { return inner_enqueue_bulk(token, itemFirst, count); } // Enqueues a single item (by copying it). // Does not allocate memory. Fails if not enough room to enqueue (or implicit // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE // is 0). // Thread-safe. inline bool try_enqueue(T const& item) { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; return inner_enqueue(item); } // Enqueues a single item (by moving it, if possible). // Does not allocate memory (except for one-time implicit producer). // Fails if not enough room to enqueue (or implicit production is // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0). // Thread-safe. inline bool try_enqueue(T&& item) { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; return inner_enqueue(std::move(item)); } // Enqueues a single item (by copying it) using an explicit producer token. // Does not allocate memory. Fails if not enough room to enqueue. // Thread-safe. inline bool try_enqueue(producer_token_t const& token, T const& item) { return inner_enqueue(token, item); } // Enqueues a single item (by moving it, if possible) using an explicit producer token. // Does not allocate memory. Fails if not enough room to enqueue. // Thread-safe. inline bool try_enqueue(producer_token_t const& token, T&& item) { return inner_enqueue(token, std::move(item)); } // Enqueues several items. // Does not allocate memory (except for one-time implicit producer). // Fails if not enough room to enqueue (or implicit production is // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0). // Note: Use std::make_move_iterator if the elements should be moved // instead of copied. // Thread-safe. template bool try_enqueue_bulk(It itemFirst, size_t count) { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; return inner_enqueue_bulk(itemFirst, count); } // Enqueues several items using an explicit producer token. // Does not allocate memory. Fails if not enough room to enqueue. // Note: Use std::make_move_iterator if the elements should be moved // instead of copied. // Thread-safe. template bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) { return inner_enqueue_bulk(token, itemFirst, count); } // Attempts to dequeue from the queue. // Returns false if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template bool try_dequeue(U& item) { // Instead of simply trying each producer in turn (which could cause needless contention on the first // producer), we score them heuristically. size_t nonEmptyCount = 0; ProducerBase* best = nullptr; size_t bestSize = 0; for (auto ptr = producerListTail.load(std::memory_order_acquire); nonEmptyCount < 3 && ptr != nullptr; ptr = ptr->next_prod()) { auto size = ptr->size_approx(); if (size > 0) { if (size > bestSize) { bestSize = size; best = ptr; } ++nonEmptyCount; } } // If there was at least one non-empty queue but it appears empty at the time // we try to dequeue from it, we need to make sure every queue's been tried if (nonEmptyCount > 0) { if ((details::likely)(best->dequeue(item))) { return true; } for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { if (ptr != best && ptr->dequeue(item)) { return true; } } } return false; } // Attempts to dequeue from the queue. // Returns false if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // This differs from the try_dequeue(item) method in that this one does // not attempt to reduce contention by interleaving the order that producer // streams are dequeued from. So, using this method can reduce overall throughput // under contention, but will give more predictable results in single-threaded // consumer scenarios. This is mostly only useful for internal unit tests. // Never allocates. Thread-safe. template bool try_dequeue_non_interleaved(U& item) { for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { if (ptr->dequeue(item)) { return true; } } return false; } // Attempts to dequeue from the queue using an explicit consumer token. // Returns false if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template bool try_dequeue(consumer_token_t& token, U& item) { // The idea is roughly as follows: // Every 256 items from one producer, make everyone rotate (increase the global offset) -> this means the highest efficiency consumer dictates the rotation speed of everyone else, more or less // If you see that the global offset has changed, you must reset your consumption counter and move to your designated place // If there's no items where you're supposed to be, keep moving until you find a producer with some items // If the global offset has not changed but you've run out of items to consume, move over from your current position until you find an producer with something in it if (token.desiredProducer == nullptr || token.lastKnownGlobalOffset != globalExplicitConsumerOffset.load(std::memory_order_relaxed)) { if (!update_current_producer_after_rotation(token)) { return false; } } // If there was at least one non-empty queue but it appears empty at the time // we try to dequeue from it, we need to make sure every queue's been tried if (static_cast(token.currentProducer)->dequeue(item)) { if (++token.itemsConsumedFromCurrent == EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE) { globalExplicitConsumerOffset.fetch_add(1, std::memory_order_relaxed); } return true; } auto tail = producerListTail.load(std::memory_order_acquire); auto ptr = static_cast(token.currentProducer)->next_prod(); if (ptr == nullptr) { ptr = tail; } while (ptr != static_cast(token.currentProducer)) { if (ptr->dequeue(item)) { token.currentProducer = ptr; token.itemsConsumedFromCurrent = 1; return true; } ptr = ptr->next_prod(); if (ptr == nullptr) { ptr = tail; } } return false; } // Attempts to dequeue several elements from the queue. // Returns the number of items actually dequeued. // Returns 0 if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template size_t try_dequeue_bulk(It itemFirst, size_t max) { size_t count = 0; for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { count += ptr->dequeue_bulk(itemFirst, max - count); if (count == max) { break; } } return count; } // Attempts to dequeue several elements from the queue using an explicit consumer token. // Returns the number of items actually dequeued. // Returns 0 if all producer streams appeared empty at the time they // were checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max) { if (token.desiredProducer == nullptr || token.lastKnownGlobalOffset != globalExplicitConsumerOffset.load(std::memory_order_relaxed)) { if (!update_current_producer_after_rotation(token)) { return 0; } } size_t count = static_cast(token.currentProducer)->dequeue_bulk(itemFirst, max); if (count == max) { if ((token.itemsConsumedFromCurrent += static_cast(max)) >= EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE) { globalExplicitConsumerOffset.fetch_add(1, std::memory_order_relaxed); } return max; } token.itemsConsumedFromCurrent += static_cast(count); max -= count; auto tail = producerListTail.load(std::memory_order_acquire); auto ptr = static_cast(token.currentProducer)->next_prod(); if (ptr == nullptr) { ptr = tail; } while (ptr != static_cast(token.currentProducer)) { auto dequeued = ptr->dequeue_bulk(itemFirst, max); count += dequeued; if (dequeued != 0) { token.currentProducer = ptr; token.itemsConsumedFromCurrent = static_cast(dequeued); } if (dequeued == max) { break; } max -= dequeued; ptr = ptr->next_prod(); if (ptr == nullptr) { ptr = tail; } } return count; } // Attempts to dequeue from a specific producer's inner queue. // If you happen to know which producer you want to dequeue from, this // is significantly faster than using the general-case try_dequeue methods. // Returns false if the producer's queue appeared empty at the time it // was checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template inline bool try_dequeue_from_producer(producer_token_t const& producer, U& item) { return static_cast(producer.producer)->dequeue(item); } // Attempts to dequeue several elements from a specific producer's inner queue. // Returns the number of items actually dequeued. // If you happen to know which producer you want to dequeue from, this // is significantly faster than using the general-case try_dequeue methods. // Returns 0 if the producer's queue appeared empty at the time it // was checked (so, the queue is likely but not guaranteed to be empty). // Never allocates. Thread-safe. template inline size_t try_dequeue_bulk_from_producer(producer_token_t const& producer, It itemFirst, size_t max) { return static_cast(producer.producer)->dequeue_bulk(itemFirst, max); } // Returns an estimate of the total number of elements currently in the queue. This // estimate is only accurate if the queue has completely stabilized before it is called // (i.e. all enqueue and dequeue operations have completed and their memory effects are // visible on the calling thread, and no further operations start while this method is // being called). // Thread-safe. size_t size_approx() const { size_t size = 0; for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { size += ptr->size_approx(); } return size; } // Returns true if the underlying atomic variables used by // the queue are lock-free (they should be on most platforms). // Thread-safe. static bool is_lock_free() { return details::static_is_lock_free::value == 2 && details::static_is_lock_free::value == 2 && details::static_is_lock_free::value == 2 && details::static_is_lock_free::value == 2 && details::static_is_lock_free::value == 2 && details::static_is_lock_free::thread_id_numeric_size_t>::value == 2; } private: friend struct ProducerToken; friend struct ConsumerToken; struct ExplicitProducer; friend struct ExplicitProducer; struct ImplicitProducer; friend struct ImplicitProducer; friend class ConcurrentQueueTests; enum AllocationMode { CanAlloc, CannotAlloc }; /////////////////////////////// // Queue methods /////////////////////////////// template inline bool inner_enqueue(producer_token_t const& token, U&& element) { return static_cast(token.producer)->ConcurrentQueue::ExplicitProducer::template enqueue(std::forward(element)); } template inline bool inner_enqueue(U&& element) { auto producer = get_or_add_implicit_producer(); return producer == nullptr ? false : producer->ConcurrentQueue::ImplicitProducer::template enqueue(std::forward(element)); } template inline bool inner_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count) { return static_cast(token.producer)->ConcurrentQueue::ExplicitProducer::template enqueue_bulk(itemFirst, count); } template inline bool inner_enqueue_bulk(It itemFirst, size_t count) { auto producer = get_or_add_implicit_producer(); return producer == nullptr ? false : producer->ConcurrentQueue::ImplicitProducer::template enqueue_bulk(itemFirst, count); } inline bool update_current_producer_after_rotation(consumer_token_t& token) { // Ah, there's been a rotation, figure out where we should be! auto tail = producerListTail.load(std::memory_order_acquire); if (token.desiredProducer == nullptr && tail == nullptr) { return false; } auto prodCount = producerCount.load(std::memory_order_relaxed); auto globalOffset = globalExplicitConsumerOffset.load(std::memory_order_relaxed); if ((details::unlikely)(token.desiredProducer == nullptr)) { // Aha, first time we're dequeueing anything. // Figure out our local position // Note: offset is from start, not end, but we're traversing from end -- subtract from count first std::uint32_t offset = prodCount - 1 - (token.initialOffset % prodCount); token.desiredProducer = tail; for (std::uint32_t i = 0; i != offset; ++i) { token.desiredProducer = static_cast(token.desiredProducer)->next_prod(); if (token.desiredProducer == nullptr) { token.desiredProducer = tail; } } } std::uint32_t delta = globalOffset - token.lastKnownGlobalOffset; if (delta >= prodCount) { delta = delta % prodCount; } for (std::uint32_t i = 0; i != delta; ++i) { token.desiredProducer = static_cast(token.desiredProducer)->next_prod(); if (token.desiredProducer == nullptr) { token.desiredProducer = tail; } } token.lastKnownGlobalOffset = globalOffset; token.currentProducer = token.desiredProducer; token.itemsConsumedFromCurrent = 0; return true; } /////////////////////////// // Free list /////////////////////////// template struct FreeListNode { FreeListNode() : freeListRefs(0), freeListNext(nullptr) { } std::atomic freeListRefs; std::atomic freeListNext; }; // A simple CAS-based lock-free free list. Not the fastest thing in the world under heavy contention, but // simple and correct (assuming nodes are never freed until after the free list is destroyed), and fairly // speedy under low contention. template // N must inherit FreeListNode or have the same fields (and initialization of them) struct FreeList { FreeList() : freeListHead(nullptr) { } FreeList(FreeList&& other) : freeListHead(other.freeListHead.load(std::memory_order_relaxed)) { other.freeListHead.store(nullptr, std::memory_order_relaxed); } void swap(FreeList& other) { details::swap_relaxed(freeListHead, other.freeListHead); } FreeList(FreeList const&) MOODYCAMEL_DELETE_FUNCTION; FreeList& operator=(FreeList const&) MOODYCAMEL_DELETE_FUNCTION; inline void add(N* node) { #if MCDBGQ_NOLOCKFREE_FREELIST debug::DebugLock lock(mutex); #endif // We know that the should-be-on-freelist bit is 0 at this point, so it's safe to // set it using a fetch_add if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST, std::memory_order_acq_rel) == 0) { // Oh look! We were the last ones referencing this node, and we know // we want to add it to the free list, so let's do it! add_knowing_refcount_is_zero(node); } } inline N* try_get() { #if MCDBGQ_NOLOCKFREE_FREELIST debug::DebugLock lock(mutex); #endif auto head = freeListHead.load(std::memory_order_acquire); while (head != nullptr) { auto prevHead = head; auto refs = head->freeListRefs.load(std::memory_order_relaxed); if ((refs & REFS_MASK) == 0 || !head->freeListRefs.compare_exchange_strong(refs, refs + 1, std::memory_order_acquire, std::memory_order_relaxed)) { head = freeListHead.load(std::memory_order_acquire); continue; } // Good, reference count has been incremented (it wasn't at zero), which means we can read the // next and not worry about it changing between now and the time we do the CAS auto next = head->freeListNext.load(std::memory_order_relaxed); if (freeListHead.compare_exchange_strong(head, next, std::memory_order_acquire, std::memory_order_relaxed)) { // Yay, got the node. This means it was on the list, which means shouldBeOnFreeList must be false no // matter the refcount (because nobody else knows it's been taken off yet, it can't have been put back on). assert((head->freeListRefs.load(std::memory_order_relaxed) & SHOULD_BE_ON_FREELIST) == 0); // Decrease refcount twice, once for our ref, and once for the list's ref head->freeListRefs.fetch_sub(2, std::memory_order_release); return head; } // OK, the head must have changed on us, but we still need to decrease the refcount we increased. // Note that we don't need to release any memory effects, but we do need to ensure that the reference // count decrement happens-after the CAS on the head. refs = prevHead->freeListRefs.fetch_sub(1, std::memory_order_acq_rel); if (refs == SHOULD_BE_ON_FREELIST + 1) { add_knowing_refcount_is_zero(prevHead); } } return nullptr; } // Useful for traversing the list when there's no contention (e.g. to destroy remaining nodes) N* head_unsafe() const { return freeListHead.load(std::memory_order_relaxed); } private: inline void add_knowing_refcount_is_zero(N* node) { // Since the refcount is zero, and nobody can increase it once it's zero (except us, and we run // only one copy of this method per node at a time, i.e. the single thread case), then we know // we can safely change the next pointer of the node; however, once the refcount is back above // zero, then other threads could increase it (happens under heavy contention, when the refcount // goes to zero in between a load and a refcount increment of a node in try_get, then back up to // something non-zero, then the refcount increment is done by the other thread) -- so, if the CAS // to add the node to the actual list fails, decrease the refcount and leave the add operation to // the next thread who puts the refcount back at zero (which could be us, hence the loop). auto head = freeListHead.load(std::memory_order_relaxed); while (true) { node->freeListNext.store(head, std::memory_order_relaxed); node->freeListRefs.store(1, std::memory_order_release); if (!freeListHead.compare_exchange_strong(head, node, std::memory_order_release, std::memory_order_relaxed)) { // Hmm, the add failed, but we can only try again when the refcount goes back to zero if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST - 1, std::memory_order_release) == 1) { continue; } } return; } } private: // Implemented like a stack, but where node order doesn't matter (nodes are inserted out of order under contention) std::atomic freeListHead; static const std::uint32_t REFS_MASK = 0x7FFFFFFF; static const std::uint32_t SHOULD_BE_ON_FREELIST = 0x80000000; #if MCDBGQ_NOLOCKFREE_FREELIST debug::DebugMutex mutex; #endif }; /////////////////////////// // Block /////////////////////////// enum InnerQueueContext { implicit_context = 0, explicit_context = 1 }; struct Block { Block() : next(nullptr), elementsCompletelyDequeued(0), freeListRefs(0), freeListNext(nullptr), shouldBeOnFreeList(false), dynamicallyAllocated(true) { #if MCDBGQ_TRACKMEM owner = nullptr; #endif } template inline bool is_empty() const { if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { // Check flags for (size_t i = 0; i < BLOCK_SIZE; ++i) { if (!emptyFlags[i].load(std::memory_order_relaxed)) { return false; } } // Aha, empty; make sure we have all other memory effects that happened before the empty flags were set std::atomic_thread_fence(std::memory_order_acquire); return true; } else { // Check counter if (elementsCompletelyDequeued.load(std::memory_order_relaxed) == BLOCK_SIZE) { std::atomic_thread_fence(std::memory_order_acquire); return true; } assert(elementsCompletelyDequeued.load(std::memory_order_relaxed) <= BLOCK_SIZE); return false; } } // Returns true if the block is now empty (does not apply in explicit context) template inline bool set_empty(index_t i) { if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { // Set flag assert(!emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].load(std::memory_order_relaxed)); emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].store(true, std::memory_order_release); return false; } else { // Increment counter auto prevVal = elementsCompletelyDequeued.fetch_add(1, std::memory_order_release); assert(prevVal < BLOCK_SIZE); return prevVal == BLOCK_SIZE - 1; } } // Sets multiple contiguous item statuses to 'empty' (assumes no wrapping and count > 0). // Returns true if the block is now empty (does not apply in explicit context). template inline bool set_many_empty(index_t i, size_t count) { if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { // Set flags std::atomic_thread_fence(std::memory_order_release); i = BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1)) - count + 1; for (size_t j = 0; j != count; ++j) { assert(!emptyFlags[i + j].load(std::memory_order_relaxed)); emptyFlags[i + j].store(true, std::memory_order_relaxed); } return false; } else { // Increment counter auto prevVal = elementsCompletelyDequeued.fetch_add(count, std::memory_order_release); assert(prevVal + count <= BLOCK_SIZE); return prevVal + count == BLOCK_SIZE; } } template inline void set_all_empty() { if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { // Set all flags for (size_t i = 0; i != BLOCK_SIZE; ++i) { emptyFlags[i].store(true, std::memory_order_relaxed); } } else { // Reset counter elementsCompletelyDequeued.store(BLOCK_SIZE, std::memory_order_relaxed); } } template inline void reset_empty() { if (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) { // Reset flags for (size_t i = 0; i != BLOCK_SIZE; ++i) { emptyFlags[i].store(false, std::memory_order_relaxed); } } else { // Reset counter elementsCompletelyDequeued.store(0, std::memory_order_relaxed); } } inline T* operator[](index_t idx) MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); } inline T const* operator[](index_t idx) const MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); } private: // IMPORTANT: This must be the first member in Block, so that if T depends on the alignment of // addresses returned by malloc, that alignment will be preserved. Apparently clang actually // generates code that uses this assumption for AVX instructions in some cases. Ideally, we // should also align Block to the alignment of T in case it's higher than malloc's 16-byte // alignment, but this is hard to do in a cross-platform way. Assert for this case: static_assert(std::alignment_of::value <= std::alignment_of::value, "The queue does not support super-aligned types at this time"); // Additionally, we need the alignment of Block itself to be a multiple of max_align_t since // otherwise the appropriate padding will not be added at the end of Block in order to make // arrays of Blocks all be properly aligned (not just the first one). We use a union to force // this. union { char elements[sizeof(T) * BLOCK_SIZE]; details::max_align_t dummy; }; public: Block* next; std::atomic elementsCompletelyDequeued; std::atomic emptyFlags[BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD ? BLOCK_SIZE : 1]; public: std::atomic freeListRefs; std::atomic freeListNext; std::atomic shouldBeOnFreeList; bool dynamicallyAllocated; // Perhaps a better name for this would be 'isNotPartOfInitialBlockPool' #if MCDBGQ_TRACKMEM void* owner; #endif }; static_assert(std::alignment_of::value >= std::alignment_of::value, "Internal error: Blocks must be at least as aligned as the type they are wrapping"); #if MCDBGQ_TRACKMEM public: struct MemStats; private: #endif /////////////////////////// // Producer base /////////////////////////// struct ProducerBase : public details::ConcurrentQueueProducerTypelessBase { ProducerBase(ConcurrentQueue* parent_, bool isExplicit_) : tailIndex(0), headIndex(0), dequeueOptimisticCount(0), dequeueOvercommit(0), tailBlock(nullptr), isExplicit(isExplicit_), parent(parent_) { } virtual ~ProducerBase() { }; template inline bool dequeue(U& element) { if (isExplicit) { return static_cast(this)->dequeue(element); } else { return static_cast(this)->dequeue(element); } } template inline size_t dequeue_bulk(It& itemFirst, size_t max) { if (isExplicit) { return static_cast(this)->dequeue_bulk(itemFirst, max); } else { return static_cast(this)->dequeue_bulk(itemFirst, max); } } inline ProducerBase* next_prod() const { return static_cast(next); } inline size_t size_approx() const { auto tail = tailIndex.load(std::memory_order_relaxed); auto head = headIndex.load(std::memory_order_relaxed); return details::circular_less_than(head, tail) ? static_cast(tail - head) : 0; } inline index_t getTail() const { return tailIndex.load(std::memory_order_relaxed); } protected: std::atomic tailIndex; // Where to enqueue to next std::atomic headIndex; // Where to dequeue from next std::atomic dequeueOptimisticCount; std::atomic dequeueOvercommit; Block* tailBlock; public: bool isExplicit; ConcurrentQueue* parent; protected: #if MCDBGQ_TRACKMEM friend struct MemStats; #endif }; /////////////////////////// // Explicit queue /////////////////////////// struct ExplicitProducer : public ProducerBase { explicit ExplicitProducer(ConcurrentQueue* parent) : ProducerBase(parent, true), blockIndex(nullptr), pr_blockIndexSlotsUsed(0), pr_blockIndexSize(EXPLICIT_INITIAL_INDEX_SIZE >> 1), pr_blockIndexFront(0), pr_blockIndexEntries(nullptr), pr_blockIndexRaw(nullptr) { size_t poolBasedIndexSize = details::ceil_to_pow_2(parent->initialBlockPoolSize) >> 1; if (poolBasedIndexSize > pr_blockIndexSize) { pr_blockIndexSize = poolBasedIndexSize; } new_block_index(0); // This creates an index with double the number of current entries, i.e. EXPLICIT_INITIAL_INDEX_SIZE } ~ExplicitProducer() { // Destruct any elements not yet dequeued. // Since we're in the destructor, we can assume all elements // are either completely dequeued or completely not (no halfways). if (this->tailBlock != nullptr) { // Note this means there must be a block index too // First find the block that's partially dequeued, if any Block* halfDequeuedBlock = nullptr; if ((this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) != 0) { // The head's not on a block boundary, meaning a block somewhere is partially dequeued // (or the head block is the tail block and was fully dequeued, but the head/tail are still not on a boundary) size_t i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & (pr_blockIndexSize - 1); while (details::circular_less_than(pr_blockIndexEntries[i].base + BLOCK_SIZE, this->headIndex.load(std::memory_order_relaxed))) { i = (i + 1) & (pr_blockIndexSize - 1); } assert(details::circular_less_than(pr_blockIndexEntries[i].base, this->headIndex.load(std::memory_order_relaxed))); halfDequeuedBlock = pr_blockIndexEntries[i].block; } // Start at the head block (note the first line in the loop gives us the head from the tail on the first iteration) auto block = this->tailBlock; do { block = block->next; if (block->ConcurrentQueue::Block::template is_empty()) { continue; } size_t i = 0; // Offset into block if (block == halfDequeuedBlock) { i = static_cast(this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)); } // Walk through all the items in the block; if this is the tail block, we need to stop when we reach the tail index auto lastValidIndex = (this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) == 0 ? BLOCK_SIZE : static_cast(this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)); while (i != BLOCK_SIZE && (block != this->tailBlock || i != lastValidIndex)) { (*block)[i++]->~T(); } } while (block != this->tailBlock); } // Destroy all blocks that we own if (this->tailBlock != nullptr) { auto block = this->tailBlock; do { auto nextBlock = block->next; if (block->dynamicallyAllocated) { destroy(block); } else { this->parent->add_block_to_free_list(block); } block = nextBlock; } while (block != this->tailBlock); } // Destroy the block indices auto header = static_cast(pr_blockIndexRaw); while (header != nullptr) { auto prev = static_cast(header->prev); header->~BlockIndexHeader(); (Traits::free)(header); header = prev; } } template inline bool enqueue(U&& element) { index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed); index_t newTailIndex = 1 + currentTailIndex; if ((currentTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { // We reached the end of a block, start a new one auto startBlock = this->tailBlock; auto originalBlockIndexSlotsUsed = pr_blockIndexSlotsUsed; if (this->tailBlock != nullptr && this->tailBlock->next->ConcurrentQueue::Block::template is_empty()) { // We can re-use the block ahead of us, it's empty! this->tailBlock = this->tailBlock->next; this->tailBlock->ConcurrentQueue::Block::template reset_empty(); // We'll put the block on the block index (guaranteed to be room since we're conceptually removing the // last block from it first -- except instead of removing then adding, we can just overwrite). // Note that there must be a valid block index here, since even if allocation failed in the ctor, // it would have been re-attempted when adding the first block to the queue; since there is such // a block, a block index must have been successfully allocated. } else { // Whatever head value we see here is >= the last value we saw here (relatively), // and <= its current value. Since we have the most recent tail, the head must be // <= to it. auto head = this->headIndex.load(std::memory_order_relaxed); assert(!details::circular_less_than(currentTailIndex, head)); if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) { // We can't enqueue in another block because there's not enough leeway -- the // tail could surpass the head by the time the block fills up! (Or we'll exceed // the size limit, if the second part of the condition was true.) return false; } // We're going to need a new block; check that the block index has room if (pr_blockIndexRaw == nullptr || pr_blockIndexSlotsUsed == pr_blockIndexSize) { // Hmm, the circular block index is already full -- we'll need // to allocate a new index. Note pr_blockIndexRaw can only be nullptr if // the initial allocation failed in the constructor. if (allocMode == CannotAlloc || !new_block_index(pr_blockIndexSlotsUsed)) { return false; } } // Insert a new block in the circular linked list auto newBlock = this->parent->ConcurrentQueue::template requisition_block(); if (newBlock == nullptr) { return false; } #if MCDBGQ_TRACKMEM newBlock->owner = this; #endif newBlock->ConcurrentQueue::Block::template reset_empty(); if (this->tailBlock == nullptr) { newBlock->next = newBlock; } else { newBlock->next = this->tailBlock->next; this->tailBlock->next = newBlock; } this->tailBlock = newBlock; ++pr_blockIndexSlotsUsed; } if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { // The constructor may throw. We want the element not to appear in the queue in // that case (without corrupting the queue): MOODYCAMEL_TRY { new ((*this->tailBlock)[currentTailIndex]) T(std::forward(element)); } MOODYCAMEL_CATCH (...) { // Revert change to the current block, but leave the new block available // for next time pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; this->tailBlock = startBlock == nullptr ? this->tailBlock : startBlock; MOODYCAMEL_RETHROW; } } else { (void)startBlock; (void)originalBlockIndexSlotsUsed; } // Add block to block index auto& entry = blockIndex.load(std::memory_order_relaxed)->entries[pr_blockIndexFront]; entry.base = currentTailIndex; entry.block = this->tailBlock; blockIndex.load(std::memory_order_relaxed)->front.store(pr_blockIndexFront, std::memory_order_release); pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1); if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { this->tailIndex.store(newTailIndex, std::memory_order_release); return true; } } // Enqueue new ((*this->tailBlock)[currentTailIndex]) T(std::forward(element)); this->tailIndex.store(newTailIndex, std::memory_order_release); return true; } template bool dequeue(U& element) { auto tail = this->tailIndex.load(std::memory_order_relaxed); auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); if (details::circular_less_than(this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit, tail)) { // Might be something to dequeue, let's give it a try // Note that this if is purely for performance purposes in the common case when the queue is // empty and the values are eventually consistent -- we may enter here spuriously. // Note that whatever the values of overcommit and tail are, they are not going to change (unless we // change them) and must be the same value at this point (inside the if) as when the if condition was // evaluated. // We insert an acquire fence here to synchronize-with the release upon incrementing dequeueOvercommit below. // This ensures that whatever the value we got loaded into overcommit, the load of dequeueOptisticCount in // the fetch_add below will result in a value at least as recent as that (and therefore at least as large). // Note that I believe a compiler (signal) fence here would be sufficient due to the nature of fetch_add (all // read-modify-write operations are guaranteed to work on the latest value in the modification order), but // unfortunately that can't be shown to be correct using only the C++11 standard. // See http://stackoverflow.com/questions/18223161/what-are-the-c11-memory-ordering-guarantees-in-this-corner-case std::atomic_thread_fence(std::memory_order_acquire); // Increment optimistic counter, then check if it went over the boundary auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(1, std::memory_order_relaxed); // Note that since dequeueOvercommit must be <= dequeueOptimisticCount (because dequeueOvercommit is only ever // incremented after dequeueOptimisticCount -- this is enforced in the `else` block below), and since we now // have a version of dequeueOptimisticCount that is at least as recent as overcommit (due to the release upon // incrementing dequeueOvercommit and the acquire above that synchronizes with it), overcommit <= myDequeueCount. // However, we can't assert this since both dequeueOptimisticCount and dequeueOvercommit may (independently) // overflow; in such a case, though, the logic still holds since the difference between the two is maintained. // Note that we reload tail here in case it changed; it will be the same value as before or greater, since // this load is sequenced after (happens after) the earlier load above. This is supported by read-read // coherency (as defined in the standard), explained here: http://en.cppreference.com/w/cpp/atomic/memory_order tail = this->tailIndex.load(std::memory_order_acquire); if ((details::likely)(details::circular_less_than(myDequeueCount - overcommit, tail))) { // Guaranteed to be at least one element to dequeue! // Get the index. Note that since there's guaranteed to be at least one element, this // will never exceed tail. We need to do an acquire-release fence here since it's possible // that whatever condition got us to this point was for an earlier enqueued element (that // we already see the memory effects for), but that by the time we increment somebody else // has incremented it, and we need to see the memory effects for *that* element, which is // in such a case is necessarily visible on the thread that incremented it in the first // place with the more current condition (they must have acquired a tail that is at least // as recent). auto index = this->headIndex.fetch_add(1, std::memory_order_acq_rel); // Determine which block the element is in auto localBlockIndex = blockIndex.load(std::memory_order_acquire); auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire); // We need to be careful here about subtracting and dividing because of index wrap-around. // When an index wraps, we need to preserve the sign of the offset when dividing it by the // block size (in order to get a correct signed block count offset in all cases): auto headBase = localBlockIndex->entries[localBlockIndexHead].base; auto blockBaseIndex = index & ~static_cast(BLOCK_SIZE - 1); auto offset = static_cast(static_cast::type>(blockBaseIndex - headBase) / BLOCK_SIZE); auto block = localBlockIndex->entries[(localBlockIndexHead + offset) & (localBlockIndex->size - 1)].block; // Dequeue auto& el = *((*block)[index]); if (!MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, element = std::move(el))) { // Make sure the element is still fully dequeued and destroyed even if the assignment // throws struct Guard { Block* block; index_t index; ~Guard() { (*block)[index]->~T(); block->ConcurrentQueue::Block::template set_empty(index); } } guard = { block, index }; element = std::move(el); } else { element = std::move(el); el.~T(); block->ConcurrentQueue::Block::template set_empty(index); } return true; } else { // Wasn't anything to dequeue after all; make the effective dequeue count eventually consistent this->dequeueOvercommit.fetch_add(1, std::memory_order_release); // Release so that the fetch_add on dequeueOptimisticCount is guaranteed to happen before this write } } return false; } template bool enqueue_bulk(It itemFirst, size_t count) { // First, we need to make sure we have enough room to enqueue all of the elements; // this means pre-allocating blocks and putting them in the block index (but only if // all the allocations succeeded). index_t startTailIndex = this->tailIndex.load(std::memory_order_relaxed); auto startBlock = this->tailBlock; auto originalBlockIndexFront = pr_blockIndexFront; auto originalBlockIndexSlotsUsed = pr_blockIndexSlotsUsed; Block* firstAllocatedBlock = nullptr; // Figure out how many blocks we'll need to allocate, and do so size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1)); index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); if (blockBaseDiff > 0) { // Allocate as many blocks as possible from ahead while (blockBaseDiff > 0 && this->tailBlock != nullptr && this->tailBlock->next != firstAllocatedBlock && this->tailBlock->next->ConcurrentQueue::Block::template is_empty()) { blockBaseDiff -= static_cast(BLOCK_SIZE); currentTailIndex += static_cast(BLOCK_SIZE); this->tailBlock = this->tailBlock->next; firstAllocatedBlock = firstAllocatedBlock == nullptr ? this->tailBlock : firstAllocatedBlock; auto& entry = blockIndex.load(std::memory_order_relaxed)->entries[pr_blockIndexFront]; entry.base = currentTailIndex; entry.block = this->tailBlock; pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1); } // Now allocate as many blocks as necessary from the block pool while (blockBaseDiff > 0) { blockBaseDiff -= static_cast(BLOCK_SIZE); currentTailIndex += static_cast(BLOCK_SIZE); auto head = this->headIndex.load(std::memory_order_relaxed); assert(!details::circular_less_than(currentTailIndex, head)); bool full = !details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head)); if (pr_blockIndexRaw == nullptr || pr_blockIndexSlotsUsed == pr_blockIndexSize || full) { if (allocMode == CannotAlloc || full || !new_block_index(originalBlockIndexSlotsUsed)) { // Failed to allocate, undo changes (but keep injected blocks) pr_blockIndexFront = originalBlockIndexFront; pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; this->tailBlock = startBlock == nullptr ? firstAllocatedBlock : startBlock; return false; } // pr_blockIndexFront is updated inside new_block_index, so we need to // update our fallback value too (since we keep the new index even if we // later fail) originalBlockIndexFront = originalBlockIndexSlotsUsed; } // Insert a new block in the circular linked list auto newBlock = this->parent->ConcurrentQueue::template requisition_block(); if (newBlock == nullptr) { pr_blockIndexFront = originalBlockIndexFront; pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; this->tailBlock = startBlock == nullptr ? firstAllocatedBlock : startBlock; return false; } #if MCDBGQ_TRACKMEM newBlock->owner = this; #endif newBlock->ConcurrentQueue::Block::template set_all_empty(); if (this->tailBlock == nullptr) { newBlock->next = newBlock; } else { newBlock->next = this->tailBlock->next; this->tailBlock->next = newBlock; } this->tailBlock = newBlock; firstAllocatedBlock = firstAllocatedBlock == nullptr ? this->tailBlock : firstAllocatedBlock; ++pr_blockIndexSlotsUsed; auto& entry = blockIndex.load(std::memory_order_relaxed)->entries[pr_blockIndexFront]; entry.base = currentTailIndex; entry.block = this->tailBlock; pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1); } // Excellent, all allocations succeeded. Reset each block's emptiness before we fill them up, and // publish the new block index front auto block = firstAllocatedBlock; while (true) { block->ConcurrentQueue::Block::template reset_empty(); if (block == this->tailBlock) { break; } block = block->next; } if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) { blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release); } } // Enqueue, one block at a time index_t newTailIndex = startTailIndex + static_cast(count); currentTailIndex = startTailIndex; auto endBlock = this->tailBlock; this->tailBlock = startBlock; assert((startTailIndex & static_cast(BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock != nullptr || count == 0); if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0 && firstAllocatedBlock != nullptr) { this->tailBlock = firstAllocatedBlock; } while (true) { auto stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); if (details::circular_less_than(newTailIndex, stopIndex)) { stopIndex = newTailIndex; } if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) { while (currentTailIndex != stopIndex) { new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++); } } else { MOODYCAMEL_TRY { while (currentTailIndex != stopIndex) { // Must use copy constructor even if move constructor is available // because we may have to revert if there's an exception. // Sorry about the horrible templated next line, but it was the only way // to disable moving *at compile time*, which is important because a type // may only define a (noexcept) move constructor, and so calls to the // cctor will not compile, even if they are in an if branch that will never // be executed new ((*this->tailBlock)[currentTailIndex]) T(details::nomove_if<(bool)!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))>::eval(*itemFirst)); ++currentTailIndex; ++itemFirst; } } MOODYCAMEL_CATCH (...) { // Oh dear, an exception's been thrown -- destroy the elements that // were enqueued so far and revert the entire bulk operation (we'll keep // any allocated blocks in our linked list for later, though). auto constructedStopIndex = currentTailIndex; auto lastBlockEnqueued = this->tailBlock; pr_blockIndexFront = originalBlockIndexFront; pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed; this->tailBlock = startBlock == nullptr ? firstAllocatedBlock : startBlock; if (!details::is_trivially_destructible::value) { auto block = startBlock; if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { block = firstAllocatedBlock; } currentTailIndex = startTailIndex; while (true) { stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); if (details::circular_less_than(constructedStopIndex, stopIndex)) { stopIndex = constructedStopIndex; } while (currentTailIndex != stopIndex) { (*block)[currentTailIndex++]->~T(); } if (block == lastBlockEnqueued) { break; } block = block->next; } } MOODYCAMEL_RETHROW; } } if (this->tailBlock == endBlock) { assert(currentTailIndex == newTailIndex); break; } this->tailBlock = this->tailBlock->next; } if (!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst))) && firstAllocatedBlock != nullptr) { blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release); } this->tailIndex.store(newTailIndex, std::memory_order_release); return true; } template size_t dequeue_bulk(It& itemFirst, size_t max) { auto tail = this->tailIndex.load(std::memory_order_relaxed); auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); auto desiredCount = static_cast(tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit)); if (details::circular_less_than(0, desiredCount)) { desiredCount = desiredCount < max ? desiredCount : max; std::atomic_thread_fence(std::memory_order_acquire); auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed);; tail = this->tailIndex.load(std::memory_order_acquire); auto actualCount = static_cast(tail - (myDequeueCount - overcommit)); if (details::circular_less_than(0, actualCount)) { actualCount = desiredCount < actualCount ? desiredCount : actualCount; if (actualCount < desiredCount) { this->dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release); } // Get the first index. Note that since there's guaranteed to be at least actualCount elements, this // will never exceed tail. auto firstIndex = this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel); // Determine which block the first element is in auto localBlockIndex = blockIndex.load(std::memory_order_acquire); auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire); auto headBase = localBlockIndex->entries[localBlockIndexHead].base; auto firstBlockBaseIndex = firstIndex & ~static_cast(BLOCK_SIZE - 1); auto offset = static_cast(static_cast::type>(firstBlockBaseIndex - headBase) / BLOCK_SIZE); auto indexIndex = (localBlockIndexHead + offset) & (localBlockIndex->size - 1); // Iterate the blocks and dequeue auto index = firstIndex; do { auto firstIndexInBlock = index; auto endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; auto block = localBlockIndex->entries[indexIndex].block; if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, details::deref_noexcept(itemFirst) = std::move((*(*block)[index])))) { while (index != endIndex) { auto& el = *((*block)[index]); *itemFirst++ = std::move(el); el.~T(); ++index; } } else { MOODYCAMEL_TRY { while (index != endIndex) { auto& el = *((*block)[index]); *itemFirst = std::move(el); ++itemFirst; el.~T(); ++index; } } MOODYCAMEL_CATCH (...) { // It's too late to revert the dequeue, but we can make sure that all // the dequeued objects are properly destroyed and the block index // (and empty count) are properly updated before we propagate the exception do { block = localBlockIndex->entries[indexIndex].block; while (index != endIndex) { (*block)[index++]->~T(); } block->ConcurrentQueue::Block::template set_many_empty(firstIndexInBlock, static_cast(endIndex - firstIndexInBlock)); indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1); firstIndexInBlock = index; endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; } while (index != firstIndex + actualCount); MOODYCAMEL_RETHROW; } } block->ConcurrentQueue::Block::template set_many_empty(firstIndexInBlock, static_cast(endIndex - firstIndexInBlock)); indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1); } while (index != firstIndex + actualCount); return actualCount; } else { // Wasn't anything to dequeue after all; make the effective dequeue count eventually consistent this->dequeueOvercommit.fetch_add(desiredCount, std::memory_order_release); } } return 0; } private: struct BlockIndexEntry { index_t base; Block* block; }; struct BlockIndexHeader { size_t size; std::atomic front; // Current slot (not next, like pr_blockIndexFront) BlockIndexEntry* entries; void* prev; }; bool new_block_index(size_t numberOfFilledSlotsToExpose) { auto prevBlockSizeMask = pr_blockIndexSize - 1; // Create the new block pr_blockIndexSize <<= 1; auto newRawPtr = static_cast((Traits::malloc)(sizeof(BlockIndexHeader) + std::alignment_of::value - 1 + sizeof(BlockIndexEntry) * pr_blockIndexSize)); if (newRawPtr == nullptr) { pr_blockIndexSize >>= 1; // Reset to allow graceful retry return false; } auto newBlockIndexEntries = reinterpret_cast(details::align_for(newRawPtr + sizeof(BlockIndexHeader))); // Copy in all the old indices, if any size_t j = 0; if (pr_blockIndexSlotsUsed != 0) { auto i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & prevBlockSizeMask; do { newBlockIndexEntries[j++] = pr_blockIndexEntries[i]; i = (i + 1) & prevBlockSizeMask; } while (i != pr_blockIndexFront); } // Update everything auto header = new (newRawPtr) BlockIndexHeader; header->size = pr_blockIndexSize; header->front.store(numberOfFilledSlotsToExpose - 1, std::memory_order_relaxed); header->entries = newBlockIndexEntries; header->prev = pr_blockIndexRaw; // we link the new block to the old one so we can free it later pr_blockIndexFront = j; pr_blockIndexEntries = newBlockIndexEntries; pr_blockIndexRaw = newRawPtr; blockIndex.store(header, std::memory_order_release); return true; } private: std::atomic blockIndex; // To be used by producer only -- consumer must use the ones in referenced by blockIndex size_t pr_blockIndexSlotsUsed; size_t pr_blockIndexSize; size_t pr_blockIndexFront; // Next slot (not current) BlockIndexEntry* pr_blockIndexEntries; void* pr_blockIndexRaw; #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG public: ExplicitProducer* nextExplicitProducer; private: #endif #if MCDBGQ_TRACKMEM friend struct MemStats; #endif }; ////////////////////////////////// // Implicit queue ////////////////////////////////// struct ImplicitProducer : public ProducerBase { ImplicitProducer(ConcurrentQueue* parent) : ProducerBase(parent, false), nextBlockIndexCapacity(IMPLICIT_INITIAL_INDEX_SIZE), blockIndex(nullptr) { new_block_index(); } ~ImplicitProducer() { // Note that since we're in the destructor we can assume that all enqueue/dequeue operations // completed already; this means that all undequeued elements are placed contiguously across // contiguous blocks, and that only the first and last remaining blocks can be only partially // empty (all other remaining blocks must be completely full). #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED // Unregister ourselves for thread termination notification if (!this->inactive.load(std::memory_order_relaxed)) { details::ThreadExitNotifier::unsubscribe(&threadExitListener); } #endif // Destroy all remaining elements! auto tail = this->tailIndex.load(std::memory_order_relaxed); auto index = this->headIndex.load(std::memory_order_relaxed); Block* block = nullptr; assert(index == tail || details::circular_less_than(index, tail)); bool forceFreeLastBlock = index != tail; // If we enter the loop, then the last (tail) block will not be freed while (index != tail) { if ((index & static_cast(BLOCK_SIZE - 1)) == 0 || block == nullptr) { if (block != nullptr) { // Free the old block this->parent->add_block_to_free_list(block); } block = get_block_index_entry_for_index(index)->value.load(std::memory_order_relaxed); } ((*block)[index])->~T(); ++index; } // Even if the queue is empty, there's still one block that's not on the free list // (unless the head index reached the end of it, in which case the tail will be poised // to create a new block). if (this->tailBlock != nullptr && (forceFreeLastBlock || (tail & static_cast(BLOCK_SIZE - 1)) != 0)) { this->parent->add_block_to_free_list(this->tailBlock); } // Destroy block index auto localBlockIndex = blockIndex.load(std::memory_order_relaxed); if (localBlockIndex != nullptr) { for (size_t i = 0; i != localBlockIndex->capacity; ++i) { localBlockIndex->index[i]->~BlockIndexEntry(); } do { auto prev = localBlockIndex->prev; localBlockIndex->~BlockIndexHeader(); (Traits::free)(localBlockIndex); localBlockIndex = prev; } while (localBlockIndex != nullptr); } } template inline bool enqueue(U&& element) { index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed); index_t newTailIndex = 1 + currentTailIndex; if ((currentTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { // We reached the end of a block, start a new one auto head = this->headIndex.load(std::memory_order_relaxed); assert(!details::circular_less_than(currentTailIndex, head)); if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) { return false; } #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX debug::DebugLock lock(mutex); #endif // Find out where we'll be inserting this block in the block index BlockIndexEntry* idxEntry; if (!insert_block_index_entry(idxEntry, currentTailIndex)) { return false; } // Get ahold of a new block auto newBlock = this->parent->ConcurrentQueue::template requisition_block(); if (newBlock == nullptr) { rewind_block_index_tail(); idxEntry->value.store(nullptr, std::memory_order_relaxed); return false; } #if MCDBGQ_TRACKMEM newBlock->owner = this; #endif newBlock->ConcurrentQueue::Block::template reset_empty(); if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { // May throw, try to insert now before we publish the fact that we have this new block MOODYCAMEL_TRY { new ((*newBlock)[currentTailIndex]) T(std::forward(element)); } MOODYCAMEL_CATCH (...) { rewind_block_index_tail(); idxEntry->value.store(nullptr, std::memory_order_relaxed); this->parent->add_block_to_free_list(newBlock); MOODYCAMEL_RETHROW; } } // Insert the new block into the index idxEntry->value.store(newBlock, std::memory_order_relaxed); this->tailBlock = newBlock; if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) { this->tailIndex.store(newTailIndex, std::memory_order_release); return true; } } // Enqueue new ((*this->tailBlock)[currentTailIndex]) T(std::forward(element)); this->tailIndex.store(newTailIndex, std::memory_order_release); return true; } template bool dequeue(U& element) { // See ExplicitProducer::dequeue for rationale and explanation index_t tail = this->tailIndex.load(std::memory_order_relaxed); index_t overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); if (details::circular_less_than(this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit, tail)) { std::atomic_thread_fence(std::memory_order_acquire); index_t myDequeueCount = this->dequeueOptimisticCount.fetch_add(1, std::memory_order_relaxed); tail = this->tailIndex.load(std::memory_order_acquire); if ((details::likely)(details::circular_less_than(myDequeueCount - overcommit, tail))) { index_t index = this->headIndex.fetch_add(1, std::memory_order_acq_rel); // Determine which block the element is in auto entry = get_block_index_entry_for_index(index); // Dequeue auto block = entry->value.load(std::memory_order_relaxed); auto& el = *((*block)[index]); if (!MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, element = std::move(el))) { #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX // Note: Acquiring the mutex with every dequeue instead of only when a block // is released is very sub-optimal, but it is, after all, purely debug code. debug::DebugLock lock(producer->mutex); #endif struct Guard { Block* block; index_t index; BlockIndexEntry* entry; ConcurrentQueue* parent; ~Guard() { (*block)[index]->~T(); if (block->ConcurrentQueue::Block::template set_empty(index)) { entry->value.store(nullptr, std::memory_order_relaxed); parent->add_block_to_free_list(block); } } } guard = { block, index, entry, this->parent }; element = std::move(el); } else { element = std::move(el); el.~T(); if (block->ConcurrentQueue::Block::template set_empty(index)) { { #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX debug::DebugLock lock(mutex); #endif // Add the block back into the global free pool (and remove from block index) entry->value.store(nullptr, std::memory_order_relaxed); } this->parent->add_block_to_free_list(block); // releases the above store } } return true; } else { this->dequeueOvercommit.fetch_add(1, std::memory_order_release); } } return false; } template bool enqueue_bulk(It itemFirst, size_t count) { // First, we need to make sure we have enough room to enqueue all of the elements; // this means pre-allocating blocks and putting them in the block index (but only if // all the allocations succeeded). // Note that the tailBlock we start off with may not be owned by us any more; // this happens if it was filled up exactly to the top (setting tailIndex to // the first index of the next block which is not yet allocated), then dequeued // completely (putting it on the free list) before we enqueue again. index_t startTailIndex = this->tailIndex.load(std::memory_order_relaxed); auto startBlock = this->tailBlock; Block* firstAllocatedBlock = nullptr; auto endBlock = this->tailBlock; // Figure out how many blocks we'll need to allocate, and do so size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1)); index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); if (blockBaseDiff > 0) { #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX debug::DebugLock lock(mutex); #endif do { blockBaseDiff -= static_cast(BLOCK_SIZE); currentTailIndex += static_cast(BLOCK_SIZE); // Find out where we'll be inserting this block in the block index BlockIndexEntry* idxEntry = nullptr; // initialization here unnecessary but compiler can't always tell Block* newBlock; bool indexInserted = false; auto head = this->headIndex.load(std::memory_order_relaxed); assert(!details::circular_less_than(currentTailIndex, head)); bool full = !details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head)); if (full || !(indexInserted = insert_block_index_entry(idxEntry, currentTailIndex)) || (newBlock = this->parent->ConcurrentQueue::template requisition_block()) == nullptr) { // Index allocation or block allocation failed; revert any other allocations // and index insertions done so far for this operation if (indexInserted) { rewind_block_index_tail(); idxEntry->value.store(nullptr, std::memory_order_relaxed); } currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); for (auto block = firstAllocatedBlock; block != nullptr; block = block->next) { currentTailIndex += static_cast(BLOCK_SIZE); idxEntry = get_block_index_entry_for_index(currentTailIndex); idxEntry->value.store(nullptr, std::memory_order_relaxed); rewind_block_index_tail(); } this->parent->add_blocks_to_free_list(firstAllocatedBlock); this->tailBlock = startBlock; return false; } #if MCDBGQ_TRACKMEM newBlock->owner = this; #endif newBlock->ConcurrentQueue::Block::template reset_empty(); newBlock->next = nullptr; // Insert the new block into the index idxEntry->value.store(newBlock, std::memory_order_relaxed); // Store the chain of blocks so that we can undo if later allocations fail, // and so that we can find the blocks when we do the actual enqueueing if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock != nullptr) { assert(this->tailBlock != nullptr); this->tailBlock->next = newBlock; } this->tailBlock = newBlock; endBlock = newBlock; firstAllocatedBlock = firstAllocatedBlock == nullptr ? newBlock : firstAllocatedBlock; } while (blockBaseDiff > 0); } // Enqueue, one block at a time index_t newTailIndex = startTailIndex + static_cast(count); currentTailIndex = startTailIndex; this->tailBlock = startBlock; assert((startTailIndex & static_cast(BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock != nullptr || count == 0); if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0 && firstAllocatedBlock != nullptr) { this->tailBlock = firstAllocatedBlock; } while (true) { auto stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); if (details::circular_less_than(newTailIndex, stopIndex)) { stopIndex = newTailIndex; } if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) { while (currentTailIndex != stopIndex) { new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++); } } else { MOODYCAMEL_TRY { while (currentTailIndex != stopIndex) { new ((*this->tailBlock)[currentTailIndex]) T(details::nomove_if<(bool)!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))>::eval(*itemFirst)); ++currentTailIndex; ++itemFirst; } } MOODYCAMEL_CATCH (...) { auto constructedStopIndex = currentTailIndex; auto lastBlockEnqueued = this->tailBlock; if (!details::is_trivially_destructible::value) { auto block = startBlock; if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) { block = firstAllocatedBlock; } currentTailIndex = startTailIndex; while (true) { stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); if (details::circular_less_than(constructedStopIndex, stopIndex)) { stopIndex = constructedStopIndex; } while (currentTailIndex != stopIndex) { (*block)[currentTailIndex++]->~T(); } if (block == lastBlockEnqueued) { break; } block = block->next; } } currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1); for (auto block = firstAllocatedBlock; block != nullptr; block = block->next) { currentTailIndex += static_cast(BLOCK_SIZE); auto idxEntry = get_block_index_entry_for_index(currentTailIndex); idxEntry->value.store(nullptr, std::memory_order_relaxed); rewind_block_index_tail(); } this->parent->add_blocks_to_free_list(firstAllocatedBlock); this->tailBlock = startBlock; MOODYCAMEL_RETHROW; } } if (this->tailBlock == endBlock) { assert(currentTailIndex == newTailIndex); break; } this->tailBlock = this->tailBlock->next; } this->tailIndex.store(newTailIndex, std::memory_order_release); return true; } template size_t dequeue_bulk(It& itemFirst, size_t max) { auto tail = this->tailIndex.load(std::memory_order_relaxed); auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed); auto desiredCount = static_cast(tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit)); if (details::circular_less_than(0, desiredCount)) { desiredCount = desiredCount < max ? desiredCount : max; std::atomic_thread_fence(std::memory_order_acquire); auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed); tail = this->tailIndex.load(std::memory_order_acquire); auto actualCount = static_cast(tail - (myDequeueCount - overcommit)); if (details::circular_less_than(0, actualCount)) { actualCount = desiredCount < actualCount ? desiredCount : actualCount; if (actualCount < desiredCount) { this->dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release); } // Get the first index. Note that since there's guaranteed to be at least actualCount elements, this // will never exceed tail. auto firstIndex = this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel); // Iterate the blocks and dequeue auto index = firstIndex; BlockIndexHeader* localBlockIndex; auto indexIndex = get_block_index_index_for_index(index, localBlockIndex); do { auto blockStartIndex = index; auto endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; auto entry = localBlockIndex->index[indexIndex]; auto block = entry->value.load(std::memory_order_relaxed); if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, details::deref_noexcept(itemFirst) = std::move((*(*block)[index])))) { while (index != endIndex) { auto& el = *((*block)[index]); *itemFirst++ = std::move(el); el.~T(); ++index; } } else { MOODYCAMEL_TRY { while (index != endIndex) { auto& el = *((*block)[index]); *itemFirst = std::move(el); ++itemFirst; el.~T(); ++index; } } MOODYCAMEL_CATCH (...) { do { entry = localBlockIndex->index[indexIndex]; block = entry->value.load(std::memory_order_relaxed); while (index != endIndex) { (*block)[index++]->~T(); } if (block->ConcurrentQueue::Block::template set_many_empty(blockStartIndex, static_cast(endIndex - blockStartIndex))) { #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX debug::DebugLock lock(mutex); #endif entry->value.store(nullptr, std::memory_order_relaxed); this->parent->add_block_to_free_list(block); } indexIndex = (indexIndex + 1) & (localBlockIndex->capacity - 1); blockStartIndex = index; endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE); endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex; } while (index != firstIndex + actualCount); MOODYCAMEL_RETHROW; } } if (block->ConcurrentQueue::Block::template set_many_empty(blockStartIndex, static_cast(endIndex - blockStartIndex))) { { #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX debug::DebugLock lock(mutex); #endif // Note that the set_many_empty above did a release, meaning that anybody who acquires the block // we're about to free can use it safely since our writes (and reads!) will have happened-before then. entry->value.store(nullptr, std::memory_order_relaxed); } this->parent->add_block_to_free_list(block); // releases the above store } indexIndex = (indexIndex + 1) & (localBlockIndex->capacity - 1); } while (index != firstIndex + actualCount); return actualCount; } else { this->dequeueOvercommit.fetch_add(desiredCount, std::memory_order_release); } } return 0; } private: // The block size must be > 1, so any number with the low bit set is an invalid block base index static const index_t INVALID_BLOCK_BASE = 1; struct BlockIndexEntry { std::atomic key; std::atomic value; }; struct BlockIndexHeader { size_t capacity; std::atomic tail; BlockIndexEntry* entries; BlockIndexEntry** index; BlockIndexHeader* prev; }; template inline bool insert_block_index_entry(BlockIndexEntry*& idxEntry, index_t blockStartIndex) { auto localBlockIndex = blockIndex.load(std::memory_order_relaxed); // We're the only writer thread, relaxed is OK if (localBlockIndex == nullptr) { return false; // this can happen if new_block_index failed in the constructor } auto newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1); idxEntry = localBlockIndex->index[newTail]; if (idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE || idxEntry->value.load(std::memory_order_relaxed) == nullptr) { idxEntry->key.store(blockStartIndex, std::memory_order_relaxed); localBlockIndex->tail.store(newTail, std::memory_order_release); return true; } // No room in the old block index, try to allocate another one! if (allocMode == CannotAlloc || !new_block_index()) { return false; } localBlockIndex = blockIndex.load(std::memory_order_relaxed); newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1); idxEntry = localBlockIndex->index[newTail]; assert(idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE); idxEntry->key.store(blockStartIndex, std::memory_order_relaxed); localBlockIndex->tail.store(newTail, std::memory_order_release); return true; } inline void rewind_block_index_tail() { auto localBlockIndex = blockIndex.load(std::memory_order_relaxed); localBlockIndex->tail.store((localBlockIndex->tail.load(std::memory_order_relaxed) - 1) & (localBlockIndex->capacity - 1), std::memory_order_relaxed); } inline BlockIndexEntry* get_block_index_entry_for_index(index_t index) const { BlockIndexHeader* localBlockIndex; auto idx = get_block_index_index_for_index(index, localBlockIndex); return localBlockIndex->index[idx]; } inline size_t get_block_index_index_for_index(index_t index, BlockIndexHeader*& localBlockIndex) const { #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX debug::DebugLock lock(mutex); #endif index &= ~static_cast(BLOCK_SIZE - 1); localBlockIndex = blockIndex.load(std::memory_order_acquire); auto tail = localBlockIndex->tail.load(std::memory_order_acquire); auto tailBase = localBlockIndex->index[tail]->key.load(std::memory_order_relaxed); assert(tailBase != INVALID_BLOCK_BASE); // Note: Must use division instead of shift because the index may wrap around, causing a negative // offset, whose negativity we want to preserve auto offset = static_cast(static_cast::type>(index - tailBase) / BLOCK_SIZE); size_t idx = (tail + offset) & (localBlockIndex->capacity - 1); assert(localBlockIndex->index[idx]->key.load(std::memory_order_relaxed) == index && localBlockIndex->index[idx]->value.load(std::memory_order_relaxed) != nullptr); return idx; } bool new_block_index() { auto prev = blockIndex.load(std::memory_order_relaxed); size_t prevCapacity = prev == nullptr ? 0 : prev->capacity; auto entryCount = prev == nullptr ? nextBlockIndexCapacity : prevCapacity; auto raw = static_cast((Traits::malloc)( sizeof(BlockIndexHeader) + std::alignment_of::value - 1 + sizeof(BlockIndexEntry) * entryCount + std::alignment_of::value - 1 + sizeof(BlockIndexEntry*) * nextBlockIndexCapacity)); if (raw == nullptr) { return false; } auto header = new (raw) BlockIndexHeader; auto entries = reinterpret_cast(details::align_for(raw + sizeof(BlockIndexHeader))); auto index = reinterpret_cast(details::align_for(reinterpret_cast(entries) + sizeof(BlockIndexEntry) * entryCount)); if (prev != nullptr) { auto prevTail = prev->tail.load(std::memory_order_relaxed); auto prevPos = prevTail; size_t i = 0; do { prevPos = (prevPos + 1) & (prev->capacity - 1); index[i++] = prev->index[prevPos]; } while (prevPos != prevTail); assert(i == prevCapacity); } for (size_t i = 0; i != entryCount; ++i) { new (entries + i) BlockIndexEntry; entries[i].key.store(INVALID_BLOCK_BASE, std::memory_order_relaxed); index[prevCapacity + i] = entries + i; } header->prev = prev; header->entries = entries; header->index = index; header->capacity = nextBlockIndexCapacity; header->tail.store((prevCapacity - 1) & (nextBlockIndexCapacity - 1), std::memory_order_relaxed); blockIndex.store(header, std::memory_order_release); nextBlockIndexCapacity <<= 1; return true; } private: size_t nextBlockIndexCapacity; std::atomic blockIndex; #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED public: details::ThreadExitListener threadExitListener; private: #endif #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG public: ImplicitProducer* nextImplicitProducer; private: #endif #if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX mutable debug::DebugMutex mutex; #endif #if MCDBGQ_TRACKMEM friend struct MemStats; #endif }; ////////////////////////////////// // Block pool manipulation ////////////////////////////////// void populate_initial_block_list(size_t blockCount) { initialBlockPoolSize = blockCount; if (initialBlockPoolSize == 0) { initialBlockPool = nullptr; return; } initialBlockPool = create_array(blockCount); if (initialBlockPool == nullptr) { initialBlockPoolSize = 0; } for (size_t i = 0; i < initialBlockPoolSize; ++i) { initialBlockPool[i].dynamicallyAllocated = false; } } inline Block* try_get_block_from_initial_pool() { if (initialBlockPoolIndex.load(std::memory_order_relaxed) >= initialBlockPoolSize) { return nullptr; } auto index = initialBlockPoolIndex.fetch_add(1, std::memory_order_relaxed); return index < initialBlockPoolSize ? (initialBlockPool + index) : nullptr; } inline void add_block_to_free_list(Block* block) { #if MCDBGQ_TRACKMEM block->owner = nullptr; #endif freeList.add(block); } inline void add_blocks_to_free_list(Block* block) { while (block != nullptr) { auto next = block->next; add_block_to_free_list(block); block = next; } } inline Block* try_get_block_from_free_list() { return freeList.try_get(); } // Gets a free block from one of the memory pools, or allocates a new one (if applicable) template Block* requisition_block() { auto block = try_get_block_from_initial_pool(); if (block != nullptr) { return block; } block = try_get_block_from_free_list(); if (block != nullptr) { return block; } if (canAlloc == CanAlloc) { return create(); } return nullptr; } #if MCDBGQ_TRACKMEM public: struct MemStats { size_t allocatedBlocks; size_t usedBlocks; size_t freeBlocks; size_t ownedBlocksExplicit; size_t ownedBlocksImplicit; size_t implicitProducers; size_t explicitProducers; size_t elementsEnqueued; size_t blockClassBytes; size_t queueClassBytes; size_t implicitBlockIndexBytes; size_t explicitBlockIndexBytes; friend class ConcurrentQueue; private: static MemStats getFor(ConcurrentQueue* q) { MemStats stats = { 0 }; stats.elementsEnqueued = q->size_approx(); auto block = q->freeList.head_unsafe(); while (block != nullptr) { ++stats.allocatedBlocks; ++stats.freeBlocks; block = block->freeListNext.load(std::memory_order_relaxed); } for (auto ptr = q->producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { bool implicit = dynamic_cast(ptr) != nullptr; stats.implicitProducers += implicit ? 1 : 0; stats.explicitProducers += implicit ? 0 : 1; if (implicit) { auto prod = static_cast(ptr); stats.queueClassBytes += sizeof(ImplicitProducer); auto head = prod->headIndex.load(std::memory_order_relaxed); auto tail = prod->tailIndex.load(std::memory_order_relaxed); auto hash = prod->blockIndex.load(std::memory_order_relaxed); if (hash != nullptr) { for (size_t i = 0; i != hash->capacity; ++i) { if (hash->index[i]->key.load(std::memory_order_relaxed) != ImplicitProducer::INVALID_BLOCK_BASE && hash->index[i]->value.load(std::memory_order_relaxed) != nullptr) { ++stats.allocatedBlocks; ++stats.ownedBlocksImplicit; } } stats.implicitBlockIndexBytes += hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry); for (; hash != nullptr; hash = hash->prev) { stats.implicitBlockIndexBytes += sizeof(typename ImplicitProducer::BlockIndexHeader) + hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry*); } } for (; details::circular_less_than(head, tail); head += BLOCK_SIZE) { //auto block = prod->get_block_index_entry_for_index(head); ++stats.usedBlocks; } } else { auto prod = static_cast(ptr); stats.queueClassBytes += sizeof(ExplicitProducer); auto tailBlock = prod->tailBlock; bool wasNonEmpty = false; if (tailBlock != nullptr) { auto block = tailBlock; do { ++stats.allocatedBlocks; if (!block->ConcurrentQueue::Block::template is_empty() || wasNonEmpty) { ++stats.usedBlocks; wasNonEmpty = wasNonEmpty || block != tailBlock; } ++stats.ownedBlocksExplicit; block = block->next; } while (block != tailBlock); } auto index = prod->blockIndex.load(std::memory_order_relaxed); while (index != nullptr) { stats.explicitBlockIndexBytes += sizeof(typename ExplicitProducer::BlockIndexHeader) + index->size * sizeof(typename ExplicitProducer::BlockIndexEntry); index = static_cast(index->prev); } } } auto freeOnInitialPool = q->initialBlockPoolIndex.load(std::memory_order_relaxed) >= q->initialBlockPoolSize ? 0 : q->initialBlockPoolSize - q->initialBlockPoolIndex.load(std::memory_order_relaxed); stats.allocatedBlocks += freeOnInitialPool; stats.freeBlocks += freeOnInitialPool; stats.blockClassBytes = sizeof(Block) * stats.allocatedBlocks; stats.queueClassBytes += sizeof(ConcurrentQueue); return stats; } }; // For debugging only. Not thread-safe. MemStats getMemStats() { return MemStats::getFor(this); } private: friend struct MemStats; #endif ////////////////////////////////// // Producer list manipulation ////////////////////////////////// ProducerBase* recycle_or_create_producer(bool isExplicit) { bool recycled; return recycle_or_create_producer(isExplicit, recycled); } ProducerBase* recycle_or_create_producer(bool isExplicit, bool& recycled) { #if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH debug::DebugLock lock(implicitProdMutex); #endif // Try to re-use one first for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { if (ptr->inactive.load(std::memory_order_relaxed) && ptr->isExplicit == isExplicit) { bool expected = true; if (ptr->inactive.compare_exchange_strong(expected, /* desired */ false, std::memory_order_acquire, std::memory_order_relaxed)) { // We caught one! It's been marked as activated, the caller can have it recycled = true; return ptr; } } } recycled = false; return add_producer(isExplicit ? static_cast(create(this)) : create(this)); } ProducerBase* add_producer(ProducerBase* producer) { // Handle failed memory allocation if (producer == nullptr) { return nullptr; } producerCount.fetch_add(1, std::memory_order_relaxed); // Add it to the lock-free list auto prevTail = producerListTail.load(std::memory_order_relaxed); do { producer->next = prevTail; } while (!producerListTail.compare_exchange_weak(prevTail, producer, std::memory_order_release, std::memory_order_relaxed)); #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG if (producer->isExplicit) { auto prevTailExplicit = explicitProducers.load(std::memory_order_relaxed); do { static_cast(producer)->nextExplicitProducer = prevTailExplicit; } while (!explicitProducers.compare_exchange_weak(prevTailExplicit, static_cast(producer), std::memory_order_release, std::memory_order_relaxed)); } else { auto prevTailImplicit = implicitProducers.load(std::memory_order_relaxed); do { static_cast(producer)->nextImplicitProducer = prevTailImplicit; } while (!implicitProducers.compare_exchange_weak(prevTailImplicit, static_cast(producer), std::memory_order_release, std::memory_order_relaxed)); } #endif return producer; } void reown_producers() { // After another instance is moved-into/swapped-with this one, all the // producers we stole still think their parents are the other queue. // So fix them up! for (auto ptr = producerListTail.load(std::memory_order_relaxed); ptr != nullptr; ptr = ptr->next_prod()) { ptr->parent = this; } } ////////////////////////////////// // Implicit producer hash ////////////////////////////////// struct ImplicitProducerKVP { std::atomic key; ImplicitProducer* value; // No need for atomicity since it's only read by the thread that sets it in the first place ImplicitProducerKVP() : value(nullptr) { } ImplicitProducerKVP(ImplicitProducerKVP&& other) MOODYCAMEL_NOEXCEPT { key.store(other.key.load(std::memory_order_relaxed), std::memory_order_relaxed); value = other.value; } inline ImplicitProducerKVP& operator=(ImplicitProducerKVP&& other) MOODYCAMEL_NOEXCEPT { swap(other); return *this; } inline void swap(ImplicitProducerKVP& other) MOODYCAMEL_NOEXCEPT { if (this != &other) { details::swap_relaxed(key, other.key); std::swap(value, other.value); } } }; template friend void moodycamel::swap(typename ConcurrentQueue::ImplicitProducerKVP&, typename ConcurrentQueue::ImplicitProducerKVP&) MOODYCAMEL_NOEXCEPT; struct ImplicitProducerHash { size_t capacity; ImplicitProducerKVP* entries; ImplicitProducerHash* prev; }; inline void populate_initial_implicit_producer_hash() { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return; implicitProducerHashCount.store(0, std::memory_order_relaxed); auto hash = &initialImplicitProducerHash; hash->capacity = INITIAL_IMPLICIT_PRODUCER_HASH_SIZE; hash->entries = &initialImplicitProducerHashEntries[0]; for (size_t i = 0; i != INITIAL_IMPLICIT_PRODUCER_HASH_SIZE; ++i) { initialImplicitProducerHashEntries[i].key.store(details::invalid_thread_id, std::memory_order_relaxed); } hash->prev = nullptr; implicitProducerHash.store(hash, std::memory_order_relaxed); } void swap_implicit_producer_hashes(ConcurrentQueue& other) { if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return; // Swap (assumes our implicit producer hash is initialized) initialImplicitProducerHashEntries.swap(other.initialImplicitProducerHashEntries); initialImplicitProducerHash.entries = &initialImplicitProducerHashEntries[0]; other.initialImplicitProducerHash.entries = &other.initialImplicitProducerHashEntries[0]; details::swap_relaxed(implicitProducerHashCount, other.implicitProducerHashCount); details::swap_relaxed(implicitProducerHash, other.implicitProducerHash); if (implicitProducerHash.load(std::memory_order_relaxed) == &other.initialImplicitProducerHash) { implicitProducerHash.store(&initialImplicitProducerHash, std::memory_order_relaxed); } else { ImplicitProducerHash* hash; for (hash = implicitProducerHash.load(std::memory_order_relaxed); hash->prev != &other.initialImplicitProducerHash; hash = hash->prev) { continue; } hash->prev = &initialImplicitProducerHash; } if (other.implicitProducerHash.load(std::memory_order_relaxed) == &initialImplicitProducerHash) { other.implicitProducerHash.store(&other.initialImplicitProducerHash, std::memory_order_relaxed); } else { ImplicitProducerHash* hash; for (hash = other.implicitProducerHash.load(std::memory_order_relaxed); hash->prev != &initialImplicitProducerHash; hash = hash->prev) { continue; } hash->prev = &other.initialImplicitProducerHash; } } // Only fails (returns nullptr) if memory allocation fails ImplicitProducer* get_or_add_implicit_producer() { // Note that since the data is essentially thread-local (key is thread ID), // there's a reduced need for fences (memory ordering is already consistent // for any individual thread), except for the current table itself. // Start by looking for the thread ID in the current and all previous hash tables. // If it's not found, it must not be in there yet, since this same thread would // have added it previously to one of the tables that we traversed. // Code and algorithm adapted from http://preshing.com/20130605/the-worlds-simplest-lock-free-hash-table #if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH debug::DebugLock lock(implicitProdMutex); #endif auto id = details::thread_id(); auto hashedId = details::hash_thread_id(id); auto mainHash = implicitProducerHash.load(std::memory_order_acquire); for (auto hash = mainHash; hash != nullptr; hash = hash->prev) { // Look for the id in this hash auto index = hashedId; while (true) { // Not an infinite loop because at least one slot is free in the hash table index &= hash->capacity - 1; auto probedKey = hash->entries[index].key.load(std::memory_order_relaxed); if (probedKey == id) { // Found it! If we had to search several hashes deep, though, we should lazily add it // to the current main hash table to avoid the extended search next time. // Note there's guaranteed to be room in the current hash table since every subsequent // table implicitly reserves space for all previous tables (there's only one // implicitProducerHashCount). auto value = hash->entries[index].value; if (hash != mainHash) { index = hashedId; while (true) { index &= mainHash->capacity - 1; probedKey = mainHash->entries[index].key.load(std::memory_order_relaxed); auto empty = details::invalid_thread_id; #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED auto reusable = details::invalid_thread_id2; if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed)) || (probedKey == reusable && mainHash->entries[index].key.compare_exchange_strong(reusable, id, std::memory_order_acquire, std::memory_order_acquire))) { #else if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed))) { #endif mainHash->entries[index].value = value; break; } ++index; } } return value; } if (probedKey == details::invalid_thread_id) { break; // Not in this hash table } ++index; } } // Insert! auto newCount = 1 + implicitProducerHashCount.fetch_add(1, std::memory_order_relaxed); while (true) { if (newCount >= (mainHash->capacity >> 1) && !implicitProducerHashResizeInProgress.test_and_set(std::memory_order_acquire)) { // We've acquired the resize lock, try to allocate a bigger hash table. // Note the acquire fence synchronizes with the release fence at the end of this block, and hence when // we reload implicitProducerHash it must be the most recent version (it only gets changed within this // locked block). mainHash = implicitProducerHash.load(std::memory_order_acquire); if (newCount >= (mainHash->capacity >> 1)) { auto newCapacity = mainHash->capacity << 1; while (newCount >= (newCapacity >> 1)) { newCapacity <<= 1; } auto raw = static_cast((Traits::malloc)(sizeof(ImplicitProducerHash) + std::alignment_of::value - 1 + sizeof(ImplicitProducerKVP) * newCapacity)); if (raw == nullptr) { // Allocation failed implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed); implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); return nullptr; } auto newHash = new (raw) ImplicitProducerHash; newHash->capacity = newCapacity; newHash->entries = reinterpret_cast(details::align_for(raw + sizeof(ImplicitProducerHash))); for (size_t i = 0; i != newCapacity; ++i) { new (newHash->entries + i) ImplicitProducerKVP; newHash->entries[i].key.store(details::invalid_thread_id, std::memory_order_relaxed); } newHash->prev = mainHash; implicitProducerHash.store(newHash, std::memory_order_release); implicitProducerHashResizeInProgress.clear(std::memory_order_release); mainHash = newHash; } else { implicitProducerHashResizeInProgress.clear(std::memory_order_release); } } // If it's < three-quarters full, add to the old one anyway so that we don't have to wait for the next table // to finish being allocated by another thread (and if we just finished allocating above, the condition will // always be true) if (newCount < (mainHash->capacity >> 1) + (mainHash->capacity >> 2)) { bool recycled; auto producer = static_cast(recycle_or_create_producer(false, recycled)); if (producer == nullptr) { implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed); return nullptr; } if (recycled) { implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed); } #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED producer->threadExitListener.callback = &ConcurrentQueue::implicit_producer_thread_exited_callback; producer->threadExitListener.userData = producer; details::ThreadExitNotifier::subscribe(&producer->threadExitListener); #endif auto index = hashedId; while (true) { index &= mainHash->capacity - 1; auto probedKey = mainHash->entries[index].key.load(std::memory_order_relaxed); auto empty = details::invalid_thread_id; #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED auto reusable = details::invalid_thread_id2; if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed)) || (probedKey == reusable && mainHash->entries[index].key.compare_exchange_strong(reusable, id, std::memory_order_acquire, std::memory_order_acquire))) { #else if ((probedKey == empty && mainHash->entries[index].key.compare_exchange_strong(empty, id, std::memory_order_relaxed, std::memory_order_relaxed))) { #endif mainHash->entries[index].value = producer; break; } ++index; } return producer; } // Hmm, the old hash is quite full and somebody else is busy allocating a new one. // We need to wait for the allocating thread to finish (if it succeeds, we add, if not, // we try to allocate ourselves). mainHash = implicitProducerHash.load(std::memory_order_acquire); } } #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED void implicit_producer_thread_exited(ImplicitProducer* producer) { // Remove from thread exit listeners details::ThreadExitNotifier::unsubscribe(&producer->threadExitListener); // Remove from hash #if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH debug::DebugLock lock(implicitProdMutex); #endif auto hash = implicitProducerHash.load(std::memory_order_acquire); assert(hash != nullptr); // The thread exit listener is only registered if we were added to a hash in the first place auto id = details::thread_id(); auto hashedId = details::hash_thread_id(id); details::thread_id_t probedKey; // We need to traverse all the hashes just in case other threads aren't on the current one yet and are // trying to add an entry thinking there's a free slot (because they reused a producer) for (; hash != nullptr; hash = hash->prev) { auto index = hashedId; do { index &= hash->capacity - 1; probedKey = hash->entries[index].key.load(std::memory_order_relaxed); if (probedKey == id) { hash->entries[index].key.store(details::invalid_thread_id2, std::memory_order_release); break; } ++index; } while (probedKey != details::invalid_thread_id); // Can happen if the hash has changed but we weren't put back in it yet, or if we weren't added to this hash in the first place } // Mark the queue as being recyclable producer->inactive.store(true, std::memory_order_release); } static void implicit_producer_thread_exited_callback(void* userData) { auto producer = static_cast(userData); auto queue = producer->parent; queue->implicit_producer_thread_exited(producer); } #endif ////////////////////////////////// // Utility functions ////////////////////////////////// template static inline U* create_array(size_t count) { assert(count > 0); auto p = static_cast((Traits::malloc)(sizeof(U) * count)); if (p == nullptr) { return nullptr; } for (size_t i = 0; i != count; ++i) { new (p + i) U(); } return p; } template static inline void destroy_array(U* p, size_t count) { if (p != nullptr) { assert(count > 0); for (size_t i = count; i != 0; ) { (p + --i)->~U(); } (Traits::free)(p); } } template static inline U* create() { auto p = (Traits::malloc)(sizeof(U)); return p != nullptr ? new (p) U : nullptr; } template static inline U* create(A1&& a1) { auto p = (Traits::malloc)(sizeof(U)); return p != nullptr ? new (p) U(std::forward(a1)) : nullptr; } template static inline void destroy(U* p) { if (p != nullptr) { p->~U(); } (Traits::free)(p); } private: std::atomic producerListTail; std::atomic producerCount; std::atomic initialBlockPoolIndex; Block* initialBlockPool; size_t initialBlockPoolSize; #if !MCDBGQ_USEDEBUGFREELIST FreeList freeList; #else debug::DebugFreeList freeList; #endif std::atomic implicitProducerHash; std::atomic implicitProducerHashCount; // Number of slots logically used ImplicitProducerHash initialImplicitProducerHash; std::array initialImplicitProducerHashEntries; std::atomic_flag implicitProducerHashResizeInProgress; std::atomic nextExplicitConsumerId; std::atomic globalExplicitConsumerOffset; #if MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH debug::DebugMutex implicitProdMutex; #endif #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG std::atomic explicitProducers; std::atomic implicitProducers; #endif }; template ProducerToken::ProducerToken(ConcurrentQueue& queue) : producer(queue.recycle_or_create_producer(true)) { if (producer != nullptr) { producer->token = this; } } template ProducerToken::ProducerToken(BlockingConcurrentQueue& queue) : producer(reinterpret_cast*>(&queue)->recycle_or_create_producer(true)) { if (producer != nullptr) { producer->token = this; } } template ConsumerToken::ConsumerToken(ConcurrentQueue& queue) : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr) { initialOffset = queue.nextExplicitConsumerId.fetch_add(1, std::memory_order_release); lastKnownGlobalOffset = -1; } template ConsumerToken::ConsumerToken(BlockingConcurrentQueue& queue) : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr) { initialOffset = reinterpret_cast*>(&queue)->nextExplicitConsumerId.fetch_add(1, std::memory_order_release); lastKnownGlobalOffset = -1; } template inline void swap(ConcurrentQueue& a, ConcurrentQueue& b) MOODYCAMEL_NOEXCEPT { a.swap(b); } inline void swap(ProducerToken& a, ProducerToken& b) MOODYCAMEL_NOEXCEPT { a.swap(b); } inline void swap(ConsumerToken& a, ConsumerToken& b) MOODYCAMEL_NOEXCEPT { a.swap(b); } template inline void swap(typename ConcurrentQueue::ImplicitProducerKVP& a, typename ConcurrentQueue::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT { a.swap(b); } } #if defined(__GNUC__) #pragma GCC diagnostic pop #endif ================================================ FILE: src/third_party/concurrentqueue/internal/concurrentqueue_internal_debug.h ================================================ #pragma once //#define MCDBGQ_TRACKMEM 1 //#define MCDBGQ_NOLOCKFREE_FREELIST 1 //#define MCDBGQ_USEDEBUGFREELIST 1 //#define MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX 1 //#define MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH 1 #if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__) #define WIN32_LEAN_AND_MEAN #include namespace moodycamel { namespace debug { struct DebugMutex { DebugMutex() { InitializeCriticalSectionAndSpinCount(&cs, 0x400); } ~DebugMutex() { DeleteCriticalSection(&cs); } void lock() { EnterCriticalSection(&cs); } void unlock() { LeaveCriticalSection(&cs); } private: CRITICAL_SECTION cs; }; } } #else #include namespace moodycamel { namespace debug { struct DebugMutex { void lock() { m.lock(); } void unlock() { m.unlock(); } private: std::mutex m; }; } } #define #endif namespace moodycamel { namespace debug { struct DebugLock { explicit DebugLock(DebugMutex& mutex) : mutex(mutex) { mutex.lock(); } ~DebugLock() { mutex.unlock(); } private: DebugMutex& mutex; }; template struct DebugFreeList { DebugFreeList() : head(nullptr) { } DebugFreeList(DebugFreeList&& other) : head(other.head) { other.head = nullptr; } void swap(DebugFreeList& other) { std::swap(head, other.head); } inline void add(N* node) { DebugLock lock(mutex); node->freeListNext = head; head = node; } inline N* try_get() { DebugLock lock(mutex); if (head == nullptr) { return nullptr; } auto prevHead = head; head = head->freeListNext; return prevHead; } N* head_unsafe() const { return head; } private: N* head; DebugMutex mutex; }; } } ================================================ FILE: src/third_party/concurrentqueue/samples.md ================================================ # Samples for moodycamel::ConcurrentQueue Here are some example usage scenarios with sample code. Note that most use the simplest version of each available method for demonstration purposes, but they can all be adapted to use tokens and/or the corresponding bulk methods for extra speed. ## Hello queue ```C++ ConcurrentQueue q; for (int i = 0; i != 123; ++i) q.enqueue(i); int item; for (int i = 0; i != 123; ++i) { q.try_dequeue(item); assert(item == i); } ``` ## Hello concurrency Basic example of how to use the queue from multiple threads, with no particular goal (i.e. it does nothing, but in an instructive way). ```C++ ConcurrentQueue q; int dequeued[100] = { 0 }; std::thread threads[20]; // Producers for (int i = 0; i != 10; ++i) { threads[i] = std::thread([&](int i) { for (int j = 0; j != 10; ++j) { q.enqueue(i * 10 + j); } }, i); } // Consumers for (int i = 10; i != 20; ++i) { threads[i] = std::thread([&]() { int item; for (int j = 0; j != 20; ++j) { if (q.try_dequeue(item)) { ++dequeued[item]; } } }); } // Wait for all threads for (int i = 0; i != 20; ++i) { threads[i].join(); } // Collect any leftovers (could be some if e.g. consumers finish before producers) int item; while (q.try_dequeue(item)) { ++dequeued[item]; } // Make sure everything went in and came back out! for (int i = 0; i != 100; ++i) { assert(dequeued[i] == 1); } ``` ## Bulk up Same as previous example, but runs faster. ```C++ ConcurrentQueue q; int dequeued[100] = { 0 }; std::thread threads[20]; // Producers for (int i = 0; i != 10; ++i) { threads[i] = std::thread([&](int i) { int items[10]; for (int j = 0; j != 10; ++j) { items[j] = i * 10 + j; } q.enqueue_bulk(items, 10); }, i); } // Consumers for (int i = 10; i != 20; ++i) { threads[i] = std::thread([&]() { int items[20]; for (std::size_t count = q.try_dequeue_bulk(items, 20); count != 0; --count) { ++dequeued[items[count - 1]]; } }); } // Wait for all threads for (int i = 0; i != 20; ++i) { threads[i].join(); } // Collect any leftovers (could be some if e.g. consumers finish before producers) int items[10]; std::size_t count; while ((count = q.try_dequeue_bulk(items, 10)) != 0) { for (std::size_t i = 0; i != count; ++i) { ++dequeued[items[i]]; } } // Make sure everything went in and came back out! for (int i = 0; i != 100; ++i) { assert(dequeued[i] == 1); } ``` ## Producer/consumer model (simultaneous) In this model, one set of threads is producing items, and the other is consuming them concurrently until all of them have been consumed. The counters are required to ensure that all items eventually get consumed. ```C++ ConcurrentQueue q; const int ProducerCount = 8; const int ConsumerCount = 8; std::thread producers[ProducerCount]; std::thread consumers[ConsumerCount]; std::atomic doneProducers(0); std::atomic doneConsumers(0); for (int i = 0; i != ProducerCount; ++i) { producers[i] = std::thread([&]() { while (produce) { q.enqueue(produceItem()); } doneProducers.fetch_add(1, std::memory_order_release); }); } for (int i = 0; i != ConsumerCount; ++i) { consumers[i] = std::thread([&]() { Item item; bool itemsLeft; do { // It's important to fence (if the producers have finished) *before* dequeueing itemsLeft = doneProducers.load(std::memory_order_acquire) != ProducerCount; while (q.try_dequeue(item)) { itemsLeft = true; consumeItem(item); } } while (itemsLeft || doneConsumers.fetch_add(1, std::memory_order_acq_rel) + 1 == ConsumerCount); // The condition above is a bit tricky, but it's necessary to ensure that the // last consumer sees the memory effects of all the other consumers before it // calls try_dequeue for the last time }); } for (int i = 0; i != ProducerCount; ++i) { producers[i].join(); } for (int i = 0; i != ConsumerCount; ++i) { consumers[i].join(); } ``` ## Producer/consumer model (simultaneous, blocking) The blocking version is different, since either the number of elements being produced needs to be known ahead of time, or some other coordination is required to tell the consumers when to stop calling wait_dequeue (not shown here). This is necessary because otherwise a consumer could end up blocking forever -- and destroying a queue while a consumer is blocking on it leads to undefined behaviour. ```C++ BlockingConcurrentQueue q; const int ProducerCount = 8; const int ConsumerCount = 8; std::thread producers[ProducerCount]; std::thread consumers[ConsumerCount]; std::atomic promisedElementsRemaining(ProducerCount * 1000); for (int i = 0; i != ProducerCount; ++i) { producers[i] = std::thread([&]() { for (int j = 0; j != 1000; ++j) { q.enqueue(produceItem()); } }); } for (int i = 0; i != ConsumerCount; ++i) { consumers[i] = std::thread([&]() { Item item; while (promisedElementsRemaining.fetch_sub(1, std::memory_order_relaxed)) { q.wait_dequeue(item); consumeItem(item); } }); } for (int i = 0; i != ProducerCount; ++i) { producers[i].join(); } for (int i = 0; i != ConsumerCount; ++i) { consumers[i].join(); } ``` ## Producer/consumer model (separate stages) ```C++ ConcurrentQueue q; // Production stage std::thread threads[8]; for (int i = 0; i != 8; ++i) { threads[i] = std::thread([&]() { while (produce) { q.enqueue(produceItem()); } }); } for (int i = 0; i != 8; ++i) { threads[i].join(); } // Consumption stage std::atomic doneConsumers(0); for (int i = 0; i != 8; ++i) { threads[i] = std::thread([&]() { Item item; do { while (q.try_dequeue(item)) { consumeItem(item); } // Loop again one last time if we're the last producer (with the acquired // memory effects of the other producers): } while (doneConsumers.fetch_add(1, std::memory_order_acq_rel) + 1 == 8); }); } for (int i = 0; i != 8; ++i) { threads[i].join(); } ``` Note that there's no point trying to use the blocking queue with this model, since there's no need to use the `wait` methods (all the elements are produced before any are consumed), and hence the complexity would be the same but with additional overhead. ## Object pool If you don't know what threads will be using the queue in advance, you can't really declare any long-term tokens. The obvious solution is to use the implicit methods (that don't take any tokens): ```C++ // A pool of 'Something' objects that can be safely accessed // from any thread class SomethingPool { public: Something getSomething() { Something obj; queue.try_dequeue(obj); // If the dequeue succeeded, obj will be an object from the // thread pool, otherwise it will be the default-constructed // object as declared above return obj; } void recycleSomething(Something&& obj) { queue.enqueue(std::move(obj)); } }; ``` ## Threadpool task queue ```C++ BlockingConcurrentQueue q; // To create a task from any thread: q.enqueue(...); // On threadpool threads: Task task; while (true) { q.wait_dequeue(task); // Process task... } ``` ## Multithreaded game loop ```C++ BlockingConcurrentQueue q; std::atomic pendingTasks(0); // On threadpool threads: Task task; while (true) { q.wait_dequeue(task); // Process task... pendingTasks.fetch_add(-1, std::memory_order_release); } // Whenever a new task needs to be processed for the frame: pendingTasks.fetch_add(1, std::memory_order_release); q.enqueue(...); // To wait for all the frame's tasks to complete before rendering: while (pendingTasks.load(std::memory_order_acquire) != 0) continue; // Alternatively you could help out the thread pool while waiting: while (pendingTasks.load(std::memory_order_acquire) != 0) { if (!q.try_dequeue(task)) { continue; } // Process task... pendingTasks.fetch_add(-1, std::memory_order_release); } ``` ## Pump until empty This might be useful if, for example, you want to process any remaining items in the queue before it's destroyed. Note that it is your responsibility to ensure that the memory effects of any enqueue operations you wish to see on the dequeue thread are visible (i.e. if you're waiting for a certain set of elements, you need to use memory fences to ensure that those elements are visible to the dequeue thread after they've been enqueued). ```C++ ConcurrentQueue q; // Single-threaded pumping: Item item; while (q.try_dequeue(item)) { // Process item... } // q is guaranteed to be empty here, unless there is another thread enqueueing still or // there was another thread dequeueing at one point and its memory effects have not // yet been propagated to this thread. // Multi-threaded pumping: std::thread threads[8]; std::atomic doneConsumers(0); for (int i = 0; i != 8; ++i) { threads[i] = std::thread([&]() { Item item; do { while (q.try_dequeue(item)) { // Process item... } } while (doneConsumers.fetch_add(1, std::memory_order_acq_rel) + 1 == 8); // If there are still enqueue operations happening on other threads, // then the queue may not be empty at this point. However, if all enqueue // operations completed before we finished pumping (and the propagation of // their memory effects too), and all dequeue operations apart from those // our threads did above completed before we finished pumping (and the // propagation of their memory effects too), then the queue is guaranteed // to be empty at this point. }); } for (int i = 0; i != 8; ++i) { threads[i].join(); } ``` ## Wait for a queue to become empty (without dequeueing) You can't (robustly) :-) However, you can set up your own atomic counter and poll that instead (see the game loop example). If you're satisfied with merely an estimate, you can use `size_approx()`. Note that `size_approx()` may return 0 even if the queue is not completely empty, unless the queue has already stabilized first (no threads are enqueueing or dequeueing, and all memory effects of any previous operations have been propagated to the thread before it calls `size_approx()`). ================================================ FILE: src/third_party/concurrentqueue/tests/CDSChecker/README.txt ================================================ These tests require CDSChecker to be checked out into a subdirectory named 'model-checker'. CDSChecker can be obtained from: git://demsky.eecs.uci.edu/model-checker.git The version last used for testing was: 5c4efe5cd8bdfe1e85138396109876a121ca61d1 ================================================ FILE: src/third_party/concurrentqueue/tests/CDSChecker/corealgo.h ================================================ // ©2013 Cameron Desrochers // Provides the core enqueue/dequeue algorithm of moodycamel::ConcurrentQueue // for testing with CDSChecker (a C++11 memory model checking tool). // See http://demsky.eecs.uci.edu/c11modelchecker.html for more info. #pragma once #include "model-checker/include/atomic" #include "model-checker/include/librace.h" #include "model-checker/include/model-assert.h" #ifndef CHAR_BIT #define CHAR_BIT 8 #endif typedef unsigned int index_t; static std::atomic headIndex; static std::atomic tailIndex; static std::atomic dequeueOvercommit; static std::atomic dequeueOptimisticCount; static const unsigned int BLOCK_SIZE = 256; static int block[BLOCK_SIZE]; static void init() { headIndex.store(0, std::memory_order_relaxed); tailIndex.store(0, std::memory_order_relaxed); dequeueOvercommit.store(0, std::memory_order_relaxed); dequeueOptimisticCount.store(0, std::memory_order_relaxed); } template static inline bool circular_less_than(T a, T b) { return static_cast(a - b) > static_cast(static_cast(1) << static_cast(sizeof(T) * CHAR_BIT - 1)); } static void enqueue(int element) { index_t currentTailIndex = tailIndex.load(std::memory_order_relaxed); index_t newTailIndex = 1 + currentTailIndex; store_32(&block[currentTailIndex & (BLOCK_SIZE - 1)], element); tailIndex.store(newTailIndex, std::memory_order_release); } static bool try_dequeue(int& element) { auto tail = tailIndex.load(std::memory_order_relaxed); auto overcommit = dequeueOvercommit.load(std::memory_order_relaxed); if (circular_less_than(dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit, tail)) { // Might be something to dequeue, let's give it a try // Note that this if is purely for performance purposes in the common case when the queue is // empty and the values are eventually consistent -- we may enter here spuriously. // Note that whatever the values of overcommit and tail are, they are not going to change (unless we // change them) and must be the same value at this point (inside the if) as when the if condition was // evaluated. // We insert an acquire fence here to synchronize-with the release upon incrementing dequeueOvercommit below. // This ensures that whatever the value we got loaded into overcommit, the load of dequeueOptisticCount in // the fetch_add below will result in a value at least as recent as that (and therefore at least as large). // Note that I believe a compiler (signal) fence here would be sufficient due to the nature of fetch_add (all // read-modify-write operations are guaranteed to work on the latest value in the modification order), but // unfortunately that can't be shown to be correct using only the C++11 standard. // See http://stackoverflow.com/questions/18223161/what-are-the-c11-memory-ordering-guarantees-in-this-corner-case std::atomic_thread_fence(std::memory_order_acquire); // Increment optimistic counter, then check if it went over the boundary auto myDequeueCount = dequeueOptimisticCount.fetch_add(1, std::memory_order_relaxed); // Note that since dequeueOvercommit must be <= dequeueOptimisticCount (because dequeueOvercommit is only ever // incremented after dequeueOptimisticCount -- this is enforced in the `else` block below), and since we now // have a version of dequeueOptimisticCount that is at least as recent as overcommit (due to the release upon // incrementing dequeueOvercommit and the acquire above that synchronizes with it), overcommit <= myDequeueCount. MODEL_ASSERT(overcommit <= myDequeueCount); // Note that we reload tail here in case it changed; it will be the same value as before or greater, since // this load is sequenced after (happens after) the earlier load above. This is supported by read-read // coherance (as defined in the standard), explained here: http://en.cppreference.com/w/cpp/atomic/memory_order auto newTail = tailIndex.load(std::memory_order_relaxed); MODEL_ASSERT(newTail >= tail); tail = newTail; if (circular_less_than(myDequeueCount - overcommit, tail)) { // Guaranteed to be at least one element to dequeue! // Get the index. Note that since there's guaranteed to be at least one element, this // will never exceed tail. auto index = headIndex.fetch_add(1, std::memory_order_relaxed); MODEL_ASSERT(index <= tail); // Dequeue element = load_32(&block[index & (BLOCK_SIZE - 1)]); return true; } else { // Wasn't anything to dequeue after all; make the effective dequeue count eventually consistent dequeueOvercommit.fetch_add(1, std::memory_order_release); // Release so that the fetch_add on dequeueOptimisticCount is guaranteed to happen before this write } } return false; } static int size_approx() { auto tail = tailIndex.load(std::memory_order_relaxed); auto head = headIndex.load(std::memory_order_relaxed); return circular_less_than(head, tail) ? static_cast(tail - head) : 0; } ================================================ FILE: src/third_party/concurrentqueue/tests/CDSChecker/enqueue_dequeue_many.cpp ================================================ // ©2013 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this file). #include "model-checker/include/threads.h" #include "corealgo.h" void thread_main(void* param) { int id = *(int*)param; int& dequeueCount = *(int*)param; dequeueCount = 0; int last[4] = { 0 }; enqueue((id << 24) | 1); enqueue((id << 24) | 2); int element; bool success = try_dequeue(element); if (success) { MODEL_ASSERT((element & 0xFFFFFF) > last[element >> 24]); last[element >> 24] = element & 0xFFFFFF; ++dequeueCount; } success = try_dequeue(element); if (success) { MODEL_ASSERT((element & 0xFFFFFF) > last[element >> 24]); last[element >> 24] = element & 0xFFFFFF; ++dequeueCount; } } int user_main(int, char**) { init(); // Start out as thread IDs, but are re-used by the threads // to indicate the number of elements each one dequeued int w = 1, x = 2, y = 3, z = 4; thrd_t a, b, c, d; thrd_create(&a, &thread_main, &w); thrd_create(&b, &thread_main, &x); thrd_create(&c, &thread_main, &y); thrd_create(&d, &thread_main, &z); thrd_join(a); thrd_join(b); thrd_join(c); thrd_join(d); MODEL_ASSERT(w + x + y + z + size_approx() == 8); return 0; } ================================================ FILE: src/third_party/concurrentqueue/tests/CDSChecker/enqueue_dequeue_one.cpp ================================================ // ©2013 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this file). #include "model-checker/include/threads.h" #include "corealgo.h" void producer_thread(void*) { enqueue(1234); } void consumer_thread(void*) { int element; bool result = try_dequeue(element); MODEL_ASSERT(!result || element == 1234); if (result) { MODEL_ASSERT(!try_dequeue(element)); } } int user_main(int, char**) { init(); thrd_t p, c; thrd_create(&p, &producer_thread, nullptr); thrd_create(&c, &consumer_thread, nullptr); thrd_join(p); thrd_join(c); return 0; } ================================================ FILE: src/third_party/concurrentqueue/tests/common/simplethread.cpp ================================================ // ©2013 Cameron Desrochers #include "simplethread.h" #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include struct SimpleThread::ThreadRef { HANDLE handle; static DWORD WINAPI ThreadProc(LPVOID param) { auto threadRef = static_cast(param); threadRef->callbackFunc(threadRef->callbackObj); return 0; } ThreadRef(void* callbackObj, CallbackFunc callbackFunc) : callbackObj(callbackObj), callbackFunc(callbackFunc) { } void* callbackObj; CallbackFunc callbackFunc; }; void SimpleThread::startThread(void* callbackObj, CallbackFunc callbackFunc) { thread = new ThreadRef(callbackObj, callbackFunc); thread->handle = CreateThread(NULL, StackSize, &ThreadRef::ThreadProc, thread, 0, NULL); } void SimpleThread::join() { if (thread != nullptr && thread->handle != NULL) { WaitForSingleObject(thread->handle, INFINITE); CloseHandle(thread->handle); thread->handle = NULL; } } #else #include struct SimpleThread::ThreadRef { std::thread thread; static void threadProc(ThreadRef* threadRef) { threadRef->callbackFunc(threadRef->callbackObj); } ThreadRef(void* callbackObj, CallbackFunc callbackFunc) : callbackObj(callbackObj), callbackFunc(callbackFunc) { } void* callbackObj; CallbackFunc callbackFunc; }; void SimpleThread::startThread(void* callbackObj, CallbackFunc callbackFunc) { thread = new ThreadRef(callbackObj, callbackFunc); thread->thread = std::thread(&ThreadRef::threadProc, thread); } void SimpleThread::join() { if (thread != nullptr && thread->thread.joinable()) { thread->thread.join(); } } #endif SimpleThread::~SimpleThread() { if (thread != nullptr) { join(); delete thread; } } ================================================ FILE: src/third_party/concurrentqueue/tests/common/simplethread.h ================================================ // ©2013 Cameron Desrochers #pragma once // Like C++11's std::thread, but with a reduced API, and works on Windows with MSVC2010+. // Wraps std::thread on other OSes. Perhaps the most significant departure between // std::thread and this mini-library is that join() is called implicitly in the destructor, // if the thread is joinable. The thread callback functions should not throw exceptions. #include #include namespace details { template struct ArgWrapper { typename std::remove_reference::type arg1; typename std::remove_reference::type arg2; typename std::remove_reference::type arg3; ArgWrapper(ArgWrapper const& o) : arg1(o.arg1), arg2(o.arg2), arg3(o.arg3) { } ArgWrapper(ArgWrapper&& o) : arg1(std::move(o.arg1)), arg2(std::move(o.arg2)), arg3(std::move(o.arg3)) { } template ArgWrapper(T&& a1, U&& a2, V&& a3) : arg1(std::forward(a1)), arg2(std::forward(a2)), arg3(std::forward(a3)) { } template void callCallback(TCallback&& callback) const { std::forward(callback)(std::move(arg1), std::move(arg2), std::move(arg3)); } }; template struct ArgWrapper { typename std::remove_reference::type arg1; typename std::remove_reference::type arg2; ArgWrapper(ArgWrapper const& o) : arg1(o.arg1), arg2(o.arg2) { } ArgWrapper(ArgWrapper&& o) : arg1(std::move(o.arg1)), arg2(std::move(o.arg2)) { } template ArgWrapper(T&& a1, U&& a2) : arg1(std::forward(a1)), arg2(std::forward(a2)) { } template void callCallback(TCallback&& callback) const { std::forward(callback)(std::move(arg1), std::move(arg2)); } }; template struct ArgWrapper { typename std::remove_reference::type arg1; ArgWrapper(ArgWrapper const& o) : arg1(o.arg1) { } ArgWrapper(ArgWrapper&& o) : arg1(std::move(o.arg1)) { } template ArgWrapper(T&& a1) : arg1(std::forward(a1)) { } template void callCallback(TCallback&& callback) const { std::forward(callback)(std::move(arg1)); } }; template<> struct ArgWrapper { template void callCallback(TCallback&& callback) const { std::forward(callback)(); } }; } class SimpleThread { private: struct ThreadRef; template struct CallbackWrapper { template CallbackWrapper(TCallback&& callback, U&& args) : callback(std::forward(callback)), args(std::forward(args)) { } static void callAndDelete(void* wrapper) { auto typedWrapper = static_cast(wrapper); typedWrapper->args.callCallback(std::move(typedWrapper->callback)); delete typedWrapper; } typename std::decay::type callback; TArgs args; }; typedef void (*CallbackFunc)(void*); void startThread(void* callbackObj, CallbackFunc callbackFunc); public: static const int StackSize = 4 * 1024; // bytes SimpleThread() : thread(nullptr) { } SimpleThread(SimpleThread&& other) : thread(other.thread) { other.thread = nullptr; } SimpleThread& operator=(SimpleThread&& other) { thread = other.thread; other.thread = nullptr; return *this; } // Disable copying and copy-assignment private: SimpleThread(SimpleThread const&); SimpleThread& operator=(SimpleThread const&); public: template explicit SimpleThread(TCallback&& callback) { auto wrapper = new CallbackWrapper>( std::forward(callback), ::details::ArgWrapper<>() ); startThread(wrapper, &CallbackWrapper>::callAndDelete); } template explicit SimpleThread(TCallback&& callback, TArg1&& arg1) { auto wrapper = new CallbackWrapper>( std::forward(callback), ::details::ArgWrapper(std::forward(arg1)) ); startThread(wrapper, &CallbackWrapper>::callAndDelete); } template explicit SimpleThread(TCallback&& callback, TArg1&& arg1, TArg2&& arg2) { auto wrapper = new CallbackWrapper>( std::forward(callback), ::details::ArgWrapper(std::forward(arg1), std::forward(arg2)) ); startThread(wrapper, &CallbackWrapper>::callAndDelete); } template explicit SimpleThread(TCallback&& callback, TArg1&& arg1, TArg2&& arg2, TArg3&& arg3) { auto wrapper = new CallbackWrapper>( std::forward(callback), ::details::ArgWrapper(std::forward(arg1), std::forward(arg2), std::forward(arg3)) ); startThread(wrapper, &CallbackWrapper>::callAndDelete); } ~SimpleThread(); void join(); private: ThreadRef* thread; }; ================================================ FILE: src/third_party/concurrentqueue/tests/common/systemtime.cpp ================================================ // ©2013-2014 Cameron Desrochers #include "systemtime.h" #include #if defined(_MSC_VER) && _MSC_VER < 1700 #include #define CompilerMemBar() _ReadWriteBarrier() #else #include #define CompilerMemBar() std::atomic_signal_fence(std::memory_order_seq_cst) #endif #if defined(ST_WINDOWS) #include namespace moodycamel { void sleep(int milliseconds) { ::Sleep(milliseconds); } SystemTime getSystemTime() { LARGE_INTEGER t; CompilerMemBar(); if (!QueryPerformanceCounter(&t)) { return static_cast(-1); } CompilerMemBar(); return static_cast(t.QuadPart); } double getTimeDelta(SystemTime start) { LARGE_INTEGER t; CompilerMemBar(); if (start == static_cast(-1) || !QueryPerformanceCounter(&t)) { return -1; } CompilerMemBar(); auto now = static_cast(t.QuadPart); LARGE_INTEGER f; if (!QueryPerformanceFrequency(&f)) { return -1; } #if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif return static_cast(static_cast<__int64>(now - start)) / f.QuadPart * 1000; #if defined(__GNUC__) #pragma GCC diagnostic pop #endif } } // end namespace moodycamel #elif defined(ST_APPLE) #include #include #include #include namespace moodycamel { void sleep(int milliseconds) { ::usleep(milliseconds * 1000); } SystemTime getSystemTime() { CompilerMemBar(); std::uint64_t result = mach_absolute_time(); CompilerMemBar(); return result; } double getTimeDelta(SystemTime start) { CompilerMemBar(); std::uint64_t end = mach_absolute_time(); CompilerMemBar(); mach_timebase_info_data_t tb = { 0 }; mach_timebase_info(&tb); double toNano = static_cast(tb.numer) / tb.denom; return static_cast(end - start) * toNano * 0.000001; } } // end namespace moodycamel #elif defined(ST_NIX) #include namespace moodycamel { void sleep(int milliseconds) { ::usleep(milliseconds * 1000); } SystemTime getSystemTime() { timespec t; CompilerMemBar(); if (clock_gettime(CLOCK_MONOTONIC_RAW, &t) != 0) { t.tv_sec = (time_t)-1; t.tv_nsec = -1; } CompilerMemBar(); return t; } double getTimeDelta(SystemTime start) { timespec t; CompilerMemBar(); if ((start.tv_sec == (time_t)-1 && start.tv_nsec == -1) || clock_gettime(CLOCK_MONOTONIC_RAW, &t) != 0) { return -1; } CompilerMemBar(); return static_cast(static_cast(t.tv_sec) - static_cast(start.tv_sec)) * 1000 + double(t.tv_nsec - start.tv_nsec) / 1000000; } } // end namespace moodycamel #endif ================================================ FILE: src/third_party/concurrentqueue/tests/common/systemtime.h ================================================ // ©2013-2014 Cameron Desrochers #pragma once #if defined(_WIN32) #define ST_WINDOWS #elif defined(__APPLE__) && defined(__MACH__) #define ST_APPLE #elif defined(__linux__) || defined(__FreeBSD__) || defined(BSD) #define ST_NIX #else #error "Unknown platform" #endif #if defined(ST_WINDOWS) namespace moodycamel { typedef unsigned long long SystemTime; } #elif defined(ST_APPLE) #include namespace moodycamel { typedef std::uint64_t SystemTime; } #elif defined(ST_NIX) #include namespace moodycamel { typedef timespec SystemTime; } #endif namespace moodycamel { void sleep(int milliseconds); SystemTime getSystemTime(); // Returns the delta time, in milliseconds double getTimeDelta(SystemTime start); } ================================================ FILE: src/third_party/concurrentqueue/tests/corealgos.h ================================================ // ©2014 Cameron Desrochers // moodycamel::ConcurrentQueue contains many inner data structures which // are difficult to test in isolation. So, this file contains copies of // them, extracted and isolated so as to be independently testable. #pragma once #include #include #include #include #include #include #include // Define corealgos_allocator before including this header in order to override the // default malloc/free functions #ifndef corealgos_allocator struct corealgos_allocator { static inline void* malloc(std::size_t size) { return std::malloc(size); } static inline void free(void* ptr) { std::free(ptr); } }; #endif //////////////////////////////////////////////////////////////////////////////// // Lock-free add-only list (e.g. used to track producers) //////////////////////////////////////////////////////////////////////////////// namespace moodycamel { namespace corealgos { struct ListItem { ListItem() : concurrentListPrev(nullptr) { } public: std::atomic concurrentListPrev; }; template // T should inherit ListItem or implement the same interface struct ConcurrentAddOnlyList { ConcurrentAddOnlyList() : tail_(nullptr) { } inline T* tail() { return tail_.load(std::memory_order_acquire); } void add(T* element) { assert(element != nullptr); // Add it to the lock-free list auto prevTail = tail_.load(std::memory_order_relaxed); do { element->concurrentListPrev = prevTail; } while (!tail_.compare_exchange_weak(prevTail, element, std::memory_order_release, std::memory_order_relaxed)); } private: std::atomic tail_; }; } } //////////////////////////////////////////////////////////////////////////////// // Thread local hash map //////////////////////////////////////////////////////////////////////////////// #if defined(__APPLE__) #include "TargetConditionals.h" // Needed for TARGET_OS_IPHONE #endif // Platform-specific definitions of a numeric thread ID type and an invalid value #if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__) // No sense pulling in windows.h in a header, we'll manually declare the function // we use and rely on backwards-compatibility for this not to break extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); namespace moodycamel { namespace corealgos { namespace details { static_assert(sizeof(unsigned long) == sizeof(std::uint32_t), "Expected size of unsigned long to be 32 bits on Windows"); typedef std::uint32_t thread_id_t; static const thread_id_t invalid_thread_id = 0; // See http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx static inline thread_id_t thread_id() { return static_cast(::GetCurrentThreadId()); } } } } #elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE) namespace moodycamel { namespace corealgos { namespace details { typedef std::uintptr_t thread_id_t; static const thread_id_t invalid_thread_id = 0; static inline thread_id_t thread_id() { return std::hash()(std::this_thread::get_id()); } } } } #else // Use a nice trick from this answer: http://stackoverflow.com/a/8438730/21475 // In order to get a numeric thread ID in a platform-independent way, we use a thread-local // static variable's address as a thread identifier :-) #if defined(__GNUC__) || defined(__INTEL_COMPILER) #define MOODYCAMEL_COREALGO_THREADLOCAL __thread #elif defined(_MSC_VER) #define MOODYCAMEL_COREALGO_THREADLOCAL __declspec(thread) #else // Assume C++11 compliant compiler #define MOODYCAMEL_COREALGO_THREADLOCAL thread_local #endif namespace moodycamel { namespace corealgos { namespace details { typedef std::uintptr_t thread_id_t; static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr static inline thread_id_t thread_id() { static MOODYCAMEL_COREALGO_THREADLOCAL int x; return reinterpret_cast(&x); } } } } #endif namespace moodycamel { namespace corealgos { namespace details { template struct _hash_32_or_64 { static inline std::size_t hash(std::uint32_t h) { // MurmurHash3 finalizer -- see https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp // Since the thread ID is already unique, all we really want to do is propagate that // uniqueness evenly across all the bits, so that we can use a subset of the bits while // reducing collisions significantly h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; return static_cast(h ^ (h >> 16)); } }; template<> struct _hash_32_or_64<1> { static inline std::size_t hash(std::uint64_t h) { h ^= h >> 33; h *= 0xff51afd7ed558ccd; h ^= h >> 33; h *= 0xc4ceb9fe1a85ec53; return static_cast(h ^ (h >> 33)); } }; template struct hash_32_or_64 : public _hash_32_or_64<(size > 4)> { }; static inline std::size_t hash_thread_id(thread_id_t id) { static_assert(sizeof(thread_id_t) <= 8, "Expected a platform where thread IDs are at most 64-bit values"); return hash_32_or_64::hash(id); } template static inline char* align_for(char* ptr) { const std::size_t alignment = std::alignment_of::value; return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment; } } template // T should inherit ListItem or implement the same interface struct ThreadLocal { explicit ThreadLocal(std::size_t initialHashSize) : initialHashEntries(initialHashSize) { assert(initialHashSize > 0 && (initialHashSize & (initialHashSize - 1)) == 0); resizeInProgress.clear(); currentHashCount.store(0, std::memory_order_relaxed); auto hash = &initialHash; hash->capacity = initialHashSize; hash->entries = &initialHashEntries[0]; for (std::size_t i = 0; i != initialHashSize; ++i) { initialHashEntries[i].key.store(details::invalid_thread_id, std::memory_order_relaxed); } hash->prev = nullptr; currentHash.store(hash, std::memory_order_relaxed); } ~ThreadLocal() { // Destroy items auto ptr = items.tail(); while (ptr != nullptr) { auto prev = static_cast(ptr->concurrentListPrev.load(std::memory_order_relaxed)); ptr->~T(); corealgos_allocator::free(ptr); ptr = prev; } // Destroy hash tables auto hash = currentHash.load(std::memory_order_relaxed); while (hash != nullptr) { auto prev = hash->prev; if (prev != nullptr) { // The last hash is part of this object and was not allocated dynamically for (std::size_t i = 0; i != hash->capacity; ++i) { hash->entries[i].~KeyValuePair(); } hash->~InnerHash(); corealgos_allocator::free(hash); } hash = prev; } } // Only fails (returns nullptr) if memory allocation fails T* get_or_create() { // Note that since the data is essentially thread-local (key is thread ID), // there's a reduced need for fences (memory ordering is already consistent // for any individual thread), except for the current table itself // Start by looking for the thread ID in the current and all previous hash tables. // If it's not found, it must not be in there yet, since this same thread would // have added it previously to one of the tables that we traversed. // Code and algorithm adapted from http://preshing.com/20130605/the-worlds-simplest-lock-free-hash-table auto id = details::thread_id(); auto hashedId = details::hash_thread_id(id); auto mainHash = currentHash.load(std::memory_order_acquire); for (auto hash = mainHash; hash != nullptr; hash = hash->prev) { // Look for the id in this hash auto index = hashedId; while (true) { // Not an infinite loop because at least one slot is free in the hash table index &= hash->capacity - 1; auto probedKey = hash->entries[index].key.load(std::memory_order_relaxed); if (probedKey == id) { // Found it! If we had to search several hashes deep, though, we should lazily add it // to the current main hash table to avoid the extended search next time. // Note there's guaranteed to be room in the current hash table since every subsequent // table implicitly reserves space for all previous tables (there's only one // currentHashCount). auto value = hash->entries[index].value; if (hash != mainHash) { index = hashedId; while (true) { index &= mainHash->capacity - 1; probedKey = mainHash->entries[index].key.load(std::memory_order_relaxed); auto expected = details::invalid_thread_id; if (probedKey == expected && mainHash->entries[index].key.compare_exchange_strong(expected, id, std::memory_order_relaxed)) { mainHash->entries[index].value = value; break; } ++index; } } return value; } if (probedKey == details::invalid_thread_id) { break; // Not in this hash table } ++index; } } // Insert! auto newCount = 1 + currentHashCount.fetch_add(1, std::memory_order_relaxed); while (true) { if (newCount >= (mainHash->capacity >> 1) && !resizeInProgress.test_and_set(std::memory_order_acquire)) { // We've acquired the resize lock, try to allocate a bigger hash table. // Note the acquire fence synchronizes with the release fence at the end of this block, and hence when // we reload currentHash it must be the most recent version (it only gets changed within this // locked block). mainHash = currentHash.load(std::memory_order_acquire); auto newCapacity = mainHash->capacity << 1; while (newCount >= (newCapacity >> 1)) { newCapacity <<= 1; } auto raw = static_cast(corealgos_allocator::malloc(sizeof(InnerHash) + std::alignment_of::value - 1 + sizeof(KeyValuePair) * newCapacity)); if (raw == nullptr) { // Allocation failed currentHashCount.fetch_add(-1, std::memory_order_relaxed); resizeInProgress.clear(std::memory_order_relaxed); return nullptr; } auto newHash = new (raw) InnerHash; newHash->capacity = newCapacity; newHash->entries = reinterpret_cast(details::align_for(raw + sizeof(InnerHash))); for (std::size_t i = 0; i != newCapacity; ++i) { new (newHash->entries + i) KeyValuePair; newHash->entries[i].key.store(details::invalid_thread_id, std::memory_order_relaxed); } newHash->prev = mainHash; currentHash.store(newHash, std::memory_order_release); resizeInProgress.clear(std::memory_order_release); mainHash = newHash; } // If it's < three-quarters full, add to the old one anyway so that we don't have to wait for the next table // to finish being allocated by another thread (and if we just finished allocating above, the condition will // always be true) if (newCount < (mainHash->capacity >> 1) + (mainHash->capacity >> 2)) { auto element = (T*)corealgos_allocator::malloc(sizeof(T)); if (element == nullptr) { return nullptr; } new (element) T(); items.add(element); // Track items so they can be destructed later auto index = hashedId; while (true) { index &= mainHash->capacity - 1; auto probedKey = mainHash->entries[index].key.load(std::memory_order_relaxed); auto expected = details::invalid_thread_id; if (probedKey == expected && mainHash->entries[index].key.compare_exchange_strong(expected, id, std::memory_order_relaxed)) { mainHash->entries[index].value = element; break; } ++index; } return element; } // Hmm, the old hash is quite full and somebody else is busy allocating a new one. // We need to wait for the allocating thread to finish (if it succeeds, we add, if not, // we try to allocate ourselves). mainHash = currentHash.load(std::memory_order_acquire); } } private: struct KeyValuePair { std::atomic key; T* value; // No need for atomicity since it's only read by the thread that sets it in the first place KeyValuePair() { } KeyValuePair(KeyValuePair const& other) : key(other.key.load()), value(other.value) { } KeyValuePair& operator=(KeyValuePair const& other) { key.store(other.key.load()); value = other.value; return *this; } }; struct InnerHash { std::size_t capacity; KeyValuePair* entries; InnerHash* prev; }; std::atomic_flag resizeInProgress; std::atomic currentHash; std::atomic currentHashCount; // Number of slots logically used InnerHash initialHash; std::vector initialHashEntries; ConcurrentAddOnlyList items; }; //////////////////////////////////////////////////////////////////////////////// // Lock-free free list //////////////////////////////////////////////////////////////////////////////// template struct FreeListNode { FreeListNode() : freeListRefs(0), freeListNext(nullptr) { } std::atomic freeListRefs; std::atomic freeListNext; FreeListNode(FreeListNode const& other) : freeListRefs(other.freeListRefs.load()), freeListNext(other.freeListNext.load()) { } FreeListNode& operator=(FreeListNode const& other) { freeListRefs.store(other.freeListRefs.load()); freeListNext.store(other.freeListNext.load()); return *this; } }; // A simple CAS-based lock-free free list. Not the fastest thing in the world under heavy contention, // but simple and correct (assuming nodes are never freed until after the free list is destroyed), // and fairly speedy under low contention. template // N must inherit FreeListNode or have the same fields (and initialization) struct FreeList { FreeList() : freeListHead(nullptr) { } inline void add(N* node) { // We know that the should-be-on-freelist bit is 0 at this point, so it's safe to // set it using a fetch_add if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST, std::memory_order_acq_rel) == 0) { // Oh look! We were the last ones referencing this node, and we know // we want to add it to the free list, so let's do it! add_knowing_refcount_is_zero(node); } } inline N* try_get() { auto head = freeListHead.load(std::memory_order_acquire); while (head != nullptr) { auto prevHead = head; auto refs = head->freeListRefs.load(std::memory_order_relaxed); if ((refs & REFS_MASK) == 0 || !head->freeListRefs.compare_exchange_strong(refs, refs + 1, std::memory_order_acquire, std::memory_order_relaxed)) { head = freeListHead.load(std::memory_order_acquire); continue; } // Good, reference count has been incremented (it wasn't at zero), which means // we can read the next and not worry about it changing between now and the time // we do the CAS auto next = head->freeListNext.load(std::memory_order_relaxed); if (freeListHead.compare_exchange_strong(head, next, std::memory_order_acquire, std::memory_order_relaxed)) { // Yay, got the node. This means it was on the list, which means // shouldBeOnFreeList must be false no matter the refcount (because // nobody else knows it's been taken off yet, it can't have been put back on). assert((head->freeListRefs.load(std::memory_order_relaxed) & SHOULD_BE_ON_FREELIST) == 0); // Decrease refcount twice, once for our ref, and once for the list's ref head->freeListRefs.fetch_add(-2, std::memory_order_release); return head; } // OK, the head must have changed on us, but we still need to decrease the refcount we // increased. // Note that we don't need to release any memory effects, but we do need to ensure that the reference // count decrement happens-after the CAS on the head. refs = prevHead->freeListRefs.fetch_add(-1, std::memory_order_acq_rel); if (refs == SHOULD_BE_ON_FREELIST + 1) { add_knowing_refcount_is_zero(prevHead); } } return nullptr; } // Useful for traversing the list when there's no contention (e.g. to destroy remaining nodes) N* head_unsafe() const { return freeListHead.load(std::memory_order_relaxed); } private: inline void add_knowing_refcount_is_zero(N* node) { // Since the refcount is zero, and nobody can increase it once it's zero (except us, and we // run only one copy of this method per node at a time, i.e. the single thread case), then we // know we can safely change the next pointer of the node; however, once the refcount is back // above zero, then other threads could increase it (happens under heavy contention, when the // refcount goes to zero in between a load and a refcount increment of a node in try_get, then // back up to something non-zero, then the refcount increment is done by the other thread) -- // so, if the CAS to add the node to the actual list fails, decrease the refcount and leave // the add operation to the next thread who puts the refcount back at zero (which could be us, // hence the loop). auto head = freeListHead.load(std::memory_order_relaxed); while (true) { node->freeListNext.store(head, std::memory_order_relaxed); node->freeListRefs.store(1, std::memory_order_release); if (!freeListHead.compare_exchange_strong(head, node, std::memory_order_release, std::memory_order_relaxed)) { // Hmm, the add failed, but we can only try again when the refcount goes back to zero if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST - 1, std::memory_order_release) == 1) { continue; } } return; } } private: static const std::uint32_t REFS_MASK = 0x7FFFFFFF; static const std::uint32_t SHOULD_BE_ON_FREELIST = 0x80000000; // Implemented like a stack, but where node order doesn't matter (nodes are // inserted out of order under contention) std::atomic freeListHead; }; //////////////////////////////////////////////////////////////////////////////// // Lock-free (single-producer, multi-consumer) numeric-key hash map of sorts; // there are many conditions that must be met, i.e. items have to be inserted // in increasing order by key (wrap-around is OK), and items cannot be searched // for or removed unless they are known to be in the map in the first place. //////////////////////////////////////////////////////////////////////////////// template struct SPMCSequentialHashMap { explicit SPMCSequentialHashMap(std::size_t initialSize) : nextCapacity(initialSize), index(nullptr) { new_index(); } ~SPMCSequentialHashMap() { auto ptr = index.load(std::memory_order_relaxed); if (ptr != nullptr) { for (std::size_t i = 0; i != ptr->capacity; ++i) { ptr->index[i]->~IndexEntry(); } do { auto prev = ptr->prev; ptr->~IndexHeader(); corealgos_allocator::free(ptr); ptr = prev; } while (ptr != nullptr); } } // Not thread safe. Only call from single producer thread. // Note: key must *not* be in hash already, and must be exactly // one larger than the previously inserted key value. void insert(std::uint64_t key, TValue* value) { IndexEntry* idxEntry; insert_index_entry(idxEntry, key); idxEntry->value.store(value, std::memory_order_release); } // Thread-safe, but if somebody can remove the key while find() is // in progress, then any returned value is not guaranteed to correspond // to that key. This also applies if the key was not already present but // once was. Elements can be found in any order. TValue* find(std::uint64_t key) { auto idxEntry = get_entry_for_key(key); if (idxEntry == nullptr) return nullptr; return idxEntry->value.load(std::memory_order_acquire); } // Thread-safe, but if somebody else can remove the same key while remove() // is in progress, then any removed value is not guaranteed to correspond // to that key This also applies if the key was not already present but // once was. Elements can be removed in an order. TValue* remove(std::uint64_t key) { auto idxEntry = get_entry_for_key(key); if (idxEntry == nullptr) return nullptr; TValue* val = nullptr; while (!idxEntry->value.compare_exchange_weak(val, nullptr, std::memory_order_acquire, std::memory_order_relaxed)) continue; return val; } private: struct IndexEntry { std::atomic key; std::atomic value; }; struct IndexHeader { std::size_t capacity; std::atomic tail; IndexEntry* entries; IndexEntry** index; IndexHeader* prev; }; inline void insert_index_entry(IndexEntry*& idxEntry, std::uint64_t key) { auto localIndex = index.load(std::memory_order_relaxed); // We're the only writer thread, relaxed is OK auto newTail = (localIndex->tail.load(std::memory_order_relaxed) + 1) & (localIndex->capacity - 1); idxEntry = localIndex->index[newTail]; if (idxEntry->key.load(std::memory_order_relaxed) == INVALID_KEY || idxEntry->value.load(std::memory_order_relaxed) == nullptr) { idxEntry->key.store(key, std::memory_order_relaxed); localIndex->tail.store(newTail, std::memory_order_release); return; } // No room in the old index, try to allocate another one! new_index(); localIndex = index.load(std::memory_order_relaxed); newTail = (localIndex->tail.load(std::memory_order_relaxed) + 1) & (localIndex->capacity - 1); idxEntry = localIndex->index[newTail]; assert(idxEntry->key.load(std::memory_order_relaxed) == INVALID_KEY); idxEntry->key.store(key, std::memory_order_relaxed); localIndex->tail.store(newTail, std::memory_order_release); } inline IndexEntry* get_entry_for_key(std::uint64_t key) const { auto localIndex = index.load(std::memory_order_acquire); auto tail = localIndex->tail.load(std::memory_order_acquire); auto tailBase = localIndex->index[tail]->key.load(std::memory_order_relaxed); if (tailBase == INVALID_KEY) { return nullptr; } auto offset = static_cast(key - tailBase); std::size_t idx = (tail + offset) & (localIndex->capacity - 1); auto entry = localIndex->index[idx]; return entry->key.load(std::memory_order_relaxed) == key ? entry : nullptr; } bool new_index() { auto prev = index.load(std::memory_order_relaxed); std::size_t prevCapacity = prev == nullptr ? 0 : prev->capacity; auto entryCount = prev == nullptr ? nextCapacity : prevCapacity; auto raw = static_cast(corealgos_allocator::malloc( sizeof(IndexHeader) + std::alignment_of::value - 1 + sizeof(IndexEntry) * entryCount + std::alignment_of::value - 1 + sizeof(IndexEntry*) * nextCapacity)); if (raw == nullptr) { return false; } auto header = new (raw) IndexHeader; auto entries = reinterpret_cast(details::align_for(raw + sizeof(IndexHeader))); auto idx = reinterpret_cast(details::align_for(reinterpret_cast(entries) + sizeof(IndexEntry) * entryCount)); if (prev != nullptr) { auto prevTail = prev->tail.load(std::memory_order_relaxed); auto prevPos = prevTail; std::size_t i = 0; do { prevPos = (prevPos + 1) & (prev->capacity - 1); idx[i++] = prev->index[prevPos]; } while (prevPos != prevTail); assert(i == prevCapacity); } for (std::size_t i = 0; i != entryCount; ++i) { new (entries + i) IndexEntry; entries[i].key.store(INVALID_KEY, std::memory_order_relaxed); entries[i].value.store(nullptr, std::memory_order_relaxed); idx[prevCapacity + i] = entries + i; } header->prev = prev; header->entries = entries; header->index = idx; header->capacity = nextCapacity; header->tail.store((prevCapacity - 1) & (nextCapacity - 1), std::memory_order_relaxed); index.store(header, std::memory_order_release); nextCapacity <<= 1; return true; } private: std::size_t nextCapacity; std::atomic index; static const std::uint64_t INVALID_KEY = ~(std::uint64_t)0; }; } } ================================================ FILE: src/third_party/concurrentqueue/tests/fuzztests/fuzztests.cpp ================================================ // ©2013-2014 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this file). // Fuzz (random) tests for moodycamel::ConcurrentQueue #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #ifndef NOMINMAX #define NOMINMAX #endif #include #endif #include "../../concurrentqueue.h" #include "../common/simplethread.h" #include "../common/systemtime.h" #include "../corealgos.h" void failHook() { (void)1; // Attach debuggers here } #define _STR(x) #x #define STR(x) _STR(x) #define ASSERT_OR_FAIL_THREAD(cond) if (!(cond)) { const char* n = nullptr; failReason.compare_exchange_strong(n, "assertion failed on line " STR(__LINE__) ": " #cond, std::memory_order_relaxed, std::memory_order_relaxed); \ failed.store(true, std::memory_order_relaxed); failHook(); return; } #define FAIL_IF_THREAD_TIMEOUT() if (getTimeDelta(startTime) > 60000) { const char* n = nullptr; failReason.compare_exchange_strong(n, "test timed out (detected on line " STR(__LINE__) ")", std::memory_order_relaxed, std::memory_order_relaxed); \ failed.store(true, std::memory_order_relaxed); failHook(); return; } #define ASSERT_OR_FAIL(cond) if (!(cond)) { out_failReason = "assertion failed on line " STR(__LINE__) ": " #cond; result = false; failHook(); break; } using namespace moodycamel; typedef std::minstd_rand RNG_t; enum test_type { multithread_produce, multithread_consume, multithread_produce_and_consume, completely_random, // Core algo tests core_add_only_list, core_thread_local, TEST_TYPE_COUNT }; std::uint64_t test_count[TEST_TYPE_COUNT] = { 0 }; std::uint64_t fail_count[TEST_TYPE_COUNT] = { 0 }; const char* test_names[TEST_TYPE_COUNT] = { "multithread_produce", "multithread_consume", "multithread_produce_and_consume", "completely_random", "core_add_only_list", "core_thread_local", }; const int SINGLE_SEED_ITERATIONS = 100; const char* LOG_FILE = "fuzztests.log"; struct FuzzTraits : public ConcurrentQueueDefaultTraits { static const size_t BLOCK_SIZE = 8; static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 4; static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 4; static const size_t INITIAL_IMPLCICIT_PRODUCER_HASH_SIZE = 1; static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 24; }; struct TestListItem : corealgos::ListItem { int value; TestListItem() : value(0) { } explicit TestListItem(int value) : value(value) { } inline TestListItem* prev(std::memory_order order = std::memory_order_relaxed) const { return static_cast(concurrentListPrev.load(order)); } }; bool run_test(uint64_t seed, int iterations, test_type& out_type, const char*& out_failReason) { bool result = true; RNG_t baseRng((unsigned int)seed); std::uniform_int_distribution randTest(0, TEST_TYPE_COUNT - 1); std::uniform_int_distribution randInitialSize(0, 70); auto type = static_cast(randTest(baseRng)); out_type = type; for (int iteration = 0; iteration != iterations; ++iteration) { RNG_t rng(baseRng); std::atomic failed(false); std::atomic failReason; failReason = nullptr; SystemTime startTime = getSystemTime(); switch (type) { case multithread_produce: { const int countIncrement = std::uniform_int_distribution(1, 1000)(rng); int count = std::uniform_int_distribution(0, 500)(rng) * countIncrement; int prodCount = std::uniform_int_distribution(0, 6)(rng); bool useConsumerToken = static_cast(std::uniform_int_distribution(0, 1)(rng)); ConcurrentQueue q(randInitialSize(rng)); std::vector producers(prodCount); std::vector useProducerToken(prodCount); for (int i = 0; i != prodCount; ++i) { useProducerToken[i] = static_cast(std::uniform_int_distribution(0, 1)(rng)); producers[i] = SimpleThread([&](int i) { ProducerToken t(q); for (int j = 0; j != count && !failed.load(std::memory_order_relaxed); j += countIncrement) { if (useProducerToken[i]) { for (int k = 0; k != countIncrement; ++k) { ASSERT_OR_FAIL_THREAD(q.enqueue(t, (i << 24) | (k + j))); } } else { for (int k = 0; k != countIncrement; ++k) { ASSERT_OR_FAIL_THREAD(q.enqueue((i << 24) | (k + j))); } } FAIL_IF_THREAD_TIMEOUT(); } }, i); } SimpleThread consumer([&]() { int item; std::vector lastItems(prodCount); ConsumerToken t(q); for (int i = 0; i != prodCount; ++i) { lastItems[i] = -1; } for (int i = 0; i != count * prodCount && !failed.load(std::memory_order_relaxed);) { if (useConsumerToken) { for (int j = 0; j != 10000; ++j) { if (q.try_dequeue(t, item)) { ++i; ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) < count); ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) == lastItems[item >> 24] + 1); lastItems[item >> 24] = (item & 0xFFFFFF); } } } else { for (int j = 0; j != 10000; ++j) { if (q.try_dequeue(item)) { ++i; ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) < count); ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) == lastItems[item >> 24] + 1); lastItems[item >> 24] = (item & 0xFFFFFF); } } } FAIL_IF_THREAD_TIMEOUT(); } }); for (int i = 0; i != prodCount; ++i) { producers[i].join(); } consumer.join(); if (failed.load(std::memory_order_relaxed)) { break; } int item; ASSERT_OR_FAIL(!q.try_dequeue(item)); break; } case multithread_consume: { const int countIncrement = std::uniform_int_distribution(1, 1000)(rng); int count = std::uniform_int_distribution(0, 500)(rng) * countIncrement; int consCount = std::uniform_int_distribution(0, 6)(rng); bool useProducerToken = static_cast(std::uniform_int_distribution(0, 1)(rng)); std::atomic producerDone(false); ConcurrentQueue q(randInitialSize(rng)); std::vector consumers(consCount); std::vector useConsumerToken(consCount); for (int i = 0; i != consCount; ++i) { useConsumerToken[i] = static_cast(std::uniform_int_distribution(0, 1)(rng)); consumers[i] = SimpleThread([&](int i) { int item, lastItem = -1; ConsumerToken t(q); bool doneConsuming = false; while (!doneConsuming && !failed.load(std::memory_order_relaxed)) { auto producerDoneLocal = producerDone.load(std::memory_order_acquire); if (useConsumerToken[i]) { for (int j = 0; j != 10000; ++j) { if (q.try_dequeue(t, item)) { ASSERT_OR_FAIL_THREAD(item >= 0 && item < count * consCount && item > lastItem); lastItem = item; } else if (producerDoneLocal) { doneConsuming = true; break; } } } else { for (int j = 0; j != 10000; ++j) { if (q.try_dequeue(item)) { ASSERT_OR_FAIL_THREAD(item >= 0 && item < count * consCount && item > lastItem); lastItem = item; } else if (producerDoneLocal) { doneConsuming = true; break; } } } FAIL_IF_THREAD_TIMEOUT(); } }, i); } SimpleThread producer([&]() { ProducerToken t(q); for (int i = 0; i != count * consCount && !failed.load(std::memory_order_relaxed); i += countIncrement) { if (useProducerToken) { for (int j = 0; j != countIncrement; ++j) { ASSERT_OR_FAIL_THREAD(q.enqueue(t, i + j)); } } else { for (int j = 0; j != countIncrement; ++j) { ASSERT_OR_FAIL_THREAD(q.enqueue(i + j)); } } FAIL_IF_THREAD_TIMEOUT(); } producerDone.store(true, std::memory_order_release); }); producer.join(); for (int i = 0; i != consCount; ++i) { consumers[i].join(); } if (failed.load(std::memory_order_relaxed)) { break; } int item; ASSERT_OR_FAIL(consCount == 0 || !q.try_dequeue(item)); break; } case multithread_produce_and_consume: { const int countIncrement = std::uniform_int_distribution(1, 1000)(rng); int count = std::uniform_int_distribution(0, 500)(rng) * countIncrement; int prodCount = std::uniform_int_distribution(0, 6)(rng); int consCount = std::uniform_int_distribution(0, 6)(rng); std::atomic producersDone(false); ConcurrentQueue q(randInitialSize(rng)); std::vector producers(prodCount); std::vector useProducerToken(prodCount); for (int i = 0; i != prodCount; ++i) { useProducerToken[i] = static_cast(std::uniform_int_distribution(0, 1)(rng)); producers[i] = SimpleThread([&](int i) { ProducerToken t(q); for (int j = 0; j != count && !failed.load(std::memory_order_relaxed); j += countIncrement) { if (useProducerToken[i]) { for (int k = 0; k != countIncrement; ++k) { ASSERT_OR_FAIL_THREAD(q.enqueue(t, (i << 24) | (k + j))); } } else { for (int k = 0; k != countIncrement; ++k) { ASSERT_OR_FAIL_THREAD(q.enqueue((i << 24) | (k + j))); } } FAIL_IF_THREAD_TIMEOUT(); } }, i); } std::vector consumers(consCount); std::vector useConsumerToken(consCount); for (int i = 0; i != consCount; ++i) { useConsumerToken[i] = static_cast(std::uniform_int_distribution(0, 1)(rng)); consumers[i] = SimpleThread([&](int i) { int item; std::vector lastItems(prodCount); ConsumerToken t(q); for (int j = 0; j != prodCount; ++j) { lastItems[j] = -1; } bool doneConsuming = false; while (!doneConsuming && !failed.load(std::memory_order_relaxed)) { auto producersDoneLocal = producersDone.load(std::memory_order_acquire); if (useConsumerToken[i]) { for (int j = 0; j != 10000; ++j) { if (q.try_dequeue(t, item)) { ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) < count); ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) > lastItems[item >> 24]); lastItems[item >> 24] = item & 0xFFFFFF; } else if (producersDoneLocal) { doneConsuming = true; break; } } } else { for (int j = 0; j != 10000; ++j) { if (q.try_dequeue(item)) { ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) < count); ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) > lastItems[item >> 24]); lastItems[item >> 24] = item & 0xFFFFFF; } else if (producersDoneLocal) { doneConsuming = true; break; } } } FAIL_IF_THREAD_TIMEOUT(); } }, i); } for (int i = 0; i != prodCount; ++i) { producers[i].join(); } producersDone.store(true, std::memory_order_release); for (int i = 0; i != consCount; ++i) { consumers[i].join(); } if (failed.load(std::memory_order_relaxed)) { break; } int item; ASSERT_OR_FAIL(consCount == 0 || !q.try_dequeue(item)); break; } case completely_random: { int threadCount = std::uniform_int_distribution(0, 32)(rng); ConcurrentQueue q(randInitialSize(rng)); std::vector threads(threadCount); std::vector seeds(threadCount); std::vector opCounts(threadCount); unsigned int largestOpCount = 0; for (int i = 0; i != threadCount; ++i) { opCounts[i] = std::uniform_int_distribution(0, 500000)(rng); if (opCounts[i] > largestOpCount) { largestOpCount = opCounts[i]; } } // Note: If you're wondering where all the memory goes, it's mostly here! std::vector itemStates(largestOpCount * threadCount * 2); for (std::size_t j = 0; j != itemStates.size(); ++j) { itemStates[j] = 0; } for (int i = 0; i != threadCount; ++i) { seeds[i] = std::uniform_int_distribution(0, 0xFFFFFFFF)(rng); threads[i] = SimpleThread([&](int i) { RNG_t rng((unsigned int)seeds[i]); ConsumerToken ct(q); ProducerToken pt(q); int item; int opCount = opCounts[i]; std::vector lastItems(threadCount * 2); // * 2 because there's two producer queues per thread (one implicit, one explicit) for (int j = 0; j != threadCount * 2; ++j) { lastItems[j] = -1; } for (int j = 0; j < opCount && !failed.load(std::memory_order_relaxed); ++j) { int op = std::uniform_int_distribution(0, 7)(rng); unsigned int* state; switch (op) { case 0: state = &itemStates[(i * 2) * largestOpCount + j]; ASSERT_OR_FAIL_THREAD(*state == 0); *state = 1; ASSERT_OR_FAIL_THREAD(q.enqueue(pt, ((i * 2) << 24) | j)); break; case 1: state = &itemStates[(i * 2 + 1) * largestOpCount + j]; ASSERT_OR_FAIL_THREAD(*state == 0); *state = 1; ASSERT_OR_FAIL_THREAD(q.enqueue(((i * 2 + 1) << 24) | j)); break; case 2: if (q.try_dequeue(ct, item)) { ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) >= 0 && (item & 0xFFFFFF) < (int)largestOpCount); ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) > lastItems[item >> 24]); lastItems[item >> 24] = item & 0xFFFFFF; state = &itemStates[(item >> 24) * largestOpCount + (item & 0xFFFFFF)]; ASSERT_OR_FAIL_THREAD(*state == 1); *state = 2; } break; case 3: if (q.try_dequeue(item)) { ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) >= 0 && (item & 0xFFFFFF) < (int)largestOpCount); ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) > lastItems[item >> 24]); lastItems[item >> 24] = item & 0xFFFFFF; state = &itemStates[(item >> 24) * largestOpCount + (item & 0xFFFFFF)]; ASSERT_OR_FAIL_THREAD(*state == 1); *state = 2; } break; case 4: case 5: { std::vector bulkData(std::min(opCount - j, std::uniform_int_distribution(0, 1024)(rng))); for (std::size_t k = 0; k != bulkData.size(); ++k) { state = &itemStates[(i * 2 + op - 4) * largestOpCount + j + k]; ASSERT_OR_FAIL_THREAD(*state == 0); *state = 1; bulkData[k] = ((i * 2 + op - 4) << 24) | (j + (int)k); } if (op == 4) { ASSERT_OR_FAIL_THREAD(q.enqueue_bulk(pt, bulkData.begin(), bulkData.size())); } else { ASSERT_OR_FAIL_THREAD(q.enqueue_bulk(bulkData.begin(), bulkData.size())); } j += (int)bulkData.size() - 1; break; } case 6: case 7: { std::vector bulkData(std::min(opCount - j, std::uniform_int_distribution(0, 1024)(rng))); std::size_t count = 0; if (op == 6) { count = q.try_dequeue_bulk(ct, bulkData.begin(), bulkData.size()); } else { count = q.try_dequeue_bulk(bulkData.begin(), bulkData.size()); } for (std::size_t k = 0; k != count; ++k) { auto item = bulkData[k]; ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) >= 0 && (item & 0xFFFFFF) < (int)largestOpCount); ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) > lastItems[item >> 24]); lastItems[item >> 24] = item & 0xFFFFFF; state = &itemStates[(item >> 24) * largestOpCount + (item & 0xFFFFFF)]; ASSERT_OR_FAIL_THREAD(*state == 1); *state = 2; } if (count > 0) { j += (int)count - 1; } break; } default: assert(false); } FAIL_IF_THREAD_TIMEOUT(); } }, i); } for (int i = 0; i != threadCount; ++i) { threads[i].join(); } #if MCDBGQ_TRACKMEM auto stats = q.getMemStats(); // Make available under debugger ((void)stats); #endif int item; while (q.try_dequeue(item)) { unsigned int* state = &itemStates[(item >> 24) * largestOpCount + (item & 0xFFFFFF)]; ASSERT_OR_FAIL(*state == 1); *state = 2; } for (std::size_t j = 0; j != itemStates.size(); ++j) { ASSERT_OR_FAIL(itemStates[j] == 0 || itemStates[j] == 2); } if (failed.load(std::memory_order_relaxed)) { break; } break; } case core_add_only_list: { int threadCount = std::uniform_int_distribution(0, 48)(rng); std::vector threads(threadCount); std::vector opCounts(threadCount); for (int i = 0; i != threadCount; ++i) { opCounts[i] = std::uniform_int_distribution(0, 500000)(rng); } std::size_t expectedMemUsage = 0; for (int i = 0; i != threadCount; ++i) { expectedMemUsage += opCounts[i] * sizeof(TestListItem); } corealgos::ConcurrentAddOnlyList list; for (int i = 0; i != threadCount; ++i) { threads[i] = SimpleThread([&](int tid) { auto temp = expectedMemUsage; ((void)temp); int opCount = opCounts[tid]; for (int j = 0; j != opCount; ++j) { list.add(new TestListItem((tid << 24) | j)); } }, i); } for (int i = 0; i != threadCount; ++i) { threads[i].join(); } std::vector lastItems(threadCount); for (int i = 0; i != threadCount; ++i) { lastItems[i] = opCounts[i]; } auto tail = list.tail(); while (tail != nullptr) { auto tid = tail->value >> 24; ASSERT_OR_FAIL(lastItems[tid] - 1 == (tail->value & 0xFFFFFF)); --lastItems[tid]; auto next = tail->prev(); delete tail; tail = next; } break; } case core_thread_local: { int threadCount = std::uniform_int_distribution(32, 256)(rng); std::vector threads(threadCount); std::vector opCounts(threadCount); std::vector localData(threadCount); for (int i = 0; i != threadCount; ++i) { opCounts[i] = std::uniform_int_distribution(10000, 250000)(rng); } corealgos::ThreadLocal tls(1); for (int i = 0; i != threadCount; ++i) { threads[i] = SimpleThread([&](int tid) { auto p = tls.get_or_create(); ASSERT_OR_FAIL_THREAD(p->value == 0); p->value = tid; localData[tid] = &p->value; int opCount = opCounts[tid]; for (int j = 0; j != opCount; ++j) { auto q = tls.get_or_create(); ASSERT_OR_FAIL_THREAD(q == p); ASSERT_OR_FAIL_THREAD(q->value == tid); FAIL_IF_THREAD_TIMEOUT(); } }, i); } for (int i = 0; i != threadCount; ++i) { threads[i].join(); } for (int i = 0; i != threadCount; ++i) { ASSERT_OR_FAIL(localData[i] != nullptr); ASSERT_OR_FAIL(*localData[i] == i); } break; } default: assert(false); } ++test_count[type]; if (failed.load(std::memory_order_relaxed)) { out_failReason = failReason.load(std::memory_order_relaxed); result = false; } if (!result) { ++fail_count[type]; break; } } return result; } static const char* timestamp() { static char buf[32]; time_t time = std::time(NULL); strcpy(buf, std::asctime(std::localtime(&time))); buf[strlen(buf) - 1] = '\0'; // Remove trailing newline return buf; } extern "C" { typedef void (*signal_handler_t)(int); } static std::atomic g_seed(0); static std::atomic_flag reported_signal_error = ATOMIC_FLAG_INIT; static std::atomic g_prev_sigsegv(nullptr); static std::atomic g_prev_sigabrt(nullptr); static std::mutex g_signal_handler_mutex; void on_signal(int signal) { if (reported_signal_error.test_and_set()) { return; } std::unique_lock lock(g_signal_handler_mutex); auto seed = g_seed.load(std::memory_order_acquire); // Technically undefined behaviour to use stdlib functions, // but oh well const char* error = signal == SIGABRT ? "Abort detected (assertion failed?)" : "Segmentation fault detected!"; { std::ofstream fout(LOG_FILE, std::ios::app); fout << "*** " << error << "\n Seed: " << std::hex << seed << std::endl; } std::printf("*** %s\n Seed: %08x%08x\n", error, (uint32_t)(seed >> 32), (uint32_t)(seed)); std::fflush(stdout); } extern "C" void signal_handler(int signal) { on_signal(signal); if (signal_handler_t handler_fn = g_prev_sigsegv.load(std::memory_order_relaxed)) { handler_fn(signal); } else { std::exit(signal); } } #ifdef _WIN32 LONG CALLBACK se_handler(PEXCEPTION_POINTERS info) { if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { on_signal(SIGSEGV); } return EXCEPTION_CONTINUE_SEARCH; } #endif int main(int argc, char** argv) { bool singleSeed = false; uint64_t seed = 0; // Disable buffering (so that when run in, e.g., Sublime Text, the output appears as it is written) std::setvbuf(stdout, nullptr, _IONBF, 0); // Isolate the executable name std::string progName = argv[0]; auto slash = progName.find_last_of("/\\"); if (slash != std::string::npos) { progName = progName.substr(slash + 1); } // Parse command line options if (argc > 1) { bool printHelp = false; bool error = false; for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "--help") == 0) { printHelp = true; } else if (std::strcmp(argv[i], "--seed") == 0) { if (i + 1 == argc || argv[i + 1][0] == '-') { std::printf("Expected seed number argument for --seed option.\n"); error = true; continue; } ++i; seed = 0; // hex for (int j = 0; argv[i][j] != '\0'; ++j) { char ch = static_cast(std::tolower(argv[i][j])); if (j == 1 && seed == 0 && ch == 'x') { continue; // Skip 0x, if any } else if (ch >= 'a' && ch <= 'f') { seed = (seed << 4) | (10 + ch - 'a'); } else if (ch >= '0' && ch <= '9') { seed = (seed << 4) | (ch - '0'); } else { std::printf("Expected hex seed argument, found '%s' instead\n", argv[i]); error = true; } } singleSeed = true; } else { std::printf("Unrecognized option '%s'.\n\n", argv[i]); error = true; } } if (error || printHelp) { std::printf("%s\n Description: Runs fuzz tests (randomized stability tests) for moodycamel::ConcurrentQueue\n", progName.c_str()); std::printf(" An infinite series of random tests are run, each with a different seed.\nIf a test fails, the seed for that test is reported.\n"); std::printf(" --help Prints this help blurb\n"); std::printf(" --seed N Runs one test with the given seed\n"); return error ? -1 : 0; } } { bool logExists = true; { std::ifstream fin(LOG_FILE); if (!fin) { logExists = false; } } std::ofstream fout(LOG_FILE, std::ios::app); if (logExists) { fout << "\n\n"; } if (singleSeed) { std::printf("Running %d iterations of single test with seed %08x%08x.\n\n", SINGLE_SEED_ITERATIONS, (uint32_t)(seed >> 32), (uint32_t)(seed)); fout << "--- New run (" << timestamp() << "): Executing " << SINGLE_SEED_ITERATIONS << " iterations of a single test with seed " << std::hex << seed << " ---" << std::endl; } else { std::printf("Running random fuzz tests for moodycamel::ConcurrentQueue.\n"); std::printf("Press CTRL+C to exit.\n"); std::printf("(Run %s --help for options.)\n\n", progName.c_str()); fout << "--- New run (" << timestamp() << "): Executing random fuzz tests ---" << std::endl; } } int result = 0; test_type test; const char* failReason; if (singleSeed) { if (!run_test(seed, SINGLE_SEED_ITERATIONS, test, failReason)) { result = 1; std::ofstream fout(LOG_FILE, std::ios::app); fout << test_names[test] << " failed: " << failReason << std::endl; std::printf(" %s failed: %s\n", test_names[test], failReason); } else { std::ofstream fout(LOG_FILE, std::ios::app); fout << test_names[test] << " succeeded!" << std::endl; std::printf(" %s succeeded!\n", test_names[test]); } } else { #ifdef _WIN32 AddVectoredExceptionHandler(1 /* first? */, &se_handler); #endif uint32_t iteration = 0; while (true) { seed = (static_cast(std::time(NULL)) << 32) | iteration++; // MurmurHash3 64-bit finalizer seed ^= seed >> 33; seed *= 0xff51afd7ed558ccd; seed ^= seed >> 33; seed *= 0xc4ceb9fe1a85ec53; g_seed.store(seed, std::memory_order_release); std::signal(SIGSEGV, signal_handler); std::signal(SIGABRT, signal_handler); int result; try { result = run_test(seed, 2, test, failReason); } catch (std::exception const& e) { std::ofstream fout(LOG_FILE, std::ios::app); fout << "*** Exception thrown: " << e.what() << "\n Seed: " << std::hex << seed << "\n Test: " << test_names[test] << std::endl; std::printf("*** Exception thrown: %s\n Seed: %08x%08x\n Test: %s\n\n", e.what(), (uint32_t)(seed >> 32), (uint32_t)(seed), test_names[test]); std::exit(2); // There shouldn't be any exceptions! } catch (...) { std::ofstream fout(LOG_FILE, std::ios::app); fout << "*** Unknown exception thrown!\n Seed: " << std::hex << seed << "\n Test: " << test_names[test] << std::endl; std::printf("*** Unknown exception thrown!\n Seed: %08x%08x\n Test: %s\n\n", (uint32_t)(seed >> 32), (uint32_t)(seed), test_names[test]); std::exit(2); } std::signal(SIGSEGV, SIG_DFL); std::signal(SIGABRT, SIG_DFL); if (!result) { result = 1; std::ofstream fout(LOG_FILE, std::ios::app); fout << "*** Failure detected!\n Seed: " << std::hex << seed << "\n Test: " << test_names[test] << "\n Reason: " << failReason << std::endl; std::printf("*** Failure detected!\n Seed: %08x%08x\n Test: %s\n Reason: %s\n", (uint32_t)(seed >> 32), (uint32_t)(seed), test_names[test], failReason); } if ((iteration & 31) == 0) { std::uint64_t total = 0; char breakdown[128 * TEST_TYPE_COUNT]; char* ptr = breakdown; for (int i = 0; i != TEST_TYPE_COUNT; ++i) { std::sprintf(ptr, " %s: %llu successful, %llu failed\n", test_names[i], (unsigned long long)(test_count[i] - fail_count[i]), (unsigned long long)fail_count[i]); ptr += std::strlen(ptr); total += test_count[i]; } std::ofstream fout(LOG_FILE, std::ios::app); fout << "Executed " << total << " tests so far:\n" << breakdown; std::printf("Executed %llu tests so far:\n%s", (unsigned long long)total, breakdown); } } } return result; } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/freelist.cpp ================================================ // ©2014 Cameron Desrochers #include "relacy/relacy/relacy_std.hpp" template struct FreeListNode { FreeListNode() : freeListRefs(0), freeListNext(nullptr) { } std::atomic freeListRefs; std::atomic freeListNext; }; // A simple CAS-based lock-free free list. Not the fastest thing in the world under heavy contention, // but simple and correct (assuming nodes are never freed until after the free list is destroyed), // and fairly speedy under low contention. template // N must inherit FreeListNode or have the same fields (and initialization) struct FreeList { FreeList() : freeListHead(nullptr) { } inline void add(N* node) { // We know that the should-be-on-freelist bit is 0 at this point, so it's safe to // set it using a fetch_add if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST, std::memory_order_acq_rel) == 0) { // Oh look! We were the last ones referencing this node, and we know // we want to add it to the free list, so let's do it! add_knowing_refcount_is_zero(node); } } inline N* try_get() { auto head = freeListHead.load(std::memory_order_acquire); while (head != nullptr) { auto prevHead = head; auto refs = head->freeListRefs.load(std::memory_order_relaxed); if ((refs & REFS_MASK) == 0 || !head->freeListRefs.compare_exchange_strong(refs, refs + 1, std::memory_order_acquire, std::memory_order_relaxed)) { head = freeListHead.load(std::memory_order_acquire); continue; } // Good, reference count has been incremented (it wasn't at zero), which means // we can read the next and not worry about it changing between now and the time // we do the CAS auto next = head->freeListNext.load(std::memory_order_relaxed); if (freeListHead.compare_exchange_strong(head, next, std::memory_order_acquire, std::memory_order_relaxed)) { // Yay, got the node. This means it was on the list, which means // shouldBeOnFreeList must be false no matter the refcount (because // nobody else knows it's been taken off yet, it can't have been put back on). RL_ASSERT((head->freeListRefs.load(std::memory_order_relaxed) & SHOULD_BE_ON_FREELIST) == 0); // Decrease refcount twice, once for our ref, and once for the list's ref head->freeListRefs.fetch_add(-2, std::memory_order_release); return head; } // OK, the head must have changed on us, but we still need to decrease the refcount we // increased. // Note that we don't need to release any memory effects, but we do need to ensure that the reference // count decrement happens-after the CAS on the head. refs = prevHead->freeListRefs.fetch_add(-1, std::memory_order_acq_rel); if (refs == SHOULD_BE_ON_FREELIST + 1) { add_knowing_refcount_is_zero(prevHead); } } return nullptr; } // Useful for traversing the list when there's no contention (e.g. to destroy remaining nodes) N* head_unsafe() const { return freeListHead.load(std::memory_order_relaxed); } private: inline void add_knowing_refcount_is_zero(N* node) { // Since the refcount is zero, and nobody can increase it once it's zero (except us, and we // run only one copy of this method per node at a time, i.e. the single thread case), then we // know we can safely change the next pointer of the node; however, once the refcount is back // above zero, then other threads could increase it (happens under heavy contention, when the // refcount goes to zero in between a load and a refcount increment of a node in try_get, then // back up to something non-zero, then the refcount increment is done by the other thread) -- // so, if the CAS to add the node to the actual list fails, decrease the refcount and leave // the add operation to the next thread who puts the refcount back at zero (which could be us, // hence the loop). auto head = freeListHead.load(std::memory_order_relaxed); while (true) { node->freeListNext.store(head, std::memory_order_relaxed); node->freeListRefs.store(1, std::memory_order_release); if (!freeListHead.compare_exchange_strong(head, node, std::memory_order_release, std::memory_order_relaxed)) { // Hmm, the add failed, but we can only try again when the refcount goes back to zero if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST - 1, std::memory_order_release) == 1) { continue; } } return; } } private: static const std::uint32_t REFS_MASK = 0x7FFFFFFF; static const std::uint32_t SHOULD_BE_ON_FREELIST = 0x80000000; // Implemented like a stack, but where node order doesn't matter (nodes are // inserted out of order under contention) std::atomic freeListHead; }; struct TestNode : FreeListNode { int value; TestNode() { } explicit TestNode(int value) : value(value) { } }; struct basic_test : rl::test_suite { FreeList freeList; TestNode initialNodes[2]; void before() { } void thread(unsigned int tid) { TestNode* node = &initialNodes[tid]; node->value = tid; freeList.add(node); node = freeList.try_get(); if (node != nullptr) { freeList.add(node); } } void after() { } void invariant() { } }; struct full_test : rl::test_suite { FreeList freeList; TestNode initialNodes[6]; void before() { } void thread(unsigned int tid) { TestNode* node; int myNodeCount = tid >= 4 ? 2 : 1; for (int i = 0; i != myNodeCount; ++i) { node = &initialNodes[tid + (tid >= 5 ? 1 : 0) + i]; node->value = tid; freeList.add(node); } for (int i = 0; i != 3; ++i) { node = freeList.try_get(); if (node != nullptr) { freeList.add(node); } } } void after() { } void invariant() { } }; int main() { rl::test_params params; //params.search_type = rl::sched_full; //params.iteration_count = 100000000; params.search_type = rl::sched_random; params.iteration_count = 1000000; rl::simulate(params); rl::simulate(params); return 0; } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/integrated.cpp ================================================ // ©2015 Cameron Desrochers // Tests various parts of the queue using the actual // full implementation itself, instead of isolated // components. This is much slower, but provides much // better coverage too. #define MCDBGQ_USE_RELACY #include "../../concurrentqueue.h" #include using namespace moodycamel; struct SmallConstantTraits : public ConcurrentQueueDefaultTraits { static const size_t BLOCK_SIZE = 2; static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 2; static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 2; static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 1; static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 2; }; struct MediumConstantTraits : public ConcurrentQueueDefaultTraits { static const size_t BLOCK_SIZE = 4; static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 2; static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 4; static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 2; static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 4; }; struct Foo { static int& ctorCount() { static int c; return c; } static int& dtorCount() { static int c; return c; } static void reset() { ctorCount() = 0; dtorCount() = 0; } Foo() : id(-2) { ++ctorCount(); } Foo(int id) : id(id) { ++ctorCount(); } Foo(Foo const& o) : id(o.id) { ++ctorCount(); } ~Foo() { RL_ASSERT(id != -1); ++dtorCount(); id = -1; } public: int id; }; struct enqueue_explicit_one : rl::test_suite { ConcurrentQueue q; void before() { } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); ProducerToken t(q); q.enqueue(t, tid); RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int tid0, tid1; RL_ASSERT(q.try_dequeue(tid0)); RL_ASSERT(tid0 == 0 || tid0 == 1); RL_ASSERT(q.try_dequeue(tid1)); RL_ASSERT(tid1 == 0 || tid1 == 1); RL_ASSERT(tid0 != tid1); RL_ASSERT(!q.try_dequeue(tid0)); } void invariant() { } }; struct enqueue_explicit_many : rl::test_suite { ConcurrentQueue q; void before() { } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); ProducerToken t(q); for (int i = 0; i != 5; ++i) { q.enqueue(t, tid * 10 + i); } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; for (int i = 0; i != 15; ++i) { RL_ASSERT(q.try_dequeue(item)); } RL_ASSERT(!q.try_dequeue(item)); } void invariant() { } }; // This one caught a bug with the memory ordering in the core dequeue algorithm struct dequeue_some_explicit : rl::test_suite { ConcurrentQueue q; void before() { } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); if (tid <= 1) { int item; ConsumerToken t(q); for (int i = 0; i != 5; ++i) { q.try_dequeue(t, item); } } else { ProducerToken t(q); for (int i = 0; i != 3; ++i) { q.enqueue(t, tid * 10 + i); } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { } void invariant() { } }; // Causes blocks to be reused struct recycle_blocks_explicit : rl::test_suite { ConcurrentQueue q; std::vector seen; void before() { seen.resize(8, false); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); if (tid == 0) { ProducerToken t(q); for (int i = 0; i != 8; ++i) { q.enqueue(t, i); } } else { int item; ConsumerToken t(q); for (int i = 0; i != 6; ++i) { if (q.try_dequeue(t, item)) { RL_ASSERT(!seen[item]); seen[item] = true; } } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; while (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } for (auto s : seen) { RL_ASSERT(s); } } void invariant() { } }; // Causes the explicit producer's block index to expand struct expand_block_index_explicit : rl::test_suite { ConcurrentQueue q; std::vector seen; void before() { seen.resize(12, false); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); if (tid == 0) { ProducerToken t(q); for (int i = 0; i != 12; ++i) { q.enqueue(t, i); } } else { int item; ConsumerToken t(q); for (int i = 0; i != 3; ++i) { if (q.try_dequeue(t, item)) { RL_ASSERT(!seen[item]); seen[item] = true; } } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; while (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } for (auto s : seen) { RL_ASSERT(s); } } void invariant() { } }; // Tests that implicit producers work at a very basic level struct enqueue_implicit_one : rl::test_suite { ConcurrentQueue q; void before() { } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); q.enqueue(tid); RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int tid0, tid1; RL_ASSERT(q.try_dequeue(tid0)); RL_ASSERT(tid0 == 0 || tid0 == 1); RL_ASSERT(q.try_dequeue(tid1)); RL_ASSERT(tid1 == 0 || tid1 == 1); RL_ASSERT(tid0 != tid1); RL_ASSERT(!q.try_dequeue(tid0)); } void invariant() { } }; // Tests implicit producer at a simple level struct implicit_simple : rl::test_suite { ConcurrentQueue q; std::vector seen; void before() { seen.resize(5, false); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); if (tid == 0) { for (int i = 0; i != 5; ++i) { q.enqueue(i); } } else { int item; for (int i = 0; i != 3; ++i) { if (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; while (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } for (auto s : seen) { RL_ASSERT(s); } } void invariant() { } }; // Tests multiple implicit producers being created (stresses the implicit producer hash map) struct many_implicit_producers : rl::test_suite { ConcurrentQueue q; std::vector seen; void before() { seen.resize(18, false); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); q.enqueue(tid * 3 + 0); q.enqueue(tid * 3 + 1); q.enqueue(tid * 3 + 2); int item; for (int i = 0; i != 2; ++i) { if (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; while (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } for (auto s : seen) { RL_ASSERT(s); } } void invariant() { } }; // Tests multiple implicit producers being created (stresses the implicit producer hash map) struct implicit_producer_reuse : rl::test_suite { ConcurrentQueue q; std::vector seen; void before() { seen.resize(9, false); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); q.enqueue(tid); RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; while (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } for (auto s : seen) { RL_ASSERT(s); } } void invariant() { } }; // Tests implicit producer block recycling struct implicit_block_reuse : rl::test_suite { ConcurrentQueue q; std::vector seen; void before() { seen.resize(28, false); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); for (int i = 0; i != 7; ++i) { q.enqueue(tid * 7 + i); } int item; ConsumerToken t(q); for (int i = 0; i != 7; ++i) { if (q.try_dequeue(t, item)) { RL_ASSERT(!seen[item]); seen[item] = true; } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; while (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } for (auto s : seen) { RL_ASSERT(s); } } void invariant() { } }; // Tests consumption from mixed producers struct mixed : rl::test_suite { ConcurrentQueue q; std::vector seen; void before() { seen.resize(28, false); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); if (tid <= 1) { for (int i = 0; i != 7; ++i) { q.enqueue(tid * 7 + i); } } else { ProducerToken t(q); for (int i = 0; i != 7; ++i) { q.enqueue(t, tid * 7 + i); } } int item; if (tid & 1) { for (int i = 0; i != 4; ++i) { if (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } } } else { ConsumerToken t(q); for (int i = 0; i != 4; ++i) { if (q.try_dequeue(t, item)) { RL_ASSERT(!seen[item]); seen[item] = true; } } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int item; while (q.try_dequeue(item)) { RL_ASSERT(!seen[item]); seen[item] = true; } for (auto s : seen) { RL_ASSERT(s); } } void invariant() { } }; // Test leftovers are being properly destroyed struct leftovers_destroyed_explicit : rl::test_suite { ConcurrentQueue* q; std::vector seen; void before() { seen.resize(rl::rand(32), false); q = new ConcurrentQueue(); Foo::reset(); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); if (tid == 0) { ProducerToken t(*q); for (int i = 0; i != (int)seen.size(); ++i) { q->enqueue(t, Foo(i)); } } else { Foo item; ConsumerToken t(*q); for (int i = rl::rand(17); i > 0; --i) { if (q->try_dequeue(t, item)) { RL_ASSERT(!seen[item.id]); seen[item.id] = true; } } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int seenCount = 0; { for (auto s : seen) { if (s) { ++seenCount; } } } RL_ASSERT(Foo::ctorCount() == seen.size() * 2 + 2); RL_ASSERT(Foo::dtorCount() == seen.size() + seenCount + 2); delete q; RL_ASSERT(Foo::ctorCount() == seen.size() * 2 + 2); RL_ASSERT(Foo::ctorCount() == Foo::dtorCount()); } void invariant() { } }; // implicit struct leftovers_destroyed_implicit : rl::test_suite { ConcurrentQueue* q; std::vector seen; void before() { seen.resize(rl::rand(32), false); q = new ConcurrentQueue(); Foo::reset(); } void thread(unsigned int tid) { RelacyThreadExitNotifier::notify_relacy_thread_start(); if (tid == 0) { for (int i = 0; i != (int)seen.size(); ++i) { q->enqueue(Foo(i)); } } else { Foo item; for (int i = rl::rand(17); i > 0; --i) { if (q->try_dequeue(item)) { RL_ASSERT(!seen[item.id]); seen[item.id] = true; } } } RelacyThreadExitNotifier::notify_relacy_thread_exit(); } void after() { int seenCount = 0; { for (auto s : seen) { if (s) { ++seenCount; } } } RL_ASSERT(Foo::ctorCount() == seen.size() * 2 + 2); RL_ASSERT(Foo::dtorCount() == seen.size() + seenCount + 2); delete q; RL_ASSERT(Foo::ctorCount() == seen.size() * 2 + 2); RL_ASSERT(Foo::ctorCount() == Foo::dtorCount()); } void invariant() { } }; template void simulate(int iterations) { // Note: There's no point using the full search params // Even with the simple enqueue_explicit_one test, it // would take a few millenia to complete(!) //rl::test_params fullParams; //fullParams.search_type = rl::sched_full; rl::test_params randomParams; randomParams.search_type = rl::sched_random; randomParams.iteration_count = iterations; rl::simulate(randomParams); } int main() { simulate(1000000); simulate(1000000); simulate(1000000); simulate(1000000); simulate(1000000); simulate(1000000); simulate(1000000); simulate(500000); simulate(1000000); simulate(1000000); simulate(1000000); simulate(1000000); simulate(1000000); return 0; } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/CHANGES ================================================ Version 2.4 Features: + Support for futex(FUTEX_WAIT/FUTEX_WAKE) + Linux/Darwin performance improved (2.5x for Linux, 7x for Darwin) Fixes: + Fixed a bunch of issues with WaitForMultipleObjects()/SignalObjectAndWait() + Fixed rare spurious memory leak reports related to test progress reporting Version 2.3 Features: + Support for FlushProcessWriteBuffers() Version 2.2 Features: + Support for pthread_mutex_timedlock() + Support for ETIMEDOUT, EINTR in pthread_cond_timedwait()/pthread_cond_wait() + rl::hash_ptr(p, sz) function which provides deterministic hashing of pointers Fixes: + Win32 mutex is now recursive + Compilation issue on MSVC x64 when RL_DEBUGBREAK_ON_ASSERT/RL_DEBUGBREAK_ON_FAILURE defined + Fixed OOM crash when execution history is very large + Fixed rare crash during iteration count estimation in context bound scheduler + Fixed bug in pthread_rwlock/SRWLOCK that at most 2 readers may acquire it simultaneously + Fixed bug regarding false race detection when simulation runs for very long time (int overflow) ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/LICENSE ================================================ Relacy Race Detector Copyright (c) 2008-2013, Dmitry S. Vyukov All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - The name of the owner may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE OWNER "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OWNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/VERSION ================================================ 974f5c228473 ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/cli_ws_deque/cli_ws_deque.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_cli.hpp" using rl::nvar; using rl::nvolatile; using rl::mutex; template class ws_deque { public: ws_deque() { m_mask($) = initial_size - 1; m_headIndex($) = 0; m_tailIndex($) = 0; m_array($) = new nvar [initial_size]; m_arraySize($) = initial_size; } bool IsEmpty() { return m_headIndex($) >= m_tailIndex($); } size_t Count() { return m_tailIndex($) - m_headIndex($); } void push(T item) { size_t tail = m_tailIndex($); if (tail <= m_headIndex($) + m_mask($)) { m_array($)[tail & m_mask($)]($) = item; m_tailIndex($) = tail + 1; } else { m_foreignLock.lock($); size_t head = m_headIndex($); size_t count = Count(); if (count >= m_mask($)) { size_t arraySize = m_arraySize($); size_t mask = m_mask($); nvar* newArray = new nvar [arraySize * 2]; nvar* arr = m_array($); for (size_t i = 0; i != count; ++i) newArray[i]($) = arr[(i + head) & mask]($); m_array($) = newArray; m_arraySize($) = arraySize * 2; m_headIndex($) = 0; m_tailIndex($) = count; tail = count; m_mask($) = (mask * 2) | 1; } m_array($)[tail & m_mask($)]($) = item; m_tailIndex($) = tail + 1; m_foreignLock.unlock($); } } bool pop(T& item) { size_t tail = m_tailIndex($); if (tail == 0) return false; tail -= 1; rl::Interlocked::Exchange(m_tailIndex, tail, $); if (m_headIndex($) <= tail) { item = m_array($)[tail & m_mask($)]($); return true; } else { m_foreignLock.lock($); if (m_headIndex($) <= tail) { item = m_array($)[tail & m_mask($)]($); m_foreignLock.unlock($); return true; } else { m_tailIndex($) = tail + 1; m_foreignLock.unlock($); return false; } } } bool steal(T& item) { if (false == m_foreignLock.try_lock($)) return false; size_t head = m_headIndex($); rl::Interlocked::Exchange(m_headIndex, head + 1, $); if (head < m_tailIndex($)) { item = m_array($)[head & m_mask($)]($); m_foreignLock.unlock($); return true; } else { m_headIndex($) = head; m_foreignLock.unlock($); return false; } } private: static size_t const initial_size = 2; nvar*> m_array; nvar m_mask; nvar m_arraySize; nvolatile m_headIndex; nvolatile m_tailIndex; mutex m_foreignLock; }; struct ws_deque_test : rl::test_suite { ws_deque q; bool state [2]; void before() { state[0] = true; state[1] = true; } void after() { RL_ASSERT(state[0] == false); RL_ASSERT(state[1] == false); } void thread(unsigned index) { if (0 == index) { q.push(1); q.push(2); int item = 0; bool res = q.pop(item); RL_ASSERT(res && item == 2); RL_ASSERT(state[1]); state[1] = false; item = 0; res = q.pop(item); if (res) { RL_ASSERT(state[0]); state[0] = false; } item = 0; res = q.pop(item); RL_ASSERT(res == false); } else { int item = 0; bool res = q.steal(item); if (res) { RL_ASSERT(item == 1); RL_ASSERT(state[0]); state[0] = false; } } } }; int main() { rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/cli_ws_deque/msvc8/cli_ws_deque.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cli_ws_deque", "cli_ws_deque.vcproj", "{0B597F19-DEBB-4832-B520-9A93A286D595}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.ActiveCfg = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.Build.0 = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.ActiveCfg = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/cli_ws_deque/msvc8/cli_ws_deque.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/cli_ws_deque/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/cli_ws_deque/stdafx.h ================================================ #pragma once #include "../../relacy/pch.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/condvar/condvar.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" // THE TEST IS EXPECTED TO FAIL WITH "DEADLOCK" class CondVar { public: CondVar(); ~CondVar(); void Enter(); void Wait(); void Release(); void ReleaseAll(); void Leave(); private: std::atomic m_lMutex; std::atomic m_dwWaitingForSignal; HANDLE m_xhEvtEnter; HANDLE m_xhSemRelease; }; CondVar::CondVar() : m_xhEvtEnter(CreateEvent(0, 0, 0, 0)) , m_xhSemRelease(CreateSemaphore(0, 0, 0x7FFFFFFF, 0)) { m_lMutex.store(0, std::memory_order_relaxed); m_dwWaitingForSignal.store(0, std::memory_order_relaxed); } CondVar::~CondVar() { CloseHandle(m_xhEvtEnter); CloseHandle(m_xhSemRelease); } void CondVar::Enter() { int lMutex = m_lMutex.load(std::memory_order_seq_cst); for (;;) { if( lMutex >= 0 ) { if (m_lMutex.compare_exchange_weak(lMutex, lMutex | 0x80000000u, std::memory_order_seq_cst)) break; } else { if (false == m_lMutex.compare_exchange_weak(lMutex, lMutex + 1, std::memory_order_seq_cst)) continue; WaitForSingleObject(m_xhEvtEnter, INFINITE); RL_ASSERT(m_lMutex.load(std::memory_order_seq_cst) < 0); break; } } } void CondVar::Wait() { unsigned dwWaitingForSignal = m_dwWaitingForSignal.load(std::memory_order_seq_cst); m_dwWaitingForSignal.store(dwWaitingForSignal + 1, std::memory_order_seq_cst); RL_ASSERT(m_lMutex.load(std::memory_order_seq_cst) < 0); int lMutex = m_lMutex.load(std::memory_order_seq_cst); for (;;) { unsigned dwWaitingToOwn = lMutex & 0x7FFFFFFFu; RL_ASSERT(dwWaitingToOwn >= dwWaitingForSignal); if (dwWaitingToOwn == dwWaitingForSignal) { if (m_lMutex.compare_exchange_weak(lMutex, dwWaitingToOwn + 1, std::memory_order_seq_cst)) break; } else { SetEvent(m_xhEvtEnter); break; } } WaitForSingleObject(m_xhSemRelease, INFINITE); WaitForSingleObject(m_xhEvtEnter, INFINITE); RL_ASSERT(m_lMutex.load(std::memory_order_seq_cst) < 0); } void CondVar::Release() { RL_ASSERT(m_lMutex.load(std::memory_order_seq_cst) < 0); unsigned dwWaitingForSignal = m_dwWaitingForSignal.load(std::memory_order_seq_cst); if (dwWaitingForSignal != 0) { m_dwWaitingForSignal.store(dwWaitingForSignal - 1, std::memory_order_seq_cst); ReleaseSemaphore(m_xhSemRelease, 1, 0); } } void CondVar::ReleaseAll() { RL_ASSERT(m_lMutex.load(std::memory_order_seq_cst) < 0); unsigned dwWaitingForSignal = m_dwWaitingForSignal.load(std::memory_order_seq_cst); if (dwWaitingForSignal != 0) { m_dwWaitingForSignal.store(0, std::memory_order_seq_cst); ReleaseSemaphore(m_xhSemRelease, dwWaitingForSignal, 0); } } void CondVar::Leave() { int lMutex = m_lMutex.load(std::memory_order_seq_cst); RL_ASSERT(lMutex < 0); for (;;) { unsigned dwWaitingToOwn = lMutex & 0x7FFFFFFFu; unsigned dwWaitingForSignal = m_dwWaitingForSignal.load(std::memory_order_seq_cst); RL_ASSERT(dwWaitingToOwn >= dwWaitingForSignal); if (dwWaitingToOwn == dwWaitingForSignal) { if (m_lMutex.compare_exchange_weak(lMutex, lMutex & 0x7FFFFFFF, std::memory_order_seq_cst)) break; } else { if (false == m_lMutex.compare_exchange_weak(lMutex, lMutex - 1, std::memory_order_seq_cst)) continue; SetEvent(m_xhEvtEnter); break; } } } struct CondVarTest : rl::test_suite { VAR_T(int) stage; CondVar cv; void before() { VAR(stage) = 0; } void thread(unsigned index) { if (0 == index) { cv.Enter(); VAR(stage) += 1; cv.ReleaseAll(); while (VAR(stage) != 2) cv.Wait(); cv.Leave(); } else if (1 == index) { cv.Enter(); while (VAR(stage) != 1) cv.Wait(); VAR(stage) += 1; cv.ReleaseAll(); cv.Leave(); } else if (2 == index) { cv.Enter(); while (VAR(stage) != 2) cv.Wait(); cv.Leave(); } } }; int main() { rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/condvar/msvc8/condvar.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condvar", "condvar.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/condvar/msvc8/condvar.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/condvar/msvc9/condvar.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condvar", "condvar.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/condvar/msvc9/condvar.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/condvar/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/condvar/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #define RL_MSVC_OUTPUT //#define RL_DEBUGBREAK_ON_FAILURE #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eao_blocking/eao_blocking.cpp ================================================ /* #define BOOST_ALL_NO_LIB #pragma warning (push, 3) #include #include #include "C:\boost_1_35_0\libs\thread\src\win32\exceptions.cpp" #pragma warning (pop) class business_logic { public: typedef unsigned account_id_t; typedef double balance_t; bool add_account(account_id_t acc_id, balance_t balance) { accounts_guard.lock(); if (accounts.find(acc_id) != accounts.end()) { accounts_guard.unlock(); return false; } accounts[acc_id].balance = balance; accounts_guard.unlock(); return true; } bool transfer_balance(account_id_t acc_id1, account_id_t acc_id2, balance_t amount) { accounts_guard.lock_shared(); if (accounts.find(acc_id1) != accounts.end() || accounts.find(acc_id2) != accounts.end()) { accounts_guard.unlock_shared(); return false; } account_info& acc1 = accounts[acc_id1]; account_info& acc2 = accounts[acc_id2]; acc1.mtx.lock(); acc2.mtx.lock(); accounts_guard.unlock_shared(); acc1.balance -= amount; acc2.balance += amount; acc1.mtx.unlock(); acc2.mtx.unlock(); return true; } private: struct account_info { balance_t balance; boost::mutex mtx; account_info() : balance() {} account_info(account_info const& acc) : balance(acc.balance) {} }; typedef std::map account_map_t; account_map_t accounts; boost::shared_mutex accounts_guard; }; */ /* #undef RL_TEST #ifndef RL_TEST //# define ASSERT assert typedef boost::mutex mutex_t; # define $$ #else //# define ASSERT RL_ASSERT typedef rl::recursive_mutex mutex_t; # define $$ $ #endif class business_logic { public: typedef unsigned account_id_t; typedef double balance_t; bool add_account(account_id_t acc_id, balance_t balance) { accounts_guard.lock($$); if (accounts.find(acc_id) != accounts.end()) { accounts_guard.unlock($$); return false; } accounts[acc_id].balance = balance; accounts_guard.unlock($$); return true; } bool transfer_balance(account_id_t acc_id1, account_id_t acc_id2, balance_t amount) { accounts_guard.lock($$); if (accounts.find(acc_id1) == accounts.end() || accounts.find(acc_id2) == accounts.end()) { accounts_guard.unlock($$); return false; } account_info& acc1 = accounts[acc_id1]; account_info& acc2 = accounts[acc_id2]; acc1.mtx.lock($$); acc2.mtx.lock($$); accounts_guard.unlock($$); acc1.balance -= amount; acc2.balance += amount; acc1.mtx.unlock($$); acc2.mtx.unlock($$); return true; } private: struct account_info { balance_t balance; mutex_t mtx; account_info() : balance() {} account_info(account_info const& acc) : balance(acc.balance) {} }; typedef std::map account_map_t; account_map_t accounts; mutex_t accounts_guard; }; */ /* struct business_logic_test : rl::test_suite { business_logic bl; static size_t const account_count = 10; void before() { for (size_t i = 0; i != account_count; ++i) { bool rv = bl.add_account(i, i * 10.0); RL_ASSERT(rv); } } void thread(unsigned) { business_logic::account_id_t acc1 = rl::rand(account_count); business_logic::account_id_t acc2 = rl::rand(account_count); bool rv = bl.transfer_balance(acc1, acc2, 1.0); RL_ASSERT(rv); } }; */ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eventcount/eventcount.cpp ================================================ #include "stdafx.h" #include "../../relacy/windows.h" #define HANDLE rl::HANDLE #define CreateSemaphoreA rl::RL_CreateSemaphore($) #define CreateSemaphoreW rl::RL_CreateSemaphore($) #ifndef CreateSemaphore # define CreateSemaphore CreateSemaphoreW #endif #define CloseHandle rl::RL_CloseHandle($) #include #if defined(WIN32) && defined(_MSC_VER) #include #include class semaphore { public: semaphore() { h_ = CreateSemaphore(0, 0, LONG_MAX, 0); } ~semaphore() { CloseHandle(h_); } void wait() { WaitForSingleObject(h_, INFINITE); } void post() { ReleaseSemaphore(h_, 1, 0); } private: HANDLE h_; semaphore(semaphore const&); semaphore& operator = (semaphore const&); }; class mutex { public: mutex() { InitializeCriticalSection(&cs_); } ~mutex() { DeleteCriticalSection(&cs_); } void lock() { EnterCriticalSection(&cs_); } void unlock() { LeaveCriticalSection(&cs_); } private: CRITICAL_SECTION cs_; mutex(mutex const&); mutex& operator = (mutex const&); }; void full_memory_fence() { _mm_mfence(); } #define THREAD_LOCAL __declspec(thread) #elif defined(POSIX) && defined(GCC) #include #include class semaphore { public: semaphore() { sem_init(&sem_, 0, 0); } ~semaphore() { sem_destroy(&sem_); } void wait() { sem_wait(&sem_); } void post() { sem_post(&sem_); } private: sem_t sem_; semaphore(semaphore const&); semaphore& operator = (semaphore const&); }; class mutex { public: mutex() { pthread_mutex_init(&mutex_, 0); } ~mutex() { pthread_mutex_destroy(&mutex_); } void lock() { pthread_mutex_lock(&mutex_); } void unlock() { pthread_mutex_unlock(&mutex_); } private: pthread_mutex_t mutex_; mutex(mutex const&); mutex& operator = (mutex const&); }; void full_memory_fence() { __sync_synchronize(); } #define THREAD_LOCAL __thread #endif class lock { public: lock(mutex& m) : m_(m) { m.lock(); } ~lock() { m_.unlock(); } private: mutex& m_; lock(lock const&); lock& operator = (lock const&); }; /** simple single-threaded double-linked list * nothing interesting */ class dlist { public: struct node { node* prev_; node* next_; node() { prev_ = 0; next_ = 0; } }; dlist() { reset(); } void push(node* n) { size_ += 1; n->next_ = head_.next_; n->prev_ = &head_; head_.next_->prev_ = n; head_.next_ = n; } node* pop() { if (size_ == 0) return 0; node* n = head_.next_; remove(n); return n; } void remove(node* n) { size_ -= 1; n->prev_->next_ = n->next_; n->next_->prev_ = n->prev_; } size_t size() const { return size_; } node* begin() { return head_.next_; } void flush_to(dlist& target) { if (size_) { target.size_ = size_; target.head_.next_ = head_.next_; target.head_.next_->prev_ = &target.head_; target.tail_.prev_ = tail_.prev_; target.tail_.prev_->next_ = &target.tail_; } else { target.reset(); } reset(); } static bool not_last(node* n) { return n->next_ != 0; } static node* get_next(node* n) { return n->next_; } private: size_t volatile size_; node head_; node tail_; void reset() { size_ = 0; head_.next_ = &tail_; head_.prev_ = 0; tail_.next_ = 0; tail_.prev_ = &head_; } dlist(dlist const&); dlist& operator = (dlist const&); }; /** pre-thread descriptor for eventcount */ struct ec_thread { dlist::node node_; semaphore sema_; unsigned epoch_; bool volatile in_waitset_; bool spurious_; void* ctx_; ec_thread() { epoch_ = 0; in_waitset_ = false; spurious_ = false; ctx_ = 0; } ~ec_thread() { if (spurious_) sema_.wait(); } static ec_thread* current() { static THREAD_LOCAL ec_thread* ec_thread_instance = 0; ec_thread* instance = ec_thread_instance; if (instance == 0) { instance = new ec_thread; ec_thread_instance = instance; } return instance; // instance must be destroyed in DllMain() callback // or in pthread_key_create() callback } private: ec_thread(ec_thread const&); ec_thread& operator = (ec_thread const&); }; /** fine-grained eventcount implementation */ class eventcount { public: eventcount() { epoch_ = 0; } void prepare_wait(void* ctx = 0) { ec_thread* th = ec_thread::current(); // this is good place to pump previous spurious wakeup if (th->spurious_) { th->spurious_ = false; th->sema_.wait(); } th->in_waitset_ = true; th->ctx_ = ctx; { lock l (mtx_); th->epoch_ = epoch_; waitset_.push(&th->node_); } full_memory_fence(); } void wait() { ec_thread* th = ec_thread::current(); // this check is just an optimization if (th->epoch_ == epoch_) th->sema_.wait(); else retire_wait(); } void retire_wait() { ec_thread* th = ec_thread::current(); // spurious wakeup will be pumped in following prepare_wait() th->spurious_ = true; // try to remove node from waitset if (th->in_waitset_) { lock l (mtx_); if (th->in_waitset_) { // successfully removed from waitset, // so there will be no spurious wakeup th->in_waitset_ = false; th->spurious_ = false; waitset_.remove(&th->node_); } } } void notify_one() { full_memory_fence(); notify_one_relaxed(); } template void notify(predicate_t pred) { full_memory_fence(); notify_relaxed(pred); } void notify_all() { full_memory_fence(); notify_all_relaxed(); } void notify_one_relaxed() { if (waitset_.size() == 0) return; dlist::node* n; { lock l (mtx_); epoch_ += 1; n = waitset_.pop(); if (n) to_ec_thread(n)->in_waitset_ = false; } if (n) { to_ec_thread(n)->sema_.post(); } } template void notify_relaxed(predicate_t pred) { if (waitset_.size() == 0) return; dlist temp; { lock l (mtx_); epoch_ += 1; size_t size = waitset_.size(); size_t idx = 0; dlist::node* n = waitset_.begin(); while (dlist::not_last(n)) { dlist::node* next = dlist::get_next(n); ec_thread* th = to_ec_thread(n); if (pred(th->ctx_, size, idx)) { waitset_.remove(n); temp.push(n); th->in_waitset_ = false; } n = next; idx += 1; } } dlist::node* n = temp.begin(); while (dlist::not_last(n)) { dlist::node* next = dlist::get_next(n); to_ec_thread(n)->sema_.post(); n = next; } } void notify_all_relaxed() { if (waitset_.size() == 0) return; dlist temp; { lock l (mtx_); epoch_ += 1; waitset_.flush_to(temp); dlist::node* n = temp.begin(); while (dlist::not_last(n)) { to_ec_thread(n)->in_waitset_ = false; n = dlist::get_next(n); } } dlist::node* n = temp.begin(); while (dlist::not_last(n)) { dlist::node* next = dlist::get_next(n); to_ec_thread(n)->sema_.post(); n = next; } } private: mutex mtx_; dlist waitset_; volatile unsigned epoch_; ec_thread* to_ec_thread(dlist::node* n) { return (ec_thread*)((char*)n - offsetof(ec_thread, node_)); } eventcount(eventcount const&); eventcount& operator = (eventcount const&); }; struct scheduler { struct tbb_thread {}; eventcount ec_; tbb_thread* threads_; bool volatile is_permanently_open_; void wait_while_pool_is_empty(tbb_thread* th) { if (is_permanently_open_) return; ec_.prepare_wait(th); if (pool_is_empty()) ec_.wait(); else ec_.retire_wait(); } void notify_about_new_task_available() { ec_.notify_one_relaxed(); } void notify_about_new_task_available_with_preference(tbb_thread* preference) { struct local { tbb_thread* preference_; bool fired_; bool operator () (void* ctx, size_t count, size_t idx) { tbb_thread* th = (tbb_thread*)ctx; if (th == preference_) { fired_ = true; return true; } else if (idx == count - 1 && fired_ == false) { return true; } else { return false; } } } pred = {preference}; ec_.notify_relaxed(pred); } void notify_about_list_of_tasks_available(size_t total_count, size_t preference_count, tbb_thread** preferences) { struct local { size_t remain_to_signal_; size_t preference_count_; tbb_thread** preferences_; bool operator () (void* ctx, size_t count, size_t idx) { tbb_thread* th = (tbb_thread*)ctx; size_t remain_in_waitset = count - idx; if (remain_in_waitset <= remain_to_signal_) { return true; } else { for (size_t i = 0; i != preference_count_; ++i) { if (preferences_[i] == th) { remain_to_signal_ -= 1; return true; } } } return false; } } pred = {total_count, preference_count, preferences}; ec_.notify_relaxed(pred); } bool pool_is_empty() { return true; } }; struct queue { int producer_idx_; int consumer_idx_; void** buffer_; eventcount ec_; void enqueue(void* data) { int idx = ++producer_idx_; // atomic buffer_[idx] = data; struct local { int idx_; bool operator () (void* ctx, size_t /*count*/, size_t /*idx*/) { return idx_ == *(int*)ctx; } } pred = {idx}; ec_.notify(pred); // not relaxed!!! } void* dequeue() { int idx = ++consumer_idx_; // atomic void* data = buffer_[idx]; if (data) return data; for (;;) { ec_.prepare_wait(&idx); data = buffer_[idx]; if (data) { ec_.retire_wait(); return data; } ec_.wait(); data = buffer_[idx]; if (data) { return data; } } } }; class condition_variable { eventcount ec_; public: void wait(mutex& mtx) { ec_.prepare_wait(); mtx.unlock(); ec_.wait(); mtx.lock(); } void signal() { ec_.notify_one(); } void broadcast() { ec_.notify_all(); } }; struct eventcount_test : rl::test_suite { void thread(unsigned index) { delete ec_thread::current(); (void)index; } }; int main() { rl::test_params p; //p.iteration_count = 1000000; rl::simulate(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eventcount/msvc8/eventcount.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eventcount", "eventcount.vcproj", "{ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Debug|Win32.ActiveCfg = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Debug|Win32.Build.0 = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Release|Win32.ActiveCfg = Release|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eventcount/msvc8/eventcount.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eventcount/msvc9/eventcount.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eventcount", "eventcount.vcproj", "{ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Debug|Win32.ActiveCfg = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Debug|Win32.Build.0 = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Release|Win32.ActiveCfg = Release|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eventcount/msvc9/eventcount.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eventcount/stdafx.cpp ================================================ // stdafx.cpp : source file that includes just the standard includes // ws_deque.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/eventcount/stdafx.h ================================================ #pragma once #define _WIN32_WINNT 0x0500 #include #include #include #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/examples/amp_condvar.hpp ================================================ #pragma once struct amp_raw_condition_variable_s { CRITICAL_SECTION access_waiting_threads_count_critsec; HANDLE wake_waiting_threads_mutex; HANDLE waking_waiting_threads_count_control_sem; HANDLE finished_waking_waiting_threads_event; VAR_T(LONG) waiting_thread_count; VAR_T(BOOL) broadcast_in_progress; }; struct amp_raw_mutex_s { CRITICAL_SECTION critical_section; BOOL is_locked; }; typedef amp_raw_condition_variable_s* amp_raw_condition_variable_t; typedef amp_raw_mutex_s* amp_raw_mutex_t; int const AMP_SUCCESS = 0; int amp_raw_mutex_init(amp_raw_mutex_t mutex) { InitializeCriticalSectionAndSpinCount(&mutex->critical_section, 1); mutex->is_locked = FALSE; return AMP_SUCCESS; } int amp_raw_mutex_finalize(amp_raw_mutex_t mutex) { assert(NULL != mutex); int retval = AMP_SUCCESS; DeleteCriticalSection(&mutex->critical_section); return retval; } int amp_raw_mutex_lock(amp_raw_mutex_t mutex) { assert(NULL != mutex); EnterCriticalSection(&mutex->critical_section); mutex->is_locked = TRUE; return AMP_SUCCESS; } int amp_raw_mutex_unlock(amp_raw_mutex_t mutex) { assert(NULL != mutex); mutex->is_locked = FALSE; LeaveCriticalSection(&mutex->critical_section); return AMP_SUCCESS; } int amp_raw_condition_variable_init(amp_raw_condition_variable_t cond) { InitializeCriticalSectionAndSpinCount(&cond->access_waiting_threads_count_critsec, 1); cond->wake_waiting_threads_mutex = CreateMutex(0, 0, 0); cond->waking_waiting_threads_count_control_sem = CreateSemaphore(NULL, /* No inheritance to child processes */ 0, /* Initially no threads can pass */ LONG_MAX, /* Max semaphore count */ NULL); /* Only intra-process semaphore */ cond->finished_waking_waiting_threads_event = CreateEvent(NULL, /* Default security and no inheritance to child processes */ FALSE, /* No manual reset */ 0, /* Initially not signaled */ NULL /* Not inter-process available */ ); cond->VAR(waiting_thread_count) = 0l; cond->VAR(broadcast_in_progress) = FALSE; return AMP_SUCCESS; } int amp_raw_condition_variable_finalize(amp_raw_condition_variable_t cond) { DeleteCriticalSection(&cond->access_waiting_threads_count_critsec); CloseHandle(cond->wake_waiting_threads_mutex); CloseHandle(cond->waking_waiting_threads_count_control_sem); CloseHandle(cond->finished_waking_waiting_threads_event); int ret_error_code = AMP_SUCCESS; return ret_error_code; } int amp_raw_condition_variable_signal(amp_raw_condition_variable_t cond) { WaitForSingleObject(cond->wake_waiting_threads_mutex, INFINITE); BOOL at_least_one_waiting_thread = (0l != cond->VAR(waiting_thread_count)); if (at_least_one_waiting_thread) { LONG prev_sem_count = 0; ReleaseSemaphore(cond->waking_waiting_threads_count_control_sem, 1, &prev_sem_count /* No interest in the previous sem count. */ ); WaitForSingleObject(cond->finished_waking_waiting_threads_event, INFINITE); } ReleaseMutex(cond->wake_waiting_threads_mutex); return AMP_SUCCESS; } int amp_raw_condition_variable_broadcast(amp_raw_condition_variable_t cond) { WaitForSingleObject(cond->wake_waiting_threads_mutex, INFINITE); LONG const waiting_thread_count = cond->VAR(waiting_thread_count); if (0 < waiting_thread_count) { cond->VAR(broadcast_in_progress) = TRUE; /* Releasing the sem here and waiting on it should update the memory of * the waiting threads to see that a broadcast is in progress. */ LONG prev_sem_count = 0; /* Assuming that less threads exist than max possible semaphore count. * TODO: @todo Decide if to spin here if the assumption doesn't hold * true in the future? */ ReleaseSemaphore(cond->waking_waiting_threads_count_control_sem, waiting_thread_count, &prev_sem_count /* No interest in the previous sem count. */ ); WaitForSingleObject(cond->finished_waking_waiting_threads_event, INFINITE); cond->VAR(broadcast_in_progress) = FALSE; } ReleaseMutex(cond->wake_waiting_threads_mutex); return AMP_SUCCESS; } int amp_raw_condition_variable_wait(amp_raw_condition_variable_t cond, struct amp_raw_mutex_s *mutex) { WaitForSingleObject(cond->wake_waiting_threads_mutex, INFINITE); { ++(cond->VAR(waiting_thread_count)); } amp_raw_mutex_unlock(mutex); SignalObjectAndWait(cond->wake_waiting_threads_mutex, cond->waking_waiting_threads_count_control_sem, INFINITE, FALSE); BOOL broadcast_in_progress = FALSE; LONG count = 0; EnterCriticalSection(&cond->access_waiting_threads_count_critsec); { count = --(cond->VAR(waiting_thread_count)); broadcast_in_progress = cond->VAR(broadcast_in_progress); } LeaveCriticalSection(&cond->access_waiting_threads_count_critsec); BOOL all_waiting_threads_awake = TRUE; if (TRUE == broadcast_in_progress && count > 0) { all_waiting_threads_awake = FALSE; } if (TRUE == all_waiting_threads_awake) { SetEvent(cond->finished_waking_waiting_threads_event); } amp_raw_mutex_lock(mutex); return AMP_SUCCESS; } struct amp_condvar_test : rl::test_suite { VAR_T(int) data; amp_raw_mutex_s mtx; amp_raw_condition_variable_s cv; void before() { VAR(data) = 0; amp_raw_mutex_init(&mtx); amp_raw_condition_variable_init(&cv); } void after() { amp_raw_mutex_finalize(&mtx); amp_raw_condition_variable_finalize(&cv); } void thread(unsigned index) { if (0 == index) { amp_raw_mutex_lock(&mtx); data($) += 1; amp_raw_condition_variable_signal(&cv); amp_raw_mutex_unlock(&mtx); } else { amp_raw_mutex_lock(&mtx); while (0 == data($)) { amp_raw_condition_variable_wait(&cv, &mtx); } amp_raw_mutex_unlock(&mtx); } } }; struct amp_condvar_test2 : rl::test_suite { VAR_T(int) stage; amp_raw_mutex_s mtx; amp_raw_condition_variable_s cv; void before() { VAR(stage) = 0; amp_raw_mutex_init(&mtx); amp_raw_condition_variable_init(&cv); } void after() { amp_raw_mutex_finalize(&mtx); amp_raw_condition_variable_finalize(&cv); } void thread(unsigned index) { if (0 == index) { amp_raw_mutex_lock(&mtx); stage($) += 1; amp_raw_condition_variable_broadcast(&cv); while (stage($) < 2) amp_raw_condition_variable_wait(&cv, &mtx); amp_raw_mutex_unlock(&mtx); } else if (1 == index) { amp_raw_mutex_lock(&mtx); while (stage($) != 1) amp_raw_condition_variable_wait(&cv, &mtx); stage($) += 1; amp_raw_condition_variable_broadcast(&cv); amp_raw_mutex_unlock(&mtx); } else if (2 == index) { amp_raw_mutex_lock(&mtx); while (stage($) != 2) amp_raw_condition_variable_wait(&cv, &mtx); stage($) += 1; //amp_raw_condition_variable_broadcast(&cv); amp_raw_mutex_unlock(&mtx); amp_raw_condition_variable_signal(&cv); } else if (3 == index) { amp_raw_mutex_lock(&mtx); while (stage($) != 3) amp_raw_condition_variable_wait(&cv, &mtx); amp_raw_mutex_unlock(&mtx); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/examples/examples.cpp ================================================ #include "stdafx.h" #include "spsc_overwrite_queue.hpp" #include "amp_condvar.hpp" int main() { rl::test_params p; p.iteration_count = 10000; //p.search_type = rl::sched_bound; //p.context_bound = 3; rl::execute(p); rl::simulate(p); rl::simulate(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/examples/msvc9/examples.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples", "examples.vcproj", "{6CC59CF8-408B-441B-8F65-15651210CB82}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.ActiveCfg = Debug|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.Build.0 = Debug|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.ActiveCfg = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/examples/msvc9/examples.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/examples/spsc_overwrite_queue.hpp ================================================ #pragma once template class queue { public: queue(size_t count) { assert(count >= 6); sema = CreateSemaphore(0, 0, 1, 0); waiting.store(false, std::memory_order_relaxed); deq_node = 0; block = new node [count]; block->next.store(0, std::memory_order_relaxed); full_tail = block; full_head.store(block, std::memory_order_relaxed); free_head = block + 1; free_tail.store(block + count - 1, std::memory_order_relaxed); free_tail.load(std::memory_order_relaxed)->next.store(0, std::memory_order_relaxed); for (size_t i = 1; i != count - 1; i += 1) block[i].next.store(block + i + 1, std::memory_order_relaxed); } ~queue() { CloseHandle(sema); delete [] block; } VAR_T(T)& enqueue_prepare() { return full_tail->data; } void enqueue_commit() { node* n = get_free_node(); n->next.store(0, std::memory_order_release); full_tail->next.store(n, std::memory_order_seq_cst); bool signal = waiting.load(std::memory_order_seq_cst); full_tail = n; if (signal) { waiting.store(false, std::memory_order_relaxed); ReleaseSemaphore(sema, 1, 0); } } VAR_T(T)& dequeue_prepare() { deq_node = get_full_node(); return deq_node->data; } void dequeue_commit() { deq_node->next.store(0, std::memory_order_release); node* prev = free_tail.exchange(deq_node, std::memory_order_acq_rel); prev->next.store(deq_node, std::memory_order_release); } private: struct node { std::atomic next; VAR_T(T) data; }; node* block; node* full_tail; node* free_head; node* deq_node; char pad [64]; std::atomic full_head; std::atomic free_tail; std::atomic waiting; HANDLE sema; node* get_free_node() { for (;;) { node* n = free_head; node* next = n->next.load(std::memory_order_acquire); if (next) { free_head = next; return n; } n = full_head.load(std::memory_order_acquire); next = n->next.load(std::memory_order_acquire); if (next) { if (full_head.compare_exchange_strong(n, next, std::memory_order_seq_cst)) { //node* n2 = free_head; //node* next2 = n2->next.load(std::memory_order_acquire); //if (next2) //{ // n->next.store(0, std::memory_order_release); // node* prev = free_tail.exchange(n, std::memory_order_acq_rel); // prev->next.store(n, std::memory_order_release); // free_head = next2; // return n2; //} //else { return n; } } } } } node* get_full_node() { node* n = full_head.load(std::memory_order_acquire); for (;;) { node* next = n->next.load(std::memory_order_acquire); if (next == 0) { waiting.store(true, std::memory_order_seq_cst); n = full_head.load(std::memory_order_seq_cst); next = n->next.load(std::memory_order_acquire); if (next) { waiting.store(false, std::memory_order_relaxed); } else { WaitForSingleObject(sema, INFINITE); n = full_head.load(std::memory_order_acquire); continue; } } if (full_head.compare_exchange_strong(n, next, std::memory_order_acq_rel)) return n; } } }; unsigned RL_STDCALL consumer_thread(void* ctx) { queue* q = (queue*)ctx; int prev_data = -1; for (;;) { VAR_T(int)& data0 = q->dequeue_prepare(); int data = VAR(data0); assert(data > prev_data); prev_data = data; q->dequeue_commit(); //printf("%d\n", prev_data); if (prev_data == 11) break; //Sleep(5); } return 0; } unsigned RL_STDCALL producer_thread(void* ctx) { queue* q = (queue*)ctx; for (int i = 0; i != 12; i += 1) { VAR_T(int)& data = q->enqueue_prepare(); VAR(data) = i; q->enqueue_commit(); //Sleep(1); } return 0; } void spsc_overwrite_queue_test() { queue q (6); HANDLE th [2]; th[0] = (HANDLE)_beginthreadex(0, 0, consumer_thread, &q, 0, 0); th[1] = (HANDLE)_beginthreadex(0, 0, producer_thread, &q, 0, 0); WaitForMultipleObjects(2, th, 1, INFINITE); for (int i = 100; i != 104; i += 1) { VAR_T(int)& data = q.enqueue_prepare(); VAR(data) = i; q.enqueue_commit(); } for (int i = 100; i != 104; i += 1) { VAR_T(int)& data0 = q.dequeue_prepare(); int data = VAR(data0); assert(data == i); q.dequeue_commit(); } } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/examples/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/examples/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #define RL_FORCE_SEQ_CST #define RL_MSVC_OUTPUT //#define RL_DEBUGBREAK_ON_FAILURE #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" #include "../../relacy/stdlib/windows.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/java_ws_deque/java_ws_deque.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_java.hpp" using rl::jvar; using rl::jvolatile; using rl::mutex; template class ws_deque { public: ws_deque() { m_mask($) = initial_size - 1; m_headIndex($) = 0; m_tailIndex($) = 0; m_array($) = new jvar [initial_size]; m_arraySize($) = initial_size; } bool IsEmpty() { return m_headIndex($) >= m_tailIndex($); } size_t Count() { return m_tailIndex($) - m_headIndex($); } void push(T item) { size_t tail = m_tailIndex($); if (tail <= m_headIndex($) + m_mask($)) { m_array($)[tail & m_mask($)]($) = item; m_tailIndex($) = tail + 1; } else { m_foreignLock.lock($); size_t head = m_headIndex($); size_t count = Count(); if (count >= m_mask($)) { size_t arraySize = m_arraySize($); size_t mask = m_mask($); jvar* newArray = new jvar [arraySize * 2]; jvar* arr = m_array($); for (size_t i = 0; i != count; ++i) newArray[i]($) = arr[(i + head) & mask]($); m_array($) = newArray; m_arraySize($) = arraySize * 2; m_headIndex($) = 0; m_tailIndex($) = count; tail = count; m_mask($) = (mask * 2) | 1; } m_array($)[tail & m_mask($)]($) = item; m_tailIndex($) = tail + 1; m_foreignLock.unlock($); } } bool pop(T& item) { size_t tail = m_tailIndex($); if (tail == 0) return false; tail -= 1; m_tailIndex($) = tail; if (m_headIndex($) <= tail) { item = m_array($)[tail & m_mask($)]($); return true; } else { m_foreignLock.lock($); if (m_headIndex($) <= tail) { item = m_array($)[tail & m_mask($)]($); m_foreignLock.unlock($); return true; } else { m_tailIndex($) = tail + 1; m_foreignLock.unlock($); return false; } } } bool steal(T& item) { if (false == m_foreignLock.try_lock($)) return false; size_t head = m_headIndex($); m_headIndex($) = head + 1; if (head < m_tailIndex($)) { item = m_array($)[head & m_mask($)]($); m_foreignLock.unlock($); return true; } else { m_headIndex($) = head; m_foreignLock.unlock($); return false; } } private: static size_t const initial_size = 2; jvar*> m_array; jvar m_mask; jvar m_arraySize; jvolatile m_headIndex; jvolatile m_tailIndex; mutex m_foreignLock; }; struct ws_deque_test : rl::test_suite { ws_deque q; bool state [2]; void before() { state[0] = true; state[1] = true; } void after() { RL_ASSERT(state[0] == false); RL_ASSERT(state[1] == false); } void thread(unsigned index) { if (0 == index) { q.push(1); q.push(2); int item = 0; bool res = q.pop(item); RL_ASSERT(res && item == 2); RL_ASSERT(state[1]); state[1] = false; item = 0; res = q.pop(item); if (res) { RL_ASSERT(state[0]); state[0] = false; } item = 0; res = q.pop(item); RL_ASSERT(res == false); } else { int item = 0; bool res = q.steal(item); if (res) { RL_ASSERT(item == 1); RL_ASSERT(state[0]); state[0] = false; } } } }; int main() { rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/java_ws_deque/msvc8/java_ws_deque.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "java_ws_deque", "java_ws_deque.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/java_ws_deque/msvc8/java_ws_deque.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/java_ws_deque/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/java_ws_deque/stdafx.h ================================================ #pragma once #include "../../relacy/pch.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mpmc/mpmc.cpp ================================================ #include "stdafx.h" #ifdef RL_TEST #define ATOMIC(x) rl::atomic #define VAR(x) rl::var #define ATOMIC_FETCH_ADD(x, v) x($).fetch_add(v) #define ATOMIC_COMPARE_EXCHANGE(x, c, v) x($).compare_exchange(c, v) #define LOAD_ACQ(x) x($).load(rl::memory_order_acquire) #define STORE_REL(x, v) x($).store(v, rl::memory_order_release) #else #define ATOMIC(x) x volatile #define VAR(x) x #define ATOMIC_FETCH_ADD(x, v) _InterlockedExchangeAdd((long*)&x, v) #define ATOMIC_COMPARE_EXCHANGE(x, c, v) interlocked_compare_exchange(x, c, v) #define LOAD_ACQ(x) x #define STORE_REL(x, v) x = v template bool interlocked_compare_exchange(T& x, T& c, T v) { T c0 = _InterlockedCompareExchange((long*)&x), v, c); if (c0 == c) { return true; } else { c = c0; return false; } } #endif //#include "pcx.h" /* template class mpmcq { public: mpmcq() { STORE_REL(head_, alloc_block()); STORE_REL(tail_, LOAD_ACQ(head_)); } void enqueue(T v) { for (;;) { block* b = LOAD_ACQ(head_); unsigned raw = ATOMIC_FETCH_ADD(b->state_, state_head_inc); unsigned idx = raw >> state_head_pos; if (idx < item_count) { STORE_REL(b->data_[idx], v); return; } unsigned last = raw & state_last_msk; if (0 == last) { ATOMIC_COMPARE_EXCHANGE(head_, b, b+1); } else { block* b2 = LOAD_ACQ(b->next_); if (b2) { ATOMIC_COMPARE_EXCHANGE(head_, b, b2); } else { b2 = alloc_block(); block* b3 = 0; if (ATOMIC_COMPARE_EXCHANGE(b->next_, b3, b2)) { ATOMIC_COMPARE_EXCHANGE(head_, b, b2); } else { for (;;) { b = LOAD_ACQ(head_); while (0 == (LOAD_ACQ(b->state_) & state_last_msk)) b = b + 1; while (LOAD_ACQ(b->next_)) b = LOAD_ACQ(b->next_) + block_count - 1; b3 = 0; if (ATOMIC_COMPARE_EXCHANGE(b->next_, b3, b2)) break; } } } } } } T dequeue() { for (;;) { block* b = LOAD_ACQ(tail_); unsigned cmp = LOAD_ACQ(b->state_); unsigned tail = cmp & (state_last_msk - 1); if (tail < item_count) { unsigned head = cmp >> state_head_pos; if (tail < head) { unsigned xchg = cmp + state_tail_inc; if (ATOMIC_COMPARE_EXCHANGE(b->state_, cmp, xchg)) { for (;;) { T v = LOAD_ACQ(b->data_[tail]); if (v != T()) return v; rl::yield($); } } } else { return T(); } } else { unsigned last = cmp & state_last_msk; if (0 == last) { ATOMIC_COMPARE_EXCHANGE(tail_, b, b+1); } else { block* b2 = LOAD_ACQ(b->next_); if (0 == b2) return T(); ATOMIC_COMPARE_EXCHANGE(tail_, b, b2); } } } } private: static unsigned const state_head_pos = 7; static unsigned const state_head_inc = 1 << state_head_pos; static unsigned const state_last_msk = 1 << 6; static unsigned const state_tail_inc = 1 << 0; static unsigned const item_count = 2; static unsigned const block_count = 16; struct block { //unsigned head_ : 24; //unsigned last_ : 1; //unsigned tail_ : 7; ATOMIC(unsigned) state_; ATOMIC(block*) next_; ATOMIC(T) data_ [item_count]; }; struct superblock { block blocks_ [block_count]; }; char pad0_ [64]; ATOMIC(block*) head_; char pad1_ [64]; ATOMIC(block*) tail_; char pad2_ [64]; block* alloc_block() { superblock* sb = RL_NEW(superblock); for (int x = 0; x != block_count; ++x) { block* b = &sb->blocks_[x]; STORE_REL(b->state_, 0); STORE_REL(b->next_, 0); for (int y = 0; y != item_count; ++y) { STORE_REL(b->data_[y], 0); } } STORE_REL(sb->blocks_[block_count - 1].state_, 1 * state_head_inc + 1 * state_tail_inc + state_last_msk); return &sb->blocks_[0]; } }; struct test_mpmc : rl::test_suite { mpmcq q; void thread(unsigned idx) { if (idx < thread_count / 2) { for (int i = 0; i != 2; ++i) q.enqueue(1); } else { for (int i = 0; i != 2; ++i) q.dequeue(); } } }; */ struct thread_node { rl::var next; rl::var count; rl::var unconsumed; rl::HANDLE sema; rl::CRITICAL_SECTION mtx; }; void on_thread_exit(thread_node*& t_thread_node) { thread_node* head = t_thread_node; thread_node* my = 0; if (head) { rl::EnterCriticalSection(&head->mtx, $); std::atomic_thread_fence($)(std::memory_order_seq_cst); if (head->next($)) { my = head->next($); head->next($) = (thread_node*)my->next($); } else { my = head; } std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&head->mtx, $); while (my->unconsumed($)) { rl::WaitForSingleObject(my->sema, rl::RL_INFINITE, $); my->unconsumed($) -= 1; } rl::DeleteCriticalSection(&my->mtx, $); rl::CloseHandle(my->sema, $); RL_DELETE(my); } } struct eventcount { eventcount() { root($) = 0; rl::InitializeCriticalSection(&mtx, $); } ~eventcount() { rl::DeleteCriticalSection(&mtx, $); } void prepare_wait(thread_node*& t_thread_node) { thread_node* my = 0; thread_node* head = t_thread_node; if (head) { rl::EnterCriticalSection(&head->mtx, $); std::atomic_thread_fence($)(std::memory_order_seq_cst); //RL_ASSERT(head->status == stat_root); RL_ASSERT (root($) != head); if (head->next($)) { my = head->next($); head->next($) = (thread_node*)my->next($); my->next($) = 0; //node_status st; //if (stat_bucket != (st = (node_status)_InterlockedExchange(&my->status, stat_private))) // __asm int 3; RL_ASSERT (0 == my->count($)); } else { my = head; //node_status st; //if (stat_root != (st = (node_status)_InterlockedExchange(&my->status, stat_private))) // __asm int 3; RL_ASSERT(0 == my->count($)); } std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&head->mtx, $); } else { my = RL_NEW thread_node; my->next($) = 0; my->count($) = 0; my->unconsumed($) = 0; my->sema = rl::CreateSemaphore(0, 0, LONG_MAX, 0, $); //my->status = stat_private; rl::InitializeCriticalSection(&my->mtx, $); } while (my->unconsumed($)) { rl::WaitForSingleObject(my->sema, rl::RL_INFINITE, $); my->unconsumed($) -= 1; } RL_ASSERT(0 == my->next($)); RL_ASSERT(0 == my->count($)); //if (my->status != stat_private) __asm int 3; rl::EnterCriticalSection(&mtx, $); std::atomic_thread_fence($)(std::memory_order_seq_cst); RL_ASSERT(root($) != my); if (root($)) { my->next($) = (thread_node*)((thread_node*)root($))->next($); ((thread_node*)root($))->next($) = my; //node_status st; //if (stat_private != (st = (node_status)_InterlockedExchange(&my->status, stat_bucket))) // __asm int 3; my = root($); } else { root($) = my; //node_status st; //if (stat_private != (st = (node_status)_InterlockedExchange(&my->status, stat_root))) // __asm int 3; } ((thread_node*)root($))->count($) += 1; std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&mtx, $); t_thread_node = my; } void wait(thread_node*& t_thread_node) { thread_node* head = t_thread_node; if (head == root($)) { rl::WaitForSingleObject(head->sema, rl::RL_INFINITE, $); } else { rl::EnterCriticalSection(&head->mtx, $); std::atomic_thread_fence($)(std::memory_order_seq_cst); head->unconsumed($) += 1; std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&head->mtx, $); } } void retire_wait(thread_node*& t_thread_node) { thread_node* head = t_thread_node; if (head == root($)) { rl::EnterCriticalSection(&mtx, $); std::atomic_thread_fence($)(std::memory_order_seq_cst); if (head == root($)) { thread_node* my = 0; head->count($) -= 1; if (head->next($)) { my = head->next($); head->next($) = (thread_node*)my->next($); my->next($) = 0; } else { my = head; root($) = 0; } std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&mtx, $); //my->status = stat_root; t_thread_node = my; return; } std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&mtx, $); } rl::EnterCriticalSection(&head->mtx, $); std::atomic_thread_fence($)(std::memory_order_seq_cst); head->unconsumed($) += 1; std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&head->mtx, $); } void signal_all() { //std:: //_mm_mfence(); thread_node* head = root($); if (0 == head) return; rl::EnterCriticalSection(&mtx, $); std::atomic_thread_fence($)(std::memory_order_seq_cst); if (head != root($)) { std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&mtx, $); return; } size_t count = head->count($); head->count($) = 0; root($) = 0; std::atomic_thread_fence($)(std::memory_order_seq_cst); rl::LeaveCriticalSection(&mtx, $); rl::ReleaseSemaphore(head->sema, count, 0, $); } std::atomic root; rl::CRITICAL_SECTION mtx; }; struct test_ec : rl::test_suite { std::atomic x [2]; eventcount ec; void before() { x[0]($) = 0; x[1]($) = 0; } void thread(unsigned idx) { if (idx < 4) { for (int i = 0; i != 3; ++i) { x[idx % 2]($).fetch_add(1); ec.signal_all(); } } else { thread_node* my = 0; for (int i = 0; i != 3; ++i) { for (;;) { int cmp = x[idx % 2]($); if (cmp > 0) { if (x[idx % 2]($).compare_exchange(cmp, cmp - 1)) break; } else { for (;;) { ec.prepare_wait(my); cmp = x[idx % 2]($); if (cmp > 0) { ec.retire_wait(my); break; } ec.wait(my); cmp = x[idx % 2]($); if (cmp > 0) { break; } } } } } on_thread_exit(my); } } }; int main() { rl::test_params p; p.iteration_count = 20000000; p.initial_state = "10000000"; rl::simulate(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mpmc/msvc8/mpmc.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpmc", "mpmc.vcproj", "{ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Debug|Win32.ActiveCfg = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Debug|Win32.Build.0 = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Release|Win32.ActiveCfg = Release|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mpmc/msvc8/mpmc.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mpmc/pcx.h ================================================ #pragma once #include #pragma intrinsic (_InterlockedExchangeAdd) #pragma intrinsic (_InterlockedCompareExchange) //#define PCX_DEBUG #ifdef PCX_DEBUG #include #include #endif namespace rl { size_t const cacheline_size = 64; struct pcx_node { typedef void (*pcx_dtor_t)(pcx_node*); ATOMIC(pcx_node*) pcx_next_; ATOMIC(pcx_dtor_t) pcx_dtor_; }; namespace pcx_int { unsigned const word_bits = 32; unsigned const collector_bits = 4; unsigned const collector_count = 1 << collector_bits; unsigned const counter_inc = 1 << (collector_bits * 2); unsigned const is_current_inc = 1; unsigned const back_link_inc = 2; struct master; struct collector; struct local_collector { pcx_node* defer_head_; pcx_node defer_tail_; unsigned defer_size_; }; struct thread_int { pcx_int::master* master_; pcx_int::collector* collectors_; unsigned recursion_count_; unsigned is_acquired_; unsigned collector_index_; unsigned last_seen_collector_index_; unsigned flush_tail_; pcx_node* defer_head_; pcx_node defer_tail_; unsigned defer_size_; unsigned promote_; local_collector local_collectors_ [collector_count]; }; } class pcx_thread : private pcx_int::thread_int { public: static pcx_thread& get(); void acquire(); void release(); void defer(pcx_node* node, pcx_node::pcx_dtor_t dtor); void flush(); void promote(); void quiescent(); void init(); void deinit(); private: unsigned acquire_impl(); void release_impl(unsigned, unsigned); void flush_impl(); void local_flush(); void quiescent_impl(); friend void init(); friend void deinit(); friend void thread_callback(bool); }; namespace pcx_int { struct master { char pad0_ [64]; unsigned garbage_threshold_; char pad1_ [64]; struct state_part { unsigned current_collector_ : collector_bits; unsigned collector_tail_ : collector_bits; unsigned outer_counter_ : word_bits - 2 * collector_bits; }; union state { long whole_; state_part part_; }; state state_; char pad2_ [64]; state state_copy_; char pad3_ [64]; }; struct collector { char pad0_ [64]; pcx_node* defer_list_head_; unsigned defer_list_size_; char pad1_ [64]; struct state_part { unsigned is_current_ : 1; unsigned back_link_ : 1; unsigned pad_ : collector_bits * 2 - 2; unsigned inner_counter_ : word_bits - 2 * collector_bits; }; union state { long whole_; state_part part_; }; state state_; char pad2_ [64]; }; __declspec(selectany) master g_master; __declspec(selectany) collector g_collectors [collector_count]; __declspec(selectany, thread) thread_int* g_thread_instance; typedef void (__stdcall nt_tls_cb_t)(void*, unsigned long, void*); nt_tls_cb_t on_tls_callback; #pragma data_seg(push, old_seg) #pragma data_seg(".CRT$XLB") __declspec(selectany, dllexport) nt_tls_cb_t* volatile p_thread_callback = on_tls_callback; #pragma data_seg(pop, old_seg) inline void __stdcall on_tls_callback(void*, unsigned long reason, void*) { if (1 == reason) { init(); thread_callback(true); } else if (0 == reason) { thread_callback(false); deinit(); } if (2 == reason) { thread_callback(true); } else if (3 == reason) { thread_callback(false); } } } inline void init() { using namespace pcx_int; master& m = g_master; m.garbage_threshold_ = 128; m.state_.part_.current_collector_ = 0; m.state_.part_.collector_tail_ = 0; m.state_.part_.outer_counter_ = 0; m.state_copy_.part_.current_collector_ = 0; m.state_copy_.part_.collector_tail_ = 0; m.state_copy_.part_.outer_counter_ = 0; for (unsigned i = 0; i != collector_count; ++i) { collector& c = g_collectors[i]; c.defer_list_head_ = 0; c.defer_list_size_ = 0; c.state_.part_.is_current_ = 1; c.state_.part_.back_link_ = 1; c.state_.part_.inner_counter_ = 0; } g_collectors[0].state_.part_.back_link_ = 0; } inline void deinit() { using namespace pcx_int; pcx_thread::get().release_impl(g_master.state_.part_.current_collector_, is_current_inc); } inline void thread_callback(bool init) { if (init) { g_thread_instance = RL_NEW pcx_thread (); pcx_thread::get().init(); } else { pcx_thread::get().deinit(); RL_DELETE(g_thread_instance); g_thread_instance = 0; } } inline pcx_thread& pcx_thread::get() { return static_cast(*pcx_int::g_thread_instance); } inline unsigned pcx_thread::acquire_impl() { using namespace pcx_int; long const prev = _InterlockedExchangeAdd( &master_->state_.whole_, counter_inc); master::state_part u = {prev}; #ifdef PCX_DEBUG std::ostringstream ss; ss << "[PCX] thread " << this << " acquire " << u.current_collector_ << "\n"; OutputDebugStringA(ss.str().c_str()); #endif if (u.current_collector_ == flush_tail_ && local_collectors_[flush_tail_].defer_size_) { local_flush(); } return u.current_collector_; } inline void pcx_thread::release_impl(unsigned index, unsigned count) { using namespace pcx_int; collector& c = collectors_[index]; unsigned const prev = _InterlockedExchangeAdd( &c.state_.whole_, (unsigned)-(int)count); #ifdef PCX_DEBUG std::ostringstream ss; ss << "[PCX] thread " << this << " release " << index << "\n"; OutputDebugStringA(ss.str().c_str()); #endif if (0 == prev - count) { pcx_node* curr = c.defer_list_head_; while (curr) { pcx_node* next = curr->pcx_next_; curr->pcx_dtor_(curr); curr = next; } c.defer_list_head_ = 0; c.defer_list_size_ = 0; c.state_.part_.back_link_ = 1; c.state_.part_.is_current_ = 1; long u; if (index != collector_count - 1) u = collector_count; else u = -(long)(collector_count * (collector_count - 1)); _InterlockedExchangeAdd(&master_->state_.whole_, u); release_impl((index + 1) % collector_count, back_link_inc); } } inline void pcx_thread::flush_impl() { using namespace pcx_int; _mm_mfence(); master::state state = master_->state_; last_seen_collector_index_ = state.part_.current_collector_; collector& gc = collectors_[state.part_.current_collector_]; local_collector& lc = local_collectors_[state.part_.current_collector_]; lc.defer_head_->pcx_next_ = defer_tail_.pcx_next_; lc.defer_head_ = defer_tail_.pcx_next_; lc.defer_size_ += defer_size_; defer_head_ = &defer_tail_; defer_tail_.pcx_next_ = 0; defer_size_ = 0; if (master_->garbage_threshold_ < lc.defer_size_ || promote_) { master::state cmp; master::state val; do { cmp = master_->state_; if (cmp.part_.current_collector_ != last_seen_collector_index_) { promote_ = 0; return; } unsigned next_index = (last_seen_collector_index_ + 1) % collector_count; if (cmp.part_.collector_tail_ == next_index) return; val = cmp; val.part_.current_collector_ += 1; val.part_.outer_counter_ = 0; } while (cmp.whole_ != _InterlockedCompareExchange( (long*)&master_->state_.whole_, val.whole_, cmp.whole_)); last_seen_collector_index_ = val.part_.current_collector_; promote_ = 0; _InterlockedIncrement((long*)&master_->state_copy_.whole_); _InterlockedExchangeAdd((long*)&gc.state_.whole_, cmp.part_.outer_counter_ * counter_inc - is_current_inc); } } __declspec(noinline) inline void pcx_thread::local_flush() { using namespace pcx_int; if (flush_tail_ == master_->state_.part_.collector_tail_) return; #ifdef PCX_DEBUG std::ostringstream ss; ss << "[PCX] thread " << this << " flush " << flush_tail_ << "\n"; OutputDebugStringA(ss.str().c_str()); #endif local_collector& lc = local_collectors_[flush_tail_]; pcx_node* curr = lc.defer_tail_.pcx_next_; while (curr) { #ifdef PCX_DEBUG std::ostringstream ss; ss << "[PCX] thread " << this << " destroy " << curr << "\n"; OutputDebugStringA(ss.str().c_str()); #endif pcx_node* next = curr->pcx_next_; curr->pcx_dtor_(curr); curr = next; } lc.defer_head_ = &lc.defer_tail_; lc.defer_tail_.pcx_next_ = 0; lc.defer_size_ = 0; flush_tail_ = (flush_tail_ + 1) % collector_count; } __declspec(noinline) inline void pcx_thread::quiescent_impl() { using namespace pcx_int; if (defer_size_) flush_impl(); release_impl(collector_index_, counter_inc); collector_index_ = acquire_impl(); } inline void pcx_thread::acquire() { using namespace pcx_int; recursion_count_ += 1; if (1 != recursion_count_) return; if (is_acquired_) return; collector_index_ = acquire_impl(); last_seen_collector_index_ = collector_index_; is_acquired_ = 1; } inline void pcx_thread::release() { using namespace pcx_int; recursion_count_ -= 1; if (0 == recursion_count_) { if (master_->state_copy_.part_.current_collector_ != collector_index_ || promote_) { if (defer_size_) flush_impl(); release_impl(collector_index_, counter_inc); is_acquired_ = 0; } } if (flush_tail_ != last_seen_collector_index_) { local_flush(); } } inline void pcx_thread::quiescent() { if (master_->state_copy_.part_.current_collector_ != collector_index_ || promote_) { quiescent_impl(); } if (flush_tail_ != last_seen_collector_index_) { local_flush(); } } inline void pcx_thread::defer(pcx_node* node, pcx_node::pcx_dtor_t dtor) { using namespace pcx_int; node->pcx_next_ = 0; node->pcx_dtor_ = dtor; defer_head_->pcx_next_ = node; defer_head_ = node; defer_size_ += 1; } inline void pcx_thread::flush() { using namespace pcx_int; if (recursion_count_) return; if (0 == is_acquired_) return; if (defer_size_) flush_impl(); release_impl(collector_index_, counter_inc); is_acquired_ = 0; } inline void pcx_thread::promote() { promote_ = 1; } inline void pcx_thread::init() { using namespace pcx_int; master_ = &g_master; collectors_ = g_collectors; defer_head_ = &defer_tail_; defer_tail_.pcx_next_ = 0; for (unsigned i = 0; i != collector_count; ++i) { local_collectors_[i].defer_head_ = &local_collectors_[i].defer_tail_; } } inline void pcx_thread::deinit() { flush(); } } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mpmc/stdafx.cpp ================================================ // stdafx.cpp : source file that includes just the standard includes // ws_deque.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mpmc/stdafx.h ================================================ #pragma once #pragma warning (disable: 4201) //#define RL_GC #define RL_MSVC_OUTPUT #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mutex_business_logic/msvc8/mutex_business_logic.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutex_business_logic", "mutex_business_logic.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mutex_business_logic/msvc8/mutex_business_logic.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mutex_business_logic/mutex_business_logic.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" class business_logic { public: typedef unsigned account_id_t; typedef double balance_t; business_logic() { pthread_rwlock_init(&accounts_guard, 0); } ~business_logic() { pthread_rwlock_destroy(&accounts_guard); } bool add_account(account_id_t acc_id, balance_t balance) { pthread_rwlock_wrlock(&accounts_guard); if (accounts.find(acc_id) != accounts.end()) { pthread_rwlock_unlock(&accounts_guard); return false; } accounts[acc_id].balance = balance; pthread_rwlock_unlock(&accounts_guard); return true; } bool transfer_balance(account_id_t acc_id1, account_id_t acc_id2, balance_t amount) { if (acc_id1 == acc_id2) return true; pthread_rwlock_rdlock(&accounts_guard); if (accounts.find(acc_id1) == accounts.end() || accounts.find(acc_id2) == accounts.end()) { pthread_rwlock_unlock(&accounts_guard); return false; } account_info& acc1 = accounts[acc_id1]; account_info& acc2 = accounts[acc_id2]; if (acc_id1 > acc_id2) { pthread_mutex_lock(&acc1.mtx); pthread_mutex_lock(&acc2.mtx); } else { pthread_mutex_lock(&acc2.mtx); pthread_mutex_lock(&acc1.mtx); } pthread_rwlock_unlock(&accounts_guard); acc1.balance -= amount; acc2.balance += amount; pthread_mutex_unlock(&acc1.mtx); pthread_mutex_unlock(&acc2.mtx); return true; } private: struct account_info { balance_t balance; pthread_mutex_t mtx; account_info() : balance() { pthread_mutex_init(&mtx, 0); } account_info(account_info const& acc) : balance(acc.balance) { pthread_mutex_init(&mtx, 0); } ~account_info() { pthread_mutex_destroy(&mtx); } }; typedef std::map account_map_t; account_map_t accounts; pthread_rwlock_t accounts_guard; }; struct business_logic_test : rl::test_suite { business_logic bl; static size_t const account_count = 4; void before() { for (size_t i = 0; i != account_count; ++i) { bool rv = bl.add_account(i, i * 10.0); RL_ASSERT(rv); } } void thread(unsigned /*index*/) { business_logic::account_id_t acc1 = rl::rand(account_count); business_logic::account_id_t acc2 = rl::rand(account_count); bool rv = bl.transfer_balance(acc1, acc2, 1.0); RL_ASSERT(rv); } }; int main() { rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mutex_business_logic/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/mutex_business_logic/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #define RL_MSVC_OUTPUT //#define RL_DEBUGBREAK_ON_FAILURE #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/peterson/msvc8/peterson.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peterson", "peterson.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/peterson/msvc8/peterson.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/peterson/msvc9/peterson.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peterson", "peterson.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/peterson/msvc9/peterson.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/peterson/peterson.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" #include "../../relacy/windows.h" struct peterson_mutex_test : rl::test_suite { std::atomic flag0; std::atomic flag1; std::atomic turn; rl::var data; void before() { flag0($) = 0; flag1($) = 0; turn($) = 0; } void thread(unsigned index) { if (0 == index) { flag0($).store(1); turn($).store(1); while (flag1($).load() && 1 == turn($).load()); data($) = 1; flag0($).store(0); } else { flag1($).store(1); turn($).store(0); while (flag0($).load() && 0 == turn($).load()); data($) = 2; flag1($).store(0); } } }; struct peterson_mutex_test2 : rl::test_suite { std::atomic flag0; std::atomic flag1; std::atomic turn; rl::var data; void before() { flag0($) = 0; flag1($) = 0; turn($) = 0; } void thread(unsigned index) { if (0 == index) { flag0.store(1, rl::memory_order_relaxed); turn.exchange(1, rl::memory_order_acq_rel); while (flag1.load(rl::memory_order_acquire) && 1 == turn.load(rl::memory_order_relaxed)) rl::yield(1, $); data($) = 1; flag0.store(0, rl::memory_order_release); } else { flag1.store(1, rl::memory_order_relaxed); turn.exchange(0, rl::memory_order_acq_rel); while (flag0.load(rl::memory_order_acquire) && 0 == turn.load(rl::memory_order_relaxed)) rl::yield(1, $); data($) = 2; flag1.store(0, rl::memory_order_release); } } }; struct peterson_mutex_test3 : rl::test_suite { std::atomic flag0; std::atomic flag1; std::atomic turn; rl::var data; void before() { flag0($) = 0; flag1($) = 0; turn($) = 0; } void thread(unsigned index) { if (0 == index) { flag0.store(1, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); turn.store(1, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); while (flag1.load(std::memory_order_acquire) && 1 == turn.load(std::memory_order_relaxed)); data($) = 1; flag0.store(0, std::memory_order_release); } else { flag1.store(1, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); turn.store(0, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); while (flag0.load(std::memory_order_acquire) && 0 == turn.load(std::memory_order_relaxed)); data($) = 2; flag1.store(0, std::memory_order_release); } } }; // FAILS WITH DATA RACE struct peterson_mutex_test4 : rl::test_suite { std::atomic flag0; std::atomic flag1; std::atomic turn; rl::var data; void before() { flag0($) = 0; flag1($) = 0; turn($) = 0; } void thread(unsigned index) { if (0 == index) { flag0.exchange(1, rl::memory_order_acq_rel); turn.store(1, rl::memory_order_release); while (flag1.load(rl::memory_order_acquire) && 1 == turn.load(rl::memory_order_acquire)) rl::yield(1, $); data($) = 1; flag0.store(0, rl::memory_order_release); } else { flag1.exchange(1, rl::memory_order_acq_rel); turn.store(0, rl::memory_order_release); while (flag0.load(rl::memory_order_acquire) && 0 == turn.load(rl::memory_order_relaxed)) rl::yield(1, $); data($) = 2; flag1.store(0, rl::memory_order_release); } } }; class eventcount { public: typedef unsigned state_t; eventcount() { state_.store(0, std::memory_order_relaxed); sema_ = CreateSemaphore(0, 0, LONG_MAX, 0); } ~eventcount() { CloseHandle(sema_); } state_t prepare() { return state_.fetch_add(waiters_inc, std::memory_order_seq_cst); } void retire() { state_.fetch_add((state_t)-(int)waiters_inc, std::memory_order_seq_cst); } void wait(state_t cmp) { WaitForSingleObject(sema_, INFINITE); state_t cmp0 = state_.load(std::memory_order_seq_cst); if ((cmp & generation_mask) == (cmp0 & generation_mask)) { state_.fetch_add((state_t)-(int)waiters_inc, std::memory_order_seq_cst); ReleaseSemaphore(sema_, 1, 0); SwitchToThread(); } } void signal() { std::atomic_thread_fence(std::memory_order_seq_cst); signal_relaxed(); } void signal_relaxed() { state_t cmp = state_.load(std::memory_order_seq_cst); if (0 == (cmp & waiters_mask)) return; for (;;) { state_t xchg = (cmp & ~waiters_mask) + generation_inc; if (state_.compare_exchange_weak(cmp, xchg, std::memory_order_seq_cst)) { ReleaseSemaphore(sema_, cmp & waiters_mask, 0); return; } if (0 == (cmp & waiters_mask)) return; } } private: std::atomic state_; HANDLE sema_; static state_t const waiters_inc = 1; static state_t const waiters_mask = (1 << 20) - 1; static state_t const generation_inc = 1 << 20; static state_t const generation_mask = ~waiters_mask; eventcount(eventcount const&); eventcount& operator = (eventcount const&); }; class eventcount_blocking { public: eventcount_blocking(eventcount& ec) : ec_(ec) { cmp_ = ec_.prepare(); wait_ = false; } void wait() { RL_ASSERT(false == wait_); wait_ = true; ec_.wait(cmp_); } ~eventcount_blocking() { if (false == wait_) ec_.retire(); } private: eventcount& ec_; eventcount::state_t cmp_; bool wait_; eventcount_blocking(eventcount_blocking const&); eventcount_blocking& operator = (eventcount_blocking const&); }; struct signaling_test : rl::test_suite { //rl::HANDLE var_wait_for_items; //rl::CRITICAL_SECTION mtx_items_avail; //std::atomic n_waiting_consumers; //rl::var consumer_wait_generation; //rl::var n_consumers_to_wakeup; eventcount ec_; static int const max_queue_length = 4; int queue [max_queue_length]; int queue_head; int queue_tail; int queue_head_data; int queue_tail_data; void before() { //var_wait_for_items = rl::CreateEvent(0, 1, 0, 0, $); //rl::InitializeCriticalSection(&mtx_items_avail, $); //n_waiting_consumers($) = 0; //consumer_wait_generation($) = 0; //n_consumers_to_wakeup($) = 0; for (int i = 0; i != max_queue_length; ++i) queue[i] = 0; queue_head = 0; queue_tail = 0; queue_head_data = 0; queue_tail_data = 0; } void after() { //rl::CloseHandle(var_wait_for_items, $); //rl::DeleteCriticalSection(&mtx_items_avail, $); } struct enqueue_desc { int pos; void output(std::ostream& s) const { s << "enqueue " << pos; } }; void enqueue() { queue[queue_head++] = ++queue_head_data; RL_HIST_IMPL(rl::ctx(), $, enqueue_desc) {queue_head - 1} RL_HIST_END(); signal(); } void dequeue() { int my_pos = queue_tail++; for (;;) { if (queue[my_pos]) { RL_ASSERT(queue[my_pos] == my_pos + 1); return; } wait(my_pos); } } void signal() { ec_.signal(); /* std::atomic_thread_fence($)(std::memory_order_seq_cst); if (n_waiting_consumers($).load(std::memory_order_relaxed)) { rl::EnterCriticalSection(&mtx_items_avail, $); if (n_waiting_consumers($).load(std::memory_order_relaxed) > 0) { consumer_wait_generation($) += 1; //RL_ASSERT(n_consumers_to_wakeup($) == 0); n_consumers_to_wakeup($) = n_waiting_consumers($).load(std::memory_order_relaxed); rl::SetEvent(var_wait_for_items, $); } rl::LeaveCriticalSection(&mtx_items_avail, $); } */ } void wait(int my_pos) { eventcount_blocking block (ec_); if (queue[my_pos]) return; block.wait(); /* rl::EnterCriticalSection(&mtx_items_avail, $); n_waiting_consumers($).store(n_waiting_consumers($).load(std::memory_order_relaxed) + 1, std::memory_order_relaxed); std::atomic_thread_fence($)(std::memory_order_seq_cst); while (0 == queue[my_pos]) { unsigned my_generation = consumer_wait_generation($); for (;;) { rl::LeaveCriticalSection(&mtx_items_avail, $); rl::WaitForSingleObject(var_wait_for_items, rl::RL_INFINITE, $); rl::EnterCriticalSection(&mtx_items_avail, $); if (n_consumers_to_wakeup($) > 0 && consumer_wait_generation($) != my_generation) break; } if (--n_consumers_to_wakeup($) == 0) rl::ResetEvent(var_wait_for_items, $); } n_waiting_consumers($).store(n_waiting_consumers($).load(std::memory_order_relaxed) - 1, std::memory_order_relaxed); rl::LeaveCriticalSection(&mtx_items_avail, $); */ } void thread(unsigned index) { if (index < rl::test_suite::params::thread_count/2+1) { enqueue(); } else { dequeue(); } } }; int main() { rl::test_params p; //p.search_type = rl::fair_context_bound_scheduler_type; p.search_type = rl::sched_bound; //p.context_bound = 1; //p.execution_depth_limit = 100; //p.iteration_count = 5000; //p.initial_state = "280572"; //rl::simulate(p); rl::simulate(); rl::simulate(p); rl::simulate(); rl::simulate(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/peterson/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/peterson/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #define RL_MSVC_OUTPUT //#define RL_DEBUGBREAK_ON_FAILURE #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/proxy_collector/msvc8/proxy_collector.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proxy_collector", "proxy_collector.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B29}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/proxy_collector/msvc8/proxy_collector.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/proxy_collector/msvc9/proxy_collector.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proxy_collector", "proxy_collector.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B29}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/proxy_collector/msvc9/proxy_collector.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/proxy_collector/proxy_collector.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" struct pc_sys_anchor; struct pc_region; struct pc_master; typedef pc_region pc_node; typedef void (pc_fp_dtor) (pc_region*); typedef unsigned __int64 uint64_t; struct pc_sys_anchor { int refcnt; pc_region* region; pc_sys_anchor() { } pc_sys_anchor(int rc, pc_region* r = 0) { refcnt = rc; region = r; } bool operator == (pc_sys_anchor const& right) const { return refcnt == right.refcnt && region == right.region; } pc_sys_anchor operator + (pc_sys_anchor const& right) const { pc_sys_anchor res; res.refcnt = refcnt + right.refcnt; res.region = (pc_region*)((intptr_t)region + (intptr_t)right.region); return res; } pc_sys_anchor operator - (pc_sys_anchor const& right) const { pc_sys_anchor res; res.refcnt = refcnt - right.refcnt; res.region = (pc_region*)((intptr_t)region - (intptr_t)right.region); return res; } }; std::ostream& operator << (std::ostream& s, pc_sys_anchor const& right) { return s << "{" << right.refcnt << "," << right.region << "}"; } struct pc_region { std::atomic next; std::atomic defer; pc_region() { next($) = pc_sys_anchor(0, 0); defer($) = 0; } void link(pc_region* next) { defer.store(next, rl::memory_order_relaxed); } void defer_node(pc_region* node) { pc_region* region = defer.exchange(node, rl::memory_order_release); node->defer.store(region, rl::memory_order_relaxed); } }; struct pc_master { std::atomic head; pc_region stub_region; pc_fp_dtor* fp_dtor; pc_master(pc_fp_dtor* const dtor) { pc_sys_anchor src (0, &stub_region); head.store(src, rl::memory_order_relaxed); fp_dtor = dtor; } pc_region* acquire() { pc_sys_anchor cmp (head.load(rl::memory_order_relaxed)); pc_sys_anchor xchg; do { xchg.refcnt = cmp.refcnt + 2; xchg.region = cmp.region; } while (false == head.compare_exchange_weak(cmp, xchg, rl::memory_order_acquire)); return cmp.region; } void release(pc_region* region) { pc_sys_anchor prev = region->next.fetch_sub(2, rl::memory_order_acq_rel); if (prev.refcnt == 3) sys_dtor(region); } void mutate(pc_region* node) { pc_sys_anchor src (2, 0); node->next.store(src, rl::memory_order_relaxed); pc_sys_anchor xchg (0, node); pc_sys_anchor cmp = head.load(rl::memory_order_relaxed); while (false == head.compare_exchange_weak(cmp, xchg, std::memory_order_acq_rel)); pc_sys_anchor cmp2 = cmp.region->next.load(rl::memory_order_relaxed); pc_sys_anchor xchg2; do { xchg2 = pc_sys_anchor(cmp2.refcnt, node); } while (false == cmp.region->next.compare_exchange_weak(cmp2, xchg2, rl::memory_order_release)); pc_sys_anchor prev = cmp.region->next.fetch_add(cmp.refcnt + 1, rl::memory_order_acq_rel); if (prev.refcnt == -cmp.refcnt) sys_dtor(cmp.region); } void sys_dtor(pc_region* region) { int reset = 0; pc_region* head = region; pc_region* tail = region; pc_sys_anchor nx = region->next.load(rl::memory_order_relaxed); pc_region* next = nx.region; while (next) { pc_sys_anchor prev = next->next.fetch_sub(2, rl::memory_order_acq_rel); if (prev.refcnt != 3) break; tail = next; nx = next->next.load(rl::memory_order_relaxed); next = nx.region; } nx = tail->next.load(rl::memory_order_relaxed); nx.region = 0; tail->next.store(nx, rl::memory_order_relaxed); while (head) { nx = head->next.load(rl::memory_order_relaxed); pc_region* const next = nx.region; pc_region* defer = head->defer.load(rl::memory_order_relaxed); nx = head->next.load(rl::memory_order_relaxed); RL_ASSERT(nx.refcnt == 1); if (head != &stub_region) { head->defer.store(defer, rl::memory_order_relaxed); defer = head; } else { reset = 1; } while (defer) { pc_region* const next = defer->defer.load(rl::memory_order_relaxed); fp_dtor(defer); defer = next; } head = next; } if (reset) { stub_region.defer.store(0, rl::memory_order_relaxed); mutate(&stub_region); } } }; struct foo_node { pc_node pcn; std::atomic next; rl::var data; }; void foo_node_dtor(pc_node* pcn) { // yes, very fragile foo_node* const n = (foo_node*)pcn; delete n; } struct foo_list { std::atomic head; pc_master pc; foo_list() : head(0) , pc(foo_node_dtor) { } }; struct proxy_collector_test : rl::test_suite { foo_list m_list; void before() { m_list.head($) = 0; } void after() { foo_node* node = new foo_node; m_list.pc.mutate(&node->pcn); } void thread(unsigned index) { if (index < 2) { pc_region* pcr = m_list.pc.acquire(); for (int i = 0; i != 4; ++i) { foo_node* node = m_list.head.load(rl::memory_order_acquire); while (node) { foo_node* const next = node->next.load(rl::memory_order_acquire); intptr_t volatile data = node->data($); (void)data; node = next; } if (2 == i) { m_list.pc.release(pcr); pcr = m_list.pc.acquire(); } } m_list.pc.release(pcr); } else { pc_region* pcr = m_list.pc.acquire(); for (int i = 0; i != 4; ++i) { if (0 == (i % 2)) { foo_node* node = new foo_node; node->data($) = 1; foo_node* cmp = m_list.head.load(rl::memory_order_relaxed); do { node->next.store(cmp, rl::memory_order_relaxed); } while (false == m_list.head.compare_exchange_weak(cmp, node, rl::memory_order_release)); } else { foo_node* node = m_list.head.load(rl::memory_order_acquire); foo_node* next; do { if (0 == node) break; next = node->next.load(rl::memory_order_relaxed); } while (false == m_list.head.compare_exchange_weak(node, next, rl::memory_order_acquire)); if (node) { //if (1 == i) { m_list.pc.mutate(&node->pcn); } //else //{ // pcr->defer_node(&node->pcn); //} } } if (i % 2) { m_list.pc.release(pcr); pcr = m_list.pc.acquire(); } } m_list.pc.release(pcr); } } }; int main() { rl::test_params params; params.iteration_count = 1000; rl::simulate(params); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/proxy_collector/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/proxy_collector/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #include "../../relacy/pch.hpp" #include ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ref_counting/msvc8/ref_counting.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ref_counting", "ref_counting.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B28}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ref_counting/msvc8/ref_counting.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ref_counting/msvc9/ref_counting.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ref_counting", "ref_counting.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B28}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ref_counting/msvc9/ref_counting.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ref_counting/ref_counting.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" struct rc_object { std::atomic rc; rl::var data; void acquire() { rc.fetch_add(1, rl::memory_order_acquire); } void release() { if (1 == rc.fetch_sub(1, rl::memory_order_release)) { rc.load(rl::memory_order_acquire); data($) = 0; delete this; } } rc_object(int data) : rc(1) , data(data) { } }; void post_to_channel(rl::atomic& ch, rc_object* obj) { obj->acquire(); rl::backoff b; for (;;) { rc_object* cmp = 0; if (ch.compare_exchange_weak(cmp, obj, rl::memory_order_release)) break; b.yield($); } } rc_object* get_from_channel(rl::atomic& ch) { return ch.exchange(0, rl::memory_order_acquire); } struct ref_counting_test : rl::test_suite { std::atomic channel; void before() { channel($) = 0; } void thread(unsigned index) { if (0 == index) { rc_object* obj = new rc_object (rand()); post_to_channel(channel, obj); int data = obj->data($); (void)data; obj->release(); } else if (1 == index) { rl::backoff b; for (;;) { rc_object* obj = get_from_channel(channel); if (obj) { int data = obj->data($); (void)data; obj->release(); break; } else { b.yield($); } } } } }; struct ref_counting_test2 : rl::test_suite { std::atomic channel01; std::atomic channel02; std::atomic channel12; std::atomic channel21; void before() { channel01($) = 0; channel02($) = 0; channel12($) = 0; channel21($) = 0; } void thread(unsigned index) { if (0 == index) { { rc_object* obj1 = new rc_object (rand()); post_to_channel(channel01, obj1); volatile int data = obj1->data($); (void)data; obj1->release(); } { rc_object* obj2 = new rc_object (rand()); post_to_channel(channel02, obj2); volatile int data = obj2->data($); (void)data; obj2->release(); } } else if (1 == index) { rl::backoff b; bool ch0 = false; bool ch2 = false; while (!ch0 || !ch2) { { rc_object* obj = get_from_channel(channel01); if (obj) { post_to_channel(channel12, obj); volatile int data = obj->data($); (void)data; obj->release(); ch0 = true; } else { b.yield($); } } { rc_object* obj = get_from_channel(channel21); if (obj) { volatile int data = obj->data($); (void)data; obj->release(); ch2 = true; } else { b.yield($); } } } } else { rl::backoff b; bool ch0 = false; bool ch1 = false; while (!ch0 || !ch1) { { rc_object* obj = get_from_channel(channel02); if (obj) { post_to_channel(channel21, obj); volatile int data = obj->data($); (void)data; obj->release(); ch0 = true; } else { b.yield($); } } { rc_object* obj = get_from_channel(channel12); if (obj) { volatile int data = obj->data($); (void)data; obj->release(); ch1 = true; } else { b.yield($); } } } } } }; struct ref_counting_test3 : rl::test_suite { std::atomic channel; void before() { channel($) = 0; } void thread(unsigned index) { if (0 == index) { rc_object* obj = new rc_object (rand()); post_to_channel(channel, obj); volatile int data = obj->data($); (void)data; obj->release(); } else if (1 == index) { rl::backoff b; rc_object* obj = 0; for (;;) { obj = get_from_channel(channel); if (obj) break; else b.yield($); } obj->acquire(); obj->release(); //volatile int data = obj->data($); //(void)data; obj->release(); } } }; int main() { rl::test_params params; params.context_bound = 2; params.iteration_count = 10000; rl::simulate(params); std::cout << "count: " << params.stop_iteration << std::endl; } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ref_counting/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ref_counting/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #include "../../relacy/pch.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/smr/msvc8/smr.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smr", "smr.vcproj", "{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.ActiveCfg = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.Build.0 = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.ActiveCfg = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/smr/msvc8/smr.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/smr/msvc9/smr.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smr", "smr.vcproj", "{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.ActiveCfg = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.Build.0 = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.ActiveCfg = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/smr/msvc9/smr.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/smr/smr.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" unsigned const thread_count = 3; unsigned const node_count = 6; struct smr_test : rl::test_suite { struct node { std::atomic next_; rl::var data_; }; std::atomic head_; std::atomic hp_ [thread_count]; rl::var defer_ [thread_count][thread_count]; rl::var defer_size_ [thread_count]; void before() { head_.store(0, std::memory_order_relaxed); for (size_t i = 0; i != thread_count; ++i) { hp_[i].store(0, std::memory_order_relaxed); VAR(defer_size_[i]) = 0; for (size_t j = 0; j != thread_count; ++j) VAR(defer_[i][j]) = 0; } } void push(unsigned index, int data) { node* n = new node (); n->VAR(data_) = data; node* next = head_.load(std::memory_order_relaxed); for (;;) { n->next_.store(next, rl::memory_order_relaxed); if (head_.compare_exchange_weak(next, n, rl::memory_order_release)) break; } } int pop(unsigned index) { node* n = 0; for (;;) { n = smr_acquire(index, head_); if (0 == n) break; node* next = n->next_.load(rl::memory_order_relaxed); if (head_.compare_exchange_weak(n, next, rl::memory_order_acquire)) break; smr_release(index); } smr_release(index); if (n) { int data = n->VAR(data_); smr_defer(index, n); return data; } else { return 0; } } void smr_pump(unsigned index) { node* hp [thread_count] = {}; for (size_t i = 0; i != thread_count; ++i) { hp[i] = hp_[i].load(std::memory_order_relaxed); } for (size_t i = 0; i != thread_count; ++i) { node* nn = VAR(defer_[index][i]); if (nn) { for (size_t j = 0; j != thread_count; ++j) { if (nn == hp[j]) { nn = 0; break; } } if (nn) { VAR(defer_[index][i]) = 0; VAR(defer_size_[index]) -= 1; delete nn; } } } } void smr_defer(unsigned index, node* n) { std::atomic_thread_fence(std::memory_order_seq_cst); smr_pump(index); if (VAR(defer_size_[index]) == thread_count) { delete n; } else { bool found = false; for (size_t i = 0; i != thread_count; ++i) { if (VAR(defer_[index][i]) == 0) { VAR(defer_[index][i]) = n; found = true; break; } } RL_ASSERT(found); VAR(defer_size_[index]) += 1; } } node* smr_acquire(unsigned index, std::atomic& n) { node* v = 0; for (;;) { v = n.load(std::memory_order_relaxed); hp_[index].store(v, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); node* v2 = n.load(std::memory_order_acquire); if (v2 == v) break; } return v; } void smr_release(unsigned index) { hp_[index].store(0, std::memory_order_relaxed); } void thread(unsigned index) { for (unsigned i = 0; i != node_count; ++i) { push(index, index * thread_count + i + 1); } for (unsigned i = 0; i != node_count; ++i) { int data = pop(index); RL_ASSERT(0 != data); } } void after() { for (unsigned i = 0; i != ::thread_count; ++i) { smr_pump(i); } } }; int main() { rl::test_params p; //p.collect_history = true; //p.output_history = true; //p.initial_state = "991172"; p.iteration_count = 1000; rl::simulate(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/smr/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/smr/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #define RL_MSVC_OUTPUT #include "../../relacy/pch.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/spsc_queue/msvc8/spsc_queue.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spsc_queue", "spsc_queue.vcproj", "{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Debug|Win32.ActiveCfg = Debug|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Debug|Win32.Build.0 = Debug|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Release|Win32.ActiveCfg = Release|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/spsc_queue/msvc8/spsc_queue.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/spsc_queue/msvc9/spsc_queue.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spsc_queue", "spsc_queue.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/spsc_queue/msvc9/spsc_queue.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/spsc_queue/spsc_queue.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" template class nonblocking_spsc_queue { public: nonblocking_spsc_queue() { node* n = new node (); VAR(head) = n; VAR(tail) = n; } ~nonblocking_spsc_queue() { RL_ASSERT(VAR(head) == VAR(tail)); delete (node*)VAR(head); } void enqueue(T data) { node* n = new node (data); VAR(head)->next.store(n, std::memory_order_release); VAR(head) = n; } bool dequeue(T& data) { node* t = VAR(tail); node* n = t->next.load(std::memory_order_acquire); if (0 == n) return false; data = n->VAR(data); delete t; VAR(tail) = n; return true; } private: struct node { std::atomic next; VAR_T(T) data; node(T data = T()) : next(0) , data(data) {} }; VAR_T(node*) head; VAR_T(node*) tail; }; struct nonblocking_spsc_queue_test : rl::test_suite { nonblocking_spsc_queue q; void thread(unsigned thread_index) { if (0 == thread_index) { q.enqueue(11); } else { int data = 0; while (false == q.dequeue(data)) {} RL_ASSERT(11 == data); } } }; class eventcount { public: eventcount() : count(0) , waiters(0) {} void signal_relaxed() { unsigned cmp = count.load(std::memory_order_relaxed); signal_impl(cmp); } void signal() { unsigned cmp = count.fetch_add(0, std::memory_order_seq_cst); signal_impl(cmp); } unsigned get() { unsigned cmp = count.fetch_or(0x80000000, std::memory_order_acquire); return cmp & 0x7FFFFFFF; } void wait(unsigned cmp) { unsigned ec = count.load(std::memory_order_seq_cst); if (cmp == (ec & 0x7FFFFFFF)) { guard.lock($); ec = count.load(std::memory_order_seq_cst); if (cmp == (ec & 0x7FFFFFFF)) { waiters($) += 1; cv.wait(guard, $); } guard.unlock($); } } private: std::atomic count; VAR_T(unsigned) waiters; std::mutex guard; std::condition_variable cv; void signal_impl(unsigned cmp) { if (cmp & 0x80000000) { guard.lock($); while (false == count.compare_exchange_weak(cmp, (cmp + 1) & 0x7FFFFFFF, std::memory_order_relaxed)); unsigned w = VAR(waiters); VAR(waiters) = 0; guard.unlock($); if (w) cv.notify_all($); } } }; template class spsc_queue : nonblocking_spsc_queue { public: typedef nonblocking_spsc_queue base_t; void enqueue(T data) { base_t::enqueue(data); ec.signal/*_relaxed*/(); } T dequeue() { T data; bool res = base_t::dequeue(data); while (false == res) { int cmp = ec.get(); res = base_t::dequeue(data); if (res) break; ec.wait(cmp); res = base_t::dequeue(data); if (res) break; } return data; } private: eventcount ec; }; struct spsc_queue_test : rl::test_suite { spsc_queue q; void thread(unsigned thread_index) { if (0 == thread_index) { q.enqueue(11); } else { int d = q.dequeue(); RL_ASSERT(11 == d); } } }; int main() { rl::simulate(); rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/spsc_queue/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/spsc_queue/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif //#define RL_MSVC_OUTPUT #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/DESCRIPTION.TXT ================================================ lock-free stack code contains several bugs: access to freed memory and ABA problem ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/msvc8/stack.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stack", "stack.vcproj", "{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.ActiveCfg = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.Build.0 = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.ActiveCfg = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/msvc8/stack.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/msvc9/stack.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stack", "stack.vcproj", "{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.ActiveCfg = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.Build.0 = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.ActiveCfg = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/msvc9/stack.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/stack.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" // TEST FAILS WITH "ACCESS TO FREED MEMORY" class stack { public: stack() : head_(0) { } void push(int data) { rl::var n = new node (); n($)->data_($) = data; node* next = head_.load(rl::memory_order_relaxed); for (;;) { n($)->next_.store(next, rl::memory_order_relaxed); if (head_.compare_exchange_weak(next, n($), rl::memory_order_release)) break; } } int pop() { node* n = head_.load(rl::memory_order_relaxed); for (;;) { if (0 == n) break; node* next = n->next_.load(rl::memory_order_relaxed); if (head_.compare_exchange_weak(n, next, rl::memory_order_acquire)) break; } if (n) { int data = n->data_($); delete n; return data; } else { return 0; } } private: struct node { std::atomic next_; rl::var data_; }; std::atomic head_; stack(stack const&); stack& operator = (stack const&); }; struct stack_test : rl::test_suite { stack s_; int produced_count_; int consumed_count_; void before() { produced_count_ = 0; consumed_count_ = 0; } void after() { typedef rl::test_suite base_t; RL_ASSERT(base_t::params::thread_count == produced_count_); RL_ASSERT(base_t::params::thread_count == consumed_count_); } void thread(unsigned /*index*/) { s_.push(rand() + 1); produced_count_ += 1; int data = s_.pop(); RL_ASSERT(data); consumed_count_ += 1; } }; int main() { rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/stack/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #include "../../relacy/pch.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/tbb_eventcount/eventcount.cpp ================================================ #include "stdafx.h" #include "../../relacy/windows.h" /* #define HANDLE rl::HANDLE #define CreateSemaphoreA rl::RL_CreateSemaphore($) #define CreateSemaphoreW rl::RL_CreateSemaphore($) #ifndef CreateSemaphore # define CreateSemaphore CreateSemaphoreW #endif //#define CRITICAL_SECTION rl::CRITICAL_SECTION //#define InitializeCriticalSection rl::InitializeCriticalSection($) #define CloseHandle rl::RL_CloseHandle($) */ #include #if defined(WIN32) && defined(_MSC_VER) #include #include class semaphore { public: semaphore() { h_ = rl::CreateSemaphore(0, 0, LONG_MAX, 0, $); } ~semaphore() { rl::CloseHandle(h_, $); } void wait() { rl::WaitForSingleObject(h_, rl::RL_INFINITE, $); } void post() { rl::ReleaseSemaphore(h_, 1, 0, $); } private: rl::HANDLE h_; semaphore(semaphore const&); semaphore& operator = (semaphore const&); }; class mutex { public: mutex() { rl::InitializeCriticalSection(&cs_, $); } ~mutex() { rl::DeleteCriticalSection(&cs_, $); } void lock() { rl::EnterCriticalSection(&cs_, $); } void unlock() { rl::LeaveCriticalSection(&cs_, $); } private: rl::CRITICAL_SECTION cs_; mutex(mutex const&); mutex& operator = (mutex const&); }; //void full_memory_fence() //{ // _mm_mfence(); //} //#define THREAD_LOCAL __declspec(thread) #elif defined(POSIX) && defined(GCC) #include #include class semaphore { public: semaphore() { sem_init(&sem_, 0, 0); } ~semaphore() { sem_destroy(&sem_); } void wait() { sem_wait(&sem_); } void post() { sem_post(&sem_); } private: sem_t sem_; semaphore(semaphore const&); semaphore& operator = (semaphore const&); }; class mutex { public: mutex() { pthread_mutex_init(&mutex_, 0); } ~mutex() { pthread_mutex_destroy(&mutex_); } void lock() { pthread_mutex_lock(&mutex_); } void unlock() { pthread_mutex_unlock(&mutex_); } private: pthread_mutex_t mutex_; mutex(mutex const&); mutex& operator = (mutex const&); }; void full_memory_fence() { __sync_synchronize(); } //#define THREAD_LOCAL __thread #endif class lock { public: lock(mutex& m) : m_(m) { m.lock(); } ~lock() { m_.unlock(); } private: mutex& m_; lock(lock const&); lock& operator = (lock const&); }; /** simple single-threaded double-linked list * nothing interesting */ class dlist { public: struct node { rl::var prev_; rl::var next_; node() { prev_($) = 0; next_($) = 0; } }; dlist() { reset(); } void push(node* n) { size_t s = size_($).load(rl::memory_order_relaxed); size_($).store(s + 1, rl::memory_order_relaxed); n->next_($) = head_.next_($); n->prev_($) = &head_; head_.next_($)->prev_($) = n; head_.next_($) = n; } node* pop() { if (size_($).load(rl::memory_order_relaxed) == 0) return 0; node* n = head_.next_($); remove(n); return n; } void remove(node* n) { size_t s = size_($).load(rl::memory_order_relaxed); size_($).store(s - 1, rl::memory_order_relaxed); n->prev_($)->next_($) = n->next_($); n->next_($)->prev_($) = n->prev_($); } size_t size() const { return size_($).load(rl::memory_order_relaxed); } node* begin() { return head_.next_($); } void flush_to(dlist& target) { if (size_($).load(rl::memory_order_relaxed)) { target.size_($).store(size_($).load(rl::memory_order_relaxed)); target.head_.next_($) = head_.next_($); target.head_.next_($)->prev_($) = &target.head_; target.tail_.prev_($) = tail_.prev_($); target.tail_.prev_($)->next_($) = &target.tail_; } else { target.reset(); } reset(); } static bool not_last(node* n) { return n->next_($) != 0; } static node* get_next(node* n) { return n->next_($); } private: rl::atomic size_; node head_; node tail_; void reset() { size_($) = 0; head_.next_($) = &tail_; head_.prev_($) = 0; tail_.next_($) = 0; tail_.prev_($) = &head_; } dlist(dlist const&); dlist& operator = (dlist const&); }; /** pre-thread descriptor for eventcount */ struct ec_thread { dlist::node node_; semaphore sema_; rl::var epoch_; rl::atomic in_waitset_; rl::var spurious_; rl::var ctx_; ec_thread() { epoch_($) = 0; in_waitset_($) = false; spurious_($) = false; ctx_($) = 0; } ~ec_thread() { if (spurious_($)) sema_.wait(); } /* static ec_thread* current() { static THREAD_LOCAL ec_thread* ec_thread_instance = 0; ec_thread* instance = ec_thread_instance; if (instance == 0) { instance = new ec_thread; ec_thread_instance = instance; } return instance; // instance must be destroyed in DllMain() callback // or in pthread_key_create() callback } */ private: ec_thread(ec_thread const&); ec_thread& operator = (ec_thread const&); }; /** fine-grained eventcount implementation */ class eventcount { public: eventcount() { epoch_($) = 0; } void prepare_wait(ec_thread* th = 0, void* ctx = 0) { RL_ASSERT(th); // this is good place to pump previous spurious wakeup if (th->spurious_($)) { th->spurious_($) = false; th->sema_.wait(); } th->in_waitset_($).store(true, rl::memory_order_relaxed); th->ctx_($) = ctx; { lock l (mtx_); th->epoch_($) = epoch_($).load(rl::memory_order_relaxed); waitset_.push(&th->node_); } rl::atomic_thread_fence($)(rl::memory_order_seq_cst); } void commit_wait(ec_thread* th = 0) { RL_ASSERT(th); // this check is just an optimization //if (th->epoch_($) == epoch_($).load(rl::memory_order_relaxed)) if (th->in_waitset_($).load(rl::memory_order_acquire)) th->sema_.wait(); else cancel_wait(true, th); //!!! add 'th' } void cancel_wait(bool /*from_commit*/, ec_thread* th = 0) { RL_ASSERT(th); // spurious wakeup will be pumped in the following prepare_wait() th->spurious_($) = true; // try to remove node from waitset if (th->in_waitset_($).load(rl::memory_order_acquire)) { lock l (mtx_); if (th->in_waitset_($).load(rl::memory_order_relaxed)) { // successfully removed from waitset, // so there will be no spurious wakeup th->in_waitset_($).store(false, rl::memory_order_relaxed); th->spurious_($) = false; waitset_.remove(&th->node_); } else { //if (from_commit) //int volatile x = 0; } } else { //RL_ASSERT(from_commit == false); //if (from_commit) // int volatile x = 0; } } void notify_one() { rl::atomic_thread_fence($)(rl::memory_order_seq_cst); notify_one_relaxed(); } template void notify(predicate_t pred) { rl::atomic_thread_fence($)(rl::memory_order_seq_cst); notify_relaxed(pred); } void notify_all() { rl::atomic_thread_fence($)(rl::memory_order_seq_cst); notify_all_relaxed(); } void notify_one_relaxed() { if (waitset_.size() == 0) return; dlist::node* n; { lock l (mtx_); unsigned ep = epoch_($).load(rl::memory_order_relaxed); epoch_($).store(ep + 1, rl::memory_order_relaxed); n = waitset_.pop(); if (n) to_ec_thread(n)->in_waitset_($).store(false, rl::memory_order_release); } if (n) { to_ec_thread(n)->sema_.post(); } } template void notify_relaxed(predicate_t pred) { if (waitset_.size() == 0) return; dlist temp; { lock l (mtx_); unsigned ep = epoch_($).load(rl::memory_order_relaxed); epoch_($).store(ep + 1, rl::memory_order_relaxed); size_t size = waitset_.size(); size_t idx = 0; dlist::node* n = waitset_.begin(); while (dlist::not_last(n)) { dlist::node* next = dlist::get_next(n); ec_thread* th = to_ec_thread(n); if (pred(th->ctx_($), size, idx)) { waitset_.remove(n); temp.push(n); th->in_waitset_($).store(false, rl::memory_order_release); } n = next; idx += 1; } } dlist::node* n = temp.begin(); while (dlist::not_last(n)) { dlist::node* next = dlist::get_next(n); to_ec_thread(n)->sema_.post(); n = next; } } void notify_all_relaxed() { if (waitset_.size() == 0) return; dlist temp; { lock l (mtx_); waitset_.flush_to(temp); dlist::node* n = temp.begin(); while (dlist::not_last(n)) { to_ec_thread(n)->in_waitset_($).store(false, rl::memory_order_release); n = dlist::get_next(n); } unsigned ep = epoch_($).load(rl::memory_order_relaxed); epoch_($).store(ep + 1, rl::memory_order_relaxed); } dlist::node* n = temp.begin(); while (dlist::not_last(n)) { dlist::node* next = dlist::get_next(n); to_ec_thread(n)->sema_.post(); n = next; } } class wait_guard; private: mutex mtx_; dlist waitset_; rl::atomicepoch_; ec_thread* to_ec_thread(dlist::node* n) { return (ec_thread*)((char*)n - offsetof(ec_thread, node_)); } eventcount(eventcount const&); eventcount& operator = (eventcount const&); }; class eventcount::wait_guard { public: wait_guard(eventcount& ec, ec_thread* th = 0, void* ctx = 0) : ec_(ec) , th_(th) , wait_(false) { ec_.prepare_wait(th_, ctx); } void commit_wait() { assert(false == wait_); wait_ = true; ec_.commit_wait(th_); } ~wait_guard() { if (false == wait_) ec_.cancel_wait(false, th_); } private: eventcount& ec_; ec_thread* th_; bool wait_; wait_guard(wait_guard const&); wait_guard& operator = (wait_guard const&); }; struct scheduler { struct tbb_thread { ec_thread th; }; eventcount ec_; tbb_thread* threads_; bool volatile is_permanently_open_; void wait_while_pool_is_empty(tbb_thread* th) { if (is_permanently_open_) return; eventcount::wait_guard wait (ec_, &th->th); if (pool_is_empty()) wait.commit_wait(); } void notify_about_new_task_available() { ec_.notify_one_relaxed(); } void notify_about_new_task_available_with_preference(tbb_thread* preference) { struct local { tbb_thread* preference_; bool fired_; bool operator () (void* ctx, size_t count, size_t idx) { tbb_thread* th = (tbb_thread*)ctx; if (th == preference_) { fired_ = true; return true; } else if (idx == count - 1 && fired_ == false) { return true; } else { return false; } } } pred = {preference}; ec_.notify_relaxed(pred); } void notify_about_list_of_tasks_available(size_t total_count, size_t preference_count, tbb_thread** preferences) { struct local { size_t remain_to_signal_; size_t preference_count_; tbb_thread** preferences_; bool operator () (void* ctx, size_t count, size_t idx) { tbb_thread* th = (tbb_thread*)ctx; size_t remain_in_waitset = count - idx; if (remain_in_waitset <= remain_to_signal_) { return true; } else { for (size_t i = 0; i != preference_count_; ++i) { if (preferences_[i] == th) { remain_to_signal_ -= 1; return true; } } } return false; } } pred = {total_count, preference_count, preferences}; ec_.notify_relaxed(pred); } bool pool_is_empty() { return true; } }; struct queue { rl::atomic producer_idx_; rl::atomic consumer_idx_; rl::atomic* buffer_; eventcount ec_; queue() { producer_idx_($) = 0; consumer_idx_($) = 0; buffer_ = RL_NEW_ARR(rl::atomic, 10); for (size_t i = 0; i != 10; ++i) buffer_[i]($) = 0; } ~queue() { RL_DELETE_ARR(buffer_); } void enqueue(void* data) { int idx = producer_idx_($).fetch_add(1) + 1; // atomic buffer_[idx]($).store(data, rl::memory_order_relaxed); struct local { int idx_; bool operator () (void* ctx, size_t /*count*/, size_t /*idx*/) { return idx_ == (*(rl::var*)ctx)($); } } pred = {idx}; ec_.notify(pred); // not relaxed!!! } void* dequeue(ec_thread* th) { int idx = consumer_idx_($).fetch_add(1) + 1; // atomic void* data = buffer_[idx]($).load(rl::memory_order_relaxed); if (data) return data; for (;;) { rl::var idxv (idx); eventcount::wait_guard wait (ec_, th, &idxv); data = buffer_[idx]($).load(rl::memory_order_relaxed); if (data) { return data; } wait.commit_wait(); idxv($) = 0; data = buffer_[idx]($).load(rl::memory_order_relaxed); if (data) { return data; } rl::yield($, 1); //RL_ASSERT(false); } } }; class condition_variable { eventcount ec_; public: void wait(mutex& mtx, ec_thread* th) { eventcount::wait_guard wait (ec_, th); mtx.unlock(); wait.commit_wait(); mtx.lock(); } void signal() { ec_.notify_one(); } void broadcast() { ec_.notify_all(); } }; struct queue_test : rl::test_suite { ec_thread threads_ [6]; queue q_; void thread(unsigned index) { if (index < 2) { q_.enqueue((void*)(index*2+1)); q_.enqueue((void*)(index*2+2)); } else { int data1 = (int)q_.dequeue(&threads_[index]); RL_ASSERT(data1 >= 1 && data1 <= 6); int data2 = (int)q_.dequeue(&threads_[index]); RL_ASSERT(data2 >= 1 && data2 <= 6); } } }; struct condvar_test : rl::test_suite { rl::var stage; condition_variable cv; mutex mtx; ec_thread th [3]; void before() { stage($) = 0; } void thread(unsigned index) { if (0 == index) { mtx.lock(); stage($) += 1; cv.broadcast(); while (stage($) != 2) cv.wait(mtx, &th[index]); mtx.unlock(); } else if (1 == index) { mtx.lock(); while (stage($) != 1) cv.wait(mtx, &th[index]); stage($) += 1; cv.broadcast(); mtx.unlock(); } else if (2 == index) { mtx.lock(); while (stage($) != 2) cv.wait(mtx, &th[index]); mtx.unlock(); } } }; int main() { rl::test_params p; p.iteration_count = 100000000; //p.initial_state = "30000000"; //p.search_type = rl::fair_context_bound_scheduler_type; rl::simulate(p); //rl::simulate(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/tbb_eventcount/msvc8/eventcount.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eventcount", "eventcount.vcproj", "{ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Debug|Win32.ActiveCfg = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Debug|Win32.Build.0 = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Release|Win32.ActiveCfg = Release|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/tbb_eventcount/msvc8/eventcount.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/tbb_eventcount/msvc9/eventcount.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eventcount", "eventcount.vcproj", "{ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Debug|Win32.ActiveCfg = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Debug|Win32.Build.0 = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Release|Win32.ActiveCfg = Release|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/tbb_eventcount/msvc9/eventcount.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/tbb_eventcount/stdafx.cpp ================================================ // stdafx.cpp : source file that includes just the standard includes // ws_deque.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/tbb_eventcount/stdafx.h ================================================ #pragma once #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque/msvc8/ws_deque.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ws_deque", "ws_deque.vcproj", "{0B597F19-DEBB-4832-B520-9A93A286D595}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.ActiveCfg = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.Build.0 = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.ActiveCfg = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque/msvc8/ws_deque.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque/msvc9/ws_deque.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ws_deque", "ws_deque.vcproj", "{0B597F19-DEBB-4832-B520-9A93A286D595}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.ActiveCfg = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.Build.0 = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.ActiveCfg = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque/msvc9/ws_deque.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque/stdafx.h ================================================ #pragma once #ifdef NDEBUG # define _SECURE_SCL 0 #endif #define RL_MSVC_OUTPUT //#define RL_DEBUGBREAK_ON_FAILURE #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque/ws_deque.cpp ================================================ #include "stdafx.h" #include "../../relacy/relacy_std.hpp" using namespace std; using rl::var; template class ws_deque { public: ws_deque() { VAR(m_mask) = initial_size - 1; m_headIndex.store(0, memory_order_relaxed); m_tailIndex.store(0, memory_order_relaxed); VAR(m_array) = new atomic [initial_size]; VAR(m_arraySize) = initial_size; } ~ws_deque() { delete [] VAR(m_array); } bool IsEmpty() const { return m_headIndex.load(memory_order_acquire) >= m_tailIndex.load(memory_order_acquire); } size_t Count() const { return m_tailIndex.load(memory_order_acquire) - m_headIndex.load(memory_order_acquire); } void push(T item) { size_t tail = m_tailIndex.load(memory_order_acquire); if (tail < m_headIndex.load(memory_order_acquire) + VAR(m_mask)) { VAR(m_array)[tail & VAR(m_mask)].store(item, memory_order_relaxed); m_tailIndex.store(tail + 1, memory_order_release); } else { m_foreignLock.lock($); size_t head = m_headIndex.load(memory_order_acquire); size_t count = Count(); if (count >= VAR(m_mask)) { size_t arraySize = m_arraySize($); size_t mask = VAR(m_mask); atomic* newArray = new atomic [arraySize * 2]; atomic* arr = m_array($); //!!! for (size_t i = 0; i != arraySize; ++i) for (size_t i = 0; i != count; ++i) newArray[i].store(arr[(i + head) & mask].load(memory_order_seq_cst), memory_order_relaxed); delete [] VAR(m_array); VAR(m_array) = newArray; VAR(m_arraySize) = arraySize * 2; m_headIndex.store(0, memory_order_release); m_tailIndex.store(count, memory_order_release); tail = count; VAR(m_mask) = (mask * 2) | 1; } VAR(m_array)[tail & VAR(m_mask)].store(item, memory_order_relaxed); m_tailIndex.store(tail + 1, memory_order_release); m_foreignLock.unlock($); } } bool pop(T& item) { size_t tail = m_tailIndex.load(memory_order_acquire); if (tail == 0) return false; tail -= 1; m_tailIndex.store(tail, memory_order_release); atomic_thread_fence(memory_order_seq_cst); if (m_headIndex.load(memory_order_acquire) <= tail) { item = VAR(m_array)[tail & VAR(m_mask)].load(memory_order_relaxed); return true; } else { m_foreignLock.lock($); if (m_headIndex.load(memory_order_acquire) <= tail) { item = VAR(m_array)[tail & VAR(m_mask)].load(memory_order_relaxed); m_foreignLock.unlock($); return true; } else { m_tailIndex.store(tail + 1, memory_order_release); m_foreignLock.unlock($); return false; } } } bool steal(T& item) { if (false == m_foreignLock.try_lock($)) return false; size_t head = m_headIndex.load(memory_order_acquire); m_headIndex.store(head + 1, memory_order_release); atomic_thread_fence(memory_order_seq_cst); if (head < m_tailIndex.load(memory_order_acquire)) { item = VAR(m_array)[head & VAR(m_mask)].load(memory_order_relaxed); m_foreignLock.unlock($); return true; } else { m_headIndex.store(head, memory_order_release); m_foreignLock.unlock($); return false; } } private: static size_t const initial_size = 2; var*> m_array; var m_mask; var m_arraySize; atomic m_headIndex; atomic m_tailIndex; mutex m_foreignLock; }; struct ws_deque_test0 : rl::test_suite { ws_deque q; void before() { } void after() { } void thread(unsigned index) { if (0 == index) { for (size_t i = 0; i != 4; ++i) { q.push(10); } for (size_t i = 0; i != 5; ++i) { int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 4; ++i) { q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 4; ++i) { q.push(10); q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); p = 0; res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 4; ++i) { q.push(10); q.push(10); q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 14; ++i) { q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } } else { for (size_t i = 0; i != 4; ++i) { int p = 0; bool res = q.steal(p); RL_ASSERT(10 == p || false == res); } } } }; struct ws_deque_test : rl::test_suite { ws_deque q; bool state [2]; void before() { state[0] = true; state[1] = true; } void after() { RL_ASSERT(state[0] == false); RL_ASSERT(state[1] == false); } void thread(unsigned index) { if (0 == index) { q.push(1); q.push(2); int item = 0; bool res = q.pop(item); RL_ASSERT(res && item == 2); RL_ASSERT(state[1]); state[1] = false; item = 0; res = q.pop(item); if (res) { RL_ASSERT(state[0]); state[0] = false; } item = 0; res = q.pop(item); RL_ASSERT(res == false); } else { int item = 0; bool res = q.steal(item); if (res) { RL_ASSERT(item == 1); RL_ASSERT(state[0]); state[0] = false; } } } }; int main() { rl::simulate(); rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque2/msvc8/ws_deque.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ws_deque", "ws_deque.vcproj", "{ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Debug|Win32.ActiveCfg = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Debug|Win32.Build.0 = Debug|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Release|Win32.ActiveCfg = Release|Win32 {ECB64178-A35E-4EB2-9EB0-BD72D6F7B6E4}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque2/msvc8/ws_deque.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque2/stdafx.cpp ================================================ // stdafx.cpp : source file that includes just the standard includes // ws_deque.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque2/stdafx.h ================================================ #pragma once #include "../../relacy/pch.hpp" #include "../../relacy/relacy_std.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/example/ws_deque2/ws_deque.cpp ================================================ #include "stdafx.h" struct pdr { __declspec(thread) static pdr* instance; static size_t const defer_limit = 1024; typedef void(*dtor_f)(void*); struct entry_t { dtor_f dtor; void* ctx; }; entry_t defer_list [defer_limit]; size_t pos; size_t pos0; size_t thread_count; size_t th [4]; void init(size_t count) { //assert(0 == instance); instance = this; thread_count = count; pos = 0; pos0 = 0; for (size_t i = 0; i != thread_count; ++i) { th[i] = defer_limit; } } void fini() { for (size_t i = 0; i != thread_count; ++i) { assert(th[i] == defer_limit); } for (size_t i = pos0; i != pos; ++i) { assert(defer_list[i].dtor); defer_list[i].dtor(defer_list[i].ctx); } assert(this == instance); instance = 0; } void lock() { std::atomic_thread_fence($)(std::memory_order_seq_cst); assert(th[rl::ctx().threadx_->index_] == defer_limit); th[rl::ctx().threadx_->index_] = pos; } void unlock() { assert(th[rl::ctx().threadx_->index_] != defer_limit); th[rl::ctx().threadx_->index_] = defer_limit; pump(); } template static void dtor_impl(void* p) { RL_DELETE(static_cast(p)); } template void defer(T* p) { std::atomic_thread_fence($)(std::memory_order_seq_cst); assert(pos < defer_limit); entry_t& e = defer_list[pos++]; e.dtor = &pdr::dtor_impl; e.ctx = p; pump(); } void pump() { if (pos0 == pos) return; size_t min_pos = pos; for (size_t i = 0; i != thread_count; ++i) { if (th[i] < min_pos) min_pos = th[i]; } for (size_t i = pos0; i != min_pos; ++i) { assert(defer_list[i].dtor); defer_list[i].dtor(defer_list[i].ctx); } pos0 = min_pos; } }; pdr* pdr::instance = 0; void pdr_lock() { assert(pdr::instance); pdr::instance->lock(); } void pdr_unlock() { assert(pdr::instance); pdr::instance->unlock(); } template void pdr_defer(T* p) { assert(pdr::instance); pdr::instance->defer(p); } class ws_deque { public: ws_deque() { bottom_.block_($) = 0; bottom_.real_block_id_ = 0; bottom_.real_index_ = 0; bottom_.block_id_ = 0; bottom_.index_ = 0; bottom_.block_seq_ = 0; bottom_.check_order_ = 1; top::info t = {}; top_.block_($) = 0; top_.info_($) = t; alloc_block(); bottom_.block_id_ = bottom_.block_($)->header_.id_; top_.block_($) = bottom_.block_($); t.top_block_id_ = static_cast(top_.block_($).load()->header_.id_); t.bottom_block_id_ = static_cast(top_.block_($).load()->header_.id_); top_.info_($) = t; } ~ws_deque() { for (block* p = top_.block_($), *next; p; p = next) { next = p->header_.next_($).load(std::memory_order_relaxed); RL_DELETE(p); } } void push(void* const& i) { pdr_lock(); push_unbalanced(i); rebalance(); pdr_unlock(); } void push_unbalanced(void* i) { RL_ASSERT(bottom_.block_($)->header_.id_); bottom_.block_($)->data_[bottom_.real_index_]($).store(i, std::memory_order_release); if (block::item_count - 1 != bottom_.real_index_) { bottom_.real_index_ += 1; } else { alloc_block(); } } void rebalance() { if (0 == --bottom_.check_order_) { check_bottom(); } } void* pop() { pdr_lock(); rebalance(); void* p = pop_unbalanced(); pdr_unlock(); return p; } void* pop_unbalanced() { //!!! optimize //! fast-path for empty deque //! make comparasion faster if ((bottom_.block_id_ != bottom_.real_block_id_ || bottom_.index_ != bottom_.real_index_) && bottom_.real_index_) { bottom_.real_index_ -= 1; void* i = bottom_.block_($)->data_[bottom_.real_index_]($).load(std::memory_order_consume); return i; } else { return pop_unbalanced_slow(); } } void* pop_unbalanced_slow() { if (0 == bottom_.real_index_) { if (bottom_.real_block_id_ > bottom_.block_id_) { return pop_slow(); } else { return 0; } } else { void* i; pop_check_result const rv = pop_check(i); if (pop_check_cont != rv) return pop_check_succ == rv ? i : 0; return pop_unbalanced(); // recursion, must succeed } } void* steal() { pdr_lock(); retry: for (;;) { block* old_b = top_.block_($).load(std::memory_order_acquire); block* b = old_b; top::info old = top_.info_($).load(std::memory_order_consume); if (old.top_index_ == old.bottom_index_ && old.top_block_id_ == old.bottom_block_id_) { pdr_unlock(); return 0; } if (b->header_.id_ != old.top_block_id_) { do { b = b->header_.next_($).load(std::memory_order_relaxed); //RL_ASSERT(b); //!!! temp stub - is it right? // it seems that we always return 0 after we hit this goto if (0 == b) goto retry; } //!!! AV // b == 0 while (b->header_.id_ != old.top_block_id_); if (top_.block_($).compare_swap(old_b, b, std::memory_order_seq_cst)) { block* cur_b = old_b; do { pdr_defer(cur_b); cur_b = cur_b->header_.next_($).load(std::memory_order_relaxed); } while (cur_b != b); } } block* next_block = 0; top::info mod = old; void* i = b->data_[mod.top_index_]($).load(std::memory_order_consume); if (block::item_count - 1 == mod.top_index_) { next_block = b->header_.next_($).load(std::memory_order_relaxed); mod.top_block_id_ += 1; mod.top_index_ = 0; } else { mod.top_index_ += 1; } if (top_.info_($).compare_swap(old, mod, std::memory_order_seq_cst)) { if (next_block) { if (top_.block_($).compare_swap(b, next_block)) { pdr_defer(b); } } pdr_unlock(); return i; } } } unsigned size() const { top::info const top = top_.info_($).load(std::memory_order_relaxed); //unsigned volatile const top_block_id = top_.info_.part_.top_block_id_; //unsigned volatile const top_index = top_.info_.part_.top_index_; if (bottom_.real_block_id_ == top.top_block_id_) { unsigned const size = bottom_.real_index_ - top.top_index_; return size; } else { unsigned size = bottom_.real_index_; size += block::item_count - top.top_index_; size += (bottom_.real_block_id_ - top.top_block_id_ - 1) * block::item_count; return size; } } private: struct block { struct header { std::atomic next_; std::atomic prev_; ws_deque* deque_; unsigned id_; //!!! ~header() { id_ = 0; } }; static unsigned const item_count = 2; header header_; std::atomic data_ [item_count]; }; struct bottom { rl::var block_; unsigned check_order_; unsigned real_block_id_; unsigned real_index_; unsigned block_id_; unsigned index_; unsigned block_seq_; }; struct top { struct info { unsigned short top_index_; unsigned short top_block_id_; unsigned short bottom_index_; unsigned short bottom_block_id_; bool operator == (info const& x) const { return top_index_ == x.top_index_ && top_block_id_ == x.top_block_id_ && bottom_index_ == x.bottom_index_ && bottom_block_id_ == x.bottom_block_id_; } friend std::ostream& operator << (std::ostream& ss, info const& x) { return ss << "{" << x.top_index_ << "," << x.top_block_id_ << "," << x.bottom_index_ << "," << x.bottom_block_id_ << "}"; } }; std::atomic block_; std::atomic info_; }; bottom bottom_; char pad1 [64]; top top_; char pad2 [64]; void alloc_block() { //!!! check whether we already have next block in // bottom_.block_->header_.next_ block* b = bottom_.block_($) ? bottom_.block_($)->header_.next_($).load(std::memory_order_relaxed) : 0; if (0 == b) { b = RL_NEW block; b->header_.deque_ = this; bottom_.block_seq_ += 1; //!!! if (bottom_.block_seq_ > 0xffff) __asm int 3; bottom_.block_seq_ &= 0xffff; b->header_.id_ = bottom_.block_seq_; b->header_.prev_($).store(bottom_.block_($), std::memory_order_relaxed); if (bottom_.block_($)) bottom_.block_($)->header_.next_($).store(b, std::memory_order_relaxed); b->header_.next_($).store(0, std::memory_order_relaxed); } else { b = b; bottom_.block_seq_ += 1; //__asm int 3; } bottom_.block_($) = b; bottom_.real_block_id_ = b->header_.id_; bottom_.real_index_ = 0; } enum pop_check_result {pop_check_fail, pop_check_succ, pop_check_cont}; pop_check_result pop_check(void*& i) { check_bottom(); if (bottom_.block_id_ == bottom_.real_block_id_ && bottom_.index_ == bottom_.real_index_) { top::info const top = top_.info_($).load(std::memory_order_seq_cst); if ((bottom_.block_id_ == top.top_block_id_ && bottom_.index_ == (unsigned)top.top_index_ + 1) || (bottom_.block_id_ == (unsigned)top.top_block_id_ + 1 && block::item_count - 1 == top.top_index_ && 0 == bottom_.index_ )) { __asm int 3; i = steal(); if (i) return pop_check_succ; } return pop_check_fail; } return pop_check_cont; } void* pop_slow() { bottom_.block_seq_ -= 1; bottom_.block_seq_ &= 0xffff; bottom_.block_($) = bottom_.block_($)->header_.prev_($).load(std::memory_order_relaxed); //!!! AV: when core count set to 16 // bottom_.block_ = 0 // bottom.real_block_id = 1 // bottom.block_id = 8 //!!! AV in xscale too (thread count is 4) // the same variables values bottom_.real_block_id_ = bottom_.block_($)->header_.id_; bottom_.real_index_ = block::item_count - 1; top::info i = top_.info_($).load(std::memory_order_relaxed); RL_ASSERT(bottom_.block_($)->header_.id_ == bottom_.block_seq_); RL_ASSERT((bottom_.real_block_id_ == i.bottom_block_id_ && bottom_.real_index_ >= i.bottom_index_) || (bottom_.real_block_id_ > i.bottom_block_id_)); void* v = bottom_.block_($)->data_[block::item_count - 1]($).load(std::memory_order_consume); return v; } void check_bottom() { //!!! must leave at least 1 element unreserved // because owner have to steal it for (;;) { top::info old = top_.info_($).load(std::memory_order_relaxed); unsigned const top_block_id = old.top_block_id_; unsigned const top_index = old.top_index_; if (bottom_.real_block_id_ == top_block_id && bottom_.real_index_ == top_index) { bottom_.check_order_ = 2; return; } unsigned const s = size(); unsigned const r = reserved(); if (!(0 == r || (r > 1 && 4*r > 3*s))) { //bottom_.check_order_ = 2; //!!! bottom_.check_order_ = s / 8 + 2; bottom_.check_order_ = s / 2 + 2; return; } unsigned r2 = s*3/4 + 1; if (r2 >= s) r2 = s - 1; unsigned bottom_block_id; unsigned bottom_index; if (r2 + top_index < block::item_count) { bottom_block_id = top_block_id; bottom_index = top_index + r2; } else { unsigned const r3 = r2 + top_index; bottom_block_id = top_block_id + r3 / block::item_count; bottom_index = r3 % block::item_count; } top::info i; i.top_block_id_ = static_cast(top_block_id); i.top_index_ = static_cast(top_index); i.bottom_block_id_ = static_cast(bottom_block_id); i.bottom_index_ = static_cast(bottom_index); /* bottom volatile btm = bottom_; if (i.part_.top_block_id_ > i.part_.bottom_block_id_) __asm int 3; if (i.part_.top_block_id_ == i.part_.bottom_block_id_ && i.part_.top_index_ >= i.part_.bottom_index_) __asm int 3; if (i.part_.bottom_block_id_ > btm.real_block_id_) __asm int 3; if (i.part_.bottom_block_id_ == btm.real_block_id_ && i.part_.bottom_index_ > btm.real_index_) __asm int 3; */ if (top_.info_($).compare_swap(old, i, std::memory_order_seq_cst)) { bottom_.block_id_ = bottom_block_id; bottom_.index_ = bottom_index; //!!! bottom_.check_order_ = s / 8 + 2; bottom_.check_order_ = s / 2 + 2; return; } } } unsigned reserved() const { if (bottom_.real_block_id_ == bottom_.block_id_) { unsigned const reserved = bottom_.real_index_ - bottom_.index_; return reserved; } else { unsigned reserved = bottom_.real_index_; reserved += block::item_count - bottom_.index_; reserved += (bottom_.real_block_id_ - bottom_.block_id_ - 1) * block::item_count; return reserved; } } }; int x = 0; struct ws_deque_test : rl::test_suite { ws_deque q; pdr p; void before() { p.init(4); } void after() { p.fini(); } void thread(unsigned index) { if (0 == index) { for (size_t i = 0; i != 4; ++i) { q.push((void*)10); } for (size_t i = 0; i != 5; ++i) { void* p = q.pop(); RL_ASSERT((void*)10 == p || 0 == p); } for (size_t i = 0; i != 4; ++i) { q.push((void*)10); void* p = q.pop(); RL_ASSERT((void*)10 == p || 0 == p); } for (size_t i = 0; i != 4; ++i) { q.push((void*)10); q.push((void*)10); void* p = q.pop(); RL_ASSERT((void*)10 == p || 0 == p); p = q.pop(); RL_ASSERT((void*)10 == p || 0 == p); } for (size_t i = 0; i != 4; ++i) { q.push((void*)10); q.push((void*)10); q.push((void*)10); void* p = q.pop(); RL_ASSERT((void*)10 == p || 0 == p); } for (size_t i = 0; i != 14; ++i) { q.push((void*)10); void* p = q.pop(); RL_ASSERT((void*)10 == p || 0 == p); } } else { for (size_t i = 0; i != 4; ++i) { void* p = q.steal(); RL_ASSERT((void*)10 == p || 0 == p); } } } }; int main() { rl::test_params p; p.iteration_count = 1000000; rl::simulate(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/atomic.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_ATOMIC_HPP #define RL_ATOMIC_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context.hpp" #include "memory_order.hpp" #include "signature.hpp" #include "atomic_events.hpp" #include "waitset.hpp" #include "rmw.hpp" namespace rl { template class atomic; template struct bool_t {}; template class atomic_proxy_const { public: atomic_proxy_const(atomic const /*volatile*/& var, debug_info_param info) : var_(const_cast&>(var)) , info_(info) { } T load(memory_order mo = mo_seq_cst) const { return var_.load(mo, info_); } operator T () const { return load(); } protected: atomic& var_; debug_info info_; atomic_proxy_const& operator = (atomic_proxy_const const&); }; template class atomic_proxy : public atomic_proxy_const { public: typedef typename atomic_add_type::type add_type; atomic_proxy(atomic /*volatile*/& var, debug_info_param info) : atomic_proxy_const(var, info) { } void store(T value, memory_order mo = mo_seq_cst) { this->var_.store(value, mo, this->info_); } bool compare_exchange_weak(T& cmp, T xchg, memory_order mo = mo_seq_cst) { return this->var_.compare_exchange(bool_t(), cmp, xchg, mo, this->info_); } bool compare_exchange_weak(T& cmp, T xchg, memory_order mo, memory_order failure_mo) { return this->var_.compare_exchange(bool_t(), cmp, xchg, mo, failure_mo, this->info_); } bool compare_exchange_strong(T& cmp, T xchg, memory_order mo = mo_seq_cst) { return this->var_.compare_exchange(bool_t(), cmp, xchg, mo, this->info_); } bool compare_exchange_strong(T& cmp, T xchg, memory_order mo, memory_order failure_mo) { return this->var_.compare_exchange(bool_t(), cmp, xchg, mo, failure_mo, this->info_); } T exchange(T xchg, memory_order mo = mo_seq_cst) { return this->var_.rmw(rmw_type_t(), xchg, mo, this->info_); } T fetch_add(add_type value, memory_order mo = mo_seq_cst) { return this->var_.rmw(rmw_type_t(), value, mo, this->info_); } T fetch_sub(add_type value, memory_order mo = mo_seq_cst) { return this->var_.rmw(rmw_type_t(), value, mo, this->info_); } T fetch_and(T value, memory_order mo = mo_seq_cst) { return this->var_.rmw(rmw_type_t(), value, mo, this->info_); } T fetch_or(T value, memory_order mo = mo_seq_cst) { return this->var_.rmw(rmw_type_t(), value, mo, this->info_); } T fetch_xor(T value, memory_order mo = mo_seq_cst) { return this->var_.rmw(rmw_type_t(), value, mo, this->info_); } T operator = (T value) { store(value); return value; } T operator ++ (int) { return fetch_add(1); } T operator -- (int) { return fetch_sub(1); } T operator ++ () { return fetch_add(1) + 1; } T operator -- () { return fetch_sub(1) - 1; } T operator += (add_type value) { return fetch_add(value) + value; } T operator -= (add_type value) { return fetch_sub(value) + value; } T operator &= (T value) { return fetch_and(value) & value; } T operator |= (T value) { return fetch_or(value) | value; } T operator ^= (T value) { return fetch_xor(value) ^ value; } }; template class generic_atomic { public: generic_atomic() { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); impl_ = c.atomic_ctor(this); initialized_ = false; value_ = T(); already_failed_ = false; if (val(strong_init)) { unsigned const index = c.threadx_->atomic_init(impl_); last_index_ = index; initialized_ = true; history_[index] = T(); value_ = T(); } } ~generic_atomic() { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); sign_.check($); c.atomic_dtor(impl_); } T debug_value() const { sign_.check($); return value_; } RL_INLINE T load(memory_order mo, debug_info_param info) const { RL_VERIFY(mo_release != mo); RL_VERIFY(mo_acq_rel != mo); switch (mo) { case mo_relaxed: return load_impl(info); case mo_consume: return load_impl(info); case mo_acquire: return load_impl(info); case mo_seq_cst: return load_impl(info); default: break; } RL_VERIFY(false); return T(); } RL_INLINE void store(T v, memory_order mo, debug_info_param info) { RL_VERIFY(mo_acquire != mo); RL_VERIFY(mo_acq_rel != mo); switch (mo) { case mo_relaxed: return store_impl(v, info); case mo_release: return store_impl(v, info); case mo_seq_cst: return store_impl< mo_seq_cst, &thread_info_base::atomic_store_seq_cst>(v, info); default: break; } RL_VERIFY(false); } RL_INLINE bool compare_exchange_weak(T& cmp, T xchg, memory_order mo, debug_info_param info) { return compare_exchange(bool_t(), cmp, xchg, mo, info); } RL_INLINE bool compare_exchange_strong(T& cmp, T xchg, memory_order mo, debug_info_param info) { return compare_exchange(bool_t(), cmp, xchg, mo, info); } RL_INLINE bool compare_exchange_weak(T& cmp, T xchg, memory_order mo, debug_info_param info, memory_order failure_mo, debug_info_param) { return compare_exchange(bool_t(), cmp, xchg, mo, failure_mo, info); } RL_INLINE bool compare_exchange_strong(T& cmp, T xchg, memory_order mo, debug_info_param info, memory_order failure_mo, debug_info_param) { return compare_exchange(bool_t(), cmp, xchg, mo, failure_mo, info); } template RL_INLINE bool compare_exchange(bool_t, T& cmp, T xchg, memory_order mo, debug_info_param info) { switch (mo) { case mo_relaxed: return compare_swap_impl(cmp, xchg, info); case mo_consume: return compare_swap_impl(cmp, xchg, info); case mo_acquire: return compare_swap_impl(cmp, xchg, info); case mo_release: return compare_swap_impl(cmp, xchg, info); case mo_acq_rel: return compare_swap_impl(cmp, xchg, info); case mo_seq_cst: return compare_swap_impl(cmp, xchg, info); } RL_VERIFY(false); return false; } template RL_INLINE bool compare_exchange(bool_t, T& cmp, T xchg, memory_order mo, memory_order failure_mo, debug_info_param info) { switch (mo) { case mo_relaxed: { RL_VERIFY(mo_relaxed == failure_mo); return compare_swap_impl(cmp, xchg, info); } case mo_consume: { RL_VERIFY(mo_relaxed == failure_mo || mo_consume == failure_mo); switch (failure_mo) { case mo_relaxed: return compare_swap_impl(cmp, xchg, info); case mo_consume: return compare_swap_impl(cmp, xchg, info); default: RL_VERIFY(false); return false; } } case mo_acquire: { RL_VERIFY(mo_relaxed == failure_mo || mo_consume == failure_mo || mo_acquire == failure_mo); switch (failure_mo) { case mo_relaxed: return compare_swap_impl(cmp, xchg, info); case mo_consume: return compare_swap_impl(cmp, xchg, info); case mo_acquire: return compare_swap_impl(cmp, xchg, info); default: RL_VERIFY(false); return false; } } case mo_release: { RL_VERIFY(mo_relaxed == failure_mo); return compare_swap_impl(cmp, xchg, info); } case mo_acq_rel: { RL_VERIFY(mo_relaxed == failure_mo || mo_consume == failure_mo || mo_acquire == failure_mo); switch (failure_mo) { case mo_relaxed: return compare_swap_impl(cmp, xchg, info); case mo_consume: return compare_swap_impl(cmp, xchg, info); case mo_acquire: return compare_swap_impl(cmp, xchg, info); default: RL_VERIFY(false); return false; } } case mo_seq_cst: { RL_VERIFY(mo_relaxed == failure_mo || mo_consume == failure_mo || mo_acquire == failure_mo || mo_seq_cst == failure_mo); switch (failure_mo) { case mo_relaxed: return compare_swap_impl(cmp, xchg, info); case mo_consume: return compare_swap_impl(cmp, xchg, info); case mo_acquire: return compare_swap_impl(cmp, xchg, info); case mo_seq_cst: return compare_swap_impl(cmp, xchg, info); default: RL_VERIFY(false); return false; } } } RL_VERIFY(false); return false; } T exchange(T xchg, memory_order mo, debug_info_param info) { return rmw(rmw_type_t(), xchg, mo, info); } T fetch_add(typename atomic_add_type::type value, memory_order mo, debug_info_param info) { return rmw(rmw_type_t(), value, mo, info); } T fetch_sub(typename atomic_add_type::type value, memory_order mo, debug_info_param info) { return rmw(rmw_type_t(), value, mo, info); } T fetch_and(T value, memory_order mo, debug_info_param info) { return rmw(rmw_type_t(), value, mo, info); } T fetch_or(T value, memory_order mo, debug_info_param info) { return rmw(rmw_type_t(), value, mo, info); } T fetch_xor(T value, memory_order mo, debug_info_param info) { return rmw(rmw_type_t(), value, mo, info); } template RL_INLINE T rmw(rmw_type_t, Y op, memory_order mo, debug_info_param info) { switch (mo) { case mo_relaxed: return rmw_impl(rmw_type_t(), op, info); case mo_consume: return rmw_impl(rmw_type_t(), op, info); case mo_acquire: return rmw_impl(rmw_type_t(), op, info); case mo_release: return rmw_impl(rmw_type_t(), op, info); case mo_acq_rel: return rmw_impl(rmw_type_t(), op, info); case mo_seq_cst: return rmw_impl(rmw_type_t(), op, info); } RL_VERIFY(false); return T(); } unpark_reason wait(context& c, bool is_timed, bool allow_spurious_wakeup, debug_info_param info) { sign_.check(info); return c.threadx_->atomic_wait(impl_, is_timed, allow_spurious_wakeup, info); } thread_id_t wake(context& c, thread_id_t count, debug_info_param info) { sign_.check(info); return c.threadx_->atomic_wake(impl_, count, info); } private: T value_; T history_ [atomic_history_size]; atomic_data* impl_; unsigned last_index_; signature<987654321> sign_; bool initialized_; bool already_failed_; template T load_impl(debug_info_param info) const { context& c = ctx(); c.sched(); sign_.check(info); if (false == c.invariant_executing) { unsigned const index = (c.threadx_->*impl)(impl_); if ((unsigned)-1 == index) { RL_HIST(atomic_load_event) {this, T(), mo, false} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_unitialized_access, "", info); } T const v = history_[index]; RL_HIST(atomic_load_event) {this, v, mo, last_index_ != index} RL_HIST_END(); return v; } else { if (false == initialized_) { RL_HIST(atomic_load_event) {this, T(), mo, false} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_unitialized_access, "", info); } return value_; } } template void store_impl(T v, debug_info_param info) { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); c.sched(); sign_.check(info); unsigned const index = (c.threadx_->*impl)(impl_); T const prev = value_; last_index_ = index; history_[index] = v; value_ = v; initialized_ = true; RL_HIST(atomic_store_event) {this, prev, v, mo} RL_HIST_END(); } template bool compare_swap_impl(T& cmp, T xchg, debug_info_param info) { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); c.sched(); sign_.check(info); if (false == initialized_) { RL_HIST(atomic_load_event) {this, T(), mo, false} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_unitialized_access, "", info); } bool success = false; bool spurious_failure = false; bool aba = false; T const cmpv = cmp; T const current = value_; if (current == cmpv) { if (val(spurious_failures)) { if (c.is_random_sched()) { spurious_failure = (0 == c.rand(4, sched_type_cas_fail)); } else { if (false == already_failed_) { spurious_failure = 0 == c.rand(2, sched_type_cas_fail); if (spurious_failure) already_failed_ = true; } } } if (false == spurious_failure) { success = true; unsigned const index = (c.threadx_->*impl)(impl_, aba); value_ = xchg; last_index_ = index; history_[index] = xchg; } } if (false == success) { (c.threadx_->*failure_impl)(impl_); cmp = current; } RL_HIST(atomic_cas_event) {RL_INFO, this, current, cmpv, xchg, mo, success, spurious_failure, aba} RL_HIST_END(); return success; } template T rmw_impl(rmw_type_t, Y op, debug_info_param info) { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); c.sched(); sign_.check(info); if (false == initialized_) { RL_HIST(atomic_load_event) {this, T(), mo, false} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_unitialized_access, "", info); } bool aba; unsigned const index = (c.threadx_->*impl)(impl_, aba); T const prev_value = value_; T const new_value = perform_rmw(rmw_type_t(), prev_value, op); value_ = new_value; last_index_ = index; history_[index] = new_value; typedef atomic_rmw_event atomic_rmw_event_t; RL_HIST(atomic_rmw_event_t) {RL_INFO, this, prev_value, op, new_value, mo, type} RL_HIST_END(); return prev_value; } RL_NOCOPY(generic_atomic); }; template class atomic : public generic_atomic { public: atomic() { } /*explicit*/ atomic(T value) { this->store(value, mo_relaxed, $); } atomic_proxy_const operator () (debug_info_param info) const /*volatile*/ { return atomic_proxy_const(*this, info); } atomic_proxy operator () (debug_info_param info) /*volatile*/ { return atomic_proxy(*this, info); } bool is_lock_free() const /*volatile*/ { return true; } friend class atomic_proxy; friend class atomic_proxy_const; RL_NOCOPY(atomic); }; typedef atomic atomic_bool; typedef atomic atomic_address; typedef atomic atomic_char; typedef atomic atomic_schar; typedef atomic atomic_uchar; typedef atomic atomic_short; typedef atomic atomic_ushort; typedef atomic atomic_int; typedef atomic atomic_uint; typedef atomic atomic_long; typedef atomic atomic_ulong; typedef atomic atomic_llong; typedef atomic atomic_ullong; //typedef atomic atomic_char16_t; //typedef atomic atomic_char32_t; typedef atomic atomic_wchar_t; //typedef atomic atomic_int_least8_t; //typedef atomic atomic_uint_least8_t; //typedef atomic atomic_int_least16_t; //typedef atomic atomic_uint_least16_t; //typedef atomic atomic_int_least32_t; //typedef atomic atomic_uint_least32_t; //typedef atomic atomic_int_least64_t; //typedef atomic atomic_uint_least64_t; //typedef atomic atomic_int_fast8_t; //typedef atomic atomic_uint_fast8_t; //typedef atomic atomic_int_fast16_t; //typedef atomic atomic_uint_fast16_t; //typedef atomic atomic_int_fast32_t; //typedef atomic atomic_uint_fast32_t; //typedef atomic atomic_int_fast64_t; //typedef atomic atomic_uint_fast64_t; typedef atomic atomic_intptr_t; typedef atomic atomic_uintptr_t; typedef atomic atomic_size_t; //typedef atomic atomic_ssize_t; typedef atomic atomic_ptrdiff_t; //typedef atomic atomic_intmax_t; //typedef atomic atomic_uintmax_t; template struct atomic_data_impl : atomic_data { typedef thread_info thread_info_t; struct history_record { timestamp_t acq_rel_order_ [thread_count]; timestamp_t last_seen_order_ [thread_count]; bool busy_; bool seq_cst_; thread_id_t thread_id_; timestamp_t acq_rel_timestamp_; }; static size_t const history_size = atomic_history_size; aligned history_ [history_size]; unsigned current_index_; waitset futex_ws_; sync_var futex_sync_; atomic_data_impl() { current_index_ = 0; history_record& rec = history_[0]; history_[atomic_history_size - 1].busy_ = false; rec.busy_ = false; rec.seq_cst_ = false; rec.thread_id_ = (thread_id_t)-1; } atomic_data_impl(thread_info_t& th) { current_index_ = 0; history_[atomic_history_size - 1].busy_ = false; history_record& rec = history_[0]; rec.busy_ = true; rec.seq_cst_ = false; rec.thread_id_ = th.index_; th.own_acq_rel_order_ += 1; rec.acq_rel_timestamp_ = th.own_acq_rel_order_; foreach(rec.acq_rel_order_, assign_zero); foreach(rec.last_seen_order_, assign<(timestamp_t)-1>); rec.last_seen_order_[th.index_] = th.own_acq_rel_order_; } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/atomic_events.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_ATOMIC_EVENTS_HPP #define RL_ATOMIC_EVENTS_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "memory_order.hpp" #include "rmw.hpp" namespace rl { template class atomic; template class generic_atomic; template struct atomic_add_type { typedef T type; typedef T output_type; }; template struct atomic_add_type { typedef ptrdiff_t type; typedef void* output_type; }; template struct atomic_cas_event { typedef typename atomic_add_type::output_type type; debug_info var_info_; void const* var_addr_; type cur_value_; type cmp_value_; type xchg_value_; memory_order mo_; bool success_; bool spurious_failure_; bool aba_; void output(std::ostream& s) const { s << "<" << std::hex << var_addr_ << std::dec << ">" << " CAS " << (success_ ? "succ " : "fail ") << (spurious_failure_ ? "[SPURIOUSLY] " : "") << (aba_ ? "[ABA] " : "") << "orig=" << cur_value_ << ", cmp=" << cmp_value_ << ", xchg=" << xchg_value_ << ", order=" << format(mo_); } }; template struct atomic_load_event { typedef typename atomic_add_type::output_type type; void const* var_addr_; type value_; memory_order mo_; bool not_current_; void output(std::ostream& s) const { s << "<" << std::hex << var_addr_ << std::dec << ">" << " atomic load, value=" << value_ << (not_current_ ? " [NOT CURRENT]" : "") << ", order=" << format(mo_); } }; template struct atomic_store_event { typedef typename atomic_add_type::output_type type; void const* var_addr_; type prev_value_; type value_; memory_order mo_; void output(std::ostream& s) const { s << "<" << std::hex << var_addr_ << std::dec << ">" << " atomic store, value=" << value_ << ", (prev value=" << prev_value_ << ")" << ", order=" << format(mo_); } }; template struct atomic_rmw_event { typedef typename atomic_add_type::output_type type; debug_info var_info_; void const* var_addr_; type prev_value_; Y op_value_; type new_value_; memory_order mo_; rmw_type_e type_; void output(std::ostream& s) const { s << "<" << std::hex << var_addr_ << std::dec << ">" << " " << format(type_) << " " << ", prev=" << prev_value_ << ", arg=" << op_value_ << ", new=" << new_value_ << ", order=" << format(mo_); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/atomic_fence.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_FENCE_HPP #define RL_FENCE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context.hpp" #include "memory_order.hpp" namespace rl { struct atomic_fence_event { memory_order mo_; bool is_thread_fence_; void output(std::ostream& s) const { s << (is_thread_fence_ ? "" : "compiler ") << format(mo_) << " fence"; } }; RL_INLINE void atomic_thread_fence(memory_order mo, debug_info_param info) { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); switch (mo) { case mo_relaxed: RL_VERIFY(false); break; case mo_consume: case mo_acquire: c.atomic_thread_fence_acquire(); break; case mo_release: c.atomic_thread_fence_release(); break; case mo_acq_rel: c.atomic_thread_fence_acq_rel(); break; case mo_seq_cst: c.atomic_thread_fence_seq_cst(); break; } RL_HIST(atomic_fence_event) {mo, true} RL_HIST_END(); } RL_INLINE void atomic_signal_fence(memory_order mo, debug_info_param info) { context& c = ctx(); RL_HIST(atomic_fence_event) {mo, false} RL_HIST_END(); } } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/backoff.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_BACKOFF_HPP #define RL_BACKOFF_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context_base.hpp" namespace rl { inline void yield(unsigned count, debug_info_param info) { ctx().yield(count, info); } template class backoff_t { public: backoff_t() : count_(1) { } void yield(debug_info_param info) { rl::yield(count_, info); count_ = count_ * factor_t + add_t; } private: unsigned count_; }; typedef backoff_t<1, 0> backoff; typedef backoff_t<1, 1> linear_backoff; typedef backoff_t<2, 0> exp_backoff; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/base.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_BASE_HPP #define RL_BASE_HPP #ifdef _MSC_VER # pragma once #endif #include "pch.hpp" #include "platform.hpp" namespace rl { size_t const subsequent_timed_wait_limit = 4; } #define RL_TEST #ifdef RL_JAVA_MODE # define RL_GC # define RL_NO_MALLOC # define RL_JAVA_API # define RL_JAVA_MM #endif #ifdef RL_CLI_MODE # define RL_GC # define RL_NO_MALLOC # define RL_CLI_API # define RL_CLI_MM #endif #ifdef RL_POSIX_MODE # define RL_POSIX_API #endif #ifdef RL_WIN_MODE # define RL_WIN_API #endif #ifdef RL_CPP_MODE # define RL_CPP_API # define RL_CPP_MM #endif #if defined(RL_JAVA_MM) || defined(RL_CLI_MM) # define RL_IMPROVED_SEQ_CST_FENCE # define RL_IMPROVED_SEQ_CST_RMW #endif namespace rl { #define RL_NOCOPY(CLASS) \ private: \ CLASS(CLASS const&); \ CLASS& operator = (CLASS const&); /**/ template class nocopy { nocopy(nocopy const&); nocopy& operator = (nocopy const&); protected: nocopy() {} }; template struct align_pad { template struct helper { struct type { char pad [base - sz]; }; }; template struct helper { struct type {}; }; template struct helper { typedef typename align_pad::type type; }; typedef typename helper::type type; }; template struct aligned : T, align_pad::type {}; template T val(T x) { return x; } } #include "defs.hpp" #define RL_INFO ::rl::debug_info(__FUNCTION__, __FILE__, __LINE__) #define $ RL_INFO #ifdef RL_DO_ASSERT # if RL_DO_ASSERT # define RL_DO_ASSERT_IMPL # endif #else # ifdef _DEBUG # define RL_DO_ASSERT_IMPL # endif #endif #ifdef _MSC_VER # define RL_INT3() __debugbreak(); abort() #else # define RL_INT3() abort() #endif #ifdef RL_DO_ASSERT_IMPL # define RL_VERIFY(x) do { if (!((void)0, (x))) { \ ::rl::assert_failed(#x, $); RL_INT3(); } } while ((void)0, 0) #else # define RL_VERIFY(x) (void)0 #endif #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/cli.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CLI_HPP #define RL_CLI_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context_base.hpp" #include "atomic_fence.hpp" namespace rl { struct Thread { static void MemoryBarrier(debug_info_param info) { atomic_thread_fence(mo_seq_cst, info); } template static T VolatileRead(generic_atomic const& v, debug_info_param info) { return v.load(mo_acquire, info); } template static void VolatileWrite(generic_atomic& v, T x, debug_info_param info) { v.store(x, mo_release, info); } static void SpinWait(int iterations, debug_info_param info) { ctx().yield(iterations, info); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/cli_interlocked.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CLI_INTERLOCKED_HPP #define RL_CLI_INTERLOCKED_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "atomic.hpp" namespace rl { struct Interlocked { template static T Add(generic_atomic& v, T x, debug_info_param info) { T result = v.rmw(rmw_type_t(), x, mo_seq_cst, info) + x; return result; } template static T CompareExchange(generic_atomic& v, T xchg, T cmp, debug_info_param info) { v.compare_exchange(bool_t(), cmp, xchg, mo_seq_cst, mo_seq_cst, info); return cmp; } template static T Increment(generic_atomic& v, debug_info_param info) { return Add(v, (T)1, info); } template static T Decrement(generic_atomic& v, debug_info_param info) { return Add(v, (T)-1, info); } template static T Exchange(generic_atomic& v, T x, debug_info_param info) { T result = v.rmw(rmw_type_t(), x, mo_seq_cst, info); return result; } template static T Read(generic_atomic const& v, debug_info_param info) { return v.load(mo_acquire, info); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/cli_var.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CLI_VAR_HPP #define RL_CLI_VAR_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "atomic.hpp" namespace rl { template class nvar; template class nvar_proxy { public: typedef typename atomic_add_type::type add_type; template friend class nvar; operator T () const { return load(); } T operator = (T value) { store(value); return value; } T operator = (nvar_proxy const& r) { T const value = r.load(); store(value); return *this; } T operator ++ (int) { T tmp = load(); store(tmp + 1); return tmp; } T operator -- (int) { T tmp = load(); store(tmp - 1); return tmp; } T operator ++ () { T tmp = load(); store(tmp + 1); return tmp + 1; } T operator -- () { T tmp = load(); store(tmp - 1); return tmp - 1; } T operator += (add_type value) { T tmp = load(); store(tmp + value); return tmp + value; } T operator -= (add_type value) { T tmp = load(); store(tmp - value); return tmp - value; } private: nvar& var_; debug_info info_; nvar_proxy(nvar& var, debug_info_param info) : var_(var) , info_(info) { } T load() const { return var_.load(mo_relaxed, info_); } void store(T value) { var_.store(value, mo_relaxed, info_); } }; template class nvar : public generic_atomic { public: typedef nvar_proxy proxy_t; friend class nvar_proxy; nvar() { } explicit nvar(T value) { this->store(value, mo_relaxed, $); } nvar(nvar const& r) { T const value = r.load(mo_relaxed, $); this->store(value, mo_relaxed, $); } nvar(proxy_t const& r) { T const value = r.load(); this->store(value, mo_relaxed, r.info_); } proxy_t operator () (debug_info_param info) { return proxy_t(*this, info); } private: nvar& operator = (nvar const&); }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/cli_volatile.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CLI_VOLATILE_HPP #define RL_CLI_VOLATILE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "atomic.hpp" //!!! fix Java volatiles! // they must be modeled as seq_cst stores/loads namespace rl { template class nvolatile; template class nvolatile_proxy { public: typedef typename atomic_add_type::type add_type; template friend class nvolatile; operator T () const { return load(); } T operator = (T value) { store(value); return value; } T operator = (nvolatile_proxy const& r) { T const value = r.load(); store(value); return *this; } T operator ++ (int) { T tmp = load(); store(tmp + 1); return tmp; } T operator -- (int) { T tmp = load(); store(tmp - 1); return tmp; } T operator ++ () { T tmp = load(); store(tmp + 1); return tmp + 1; } T operator -- () { T tmp = load(); store(tmp - 1); return tmp - 1; } T operator += (add_type value) { T tmp = load(); store(tmp + value); return tmp + value; } T operator -= (add_type value) { T tmp = load(); store(tmp - value); return tmp - value; } private: nvolatile& var_; debug_info info_; nvolatile_proxy(nvolatile& var, debug_info_param info) : var_(var) , info_(info) { } T load() const { return var_.load(mo_acquire, info_); } void store(T value) { var_.store(value, mo_release, info_); } }; template class nvolatile : public generic_atomic { public: typedef nvolatile_proxy proxy_t; friend class nvolatile_proxy; nvolatile() { } explicit nvolatile(T value) { //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_release, $); } nvolatile(nvolatile const& r) { T const value = r.load(mo_acquire, $); //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_release, $); } nvolatile(proxy_t const& r) { T const value = r.var_.load(mo_acquire, r.info_); //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_release, r.info_); } proxy_t operator () (debug_info_param info) { return proxy_t(*this, info); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/context.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CONTEXT_HPP #define RL_CONTEXT_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "thread_local_ctx.hpp" #include "context_base.hpp" #include "thread.hpp" #include "history.hpp" #include "memory.hpp" #include "test_result.hpp" #include "slab_allocator.hpp" #include "test_params.hpp" #include "random.hpp" #include "foreach.hpp" #include "random_scheduler.hpp" #include "full_search_scheduler.hpp" #include "context_bound_scheduler.hpp" namespace rl { template class generic_mutex_data_impl; template class condvar_data_impl; template class sema_data_impl; template class event_data_impl; struct park_event { bool is_timed_; bool allow_spurious_; void output(std::ostream& s) const { s << "blocking current thread" << (is_timed_ ? " [timed]" : ""); } }; struct unpark_event { thread_id_t thread_; void output(std::ostream& s) const { s << "unblocking thread " << thread_; } }; struct yield_event { unsigned count_; void output(std::ostream& s) const { s << "yield(" << count_ << ")"; } }; /* template struct context_persistent { static thread_id_t const thread_count = test_t::params::thread_count; fiber_t fibers_ [thread_count]; memory_mgr memory_; context_persistent() { for (thread_id_t i = 0; i != thread_count; ++i) { create_fiber(fibers_[i], &context_impl::fiber_proc, (void*)(intptr_t)i); } } ~context_persistent() { for (thread_id_t i = 0; i != thread_count; ++i) { delete_fiber(fibers_[i]); } } }; */ template class context_impl : thread_local_contxt_impl, test_t::params::thread_count> { private: typedef thread_local_contxt_impl , test_t::params::thread_count> base_t; typedef typename scheduler_t::shared_context_t shared_context_t; using base_t::params_; using base_t::history_; using base_t::threadx_; using base_t::disable_preemption_; using base_t::disable_alloc_; using base_t::invariant_executing; static thread_id_t const main_thread_id = -1; static thread_id_t const static_thread_count = test_t::params::static_thread_count; static thread_id_t const dynamic_thread_count = test_t::params::dynamic_thread_count; static thread_id_t const thread_count = test_t::params::thread_count; iteration_t current_iter_; test_result_e test_result_; string test_result_str_; fiber_t main_fiber_; bool special_function_executing; memory_mgr memory_; iteration_t start_iteration_; size_t sched_count_; scheduler_t sched_; shared_context_t& sctx_; random_generator rand_; test_t* current_test_suite; bool current_test_suite_constructed; bool first_thread_; timestamp_t seq_cst_fence_order_ [thread_count]; aligned > threads_ [thread_count]; thread_info& threadi() { return *static_cast*>(threadx_); } slab_allocator >* atomic_alloc_; slab_allocator >* var_alloc_; slab_allocator >* mutex_alloc_; slab_allocator >* condvar_alloc_; slab_allocator >* sema_alloc_; slab_allocator >* event_alloc_; virtual atomic_data* atomic_ctor(void* ctx) { return new (atomic_alloc_->alloc(ctx)) atomic_data_impl (); } virtual void atomic_dtor(atomic_data* data) { static_cast*>(data)->~atomic_data_impl(); atomic_alloc_->free(static_cast*>(data)); } virtual var_data* var_ctor() { return new (var_alloc_->alloc()) var_data_impl (); } virtual void var_dtor(var_data* data) { static_cast*>(data)->~var_data_impl(); var_alloc_->free(static_cast*>(data)); } virtual unpark_reason wfmo_park(void** ws, win_waitable_object** wo, size_t count, bool wait_all, bool is_timed, debug_info_param info) { return waitset::park_current(*this, reinterpret_cast**>(ws), wo, count, wait_all, is_timed, true, info); } public: context_impl(test_params& params, shared_context_t& sctx) : base_t(thread_count, params) , current_iter_(0) , start_iteration_(1) , sched_(params, sctx, dynamic_thread_count) , sctx_(sctx) { this->context::seq_cst_fence_order_ = this->seq_cst_fence_order_; current_test_suite = (test_t*)(::malloc)(sizeof(test_t)); current_test_suite_constructed = false; test_result_ = test_result_success; threadx_ = 0; special_function_executing = false; invariant_executing = false; create_main_fiber(main_fiber_); set_low_thread_prio(); if (0 == val(thread_count)) { throw std::logic_error("no threads created"); } atomic_alloc_ = new slab_allocator >(); var_alloc_ = new slab_allocator >(); mutex_alloc_ = new slab_allocator >(); condvar_alloc_ = new slab_allocator >(); sema_alloc_ = new slab_allocator >(); event_alloc_ = new slab_allocator >(); for (thread_id_t i = 0; i != thread_count; ++i) { new (&threads_[i]) thread_info (i); threads_[i].ctx_ = this; } for (thread_id_t i = 0; i != thread_count; ++i) { //threads_[i].fiber_ = persistent.fibers_[i]; create_fiber(threads_[i].fiber_, &context_impl::fiber_proc, (void*)(intptr_t)i); } disable_alloc_ = 0; } ~context_impl() { disable_alloc_ += 1; for (thread_id_t i = 0; i != thread_count; ++i) { delete_fiber(threads_[i].fiber_); } delete_main_fiber(main_fiber_); // there can be atomic loads and stores etc // it's not good place to calling user code //destroy_current_test_suite(); //::free(current_test_suite); delete atomic_alloc_; delete var_alloc_; delete mutex_alloc_; delete condvar_alloc_; delete sema_alloc_; delete event_alloc_; } void construct_current_test_suite() { RL_VERIFY(false == current_test_suite_constructed); new (current_test_suite) test_t (); current_test_suite_constructed = true; } void destroy_current_test_suite() { if (current_test_suite_constructed) { current_test_suite->~test_t(); current_test_suite_constructed = false; } } virtual void* alloc(size_t size, bool is_array, debug_info_param info) { disable_alloc_ += 1; #ifndef RL_GC void* p = memory_.alloc(size); #else void* p = memory_.alloc(size, (void(*)(void*))0); #endif disable_alloc_ -= 1; RL_HIST_CTX(memory_alloc_event) {p, size, is_array} RL_HIST_END(); return p; } #ifdef RL_GC virtual void* alloc(size_t size, bool is_array, void(*dtor)(void*), debug_info_param info) { disable_alloc_ += 1; void* p = memory_.alloc(size, dtor); disable_alloc_ -= 1; RL_HIST_CTX(memory_alloc_event) {p, size, is_array} RL_HIST_END(); return p; } #endif virtual void free(void* p, bool is_array, debug_info_param info) { RL_HIST_CTX(memory_free_event) {p, is_array} RL_HIST_END(); #ifndef RL_GC bool const defer = (0 == sched_.rand(this->is_random_sched() ? 4 : 2, sched_type_mem_realloc)); #else bool const defer = false; #endif disable_alloc_ += 1; if (false == memory_.free(p, defer)) fail_test("incorrect address passed to free() function", test_result_double_free, info); disable_alloc_ -= 1; } size_t prev_alloc_size_; debug_info last_info_; virtual void* alloc(size_t size) { if (disable_alloc_) return (::malloc)(size); prev_alloc_size_ = size; disable_alloc_ += 1; #ifndef RL_GC void* p = (memory_.alloc)(size); #else void* p = (memory_.alloc)(size, 0); #endif disable_alloc_ -= 1; return p; } virtual size_t prev_alloc_size() { size_t sz = prev_alloc_size_; prev_alloc_size_ = 0; return sz; } virtual void set_debug_info(debug_info_param info) { last_info_ = info; } virtual void free(void* p) { if (disable_alloc_) { (::free)(p); return; } disable_alloc_ += 1; debug_info const& info = last_info_; RL_HIST_CTX(memory_free_event) {p, false} RL_HIST_END(); #ifndef RL_GC bool const defer = (0 == sched_.rand(this->is_random_sched() ? 4 : 2, sched_type_mem_realloc)); #else bool const defer = false; #endif if (false == memory_.free(p, defer)) fail_test("incorrect address passed to free() function", test_result_double_free, info); disable_alloc_ -= 1; } virtual unpark_reason park_current_thread(bool is_timed, bool allow_spurious_wakeup, bool do_switch, debug_info_param info) { RL_VERIFY(false == special_function_executing); RL_VERIFY(threadx_->saved_disable_preemption_ == -1); unsigned dp = disable_preemption_; disable_preemption_ = 0; RL_HIST_CTX(park_event) {is_timed, allow_spurious_wakeup} RL_HIST_END(); if (false == sched_.park_current_thread(is_timed, allow_spurious_wakeup)) { fail_test("deadlock detected", test_result_deadlock, info); } schedule(1); // otherwise it's restored in switch_back() RL_VERIFY(threadx_->saved_disable_preemption_ == -1); if (do_switch == false || threadx_->unpark_reason_ != unpark_reason_normal) disable_preemption_ = dp; else threadx_->saved_disable_preemption_ = dp; unpark_reason reason = threadx_->unpark_reason_; return reason; } virtual void unpark_thread(thread_id_t th, bool do_switch, debug_info_param info) { RL_VERIFY(false == special_function_executing); RL_HIST_CTX(unpark_event) {th} RL_HIST_END(); sched_.unpark_thread(th, do_switch); if (do_switch) { threads_[th].unpark_reason_ = unpark_reason_normal; threads_[th].temp_switch_from_ = threadx_->index_; switch_to_fiber(th); } } virtual void switch_back(debug_info_param info) { //std::cout << "switching back from " << threadx_->index_ << " to " << threadx_->temp_switch_from_ << std::endl; (void)info; RL_VERIFY(threadx_->saved_disable_preemption_ != -1); RL_VERIFY(threadx_->temp_switch_from_ != -1); thread_id_t const tid = threadx_->temp_switch_from_; threadx_->temp_switch_from_ = -1; switch_to_fiber(tid); RL_VERIFY(threadx_->saved_disable_preemption_ != -1); disable_preemption_ = threadx_->saved_disable_preemption_; threadx_->saved_disable_preemption_ = -1; } void ensure(bool cond, char const* desc, test_result_e res, debug_info_param info) { if (false == cond) fail_test(desc, res, info); } virtual void fail_test(char const* desc, test_result_e res, debug_info_param info) { RL_DEBUGBREAK_ON_FAILURE_IMPL; RL_VERIFY(test_result_success != res); test_result_ = res; if (test_result_user_assert_failed == res && invariant_executing) test_result_ = test_result_user_invariant_failed; if (0 == desc || 0 == desc[0]) test_result_str_ = test_result_str(test_result_); else test_result_str_ = string(test_result_str(test_result_)) + " (" + desc + ")"; RL_HIST_CTX(user_event) {test_result_str_.c_str()} RL_HIST_END(); switch_to_main_fiber(); } virtual void rl_until(char const* desc, debug_info_param info) { RL_HIST_CTX(user_event) {desc} RL_HIST_END(); test_result_ = test_result_until_condition_hit; switch_to_main_fiber(); } static void fiber_proc(void* thread_index); virtual void fiber_proc_impl(int thread_index) { thread_info_base* param = &threads_[thread_index]; debug_info info = $; for (;;) { if (first_thread_) { first_thread_ = false; special_function_executing = true; RL_HIST_CTX(user_event) {"[CTOR BEGIN]"} RL_HIST_END(); construct_current_test_suite(); RL_HIST_CTX(user_event) {"[CTOR END]"} RL_HIST_END(); RL_HIST_CTX(user_event) {"[BEFORE BEGIN]"} RL_HIST_END(); current_test_suite->before(); RL_HIST_CTX(user_event) {"[BEFORE END]"} RL_HIST_END(); rl_global_fence(); invariant_executing = true; current_test_suite->invariant(); invariant_executing = false; special_function_executing = false; } //std::cout << "thread " << param->index_ << " started" << std::endl; param->on_start(); if (param->index_ < static_thread_count) { current_test_suite->thread(param->index_); } else { if (param->dynamic_thread_func_) param->dynamic_thread_func_(param->dynamic_thread_param_); } //std::cout << "thread " << param->index_ << " finished" << std::endl; RL_HIST_CTX(user_event) {"[THREAD FINISHED]"} RL_HIST_END(); RL_VERIFY(disable_preemption_ == 0); RL_VERIFY(threadx_->temp_switch_from_ == -1); RL_VERIFY(threadx_->saved_disable_preemption_ == -1); param->on_finish(); thread_finish_result res = sched_.thread_finished(); //std::cout << "thread " << param->index_ << " finished res=" << res << std::endl; if (thread_finish_result_normal == res) { sched(); } else if (thread_finish_result_last == res) { special_function_executing = true; invariant_executing = true; current_test_suite->invariant(); invariant_executing = false; rl_global_fence(); RL_HIST_CTX(user_event) {"[AFTER BEGIN]"} RL_HIST_END(); current_test_suite->after(); RL_HIST_CTX(user_event) {"[AFTER END]"} RL_HIST_END(); RL_HIST_CTX(user_event) {"[DTOR BEGIN]"} RL_HIST_END(); destroy_current_test_suite(); RL_HIST_CTX(user_event) {"[DTOR END]"} RL_HIST_END(); special_function_executing = false; ensure(memory_.iteration_end(), "memory leak detected", test_result_memory_leak, $); ensure(atomic_alloc_->iteration_end(), "atomic leak", test_result_resource_leak, $); ensure(var_alloc_->iteration_end(), "var leak", test_result_resource_leak, $); ensure(mutex_alloc_->iteration_end(), "mutex leak", test_result_resource_leak, $); ensure(condvar_alloc_->iteration_end(), "condition variable leak", test_result_resource_leak, $); ensure(sema_alloc_->iteration_end(), "semaphore leak", test_result_resource_leak, $); ensure(event_alloc_->iteration_end(), "event leak", test_result_resource_leak, $); switch_to_main_fiber(); } else if (thread_finish_result_deadlock == res) { fail_test("deadlock detected", test_result_deadlock, info); } else { RL_VERIFY(false); } } } virtual win_waitable_object* create_thread(void*(*fn)(void*), void* ctx) { RL_VERIFY(fn); thread_id_t id = sched_.create_thread(); threads_[id].dynamic_thread_func_ = fn; threads_[id].dynamic_thread_param_ = ctx; threads_[id].sync_object_.on_create(); return &threads_[id].sync_object_; } virtual void yield(unsigned count, debug_info_param info) { RL_VERIFY(count); RL_HIST_CTX(yield_event) {count} RL_HIST_END(); if (sched_count_++ > params_.execution_depth_limit) fail_test("livelock", test_result_livelock, RL_INFO); schedule(count); } virtual void sched() { if (sched_count_++ > params_.execution_depth_limit) fail_test("livelock", test_result_livelock, RL_INFO); if (disable_preemption_) return; schedule(0); } void schedule(unsigned yield) { RL_VERIFY(threadx_->temp_switch_from_ == -1); RL_VERIFY(disable_preemption_ == 0); if (special_function_executing) { threadx_->unpark_reason_ = unpark_reason_normal; return; } special_function_executing = true; invariant_executing = true; current_test_suite->invariant(); invariant_executing = false; special_function_executing = false; if (yield) threadx_->last_yield_ = threadi().own_acq_rel_order_; unpark_reason reason = unpark_reason_normal; thread_id_t const th = sched_.schedule(reason, yield); threads_[th].unpark_reason_ = reason; switch_to_fiber(th); RL_VERIFY(0 == disable_preemption_); } test_result_e simulate(std::ostream& ss, std::istream& sss, bool second) { if (EOF != sss.peek()) { sss >> start_iteration_; sched_.set_state(sss); } test_result_e const res = simulate2(second); if (test_result_success != res && false == params_.collect_history) { ss << params_.stop_iteration << " "; sched_.get_state(ss); } return res; } test_result_e simulate2(bool second) { debug_info info = $; current_iter_ = start_iteration_; for (; ; ++current_iter_) { rand_.seed(current_iter_); iteration(current_iter_); if (test_result_success != test_result_) { params_.test_result = test_result_; params_.stop_iteration = current_iter_; if (params_.collect_history) output_history(); return test_result_; } // If you hit assert here, then probably your test is non-deterministic // Check whether you are using functions like ::rand() // or static variables or values of object addresses (for hashing) in your test // Replace ::rand() with rl::rand(), eliminate static variables in the test RL_VERIFY(second == false); (void)second; RL_HIST_CTX(user_event) {"ITERATION END"} RL_HIST_END(); if (sched_.iteration_end()) break; } params_.test_result = test_result_success; params_.stop_iteration = current_iter_; return test_result_success; } RL_INLINE static void reset_thread(thread_info& ti) { foreach( ti.acquire_fence_order_, &assign_zero); foreach( ti.release_fence_order_, &assign_zero); #ifdef RL_IMPROVED_SEQ_CST_FENCE foreach(ti.imp_seq_cst_order_, &assign_zero); #endif } void iteration(iteration_t iter) { first_thread_ = true; disable_preemption_ = 0; sched_count_ = 0; foreach( threads_, &context_impl::reset_thread); foreach( seq_cst_fence_order_, &assign_zero); base_t::iteration_begin(); for (thread_id_t i = 0; i != thread_count; ++i) { threads_[i].iteration_begin(); } disable_alloc_ += 1; thread_id_t const th = sched_.iteration_begin(iter); disable_alloc_ -= 1; switch_to_fiber(th); if (0 == iter % progress_probe_period) { output_progress(iter); } } private: void switch_to_fiber(thread_id_t th) { fiber_t& prev = threadx_ ? threadx_->fiber_ : main_fiber_; threadx_ = &threads_[th]; ::switch_to_fiber(threadx_->fiber_, prev); } void switch_to_main_fiber() { fiber_t& prev = threadx_->fiber_; threadx_ = 0; ::switch_to_fiber(main_fiber_, prev); } void output_progress(iteration_t iter) { iteration_t const total = sched_.iteration_count(); if (0 == iter % (progress_probe_period * 16)) { disable_alloc_ += 1; *params_.progress_stream << iter * 100 / total << "% (" << iter << "/" << total << ")" << std::endl; disable_alloc_ -= 1; } } virtual unsigned rand(unsigned limit, sched_type t) { return sched_.rand(limit, t); } void output_history() { if (false == params_.output_history) { *params_.output_stream << test_result_str_ << std::endl; *params_.output_stream << "iteration: " << params_.stop_iteration << std::endl; *params_.output_stream << std::endl; } history_.print_exec_history(params_.output_history); #ifndef RL_GC if (test_result_memory_leak == test_result_) { memory_.output_allocs(*params_.output_stream); } #endif //!!! output other leaked resources if (test_result_ == test_result_resource_leak && atomic_alloc_->iteration_end() == false) { *params_.output_stream << "leaked atomics:" << std::endl; atomic_alloc_->output_allocs(*params_.output_stream); } } void rl_global_fence() { timestamp_t max_acq_rel = 0; for (thread_id_t i = 0; i != thread_count; ++i) { if (threads_[i].acq_rel_order_[i] > max_acq_rel) max_acq_rel = threads_[i].acq_rel_order_[i]; } for (thread_id_t i = 0; i != thread_count; ++i) { for (thread_id_t j = 0; j != thread_count; ++j) { threads_[i].acq_rel_order_[j] = max_acq_rel; } } } virtual void atomic_thread_fence_acquire() { threadi().atomic_thread_fence_acquire(); } virtual void atomic_thread_fence_release() { threadi().atomic_thread_fence_release(); } virtual void atomic_thread_fence_acq_rel() { threadi().atomic_thread_fence_acq_rel(); } virtual void atomic_thread_fence_seq_cst() { sched(); threadi().atomic_thread_fence_seq_cst(seq_cst_fence_order_); } virtual thread_id_t get_thread_count() const { return thread_count; } virtual generic_mutex_data* mutex_ctor(bool is_rw, bool is_exclusive_recursive, bool is_shared_recursive, bool failing_try_lock) { return new (mutex_alloc_->alloc()) generic_mutex_data_impl(is_rw, is_exclusive_recursive, is_shared_recursive, failing_try_lock); } virtual void mutex_dtor(generic_mutex_data* m) { generic_mutex_data_impl* mm = static_cast*>(m); mm->~generic_mutex_data_impl(); mutex_alloc_->free(mm); } virtual condvar_data* condvar_ctor(bool allow_spurious_wakeups) { return new (condvar_alloc_->alloc()) condvar_data_impl(allow_spurious_wakeups); } virtual void condvar_dtor(condvar_data* cv) { condvar_data_impl* mm = static_cast*>(cv); mm->~condvar_data_impl(); condvar_alloc_->free(mm); } virtual sema_data* sema_ctor(bool spurious_wakeups, unsigned initial_count, unsigned max_count) { return new (sema_alloc_->alloc()) sema_data_impl(spurious_wakeups, initial_count, max_count); } virtual void sema_dtor(sema_data* cv) { sema_data_impl* mm = static_cast*>(cv); mm->~sema_data_impl(); sema_alloc_->free(mm); } virtual event_data* event_ctor(bool manual_reset, bool initial_state) { return new (event_alloc_->alloc()) event_data_impl(manual_reset, initial_state); } virtual void event_dtor(event_data* cv) { event_data_impl* mm = static_cast*>(cv); mm->~event_data_impl(); event_alloc_->free(mm); } context_impl(context_impl const&); context_impl& operator = (context_impl const&); }; /* template struct thread_params_t { typedef context_impl context_t; //HANDLE handle; context_t* ctx; ostringstream oss; istringstream* iss; //RL_NOCOPY(thread_params_t); }; template unsigned __stdcall thread_func(void * ctx) { typedef thread_params_t params_t; params_t& p = *static_cast(ctx); p.ctx->simulate(p.oss, *p.iss, false); return 0; } */ template test_result_e run_test(test_params& params, std::ostream& oss, bool second) { typedef context_impl context_t; typedef typename sched_t::shared_context_t shared_context_t; //typedef thread_params_t params_t; //bool destroy_persistent = false; //context_persistent* persistent = 0; //if (persistent_ptr == 0) //{ // persistent = new context_persistent; // persistent_ptr = persistent; //} //else //{ // persistent = static_cast*>(persistent_ptr); // destroy_persistent = true; //} shared_context_t sctx; test_result_e res; //if (second == false) { istringstream iss (params.initial_state); res = context_t(params, sctx).simulate(oss, iss, second); } //else //{ // size_t const thread_count = 2; // vector::type threads (thread_count); // for (size_t i = 0; i != thread_count; i += 1) // { // threads[i] = new params_t; // threads[i]->iss = new istringstream(params.initial_state); // threads[i]->ctx = new context_t(params, sctx); // threads[i]->handle = (HANDLE)(_beginthreadex)(0, 0, &thread_func, threads[i], 0, 0); // } // for (size_t i = 0; i != thread_count; i += 1) // { // (WaitForSingleObject)(threads[i]->handle, (INFINITE)); // } // for (size_t i = 0; i != thread_count; i += 1) // { // delete threads[i]->ctx; // delete threads[i]->iss; // delete threads[i]; // } // return test_result_success; //} //if (destroy_persistent) //{ // delete persistent; // persistent_ptr = 0; //} return res; } template bool simulate(test_params& params) { char const* test_name = typeid(test_t).name(); while (test_name[0] >= '0' && test_name[0] <= '9') test_name += 1; params.test_name = test_name; *params.output_stream << params.test_name << std::endl; unsigned start_time = get_tick_count(); //void* persistent = 0; ostringstream oss; //istringstream iss (params.initial_state); test_result_e res = test_result_success; if (random_scheduler_type == params.search_type) res = run_test >(params, oss, false); else if (fair_full_search_scheduler_type == params.search_type) res = run_test >(params, oss, false); else if (fair_context_bound_scheduler_type == params.search_type) res = run_test >(params, oss, false); else RL_VERIFY(false); if (test_result_success == res) { unsigned t = get_tick_count() - start_time; if (0 == t) t = 1; *params.output_stream << "iterations: " << params.stop_iteration << std::endl; *params.output_stream << "total time: " << t << std::endl; *params.output_stream << "throughput: " << (uint64_t)params.stop_iteration * 1000 / t << std::endl; *params.output_stream << std::endl; } else if (false == params.output_history && false == params.collect_history) { ostringstream oss2; params.initial_state = oss.str(); //istringstream iss2 (oss.str()); params.collect_history = true; params.final_state = oss.str(); iteration_t const stop_iter = params.stop_iteration; test_result_e res2 = test_result_success; if (random_scheduler_type == params.search_type) res2 = run_test >(params, oss2, true); else if (fair_full_search_scheduler_type == params.search_type) res2 = run_test >(params, oss2, true); else if (fair_context_bound_scheduler_type == params.search_type) res2 = run_test >(params, oss2, true); else RL_VERIFY(false); // If you hit assert here, then probably your test is non-deterministic // Check whether you are using functions like ::rand() // or static variables or values of object addresses (for hashing) in your test // Replace ::rand() with rl::rand(), eliminate static variables in the test RL_VERIFY(res == res2); RL_VERIFY(params.stop_iteration == stop_iter); (void)stop_iter; (void)res2; } return test_t::params::expected_result == res; } template bool simulate() { test_params params; return simulate(params); } template struct simulate_thunk : test_suite, 1> { static size_t const dynamic_thread_count = thread_count; void thread(unsigned) { func(); } }; template bool execute(test_params& params) { return simulate >(params); } template bool execute() { return simulate >(); } typedef bool (*simulate_f)(test_params&); template void context_impl::fiber_proc(void* thread_index) { ctx().fiber_proc_impl((int)(intptr_t)thread_index); } template void dtor_arr_impl(void* pp) { type* p = (type*)((char*)pp + alignment); size_t count = *(size_t*)pp; for (size_t i = 0; i != count; ++i) { p->~type(); p += 1; } } template type* new_arr_impl(size_t count, rl::debug_info_param info) { RL_VERIFY(alignment >= sizeof(size_t)); context& c = ctx(); #ifndef RL_GC void* mem = c.alloc(alignment + count * sizeof(type), true, info); #else void* mem = c.alloc(alignment + count * sizeof(type), true, &dtor_arr_impl, info); #endif *(size_t*)mem = count; size_t i = 0; char* begin = (char*)mem + alignment; char* pos = begin; try { for (; i != count; ++i) { new (pos) type; pos += sizeof(type); } return (type*)begin; } catch (...) { pos -= sizeof(type); i -= 1; for (; i < count; --i) { ((type*)pos)->~type(); pos -= sizeof(type); } ctx().free(mem, true, info); throw; } } template void delete_arr_impl(type* p, debug_info_param info) { if (p == 0) return; context& c = ctx(); char* begin = (char*)p - alignment; size_t count = *(size_t*)begin; for (size_t i = 0; i != count; ++i) { p->~type(); p += 1; } c.free(begin, true, info); } template void delete_impl(type* p, debug_info_param info) { p->~type(); ctx().free(p, false, info); } template void dtor_impl(void* p) { static_cast(p)->~type(); } inline unsigned rand(unsigned limit) { return ctx().rand(limit, sched_type_user); } inline unsigned thread_index() { return ctx().threadx_->index_; } struct new_proxy { debug_info info; new_proxy(debug_info_param info) : info(info) { //printf(__FUNCSIG__ "\n"); } template T* operator % (T* p) { context& c = ctx(); size_t sz = c.prev_alloc_size(); if (sz) { RL_HIST(memory_alloc_event) {p, sz, false} RL_HIST_END(); } return p; } }; struct delete_proxy { //debug_info info_; delete_proxy(debug_info_param info) //: info_(info) { ctx().set_debug_info(info); //printf(__FUNCSIG__ "\n"); } }; inline void* rl_malloc(size_t sz, debug_info_param info) { return ctx().alloc(sz, false, info); } inline void* rl_calloc(size_t sz, size_t cnt, debug_info_param info) { void* p = ctx().alloc(sz * cnt, false, info); memset(p, 0, sz * cnt); return p; } inline void* realloc(void* p, size_t sz, debug_info_param info) { if (sz == 0) { ctx().free(p, false, info); return 0; } else { void* pp = ctx().alloc(sz, false, info); memcpy(pp, p, sz); //!!! how much memory to move? ctx().free(p, false, info); return pp; } } inline void rl_free(void* p, debug_info_param info) { ctx().free(p, false, info); } inline size_t hash_ptr(void const* p, size_t size) { return ctx().get_addr_hash(p) % size; } inline void systemwide_fence(debug_info_param info) { context& c = ctx(); RL_HIST(user_msg_event) {"system-wide fence"} RL_HIST_END(); c.rl_global_fence(); } } // namespace rl #ifndef RL_GC inline void* operator new (size_t size, rl::debug_info_param info) { return rl::ctx().alloc(size, false, info); } inline void* operator new [] (size_t size, rl::debug_info_param info) { return rl::ctx().alloc(size, false, info); } inline void operator delete (void* p, rl::debug_info_param info) { rl::ctx().free(p, false, info); } inline void operator delete [] (void* p, rl::debug_info_param info) { rl::ctx().free(p, false, info); } #endif #ifdef RL_GC inline void* operator new (size_t size, void(*dtor)(void*), rl::debug_info_param info) { return rl::ctx().alloc(size, false, dtor, info); } inline void operator delete (void* p, void(*dtor)(void*), rl::debug_info_param info) { (void)p; (void)dtor; (void)info; } #endif inline void* operator new (size_t size) RL_THROW_SPEC(std::bad_alloc) { if (&rl::ctx()) return rl::ctx().alloc(size); else return (::malloc)(size); } inline void* operator new [] (size_t size) RL_THROW_SPEC(std::bad_alloc) { if (&rl::ctx()) return rl::ctx().alloc(size); else return (::malloc)(size); } inline void operator delete (void* p) throw() { if (&rl::ctx()) rl::ctx().free(p); else (::free)(p); } inline void operator delete [] (void* p) throw() { if (&rl::ctx()) rl::ctx().free(p); else (::free)(p); } #define RL_NEW_PROXY rl::new_proxy($) % new #define RL_DELETE_PROXY rl::delete_proxy($) , delete #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/context_addr_hash.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CONTEXT_ADDR_HASH_HPP #define RL_CONTEXT_ADDR_HASH_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { struct context_addr_hash_iface { virtual size_t get_addr_hash (void const* p) = 0; virtual ~context_addr_hash_iface () {} // to calm down g++ }; template class context_addr_hash_impl : protected base_t { public: context_addr_hash_impl(thread_id_t thread_count_param, test_params& params) : base_t(thread_count_param, params) { } void iteration_begin() { base_t::iteration_begin(); hash_map_.clear(); hash_seq_ = 0; } private: struct entry { uintptr_t ptr_; size_t hash_; }; typedef map::type hash_map_t; hash_map_t hash_map_; size_t hash_seq_; virtual size_t get_addr_hash (void const* p) { //!!! accept 'table size' to do 'hash % table_size' // will give more information for state exploration hash_map_t::iterator iter (hash_map_.find(p)); if (iter != hash_map_.end() && iter->first == p) { return iter->second; } else { //!!! distribute hashes more randomly, use rand() size_t hash = hash_seq_++; hash_map_.insert(std::make_pair(p, hash)); return hash; } } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/context_base.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CONTEXT_BASE_HPP #define RL_CONTEXT_BASE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "history.hpp" #include "memory.hpp" #include "test_result.hpp" #include "slab_allocator.hpp" #include "test_params.hpp" #include "random.hpp" #include "foreach.hpp" #include "thread_base.hpp" #include "context_addr_hash.hpp" #ifdef RL_DEBUGBREAK_ON_ASSERT # ifdef _MSC_VER # define RL_DEBUGBREAK_ON_ASSERT_IMPL {if (IsDebuggerPresent()) __debugbreak();} # else # define RL_DEBUGBREAK_ON_ASSERT_IMPL {__asm("int3");} # endif #else # define RL_DEBUGBREAK_ON_ASSERT_IMPL #endif #ifdef RL_DEBUGBREAK_ON_FAILURE # ifdef _MSC_VER # define RL_DEBUGBREAK_ON_FAILURE_IMPL {if (IsDebuggerPresent()) __debugbreak();} # else # define RL_DEBUGBREAK_ON_FAILURE_IMPL {__asm("int3");} # endif #else # define RL_DEBUGBREAK_ON_FAILURE_IMPL #endif namespace rl { class thread_info_base; struct atomic_data {}; struct var_data { virtual void init(thread_info_base& th) = 0; virtual bool store(thread_info_base& th) = 0; virtual bool load(thread_info_base& th) = 0; virtual ~var_data() {} // just to calm down gcc }; struct generic_mutex_data; struct condvar_data; struct sema_data; struct event_data; struct user_msg_event { string msg_; void output(std::ostream& s) const { s << msg_; } }; class context; template struct context_holder { static context* instance_; static long volatile ctx_seq; }; template long volatile context_holder::ctx_seq = 0; class context : public thread_local_context_iface , public context_addr_hash_iface , nocopy<> { public: static context& instance() { //!!! disabled for check in operator new RL_VERIFY(context_holder<>::instance_); return *context_holder<>::instance_; } virtual atomic_data* atomic_ctor(void* ctx) = 0; virtual void atomic_dtor(atomic_data* data) = 0; virtual var_data* var_ctor() = 0; virtual void var_dtor(var_data* data) = 0; virtual generic_mutex_data* mutex_ctor(bool is_rw, bool is_exclusive_recursive, bool is_shared_recursive, bool failing_try_lock) = 0; virtual void mutex_dtor(generic_mutex_data* m) = 0; virtual condvar_data* condvar_ctor(bool allow_spurious_wakeups) = 0; virtual void condvar_dtor(condvar_data* cv) = 0; virtual sema_data* sema_ctor(bool spurious_wakeups, unsigned initial_count, unsigned max_count) = 0; virtual void sema_dtor(sema_data* cv) = 0; virtual event_data* event_ctor(bool manual_reset, bool initial_state) = 0; virtual void event_dtor(event_data* cv) = 0; virtual void rl_global_fence() = 0; virtual void sched() = 0; virtual void yield(unsigned count, debug_info_param info) = 0; virtual void fail_test(char const* desc, test_result_e res, debug_info_param info) = 0; virtual void rl_until(char const* desc, debug_info_param info) = 0; virtual void* alloc(size_t size, bool is_array, debug_info_param info) = 0; #ifdef RL_GC virtual void* alloc(size_t size, bool is_array, void(*dtor)(void*), debug_info_param info) = 0; #endif virtual void free(void* p, bool is_array, debug_info_param info) = 0; virtual void* alloc(size_t size) = 0; virtual void free(void* p) = 0; virtual size_t prev_alloc_size() = 0; virtual void set_debug_info(debug_info_param info) = 0; virtual void fiber_proc_impl(int thread_index) = 0; virtual unpark_reason park_current_thread(bool is_timed, bool allow_spurious_wakeup, bool do_switch, debug_info_param info) = 0; virtual void unpark_thread(thread_id_t th, bool do_switch, debug_info_param info) = 0; virtual void switch_back(debug_info_param info) = 0; virtual void atomic_thread_fence_acquire() = 0; virtual void atomic_thread_fence_release() = 0; virtual void atomic_thread_fence_acq_rel() = 0; virtual void atomic_thread_fence_seq_cst() = 0; virtual unsigned rand(unsigned limit, sched_type t) = 0; virtual win_waitable_object* create_thread(void*(*fn)(void*), void* ctx) = 0; virtual unpark_reason wfmo_park(void** ws, win_waitable_object** wo, size_t count, bool wait_all, bool is_timed, debug_info_param info) = 0; int get_errno(); void set_errno(int value); thread_info_base* threadx_; timestamp_t* seq_cst_fence_order_; bool invariant_executing; RL_INLINE bool collecting_history() const { return params_.collect_history && false == invariant_executing; } template void exec_log(debug_info_param info, event_t const& ev); void exec_log_msg(debug_info_param info, char const* msg) { user_msg_event ev = {msg}; exec_log(info, ev); } bool is_random_sched() const { return is_random_sched_; } unsigned get_ctx_seq() const { return ctx_seq_; } void disable_preemption(); void enable_preemption(); virtual thread_id_t get_thread_count() const = 0; thread_id_t current_thread() const { return threadx_->index_; } void iteration_begin() { } protected: history_mgr history_; test_params& params_; unsigned disable_preemption_; int disable_alloc_; context(thread_id_t thread_count, test_params& params) : history_(*params.output_stream, thread_count) , params_(params) , disable_alloc_(1) { RL_VERIFY(0 == context_holder<>::instance_); context_holder<>::instance_ = this; is_random_sched_ = params_.search_type == random_scheduler_type; #ifdef _MSC_VER ctx_seq_ = _InterlockedExchangeAdd(&context_holder<>::ctx_seq, 1) + 1; #else ctx_seq_ = __sync_fetch_and_add(&context_holder<>::ctx_seq, 1) + 1; #endif } virtual ~context() { RL_VERIFY(this == context_holder<>::instance_); context_holder<>::instance_ = 0; } private: bool is_random_sched_; unsigned ctx_seq_; }; template context* context_holder::instance_ = 0; inline context& ctx() { return context::instance(); } inline int get_errno() { return ctx().get_errno(); } inline void set_errno(int value) { return ctx().set_errno(value); } class preemption_disabler : nocopy<> { public: preemption_disabler(context& c) : c_(c) { c_.disable_preemption(); } ~preemption_disabler() { c_.enable_preemption(); } private: context& c_; }; } #define RL_HIST_IMPL(C, INFO, TYPE) \ do { \ if (C.collecting_history()) { \ rl::debug_info const& rl_info_c = INFO; \ rl::context& rl_hist_c = C; \ TYPE ev = \ /**/ #define RL_HIST_END() \ ; \ rl_hist_c.exec_log(rl_info_c, ev); \ } \ } while ((void)0, 0) \ /**/ #define RL_HIST_CTX(TYPE) RL_HIST_IMPL((*this), info, TYPE) #define RL_HIST(TYPE) RL_HIST_IMPL(c, info, TYPE) #define RL_LOG(desc) rl::ctx().exec_log_msg(RL_INFO, desc) #ifdef _MSC_VER # define RL_ASSERT_IMPL(x, res, str, info) do {if (!((void)0, (x))) {{RL_DEBUGBREAK_ON_ASSERT_IMPL} rl::ctx().fail_test(str, res, info);}} while ((void)0, 0) #else # define RL_ASSERT_IMPL(x, res, str, info) do {if (!((void)0, (x))) rl::ctx().fail_test(str, res, info);} while ((void)0, 0) #endif #define RL_ASSERT(x) RL_ASSERT_IMPL(x, rl::test_result_user_assert_failed, "assertion: " #x, RL_INFO) #define RL_UNTIL(x) do {if ((x)) rl::ctx().rl_until(#x, RL_INFO);} while ((void)0, 0) #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/context_base_impl.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CONTEXT_BASE_IMPL_HPP #define RL_CONTEXT_BASE_IMPL_HPP #ifdef _MSC_VER # pragma once #endif namespace rl { /* inline void context::disable_history() { RL_VERIFY(threadx_); threadx_->disable_history_ += 1; } inline void context::enable_history() { RL_VERIFY(threadx_); RL_VERIFY(threadx_->disable_history_); threadx_->disable_history_ -= 1; } */ inline void context::disable_preemption() { disable_preemption_ += 1; } inline void context::enable_preemption() { disable_preemption_ -= 1; } inline int context::get_errno() { RL_VERIFY(threadx_); return threadx_->errno_; } inline void context::set_errno(int value) { RL_VERIFY(threadx_); threadx_->errno_ = value; } template void context::exec_log(debug_info_param info, event_t const& ev) { RL_VERIFY(collecting_history()); disable_alloc_ += 1; history_.exec_log(threadx_ ? threadx_->index_ : -1, info, ev, params_.output_history); disable_alloc_ -= 1; } } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/context_bound_scheduler.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CONTEXT_BOUND_SCHEDULER_HPP #define RL_CONTEXT_BOUND_SCHEDULER_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "full_search_scheduler.hpp" #include "foreach.hpp" namespace rl { template struct context_bound_scheduler_thread_info : tree_search_scheduler_thread_info { unsigned sched_count_; unsigned forced_context_switch_count_; void reset(test_params& params) { tree_search_scheduler_thread_info::reset(params); sched_count_ = 0; forced_context_switch_count_ = 0; } }; template class context_bound_scheduler : public tree_search_scheduler , context_bound_scheduler_thread_info, thread_count> { public: typedef tree_search_scheduler , context_bound_scheduler_thread_info, thread_count> base_t; typedef typename base_t::thread_info_t thread_info_t; typedef typename base_t::shared_context_t shared_context_t; context_bound_scheduler(test_params& params, shared_context_t& ctx, thread_id_t dynamic_thread_count) : base_t(params, ctx, dynamic_thread_count) { } thread_id_t iteration_begin_impl() { switches_remain_ = this->params_.context_bound; return base_t::iteration_begin_impl(); } bool can_switch(thread_info_t& t) { t.sched_count_ += 1; return switches_remain_ != 0; } void on_switch(thread_info_t& t) { if (t.state_ == thread_state_running) { RL_VERIFY(switches_remain_); switches_remain_ -= 1; } else { t.forced_context_switch_count_ += 1; } } double iteration_count_approx() { return 1.0; /* iteration_t const P = thread_count; iteration_t const C0 = this->params_.context_bound; iteration_t total = 1;//factorial(P);// * power(P, P * C0); for (iteration_t i = 0; i != P - 1; ++i) total *= power(i + 1, C0 + 1); //if (C0) // total *= power(P - 1, P - 1); if (val(P) > 1) { for (iteration_t i = 0; i != P; ++i) { iteration_t const N = this->threads_[i].sched_count_; iteration_t const C = C0 + this->threads_[i].forced_context_switch_count_; //total *= (iteration_t)pow((double)(threads_[i].sched_count_ + 2) * (thread_count - 1), (int)(params_.context_bound + threads_[i].forced_context_switch_count_)); total *= factorial(N, C) / factorial(C); //C$ += C + 1; //total *= (int)(params_.context_bound + threads_[i].forced_context_switch_count_)); } //total *= factorial(C$); } else { total = 1; } //iteration_t total = (iteration_t)pow((double)sched_count / thread_count + 1, (int)(params_.context_bound * thread_count + forced_context_switch_mean_ + 0.5)); //total *= thread_count; //total *= (iteration_t)pow((double)thread_count - 1, thread_count); for (size_t i = 0; i != this->stree_.size(); ++i) { if (this->stree_[i].type_ != sched_type_sched) { total *= this->stree_[i].count_; } } return (double)total; */ } private: unsigned switches_remain_; template static T factorial(T x, T i) { if (0 == i) return 1; T r = x; for (--i; i; --i) r *= x - i; return r; } template static T factorial(T x) { if (0 == x) return 1; T r = x; for (T i = x - 1; i; --i) r *= i; return r; } template static T power(T x, T y) { if (0 == y) return 1; T r = x; for (T i = y - 1; i; --i) r *= x; return r; } RL_NOCOPY(context_bound_scheduler); }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/defs.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_DEFS_HPP #define RL_DEFS_HPP #ifdef _MSC_VER # pragma once #endif namespace rl { typedef int thread_id_t; typedef size_t timestamp_t; typedef uint64_t iteration_t; size_t const atomic_history_size = 3; iteration_t const progress_probe_period = 4 * 1024; size_t const alignment = 16; class context; class thread_base; struct win_waitable_object; enum sched_type { sched_type_sched, sched_type_atomic_load, sched_type_cas_fail, sched_type_mem_realloc, sched_type_user, }; enum unpark_reason { unpark_reason_normal, unpark_reason_timeout, unpark_reason_spurious, }; struct debug_info { char const* func_; char const* file_; unsigned line_; debug_info(char const* func = "", char const* file = "", unsigned line = 0) : func_(func) , file_(file) , line_(line) { } }; typedef debug_info const& debug_info_param; inline void assert_failed(char const* cond, debug_info_param info) { std::cout << "RELACY INTERNAL ASSERT FAILED: '" << cond << "' at " << info.file_ << ":" << info.line_ << " (" << info.func_ << ")" << std::endl; } template struct raw_allocator : std::allocator { template struct rebind { typedef raw_allocator other; }; template raw_allocator(raw_allocator const&) { } raw_allocator(raw_allocator const& rhs) : std::allocator(rhs) { } raw_allocator() : std::allocator() { } T* allocate(size_t count, void* = 0) { return (T*)(::malloc)(count * sizeof(T)); } void deallocate(T* p, size_t) { (::free)(p); } }; template struct vector { typedef std::vector > type; }; template struct queue { typedef std::queue > > type; }; template struct stack { typedef std::stack > > type; }; template struct set { typedef std::set, raw_allocator > type; }; template struct map { typedef std::map, raw_allocator > > type; }; typedef std::basic_string, raw_allocator > string; typedef std::basic_ostringstream, raw_allocator > ostringstream; typedef std::basic_istringstream, raw_allocator > istringstream; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/dyn_thread.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_DYN_THREAD_HPP #define RL_DYN_THREAD_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context_base.hpp" #include "stdlib/semaphore.hpp" namespace rl { class dyn_thread : nocopy<> { public: dyn_thread() { handle_ = 0; } void start(void*(*fn)(void*), void* arg) { RL_VERIFY(handle_ == 0); handle_ = ctx().create_thread(fn, arg); } void join() { RL_VERIFY(handle_); handle_->wait(false, false, $); handle_ = 0; } private: win_waitable_object* handle_; }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/dyn_thread_ctx.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_DYN_THREAD_CTX_HPP #define RL_DYN_THREAD_CTX_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "waitset.hpp" #include "sync_var.hpp" #include "stdlib/semaphore.hpp" namespace rl { template class thread_sync_object : public win_waitable_object { public: thread_sync_object() { } void iteration_begin() { finished_ = false; sync_.iteration_begin(); RL_VERIFY(!ws_); } void on_create() { sync_.release(ctx().threadx_); } void on_start() { RL_VERIFY(finished_ == false); context& c = ctx(); sync_.acquire(c.threadx_); } void on_finish() { RL_VERIFY(finished_ == false); context& c = ctx(); finished_ = true; sync_.release(c.threadx_); ws_.unpark_all(c, $); } private: bool finished_; waitset ws_; sync_var sync_; virtual void deinit(debug_info_param info) { (void)info; } virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) { context& c = ctx(); if (finished_) { sync_.acquire(c.threadx_); return sema_wakeup_reason_success; } else if (try_wait) { sync_.acquire(c.threadx_); return sema_wakeup_reason_failed; } else { unpark_reason reason = ws_.park_current(c, is_timed, false, false, info); sync_.acquire(c.threadx_); if (reason == unpark_reason_normal) return sema_wakeup_reason_success; else if (reason == unpark_reason_timeout) return sema_wakeup_reason_timeout; RL_VERIFY(false); return sema_wakeup_reason_failed; } } virtual bool signal(debug_info_param info) { RL_ASSERT_IMPL(false, test_result_thread_signal, "trying to signal a thread", info); return false; } virtual bool is_signaled(debug_info_param info) { (void)info; return finished_; } virtual void memory_acquire(debug_info_param info) { (void)info; sync_.acquire(ctx().threadx_); } virtual void* prepare_wait(debug_info_param info) { (void)info; return &ws_; } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/foreach.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_FOREACH_HPP #define RL_FOREACH_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { template struct foreach_thread_impl { template RL_INLINE static void exec( T* v1, F func) { (*func)(v1[i]); foreach_thread_impl::exec(v1, func); } RL_INLINE static void exec( T* v1, T* v2, void (*func)(T& e1, T& e2)) { (*func)(v1[i], v2[i]); foreach_thread_impl::exec(v1, v2, func); } RL_INLINE static void exec( T* v1, T* v2, T* v3, void (*func)(T& e1, T& e2, T& e3)) { (*func)(v1[i], v2[i], v3[i]); foreach_thread_impl::exec(v1, v2, v3, func); } }; template struct foreach_thread_impl { template RL_INLINE static void exec( T*, F) { } RL_INLINE static void exec( T*, T*, void (*)(T&, T&)) { } RL_INLINE static void exec( T*, T*, T*, void (*)(T&, T&, T&)) { } }; template RL_INLINE void foreach( T* v1, F func) { foreach_thread_impl::exec(v1, func); } template RL_INLINE void foreach( T* v1, T* v2, void (*func)(T& e1, T& e2)) { foreach_thread_impl::exec(v1, v2, func); } template RL_INLINE void foreach( T* v1, T* v2, T* v3, void (*func)(T& e1, T& e2, T& e3)) { foreach_thread_impl::exec(v1, v2, v3, func); } RL_INLINE void assign_zero(timestamp_t& elem) { elem = 0; } RL_INLINE void assign_zero_u(unsigned& elem) { elem = 0; } template RL_INLINE void assign(timestamp_t& elem) { elem = value; } RL_INLINE void assign(timestamp_t& elem1, timestamp_t& elem2) { elem1 = elem2; } RL_INLINE void assign_max(timestamp_t& elem1, timestamp_t& elem2) { if (elem2 > elem1) elem1 = elem2; } RL_INLINE void plus_one(timestamp_t& elem) { elem += 1; } } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/full_search_scheduler.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_FULL_SEARCH_SCHEDULER_HPP #define RL_FULL_SEARCH_SCHEDULER_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "scheduler.hpp" #include "foreach.hpp" namespace rl { template struct tree_search_scheduler_thread_info : scheduler_thread_info { unsigned yield_sched_count_ [thread_count]; unsigned yield_priority_ [thread_count]; unsigned total_yield_priority_; //unsigned subsequent_timed_waits_; void reset(test_params& params) { scheduler_thread_info::reset(params); foreach(yield_sched_count_, &assign_zero_u); foreach(yield_priority_, &assign_zero_u); total_yield_priority_ = 0; //subsequent_timed_waits_ = 0; } }; template class tree_search_scheduler : public scheduler { public: typedef scheduler base_t; typedef typename base_t::thread_info_t thread_info_t; typedef typename base_t::shared_context_t shared_context_t; struct task_t { }; tree_search_scheduler(test_params& params, shared_context_t& ctx, thread_id_t dynamic_thread_count) : base_t(params, ctx, dynamic_thread_count) , stree_depth_() , iteration_count_mean_() , iteration_count_probe_count_() { stree_.reserve(128); } thread_id_t iteration_begin_impl() { stree_depth_ = 0; unsigned const index = rand_impl(this->running_threads_count, sched_type_sched); thread_id_t const th = this->running_threads[index]; return th; } bool iteration_end_impl() { RL_VERIFY(stree_depth_ == stree_.size()); for (size_t i = stree_.size(); i != 0; --i) { stree_node& n = stree_[i - 1]; if (n.index_ != n.count_ - 1) { stree_.resize(i); n.index_ += 1; RL_VERIFY(n.index_ < n.count_); return false; } } return true; } void yield_priority(unsigned yield) { RL_VERIFY(yield); thread_info_t& t = *this->thread_; thread_id_t const& running_thread_count = this->running_threads_count; for (thread_id_t i = 0; i != thread_count; ++i) { thread_info_t& y = this->threads_[i]; RL_VERIFY(0 == y.yield_priority_[t.index_]); if (t.index_ != i && y.yield_sched_count_[t.index_] < yield && y.state_ != thread_state_finished) { y.yield_priority_[t.index_] = yield; y.total_yield_priority_ += yield; this->block_thread(t.index_, false); } y.yield_sched_count_[t.index_] = 0; } if (0 == running_thread_count) purge_blocked_threads(); } thread_id_t schedule_impl(unpark_reason& reason, unsigned yield) { thread_info_t& t = *this->thread_; thread_id_t const& running_thread_count = this->running_threads_count; #ifdef _DEBUG { unsigned tmp = 0; for (thread_id_t i = 0; i != thread_count; ++i) tmp += t.yield_priority_[i]; RL_VERIFY(t.total_yield_priority_ == tmp); } #endif if (t.total_yield_priority_) { for (thread_id_t i = 0; i != thread_count; ++i) { unsigned& prio = t.yield_priority_[i]; if (prio) { prio -= 1; t.total_yield_priority_ -= 1; if (0 == prio) { this->unblock_thread(i); } } t.yield_sched_count_[i] += 1; } } if (yield) yield_priority(yield); reason = unpark_reason_normal; thread_id_t thread_index = 0; if (self().can_switch(t) || t.state_ != thread_state_running) { thread_id_t timed_thread_count = this->timed_thread_count_; if (timed_thread_count) { thread_id_t cnt; if (running_thread_count) cnt = timed_thread_count + 1; else //!!! spurious thread will be never unblocked in such case - bad cnt = timed_thread_count; thread_id_t idx = this->rand(cnt, sched_type_user); if (idx < timed_thread_count) { thread_info_t* thr = this->timed_threads_[idx]; thread_index = thr->index_; //??? suboptimal state space exploration // if (1 != thr->block_count_) then we are making // superfluous rand() if (1 == thr->block_count_) { this->unpark_thread(thread_index); RL_VERIFY(thr->state_ == thread_state_running); reason = unpark_reason_timeout; } } } RL_VERIFY(running_thread_count); if (unpark_reason_normal == reason) { thread_id_t spurious_thread_count = this->spurious_thread_count_; if (spurious_thread_count) { thread_id_t cnt = spurious_thread_count + 1; thread_id_t idx = this->rand(cnt, sched_type_user); if (idx < spurious_thread_count) { thread_info_t* thr = this->spurious_threads_[idx]; thread_index = thr->index_; //??? suboptimal state space exploration // if (1 != thr->block_count_) then we are making // superfluous rand() if (1 == thr->block_count_) { this->unpark_thread(thread_index); RL_VERIFY(thr->state_ == thread_state_running); reason = unpark_reason_spurious; } } } } if (unpark_reason_normal == reason) { if (1 != running_thread_count) { unsigned const index = this->rand(running_thread_count, sched_type_sched); thread_index = this->running_threads[index]; } else { thread_index = this->running_threads[0]; } } } else { RL_VERIFY(t.state_ == thread_state_running); thread_index = t.index_; } if (t.index_ == thread_index) return thread_index; //t.subsequent_timed_waits_ = 0; self().on_switch(t); return thread_index; } void thread_finished_impl() { } void purge_blocked_threads() { for (thread_id_t i = 0; i != thread_count; ++i) { on_thread_block(i, false); } } unsigned rand_impl(unsigned limit, sched_type t) { unsigned result = 0; size_t const size = stree_.size(); if (stree_depth_ == size) { stree_node n = {limit, 0, t}; stree_.push_back(n); } else { RL_VERIFY(size); stree_node& n = stree_[stree_depth_]; // If you hit assert here, then probably your test is non-deterministic // Check whether you are using functions like ::rand() // or static variables or values of object addresses (for hashing) in your test // Replace ::rand() with rl::rand(), eliminate static variables in the test RL_VERIFY(n.type_ == t); RL_VERIFY(n.count_ == limit); RL_VERIFY(n.index_ < n.count_); result = n.index_; } stree_depth_ += 1; return result; } iteration_t iteration_count_impl() { double current = self().iteration_count_approx(); if (current <= this->iter_) current = this->iter_ + 1.0; iteration_count_mean_ *= iteration_count_probe_count_; iteration_count_probe_count_ += 1; iteration_count_mean_ /= iteration_count_probe_count_; iteration_count_mean_ += current / iteration_count_probe_count_; iteration_t result = (iteration_t)(iteration_count_mean_ + 0.5); if (result <= this->iter_) result = this->iter_ + 1; return result; } void get_state_impl(std::ostream& ss) { ss << (unsigned)stree_.size() << " "; for (size_t i = 0; i != stree_.size(); ++i) { stree_node& n = stree_[i]; ss << n.count_ << " "; ss << n.index_ << " "; ss << static_cast(n.type_) << " "; } } void set_state_impl(std::istream& ss) { size_t size = 0; ss >> size; for (size_t i = 0; i != size; ++i) { stree_node n = {}; ss >> n.count_; ss >> n.index_; unsigned type = 0; ss >> type; n.type_ = static_cast(type); stree_.push_back(n); } } void on_thread_block(thread_id_t th, bool yield) { //!!! doubled in schedule_impl() thread_info_t& t = this->threads_[th]; if (t.total_yield_priority_) { for (thread_id_t i = 0; i != thread_count; ++i) { if (t.yield_priority_[i]) { t.total_yield_priority_ -= t.yield_priority_[i]; t.yield_priority_[i] = 0; this->unblock_thread(i); } } } (void)yield; //if (yield) // yield_priority(1); } protected: struct stree_node { unsigned count_; unsigned index_; sched_type type_; unsigned pad_; }; typedef typename vector::type stree_t; stree_t stree_; size_t stree_depth_; private: double iteration_count_mean_; unsigned iteration_count_probe_count_; derived_t& self() { return *static_cast(this); } RL_NOCOPY(tree_search_scheduler); }; template class full_search_scheduler : public tree_search_scheduler , tree_search_scheduler_thread_info, thread_count> { public: typedef tree_search_scheduler , tree_search_scheduler_thread_info, thread_count> base_t; typedef typename base_t::thread_info_t thread_info_t; typedef typename base_t::shared_context_t shared_context_t; full_search_scheduler(test_params& params, shared_context_t& ctx, thread_id_t dynamic_thread_count) : base_t(params, ctx, dynamic_thread_count) { } bool can_switch(thread_info_t& /*t*/) { return true; } void on_switch(thread_info_t& /*t*/) { } double iteration_count_approx() { double total = 1; size_t const size = this->stree_.size(); for (size_t i = 0; i != size; ++i) { total *= this->stree_[i].count_; } return total; } RL_NOCOPY(full_search_scheduler); }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/history.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_HISTORY_HPP #define RL_HISTORY_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { typedef void (*event_output_f)(std::ostream& s, void const* ev); typedef void (*event_dtor_f)(void* ev); struct history_entry { thread_id_t thread_index_; debug_info info_; void* ev_; event_output_f output_; event_dtor_f dtor_; history_entry(thread_id_t thread_index, debug_info_param info, void* ev, event_output_f output, event_dtor_f dtor) : thread_index_(thread_index) , info_(info) , ev_(ev) , output_(output) , dtor_(dtor) { } }; template void event_output(std::ostream& s, void const* ev) { static_cast(ev)->output(s); } template void event_dtor(void* ev) { delete static_cast(ev); } struct user_event { char const* desc_; void output(std::ostream& s) const { s << desc_; } }; inline string strip_path(char const* filename) { char const* slash = strrchr(filename, '\\'); if (slash) return slash + 1; else return filename; } inline std::ostream& operator << (std::ostream& ss, debug_info_param info) { /* char const* func = info; char const* file = info + strlen(info) + 1; char const* line = file + strlen(file) + 1; */ #ifdef RL_MSVC_OUTPUT ss << info.file_ << "(" << info.line_ << ") : "; #else ss << info.func_ << ", " << strip_path(info.file_) << "(" << info.line_ << ")"; #endif return ss; } class history_mgr : nocopy<> { public: history_mgr(std::ostream& stream, thread_id_t thread_count) : thread_count_(thread_count) , out_stream_(stream) { } ~history_mgr() { clear(); } template void exec_log(thread_id_t th, debug_info_param info, event_t const& ev, bool output_history) { exec_history_.push_back(history_entry(th, info, new event_t(ev), &event_output, &event_dtor)); if (output_history) { output(exec_history_.size() - 1); } } void print_exec_history(bool output_history) { size_t const buf_size = 4096; char buf [buf_size + 1]; size_t const count = exec_history_.size(); if (false == output_history) { sprintf(buf, "execution history (%u):\n", (unsigned)count); out_stream_ << buf; #if defined(_MSC_VER) && defined(RL_MSVC_OUTPUT) OutputDebugStringA(buf); #endif for (size_t i = 0; i != count; ++i) { output(i); } } out_stream_ << "\n"; #if defined(_MSC_VER) && defined(RL_MSVC_OUTPUT) OutputDebugStringA("\n"); #endif for (thread_id_t th = 0; th != thread_count_; ++th) { sprintf(buf, "thread %u:\n", th); out_stream_ << buf; #if defined(_MSC_VER) && defined(RL_MSVC_OUTPUT) OutputDebugStringA(buf); #endif for (size_t i = 0; i != count; ++i) { if (exec_history_[i].thread_index_ == th) { output(i); } } out_stream_ << "\n"; #if defined(_MSC_VER) && defined(RL_MSVC_OUTPUT) OutputDebugStringA("\n"); #endif } } void clear() { for (size_t i = 0; i != exec_history_.size(); ++i) { history_entry const& ent = exec_history_[i]; ent.dtor_(ent.ev_); } exec_history_.clear(); } private: vector::type exec_history_; thread_id_t thread_count_; std::ostream& out_stream_; void output(size_t i) { std::basic_ostringstream, raw_allocator > stream; history_entry const& ent = exec_history_[i]; #ifdef RL_MSVC_OUTPUT { stream << ent.info_ << "[" << i << "] " << ent.thread_index_ << ": "; ent.output_(stream, ent.ev_); stream << std::endl; } #else stream << "[" << (unsigned)i << "] " << ent.thread_index_ << ": "; ent.output_(stream, ent.ev_); stream << ", in " << ent.info_ << std::endl; #endif out_stream_ << stream.str(); #if defined(_MSC_VER) && defined(RL_MSVC_OUTPUT) OutputDebugStringA(stream.str().c_str()); #endif } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/java.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_JAVA_HPP #define RL_JAVA_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { /* Hierarchy For Package java.util.concurrent.locks Class Hierarchy * java.lang.Object o java.util.concurrent.locks.AbstractQueuedSynchronizer (implements java.io.Serializable) o java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject (implements java.util.concurrent.locks.Condition, java.io.Serializable) o java.util.concurrent.locks.LockSupport o java.util.concurrent.locks.ReentrantLock (implements java.util.concurrent.locks.Lock, java.io.Serializable) o java.util.concurrent.locks.ReentrantReadWriteLock (implements java.util.concurrent.locks.ReadWriteLock, java.io.Serializable) o java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock (implements java.util.concurrent.locks.Lock, java.io.Serializable) o java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock (implements java.util.concurrent.locks.Lock, java.io.Serializable) Interface Hierarchy * java.util.concurrent.locks.Condition * java.util.concurrent.locks.Lock * java.util.concurrent.locks.ReadWriteLock */ /* java.util.concurrent.Semaphore Public Constructors public Semaphore(int permits) Creates a Semaphore with the given number of permits and nonfair fairness setting. Parameters permits the initial number of permits available. This value may be negative, in which case releases must occur before any acquires will be granted. public Semaphore(int permits, boolean fair) Creates a Semaphore with the given number of permits and the given fairness setting. Parameters permits the initial number of permits available. This value may be negative, in which case releases must occur before any acquires will be granted. fair true if this semaphore will guarantee first-in first-out granting of permits under contention, else false. Public Methods public void acquire() Acquires a permit from this semaphore, blocking until one is available, or the thread is interrupted. Acquires a permit, if one is available and returns immediately, reducing the number of available permits by one. If no permit is available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens: * Some other thread invokes the release() method for this semaphore and the current thread is next to be assigned a permit; or * Some other thread interrupts the current thread. If the current thread: * has its interrupted status set on entry to this method; or * is interrupted while waiting for a permit, then InterruptedException is thrown and the current thread's interrupted status is cleared. Throws InterruptedException if the current thread is interrupted See Also * interrupt() public void acquire(int permits) Acquires the given number of permits from this semaphore, blocking until all are available, or the thread is interrupted. Acquires the given number of permits, if they are available, and returns immediately, reducing the number of available permits by the given amount. If insufficient permits are available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens: * Some other thread invokes one of the release methods for this semaphore, the current thread is next to be assigned permits and the number of available permits satisfies this request; or * Some other thread interrupts the current thread. If the current thread: * has its interrupted status set on entry to this method; or * is interrupted while waiting for a permit, then InterruptedException is thrown and the current thread's interrupted status is cleared. Any permits that were to be assigned to this thread are instead assigned to the next waiting thread(s), as if they had been made available by a call to release(). Parameters permits the number of permits to acquire Throws InterruptedException if the current thread is interrupted IllegalArgumentException if permits less than zero. See Also * interrupt() public void acquireUninterruptibly(int permits) Acquires the given number of permits from this semaphore, blocking until all are available. Acquires the given number of permits, if they are available, and returns immediately, reducing the number of available permits by the given amount. If insufficient permits are available then the current thread becomes disabled for thread scheduling purposes and lies dormant until some other thread invokes one of the release methods for this semaphore, the current thread is next to be assigned permits and the number of available permits satisfies this request. If the current thread is interrupted while waiting for permits then it will continue to wait and its position in the queue is not affected. When the thread does return from this method its interrupt status will be set. Parameters permits the number of permits to acquire Throws IllegalArgumentException if permits less than zero. public void acquireUninterruptibly() Acquires a permit from this semaphore, blocking until one is available. Acquires a permit, if one is available and returns immediately, reducing the number of available permits by one. If no permit is available then the current thread becomes disabled for thread scheduling purposes and lies dormant until some other thread invokes the release() method for this semaphore and the current thread is next to be assigned a permit. If the current thread is interrupted while waiting for a permit then it will continue to wait, but the time at which the thread is assigned a permit may change compared to the time it would have received the permit had no interruption occurred. When the thread does return from this method its interrupt status will be set. public int availablePermits() Returns the current number of permits available in this semaphore. This method is typically used for debugging and testing purposes. Returns * the number of permits available in this semaphore. public int drainPermits() Acquire and return all permits that are immediately available. Returns * the number of permits public final int getQueueLength() Returns an estimate of the number of threads waiting to acquire. The value is only an estimate because the number of threads may change dynamically while this method traverses internal data structures. This method is designed for use in monitoring of the system state, not for synchronization control. Returns * the estimated number of threads waiting for this lock public final boolean hasQueuedThreads() Queries whether any threads are waiting to acquire. Note that because cancellations may occur at any time, a true return does not guarantee that any other thread will ever acquire. This method is designed primarily for use in monitoring of the system state. Returns * true if there may be other threads waiting to acquire the lock. public boolean isFair() Returns true if this semaphore has fairness set true. Returns * true if this semaphore has fairness set true. public void release(int permits) Releases the given number of permits, returning them to the semaphore. Releases the given number of permits, increasing the number of available permits by that amount. If any threads are blocking trying to acquire permits, then the one that has been waiting the longest is selected and given the permits that were just released. If the number of available permits satisfies that thread's request then that thread is re-enabled for thread scheduling purposes; otherwise the thread continues to wait. If there are still permits available after the first thread's request has been satisfied, then those permits are assigned to the next waiting thread. If it is satisfied then it is re-enabled for thread scheduling purposes. This continues until there are insufficient permits to satisfy the next waiting thread, or there are no more waiting threads. There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire. Correct usage of a semaphore is established by programming convention in the application. Parameters permits the number of permits to release Throws IllegalArgumentException if permits less than zero. public void release() Releases a permit, returning it to the semaphore. Releases a permit, increasing the number of available permits by one. If any threads are blocking trying to acquire a permit, then one is selected and given the permit that was just released. That thread is re-enabled for thread scheduling purposes. There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire(). Correct usage of a semaphore is established by programming convention in the application. public String toString() Returns a string identifying this semaphore, as well as its state. The state, in brackets, includes the String "Permits =" followed by the number of permits. Returns * a string identifying this semaphore, as well as its state public boolean tryAcquire(long timeout, TimeUnit unit) Acquires a permit from this semaphore, if one becomes available within the given waiting time and the current thread has not been interrupted. Acquires a permit, if one is available and returns immediately, with the value true, reducing the number of available permits by one. If no permit is available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens: * Some other thread invokes the release() method for this semaphore and the current thread is next to be assigned a permit; or * Some other thread interrupts the current thread; or * The specified waiting time elapses. If a permit is acquired then the value true is returned. If the current thread: * has its interrupted status set on entry to this method; or * is interrupted while waiting to acquire a permit, then InterruptedException is thrown and the current thread's interrupted status is cleared. If the specified waiting time elapses then the value false is returned. If the time is less than or equal to zero, the method will not wait at all. Parameters timeout the maximum time to wait for a permit unit the time unit of the timeout argument. Returns * true if a permit was acquired and false if the waiting time elapsed before a permit was acquired. Throws InterruptedException if the current thread is interrupted See Also * interrupt() public boolean tryAcquire(int permits, long timeout, TimeUnit unit) Acquires the given number of permits from this semaphore, if all become available within the given waiting time and the current thread has not been interrupted. Acquires the given number of permits, if they are available and returns immediately, with the value true, reducing the number of available permits by the given amount. If insufficient permits are available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens: * Some other thread invokes one of the release methods for this semaphore, the current thread is next to be assigned permits and the number of available permits satisfies this request; or * Some other thread interrupts the current thread; or * The specified waiting time elapses. If the permits are acquired then the value true is returned. If the current thread: * has its interrupted status set on entry to this method; or * is interrupted while waiting to acquire the permits, then InterruptedException is thrown and the current thread's interrupted status is cleared. Any permits that were to be assigned to this thread, are instead assigned to the next waiting thread(s), as if they had been made available by a call to release(). If the specified waiting time elapses then the value false is returned. If the time is less than or equal to zero, the method will not wait at all. Any permits that were to be assigned to this thread, are instead assigned to the next waiting thread(s), as if they had been made available by a call to release(). Parameters permits the number of permits to acquire timeout the maximum time to wait for the permits unit the time unit of the timeout argument. Returns * true if all permits were acquired and false if the waiting time elapsed before all permits were acquired. Throws InterruptedException if the current thread is interrupted IllegalArgumentException if permits less than zero. See Also * interrupt() public boolean tryAcquire(int permits) Acquires the given number of permits from this semaphore, only if all are available at the time of invocation. Acquires the given number of permits, if they are available, and returns immediately, with the value true, reducing the number of available permits by the given amount. If insufficient permits are available then this method will return immediately with the value false and the number of available permits is unchanged. Even when this semaphore has been set to use a fair ordering policy, a call to tryAcquire will immediately acquire a permit if one is available, whether or not other threads are currently waiting. This "barging" behavior can be useful in certain circumstances, even though it breaks fairness. If you want to honor the fairness setting, then use tryAcquire(permits, 0, TimeUnit.SECONDS) which is almost equivalent (it also detects interruption). Parameters permits the number of permits to acquire Returns * true if the permits were acquired and false otherwise. Throws IllegalArgumentException if permits less than zero. public boolean tryAcquire() Acquires a permit from this semaphore, only if one is available at the time of invocation. Acquires a permit, if one is available and returns immediately, with the value true, reducing the number of available permits by one. If no permit is available then this method will return immediately with the value false. Even when this semaphore has been set to use a fair ordering policy, a call to tryAcquire() will immediately acquire a permit if one is available, whether or not other threads are currently waiting. This "barging" behavior can be useful in certain circumstances, even though it breaks fairness. If you want to honor the fairness setting, then use tryAcquire(0, TimeUnit.SECONDS) which is almost equivalent (it also detects interruption). Returns * true if a permit was acquired and false otherwise. Protected Methods protected Collection getQueuedThreads() Returns a collection containing threads that may be waiting to acquire. Because the actual set of threads may change dynamically while constructing this result, the returned collection is only a best-effort estimate. The elements of the returned collection are in no particular order. This method is designed to facilitate construction of subclasses that provide more extensive monitoring facilities. Returns * the collection of threads protected void reducePermits(int reduction) Shrinks the number of available permits by the indicated reduction. This method can be useful in subclasses that use semaphores to track resources that become unavailable. This method differs from acquire in that it does not block waiting for permits to become available. Parameters reduction the number of permits to remove Throws IllegalArgumentException if reduction is negative */ } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/java_atomic.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_JAVA_ATOMIC_HPP #define RL_JAVA_ATOMIC_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "atomic.hpp" namespace rl { template class jatomic; template class jatomic_proxy { public: T get() const { return var_.load(mo_seq_cst, info_); } void set(T value) { var_.store(value, mo_seq_cst, info_); } T addAndGet(T delta) { return getAndAdd(delta) + delta; } bool compareAndSet(T expect, T update) { bool result = var_.compare_exchange(bool_t(), expect, update, mo_seq_cst, info_); return result; } bool weakCompareAndSet(T expect, T update) { bool result = var_.compare_exchange(bool_t(), expect, update, mo_seq_cst, info_); return result; } T decrementAndGet() { return getAndAdd(-1) - 1; } T getAndAdd(T delta) { T result = var_.rmw(rmw_type_t(), delta, mo_seq_cst, info_); return result; } T getAndDecrement() { return getAndAdd(-1); } T getAndIncrement() { return getAndAdd(+1); } T getAndSet(T newValue) { T result = var_.rmw(rmw_type_t(), newValue, mo_seq_cst, info_); return result; } T incrementAndGet() { return getAndAdd(1) + 1; } private: jatomic& var_; debug_info info_; //typedef typename atomic_add_type::type add_type; template friend class jatomic; jatomic_proxy(jatomic& var, debug_info_param info) : var_(var) , info_(info) { } jatomic_proxy& operator = (jatomic_proxy const&); }; template class jatomic : generic_atomic { public: typedef jatomic_proxy proxy_t; friend class jatomic_proxy; jatomic() { } jatomic(T value) { //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_seq_cst, $); } jatomic(jatomic const& r) { T const value = r.load(mo_seq_cst, $); //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_seq_cst, $); } jatomic(proxy_t const& r) { T const value = r.var_.load(mo_seq_cst, r.info_); //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_seq_cst, r.info_); } proxy_t operator () (debug_info_param info) { return proxy_t(*this, info); } }; typedef jatomic AtomicInteger; typedef jatomic AtomicLong; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/java_var.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_JAVA_VAR_HPP #define RL_JAVA_VAR_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "atomic.hpp" namespace rl { template class jvar; template class jvar_proxy { public: typedef typename atomic_add_type::type add_type; template friend class jvar; operator T () const { return load(); } T operator = (T value) { store(value); return value; } T operator = (jvar_proxy const& r) { T const value = r.load(); store(value); return *this; } T operator ++ (int) { T tmp = load(); store(tmp + 1); return tmp; } T operator -- (int) { T tmp = load(); store(tmp - 1); return tmp; } T operator ++ () { T tmp = load(); store(tmp + 1); return tmp + 1; } T operator -- () { T tmp = load(); store(tmp - 1); return tmp - 1; } T operator += (add_type value) { T tmp = load(); store(tmp + value); return tmp + value; } T operator -= (add_type value) { T tmp = load(); store(tmp - value); return tmp - value; } private: jvar& var_; debug_info info_; jvar_proxy(jvar& var, debug_info_param info) : var_(var) , info_(info) { } T load() const { return var_.load(mo_relaxed, info_); } void store(T value) { var_.store(value, mo_relaxed, info_); } }; template class jvar : generic_atomic { public: typedef jvar_proxy proxy_t; friend class jvar_proxy; jvar() { } jvar(T value) { this->store(value, mo_relaxed, $); } jvar(jvar const& r) { T const value = r.load(mo_relaxed, $); this->store(value, mo_relaxed, $); } jvar(proxy_t const& r) { T const value = r.load(); this->store(value, mo_relaxed, r.info_); } proxy_t operator () (debug_info_param info) { return proxy_t(*this, info); } private: jvar& operator = (jvar const&); }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/java_volatile.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_JAVA_VOLATILE_HPP #define RL_JAVA_VOLATILE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "atomic.hpp" namespace rl { template class jvolatile; template class jvolatile_proxy { public: typedef typename atomic_add_type::type add_type; template friend class jvolatile; operator T () const { return load(); } T operator = (T value) { store(value); return value; } T operator = (jvolatile_proxy const& r) { T const value = r.load(); store(value); return *this; } T operator ++ (int) { T tmp = load(); store(tmp + 1); return tmp; } T operator -- (int) { T tmp = load(); store(tmp - 1); return tmp; } T operator ++ () { T tmp = load(); store(tmp + 1); return tmp + 1; } T operator -- () { T tmp = load(); store(tmp - 1); return tmp - 1; } T operator += (add_type value) { T tmp = load(); store(tmp + value); return tmp + value; } T operator -= (add_type value) { T tmp = load(); store(tmp - value); return tmp - value; } private: jvolatile& var_; debug_info info_; jvolatile_proxy(jvolatile& var, debug_info_param info) : var_(var) , info_(info) { } T load() const { return var_.load(mo_seq_cst, info_); } void store(T value) { var_.store(value, mo_seq_cst, info_); } }; template class jvolatile : generic_atomic { public: typedef jvolatile_proxy proxy_t; friend class jvolatile_proxy; jvolatile() { } explicit jvolatile(T value) { //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_seq_cst, $); } jvolatile(jvolatile const& r) { T const value = r.load(mo_seq_cst, $); //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_seq_cst, $); } jvolatile(proxy_t const& r) { T const value = r.var_.load(mo_seq_cst, r.info_); //??? whether here must be mo_relaxed or mo_release? this->store(value, mo_seq_cst, r.info_); } proxy_t operator () (debug_info_param info) { return proxy_t(*this, info); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/memory.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_MEMORY_HPP #define RL_MEMORY_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { class memory_mgr : nocopy<> { public: memory_mgr() { memset(deferred_free_, 0, sizeof(deferred_free_)); memset(deferred_free_size_, 0, sizeof(deferred_free_size_)); deferred_index_ = 0; } ~memory_mgr() { /* while (allocs_.size()) { size_t* p = (size_t*)(allocs_.begin()->first); free(p - 1, false); allocs_.erase(allocs_.begin()); } */ } #ifndef RL_GC void* alloc(size_t size) #else void* alloc(size_t size, void (*dtor)(void*)) #endif { void* pp = 0; for (size_t i = 0; i != alloc_cache_.size(); ++i) { if (alloc_cache_[i].first == size) { if (alloc_cache_[i].second.size()) { pp = alloc_cache_[i].second.top(); alloc_cache_[i].second.pop(); } break; } } if (0 == pp) pp = (::malloc)(size + alignment); if (pp) { RL_VERIFY(alignment >= sizeof(void*)); *(size_t*)pp = size; void* p = (char*)pp + alignment; #ifndef RL_GC allocs_.insert(std::make_pair(p, size)); #else alloc_desc_t desc = {p, size, dtor}; gc_allocs_.push_back(desc); #endif return p; } else { throw std::bad_alloc(); } } bool free(void* pp, bool defer) { if (0 == pp) return true; #ifndef RL_GC map::type::iterator iter = allocs_.find(pp); if (allocs_.end() == iter) return false; allocs_.erase(iter); void* p = (char*)pp - alignment; size_t size = *(size_t*)p; if (defer) { deferred_free_[deferred_index_ % deferred_count] = p; deferred_free_size_[deferred_index_ % deferred_count] = size; deferred_index_ += 1; p = deferred_free_[deferred_index_ % deferred_count]; size = deferred_free_size_[deferred_index_ % deferred_count]; if (p) rl_free_impl(p, size); } else { rl_free_impl(p, size); } return true; #else (void)defer; for (size_t i = 0; i != gc_allocs_.size(); ++i) { alloc_desc_t const& desc = gc_allocs_[i]; if (desc.addr == pp) { void* p = (char*)desc.addr - alignment; rl_free_impl(p, desc.size); gc_allocs_.erase(gc_allocs_.begin() + i); return true; } } return false; #endif } bool iteration_end() { #ifndef RL_GC return allocs_.empty(); #else for (size_t i = 0; i != gc_allocs_.size(); ++i) { alloc_desc_t const& desc = gc_allocs_[i]; if (desc.dtor) desc.dtor(desc.addr); void* p = (char*)desc.addr - alignment; rl_free_impl(p, desc.size); } gc_allocs_.clear(); return true; #endif } #ifndef RL_GC void output_allocs(std::ostream& stream) { stream << "memory allocations:" << std::endl; map::type::iterator iter = allocs_.begin(); map::type::iterator end = allocs_.end(); for (; iter != end; ++iter) { stream << iter->first << " [" << (unsigned)iter->second << "]" << std::endl; } stream << std::endl; } #endif private: typedef stack::type freelist_t; typedef std::pair alloc_entry_t; typedef vector::type alloc_t; static size_t const deferred_count = 64; alloc_t alloc_cache_; size_t deferred_index_; void* deferred_free_ [deferred_count]; size_t deferred_free_size_ [deferred_count]; #ifndef RL_GC map::type allocs_; #else struct alloc_desc_t { void* addr; size_t size; void (*dtor)(void*); }; vector::type gc_allocs_; #endif void rl_free_impl(void* p, size_t size) { bool found = false; for (size_t i = 0; i != alloc_cache_.size(); ++i) { if (alloc_cache_[i].first == size) { found = true; alloc_cache_[i].second.push(p); break; } } if (!found) { alloc_cache_.push_back(std::make_pair(size, freelist_t())); alloc_cache_.back().second.push(p); } } }; struct memory_alloc_event { void* addr_; size_t size_; bool is_array_; void output(std::ostream& s) const { s << "memory allocation: addr=" << std::hex << (void*)((char*)addr_ + (is_array_ ? alignment : 0)) << std::dec << ", size=" << (unsigned)size_; } }; struct memory_free_event { void* addr_; bool is_array_; void output(std::ostream& s) const { s << "memory deallocation: addr=" << std::hex << (void*)((char*)addr_ + (is_array_ ? alignment : 0)) << std::dec; } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/memory_order.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_MEMORY_ORDER_HPP #define RL_MEMORY_ORDER_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { enum memory_order { mo_relaxed, mo_consume, mo_acquire, mo_release, mo_acq_rel, mo_seq_cst, }; inline char const* format(memory_order mo) { switch (mo) { case mo_relaxed: return "relaxed"; case mo_consume: return "consume"; case mo_acquire: return "acquire"; case mo_release: return "release"; case mo_acq_rel: return "acq_rel"; case mo_seq_cst: return "seq_cst"; } RL_VERIFY(!"invalid value of memory order"); throw std::logic_error("invalid value of memory order"); } } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/pch.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_PCH_HPP #define RL_PCH_HPP #ifdef _MSC_VER # pragma once #endif #ifndef _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_WARNINGS 1 #endif #ifdef _FORTIFY_SOURCE # undef _FORTIFY_SOURCE #endif #ifndef _XOPEN_SOURCE # define _XOPEN_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) # define RL_WIN #endif #if defined(RL_WIN) || defined(_CYGWIN) # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0500 # endif # define WIN32_LEAN_AND_MEAN # include # include # ifdef RL_WIN # include # else # include # include # endif #else # include # include # include # include # include #endif #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/platform.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_PLATFORM_HPP #define RL_PLATFORM_HPP #ifdef _MSC_VER # pragma once #endif #include "pch.hpp" #if defined(RL_WIN) || defined(_CYGWIN) typedef void* fiber_t; inline unsigned get_tick_count() { return GetTickCount(); } inline void set_low_thread_prio() { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); } inline void create_main_fiber(fiber_t& fib) { fib = ConvertThreadToFiber(0); if (0 == fib) { unsigned long err = ::GetLastError(); (void)err; throw std::logic_error("you must start simulation inside a thread (not a fiber)"); } } inline void delete_main_fiber(fiber_t& fib) { (void)fib; HMODULE lib = LoadLibraryW(L"kernel32.dll"); if (lib) { void* proc = (void*)GetProcAddress(lib, "ConvertFiberToThread"); if (proc) { typedef BOOL (WINAPI * ConvertFiberToThreadT)(); ConvertFiberToThreadT ConvertFiberToThread = (ConvertFiberToThreadT)proc; ConvertFiberToThread(); } FreeLibrary(lib); } } inline void create_fiber(fiber_t& fib, void(*fiber_proc)(void*), void* ctx) { size_t const stack_size = 64*1024; fib = CreateFiberEx(4*1024, stack_size, 0, (LPFIBER_START_ROUTINE)fiber_proc, ctx); if (fib == 0) throw std::runtime_error("error creating fiber"); } inline void delete_fiber(fiber_t& fib) { DeleteFiber(fib); } inline void switch_to_fiber(fiber_t fib, fiber_t) { SwitchToFiber(fib); } // work-around for some versions of cygwin extern "C" inline int __gxx_personality_v0() { return 0; } #ifdef RL_WIN #else /* inline unsigned get_tick_count() { return GetTickCount(); } typedef void* fiber_t; struct ucontext_t { struct stack_t { void* ss_sp; size_t ss_size; }; stack_t uc_stack; void* uc_link; }; void getcontext(void*) {} void makecontext(void*, void(*)(), int, void*) {} void swapcontext(void*, void*) {} */ #endif #else inline unsigned get_tick_count() { struct tms tms; return ((unsigned)(times (&tms) * (1000 / sysconf(_SC_CLK_TCK)))); } inline void set_low_thread_prio() { } #if 0 typedef ucontext_t fiber_t; inline void create_main_fiber(fiber_t& fib) { ucontext_t f = {}; fib = f; } inline void delete_main_fiber(fiber_t& fib) { (void)fib; } inline void create_fiber(fiber_t& fib, void(*fiber_proc)(void*), void* ctx) { size_t const stack_size = 64*1024; getcontext(&fib); fib.uc_stack.ss_sp = (::malloc)(stack_size); fib.uc_stack.ss_size = stack_size; fib.uc_link = 0; typedef void(*fn_t)(); fn_t fn = (fn_t)fiber_proc; makecontext(&fib, fn, 1, ctx); } inline void delete_fiber(fiber_t& fib) { //(::free)(fib.uc_stack.ss_sp); } inline void switch_to_fiber(fiber_t& fib, fiber_t& prev) { swapcontext(&prev, &fib); } #else struct fiber_t { ucontext_t fib; jmp_buf jmp; }; struct fiber_ctx_t { void(* fnc)(void*); void* ctx; jmp_buf* cur; ucontext_t* prv; }; static void fiber_start_fnc(void* p) { fiber_ctx_t* ctx = (fiber_ctx_t*)p; void (*volatile ufnc)(void*) = ctx->fnc; void* volatile uctx = ctx->ctx; if (_setjmp(*ctx->cur) == 0) { ucontext_t tmp; swapcontext(&tmp, ctx->prv); } ufnc(uctx); } inline void create_main_fiber(fiber_t& fib) { memset(&fib, 0, sizeof(fib)); } inline void delete_main_fiber(fiber_t& fib) { (void)fib; } inline void create_fiber(fiber_t& fib, void(*ufnc)(void*), void* uctx) { size_t const stack_size = 64*1024; getcontext(&fib.fib); fib.fib.uc_stack.ss_sp = (::malloc)(stack_size); fib.fib.uc_stack.ss_size = stack_size; fib.fib.uc_link = 0; ucontext_t tmp; fiber_ctx_t ctx = {ufnc, uctx, &fib.jmp, &tmp}; makecontext(&fib.fib, (void(*)())fiber_start_fnc, 1, &ctx); swapcontext(&tmp, &fib.fib); } inline void delete_fiber(fiber_t& fib) { //(::free)(fib.uc_stack.ss_sp); } inline void switch_to_fiber(fiber_t& fib, fiber_t& prv) { if (_setjmp(prv.jmp) == 0) _longjmp(fib.jmp, 1); } #endif #endif #ifdef _MSC_VER typedef unsigned __int64 uint64_t; # define RL_INLINE __forceinline # define RL_NOINLINE __declspec(noinline) # define RL_STRINGIZE(text) RL_STRINGIZE_A((text)) # define RL_STRINGIZE_I(text) #text # define RL_STRINGIZE_A(arg) RL_STRINGIZE_I arg # define RL_STDCALL __stdcall # define RL_THROW_SPEC(ex) #else # define RL_INLINE inline # define RL_NOINLINE # define RL_STRINGIZE_I(text) #text # define RL_STRINGIZE(text) RL_STRINGIZE_I(text) # define RL_STDCALL # define RL_THROW_SPEC(ex) throw(ex) #endif #if defined (_MSC_VER) && (_MSC_VER >= 1400) # define RL_RESTRICT __restrict #else # define RL_RESTRICT #endif #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/pthread.h ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_PTHREAD_IFACE_HPP #define RL_PTHREAD_IFACE_HPP #ifdef _MSC_VER # pragma once #endif #include "relacy.hpp" #include "stdlib/pthread.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/random.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_RANDOM_HPP #define RL_RANDOM_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { unsigned const primes[16] = {1, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53}; struct random_generator { unsigned k; unsigned c; unsigned x; void seed(iteration_t s) { k = ((unsigned)(s >> 32) & 0xf) + 8; c = primes[((unsigned)(s >> 36) & 0xf)]; x = (unsigned)((s + 1) * 0x95949347 + c); } unsigned rand() { return ((x = x + c + (x << k)) >> 16); } template RL_INLINE T get() { return static_cast(rand() % max); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/random_scheduler.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_RANDOM_SCHEDULER_HPP #define RL_RANDOM_SCHEDULER_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "scheduler.hpp" #include "random.hpp" namespace rl { template class random_scheduler : public scheduler, scheduler_thread_info, thread_count> { public: typedef scheduler, scheduler_thread_info, thread_count> base_t; typedef typename base_t::thread_info_t thread_info_t; typedef typename base_t::shared_context_t shared_context_t; struct task_t { }; random_scheduler(test_params& params, shared_context_t& ctx, thread_id_t dynamic_thread_count) : base_t(params, ctx, dynamic_thread_count) { } thread_id_t iteration_begin_impl() { rand_.seed(this->iter_); unpark_reason reason; return schedule_impl(reason, false); } bool iteration_end_impl() { return this->iter_ == this->params_.iteration_count; } thread_id_t schedule_impl(unpark_reason& reason, unsigned /*yield*/) { thread_id_t const running_thread_count = this->running_threads_count; thread_id_t timed_thread_count = this->timed_thread_count_; if (timed_thread_count) { thread_id_t cnt = running_thread_count ? timed_thread_count * 4 : timed_thread_count; thread_id_t idx = rand_.rand() % cnt; if (idx < timed_thread_count) { thread_info_t* thr = this->timed_threads_[idx]; thread_id_t th = thr->index_; RL_VERIFY(1 == thr->block_count_); this->unpark_thread(th); RL_VERIFY(thr->state_ == thread_state_running); reason = unpark_reason_timeout; return th; } } thread_id_t spurious_thread_count = this->spurious_thread_count_; if (spurious_thread_count && running_thread_count) { thread_id_t cnt = spurious_thread_count * 8; thread_id_t idx = rand_.rand() % cnt; if (idx < spurious_thread_count) { thread_info_t* thr = this->spurious_threads_[idx]; thread_id_t th = thr->index_; RL_VERIFY(1 == thr->block_count_); this->unpark_thread(th); RL_VERIFY(thr->state_ == thread_state_running); reason = unpark_reason_spurious; return th; } } RL_VERIFY(running_thread_count); unsigned index = rand_.rand() % running_thread_count; thread_id_t th = this->running_threads[index]; reason = unpark_reason_normal; return th; } unsigned rand_impl(unsigned limit, sched_type t) { (void)t; unsigned r = rand_.rand() % limit; ///!!! #ifdef RL_MY_TEST if (this->iter_ == 8761115) { char buf [1024]; sprintf(buf, "rand(%u, %u) = %u\n", t, limit, r); OutputDebugStringA(buf); } #endif return r; } iteration_t iteration_count_impl() { return this->params_.iteration_count; } void get_state_impl(std::ostream& /*ss*/) { } void set_state_impl(std::istream& /*ss*/) { } void on_thread_block(thread_id_t /*th*/, bool /*yield*/) { } private: random_generator rand_; RL_NOCOPY(random_scheduler); }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/relacy.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_RELACY_HPP #define RL_RELACY_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context.hpp" #include "context_base_impl.hpp" #include "backoff.hpp" #include "atomic_fence.hpp" #include "atomic.hpp" #include "var.hpp" #include "thread_local.hpp" #include "test_suite.hpp" #include "dyn_thread.hpp" #include "stdlib/mutex.hpp" #include "stdlib/condition_variable.hpp" #include "stdlib/semaphore.hpp" #include "stdlib/event.hpp" #include "stdlib/windows.hpp" #include "stdlib/pthread.hpp" #define VAR_T(x) rl::var #define TLS_T(T) rl::thread_local_var #define VAR(x) x($) #ifndef RL_FORCE_SEQ_CST #define memory_order_relaxed mo_relaxed, $ #define memory_order_consume mo_consume, $ #define memory_order_acquire mo_acquire, $ #define memory_order_release mo_release, $ #define memory_order_acq_rel mo_acq_rel, $ #define memory_order_seq_cst mo_seq_cst, $ #else #define memory_order_relaxed mo_seq_cst, $ #define memory_order_consume mo_seq_cst, $ #define memory_order_acquire mo_seq_cst, $ #define memory_order_release mo_seq_cst, $ #define memory_order_acq_rel mo_seq_cst, $ #define memory_order_seq_cst mo_seq_cst, $ #endif #define new RL_NEW_PROXY #define delete RL_DELETE_PROXY #define malloc(sz) rl::rl_malloc((sz), $) #define calloc(sz, cnt) rl::rl_calloc((sz), (cnt), $) #define realloc(p, sz) rl::rl_realloc((p), (sz), $) #define free(p) rl::rl_free((p), $) #ifdef assert #undef assert #endif #define assert RL_ASSERT #ifdef errno #undef errno #endif #define errno (rl::get_errno()) #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/relacy_cli.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_RELACY_CLI_HPP #define RL_RELACY_CLI_HPP #ifdef _MSC_VER # pragma once #endif #define RL_CLI_MODE #include "relacy.hpp" #include "cli.hpp" #include "cli_interlocked.hpp" #include "cli_volatile.hpp" #include "cli_var.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/relacy_java.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_RELACY_JAVA_HPP #define RL_RELACY_JAVA_HPP #ifdef _MSC_VER # pragma once #endif #define RL_JAVA_MODE #include "relacy.hpp" #include "java.hpp" #include "java_atomic.hpp" #include "java_volatile.hpp" #include "java_var.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/relacy_std.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_RELACY_STD_HPP #define RL_RELACY_STD_HPP #ifdef _MSC_VER # pragma once #endif #include "relacy.hpp" namespace std { using rl::memory_order; using rl::mo_relaxed; using rl::mo_consume; using rl::mo_acquire; using rl::mo_release; using rl::mo_acq_rel; using rl::mo_seq_cst; using rl::atomic; using rl::atomic_thread_fence; using rl::atomic_signal_fence; using rl::atomic_bool; using rl::atomic_address; using rl::atomic_char; using rl::atomic_schar; using rl::atomic_uchar; using rl::atomic_short; using rl::atomic_ushort; using rl::atomic_int; using rl::atomic_uint; using rl::atomic_long; using rl::atomic_ulong; using rl::atomic_llong; using rl::atomic_ullong; // using rl::atomic_char16_t; // using rl::atomic_char32_t; using rl::atomic_wchar_t; // using rl::atomic_int_least8_t; // using rl::atomic_uint_least8_t; // using rl::atomic_int_least16_t; // using rl::atomic_uint_least16_t; // using rl::atomic_int_least32_t; // using rl::atomic_uint_least32_t; // using rl::atomic_int_least64_t; // using rl::atomic_uint_least64_t; // using rl::atomic_int_fast8_t; // using rl::atomic_uint_fast8_t; // using rl::atomic_int_fast16_t; // using rl::atomic_uint_fast16_t; // using rl::atomic_int_fast32_t; // using rl::atomic_uint_fast32_t; // using rl::atomic_int_fast64_t; // using rl::atomic_uint_fast64_t; using rl::atomic_intptr_t; using rl::atomic_uintptr_t; using rl::atomic_size_t; // using rl::atomic_ssize_t; using rl::atomic_ptrdiff_t; // using rl::atomic_intmax_t; // using rl::atomic_uintmax_t; using rl::mutex; using rl::recursive_mutex; using rl::condition_variable; using rl::condition_variable_any; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/rmw.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_RMW_HPP #define RL_RMW_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { enum rmw_type_e { rmw_type_swap, rmw_type_add, rmw_type_sub, rmw_type_and, rmw_type_or, rmw_type_xor, }; inline char const* format(rmw_type_e t) { switch (t) { case rmw_type_swap: return "exchange"; case rmw_type_add: return "fetch_add"; case rmw_type_sub: return "fetch_sub"; case rmw_type_and: return "fetch_and"; case rmw_type_or: return "fetch_or"; case rmw_type_xor: return "fetch_xor"; } RL_VERIFY(!"invalid rmw type"); throw std::logic_error("invalid rmw type"); } template struct rmw_type_t {}; template T perform_rmw(rmw_type_t, T v, Y op) { (void)v; return op; } template T perform_rmw(rmw_type_t, T v, Y op) { return v + op; } template T perform_rmw(rmw_type_t, T v, Y op) { return v - op; } template T perform_rmw(rmw_type_t, T v, Y op) { return v & op; } template T perform_rmw(rmw_type_t, T v, Y op) { return v | op; } template T perform_rmw(rmw_type_t, T v, Y op) { return v ^ op; } } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/scheduler.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_SCHEDULER_HPP #define RL_SCHEDULER_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context_base.hpp" namespace rl { enum thread_state_e { thread_state_running, thread_state_blocked, thread_state_finished, }; enum thread_finish_result { thread_finish_result_normal, thread_finish_result_last, thread_finish_result_deadlock, }; struct scheduler_thread_info { thread_id_t index_; unsigned block_count_; thread_state_e state_; void reset(test_params& /*params*/) { block_count_ = 0; state_ = thread_state_running; } }; template class scheduler : nocopy<> { public: typedef thread_info_type thread_info_t; struct shared_context_t { typedef typename derived_t::task_t task_t; //CRITICAL_SECTION guard_; queue queue_; }; scheduler(test_params& params, shared_context_t& ctx, thread_id_t dynamic_thread_count) : params_(params) , ctx_(ctx) , total_dynamic_threads_(dynamic_thread_count) , iter_() , thread_() { for (thread_id_t i = 0; i != thread_count; ++i) { threads_[i].index_ = i; } } thread_id_t iteration_begin(iteration_t iter) { iter_ = iter; running_threads_count = thread_count; finished_thread_count_ = 0; timed_thread_count_ = 0; spurious_thread_count_ = 0; dynamic_thread_count_ = 0; for (thread_id_t i = 0; i != thread_count; ++i) { running_threads.push_back(i); threads_[i].reset(params_); } for (thread_id_t i = thread_count - total_dynamic_threads_; i != thread_count; ++i) { dynamic_threads_[dynamic_thread_count_++] = &threads_[i]; block_thread(i, false); } thread_id_t const th = self().iteration_begin_impl(); thread_ = &threads_[th]; return th; } bool iteration_end() { bool const finish = self().iteration_end_impl(); thread_ = 0; return finish; } thread_id_t schedule(unpark_reason& reason, unsigned yield) { thread_id_t const th = self().schedule_impl(reason, yield); RL_VERIFY(threads_[th].state_ == thread_state_running); thread_ = &threads_[th]; return th; } RL_INLINE unsigned rand(unsigned limit, sched_type t) { RL_VERIFY(limit); return self().rand_impl(limit, t); } iteration_t iteration_count() { return self().iteration_count_impl(); } bool park_current_thread(bool is_timed, bool allow_spurious_wakeup) { if (is_timed) { timed_threads_[timed_thread_count_++] = thread_; RL_VERIFY(timed_thread_count_ <= thread_count); } if (allow_spurious_wakeup) { spurious_threads_[spurious_thread_count_++] = thread_; RL_VERIFY(spurious_thread_count_ <= thread_count); } block_thread(thread_->index_, true); return is_deadlock() ? false : true; } void unpark_thread(thread_id_t th, bool do_switch = false) { (void)do_switch; unblock_thread(th); thread_info_t& t = threads_[th]; //!!! store flag as to whether thread is spurious blocked in thread object // (to eliminate iteration over all threads) for (thread_id_t i = 0; i != spurious_thread_count_; ++i) { if (spurious_threads_[i] == &t) { for (thread_id_t j = i + 1; j != spurious_thread_count_; ++j) spurious_threads_[j - 1] = spurious_threads_[j]; spurious_thread_count_ -= 1; break; } } //!!! store flag as to whether thread is spurious blocked in thread object for (thread_id_t i = 0; i != timed_thread_count_; ++i) { if (timed_threads_[i] == &t) { for (thread_id_t j = i + 1; j != timed_thread_count_; ++j) timed_threads_[j - 1] = timed_threads_[j]; timed_thread_count_ -= 1; break; } } } thread_finish_result thread_finished() { RL_VERIFY(thread_->state_ == thread_state_running); block_thread(thread_->index_, false); thread_->state_ = thread_state_finished; finished_thread_count_ += 1; self().thread_finished_impl(); retry: if (finished_thread_count_ == thread_count) { return thread_finish_result_last; } else if (is_deadlock()) { if (dynamic_thread_count_) { while (dynamic_thread_count_) { thread_info_t* th = dynamic_threads_[--dynamic_thread_count_]; unblock_thread(th->index_); } goto retry; } return thread_finish_result_deadlock; } else { return thread_finish_result_normal; } } thread_id_t create_thread() { RL_VERIFY(dynamic_thread_count_); thread_info_t* th = dynamic_threads_[--dynamic_thread_count_]; unblock_thread(th->index_); return th->index_; } void get_state(std::ostream& ss) { self().get_state_impl(ss); } void set_state(std::istream& ss) { self().set_state_impl(ss); } protected: test_params& params_; shared_context_t& ctx_; thread_id_t const total_dynamic_threads_; iteration_t iter_; aligned threads_ [thread_count]; thread_info_t* thread_; vector::type running_threads; thread_id_t running_threads_count; thread_id_t finished_thread_count_; //!!! doesn't timed/spurious waits must belong to full scheduler? // hyphotesis: random scheduler can ignore timed/spurious waits // (however must detect deadlock with spurious threads) thread_info_t* timed_threads_ [thread_count]; thread_id_t timed_thread_count_; thread_info_t* spurious_threads_ [thread_count]; thread_id_t spurious_thread_count_; thread_info_t* dynamic_threads_ [thread_count]; thread_id_t dynamic_thread_count_; void block_thread(thread_id_t th, bool yield) { RL_VERIFY(th < thread_count); thread_info_t& t = threads_[th]; RL_VERIFY(t.state_ != thread_state_finished); if (t.block_count_++) return; for (thread_id_t i = 0; i != running_threads_count; ++i) { if (running_threads[i] == th) { running_threads.erase(running_threads.begin() + i); running_threads_count -= 1; t.state_ = thread_state_blocked; self().on_thread_block(th, yield); return; } } RL_VERIFY(false); } bool unblock_thread(thread_id_t th) { RL_VERIFY(th < thread_count); thread_info_t& t = threads_[th]; RL_VERIFY(t.state_ == thread_state_blocked); if (--t.block_count_) return false; running_threads.push_back(th); running_threads_count += 1; t.state_ = thread_state_running; return true; } private: derived_t& self() { return *static_cast(this); } bool is_deadlock() { if ((0 == running_threads_count) && (0 == timed_thread_count_)) { self().purge_blocked_threads(); if ((0 == running_threads_count) && (0 == timed_thread_count_)) return true; } return false; } void thread_finished_impl() { } void purge_blocked_threads() { } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/signature.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_SIGNATURE_HPP #define RL_SIGNATURE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "test_result.hpp" #include "context_base.hpp" namespace rl { template class signature { public: signature() : magic_(magic) { } signature(signature const&) : magic_(magic) { } ~signature() { check(RL_INFO); magic_ = 0; } void check(debug_info_param info) const { if ( ((uintptr_t)this <= (uintptr_t)-1 - 4096) && ((uintptr_t)this >= 4096) && ((uintptr_t)this % sizeof(unsigned) == 0) && (magic == magic_)) { return; } else { fail(info); } } private: unsigned magic_; struct fault_event { void const* addr_; void output(std::ostream& s) const { s << "<" << std::hex << addr_ << std::dec << ">" << " access to freed memory"; } }; RL_NOINLINE void fail(debug_info_param info) const { context& c = ctx(); RL_HIST(fault_event) {this} RL_HIST_END(); rl::ctx().fail_test("access to freed memory", test_result_access_to_freed_memory, info); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/slab_allocator.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_SLAB_ALLOCATOR_HPP #define RL_SLAB_ALLOCATOR_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { template class slab_allocator : nocopy<> { public: slab_allocator() : freelist_() , blocks_() , alloc_count_() { } ~slab_allocator() { char* pos = blocks_; while (pos) { char* const next = *reinterpret_cast(pos); ::free(pos); pos = next; } } type* alloc(void* ctx = 0) { if (freelist_) { type* p = freelist_; freelist_ = *reinterpret_cast(p); alloc_count_ += 1; *(void**)p = ctx; type* pp = reinterpret_cast((reinterpret_cast(p) + 1)); return pp; } else { return alloc_batch(); } } void free(type* p) { type** pos = reinterpret_cast((reinterpret_cast(p) - 1)); pos[0] = freelist_; freelist_ = reinterpret_cast(pos); alloc_count_ -= 1; } bool iteration_end() { #ifndef RL_GC return alloc_count_ == 0; #else freelist_ = 0; size_t elem_size = sizeof(void*) + sizeof(type); elem_size = (elem_size + 15) & ~15; char* pos = blocks_; while (pos) { char* p = pos; p += elem_size; for (size_t i = 0; i != batch_size; ++i) { *reinterpret_cast(p) = freelist_; freelist_ = reinterpret_cast(p); p += elem_size; } pos = *reinterpret_cast(pos); } return true; #endif } void output_allocs(std::ostream& stream) { size_t elem_size = sizeof(void*) + sizeof(type); elem_size = (elem_size + 15) & ~15; set::type allocs; char* pos = blocks_; while (pos) { char* p = pos; p += elem_size; for (size_t i = 0; i != batch_size; ++i) { allocs.insert(p); p += elem_size; } pos = *reinterpret_cast(pos); } set::type avail; type* pos2 = freelist_; while (pos2) { avail.insert(pos2); pos2 = *reinterpret_cast(pos2); } vector::type diff; std::set_difference(allocs.begin(), allocs.end(), avail.begin(), avail.end(), std::back_inserter(diff)); for (size_t i = 0; i != diff.size(); ++i) { stream << *(void**)diff[i] << std::endl; } } private: static size_t const batch_size = 128; type* freelist_; char* blocks_; size_t alloc_count_; RL_NOINLINE type* alloc_batch() { size_t elem_size = sizeof(void*) + sizeof(type); elem_size = (elem_size + 15) & ~15; char* const batch = (char*)(::malloc)(elem_size * (batch_size + 1)); if (0 == batch) throw std::bad_alloc(); *reinterpret_cast(batch) = blocks_; blocks_ = batch; char* p = batch; p += elem_size; for (size_t i = 0; i != batch_size; ++i) { *reinterpret_cast(p) = freelist_; freelist_ = reinterpret_cast(p); p += elem_size; } return alloc(); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/stdlib/condition_variable.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_CONDITION_VARIABLE_HPP #define RL_CONDITION_VARIABLE_HPP #ifdef _MSC_VER # pragma once #endif #include "../base.hpp" #include "../context_base.hpp" #include "../waitset.hpp" #include "../signature.hpp" namespace rl { struct mutex_wrapper { virtual void lock(debug_info_param info) const = 0; virtual void unlock(debug_info_param info) const = 0; virtual ~mutex_wrapper() {} }; template class mutex_wrapper_impl : public mutex_wrapper { public: mutex_wrapper_impl(mutex_t& m) : m_(m) { } private: mutex_t& m_; virtual void lock(debug_info_param info) const { m_.lock(info); } virtual void unlock(debug_info_param info) const { m_.unlock(info); } RL_NOCOPY(mutex_wrapper_impl); }; struct pred_wrapper { virtual bool exec() const = 0; virtual ~pred_wrapper() {} }; template class pred_wrapper_impl : public pred_wrapper { public: pred_wrapper_impl(pred_t p) : p_(p) { } private: mutable pred_t p_; virtual bool exec() const { return p_(); } RL_NOCOPY(pred_wrapper_impl); }; struct condvar_data { virtual void notify_one(debug_info_param info) = 0; virtual void notify_all(debug_info_param info) = 0; virtual sema_wakeup_reason wait(mutex_wrapper const& lock, bool is_timed, debug_info_param info) = 0; virtual bool wait(mutex_wrapper const& lock, pred_wrapper const& pred, bool is_timed, debug_info_param info) = 0; virtual ~condvar_data() {} // just to calm down gcc }; template class condvar_data_impl : public condvar_data { public: condvar_data_impl(bool allow_spurious_wakeups) { spurious_wakeup_limit_ = 0; if (allow_spurious_wakeups && ctx().is_random_sched()) spurious_wakeup_limit_ = 10; } ~condvar_data_impl() { //!!! detect destoy when there are blocked threads } private: waitset ws_; signature<0xc0ffe3ad> sign_; int spurious_wakeup_limit_; struct event_t { enum type_e { type_notify_one, type_notify_all, type_wait_enter, type_wait_exit, type_wait_pred_enter, type_wait_pred_exit, }; condvar_data_impl const* var_addr_; type_e type_; thread_id_t thread_count_; unpark_reason reason_; void output(std::ostream& s) const { s << "<" << std::hex << var_addr_ << std::dec << "> cond_var: "; switch (type_) { case type_notify_one: s << "notify one total_blocked=" << thread_count_ << " unblocked=" << (thread_count_ ? 1 : 0); break; case type_notify_all: s << "notify all unblocked=" << thread_count_; break; case type_wait_enter: s << "wait enter"; break; case type_wait_exit: s << "wait exit"; if (unpark_reason_normal == reason_) s << " due to notified"; else if (unpark_reason_timeout == reason_) s << " due to timeout"; else if (unpark_reason_spurious == reason_) s << " spuriously"; break; case type_wait_pred_enter: s << "wait pred enter"; break; case type_wait_pred_exit: s << "wait pred exit"; break; } } }; virtual void notify_one(debug_info_param info) { context& c = ctx(); //??? do I need this scheduler call? c.sched(); sign_.check(info); RL_HIST(event_t) {this, event_t::type_notify_one, ws_.size()} RL_HIST_END(); ws_.unpark_one(c, info); } virtual void notify_all(debug_info_param info) { context& c = ctx(); //??? do I need this scheduler call? c.sched(); sign_.check(info); RL_HIST(event_t) {this, event_t::type_notify_all, ws_.size()} RL_HIST_END(); ws_.unpark_all(c, info); } virtual sema_wakeup_reason wait(mutex_wrapper const& lock, bool is_timed, debug_info_param info) { //!!! detect whether mutex is the same context& c = ctx(); sign_.check(info); RL_HIST(event_t) {this, event_t::type_wait_enter} RL_HIST_END(); lock.unlock(info); sign_.check(info); bool allow_spurious_wakeup = (spurious_wakeup_limit_ > 0); unpark_reason reason = ws_.park_current(c, is_timed, allow_spurious_wakeup, false, info); if (reason == unpark_reason_spurious) spurious_wakeup_limit_ -= 1; RL_HIST(event_t) {this, event_t::type_wait_exit, 0, reason} RL_HIST_END(); lock.lock(info); sign_.check(info); if (reason == unpark_reason_normal) return sema_wakeup_reason_success; else if (reason == unpark_reason_spurious) return sema_wakeup_reason_spurious; else //if (reason == unpark_reason_timeout) return sema_wakeup_reason_timeout; } virtual bool wait(mutex_wrapper const& lock, pred_wrapper const& pred, bool is_timed, debug_info_param info) { context& c = ctx(); sign_.check(info); RL_HIST(event_t) {this, event_t::type_wait_pred_enter} RL_HIST_END(); while (!pred.exec()) { sema_wakeup_reason reason = wait(lock, is_timed, info); if (reason == sema_wakeup_reason_timeout) { RL_HIST(event_t) {this, event_t::type_wait_pred_exit} RL_HIST_END(); return pred.exec(); } } RL_HIST(event_t) {this, event_t::type_wait_pred_exit} RL_HIST_END(); return true; } }; template class condvar { public: condvar() : impl_() { } condvar(condvar const&) : impl_() { } condvar& operator = (condvar const&) { return *this; } ~condvar() { } void init(bool allow_spurious_wakeups, debug_info_param info) { context& c = ctx(); RL_ASSERT_IMPL(0 == impl_, test_result_double_initialization_of_condvar, "", info); sign_.check(info); impl_ = c.condvar_ctor(allow_spurious_wakeups); } void deinit(debug_info_param info) { context& c = ctx(); check(info); c.condvar_dtor(impl_); impl_ = 0; } void notify_one(debug_info_param info) { check(info); impl_->notify_one(info); } void notify_all(debug_info_param info) { check(info); impl_->notify_all(info); } template sema_wakeup_reason wait(lock_t& lock, bool is_timed, debug_info_param info) { check(info); mutex_wrapper_impl w (lock); return impl_->wait(w, is_timed, info); } template bool wait(mutex_wrapper const& lock, pred_wrapper const& pred, bool is_timed, debug_info_param info) { check(info); return impl_->wait(mutex_wrapper_impl(lock), pred_wrapper_impl(pred), is_timed, info); } private: condvar_data* impl_; signature<0xbadc0ffe> sign_; void check(debug_info_param info) { RL_ASSERT_IMPL(impl_, test_result_usage_of_non_initialized_condvar, "", info); sign_.check(info); } }; template class condition_variable_std : condvar { public: condition_variable_std() { condvar::init(true, $); } ~condition_variable_std() { condvar::deinit($); } void notify_one(debug_info_param info) { condvar::notify_one(info); } void notify_all(debug_info_param info) { condvar::notify_all(info); } template void wait(lock_t& lock, debug_info_param info) { condvar::wait(lock, false, info); } template void wait(lock_t& lock, pred_t pred, debug_info_param info) { condvar::wait(lock, pred, false, info); } template bool wait_until(lock_t& lock, abs_time_t const&, debug_info_param info) { return condvar::wait(lock, true, info); } template bool wait_until(lock_t& lock, abs_time_t const&, pred_t pred, debug_info_param info) { return condvar::wait(lock, pred, true, info); } template bool wait_for(lock_t& lock, rel_time_t const&, debug_info_param info) { sema_wakeup_reason reason = condvar::wait(lock, true, info); return reason == sema_wakeup_reason_success; } template bool wait_for(lock_t& lock, rel_time_t const&, pred_t pred, debug_info_param info) { return condvar::wait(lock, pred, true, info); } RL_NOCOPY(condition_variable_std); }; struct condvar_tag_std; typedef condition_variable_std condition_variable; struct condvar_tag_std_any; typedef condition_variable_std condition_variable_any; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/stdlib/event.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_EVENT_HPP #define RL_EVENT_HPP #ifdef _MSC_VER # pragma once #endif #include "../base.hpp" #include "../context_base.hpp" #include "../sync_var.hpp" #include "../waitset.hpp" #include "semaphore.hpp" namespace rl { struct event_data { virtual void set(debug_info_param info) = 0; virtual void reset(debug_info_param info) = 0; virtual void pulse(debug_info_param info) = 0; virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) = 0; virtual bool is_signaled(debug_info_param info) = 0; virtual void memory_acquire(debug_info_param info) = 0; virtual void* prepare_wait(debug_info_param info) = 0; virtual ~event_data() {} // just to calm down gcc }; template class event_data_impl : public event_data { public: event_data_impl(bool manual_reset, bool initial_state) : manual_reset_(manual_reset) , state_(initial_state) { } ~event_data_impl() { //!!! detect destuction with waiters } private: signature<0xdada1234> sign_; bool const manual_reset_; bool state_; waitset ws_; sync_var sync_; struct state_event { enum type { type_set, type_reset, type_pulse, }; event_data_impl* addr_; type type_; bool initial_state_; bool final_state_; thread_id_t unblocked_; void output(std::ostream& s) const { s << "<" << std::hex << addr_ << std::dec << "> event: "; if (type_set == type_) s << "set "; else if (type_reset == type_) s << "reset "; else s << "pulse "; s << "initial_state=" << initial_state_ << " final_state=" << final_state_; if (type_reset != type_) s << " unblocked=" << unblocked_; } }; virtual void set(debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); bool initial_state = state_; thread_id_t unblocked = 0; if (state_) { //!!! probably can break if a thread waits in wfmo RL_VERIFY(false == ws_); } else { sync_.release(c.threadx_); state_ = true; if (manual_reset_) { unblocked = ws_.unpark_all(c, info); } else { if (ws_.unpark_one(c, info)) unblocked = 1; } } RL_HIST(state_event) {this, state_event::type_set, initial_state, state_, unblocked} RL_HIST_END(); } virtual void reset(debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); bool initial_state = state_; if (state_) { RL_VERIFY(false == ws_); sync_.release(c.threadx_); state_ = false; } RL_HIST(state_event) {this, state_event::type_reset, initial_state, state_, 0} RL_HIST_END(); } virtual void pulse(debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); //??? should I model nasty caveat described in MSDN thread_id_t unblocked = 0; if (state_) { //!!! probably can break if a thread waits in wfmo RL_VERIFY(false == ws_); } else { sync_.release(c.threadx_); state_ = true; unblocked = ws_.unpark_all(c, info); state_ = false; } RL_HIST(state_event) {this, state_event::type_pulse, state_, state_, unblocked} RL_HIST_END(); } struct wait_event { event_data_impl* addr_; bool try_wait_; bool is_timed_; bool initial_state_; bool final_state_; sema_wakeup_reason reason_; void output(std::ostream& s) const { s << "<" << std::hex << addr_ << std::dec << "> event: "; if (try_wait_) s << "try_wait "; else if (is_timed_) s << "timed wait "; else s << "wait "; if (reason_ == sema_wakeup_reason_success) s << "succeeded "; else if (reason_ == sema_wakeup_reason_failed) s << "failed "; else if (reason_ == sema_wakeup_reason_timeout) s << "timed out "; else if (reason_ == sema_wakeup_reason_spurious) s << "spuriously failed "; s << "initial_state=" << initial_state_ << " final_state=" << final_state_; } }; virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); bool initial_state = state_; sema_wakeup_reason reason = sema_wakeup_reason_success; for (;;) { if (state_) { if (manual_reset_) { sync_.acquire(c.threadx_); } else { state_ = false; sync_.acq_rel(c.threadx_); } reason = sema_wakeup_reason_success; break; } if (try_wait) { sync_.acquire(c.threadx_); reason = sema_wakeup_reason_failed; break; } unpark_reason wr = ws_.park_current(c, is_timed, false, true, info); initial_state = state_; if (unpark_reason_timeout == wr) { sync_.acquire(c.threadx_); reason = sema_wakeup_reason_timeout; break; } else if (unpark_reason_normal == wr) { RL_VERIFY(state_ == true); if (manual_reset_) { sync_.acquire(c.threadx_); } else { state_ = false; sync_.acq_rel(c.threadx_); } c.switch_back(info); reason = sema_wakeup_reason_success; break; } RL_VERIFY(false); } RL_HIST(wait_event) {this, try_wait, is_timed, initial_state, state_, reason} RL_HIST_END(); return reason; } virtual bool is_signaled(debug_info_param info) { (void)info; return state_; } virtual void memory_acquire(debug_info_param info) { (void)info; sync_.acquire(ctx().threadx_); } virtual void* prepare_wait(debug_info_param info) { (void)info; return &ws_; } RL_NOCOPY(event_data_impl); }; class generic_event : public win_waitable_object { public: generic_event() : impl_() { } generic_event(generic_event const&) : impl_() { } generic_event& operator = (generic_event const&) { return *this; } void init(bool manual_reset, bool initial_state, debug_info_param info) { context& c = ctx(); RL_ASSERT_IMPL(0 == impl_, test_result_double_initialization_of_event, "", info); sign_.check(info); impl_ = c.event_ctor(manual_reset, initial_state); } void deinit(debug_info_param info) { context& c = ctx(); check(info); c.event_dtor(impl_); impl_ = 0; } void set(debug_info_param info) { check(info); impl_->set(info); } void reset(debug_info_param info) { check(info); impl_->reset(info); } void pulse(debug_info_param info) { check(info); impl_->pulse(info); } virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) { check(info); return impl_->wait(try_wait, is_timed, info); } virtual bool signal(debug_info_param info) { set(info); return true; } private: event_data* impl_; signature<0x3390eeaa> sign_; event_data* check(debug_info_param info) { RL_ASSERT_IMPL(impl_, test_result_usage_of_non_initialized_event, "", info); sign_.check(info); return impl_; } virtual bool is_signaled(debug_info_param info) { return check(info)->is_signaled(info); } virtual void memory_acquire(debug_info_param info) { check(info)->memory_acquire(info); } virtual void* prepare_wait(debug_info_param info) { return check(info)->prepare_wait(info); } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/stdlib/mutex.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_MUTEX_HPP #define RL_MUTEX_HPP #ifdef _MSC_VER # pragma once #endif #include "../base.hpp" #include "../context.hpp" #include "../thread.hpp" #include "../atomic.hpp" #include "../waitset.hpp" #include "../signature.hpp" #include "../sync_var.hpp" #include "../foreach.hpp" #include "semaphore.hpp" namespace rl { struct generic_mutex_data : nocopy<> { virtual bool lock_exclusive(bool is_timed, debug_info_param info) = 0; virtual bool try_lock_exclusive(debug_info_param info) = 0; virtual void unlock_exclusive(debug_info_param info) = 0; virtual void lock_shared(debug_info_param info) = 0; virtual bool try_lock_shared(debug_info_param info) = 0; virtual void unlock_shared(debug_info_param info) = 0; virtual void unlock_exclusive_or_shared(debug_info_param info) = 0; virtual bool is_signaled(debug_info_param info) = 0; virtual void memory_acquire(debug_info_param info) = 0; virtual void* prepare_wait(debug_info_param info) = 0; virtual ~generic_mutex_data() {} // just to calm down gcc }; template class generic_mutex_data_impl : public generic_mutex_data { public: struct event_t { enum type_e { type_lock, type_unlock, type_recursive_lock, type_recursive_unlock, type_failed_try_lock, type_spuriously_failed_try_lock, type_lock_shared, type_unlock_shared, type_recursive_lock_shared, type_recursive_unlock_shared, type_failed_try_lock_shared, type_spuriously_failed_try_lock_shared, type_wait, type_destroying_owned_mutex, }; generic_mutex_data_impl const* var_addr_; type_e type_; void output(std::ostream& s) const { s << "<" << std::hex << var_addr_ << std::dec << "> mutex: "; switch (type_) { case type_lock: s << "exclusive lock"; break; case type_unlock: s << "exclusive unlock"; break; case type_recursive_lock: s << "recursive exclusive lock"; break; case type_recursive_unlock: s << "recursive exclusive unlock"; break; case type_failed_try_lock: s << "failed exclusive try lock"; break; case type_spuriously_failed_try_lock: s << "spuriously failed exclusive try lock"; break; case type_lock_shared: s << "shared lock"; break; case type_unlock_shared: s << "shared unlock"; break; case type_recursive_lock_shared: s << "recursive shared lock"; break; case type_recursive_unlock_shared: s << "recursive shared unlock"; break; case type_failed_try_lock_shared: s << "failed shared try lock"; break; case type_spuriously_failed_try_lock_shared: s << "spuriously failed shared try lock"; break; case type_wait: s << "blocking"; break; case type_destroying_owned_mutex: s << "destroying owned mutex"; break; } } }; generic_mutex_data_impl(bool is_rw, bool is_exclusive_recursive, bool is_shared_recursive, bool failing_try_lock) : is_rw_(is_rw) , is_exclusive_recursive_(is_exclusive_recursive) , is_shared_recursive_(is_shared_recursive) , failing_try_lock_(failing_try_lock) , exclusive_owner_(state_free) , exclusive_recursion_count_(0) , shared_lock_count_(0) , try_lock_failed_() { context& c = ctx(); (void)c; RL_VERIFY(false == c.invariant_executing); foreach(shared_owner_, &assign_zero); } ~generic_mutex_data_impl() { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); if (exclusive_owner_ != state_free || exclusive_waitset_ || shared_waitset_) { debug_info info = $; RL_HIST(event_t) {this, event_t::type_destroying_owned_mutex} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_destroying_owned_mutex, "", $); } } virtual bool lock_exclusive(bool is_timed, debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); RL_VERIFY(false == c.invariant_executing); thread_id_t const my_id = c.threadx_->index_; if (exclusive_owner_ == state_shared && shared_owner_[my_id]) { RL_HIST(event_t) {this, event_t::type_lock} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_mutex_read_to_write_upgrade, "", info); } if (exclusive_owner_ == my_id) { RL_HIST(event_t) {this, event_t::type_recursive_lock} RL_HIST_END(); if (is_exclusive_recursive_) { exclusive_recursion_count_ += 1; return true; } else { RL_ASSERT_IMPL(false, test_result_recursion_on_nonrecursive_mutex, "", info); } } for (;;) { if (exclusive_owner_ == state_free) { RL_VERIFY(exclusive_recursion_count_ == 0); //!!! in some implementation here must be acq_rel sync_.acquire(c.threadx_); exclusive_recursion_count_ = 1; exclusive_owner_ = my_id; RL_HIST(event_t) {this, event_t::type_lock} RL_HIST_END(); return true; } else { RL_VERIFY(my_id != exclusive_owner_); RL_HIST(event_t) {this, event_t::type_wait} RL_HIST_END(); unpark_reason reason = exclusive_waitset_.park_current(c, is_timed, false, false, info); RL_VERIFY(reason != unpark_reason_spurious); if (reason == unpark_reason_timeout) { sync_.acquire(c.threadx_); return false; } } //??? c.sched(); //sign_.check(info); } } virtual bool try_lock_exclusive(debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); RL_VERIFY(false == c.invariant_executing); thread_id_t const my_id = c.threadx_->index_; if (exclusive_owner_ == state_shared && shared_owner_[my_id]) { RL_HIST(event_t) {this, event_t::type_lock} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_mutex_read_to_write_upgrade, "", info); } if (exclusive_owner_ == my_id) { RL_HIST(event_t) {this, event_t::type_recursive_lock} RL_HIST_END(); if (is_exclusive_recursive_) { exclusive_recursion_count_ += 1; return true; } else { RL_ASSERT_IMPL(false, test_result_recursion_on_nonrecursive_mutex, "", info); } } if (exclusive_owner_ == state_free) { RL_VERIFY(exclusive_recursion_count_ == 0); //!!! probability rand if (true == failing_try_lock_ && false == try_lock_failed_ && c.rand(2, sched_type_user)) { try_lock_failed_ = true; RL_HIST(event_t) {this, event_t::type_spuriously_failed_try_lock} RL_HIST_END(); return false; } else { sync_.acquire(c.threadx_); exclusive_recursion_count_ = 1; exclusive_owner_ = my_id; RL_HIST(event_t) {this, event_t::type_lock} RL_HIST_END(); return true; } } else { //!!! in some implementation here must be acquire //sync_.acquire(c.threadx_); RL_VERIFY(my_id != exclusive_owner_); RL_HIST(event_t) {this, event_t::type_failed_try_lock} RL_HIST_END(); return false; } } virtual void unlock_exclusive(debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); RL_VERIFY(false == c.invariant_executing); thread_id_t const my_id = c.threadx_->index_; if (exclusive_owner_ != my_id) { RL_HIST(event_t) {this, event_t::type_unlock} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_unlocking_mutex_wo_ownership, "", info); } exclusive_recursion_count_ -= 1; if (exclusive_recursion_count_) { RL_VERIFY(is_exclusive_recursive_); RL_HIST(event_t) {this, event_t::type_recursive_unlock} RL_HIST_END(); return; } sync_.release(c.threadx_); exclusive_owner_ = state_free; RL_VERIFY(exclusive_recursion_count_ == 0); if (false == exclusive_waitset_.unpark_one(c, info)) shared_waitset_.unpark_all(c, info); RL_HIST(event_t) {this, event_t::type_unlock} RL_HIST_END(); } virtual void lock_shared(debug_info_param info) { RL_VERIFY(is_rw_); context& c = ctx(); c.sched(); sign_.check(info); RL_VERIFY(false == c.invariant_executing); thread_id_t const my_id = c.threadx_->index_; if (exclusive_owner_ == my_id) { RL_HIST(event_t) {this, event_t::type_lock_shared} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_mutex_write_to_read_upgrade, "", info); } if (exclusive_owner_ == state_shared && shared_owner_[my_id]) { RL_HIST(event_t) {this, event_t::type_recursive_lock_shared} RL_HIST_END(); if (is_shared_recursive_) { shared_owner_[my_id] += 1; shared_lock_count_ += 1; return; } else { RL_ASSERT_IMPL(false, test_result_recursion_on_nonrecursive_mutex, "", info); } } for (;;) { if ((exclusive_owner_ == state_free) || (exclusive_owner_ == state_shared && false == exclusive_waitset_)) { sync_.acquire(c.threadx_); shared_owner_[my_id] += 1; shared_lock_count_ += 1; exclusive_owner_ = state_shared; RL_HIST(event_t) {this, event_t::type_lock_shared} RL_HIST_END(); break; } else { RL_VERIFY(my_id != exclusive_owner_); RL_HIST(event_t) {this, event_t::type_wait} RL_HIST_END(); shared_waitset_.park_current(c, false, false, false, info); } //??? c.sched(); //sign_.check(info); } } virtual bool try_lock_shared(debug_info_param info) { RL_VERIFY(is_rw_); context& c = ctx(); c.sched(); sign_.check(info); RL_VERIFY(false == c.invariant_executing); thread_id_t const my_id = c.threadx_->index_; if (exclusive_owner_ == my_id) { RL_HIST(event_t) {this, event_t::type_lock_shared} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_mutex_write_to_read_upgrade, "", info); } if (exclusive_owner_ == state_shared && shared_owner_[my_id]) { RL_HIST(event_t) {this, event_t::type_recursive_lock_shared} RL_HIST_END(); if (is_shared_recursive_) { shared_owner_[my_id] += 1; shared_lock_count_ += 1; return true; } else { RL_ASSERT_IMPL(false, test_result_recursion_on_nonrecursive_mutex, "", info); } } if ((exclusive_owner_ == state_free) || (exclusive_owner_ == state_shared && false == exclusive_waitset_)) { //!!! probability rand if (true == failing_try_lock_ && false == try_lock_failed_ && c.rand(2, sched_type_user)) { try_lock_failed_ = true; RL_HIST(event_t) {this, event_t::type_spuriously_failed_try_lock_shared} RL_HIST_END(); return false; } else { sync_.acquire(c.threadx_); shared_owner_[my_id] += 1; shared_lock_count_ += 1; exclusive_owner_ = state_shared; RL_HIST(event_t) {this, event_t::type_lock_shared} RL_HIST_END(); return true; } } else { RL_VERIFY(my_id != exclusive_owner_); RL_HIST(event_t) {this, event_t::type_failed_try_lock_shared} RL_HIST_END(); return false; } } virtual void unlock_shared(debug_info_param info) { RL_VERIFY(is_rw_); context& c = ctx(); c.sched(); sign_.check(info); RL_VERIFY(false == c.invariant_executing); thread_id_t const my_id = c.threadx_->index_; if (exclusive_owner_ != state_shared || 0 == shared_owner_[my_id]) { RL_HIST(event_t) {this, event_t::type_unlock_shared} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_unlocking_mutex_wo_ownership, "", info); } RL_VERIFY(shared_lock_count_); shared_owner_[my_id] -= 1; shared_lock_count_ -= 1; if (shared_lock_count_ != 0) { if (shared_owner_[my_id]) { RL_VERIFY(is_shared_recursive_); RL_HIST(event_t) {this, event_t::type_recursive_unlock_shared} RL_HIST_END(); } else { sync_.release(c.threadx_); RL_HIST(event_t) {this, event_t::type_unlock_shared} RL_HIST_END(); } return; } sync_.release(c.threadx_); exclusive_owner_ = state_free; exclusive_waitset_.unpark_one(c, info); RL_HIST(event_t) {this, event_t::type_unlock_shared} RL_HIST_END(); } virtual void unlock_exclusive_or_shared(debug_info_param info) { if (exclusive_owner_ == ctx().threadx_->index_) unlock_exclusive(info); else unlock_shared(info); } virtual bool is_signaled(debug_info_param info) { (void)info; return (exclusive_owner_ == state_free); } virtual void memory_acquire(debug_info_param info) { (void)info; sync_.acquire(ctx().threadx_); } virtual void* prepare_wait(debug_info_param info) { (void)info; return &exclusive_waitset_; } private: static thread_id_t const state_shared = (thread_id_t)-1; static thread_id_t const state_free = (thread_id_t)-2; signature<0xbabaf1f1> sign_; bool is_rw_; bool is_exclusive_recursive_; bool is_shared_recursive_; bool failing_try_lock_; sync_var sync_; thread_id_t exclusive_owner_; unsigned exclusive_recursion_count_; waitset exclusive_waitset_; waitset shared_waitset_; timestamp_t shared_owner_ [thread_count]; unsigned shared_lock_count_; bool try_lock_failed_; RL_NOCOPY(generic_mutex_data_impl); }; template class generic_mutex : public win_waitable_object { public: generic_mutex() : impl_() { } generic_mutex(generic_mutex const&) : impl_() { } generic_mutex& operator = (generic_mutex const&) { return *this; } ~generic_mutex() { } void init(bool is_rw, bool is_exclusive_recursive, bool is_shared_recursive, bool failing_try_lock, debug_info_param info) { context& c = ctx(); RL_ASSERT_IMPL(0 == impl_, test_result_double_initialization_of_mutex, "", info); sign_.check(info); impl_ = c.mutex_ctor(is_rw, is_exclusive_recursive, is_shared_recursive, failing_try_lock); } void deinit(debug_info_param info) { context& c = ctx(); check(info); c.mutex_dtor(impl_); impl_ = 0; } void lock(debug_info_param info) { lock_exclusive(info); } bool lock_exclusive_timed(debug_info_param info) { return check(info)->lock_exclusive(true, info); } void unlock(debug_info_param info) { unlock_exclusive(info); } void lock_exclusive(debug_info_param info) { check(info)->lock_exclusive(false, info); } bool try_lock_exclusive(debug_info_param info) { return check(info)->try_lock_exclusive(info); } void unlock_exclusive(debug_info_param info) { check(info)->unlock_exclusive(info); } void lock_shared(debug_info_param info) { check(info)->lock_shared(info); } bool try_lock_shared(debug_info_param info) { return check(info)->try_lock_shared(info); } void unlock_shared(debug_info_param info) { check(info)->unlock_shared(info); } void unlock_exclusive_or_shared(debug_info_param info) { check(info)->unlock_exclusive_or_shared(info); } private: generic_mutex_data* impl_; signature<0x6A6cB03A> sign_; generic_mutex_data* check(debug_info_param info) { RL_ASSERT_IMPL(impl_, test_result_usage_of_non_initialized_mutex, "", info); sign_.check(info); return impl_; } virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) { if (try_wait) { if (check(info)->try_lock_exclusive(info)) return sema_wakeup_reason_success; else return sema_wakeup_reason_failed; } else { if (check(info)->lock_exclusive(is_timed, info)) return sema_wakeup_reason_success; else return sema_wakeup_reason_timeout; } } virtual bool signal(debug_info_param info) { check(info)->unlock_exclusive(info); return true; } virtual bool is_signaled(debug_info_param info) { return check(info)->is_signaled(info); } virtual void memory_acquire(debug_info_param info) { check(info)->memory_acquire(info); } virtual void* prepare_wait(debug_info_param info) { return check(info)->prepare_wait(info); } }; template class std_generic_mutex : generic_mutex, nocopy<> { public: std_generic_mutex() { generic_mutex::init(false, is_recursive, false, true, $); } ~std_generic_mutex() { generic_mutex::deinit($); } void lock(debug_info_param info) { generic_mutex::lock_exclusive(info); } bool try_lock(debug_info_param info) { return generic_mutex::try_lock_exclusive(info); } void unlock(debug_info_param info) { generic_mutex::unlock_exclusive(info); } }; struct mutex_tag_std; typedef std_generic_mutex mutex; struct mutex_tag_std_recursive; typedef std_generic_mutex recursive_mutex; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/stdlib/pthread.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_PTHREAD_HPP #define RL_PTHREAD_HPP #ifdef _MSC_VER # pragma once #endif #include "mutex.hpp" #include "condition_variable.hpp" #include "semaphore.hpp" namespace rl { enum RL_POSIX_ERROR_CODE { RL_SUCCESS, RL_EINVAL, RL_ETIMEDOUT, RL_EBUSY, RL_EINTR, RL_EAGAIN, RL_EWOULDBLOCK, }; inline void rl_sched_yield(debug_info_param info) { yield(1, info); } typedef win_waitable_object* rl_pthread_t; typedef void* rl_pthread_attr_t; inline int rl_pthread_create(rl_pthread_t* th, rl_pthread_attr_t* attr, void* (*func) (void*), void* arg, debug_info_param info) { (void)attr; (void)info;//!!! RL_VERIFY(th && func); th[0] = ctx().create_thread(func, arg); return 0; } inline int rl_pthread_join(rl_pthread_t th, void** res, debug_info_param info) { RL_VERIFY(th && res); res[0] = 0; //!!! th->wait(false, false, info); return 0; } struct sem_tag_pthread; typedef semaphore rl_sem_t; inline int rl_sem_init(rl_sem_t* sema, int /*pshared*/, unsigned int initial_count, debug_info_param info) { RL_VERIFY(initial_count >= 0); sema->init(true, initial_count, INT_MAX, info); return 0; } inline int rl_sem_destroy(rl_sem_t* sema, debug_info_param info) { sema->deinit(info); return 0; } inline int rl_sem_wait(rl_sem_t* sema, debug_info_param info) { sema_wakeup_reason reason = sema->wait(false, false, info); if (reason == sema_wakeup_reason_success) return 0; if (reason == sema_wakeup_reason_spurious) { set_errno(RL_EINTR); return -1; } RL_VERIFY(false); return -1; } inline int rl_sem_trywait(rl_sem_t* sema, debug_info_param info) { sema_wakeup_reason reason = sema->wait(true, false, info); if (sema_wakeup_reason_success == reason) return 0; if (sema_wakeup_reason_failed == reason) { set_errno(RL_EAGAIN); return -1; } if (sema_wakeup_reason_spurious == reason) { set_errno(RL_EINTR); return -1; } RL_VERIFY(false); return -1; } inline int rl_sem_post(rl_sem_t* sema, debug_info_param info) { unsigned prev_cout = 0; bool result = sema->post(1, prev_cout, info); RL_VERIFY(result); (void)result; return 0; } inline int rl_sem_getvalue(rl_sem_t* sema, int* value, debug_info_param info) { RL_VERIFY(value); if (value) value[0] = sema->get_value(info); return 0; } struct mutex_tag_pthread_mtx; typedef generic_mutex rl_pthread_mutex_t; struct rl_pthread_mutexattr_t { bool is_recursive_; }; enum RL_PTHREAD_MUTEX_TYPE { RL_PTHREAD_MUTEX_NORMAL, RL_PTHREAD_MUTEX_ERRORCHECK, RL_PTHREAD_MUTEX_RECURSIVE, RL_PTHREAD_MUTEX_DEFAULT, }; inline int rl_pthread_mutexattr_init(rl_pthread_mutexattr_t* attr, debug_info_param info) { (void)info; if (0 == attr) return RL_EINVAL; attr->is_recursive_ = false; return 0; } inline int rl_pthread_mutexattr_destroy(rl_pthread_mutexattr_t* attr, debug_info_param info) { (void)info; if (0 == attr) return RL_EINVAL; return 0; } inline int rl_pthread_mutexattr_settype(rl_pthread_mutexattr_t* attr, int type, debug_info_param info) { (void)info; if (0 == attr) return RL_EINVAL; if (RL_PTHREAD_MUTEX_RECURSIVE == type) attr->is_recursive_ = true; return 0; } inline int rl_pthread_mutex_init(rl_pthread_mutex_t* m, rl_pthread_mutexattr_t const* attr, debug_info_param info) { bool is_recursive = attr && attr->is_recursive_; m->init(false, is_recursive, false, false, info); return 0; } inline int rl_pthread_mutex_destroy(rl_pthread_mutex_t* m, debug_info_param info) { m->deinit(info); return 0; } inline int rl_pthread_mutex_lock(rl_pthread_mutex_t* m, debug_info_param info) { m->lock_exclusive(info); return 0; } inline int rl_pthread_mutex_timedlock(rl_pthread_mutex_t* m, const void* abs_timeout, debug_info_param info) { (void)abs_timeout; bool rv = m->lock_exclusive_timed(info); return rv ? 0 : RL_ETIMEDOUT; } inline int rl_pthread_mutex_try_lock(rl_pthread_mutex_t* m, debug_info_param info) { return m->try_lock_exclusive(info) ? 0 : 1; } inline int rl_pthread_mutex_unlock(rl_pthread_mutex_t* m, debug_info_param info) { m->unlock_exclusive(info); return 0; } struct mutex_tag_pthread_rwlock; typedef generic_mutex rl_pthread_rwlock_t; inline int rl_pthread_rwlock_init(rl_pthread_rwlock_t* lock, void const* /*attr*/, debug_info_param info) { lock->init(true, false, true, false, info); return 0; } inline int rl_pthread_rwlock_destroy(rl_pthread_rwlock_t* lock, debug_info_param info) { lock->deinit(info); return 0; } inline int rl_pthread_rwlock_rdlock(rl_pthread_rwlock_t* lock, debug_info_param info) { lock->lock_shared(info); return 0; } inline int rl_pthread_rwlock_tryrdlock(rl_pthread_rwlock_t* lock, debug_info_param info) { bool res = lock->try_lock_shared(info); return res ? 0 : RL_EBUSY; } inline int rl_pthread_rwlock_wrlock(rl_pthread_rwlock_t* lock, debug_info_param info) { lock->lock_exclusive(info); return 0; } inline int rl_pthread_rwlock_trywrlock(rl_pthread_rwlock_t* lock, debug_info_param info) { bool res = lock->try_lock_exclusive(info); return res ? 0 : RL_EBUSY; } inline int rl_pthread_rwlock_unlock(rl_pthread_rwlock_t* lock, debug_info_param info) { lock->unlock_exclusive_or_shared(info); return 0; } struct condvar_tag_pthread; typedef condvar rl_pthread_cond_t; typedef int rl_pthread_condattr_t; inline int rl_pthread_cond_init(rl_pthread_cond_t* cv, rl_pthread_condattr_t* /*condattr*/, debug_info_param info) { cv->init(true, info); return 0; } inline int rl_pthread_cond_destroy(rl_pthread_cond_t* cv, debug_info_param info) { cv->deinit(info); return 0; } inline int rl_pthread_cond_broadcast(rl_pthread_cond_t* cv, debug_info_param info) { cv->notify_all(info); return 0; } inline int rl_pthread_cond_signal(rl_pthread_cond_t* cv, debug_info_param info) { cv->notify_one(info); return 0; } inline int rl_pthread_cond_timedwait(rl_pthread_cond_t* cv, rl_pthread_mutex_t* m, void const* /*timespec*/, debug_info_param info) { sema_wakeup_reason res = cv->wait(*m, true, info); if (res == sema_wakeup_reason_success) return 0; else if (res == sema_wakeup_reason_timeout) return RL_ETIMEDOUT; else if (res == sema_wakeup_reason_spurious) return RL_EINTR; else return RL_EINVAL; } inline int rl_pthread_cond_wait(rl_pthread_cond_t* cv, rl_pthread_mutex_t* m, debug_info_param info) { sema_wakeup_reason res = cv->wait(*m, false, info); if (res == sema_wakeup_reason_success) return 0; else if (res == sema_wakeup_reason_spurious) return RL_EINTR; else return RL_EINVAL; } enum RL_FUTEX_OP { RL_FUTEX_WAIT, RL_FUTEX_WAKE, }; inline int rl_int_futex_impl(context& c, atomic* uaddr, int op, int val, struct timespec const* timeout, atomic* uaddr2, int val3, debug_info_param info) { (void)uaddr2; (void)val3; if (op == RL_FUTEX_WAIT) { c.sched(); c.atomic_thread_fence_seq_cst(); int v0; { preemption_disabler pd (c); v0 = uaddr->load(mo_acquire, info); } if (v0 != val) return RL_EWOULDBLOCK; unpark_reason reason = uaddr->wait(c, timeout != 0, true, info); if (reason == unpark_reason_normal) return 0; else if (reason == unpark_reason_timeout) return RL_ETIMEDOUT; else if (reason == unpark_reason_spurious) return RL_EINTR; RL_VERIFY(false); return RL_EINVAL; } else if (op == RL_FUTEX_WAKE) { if (val <= 0) return 0; c.sched(); c.atomic_thread_fence_seq_cst(); return uaddr->wake(c, val, info); } else { return RL_EINVAL; } } struct futex_event { void* addr_; int op_; int val_; bool timeout_; int res_; void output(std::ostream& s) const { s << "<" << std::hex << addr_ << std::dec << "> futex(" << (op_ == RL_FUTEX_WAIT ? "FUTEX_WAIT" : op_ == RL_FUTEX_WAKE ? "FUTEX_WAKE" : "UNSUPPORTED") << ", " << val_ << ", " << timeout_ << ") = "; if (op_ == RL_FUTEX_WAKE) s << res_; else s << (res_ == RL_EWOULDBLOCK ? "EWOULDBLOCK" : res_ == RL_ETIMEDOUT ? "ETIMEDOUT" : res_ == RL_EINTR ? "EINTR" : "UNKNOWN"); } }; inline int rl_futex(atomic* uaddr, int op, int val, struct timespec const* timeout, atomic* uaddr2, int val3, debug_info_param info) { context& c = ctx(); int res = rl_int_futex_impl(c, uaddr, op, val, timeout, uaddr2, val3, info); RL_HIST(futex_event) {uaddr, op, val, timeout != 0, res} RL_HIST_END(); return res; } } #ifdef EINVAL # undef EINVAL #endif #define EINVAL rl::RL_EINVAL #ifdef ETIMEDOUT # undef ETIMEDOUT #endif #define ETIMEDOUT rl::RL_ETIMEDOUT #ifdef EBUSY # undef EBUSY #endif #define EBUSY rl::RL_EBUSY #ifdef EINTR # undef EINTR #endif #define EINTR rl::RL_EINTR #ifdef EAGAIN # undef EAGAIN #endif #define EAGAIN rl::RL_EAGAIN #ifdef EWOULDBLOCK # undef EWOULDBLOCK #endif #define EWOULDBLOCK rl::RL_EWOULDBLOCK #define sched_yield() \ rl::rl_sched_yield($) #define pthread_yield() \ rl::rl_sched_yield($) #define pthread_t rl::rl_pthread_t #define pthread_attr_t rl::rl_pthread_attr_t #define pthread_create(th, attr, func, arg) \ rl::rl_pthread_create(th, attr, func, arg, $) #define pthread_join(th, res) \ rl::rl_pthread_join(th, res, $) #define sem_t rl::rl_sem_t #define sem_init(sema, pshared, initial_count)\ rl::rl_sem_init(sema, pshared, initial_count, $) #define sem_destroy(sema)\ rl::rl_sem_destroy(sema, $) #define sem_wait(sema)\ rl::rl_sem_wait(sema, $) #define sem_trywait(sema)\ rl::rl_sem_trywait(sema, $) #define sem_post(sema)\ rl::rl_sem_post(sema, $) #define sem_getvalue(sema, pvalue)\ rl::rl_sem_getvalue(sema, pvalue, $) #define pthread_mutex_t rl::rl_pthread_mutex_t #define pthread_mutexattr_t rl::rl_pthread_mutexattr_t #ifdef PTHREAD_MUTEX_NORMAL # undef PTHREAD_MUTEX_NORMAL # undef PTHREAD_MUTEX_ERRORCHECK # undef PTHREAD_MUTEX_RECURSIVE # undef PTHREAD_MUTEX_DEFAULT #endif #define PTHREAD_MUTEX_NORMAL rl::RL_PTHREAD_MUTEX_NORMAL #define PTHREAD_MUTEX_ERRORCHECK rl::RL_PTHREAD_MUTEX_ERRORCHECK #define PTHREAD_MUTEX_RECURSIVE rl::RL_PTHREAD_MUTEX_RECURSIVE #define PTHREAD_MUTEX_DEFAULT rl::RL_PTHREAD_MUTEX_DEFAULT #define pthread_mutexattr_init(attr) \ rl::rl_pthread_mutexattr_init(attr, $) #define pthread_mutexattr_destroy(attr) \ rl::rl_pthread_mutexattr_destroy(attr, $) #define pthread_mutexattr_settype(attr, type) \ rl::rl_pthread_mutexattr_settype(attr, type, $) #define pthread_mutex_init(m, attr) \ rl::rl_pthread_mutex_init(m, attr, $) #define pthread_mutex_destroy(m) \ rl::rl_pthread_mutex_destroy(m, $) #define pthread_mutex_lock(m) \ rl::rl_pthread_mutex_lock(m, $) #define pthread_mutex_timedlock(m, abs_timeout) \ rl::rl_pthread_mutex_timedlock(m, abs_timeout, $) #define pthread_mutex_try_lock(m) \ rl::rl_pthread_mutex_try_lock(m, $) #define pthread_mutex_unlock(m) \ rl::rl_pthread_mutex_unlock(m, $) #define pthread_rwlock_t rl::rl_pthread_rwlock_t #define pthread_rwlock_init(lock, attr) \ rl::rl_pthread_rwlock_init(lock, attr, $) #define pthread_rwlock_destroy(lock) \ rl::rl_pthread_rwlock_destroy(lock, $) #define pthread_rwlock_rdlock(lock) \ rl::rl_pthread_rwlock_rdlock(lock, $) #define pthread_rwlock_tryrdlock(lock) \ rl::rl_pthread_rwlock_tryrdlock(lock, $) #define pthread_rwlock_wrlock(lock) \ rl::rl_pthread_rwlock_wrlock(lock, $) #define pthread_rwlock_trywrlock(lock) \ rl::rl_pthread_rwlock_trywrlock(lock, $) #define pthread_rwlock_unlock(lock) \ rl::rl_pthread_rwlock_unlock(lock, $) #define pthread_cond_t rl::rl_pthread_cond_t #define pthread_condattr_t rl::rl_pthread_condattr_t #define pthread_cond_init(cv, condattr) \ rl::rl_pthread_cond_init(cv, condattr, $) #define pthread_cond_destroy(cv) \ rl::rl_pthread_cond_destroy(cv, $) #define pthread_cond_broadcast(cv) \ rl::rl_pthread_cond_broadcast(cv, $) #define pthread_cond_signal(cv) \ rl::rl_pthread_cond_signal(cv, $) #define pthread_cond_timedwait(cv, m, timespec) \ rl::rl_pthread_cond_timedwait(cv, m, timespec, $) #define pthread_cond_wait(cv, m) \ rl::rl_pthread_cond_wait(cv, m, $) #ifdef FUTEX_WAKE # undef FUTEX_WAKE #endif #define FUTEX_WAKE rl::RL_FUTEX_WAKE #ifdef FUTEX_WAIT # undef FUTEX_WAIT #endif #define FUTEX_WAIT rl::RL_FUTEX_WAIT #define futex(uaddr, op, val, timeout, uaddr2, val3) \ rl::rl_futex(uaddr, op, val, timeout, uaddr2, val3, $) #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/stdlib/semaphore.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_SEMAPHORE_HPP #define RL_SEMAPHORE_HPP #ifdef _MSC_VER # pragma once #endif #include "../base.hpp" #include "../context_base.hpp" #include "../sync_var.hpp" #include "../waitset.hpp" #include "../signature.hpp" namespace rl { enum sema_wakeup_reason { sema_wakeup_reason_success, sema_wakeup_reason_failed, sema_wakeup_reason_timeout, sema_wakeup_reason_spurious, }; struct win_object { virtual void deinit(debug_info_param info) = 0; virtual ~win_object() {} }; struct win_waitable_object : win_object { virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) = 0; virtual bool signal(debug_info_param info) = 0; virtual bool is_signaled(debug_info_param info) = 0; virtual void memory_acquire(debug_info_param info) = 0; virtual void* prepare_wait(debug_info_param info) = 0; }; struct sema_data { virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) = 0; virtual bool post(unsigned count, unsigned& prev_count, debug_info_param info) = 0; virtual int get_value(debug_info_param info) = 0; virtual bool is_signaled(debug_info_param info) = 0; virtual void memory_acquire(debug_info_param info) = 0; virtual void* prepare_wait(debug_info_param info) = 0; virtual ~sema_data() {} // just to calm down gcc }; template class sema_data_impl : public sema_data { public: sema_data_impl(bool spurious_wakeups, unsigned initial_count, unsigned max_count) : spurious_wakeups_(spurious_wakeups) , count_(initial_count) , max_count_(max_count) { RL_VERIFY(max_count <= INT_MAX); } ~sema_data_impl() { //!!! detect destruction with waiters } struct wait_event { sema_data_impl* addr_; bool try_wait_; bool is_timed_; unsigned count_; sema_wakeup_reason reason_; void output(std::ostream& s) const { s << "<" << std::hex << addr_ << std::dec << "> semaphore: "; if (try_wait_) s << "try_wait "; else if (is_timed_) s << "timed wait "; else s << "wait "; if (reason_ == sema_wakeup_reason_success) s << "succeeded "; else if (reason_ == sema_wakeup_reason_failed) s << "failed "; else if (reason_ == sema_wakeup_reason_timeout) s << "timed out "; else if (reason_ == sema_wakeup_reason_spurious) s << "spuriously failed "; s << "new_count=" << count_; } }; struct post_event { sema_data_impl* addr_; unsigned value_; unsigned count_; bool result_; thread_id_t unblocked_; void output(std::ostream& s) const { s << "<" << std::hex << addr_ << std::dec << "> semaphore: "; if (result_) s << "post "; else s << "post FAILED "; s << "value=" << value_; s << " new_count=" << count_; s << " unblocked=" << unblocked_; } }; struct get_value_event { sema_data_impl* addr_; unsigned count_; void output(std::ostream& s) const { s << "<" << std::hex << addr_ << std::dec << "> semaphore: "; s << "get_value count=" << count_; } }; virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); sema_wakeup_reason reason = sema_wakeup_reason_success; for (;;) { if (count_) { count_ -= 1; sync_.acq_rel(c.threadx_); reason = sema_wakeup_reason_success; break; } if (try_wait) { sync_.acquire(c.threadx_); reason = sema_wakeup_reason_failed; break; } unpark_reason wr = ws_.park_current(c, is_timed, spurious_wakeups_, true, info); if (unpark_reason_timeout == wr) { RL_VERIFY(is_timed); sync_.acquire(c.threadx_); reason = sema_wakeup_reason_timeout; break; } else if (unpark_reason_spurious == wr) { RL_VERIFY(spurious_wakeups_); sync_.acquire(c.threadx_); reason = sema_wakeup_reason_spurious; break; } else if (unpark_reason_normal == wr) { RL_VERIFY(count_ > 0); count_ -= 1; sync_.acq_rel(c.threadx_); c.switch_back(info); reason = sema_wakeup_reason_success; break; } RL_VERIFY(false); } RL_HIST(wait_event) {this, try_wait, is_timed, count_, reason} RL_HIST_END(); return reason; } virtual bool post(unsigned count, unsigned& prev_count, debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); bool result = false; prev_count = count_; thread_id_t unblocked = 0; if (false == (count >= INT_MAX || count + count_ > max_count_)) { result = true; count_ += count; sync_.acq_rel(c.threadx_); for (unsigned i = 0; i != count; ++i) { if (false == ws_.unpark_one(c, info)) break; unblocked += 1; } } else { sync_.acquire(c.threadx_); } RL_HIST(post_event) {this, count, count_, result, unblocked} RL_HIST_END(); return result; } virtual int get_value(debug_info_param info) { context& c = ctx(); c.sched(); sign_.check(info); RL_VERIFY(count_ <= INT_MAX); int result = (int)count_ - ws_.size(); sync_.acquire(c.threadx_); RL_HIST(get_value_event) {this, (unsigned)result} RL_HIST_END(); return result; } private: signature<0xaabb6634> sign_; bool const spurious_wakeups_; unsigned count_; unsigned const max_count_; waitset ws_; sync_var sync_; virtual bool is_signaled(debug_info_param info) { (void)info; return count_ > 0; } virtual void memory_acquire(debug_info_param info) { (void)info; sync_.acquire(ctx().threadx_); } virtual void* prepare_wait(debug_info_param info) { (void)info; return &ws_; } RL_NOCOPY(sema_data_impl); }; template class semaphore : public win_waitable_object { public: semaphore() : impl_() { } semaphore(semaphore const&) : impl_() { } semaphore& operator = (semaphore const&) { return *this; } void init(bool spurious_wakeups, unsigned initial_count, unsigned max_count, debug_info_param info) { context& c = ctx(); RL_ASSERT_IMPL(0 == impl_, test_result_double_initialization_of_semaphore, "", info); sign_.check(info); impl_ = c.sema_ctor(spurious_wakeups, initial_count, max_count); } void deinit(debug_info_param info) { context& c = ctx(); check(info); c.sema_dtor(impl_); impl_ = 0; } virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) { check(info); return impl_->wait(try_wait, is_timed, info); } virtual bool signal(debug_info_param info) { unsigned prev_count = 0; return post(1, prev_count, info); } bool post(unsigned count, unsigned& prev_count, debug_info_param info) { check(info); return impl_->post(count, prev_count, info); } int get_value(debug_info_param info) { check(info); return impl_->get_value(info); } private: sema_data* impl_; signature<0x228855dd> sign_; sema_data* check(debug_info_param info) { RL_ASSERT_IMPL(impl_, test_result_usage_of_non_initialized_semaphore, "", info); sign_.check(info); return impl_; } virtual bool is_signaled(debug_info_param info) { return check(info)->is_signaled(info); } virtual void memory_acquire(debug_info_param info) { check(info)->memory_acquire(info); } virtual void* prepare_wait(debug_info_param info) { return check(info)->prepare_wait(info); } }; struct wfmo_event { unsigned long count_; bool wait_all_; bool try_wait_; bool is_timed_; sema_wakeup_reason result_; size_t signaled_; void output(std::ostream& s) const { s << "WFMO: " << "count=" << count_ << ", wait_all=" << wait_all_ << ", try_wait=" << try_wait_ << ", is_timed=" << is_timed_ << ", result="; if (sema_wakeup_reason_success == result_) { s << "success"; if (wait_all_ == false) s << ", object=" << signaled_; } else { s << "timeout"; } } }; size_t const wfmo_max_objects = 32; inline sema_wakeup_reason wait_for_multiple_objects( size_t& signaled, size_t count, win_waitable_object** wo, bool wait_all, bool try_wait, bool is_timed, debug_info_param info) { context& c = ctx(); c.sched(); RL_VERIFY(count <= wfmo_max_objects); void* ws [wfmo_max_objects]; sema_wakeup_reason result = sema_wakeup_reason_failed; signaled = 0; if (wait_all) { for (;;) { unsigned long i = 0; for (i = 0; i != count; ++i) { if (false == wo[i]->is_signaled(info)) break; } if (i == count) { preemption_disabler pd (c); for (i = 0; i != count; ++i) { sema_wakeup_reason r = wo[i]->wait(true, false, info); RL_VERIFY(r == sema_wakeup_reason_success); (void)r; } result = sema_wakeup_reason_success; break; } else if (try_wait) { for (i = 0; i != count; ++i) wo[i]->memory_acquire(info); result = sema_wakeup_reason_timeout; break; } else { for (i = 0; i != count; ++i) { ws[i] = wo[i]->prepare_wait(info); } unpark_reason reason = c.wfmo_park(ws, wo, (unsigned)count, !!wait_all, is_timed, info); RL_VERIFY(unpark_reason_spurious != reason); if (unpark_reason_timeout == reason) { for (i = 0; i != count; ++i) wo[i]->memory_acquire(info); result = sema_wakeup_reason_timeout; break; } else if (unpark_reason_normal == reason) { { preemption_disabler pd (c); for (unsigned long i = 0; i != count; ++i) { RL_VERIFY(wo[i]->is_signaled(info)); sema_wakeup_reason r = wo[i]->wait(true, false, info); RL_VERIFY(r == sema_wakeup_reason_success); (void)r; } } c.switch_back(info); result = sema_wakeup_reason_success; break; } RL_VERIFY(false); } } } else { for (;;) { unsigned long i = 0; for (i = 0; i != count; ++i) { if (true == wo[i]->is_signaled(info)) break; } if (i != count) { preemption_disabler pd (c); sema_wakeup_reason r = wo[i]->wait(true, false, info); RL_VERIFY(r == sema_wakeup_reason_success); (void)r; signaled = i; result = sema_wakeup_reason_success; break; } else if (try_wait) { for (i = 0; i != count; ++i) wo[i]->memory_acquire(info); result = sema_wakeup_reason_timeout; break; } else { for (i = 0; i != count; ++i) { ws[i] = wo[i]->prepare_wait(info); } unpark_reason reason = c.wfmo_park(ws, wo, (unsigned)count, !!wait_all, is_timed, info); RL_VERIFY(unpark_reason_spurious != reason); if (unpark_reason_timeout == reason) { for (i = 0; i != count; ++i) wo[i]->memory_acquire(info); result = sema_wakeup_reason_timeout; break; } else if (unpark_reason_normal == reason) { unsigned long i = 0; for (i = 0; i != count; ++i) { if (true == wo[i]->is_signaled(info)) break; } RL_VERIFY(i != count); { preemption_disabler pd (c); sema_wakeup_reason r = wo[i]->wait(true, false, info); RL_VERIFY(r == sema_wakeup_reason_success); (void)r; } c.switch_back(info); signaled = i; result = sema_wakeup_reason_success; break; } RL_VERIFY(false); } } } RL_HIST(wfmo_event) {(unsigned)count, wait_all, try_wait, is_timed, result, signaled} RL_HIST_END(); return result; } } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/stdlib/windows.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2010, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE.TXT in this distribution. */ #ifndef RL_WINDOWS_HPP #define RL_WINDOWS_HPP #ifdef _MSC_VER # pragma once #endif #include "mutex.hpp" #include "condition_variable.hpp" #include "semaphore.hpp" #include "event.hpp" namespace rl { typedef win_object* rl_HANDLE; unsigned long const rl_INFINITE = (unsigned long)-1; unsigned long const rl_WAIT_FAILED = (unsigned long)-1; unsigned long const rl_WAIT_OBJECT_0 = 100; unsigned long const rl_WAIT_TIMEOUT = 1; unsigned long const rl_WAIT_IO_COMPLETION = 2; unsigned long const rl_MAXIMUM_WAIT_OBJECTS = wfmo_max_objects; inline int rl_SwitchToThread(debug_info_param info) { yield(1, info); return 1; } inline void rl_Sleep(unsigned long milliseconds, debug_info_param info) { yield(milliseconds ? milliseconds : 1, info); } inline unsigned long rl_WaitForSingleObjectEx(rl_HANDLE obj, unsigned long timeout, int alertable, debug_info_param info) { (void)alertable; //!!! not yet supported support it! //!!! support WAIT_IO_COMPLETION RL_VERIFY(false == alertable && "Alertable wait is not supported in WaitForSingleObject() yet"); bool try_wait = (timeout == 0); bool is_timed = (timeout != rl_INFINITE); sema_wakeup_reason reason = static_cast(obj)->wait(try_wait, is_timed, info); if (reason == sema_wakeup_reason_success) return rl_WAIT_OBJECT_0; else if (reason == sema_wakeup_reason_timeout) return rl_WAIT_TIMEOUT; else if (reason == sema_wakeup_reason_failed) return rl_WAIT_TIMEOUT; RL_VERIFY(false); return rl_WAIT_FAILED; } inline unsigned long rl_WaitForSingleObject(rl_HANDLE obj, unsigned long timeout, debug_info_param info) { return rl_WaitForSingleObjectEx(obj, timeout, 0, info); } inline unsigned long rl_WaitForMultipleObjectsEx(unsigned long count, rl_HANDLE* objects, int wait_all, unsigned long timeout, int alertable, debug_info_param info) { (void)alertable; //!!! //!!! support WAIT_IO_COMPLETION RL_VERIFY(false == alertable && "Alertable wait is not supported in WaitForMultipleObjects() yet"); bool try_wait = (timeout == 0); bool is_timed = (timeout != rl_INFINITE); win_waitable_object** obj = reinterpret_cast(objects); size_t signaled = 0; sema_wakeup_reason reason = wait_for_multiple_objects(signaled, count, obj, !!wait_all, try_wait, is_timed, info); if (reason == sema_wakeup_reason_success) return rl_WAIT_OBJECT_0 + (int)signaled; else if (reason == sema_wakeup_reason_timeout) return rl_WAIT_TIMEOUT; RL_VERIFY(false); return rl_WAIT_FAILED; } inline unsigned long rl_WaitForMultipleObjects(unsigned long count, rl_HANDLE* objects, int wait_all, unsigned long timeout, debug_info_param info) { return rl_WaitForMultipleObjectsEx(count, objects, wait_all, timeout, 0, info); } inline unsigned long rl_SignalObjectAndWait(rl_HANDLE obj_to_signal, rl_HANDLE obj_to_wait, unsigned long timeout, int alertable, debug_info_param info) { bool result = static_cast(obj_to_signal)->signal(info); if (false == result) return result ? 1 : 0; preemption_disabler pd (ctx()); return rl_WaitForSingleObjectEx(obj_to_wait, timeout, alertable, info); } struct sem_tag_win; inline rl_HANDLE rl_CreateSemaphore(void* /*security*/, long initial_count, long max_count, void const* /*name*/, debug_info_param info) { void* mem = ctx().alloc(sizeof(semaphore), false, info); semaphore* sema = new (mem) semaphore; sema->init(false, initial_count, max_count, info); return sema; } inline int rl_CloseHandle(rl_HANDLE h, debug_info_param info) { h->deinit(info); h->~win_object(); (ctx().free)(h, false, info); //!!! rename free because of the define return 1; } inline int rl_ReleaseSemaphore(rl_HANDLE sema, long count, long* prev_count, debug_info_param info) { unsigned prev = 0; bool result = static_cast*>(sema)->post(count, prev, info); if (prev_count) prev_count[0] = prev; return result ? 1 : 0; } inline rl_HANDLE rl_CreateEvent(void* /*security*/, int manual_reset, int initial_state, void const* /*name*/, debug_info_param info) { void* mem = ctx().alloc(sizeof(generic_event), false, info); generic_event* ev = new (mem) generic_event; ev->init(!!manual_reset, !!initial_state, info); return ev; } inline int rl_SetEvent(rl_HANDLE ev, debug_info_param info) { static_cast(ev)->set(info); return 1; } inline int rl_ResetEvent(rl_HANDLE ev, debug_info_param info) { static_cast(ev)->reset(info); return 1; } inline int rl_PulseEvent(rl_HANDLE ev, debug_info_param info) { static_cast(ev)->pulse(info); return 1; } struct mutex_tag_win_cs; typedef generic_mutex rl_CRITICAL_SECTION; inline void rl_InitializeCriticalSection(rl_CRITICAL_SECTION* m, debug_info_param info) { m->init(false, true, false, false, info); } inline int rl_InitializeCriticalSectionAndSpinCount(rl_CRITICAL_SECTION* m, unsigned long spin_count, debug_info_param info) { (void)spin_count; m->init(false, true, false, false, info); return 1; } inline int rl_InitializeCriticalSectionEx(rl_CRITICAL_SECTION* m, unsigned long spin_count, unsigned long flags, debug_info_param info) { (void)spin_count; (void)flags; m->init(false, true, false, false, info); return 1; } inline void rl_DeleteCriticalSection(rl_CRITICAL_SECTION* m, debug_info_param info) { m->deinit(info); } inline void rl_EnterCriticalSection(rl_CRITICAL_SECTION* m, debug_info_param info) { m->lock_exclusive(info); } inline int rl_TryEnterCriticalSection(rl_CRITICAL_SECTION* m, debug_info_param info) { return m->try_lock_exclusive(info) ? 1 : 0; } inline void rl_LeaveCriticalSection(rl_CRITICAL_SECTION* m, debug_info_param info) { m->unlock_exclusive(info); } struct mutex_tag_win_srwl; typedef generic_mutex rl_SRWLOCK; inline void rl_InitializeSRWLock(rl_SRWLOCK* lock, debug_info_param info) { lock->init(true, false, false, false, info); } inline void rl_AcquireSRWLockExclusive(rl_SRWLOCK* lock, debug_info_param info) { lock->lock_exclusive(info); } inline void rl_AcquireSRWLockShared(rl_SRWLOCK* lock, debug_info_param info) { lock->lock_shared(info); } inline void rl_ReleaseSRWLockExclusive(rl_SRWLOCK* lock, debug_info_param info) { lock->unlock_exclusive(info); } inline void rl_ReleaseSRWLockShared(rl_SRWLOCK* lock, debug_info_param info) { lock->unlock_shared(info); } //!!! inline void rl_DeleteSRWLock(rl_SRWLOCK* lock, debug_info_param info) { lock->deinit(info); } struct mutex_tag_win_mutex; typedef generic_mutex rl_win_mutex; inline rl_HANDLE rl_CreateMutex(void* /*security*/, int initial_owner, void const* /*name*/, debug_info_param info) { void* mem = ctx().alloc(sizeof(rl_win_mutex), false, info); rl_win_mutex* mtx = new (mem) rl_win_mutex (); mtx->init(false, true, false, false, info); if (initial_owner) mtx->lock_exclusive(info); return mtx; } inline int rl_ReleaseMutex(rl_HANDLE mtx, debug_info_param info) { static_cast(mtx)->unlock_exclusive(info); return 1; } struct condvar_tag_win; typedef condvar rl_CONDITION_VARIABLE; unsigned long const rl_CONDITION_VARIABLE_LOCKMODE_SHARED = 1; inline void rl_InitializeConditionVariable(rl_CONDITION_VARIABLE* cv, debug_info_param info) { cv->init(false, info); } inline int rl_SleepConditionVariableCS(rl_CONDITION_VARIABLE* cv, rl_CRITICAL_SECTION* cs, unsigned long ms, debug_info_param info) { cv->wait(*cs, ms != rl_INFINITE, info); return 0; } inline int rl_SleepConditionVariableSRW(rl_CONDITION_VARIABLE* cv, rl_SRWLOCK* lock, unsigned long ms, unsigned long flags, debug_info_param info) { //!!! CONDITION_VARIABLE_LOCKMODE_SHARED (void)flags; cv->wait(*lock, ms != rl_INFINITE, info); return 0; } inline void rl_WakeAllConditionVariable(rl_CONDITION_VARIABLE* cv, debug_info_param info) { cv->notify_all(info); } inline void rl_WakeConditionVariable(rl_CONDITION_VARIABLE* cv, debug_info_param info) { cv->notify_one(info); } inline void rl_DeleteConditionVariable(rl_CONDITION_VARIABLE* cv, debug_info_param info) { cv->deinit(info); } typedef unsigned long (RL_STDCALL *rl_WIN_START_ROUTINE)(void* param); typedef unsigned (RL_STDCALL *rl_MSVCR_THREAD_ROUTINE)(void* param); template struct win32_thread_helper { thread_fn_t fn; void* param; static void* thread(void* p) { win32_thread_helper* self = (win32_thread_helper*)p; void* result = (void*)(uintptr_t)(self->fn(self->param)); delete_impl(self, $); return result; } }; inline rl_HANDLE rl_CreateThread(void* security, unsigned stack_size, rl_WIN_START_ROUTINE fn, void* param, unsigned long creation_flags, unsigned long* thread_id, debug_info_param info) { (void)security; (void)stack_size; (void)creation_flags; (void)thread_id; void* mem = ctx().alloc(sizeof(win32_thread_helper), false, info); win32_thread_helper* arg = new (mem) win32_thread_helper; arg->fn = fn; arg->param = param; win_waitable_object* handle = ctx().create_thread(&win32_thread_helper::thread, arg); return handle; } inline uintptr_t rl_beginthreadex(void *security, unsigned stack_size, rl_MSVCR_THREAD_ROUTINE start_address, void *arglist, unsigned initflag, unsigned* thrdaddr, debug_info_param info) { (void)security; (void)stack_size; (void)initflag; (void)thrdaddr; void* mem = ctx().alloc(sizeof(win32_thread_helper), false, info); win32_thread_helper* arg = new (mem) win32_thread_helper; arg->fn = start_address; arg->param = arglist; win_waitable_object* handle = ctx().create_thread(&win32_thread_helper::thread, arg); return (uintptr_t)handle; } inline unsigned long rl_SetThreadAffinityMask(rl_HANDLE th, unsigned long affinity_mask, debug_info_param info) { (void)(th); (void)(affinity_mask); (void)info; return 0; } inline int rl_SuspendThread(rl_HANDLE th, debug_info_param info) { (void)th; (void)info; return 1; } inline int rl_ResumeThread(rl_HANDLE th, debug_info_param info) { (void)th; (void)info; return 1; } inline unsigned long GetLastError() { return (unsigned long)get_errno(); } inline void SetLastError(unsigned long value) { set_errno((int)value); } inline void rl_FlushProcessWriteBuffers(debug_info_param info) { systemwide_fence(info); } } #ifdef HANDLE # undef HANDLE #endif #define HANDLE rl::rl_HANDLE #ifdef INFINITE # undef INFINITE #endif #define INFINITE rl::rl_INFINITE #ifdef WAIT_FAILED # undef WAIT_FAILED #endif #define WAIT_FAILED rl::rl_WAIT_FAILED #ifdef WAIT_OBJECT_0 # undef WAIT_OBJECT_0 #endif #define WAIT_OBJECT_0 rl::rl_WAIT_OBJECT_0 #ifdef WAIT_TIMEOUT # undef WAIT_TIMEOUT #endif #define WAIT_TIMEOUT rl::rl_WAIT_TIMEOUT #ifdef WAIT_IO_COMPLETION # undef WAIT_IO_COMPLETION #endif #define WAIT_IO_COMPLETION rl::rl_WAIT_IO_COMPLETION #ifdef MAXIMUM_WAIT_OBJECTS # undef MAXIMUM_WAIT_OBJECTS #endif #define MAXIMUM_WAIT_OBJECTS rl::rl_MAXIMUM_WAIT_OBJECTS #define SwitchToThread() \ rl::rl_SwitchToThread($) #define Sleep(milliseconds) \ rl::rl_Sleep(milliseconds, $) #define CloseHandle(obj) \ rl::rl_CloseHandle(obj, $) #define WaitForSingleObject(obj, timeout) \ rl::rl_WaitForSingleObject(obj, timeout, $) #define WaitForMultipleObjects(count, objects, wait_all, timeout) \ rl::rl_WaitForMultipleObjects(count, objects, wait_all, timeout, $) #define WaitForMultipleObjectsEx(count, objects, wait_all, timeout, alertable)] \ rl::rl_WaitForMultipleObjectsEx(count, objects, wait_all, timeout, alertable, $) #define SignalObjectAndWait(obj_to_signal, obj_to_wait, timeout, alertable) \ rl::rl_SignalObjectAndWait(obj_to_signal, obj_to_wait, timeout, alertable, $) #ifdef CreateSemaphore # undef CreateSemaphore #endif #ifdef CreateSemaphore # undef ReleaseSemaphore #endif #define CreateSemaphoreA rl_CreateSemaphore #define CreateSemaphoreW rl_CreateSemaphore #define CreateSemaphore rl_CreateSemaphore #define rl_CreateSemaphore(security, initial_count, max_count, name) \ rl::rl_CreateSemaphore(security, initial_count, max_count, name, $)\ #define ReleaseSemaphore(sema, count, prev_count) \ rl::rl_ReleaseSemaphore(sema, count, prev_count, $) #ifdef CreateEvent # undef CreateEvent #endif #define CreateEventA rl_CreateEvent #define CreateEventW rl_CreateEvent #define CreateEvent rl_CreateEvent #define rl_CreateEvent(security, manual_reset, initial_state, name)\ rl::rl_CreateEvent(security, manual_reset, initial_state, name, $) #define SetEvent(ev)\ rl::rl_SetEvent(ev, $) #define ResetEvent(ev)\ rl::rl_ResetEvent(ev, $) #define PulseEvent(ev)\ rl::rl_PulseEvent(ev, $) #ifdef CreateMutex # undef CreateMutex #endif #define CreateMutexA rl_CreateMutex #define CreateMutexW rl_CreateMutex #define CreateMutex rl_CreateMutex #define rl_CreateMutex(security, initial_owner, name)\ rl::rl_CreateMutex(security, initial_owner, name, $) #define ReleaseMutex(mtx)\ rl::rl_ReleaseMutex(mtx, $) #define CRITICAL_SECTION rl::rl_CRITICAL_SECTION #define InitializeCriticalSection(cs) \ rl::rl_InitializeCriticalSection(cs, $) #define InitializeCriticalSectionAndSpinCount(cs, spin) \ rl::rl_InitializeCriticalSectionAndSpinCount(cs, spin, $) #define InitializeCriticalSectionEx(cs, spin, flags) \ rl::rl_InitializeCriticalSectionEx(cs, spin, flags, $) #define DeleteCriticalSection(cs) \ rl::rl_DeleteCriticalSection(cs, $) #define EnterCriticalSection(cs) \ rl::rl_EnterCriticalSection(cs, $) #define TryEnterCriticalSection(cs) \ rl::rl_TryEnterCriticalSection(cs, $) #define LeaveCriticalSection(cs) \ rl::rl_LeaveCriticalSection(cs, $) #define SRWLOCK rl::rl_SRWLOCK #define InitializeSRWLock(lock) \ rl::rl_InitializeSRWLock(lock, $) #define AcquireSRWLockExclusive(lock) \ rl::rl_AcquireSRWLockExclusive(lock, $) #define AcquireSRWLockShared(lock) \ rl::rl_AcquireSRWLockShared(lock, $) #define ReleaseSRWLockExclusive(lock) \ rl::rl_ReleaseSRWLockExclusive(lock, $) #define ReleaseSRWLockShared(lock) \ rl::rl_ReleaseSRWLockShared(lock, $) //!!! no such function in WIN API #define DeleteSRWLock(lock) \ rl::rl_DeleteSRWLock(lock, $) #define CONDITION_VARIABLE rl::rl_CONDITION_VARIABLE #ifdef CONDITION_VARIABLE_LOCKMODE_SHARED # undef CONDITION_VARIABLE_LOCKMODE_SHARED #endif #define CONDITION_VARIABLE_LOCKMODE_SHARED rl::rl_CONDITION_VARIABLE_LOCKMODE_SHARED #define InitializeConditionVariable(cv) \ rl::rl_InitializeConditionVariable(cv, $) #define SleepConditionVariableCS(cv, cs, ms) \ rl::rl_SleepConditionVariableCS(cv, cs, ms, $) #define SleepConditionVariableSRW(cv, lock, ms, flags) \ rl::rl_SleepConditionVariableSRW(cv, lock, ms, flags, $) #define WakeAllConditionVariable(cv) \ rl::rl_WakeAllConditionVariable(cv, $) #define WakeConditionVariable(cv) \ rl::rl_WakeConditionVariable(cv, $) //!!! no such function in WIN API #define DeleteConditionVariable(cv) \ rl::rl_DeleteConditionVariable(cv, $) #define CreateThread(security, stack_size, fn, param, creation_flags, thread_id) \ rl::rl_CreateThread(security, stack_size, fn, param, creation_flags, thread_id, $) #define _beginthreadex(security, stack_size, start_address, arglist, initflag, thrdaddr) \ rl::rl_beginthreadex(security, stack_size, start_address, arglist, initflag, thrdaddr, $) #define SetThreadAffinityMask(th, affinity_mask) \ rl::rl_SetThreadAffinityMask(th, affinity_mask, $) #define SuspendThread(th) \ rl::rl_SuspendThread(th, $) #define ResumeThread(th) \ rl::rl_ResumeThread(th, $) #define FlushProcessWriteBuffers() \ rl::rl_FlushProcessWriteBuffers($) #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/sync_var.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_SYNC_VAR_HPP #define RL_SYNC_VAR_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "foreach.hpp" namespace rl { template class sync_var : nocopy<> { public: sync_var() { iteration_begin(); } void iteration_begin() { foreach(order_, &assign_zero); } void acquire(thread_info_base* th) { th->own_acq_rel_order_ += 1; foreach(th->acq_rel_order_, order_, &assign_max); } void release(thread_info_base* th) { th->own_acq_rel_order_ += 1; foreach(order_, th->acq_rel_order_, &assign_max); } void acq_rel(thread_info_base* th) { th->own_acq_rel_order_ += 1; timestamp_t* acq_rel_order = th->acq_rel_order_; timestamp_t* order = order_; foreach(acq_rel_order, order, &assign_max); foreach(order, acq_rel_order, &assign_max); } private: timestamp_t order_ [thread_count]; }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/test_params.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_TEST_PARAMS_HPP #define RL_TEST_PARAMS_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "test_result.hpp" namespace rl { enum scheduler_type_e { sched_random, sched_bound, sched_full, sched_count, random_scheduler_type = sched_random, fair_context_bound_scheduler_type = sched_bound, fair_full_search_scheduler_type = sched_full, scheduler_type_count }; inline char const* format(scheduler_type_e t) { switch (t) { case sched_random: return "random scheduler"; case sched_bound: return "context bound scheduler"; case sched_full: return "full search scheduler"; default: break; } RL_VERIFY(false); throw std::logic_error("invalid scheduler type"); } struct test_params { // input params iteration_t iteration_count; std::ostream* output_stream; std::ostream* progress_stream; unsigned progress_output_period; bool collect_history; bool output_history; scheduler_type_e search_type; unsigned context_bound; unsigned execution_depth_limit; string initial_state; // output params test_result_e test_result; iteration_t stop_iteration; string test_name; string final_state; test_params() { iteration_count = 1000; output_stream = &std::cout; progress_stream = &std::cout; progress_output_period = 3; collect_history = false; output_history = false; search_type = random_scheduler_type; context_bound = 1; execution_depth_limit = 2000; test_result = test_result_success; stop_iteration = 0; } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/test_result.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_TEST_RESULT_HPP #define RL_TEST_RESULT_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { enum test_result_e { test_result_success, test_result_until_condition_hit, test_result_inconsistent_test_suite, test_result_user_assert_failed, test_result_user_invariant_failed, test_result_data_race, test_result_access_to_freed_memory, test_result_double_free, test_result_memory_leak, test_result_resource_leak, test_result_unitialized_access, test_result_deadlock, test_result_livelock, // mutex test_result_recursion_on_nonrecursive_mutex, test_result_unlocking_mutex_wo_ownership, test_result_destroying_owned_mutex, test_result_double_initialization_of_mutex, test_result_usage_of_non_initialized_mutex, test_result_mutex_write_to_read_upgrade, test_result_mutex_read_to_write_upgrade, //condvar test_result_double_initialization_of_condvar, test_result_usage_of_non_initialized_condvar, //semaphore test_result_double_initialization_of_semaphore, test_result_usage_of_non_initialized_semaphore, //event test_result_double_initialization_of_event, test_result_usage_of_non_initialized_event, //dynamic thread test_result_thread_signal, }; inline char const* test_result_str(test_result_e r) { switch (r) { case test_result_success: return "SUCCESS"; case test_result_until_condition_hit: return "UNTIL CONDITION HIT"; case test_result_inconsistent_test_suite: return "INCONSISTENT TEST SUITE"; case test_result_user_assert_failed: return "USER ASSERT FAILED"; case test_result_user_invariant_failed: return "USER INVARIANT FAILED"; case test_result_data_race: return "DATA RACE"; case test_result_access_to_freed_memory: return "ACCESS TO FREED MEMORY"; case test_result_double_free: return "DOUBLE FREE"; case test_result_memory_leak: return "MEMORY LEAK"; case test_result_resource_leak: return "RESOURCE LEAK"; case test_result_unitialized_access: return "ACCESS TO UNITIALIZED VARIABLE"; case test_result_deadlock: return "DEADLOCK"; case test_result_livelock: return "LIVELOCK"; // mutex case test_result_recursion_on_nonrecursive_mutex: return "RECURSION ON NON-RECURSIVE MUTEX"; case test_result_unlocking_mutex_wo_ownership: return "UNLOCKING MUTEX W/O OWNERSHIP"; case test_result_destroying_owned_mutex: return "DESTROYING OWNED MUTEX"; case test_result_double_initialization_of_mutex: return "DOUBLE INITIALIZATION OF MUTEX"; case test_result_usage_of_non_initialized_mutex: return "USAGE OF NON INITIALIZED MUTEX"; case test_result_mutex_write_to_read_upgrade: return "ATTEMPT TO UPGRADE EXCLUSIVE MUTEX OWNERSHIP TO SHARED"; case test_result_mutex_read_to_write_upgrade: return "ATTEMPT TO UPGRADE SHARED MUTEX OWNERSHIP TO EXCLUSIVE"; // condvar case test_result_double_initialization_of_condvar: return "DOUBLE INITIALIZATION OF CONDITION VARIABLE"; case test_result_usage_of_non_initialized_condvar: return "USAGE OF NON INITIALIZED CONDITION VARIABLE"; // semaphore case test_result_double_initialization_of_semaphore: return "DOUBLE INITIALIZATION OF SEMAPHORE"; case test_result_usage_of_non_initialized_semaphore: return "USAGE OF NON INITIALIZED SEMAPHORE"; // event case test_result_double_initialization_of_event: return "DOUBLE INITIALIZATION OF EVENT"; case test_result_usage_of_non_initialized_event: return "USAGE OF NON INITIALIZED EVENT"; default: RL_VERIFY(false); return "UNKNOWN ERROR"; } } } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/test_suite.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_TEST_SUITE_HPP #define RL_TEST_SUITE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "test_result.hpp" namespace rl { template< typename derived_t, thread_id_t static_thread_count_param, test_result_e result = test_result_success> struct test_suite : nocopy<> { static thread_id_t const dynamic_thread_count = 0; struct params { static thread_id_t const static_thread_count = static_thread_count_param; static thread_id_t const dynamic_thread_count = derived_t::dynamic_thread_count; static thread_id_t const thread_count = static_thread_count + dynamic_thread_count; static test_result_e const expected_result = result; }; void invariant() {} void before() {} void after() {} }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/thread.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_THREAD_HPP #define RL_THREAD_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context_base.hpp" #include "dyn_thread_ctx.hpp" #include "thread_base.hpp" #include "test_suite.hpp" #include "memory_order.hpp" #include "foreach.hpp" namespace rl { struct atomic_data; struct var_data; template struct atomic_data_impl; template struct var_data_impl; template struct thread_info : thread_info_base { thread_info(thread_id_t index = 0) : thread_info_base(index, acq_rel_order_) { } void iteration_begin() { sync_object_.iteration_begin(); last_yield_ = 0; dynamic_thread_func_ = 0; dynamic_thread_param_ = 0; for (thread_id_t j = 0; j != thread_count; ++j) { acq_rel_order_[j] = 0; } acq_rel_order_[index_] = 1; temp_switch_from_ = -1; saved_disable_preemption_ = -1; } thread_sync_object sync_object_; timestamp_t acq_rel_order_ [thread_count]; timestamp_t acquire_fence_order_ [thread_count]; timestamp_t release_fence_order_ [thread_count]; #ifdef RL_IMPROVED_SEQ_CST_FENCE timestamp_t imp_seq_cst_order_ [thread_count]; #endif virtual void on_start() { RL_VERIFY(temp_switch_from_ == -1); RL_VERIFY(saved_disable_preemption_ == -1); sync_object_.on_start(); } virtual void on_finish() { RL_VERIFY(temp_switch_from_ == -1); RL_VERIFY(saved_disable_preemption_ == -1); sync_object_.on_finish(); } void atomic_thread_fence_acquire() { foreach( acq_rel_order_, acquire_fence_order_, &assign_max); } void atomic_thread_fence_release() { foreach( release_fence_order_, acq_rel_order_, &assign); } void atomic_thread_fence_acq_rel() { atomic_thread_fence_acquire(); atomic_thread_fence_release(); } void atomic_thread_fence_seq_cst(timestamp_t* seq_cst_fence_order) { #ifdef RL_IMPROVED_SEQ_CST_FENCE foreach(acq_rel_order_, imp_seq_cst_order_, assign_max); #endif atomic_thread_fence_acquire(); foreach( acq_rel_order_, seq_cst_fence_order, &assign_max); foreach( seq_cst_fence_order, acq_rel_order_, &assign); atomic_thread_fence_release(); } virtual ~thread_info() {} // just to calm down gcc private: thread_info(thread_info const&); thread_info& operator = (thread_info const&); virtual unsigned atomic_load_relaxed(atomic_data* RL_RESTRICT data) { return atomic_load(data); } virtual unsigned atomic_load_acquire(atomic_data* RL_RESTRICT data) { return atomic_load(data); } virtual unsigned atomic_load_seq_cst(atomic_data* RL_RESTRICT data) { return atomic_load(data); } virtual unsigned atomic_load_relaxed_rmw(atomic_data* RL_RESTRICT data) { return atomic_load(data); } virtual unsigned atomic_load_acquire_rmw(atomic_data* RL_RESTRICT data) { return atomic_load(data); } virtual unsigned atomic_load_seq_cst_rmw(atomic_data* RL_RESTRICT data) { return atomic_load(data); } virtual unsigned atomic_store_relaxed(atomic_data* RL_RESTRICT data) { return atomic_store(data); } virtual unsigned atomic_store_release(atomic_data* RL_RESTRICT data) { return atomic_store(data); } virtual unsigned atomic_store_seq_cst(atomic_data* RL_RESTRICT data) { return atomic_store(data); } virtual unsigned atomic_rmw_relaxed(atomic_data* RL_RESTRICT data, bool& aba) { return atomic_rmw(data, aba); } virtual unsigned atomic_rmw_acquire(atomic_data* RL_RESTRICT data, bool& aba) { return atomic_rmw(data, aba); } virtual unsigned atomic_rmw_release(atomic_data* RL_RESTRICT data, bool& aba) { return atomic_rmw(data, aba); } virtual unsigned atomic_rmw_acq_rel(atomic_data* RL_RESTRICT data, bool& aba) { return atomic_rmw(data, aba); } virtual unsigned atomic_rmw_seq_cst(atomic_data* RL_RESTRICT data, bool& aba) { return atomic_rmw(data, aba); } template unsigned get_load_index(atomic_data_impl& var) { typedef typename atomic_data_impl::history_record history_t; unsigned index = var.current_index_; context& c = ctx(); if (false == val(rmw)) { size_t const limit = c.is_random_sched() ? atomic_history_size - 1: 1; for (size_t i = 0; i != limit; ++i, --index) { history_t const& rec = var.history_[index % atomic_history_size]; if (false == rec.busy_) return (unsigned)-1; // access to unitialized var history_t const& prev = var.history_[(index - 1) % atomic_history_size]; if (prev.busy_ && prev.last_seen_order_[index_] <= last_yield_) break; if (mo_seq_cst == val(mo) && rec.seq_cst_) break; timestamp_t acq_rel_order = acq_rel_order_[rec.thread_id_]; if (acq_rel_order >= rec.acq_rel_timestamp_) break; bool stop = false; for (thread_id_t i = 0; i != thread_count; ++i) { timestamp_t acq_rel_order2 = acq_rel_order_[i]; if (acq_rel_order2 >= rec.last_seen_order_[i]) { stop = true; break; } } if (stop) break; if (0 == c.rand(2, sched_type_atomic_load)) break; } } if (false == var.history_[index % atomic_history_size].busy_) return (unsigned)-1; return index; } template unsigned atomic_load(atomic_data* RL_RESTRICT data) { RL_VERIFY(mo_release != mo || rmw); RL_VERIFY(mo_acq_rel != mo || rmw); atomic_data_impl& var = *static_cast*>(data); typedef typename atomic_data_impl::history_record history_t; unsigned index = get_load_index(var); if ((unsigned)-1 == index) return (unsigned)-1; index %= atomic_history_size; history_t& rec = var.history_[index]; RL_VERIFY(rec.busy_); own_acq_rel_order_ += 1; rec.last_seen_order_[index_] = own_acq_rel_order_; bool const synch = (mo_acquire == mo || mo_acq_rel == mo || mo_seq_cst == mo); timestamp_t* acq_rel_order = (synch ? acq_rel_order_ : acquire_fence_order_); foreach(acq_rel_order, rec.acq_rel_order_, assign_max); return index; } virtual unsigned atomic_init(atomic_data* RL_RESTRICT data) { atomic_data_impl& var = *static_cast*>(data); typedef typename atomic_data_impl::history_record history_t; unsigned const idx = ++var.current_index_ % atomic_history_size; history_t& rec = var.history_[idx]; rec.busy_ = true; rec.thread_id_ = index_; rec.seq_cst_ = false; rec.acq_rel_timestamp_ = 0; foreach(rec.acq_rel_order_, assign_zero); return idx; } template unsigned atomic_store(atomic_data* RL_RESTRICT data) { RL_VERIFY(mo_consume != mo || rmw); RL_VERIFY(mo_acquire != mo || rmw); RL_VERIFY(mo_acq_rel != mo || rmw); atomic_data_impl& var = *static_cast*>(data); typedef typename atomic_data_impl::history_record history_t; unsigned const idx = ++var.current_index_ % atomic_history_size; history_t& rec = var.history_[idx]; rec.busy_ = true; rec.thread_id_ = index_; rec.seq_cst_ = (mo_seq_cst == mo); own_acq_rel_order_ += 1; rec.acq_rel_timestamp_ = own_acq_rel_order_; foreach(rec.last_seen_order_, assign<(timestamp_t)-1>); rec.last_seen_order_[index_] = own_acq_rel_order_; unsigned const prev_idx = (var.current_index_ - 1) % atomic_history_size; history_t& prev = var.history_[prev_idx]; #ifdef RL_IMPROVED_SEQ_CST_FENCE if (val(mo) == mo_release && val(rmw) == false) foreach(imp_seq_cst_order_, prev.acq_rel_order_, assign_max); #endif bool const synch = (mo_release == mo || mo_acq_rel == mo || mo_seq_cst == mo); bool const preserve = prev.busy_ && (rmw || (index_ == prev.thread_id_)); timestamp_t* acq_rel_order = (synch ? acq_rel_order_ : release_fence_order_); if (preserve) { foreach(rec.acq_rel_order_, prev.acq_rel_order_, assign); foreach(rec.acq_rel_order_, acq_rel_order, assign_max); } else { foreach(rec.acq_rel_order_, acq_rel_order, assign); } return idx; } template unsigned atomic_rmw(atomic_data* RL_RESTRICT data, bool& aba) { atomic_data_impl& var = *static_cast*>(data); timestamp_t const last_seen = var.history_[var.current_index_ % atomic_history_size].last_seen_order_[index_]; aba = (last_seen > own_acq_rel_order_); atomic_load(data); unsigned result = atomic_store(data); #ifdef RL_IMPROVED_SEQ_CST_RMW atomic_thread_fence_seq_cst(ctx_->seq_cst_fence_order_); #endif return result; } virtual unpark_reason atomic_wait(atomic_data* RL_RESTRICT data, bool is_timed, bool allow_spurious_wakeup, debug_info_param info) { context& c = ctx(); atomic_data_impl& var = *static_cast*>(data); unpark_reason const res = var.futex_ws_.park_current(c, is_timed, allow_spurious_wakeup, false, info); if (res == unpark_reason_normal) var.futex_sync_.acquire(this); return res; } virtual thread_id_t atomic_wake(atomic_data* RL_RESTRICT data, thread_id_t count, debug_info_param info) { context& c = ctx(); atomic_data_impl& var = *static_cast*>(data); thread_id_t unblocked = 0; for (; count != 0; count -= 1, unblocked += 1) { if (var.futex_ws_.unpark_one(c, info) == false) break; } if (unblocked != 0) var.futex_sync_.release(this); return unblocked; } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/thread_base.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_THREAD_BASE_HPP #define RL_THREAD_BASE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context_base.hpp" //#include "test_suite.hpp" //#include "memory_order.hpp" //#include "foreach.hpp" namespace rl { struct atomic_data; struct var_data; template struct atomic_data_impl; template struct var_data_impl; class thread_info_base { public: virtual void on_start() = 0; virtual void on_finish() = 0; virtual unsigned atomic_init(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_load_relaxed(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_load_acquire(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_load_seq_cst(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_load_relaxed_rmw(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_load_acquire_rmw(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_load_seq_cst_rmw(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_store_relaxed(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_store_release(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_store_seq_cst(atomic_data* RL_RESTRICT data) = 0; virtual unsigned atomic_rmw_relaxed(atomic_data* RL_RESTRICT data, bool& aba) = 0; virtual unsigned atomic_rmw_acquire(atomic_data* RL_RESTRICT data, bool& aba) = 0; virtual unsigned atomic_rmw_release(atomic_data* RL_RESTRICT data, bool& aba) = 0; virtual unsigned atomic_rmw_acq_rel(atomic_data* RL_RESTRICT data, bool& aba) = 0; virtual unsigned atomic_rmw_seq_cst(atomic_data* RL_RESTRICT data, bool& aba) = 0; virtual unpark_reason atomic_wait(atomic_data* RL_RESTRICT data, bool is_timed, bool allow_spurious_wakeup, debug_info_param info) = 0; virtual thread_id_t atomic_wake(atomic_data* RL_RESTRICT data, thread_id_t count, debug_info_param info) = 0; virtual ~thread_info_base() {} // just to calm down gcc fiber_t fiber_; thread_id_t const index_; context* ctx_; timestamp_t* const acq_rel_order_; timestamp_t last_yield_; timestamp_t& own_acq_rel_order_; unpark_reason unpark_reason_; thread_id_t temp_switch_from_; int saved_disable_preemption_; int errno_; void* (*dynamic_thread_func_)(void*); void* dynamic_thread_param_; //unsigned disable_history_; thread_info_base(thread_id_t index, timestamp_t* acq_rel_order) : index_(index) , acq_rel_order_(acq_rel_order) , own_acq_rel_order_(acq_rel_order[index]) { } private: thread_info_base(thread_info_base const&); thread_info_base& operator = (thread_info_base const&); }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/thread_local.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_THREAD_LOCAL_HPP #define RL_THREAD_LOCAL_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "signature.hpp" #include "context.hpp" namespace rl { class generic_thread_local : nocopy<> { public: generic_thread_local() : index_(-1) { } ~generic_thread_local() { } void init(void (*dtor)(intptr_t), debug_info_param info) { sign_.check(info); //RL_ASSERT(index_ == -1); index_ = ctx().thread_local_alloc(dtor); } void deinit(debug_info_param info) { sign_.check(info); RL_ASSERT(index_ != -1); ctx().thread_local_free(index_); index_ = -1; } void set(intptr_t value, debug_info_param info) { sign_.check(info); ctx().thread_local_set(index_, value); } intptr_t get(debug_info_param info) { sign_.check(info); return ctx().thread_local_get(index_); } private: signature<0xf1724ae2> sign_; int index_; }; template class thread_local_var; template class thread_local_proxy { public: thread_local_proxy(thread_local_var& var, debug_info_param info) : var_(var) , info_(info) {} operator T () const { return var_.get(info_); } T operator -> () const { return var_.get(info_); } thread_local_proxy operator = (T value) { var_.set(value, info_); return *this; } private: thread_local_var& var_; debug_info info_; thread_local_proxy& operator = (thread_local_proxy const&); }; template class thread_local_var : generic_thread_local { public: thread_local_var() : ctx_seq_() { } ~thread_local_var() { } thread_local_proxy operator () (debug_info_param info) { return thread_local_proxy(*this, info); } void set(T value, debug_info_param info) { if (ctx_seq_ != ctx().get_ctx_seq()) { ctx_seq_ = ctx().get_ctx_seq(); generic_thread_local::init(0, info); } generic_thread_local::set((intptr_t)value, info); } T get(debug_info_param info) { if (ctx_seq_ != ctx().get_ctx_seq()) { ctx_seq_ = ctx().get_ctx_seq(); generic_thread_local::init(0, info); } return (T)generic_thread_local::get(info); } private: unsigned ctx_seq_; }; inline unsigned long rl_TlsAlloc(debug_info_param info) { #ifndef RL_GC //!!! may break on x64 platform // TLS index is exactly DWORD (not DWORD_PTR), so one has to use indirection return (unsigned long)new (info) thread_local_var (); #else void* p = ctx().alloc(sizeof(thread_local_var), false, info); new (p) thread_local_var (); return (unsigned long)p; #endif } inline void rl_TlsFree(unsigned long slot, debug_info_param info) { #ifndef RL_GC delete_impl((thread_local_var*)slot, info); #else thread_local_var* t = (thread_local_var*)slot; t->~thread_local_var(); ctx().free(t, false, info); #endif } inline void* rl_TlsGetValue(unsigned long slot, debug_info_param info) { return ((thread_local_var*)slot)->get(info); } inline int rl_TlsSetValue(unsigned long slot, void* value, debug_info_param info) { ((thread_local_var*)slot)->set(value, info); return 1; } #define TlsAlloc() rl::rl_TlsAlloc($) #define TlsFree(slot) rl::rl_TlsFree((slot), $) #define TlsGetValue(slot) rl::rl_TlsGetValue((slot), $) #define TlsSetValue(slot, value) rl::rl_TlsSetValue((slot), (value), $) } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/thread_local_ctx.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_THREAD_LOCAL_CTX_HPP #define RL_THREAD_LOCAL_CTX_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "test_params.hpp" namespace rl { struct thread_local_context_iface { virtual int thread_local_alloc (void (*dtor)(intptr_t)) = 0; virtual void thread_local_free (int index) = 0; virtual void thread_local_set (int index, intptr_t value) = 0; virtual intptr_t thread_local_get (int index) = 0; virtual ~thread_local_context_iface () {} // to calm down g++ }; template class thread_local_contxt_impl : protected base_t { public: thread_local_contxt_impl(thread_id_t thread_count_param, test_params& params) : base_t(thread_count_param, params) { } void iteration_begin() { base_t::iteration_begin(); for (size_t ent = 0; ent != entries_.size(); ent += 1) { for (size_t th = 0; th != thread_count; th += 1) { entries_[ent].value_[th] = 0; } } } private: struct entry { bool alive_; intptr_t value_ [thread_count]; void (*dtor_) (intptr_t); }; typename vector::type entries_; using base_t::current_thread; virtual int thread_local_alloc (void (*dtor)(intptr_t)) { int index = (int)entries_.size(); entries_.resize(index + 1); entry& ent = entries_[index]; ent.alive_ = true; ent.dtor_ = dtor; for (size_t i = 0; i != thread_count; ++i) { ent.value_[i] = 0; } return index; } virtual void thread_local_free (int index) { RL_VERIFY(index >= 0 && (size_t)index < entries_.size()); entry& ent = entries_[index]; RL_VERIFY(ent.alive_); ent.alive_ = false; if (ent.dtor_) { for (size_t i = 0; i != thread_count; ++i) { if (ent.value_[i]) { ent.dtor_(ent.value_[i]); } } } } virtual void thread_local_set (int index, intptr_t value) { RL_VERIFY(index >= 0 && (size_t)index < entries_.size()); entry& ent = entries_[index]; RL_VERIFY(ent.alive_); ent.value_[current_thread()] = value; } virtual intptr_t thread_local_get (int index) { RL_VERIFY(index >= 0 && (size_t)index < entries_.size()); entry& ent = entries_[index]; RL_VERIFY(ent.alive_); return ent.value_[current_thread()]; } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/var.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_VAR_HPP #define RL_VAR_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "context.hpp" #include "signature.hpp" #include "atomic_events.hpp" namespace rl { template class var; template class var_proxy_const { public: var_proxy_const(var const& v, debug_info_param info) : var_(const_cast&>(v)) , info_(info) { } T load() const { return var_.load(info_); } operator T () const { return this->load(); } T const operator -> () const { return this->load(); } protected: var& var_; debug_info info_; private: var_proxy_const& operator = (var_proxy_const const&); }; template class var_proxy : public var_proxy_const { public: typedef typename atomic_add_type::type add_type; var_proxy(var& v, debug_info_param info) : var_proxy_const(v, info) { } void store(T value) { this->var_.store(value, this->info_); } template T operator = (var_proxy_const const& v) { Y y = v.load(); T t = y; store(t); return t; } T operator = (var_proxy const& v) { T t = v.load(); store(t); return t; } T operator = (T value) { store(value); return value; } T operator -> () { return this->load(); } T operator ++ (int) { T v = this->load(); T y = ++v; this->store(y); return v; } T operator -- (int) { T v = this->load(); T y = --v; this->store(y); return v; } T operator ++ () { T v = this->load(); this->store(++v); return v; } T operator -- () { T v = this->load(); this->store(--v); return v; } T operator += (add_type value) { T v = this->load(); v += value; this->store(v); return v; } T operator -= (add_type value) { T v = this->load(); v -= value; this->store(v); return v; } T operator &= (T value) { T v = this->load(); v &= value; this->store(v); return v; } T operator |= (T value) { T v = this->load(); v |= value; this->store(v); return v; } T operator ^= (T value) { T v = this->load(); v ^= value; this->store(v); return v; } }; template struct var_event { debug_info var_info_; var const* var_addr_; T value_; bool load_; template struct map_type { typedef T result; }; template struct map_type { typedef void* result; }; void output(std::ostream& s) const { s << "<" << std::hex << var_addr_ << std::dec << "> " << (load_ ? "load" : "store") << ", value=" << (typename map_type::result)value_; } }; template class var { public: var() { value_ = 0; initialized_ = false; data_ = ctx().var_ctor(); } var(T value) { init(value); } var(var const& r) { init(r.load($)); } ~var() { sign_.check($); ctx().var_dtor(data_); } var_proxy_const operator () (debug_info_param info) const { return var_proxy_const(*this, info); } var_proxy operator () (debug_info_param info) { return var_proxy(*this, info); } private: T value_; bool initialized_; var_data* data_; signature<123456789> sign_; friend class var_proxy; friend class var_proxy_const; void init(T value) { context& c = ctx(); initialized_ = true; value_ = value; data_ = ctx().var_ctor(); data_->init(*c.threadx_); } T load(debug_info_param info) const { context& c = ctx(); sign_.check(info); if (false == initialized_) { RL_HIST(var_event) {RL_INFO, this, T(), true} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_unitialized_access, "", info); } if (false == c.invariant_executing) { if (false == data_->load(*c.threadx_)) { RL_HIST(var_event) {RL_INFO, this, T(), true} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_data_race, "data race detected", info); } T const v = value_; RL_HIST(var_event) {RL_INFO, this, v, true} RL_HIST_END(); return v; } else { return value_; } } void store(T v, debug_info_param info) { context& c = ctx(); RL_VERIFY(false == c.invariant_executing); sign_.check(info); if (initialized_) { if (false == data_->store(*c.threadx_)) { RL_HIST(var_event) {RL_INFO, this, T(), false} RL_HIST_END(); RL_ASSERT_IMPL(false, test_result_data_race, "data race detected", info); } } else { initialized_ = true; data_->init(*c.threadx_); } value_ = v; RL_HIST(var_event) {RL_INFO, this, v, false} RL_HIST_END(); } var& operator = (var const& r); }; template struct var_data_impl : var_data { typedef thread_info thread_info_t; timestamp_t load_acq_rel_timestamp_ [thread_count]; timestamp_t store_acq_rel_timestamp_ [thread_count]; var_data_impl() { foreach(load_acq_rel_timestamp_, assign_zero); foreach(store_acq_rel_timestamp_, assign_zero); } virtual void init(thread_info_base& th) { th.own_acq_rel_order_ += 1; store_acq_rel_timestamp_[th.index_] = th.own_acq_rel_order_; } virtual bool store(thread_info_base& th) { for (thread_id_t i = 0; i != thread_count; ++i) { if (th.acq_rel_order_[i] < store_acq_rel_timestamp_[i]) return false; if (th.acq_rel_order_[i] < load_acq_rel_timestamp_[i]) return false; } th.own_acq_rel_order_ += 1; store_acq_rel_timestamp_[th.index_] = th.own_acq_rel_order_; return true; } virtual bool load(thread_info_base& th) { for (thread_id_t i = 0; i != thread_count; ++i) { if (th.acq_rel_order_[i] < store_acq_rel_timestamp_[i]) return false; } th.own_acq_rel_order_ += 1; load_acq_rel_timestamp_[th.index_] = th.own_acq_rel_order_; return true; } virtual ~var_data_impl() {} // just to calm down gcc }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/volatile.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_VOLATILE_HPP #define RL_VOLATILE_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" namespace rl { } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/waitset.hpp ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_WAITSET_HPP #define RL_WAITSET_HPP #ifdef _MSC_VER # pragma once #endif #include "base.hpp" #include "thread_base.hpp" #include "context_base.hpp" namespace rl { template class waitset { public: waitset() { size_ = 0; } unpark_reason park_current(context& c, bool is_timed, bool allow_spurious_wakeup, bool do_switch, debug_info_param info) { RL_VERIFY(size_ < thread_count); thread_info_base* th = c.threadx_; thread_desc desc = {th, 0, 0, 0, false, do_switch}; set_[size_] = desc; size_ += 1; unpark_reason reason = c.park_current_thread(is_timed, allow_spurious_wakeup, do_switch, info); if (reason == unpark_reason_normal) { if (do_switch) RL_VERIFY(c.threadx_->temp_switch_from_ != -1); else RL_VERIFY(c.threadx_->temp_switch_from_ == -1); } else { remove(th); } return reason; } static unpark_reason park_current(context& c, waitset** ws, win_waitable_object** wo, size_t count, bool wait_all, bool is_timed, bool do_switch, debug_info_param info) { thread_info_base* th = c.threadx_; thread_desc desc = {th, (unsigned)count, ws, wo, wait_all, do_switch}; for (unsigned wsi = 0; wsi != count; ++wsi) { RL_VERIFY(ws[wsi]->size_ < thread_count); ws[wsi]->set_[ws[wsi]->size_] = desc; ws[wsi]->size_ += 1; } unpark_reason reason = c.park_current_thread(is_timed, false, do_switch, info); if (reason == unpark_reason_normal) { if (do_switch) RL_VERIFY(c.threadx_->temp_switch_from_ != -1); else RL_VERIFY(c.threadx_->temp_switch_from_ == -1); } else { remove(th, ws, (unsigned)count); } return reason; } bool unpark_one(context& c, debug_info_param info) { if (0 == size_) return false; //!!! too high preassure on full sched thread_id_t idx = c.rand(size_, sched_type_user); if (try_remove(c, idx, info)) return true; for (idx = 0; idx != size_; idx += 1) { if (try_remove(c, idx, info)) return true; } return false; } thread_id_t unpark_all(context& c, debug_info_param info) { thread_id_t cnt = 0; for (thread_id_t idx = 0; idx != size_; idx += 1) { if (try_remove(c, idx, info)) { cnt += 1; idx -= 1; } } return cnt; } thread_id_t size() const { return size_; } operator bool () const { return 0 != size_; } private: struct thread_desc { thread_info_base* th_; unsigned count_; // 0 - wfso, !0 - wfmo waitset** ws_; // 0 - wfso, !0 - wfmo win_waitable_object** wo_; // 0 - wfso, !0 - wfmo bool wait_all_; bool do_switch_; }; thread_desc set_ [thread_count]; thread_id_t size_; bool try_remove(context& c, thread_id_t const idx, debug_info_param info) { RL_VERIFY(idx < size_); thread_desc const& d = set_[idx]; if (d.count_ != 0 && d.wait_all_ == true) { for (size_t i = 0; i != d.count_; i += 1) { if (d.wo_[i]->is_signaled(info) == false) return false; } } size_t const tid = d.th_->index_; bool const do_switch = d.do_switch_; if (d.ws_) remove(d.th_, d.ws_, d.count_); else remove(d.th_); c.unpark_thread(tid, do_switch, info); return true; } void remove(thread_info_base* th) { thread_id_t size = size_; thread_id_t i = 0; for (; i != size; ++i) { if (set_[i].th_ == th) break; } RL_VERIFY(i != size); for (thread_id_t j = i + 1; j != size; ++j) { set_[j - 1] = set_[j]; } size_ -= 1; } static void remove(thread_info_base* th, waitset** ws, unsigned count) { for (unsigned wsi = 0; wsi != count; ++wsi) { ws[wsi]->remove(th); } } }; } #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/relacy/windows.h ================================================ /* Relacy Race Detector * Copyright (c) 2008-2013, Dmitry S. Vyukov * All rights reserved. * This software is provided AS-IS with no warranty, either express or implied. * This software is distributed under a license and may not be copied, * modified or distributed except as expressly authorized under the * terms of the license contained in the file LICENSE in this distribution. */ #ifndef RL_WINDOWS_IFACE_HPP #define RL_WINDOWS_IFACE_HPP #ifdef _MSC_VER # pragma once #endif #include "relacy.hpp" #include "stdlib/windows.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/addr_hash.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct test_addr_hash : rl::test_suite { void* p1; void* p2; size_t h1, h2; static size_t const table_size = 1000; void before() { p1 = malloc(0); h1 = rl::hash_ptr(p1, table_size); p2 = malloc(0); h2 = rl::hash_ptr(p2, table_size); } void after() { free(p1); free(p2); } void thread(unsigned index) { assert(h1 == rl::hash_ptr(p1, table_size)); assert(h2 == rl::hash_ptr(p2, table_size)); assert(rl::hash_ptr(&index, table_size) == rl::hash_ptr(&index,table_size)); assert(rl::hash_ptr(0, table_size) == rl::hash_ptr(0, table_size)); } }; struct test_addr_hash2 : rl::test_suite { static size_t const table_size = 4; std::atomic table [table_size]; void before() { for (size_t i = 0; i != table_size; i += 1) table[i].store(0, std::memory_order_relaxed); } void thread(unsigned) { for (size_t i = 0; i != table_size + 1; i += 1) { void* p = malloc(0); size_t idx = rl::hash_ptr(p, table_size); free(p); int v = table[idx].exchange(1, std::memory_order_relaxed); RL_UNTIL(v); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/advanced.txt ================================================ Test parameters. You can specify various parameters for test. rl::test_params p; p.search_type = rl::fair_context_bound_scheduler_type; p.context_bound = 1; p.execution_depth_limit = 1000; rl::simulate(p); The main parameter is scheduler type used for simulation. There is 3 types of scheduler: random_scheduler_type - random exploration of state space fair_full_search_scheduler_type - exhaustive systematic exploration of state space fair_context_bound_scheduler_type - systematic exploration of state space with limit on context switches. For random_scheduler_type you can specify 'iteration_count' parameter - number of explored executions. For fair_context_bound_scheduler_type you can specify 'context_bound' parameter - limit on context switches. Also you can specify 'execution_depth_limit' parameter - used for livelock detection. All executions with trace longer than execution_depth_limit will be treated as livelocked (or non-terminating). Also from test_params structure you can receive output parameters from simulation. Main output parameter is 'test_result' which describes cause of test failure. If you use fair_full_search_scheduler_type or fair_context_bound_scheduler_type, in order to ensure fairness of scheduler, you must use 'yield' calls in all 'spin-loops', otherwise simulation will report non-terminating execution. Example: struct race_seq_ld_ld_test : rl::test_suite { std::atomic a; rl::var x; void before() { a($) = 0; x($) = 0; } void thread(unsigned index) { if (index) { x($).load(); a($).store(1, std::memory_order_relaxed); } else { rl::backoff b; while (0 == a($).load(rl::memory_order_relaxed)) b.yield($); x($).load(); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/compare_swap.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" template struct cas_spurious_fail_test : rl::test_suite, 1, rl::test_result_until_condition_hit> { std::atomic x; std::atomic y; void before() { x.store(0, std::memory_order_relaxed); y.store(0, std::memory_order_relaxed); } void thread(unsigned /*index*/) { int cmp = 0; if (x.compare_exchange_weak(cmp, 1, std::memory_order_seq_cst, std::memory_order_seq_cst)) { cmp = 1; if (x.compare_exchange_weak(cmp, 2, std::memory_order_seq_cst)) { cmp = 0; if (y.compare_exchange_weak(cmp, 1, std::memory_order_seq_cst)) { } else { if (T == 2) RL_UNTIL(true); } } else { if (T == 1) RL_UNTIL(true); } } else { if (T == 0) RL_UNTIL(true); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/condvar.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct test_condvar : rl::test_suite { std::mutex mtx; std::condition_variable cv; rl::var data; void before() { data($) = 0; } void thread(unsigned index) { if (0 == index) { mtx.lock($); data($) += 1; mtx.unlock($); cv.notify_one($); } else { mtx.lock($); while (0 == data($)) { cv.wait(mtx, $); } mtx.unlock($); } } }; struct test_condvar2 : rl::test_suite { rl::var stage; std::mutex mtx; std::condition_variable cv; void before() { stage($) = 0; } void thread(unsigned index) { if (0 == index) { mtx.lock($); stage($) += 1; cv.notify_all($); while (stage($) != 2) cv.wait(mtx, $); mtx.unlock($); } else if (1 == index) { mtx.lock($); while (stage($) != 1) cv.wait(mtx, $); stage($) += 1; cv.notify_all($); mtx.unlock($); } else if (2 == index) { mtx.lock($); while (stage($) != 2) cv.wait(mtx, $); mtx.unlock($); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/data_race.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct race_ld_ld_test : rl::test_suite { rl::var x; void before() { x($) = 0; } void thread(unsigned index) { if (index) x($).load(); else x($).load(); } }; struct race_ld_st_test : rl::test_suite { rl::var x; void before() { x($) = 0; } void thread(unsigned index) { if (index) x($).load(); else x($).store(1); } }; struct race_st_st_test : rl::test_suite { rl::var x; void thread(unsigned index) { if (index) x($).store(1); else x($).store(1); } }; struct race_seq_ld_ld_test : rl::test_suite { std::atomic a; rl::var x; void before() { a($) = 0; x($) = 0; } void thread(unsigned index) { if (index) { x($).load(); a.store(1, std::memory_order_relaxed); } else { rl::backoff b; while (0 == a.load(std::memory_order_relaxed)) b.yield($); x($).load(); } } }; struct race_seq_ld_st_test : rl::test_suite { std::atomic a; rl::var x; void before() { a($) = 0; x($) = 0; } void thread(unsigned index) { if (index) { x($).load(); a.store(1, std::memory_order_relaxed); } else { rl::backoff b; while (0 == a.load(std::memory_order_relaxed)) b.yield($); x($).store(1); } } }; struct race_seq_st_ld_test : rl::test_suite { std::atomic a; rl::var x; void before() { a($) = 0; } void thread(unsigned index) { if (0 == index) { x($).store(1); a.store(1, std::memory_order_relaxed); } else { rl::backoff b; while (0 == a.load(std::memory_order_relaxed)) b.yield($); x($).load(); } } }; struct race_seq_st_st_test : rl::test_suite { std::atomic a; rl::var x; void before() { a($) = 0; } void thread(unsigned index) { if (index) { x($).store(1); a.store(1, std::memory_order_relaxed); } else { rl::backoff b; while (0 == a.load(std::memory_order_relaxed)) b.yield($); VAR(x) = 1; } } }; struct race_uninit_test : rl::test_suite { std::atomic a; std::atomic x; void before() { a($) = 0; } void thread(unsigned index) { if (index) { x.store(1, std::memory_order_relaxed); a.store(1, std::memory_order_relaxed); } else { rl::backoff b; while (0 == a.load(std::memory_order_relaxed)) b.yield($); x.load(std::memory_order_seq_cst); } } }; struct race_indirect_test : rl::test_suite { std::atomic a; rl::var x; void before() { a($) = 0; x($) = 0; } void thread(unsigned index) { if (0 == index) { x($) = 1; a.store(1, std::memory_order_release); (void)(int)x($); } else { rl::backoff b; while (0 == a.load(std::memory_order_acquire)) b.yield($); (void)(int)x($); x($) = 2; } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/detection.txt ================================================ - Race condition (accoring to ISO C++0x) - Access to uninitialized variable - Access to freed memory - Double free - Memory leak - Deadlock - Livelock - User assert failed - User invariant failed ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/dyn_thread.hpp ================================================ #pragma once #include "../relacy/relacy.hpp" #include "../relacy/dyn_thread.hpp" struct dyn_thread_basic_test : rl::test_suite { static unsigned const dynamic_thread_count = 4; rl::var data1; rl::var data2; rl::atomic data3; void before() { data3($) = 0; } static void* thread1(void* p) { dyn_thread_basic_test& self = *(dyn_thread_basic_test*)p; self.data1($) = 1; return 0; } static void* thread2(void* p) { dyn_thread_basic_test& self = *(dyn_thread_basic_test*)p; self.data2($) = 2; return 0; } static void* thread3(void* p) { dyn_thread_basic_test& self = *(dyn_thread_basic_test*)p; self.data3.store(3, rl::memory_order_relaxed); return 0; } void thread(unsigned index) { if (index == 0) { rl::dyn_thread t1; t1.start(&dyn_thread_basic_test::thread1, this); rl::dyn_thread t2; t2.start(&dyn_thread_basic_test::thread2, this); t1.join(); t2.join(); RL_ASSERT(data1($) == 1); RL_ASSERT(data2($) == 2); } else if (index == 1) { rl::dyn_thread t1; t1.start(&dyn_thread_basic_test::thread3, this); while (data3.load(rl::memory_order_relaxed) != 3) rl::yield(1, $); t1.join(); } else { RL_ASSERT(false); } } }; struct dyn_thread_win32_test : rl::test_suite { static unsigned const dynamic_thread_count = 4; rl::var data1; rl::var data2; rl::atomic data3; void before() { data3($) = 0; } static unsigned long RL_STDCALL thread1(void* p) { dyn_thread_win32_test& self = *(dyn_thread_win32_test*)p; self.data1($) = 1; return 0; } static unsigned long RL_STDCALL thread2(void* p) { dyn_thread_win32_test& self = *(dyn_thread_win32_test*)p; self.data2($) = 2; return 0; } static unsigned long RL_STDCALL thread3(void* p) { dyn_thread_win32_test& self = *(dyn_thread_win32_test*)p; self.data3.store(3, rl::memory_order_relaxed); return 0; } void thread(unsigned index) { if (index == 0) { HANDLE threads [2]; threads[0] = CreateThread(0, 0, &dyn_thread_win32_test::thread1, this, 0, 0); threads[1] = CreateThread(0, 0, &dyn_thread_win32_test::thread2, this, 0, 0); WaitForMultipleObjects(2, threads, 1, INFINITE); RL_ASSERT(VAR(data1) == 1); RL_ASSERT(VAR(data2) == 2); } else if (index == 1) { HANDLE th = CreateThread(0, 0, &dyn_thread_win32_test::thread3, this, 0, 0); while (data3.load(rl::memory_order_relaxed) != 3) rl::yield(1, $); WaitForSingleObject(th, INFINITE); } else { RL_ASSERT(false); } } }; struct dyn_thread_visibility_test : rl::test_suite { static unsigned const dynamic_thread_count = 1; rl::var data; static unsigned long RL_STDCALL thread(void* p) { dyn_thread_visibility_test& self = *(dyn_thread_visibility_test*)p; RL_ASSERT(self.data($) == 1); self.data($) = 2; return 0; } void thread(unsigned /*index*/) { data($) = 1; HANDLE th = CreateThread(0, 0, &dyn_thread_visibility_test::thread, this, 0, 0); WaitForSingleObject(th, INFINITE); RL_ASSERT(data($) == 2); } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/event.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct test_event_auto : rl::test_suite { HANDLE ev; VAR_T(int) data; void before() { VAR(data) = 0; ev = CreateEvent(0, 0, 0, 0); } void after() { CloseHandle(ev); } void thread(unsigned index) { if (0 == index) { VAR(data) = 1; SetEvent(ev); } else { unsigned rv = WaitForSingleObject(ev, INFINITE); assert(rv == WAIT_OBJECT_0); assert(VAR(data) == 1); rv = WaitForSingleObject(ev, 0); assert(rv == WAIT_TIMEOUT); } } }; struct test_event_atomic : rl::test_suite { HANDLE ev1; HANDLE ev2; void before() { ev1 = CreateEvent(0, 0, 0, 0); ev2 = CreateEvent(0, 0, 0, 0); } void after() { CloseHandle(ev1); CloseHandle(ev2); } void thread(unsigned index) { if (0 == index) { unsigned rv = WaitForSingleObject(ev1, INFINITE); assert(rv == WAIT_OBJECT_0); SetEvent(ev2); rv = WaitForSingleObject(ev2, 0); assert(rv == WAIT_TIMEOUT); } else { unsigned rv = SignalObjectAndWait(ev1, ev2, INFINITE, 0); assert(rv == WAIT_OBJECT_0); rv = WaitForSingleObject(ev2, 0); assert(rv == WAIT_TIMEOUT); } } }; struct test_event_manual : rl::test_suite { HANDLE ev; VAR_T(int) data; void before() { VAR(data) = 0; ev = CreateEvent(0, 1, 0, 0); } void after() { CloseHandle(ev); } void thread(unsigned index) { if (0 == index) { VAR(data) = 1; SetEvent(ev); } else { unsigned rv = WaitForSingleObject(ev, INFINITE); assert(rv == WAIT_OBJECT_0); assert(VAR(data) == 1); rv = WaitForSingleObject(ev, 0); assert(rv == WAIT_OBJECT_0); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/features.txt ================================================ - Relaxed ISO C++0x Memory Model. Relaxed/acquire/release/acq_rel/seq_cst memory operations. The only non-supported feature is memory_order_consume, it's simulated with memory_order_acquire. - Exhaustive automatic error checking (including ABA detection). - Full-fledged atomics library (with spurious failures in compare_exchange()). - Memory fences. - Arbitrary number of threads. - Detailed execution history for failed tests. - No false positives. - Before/after/invariant functions for test suites. ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/fence.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" template struct fence_synch_test : rl::test_suite, 2> { std::atomic x; rl::var data; void before() { x($) = 0; } void thread(unsigned th) { if (0 == th) { data($) = 1; if (0 == index || 1 == index) { std::atomic_thread_fence(order().first, $); x.store(1, std::memory_order_relaxed); } else { x.store(1, order().first, $); } } else { if (0 == index || 2 == index) { if (x.load(std::memory_order_relaxed)) { std::atomic_thread_fence(order().second, $); data($).load(); } } else { if (x.load(order().second, $)) { data($).load(); } } } } std::pair order() { switch (mo_index) { default: RL_VERIFY(false); case 0: return std::make_pair(std::mo_release, std::mo_acquire); case 1: return std::make_pair(std::mo_seq_cst, std::mo_seq_cst); } } }; struct two_fence_synch_test : rl::test_suite { std::atomic x0; std::atomic x1; rl::var data0; rl::var data1; void before() { x0($) = 0; x1($) = 0; } void thread(unsigned index) { if (0 == index) { data0($) = 1; std::atomic_thread_fence(std::memory_order_release); x0.store(1, std::memory_order_relaxed); } else if (1 == index) { data1($) = 1; std::atomic_thread_fence(std::memory_order_release); x1.store(1, std::memory_order_relaxed); } else { int y0 = x0.load(std::memory_order_relaxed); int y1 = x1.load(std::memory_order_relaxed); if (y0 || y1) { std::atomic_thread_fence(std::memory_order_acquire); if (y0) data0($).load(); if (y1) data1($).load(); } } } }; template struct seq_cst_fence_test : rl::test_suite, 2, (rl::test_result_e)((0 == index) * rl::test_result_success + (1 == index) * rl::test_result_until_condition_hit)> { std::atomic x0; std::atomic x1; rl::var r0; rl::var r1; void before() { x0($) = 0; x1($) = 0; } void thread(unsigned th) { if (0 == th) { x0.store(1, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); r0($) = x1.load(std::memory_order_relaxed); } else { x1.store(1, std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_seq_cst); r1($) = x0.load(std::memory_order_relaxed); } } void after() { if (0 == index) RL_ASSERT(r0($) || r1($)); else if (1 == index) RL_UNTIL(r0($) && r1($)); } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/foo.cpp ================================================ #include "stdafx.h" #include "../relacy/relacy_std.hpp" #include "../relacy/windows.h" #include "../relacy/pthread.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/futex.hpp ================================================ #pragma once #include "../relacy/pthread.h" struct test_futex : rl::test_suite { rl::atomic state; int wakeres; int waitres; void before() { state.store(0, rl::memory_order_relaxed); wakeres = 0; waitres = 0; } void after() { assert((waitres == 0 && wakeres == 1) || (waitres == EWOULDBLOCK && wakeres == 0) || (waitres == EINTR && wakeres == 0)); } void thread(unsigned index) { if (index == 0) { state.store(1, std::memory_order_relaxed); wakeres = futex(&state, FUTEX_WAKE, 1, 0, 0, 0); } else { waitres = EINTR; while (state.load(rl::memory_order_relaxed) == 0) { waitres = futex(&state, FUTEX_WAIT, 0, 0, 0, 0); } } } }; struct test_futex_deadlock : rl::test_suite { rl::atomic state; void thread(unsigned index) { state.store(0, rl::memory_order_relaxed); int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0); assert(rv == EINTR); } }; struct test_futex_sync1 : rl::test_suite { rl::atomic state; VAR_T(int) data; void before() { state.store(0, rl::memory_order_relaxed); VAR(data) = 0; } void thread(unsigned index) { if (index == 0) { VAR(data) = 1; state.store(1, std::memory_order_release); futex(&state, FUTEX_WAKE, 1, 0, 0, 0); } else { int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0); assert(rv == 0 || rv == EWOULDBLOCK || rv == EINTR); if (rv == 0) { assert(VAR(data) == 1); assert(state.load(rl::memory_order_relaxed) == 1); RL_UNTIL(true); } } } }; struct test_futex_sync2 : rl::test_suite { rl::atomic state; VAR_T(int) data; void before() { state.store(0, rl::memory_order_relaxed); VAR(data) = 0; } void thread(unsigned index) { if (index == 0) { VAR(data) = 1; state.store(1, std::memory_order_release); futex(&state, FUTEX_WAKE, 1, 0, 0, 0); } else { int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0); assert(rv == 0 || rv == EWOULDBLOCK || rv == EINTR); if (rv == EWOULDBLOCK) { assert(VAR(data) == 1); assert(state.load(rl::memory_order_relaxed) == 1); RL_UNTIL(true); } } } }; struct test_futex_intr : rl::test_suite { rl::atomic state; VAR_T(int) data; void before() { state.store(0, rl::memory_order_relaxed); VAR(data) = 0; } void thread(unsigned index) { if (index == 0) { VAR(data) = 1; state.store(1, std::memory_order_release); futex(&state, FUTEX_WAKE, 1, 0, 0, 0); } else { int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0); assert(rv == 0 || rv == EWOULDBLOCK || rv == EINTR); RL_UNTIL(rv == EINTR); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/g++/build_all_cygwin_debug.bat ================================================ g++ ../../jtest/jtest.cpp -c -o jtest_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../ntest/ntest.cpp -c -o ntest_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/peterson/peterson.cpp -c -o peterson_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/proxy_collector/proxy_collector.cpp -c -o proxy_collector_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/ref_counting/ref_counting.cpp -c -o ref_counting_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/smr/smr.cpp -c -o smr_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/spsc_queue/spsc_queue.cpp -c -o spsc_queue_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/stack/stack.cpp -c -o stack_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/condvar/condvar.cpp -c -o condvar_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/mutex_business_logic/mutex_business_logic.cpp -c -o mutex_business_logic_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/ws_deque/ws_deque.cpp -c -o ws_deque_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/cli_ws_deque/cli_ws_deque.cpp -c -o cli_ws_deque_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../../example/java_ws_deque/java_ws_deque.cpp -c -o java_ws_deque_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 g++ ../main.cpp -c -o test_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686 ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/g++/build_all_debug.bat ================================================ g++ ../../jtest/jtest.cpp -o jtest_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../ntest/ntest.cpp -o ntest_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/peterson/peterson.cpp -o peterson_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/proxy_collector/proxy_collector.cpp -o proxy_collector_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/ref_counting/ref_counting.cpp -o ref_counting_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/smr/smr.cpp -o smr_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/spsc_queue/spsc_queue.cpp -o spsc_queue_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/stack/stack.cpp -o stack_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/condvar/condvar.cpp -o condvar_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/mutex_business_logic/mutex_business_logic.cpp -o mutex_business_logic_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/ws_deque/ws_deque.cpp -o ws_deque_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/cli_ws_deque/cli_ws_deque.cpp -o cli_ws_deque_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../../example/java_ws_deque/java_ws_deque.cpp -o java_ws_deque_debug.exe -D_DEBUG -Wall -Wno-deprecated -g g++ ../main.cpp -o test_debug.exe -D_DEBUG -Wall -Wno-deprecated -g ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/g++/build_all_release.sh ================================================ g++ ../../jtest/jtest.cpp -o jtest_debug.exe -Wall -D_DEBUG g++ ../../ntest/ntest.cpp -o ntest_debug.exe -Wall -D_DEBUG g++ ../../example/peterson/peterson.cpp -o peterson_debug.exe -Wall -D_DEBUG g++ ../../example/proxy_collector/proxy_collector.cpp -o proxy_collector_debug.exe -Wall -D_DEBUG g++ ../../example/ref_counting/ref_counting.cpp -o ref_counting_debug.exe -Wall -D_DEBUG g++ ../../example/smr/smr.cpp -o smr_debug.exe -Wall -D_DEBUG g++ ../../example/spsc_queue/spsc_queue.cpp -o spsc_queue_debug.exe -Wall -D_DEBUG g++ ../../example/stack/stack.cpp -o stack_debug.exe -Wall -D_DEBUG g++ ../../example/condvar/condvar.cpp -o condvar_debug.exe -Wall -D_DEBUG g++ ../../example/mutex_business_logic/mutex_business_logic.cpp -o mutex_business_logic_debug.exe -Wall -D_DEBUG g++ ../../example/ws_deque/ws_deque.cpp -o ws_deque_debug.exe -Wall -D_DEBUG g++ ../../example/cli_ws_deque/cli_ws_deque.cpp -o cli_ws_deque_debug.exe -Wall -D_DEBUG g++ ../../example/java_ws_deque/java_ws_deque.cpp -o java_ws_deque_debug.exe -Wall -D_DEBUG g++ ../main.cpp -o test_debug.exe -Wall -D_DEBUG ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/g++/build_cygwin_release.cmd ================================================ #!/bin/bash g++ ../main.cpp -o test_release.exe -DNDEBUG -DRL_CYGWIN_STUB -Wall -O3 ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/g++/build_debug.cmd ================================================ #!/bin/bash g++ ../main.cpp -o test_debug.exe -D_DEBUG -D_XOPEN_SOURCE -Wall -Wno-deprecated -g -O0 -fno-inline ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/g++/build_release.cmd ================================================ #!/bin/bash g++ ../main.cpp -o test_release.exe -DNDEBUG -Wall -O3 -D_XOPEN_SOURCE -Wno-deprecated ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/g++/test.cpp ================================================ //#ifdef _FORTIFY_SOURCE //#undef _FORTIFY_SOURCE //#endif //#define _FORTIFY_SOURCE 0 #include "../../relacy/pthread.h" class queue_t { public: queue_t() { VAR(head) = 0; VAR(tail) = 0; pthread_mutex_init(&mtx, 0); pthread_cond_init(&cv, 0); } ~queue_t() { pthread_mutex_destroy(&mtx); pthread_cond_destroy(&cv); } void enqueue(void* data) { node_t* n = new node_t; n->VAR(next) = 0; n->VAR(data) = data; bool was_empty = false; pthread_mutex_lock(&mtx); if (VAR(head) == 0) { was_empty = true; VAR(head) = n; VAR(tail) = n; } else { VAR(tail)->VAR(next) = n; VAR(tail) = n; } pthread_mutex_unlock(&mtx); if (was_empty) pthread_cond_broadcast(&cv); } void* dequeue() { node_t* n = 0; pthread_mutex_lock(&mtx); while (VAR(head) == 0) pthread_cond_wait(&cv, &mtx); n = VAR(head); if (n->VAR(next) == 0) VAR(tail) = 0; VAR(head) = n->VAR(next); pthread_mutex_unlock(&mtx); void* data = n->VAR(data); delete n; return data; } private: struct node_t { VAR_T(node_t*) next; VAR_T(void*) data; }; VAR_T(node_t*) head; VAR_T(node_t*) tail; pthread_mutex_t mtx; pthread_cond_t cv; }; void* enqueue_thread(void* ctx) { queue_t* q = static_cast(ctx); for (size_t i = 0; i != 4; i += 1) q->enqueue((void*)(i + 1)); return 0; } void* dequeue_thread(void* ctx) { queue_t* q = static_cast(ctx); for (size_t i = 0; i != 4; i += 1) { void* data = q->dequeue(); assert((int)(uintptr_t)data >= 1 && (int)(uintptr_t)data <= 4); } return 0; } void queue_test() { queue_t q; pthread_t th [4]; for (size_t i = 0; i != 2; i += 1) pthread_create(&th[i], 0, enqueue_thread, &q); for (size_t i = 2; i != 4; i += 1) pthread_create(&th[i], 0, dequeue_thread, &q); void* res = 0; for (size_t i = 0; i != 4; i += 1) pthread_join(th[i], &res); } int main() { rl::test_params p; p.iteration_count = 100000; //p.search_type = rl::sched_full; //p.context_bound = 5; //p.execution_depth_limit = 200; rl::execute(p); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/jtest/jtest.cpp ================================================ #include "stdafx.h" #include "../relacy/relacy_java.hpp" class stack { public: stack() : head_(0) { } void push(int data) { rl::var n = new node (); VAR(n)->VAR(data_) = data; node* next = head_.load(rl::memory_order_relaxed); for (;;) { VAR(n)->next_.store(next, rl::memory_order_relaxed); if (head_.compare_exchange_weak(next, VAR(n), rl::memory_order_release)) break; } } int pop() { node* n = head_.load(rl::memory_order_acquire); for (;;) { if (0 == n) break; node* next = n->next_.load(rl::memory_order_relaxed); if (head_.compare_exchange_weak(n, next, rl::memory_order_acquire)) break; } if (n) { int data = n->VAR(data_); return data; } else { return 0; } } private: struct node { rl::atomic next_; rl::var data_; }; rl::atomic head_; stack(stack const&); stack& operator = (stack const&); }; struct stack_test : rl::test_suite { stack s_; int produced_count_; int consumed_count_; void before() { produced_count_ = 0; consumed_count_ = 0; } void after() { typedef rl::test_suite base_t; RL_ASSERT(base_t::params::thread_count == produced_count_); RL_ASSERT(base_t::params::thread_count == consumed_count_); } void thread(unsigned /*index*/) { s_.push(rand() + 1); produced_count_ += 1; int data = s_.pop(); RL_ASSERT(data); consumed_count_ += 1; } }; struct test_api : rl::test_suite { void thread(unsigned) { rl::jvolatile jv1; rl::jvolatile jv2 (2); rl::jvolatile jv3 (jv2($)); rl::jvolatile jv4 (jv1); jv1($) = jv3($); jv1($) = 2; (int)jv1($); jv1($) += 1; jv1($) -= 1; int x = jv1($)++; x = jv1($)--; x = --jv1($); x = ++jv1($); rl::AtomicInteger ai, ai2(1), ai3(x), ai4(ai($)), ai5(ai); x = ai($).get(); ai($).set(1); x = ai($).addAndGet(2); bool b = ai($).compareAndSet(1, 2); (void)b; x = ai($).addAndGet(2); x = ai($).getAndSet(2); } }; struct test_seq_cst_volatiles : rl::test_suite { rl::jvolatile flag0; rl::jvolatile flag1; rl::jvolatile turn; rl::var data; void thread(unsigned index) { if (0 == index) { flag0($) = 1; turn($) = 1; while (flag1($) && 1 == turn($)) rl::yield(1, $); data($) = 1; flag0($) = 0; } else { flag1($) = 1; turn($) = 0; while (flag0($) && 0 == turn($)) rl::yield(1, $); data($) = 2; flag1($) = 0; } } }; struct test_seq_cst_volatiles2 : rl::test_suite { rl::jvolatile x; rl::jvolatile y; int r1, r2, r3, r4; void before() { r1 = r2 = r3 = r4 = 0; } void thread(unsigned index) { if (0 == index) { x($) = 0; } else if (1 == index) { y($) = 0; } else if (2 == index) { r1 = x($); r2 = y($); } else if (3 == index) { r3 = y($); r4 = x($); } } void after() { RL_ASSERT(false == (r1 && !r2 && r3 && !r4)); } }; template struct test_unitialized_var : rl::test_suite, 2, rl::test_result_until_condition_hit> { rl::jvar*> www; void thread(unsigned index) { if (0 == index) { www($) = new rl::jvar (1); } else { while (0 == www($)) rl::yield(1, $); int x = (*www($))($); RL_UNTIL(x == expected); } } }; int main() { rl::simulate_f tests[] = { //!!! broken &rl::simulate >, &rl::simulate >, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, }; for (size_t i = 0; i != sizeof(tests)/sizeof(*tests); ++i) { rl::ostringstream stream; rl::test_params params; params.iteration_count = 10000; params.output_stream = &stream; params.progress_stream = &stream; params.context_bound = 2; params.execution_depth_limit = 500; if (false == tests[i](params)) { std::cout << std::endl; std::cout << "FAILED" << std::endl; std::cout << stream.str(); return 1; } else { std::cout << params.test_name << "...OK" << std::endl; } } std::cout << std::endl << "SUCCESS" << std::endl; } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/jtest/msvc8/jtest.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc8\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug64|Win32 = Debug64|Win32 Debug64|x64 = Debug64|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|x64.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.Build.0 = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|x64.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|x64.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.ActiveCfg = Debug64|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.Build.0 = Debug64|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.ActiveCfg = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.Build.0 = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/jtest/msvc8/jtest.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/jtest/msvc9/jtest.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc9\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug64|Win32 = Debug64|Win32 Debug64|x64 = Debug64|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|x64.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.Build.0 = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|x64.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|x64.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.ActiveCfg = Debug64|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.Build.0 = Debug64|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.ActiveCfg = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.Build.0 = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/jtest/msvc9/jtest.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/jtest/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/jtest/stdafx.h ================================================ #pragma once //#define RL_JAVA_MODE //#define RL_MSVC_OUTPUT #include "../relacy/pch.hpp" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/main.cpp ================================================ #include "stdafx.h" //#define RL_MSVC_OUTPUT #include "../relacy/relacy_std.hpp" #include "memory_order.hpp" #include "fence.hpp" #include "data_race.hpp" #include "mutex.hpp" #include "condvar.hpp" #include "semaphore.hpp" #include "event.hpp" #include "scheduler.hpp" #include "compare_swap.hpp" #include "wfmo.hpp" #include "thread_local.hpp" #include "dyn_thread.hpp" #include "memory.hpp" #include "pthread.hpp" #include "windows.hpp" #include "addr_hash.hpp" #include "futex.hpp" #include "../relacy/windows.h" #include "../relacy/pthread.h" #include #include class queue_t { public: queue_t() { VAR(head) = 0; VAR(tail) = 0; pthread_mutex_init(&mtx, 0); pthread_cond_init(&cv, 0); } ~queue_t() { pthread_mutex_destroy(&mtx); pthread_cond_destroy(&cv); } void enqueue(void* data) { node_t* n = new node_t; n->VAR(next) = 0; n->VAR(data) = data; bool was_empty = false; pthread_mutex_lock(&mtx); if (VAR(head) == 0) { was_empty = true; VAR(head) = n; VAR(tail) = n; } else { VAR(tail)->VAR(next) = n; VAR(tail) = n; } pthread_mutex_unlock(&mtx); if (was_empty) pthread_cond_broadcast(&cv); } void* dequeue() { node_t* n = 0; pthread_mutex_lock(&mtx); while (VAR(head) == 0) pthread_cond_wait(&cv, &mtx); n = VAR(head); if (n->VAR(next) == 0) VAR(tail) = 0; VAR(head) = n->VAR(next); pthread_mutex_unlock(&mtx); void* data = n->VAR(data); delete n; return data; } private: struct node_t { VAR_T(node_t*) next; VAR_T(void*) data; }; VAR_T(node_t*) head; VAR_T(node_t*) tail; pthread_mutex_t mtx; pthread_cond_t cv; }; void* enqueue_thread(void* ctx) { queue_t* q = static_cast(ctx); for (size_t i = 0; i != 4; i += 1) q->enqueue((void*)(i + 1)); return 0; } void* dequeue_thread(void* ctx) { queue_t* q = static_cast(ctx); for (size_t i = 0; i != 4; i += 1) { void* data = q->dequeue(); assert((int)(uintptr_t)data >= 1 && (int)(uintptr_t)data <= 4); } return 0; } void queue_test() { queue_t q; pthread_t th [4]; for (size_t i = 0; i != 2; i += 1) pthread_create(&th[i], 0, enqueue_thread, &q); for (size_t i = 2; i != 4; i += 1) pthread_create(&th[i], 0, dequeue_thread, &q); void* res = 0; for (size_t i = 0; i != 4; i += 1) pthread_join(th[i], &res); } /* class recursive_timed_mutex { public: recursive_timed_mutex() { sema.init(false, 1, 1, $); owner = -1; recursion_count = 0; } ~recursive_timed_mutex() { assert(owner == -1 && recursion_count == 0); sema.deinit($); } void lock(rl::debug_info_param info) { rl::context& c = rl::ctx(); if (owner == c.current_thread()) { RL_HIST(rl::user_msg_event) {"recursive mutex lock"} RL_HIST_END(); assert(recursion_count > 0); recursion_count += 1; } else { sema.wait(false, false, info); assert(owner == -1 && recursion_count == 0); owner = c.current_thread(); recursion_count = 1; } } bool try_lock(rl::debug_info_param info) { rl::context& c = rl::ctx(); if (owner == c.current_thread()) { RL_HIST(rl::user_msg_event) {"recursive mutex try lock"} RL_HIST_END(); assert(recursion_count > 0); recursion_count += 1; return true; } else { rl::sema_wakeup_reason r = sema.wait(true, false, info); if (r == rl::sema_wakeup_reason_success) { assert(owner == -1 && recursion_count == 0); owner = c.current_thread(); recursion_count = 1; return true; } else { return false; } } } void unlock(rl::debug_info_param info) { rl::context& c = rl::ctx(); assert(owner == c.current_thread() && recursion_count > 0); RL_HIST(rl::user_msg_event) {"recursive mutex unlock"} RL_HIST_END(); recursion_count -= 1; if (recursion_count == 0) { owner = -1; unsigned prev; sema.post(1, prev, info); } } bool timed_lock(rl::debug_info_param info, ... ) { rl::context& c = rl::ctx(); if (owner == c.current_thread()) { RL_HIST(rl::user_msg_event) {"recursive mutex timed lock"} RL_HIST_END(); assert(recursion_count > 0); recursion_count += 1; return true; } else { rl::sema_wakeup_reason r = sema.wait(false, true, info); if (r == rl::sema_wakeup_reason_success) { assert(owner == -1 && recursion_count == 0); owner = c.current_thread(); recursion_count = 1; return true; } else { return false; } } } private: struct tag_t; rl::semaphore sema; rl::thread_id_t owner; int recursion_count; recursive_timed_mutex(recursive_timed_mutex const&); recursive_timed_mutex& operator = (recursive_timed_mutex const&); }; */ class recursive_timed_mutex { public: recursive_timed_mutex() { mtx = CreateMutex(0, 0, 0); } ~recursive_timed_mutex() { CloseHandle(mtx); } void lock(rl::debug_info_param info) { rl::rl_WaitForSingleObject(mtx, INFINITE, info); } bool try_lock(rl::debug_info_param info) { return WAIT_OBJECT_0 == rl::rl_WaitForSingleObject(mtx, 0, info); } void unlock(rl::debug_info_param info) { rl::rl_ReleaseMutex(mtx, info); } bool timed_lock(rl::debug_info_param info, ... /*abs_time*/) { return WAIT_OBJECT_0 == rl::rl_WaitForSingleObject(mtx, 1, info); } private: HANDLE mtx; recursive_timed_mutex(recursive_timed_mutex const&); recursive_timed_mutex& operator = (recursive_timed_mutex const&); }; struct recursive_timed_mutex_test : rl::test_suite { recursive_timed_mutex mtx; VAR_T(int) data; void thread(unsigned idx) { if (idx) { mtx.lock($); mtx.lock($); VAR(data) = 1; mtx.unlock($); mtx.unlock($); } else { if (mtx.timed_lock($)) { VAR(data) = 2; mtx.unlock($); } } } void after() { //assert(VAR(data) != 2); } }; int main() { //rl::test_params p; //p.search_type = rl::sched_full; //p.context_bound = 5; //p.execution_depth_limit = 200; //rl::simulate(p); //if (rand() <= RAND_MAX) return 0; //rl::execute(); //if (rand() <= RAND_MAX) return 0; //rl::test_params p; //p.initial_state = "1000000"; //p.iteration_count = 2000000; //p.collect_history = true; //p.output_history = true; //p.search_type = rl::sched_bound; //p.search_type = rl::sched_full; //p.execution_depth_limit = 500; //p.context_bound = 1; //rl::simulate(p); //std::cout << "scheduler state = \"" << p.final_state << "\"" << std::endl; //std::cout << std::endl; //if (rand() <= RAND_MAX) return 0; //rl::test_params p; //p.iteration_count = 80000000; //p.initial_state = "50000000"; //p.search_type = rl::fair_context_bound_scheduler_type; //p.context_bound = 1; //p.collect_history = true; //p.output_history = true; //rl::simulate(p); //if (rand() <= RAND_MAX) return 0; //rl::test_params p; //p.context_bound = 1; //p.iteration_count = 1000; //p.search_type = rl::fair_full_search_scheduler_type; //p.search_type = rl::random_scheduler_type; //p.collect_history = true; //p.output_history = true; //p.execution_depth_limit = 1000; //p.initial_state = "550 24 3 0 0 3 0 0 3 0 0 3 0 0 2 0 4 2 0 0 2 0 4 2 1 0 2 0 4 3 1 0 3 0 0 2 0 0 1 0 4 2 0 4 3 0 0 3 0 0 2 0 4 3 1 0 3 0 0 2 1 0 2 0 4 2 1 0 2 1 0 2 1 4"; //bool result = rl::simulate(p); //std::cout << "result=" << result << std::endl; //simulate(); //if (rand() <= RAND_MAX) return 0; rl::simulate_f tests[] = { #if 1 &rl::simulate, &rl::simulate, &rl::simulate, //!!! fails &rl::simulate, &rl::simulate, // memory model &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate >, &rl::simulate >, &rl::simulate >, &rl::simulate >, &rl::simulate >, &rl::simulate, &rl::simulate, &rl::simulate >, &rl::simulate >, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, // fences &rl::simulate >, &rl::simulate >, &rl::simulate >, &rl::simulate >, &rl::simulate >, &rl::simulate >, &rl::simulate, &rl::simulate >, &rl::simulate >, // data races &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, // compare_exchange &rl::simulate >, &rl::simulate >, &rl::simulate >, // mutex &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, // futex &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, // condition variable &rl::simulate, &rl::simulate, // semaphore &rl::simulate, &rl::simulate, // event &rl::simulate, &rl::simulate, &rl::simulate, //wfmo &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, // thread local storage &rl::simulate, &rl::simulate, &rl::simulate, &rl::simulate, // dynamic thread &rl::simulate, &rl::simulate, &rl::simulate, #endif }; for (size_t sched = 0; sched != rl::sched_count; ++sched) { std::cout << format((rl::scheduler_type_e)sched) << " tests:" << std::endl; for (size_t i = 0; i != sizeof(tests)/sizeof(*tests); ++i) { //!!! make it work under sched_full if (sched == rl::sched_full && (tests[i] == (rl::simulate_f)&rl::simulate || tests[i] == (rl::simulate_f)&rl::simulate)) continue; rl::ostringstream stream; rl::test_params params; params.search_type = (rl::scheduler_type_e)sched; params.iteration_count = (params.test_result == rl::test_result_success ? 100000 : 500); params.output_stream = &stream; params.progress_stream = &stream; params.context_bound = 2; params.execution_depth_limit = 500; if (false == tests[i](params)) { std::cout << std::endl; std::cout << "FAILED" << std::endl; std::cout << stream.str(); std::cout << std::endl; return 1; } else { std::cout << params.test_name << "...OK" << std::endl; } } std::cout << std::endl; } rl::simulate_f scheduler_tests[] = { &rl::simulate, &rl::simulate, }; std::cout << "full search scheduler tests:" << std::endl; for (size_t i = 0; i != sizeof(scheduler_tests)/sizeof(*scheduler_tests); ++i) { rl::ostringstream stream; rl::test_params params; params.search_type = rl::sched_full; params.output_stream = &stream; params.progress_stream = &stream; params.context_bound = 2; params.execution_depth_limit = 500; if (false == scheduler_tests[i](params)) { std::cout << std::endl; std::cout << "FAILED" << std::endl; std::cout << stream.str(); return 1; } else { std::cout << params.test_name << "...OK" << std::endl; } } std::cout << std::endl; std::cout << "SUCCESS" << std::endl; } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/memory.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct test_memory_allocation : rl::test_suite { void thread(unsigned /*index*/) { VAR_T(int)* p1 = new VAR_T(int) (5), i1 = 5, * p11 = new VAR_T(int) (6); VAR(p1[0]) = 1; delete p1, delete p11; VAR_T(int)* p2 = new VAR_T(int) [10], i2 = 6, *p22 = new VAR_T(int) [20]; VAR(p2[0]) = 1; delete [] p2, delete [] p22; void* p3 = malloc(10), *i3 = 0, *p33 = malloc(20); free(p3), free(p33); void* p4 = malloc(sizeof(int)); int* i4 = new (p4) int (11); free(p4); //RL_ASSERT(false); (void)i1, (void)i2, (void)i3; (void)i4; } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/memory_order.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" template struct order_relaxed_test : rl::test_suite, 2> { std::atomic x1; std::atomic x2; void before() { x1($) = 0; x2($) = 0; } void thread(unsigned th) { if (th) { x1.store(1, order().first, $); x2.store(1, order().first, $); } else { int y2 = x2.load(order().second, $); int y1 = x1.load(order().second, $); //RL_UNTIL(0 == y1 && 0 != y2); (void)y2; (void)y1; } } std::pair order() { switch (index) { default: RL_VERIFY(false); case 0: return std::make_pair(rl::mo_relaxed, rl::mo_relaxed); case 1: return std::make_pair(rl::mo_release, rl::mo_relaxed); case 2: return std::make_pair(rl::mo_seq_cst, rl::mo_relaxed); case 3: return std::make_pair(rl::mo_relaxed, rl::mo_acquire); case 4: return std::make_pair(rl::mo_relaxed, rl::mo_seq_cst); } } }; struct reorder_single_var_test : rl::test_suite { std::atomic x; void before() { x($) = 0; } void thread(unsigned index) { if (index) { x.store(1, rl::memory_order_relaxed); } else { int y1 = x.load(rl::memory_order_relaxed); int y2 = x.load(rl::memory_order_relaxed); RL_ASSERT(y1 == 0 || y2 == 1); } } }; struct acq_rel_test : rl::test_suite { std::atomic x; rl::var y; void before() { x($) = 0; } void thread(unsigned index) { if (index) { VAR(y) = 1; x.store(1, std::memory_order_release); } else { int f = x.load(rl::memory_order_acquire); if (f) { int d = VAR(y); RL_ASSERT(1 == d); } } } }; template struct seq_cst_test : rl::test_suite, 4, (rl::test_result_e)((1 - index) * rl::test_result_until_condition_hit)> { std::atomic x1; std::atomic x2; int res; void before() { x1($) = 0; x2($) = 0; res = 0; } void thread(unsigned th) { if (0 == th) { x1.store(1, order().first, $); } else if (1 == th) { x2.store(1, order().first, $); } else if (2 == th) { int v1 = x1.load(order().second, $); int v2 = x2.load(order().second, $); res += (v1 == 1 && v2 == 0); } else if (3 == th) { int v2 = x2.load(order().second, $); int v1 = x1.load(order().second, $); res += (v2 == 1 && v1 == 0); } } void after() { if ((void)0, 0 == index) { RL_UNTIL(2 == res); } else { RL_ASSERT(2 != res); } } std::pair order() { switch (index) { default: RL_VERIFY(false); case 0: return std::make_pair(rl::mo_release, rl::mo_acquire); case 1: return std::make_pair(rl::mo_seq_cst, rl::mo_seq_cst); } } }; struct modification_order_test : rl::test_suite { std::atomic a; rl::var x; void before() { a($) = 0; x($) = 0; } void thread(unsigned index) { if (index) { x($) = 1; a.store(1, rl::memory_order_release); a.store(2, rl::memory_order_relaxed); } else { if (a.load(rl::memory_order_acquire)) x($).load(); } } }; struct reordering_test : rl::test_suite { std::atomic x; std::atomic y; std::atomic r; void before() { x($) = 0; y($) = 0; r($) = 0; } void thread(unsigned index) { if (0 == index) { x.store(1, rl::memory_order_relaxed); } else if (1 == index) { if (x.load(rl::memory_order_relaxed)) r.store(1, rl::memory_order_relaxed); y.store(1, rl::memory_order_release); } else { if (y.load(rl::memory_order_acquire)) { if (r.load(rl::memory_order_relaxed)) { RL_ASSERT(x.load(rl::memory_order_relaxed)); } } } } }; struct reordering_test2 : rl::test_suite { std::atomic x1; std::atomic x2; std::atomic y; std::atomic r; void before() { std::atomic x (0); char* ch = 0; x.compare_exchange_weak(ch, 0, std::memory_order_seq_cst); x1($) = 0; x2($) = 0; y($) = 0; r($) = 0; } void thread(unsigned index) { if (0 == index) { x1.store(1, rl::memory_order_relaxed); x2.store(1, rl::memory_order_relaxed); } else if (1 == index) { if (x2.load(rl::memory_order_relaxed)) r.store(1, rl::memory_order_relaxed); y.store(1, rl::memory_order_release); } else { if (y.load(rl::memory_order_acquire)) { if (r.load(rl::memory_order_relaxed)) { RL_UNTIL(0 == x1.load(rl::memory_order_relaxed)); } } } } }; struct transitive_test : rl::test_suite { std::atomic x; rl::var y; void before() { x($) = 0; } void thread(unsigned index) { if (0 == index) { VAR(y) = 1; x.fetch_add(1, rl::memory_order_release); } else if (1 == index) { x.fetch_add(2, rl::memory_order_acquire); } else { x.load(rl::memory_order_acquire); int w = x.load(rl::memory_order_acquire); if (1 == w || 3 == w) { y($).load(); } } } }; struct cc_transitive_test : rl::test_suite { std::atomic x; std::atomic y; void before() { x.store(0, std::memory_order_relaxed); y.store(0, std::memory_order_relaxed); } void thread(unsigned index) { if (0 == index) { x.store(1, std::memory_order_relaxed); } else if (1 == index) { if (x.load(std::memory_order_relaxed)) y.store(1, std::memory_order_release); } else { if (y.load(std::memory_order_acquire)) assert(x.load(std::memory_order_relaxed)); } } }; struct occasional_test : rl::test_suite { std::atomic x, y, z; void before() { x.store(0, std::memory_order_relaxed); y.store(0, std::memory_order_relaxed); z.store(0, std::memory_order_relaxed); } void thread(unsigned index) { if (0 == index) { x.store(1, rl::memory_order_relaxed); y.store(1, rl::memory_order_release); } else if (1 == index) { if (y.load(rl::memory_order_relaxed)) z.store(1, rl::memory_order_release); } else { if (z.load(rl::memory_order_acquire)) { RL_ASSERT(y.load(rl::memory_order_relaxed)); RL_UNTIL(0 == x.load(rl::memory_order_relaxed)); } } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc71/test.sln ================================================ Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{8C8174E2-2B2E-484D-9EB4-85D29347F22F}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Debug.ActiveCfg = Debug|Win32 {8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Debug.Build.0 = Debug|Win32 {8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Release.ActiveCfg = Release|Win32 {8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc71/test.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc8/rrd.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peterson", "..\..\example\peterson\msvc8\peterson.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proxy_collector", "..\..\example\proxy_collector\msvc8\proxy_collector.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B29}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ref_counting", "..\..\example\ref_counting\msvc8\ref_counting.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B28}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stack", "..\..\example\stack\msvc8\stack.vcproj", "{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spsc_queue", "..\..\example\spsc_queue\msvc8\spsc_queue.vcproj", "{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condvar", "..\..\example\condvar\msvc8\condvar.vcproj", "{6CC59CF8-408B-441B-8F65-15651210CB82}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smr", "..\..\example\smr\msvc8\smr.vcproj", "{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutex_business_logic", "..\..\example\mutex_business_logic\msvc8\mutex_business_logic.vcproj", "{B03A7216-E196-44C6-8861-C77D90055512}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ws_deque", "..\..\example\ws_deque\msvc8\ws_deque.vcproj", "{0B597F19-DEBB-4832-B520-9A93A286D595}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "..\..\jtest\msvc8\jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "..\..\ntest\msvc8\ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cli_ws_deque", "..\..\example\cli_ws_deque\msvc8\cli_ws_deque.vcproj", "{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "java_ws_deque", "..\..\example\java_ws_deque\msvc8\java_ws_deque.vcproj", "{9E88433F-779E-4461-9963-35E3338873AC}" ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Profile|Win32 = Profile|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.Build.0 = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.ActiveCfg = Profile|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.Build.0 = Profile|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.Build.0 = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.Build.0 = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.Build.0 = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.ActiveCfg = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.Build.0 = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.ActiveCfg = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.Build.0 = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.ActiveCfg = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.Build.0 = Release|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Debug|Win32.ActiveCfg = Debug|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Debug|Win32.Build.0 = Debug|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Profile|Win32.ActiveCfg = Release|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Profile|Win32.Build.0 = Release|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Release|Win32.ActiveCfg = Release|Win32 {2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Release|Win32.Build.0 = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.ActiveCfg = Debug|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.Build.0 = Debug|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.ActiveCfg = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.Build.0 = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.ActiveCfg = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.Build.0 = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.ActiveCfg = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.Build.0 = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.ActiveCfg = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.Build.0 = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.ActiveCfg = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.Build.0 = Release|Win32 {B03A7216-E196-44C6-8861-C77D90055512}.Debug|Win32.ActiveCfg = Debug|Win32 {B03A7216-E196-44C6-8861-C77D90055512}.Debug|Win32.Build.0 = Debug|Win32 {B03A7216-E196-44C6-8861-C77D90055512}.Profile|Win32.ActiveCfg = Release|Win32 {B03A7216-E196-44C6-8861-C77D90055512}.Profile|Win32.Build.0 = Release|Win32 {B03A7216-E196-44C6-8861-C77D90055512}.Release|Win32.ActiveCfg = Release|Win32 {B03A7216-E196-44C6-8861-C77D90055512}.Release|Win32.Build.0 = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.ActiveCfg = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.Build.0 = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.ActiveCfg = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.Build.0 = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.ActiveCfg = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.Build.0 = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.ActiveCfg = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.Build.0 = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.ActiveCfg = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.Build.0 = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32 {967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Debug|Win32.ActiveCfg = Debug|Win32 {967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Debug|Win32.Build.0 = Debug|Win32 {967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Profile|Win32.ActiveCfg = Release|Win32 {967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Profile|Win32.Build.0 = Release|Win32 {967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Release|Win32.ActiveCfg = Release|Win32 {967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Release|Win32.Build.0 = Release|Win32 {9E88433F-779E-4461-9963-35E3338873AC}.Debug|Win32.ActiveCfg = Debug|Win32 {9E88433F-779E-4461-9963-35E3338873AC}.Debug|Win32.Build.0 = Debug|Win32 {9E88433F-779E-4461-9963-35E3338873AC}.Profile|Win32.ActiveCfg = Release|Win32 {9E88433F-779E-4461-9963-35E3338873AC}.Profile|Win32.Build.0 = Release|Win32 {9E88433F-779E-4461-9963-35E3338873AC}.Release|Win32.ActiveCfg = Release|Win32 {9E88433F-779E-4461-9963-35E3338873AC}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc8/rrd.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc8/test.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug64|Win32 = Debug64|Win32 Debug64|x64 = Debug64|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.ActiveCfg = Debug|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.Build.0 = Debug|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|Win32.ActiveCfg = Debug64|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|Win32.Build.0 = Debug64|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|x64.ActiveCfg = Debug64|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|x64.Build.0 = Debug64|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.Build.0 = Profile|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.ActiveCfg = Profile|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.Build.0 = Profile|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.ActiveCfg = Release|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.Build.0 = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.ActiveCfg = Debug64|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.Build.0 = Debug64|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.ActiveCfg = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.Build.0 = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.ActiveCfg = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.Build.0 = Debug64|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc8/test.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc9/rrd.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ref_counting", "..\..\example\ref_counting\msvc9\ref_counting.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B28}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peterson", "..\..\example\peterson\msvc9\peterson.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stack", "..\..\example\stack\msvc9\stack.vcproj", "{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proxy_collector", "..\..\example\proxy_collector\msvc9\proxy_collector.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B29}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "..\..\ntest\msvc9\ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "..\..\jtest\msvc9\jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smr", "..\..\example\smr\msvc9\smr.vcproj", "{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spsc_queue", "..\..\example\spsc_queue\msvc9\spsc_queue.vcproj", "{3F32C4FA-E451-42BC-9E65-74129120B6E4}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condvar", "..\..\example\condvar\msvc9\condvar.vcproj", "{6CC59CF8-408B-441B-8F65-15651210CB82}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ws_deque", "..\..\example\ws_deque\msvc9\ws_deque.vcproj", "{0B597F19-DEBB-4832-B520-9A93A286D595}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples", "..\..\example\examples\msvc9\examples.vcproj", "{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Profile|Win32 = Profile|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.Build.0 = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.Build.0 = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.Build.0 = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32 {D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.ActiveCfg = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.Build.0 = Debug|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.ActiveCfg = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.Build.0 = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.ActiveCfg = Release|Win32 {4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.Build.0 = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.ActiveCfg = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.Build.0 = Debug|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.ActiveCfg = Profile|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.Build.0 = Profile|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.ActiveCfg = Release|Win32 {31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.ActiveCfg = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.Build.0 = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.ActiveCfg = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.Build.0 = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32 {1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.ActiveCfg = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.Build.0 = Debug|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.ActiveCfg = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.Build.0 = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.ActiveCfg = Release|Win32 {BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.Build.0 = Release|Win32 {3F32C4FA-E451-42BC-9E65-74129120B6E4}.Debug|Win32.ActiveCfg = Debug|Win32 {3F32C4FA-E451-42BC-9E65-74129120B6E4}.Debug|Win32.Build.0 = Debug|Win32 {3F32C4FA-E451-42BC-9E65-74129120B6E4}.Profile|Win32.ActiveCfg = Release|Win32 {3F32C4FA-E451-42BC-9E65-74129120B6E4}.Profile|Win32.Build.0 = Release|Win32 {3F32C4FA-E451-42BC-9E65-74129120B6E4}.Release|Win32.ActiveCfg = Release|Win32 {3F32C4FA-E451-42BC-9E65-74129120B6E4}.Release|Win32.Build.0 = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.ActiveCfg = Debug|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.Build.0 = Debug|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.ActiveCfg = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.Build.0 = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.ActiveCfg = Release|Win32 {6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.Build.0 = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.ActiveCfg = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.Build.0 = Debug|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.ActiveCfg = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.Build.0 = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.ActiveCfg = Release|Win32 {0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.Build.0 = Release|Win32 {1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Debug|Win32.ActiveCfg = Debug|Win32 {1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Debug|Win32.Build.0 = Debug|Win32 {1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Profile|Win32.ActiveCfg = Release|Win32 {1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Profile|Win32.Build.0 = Release|Win32 {1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Release|Win32.ActiveCfg = Release|Win32 {1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc9/rrd.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc9/test.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.ActiveCfg = Debug|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.Build.0 = Debug|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.Build.0 = Profile|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.ActiveCfg = Profile|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.Build.0 = Profile|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.ActiveCfg = Release|x64 {99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.Build.0 = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.ActiveCfg = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.Build.0 = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/msvc9/test.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/mutex.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct test_mutex : rl::test_suite { rl::mutex mtx; rl::var data; void before() { data($) = 0; } void after() { RL_ASSERT(data($) == 3); } void thread(unsigned /*index*/) { mtx.lock($); data($) += 1; mtx.unlock($); } }; struct test_deadlock : rl::test_suite { rl::mutex mtx1; rl::mutex mtx2; void thread(unsigned index) { if (0 == index) { mtx1.lock($); mtx2.lock($); mtx1.unlock($); mtx2.unlock($); } else { mtx2.lock($); mtx1.lock($); mtx1.unlock($); mtx2.unlock($); } } }; struct test_deadlock2 : rl::test_suite { std::mutex m; std::atomic f; void before() { f($) = 0; } void thread(unsigned index) { if (index) { m.lock($); f($) = 1; for (int i = 0; i != 100; ++i) rl::yield(1, $); } else { while (0 == f($)) rl::yield(1, $); m.lock($); } } }; struct test_mutex_destuction : rl::test_suite { void thread(unsigned) { std::mutex* m = new std::mutex; m->lock($); delete m; } }; struct test_mutex_destuction2 : rl::test_suite { std::mutex* m; std::atomic f; void before() { m = new std::mutex; f($) = 0; } void thread(unsigned index) { if (0 == index) { m->lock($); f($) = 1; while (1 == f($)) rl::yield(1, $); m->unlock($); } else { while (0 == f($)) rl::yield(1, $); delete m; f($) = 2; } } }; struct test_mutex_recursion : rl::test_suite { std::recursive_mutex mtx; rl::var data; void before() { data($) = 0; } void after() { RL_ASSERT(data($) == 2); } void thread(unsigned /*index*/) { mtx.lock($); mtx.lock($); data($) += 1; mtx.unlock($); mtx.unlock($); } }; struct test_mutex_try_lock : rl::test_suite { std::recursive_mutex mtx; rl::var data; void before() { data($) = 0; } void after() { RL_ASSERT(data($) == 2); } void thread(unsigned /*index*/) { while (false == mtx.try_lock($)) rl::yield(1, $); RL_ASSERT(mtx.try_lock($)); data($) += 1; mtx.unlock($); mtx.unlock($); } }; struct test_mutex_recursion_error : rl::test_suite { void thread(unsigned) { std::mutex m; m.lock($); m.lock($); } }; struct test_mutex_unlock_error : rl::test_suite { void thread(unsigned) { std::mutex m; m.lock($); m.unlock($); m.unlock($); } }; struct test_mutex_leak : rl::test_suite { void thread(unsigned) { char* p = new char [sizeof(std::mutex)]; new (p) std::mutex(); delete [] p; } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/ntest/msvc8/ntest.sln ================================================  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc8\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/ntest/msvc8/ntest.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/ntest/msvc9/ntest.sln ================================================  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc9\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32 {D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32 {D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/ntest/msvc9/ntest.vcproj ================================================ ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/ntest/ntest.cpp ================================================ #include "stdafx.h" #include "../relacy/relacy_cli.hpp" using rl::nvar; using rl::nvolatile; using rl::mutex; template class ws_deque { public: ws_deque() { m_mask($) = initial_size - 1; m_headIndex($) = 0; m_tailIndex($) = 0; m_array($) = new nvar [initial_size]; m_arraySize($) = initial_size; } bool IsEmpty() { return m_headIndex($) >= m_tailIndex($); } size_t Count() { return m_tailIndex($) - m_headIndex($); } void push(T item) { size_t tail = m_tailIndex($); // original version: //if (tail < m_headIndex($) + m_mask($)) // corrected version: if (tail <= m_headIndex($) + m_mask($)) { m_array($)[tail & m_mask($)]($) = item; m_tailIndex($) = tail + 1; } else { m_foreignLock.lock($); size_t head = m_headIndex($); size_t count = Count(); if (count >= m_mask($)) { size_t arraySize = m_arraySize($); size_t mask = m_mask($); nvar* newArray = new nvar [arraySize * 2]; nvar* arr = m_array($); // original version: //for (size_t i = 0; i != arraySize; ++i) // corrected version: for (size_t i = 0; i != count; ++i) newArray[i]($) = arr[(i + head) & mask]($); m_array($) = newArray; m_arraySize($) = arraySize * 2; m_headIndex($) = 0; m_tailIndex($) = count; tail = count; m_mask($) = (mask * 2) | 1; } m_array($)[tail & m_mask($)]($) = item; m_tailIndex($) = tail + 1; m_foreignLock.unlock($); } } bool pop(T& item) { size_t tail = m_tailIndex($); // original version: //if (m_headIndex($) >= tail) // return false; // corrected version: if (tail == 0) return false; tail -= 1; rl::Interlocked::Exchange(m_tailIndex, tail, $); if (m_headIndex($) <= tail) { item = m_array($)[tail & m_mask($)]($); return true; } else { m_foreignLock.lock($); if (m_headIndex($) <= tail) { item = m_array($)[tail & m_mask($)]($); m_foreignLock.unlock($); return true; } else { m_tailIndex($) = tail + 1; m_foreignLock.unlock($); return false; } } } bool steal(T& item) { if (false == m_foreignLock.try_lock($)) return false; size_t head = m_headIndex($); rl::Interlocked::Exchange(m_headIndex, head + 1, $); if (head < m_tailIndex($)) { item = m_array($)[head & m_mask($)]($); m_foreignLock.unlock($); return true; } else { m_headIndex($) = head; m_foreignLock.unlock($); return false; } } private: static size_t const initial_size = 2; nvar*> m_array; nvar m_mask; nvar m_arraySize; nvolatile m_headIndex; nvolatile m_tailIndex; mutex m_foreignLock; }; struct ws_deque_test : rl::test_suite { ws_deque q; bool state [2]; void before() { state[0] = true; state[1] = true; } void after() { RL_ASSERT(state[0] == false); RL_ASSERT(state[1] == false); } void thread(unsigned index) { if (0 == index) { q.push(1); q.push(2); int item = 0; bool res = q.pop(item); RL_ASSERT(res && item == 2); RL_ASSERT(state[1]); state[1] = false; item = 0; res = q.pop(item); if (res) { RL_ASSERT(state[0]); state[0] = false; } item = 0; res = q.pop(item); RL_ASSERT(res == false); } else { int item = 0; bool res = q.steal(item); if (res) { RL_ASSERT(item == 1); RL_ASSERT(state[0]); state[0] = false; } } } }; struct test_api : rl::test_suite { void thread(unsigned) { rl::nvar cv1, cv2(3), cv3(cv1($)), cv4(cv1); cv1($) = cv2($); cv1($) = 1; (int)cv1($); cv1($) += 1; cv1($) -= 1; cv1($)++; cv1($)--; ++cv1($); --cv1($); int x = rl::Interlocked::Add(cv1, 3, $); x = rl::Interlocked::CompareExchange(cv1, 3, x, $); x = rl::Interlocked::Exchange(cv2, 6, $); x = rl::Interlocked::Read(cv2, $); x = rl::Interlocked::Increment(cv2, $); x = rl::Interlocked::Decrement(cv2, $); rl::Thread::MemoryBarrier($); x = rl::Thread::VolatileRead(cv1, $); rl::Thread::VolatileWrite(cv1, 5, $); rl::Thread::SpinWait(1, $); } }; struct ws_deque_test0 : rl::test_suite { ws_deque q; void before() { } void after() { } void thread(unsigned index) { if (0 == index) { for (size_t i = 0; i != 4; ++i) { q.push(10); } for (size_t i = 0; i != 5; ++i) { int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 4; ++i) { q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 4; ++i) { q.push(10); q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); p = 0; res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 4; ++i) { q.push(10); q.push(10); q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } for (size_t i = 0; i != 14; ++i) { q.push(10); int p = 0; bool res = q.pop(p); RL_ASSERT(10 == p || false == res); } } else { for (size_t i = 0; i != 4; ++i) { int p = 0; bool res = q.steal(p); RL_ASSERT(10 == p || false == res); } } } }; int main() { rl::test_params p; p.iteration_count = 1000; rl::simulate(p); rl::simulate(p); rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/ntest/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/ntest/stdafx.h ================================================ #ifndef STDAFX_H #define STDAFX_H #ifdef _MSC_VER # pragma once #endif #include "../relacy/pch.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/pthread.hpp ================================================ #pragma once #include "../relacy/pthread.h" struct test_pthread_thread : rl::test_suite { static size_t const dynamic_thread_count = 2; VAR_T(int) data; static void* func(void* param) { static_cast(param)->VAR(data) += 1; return 0; } void thread(unsigned) { VAR(data) = 0; pthread_t th1; pthread_create(&th1, 0, &test_pthread_thread::func, this); void* res1 = 0; pthread_join(th1, &res1); RL_ASSERT(VAR(data) == 1); pthread_t th2; pthread_create(&th2, 0, &test_pthread_thread::func, this); void* res2 = 0; pthread_join(th2, &res2); RL_ASSERT(VAR(data) == 2); } }; struct test_pthread_mutex : rl::test_suite { pthread_mutex_t mtx; VAR_T(int) data; void before() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mtx, &attr); pthread_mutexattr_destroy(&attr); VAR(data) = 0; } void after() { pthread_mutex_destroy(&mtx); } void thread(unsigned /*index*/) { pthread_mutex_lock(&mtx); VAR(data) += 1; pthread_mutex_unlock(&mtx); if (0 == pthread_mutex_try_lock(&mtx)) { VAR(data) += 1; pthread_mutex_unlock(&mtx); } //pthread_mutex_timedlock } }; struct test_pthread_condvar : rl::test_suite { pthread_cond_t cv; pthread_mutex_t mtx; VAR_T(int) stage; void before() { pthread_condattr_t attr; pthread_cond_init(&cv, &attr); pthread_mutex_init(&mtx, 0); VAR(stage) = 0; } void after() { pthread_cond_destroy(&cv); pthread_mutex_destroy(&mtx); } void thread(unsigned index) { if (0 == index) { pthread_mutex_lock(&mtx); VAR(stage) += 1; pthread_cond_broadcast(&cv); while (VAR(stage) != 2) pthread_cond_wait(&cv, &mtx); pthread_mutex_unlock(&mtx); } else if (1 == index) { pthread_mutex_lock(&mtx); while (VAR(stage) != 1) { int ts = 1; pthread_cond_timedwait(&cv, &mtx, &ts); } VAR(stage) += 1; pthread_cond_broadcast(&cv); pthread_mutex_unlock(&mtx); } else if (2 == index) { pthread_mutex_lock(&mtx); while (VAR(stage) != 2) pthread_cond_wait(&cv, &mtx); pthread_mutex_unlock(&mtx); pthread_cond_signal(&cv); } } }; struct test_pthread_condvar2 : rl::test_suite { pthread_cond_t cv1, cv2; pthread_mutex_t mtx1, mtx2; VAR_T(int) stage; void before() { pthread_cond_init(&cv1, 0); pthread_cond_init(&cv2, 0); pthread_mutex_init(&mtx1, 0); pthread_mutex_init(&mtx2, 0); VAR(stage) = 0; } void after() { pthread_cond_destroy(&cv1); pthread_cond_destroy(&cv2); pthread_mutex_destroy(&mtx1); pthread_mutex_destroy(&mtx2); } void thread(unsigned index) { if (0 == index) { pthread_mutex_lock(&mtx1); int ts = 1; pthread_cond_timedwait(&cv1, &mtx1, &ts); pthread_mutex_unlock(&mtx1); } else if (1 == index) { pthread_mutex_lock(&mtx2); int ts = 1; pthread_cond_timedwait(&cv2, &mtx2, &ts); pthread_mutex_unlock(&mtx2); } } }; struct test_pthread_rwlock : rl::test_suite { pthread_rwlock_t mtx; VAR_T(int) data; void before() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); pthread_rwlock_init(&mtx, &attr); pthread_mutexattr_destroy(&attr); VAR(data) = 0; } void after() { pthread_rwlock_destroy(&mtx); } void thread(unsigned /*index*/) { pthread_rwlock_wrlock(&mtx); VAR(data) += 1; pthread_rwlock_unlock(&mtx); if (0 == pthread_rwlock_trywrlock(&mtx)) { VAR(data) += 1; pthread_rwlock_unlock(&mtx); } pthread_rwlock_rdlock(&mtx); (void)(int)VAR(data); pthread_rwlock_unlock(&mtx); if (0 == pthread_rwlock_tryrdlock(&mtx)) { (void)(int)VAR(data); pthread_rwlock_unlock(&mtx); } } }; struct test_pthread_sem : rl::test_suite { sem_t sem1, sem2; VAR_T(int) data; void before() { sem_init(&sem1, 0, 0); sem_init(&sem2, 0, 0); VAR(data) = 0; } void after() { sem_destroy(&sem1); sem_destroy(&sem2); } void thread(unsigned index) { if (index) { VAR(data) = 1; sem_post(&sem1); while (sem_trywait(&sem2)) { assert(errno == EINTR || errno == EAGAIN); pthread_yield(); } RL_ASSERT(VAR(data) == 2); VAR(data) = 3; int count = -1; sem_getvalue(&sem2, &count); RL_ASSERT(count == 0); sem_post(&sem2); sem_getvalue(&sem2, &count); RL_ASSERT(count == 1); } else { while (sem_wait(&sem1)) assert(errno == EINTR); RL_ASSERT(VAR(data) == 1); VAR(data) = 2; sem_post(&sem2); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/scheduler.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct livelock_test : rl::test_suite { std::atomic x; void before() { x($) = 0; } void thread(unsigned index) { if (0 == index) { for (;;) { int cmp = 1; if (x($).compare_exchange_weak(cmp, 2)) break; } } else if (1 == index) { x($).store(1); } } }; struct yield_livelock_test : rl::test_suite { std::atomic x, y; void before() { x($) = 0; y($) = 0; } void thread(unsigned index) { if (0 == index) { rl::backoff b; for (;;) { int cmp = 0; if (x($).compare_exchange_weak(cmp, 1)) { cmp = 0; if (y($).compare_exchange_weak(cmp, 1)) { x($).store(0); y($).store(0); break; } else { x($).store(0); } } b.yield($); } } else if (1 == index) { rl::backoff b; for (;;) { int cmp = 0; if (y($).compare_exchange_weak(cmp, 1)) { cmp = 0; if (x($).compare_exchange_weak(cmp, 1)) { y($).store(0); x($).store(0); break; } else { y($).store(0); } } b.yield($); } } } }; struct sched_load_test : rl::test_suite { std::recursive_mutex mtx1, mtx2; std::condition_variable_any cv1, cv2; VAR_T(int) data1, data2; void before() { } void thread(unsigned index) { if (index % 2) { mtx1.lock($); VAR(data1) = 1; mtx1.unlock($); mtx2.lock($); mtx2.lock($); VAR(data2) = 1; mtx2.unlock($); mtx2.unlock($); if (mtx1.try_lock($)) { //mtx1.lock($); VAR(data1) = 1; //mtx1.unlock($); mtx1.unlock($); } mtx1.lock($); VAR(data1) = 2; cv1.notify_all($); mtx1.unlock($); mtx2.lock($); while (VAR(data2) != 2) { rl::yield(1, $); cv2.wait_for(mtx2, 1, $); } mtx2.unlock($); } else { mtx2.lock($); VAR(data2) = 1; mtx2.unlock($); mtx1.lock($); mtx1.lock($); VAR(data1) = 1; mtx1.unlock($); mtx1.unlock($); if (mtx2.try_lock($)) { //mtx2.lock($); VAR(data2) = 1; //mtx2.unlock($); mtx2.unlock($); } mtx2.lock($); VAR(data2) = 2; mtx2.unlock($); cv2.notify_all($); mtx1.lock($); while (VAR(data1) != 2) { rl::yield(1, $); cv1.wait_for(mtx1, 1, $); } mtx1.unlock($); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/semaphore.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct test_semaphore : rl::test_suite { HANDLE sema; VAR_T(int) data; void before() { VAR(data) = 0; sema = CreateSemaphore(0, 0, 2, 0); } void after() { CloseHandle(sema); } void thread(unsigned index) { if (0 == index) { VAR(data) = 1; ReleaseSemaphore(sema, 1, 0); } else { unsigned rv = WaitForSingleObject(sema, INFINITE); assert(rv == WAIT_OBJECT_0); assert(VAR(data) == 1); rv = WaitForSingleObject(sema, 0); assert(rv == WAIT_TIMEOUT); } } }; struct test_semaphore_atomic : rl::test_suite { HANDLE sem [2]; void before() { sem[0] = CreateSemaphore(0, 0, 2, 0); sem[1] = CreateSemaphore(0, 0, 2, 0); } void after() { CloseHandle(sem[0]); CloseHandle(sem[1]); } void thread(unsigned index) { if (0 == index) { unsigned rv = WaitForSingleObject(sem[0], INFINITE); assert(rv == WAIT_OBJECT_0); ReleaseSemaphore(sem[1], 1, 0); rv = WaitForSingleObject(sem[1], 0); assert(rv == WAIT_TIMEOUT); } else { unsigned rv = SignalObjectAndWait(sem[0], sem[1], INFINITE, 0); assert(rv == WAIT_OBJECT_0); rv = WaitForSingleObject(sem[1], 0); assert(rv == WAIT_TIMEOUT); rv = WaitForSingleObject(sem[0], 0); assert(rv == WAIT_TIMEOUT); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/stdafx.h ================================================ #ifndef STDAFX_H #define STDAFX_H #ifdef _MSC_VER # pragma once #endif #ifdef _MSC_VER # pragma warning (disable: 4127) #endif #if defined(_MSC_VER) && (_MSC_VER <= 1310) //# pragma warning (disable: 4511) //# pragma warning (disable: 4512) #endif #ifdef NDEBUG # define _SECURE_SCL 0 #endif #include "../relacy/pch.hpp" #endif ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/thread_local.hpp ================================================ #pragma once #include "../relacy/relacy.hpp" struct tls_basic_test : rl::test_suite { rl::thread_local_var x; void thread(unsigned index) { RL_ASSERT(x.get($) == 0); x.set(index + 10, $); RL_ASSERT(x.get($) == index + 10); } }; struct tls_basic_test2 : rl::test_suite { TLS_T(unsigned) x; void thread(unsigned index) { RL_ASSERT(VAR(x) == 0); VAR(x) = index + 10; RL_ASSERT(VAR(x) == index + 10); } }; struct tls_reset_test : rl::test_suite { rl::thread_local_var x; void thread(unsigned index) { RL_ASSERT(x.get($) == 0); x.set(index + 10, $); RL_ASSERT(x.get($) == index + 10); RL_ASSERT(false); } }; rl::thread_local_var tls_global_test_x; struct tls_global_test : rl::test_suite { void thread(unsigned index) { RL_ASSERT(tls_global_test_x.get($) == 0); tls_global_test_x.set(index + 10, $); RL_ASSERT(tls_global_test_x.get($) == index + 10); RL_ASSERT(false); } }; struct tls_win32_test : rl::test_suite { unsigned long slot; void before() { slot = TlsAlloc(); } void after() { TlsFree(slot); } void thread(unsigned index) { RL_ASSERT(TlsGetValue(slot) == 0); TlsSetValue(slot, (void*)(uintptr_t)(index + 10)); RL_ASSERT(TlsGetValue(slot) == (void*)(uintptr_t)(index + 10)); } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/todo.txt ================================================ Relacy Race Detector Todo List: - use indirection and indices for TLS, because on Windows TLS index is DWORD (not DWORD_PTR) (eliminate pointers?) + provide rl::hash_ptr() - support for fair timed waits + remove iteration count estimation from full sched -> causes division by 0 - history: memory allocation before object ctor (new T (...)) + code in test::after() affects iteration count with full scheduler -> final and estimated iteration counts are the same - non-deterministic sub-expression calculation: foo(bar.load(std::memory_order_acquire), baz.load(std::memory_order_acquire)); - post issue: can't simulate some modification orders in presence of data-races-type-2 for atomic vars: //thread 1 x.store(1, std::memory_order_relaxed); y.store(1, std::memory_order_relaxed); //thread 2 while (y.load(std::memory_order_relaxed) == 0 {} x.store(2, std::memory_order_relaxed); -> modification order of 'x' will never be "2, 1" [CORE] - initially run threads one by one - initially run some iterations twice, in order to check that unit-test is deterministic ? add unique identifiers to atomics, vars, mutexes etc (address can be useful too) - example catalog (description, used techniques, what error is found) - do I need sched() before atomic loads? - do I need sched() before mutex unlock? - for loads output in history value of which store is loaded - detect dead-code - output which operations cause data race ? output happens-before matrix, synchronizes-with matrix etc - SEH handler to catch paging faults - sched before malloc/free to allow more ABA [PERF] - implement performance simulation - cacheline transfers - atomic rmw operations - fences [OTHER] - parallelize the run-time for random scheduler - parallelize the run-time for tree search scheduler - manual control over scheduler - persistent checkpointing of scheduler state (to allow "continue") - atomic blocks (pdr implementation -> pdr component) ? state space reductions (sleep sets, dynamic persistent sets) ? what can I do with serialization points -> user specifies "visible" results system checks for linearizablity -> "visible" results equal to some sequential execution ? save program state inside iteration (save point), continue other iterations from this save point ? partial order reductions by memorizing happens-before graphs, not program state ? estimate progress by seeing how many iterations it gets to move 0->1 on some stree level ? lower bound, upper bound, mean of progress O(X) = (P^(C + 3)) * (N^(P + C + 1)) * (P + C)! ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/trash/original.hpp ================================================ Here is a recent version of the revised pc_sample.c which uses inline x86 ASM and compiles under VC++ (I am planning on coding the entire thing in pure assembly language): ____________________________________________________________________ #if ! defined(PC_SAMPLE_INCLUDE_H) # define PC_SAMPLE_INCLUDE_H # pragma warning(push) # pragma warning (disable : 4100 4505 4706) # if defined(__cplusplus) extern "C" { # endif /*===========================================================*/ /* Very Simple x86 Atomic Operations API & Implmentation _____________________________________________________________*/ typedef __int32 atomicword; typedef atomicword volatile* const atomicword_pthis; static int x86_DWCASPTR( void volatile* const, void* const, void const* const ); static atomicword x86_XADDWORD( atomicword_pthis, atomicword const ); static atomicword x86_XCHGWORD( atomicword_pthis, atomicword const ); __declspec(naked) int x86_DWCASPTR( void volatile* const _pthis, void* const pcmp, void const* const pxhcg ) { _asm { PUSH ESI PUSH EBX MOV ESI, [ESP + 16] MOV EAX, [ESI] MOV EDX, [ESI + 4] MOV ESI, [ESP + 20] MOV EBX, [ESI] MOV ECX, [ESI + 4] MOV ESI, [ESP + 12] LOCK CMPXCHG8B QWORD PTR [ESI] JNE x86_DWCASPTR_failed MOV EAX, 1 POP EBX POP ESI RET x86_DWCASPTR_failed: MOV ESI, [ESP + 16] MOV [ESI], EAX MOV [ESI + 4], EDX MOV EAX, 0 POP EBX POP ESI RET } } __declspec(naked) atomicword x86_XADDWORD( atomicword_pthis _pthis, atomicword const value ) { _asm { MOV EDX, [ESP + 4] MOV EAX, [ESP + 8] LOCK XADD [EDX], EAX RET } } __declspec(naked) atomicword x86_XCHGWORD( atomicword_pthis _pthis, atomicword const value ) { _asm { MOV EDX, [ESP + 4] MOV EAX, [ESP + 8] XCHG [EDX], EAX RET } } #define x86_XCHGPTR(mp_pdest, mp_src) ( \ (void*)x86_XCHGWORD( \ ((atomicword_pthis)(mp_pdest)), \ ((atomicword const)(mp_src)) \ ) \ ) #define XCHGWORD x86_XCHGWORD #define XCHGPTR x86_XCHGPTR #define XADDWORD x86_XADDWORD #define DWCASPTR x86_DWCASPTR /* Proxy-Collector API & Implmentation (Revisited) ;^) Inventor: Chris M. Thomasson _____________________________________________________________*/ #include #include #if ! defined(NDEBUG) # include #endif #define CONTAINER_OF(mp_this, mp_type, mp_member) ( \ (mp_type*)(((unsigned char*)(mp_this)) - \ offsetof(mp_type, mp_member)) \ ) typedef struct pc_region_s pc_region, pc_node; typedef struct pc_master_s pc_master; typedef void (pc_fp_dtor) (pc_node*); typedef struct pc_sys_anchor_s pc_sys_anchor; struct pc_sys_anchor_s { atomicword refcnt; pc_region* region; }; struct pc_region_s { pc_sys_anchor next; pc_node* defer; }; struct pc_master_s { pc_sys_anchor head; pc_region region; pc_fp_dtor* fp_dtor; }; #define PC_MASTER_STATICINIT(mp_this, mp_fp_dtor) { \ { 0, &(mp_this)->region }, \ { { 0, NULL }, NULL }, (mp_fp_dtor) \ } static void pc_sys_dtor( pc_master* const, pc_region* const ); static void pc_init( pc_master* const, pc_fp_dtor* const ); static void pc_node_init( pc_node* const ); static void pc_node_link( pc_node* const, pc_node* const ); static pc_region* pc_acquire( pc_master* const ); static void pc_release( pc_master* const, pc_region* const ); static void pc_defer( pc_region* const, pc_node* const ); static void pc_mutate( pc_master* const, pc_node* const ); void pc_init( pc_master* const _this, pc_fp_dtor* const fp_dtor ) { pc_master src = { { 0 } }; *_this = src; _this->head.region = &_this->region; _this->fp_dtor = fp_dtor; } pc_region* pc_acquire( pc_master* const _this ) { pc_sys_anchor cmp = _this->head, xchg; do { xchg.refcnt = cmp.refcnt + 2; xchg.region = cmp.region; } while (! DWCASPTR(&_this->head, &cmp, &xchg)); return cmp.region; } void pc_release( pc_master* const _this, pc_region* const region ) { if (XADDWORD(®ion->next.refcnt, -2) == 3) { pc_sys_dtor(_this, region); } } void pc_node_init( pc_node* const _this ) { pc_node src = { { 0 } }; *_this = src; } void pc_node_link( pc_node* const _this, pc_node* const next ) { _this->defer = next; } void pc_defer( pc_region* const _this, pc_node* const node ) { node->defer = XCHGPTR(&_this->defer, node); } void pc_mutate( pc_master* const _this, pc_node* const node ) { pc_sys_anchor cmp = _this->head, xchg = { 0 }; node->next.refcnt = 2; node->next.region = NULL; xchg.region = node; while (! DWCASPTR(&_this->head, &cmp, &xchg)); cmp.region->next.region = node; if (XADDWORD(&cmp.region->next.refcnt, cmp.refcnt + 1) == -cmp.refcnt) { pc_sys_dtor(_this, cmp.region); } } void pc_sys_dtor( pc_master* const _this, pc_region* const region ) { int dtors = 0, reset = 0; pc_region* head = region; pc_region* tail = region; pc_region* next = region->next.region; while (next) { if (XADDWORD(&next->next.refcnt, -2) != 3) { break; } tail = next; next = next->next.region; } tail->next.region = NULL; while (head) { pc_region* const next = head->next.region; pc_node* defer = head->defer; assert(head->next.refcnt == 1); if (head != &_this->region) { head->defer = defer; defer = head; } else { reset = 1; } while (defer) { pc_node* const next = defer->defer; _this->fp_dtor(defer); ++dtors; defer = next; } head = next; } if (reset) { _this->region.defer = NULL; pc_mutate(_this, &_this->region); } #if ! defined(NDEBUG) { static atomicword g_pc_sys_epoch = 0; atomicword const epoch = XADDWORD(&g_pc_sys_epoch, 1); if (dtors) { printf("pc_sys_dtor::epoch/dtors(%d/%d)\n", epoch, dtors); } } #endif } /*===========================================================*/ # if defined(__cplusplus) } # endif # pragma warning(pop) #endif ____________________________________________________________________ struct foo_node { foo_node* next; pc_node pcn; }; struct foo_list { foo_node* head; pc_master pc; }; static foo_list g_list = { NULL, PC_MASTER_STATICINIT() }; void foo_node_dtor(pc_node* pcn) { foo_node* const _this = container_of(pcn, foo_node, pcn); free(_this); } void foo_reader() { int i; foo_node* node; pc_region* pcr = pc_acquire(&g_list.pc); for (i = 1 ;; ++i) { node = LOAD_DEPENDS(&g_list.head); while (node) { foo_node* const next = LOAD_MBDEPEND(&node->next); [...]; node = next; } if (! (i % 1000)) { pc_release(&g_list.pc, pcr); pcr = pc_acquire(&g_list.pc); } } pc_release(&g_list.pc, pcr); } void foo_writer() { int i; foo_node* node, *cmp; pc_region* pcr = pc_acquire(&g_list.pc); for (i = 1 ;; ++i) { if (i % 10) { node = malloc(sizeof(*node)); if (node) { foo_node* cmp; pc_node_init(node, NULL, foo_node_dtor); cmp = g_list.head; do { node->next = cmp; } while (! CASIBM_MBREL(&g_list.head, &cmp, node)); } } else { node = g_list.head; do { if (! node) { break; } } while (! CASIBM_MBACQ(&g_list.head, &node, node->next)); if (node) { if (! (i % 20)) { pc_mutate(&g_list.pc, &node->pcn); } else { pc_defer(pcr, &node->pcn); } } } if (! (i % 500)) { pc_release(&g_list.pc, pcr); pcr = pc_acquire(&g_list.pc); } } pc_release(&g_list.pc, pcr); } 1. Region 1 is current 2. Thread 1 acquires region 1 3. Thread 2 executes pc_mutate() 4. Region 2 is current 5. Thread 3 acquires region 2 6. Thread 3 loads pointer to node 1 7. Thread 1 removes node 1 from data structure 8. Thread 1 executes pc_defer() and defers node 1 to region 1 9. Thread 1 releases region 1 10. Dtor executed for region 1, node 1 is deleted 11. Thread 3 accesses node 1 12. Bang! ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/trash/rtl.hpp ================================================ #pragma once #include "../../relacy/relacy_std.hpp" intptr_t const lock_value = (intptr_t)-1; struct rdesc { rl::var const*> addr; rl::var cmp; }; struct wdesc { rl::var*> addr; rl::var cmp; rl::var xchg; }; struct trx { static size_t const rset_max_size = 64; static size_t const wset_max_size = 32; rl::var rset_idx; rl::var wset_idx; rdesc rset [rset_max_size]; wdesc wset [wset_max_size]; rl::var read(std::atomic const* addr, std::memory_order mo = std::memory_order_relaxed) { intptr_t value = (*addr)($).load(mo); if (lock_value == value) return 0; rdesc* desc = &rset[rset_idx($)]; ++rset_idx($); desc->addr($) = addr; desc->cmp($) = value; return desc; } rl::var write(std::atomic* addr) { intptr_t value = (*addr)($).swap(lock_value, rl::memory_order_acq_rel); if (lock_value == value) return 0; wdesc* desc = &wset[wset_idx($)]; ++wset_idx($); desc->addr($) = addr; desc->cmp($) = value; return desc; } bool begin() { std::atomic_signal_fence($)(std::memory_order_acquire); rset_idx($) = 0; wset_idx($) = 0; return true; } bool commit() { std::atomic_signal_fence($)(std::memory_order_release); size_t i; for (i = 0; i != rset_idx($); ++i) { rdesc const* desc = &rset[i]; if ((*(desc->addr($)))($).load(std::memory_order_relaxed) != desc->cmp($)) break; } if (i != rset_idx($)) { return rollback(); } std::atomic_thread_fence($)(std::memory_order_release); for (i = 0; i != wset_idx($); ++i) { wdesc const* desc = &wset[i]; (*(desc->addr($)))($).store(desc->xchg($), std::memory_order_relaxed); } //std::atomic_thread_fence(std::memory_order_acq_rel); return true; } bool rollback() { for (size_t i = 0; i != wset_idx($); ++i) { wdesc const* desc = &wset[i]; (*(desc->addr($)))($).store(desc->cmp($), std::memory_order_relaxed); } wset_idx($) = 0; rset_idx($) = 0; return false; } /* bool readset_validate() { for (size_t i = 0; i != rset_idx; ++i) { rdesc const* desc = &rset[i]; if (*(intptr_t const volatile*)desc->addr != desc->cmp) return true; } return false; } bool writeset_load(intptr_t* addr, intptr_t* value) { for (size_t i = 0; i != wset_idx; ++i) { wdesc const* desc = &wset[i]; if (desc->addr == addr) { *value = desc->xchg; return true; } } return false; } */ }; inline void pdr_lock() { } inline void pdr_unlock() { } inline void pdr_acquire(void*) { } inline void pdr_release(void*) { } inline void pdr_dispose(void*) { } struct dlist_trx_node { std::atomic prev; // dlist_trx_node* std::atomic next; // dlist_trx_node* rl::var key; rl::var value; dlist_trx_node(intptr_t key = 0, intptr_t value = 0) : key(key) , value(value) {} }; class dlist_trx { public: dlist_trx() : first(0, 0) , last(0, 0) { first.prev($).store(0, std::memory_order_relaxed); first.next($).store((intptr_t)&last, std::memory_order_relaxed); last.prev($).store((intptr_t)&first, std::memory_order_relaxed); last.next($).store(0, std::memory_order_relaxed); } __declspec(noinline) void remove(dlist_trx_node* node) { pdr_lock(); for (trx t; t.begin(); t.rollback()) { rdesc* r1 = t.read(&node->prev)($); if (0 == r1) continue; dlist_trx_node* prev = (dlist_trx_node*)(intptr_t)r1->cmp($); rdesc* r2 = t.read(&node->next)($); if (0 == r2) continue; dlist_trx_node* next = (dlist_trx_node*)(intptr_t)r2->cmp($); wdesc* w1 = t.write(&prev->next)($); if (0 == w1) continue; //dlist_trx_node* prev_next = (dlist_trx_node*)w1->cmp; wdesc* w2 = t.write(&next->prev)($); if (0 == w2) continue; //dlist_trx_node* next_prev = (dlist_trx_node*)w2->cmp; w1->xchg($) = (intptr_t)next; w2->xchg($) = (intptr_t)prev; if (t.commit()) break; } pdr_unlock(); } __declspec(noinline) void insert(dlist_trx_node* node) { pdr_lock(); for (trx t; t.begin(); t.rollback()) { wdesc* w1 = t.write(&first.next)($); if (0 == w1) continue; dlist_trx_node* next = (dlist_trx_node*)(intptr_t)w1->cmp($); wdesc* w2 = t.write(&next->prev)($); if (0 == w2) continue; dlist_trx_node* const& prev = (dlist_trx_node*)(intptr_t)w2->cmp($); if (prev != &first) continue; node->prev($).store((intptr_t)prev, std::memory_order_relaxed); node->next($).store((intptr_t)next, std::memory_order_relaxed); w1->xchg($) = (intptr_t)node; w2->xchg($) = (intptr_t)node; if (t.commit()) break; } pdr_unlock(); } __declspec(noinline) void foreach(void (*f)(void*, dlist_trx_node*), void (*reset)(void*), void* ctx) { pdr_lock(); for (trx t; t.begin(); t.rollback()) { reset(ctx); rdesc* r1 = t.read(&first.next, std::memory_order_consume)($); if (0 == r1) continue; dlist_trx_node* node = (dlist_trx_node*)(intptr_t)r1->cmp($); while (node->next($).load(std::memory_order_consume)) { rdesc* r = t.read(&node->next)($); if (0 == r) break; dlist_trx_node* next = (dlist_trx_node*)(intptr_t)r->cmp($); f(ctx, node); node = next; } if (node->next($).load(std::memory_order_relaxed)) continue; if (t.commit()) break; } pdr_unlock(); } dlist_trx_node first; dlist_trx_node last; }; struct dlist_trx_test : rl::test_suite { dlist_trx list; static int const count = 4; dlist_trx_node nodes[2][count]; void thread(unsigned index) { if (0 == index || 1 == index) { for (int i = 0; i != count; ++i) { dlist_trx_node* n = &nodes[index][i]; intptr_t value = 1 << ((index * count + i) * 4); n->key($) = value; n->value($) = value; list.insert(n); } for (int i = 0; i != count; ++i) { dlist_trx_node* n = &nodes[index][i]; list.remove(n); } } else if (2 == index || 3 == index) { struct local { static void reset(void* ctx) { *(int*)ctx = 0; } static void apply(void* ctx, dlist_trx_node* n) { *(int*)ctx += (int)n->value($); } }; int volatile sum = 0; list.foreach(&local::apply, &local::reset, (void*)&sum); int volatile x = sum; (void)x; } } void invariant() { int volatile sum = 0; dlist_trx_node* n = (dlist_trx_node*)list.first.next($).load(); for (;;) { if (lock_value == (intptr_t)n) break; dlist_trx_node* next = (dlist_trx_node*)n->next($).load(); if (0 == next) break; sum += (int)n->value($); n = next; } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/tutorial.txt ================================================ 1. Add #include 2. For atomic variables use type std::atomic: std::atomic head; 3. For usual non-atomic variables use type rl::var: rl::var data; Such vars will be checked for races and included into trace. 4. All accesses to std::atomic and rl::var variables postfix with '($)': std::atomic head; rl::var data; head($).store(0); data($) = head($).load(); 5. Strictly thread-private variables use can leave as-is: for (int i = 0; i != 10; ++i) Such vars will be NOT checked for races NOR included into trace. But they will accelerate verification. 6. Describe test-suite: number of threads, thread function, before/after/invariant functions. See example below. 7. Place asserts: int x = g($).load(); RL_ASSERT(x > 0); 8. Start verification: rl::simulate(); Here is complete example: #include // template parameter '2' is number of threads struct race_test : rl::test_suite { std::atomic a; rl::var x; // executed in single thread before main thread function void before() { a($) = 0; x($) = 0; } // main thread function void thread(unsigned thread_index) { if (0 == thread_index) { x($) = 1; a($).store(1, rl::memory_order_relaxed); } else { if (1 == a($).load(rl::memory_order_relaxed)) x($) = 2; } } // executed in single thread after main thread function void after() { } // executed in single thread after every 'visible' action in main threads // disallowed to modify any state void invariant() { } }; int main() { rl::simulate(); } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/wfmo.hpp ================================================ #pragma once #include "../relacy/relacy_std.hpp" struct test_wfmo_all : rl::test_suite { HANDLE sema1; HANDLE sema2; rl::var data; void before() { sema1 = CreateSemaphore(0, 0, 2, 0); sema2 = CreateSemaphore(0, 0, 2, 0); data($) = 0; } void after() { CloseHandle(sema1); CloseHandle(sema2); } void thread(unsigned index) { if (0 == index) { HANDLE handles [2] = {sema1, sema2}; WaitForMultipleObjects(2, handles, 1, INFINITE); RL_ASSERT(data($) == 2); } else { data($) = 1; ReleaseSemaphore(sema1, 1, 0); data($) = 2; ReleaseSemaphore(sema2, 1, 0); } } }; struct test_wfmo_single : rl::test_suite { HANDLE sema1; HANDLE sema2; rl::atomic data; void before() { sema1 = CreateSemaphore(0, 0, 2, 0); sema2 = CreateSemaphore(0, 0, 2, 0); data($) = 0; } void after() { CloseHandle(sema1); CloseHandle(sema2); } void thread(unsigned index) { if (0 == index) { HANDLE handles [2] = {sema1, sema2}; WaitForMultipleObjects(2, handles, 0, INFINITE); int d = data.load(rl::memory_order_relaxed); RL_ASSERT(d == 1 || d == 2); RL_UNTIL(d == 1); } else { data.store(1, rl::memory_order_relaxed); ReleaseSemaphore(sema1, 1, 0); data.store(2, rl::memory_order_relaxed); ReleaseSemaphore(sema2, 1, 0); } } }; struct test_wfmo_timeout : rl::test_suite { HANDLE sema1; HANDLE sema2; rl::atomic data; void before() { sema1 = CreateSemaphore(0, 0, 2, 0); sema2 = CreateSemaphore(0, 0, 2, 0); data($) = 0; } void after() { CloseHandle(sema1); CloseHandle(sema2); } void thread(unsigned index) { if (0 == index) { HANDLE handles [2] = {sema1, sema2}; WaitForMultipleObjects(2, handles, 0, 100); int d = data.load(rl::memory_order_relaxed); RL_ASSERT(d == 0 || d == 1 || d == 2); RL_UNTIL(d == 0); } else { data.store(1, rl::memory_order_relaxed); ReleaseSemaphore(sema1, 1, 0); data.store(2, rl::memory_order_relaxed); ReleaseSemaphore(sema2, 1, 0); } } }; struct test_wfmo_try : rl::test_suite { HANDLE sema1; HANDLE sema2; rl::atomic d; rl::atomic d1; rl::atomic d2; void before() { sema1 = CreateSemaphore(0, 1, 2, 0); sema2 = CreateSemaphore(0, 1, 2, 0); d1($) = 0; d2($) = 0; } void after() { CloseHandle(sema1); CloseHandle(sema2); } void thread(unsigned index) { if (0 == index) { d1.store(1, rl::memory_order_relaxed); HANDLE handles [2] = {sema1, sema2}; if (WAIT_TIMEOUT == WaitForMultipleObjects(2, handles, 1, 0)) RL_ASSERT(1 == d2.load(rl::memory_order_relaxed)); } else if (1 == index) { d2.store(1, rl::memory_order_relaxed); HANDLE handles [2] = {sema2, sema1}; if (WAIT_TIMEOUT == WaitForMultipleObjects(2, handles, 1, 0)) RL_ASSERT(1 == d1.load(rl::memory_order_relaxed)); } } }; struct test_wfmo_mixed : rl::test_suite { HANDLE sem [2]; void before() { sem[0] = CreateSemaphore(0, 0, 2, 0); sem[1] = CreateSemaphore(0, 0, 2, 0); } void after() { CloseHandle(sem[0]); CloseHandle(sem[1]); } void thread(unsigned index) { if (0 == index) { ReleaseSemaphore(sem[0], 1, 0); ReleaseSemaphore(sem[0], 1, 0); ReleaseSemaphore(sem[1], 1, 0); } else if (1 == index) { unsigned rv = WaitForMultipleObjects(2, sem, 1, INFINITE); assert(rv == WAIT_OBJECT_0); } else if (2 == index) { unsigned rv = WaitForSingleObject(sem[0], INFINITE); assert(rv == WAIT_OBJECT_0); } } }; struct test_wfmo_mixed2 : rl::test_suite { HANDLE sem [2]; void before() { sem[0] = CreateSemaphore(0, 0, 2, 0); sem[1] = CreateSemaphore(0, 0, 2, 0); } void after() { CloseHandle(sem[0]); CloseHandle(sem[1]); } void thread(unsigned index) { if (0 == index) { ReleaseSemaphore(sem[1], 1, 0); ReleaseSemaphore(sem[0], 1, 0); ReleaseSemaphore(sem[0], 1, 0); } else if (1 == index) { unsigned rv = WaitForSingleObject(sem[0], INFINITE); assert(rv == WAIT_OBJECT_0); } else if (2 == index || 3 == index) { unsigned rv = WaitForMultipleObjects(2, sem, 1, 42); assert(rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT); } } }; struct test_wfmo_event_all : rl::test_suite { HANDLE ev [2]; rl::atomic state; void before() { ev[0] = CreateEvent(0, 0, 0, 0); ev[1] = CreateEvent(0, 1, 0, 0); state.store(0, rl::memory_order_relaxed); } void after() { CloseHandle(ev[0]); CloseHandle(ev[1]); } void thread(unsigned index) { if (0 == index) { unsigned rv = WaitForMultipleObjects(2, ev, 1, INFINITE); assert(rv == WAIT_OBJECT_0 + 0 || rv == WAIT_OBJECT_0 + 1); assert(state.load(rl::memory_order_relaxed) == 1); } else if (1 == index) { SetEvent(ev[0]); state.store(1, rl::memory_order_relaxed); SetEvent(ev[1]); } } }; struct test_wfmo_event_any : rl::test_suite { HANDLE ev [2]; rl::atomic state; void before() { ev[0] = CreateEvent(0, 0, 0, 0); ev[1] = CreateEvent(0, 1, 0, 0); state.store(0, rl::memory_order_relaxed); } void after() { CloseHandle(ev[0]); CloseHandle(ev[1]); } void thread(unsigned index) { if (0 == index) { unsigned rv = WaitForMultipleObjects(2, ev, 0, INFINITE); assert(rv == WAIT_OBJECT_0 + 0 || rv == WAIT_OBJECT_0 + 1); assert(state.load(rl::memory_order_relaxed) == 1); } else if (1 == index) { state.store(1, rl::memory_order_relaxed); SetEvent(ev[0]); SetEvent(ev[1]); } } }; struct test_wfmo_atomic : rl::test_suite { HANDLE ev [2]; rl::atomic state; void before() { ev[0] = CreateEvent(0, 0, 0, 0); ev[1] = CreateEvent(0, 0, 0, 0); } void after() { CloseHandle(ev[0]); CloseHandle(ev[1]); } void thread(unsigned index) { if (0 == index) { state.store(1, rl::memory_order_relaxed); WaitForMultipleObjects(2, ev, 0, 1); } else if (1 == index) { SetEvent(ev[0]); SetEvent(ev[1]); unsigned rv = WaitForSingleObject(ev[0], 0); if (rv == WAIT_TIMEOUT) { assert(state.load(rl::memory_order_relaxed) == 1); RL_UNTIL(true); } } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy/test/windows.hpp ================================================ #pragma once #include "../relacy/windows.h" struct test_win_thread : rl::test_suite { static size_t const dynamic_thread_count = 2; VAR_T(int) data; static unsigned long RL_STDCALL win_func(void* param) { static_cast(param)->VAR(data) += 1; return 0; } static unsigned RL_STDCALL msvc_func(void* param) { static_cast(param)->VAR(data) += 1; return 0; } void thread(unsigned) { VAR(data) = 0; HANDLE th1 = CreateThread(0, 0, &test_win_thread::win_func, this, 0, 0); WaitForSingleObject(th1, INFINITE); RL_ASSERT(VAR(data) == 1); HANDLE th2 = (HANDLE)_beginthreadex(0, 0, &test_win_thread::msvc_func, this, 0, 0); WaitForSingleObject(th2, INFINITE); RL_ASSERT(VAR(data) == 2); } }; struct test_win_mutex : rl::test_suite { HANDLE mtx; VAR_T(int) data; void before() { mtx = CreateMutex(0, 0, 0); VAR(data) = 0; } void after() { CloseHandle(mtx); } void thread(unsigned) { WaitForSingleObject(mtx, INFINITE); WaitForSingleObject(mtx, INFINITE); VAR(data) += 1; ReleaseMutex(mtx); ReleaseMutex(mtx); if (WAIT_OBJECT_0 == WaitForSingleObject(mtx, 0)) { VAR(data) += 1; ReleaseMutex(mtx); } } }; struct test_win_cs : rl::test_suite { CRITICAL_SECTION mtx; VAR_T(int) data; void before() { InitializeCriticalSection(&mtx); VAR(data) = 0; } void after() { DeleteCriticalSection(&mtx); } void thread(unsigned) { EnterCriticalSection(&mtx); VAR(data) += 1; LeaveCriticalSection(&mtx); if (TryEnterCriticalSection(&mtx)) { VAR(data) += 1; LeaveCriticalSection(&mtx); } } }; struct test_win_condvar : rl::test_suite { CONDITION_VARIABLE cv; CRITICAL_SECTION mtx; VAR_T(int) stage; void before() { InitializeConditionVariable(&cv); InitializeCriticalSection(&mtx); VAR(stage) = 0; } void after() { DeleteCriticalSection(&mtx); DeleteConditionVariable(&cv); } void thread(unsigned index) { if (0 == index) { EnterCriticalSection(&mtx); VAR(stage) += 1; WakeAllConditionVariable(&cv); while (VAR(stage) != 2) SleepConditionVariableCS(&cv, &mtx, INFINITE); LeaveCriticalSection(&mtx); } else if (1 == index) { EnterCriticalSection(&mtx); while (VAR(stage) != 1) SleepConditionVariableCS(&cv, &mtx, 1); VAR(stage) += 1; WakeAllConditionVariable(&cv); LeaveCriticalSection(&mtx); } else if (2 == index) { EnterCriticalSection(&mtx); while (VAR(stage) != 2) SleepConditionVariableCS(&cv, &mtx, INFINITE); LeaveCriticalSection(&mtx); WakeConditionVariable(&cv); } } }; struct test_win_condvar_srw : rl::test_suite { CONDITION_VARIABLE cv; SRWLOCK mtx; VAR_T(int) stage; void before() { InitializeConditionVariable(&cv); InitializeSRWLock(&mtx); VAR(stage) = 0; } void after() { DeleteSRWLock(&mtx); DeleteConditionVariable(&cv); } void thread(unsigned index) { if (0 == index) { AcquireSRWLockExclusive(&mtx); VAR(stage) += 1; WakeAllConditionVariable(&cv); while (VAR(stage) != 2) SleepConditionVariableSRW(&cv, &mtx, INFINITE, 0); ReleaseSRWLockExclusive(&mtx); } else if (1 == index) { AcquireSRWLockExclusive(&mtx); while (VAR(stage) != 1) SleepConditionVariableSRW(&cv, &mtx, 1, 0); VAR(stage) += 1; WakeAllConditionVariable(&cv); ReleaseSRWLockExclusive(&mtx); } else if (2 == index) { AcquireSRWLockExclusive(&mtx); while (VAR(stage) != 2) SleepConditionVariableSRW(&cv, &mtx, INFINITE, 0); ReleaseSRWLockExclusive(&mtx); WakeConditionVariable(&cv); } } }; struct test_win_sem : rl::test_suite { HANDLE sem1, sem2; VAR_T(int) data; void before() { sem1 = CreateSemaphore(0, 0, 1, 0); sem2 = CreateSemaphore(0, 0, 1, 0); VAR(data) = 0; } void after() { CloseHandle(sem1); CloseHandle(sem2); } void thread(unsigned index) { if (index) { VAR(data) = 1; long count = -1; ReleaseSemaphore(sem1, 1, &count); assert(count == 0); for (;;) { unsigned long rv = WaitForSingleObject(sem2, 0); if (rv == WAIT_OBJECT_0) break; RL_ASSERT(rv == WAIT_TIMEOUT); Sleep(0); } RL_ASSERT(VAR(data) == 2); VAR(data) = 3; ReleaseSemaphore(sem2, 1, &count); RL_ASSERT(count == 0); ReleaseSemaphore(sem2, 1, &count); RL_ASSERT(count == 1); } else { unsigned long rv = WaitForSingleObject(sem1, INFINITE); assert(rv == WAIT_OBJECT_0); RL_ASSERT(VAR(data) == 1); VAR(data) = 2; ReleaseSemaphore(sem2, 1, 0); } } }; struct test_win_event : rl::test_suite { HANDLE ev; VAR_T(int) data; void before() { VAR(data) = 0; ev = CreateEvent(0, 0, 0, 0); } void after() { CloseHandle(ev); } void thread(unsigned index) { if (0 == index) { VAR(data) = 1; SetEvent(ev); PulseEvent(ev); } else { unsigned rv = WaitForSingleObject(ev, INFINITE); assert(rv == WAIT_OBJECT_0); assert(VAR(data) == 1); rv = WaitForSingleObject(ev, 0); assert(rv == WAIT_TIMEOUT); ResetEvent(ev); } } }; struct test_FlushProcessWriteBuffers : rl::test_suite { std::atomic x1; std::atomic x2; int r1; int r2; void before() { x1.store(0, std::memory_order_relaxed); x2.store(0, std::memory_order_relaxed); r1 = r2 = 0; } void after() { assert(r1 == 1 || r2 == 1); } void thread(unsigned index) { if (index) { x1.store(1, std::memory_order_relaxed); r1 = x2.load(std::memory_order_relaxed); } else { x2.store(1, std::memory_order_relaxed); FlushProcessWriteBuffers(); r2 = x1.load(std::memory_order_relaxed); } } }; ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/relacy_shims.h ================================================ #pragma once // Use relacy assertions #undef assert #ifdef NDEBUG #define assert(x) #else #define assert(x) RL_ASSERT(x) #endif struct RelacyThreadExitListener { typedef void (*callback_t)(void*); callback_t callback; void* userData; RelacyThreadExitListener* next; }; class RelacyThreadExitNotifier { public: static void subscribe(RelacyThreadExitListener* listener) { auto& tlsInst = instance(); listener->next = tlsInst.tail; tlsInst.tail = listener; } static void unsubscribe(RelacyThreadExitListener* listener) { auto& tlsInst = instance(); RelacyThreadExitListener** prev = &tlsInst.tail; for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) { if (ptr == listener) { *prev = ptr->next; break; } prev = &ptr->next; } } static void notify_relacy_thread_start() { instance().tail = nullptr; } static void notify_relacy_thread_exit() { for (auto ptr = instance().tail; ptr != nullptr; ptr = ptr->next) { ptr->callback(ptr->userData); } } private: RelacyThreadExitNotifier() : tail(nullptr) { } static RelacyThreadExitNotifier& instance() { static RelacyThreadExitNotifier instances[1024]; auto tid = rl::thread_index(); assert(tid < 1024); return instances[tid]; } private: RelacyThreadExitListener* tail; }; namespace std { // Relacy doesn't wrap std::atomic_flag struct atomic_flag { private: atomic_flag(atomic_flag const&); atomic_flag(atomic_flag&&); atomic_flag& operator=(atomic_flag const&); atomic_flag& operator=(atomic_flag&&); public: atomic_flag() { } atomic_flag(bool initialValue) : val(initialValue ? 1 : 0) { } void clear() { clear(std::memory_order_seq_cst); } void clear(rl::memory_order order, rl::debug_info_param d) { val.store(0, order, d); } bool test_and_set() { test_and_set(std::memory_order_seq_cst); } bool test_and_set(rl::memory_order order, rl::debug_info_param d) { return val.fetch_or(1, order, d) != 0; } private: std::atomic val; }; } ================================================ FILE: src/third_party/concurrentqueue/tests/relacy/spmchash.cpp ================================================ // ©2014 Cameron Desrochers #include "relacy/relacy/relacy_std.hpp" namespace details { template static inline char* align_for(char* ptr) { const std::size_t alignment = std::alignment_of::value; return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment; } } template struct SPMCSequentialHashMap { explicit SPMCSequentialHashMap(std::size_t initialSize) : nextCapacity(initialSize), index(nullptr) { new_index(); } ~SPMCSequentialHashMap() { auto ptr = index.load(std::memory_order_relaxed); if (ptr != nullptr) { for (std::size_t i = 0; i != ptr->capacity; ++i) { ptr->index[i]->~IndexEntry(); } do { auto prev = ptr->prev; ptr->~IndexHeader(); free(ptr); ptr = prev; } while (ptr != nullptr); } } // Not thread safe. Only call from single producer thread. // Note: key must *not* be in hash already, and must be exactly // one larger than the previously inserted key value. void insert(std::uint64_t key, TValue* value) { IndexEntry* idxEntry; insert_index_entry(idxEntry, key); idxEntry->value.store(value, std::memory_order_release); } // Thread-safe, but if somebody can remove the key while find() is // in progress, then any returned value is not guaranteed to correspond // to that key. This also applies if the key was not already present but // once was. Elements can be found in any order. TValue* find(std::uint64_t key) { auto idxEntry = get_entry_for_key(key); if (idxEntry == nullptr) return nullptr; return idxEntry->value.load(std::memory_order_acquire); } // Thread-safe, but if somebody else can remove the same key while remove() // is in progress, then any removed value is not guaranteed to correspond // to that key This also applies if the key was not already present but // once was. Elements can be removed in an order. TValue* remove(std::uint64_t key) { auto idxEntry = get_entry_for_key(key); if (idxEntry == nullptr) return nullptr; TValue* val = nullptr; while (!idxEntry->value.compare_exchange_weak(val, nullptr, std::memory_order_acquire, std::memory_order_relaxed)) continue; return val; } private: struct IndexEntry { std::atomic key; std::atomic value; }; struct IndexHeader { std::size_t capacity; std::atomic tail; IndexEntry* entries; IndexEntry** index; IndexHeader* prev; }; inline void insert_index_entry(IndexEntry*& idxEntry, std::uint64_t key) { auto localIndex = index.load(std::memory_order_relaxed); // We're the only writer thread, relaxed is OK auto newTail = (localIndex->tail.load(std::memory_order_relaxed) + 1) & (localIndex->capacity - 1); idxEntry = localIndex->index[newTail]; if (idxEntry->key.load(std::memory_order_relaxed) == INVALID_KEY || idxEntry->value.load(std::memory_order_relaxed) == nullptr) { idxEntry->key.store(key, std::memory_order_relaxed); localIndex->tail.store(newTail, std::memory_order_release); return; } // No room in the old index, try to allocate another one! new_index(); localIndex = index.load(std::memory_order_relaxed); newTail = (localIndex->tail.load(std::memory_order_relaxed) + 1) & (localIndex->capacity - 1); idxEntry = localIndex->index[newTail]; assert(idxEntry->key.load(std::memory_order_relaxed) == INVALID_KEY); idxEntry->key.store(key, std::memory_order_relaxed); localIndex->tail.store(newTail, std::memory_order_release); } inline IndexEntry* get_entry_for_key(std::uint64_t key) const { auto localIndex = index.load(std::memory_order_acquire); auto tail = localIndex->tail.load(std::memory_order_acquire); auto tailBase = localIndex->index[tail]->key.load(std::memory_order_relaxed); if (tailBase == INVALID_KEY) { return nullptr; } auto offset = static_cast(key - tailBase); std::size_t idx = (tail + offset) & (localIndex->capacity - 1); auto entry = localIndex->index[idx]; return entry->key.load(std::memory_order_relaxed) == key ? entry : nullptr; } bool new_index() { auto prev = index.load(std::memory_order_relaxed); std::size_t prevCapacity = prev == nullptr ? 0 : prev->capacity; auto entryCount = prev == nullptr ? nextCapacity : prevCapacity; auto raw = static_cast(malloc( sizeof(IndexHeader) + std::alignment_of::value - 1 + sizeof(IndexEntry) * entryCount + std::alignment_of::value - 1 + sizeof(IndexEntry*) * nextCapacity)); if (raw == nullptr) { return false; } auto header = new (raw) IndexHeader; auto entries = reinterpret_cast(details::align_for(raw + sizeof(IndexHeader))); auto idx = reinterpret_cast(details::align_for(reinterpret_cast(entries) + sizeof(IndexEntry) * entryCount)); if (prev != nullptr) { auto prevTail = prev->tail.load(std::memory_order_relaxed); auto prevPos = prevTail; std::size_t i = 0; do { prevPos = (prevPos + 1) & (prev->capacity - 1); idx[i++] = prev->index[prevPos]; } while (prevPos != prevTail); assert(i == prevCapacity); } for (std::size_t i = 0; i != entryCount; ++i) { new (entries + i) IndexEntry; entries[i].key.store(INVALID_KEY, std::memory_order_relaxed); entries[i].value.store(nullptr, std::memory_order_relaxed); idx[prevCapacity + i] = entries + i; } header->prev = prev; header->entries = entries; header->index = idx; header->capacity = nextCapacity; header->tail.store((prevCapacity - 1) & (nextCapacity - 1), std::memory_order_relaxed); index.store(header, std::memory_order_release); nextCapacity <<= 1; return true; } private: std::size_t nextCapacity; std::atomic index; static const std::uint64_t INVALID_KEY = ~(std::uint64_t)0; }; template struct test : rl::test_suite, ThreadCount> { SPMCSequentialHashMap* hash; int values[NUM_VALUES]; std::atomic useCounts[NUM_VALUES]; std::atomic removed[NUM_VALUES]; void before() { hash = new SPMCSequentialHashMap(2); for (int i = 0; i != NUM_VALUES; ++i) { values[i] = i; useCounts[i].store(0, std::memory_order_relaxed); removed[i].store(false, std::memory_order_relaxed); } } void thread(unsigned int tid) { if (tid == 0) { // Producer for (int i = 0; i != NUM_VALUES; ++i) { hash->insert(i, &values[i]); useCounts[i].store(ThreadCount / 2, std::memory_order_release); } } else { // Consumer for (int i = 0; i != NUM_VALUES; ++i) { auto useCount = useCounts[i].fetch_add(-1, std::memory_order_acquire); auto val = hash->find(i); bool isRemoved = removed[i].load(std::memory_order_relaxed); auto current = useCounts[i].fetch_add(0, std::memory_order_release); if (useCount > 0 && (current > 0 || current == 0 && useCount == 1)) { RL_ASSERT(val != nullptr && *val == i && !isRemoved); } if (useCount == 1) { val = hash->remove(i); RL_ASSERT(val != nullptr && *val == i && !removed[i].load(std::memory_order_relaxed)); removed[i].store(true, std::memory_order_release); } } } } void after() { delete hash; } void invariant() { } }; int main() { rl::test_params params; //params.search_type = rl::sched_full; //params.iteration_count = 100000000; params.search_type = rl::sched_random; params.iteration_count = 1000000; rl::simulate>(params); rl::simulate>(params); rl::simulate>(params); return 0; } ================================================ FILE: src/third_party/concurrentqueue/tests/unittests/mallocmacro.cpp ================================================ #define malloc(x) malloc(x) #define free(x) free(x) #include "../../blockingconcurrentqueue.h" ================================================ FILE: src/third_party/concurrentqueue/tests/unittests/minitest.h ================================================ // ©2013-2014 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this header). // Provides an extremely basic unit testing framework. #pragma once #include #include #include #include #include #include #ifdef __GNUG__ #include #include #endif #define REGISTER_TEST(testName) registerTest(#testName, &subclass_t::testName) #define ASSERT_OR_FAIL(expr) { if (!(expr)) { notifyTestFailed(__LINE__, #expr); return false; } } #define SUCCEED() { return true; } // Uses CRTP template class TestClass { public: static void notifyTestFailed(int line, const char* expr) { std::printf(" FAILED!\n ******* Assertion failed (line %d): %s\n\n", line, expr); } bool validateTestName(std::string const& which) const { return testMap.find(which) != testMap.end(); } void getAllTestNames(std::vector& names) const { for (auto it = testMap.cbegin(); it != testMap.cend(); ++it) { names.push_back(it->first); } } bool run(unsigned int iterations = 1) { bool success = true; for (auto it = testVec.cbegin(); it != testVec.cend(); ++it) { if (!execTest(*it, iterations)) { success = false; } } return success; } bool run(std::vector const& which, unsigned int iterations = 1) { bool success = true; for (auto it = which.begin(); it != which.end(); ++it) { if (!execTest(*testMap.find(*it), iterations)) { success = false; } } return success; } protected: typedef TSubclass subclass_t; void registerTest(const char* name, bool (subclass_t::* method)()) { testVec.push_back(std::make_pair(std::string(name), method)); testMap[std::string(name)] = method; } virtual bool preTest() { return true; } virtual bool postTest(bool) { return true; } bool execTest(std::pair const& testRef, unsigned int iterations) { std::printf("%s::%s... \n", demangle_type_name(typeid(subclass_t).name()).c_str(), testRef.first.c_str()); bool result = true; for (unsigned int i = 0; result && i != iterations; ++i) { result = preTest(); try { result = result && (static_cast(this)->*testRef.second)(); } catch (...) { std::printf(" FAILED!\n ******* Unhandled exception thrown\n\n"); result = false; } result = postTest(result) && result; } if (result) { std::printf(" passed\n\n"); } return result; } private: static std::string demangle_type_name(const char* name) { #ifdef __GNUG__ // Adapted from http://stackoverflow.com/a/4541470/21475 int status = -4; char* res = abi::__cxa_demangle(name, nullptr, nullptr, &status); const char* const demangled_name = (status == 0) ? res : name; std::string ret(demangled_name); std::free(res); return ret; #else return name; #endif } protected: std::vector > testVec; std::map testMap; }; ================================================ FILE: src/third_party/concurrentqueue/tests/unittests/unittests.cpp ================================================ // ©2013-2014 Cameron Desrochers. // Distributed under the simplified BSD license (see the LICENSE file that // should have come with this file). // Unit tests for moodycamel::ConcurrentQueue #define likely MAKE_SURE_LIKELY_MACRO_CAN_PEACEFULLY_COEXIST #define unlikely MAKE_SURE_UNLIKELY_MACRO_CAN_PEACEFULLY_COEXIST #include #include #include #include #include #include #ifdef _WIN32 #ifndef NOMINMAX #define NOMINMAX #endif #include // Not because we need it, but to ensure no conflicts arise with the queue's declarations #endif #include "minitest.h" #include "../common/simplethread.h" #include "../common/systemtime.h" #include "../../concurrentqueue.h" #include "../../blockingconcurrentqueue.h" namespace { struct tracking_allocator { union tag { std::size_t size; #ifdef __GNUC__ max_align_t dummy; // GCC forgot to add it to std:: for a while #else std::max_align_t dummy; // Others (e.g. MSVC) insist it can *only* be accessed via std:: #endif }; static inline void* malloc(std::size_t size) { auto ptr = std::malloc(size + sizeof(tag)); reinterpret_cast(ptr)->size = size; usage.fetch_add(size, std::memory_order_relaxed); return reinterpret_cast(ptr) + sizeof(tag); } static inline void free(void* ptr) { ptr = reinterpret_cast(ptr) - sizeof(tag); auto size = reinterpret_cast(ptr)->size; usage.fetch_add(-size, std::memory_order_relaxed); std::free(ptr); } static inline std::size_t current_usage() { return usage.load(std::memory_order_relaxed); } private: static std::atomic usage; }; std::atomic tracking_allocator::usage(0); } struct corealgos_allocator { static inline void* malloc(std::size_t size) { return tracking_allocator::malloc(size); } static inline void free(void* ptr) { tracking_allocator::free(ptr); } }; #define corealgos_allocator corealgos_allocator #include "../corealgos.h" using namespace moodycamel; namespace moodycamel { struct MallocTrackingTraits : public ConcurrentQueueDefaultTraits { static inline void* malloc(std::size_t size) { return tracking_allocator::malloc(size); } static inline void free(void* ptr) { tracking_allocator::free(ptr); } }; template struct TestTraits : public MallocTrackingTraits { typedef std::size_t size_t; typedef uint64_t index_t; static const size_t BLOCK_SIZE = BlockSize; static const size_t EXPLICIT_INITIAL_INDEX_SIZE = InitialIndexSize; static const size_t IMPLICIT_INITIAL_INDEX_SIZE = InitialIndexSize * 2; static inline void reset() { _malloc_count() = 0; _free_count() = 0; } static inline std::atomic& _malloc_count() { static std::atomic c; return c; } static inline int malloc_count() { return _malloc_count().load(std::memory_order_seq_cst); } static inline std::atomic& _free_count() { static std::atomic c; return c; } static inline int free_count() { return _free_count().load(std::memory_order_seq_cst); } static inline void* malloc(ConcurrentQueueDefaultTraits::size_t bytes) { ++_malloc_count(); return tracking_allocator::malloc(bytes); } static inline void free(void* obj) { ++_free_count(); return tracking_allocator::free(obj); } }; struct SmallIndexTraits : public MallocTrackingTraits { typedef uint16_t size_t; typedef uint16_t index_t; }; struct ExtraSmallIndexTraits : public MallocTrackingTraits { typedef uint8_t size_t; typedef uint8_t index_t; }; // Note: Not thread safe! struct Foo { static int& nextId() { static int i; return i; } static int& createCount() { static int c; return c; } static int& destroyCount() { static int c; return c; } static bool& destroyedInOrder() { static bool d = true; return d; } static void reset() { createCount() = 0; destroyCount() = 0; nextId() = 0; destroyedInOrder() = true; lastDestroyedId() = -1; } Foo() { id = nextId()++; ++createCount(); } Foo(Foo const&) MOODYCAMEL_DELETE_FUNCTION; Foo(Foo&& other) { id = other.id; other.id = -1; } void operator=(Foo&& other) { id = other.id; other.id = -1; } ~Foo() { ++destroyCount(); if (id == -2) { // Double free! destroyedInOrder() = false; } else if (id != -1) { if (id <= lastDestroyedId()) { destroyedInOrder() = false; } lastDestroyedId() = id; } id = -2; } private: int id; static int& lastDestroyedId() { static int i = -1; return i; } }; struct Copyable { Copyable(int id) : copied(false), id(id) { } Copyable(Copyable const& o) : copied(true), id(o.id) { } void operator=(Copyable const& o) { copied = true; id = o.id; } bool copied; int id; }; struct Moveable { Moveable(int id) : moved(false), copied(false), id(id) { } Moveable(Moveable&& o) MOODYCAMEL_NOEXCEPT : moved(true), copied(o.copied), id(o.id) { } void operator=(Moveable&& o) MOODYCAMEL_NOEXCEPT { moved = true; copied = o.copied; id = o.id; } bool moved; bool copied; int id; #if defined(_MSC_VER) && _MSC_VER < 1800 // VS2012's std::is_nothrow_[move_]constructible is broken, so the queue never attempts to // move objects with that compiler. In this case, we don't know whether it's really a copy // or not being done, so give the benefit of the doubt (given the tests pass on other platforms) // and assume it would have done a move if it could have (don't set copied to true). Moveable(Moveable const& o) MOODYCAMEL_NOEXCEPT : moved(o.moved), copied(o.copied), id(o.id) { } void operator=(Moveable const& o) MOODYCAMEL_NOEXCEPT { moved = o.moved; copied = o.copied; id = o.id; } #else Moveable(Moveable const& o) MOODYCAMEL_NOEXCEPT : moved(o.moved), copied(true), id(o.id) { } void operator=(Moveable const& o) MOODYCAMEL_NOEXCEPT { moved = o.moved; copied = true; id = o.id; } #endif }; struct ThrowingMovable { static std::atomic& ctorCount() { static std::atomic c; return c; } static std::atomic& destroyCount() { static std::atomic c; return c; } static void reset() { ctorCount() = 0; destroyCount() = 0; } explicit ThrowingMovable(int id, bool throwOnCctor = false, bool throwOnAssignment = false, bool throwOnSecondCctor = false) : id(id), moved(false), copied(false), throwOnCctor(throwOnCctor), throwOnAssignment(throwOnAssignment), throwOnSecondCctor(throwOnSecondCctor) { ctorCount().fetch_add(1, std::memory_order_relaxed); } ThrowingMovable(ThrowingMovable const& o) : id(o.id), moved(false), copied(true), throwOnCctor(o.throwOnCctor), throwOnAssignment(o.throwOnAssignment), throwOnSecondCctor(false) { if (throwOnCctor) { throw this; } ctorCount().fetch_add(1, std::memory_order_relaxed); throwOnCctor = o.throwOnSecondCctor; } ThrowingMovable(ThrowingMovable&& o) : id(o.id), moved(true), copied(false), throwOnCctor(o.throwOnCctor), throwOnAssignment(o.throwOnAssignment), throwOnSecondCctor(false) { if (throwOnCctor) { throw this; } ctorCount().fetch_add(1, std::memory_order_relaxed); throwOnCctor = o.throwOnSecondCctor; } ~ThrowingMovable() { destroyCount().fetch_add(1, std::memory_order_relaxed); } void operator=(ThrowingMovable const& o) { id = o.id; moved = false; copied = true; throwOnCctor = o.throwOnCctor; throwOnAssignment = o.throwOnAssignment; throwOnSecondCctor = o.throwOnSecondCctor; if (throwOnAssignment) { throw this; } } void operator=(ThrowingMovable&& o) { id = o.id; moved = true; copied = false; throwOnCctor = o.throwOnCctor; throwOnAssignment = o.throwOnAssignment; throwOnSecondCctor = o.throwOnSecondCctor; if (throwOnAssignment) { throw this; } } int id; bool moved; bool copied; public: bool throwOnCctor; bool throwOnAssignment; bool throwOnSecondCctor; }; class ConcurrentQueueTests : public TestClass { public: ConcurrentQueueTests() { REGISTER_TEST(create_empty_queue); REGISTER_TEST(create_token); REGISTER_TEST(circular_less_than); REGISTER_TEST(enqueue_one_explicit); REGISTER_TEST(enqueue_and_dequeue_one_explicit); REGISTER_TEST(enqueue_one_implicit); REGISTER_TEST(enqueue_and_dequeue_one_implicit); REGISTER_TEST(enqueue_and_dequeue_a_few); REGISTER_TEST(enqueue_bulk); REGISTER_TEST(block_alloc); REGISTER_TEST(token_move); REGISTER_TEST(multi_producers); REGISTER_TEST(producer_reuse); REGISTER_TEST(block_reuse); REGISTER_TEST(block_recycling); REGISTER_TEST(leftovers_destroyed); REGISTER_TEST(block_index_resized); REGISTER_TEST(try_dequeue); REGISTER_TEST(try_dequeue_threaded); REGISTER_TEST(try_dequeue_bulk); REGISTER_TEST(try_dequeue_bulk_threaded); REGISTER_TEST(implicit_producer_hash); REGISTER_TEST(index_wrapping); REGISTER_TEST(subqueue_size_limit); REGISTER_TEST(exceptions); REGISTER_TEST(test_threaded); REGISTER_TEST(test_threaded_bulk); REGISTER_TEST(full_api); REGISTER_TEST(full_api); REGISTER_TEST(blocking_wrappers); REGISTER_TEST(timed_blocking_wrappers); // Core algos REGISTER_TEST(core_add_only_list); REGISTER_TEST(core_thread_local); REGISTER_TEST(core_free_list); REGISTER_TEST(core_spmc_hash); REGISTER_TEST(explicit_strings_threaded); } bool postTest(bool testSucceeded) override { if (testSucceeded) { // If this assertion fails, there's necessarily a memory leak somewhere! ASSERT_OR_FAIL(tracking_allocator::current_usage() == 0); } return true; } bool create_empty_queue() { ConcurrentQueue q; return true; } bool create_token() { ConcurrentQueue q; ProducerToken tok(q); return true; } bool circular_less_than() { { uint32_t a, b; a = 0; b = 100; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 100; b = 0; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(details::circular_less_than(b, a)); a = 0; b = 0; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 100; b = 100; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 0; b = 1 << 31; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 1; b = 1 << 31; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 0; b = (1 << 31) + 1; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(details::circular_less_than(b, a)); a = 100; b = (1 << 31) + 1; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = (1 << 31) + 7; b = 5; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = (1 << 16) + 7; b = (1 << 16) + 5; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(details::circular_less_than(b, a)); a = 0xFFFFFFFF; b = 0; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 0xFFFFFFFF; b = 0xFFFFFF; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); } { uint16_t a, b; a = 0; b = 100; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 100; b = 0; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(details::circular_less_than(b, a)); a = 0; b = 0; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 100; b = 100; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 0; b = 1 << 15; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 1; b = 1 << 15; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 0; b = (1 << 15) + 1; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(details::circular_less_than(b, a)); a = 100; b = (1 << 15) + 1; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = (1 << 15) + 7; b = 5; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = (1 << 15) + 7; b = (1 << 15) + 5; ASSERT_OR_FAIL(!details::circular_less_than(a, b)); ASSERT_OR_FAIL(details::circular_less_than(b, a)); a = 0xFFFF; b = 0; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); a = 0xFFFF; b = 0xFFF; ASSERT_OR_FAIL(details::circular_less_than(a, b)); ASSERT_OR_FAIL(!details::circular_less_than(b, a)); } return true; } bool enqueue_one_explicit() { ConcurrentQueue q; ProducerToken tok(q); bool result = q.enqueue(tok, 17); ASSERT_OR_FAIL(result); return true; } bool enqueue_and_dequeue_one_explicit() { ConcurrentQueue q; ProducerToken tok(q); int item = 0; ASSERT_OR_FAIL(q.enqueue(tok, 123)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(tok, item)); ASSERT_OR_FAIL(item == 123); return true; } bool enqueue_one_implicit() { ConcurrentQueue q; bool result = q.enqueue(17); ASSERT_OR_FAIL(result); return true; } bool enqueue_and_dequeue_one_implicit() { ConcurrentQueue q; int item = 0; ASSERT_OR_FAIL(q.enqueue(123)); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == 123); return true; } bool enqueue_and_dequeue_a_few() { // Fairly straightforward mass enqueue and dequeue { ConcurrentQueue> q; ProducerToken tok(q); for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.enqueue(tok, i)); } int item; for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(tok, item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue_from_producer(tok, item)); } // Interleaved enqueue and dequeue (though still no threads involved) { ConcurrentQueue> q; ProducerToken tok(q); int item; for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.enqueue(tok, i)); ASSERT_OR_FAIL(q.enqueue(tok, i * 2)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(tok, item)); ASSERT_OR_FAIL(item == (i / 2) * (i % 2 == 0 ? 1 : 2)); } for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(tok, item)); ASSERT_OR_FAIL(item == ((i + 99999) / 2) * (i % 2 == 1 ? 1 : 2)); } ASSERT_OR_FAIL(!q.try_dequeue_from_producer(tok, item)); } // Implicit usage { ConcurrentQueue> q; for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } int item; for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue> q; int item; for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); ASSERT_OR_FAIL(q.enqueue(i * 2)); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == (i / 2) * (i % 2 == 0 ? 1 : 2)); } for (int i = 0; i != 99999; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == ((i + 99999) / 2) * (i % 2 == 1 ? 1 : 2)); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } return true; } bool enqueue_bulk() { typedef TestTraits<2> Traits2; typedef TestTraits<4> Traits4; int arr123[] = { 1, 2, 3 }; int arr1234[] = { 1, 2, 3, 4 }; int arr123456[] = { 1, 2, 3, 4, 5, 6 }; Traits2::reset(); { // Implicit, block allocation required ConcurrentQueue q(2); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); q.enqueue_bulk(arr123, 3); ASSERT_OR_FAIL(Traits2::malloc_count() == 4); // One for producer, one for block index, one for block int item; for (int i = 0; i != 3; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits4::reset(); { // Implicit, block allocation not required (end on block boundary) ConcurrentQueue q(2); ASSERT_OR_FAIL(Traits4::malloc_count() == 1); q.enqueue_bulk(arr1234, 4); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); // One for producer, one for block index int item; for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits2::reset(); { // Implicit, allocation fail ConcurrentQueue q(2); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ASSERT_OR_FAIL(!q.try_enqueue_bulk(arr123, 3)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // Still has to allocate implicit producer and block index int item; ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(q.try_enqueue_bulk(arr123, 2)); for (int i = 0; i != 2; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits2::reset(); { // Implicit, block allocation not required ConcurrentQueue q(4); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); q.enqueue_bulk(arr1234, 4); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index int item; for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits4::reset(); { // Implicit, block allocation required (end not on block boundary) ConcurrentQueue q(4); ASSERT_OR_FAIL(Traits4::malloc_count() == 1); ASSERT_OR_FAIL(q.enqueue(0)); ASSERT_OR_FAIL(q.enqueue_bulk(arr1234, 4)); ASSERT_OR_FAIL(Traits4::malloc_count() == 4); // One for producer, one for block index, one for block int item; for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits4::reset(); { // Implicit, block allocation not required (end not on block boundary) ConcurrentQueue q(5); ASSERT_OR_FAIL(Traits4::malloc_count() == 1); ASSERT_OR_FAIL(q.enqueue(0)); ASSERT_OR_FAIL(q.enqueue_bulk(arr1234, 4)); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); // One for producer, one for block index int item; for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits2::reset(); { // Implicit, block allocation fail (end not on block boundary) -- test rewind ConcurrentQueue q(4); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ASSERT_OR_FAIL(q.enqueue(17)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index ASSERT_OR_FAIL(!q.try_enqueue_bulk(arr123456, 6)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); int item; ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == 17); ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits2::reset(); { // Implicit, enqueue nothing ConcurrentQueue q(3); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ASSERT_OR_FAIL(q.try_enqueue_bulk(arr123, 0)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index int item; ASSERT_OR_FAIL(!q.try_dequeue(item)); } //////// Traits2::reset(); { // Explicit, block allocation required ConcurrentQueue q(2); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index q.enqueue_bulk(tok, arr123, 3); ASSERT_OR_FAIL(Traits2::malloc_count() == 4); // One for block int item; for (int i = 0; i != 3; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits4::reset(); { // Explicit, block allocation not required (end on block boundary) ConcurrentQueue q(2); ASSERT_OR_FAIL(Traits4::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); // One for producer, one for block index q.enqueue_bulk(tok, arr1234, 4); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); int item; for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits2::reset(); { // Explicit, allocation fail ConcurrentQueue q(2); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index ASSERT_OR_FAIL(!q.try_enqueue_bulk(tok, arr123, 3)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); int item; ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(q.try_enqueue_bulk(tok, arr123, 2)); for (int i = 0; i != 2; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); } Traits2::reset(); { // Explicit, block allocation not required ConcurrentQueue q(4); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index q.enqueue_bulk(tok, arr1234, 4); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); int item; for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits4::reset(); { // Explicit, block allocation required (end not on block boundary) ConcurrentQueue q(4); ASSERT_OR_FAIL(Traits4::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); // One for producer, one for block index ASSERT_OR_FAIL(q.enqueue(tok, 0)); ASSERT_OR_FAIL(q.enqueue_bulk(tok, arr1234, 4)); ASSERT_OR_FAIL(Traits4::malloc_count() == 4); // One for block int item; for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits4::reset(); { // Explicit, block allocation not required (end not on block boundary) ConcurrentQueue q(5); ASSERT_OR_FAIL(Traits4::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); // One for producer, one for block index ASSERT_OR_FAIL(q.enqueue(tok, 0)); ASSERT_OR_FAIL(q.enqueue_bulk(tok, arr1234, 4)); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); int item; for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits2::reset(); { // Explicit, block allocation fail (end not on block boundary) -- test rewind ConcurrentQueue q(4); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index ASSERT_OR_FAIL(q.enqueue(tok, 17)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); ASSERT_OR_FAIL(!q.try_enqueue_bulk(tok, arr123456, 6)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); int item; ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == 17); ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits2::reset(); { // Explicit, enqueue nothing ConcurrentQueue q(3); ASSERT_OR_FAIL(Traits2::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); // One for producer, one for block index ASSERT_OR_FAIL(q.try_enqueue_bulk(tok, arr123, 0)); ASSERT_OR_FAIL(Traits2::malloc_count() == 3); int item; ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(q.enqueue(tok, 17)); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == 17); ASSERT_OR_FAIL(!q.try_dequeue(item)); } Traits4::reset(); { // Explicit, re-use empty blocks ConcurrentQueue q(8); ASSERT_OR_FAIL(Traits4::malloc_count() == 1); ProducerToken tok(q); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); // One for producer, one for block index for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(q.enqueue(tok, i)); } int item; for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); ASSERT_OR_FAIL(q.enqueue_bulk(tok, arr123456, 6)); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); for (int i = 0; i != 6; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(Traits4::malloc_count() == 3); } return true; } bool block_alloc() { typedef TestTraits<2> Traits; Traits::reset(); { ConcurrentQueue q(7); ASSERT_OR_FAIL(q.initialBlockPoolSize == 4); ASSERT_OR_FAIL(Traits::malloc_count() == 1); ASSERT_OR_FAIL(Traits::free_count() == 0); ProducerToken tok(q); ASSERT_OR_FAIL(Traits::malloc_count() == 3); // one for producer, one for its block index ASSERT_OR_FAIL(Traits::free_count() == 0); // Enqueue one item too many (force extra block allocation) for (int i = 0; i != 9; ++i) { ASSERT_OR_FAIL(q.enqueue(tok, i)); } ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 0); // Still room for one more... ASSERT_OR_FAIL(q.enqueue(tok, 9)); ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 0); // No more room without further allocations ASSERT_OR_FAIL(!q.try_enqueue(tok, 10)); ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 0); // Check items were enqueued properly int item; for (int i = 0; i != 10; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(tok, item)); ASSERT_OR_FAIL(item == i); } // Queue should be empty, but not freed ASSERT_OR_FAIL(!q.try_dequeue_from_producer(tok, item)); ASSERT_OR_FAIL(Traits::free_count() == 0); } ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 4); // Implicit Traits::reset(); { ConcurrentQueue q(7); ASSERT_OR_FAIL(q.initialBlockPoolSize == 4); ASSERT_OR_FAIL(q.enqueue(39)); ASSERT_OR_FAIL(Traits::malloc_count() == 3); // one for producer, one for its block index ASSERT_OR_FAIL(Traits::free_count() == 0); // Enqueue one item too many (force extra block allocation) for (int i = 0; i != 8; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 0); // Still room for one more... ASSERT_OR_FAIL(q.enqueue(8)); ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 0); // No more room without further allocations ASSERT_OR_FAIL(!q.try_enqueue(9)); ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 0); // Check items were enqueued properly int item; ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == 39); for (int i = 0; i != 9; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } // Queue should be empty, but not freed ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(Traits::free_count() == 0); } ASSERT_OR_FAIL(Traits::malloc_count() == 4); ASSERT_OR_FAIL(Traits::free_count() == 4); return true; } bool token_move() { typedef TestTraits<16> Traits; Traits::reset(); { ConcurrentQueue q; ProducerToken t0(q); ASSERT_OR_FAIL(t0.valid()); ProducerToken t1(std::move(t0)); ASSERT_OR_FAIL(t1.valid()); ASSERT_OR_FAIL(!t0.valid()); t1 = std::move(t1); ASSERT_OR_FAIL(t1.valid()); ASSERT_OR_FAIL(!t0.valid()); ProducerToken t2(q); t2 = std::move(t1); ASSERT_OR_FAIL(t2.valid()); ASSERT_OR_FAIL(t1.valid()); ASSERT_OR_FAIL(!t0.valid()); t0 = std::move(t1); ASSERT_OR_FAIL(t2.valid()); ASSERT_OR_FAIL(!t1.valid()); ASSERT_OR_FAIL(t0.valid()); } ASSERT_OR_FAIL(Traits::malloc_count() == 5); // 2 for each producer + 1 for initial block pool ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); return true; } bool multi_producers() { typedef TestTraits<16> Traits; Traits::reset(); { ConcurrentQueue q; ProducerToken t0(q); ProducerToken t1(q); ProducerToken t2(q); ProducerToken t3(q); ProducerToken t4(q); ASSERT_OR_FAIL(q.enqueue(t0, 0)); ASSERT_OR_FAIL(q.enqueue(t1, 1)); ASSERT_OR_FAIL(q.enqueue(t2, 2)); ASSERT_OR_FAIL(q.enqueue(t3, 3)); ASSERT_OR_FAIL(q.enqueue(t4, 4)); int item; ASSERT_OR_FAIL(q.try_dequeue_from_producer(t0, item) && item == 0 && !q.try_dequeue_from_producer(t0, item)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t1, item) && item == 1 && !q.try_dequeue_from_producer(t1, item)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t2, item) && item == 2 && !q.try_dequeue_from_producer(t2, item)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t3, item) && item == 3 && !q.try_dequeue_from_producer(t3, item)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t4, item) && item == 4 && !q.try_dequeue_from_producer(t4, item)); } ASSERT_OR_FAIL(Traits::malloc_count() == 11); // 2 for each producer + 1 for initial block pool ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); // Implicit Traits::reset(); { ConcurrentQueue q; std::atomic success[5]; std::atomic done(0); for (int i = 0; i != 5; ++i) { success[i].store(false, std::memory_order_relaxed); } for (int i = 0; i != 5; ++i) { SimpleThread t([&](int j) { success[j].store(q.enqueue(j), std::memory_order_relaxed); done.fetch_add(1, std::memory_order_release); }, i); t.join(); } while (done.load(std::memory_order_acquire) != 5) { continue; } for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(success[i].load(std::memory_order_relaxed)); } // Cannot rely on order that producers are added (there's a race condition), only that they are all there somewhere. // Also, all items may not be visible to this thread yet. bool itemDequeued[5] = { false, false, false, false, false }; int item; for (int i = 0; i != 5;) { if (q.try_dequeue(item)) { itemDequeued[item] = true; ++i; } } for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(itemDequeued[i]); } } ASSERT_OR_FAIL(Traits::malloc_count() <= 11 && Traits::malloc_count() >= 3); // 2 for each producer (depending on thread ID re-use) + 1 for initial block pool ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); return true; } bool producer_reuse() { typedef TestTraits<16> Traits; Traits::reset(); { // Explicit ConcurrentQueue q; { ProducerToken t0(q); } { ProducerToken t1(q); } { ProducerToken t2(q); ProducerToken t3(q); ProducerToken t4(q); ProducerToken t5(q); } { ProducerToken t6(q); ProducerToken t7(q); } { ProducerToken t8(q); ProducerToken t9(q); } { ProducerToken t10(q); ProducerToken t11(q); } } ASSERT_OR_FAIL(Traits::malloc_count() == 9); // 2 for max number of live producers + 1 for initial block pool ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED Traits::reset(); { // Implicit const int MAX_THREADS = 48; ConcurrentQueue q(Traits::BLOCK_SIZE * (MAX_THREADS + 1)); ASSERT_OR_FAIL(Traits::malloc_count() == 1); // Initial block pool SimpleThread t0([&]() { q.enqueue(0); }); t0.join(); ASSERT_OR_FAIL(Traits::malloc_count() == 3); // Implicit producer SimpleThread t1([&]() { q.enqueue(1); }); t1.join(); ASSERT_OR_FAIL(Traits::malloc_count() == 3); SimpleThread t2([&]() { q.enqueue(2); }); t2.join(); ASSERT_OR_FAIL(Traits::malloc_count() == 3); q.enqueue(3); ASSERT_OR_FAIL(Traits::malloc_count() == 3); int item; int i = 0; while (q.try_dequeue(item)) { ASSERT_OR_FAIL(item == i); ++i; } ASSERT_OR_FAIL(i == 4); ASSERT_OR_FAIL(Traits::malloc_count() == 3); std::vector threads(MAX_THREADS); for (int rep = 0; rep != 2; ++rep) { for (std::size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](std::size_t tid) { for (volatile int i = 0; i != 4096; ++i) { continue; } q.enqueue((int)tid); for (volatile int i = 0; i != 4096; ++i) { continue; } }, tid); } for (std::size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); } std::vector seenIds(threads.size()); for (std::size_t i = 0; i != threads.size(); ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(!seenIds[item]); seenIds[item] = true; } for (std::size_t i = 0; i != seenIds.size(); ++i) { ASSERT_OR_FAIL(seenIds[i]); } ASSERT_OR_FAIL(Traits::malloc_count() <= 2 * MAX_THREADS + 1); } } ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); Traits::reset(); { // Test many threads and implicit queues being created and destroyed concurrently std::vector threads(32); std::vector success(threads.size(), true); for (std::size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](std::size_t tid) { for (int i = 0; i != 5; ++i) { ConcurrentQueue q(1); q.enqueue(i); } ConcurrentQueue q(15); for (int i = 0; i != 100; ++i) { q.enqueue(i); } int item; for (int i = 0; i != 100; ++i) { if (!q.try_dequeue(item) || item != i) { success[tid] = false; } } if (q.size_approx() != 0) { success[tid] = false; } }, tid); } for (std::size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); ASSERT_OR_FAIL(success[tid]); } } ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); #endif return true; } bool block_reuse() { int item; typedef TestTraits<4> SmallBlocks; SmallBlocks::reset(); { ConcurrentQueue q(8); // 2 blocks ProducerToken t(q); for (int j = 0; j != 3; ++j) { for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.enqueue(t, i)); } for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 8; ++i) { ASSERT_OR_FAIL(q.enqueue(t, i)); } for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.enqueue(t, i)); } for (int i = 0; i != 8; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item == ((i + 4) & 7)); } ASSERT_OR_FAIL(!q.try_dequeue_from_producer(t, item)); } } ASSERT_OR_FAIL(SmallBlocks::malloc_count() == 3); ASSERT_OR_FAIL(SmallBlocks::free_count() == SmallBlocks::malloc_count()); typedef TestTraits<8192> HugeBlocks; HugeBlocks::reset(); { ConcurrentQueue q(8192 * 2); // 2 blocks ProducerToken t(q); for (int j = 0; j != 3; ++j) { for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.enqueue(t, i)); } for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 8192 * 2; ++i) { ASSERT_OR_FAIL(q.enqueue(t, i)); } for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.enqueue(t, i)); } for (int i = 0; i != 8192 * 2; ++i) { ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item == ((i + 8192) & (8192 * 2 - 1))); } ASSERT_OR_FAIL(!q.try_dequeue_from_producer(t, item)); } } ASSERT_OR_FAIL(HugeBlocks::malloc_count() == 3); ASSERT_OR_FAIL(HugeBlocks::free_count() == HugeBlocks::malloc_count()); // Implicit SmallBlocks::reset(); { ConcurrentQueue q(8); // 2 blocks for (int j = 0; j != 3; ++j) { for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 8; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } for (int i = 0; i != 8; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == ((i + 4) & 7)); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } } ASSERT_OR_FAIL(SmallBlocks::malloc_count() == 3); ASSERT_OR_FAIL(SmallBlocks::free_count() == SmallBlocks::malloc_count()); HugeBlocks::reset(); { ConcurrentQueue q(8192 * 2); // 2 blocks for (int j = 0; j != 3; ++j) { for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 8192 * 2; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } for (int i = 0; i != 8192; ++i) { ASSERT_OR_FAIL(q.enqueue(i)); } for (int i = 0; i != 8192 * 2; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == ((i + 8192) & (8192 * 2 - 1))); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } } ASSERT_OR_FAIL(HugeBlocks::malloc_count() == 3); ASSERT_OR_FAIL(HugeBlocks::free_count() == HugeBlocks::malloc_count()); return true; } bool block_recycling() { typedef TestTraits<4> SmallBlocks; SmallBlocks::reset(); ConcurrentQueue q(24); // 6 blocks SimpleThread threads[4]; std::atomic success(true); for (int i = 0; i != 4; ++i) { threads[i] = SimpleThread([&](int i) { int item; int next = 0; int prevItems[4] = { -1, -1, -1, -1 }; for (int successfulEnqueues = 0; successfulEnqueues < 10000;) { for (int j = 0; j != 12; ++j) { if (q.try_enqueue((i << 28) | next++)) { ++successfulEnqueues; } } for (int j = 0; j != 12; ++j) { if (q.try_dequeue(item)) { if ((item & 0x0FFFFFFF) <= prevItems[item >> 28]) { success.store(false, std::memory_order_relaxed); } prevItems[item >> 28] = item & 0x0FFFFFFF; } } } }, i); } for (int i = 0; i != 4; ++i) { threads[i].join(); } int item; int prevItems[4] = { -1, -1, -1, -1 }; while (q.try_dequeue(item)) { ASSERT_OR_FAIL((item & 0x0FFFFFFF) > prevItems[item >> 28]); prevItems[item >> 28] = item & 0x0FFFFFFF; } ASSERT_OR_FAIL(success.load(std::memory_order_relaxed)); return true; } bool leftovers_destroyed() { typedef TestTraits<4> Traits; Traits::reset(); Foo::reset(); { ConcurrentQueue q(4); // One block ProducerToken t(q); Foo item; q.enqueue(t, Foo()); q.enqueue(t, Foo()); q.enqueue(t, Foo()); q.try_dequeue_from_producer(t, item); } ASSERT_OR_FAIL(Foo::createCount() == 4); ASSERT_OR_FAIL(Foo::destroyCount() == 7); ASSERT_OR_FAIL(Foo::destroyedInOrder()); Traits::reset(); Foo::reset(); { ConcurrentQueue q(4); // One block ProducerToken t(q); q.enqueue(t, Foo()); q.enqueue(t, Foo()); q.enqueue(t, Foo()); q.enqueue(t, Foo()); } ASSERT_OR_FAIL(Foo::createCount() == 4); ASSERT_OR_FAIL(Foo::destroyCount() == 8); ASSERT_OR_FAIL(Foo::destroyedInOrder()); Traits::reset(); Foo::reset(); { ConcurrentQueue q(8); // Two blocks ProducerToken t(q); for (int i = 0; i != 8; ++i) { q.enqueue(t, Foo()); } } ASSERT_OR_FAIL(Foo::createCount() == 8); ASSERT_OR_FAIL(Foo::destroyCount() == 16); ASSERT_OR_FAIL(Foo::destroyedInOrder()); Traits::reset(); Foo::reset(); { ConcurrentQueue q(12); // Three blocks ProducerToken t(q); // Last block only partially full for (int i = 0; i != 10; ++i) { q.enqueue(t, Foo()); } // First block only partially full Foo item; ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); } ASSERT_OR_FAIL(Foo::createCount() == 11); ASSERT_OR_FAIL(Foo::destroyCount() == 21); ASSERT_OR_FAIL(Foo::destroyedInOrder()); // Implicit Traits::reset(); Foo::reset(); { ConcurrentQueue q(4); // One block Foo item; q.enqueue(Foo()); q.enqueue(Foo()); q.enqueue(Foo()); q.try_dequeue(item); } ASSERT_OR_FAIL(Foo::createCount() == 4); ASSERT_OR_FAIL(Foo::destroyCount() == 7); ASSERT_OR_FAIL(Foo::destroyedInOrder()); Traits::reset(); Foo::reset(); { ConcurrentQueue q(4); // One block q.enqueue(Foo()); q.enqueue(Foo()); q.enqueue(Foo()); q.enqueue(Foo()); } ASSERT_OR_FAIL(Foo::createCount() == 4); ASSERT_OR_FAIL(Foo::destroyCount() == 8); ASSERT_OR_FAIL(Foo::destroyedInOrder()); Traits::reset(); Foo::reset(); { ConcurrentQueue q(8); // Two blocks for (int i = 0; i != 8; ++i) { q.enqueue(Foo()); } } ASSERT_OR_FAIL(Foo::createCount() == 8); ASSERT_OR_FAIL(Foo::destroyCount() == 16); ASSERT_OR_FAIL(Foo::destroyedInOrder()); Traits::reset(); Foo::reset(); { ConcurrentQueue q(12); // Three blocks // Last block only partially full for (int i = 0; i != 10; ++i) { q.enqueue(Foo()); } // First block only partially full Foo item; ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(q.try_dequeue(item)); } ASSERT_OR_FAIL(Foo::createCount() == 11); ASSERT_OR_FAIL(Foo::destroyCount() == 21); ASSERT_OR_FAIL(Foo::destroyedInOrder()); return true; } bool block_index_resized() { typedef TestTraits<4, 2> Traits; Traits::reset(); Foo::reset(); { ConcurrentQueue q(8); // 2 blocks, matches initial index size ProducerToken t(q); for (int i = 0; i != 1024; ++i) { q.enqueue(t, Foo()); } for (int i = 0; i != 1024; ++i) { Foo item; q.try_dequeue_from_producer(t, item); } } ASSERT_OR_FAIL(Traits::malloc_count() == 1 + 2 + 254 + 7); ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); ASSERT_OR_FAIL(Foo::createCount() == 2048); ASSERT_OR_FAIL(Foo::destroyCount() == 3072); ASSERT_OR_FAIL(Foo::destroyedInOrder()); // Implicit Traits::reset(); Foo::reset(); { ConcurrentQueue q(8); // 2 blocks for (int i = 0; i != 1024; ++i) { q.enqueue(Foo()); } for (int i = 0; i != 1024; ++i) { Foo item; q.try_dequeue(item); } } ASSERT_OR_FAIL(Traits::malloc_count() == 1 + 2 + 254 + 6); ASSERT_OR_FAIL(Traits::free_count() == Traits::malloc_count()); ASSERT_OR_FAIL(Foo::createCount() == 2048); ASSERT_OR_FAIL(Foo::destroyCount() == 3072); ASSERT_OR_FAIL(Foo::destroyedInOrder()); return true; } bool try_dequeue() { ConcurrentQueue q; int item; // Producer token { for (int i = 0; i != 50; ++i) { ProducerToken t(q); for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.enqueue(t, i * 100 + j)); } } for (int i = 0; i != 50; ++i) { for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i * 100 + j); } } ASSERT_OR_FAIL(!q.try_dequeue(item)); } // Mixed producer types { for (int i = 0; i != 25; ++i) { for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.enqueue(i * 100 + j)); } } for (int i = 25; i != 50; ++i) { ProducerToken t(q); for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.enqueue(t, i * 100 + j)); } } bool success[5000]; std::memset(success, 0, sizeof(success)); for (int i = 0; i != 50; ++i) { for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.try_dequeue(item)); success[item] = true; } } for (int i = 0; i != 5000; ++i) { ASSERT_OR_FAIL(success[i]); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } // Mixed producer types with consumer token { for (int i = 0; i != 25; ++i) { for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.enqueue(i * 100 + j)); } } for (int i = 25; i != 50; ++i) { ProducerToken t(q); for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.enqueue(t, i * 100 + j)); } } bool success[5000]; std::memset(success, 0, sizeof(success)); for (int i = 0; i != 50; ++i) { ConsumerToken t(q); for (int j = 0; j != 100; ++j) { ASSERT_OR_FAIL(q.try_dequeue(t, item)); success[item] = true; } } for (int i = 0; i != 5000; ++i) { ASSERT_OR_FAIL(success[i]); } ConsumerToken t(q); ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(!q.try_dequeue(t, item)); ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(!q.try_dequeue(t, item)); } return true; } bool try_dequeue_threaded() { int item; ConcurrentQueue q; // Threaded consumption with tokens { SimpleThread threads[20]; for (int i = 0; i != 10; ++i) { threads[i] = SimpleThread([&](int i) { ProducerToken t(q); for (int j = 0; j != 100; ++j) { q.enqueue(t, i * 10 + j); } }, i); } std::atomic dequeueCount(0); for (int i = 10; i != 20; ++i) { threads[i] = SimpleThread([&]() { int item; ConsumerToken t(q); while (dequeueCount.load(std::memory_order_relaxed) != 1000) { if (q.try_dequeue(t, item)) { dequeueCount.fetch_add(1, std::memory_order_relaxed); } } }); } for (int i = 0; i != 20; ++i) { threads[i].join(); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } // Threaded consumption { SimpleThread threads[20]; for (int i = 0; i != 10; ++i) { threads[i] = SimpleThread([&](int i) { for (int j = 0; j != 100; ++j) { q.enqueue(i * 10 + j); } }, i); } std::atomic dequeueCount(0); for (int i = 10; i != 20; ++i) { threads[i] = SimpleThread([&]() { int item; while (dequeueCount.load(std::memory_order_relaxed) != 1000) { if (q.try_dequeue(item)) { dequeueCount.fetch_add(1, std::memory_order_relaxed); } } }); } for (int i = 0; i != 20; ++i) { threads[i].join(); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } return true; } bool try_dequeue_bulk() { typedef TestTraits<4> Traits; int items[5]; // Explicit producer { Traits::reset(); ConcurrentQueue q; ProducerToken tok(q); ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 0); q.enqueue(tok, 17); ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 1); ASSERT_OR_FAIL(items[0] == 17); ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 4; ++i) { q.enqueue(tok, i + 1); } ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 4); for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(items[i] == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 5; ++i) { q.enqueue(tok, i + 1); } ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 5); for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(items[i] == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 6; ++i) { q.enqueue(tok, i + 1); } ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 5); for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(items[i] == i + 1); } ASSERT_OR_FAIL(q.try_dequeue(items[0])); ASSERT_OR_FAIL(items[0] == 6); ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 10; ++i) { q.enqueue(tok, i + 1); } for (int k = 0; k != 2; ++k) { ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 5); for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(items[i] == k * 5 + i + 1); } } ASSERT_OR_FAIL(!q.try_dequeue(items[0])); } // Implicit producer { Traits::reset(); ConcurrentQueue q; ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 0); q.enqueue(17); ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 1); ASSERT_OR_FAIL(items[0] == 17); ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 4; ++i) { q.enqueue(i + 1); } ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 4); for (int i = 0; i != 4; ++i) { ASSERT_OR_FAIL(items[i] == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 5; ++i) { q.enqueue(i + 1); } ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 5); for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(items[i] == i + 1); } ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 6; ++i) { q.enqueue(i + 1); } ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 5); for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(items[i] == i + 1); } ASSERT_OR_FAIL(q.try_dequeue(items[0])); ASSERT_OR_FAIL(items[0] == 6); ASSERT_OR_FAIL(!q.try_dequeue(items[0])); for (int i = 0; i != 10; ++i) { q.enqueue(i + 1); } for (int k = 0; k != 2; ++k) { ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 5) == 5); for (int i = 0; i != 5; ++i) { ASSERT_OR_FAIL(items[i] == k * 5 + i + 1); } } ASSERT_OR_FAIL(!q.try_dequeue(items[0])); } return true; } bool try_dequeue_bulk_threaded() { typedef TestTraits<2> Traits; int dummy; // Explicit producer { Traits::reset(); ConcurrentQueue q; SimpleThread threads[2]; bool success[2] = { true, true }; for (int i = 0; i != 2; ++i) { if (i == 0) { threads[i] = SimpleThread([&](int i) { // Producer ProducerToken tok(q); for (int i = 0; i != 32*1024; ++i) { q.enqueue(tok, i); } }, i); } else { threads[i] = SimpleThread([&](int i) { // Consumer int items[5]; int prevItem = -1; for (int i = 0; i != 32*1024;) { auto dequeued = q.try_dequeue_bulk(items, 5); if (dequeued > 0) { if (dequeued > 5) { success[i] = false; break; } for (std::size_t j = 0; j != dequeued; ++j) { if (items[j] != prevItem + 1) { success[i] = false; } prevItem = items[j]; } i += (int)dequeued; } } }, i); } } for (int i = 0; i != 2; ++i) { threads[i].join(); } ASSERT_OR_FAIL(success[0]); ASSERT_OR_FAIL(success[1]); ASSERT_OR_FAIL(!q.try_dequeue(dummy)); } // Implicit producer { Traits::reset(); ConcurrentQueue q; SimpleThread threads[2]; bool success[2] = { true, true }; for (int i = 0; i != 2; ++i) { if (i == 0) { threads[i] = SimpleThread([&](int i) { // Producer for (int i = 0; i != 32*1024; ++i) { q.enqueue(i); } }, i); } else { threads[i] = SimpleThread([&](int i) { // Consumer int items[5]; int prevItem = -1; for (int i = 0; i != 32*1024;) { auto dequeued = q.try_dequeue_bulk(items, 5); if (dequeued > 0) { if (dequeued > 5) { success[i] = false; break; } for (std::size_t j = 0; j != dequeued; ++j) { if (items[j] != prevItem + 1) { success[i] = false; } prevItem = items[j]; } i += (int)dequeued; } } }, i); } } for (int i = 0; i != 2; ++i) { threads[i].join(); } ASSERT_OR_FAIL(success[0]); ASSERT_OR_FAIL(success[1]); ASSERT_OR_FAIL(!q.try_dequeue(dummy)); } // Multithreaded consumption { Traits::reset(); ConcurrentQueue q; bool success[20]; SimpleThread threads[20]; for (int i = 0; i != 10; ++i) { success[i] = true; threads[i] = SimpleThread([&](int i) { ProducerToken t(q); if ((i & 1) == 1) { for (int j = 0; j != 100; ++j) { q.enqueue(t, i * 128 + j); } } else { for (int j = 0; j != 100; ++j) { q.enqueue(i * 128 + j); } } }, i); } std::atomic dequeueCount(0); for (int i = 10; i != 20; ++i) { success[i] = true; threads[i] = SimpleThread([&](int i) { int prevItems[10]; for (int j = 0; j != 10; ++j) { prevItems[j] = -1; } int items[15]; ConsumerToken t(q); while (dequeueCount.load(std::memory_order_relaxed) != 1000) { size_t count; if ((i & 1) == 1) { count = q.try_dequeue_bulk(items, 15); } else { count = q.try_dequeue_bulk(t, items, 15); } if (count > 15) { success[i] = false; } for (size_t k = 0; k != count; ++k) { if (prevItems[items[k] / 128] >= (items[k] & 127)) { success[i] = false; } prevItems[items[k] / 128] = items[k] & 127; } dequeueCount.fetch_add(count, std::memory_order_relaxed); } }, i); } for (int i = 0; i != 20; ++i) { threads[i].join(); } int item; ASSERT_OR_FAIL(!q.try_dequeue(item)); for (int i = 0; i != 20; ++i) { ASSERT_OR_FAIL(success[i]); } } return true; } bool implicit_producer_hash() { for (int j = 0; j != 5; ++j) { ConcurrentQueue q; std::vector threads; for (int i = 0; i != 20; ++i) { threads.push_back(SimpleThread([&]() { q.enqueue(7); })); } for (auto it = threads.begin(); it != threads.end(); ++it) { it->join(); } int item; ConsumerToken t(q); for (auto i = 0; i != 20; ++i) { if ((j & 1) == 0) { ASSERT_OR_FAIL(q.try_dequeue(item)); } else { ASSERT_OR_FAIL(q.try_dequeue(t, item)); } ASSERT_OR_FAIL(item == 7); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } return true; } bool index_wrapping() { { // Implicit ConcurrentQueue q(16); int item; for (int i = 0; i != (1 << 18); ++i) { if ((i & 16) == 0) { ASSERT_OR_FAIL(q.try_enqueue(i)); } else { ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == (i - 16)); } } ASSERT_OR_FAIL(!q.try_dequeue(item)); } { // Explicit ConcurrentQueue q(16); ProducerToken tok(q); int item; for (int i = 0; i != (1 << 18); ++i) { if ((i & 16) == 0) { ASSERT_OR_FAIL(q.try_enqueue(tok, i)); } else { ASSERT_OR_FAIL(q.try_dequeue_from_producer(tok, item)); ASSERT_OR_FAIL(item == (i - 16)); } } ASSERT_OR_FAIL(!q.try_dequeue(item)); } { // Implicit extra small ConcurrentQueue q(1); int item; for (int i = 0; i != 4097; ++i) { q.enqueue(i); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } { // Explicit extra small ConcurrentQueue q(1); ProducerToken tok(q); int item; for (int i = 0; i != 4097; ++i) { q.enqueue(tok, i); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue(item)); } return true; } struct SizeLimitTraits : public MallocTrackingTraits { static const size_t BLOCK_SIZE = 2; static const size_t MAX_SUBQUEUE_SIZE = 5; // Will round up to 6 because of block size }; bool subqueue_size_limit() { { // Explicit ConcurrentQueue q; ProducerToken t(q); int item; ASSERT_OR_FAIL(q.enqueue(t, 1)); ASSERT_OR_FAIL(q.enqueue(t, 2)); ASSERT_OR_FAIL(q.enqueue(t, 3)); ASSERT_OR_FAIL(q.enqueue(t, 4)); ASSERT_OR_FAIL(q.enqueue(t, 5)); ASSERT_OR_FAIL(q.enqueue(t, 6)); ASSERT_OR_FAIL(!q.enqueue(t, 7)); ASSERT_OR_FAIL(!q.enqueue(t, 8)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 1); ASSERT_OR_FAIL(!q.enqueue(t, 7)); // Can't reuse block until it's completely empty ASSERT_OR_FAIL(q.try_dequeue(item) && item == 2); ASSERT_OR_FAIL(q.enqueue(t, 7)); ASSERT_OR_FAIL(q.enqueue(t, 8)); ASSERT_OR_FAIL(!q.enqueue(t, 9)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 3); ASSERT_OR_FAIL(!q.enqueue(t, 9)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 4); ASSERT_OR_FAIL(q.enqueue(t, 9)); for (int i = 5; i <= 9; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item) && item == i); } ASSERT_OR_FAIL(q.enqueue(t, 10)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 10); ASSERT_OR_FAIL(!q.try_dequeue(item)); for (int i = 0; i != 6; ++i) { ASSERT_OR_FAIL(q.try_enqueue(t, i)); } ASSERT_OR_FAIL(!q.try_enqueue(t, 7)); ASSERT_OR_FAIL(!q.enqueue(t, 7)); // Bulk int items[6]; ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 6) == 6); ASSERT_OR_FAIL(!q.try_enqueue_bulk(t, items, 7)); ASSERT_OR_FAIL(!q.enqueue_bulk(t, items, 7)); ASSERT_OR_FAIL(q.enqueue_bulk(t, items, 6)); ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 6) == 6); ASSERT_OR_FAIL(q.enqueue_bulk(t, items, 3)); ASSERT_OR_FAIL(!q.enqueue_bulk(t, items, 4)); ASSERT_OR_FAIL(q.enqueue_bulk(t, items, 3)); ASSERT_OR_FAIL(!q.enqueue_bulk(t, items, 1)); ASSERT_OR_FAIL(!q.enqueue(t, 100)); ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 1) == 1); ASSERT_OR_FAIL(!q.enqueue(t, 100)); } { // Implicit ConcurrentQueue q; int item; ASSERT_OR_FAIL(q.enqueue(1)); ASSERT_OR_FAIL(q.enqueue(2)); ASSERT_OR_FAIL(q.enqueue(3)); ASSERT_OR_FAIL(q.enqueue(4)); ASSERT_OR_FAIL(q.enqueue(5)); ASSERT_OR_FAIL(q.enqueue(6)); ASSERT_OR_FAIL(!q.enqueue(7)); ASSERT_OR_FAIL(!q.enqueue(8)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 1); ASSERT_OR_FAIL(!q.enqueue(7)); // Can't reuse block until it's completely empty ASSERT_OR_FAIL(q.try_dequeue(item) && item == 2); ASSERT_OR_FAIL(q.enqueue(7)); ASSERT_OR_FAIL(q.enqueue(8)); ASSERT_OR_FAIL(!q.enqueue(9)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 3); ASSERT_OR_FAIL(!q.enqueue(9)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 4); ASSERT_OR_FAIL(q.enqueue(9)); for (int i = 5; i <= 9; ++i) { ASSERT_OR_FAIL(q.try_dequeue(item) && item == i); } ASSERT_OR_FAIL(q.enqueue(10)); ASSERT_OR_FAIL(q.try_dequeue(item) && item == 10); ASSERT_OR_FAIL(!q.try_dequeue(item)); for (int i = 0; i != 6; ++i) { ASSERT_OR_FAIL(q.try_enqueue(i)); } ASSERT_OR_FAIL(!q.try_enqueue(7)); ASSERT_OR_FAIL(!q.enqueue(7)); // Bulk int items[6]; ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 6) == 6); ASSERT_OR_FAIL(!q.try_enqueue_bulk(items, 7)); ASSERT_OR_FAIL(!q.enqueue_bulk(items, 7)); ASSERT_OR_FAIL(q.enqueue_bulk(items, 6)); ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 6) == 6); ASSERT_OR_FAIL(q.enqueue_bulk(items, 3)); ASSERT_OR_FAIL(!q.enqueue_bulk(items, 4)); ASSERT_OR_FAIL(q.enqueue_bulk(items, 3)); ASSERT_OR_FAIL(!q.enqueue_bulk(items, 1)); ASSERT_OR_FAIL(!q.enqueue(100)); ASSERT_OR_FAIL(q.try_dequeue_bulk(items, 1) == 1); ASSERT_OR_FAIL(!q.enqueue(100)); } return true; } bool exceptions() { typedef TestTraits<4, 2> Traits; { // Explicit, basic // enqueue ConcurrentQueue q; ProducerToken tok(q); ThrowingMovable::reset(); bool threw = false; try { q.enqueue(tok, ThrowingMovable(1, true)); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 1); ASSERT_OR_FAIL(m->moved); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 0); ASSERT_OR_FAIL(q.enqueue(tok, ThrowingMovable(2))); ThrowingMovable result(-1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 2); ASSERT_OR_FAIL(result.moved); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 3); // dequeue ThrowingMovable::reset(); q.enqueue(tok, ThrowingMovable(10)); q.enqueue(tok, ThrowingMovable(11, false, true)); q.enqueue(tok, ThrowingMovable(12)); ASSERT_OR_FAIL(q.size_approx() == 3); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 10); threw = false; try { q.try_dequeue(result); } catch (ThrowingMovable* m) { ASSERT_OR_FAIL(m->id == 11); threw = true; } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 12); ASSERT_OR_FAIL(result.moved); ASSERT_OR_FAIL(!q.try_dequeue(result)); q.enqueue(tok, ThrowingMovable(13)); ASSERT_OR_FAIL(q.size_approx() == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 13); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 8); } { // Explicit, on and off block boundaries // enqueue ConcurrentQueue q; ProducerToken tok(q); ThrowingMovable::reset(); for (int i = 0; i != 3; ++i) { q.enqueue(tok, ThrowingMovable(i)); } bool threw = false; try { q.enqueue(tok, ThrowingMovable(3, true)); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 3); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 3); q.enqueue(tok, ThrowingMovable(4)); threw = false; try { q.enqueue(tok, ThrowingMovable(5, true)); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 5); ASSERT_OR_FAIL(m->moved); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 4); q.enqueue(tok, ThrowingMovable(6)); ThrowingMovable result(-1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 0); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 2); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 4); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 6); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 12); // dequeue ThrowingMovable::reset(); q.enqueue(tok, ThrowingMovable(10, false, true)); q.enqueue(tok, ThrowingMovable(11)); q.enqueue(tok, ThrowingMovable(12)); q.enqueue(tok, ThrowingMovable(13, false, true)); q.enqueue(tok, ThrowingMovable(14, false, true)); q.enqueue(tok, ThrowingMovable(15, false, true)); q.enqueue(tok, ThrowingMovable(16)); ASSERT_OR_FAIL(q.size_approx() == 7); for (int i = 10; i != 17; ++i) { if (i == 10 || (i >= 13 && i <= 15)) { threw = false; try { q.try_dequeue(result); } catch (ThrowingMovable* m) { ASSERT_OR_FAIL(m->id == i); ASSERT_OR_FAIL(m->moved); threw = true; } ASSERT_OR_FAIL(threw); } else { ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == i); ASSERT_OR_FAIL(result.moved); } ASSERT_OR_FAIL(q.size_approx() == (std::uint32_t)(16 - i)); } ASSERT_OR_FAIL(!q.try_dequeue(result)); q.enqueue(tok, ThrowingMovable(20)); ASSERT_OR_FAIL(q.size_approx() == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 20); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 16); } { // Explicit bulk // enqueue ConcurrentQueue q; ProducerToken tok(q); ThrowingMovable::reset(); std::vector items; items.reserve(5); items.push_back(ThrowingMovable(1)); items.push_back(ThrowingMovable(2)); items.push_back(ThrowingMovable(3)); items.push_back(ThrowingMovable(4)); items.push_back(ThrowingMovable(5)); items.back().throwOnCctor = true; bool threw = false; try { q.enqueue_bulk(tok, std::make_move_iterator(items.begin()), 5); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 5); ASSERT_OR_FAIL(m->copied); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 0); q.enqueue(tok, ThrowingMovable(6)); threw = false; try { q.enqueue_bulk(tok, std::make_move_iterator(items.begin()), 5); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 5); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 1); ThrowingMovable result(-1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 6); ASSERT_OR_FAIL(result.moved); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 15); // dequeue ThrowingMovable::reset(); q.enqueue(tok, ThrowingMovable(10)); q.enqueue(tok, ThrowingMovable(11)); q.enqueue(tok, ThrowingMovable(12)); q.enqueue(tok, ThrowingMovable(13)); q.enqueue(tok, ThrowingMovable(14, false, true, true)); // std::back_inserter turns an assignment into a ctor call q.enqueue(tok, ThrowingMovable(15)); ASSERT_OR_FAIL(q.size_approx() == 6); std::vector results; results.reserve(5); ASSERT_OR_FAIL(q.try_dequeue_bulk(std::back_inserter(results), 2)); ASSERT_OR_FAIL(results.size() == 2); ASSERT_OR_FAIL(results[0].id == 10); ASSERT_OR_FAIL(results[1].id == 11); ASSERT_OR_FAIL(results[0].moved); ASSERT_OR_FAIL(results[1].moved); ASSERT_OR_FAIL(q.size_approx() == 4); threw = false; try { q.try_dequeue_bulk(std::back_inserter(results), 4); } catch (ThrowingMovable*) { // Note: Can't inspect thrown value since it points to an object whose construction was attempted on the vector and // no longer exists threw = true; } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 0); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(q.try_dequeue_bulk(std::back_inserter(results), 1) == 0); ASSERT_OR_FAIL(results.size() == 4); ASSERT_OR_FAIL(results[2].id == 12); ASSERT_OR_FAIL(results[3].id == 13); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 12); } { // Implicit, basic // enqueue ConcurrentQueue q; ThrowingMovable::reset(); bool threw = false; try { q.enqueue(ThrowingMovable(1, true)); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 1); ASSERT_OR_FAIL(m->moved); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 0); ASSERT_OR_FAIL(q.enqueue(ThrowingMovable(2))); ThrowingMovable result(-1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 2); ASSERT_OR_FAIL(result.moved); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 3); // dequeue ThrowingMovable::reset(); q.enqueue(ThrowingMovable(10)); q.enqueue(ThrowingMovable(11, false, true)); q.enqueue(ThrowingMovable(12)); ASSERT_OR_FAIL(q.size_approx() == 3); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 10); threw = false; try { q.try_dequeue(result); } catch (ThrowingMovable* m) { ASSERT_OR_FAIL(m->id == 11); threw = true; } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 12); ASSERT_OR_FAIL(result.moved); ASSERT_OR_FAIL(!q.try_dequeue(result)); q.enqueue(ThrowingMovable(13)); ASSERT_OR_FAIL(q.size_approx() == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 13); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 8); } { // Implicit, on and off block boundaries // enqueue ConcurrentQueue q; ThrowingMovable::reset(); for (int i = 0; i != 3; ++i) { q.enqueue(ThrowingMovable(i)); } bool threw = false; try { q.enqueue(ThrowingMovable(3, true)); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 3); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 3); q.enqueue(ThrowingMovable(4)); threw = false; try { q.enqueue(ThrowingMovable(5, true)); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 5); ASSERT_OR_FAIL(m->moved); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 4); q.enqueue(ThrowingMovable(6)); ThrowingMovable result(-1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 0); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 2); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 4); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 6); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 12); // dequeue ThrowingMovable::reset(); q.enqueue(ThrowingMovable(10, false, true)); q.enqueue(ThrowingMovable(11)); q.enqueue(ThrowingMovable(12)); q.enqueue(ThrowingMovable(13, false, true)); q.enqueue(ThrowingMovable(14, false, true)); q.enqueue(ThrowingMovable(15, false, true)); q.enqueue(ThrowingMovable(16)); ASSERT_OR_FAIL(q.size_approx() == 7); for (int i = 10; i != 17; ++i) { if (i == 10 || (i >= 13 && i <= 15)) { threw = false; try { q.try_dequeue(result); } catch (ThrowingMovable* m) { ASSERT_OR_FAIL(m->id == i); ASSERT_OR_FAIL(m->moved); threw = true; } ASSERT_OR_FAIL(threw); } else { ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == i); ASSERT_OR_FAIL(result.moved); } ASSERT_OR_FAIL(q.size_approx() == (std::uint32_t)(16 - i)); } ASSERT_OR_FAIL(!q.try_dequeue(result)); q.enqueue(ThrowingMovable(20)); ASSERT_OR_FAIL(q.size_approx() == 1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 20); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 16); } { // Impplicit bulk // enqueue ConcurrentQueue q; ThrowingMovable::reset(); std::vector items; items.reserve(5); items.push_back(ThrowingMovable(1)); items.push_back(ThrowingMovable(2)); items.push_back(ThrowingMovable(3)); items.push_back(ThrowingMovable(4)); items.push_back(ThrowingMovable(5)); items.back().throwOnCctor = true; bool threw = false; try { q.enqueue_bulk(std::make_move_iterator(items.begin()), 5); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 5); ASSERT_OR_FAIL(m->copied); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 0); q.enqueue(ThrowingMovable(6)); threw = false; try { q.enqueue_bulk(std::make_move_iterator(items.begin()), 5); } catch (ThrowingMovable* m) { threw = true; ASSERT_OR_FAIL(m->id == 5); } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 1); ThrowingMovable result(-1); ASSERT_OR_FAIL(q.try_dequeue(result)); ASSERT_OR_FAIL(result.id == 6); ASSERT_OR_FAIL(result.moved); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 15); // dequeue ThrowingMovable::reset(); q.enqueue(ThrowingMovable(10)); q.enqueue(ThrowingMovable(11)); q.enqueue(ThrowingMovable(12)); q.enqueue(ThrowingMovable(13)); q.enqueue(ThrowingMovable(14, false, true, true)); // std::back_inserter turns an assignment into a ctor call q.enqueue(ThrowingMovable(15)); ASSERT_OR_FAIL(q.size_approx() == 6); std::vector results; results.reserve(5); ASSERT_OR_FAIL(q.try_dequeue_bulk(std::back_inserter(results), 2)); ASSERT_OR_FAIL(results.size() == 2); ASSERT_OR_FAIL(results[0].id == 10); ASSERT_OR_FAIL(results[1].id == 11); ASSERT_OR_FAIL(results[0].moved); ASSERT_OR_FAIL(results[1].moved); ASSERT_OR_FAIL(q.size_approx() == 4); threw = false; try { q.try_dequeue_bulk(std::back_inserter(results), 4); } catch (ThrowingMovable*) { threw = true; } ASSERT_OR_FAIL(threw); ASSERT_OR_FAIL(q.size_approx() == 0); ASSERT_OR_FAIL(!q.try_dequeue(result)); ASSERT_OR_FAIL(q.try_dequeue_bulk(std::back_inserter(results), 1) == 0); ASSERT_OR_FAIL(results.size() == 4); ASSERT_OR_FAIL(results[2].id == 12); ASSERT_OR_FAIL(results[3].id == 13); ASSERT_OR_FAIL(ThrowingMovable::destroyCount() == 12); } { // Threaded ConcurrentQueue q; ThrowingMovable::reset(); std::vector threads(6); for (std::size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](std::size_t tid) { std::vector inVec; inVec.push_back(ThrowingMovable(1)); inVec.push_back(ThrowingMovable(2)); inVec.push_back(ThrowingMovable(3)); std::vector outVec; outVec.push_back(ThrowingMovable(-1)); outVec.push_back(ThrowingMovable(-1)); outVec.push_back(ThrowingMovable(-1)); ProducerToken tok(q); ThrowingMovable result(-1); for (std::size_t i = 0; i != 8192; ++i) { auto magic = (tid + 1) * i + tid * 17 + i; auto op = magic & 7; auto ctorThrow = (magic & 0x10) != 0; auto assignThrow = (magic & 0x20) != 0; auto throwOnNextCctor = (magic & 0x40) != 0; try { switch (op) { case 0: q.enqueue(tok, ThrowingMovable((int)i, ctorThrow, assignThrow, throwOnNextCctor)); break; case 1: inVec[i & 3].throwOnCctor = ctorThrow; inVec[i & 3].throwOnAssignment = assignThrow; inVec[i & 3].throwOnSecondCctor = throwOnNextCctor; q.enqueue_bulk(tok, inVec.begin(), 3); break; case 2: q.enqueue(ThrowingMovable((int)i, ctorThrow, assignThrow, throwOnNextCctor)); break; case 3: inVec[i & 3].throwOnCctor = ctorThrow; inVec[i & 3].throwOnAssignment = assignThrow; inVec[i & 3].throwOnSecondCctor = throwOnNextCctor; q.enqueue_bulk(inVec.begin(), 3); break; case 4: case 5: q.try_dequeue(result); break; case 6: case 7: q.try_dequeue_bulk(outVec.data(), 3); break; } } catch (ThrowingMovable*) { } } }, tid); } for (std::size_t i = 0; i != threads.size(); ++i) { threads[i].join(); } ThrowingMovable result(-1); while (true) { try { if (!q.try_dequeue(result)) { break; } } catch (ThrowingMovable*) { } } ASSERT_OR_FAIL(ThrowingMovable::destroyCount() + 1 == ThrowingMovable::ctorCount()); } return true; } bool test_threaded() { typedef TestTraits<4> Traits; Traits::reset(); bool inOrder = true; { // Single producer, single consumer ConcurrentQueue q; ProducerToken t(q); SimpleThread a([&]() { for (int i = 0; i != 123456; ++i) { q.enqueue(t, i); } }); SimpleThread b([&]() { int item; int prevItem = -1; while (true) { if (q.try_dequeue_from_producer(t, item)) { if (item == 123455) { break; } inOrder = item == prevItem + 1 && inOrder; prevItem = item; } } }); a.join(); b.join(); } ASSERT_OR_FAIL(inOrder); { // Single producer, multi consumer ConcurrentQueue q; ProducerToken t(q); SimpleThread a([&]() { for (int i = 0; i != 123456; ++i) { q.enqueue(t, i); } }); SimpleThread b([&]() { int item, prevItem = -1; for (int i = 0; i != 123456; ++i) { if (q.try_dequeue_from_producer(t, item)) { inOrder = item > prevItem && inOrder; prevItem = item; } } }); SimpleThread c([&]() { int item; for (int i = 0; i != 123456; ++i) q.try_dequeue_from_producer(t, item); }); SimpleThread d([&]() { int item; for (int i = 0; i != 123456; ++i) q.try_dequeue_from_producer(t, item); }); a.join(); b.join(); c.join(); d.join(); } ASSERT_OR_FAIL(inOrder); ASSERT_OR_FAIL(Traits::malloc_count() == Traits::free_count()); return true; } bool test_threaded_bulk() { typedef TestTraits<2> Traits; // Enqueue bulk (implicit) Traits::reset(); { ConcurrentQueue q; SimpleThread threads[2]; bool success[2]; int stuff[] = { 1, 2, 3, 4, 5 }; for (int i = 0; i != 2; ++i) { success[i] = true; if (i == 0) { // Enqueue bulk threads[i] = SimpleThread([&](int j) { for (int k = 0; k != 2048; ++k) { success[j] = q.enqueue_bulk(stuff, 5) && success[j]; } }, i); } else { // Dequeue threads[i] = SimpleThread([&](int j) { int item; int prevItem = 0; for (int k = 0; k != 2048 * 5;) { if (q.try_dequeue(item)) { if (item != prevItem + 1) { success[j] = false; } prevItem = item; if (item == 5) { prevItem = 0; } ++k; } } }, i); } } for (int i = 0; i != 2; ++i) { threads[i].join(); } ASSERT_OR_FAIL(success[0]); ASSERT_OR_FAIL(success[1]); } // Enqueue bulk (while somebody is dequeueing (with tokens)) Traits::reset(); { ConcurrentQueue q; SimpleThread threads[2]; bool success[2]; int stuff[] = { 1, 2, 3, 4, 5 }; for (int i = 0; i != 2; ++i) { success[i] = true; if (i == 0) { // Enqueue bulk threads[i] = SimpleThread([&](int j) { ProducerToken tok(q); for (int k = 0; k != 2048; ++k) { success[j] = q.enqueue_bulk(tok, stuff, 5) && success[j]; } }, i); } else { // Dequeue threads[i] = SimpleThread([&](int j) { ConsumerToken tok(q); int item; int prevItem = 0; for (int k = 0; k != 2048 * 5;) { if (q.try_dequeue(tok, item)) { if (item != prevItem + 1) { success[j] = false; } prevItem = item; if (item == 5) { prevItem = 0; } ++k; } } }, i); } } for (int i = 0; i != 2; ++i) { threads[i].join(); } ASSERT_OR_FAIL(success[0]); ASSERT_OR_FAIL(success[1]); } return true; } template bool full_api() { // A simple test that exercises the full public API (just to make sure every function is implemented // and works on at least the most basic level) // enqueue(T const&) { ConcurrentQueue q; Copyable original(12345); ASSERT_OR_FAIL(q.enqueue(original)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // enqueue(T&&) { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; Moveable original(12345); ASSERT_OR_FAIL(q.enqueue(std::move(original))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // enqueue(Token, T const&) { ConcurrentQueue q; ProducerToken t(q); Copyable original(12345); ASSERT_OR_FAIL(q.enqueue(t, original)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // enqueue(Token, T&&) { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.enqueue(t, Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); Moveable original(12345); ASSERT_OR_FAIL(q.enqueue(t, std::move(original))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.enqueue(t, Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_enqueue(T const&) { ConcurrentQueue q; Copyable original(12345); ASSERT_OR_FAIL(q.try_enqueue(original)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_enqueue(T&&) { ConcurrentQueue q; ASSERT_OR_FAIL(q.try_enqueue(Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; Moveable original(12345); ASSERT_OR_FAIL(q.try_enqueue(std::move(original))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ASSERT_OR_FAIL(q.try_enqueue(Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_enqueue(Token, T const&) { ConcurrentQueue q; ProducerToken t(q); Copyable original(12345); ASSERT_OR_FAIL(q.try_enqueue(t, original)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_enqueue(Token, T&&) { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.try_enqueue(t, Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); Moveable original(12345); ASSERT_OR_FAIL(q.try_enqueue(t, std::move(original))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.try_enqueue(t, Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // enqueue_bulk(It itemFirst, size_t count) { ConcurrentQueue q; Copyable original(12345); ASSERT_OR_FAIL(q.enqueue_bulk(&original, 1)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; Moveable original(12345); ASSERT_OR_FAIL(q.enqueue_bulk(std::make_move_iterator(&original), 1)); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // enqueue_bulk(Token, It itemFirst, size_t count) { ConcurrentQueue q; ProducerToken t(q); Copyable original(12345); ASSERT_OR_FAIL(q.enqueue_bulk(t, &original, 1)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); Moveable original(12345); ASSERT_OR_FAIL(q.enqueue_bulk(t, std::make_move_iterator(&original), 1)); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_enqueue_bulk(It itemFirst, size_t count) { ConcurrentQueue q; Copyable original(12345); ASSERT_OR_FAIL(q.try_enqueue_bulk(&original, 1)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; Moveable original(12345); ASSERT_OR_FAIL(q.try_enqueue_bulk(std::make_move_iterator(&original), 1)); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_enqueue_bulk(Token, It itemFirst, size_t count) { ConcurrentQueue q; ProducerToken t(q); Copyable original(12345); ASSERT_OR_FAIL(q.try_enqueue_bulk(t, &original, 1)); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); Moveable original(12345); ASSERT_OR_FAIL(q.try_enqueue_bulk(t, std::make_move_iterator(&original), 1)); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_dequeue(T&) { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_dequeue(Token, T&) { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Copyable(12345))); Copyable item(0); ConsumerToken t(q); ASSERT_OR_FAIL(q.try_dequeue(t, item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue(t, item)); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Moveable(12345))); Moveable item(0); ConsumerToken t(q); ASSERT_OR_FAIL(q.try_dequeue(t, item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue(t, item)); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_dequeue_from_producer(Token, T&) { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.enqueue(t, Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.enqueue(t, Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue_from_producer(t, item)); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // try_dequeue_bulk(T&) { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue_bulk(&item, 1) == 1); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue_bulk(&item, 1)); } { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue_bulk(&item, 1) == 1); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue_bulk(&item, 1)); } // try_dequeue_bulk(Token, T&) { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Copyable(12345))); Copyable item(0); ConsumerToken t(q); ASSERT_OR_FAIL(q.try_dequeue_bulk(t, &item, 1)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue_bulk(t, &item, 1)); ASSERT_OR_FAIL(!q.try_dequeue_bulk(&item, 1)); } { ConcurrentQueue q; ASSERT_OR_FAIL(q.enqueue(Moveable(12345))); Moveable item(0); ConsumerToken t(q); ASSERT_OR_FAIL(q.try_dequeue_bulk(t, &item, 1)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue_bulk(t, &item, 1)); ASSERT_OR_FAIL(!q.try_dequeue_bulk(&item, 1)); } // try_dequeue_bulk_from_producer(Token, T&) { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.enqueue(t, Copyable(12345))); Copyable item(0); ASSERT_OR_FAIL(q.try_dequeue_bulk_from_producer(t, &item, 1)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.copied); ASSERT_OR_FAIL(!q.try_dequeue_bulk_from_producer(t, &item, 1)); ASSERT_OR_FAIL(!q.try_dequeue(item)); } { ConcurrentQueue q; ProducerToken t(q); ASSERT_OR_FAIL(q.enqueue(t, Moveable(12345))); Moveable item(0); ASSERT_OR_FAIL(q.try_dequeue_bulk_from_producer(t, &item, 1)); ASSERT_OR_FAIL(item.id == 12345); ASSERT_OR_FAIL(item.moved); ASSERT_OR_FAIL(!item.copied); ASSERT_OR_FAIL(!q.try_dequeue_bulk_from_producer(t, &item, 1)); ASSERT_OR_FAIL(!q.try_dequeue(item)); } // size_approx() { ConcurrentQueue q; for (int i = 0; i != 1234; ++i) { q.enqueue(Foo()); } ASSERT_OR_FAIL(q.size_approx() == 1234); } // is_lock_free() { bool lockFree = ConcurrentQueue::is_lock_free(); #if defined(__amd64__) || defined(_M_X64) || defined(__x86_64__) || defined(_M_IX86) || defined(__i386__) || defined(_M_PPC) || defined(__powerpc__) ASSERT_OR_FAIL(lockFree); #endif } // moving { ConcurrentQueue q(4); ProducerToken t(q); for (int i = 0; i != 1233; ++i) { q.enqueue(i); } for (int i = 1234; i != 5678; ++i) { q.enqueue(t, i); } ASSERT_OR_FAIL(q.size_approx() == 5677); ConcurrentQueue q2(std::move(q)); ASSERT_OR_FAIL(q.size_approx() == 0); ASSERT_OR_FAIL(q2.size_approx() == 5677); q2.enqueue(t, 5678); q2.enqueue(1233); ASSERT_OR_FAIL(q2.size_approx() == 5679); for (int i = 1234; i != 0; --i) { q.enqueue(i); } ASSERT_OR_FAIL(q.size_approx() == 1234); int item; for (int i = 0; i <= 5678; ++i) { ASSERT_OR_FAIL(q2.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q2.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(q2.size_approx() == 0); for (int i = 1234; i != 0; --i) { ASSERT_OR_FAIL(q.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(q.size_approx() == 0); } // swapping { ConcurrentQueue q1, q2, q3; ProducerToken t1(q1), t2(q2), t3(q3); for (int i = 1234; i != 5678; ++i) { q1.enqueue(t1, i); } for (int i = 21234; i != 25678; ++i) { q2.enqueue(t2, i); } for (int i = 31234; i != 35678; ++i) { q3.enqueue(t3, i); } for (int i = 0; i != 1234; ++i) { q1.enqueue(i); } for (int i = 20000; i != 21234; ++i) { q2.enqueue(i); } for (int i = 30000; i != 31234; ++i) { q3.enqueue(i); } { ConcurrentQueue temp; temp = std::move(q1); q1 = std::move(q2); q2 = std::move(temp); } // q1 in q2, q2 in q1 swap(q2, q3); // q1 in q3, q3 in q2 q1.swap(q2); // q2 in q2, q3 in q1 q1.swap(q2); // q3 in q2, q2 in q1 q1.swap(q2); // q2 in q2, q3 in q1 q2.swap(q3); // q1 in q2, q2 in q3 // So now q1 is in q2, q2 is in q3, and q3 is in q1 int item; for (int i = 30000; i != 35678; ++i) { ASSERT_OR_FAIL(q1.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q1.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(q1.size_approx() == 0); for (int i = 0; i != 5678; ++i) { ASSERT_OR_FAIL(q2.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q2.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(q2.size_approx() == 0); for (int i = 20000; i != 25678; ++i) { ASSERT_OR_FAIL(q3.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(item == i); } ASSERT_OR_FAIL(!q3.try_dequeue_non_interleaved(item)); ASSERT_OR_FAIL(q3.size_approx() == 0); } return true; } bool blocking_wrappers() { typedef BlockingConcurrentQueue Q; ASSERT_OR_FAIL((Q::is_lock_free() == ConcurrentQueue::is_lock_free())); // Moving { Q a, b, c; a = std::move(b); b = std::move(c); a = std::move(a); c = std::move(b); b = Q(std::move(b)); using std::swap; swap(a, b); a.swap(c); c.swap(c); } // Implicit { Q q; ASSERT_OR_FAIL(q.enqueue(1)); ASSERT_OR_FAIL(q.size_approx() == 1); int item; ASSERT_OR_FAIL(q.try_dequeue(item)); ASSERT_OR_FAIL(item == 1); ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(q.size_approx() == 0); ASSERT_OR_FAIL(q.enqueue(2)); ASSERT_OR_FAIL(q.enqueue(3)); ASSERT_OR_FAIL(q.size_approx() == 2); q.wait_dequeue(item); ASSERT_OR_FAIL(item == 2); ASSERT_OR_FAIL(q.size_approx() == 1); q.wait_dequeue(item); ASSERT_OR_FAIL(item == 3); ASSERT_OR_FAIL(!q.try_dequeue(item)); ASSERT_OR_FAIL(q.size_approx() == 0); } // Implicit threaded { Q q; const int THREADS = 8; SimpleThread threads[THREADS]; bool success[THREADS]; for (int i = 0; i != THREADS; ++i) { success[i] = true; if (i % 2 == 0) { // Enqueue if (i % 4 == 0) { threads[i] = SimpleThread([&](int j) { int stuff[5]; for (int k = 0; k != 2048; ++k) { for (int x = 0; x != 5; ++x) { stuff[x] = (j << 16) | (k * 5 + x); } success[j] = q.enqueue_bulk(stuff, 5) && success[j]; } }, i); } else { threads[i] = SimpleThread([&](int j) { for (int k = 0; k != 4096; ++k) { success[j] = q.enqueue((j << 16) | k) && success[j]; } }, i); } } else { // Dequeue threads[i] = SimpleThread([&](int j) { int item; std::vector prevItems(THREADS, -1); if (j % 4 == 1) { for (int k = 0; k != 2048 * 5; ++k) { if (q.try_dequeue(item)) { int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } } else { int items[6]; for (int k = 0; k < 4096; ++k) { if (std::size_t dequeued = q.try_dequeue_bulk(items, 6)) { for (std::size_t x = 0; x != dequeued; ++x) { item = items[x]; int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } } } }, i); } } for (int i = 0; i != THREADS; ++i) { threads[i].join(); } for (int i = 0; i != THREADS; ++i) { ASSERT_OR_FAIL(success[i]); } } // Implicit threaded, blocking { Q q; const int THREADS = 8; SimpleThread threads[THREADS]; bool success[THREADS]; for (int i = 0; i != THREADS; ++i) { success[i] = true; if (i % 2 == 0) { // Enqueue if (i % 4 == 0) { threads[i] = SimpleThread([&](int j) { int stuff[5]; for (int k = 0; k != 2048; ++k) { for (int x = 0; x != 5; ++x) { stuff[x] = (j << 16) | (k * 5 + x); } success[j] = q.enqueue_bulk(stuff, 5) && success[j]; } }, i); } else { threads[i] = SimpleThread([&](int j) { for (int k = 0; k != 4096; ++k) { success[j] = q.enqueue((j << 16) | k) && success[j]; } }, i); } } else { // Dequeue threads[i] = SimpleThread([&](int j) { int item; std::vector prevItems(THREADS, -1); if (j % 4 == 1) { for (int k = 0; k != 2048 * 5; ++k) { q.wait_dequeue(item); int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } else { int items[6]; int k; for (k = 0; k < 4090; ) { if (std::size_t dequeued = q.wait_dequeue_bulk(items, 6)) { for (std::size_t x = 0; x != dequeued; ++x) { item = items[x]; int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } k += (int)dequeued; } else { success[j] = false; } } for (; k != 4096; ++k) { q.wait_dequeue(item); int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } }, i); } } for (int i = 0; i != THREADS; ++i) { threads[i].join(); } for (int i = 0; i != THREADS; ++i) { ASSERT_OR_FAIL(success[i]); } ASSERT_OR_FAIL(q.size_approx() == 0); } // Explicit { Q q; ProducerToken pt(q); ASSERT_OR_FAIL(q.enqueue(pt, 1)); ASSERT_OR_FAIL(q.size_approx() == 1); int item; ConsumerToken ct(q); ASSERT_OR_FAIL(q.try_dequeue(ct, item)); ASSERT_OR_FAIL(item == 1); ASSERT_OR_FAIL(!q.try_dequeue(ct, item)); ASSERT_OR_FAIL(q.size_approx() == 0); ASSERT_OR_FAIL(q.enqueue(pt, 2)); ASSERT_OR_FAIL(q.enqueue(pt, 3)); ASSERT_OR_FAIL(q.size_approx() == 2); q.wait_dequeue(ct, item); ASSERT_OR_FAIL(item == 2); ASSERT_OR_FAIL(q.size_approx() == 1); q.wait_dequeue(ct, item); ASSERT_OR_FAIL(item == 3); ASSERT_OR_FAIL(!q.try_dequeue(ct, item)); ASSERT_OR_FAIL(q.size_approx() == 0); } // Explicit threaded { Q q; const int THREADS = 8; SimpleThread threads[THREADS]; bool success[THREADS]; for (int i = 0; i != THREADS; ++i) { success[i] = true; if (i % 2 == 0) { // Enqueue if (i % 4 == 0) { threads[i] = SimpleThread([&](int j) { ProducerToken t(q); int stuff[5]; for (int k = 0; k != 2048; ++k) { for (int x = 0; x != 5; ++x) { stuff[x] = (j << 16) | (k * 5 + x); } success[j] = q.enqueue_bulk(t, stuff, 5) && success[j]; } }, i); } else { threads[i] = SimpleThread([&](int j) { ProducerToken t(q); for (int k = 0; k != 4096; ++k) { success[j] = q.enqueue(t, (j << 16) | k) && success[j]; } }, i); } } else { // Dequeue threads[i] = SimpleThread([&](int j) { ConsumerToken t(q); int item; std::vector prevItems(THREADS, -1); if (j % 4 == 1) { for (int k = 0; k != 2048 * 5; ++k) { if (q.try_dequeue(t, item)) { int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } } else { int items[6]; for (int k = 0; k < 4096; ++k) { if (std::size_t dequeued = q.try_dequeue_bulk(t, items, 6)) { for (std::size_t x = 0; x != dequeued; ++x) { item = items[x]; int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } } } }, i); } } for (int i = 0; i != THREADS; ++i) { threads[i].join(); } for (int i = 0; i != THREADS; ++i) { ASSERT_OR_FAIL(success[i]); } } // Explicit threaded, blocking { Q q; const int THREADS = 8; SimpleThread threads[THREADS]; bool success[THREADS]; for (int i = 0; i != THREADS; ++i) { success[i] = true; if (i % 2 == 0) { // Enqueue if (i % 4 == 0) { threads[i] = SimpleThread([&](int j) { ProducerToken t(q); int stuff[5]; for (int k = 0; k != 2048; ++k) { for (int x = 0; x != 5; ++x) { stuff[x] = (j << 16) | (k * 5 + x); } success[j] = q.enqueue_bulk(t, stuff, 5) && success[j]; } }, i); } else { threads[i] = SimpleThread([&](int j) { ProducerToken t(q); for (int k = 0; k != 4096; ++k) { success[j] = q.enqueue(t, (j << 16) | k) && success[j]; } }, i); } } else { // Dequeue threads[i] = SimpleThread([&](int j) { ConsumerToken t(q); int item; std::vector prevItems(THREADS, -1); if (j % 4 == 1) { for (int k = 0; k != 2048 * 5; ++k) { q.wait_dequeue(t, item); int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } else { int items[6]; int k; for (k = 0; k < 4090; ) { if (std::size_t dequeued = q.wait_dequeue_bulk(t, items, 6)) { for (std::size_t x = 0; x != dequeued; ++x) { item = items[x]; int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } k += (int)dequeued; } else { success[j] = false; } } for (; k != 4096; ++k) { q.wait_dequeue(t, item); int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } }, i); } } for (int i = 0; i != THREADS; ++i) { threads[i].join(); } for (int i = 0; i != THREADS; ++i) { ASSERT_OR_FAIL(success[i]); } ASSERT_OR_FAIL(q.size_approx() == 0); } return true; } bool timed_blocking_wrappers() { typedef BlockingConcurrentQueue Q; // Implicit { Q q; int item; ASSERT_OR_FAIL(!q.wait_dequeue_timed(item, 0)); ASSERT_OR_FAIL(!q.wait_dequeue_timed(item, 1)); ASSERT_OR_FAIL(!q.wait_dequeue_timed(item, 100)); ASSERT_OR_FAIL(!q.wait_dequeue_timed(item, std::chrono::milliseconds(1))); q.enqueue(123); ASSERT_OR_FAIL(q.wait_dequeue_timed(item, 0)); ASSERT_OR_FAIL(item == 123); } // Implicit, threaded { Q q; const int THREADS = 8; SimpleThread threads[THREADS]; bool success[THREADS]; for (int i = 0; i != THREADS; ++i) { success[i] = true; if (i % 2 == 0) { // Enqueue if (i % 4 == 0) { threads[i] = SimpleThread([&](int j) { int stuff[5]; for (int k = 0; k != 2048; ++k) { for (int x = 0; x != 5; ++x) { stuff[x] = (j << 16) | (k * 5 + x); } success[j] = q.enqueue_bulk(stuff, 5) && success[j]; } }, i); } else { threads[i] = SimpleThread([&](int j) { for (int k = 0; k != 4096; ++k) { success[j] = q.enqueue((j << 16) | k) && success[j]; } }, i); } } else { // Dequeue threads[i] = SimpleThread([&](int j) { int item; std::vector prevItems(THREADS, -1); if (j % 4 == 1) { for (int k = 0; k != 2048 * 5; ++k) { if (!q.wait_dequeue_timed(item, 1000)) { --k; continue; } int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } else { int items[6]; int k; for (k = 0; k < 4090; ) { if (std::size_t dequeued = q.wait_dequeue_bulk_timed(items, 6, 1000)) { for (std::size_t x = 0; x != dequeued; ++x) { item = items[x]; int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } k += (int)dequeued; } } for (; k != 4096; ++k) { if (!q.wait_dequeue_timed(item, std::chrono::hours(1))) { success[j] = false; } int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } }, i); } } for (int i = 0; i != THREADS; ++i) { threads[i].join(); } for (int i = 0; i != THREADS; ++i) { ASSERT_OR_FAIL(success[i]); } ASSERT_OR_FAIL(q.size_approx() == 0); int item; ASSERT_OR_FAIL(!q.wait_dequeue_timed(item, 0)); } // Explicit { Q q; ProducerToken ptok(q); ConsumerToken ctok(q); int item; ASSERT_OR_FAIL(!q.wait_dequeue_timed(ctok, item, 0)); ASSERT_OR_FAIL(!q.wait_dequeue_timed(ctok, item, 1)); ASSERT_OR_FAIL(!q.wait_dequeue_timed(ctok, item, 100)); ASSERT_OR_FAIL(!q.wait_dequeue_timed(ctok, item, std::chrono::milliseconds(1))); q.enqueue(ptok, 123); ASSERT_OR_FAIL(q.wait_dequeue_timed(ctok, item, 0)); ASSERT_OR_FAIL(item == 123); } // Explicit, threaded { Q q; const int THREADS = 8; SimpleThread threads[THREADS]; bool success[THREADS]; for (int i = 0; i != THREADS; ++i) { success[i] = true; if (i % 2 == 0) { // Enqueue if (i % 4 == 0) { threads[i] = SimpleThread([&](int j) { ProducerToken tok(q); int stuff[5]; for (int k = 0; k != 2048; ++k) { for (int x = 0; x != 5; ++x) { stuff[x] = (j << 16) | (k * 5 + x); } success[j] = q.enqueue_bulk(tok, stuff, 5) && success[j]; } }, i); } else { threads[i] = SimpleThread([&](int j) { ProducerToken tok(q); for (int k = 0; k != 4096; ++k) { success[j] = q.enqueue(tok, (j << 16) | k) && success[j]; } }, i); } } else { // Dequeue threads[i] = SimpleThread([&](int j) { int item; std::vector prevItems(THREADS, -1); ConsumerToken tok(q); if (j % 4 == 1) { for (int k = 0; k != 2048 * 5; ++k) { if (!q.wait_dequeue_timed(tok, item, 1000)) { --k; continue; } int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } else { int items[6]; int k; for (k = 0; k < 4090; ) { if (std::size_t dequeued = q.wait_dequeue_bulk_timed(tok, items, 6, 1000)) { for (std::size_t x = 0; x != dequeued; ++x) { item = items[x]; int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } k += (int)dequeued; } } for (; k != 4096; ++k) { if (!q.wait_dequeue_timed(tok, item, std::chrono::hours(1))) { success[j] = false; } int thread = item >> 16; item &= 0xffff; if (item <= prevItems[thread]) { success[j] = false; } prevItems[thread] = item; } } }, i); } } for (int i = 0; i != THREADS; ++i) { threads[i].join(); } for (int i = 0; i != THREADS; ++i) { ASSERT_OR_FAIL(success[i]); } ASSERT_OR_FAIL(q.size_approx() == 0); int item; ConsumerToken tok(q); ASSERT_OR_FAIL(!q.wait_dequeue_timed(tok, item, 0)); } return true; } struct TestListItem : corealgos::ListItem { int value; TestListItem() : value(0) { ctorCount().fetch_add(1, std::memory_order_relaxed); } explicit TestListItem(int value) : value(value) { ctorCount().fetch_add(1, std::memory_order_relaxed); } ~TestListItem() { dtorCount().fetch_add(1, std::memory_order_relaxed); } inline TestListItem* prev(std::memory_order order = std::memory_order_relaxed) const { return static_cast(concurrentListPrev.load(order)); } inline static void reset() { ctorCount().store(0, std::memory_order_relaxed); dtorCount().store(0, std::memory_order_relaxed); } inline static size_t constructed() { return ctorCount().load(std::memory_order_relaxed); } inline static size_t destructed() { return dtorCount().load(std::memory_order_relaxed); } private: inline static std::atomic& ctorCount() { static std::atomic count(0); return count; } inline static std::atomic& dtorCount() { static std::atomic count(0); return count; } }; bool core_add_only_list() { auto destroyList = [](corealgos::ConcurrentAddOnlyList& list) { size_t count = 0; auto tail = list.tail(); while (tail != nullptr) { auto next = tail->prev(); delete tail; ++count; tail = next; } return count; }; { corealgos::ConcurrentAddOnlyList list; ASSERT_OR_FAIL(list.tail() == nullptr); ASSERT_OR_FAIL(destroyList(list) == 0); } { corealgos::ConcurrentAddOnlyList list; for (int i = 0; i != 1000; ++i) { list.add(new TestListItem(i)); } int i = 999; for (auto tail = list.tail(); tail != nullptr; tail = tail->prev()) { ASSERT_OR_FAIL(i == tail->value); --i; } ASSERT_OR_FAIL(i == -1); ASSERT_OR_FAIL(destroyList(list) == 1000); } for (int repeats = 0; repeats != 10; ++repeats) { corealgos::ConcurrentAddOnlyList list; std::vector threads(8); for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](size_t tid) { for (int i = 0; i != 1000; ++i) { list.add(new TestListItem((int)((tid << 16) | i))); } }, tid); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); } std::vector prevItems(threads.size()); for (size_t i = 0; i != prevItems.size(); ++i) { prevItems[i] = 1000; } for (auto tail = list.tail(); tail != nullptr; tail = tail->prev()) { auto tid = tail->value >> 16; auto i = tail->value & ((1 << 16) - 1); ASSERT_OR_FAIL(prevItems[tid] == i + 1); prevItems[tid] = i; } ASSERT_OR_FAIL(destroyList(list) == 1000 * threads.size()); } return true; } bool core_thread_local() { TestListItem::reset(); { corealgos::ThreadLocal local(4); } ASSERT_OR_FAIL(TestListItem::constructed() == 0); ASSERT_OR_FAIL(TestListItem::destructed() == 0); TestListItem::reset(); { corealgos::ThreadLocal local(4); local.get_or_create(); } ASSERT_OR_FAIL(TestListItem::constructed() == 1); ASSERT_OR_FAIL(TestListItem::destructed() == 1); TestListItem::reset(); { corealgos::ThreadLocal local(4); auto item = local.get_or_create(); item->value = 7; item = local.get_or_create(); ASSERT_OR_FAIL(item->value == 7); } ASSERT_OR_FAIL(TestListItem::constructed() == 1); ASSERT_OR_FAIL(TestListItem::destructed() == 1); for (size_t initialSize = 1; initialSize <= 4; initialSize <<= 1) { for (int reps = 0; reps != 20; ++reps) { TestListItem::reset(); { corealgos::ThreadLocal local(initialSize); std::vector threads(5 * initialSize); std::vector failed(threads.size()); std::atomic done(0); for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](size_t tid) { failed[tid] = false; auto item = local.get_or_create(); item->value = (int)tid; for (int i = 0; i != 1024; ++i) { auto item = local.get_or_create(); if (item->value != (int)tid) { failed[tid] = true; } } done.fetch_add(1, std::memory_order_seq_cst); while (done.load(std::memory_order_relaxed) != threads.size()) { moodycamel::sleep(1); } }, tid); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); ASSERT_OR_FAIL(!failed[tid]); } ASSERT_OR_FAIL(TestListItem::constructed() == 5 * initialSize); } ASSERT_OR_FAIL(TestListItem::destructed() == 5 * initialSize); } } return true; } struct TestNode : corealgos::FreeListNode { int value; TestNode() { } explicit TestNode(int value) : value(value) { } }; bool core_free_list() { { // Basic corealgos::FreeList freeList; ASSERT_OR_FAIL(freeList.try_get() == nullptr); freeList.add(new TestNode(7)); TestNode* node = freeList.try_get(); ASSERT_OR_FAIL(node != nullptr); ASSERT_OR_FAIL(node->value == 7); ASSERT_OR_FAIL(freeList.try_get() == nullptr); freeList.add(node); node = freeList.try_get(); ASSERT_OR_FAIL(node != nullptr); ASSERT_OR_FAIL(node->value == 7); ASSERT_OR_FAIL(freeList.try_get() == nullptr); delete node; } { // Multi-threaded. Tests ABA too. for (int rep = 0; rep != 10; ++rep) { corealgos::FreeList freeList; std::vector threads(rep < 8 ? 4 : 16); std::vector failed(threads.size()); std::vector initialNodes(threads.size()); const int OP_COUNT = 2048; for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](size_t tid) { std::vector seenValues(threads.size() * OP_COUNT, false); failed[tid] = false; TestNode* node = &initialNodes[tid]; node->value = ((int)tid << 20) | 1; freeList.add(node); for (int i = 1; i != OP_COUNT - 1; ++i) { node = freeList.try_get(); if (node != nullptr) { auto seen = seenValues.begin() + ((node->value >> 20) * OP_COUNT + (node->value & 0xFFFFF)); if (*seen) { failed[tid] = true; } *seen = true; node->value = ((int)tid << 20) | (i + 1); freeList.add(node); } } }, tid); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); ASSERT_OR_FAIL(!failed[tid]); } for (size_t tid = 0; tid != threads.size(); ++tid) { auto node = freeList.try_get(); ASSERT_OR_FAIL(node != nullptr); ASSERT_OR_FAIL(node->value != -1); node->value = -1; } auto node = freeList.try_get(); ASSERT_OR_FAIL(node == nullptr); } } return true; } bool core_spmc_hash() { { for (int rep = 0; rep != 20; ++rep) { corealgos::SPMCSequentialHashMap hash(rep < 10 ? 2 : 4); std::vector threads(rep < 12 ? 4 : 16); std::vector failed(threads.size()); const int MAX_ENTRIES = 4096; std::vector values(MAX_ENTRIES); std::array, MAX_ENTRIES> useCounts; std::array, MAX_ENTRIES> removed; for (std::size_t i = 0; i != useCounts.size(); ++i) { useCounts[i].store(0, std::memory_order_relaxed); removed[i].store(false, std::memory_order_relaxed); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](size_t tid) { failed[tid] = false; if (tid == 0) { // Producer thread for (int i = 0; i != MAX_ENTRIES; ++i) { values[i] = i; hash.insert(i, &values[i]); useCounts[i].store((int)threads.size() / 2, std::memory_order_release); } } else { // One of the consumer threads for (int i = MAX_ENTRIES * 2; i != 0; --i) { // Purposefully off-by-lots int useCount = -1; if (i < MAX_ENTRIES) { useCount = useCounts[i].fetch_add(-1, std::memory_order_acquire); } int* val; if (useCount > 0) { val = hash.find(i); bool isRemoved = removed[i].load(std::memory_order_relaxed); assert(val == nullptr || *val == *val); // Find segfaults // We read the use count again; if it's still > 0, the item must have been in // the hash during the entire call to find(), so we can check its value auto currentUseCount = useCounts[i].fetch_add(0, std::memory_order_release); if ((currentUseCount > 0 || (currentUseCount == 0 && useCount == 1)) && (val == nullptr || *val != i || isRemoved)) { failed[tid] = true; } } if (useCount == 1) { val = hash.remove(i); if (val == nullptr || *val != i || removed[i].load(std::memory_order_relaxed)) { failed[tid] = true; } removed[i].store(true, std::memory_order_release); } } } }, tid); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); ASSERT_OR_FAIL(!failed[tid]); } for (int i = 0; i != MAX_ENTRIES; ++i) { auto val = hash.find(i); if (val != nullptr) { ASSERT_OR_FAIL(&values[i] == val && *val == i && !removed[i].load(std::memory_order_relaxed)); } else { ASSERT_OR_FAIL(removed[i].load(std::memory_order_relaxed)); } auto removed = hash.remove(i); ASSERT_OR_FAIL(removed == val); } for (int i = 0; i != MAX_ENTRIES; ++i) { ASSERT_OR_FAIL(hash.find(i) == nullptr); ASSERT_OR_FAIL(hash.remove(i) == nullptr); } ASSERT_OR_FAIL(hash.find(MAX_ENTRIES) == nullptr); ASSERT_OR_FAIL(hash.remove(MAX_ENTRIES) == nullptr); } } return true; } bool explicit_strings_threaded() { std::vector threads(8); ConcurrentQueue q(1024 * 1024); for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid] = SimpleThread([&](size_t tid) { const size_t ITERATIONS = 100 * 1024; if (tid % 2 == 0) { // Produce ProducerToken t(q); for (size_t i = 0; i != ITERATIONS; ++i) { q.enqueue(t, std::string("banana", i % 6)); } } else { // Consume std::string item; for (size_t i = 0; i != ITERATIONS / 2; ++i) { q.try_dequeue(item); } } }, tid); } for (size_t tid = 0; tid != threads.size(); ++tid) { threads[tid].join(); } return true; } }; } void printTests(ConcurrentQueueTests const& tests) { std::printf(" Supported tests are:\n"); std::vector names; tests.getAllTestNames(names); for (auto it = names.cbegin(); it != names.cend(); ++it) { std::printf(" %s\n", it->c_str()); } } // Basic test harness #if !defined(TARGET_OS_IPHONE) int main(int argc, char** argv) { bool disablePrompt = false; unsigned int iterations = 8; std::vector selectedTests; // Disable buffering (so that when run in, e.g., Sublime Text, the output appears as it is written) std::setvbuf(stdout, nullptr, _IONBF, 0); // Isolate the executable name std::string progName = argv[0]; auto slash = progName.find_last_of("/\\"); if (slash != std::string::npos) { progName = progName.substr(slash + 1); } ConcurrentQueueTests tests; // Parse command line options if (argc > 1) { bool printHelp = false; bool printedTests = false; bool error = false; for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "--help") == 0) { printHelp = true; } else if (std::strcmp(argv[i], "--disable-prompt") == 0) { disablePrompt = true; } else if (std::strcmp(argv[i], "--run") == 0) { if (i + 1 == argc || argv[i + 1][0] == '-') { std::printf("Expected test name argument for --run option.\n"); if (!printedTests) { printTests(tests); printedTests = true; } error = true; continue; } if (!tests.validateTestName(argv[++i])) { std::printf("Unrecognized test '%s'.\n", argv[i]); if (!printedTests) { printTests(tests); printedTests = true; } error = true; continue; } selectedTests.push_back(argv[i]); } else if (std::strcmp(argv[i], "--iterations") == 0) { if (i + 1 == argc || argv[i + 1][0] == '-') { std::printf("Expected iteration count argument for --iterations option.\n"); error = true; continue; } iterations = static_cast(std::atoi(argv[++i])); } else { std::printf("Unrecognized option '%s'.\n", argv[i]); error = true; } } if (error || printHelp) { if (error) { std::printf("\n"); } std::printf("%s\n Description: Runs unit tests for moodycamel::ConcurrentQueue\n", progName.c_str()); std::printf(" --help Prints this help blurb\n"); std::printf(" --run test Runs only the specified test(s)\n"); std::printf(" --iterations N Do N iterations of each test\n"); std::printf(" --disable-prompt Disables prompt before exit when the tests finish\n"); return error ? -1 : 0; } } int exitCode = 0; bool result; if (selectedTests.size() > 0) { std::printf("Running %d iteration%s of selected unit test%s for moodycamel::ConcurrentQueue.\n\n", iterations, iterations == 1 ? "" : "s", selectedTests.size() == 1 ? "" : "s"); result = tests.run(selectedTests, iterations); } else { std::printf("Running %d iteration%s of all unit tests for moodycamel::ConcurrentQueue.\n(Run %s --help for other options.)\n\n", iterations, iterations == 1 ? "" : "s", progName.c_str()); result = tests.run(iterations); } if (result) { std::printf("All %stests passed.\n", (selectedTests.size() > 0 ? "selected " : "")); } else { std::printf("Test(s) failed!\n"); exitCode = 2; } if (!disablePrompt) { std::printf("Press ENTER to exit.\n"); getchar(); } return exitCode; } #else // Provide entry function that can be invoked // by a test host (iOS app / test runner) bool runAllTests() { unsigned int iterations = 8; ConcurrentQueueTests tests; return tests.run(iterations); } #endif // !defined(TARGET_OS_IPHONE) ================================================ FILE: src/third_party/fmt/.clang-format ================================================ # Run manually to reformat a file: # clang-format -i --style=file Language: Cpp BasedOnStyle: Google IndentPPDirectives: AfterHash IndentCaseLabels: false AlwaysBreakTemplateDeclarations: false DerivePointerAlignment: false ================================================ FILE: src/third_party/fmt/.github/pull_request_template.md ================================================ I agree that my contributions are licensed under the {fmt} license, and agree to future changes to the licensing. ================================================ FILE: src/third_party/fmt/.gitignore ================================================ .vscode/ *.iml .idea/ .externalNativeBuild/ .gradle/ gradle/ gradlew* local.properties build/ bin/ /_CPack_Packages /CMakeScripts /doc/doxyxml /doc/html virtualenv /Testing /install_manifest.txt *~ *.a *.so* *.xcodeproj *.zip cmake_install.cmake CPack*.cmake fmt-*.cmake CTestTestfile.cmake CMakeCache.txt CMakeFiles FMT.build Makefile run-msbuild.bat fmt.pc ================================================ FILE: src/third_party/fmt/.travis.yml ================================================ language: cpp dist: trusty sudo: false os: linux git: depth: 1 env: global: - secure: |- a1eovNn4uol9won7ghr67eD3/59oeESN+G9bWE+ecI1V6yRseG9whniGhIpC/YfMW/Qz5I 5sxSmFjaw9bxCISNwUIrL1O5x2AmRYTnFcXk4dFsUvlZg+WeF/aKyBYCNRM8C2ndbBmtAO o1F2EwFbiso0EmtzhAPs19ujiVxkLn4= matrix: include: # Documentation - env: BUILD=Doc sudo: required # g++ 6 on Linux with C++14 - env: COMPILER=g++-6 BUILD=Debug STANDARD=14 compiler: gcc addons: apt: update: true sources: - ubuntu-toolchain-r-test packages: - g++-6 - env: COMPILER=g++-6 BUILD=Release STANDARD=14 compiler: gcc addons: apt: update: true sources: - ubuntu-toolchain-r-test packages: - g++-6 # g++ 8 on Linux with C++17 - env: COMPILER=g++-8 BUILD=Debug STANDARD=17 compiler: gcc addons: apt: update: true sources: - ubuntu-toolchain-r-test packages: - g++-8 - env: COMPILER=g++-8 BUILD=Release STANDARD=17 compiler: gcc addons: apt: update: true sources: - ubuntu-toolchain-r-test packages: - g++-8 # Apple clang on OS X with C++14 - env: BUILD=Debug STANDARD=14 compiler: clang os: osx - env: BUILD=Release STANDARD=14 compiler: clang os: osx # clang 6.0 on Linux with C++14 (builds the fuzzers as well) - env: COMPILER=clang++-6.0 BUILD=Debug STANDARD=14 ENABLE_FUZZING=1 compiler: clang addons: apt: update: true packages: - clang-6.0 sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty - llvm-toolchain-trusty-6.0 # clang 4.0 on Linux with C++14 - env: COMPILER=clang++-4.0 BUILD=Debug STANDARD=11 compiler: clang addons: apt: update: true packages: - clang-4.0 sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty - llvm-toolchain-trusty-4.0 # g++ 4.8 on Linux with C++11 - env: COMPILER=g++-4.8 BUILD=Debug STANDARD=11 compiler: gcc - name: Android NDK (Gradle) language: android addons: apt: update: true sources: - ubuntu-toolchain-r-test packages: - ninja-build - curl - tree android: components: - tools - platform-tools - android-25 # 7.0 - android-27 # 8.1 - android-28 # 9.0 - build-tools-28.0.3 before_install: # Install Gradle from https://sdkman.io/ - curl -s "https://get.sdkman.io" | bash > /dev/null - source "$HOME/.sdkman/bin/sdkman-init.sh" - sdk version - sdk install gradle - sdk use gradle - gradle --version install: # Accept SDK Licenses + Install NDK - yes | sdkmanager --update > /dev/null 2>&1 - sdkmanager ndk-bundle > /dev/null 2>&1 before_script: - pushd ./support script: - gradle clean - gradle assemble after_success: - popd; - tree ./libs before_script: - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then export CXX=${COMPILER}; fi - if [[ "${BUILD}" != "Doc" ]]; then ${CXX} --version; fi script: - support/travis-build.py ================================================ FILE: src/third_party/fmt/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.1.0) # Use newer policies if available, up to most recent tested version of CMake. if(${CMAKE_VERSION} VERSION_LESS 3.11) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) else() cmake_policy(VERSION 3.11) endif() # Determine if fmt is built as a subproject (using add_subdirectory) # or if it is the master project. set(MASTER_PROJECT OFF) if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(MASTER_PROJECT ON) message(STATUS "CMake version: ${CMAKE_VERSION}") endif () # Joins arguments and places the results in ${result_var}. function(join result_var) set(result ) foreach (arg ${ARGN}) set(result "${result}${arg}") endforeach () set(${result_var} "${result}" PARENT_SCOPE) endfunction() # Set the default CMAKE_BUILD_TYPE to Release. # This should be done before the project command since the latter can set # CMAKE_BUILD_TYPE itself (it does so for nmake). if (MASTER_PROJECT AND NOT CMAKE_BUILD_TYPE) join(doc "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or " "CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") set(CMAKE_BUILD_TYPE Release CACHE STRING ${doc}) endif () option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) option(FMT_WERROR "Halt the compilation with an error on compiler warnings." OFF) # Options that control generation of various targets. option(FMT_DOC "Generate the doc target." ${MASTER_PROJECT}) option(FMT_INSTALL "Generate the install target." ${MASTER_PROJECT}) option(FMT_TEST "Generate the test target." ${MASTER_PROJECT}) option(FMT_FUZZ "Generate the fuzz target." OFF) project(FMT CXX) # Get version from core.h file(READ include/fmt/core.h core_h) if (NOT core_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])") message(FATAL_ERROR "Cannot get FMT_VERSION from core.h.") endif () # Use math to skip leading zeros if any. math(EXPR CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) math(EXPR CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2}) math(EXPR CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3}) join(FMT_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}. ${CPACK_PACKAGE_VERSION_PATCH}) message(STATUS "Version: ${FMT_VERSION}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/support/cmake") include(cxx14) include(CheckCXXCompilerFlag) set(FMT_REQUIRED_FEATURES cxx_auto_type cxx_variadic_templates) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(PEDANTIC_COMPILE_FLAGS -pedantic-errors -Wall -Wextra -pedantic -Wold-style-cast -Wundef -Wredundant-decls -Wwrite-strings -Wpointer-arith -Wcast-qual -Wformat=2 -Wmissing-include-dirs -Wcast-align -Wnon-virtual-dtor -Wctor-dtor-privacy -Wdisabled-optimization -Winvalid-pch -Woverloaded-virtual -Wconversion -Wno-ctor-dtor-privacy -Wno-format-nonliteral -Wno-shadow) if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept -Wno-dangling-else -Wno-unused-local-typedefs) endif () if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion -Wtrampolines -Wzero-as-null-pointer-constant -Wuseless-cast -Wvector-operation-performance -Wsized-deallocation) endif () if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2 -Wnull-dereference -Wduplicated-cond) endif () set(WERROR_FLAG -Werror) endif () if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic -Wconversion -Wno-sign-conversion) check_cxx_compiler_flag(-Wzero-as-null-pointer-constant HAS_NULLPTR_WARNING) if (HAS_NULLPTR_WARNING) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wzero-as-null-pointer-constant) endif () set(WERROR_FLAG -Werror) endif () if (MSVC) set(PEDANTIC_COMPILE_FLAGS /W3) set(WERROR_FLAG /WX) endif () if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio") # If Microsoft SDK is installed create script run-msbuild.bat that # calls SetEnv.cmd to set up build environment and runs msbuild. # It is useful when building Visual Studio projects with the SDK # toolchain rather than Visual Studio. include(FindSetEnv) if (WINSDK_SETENV) set(MSBUILD_SETUP "call \"${WINSDK_SETENV}\"") endif () # Set FrameworkPathOverride to get rid of MSB3644 warnings. set(netfxpath "C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.0") file(WRITE run-msbuild.bat " ${MSBUILD_SETUP} ${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*") endif () set(strtod_l_headers stdlib.h) if (APPLE) set(strtod_l_headers ${strtod_l_headers} xlocale.h) endif () include(CheckSymbolExists) if (WIN32) check_symbol_exists(open io.h HAVE_OPEN) check_symbol_exists(_strtod_l "${strtod_l_headers}" HAVE_STRTOD_L) else () check_symbol_exists(open fcntl.h HAVE_OPEN) check_symbol_exists(strtod_l "${strtod_l_headers}" HAVE_STRTOD_L) endif () function(add_headers VAR) set(headers ${${VAR}}) foreach (header ${ARGN}) set(headers ${headers} include/fmt/${header}) endforeach() set(${VAR} ${headers} PARENT_SCOPE) endfunction() # Define the fmt library, its includes and the needed defines. add_headers(FMT_HEADERS chrono.h color.h core.h format.h format-inl.h locale.h ostream.h prepare.h printf.h ranges.h safe-duration-cast.h) set(FMT_SOURCES src/format.cc) if (HAVE_OPEN) add_headers(FMT_HEADERS posix.h) set(FMT_SOURCES ${FMT_SOURCES} src/posix.cc) endif () add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} README.rst ChangeLog.rst) add_library(fmt::fmt ALIAS fmt) if (HAVE_STRTOD_L) target_compile_definitions(fmt PUBLIC FMT_LOCALE) endif () if (FMT_WERROR) target_compile_options(fmt PRIVATE ${WERROR_FLAG}) endif () if (FMT_PEDANTIC) target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS}) endif () target_compile_features(fmt INTERFACE ${FMT_REQUIRED_FEATURES}) target_include_directories(fmt PUBLIC $ $) set_target_properties(fmt PROPERTIES VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR} DEBUG_POSTFIX d) if (BUILD_SHARED_LIBS) if (UNIX AND NOT APPLE) # Fix rpmlint warning: # unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6. target_link_libraries(fmt -Wl,--as-needed) endif () target_compile_definitions(fmt PRIVATE FMT_EXPORT INTERFACE FMT_SHARED) endif () if (FMT_SAFE_DURATION_CAST) target_compile_definitions(fmt PUBLIC FMT_SAFE_DURATION_CAST) endif() add_library(fmt-header-only INTERFACE) add_library(fmt::fmt-header-only ALIAS fmt-header-only) target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1) target_compile_features(fmt-header-only INTERFACE ${FMT_REQUIRED_FEATURES}) target_include_directories(fmt-header-only INTERFACE $ $) # Install targets. if (FMT_INSTALL) include(GNUInstallDirs) include(CMakePackageConfigHelpers) set(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING "Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.") set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake) set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake) set(pkgconfig ${PROJECT_BINARY_DIR}/fmt.pc) set(targets_export_name fmt-targets) set (INSTALL_TARGETS fmt) if (TARGET fmt-header-only) set(INSTALL_TARGETS ${INSTALL_TARGETS} fmt-header-only) endif () set(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING "Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.") set(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR}/fmt CACHE STRING "Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.") set(FMT_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig CACHE PATH "Installation directory for pkgconfig (.pc) files, relative to ${CMAKE_INSTALL_PREFIX}.") # Generate the version, config and target files into the build directory. write_basic_package_version_file( ${version_config} VERSION ${FMT_VERSION} COMPATIBILITY AnyNewerVersion) configure_file( "${PROJECT_SOURCE_DIR}/support/cmake/fmt.pc.in" "${pkgconfig}" @ONLY) configure_package_config_file( ${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in ${project_config} INSTALL_DESTINATION ${FMT_CMAKE_DIR}) # Use a namespace because CMake provides better diagnostics for namespaced # imported targets. export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt:: FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) # Install version, config and target files. install( FILES ${project_config} ${version_config} DESTINATION ${FMT_CMAKE_DIR}) install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR} NAMESPACE fmt::) # Install the library and headers. install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name} DESTINATION ${FMT_LIB_DIR}) install(FILES $ DESTINATION ${FMT_LIB_DIR} OPTIONAL) install(FILES ${FMT_HEADERS} DESTINATION ${FMT_INC_DIR}) install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}") endif () if (FMT_DOC) add_subdirectory(doc) endif () if (FMT_TEST) enable_testing() add_subdirectory(test) endif () # Control fuzzing independent of the unit tests. if (FMT_FUZZ) add_subdirectory(test/fuzzing) endif () set(gitignore ${PROJECT_SOURCE_DIR}/.gitignore) if (MASTER_PROJECT AND EXISTS ${gitignore}) # Get the list of ignored files from .gitignore. file (STRINGS ${gitignore} lines) LIST(REMOVE_ITEM lines /doc/html) foreach (line ${lines}) string(REPLACE "." "[.]" line "${line}") string(REPLACE "*" ".*" line "${line}") set(ignored_files ${ignored_files} "${line}$" "${line}/") endforeach () set(ignored_files ${ignored_files} /.git /breathe /format-benchmark sphinx/ .buildinfo .doctrees) set(CPACK_SOURCE_GENERATOR ZIP) set(CPACK_SOURCE_IGNORE_FILES ${ignored_files}) set(CPACK_SOURCE_PACKAGE_FILE_NAME fmt-${FMT_VERSION}) set(CPACK_PACKAGE_NAME fmt) set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.rst) include(CPack) endif () ================================================ FILE: src/third_party/fmt/CONTRIBUTING.md ================================================ Contributing to {fmt} ===================== By submitting a pull request or a patch, you represent that you have the right to license your contribution to the {fmt} project owners and the community, agree that your contributions are licensed under the {fmt} license, and agree to future changes to the licensing. All C++ code must adhere to [Google C++ Style Guide]( https://google.github.io/styleguide/cppguide.html) with the following exceptions: * Exceptions are permitted * snake_case should be used instead of UpperCamelCase for function and type names Thanks for contributing! ================================================ FILE: src/third_party/fmt/ChangeLog.rst ================================================ 6.0.0 - TBD ----------- * Made floating-point formatting locale-independent: .. code:: c++ #include #include int main() { std::locale::global(std::locale("ru_RU.UTF-8")); fmt::print("value = {}", 4.2); } prints "value = 4.2" regardless of the locale. For locale-specific formatting use the ``n`` specifier: .. code:: c++ std::locale::global(std::locale("ru_RU.UTF-8")); fmt::print("value = {:n}", 4.2); prints "value = 4,2". * Stopped setting ``CMAKE_BUILD_TYPE`` if fmt is a subproject (`#1081 `_). 5.3.0 - 2018-12-28 ------------------ * Introduced experimental chrono formatting support: .. code:: c++ #include int main() { using namespace std::literals::chrono_literals; fmt::print("Default format: {} {}\n", 42s, 100ms); fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s); } prints:: Default format: 42s 100ms strftime-like format: 03:15:30 * Added experimental support for emphasis (bold, italic, underline, strikethrough), colored output to a file stream, and improved colored formatting API (`#961 `_, `#967 `_, `#973 `_): .. code:: c++ #include int main() { print(fg(fmt::color::crimson) | fmt::emphasis::bold, "Hello, {}!\n", "world"); print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) | fmt::emphasis::underline, "Hello, {}!\n", "мир"); print(fg(fmt::color::steel_blue) | fmt::emphasis::italic, "Hello, {}!\n", "世界"); } prints the following on modern terminals with RGB color support: .. image:: https://user-images.githubusercontent.com/576385/ 50405788-b66e7500-076e-11e9-9592-7324d1f951d8.png Thanks `@Rakete1111 (Nicolas) `_. * Added support for 4-bit terminal colors (`#968 `_, `#974 `_) .. code:: c++ #include int main() { print(fg(fmt::terminal_color::red), "stop\n"); } Note that these colors vary by terminal: .. image:: https://user-images.githubusercontent.com/576385/ 50405925-dbfc7e00-0770-11e9-9b85-333fab0af9ac.png Thanks `@Rakete1111 (Nicolas) `_. * Parameterized formatting functions on the type of the format string (`#880 `_, `#881 `_, `#883 `_, `#885 `_, `#897 `_, `#920 `_). Any object of type ``S`` that has an overloaded ``to_string_view(const S&)`` returning ``fmt::string_view`` can be used as a format string: .. code:: c++ namespace my_ns { inline string_view to_string_view(const my_string& s) { return {s.data(), s.length()}; } } std::string message = fmt::format(my_string("The answer is {}."), 42); Thanks `@DanielaE (Daniela Engert) `_. * Made ``std::string_view`` work as a format string (`#898 `_): .. code:: c++ auto message = fmt::format(std::string_view("The answer is {}."), 42); Thanks `@DanielaE (Daniela Engert) `_. * Added wide string support to compile-time format string checks (`#924 `_): .. code:: c++ print(fmt(L"{:f}"), 42); // compile-time error: invalid type specifier Thanks `@XZiar `_. * Made colored print functions work with wide strings (`#867 `_): .. code:: c++ #include int main() { print(fg(fmt::color::red), L"{}\n", 42); } Thanks `@DanielaE (Daniela Engert) `_. * Introduced experimental Unicode support (`#628 `_, `#891 `_): .. code:: c++ using namespace fmt::literals; auto s = fmt::format("{:*^5}"_u, "🤡"_u); // s == "**🤡**"_u * Improved locale support: .. code:: c++ #include struct numpunct : std::numpunct { protected: char do_thousands_sep() const override { return '~'; } }; std::locale loc; auto s = fmt::format(std::locale(loc, new numpunct()), "{:n}", 1234567); // s == "1~234~567" * Constrained formatting functions on proper iterator types (`#921 `_). Thanks `@DanielaE (Daniela Engert) `_. * Added ``make_printf_args`` and ``make_wprintf_args`` functions (`#934 `_). Thanks `@tnovotny `_. * Deprecated ``fmt::visit``, ``parse_context``, and ``wparse_context``. Use ``fmt::visit_format_arg``, ``format_parse_context``, and ``wformat_parse_context`` instead. * Removed undocumented ``basic_fixed_buffer`` which has been superseded by the iterator-based API (`#873 `_, `#902 `_). Thanks `@superfunc (hollywood programmer) `_. * Disallowed repeated leading zeros in an argument ID: .. code:: c++ fmt::print("{000}", 42); // error * Reintroduced support for gcc 4.4. * Fixed compilation on platforms with exotic ``double`` (`#878 `_). * Improved documentation (`#164 `_, `#877 `_, `#901 `_, `#906 `_, `#979 `_). Thanks `@kookjr (Mathew Cucuzella) `_, `@DarkDimius (Dmitry Petrashko) `_, `@HecticSerenity `_. * Added pkgconfig support which makes it easier to consume the library from meson and other build systems (`#916 `_). Thanks `@colemickens (Cole Mickens) `_. * Various build improvements (`#909 `_, `#926 `_, `#937 `_, `#953 `_, `#959 `_). Thanks `@tchaikov (Kefu Chai) `_, `@luncliff (Park DongHa) `_, `@AndreasSchoenle (Andreas Schönle) `_, `@hotwatermorning `_, `@Zefz (JohanJansen) `_. * Improved ``string_view`` construction performance (`#914 `_). Thanks `@gabime (Gabi Melman) `_. * Fixed non-matching char types (`#895 `_). Thanks `@DanielaE (Daniela Engert) `_. * Fixed ``format_to_n`` with ``std::back_insert_iterator`` (`#913 `_). Thanks `@DanielaE (Daniela Engert) `_. * Fixed locale-dependent formatting (`#905 `_). * Fixed various compiler warnings and errors (`#882 `_, `#886 `_, `#933 `_, `#941 `_, `#931 `_, `#943 `_, `#954 `_, `#956 `_, `#962 `_, `#965 `_, `#977 `_, `#983 `_, `#989 `_). Thanks `@Luthaf (Guillaume Fraux) `_, `@stevenhoving (Steven Hoving) `_, `@christinaa (Kristina Brooks) `_, `@lgritz (Larry Gritz) `_, `@DanielaE (Daniela Engert) `_, `@0x8000-0000 (Sign Bit) `_, `@liuping1997 `_. 5.2.1 - 2018-09-21 ------------------ * Fixed ``visit`` lookup issues on gcc 7 & 8 (`#870 `_). Thanks `@medithe `_. * Fixed linkage errors on older gcc. * Prevented ``fmt/range.h`` from specializing ``fmt::basic_string_view`` (`#865 `_, `#868 `_). Thanks `@hhggit (dual) `_. * Improved error message when formatting unknown types (`#872 `_). Thanks `@foonathan (Jonathan Müller) `_, * Disabled templated user-defined literals when compiled under nvcc (`#875 `_). Thanks `@CandyGumdrop (Candy Gumdrop) `_, * Fixed ``format_to`` formatting to ``wmemory_buffer`` (`#874 `_). 5.2.0 - 2018-09-13 ------------------ * Optimized format string parsing and argument processing which resulted in up to 5x speed up on long format strings and significant performance boost on various benchmarks. For example, version 5.2 is 2.22x faster than 5.1 on decimal integer formatting with ``format_to`` (macOS, clang-902.0.39.2): ================== ======= ======= Method Time, s Speedup ================== ======= ======= fmt::format 5.1 0.58 fmt::format 5.2 0.35 1.66x fmt::format_to 5.1 0.51 fmt::format_to 5.2 0.23 2.22x sprintf 0.71 std::to_string 1.01 std::stringstream 1.73 ================== ======= ======= * Changed the ``fmt`` macro from opt-out to opt-in to prevent name collisions. To enable it define the ``FMT_STRING_ALIAS`` macro to 1 before including ``fmt/format.h``: .. code:: c++ #define FMT_STRING_ALIAS 1 #include std::string answer = format(fmt("{}"), 42); * Added compile-time format string checks to ``format_to`` overload that takes ``fmt::memory_buffer`` (`#783 `_): .. code:: c++ fmt::memory_buffer buf; // Compile-time error: invalid type specifier. fmt::format_to(buf, fmt("{:d}"), "foo"); * Moved experimental color support to ``fmt/color.h`` and enabled the new API by default. The old API can be enabled by defining the ``FMT_DEPRECATED_COLORS`` macro. * Added formatting support for types explicitly convertible to ``fmt::string_view``: .. code:: c++ struct foo { explicit operator fmt::string_view() const { return "foo"; } }; auto s = format("{}", foo()); In particular, this makes formatting function work with ``folly::StringPiece``. * Implemented preliminary support for ``char*_t`` by replacing the ``format`` function overloads with a single function template parameterized on the string type. * Added support for dynamic argument lists (`#814 `_, `#819 `_). Thanks `@MikePopoloski (Michael Popoloski) `_. * Reduced executable size overhead for embedded targets using newlib nano by making locale dependency optional (`#839 `_). Thanks `@teajay-fr (Thomas Benard) `_. * Keep ``noexcept`` specifier when exceptions are disabled (`#801 `_, `#810 `_). Thanks `@qis (Alexej Harm) `_. * Fixed formatting of user-defined types providing ``operator<<`` with ``format_to_n`` (`#806 `_). Thanks `@mkurdej (Marek Kurdej) `_. * Fixed dynamic linkage of new symbols (`#808 `_). * Fixed global initialization issue (`#807 `_): .. code:: c++ // This works on compilers with constexpr support. static const std::string answer = fmt::format("{}", 42); * Fixed various compiler warnings and errors (`#804 `_, `#809 `_, `#811 `_, `#822 `_, `#827 `_, `#830 `_, `#838 `_, `#843 `_, `#844 `_, `#851 `_, `#852 `_, `#854 `_). Thanks `@henryiii (Henry Schreiner) `_, `@medithe `_, and `@eliasdaler (Elias Daler) `_. 5.1.0 - 2018-07-05 ------------------ * Added experimental support for RGB color output enabled with the ``FMT_EXTENDED_COLORS`` macro: .. code:: c++ #define FMT_EXTENDED_COLORS #define FMT_HEADER_ONLY // or compile fmt with FMT_EXTENDED_COLORS defined #include fmt::print(fmt::color::steel_blue, "Some beautiful text"); The old API (the ``print_colored`` and ``vprint_colored`` functions and the ``color`` enum) is now deprecated. (`#762 `_ `#767 `_). thanks `@remotion (remo) `_. * Added quotes to strings in ranges and tuples (`#766 `_). Thanks `@Remotion (Remo) `_. * Made ``format_to`` work with ``basic_memory_buffer`` (`#776 `_). * Added ``vformat_to_n`` and ``wchar_t`` overload of ``format_to_n`` (`#764 `_, `#769 `_). * Made ``is_range`` and ``is_tuple_like`` part of public (experimental) API to allow specialization for user-defined types (`#751 `_, `#759 `_). Thanks `@drrlvn (Dror Levin) `_. * Added more compilers to continuous integration and increased ``FMT_PEDANTIC`` warning levels (`#736 `_). Thanks `@eliaskosunen (Elias Kosunen) `_. * Fixed compilation with MSVC 2013. * Fixed handling of user-defined types in ``format_to`` (`#793 `_). * Forced linking of inline ``vformat`` functions into the library (`#795 `_). * Fixed incorrect call to on_align in ``'{:}='`` (`#750 `_). * Fixed floating-point formatting to a non-back_insert_iterator with sign & numeric alignment specified (`#756 `_). * Fixed formatting to an array with ``format_to_n`` (`#778 `_). * Fixed formatting of more than 15 named arguments (`#754 `_). * Fixed handling of compile-time strings when including ``fmt/ostream.h``. (`#768 `_). * Fixed various compiler warnings and errors (`#742 `_, `#748 `_, `#752 `_, `#770 `_, `#775 `_, `#779 `_, `#780 `_, `#790 `_, `#792 `_, `#800 `_). Thanks `@Remotion (Remo) `_, `@gabime (Gabi Melman) `_, `@foonathan (Jonathan Müller) `_, `@Dark-Passenger (Dhruv Paranjape) `_, and `@0x8000-0000 (Sign Bit) `_. 5.0.0 - 2018-05-21 ------------------ * Added a requirement for partial C++11 support, most importantly variadic templates and type traits, and dropped ``FMT_VARIADIC_*`` emulation macros. Variadic templates are available since GCC 4.4, Clang 2.9 and MSVC 18.0 (2013). For older compilers use {fmt} `version 4.x `_ which continues to be maintained and works with C++98 compilers. * Renamed symbols to follow standard C++ naming conventions and proposed a subset of the library for standardization in `P0645R2 Text Formatting `_. * Implemented ``constexpr`` parsing of format strings and `compile-time format string checks `_. For example .. code:: c++ #include std::string s = format(fmt("{:d}"), "foo"); gives a compile-time error because ``d`` is an invalid specifier for strings (`godbolt `__):: ... :4:19: note: in instantiation of function template specialization 'fmt::v5::format' requested here std::string s = format(fmt("{:d}"), "foo"); ^ format.h:1337:13: note: non-constexpr function 'on_error' cannot be used in a constant expression handler.on_error("invalid type specifier"); Compile-time checks require relaxed ``constexpr`` (C++14 feature) support. If the latter is not available, checks will be performed at runtime. * Separated format string parsing and formatting in the extension API to enable compile-time format string processing. For example .. code:: c++ struct Answer {}; namespace fmt { template <> struct formatter { constexpr auto parse(parse_context& ctx) { auto it = ctx.begin(); spec = *it; if (spec != 'd' && spec != 's') throw format_error("invalid specifier"); return ++it; } template auto format(Answer, FormatContext& ctx) { return spec == 's' ? format_to(ctx.begin(), "{}", "fourty-two") : format_to(ctx.begin(), "{}", 42); } char spec = 0; }; } std::string s = format(fmt("{:x}"), Answer()); gives a compile-time error due to invalid format specifier (`godbolt `__):: ... :12:45: error: expression '' is not a constant expression throw format_error("invalid specifier"); * Added `iterator support `_: .. code:: c++ #include #include std::vector out; fmt::format_to(std::back_inserter(out), "{}", 42); * Added the `format_to_n `_ function that restricts the output to the specified number of characters (`#298 `_): .. code:: c++ char out[4]; fmt::format_to_n(out, sizeof(out), "{}", 12345); // out == "1234" (without terminating '\0') * Added the `formatted_size `_ function for computing the output size: .. code:: c++ #include auto size = fmt::formatted_size("{}", 12345); // size == 5 * Improved compile times by reducing dependencies on standard headers and providing a lightweight `core API `_: .. code:: c++ #include fmt::print("The answer is {}.", 42); See `Compile time and code bloat `_. * Added the `make_format_args `_ function for capturing formatting arguments: .. code:: c++ // Prints formatted error message. void vreport_error(const char *format, fmt::format_args args) { fmt::print("Error: "); fmt::vprint(format, args); } template void report_error(const char *format, const Args & ... args) { vreport_error(format, fmt::make_format_args(args...)); } * Added the ``make_printf_args`` function for capturing ``printf`` arguments (`#687 `_, `#694 `_). Thanks `@Kronuz (Germán Méndez Bravo) `_. * Added prefix ``v`` to non-variadic functions taking ``format_args`` to distinguish them from variadic ones: .. code:: c++ std::string vformat(string_view format_str, format_args args); template std::string format(string_view format_str, const Args & ... args); * Added experimental support for formatting ranges, containers and tuple-like types in ``fmt/ranges.h`` (`#735 `_): .. code:: c++ #include std::vector v = {1, 2, 3}; fmt::print("{}", v); // prints {1, 2, 3} Thanks `@Remotion (Remo) `_. * Implemented ``wchar_t`` date and time formatting (`#712 `_): .. code:: c++ #include std::time_t t = std::time(nullptr); auto s = fmt::format(L"The date is {:%Y-%m-%d}.", *std::localtime(&t)); Thanks `@DanielaE (Daniela Engert) `_. * Provided more wide string overloads (`#724 `_). Thanks `@DanielaE (Daniela Engert) `_. * Switched from a custom null-terminated string view class to ``string_view`` in the format API and provided ``fmt::string_view`` which implements a subset of ``std::string_view`` API for pre-C++17 systems. * Added support for ``std::experimental::string_view`` (`#607 `_): .. code:: c++ #include #include fmt::print("{}", std::experimental::string_view("foo")); Thanks `@virgiliofornazin (Virgilio Alexandre Fornazin) `__. * Allowed mixing named and automatic arguments: .. code:: c++ fmt::format("{} {two}", 1, fmt::arg("two", 2)); * Removed the write API in favor of the `format API `_ with compile-time handling of format strings. * Disallowed formatting of multibyte strings into a wide character target (`#606 `_). * Improved documentation (`#515 `_, `#614 `_, `#617 `_, `#661 `_, `#680 `_). Thanks `@ibell (Ian Bell) `_, `@mihaitodor (Mihai Todor) `_, and `@johnthagen `_. * Implemented more efficient handling of large number of format arguments. * Introduced an inline namespace for symbol versioning. * Added debug postfix ``d`` to the ``fmt`` library name (`#636 `_). * Removed unnecessary ``fmt/`` prefix in includes (`#397 `_). Thanks `@chronoxor (Ivan Shynkarenka) `_. * Moved ``fmt/*.h`` to ``include/fmt/*.h`` to prevent irrelevant files and directories appearing on the include search paths when fmt is used as a subproject and moved source files to the ``src`` directory. * Added qmake project file ``support/fmt.pro`` (`#641 `_). Thanks `@cowo78 (Giuseppe Corbelli) `_. * Added Gradle build file ``support/build.gradle`` (`#649 `_). Thanks `@luncliff (Park DongHa) `_. * Removed ``FMT_CPPFORMAT`` CMake option. * Fixed a name conflict with the macro ``CHAR_WIDTH`` in glibc (`#616 `_). Thanks `@aroig (Abdó Roig-Maranges) `_. * Fixed handling of nested braces in ``fmt::join`` (`#638 `_). * Added ``SOURCELINK_SUFFIX`` for compatibility with Sphinx 1.5 (`#497 `_). Thanks `@ginggs (Graham Inggs) `_. * Added a missing ``inline`` in the header-only mode (`#626 `_). Thanks `@aroig (Abdó Roig-Maranges) `_. * Fixed various compiler warnings (`#640 `_, `#656 `_, `#679 `_, `#681 `_, `#705 `__, `#715 `_, `#717 `_, `#720 `_, `#723 `_, `#726 `_, `#730 `_, `#739 `_). Thanks `@peterbell10 `_, `@LarsGullik `_, `@foonathan (Jonathan Müller) `_, `@eliaskosunen (Elias Kosunen) `_, `@christianparpart (Christian Parpart) `_, `@DanielaE (Daniela Engert) `_, and `@mwinterb `_. * Worked around an MSVC bug and fixed several warnings (`#653 `_). Thanks `@alabuzhev (Alex Alabuzhev) `_. * Worked around GCC bug 67371 (`#682 `_). * Fixed compilation with ``-fno-exceptions`` (`#655 `_). Thanks `@chenxiaolong (Andrew Gunnerson) `_. * Made ``constexpr remove_prefix`` gcc version check tighter (`#648 `_). * Renamed internal type enum constants to prevent collision with poorly written C libraries (`#644 `_). * Added detection of ``wostream operator<<`` (`#650 `_). * Fixed compilation on OpenBSD (`#660 `_). Thanks `@hubslave `_. * Fixed compilation on FreeBSD 12 (`#732 `_). Thanks `@dankm `_. * Fixed compilation when there is a mismatch between ``-std`` options between the library and user code (`#664 `_). * Fixed compilation with GCC 7 and ``-std=c++11`` (`#734 `_). * Improved generated binary code on GCC 7 and older (`#668 `_). * Fixed handling of numeric alignment with no width (`#675 `_). * Fixed handling of empty strings in UTF8/16 converters (`#676 `_). Thanks `@vgalka-sl (Vasili Galka) `_. * Fixed formatting of an empty ``string_view`` (`#689 `_). * Fixed detection of ``string_view`` on libc++ (`#686 `_). * Fixed DLL issues (`#696 `_). Thanks `@sebkoenig `_. * Fixed compile checks for mixing narrow and wide strings (`#690 `_). * Disabled unsafe implicit conversion to ``std::string`` (`#729 `_). * Fixed handling of reused format specs (as in ``fmt::join``) for pointers (`#725 `_). Thanks `@mwinterb `_. * Fixed installation of ``fmt/ranges.h`` (`#738 `_). Thanks `@sv1990 `_. 4.1.0 - 2017-12-20 ------------------ * Added ``fmt::to_wstring()`` in addition to ``fmt::to_string()`` (`#559 `_). Thanks `@alabuzhev (Alex Alabuzhev) `_. * Added support for C++17 ``std::string_view`` (`#571 `_ and `#578 `_). Thanks `@thelostt (Mário Feroldi) `_ and `@mwinterb `_. * Enabled stream exceptions to catch errors (`#581 `_). Thanks `@crusader-mike `_. * Allowed formatting of class hierarchies with ``fmt::format_arg()`` (`#547 `_). Thanks `@rollbear (Björn Fahller) `_. * Removed limitations on character types (`#563 `_). Thanks `@Yelnats321 (Elnar Dakeshov) `_. * Conditionally enabled use of ``std::allocator_traits`` (`#583 `_). Thanks `@mwinterb `_. * Added support for ``const`` variadic member function emulation with ``FMT_VARIADIC_CONST`` (`#591 `_). Thanks `@ludekvodicka (Ludek Vodicka) `_. * Various bugfixes: bad overflow check, unsupported implicit type conversion when determining formatting function, test segfaults (`#551 `_), ill-formed macros (`#542 `_) and ambiguous overloads (`#580 `_). Thanks `@xylosper (Byoung-young Lee) `_. * Prevented warnings on MSVC (`#605 `_, `#602 `_, and `#545 `_), clang (`#582 `_), GCC (`#573 `_), various conversion warnings (`#609 `_, `#567 `_, `#553 `_ and `#553 `_), and added ``override`` and ``[[noreturn]]`` (`#549 `_ and `#555 `_). Thanks `@alabuzhev (Alex Alabuzhev) `_, `@virgiliofornazin (Virgilio Alexandre Fornazin) `_, `@alexanderbock (Alexander Bock) `_, `@yumetodo `_, `@VaderY (Császár Mátyás) `_, `@jpcima (JP Cimalando) `_, `@thelostt (Mário Feroldi) `_, and `@Manu343726 (Manu Sánchez) `_. * Improved CMake: Used ``GNUInstallDirs`` to set installation location (`#610 `_) and fixed warnings (`#536 `_ and `#556 `_). Thanks `@mikecrowe (Mike Crowe) `_, `@evgen231 `_ and `@henryiii (Henry Schreiner) `_. 4.0.0 - 2017-06-27 ------------------ * Removed old compatibility headers ``cppformat/*.h`` and CMake options (`#527 `_). Thanks `@maddinat0r (Alex Martin) `_. * Added ``string.h`` containing ``fmt::to_string()`` as alternative to ``std::to_string()`` as well as other string writer functionality (`#326 `_ and `#441 `_): .. code:: c++ #include "fmt/string.h" std::string answer = fmt::to_string(42); Thanks to `@glebov-andrey (Andrey Glebov) `_. * Moved ``fmt::printf()`` to new ``printf.h`` header and allowed ``%s`` as generic specifier (`#453 `_), made ``%.f`` more conformant to regular ``printf()`` (`#490 `_), added custom writer support (`#476 `_) and implemented missing custom argument formatting (`#339 `_ and `#340 `_): .. code:: c++ #include "fmt/printf.h" // %s format specifier can be used with any argument type. fmt::printf("%s", 42); Thanks `@mojoBrendan `_, `@manylegged (Arthur Danskin) `_ and `@spacemoose (Glen Stark) `_. See also `#360 `_, `#335 `_ and `#331 `_. * Added ``container.h`` containing a ``BasicContainerWriter`` to write to containers like ``std::vector`` (`#450 `_). Thanks `@polyvertex (Jean-Charles Lefebvre) `_. * Added ``fmt::join()`` function that takes a range and formats its elements separated by a given string (`#466 `_): .. code:: c++ #include "fmt/format.h" std::vector v = {1.2, 3.4, 5.6}; // Prints "(+01.20, +03.40, +05.60)". fmt::print("({:+06.2f})", fmt::join(v.begin(), v.end(), ", ")); Thanks `@olivier80 `_. * Added support for custom formatting specifications to simplify customization of built-in formatting (`#444 `_). Thanks `@polyvertex (Jean-Charles Lefebvre) `_. See also `#439 `_. * Added ``fmt::format_system_error()`` for error code formatting (`#323 `_ and `#526 `_). Thanks `@maddinat0r (Alex Martin) `_. * Added thread-safe ``fmt::localtime()`` and ``fmt::gmtime()`` as replacement for the standard version to ``time.h`` (`#396 `_). Thanks `@codicodi `_. * Internal improvements to ``NamedArg`` and ``ArgLists`` (`#389 `_ and `#390 `_). Thanks `@chronoxor `_. * Fixed crash due to bug in ``FormatBuf`` (`#493 `_). Thanks `@effzeh `_. See also `#480 `_ and `#491 `_. * Fixed handling of wide strings in ``fmt::StringWriter``. * Improved compiler error messages (`#357 `_). * Fixed various warnings and issues with various compilers (`#494 `_, `#499 `_, `#483 `_, `#485 `_, `#482 `_, `#475 `_, `#473 `_ and `#414 `_). Thanks `@chronoxor `_, `@zhaohuaxishi `_, `@pkestene (Pierre Kestener) `_, `@dschmidt (Dominik Schmidt) `_ and `@0x414c (Alexey Gorishny) `_ . * Improved CMake: targets are now namespaced (`#511 `_ and `#513 `_), supported header-only ``printf.h`` (`#354 `_), fixed issue with minimal supported library subset (`#418 `_, `#419 `_ and `#420 `_). Thanks `@bjoernthiel (Bjoern Thiel) `_, `@niosHD (Mario Werner) `_, `@LogicalKnight (Sean LK) `_ and `@alabuzhev (Alex Alabuzhev) `_. * Improved documentation. Thanks to `@pwm1234 (Phil) `_ for `#393 `_. 3.0.2 - 2017-06-14 ------------------ * Added ``FMT_VERSION`` macro (`#411 `_). * Used ``FMT_NULL`` instead of literal ``0`` (`#409 `_). Thanks `@alabuzhev (Alex Alabuzhev) `_. * Added extern templates for ``format_float`` (`#413 `_). * Fixed implicit conversion issue (`#507 `_). * Fixed signbit detection (`#423 `_). * Fixed naming collision (`#425 `_). * Fixed missing intrinsic for C++/CLI (`#457 `_). Thanks `@calumr (Calum Robinson) `_ * Fixed Android detection (`#458 `_). Thanks `@Gachapen (Magnus Bjerke Vik) `_. * Use lean ``windows.h`` if not in header-only mode (`#503 `_). Thanks `@Quentin01 (Quentin Buathier) `_. * Fixed issue with CMake exporting C++11 flag (`#445 `_). Thanks `@EricWF (Eric) `_. * Fixed issue with nvcc and MSVC compiler bug and MinGW (`#505 `_). * Fixed DLL issues (`#469 `_ and `#502 `_). Thanks `@richardeakin (Richard Eakin) `_ and `@AndreasSchoenle (Andreas Schönle) `_. * Fixed test compilation under FreeBSD (`#433 `_). * Fixed various warnings (`#403 `_, `#410 `_ and `#510 `_). Thanks `@Lecetem `_, `@chenhayat (Chen Hayat) `_ and `@trozen `_. * Worked around a broken ``__builtin_clz`` in clang with MS codegen (`#519 `_). * Removed redundant include (`#479 `_). * Fixed documentation issues. 3.0.1 - 2016-11-01 ------------------ * Fixed handling of thousands separator (`#353 `_). * Fixed handling of ``unsigned char`` strings (`#373 `_). * Corrected buffer growth when formatting time (`#367 `_). * Removed warnings under MSVC and clang (`#318 `_, `#250 `_, also merged `#385 `_ and `#361 `_). Thanks `@jcelerier (Jean-Michaël Celerier) `_ and `@nmoehrle (Nils Moehrle) `_. * Fixed compilation issues under Android (`#327 `_, `#345 `_ and `#381 `_), FreeBSD (`#358 `_), Cygwin (`#388 `_), MinGW (`#355 `_) as well as other issues (`#350 `_, `#366 `_, `#348 `_, `#402 `_, `#405 `_). Thanks to `@dpantele (Dmitry) `_, `@hghwng (Hugh Wang) `_, `@arvedarved (Tilman Keskinöz) `_, `@LogicalKnight (Sean) `_ and `@JanHellwig (Jan Hellwig) `_. * Fixed some documentation issues and extended specification (`#320 `_, `#333 `_, `#347 `_, `#362 `_). Thanks to `@smellman (Taro Matsuzawa aka. btm) `_. 3.0.0 - 2016-05-07 ------------------ * The project has been renamed from C++ Format (cppformat) to fmt for consistency with the used namespace and macro prefix (`#307 `_). Library headers are now located in the ``fmt`` directory: .. code:: c++ #include "fmt/format.h" Including ``format.h`` from the ``cppformat`` directory is deprecated but works via a proxy header which will be removed in the next major version. The documentation is now available at https://fmt.dev. * Added support for `strftime `_-like `date and time formatting `_ (`#283 `_): .. code:: c++ #include "fmt/time.h" std::time_t t = std::time(nullptr); // Prints "The date is 2016-04-29." (with the current date) fmt::print("The date is {:%Y-%m-%d}.", *std::localtime(&t)); * ``std::ostream`` support including formatting of user-defined types that provide overloaded ``operator<<`` has been moved to ``fmt/ostream.h``: .. code:: c++ #include "fmt/ostream.h" class Date { int year_, month_, day_; public: Date(int year, int month, int day) : year_(year), month_(month), day_(day) {} friend std::ostream &operator<<(std::ostream &os, const Date &d) { return os << d.year_ << '-' << d.month_ << '-' << d.day_; } }; std::string s = fmt::format("The date is {}", Date(2012, 12, 9)); // s == "The date is 2012-12-9" * Added support for `custom argument formatters `_ (`#235 `_). * Added support for locale-specific integer formatting with the ``n`` specifier (`#305 `_): .. code:: c++ std::setlocale(LC_ALL, "en_US.utf8"); fmt::print("cppformat: {:n}\n", 1234567); // prints 1,234,567 * Sign is now preserved when formatting an integer with an incorrect ``printf`` format specifier (`#265 `_): .. code:: c++ fmt::printf("%lld", -42); // prints -42 Note that it would be an undefined behavior in ``std::printf``. * Length modifiers such as ``ll`` are now optional in printf formatting functions and the correct type is determined automatically (`#255 `_): .. code:: c++ fmt::printf("%d", std::numeric_limits::max()); Note that it would be an undefined behavior in ``std::printf``. * Added initial support for custom formatters (`#231 `_). * Fixed detection of user-defined literal support on Intel C++ compiler (`#311 `_, `#312 `_). Thanks to `@dean0x7d (Dean Moldovan) `_ and `@speth (Ray Speth) `_. * Reduced compile time (`#243 `_, `#249 `_, `#317 `_): .. image:: https://cloud.githubusercontent.com/assets/4831417/11614060/ b9e826d2-9c36-11e5-8666-d4131bf503ef.png .. image:: https://cloud.githubusercontent.com/assets/4831417/11614080/ 6ac903cc-9c37-11e5-8165-26df6efae364.png Thanks to `@dean0x7d (Dean Moldovan) `_. * Compile test fixes (`#313 `_). Thanks to `@dean0x7d (Dean Moldovan) `_. * Documentation fixes (`#239 `_, `#248 `_, `#252 `_, `#258 `_, `#260 `_, `#301 `_, `#309 `_). Thanks to `@ReadmeCritic `_ `@Gachapen (Magnus Bjerke Vik) `_ and `@jwilk (Jakub Wilk) `_. * Fixed compiler and sanitizer warnings (`#244 `_, `#256 `_, `#259 `_, `#263 `_, `#274 `_, `#277 `_, `#286 `_, `#291 `_, `#296 `_, `#308 `_) Thanks to `@mwinterb `_, `@pweiskircher (Patrik Weiskircher) `_, `@Naios `_. * Improved compatibility with Windows Store apps (`#280 `_, `#285 `_) Thanks to `@mwinterb `_. * Added tests of compatibility with older C++ standards (`#273 `_). Thanks to `@niosHD `_. * Fixed Android build (`#271 `_). Thanks to `@newnon `_. * Changed ``ArgMap`` to be backed by a vector instead of a map. (`#261 `_, `#262 `_). Thanks to `@mwinterb `_. * Added ``fprintf`` overload that writes to a ``std::ostream`` (`#251 `_). Thanks to `nickhutchinson (Nicholas Hutchinson) `_. * Export symbols when building a Windows DLL (`#245 `_). Thanks to `macdems (Maciek Dems) `_. * Fixed compilation on Cygwin (`#304 `_). * Implemented a workaround for a bug in Apple LLVM version 4.2 of clang (`#276 `_). * Implemented a workaround for Google Test bug `#705 `_ on gcc 6 (`#268 `_). Thanks to `octoploid `_. * Removed Biicode support because the latter has been discontinued. 2.1.1 - 2016-04-11 ------------------ * The install location for generated CMake files is now configurable via the ``FMT_CMAKE_DIR`` CMake variable (`#299 `_). Thanks to `@niosHD `_. * Documentation fixes (`#252 `_). 2.1.0 - 2016-03-21 ------------------ * Project layout and build system improvements (`#267 `_): * The code have been moved to the ``cppformat`` directory. Including ``format.h`` from the top-level directory is deprecated but works via a proxy header which will be removed in the next major version. * C++ Format CMake targets now have proper interface definitions. * Installed version of the library now supports the header-only configuration. * Targets ``doc``, ``install``, and ``test`` are now disabled if C++ Format is included as a CMake subproject. They can be enabled by setting ``FMT_DOC``, ``FMT_INSTALL``, and ``FMT_TEST`` in the parent project. Thanks to `@niosHD `_. 2.0.1 - 2016-03-13 ------------------ * Improved CMake find and package support (`#264 `_). Thanks to `@niosHD `_. * Fix compile error with Android NDK and mingw32 (`#241 `_). Thanks to `@Gachapen (Magnus Bjerke Vik) `_. * Documentation fixes (`#248 `_, `#260 `_). 2.0.0 - 2015-12-01 ------------------ General ~~~~~~~ * [Breaking] Named arguments (`#169 `_, `#173 `_, `#174 `_): .. code:: c++ fmt::print("The answer is {answer}.", fmt::arg("answer", 42)); Thanks to `@jamboree `_. * [Experimental] User-defined literals for format and named arguments (`#204 `_, `#206 `_, `#207 `_): .. code:: c++ using namespace fmt::literals; fmt::print("The answer is {answer}.", "answer"_a=42); Thanks to `@dean0x7d (Dean Moldovan) `_. * [Breaking] Formatting of more than 16 arguments is now supported when using variadic templates (`#141 `_). Thanks to `@Shauren `_. * Runtime width specification (`#168 `_): .. code:: c++ fmt::format("{0:{1}}", 42, 5); // gives " 42" Thanks to `@jamboree `_. * [Breaking] Enums are now formatted with an overloaded ``std::ostream`` insertion operator (``operator<<``) if available (`#232 `_). * [Breaking] Changed default ``bool`` format to textual, "true" or "false" (`#170 `_): .. code:: c++ fmt::print("{}", true); // prints "true" To print ``bool`` as a number use numeric format specifier such as ``d``: .. code:: c++ fmt::print("{:d}", true); // prints "1" * ``fmt::printf`` and ``fmt::sprintf`` now support formatting of ``bool`` with the ``%s`` specifier giving textual output, "true" or "false" (`#223 `_): .. code:: c++ fmt::printf("%s", true); // prints "true" Thanks to `@LarsGullik `_. * [Breaking] ``signed char`` and ``unsigned char`` are now formatted as integers by default (`#217 `_). * [Breaking] Pointers to C strings can now be formatted with the ``p`` specifier (`#223 `_): .. code:: c++ fmt::print("{:p}", "test"); // prints pointer value Thanks to `@LarsGullik `_. * [Breaking] ``fmt::printf`` and ``fmt::sprintf`` now print null pointers as ``(nil)`` and null strings as ``(null)`` for consistency with glibc (`#226 `_). Thanks to `@LarsGullik `_. * [Breaking] ``fmt::(s)printf`` now supports formatting of objects of user-defined types that provide an overloaded ``std::ostream`` insertion operator (``operator<<``) (`#201 `_): .. code:: c++ fmt::printf("The date is %s", Date(2012, 12, 9)); * [Breaking] The ``Buffer`` template is now part of the public API and can be used to implement custom memory buffers (`#140 `_). Thanks to `@polyvertex (Jean-Charles Lefebvre) `_. * [Breaking] Improved compatibility between ``BasicStringRef`` and `std::experimental::basic_string_view `_ (`#100 `_, `#159 `_, `#183 `_): - Comparison operators now compare string content, not pointers - ``BasicStringRef::c_str`` replaced by ``BasicStringRef::data`` - ``BasicStringRef`` is no longer assumed to be null-terminated References to null-terminated strings are now represented by a new class, ``BasicCStringRef``. * Dependency on pthreads introduced by Google Test is now optional (`#185 `_). * New CMake options ``FMT_DOC``, ``FMT_INSTALL`` and ``FMT_TEST`` to control generation of ``doc``, ``install`` and ``test`` targets respectively, on by default (`#197 `_, `#198 `_, `#200 `_). Thanks to `@maddinat0r (Alex Martin) `_. * ``noexcept`` is now used when compiling with MSVC2015 (`#215 `_). Thanks to `@dmkrepo (Dmitriy) `_. * Added an option to disable use of ``windows.h`` when ``FMT_USE_WINDOWS_H`` is defined as 0 before including ``format.h`` (`#171 `_). Thanks to `@alfps (Alf P. Steinbach) `_. * [Breaking] ``windows.h`` is now included with ``NOMINMAX`` unless ``FMT_WIN_MINMAX`` is defined. This is done to prevent breaking code using ``std::min`` and ``std::max`` and only affects the header-only configuration (`#152 `_, `#153 `_, `#154 `_). Thanks to `@DevO2012 `_. * Improved support for custom character types (`#171 `_). Thanks to `@alfps (Alf P. Steinbach) `_. * Added an option to disable use of IOStreams when ``FMT_USE_IOSTREAMS`` is defined as 0 before including ``format.h`` (`#205 `_, `#208 `_). Thanks to `@JodiTheTigger `_. * Improved detection of ``isnan``, ``isinf`` and ``signbit``. Optimization ~~~~~~~~~~~~ * Made formatting of user-defined types more efficient with a custom stream buffer (`#92 `_, `#230 `_). Thanks to `@NotImplemented `_. * Further improved performance of ``fmt::Writer`` on integer formatting and fixed a minor regression. Now it is ~7% faster than ``karma::generate`` on Karma's benchmark (`#186 `_). * [Breaking] Reduced `compiled code size `_ (`#143 `_, `#149 `_). Distribution ~~~~~~~~~~~~ * [Breaking] Headers are now installed in ``${CMAKE_INSTALL_PREFIX}/include/cppformat`` (`#178 `_). Thanks to `@jackyf (Eugene V. Lyubimkin) `_. * [Breaking] Changed the library name from ``format`` to ``cppformat`` for consistency with the project name and to avoid potential conflicts (`#178 `_). Thanks to `@jackyf (Eugene V. Lyubimkin) `_. * C++ Format is now available in `Debian `_ GNU/Linux (`stretch `_, `sid `_) and derived distributions such as `Ubuntu `_ 15.10 and later (`#155 `_):: $ sudo apt-get install libcppformat1-dev Thanks to `@jackyf (Eugene V. Lyubimkin) `_. * `Packages for Fedora and RHEL `_ are now available. Thanks to Dave Johansen. * C++ Format can now be installed via `Homebrew `_ on OS X (`#157 `_):: $ brew install cppformat Thanks to `@ortho `_, Anatoliy Bulukin. Documentation ~~~~~~~~~~~~~ * Migrated from ReadTheDocs to GitHub Pages for better responsiveness and reliability (`#128 `_). New documentation address is http://cppformat.github.io/. * Added `Building the documentation `_ section to the documentation. * Documentation build script is now compatible with Python 3 and newer pip versions. (`#189 `_, `#209 `_). Thanks to `@JodiTheTigger `_ and `@xentec `_. * Documentation fixes and improvements (`#36 `_, `#75 `_, `#125 `_, `#160 `_, `#161 `_, `#162 `_, `#165 `_, `#210 `_). Thanks to `@syohex (Syohei YOSHIDA) `_ and bug reporters. * Fixed out-of-tree documentation build (`#177 `_). Thanks to `@jackyf (Eugene V. Lyubimkin) `_. Fixes ~~~~~ * Fixed ``initializer_list`` detection (`#136 `_). Thanks to `@Gachapen (Magnus Bjerke Vik) `_. * [Breaking] Fixed formatting of enums with numeric format specifiers in ``fmt::(s)printf`` (`#131 `_, `#139 `_): .. code:: c++ enum { ANSWER = 42 }; fmt::printf("%d", ANSWER); Thanks to `@Naios `_. * Improved compatibility with old versions of MinGW (`#129 `_, `#130 `_, `#132 `_). Thanks to `@cstamford (Christopher Stamford) `_. * Fixed a compile error on MSVC with disabled exceptions (`#144 `_). * Added a workaround for broken implementation of variadic templates in MSVC2012 (`#148 `_). * Placed the anonymous namespace within ``fmt`` namespace for the header-only configuration (`#171 `_). Thanks to `@alfps (Alf P. Steinbach) `_. * Fixed issues reported by Coverity Scan (`#187 `_, `#192 `_). * Implemented a workaround for a name lookup bug in MSVC2010 (`#188 `_). * Fixed compiler warnings (`#95 `_, `#96 `_, `#114 `_, `#135 `_, `#142 `_, `#145 `_, `#146 `_, `#158 `_, `#163 `_, `#175 `_, `#190 `_, `#191 `_, `#194 `_, `#196 `_, `#216 `_, `#218 `_, `#220 `_, `#229 `_, `#233 `_, `#234 `_, `#236 `_, `#281 `_, `#289 `_). Thanks to `@seanmiddleditch (Sean Middleditch) `_, `@dixlorenz (Dix Lorenz) `_, `@CarterLi (李通洲) `_, `@Naios `_, `@fmatthew5876 (Matthew Fioravante) `_, `@LevskiWeng (Levski Weng) `_, `@rpopescu `_, `@gabime (Gabi Melman) `_, `@cubicool (Jeremy Moles) `_, `@jkflying (Julian Kent) `_, `@LogicalKnight (Sean L) `_, `@inguin (Ingo van Lil) `_ and `@Jopie64 (Johan) `_. * Fixed portability issues (mostly causing test failures) on ARM, ppc64, ppc64le, s390x and SunOS 5.11 i386 (`#138 `_, `#179 `_, `#180 `_, `#202 `_, `#225 `_, `Red Hat Bugzilla Bug 1260297 `_). Thanks to `@Naios `_, `@jackyf (Eugene V. Lyubimkin) `_ and Dave Johansen. * Fixed a name conflict with macro ``free`` defined in ``crtdbg.h`` when ``_CRTDBG_MAP_ALLOC`` is set (`#211 `_). * Fixed shared library build on OS X (`#212 `_). Thanks to `@dean0x7d (Dean Moldovan) `_. * Fixed an overload conflict on MSVC when ``/Zc:wchar_t-`` option is specified (`#214 `_). Thanks to `@slavanap (Vyacheslav Napadovsky) `_. * Improved compatibility with MSVC 2008 (`#236 `_). Thanks to `@Jopie64 (Johan) `_. * Improved compatibility with bcc32 (`#227 `_). * Fixed ``static_assert`` detection on Clang (`#228 `_). Thanks to `@dean0x7d (Dean Moldovan) `_. 1.1.0 - 2015-03-06 ------------------ * Added ``BasicArrayWriter``, a class template that provides operations for formatting and writing data into a fixed-size array (`#105 `_ and `#122 `_): .. code:: c++ char buffer[100]; fmt::ArrayWriter w(buffer); w.write("The answer is {}", 42); * Added `0 A.D. `_ and `PenUltima Online (POL) `_ to the list of notable projects using C++ Format. * C++ Format now uses MSVC intrinsics for better formatting performance (`#115 `_, `#116 `_, `#118 `_ and `#121 `_). Previously these optimizations where only used on GCC and Clang. Thanks to `@CarterLi `_ and `@objectx `_. * CMake install target (`#119 `_). Thanks to `@TrentHouliston `_. You can now install C++ Format with ``make install`` command. * Improved `Biicode `_ support (`#98 `_ and `#104 `_). Thanks to `@MariadeAnton `_ and `@franramirez688 `_. * Improved support for building with `Android NDK `_ (`#107 `_). Thanks to `@newnon `_. The `android-ndk-example `_ repository provides and example of using C++ Format with Android NDK: .. image:: https://raw.githubusercontent.com/fmtlib/android-ndk-example/ master/screenshot.png * Improved documentation of ``SystemError`` and ``WindowsError`` (`#54 `_). * Various code improvements (`#110 `_, `#111 `_ `#112 `_). Thanks to `@CarterLi `_. * Improved compile-time errors when formatting wide into narrow strings (`#117 `_). * Fixed ``BasicWriter::write`` without formatting arguments when C++11 support is disabled (`#109 `_). * Fixed header-only build on OS X with GCC 4.9 (`#124 `_). * Fixed packaging issues (`#94 `_). * Added `changelog `_ (`#103 `_). 1.0.0 - 2015-02-05 ------------------ * Add support for a header-only configuration when ``FMT_HEADER_ONLY`` is defined before including ``format.h``: .. code:: c++ #define FMT_HEADER_ONLY #include "format.h" * Compute string length in the constructor of ``BasicStringRef`` instead of the ``size`` method (`#79 `_). This eliminates size computation for string literals on reasonable optimizing compilers. * Fix formatting of types with overloaded ``operator <<`` for ``std::wostream`` (`#86 `_): .. code:: c++ fmt::format(L"The date is {0}", Date(2012, 12, 9)); * Fix linkage of tests on Arch Linux (`#89 `_). * Allow precision specifier for non-float arguments (`#90 `_): .. code:: c++ fmt::print("{:.3}\n", "Carpet"); // prints "Car" * Fix build on Android NDK (`#93 `_) * Improvements to documentation build procedure. * Remove ``FMT_SHARED`` CMake variable in favor of standard `BUILD_SHARED_LIBS `_. * Fix error handling in ``fmt::fprintf``. * Fix a number of warnings. 0.12.0 - 2014-10-25 ------------------- * [Breaking] Improved separation between formatting and buffer management. ``Writer`` is now a base class that cannot be instantiated directly. The new ``MemoryWriter`` class implements the default buffer management with small allocations done on stack. So ``fmt::Writer`` should be replaced with ``fmt::MemoryWriter`` in variable declarations. Old code: .. code:: c++ fmt::Writer w; New code: .. code:: c++ fmt::MemoryWriter w; If you pass ``fmt::Writer`` by reference, you can continue to do so: .. code:: c++ void f(fmt::Writer &w); This doesn't affect the formatting API. * Support for custom memory allocators (`#69 `_) * Formatting functions now accept `signed char` and `unsigned char` strings as arguments (`#73 `_): .. code:: c++ auto s = format("GLSL version: {}", glGetString(GL_VERSION)); * Reduced code bloat. According to the new `benchmark results `_, cppformat is close to ``printf`` and by the order of magnitude better than Boost Format in terms of compiled code size. * Improved appearance of the documentation on mobile by using the `Sphinx Bootstrap theme `_: .. |old| image:: https://cloud.githubusercontent.com/assets/576385/4792130/ cd256436-5de3-11e4-9a62-c077d0c2b003.png .. |new| image:: https://cloud.githubusercontent.com/assets/576385/4792131/ cd29896c-5de3-11e4-8f59-cac952942bf0.png +-------+-------+ | Old | New | +-------+-------+ | |old| | |new| | +-------+-------+ 0.11.0 - 2014-08-21 ------------------- * Safe printf implementation with a POSIX extension for positional arguments: .. code:: c++ fmt::printf("Elapsed time: %.2f seconds", 1.23); fmt::printf("%1$s, %3$d %2$s", weekday, month, day); * Arguments of ``char`` type can now be formatted as integers (Issue `#55 `_): .. code:: c++ fmt::format("0x{0:02X}", 'a'); * Deprecated parts of the API removed. * The library is now built and tested on MinGW with Appveyor in addition to existing test platforms Linux/GCC, OS X/Clang, Windows/MSVC. 0.10.0 - 2014-07-01 ------------------- **Improved API** * All formatting methods are now implemented as variadic functions instead of using ``operator<<`` for feeding arbitrary arguments into a temporary formatter object. This works both with C++11 where variadic templates are used and with older standards where variadic functions are emulated by providing lightweight wrapper functions defined with the ``FMT_VARIADIC`` macro. You can use this macro for defining your own portable variadic functions: .. code:: c++ void report_error(const char *format, const fmt::ArgList &args) { fmt::print("Error: {}"); fmt::print(format, args); } FMT_VARIADIC(void, report_error, const char *) report_error("file not found: {}", path); Apart from a more natural syntax, this also improves performance as there is no need to construct temporary formatter objects and control arguments' lifetimes. Because the wrapper functions are very lightweight, this doesn't cause code bloat even in pre-C++11 mode. * Simplified common case of formatting an ``std::string``. Now it requires a single function call: .. code:: c++ std::string s = format("The answer is {}.", 42); Previously it required 2 function calls: .. code:: c++ std::string s = str(Format("The answer is {}.") << 42); Instead of unsafe ``c_str`` function, ``fmt::Writer`` should be used directly to bypass creation of ``std::string``: .. code:: c++ fmt::Writer w; w.write("The answer is {}.", 42); w.c_str(); // returns a C string This doesn't do dynamic memory allocation for small strings and is less error prone as the lifetime of the string is the same as for ``std::string::c_str`` which is well understood (hopefully). * Improved consistency in naming functions that are a part of the public API. Now all public functions are lowercase following the standard library conventions. Previously it was a combination of lowercase and CapitalizedWords. Issue `#50 `_. * Old functions are marked as deprecated and will be removed in the next release. **Other Changes** * Experimental support for printf format specifications (work in progress): .. code:: c++ fmt::printf("The answer is %d.", 42); std::string s = fmt::sprintf("Look, a %s!", "string"); * Support for hexadecimal floating point format specifiers ``a`` and ``A``: .. code:: c++ print("{:a}", -42.0); // Prints -0x1.5p+5 print("{:A}", -42.0); // Prints -0X1.5P+5 * CMake option ``FMT_SHARED`` that specifies whether to build format as a shared library (off by default). 0.9.0 - 2014-05-13 ------------------ * More efficient implementation of variadic formatting functions. * ``Writer::Format`` now has a variadic overload: .. code:: c++ Writer out; out.Format("Look, I'm {}!", "variadic"); * For efficiency and consistency with other overloads, variadic overload of the ``Format`` function now returns ``Writer`` instead of ``std::string``. Use the ``str`` function to convert it to ``std::string``: .. code:: c++ std::string s = str(Format("Look, I'm {}!", "variadic")); * Replaced formatter actions with output sinks: ``NoAction`` -> ``NullSink``, ``Write`` -> ``FileSink``, ``ColorWriter`` -> ``ANSITerminalSink``. This improves naming consistency and shouldn't affect client code unless these classes are used directly which should be rarely needed. * Added ``ThrowSystemError`` function that formats a message and throws ``SystemError`` containing the formatted message and system-specific error description. For example, the following code .. code:: c++ FILE *f = fopen(filename, "r"); if (!f) ThrowSystemError(errno, "Failed to open file '{}'") << filename; will throw ``SystemError`` exception with description "Failed to open file '': No such file or directory" if file doesn't exist. * Support for AppVeyor continuous integration platform. * ``Format`` now throws ``SystemError`` in case of I/O errors. * Improve test infrastructure. Print functions are now tested by redirecting the output to a pipe. 0.8.0 - 2014-04-14 ------------------ * Initial release ================================================ FILE: src/third_party/fmt/LICENSE.rst ================================================ Copyright (c) 2012 - present, Victor Zverovich All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: src/third_party/fmt/README.rst ================================================ {fmt} ===== .. image:: https://travis-ci.org/fmtlib/fmt.png?branch=master :target: https://travis-ci.org/fmtlib/fmt .. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v :target: https://ci.appveyor.com/project/vitaut/fmt .. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg :alt: Ask questions at StackOverflow with the tag fmt :target: http://stackoverflow.com/questions/tagged/fmt **{fmt}** is an open-source formatting library for C++. It can be used as a safe and fast alternative to (s)printf and iostreams. `Documentation `__ Q&A: ask questions on `StackOverflow with the tag fmt `_. Features -------- * Replacement-based `format API `_ with positional arguments for localization. * `Format string syntax `_ similar to the one of `str.format `_ in Python. * Safe `printf implementation `_ including the POSIX extension for positional arguments. * Implementation of `C++20 std::format `__. * Support for user-defined types. * High performance: faster than common standard library implementations of `printf `_ and iostreams. See `Speed tests`_ and `Fast integer to string conversion in C++ `_. * Small code size both in terms of source code (the minimum configuration consists of just three header files, ``core.h``, ``format.h`` and ``format-inl.h``) and compiled code. See `Compile time and code bloat`_. * Reliability: the library has an extensive set of `unit tests `_. * Safety: the library is fully type safe, errors in format strings can be reported at compile time, automatic memory management prevents buffer overflow errors. * Ease of use: small self-contained code base, no external dependencies, permissive BSD `license `_ * `Portability `_ with consistent output across platforms and support for older compilers. * Clean warning-free codebase even on high warning levels (``-Wall -Wextra -pedantic``). * Support for wide strings. * Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro. See the `documentation `_ for more details. Examples -------- Print ``Hello, world!`` to ``stdout``: .. code:: c++ fmt::print("Hello, {}!", "world"); // Python-like format string syntax fmt::printf("Hello, %s!", "world"); // printf format string syntax Format a string and use positional arguments: .. code:: c++ std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy"); // s == "I'd rather be happy than right." Check a format string at compile time: .. code:: c++ // test.cc #define FMT_STRING_ALIAS 1 #include std::string s = format(fmt("{2}"), 42); .. code:: $ c++ -Iinclude -std=c++14 test.cc ... test.cc:4:17: note: in instantiation of function template specialization 'fmt::v5::format' requested here std::string s = format(fmt("{2}"), 42); ^ include/fmt/core.h:778:19: note: non-constexpr function 'on_error' cannot be used in a constant expression ErrorHandler::on_error(message); ^ include/fmt/format.h:2226:16: note: in call to '&checker.context_->on_error(&"argument index out of range"[0])' context_.on_error("argument index out of range"); ^ Use {fmt} as a safe portable replacement for ``itoa`` (`godbolt `_): .. code:: c++ fmt::memory_buffer buf; format_to(buf, "{}", 42); // replaces itoa(42, buffer, 10) format_to(buf, "{:x}", 42); // replaces itoa(42, buffer, 16) // access the string with to_string(buf) or buf.data() Format objects of user-defined types via a simple `extension API `_: .. code:: c++ #include "fmt/format.h" struct date { int year, month, day; }; template <> struct fmt::formatter { template constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } template auto format(const date &d, FormatContext &ctx) { return format_to(ctx.out(), "{}-{}-{}", d.year, d.month, d.day); } }; std::string s = fmt::format("The date is {}", date{2012, 12, 9}); // s == "The date is 2012-12-9" Create your own functions similar to `format `_ and `print `_ which take arbitrary arguments (`godbolt `_): .. code:: c++ // Prints formatted error message. void vreport_error(const char *format, fmt::format_args args) { fmt::print("Error: "); fmt::vprint(format, args); } template void report_error(const char *format, const Args & ... args) { vreport_error(format, fmt::make_format_args(args...)); } report_error("file not found: {}", path); Note that ``vreport_error`` is not parameterized on argument types which can improve compile times and reduce code size compared to a fully parameterized version. Benchmarks ---------- Speed tests ~~~~~~~~~~~ ================= ============= =========== Library Method Run Time, s ================= ============= =========== libc printf 1.01 libc++ std::ostream 3.04 {fmt} 1632f72 fmt::print 0.86 tinyformat 2.0.1 tfm::printf 3.23 Boost Format 1.67 boost::format 7.98 Folly Format folly::format 2.23 ================= ============= =========== {fmt} is the fastest of the benchmarked methods, ~17% faster than ``printf``. The above results were generated by building ``tinyformat_test.cpp`` on macOS 10.14.3 with ``clang++ -O3 -DSPEED_TEST -DHAVE_FORMAT``, and taking the best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for further details refer to the `source `_. {fmt} is 10x faster than ``std::ostringstream`` and ``sprintf`` on floating-point formatting (`dtoa-benchmark `_) and as fast as `double-conversion `_: .. image:: https://user-images.githubusercontent.com/576385/54883977-9fe8c000-4e28-11e9-8bde-272d122e7c52.jpg :target: https://fmt.dev/unknown_mac64_clang10.0.html Compile time and code bloat ~~~~~~~~~~~~~~~~~~~~~~~~~~~ The script `bloat-test.py `_ from `format-benchmark `_ tests compile time and code bloat for nontrivial projects. It generates 100 translation units and uses ``printf()`` or its alternative five times in each to simulate a medium sized project. The resulting executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), macOS Sierra, best of three) is shown in the following tables. **Optimized build (-O3)** ============= =============== ==================== ================== Method Compile Time, s Executable size, KiB Stripped size, KiB ============= =============== ==================== ================== printf 2.6 29 26 printf+string 16.4 29 26 iostreams 31.1 59 55 {fmt} 19.0 37 34 tinyformat 44.0 103 97 Boost Format 91.9 226 203 Folly Format 115.7 101 88 ============= =============== ==================== ================== As you can see, {fmt} has 60% less overhead in terms of resulting binary code size compared to iostreams and comes pretty close to ``printf``. Boost Format and Folly Format have the largest overheads. ``printf+string`` is the same as ``printf`` but with extra ```` include to measure the overhead of the latter. **Non-optimized build** ============= =============== ==================== ================== Method Compile Time, s Executable size, KiB Stripped size, KiB ============= =============== ==================== ================== printf 2.2 33 30 printf+string 16.0 33 30 iostreams 28.3 56 52 {fmt} 18.2 59 50 tinyformat 32.6 88 82 Boost Format 54.1 365 303 Folly Format 79.9 445 430 ============= =============== ==================== ================== ``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to compare formatting function overhead only. Boost Format and tinyformat are header-only libraries so they don't provide any linkage options. Running the tests ~~~~~~~~~~~~~~~~~ Please refer to `Building the library`__ for the instructions on how to build the library and run the unit tests. __ https://fmt.dev/latest/usage.html#building-the-library Benchmarks reside in a separate repository, `format-benchmarks `_, so to run the benchmarks you first need to clone this repository and generate Makefiles with CMake:: $ git clone --recursive https://github.com/fmtlib/format-benchmark.git $ cd format-benchmark $ cmake . Then you can run the speed test:: $ make speed-test or the bloat test:: $ make bloat-test Projects using this library --------------------------- * `0 A.D. `_: A free, open-source, cross-platform real-time strategy game * `AMPL/MP `_: An open-source library for mathematical programming * `AvioBook `_: A comprehensive aircraft operations suite * `Celestia `_: Real-time 3D visualization of space * `Ceph `_: A scalable distributed storage system * `CUAUV `_: Cornell University's autonomous underwater vehicle * `HarpyWar/pvpgn `_: Player vs Player Gaming Network with tweaks * `KBEngine `_: An open-source MMOG server engine * `Keypirinha `_: A semantic launcher for Windows * `Kodi `_ (formerly xbmc): Home theater software * `Lifeline `_: A 2D game * `Drake `_: A planning, control, and analysis toolbox for nonlinear dynamical systems (MIT) * `Envoy `_: C++ L7 proxy and communication bus (Lyft) * `FiveM `_: a modification framework for GTA V * `MongoDB `_: Distributed document database * `MongoDB Smasher `_: A small tool to generate randomized datasets * `OpenSpace `_: An open-source astrovisualization framework * `PenUltima Online (POL) `_: An MMO server, compatible with most Ultima Online clients * `quasardb `_: A distributed, high-performance, associative database * `readpe `_: Read Portable Executable * `redis-cerberus `_: A Redis cluster proxy * `rpclib `_: A modern C++ msgpack-RPC server and client library * `Saddy `_: Small crossplatform 2D graphic engine * `Salesforce Analytics Cloud `_: Business intelligence software * `Scylla `_: A Cassandra-compatible NoSQL data store that can handle 1 million transactions per second on a single server * `Seastar `_: An advanced, open-source C++ framework for high-performance server applications on modern hardware * `spdlog `_: Super fast C++ logging library * `Stellar `_: Financial platform * `Touch Surgery `_: Surgery simulator * `TrinityCore `_: Open-source MMORPG framework `More... `_ If you are aware of other projects using this library, please let me know by `email `_ or by submitting an `issue `_. Motivation ---------- So why yet another formatting library? There are plenty of methods for doing this task, from standard ones like the printf family of function and iostreams to Boost Format and FastFormat libraries. The reason for creating a new library is that every existing solution that I found either had serious issues or didn't provide all the features I needed. printf ~~~~~~ The good thing about ``printf`` is that it is pretty fast and readily available being a part of the C standard library. The main drawback is that it doesn't support user-defined types. ``printf`` also has safety issues although they are somewhat mitigated with `__attribute__ ((format (printf, ...)) `_ in GCC. There is a POSIX extension that adds positional arguments required for `i18n `_ to ``printf`` but it is not a part of C99 and may not be available on some platforms. iostreams ~~~~~~~~~ The main issue with iostreams is best illustrated with an example: .. code:: c++ std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n"; which is a lot of typing compared to printf: .. code:: c++ printf("%.2f\n", 1.23456); Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams don't support positional arguments by design. The good part is that iostreams support user-defined types and are safe although error handling is awkward. Boost Format ~~~~~~~~~~~~ This is a very powerful library which supports both ``printf``-like format strings and positional arguments. Its main drawback is performance. According to various benchmarks it is much slower than other methods considered here. Boost Format also has excessive build times and severe code bloat issues (see `Benchmarks`_). FastFormat ~~~~~~~~~~ This is an interesting library which is fast, safe and has positional arguments. However it has significant limitations, citing its author: Three features that have no hope of being accommodated within the current design are: * Leading zeros (or any other non-space padding) * Octal/hexadecimal encoding * Runtime width/alignment specification It is also quite big and has a heavy dependency, STLSoft, which might be too restrictive for using it in some projects. Loki SafeFormat ~~~~~~~~~~~~~~~ SafeFormat is a formatting library which uses ``printf``-like format strings and is type safe. It doesn't support user-defined types or positional arguments and makes unconventional use of ``operator()`` for passing format arguments. Tinyformat ~~~~~~~~~~ This library supports ``printf``-like format strings and is very small . It doesn't support positional arguments and wrapping it in C++98 is somewhat difficult. Tinyformat relies on iostreams which limits its performance. Boost Spirit.Karma ~~~~~~~~~~~~~~~~~~ This is not really a formatting library but I decided to include it here for completeness. As iostreams, it suffers from the problem of mixing verbatim text with arguments. The library is pretty fast, but slower on integer formatting than ``fmt::format_int`` on Karma's own benchmark, see `Fast integer to string conversion in C++ `_. FAQ --- Q: how can I capture formatting arguments and format them later? A: use ``std::tuple``: .. code:: c++ template auto capture(const Args&... args) { return std::make_tuple(args...); } auto print_message = [](const auto&... args) { fmt::print(args...); }; // Capture and store arguments: auto args = capture("{} {}", 42, "foo"); // Do formatting: std::apply(print_message, args); License ------- {fmt} is distributed under the BSD `license `_. The `Format String Syntax `_ section in the documentation is based on the one from Python `string module documentation `_ adapted for the current library. For this reason the documentation is distributed under the Python Software Foundation license available in `doc/python-license.txt `_. It only applies if you distribute the documentation of fmt. Acknowledgments --------------- The {fmt} library is maintained by Victor Zverovich (`vitaut `_) and Jonathan Müller (`foonathan `_) with contributions from many other people. See `Contributors `_ and `Releases `_ for some of the names. Let us know if your contribution is not listed or mentioned incorrectly and we'll make it right. The benchmark section of this readme file and the performance tests are taken from the excellent `tinyformat `_ library written by Chris Foster. Boost Format library is acknowledged transitively since it had some influence on tinyformat. Some ideas used in the implementation are borrowed from `Loki `_ SafeFormat and `Diagnostic API `_ in `Clang `_. Format string syntax and the documentation are based on Python's `str.format `_. Thanks `Doug Turnbull `_ for his valuable comments and contribution to the design of the type-safe API and `Gregory Czajkowski `_ for implementing binary formatting. Thanks `Ruslan Baratov `_ for comprehensive `comparison of integer formatting algorithms `_ and useful comments regarding performance, `Boris Kaul `_ for `C++ counting digits benchmark `_. Thanks to `CarterLi `_ for contributing various improvements to the code. ================================================ FILE: src/third_party/fmt/include/fmt/chrono.h ================================================ // Formatting library for C++ - chrono support // // Copyright (c) 2012 - present, Victor Zverovich // All rights reserved. // // For the license information refer to format.h. #ifndef FMT_CHRONO_H_ #define FMT_CHRONO_H_ #include "format.h" #include "locale.h" #include #include #include #include // enable safe chrono durations, unless explicitly disabled #ifndef FMT_SAFE_DURATION_CAST # define FMT_SAFE_DURATION_CAST 1 #endif #if FMT_SAFE_DURATION_CAST # include "safe-duration-cast.h" #endif FMT_BEGIN_NAMESPACE // Prevents expansion of a preceding token as a function-style macro. // Usage: f FMT_NOMACRO() #define FMT_NOMACRO namespace internal { inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); } inline null<> localtime_s(...) { return null<>(); } inline null<> gmtime_r(...) { return null<>(); } inline null<> gmtime_s(...) { return null<>(); } } // namespace internal // Thread-safe replacement for std::localtime inline std::tm localtime(std::time_t time) { struct dispatcher { std::time_t time_; std::tm tm_; dispatcher(std::time_t t) : time_(t) {} bool run() { using namespace fmt::internal; return handle(localtime_r(&time_, &tm_)); } bool handle(std::tm* tm) { return tm != nullptr; } bool handle(internal::null<>) { using namespace fmt::internal; return fallback(localtime_s(&tm_, &time_)); } bool fallback(int res) { return res == 0; } #if !FMT_MSC_VER bool fallback(internal::null<>) { using namespace fmt::internal; std::tm* tm = std::localtime(&time_); if (tm) tm_ = *tm; return tm != nullptr; } #endif }; dispatcher lt(time); // Too big time values may be unsupported. if (!lt.run()) FMT_THROW(format_error("time_t value out of range")); return lt.tm_; } // Thread-safe replacement for std::gmtime inline std::tm gmtime(std::time_t time) { struct dispatcher { std::time_t time_; std::tm tm_; dispatcher(std::time_t t) : time_(t) {} bool run() { using namespace fmt::internal; return handle(gmtime_r(&time_, &tm_)); } bool handle(std::tm* tm) { return tm != nullptr; } bool handle(internal::null<>) { using namespace fmt::internal; return fallback(gmtime_s(&tm_, &time_)); } bool fallback(int res) { return res == 0; } #if !FMT_MSC_VER bool fallback(internal::null<>) { std::tm* tm = std::gmtime(&time_); if (tm) tm_ = *tm; return tm != nullptr; } #endif }; dispatcher gt(time); // Too big time values may be unsupported. if (!gt.run()) FMT_THROW(format_error("time_t value out of range")); return gt.tm_; } namespace internal { inline std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time) { return std::strftime(str, count, format, time); } inline std::size_t strftime(wchar_t* str, std::size_t count, const wchar_t* format, const std::tm* time) { return std::wcsftime(str, count, format, time); } } // namespace internal template struct formatter { template auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { auto it = ctx.begin(); if (it != ctx.end() && *it == ':') ++it; auto end = it; while (end != ctx.end() && *end != '}') ++end; tm_format.reserve(internal::to_unsigned(end - it + 1)); tm_format.append(it, end); tm_format.push_back('\0'); return end; } template auto format(const std::tm& tm, FormatContext& ctx) -> decltype(ctx.out()) { basic_memory_buffer buf; std::size_t start = buf.size(); for (;;) { std::size_t size = buf.capacity() - start; std::size_t count = internal::strftime(&buf[start], size, &tm_format[0], &tm); if (count != 0) { buf.resize(start + count); break; } if (size >= tm_format.size() * 256) { // If the buffer is 256 times larger than the format string, assume // that `strftime` gives an empty result. There doesn't seem to be a // better way to distinguish the two cases: // https://github.com/fmtlib/fmt/issues/367 break; } const std::size_t MIN_GROWTH = 10; buf.reserve(buf.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH)); } return std::copy(buf.begin(), buf.end(), ctx.out()); } basic_memory_buffer tm_format; }; namespace internal { template FMT_CONSTEXPR const char* get_units() { return nullptr; } template <> FMT_CONSTEXPR const char* get_units() { return "as"; } template <> FMT_CONSTEXPR const char* get_units() { return "fs"; } template <> FMT_CONSTEXPR const char* get_units() { return "ps"; } template <> FMT_CONSTEXPR const char* get_units() { return "ns"; } template <> FMT_CONSTEXPR const char* get_units() { return "µs"; } template <> FMT_CONSTEXPR const char* get_units() { return "ms"; } template <> FMT_CONSTEXPR const char* get_units() { return "cs"; } template <> FMT_CONSTEXPR const char* get_units() { return "ds"; } template <> FMT_CONSTEXPR const char* get_units>() { return "s"; } template <> FMT_CONSTEXPR const char* get_units() { return "das"; } template <> FMT_CONSTEXPR const char* get_units() { return "hs"; } template <> FMT_CONSTEXPR const char* get_units() { return "ks"; } template <> FMT_CONSTEXPR const char* get_units() { return "Ms"; } template <> FMT_CONSTEXPR const char* get_units() { return "Gs"; } template <> FMT_CONSTEXPR const char* get_units() { return "Ts"; } template <> FMT_CONSTEXPR const char* get_units() { return "Ps"; } template <> FMT_CONSTEXPR const char* get_units() { return "Es"; } template <> FMT_CONSTEXPR const char* get_units>() { return "m"; } template <> FMT_CONSTEXPR const char* get_units>() { return "h"; } enum class numeric_system { standard, // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale. alternative }; // Parses a put_time-like format string and invokes handler actions. template FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, const Char* end, Handler&& handler) { auto ptr = begin; while (ptr != end) { auto c = *ptr; if (c == '}') break; if (c != '%') { ++ptr; continue; } if (begin != ptr) handler.on_text(begin, ptr); ++ptr; // consume '%' if (ptr == end) FMT_THROW(format_error("invalid format")); c = *ptr++; switch (c) { case '%': handler.on_text(ptr - 1, ptr); break; case 'n': { const char newline[] = "\n"; handler.on_text(newline, newline + 1); break; } case 't': { const char tab[] = "\t"; handler.on_text(tab, tab + 1); break; } // Day of the week: case 'a': handler.on_abbr_weekday(); break; case 'A': handler.on_full_weekday(); break; case 'w': handler.on_dec0_weekday(numeric_system::standard); break; case 'u': handler.on_dec1_weekday(numeric_system::standard); break; // Month: case 'b': handler.on_abbr_month(); break; case 'B': handler.on_full_month(); break; // Hour, minute, second: case 'H': handler.on_24_hour(numeric_system::standard); break; case 'I': handler.on_12_hour(numeric_system::standard); break; case 'M': handler.on_minute(numeric_system::standard); break; case 'S': handler.on_second(numeric_system::standard); break; // Other: case 'c': handler.on_datetime(numeric_system::standard); break; case 'x': handler.on_loc_date(numeric_system::standard); break; case 'X': handler.on_loc_time(numeric_system::standard); break; case 'D': handler.on_us_date(); break; case 'F': handler.on_iso_date(); break; case 'r': handler.on_12_hour_time(); break; case 'R': handler.on_24_hour_time(); break; case 'T': handler.on_iso_time(); break; case 'p': handler.on_am_pm(); break; case 'Q': handler.on_duration_value(); break; case 'q': handler.on_duration_unit(); break; case 'z': handler.on_utc_offset(); break; case 'Z': handler.on_tz_name(); break; // Alternative representation: case 'E': { if (ptr == end) FMT_THROW(format_error("invalid format")); c = *ptr++; switch (c) { case 'c': handler.on_datetime(numeric_system::alternative); break; case 'x': handler.on_loc_date(numeric_system::alternative); break; case 'X': handler.on_loc_time(numeric_system::alternative); break; default: FMT_THROW(format_error("invalid format")); } break; } case 'O': if (ptr == end) FMT_THROW(format_error("invalid format")); c = *ptr++; switch (c) { case 'w': handler.on_dec0_weekday(numeric_system::alternative); break; case 'u': handler.on_dec1_weekday(numeric_system::alternative); break; case 'H': handler.on_24_hour(numeric_system::alternative); break; case 'I': handler.on_12_hour(numeric_system::alternative); break; case 'M': handler.on_minute(numeric_system::alternative); break; case 'S': handler.on_second(numeric_system::alternative); break; default: FMT_THROW(format_error("invalid format")); } break; default: FMT_THROW(format_error("invalid format")); } begin = ptr; } if (begin != ptr) handler.on_text(begin, ptr); return ptr; } struct chrono_format_checker { FMT_NORETURN void report_no_date() { FMT_THROW(format_error("no date")); } template void on_text(const Char*, const Char*) {} FMT_NORETURN void on_abbr_weekday() { report_no_date(); } FMT_NORETURN void on_full_weekday() { report_no_date(); } FMT_NORETURN void on_dec0_weekday(numeric_system) { report_no_date(); } FMT_NORETURN void on_dec1_weekday(numeric_system) { report_no_date(); } FMT_NORETURN void on_abbr_month() { report_no_date(); } FMT_NORETURN void on_full_month() { report_no_date(); } void on_24_hour(numeric_system) {} void on_12_hour(numeric_system) {} void on_minute(numeric_system) {} void on_second(numeric_system) {} FMT_NORETURN void on_datetime(numeric_system) { report_no_date(); } FMT_NORETURN void on_loc_date(numeric_system) { report_no_date(); } FMT_NORETURN void on_loc_time(numeric_system) { report_no_date(); } FMT_NORETURN void on_us_date() { report_no_date(); } FMT_NORETURN void on_iso_date() { report_no_date(); } void on_12_hour_time() {} void on_24_hour_time() {} void on_iso_time() {} void on_am_pm() {} void on_duration_value() {} void on_duration_unit() {} FMT_NORETURN void on_utc_offset() { report_no_date(); } FMT_NORETURN void on_tz_name() { report_no_date(); } }; template ::value)> inline bool isnan(T) { return false; } template ::value)> inline bool isnan(T value) { return std::isnan(value); } template ::value)> inline bool isfinite(T) { return true; } template ::value)> inline bool isfinite(T value) { return std::isfinite(value); } // Convers value to int and checks that it's in the range [0, upper). template ::value)> inline int to_nonnegative_int(T value, int upper) { FMT_ASSERT(value >= 0 && value <= upper, "invalid value"); (void)upper; return static_cast(value); } template ::value)> inline int to_nonnegative_int(T value, int upper) { FMT_ASSERT( std::isnan(value) || (value >= 0 && value <= static_cast(upper)), "invalid value"); (void)upper; return static_cast(value); } template ::value)> inline T mod(T x, int y) { return x % y; } template ::value)> inline T mod(T x, int y) { return std::fmod(x, static_cast(y)); } // If T is an integral type, maps T to its unsigned counterpart, otherwise // leaves it unchanged (unlike std::make_unsigned). template ::value> struct make_unsigned_or_unchanged { using type = T; }; template struct make_unsigned_or_unchanged { using type = typename std::make_unsigned::type; }; #if FMT_SAFE_DURATION_CAST // throwing version of safe_duration_cast template To fmt_safe_duration_cast(std::chrono::duration from) { int ec; To to = safe_duration_cast::safe_duration_cast(from, ec); if (ec) FMT_THROW(format_error("cannot format duration")); return to; } #endif template ::value)> inline std::chrono::duration get_milliseconds( std::chrono::duration d) { // this may overflow and/or the result may not fit in the // target type. #if FMT_SAFE_DURATION_CAST using CommonSecondsType = typename std::common_type::type; const auto d_as_common = fmt_safe_duration_cast(d); const auto d_as_whole_seconds = fmt_safe_duration_cast(d_as_common); // this conversion should be nonproblematic const auto diff = d_as_common - d_as_whole_seconds; const auto ms = fmt_safe_duration_cast>(diff); return ms; #else auto s = std::chrono::duration_cast(d); return std::chrono::duration_cast(d - s); #endif } template ::value)> inline std::chrono::duration get_milliseconds( std::chrono::duration d) { using common_type = typename std::common_type::type; auto ms = mod(d.count() * static_cast(Period::num) / static_cast(Period::den) * 1000, 1000); return std::chrono::duration(static_cast(ms)); } template OutputIt format_chrono_duration_value(OutputIt out, Rep val, int precision) { if (precision >= 0) return format_to(out, "{:.{}f}", val, precision); return format_to(out, std::is_floating_point::value ? "{:g}" : "{}", val); } template static OutputIt format_chrono_duration_unit(OutputIt out) { if (const char* unit = get_units()) return format_to(out, "{}", unit); if (Period::den == 1) return format_to(out, "[{}]s", Period::num); return format_to(out, "[{}/{}]s", Period::num, Period::den); } template struct chrono_formatter { FormatContext& context; OutputIt out; int precision; // rep is unsigned to avoid overflow. using rep = conditional_t::value && sizeof(Rep) < sizeof(int), unsigned, typename make_unsigned_or_unchanged::type>; rep val; using seconds = std::chrono::duration; seconds s; using milliseconds = std::chrono::duration; bool negative; using char_type = typename FormatContext::char_type; explicit chrono_formatter(FormatContext& ctx, OutputIt o, std::chrono::duration d) : context(ctx), out(o), val(d.count()), negative(false) { if (d.count() < 0) { val = -val; negative = true; } // this may overflow and/or the result may not fit in the // target type. #if FMT_SAFE_DURATION_CAST // might need checked conversion (rep!=Rep) auto tmpval = std::chrono::duration(val); s = fmt_safe_duration_cast(tmpval); #else s = std::chrono::duration_cast( std::chrono::duration(val)); #endif } // returns true if nan or inf, writes to out. bool handle_nan_inf() { if (isfinite(val)) { return false; } if (isnan(val)) { write_nan(); return true; } // must be +-inf if (val > 0) { write_pinf(); } else { write_ninf(); } return true; } Rep hour() const { return static_cast(mod((s.count() / 3600), 24)); } Rep hour12() const { Rep hour = static_cast(mod((s.count() / 3600), 12)); return hour <= 0 ? 12 : hour; } Rep minute() const { return static_cast(mod((s.count() / 60), 60)); } Rep second() const { return static_cast(mod(s.count(), 60)); } std::tm time() const { auto time = std::tm(); time.tm_hour = to_nonnegative_int(hour(), 24); time.tm_min = to_nonnegative_int(minute(), 60); time.tm_sec = to_nonnegative_int(second(), 60); return time; } void write_sign() { if (negative) { *out++ = '-'; negative = false; } } void write(Rep value, int width) { write_sign(); if (isnan(value)) return write_nan(); uint32_or_64_t n = to_unsigned( to_nonnegative_int(value, (std::numeric_limits::max)())); int num_digits = internal::count_digits(n); if (width > num_digits) out = std::fill_n(out, width - num_digits, '0'); out = format_decimal(out, n, num_digits); } void write_nan() { std::copy_n("nan", 3, out); } void write_pinf() { std::copy_n("inf", 3, out); } void write_ninf() { std::copy_n("-inf", 4, out); } void format_localized(const tm& time, const char* format) { if (isnan(val)) return write_nan(); auto locale = context.locale().template get(); auto& facet = std::use_facet>(locale); std::basic_ostringstream os; os.imbue(locale); facet.put(os, os, ' ', &time, format, format + std::strlen(format)); auto str = os.str(); std::copy(str.begin(), str.end(), out); } void on_text(const char_type* begin, const char_type* end) { std::copy(begin, end, out); } // These are not implemented because durations don't have date information. void on_abbr_weekday() {} void on_full_weekday() {} void on_dec0_weekday(numeric_system) {} void on_dec1_weekday(numeric_system) {} void on_abbr_month() {} void on_full_month() {} void on_datetime(numeric_system) {} void on_loc_date(numeric_system) {} void on_loc_time(numeric_system) {} void on_us_date() {} void on_iso_date() {} void on_utc_offset() {} void on_tz_name() {} void on_24_hour(numeric_system ns) { if (handle_nan_inf()) return; if (ns == numeric_system::standard) return write(hour(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour(), 24); format_localized(time, "%OH"); } void on_12_hour(numeric_system ns) { if (handle_nan_inf()) return; if (ns == numeric_system::standard) return write(hour12(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour12(), 12); format_localized(time, "%OI"); } void on_minute(numeric_system ns) { if (handle_nan_inf()) return; if (ns == numeric_system::standard) return write(minute(), 2); auto time = tm(); time.tm_min = to_nonnegative_int(minute(), 60); format_localized(time, "%OM"); } void on_second(numeric_system ns) { if (handle_nan_inf()) return; if (ns == numeric_system::standard) { write(second(), 2); #if FMT_SAFE_DURATION_CAST // convert rep->Rep using duration_rep = std::chrono::duration; using duration_Rep = std::chrono::duration; auto tmpval = fmt_safe_duration_cast(duration_rep{val}); #else auto tmpval = std::chrono::duration(val); #endif auto ms = get_milliseconds(tmpval); if (ms != std::chrono::milliseconds(0)) { *out++ = '.'; write(ms.count(), 3); } return; } auto time = tm(); time.tm_sec = to_nonnegative_int(second(), 60); format_localized(time, "%OS"); } void on_12_hour_time() { if (handle_nan_inf()) return; format_localized(time(), "%r"); } void on_24_hour_time() { if (handle_nan_inf()) { *out++ = ':'; handle_nan_inf(); return; } write(hour(), 2); *out++ = ':'; write(minute(), 2); } void on_iso_time() { on_24_hour_time(); *out++ = ':'; if (handle_nan_inf()) return; write(second(), 2); } void on_am_pm() { if (handle_nan_inf()) return; format_localized(time(), "%p"); } void on_duration_value() { if (handle_nan_inf()) return; write_sign(); out = format_chrono_duration_value(out, val, precision); } void on_duration_unit() { out = format_chrono_duration_unit(out); } }; } // namespace internal template struct formatter, Char> { private: basic_format_specs specs; int precision; using arg_ref_type = internal::arg_ref; arg_ref_type width_ref; arg_ref_type precision_ref; mutable basic_string_view format_str; using duration = std::chrono::duration; struct spec_handler { formatter& f; basic_parse_context& context; basic_string_view format_str; template FMT_CONSTEXPR arg_ref_type make_arg_ref(Id arg_id) { context.check_arg_id(arg_id); return arg_ref_type(arg_id); } FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view arg_id) { context.check_arg_id(arg_id); const auto str_val = internal::string_view_metadata(format_str, arg_id); return arg_ref_type(str_val); } FMT_CONSTEXPR arg_ref_type make_arg_ref(internal::auto_id) { return arg_ref_type(context.next_arg_id()); } void on_error(const char* msg) { FMT_THROW(format_error(msg)); } void on_fill(Char fill) { f.specs.fill[0] = fill; } void on_align(align_t align) { f.specs.align = align; } void on_width(unsigned width) { f.specs.width = width; } void on_precision(unsigned precision) { f.precision = precision; } void end_precision() {} template void on_dynamic_width(Id arg_id) { f.width_ref = make_arg_ref(arg_id); } template void on_dynamic_precision(Id arg_id) { f.precision_ref = make_arg_ref(arg_id); } }; using iterator = typename basic_parse_context::iterator; struct parse_range { iterator begin; iterator end; }; FMT_CONSTEXPR parse_range do_parse(basic_parse_context& ctx) { auto begin = ctx.begin(), end = ctx.end(); if (begin == end || *begin == '}') return {begin, begin}; spec_handler handler{*this, ctx, format_str}; begin = internal::parse_align(begin, end, handler); if (begin == end) return {begin, begin}; begin = internal::parse_width(begin, end, handler); if (begin == end) return {begin, begin}; if (*begin == '.') { if (std::is_floating_point::value) begin = internal::parse_precision(begin, end, handler); else handler.on_error("precision not allowed for this argument type"); } end = parse_chrono_format(begin, end, internal::chrono_format_checker()); return {begin, end}; } public: formatter() : precision(-1) {} FMT_CONSTEXPR auto parse(basic_parse_context& ctx) -> decltype(ctx.begin()) { auto range = do_parse(ctx); format_str = basic_string_view( &*range.begin, internal::to_unsigned(range.end - range.begin)); return range.end; } template auto format(const duration& d, FormatContext& ctx) -> decltype(ctx.out()) { auto begin = format_str.begin(), end = format_str.end(); // As a possible future optimization, we could avoid extra copying if width // is not specified. basic_memory_buffer buf; auto out = std::back_inserter(buf); using range = internal::output_range; internal::basic_writer w(range(ctx.out())); internal::handle_dynamic_spec( specs.width, width_ref, ctx, format_str.begin()); internal::handle_dynamic_spec( precision, precision_ref, ctx, format_str.begin()); if (begin == end || *begin == '}') { out = internal::format_chrono_duration_value(out, d.count(), precision); internal::format_chrono_duration_unit(out); } else { internal::chrono_formatter f( ctx, out, d); f.precision = precision; parse_chrono_format(begin, end, f); } w.write(buf.data(), buf.size(), specs); return w.out(); } }; FMT_END_NAMESPACE #endif // FMT_CHRONO_H_ ================================================ FILE: src/third_party/fmt/include/fmt/color.h ================================================ // Formatting library for C++ - color support // // Copyright (c) 2018 - present, Victor Zverovich and fmt contributors // All rights reserved. // // For the license information refer to format.h. #ifndef FMT_COLOR_H_ #define FMT_COLOR_H_ #include "format.h" FMT_BEGIN_NAMESPACE enum class color : uint32_t { alice_blue = 0xF0F8FF, // rgb(240,248,255) antique_white = 0xFAEBD7, // rgb(250,235,215) aqua = 0x00FFFF, // rgb(0,255,255) aquamarine = 0x7FFFD4, // rgb(127,255,212) azure = 0xF0FFFF, // rgb(240,255,255) beige = 0xF5F5DC, // rgb(245,245,220) bisque = 0xFFE4C4, // rgb(255,228,196) black = 0x000000, // rgb(0,0,0) blanched_almond = 0xFFEBCD, // rgb(255,235,205) blue = 0x0000FF, // rgb(0,0,255) blue_violet = 0x8A2BE2, // rgb(138,43,226) brown = 0xA52A2A, // rgb(165,42,42) burly_wood = 0xDEB887, // rgb(222,184,135) cadet_blue = 0x5F9EA0, // rgb(95,158,160) chartreuse = 0x7FFF00, // rgb(127,255,0) chocolate = 0xD2691E, // rgb(210,105,30) coral = 0xFF7F50, // rgb(255,127,80) cornflower_blue = 0x6495ED, // rgb(100,149,237) cornsilk = 0xFFF8DC, // rgb(255,248,220) crimson = 0xDC143C, // rgb(220,20,60) cyan = 0x00FFFF, // rgb(0,255,255) dark_blue = 0x00008B, // rgb(0,0,139) dark_cyan = 0x008B8B, // rgb(0,139,139) dark_golden_rod = 0xB8860B, // rgb(184,134,11) dark_gray = 0xA9A9A9, // rgb(169,169,169) dark_green = 0x006400, // rgb(0,100,0) dark_khaki = 0xBDB76B, // rgb(189,183,107) dark_magenta = 0x8B008B, // rgb(139,0,139) dark_olive_green = 0x556B2F, // rgb(85,107,47) dark_orange = 0xFF8C00, // rgb(255,140,0) dark_orchid = 0x9932CC, // rgb(153,50,204) dark_red = 0x8B0000, // rgb(139,0,0) dark_salmon = 0xE9967A, // rgb(233,150,122) dark_sea_green = 0x8FBC8F, // rgb(143,188,143) dark_slate_blue = 0x483D8B, // rgb(72,61,139) dark_slate_gray = 0x2F4F4F, // rgb(47,79,79) dark_turquoise = 0x00CED1, // rgb(0,206,209) dark_violet = 0x9400D3, // rgb(148,0,211) deep_pink = 0xFF1493, // rgb(255,20,147) deep_sky_blue = 0x00BFFF, // rgb(0,191,255) dim_gray = 0x696969, // rgb(105,105,105) dodger_blue = 0x1E90FF, // rgb(30,144,255) fire_brick = 0xB22222, // rgb(178,34,34) floral_white = 0xFFFAF0, // rgb(255,250,240) forest_green = 0x228B22, // rgb(34,139,34) fuchsia = 0xFF00FF, // rgb(255,0,255) gainsboro = 0xDCDCDC, // rgb(220,220,220) ghost_white = 0xF8F8FF, // rgb(248,248,255) gold = 0xFFD700, // rgb(255,215,0) golden_rod = 0xDAA520, // rgb(218,165,32) gray = 0x808080, // rgb(128,128,128) green = 0x008000, // rgb(0,128,0) green_yellow = 0xADFF2F, // rgb(173,255,47) honey_dew = 0xF0FFF0, // rgb(240,255,240) hot_pink = 0xFF69B4, // rgb(255,105,180) indian_red = 0xCD5C5C, // rgb(205,92,92) indigo = 0x4B0082, // rgb(75,0,130) ivory = 0xFFFFF0, // rgb(255,255,240) khaki = 0xF0E68C, // rgb(240,230,140) lavender = 0xE6E6FA, // rgb(230,230,250) lavender_blush = 0xFFF0F5, // rgb(255,240,245) lawn_green = 0x7CFC00, // rgb(124,252,0) lemon_chiffon = 0xFFFACD, // rgb(255,250,205) light_blue = 0xADD8E6, // rgb(173,216,230) light_coral = 0xF08080, // rgb(240,128,128) light_cyan = 0xE0FFFF, // rgb(224,255,255) light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210) light_gray = 0xD3D3D3, // rgb(211,211,211) light_green = 0x90EE90, // rgb(144,238,144) light_pink = 0xFFB6C1, // rgb(255,182,193) light_salmon = 0xFFA07A, // rgb(255,160,122) light_sea_green = 0x20B2AA, // rgb(32,178,170) light_sky_blue = 0x87CEFA, // rgb(135,206,250) light_slate_gray = 0x778899, // rgb(119,136,153) light_steel_blue = 0xB0C4DE, // rgb(176,196,222) light_yellow = 0xFFFFE0, // rgb(255,255,224) lime = 0x00FF00, // rgb(0,255,0) lime_green = 0x32CD32, // rgb(50,205,50) linen = 0xFAF0E6, // rgb(250,240,230) magenta = 0xFF00FF, // rgb(255,0,255) maroon = 0x800000, // rgb(128,0,0) medium_aquamarine = 0x66CDAA, // rgb(102,205,170) medium_blue = 0x0000CD, // rgb(0,0,205) medium_orchid = 0xBA55D3, // rgb(186,85,211) medium_purple = 0x9370DB, // rgb(147,112,219) medium_sea_green = 0x3CB371, // rgb(60,179,113) medium_slate_blue = 0x7B68EE, // rgb(123,104,238) medium_spring_green = 0x00FA9A, // rgb(0,250,154) medium_turquoise = 0x48D1CC, // rgb(72,209,204) medium_violet_red = 0xC71585, // rgb(199,21,133) midnight_blue = 0x191970, // rgb(25,25,112) mint_cream = 0xF5FFFA, // rgb(245,255,250) misty_rose = 0xFFE4E1, // rgb(255,228,225) moccasin = 0xFFE4B5, // rgb(255,228,181) navajo_white = 0xFFDEAD, // rgb(255,222,173) navy = 0x000080, // rgb(0,0,128) old_lace = 0xFDF5E6, // rgb(253,245,230) olive = 0x808000, // rgb(128,128,0) olive_drab = 0x6B8E23, // rgb(107,142,35) orange = 0xFFA500, // rgb(255,165,0) orange_red = 0xFF4500, // rgb(255,69,0) orchid = 0xDA70D6, // rgb(218,112,214) pale_golden_rod = 0xEEE8AA, // rgb(238,232,170) pale_green = 0x98FB98, // rgb(152,251,152) pale_turquoise = 0xAFEEEE, // rgb(175,238,238) pale_violet_red = 0xDB7093, // rgb(219,112,147) papaya_whip = 0xFFEFD5, // rgb(255,239,213) peach_puff = 0xFFDAB9, // rgb(255,218,185) peru = 0xCD853F, // rgb(205,133,63) pink = 0xFFC0CB, // rgb(255,192,203) plum = 0xDDA0DD, // rgb(221,160,221) powder_blue = 0xB0E0E6, // rgb(176,224,230) purple = 0x800080, // rgb(128,0,128) rebecca_purple = 0x663399, // rgb(102,51,153) red = 0xFF0000, // rgb(255,0,0) rosy_brown = 0xBC8F8F, // rgb(188,143,143) royal_blue = 0x4169E1, // rgb(65,105,225) saddle_brown = 0x8B4513, // rgb(139,69,19) salmon = 0xFA8072, // rgb(250,128,114) sandy_brown = 0xF4A460, // rgb(244,164,96) sea_green = 0x2E8B57, // rgb(46,139,87) sea_shell = 0xFFF5EE, // rgb(255,245,238) sienna = 0xA0522D, // rgb(160,82,45) silver = 0xC0C0C0, // rgb(192,192,192) sky_blue = 0x87CEEB, // rgb(135,206,235) slate_blue = 0x6A5ACD, // rgb(106,90,205) slate_gray = 0x708090, // rgb(112,128,144) snow = 0xFFFAFA, // rgb(255,250,250) spring_green = 0x00FF7F, // rgb(0,255,127) steel_blue = 0x4682B4, // rgb(70,130,180) tan = 0xD2B48C, // rgb(210,180,140) teal = 0x008080, // rgb(0,128,128) thistle = 0xD8BFD8, // rgb(216,191,216) tomato = 0xFF6347, // rgb(255,99,71) turquoise = 0x40E0D0, // rgb(64,224,208) violet = 0xEE82EE, // rgb(238,130,238) wheat = 0xF5DEB3, // rgb(245,222,179) white = 0xFFFFFF, // rgb(255,255,255) white_smoke = 0xF5F5F5, // rgb(245,245,245) yellow = 0xFFFF00, // rgb(255,255,0) yellow_green = 0x9ACD32 // rgb(154,205,50) }; // enum class color enum class terminal_color : uint8_t { black = 30, red, green, yellow, blue, magenta, cyan, white, bright_black = 90, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white }; enum class emphasis : uint8_t { bold = 1, italic = 1 << 1, underline = 1 << 2, strikethrough = 1 << 3 }; // rgb is a struct for red, green and blue colors. // Using the name "rgb" makes some editors show the color in a tooltip. struct rgb { FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {} FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {} FMT_CONSTEXPR rgb(uint32_t hex) : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {} FMT_CONSTEXPR rgb(color hex) : r((uint32_t(hex) >> 16) & 0xFF), g((uint32_t(hex) >> 8) & 0xFF), b(uint32_t(hex) & 0xFF) {} uint8_t r; uint8_t g; uint8_t b; }; namespace internal { // color is a struct of either a rgb color or a terminal color. struct color_type { FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {} FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} { value.rgb_color = static_cast(rgb_color); } FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} { value.rgb_color = (static_cast(rgb_color.r) << 16) | (static_cast(rgb_color.g) << 8) | rgb_color.b; } FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(), value{} { value.term_color = static_cast(term_color); } bool is_rgb; union color_union { uint8_t term_color; uint32_t rgb_color; } value; }; } // namespace internal // Experimental text formatting support. class text_style { public: FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT : set_foreground_color(), set_background_color(), ems(em) {} FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) { if (!set_foreground_color) { set_foreground_color = rhs.set_foreground_color; foreground_color = rhs.foreground_color; } else if (rhs.set_foreground_color) { if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb) FMT_THROW(format_error("can't OR a terminal color")); foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color; } if (!set_background_color) { set_background_color = rhs.set_background_color; background_color = rhs.background_color; } else if (rhs.set_background_color) { if (!background_color.is_rgb || !rhs.background_color.is_rgb) FMT_THROW(format_error("can't OR a terminal color")); background_color.value.rgb_color |= rhs.background_color.value.rgb_color; } ems = static_cast(static_cast(ems) | static_cast(rhs.ems)); return *this; } friend FMT_CONSTEXPR text_style operator|(text_style lhs, const text_style& rhs) { return lhs |= rhs; } FMT_CONSTEXPR text_style& operator&=(const text_style& rhs) { if (!set_foreground_color) { set_foreground_color = rhs.set_foreground_color; foreground_color = rhs.foreground_color; } else if (rhs.set_foreground_color) { if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb) FMT_THROW(format_error("can't AND a terminal color")); foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color; } if (!set_background_color) { set_background_color = rhs.set_background_color; background_color = rhs.background_color; } else if (rhs.set_background_color) { if (!background_color.is_rgb || !rhs.background_color.is_rgb) FMT_THROW(format_error("can't AND a terminal color")); background_color.value.rgb_color &= rhs.background_color.value.rgb_color; } ems = static_cast(static_cast(ems) & static_cast(rhs.ems)); return *this; } friend FMT_CONSTEXPR text_style operator&(text_style lhs, const text_style& rhs) { return lhs &= rhs; } FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT { return set_foreground_color; } FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT { return set_background_color; } FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT { return static_cast(ems) != 0; } FMT_CONSTEXPR internal::color_type get_foreground() const FMT_NOEXCEPT { assert(has_foreground() && "no foreground specified for this style"); return foreground_color; } FMT_CONSTEXPR internal::color_type get_background() const FMT_NOEXCEPT { assert(has_background() && "no background specified for this style"); return background_color; } FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT { assert(has_emphasis() && "no emphasis specified for this style"); return ems; } private: FMT_CONSTEXPR text_style(bool is_foreground, internal::color_type text_color) FMT_NOEXCEPT : set_foreground_color(), set_background_color(), ems() { if (is_foreground) { foreground_color = text_color; set_foreground_color = true; } else { background_color = text_color; set_background_color = true; } } friend FMT_CONSTEXPR_DECL text_style fg(internal::color_type foreground) FMT_NOEXCEPT; friend FMT_CONSTEXPR_DECL text_style bg(internal::color_type background) FMT_NOEXCEPT; internal::color_type foreground_color; internal::color_type background_color; bool set_foreground_color; bool set_background_color; emphasis ems; }; FMT_CONSTEXPR text_style fg(internal::color_type foreground) FMT_NOEXCEPT { return text_style(/*is_foreground=*/true, foreground); } FMT_CONSTEXPR text_style bg(internal::color_type background) FMT_NOEXCEPT { return text_style(/*is_foreground=*/false, background); } FMT_CONSTEXPR text_style operator|(emphasis lhs, emphasis rhs) FMT_NOEXCEPT { return text_style(lhs) | rhs; } namespace internal { template struct ansi_color_escape { FMT_CONSTEXPR ansi_color_escape(internal::color_type text_color, const char* esc) FMT_NOEXCEPT { // If we have a terminal color, we need to output another escape code // sequence. if (!text_color.is_rgb) { bool is_background = esc == internal::data::background_color; uint32_t value = text_color.value.term_color; // Background ASCII codes are the same as the foreground ones but with // 10 more. if (is_background) value += 10u; std::size_t index = 0; buffer[index++] = static_cast('\x1b'); buffer[index++] = static_cast('['); if (value >= 100u) { buffer[index++] = static_cast('1'); value %= 100u; } buffer[index++] = static_cast('0' + value / 10u); buffer[index++] = static_cast('0' + value % 10u); buffer[index++] = static_cast('m'); buffer[index++] = static_cast('\0'); return; } for (int i = 0; i < 7; i++) { buffer[i] = static_cast(esc[i]); } rgb color(text_color.value.rgb_color); to_esc(color.r, buffer + 7, ';'); to_esc(color.g, buffer + 11, ';'); to_esc(color.b, buffer + 15, 'm'); buffer[19] = static_cast(0); } FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT { uint8_t em_codes[4] = {}; uint8_t em_bits = static_cast(em); if (em_bits & static_cast(emphasis::bold)) em_codes[0] = 1; if (em_bits & static_cast(emphasis::italic)) em_codes[1] = 3; if (em_bits & static_cast(emphasis::underline)) em_codes[2] = 4; if (em_bits & static_cast(emphasis::strikethrough)) em_codes[3] = 9; std::size_t index = 0; for (int i = 0; i < 4; ++i) { if (!em_codes[i]) continue; buffer[index++] = static_cast('\x1b'); buffer[index++] = static_cast('['); buffer[index++] = static_cast('0' + em_codes[i]); buffer[index++] = static_cast('m'); } buffer[index++] = static_cast(0); } FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; } FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; } FMT_CONSTEXPR const Char* end() const FMT_NOEXCEPT { return buffer + std::strlen(buffer); } private: Char buffer[7u + 3u * 4u + 1u]; static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out, char delimiter) FMT_NOEXCEPT { out[0] = static_cast('0' + c / 100); out[1] = static_cast('0' + c / 10 % 10); out[2] = static_cast('0' + c % 10); out[3] = static_cast(delimiter); } }; template FMT_CONSTEXPR ansi_color_escape make_foreground_color( internal::color_type foreground) FMT_NOEXCEPT { return ansi_color_escape(foreground, internal::data::foreground_color); } template FMT_CONSTEXPR ansi_color_escape make_background_color( internal::color_type background) FMT_NOEXCEPT { return ansi_color_escape(background, internal::data::background_color); } template FMT_CONSTEXPR ansi_color_escape make_emphasis(emphasis em) FMT_NOEXCEPT { return ansi_color_escape(em); } template inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT { std::fputs(chars, stream); } template <> inline void fputs(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT { std::fputws(chars, stream); } template inline void reset_color(FILE* stream) FMT_NOEXCEPT { fputs(internal::data::reset_color, stream); } template <> inline void reset_color(FILE* stream) FMT_NOEXCEPT { fputs(internal::data::wreset_color, stream); } template inline void reset_color(basic_memory_buffer& buffer) FMT_NOEXCEPT { const char* begin = data::reset_color; const char* end = begin + sizeof(data::reset_color) - 1; buffer.append(begin, end); } template std::basic_string vformat(const text_style& ts, basic_string_view format_str, basic_format_args > args) { basic_memory_buffer buffer; bool has_style = false; if (ts.has_emphasis()) { has_style = true; ansi_color_escape escape = make_emphasis(ts.get_emphasis()); buffer.append(escape.begin(), escape.end()); } if (ts.has_foreground()) { has_style = true; ansi_color_escape escape = make_foreground_color(ts.get_foreground()); buffer.append(escape.begin(), escape.end()); } if (ts.has_background()) { has_style = true; ansi_color_escape escape = make_background_color(ts.get_background()); buffer.append(escape.begin(), escape.end()); } internal::vformat_to(buffer, format_str, args); if (has_style) { reset_color(buffer); } return fmt::to_string(buffer); } } // namespace internal template > void vprint(std::FILE* f, const text_style& ts, const S& format, basic_format_args > args) { bool has_style = false; if (ts.has_emphasis()) { has_style = true; internal::fputs(internal::make_emphasis(ts.get_emphasis()), f); } if (ts.has_foreground()) { has_style = true; internal::fputs( internal::make_foreground_color(ts.get_foreground()), f); } if (ts.has_background()) { has_style = true; internal::fputs( internal::make_background_color(ts.get_background()), f); } vprint(f, format, args); if (has_style) { internal::reset_color(f); } } /** Formats a string and prints it to the specified file stream using ANSI escape sequences to specify text formatting. Example: fmt::print(fmt::emphasis::bold | fg(fmt::color::red), "Elapsed time: {0:.2f} seconds", 1.23); */ template ::value)> void print(std::FILE* f, const text_style& ts, const S& format_str, const Args&... args) { internal::check_format_string(format_str); using context = buffer_context >; format_arg_store as{args...}; vprint(f, ts, format_str, basic_format_args(as)); } /** Formats a string and prints it to stdout using ANSI escape sequences to specify text formatting. Example: fmt::print(fmt::emphasis::bold | fg(fmt::color::red), "Elapsed time: {0:.2f} seconds", 1.23); */ template ::value)> void print(const text_style& ts, const S& format_str, const Args&... args) { return print(stdout, ts, format_str, args...); } template > inline std::basic_string vformat( const text_style& ts, const S& format_str, basic_format_args > args) { return internal::vformat(ts, to_string_view(format_str), args); } /** \rst Formats arguments and returns the result as a string using ANSI escape sequences to specify text formatting. **Example**:: #include std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "The answer is {}", 42); \endrst */ template > inline std::basic_string format(const text_style& ts, const S& format_str, const Args&... args) { return internal::vformat(ts, to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } FMT_END_NAMESPACE #endif // FMT_COLOR_H_ ================================================ FILE: src/third_party/fmt/include/fmt/core.h ================================================ // Formatting library for C++ - the core API // // Copyright (c) 2012 - present, Victor Zverovich // All rights reserved. // // For the license information refer to format.h. #ifndef FMT_CORE_H_ #define FMT_CORE_H_ #include #include // std::FILE #include #include #include #include // The fmt library version in the form major * 10000 + minor * 100 + patch. #define FMT_VERSION 50301 #ifdef __has_feature # define FMT_HAS_FEATURE(x) __has_feature(x) #else # define FMT_HAS_FEATURE(x) 0 #endif #if defined(__has_include) && !defined(__INTELLISENSE__) && \ !(defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1600) # define FMT_HAS_INCLUDE(x) __has_include(x) #else # define FMT_HAS_INCLUDE(x) 0 #endif #ifdef __has_cpp_attribute # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) #else # define FMT_HAS_CPP_ATTRIBUTE(x) 0 #endif #if defined(__GNUC__) && !defined(__clang__) # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #else # define FMT_GCC_VERSION 0 #endif #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) # define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION #else # define FMT_HAS_GXX_CXX11 0 #endif #ifdef _MSC_VER # define FMT_MSC_VER _MSC_VER #else # define FMT_MSC_VER 0 #endif // Check if relaxed C++14 constexpr is supported. // GCC doesn't allow throw in constexpr until version 6 (bug 67371). #ifndef FMT_USE_CONSTEXPR # define FMT_USE_CONSTEXPR \ (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \ (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) #endif #if FMT_USE_CONSTEXPR # define FMT_CONSTEXPR constexpr # define FMT_CONSTEXPR_DECL constexpr #else # define FMT_CONSTEXPR inline # define FMT_CONSTEXPR_DECL #endif #ifndef FMT_OVERRIDE # if FMT_HAS_FEATURE(cxx_override) || \ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 # define FMT_OVERRIDE override # else # define FMT_OVERRIDE # endif #endif // Check if exceptions are disabled. #ifndef FMT_EXCEPTIONS # if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ FMT_MSC_VER && !_HAS_EXCEPTIONS # define FMT_EXCEPTIONS 0 # else # define FMT_EXCEPTIONS 1 # endif #endif // Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature). #ifndef FMT_USE_NOEXCEPT # define FMT_USE_NOEXCEPT 0 #endif #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 # define FMT_DETECTED_NOEXCEPT noexcept # define FMT_HAS_CXX11_NOEXCEPT 1 #else # define FMT_DETECTED_NOEXCEPT throw() # define FMT_HAS_CXX11_NOEXCEPT 0 #endif #ifndef FMT_NOEXCEPT # if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT # define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT # else # define FMT_NOEXCEPT # endif #endif // [[noreturn]] is disabled on MSVC because of bogus unreachable code warnings. #if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER # define FMT_NORETURN [[noreturn]] #else # define FMT_NORETURN #endif #ifndef FMT_DEPRECATED # if (FMT_HAS_CPP_ATTRIBUTE(deprecated) && __cplusplus >= 201402L) || \ FMT_MSC_VER >= 1900 # define FMT_DEPRECATED [[deprecated]] # else # if defined(__GNUC__) || defined(__clang__) # define FMT_DEPRECATED __attribute__((deprecated)) # elif FMT_MSC_VER # define FMT_DEPRECATED __declspec(deprecated) # else # define FMT_DEPRECATED /* deprecated */ # endif # endif #endif #ifndef FMT_BEGIN_NAMESPACE # if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \ FMT_MSC_VER >= 1900 # define FMT_INLINE_NAMESPACE inline namespace # define FMT_END_NAMESPACE \ } \ } # else # define FMT_INLINE_NAMESPACE namespace # define FMT_END_NAMESPACE \ } \ using namespace v5; \ } # endif # define FMT_BEGIN_NAMESPACE \ namespace fmt { \ FMT_INLINE_NAMESPACE v5 { #endif #if !defined(FMT_HEADER_ONLY) && defined(_WIN32) # ifdef FMT_EXPORT # define FMT_API __declspec(dllexport) # elif defined(FMT_SHARED) # define FMT_API __declspec(dllimport) # define FMT_EXTERN_TEMPLATE_API FMT_API # endif #endif #ifndef FMT_API # define FMT_API #endif #ifndef FMT_EXTERN_TEMPLATE_API # define FMT_EXTERN_TEMPLATE_API #endif #ifndef FMT_HEADER_ONLY # define FMT_EXTERN extern #else # define FMT_EXTERN #endif #ifndef FMT_ASSERT # define FMT_ASSERT(condition, message) assert((condition) && message) #endif // libc++ supports string_view in pre-c++17. #if (FMT_HAS_INCLUDE() && \ (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \ (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) # include # define FMT_USE_STRING_VIEW #elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L # include # define FMT_USE_EXPERIMENTAL_STRING_VIEW #endif FMT_BEGIN_NAMESPACE // Implementations of enable_if_t and other types for pre-C++14 systems. template using enable_if_t = typename std::enable_if::type; template using conditional_t = typename std::conditional::type; template using bool_constant = std::integral_constant; template using remove_reference_t = typename std::remove_reference::type; template using remove_const_t = typename std::remove_const::type; struct monostate {}; // An enable_if helper to be used in template parameters which results in much // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed // to workaround a bug in MSVC 2019 (see #1140 and #1186). #define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 namespace internal { // A workaround for gcc 4.8 to make void_t work in a SFINAE context. template struct void_t_impl { using type = void; }; #if defined(FMT_USE_STRING_VIEW) template using std_string_view = std::basic_string_view; #elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW) template using std_string_view = std::experimental::basic_string_view; #else template struct std_string_view {}; #endif // Casts nonnegative integer to unsigned. template FMT_CONSTEXPR typename std::make_unsigned::type to_unsigned(Int value) { FMT_ASSERT(value >= 0, "negative value"); return static_cast::type>(value); } } // namespace internal template using void_t = typename internal::void_t_impl::type; /** An implementation of ``std::basic_string_view`` for pre-C++17. It provides a subset of the API. ``fmt::basic_string_view`` is used for format strings even if ``std::string_view`` is available to prevent issues when a library is compiled with a different ``-std`` option than the client code (which is not recommended). */ template class basic_string_view { private: const Char* data_; size_t size_; public: using char_type = Char; using iterator = const Char*; FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} /** Constructs a string reference object from a C string and a size. */ FMT_CONSTEXPR basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT : data_(s), size_(count) {} /** \rst Constructs a string reference object from a C string computing the size with ``std::char_traits::length``. \endrst */ basic_string_view(const Char* s) : data_(s), size_(std::char_traits::length(s)) {} /** Constructs a string reference from a ``std::basic_string`` object. */ template FMT_CONSTEXPR basic_string_view(const std::basic_string& s) FMT_NOEXCEPT : data_(s.data()), size_(s.size()) {} template < typename S, FMT_ENABLE_IF(std::is_same>::value)> FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()), size_(s.size()) {} /** Returns a pointer to the string data. */ FMT_CONSTEXPR const Char* data() const { return data_; } /** Returns the string size. */ FMT_CONSTEXPR size_t size() const { return size_; } FMT_CONSTEXPR iterator begin() const { return data_; } FMT_CONSTEXPR iterator end() const { return data_ + size_; } FMT_CONSTEXPR void remove_prefix(size_t n) { data_ += n; size_ -= n; } // Lexicographically compare this string reference to other. int compare(basic_string_view other) const { size_t str_size = size_ < other.size_ ? size_ : other.size_; int result = std::char_traits::compare(data_, other.data_, str_size); if (result == 0) result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); return result; } friend bool operator==(basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) == 0; } friend bool operator!=(basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) != 0; } friend bool operator<(basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) < 0; } friend bool operator<=(basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) <= 0; } friend bool operator>(basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) > 0; } friend bool operator>=(basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) >= 0; } }; using string_view = basic_string_view; using wstring_view = basic_string_view; #ifndef __cpp_char8_t // A UTF-8 code unit type. enum char8_t : unsigned char {}; #endif /** Specifies if ``T`` is a character type. Can be specialized by users. */ template struct is_char : std::false_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; /** \rst Returns a string view of `s`. In order to add custom string type support to {fmt} provide an overload of `to_string_view` for it in the same namespace as the type for the argument-dependent lookup to work. **Example**:: namespace my_ns { inline string_view to_string_view(const my_string& s) { return {s.data(), s.length()}; } } std::string message = fmt::format(my_string("The answer is {}"), 42); \endrst */ template ::value)> inline basic_string_view to_string_view(const Char* s) { return s; } template inline basic_string_view to_string_view( const std::basic_string& s) { return {s.data(), s.size()}; } template inline basic_string_view to_string_view(basic_string_view s) { return s; } template >::value)> inline basic_string_view to_string_view( internal::std_string_view s) { return s; } // A base class for compile-time strings. It is defined in the fmt namespace to // make formatting functions visible via ADL, e.g. format(fmt("{}"), 42). struct compile_string {}; template struct is_compile_string : std::is_base_of {}; template ::value)> constexpr basic_string_view to_string_view(const S& s) { return s; } namespace internal { void to_string_view(...); using fmt::v5::to_string_view; // Specifies whether S is a string type convertible to fmt::basic_string_view. // It should be a constexpr function but MSVC 2017 fails to compile it in // enable_if and MSVC 2015 fails to compile it as an alias template. template struct is_string : std::is_class()))> { }; template struct char_t_impl {}; template struct char_t_impl::value>> { using result = decltype(to_string_view(std::declval())); using type = typename result::char_type; }; struct error_handler { FMT_CONSTEXPR error_handler() {} FMT_CONSTEXPR error_handler(const error_handler&) {} // This function is intentionally not constexpr to give a compile-time error. FMT_NORETURN FMT_API void on_error(const char* message); }; } // namespace internal /** String's character type. */ template using char_t = typename internal::char_t_impl::type; // Parsing context consisting of a format string range being parsed and an // argument counter for automatic indexing. template class basic_parse_context : private ErrorHandler { private: basic_string_view format_str_; int next_arg_id_; public: using char_type = Char; using iterator = typename basic_string_view::iterator; explicit FMT_CONSTEXPR basic_parse_context(basic_string_view format_str, ErrorHandler eh = ErrorHandler()) : ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {} // Returns an iterator to the beginning of the format string range being // parsed. FMT_CONSTEXPR iterator begin() const FMT_NOEXCEPT { return format_str_.begin(); } // Returns an iterator past the end of the format string range being parsed. FMT_CONSTEXPR iterator end() const FMT_NOEXCEPT { return format_str_.end(); } // Advances the begin iterator to ``it``. FMT_CONSTEXPR void advance_to(iterator it) { format_str_.remove_prefix(internal::to_unsigned(it - begin())); } // Returns the next argument index. FMT_CONSTEXPR int next_arg_id() { if (next_arg_id_ >= 0) return next_arg_id_++; on_error("cannot switch from manual to automatic argument indexing"); return 0; } FMT_CONSTEXPR bool check_arg_id(int) { if (next_arg_id_ > 0) { on_error("cannot switch from automatic to manual argument indexing"); return false; } next_arg_id_ = -1; return true; } FMT_CONSTEXPR void check_arg_id(basic_string_view) {} FMT_CONSTEXPR void on_error(const char* message) { ErrorHandler::on_error(message); } FMT_CONSTEXPR ErrorHandler error_handler() const { return *this; } }; using format_parse_context = basic_parse_context; using wformat_parse_context = basic_parse_context; using parse_context FMT_DEPRECATED = basic_parse_context; using wparse_context FMT_DEPRECATED = basic_parse_context; template class basic_format_arg; template class basic_format_args; // A formatter for objects of type T. template struct formatter { // A deleted default constructor indicates a disabled formatter. formatter() = delete; }; template struct FMT_DEPRECATED convert_to_int : bool_constant::value && std::is_convertible::value> {}; namespace internal { // Specifies if T has an enabled formatter specialization. A type can be // formattable even if it doesn't have a formatter e.g. via a conversion. template using has_formatter = std::is_constructible>; /** A contiguous memory buffer with an optional growing ability. */ template class buffer { private: buffer(const buffer&) = delete; void operator=(const buffer&) = delete; T* ptr_; std::size_t size_; std::size_t capacity_; protected: // Don't initialize ptr_ since it is not accessed to save a few cycles. buffer(std::size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {} buffer(T* p = nullptr, std::size_t sz = 0, std::size_t cap = 0) FMT_NOEXCEPT : ptr_(p), size_(sz), capacity_(cap) {} /** Sets the buffer data and capacity. */ void set(T* buf_data, std::size_t buf_capacity) FMT_NOEXCEPT { ptr_ = buf_data; capacity_ = buf_capacity; } /** Increases the buffer capacity to hold at least *capacity* elements. */ virtual void grow(std::size_t capacity) = 0; public: using value_type = T; using const_reference = const T&; virtual ~buffer() {} T* begin() FMT_NOEXCEPT { return ptr_; } T* end() FMT_NOEXCEPT { return ptr_ + size_; } /** Returns the size of this buffer. */ std::size_t size() const FMT_NOEXCEPT { return size_; } /** Returns the capacity of this buffer. */ std::size_t capacity() const FMT_NOEXCEPT { return capacity_; } /** Returns a pointer to the buffer data. */ T* data() FMT_NOEXCEPT { return ptr_; } /** Returns a pointer to the buffer data. */ const T* data() const FMT_NOEXCEPT { return ptr_; } /** Resizes the buffer. If T is a POD type new elements may not be initialized. */ void resize(std::size_t new_size) { reserve(new_size); size_ = new_size; } /** Clears this buffer. */ void clear() { size_ = 0; } /** Reserves space to store at least *capacity* elements. */ void reserve(std::size_t new_capacity) { if (new_capacity > capacity_) grow(new_capacity); } void push_back(const T& value) { reserve(size_ + 1); ptr_[size_++] = value; } /** Appends data to the end of the buffer. */ template void append(const U* begin, const U* end); T& operator[](std::size_t index) { return ptr_[index]; } const T& operator[](std::size_t index) const { return ptr_[index]; } }; // A container-backed buffer. template class container_buffer : public buffer { private: Container& container_; protected: void grow(std::size_t capacity) FMT_OVERRIDE { container_.resize(capacity); this->set(&container_[0], capacity); } public: explicit container_buffer(Container& c) : buffer(c.size()), container_(c) {} }; // Extracts a reference to the container from back_insert_iterator. template inline Container& get_container(std::back_insert_iterator it) { using bi_iterator = std::back_insert_iterator; struct accessor : bi_iterator { accessor(bi_iterator iter) : bi_iterator(iter) {} using bi_iterator::container; }; return *accessor(it).container; } template struct fallback_formatter { fallback_formatter() = delete; }; // Specifies if T has an enabled fallback_formatter specialization. template using has_fallback_formatter = std::is_constructible>; template struct named_arg_base; template struct named_arg; enum type { none_type, named_arg_type, // Integer types should go first, int_type, uint_type, long_long_type, ulong_long_type, bool_type, char_type, last_integer_type = char_type, // followed by floating-point types. double_type, long_double_type, last_numeric_type = long_double_type, cstring_type, string_type, pointer_type, custom_type }; // Maps core type T to the corresponding type enum constant. template struct type_constant : std::integral_constant {}; #define FMT_TYPE_CONSTANT(Type, constant) \ template \ struct type_constant : std::integral_constant {} FMT_TYPE_CONSTANT(const named_arg_base&, named_arg_type); FMT_TYPE_CONSTANT(int, int_type); FMT_TYPE_CONSTANT(unsigned, uint_type); FMT_TYPE_CONSTANT(long long, long_long_type); FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type); FMT_TYPE_CONSTANT(bool, bool_type); FMT_TYPE_CONSTANT(Char, char_type); FMT_TYPE_CONSTANT(double, double_type); FMT_TYPE_CONSTANT(long double, long_double_type); FMT_TYPE_CONSTANT(const Char*, cstring_type); FMT_TYPE_CONSTANT(basic_string_view, string_type); FMT_TYPE_CONSTANT(const void*, pointer_type); FMT_CONSTEXPR bool is_integral(type t) { FMT_ASSERT(t != named_arg_type, "invalid argument type"); return t > none_type && t <= last_integer_type; } FMT_CONSTEXPR bool is_arithmetic(type t) { FMT_ASSERT(t != named_arg_type, "invalid argument type"); return t > none_type && t <= last_numeric_type; } template struct string_value { const Char* data; std::size_t size; }; template struct custom_value { using parse_context = basic_parse_context; const void* value; void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx); }; // A formatting argument value. template class value { public: using char_type = typename Context::char_type; union { int int_value; unsigned uint_value; long long long_long_value; unsigned long long ulong_long_value; bool bool_value; char_type char_value; double double_value; long double long_double_value; const void* pointer; string_value string; custom_value custom; const named_arg_base* named_arg; }; FMT_CONSTEXPR value(int val = 0) : int_value(val) {} FMT_CONSTEXPR value(unsigned val) : uint_value(val) {} value(long long val) : long_long_value(val) {} value(unsigned long long val) : ulong_long_value(val) {} value(double val) : double_value(val) {} value(long double val) : long_double_value(val) {} value(bool val) : bool_value(val) {} value(char_type val) : char_value(val) {} value(const char_type* val) { string.data = val; } value(basic_string_view val) { string.data = val.data(); string.size = val.size(); } value(const void* val) : pointer(val) {} template value(const T& val) { custom.value = &val; // Get the formatter type through the context to allow different contexts // have different extension points, e.g. `formatter` for `format` and // `printf_formatter` for `printf`. custom.format = format_custom_arg< T, conditional_t::value, typename Context::template formatter_type, fallback_formatter>>; } value(const named_arg_base& val) { named_arg = &val; } private: // Formats an argument of a custom type, such as a user-defined class. template static void format_custom_arg(const void* arg, basic_parse_context& parse_ctx, Context& ctx) { Formatter f; parse_ctx.advance_to(f.parse(parse_ctx)); ctx.advance_to(f.format(*static_cast(arg), ctx)); } }; template FMT_CONSTEXPR basic_format_arg make_arg(const T& value); // To minimize the number of types we need to deal with, long is translated // either to int or to long long depending on its size. enum { long_short = sizeof(long) == sizeof(int) }; using long_type = conditional_t; using ulong_type = conditional_t; // Maps formatting arguments to core types. template struct arg_mapper { using char_type = typename Context::char_type; FMT_CONSTEXPR int map(signed char val) { return val; } FMT_CONSTEXPR unsigned map(unsigned char val) { return val; } FMT_CONSTEXPR int map(short val) { return val; } FMT_CONSTEXPR unsigned map(unsigned short val) { return val; } FMT_CONSTEXPR int map(int val) { return val; } FMT_CONSTEXPR unsigned map(unsigned val) { return val; } FMT_CONSTEXPR long_type map(long val) { return val; } FMT_CONSTEXPR ulong_type map(unsigned long val) { return val; } FMT_CONSTEXPR long long map(long long val) { return val; } FMT_CONSTEXPR unsigned long long map(unsigned long long val) { return val; } FMT_CONSTEXPR bool map(bool val) { return val; } template ::value)> FMT_CONSTEXPR char_type map(T val) { static_assert( std::is_same::value || std::is_same::value, "mixing character types is disallowed"); return val; } FMT_CONSTEXPR double map(float val) { return static_cast(val); } FMT_CONSTEXPR double map(double val) { return val; } FMT_CONSTEXPR long double map(long double val) { return val; } FMT_CONSTEXPR const char_type* map(char_type* val) { return val; } FMT_CONSTEXPR const char_type* map(const char_type* val) { return val; } template ::value)> FMT_CONSTEXPR basic_string_view map(const T& val) { static_assert(std::is_same>::value, "mixing character types is disallowed"); return to_string_view(val); } template , T>::value && !is_string::value)> FMT_CONSTEXPR basic_string_view map(const T& val) { return basic_string_view(val); } FMT_CONSTEXPR const char* map(const signed char* val) { static_assert(std::is_same::value, "invalid string type"); return reinterpret_cast(val); } FMT_CONSTEXPR const char* map(const unsigned char* val) { static_assert(std::is_same::value, "invalid string type"); return reinterpret_cast(val); } FMT_CONSTEXPR const void* map(void* val) { return val; } FMT_CONSTEXPR const void* map(const void* val) { return val; } FMT_CONSTEXPR const void* map(std::nullptr_t val) { return val; } template FMT_CONSTEXPR int map(const T*) { // Formatting of arbitrary pointers is disallowed. If you want to output // a pointer cast it to "void *" or "const void *". In particular, this // forbids formatting of "[const] volatile char *" which is printed as bool // by iostreams. static_assert(!sizeof(T), "formatting of non-void pointers is disallowed"); return 0; } template ::value && !has_formatter::value && !has_fallback_formatter::value)> FMT_CONSTEXPR int map(const T& val) { return static_cast(val); } template ::value && !is_char::value && (has_formatter::value || has_fallback_formatter::value))> FMT_CONSTEXPR const T& map(const T& val) { return val; } template FMT_CONSTEXPR const named_arg_base& map( const named_arg& val) { auto arg = make_arg(val.value); std::memcpy(val.data, &arg, sizeof(arg)); return val; } }; // A type constant after applying arg_mapper. template using mapped_type_constant = type_constant().map(std::declval())), typename Context::char_type>; // Maximum number of arguments with packed types. enum { max_packed_args = 15 }; enum : unsigned long long { is_unpacked_bit = 1ull << 63 }; template class arg_map; } // namespace internal // A formatting argument. It is a trivially copyable/constructible type to // allow storage in basic_memory_buffer. template class basic_format_arg { private: internal::value value_; internal::type type_; template friend FMT_CONSTEXPR basic_format_arg internal::make_arg( const T& value); template friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis, const basic_format_arg& arg) -> decltype(vis(0)); friend class basic_format_args; friend class internal::arg_map; using char_type = typename Context::char_type; public: class handle { public: explicit handle(internal::custom_value custom) : custom_(custom) {} void format(basic_parse_context& parse_ctx, Context& ctx) const { custom_.format(custom_.value, parse_ctx, ctx); } private: internal::custom_value custom_; }; FMT_CONSTEXPR basic_format_arg() : type_(internal::none_type) {} FMT_CONSTEXPR explicit operator bool() const FMT_NOEXCEPT { return type_ != internal::none_type; } internal::type type() const { return type_; } bool is_integral() const { return internal::is_integral(type_); } bool is_arithmetic() const { return internal::is_arithmetic(type_); } }; /** \rst Visits an argument dispatching to the appropriate visit method based on the argument type. For example, if the argument type is ``double`` then ``vis(value)`` will be called with the value of type ``double``. \endrst */ template FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis, const basic_format_arg& arg) -> decltype(vis(0)) { using char_type = typename Context::char_type; switch (arg.type_) { case internal::none_type: break; case internal::named_arg_type: FMT_ASSERT(false, "invalid argument type"); break; case internal::int_type: return vis(arg.value_.int_value); case internal::uint_type: return vis(arg.value_.uint_value); case internal::long_long_type: return vis(arg.value_.long_long_value); case internal::ulong_long_type: return vis(arg.value_.ulong_long_value); case internal::bool_type: return vis(arg.value_.bool_value); case internal::char_type: return vis(arg.value_.char_value); case internal::double_type: return vis(arg.value_.double_value); case internal::long_double_type: return vis(arg.value_.long_double_value); case internal::cstring_type: return vis(arg.value_.string.data); case internal::string_type: return vis(basic_string_view(arg.value_.string.data, arg.value_.string.size)); case internal::pointer_type: return vis(arg.value_.pointer); case internal::custom_type: return vis(typename basic_format_arg::handle(arg.value_.custom)); } return vis(monostate()); } namespace internal { // A map from argument names to their values for named arguments. template class arg_map { private: arg_map(const arg_map&) = delete; void operator=(const arg_map&) = delete; using char_type = typename Context::char_type; struct entry { basic_string_view name; basic_format_arg arg; }; entry* map_; unsigned size_; void push_back(value val) { const auto& named = *val.named_arg; map_[size_] = {named.name, named.template deserialize()}; ++size_; } public: arg_map() : map_(nullptr), size_(0) {} void init(const basic_format_args& args); ~arg_map() { delete[] map_; } basic_format_arg find(basic_string_view name) const { // The list is unsorted, so just return the first matching name. for (entry *it = map_, *end = map_ + size_; it != end; ++it) { if (it->name == name) return it->arg; } return {}; } }; // A type-erased reference to an std::locale to avoid heavy include. class locale_ref { private: const void* locale_; // A type-erased pointer to std::locale. public: locale_ref() : locale_(nullptr) {} template explicit locale_ref(const Locale& loc); template Locale get() const; }; template constexpr unsigned long long encode_types() { return 0; } template constexpr unsigned long long encode_types() { return mapped_type_constant::value | (encode_types() << 4); } template FMT_CONSTEXPR basic_format_arg make_arg(const T& value) { basic_format_arg arg; arg.type_ = mapped_type_constant::value; arg.value_ = arg_mapper().map(value); return arg; } template inline value make_arg(const T& val) { return arg_mapper().map(val); } template inline basic_format_arg make_arg(const T& value) { return make_arg(value); } } // namespace internal // Formatting context. template class basic_format_context { public: /** The character type for the output. */ using char_type = Char; private: OutputIt out_; basic_format_args args_; internal::arg_map map_; internal::locale_ref loc_; basic_format_context(const basic_format_context&) = delete; void operator=(const basic_format_context&) = delete; public: using iterator = OutputIt; using format_arg = basic_format_arg; template using formatter_type = formatter; /** Constructs a ``basic_format_context`` object. References to the arguments are stored in the object so make sure they have appropriate lifetimes. */ basic_format_context(OutputIt out, basic_format_args ctx_args, internal::locale_ref loc = internal::locale_ref()) : out_(out), args_(ctx_args), loc_(loc) {} format_arg arg(int id) const { return args_.get(id); } // Checks if manual indexing is used and returns the argument with the // specified name. format_arg arg(basic_string_view name); internal::error_handler error_handler() { return {}; } void on_error(const char* message) { error_handler().on_error(message); } // Returns an iterator to the beginning of the output range. iterator out() { return out_; } // Advances the begin iterator to ``it``. void advance_to(iterator it) { out_ = it; } internal::locale_ref locale() { return loc_; } }; template using buffer_context = basic_format_context>, Char>; using format_context = buffer_context; using wformat_context = buffer_context; /** \rst An array of references to arguments. It can be implicitly converted into `~fmt::basic_format_args` for passing into type-erased formatting functions such as `~fmt::vformat`. \endrst */ template class format_arg_store { private: static const size_t num_args = sizeof...(Args); static const bool is_packed = num_args < internal::max_packed_args; using value_type = conditional_t, basic_format_arg>; // If the arguments are not packed, add one more element to mark the end. value_type data_[num_args + (!is_packed || num_args == 0 ? 1 : 0)]; friend class basic_format_args; public: static constexpr unsigned long long types = is_packed ? internal::encode_types() : internal::is_unpacked_bit | num_args; FMT_DEPRECATED static constexpr unsigned long long TYPES = types; format_arg_store(const Args&... args) : data_{internal::make_arg(args)...} {} }; /** \rst Constructs an `~fmt::format_arg_store` object that contains references to arguments and can be implicitly converted to `~fmt::format_args`. `Context` can be omitted in which case it defaults to `~fmt::context`. See `~fmt::arg` for lifetime considerations. \endrst */ template inline format_arg_store make_format_args( const Args&... args) { return {args...}; } /** Formatting arguments. */ template class basic_format_args { public: using size_type = int; using format_arg = basic_format_arg; private: // To reduce compiled code size per formatting function call, types of first // max_packed_args arguments are passed in the types_ field. unsigned long long types_; union { // If the number of arguments is less than max_packed_args, the argument // values are stored in values_, otherwise they are stored in args_. // This is done to reduce compiled code size as storing larger objects // may require more code (at least on x86-64) even if the same amount of // data is actually copied to stack. It saves ~10% on the bloat test. const internal::value* values_; const format_arg* args_; }; bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; } internal::type type(int index) const { int shift = index * 4; return static_cast((types_ & (0xfull << shift)) >> shift); } friend class internal::arg_map; void set_data(const internal::value* values) { values_ = values; } void set_data(const format_arg* args) { args_ = args; } format_arg do_get(int index) const { format_arg arg; if (!is_packed()) { auto num_args = max_size(); if (index < num_args) arg = args_[index]; return arg; } if (index > internal::max_packed_args) return arg; arg.type_ = type(index); if (arg.type_ == internal::none_type) return arg; internal::value& val = arg.value_; val = values_[index]; return arg; } public: basic_format_args() : types_(0) {} /** \rst Constructs a `basic_format_args` object from `~fmt::format_arg_store`. \endrst */ template basic_format_args(const format_arg_store& store) : types_(static_cast(store.types)) { set_data(store.data_); } /** \rst Constructs a `basic_format_args` object from a dynamic set of arguments. \endrst */ basic_format_args(const format_arg* args, int count) : types_(internal::is_unpacked_bit | internal::to_unsigned(count)) { set_data(args); } /** Returns the argument at specified index. */ format_arg get(int index) const { format_arg arg = do_get(index); if (arg.type_ == internal::named_arg_type) arg = arg.value_.named_arg->template deserialize(); return arg; } int max_size() const { unsigned long long max_packed = internal::max_packed_args; return static_cast(is_packed() ? max_packed : types_ & ~internal::is_unpacked_bit); } }; /** An alias to ``basic_format_args``. */ // It is a separate type rather than an alias to make symbols readable. struct format_args : basic_format_args { template format_args(Args&&... args) : basic_format_args(std::forward(args)...) {} }; struct wformat_args : basic_format_args { template wformat_args(Args&&... args) : basic_format_args(std::forward(args)...) {} }; template struct is_contiguous : std::false_type {}; template struct is_contiguous> : std::true_type {}; template struct is_contiguous> : std::true_type {}; namespace internal { template struct is_contiguous_back_insert_iterator : std::false_type {}; template struct is_contiguous_back_insert_iterator> : is_contiguous {}; template struct named_arg_base { basic_string_view name; // Serialized value. mutable char data[sizeof(basic_format_arg>)]; named_arg_base(basic_string_view nm) : name(nm) {} template basic_format_arg deserialize() const { basic_format_arg arg; std::memcpy(&arg, data, sizeof(basic_format_arg)); return arg; } }; template struct named_arg : named_arg_base { const T& value; named_arg(basic_string_view name, const T& val) : named_arg_base(name), value(val) {} }; template ::value)> inline void check_format_string(const S&) { #if defined(FMT_ENFORCE_COMPILE_STRING) static_assert(is_compile_string::value, "FMT_ENFORCE_COMPILE_STRING requires all format strings to " "utilize FMT_STRING() or fmt()."); #endif } template ::value)> void check_format_string(S); struct view {}; template struct bool_pack; template using all_true = std::is_same, bool_pack>; template > inline format_arg_store, remove_reference_t...> make_args_checked(const S& format_str, const remove_reference_t&... args) { static_assert(all_true<(!std::is_base_of>() || !std::is_reference())...>::value, "passing views as lvalues is disallowed"); check_format_string>...>(format_str); return {args...}; } template std::basic_string vformat(basic_string_view format_str, basic_format_args> args); template typename buffer_context::iterator vformat_to( buffer& buf, basic_string_view format_str, basic_format_args> args); } // namespace internal /** \rst Returns a named argument to be used in a formatting function. The named argument holds a reference and does not extend the lifetime of its arguments. Consequently, a dangling reference can accidentally be created. The user should take care to only pass this function temporaries when the named argument is itself a temporary, as per the following example. **Example**:: fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); \endrst */ template > inline internal::named_arg arg(const S& name, const T& arg) { static_assert(internal::is_string::value, ""); return {name, arg}; } // Disable nested named arguments, e.g. ``arg("a", arg("b", 42))``. template void arg(S, internal::named_arg) = delete; /** Formats a string and writes the output to ``out``. */ // GCC 8 and earlier cannot handle std::back_insert_iterator with // vformat_to(...) overload, so SFINAE on iterator type instead. template , FMT_ENABLE_IF( internal::is_contiguous_back_insert_iterator::value)> OutputIt vformat_to(OutputIt out, const S& format_str, basic_format_args> args) { using container = remove_reference_t; internal::container_buffer buf((internal::get_container(out))); internal::vformat_to(buf, to_string_view(format_str), args); return out; } template ::value&& internal::is_string::value)> inline std::back_insert_iterator format_to( std::back_insert_iterator out, const S& format_str, Args&&... args) { return vformat_to( out, to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } template > inline std::basic_string vformat( const S& format_str, basic_format_args> args) { return internal::vformat(to_string_view(format_str), args); } /** \rst Formats arguments and returns the result as a string. **Example**:: #include std::string message = fmt::format("The answer is {}", 42); \endrst */ // Pass char_t as a default template parameter instead of using // std::basic_string> to reduce the symbol size. template > inline std::basic_string format(const S& format_str, Args&&... args) { return internal::vformat( to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } FMT_API void vprint(std::FILE* f, string_view format_str, format_args args); FMT_API void vprint(std::FILE* f, wstring_view format_str, wformat_args args); /** \rst Prints formatted data to the file *f*. For wide format strings, *f* should be in wide-oriented mode set via ``fwide(f, 1)`` or ``_setmode(_fileno(f), _O_U8TEXT)`` on Windows. **Example**:: fmt::print(stderr, "Don't {}!", "panic"); \endrst */ template ::value)> inline void print(std::FILE* f, const S& format_str, Args&&... args) { vprint(f, to_string_view(format_str), internal::make_args_checked(format_str, args...)); } FMT_API void vprint(string_view format_str, format_args args); FMT_API void vprint(wstring_view format_str, wformat_args args); /** \rst Prints formatted data to ``stdout``. **Example**:: fmt::print("Elapsed time: {0:.2f} seconds", 1.23); \endrst */ template ::value)> inline void print(const S& format_str, Args&&... args) { vprint(to_string_view(format_str), internal::make_args_checked(format_str, args...)); } FMT_END_NAMESPACE #endif // FMT_CORE_H_ ================================================ FILE: src/third_party/fmt/include/fmt/format-inl.h ================================================ // Formatting library for C++ // // Copyright (c) 2012 - 2016, Victor Zverovich // All rights reserved. // // For the license information refer to format.h. #ifndef FMT_FORMAT_INL_H_ #define FMT_FORMAT_INL_H_ #include "format.h" #include #include #include #include #include #include #include // for std::ptrdiff_t #include // for std::memmove #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) # include #endif #if FMT_USE_WINDOWS_H # if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN) # define WIN32_LEAN_AND_MEAN # endif # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX) # include # else # define NOMINMAX # include # undef NOMINMAX # endif #endif #if FMT_EXCEPTIONS # define FMT_TRY try # define FMT_CATCH(x) catch (x) #else # define FMT_TRY if (true) # define FMT_CATCH(x) if (false) #endif #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable : 4127) // conditional expression is constant # pragma warning(disable : 4702) // unreachable code // Disable deprecation warning for strerror. The latter is not called but // MSVC fails to detect it. # pragma warning(disable : 4996) #endif // Dummy implementations of strerror_r and strerror_s called if corresponding // system functions are not available. inline fmt::internal::null<> strerror_r(int, char*, ...) { return fmt::internal::null<>(); } inline fmt::internal::null<> strerror_s(char*, std::size_t, ...) { return fmt::internal::null<>(); } FMT_BEGIN_NAMESPACE namespace internal { #ifndef _MSC_VER # define FMT_SNPRINTF snprintf #else // _MSC_VER inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) { va_list args; va_start(args, format); int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args); va_end(args); return result; } # define FMT_SNPRINTF fmt_snprintf #endif // _MSC_VER using format_func = void (*)(internal::buffer&, int, string_view); // Portable thread-safe version of strerror. // Sets buffer to point to a string describing the error code. // This can be either a pointer to a string stored in buffer, // or a pointer to some static immutable string. // Returns one of the following values: // 0 - success // ERANGE - buffer is not large enough to store the error message // other - failure // Buffer should be at least of size 1. FMT_FUNC int safe_strerror(int error_code, char*& buffer, std::size_t buffer_size) FMT_NOEXCEPT { FMT_ASSERT(buffer != nullptr && buffer_size != 0, "invalid buffer"); class dispatcher { private: int error_code_; char*& buffer_; std::size_t buffer_size_; // A noop assignment operator to avoid bogus warnings. void operator=(const dispatcher&) {} // Handle the result of XSI-compliant version of strerror_r. int handle(int result) { // glibc versions before 2.13 return result in errno. return result == -1 ? errno : result; } // Handle the result of GNU-specific version of strerror_r. int handle(char* message) { // If the buffer is full then the message is probably truncated. if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1) return ERANGE; buffer_ = message; return 0; } // Handle the case when strerror_r is not available. int handle(internal::null<>) { return fallback(strerror_s(buffer_, buffer_size_, error_code_)); } // Fallback to strerror_s when strerror_r is not available. int fallback(int result) { // If the buffer is full then the message is probably truncated. return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE : result; } #if !FMT_MSC_VER // Fallback to strerror if strerror_r and strerror_s are not available. int fallback(internal::null<>) { errno = 0; buffer_ = strerror(error_code_); return errno; } #endif public: dispatcher(int err_code, char*& buf, std::size_t buf_size) : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); } }; return dispatcher(error_code, buffer, buffer_size).run(); } FMT_FUNC void format_error_code(internal::buffer& out, int error_code, string_view message) FMT_NOEXCEPT { // Report error code making sure that the output fits into // inline_buffer_size to avoid dynamic memory allocation and potential // bad_alloc. out.resize(0); static const char SEP[] = ": "; static const char ERROR_STR[] = "error "; // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; auto abs_value = static_cast>(error_code); if (internal::is_negative(error_code)) { abs_value = 0 - abs_value; ++error_code_size; } error_code_size += internal::to_unsigned(internal::count_digits(abs_value)); internal::writer w(out); if (message.size() <= inline_buffer_size - error_code_size) { w.write(message); w.write(SEP); } w.write(ERROR_STR); w.write(error_code); assert(out.size() <= inline_buffer_size); } // try an fwrite, FMT_THROW on failure FMT_FUNC void fwrite_fully(const void* ptr, size_t size, size_t count, FILE* stream) { size_t written = std::fwrite(ptr, size, count, stream); if (written < count) { FMT_THROW(system_error(errno, "cannot write to file")); } } FMT_FUNC void report_error(format_func func, int error_code, string_view message) FMT_NOEXCEPT { memory_buffer full_message; func(full_message, error_code, message); // Use Writer::data instead of Writer::c_str to avoid potential memory // allocation. fwrite_fully(full_message.data(), 1, full_message.size(), stderr); std::fputc('\n', stderr); } } // namespace internal #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) namespace internal { template locale_ref::locale_ref(const Locale& loc) : locale_(&loc) { static_assert(std::is_same::value, ""); } template Locale locale_ref::get() const { static_assert(std::is_same::value, ""); return locale_ ? *static_cast(locale_) : std::locale(); } template FMT_FUNC Char thousands_sep_impl(locale_ref loc) { return std::use_facet>(loc.get()) .thousands_sep(); } template FMT_FUNC Char decimal_point_impl(locale_ref loc) { return std::use_facet>(loc.get()) .decimal_point(); } } // namespace internal #else template FMT_FUNC Char internal::thousands_sep_impl(locale_ref) { return FMT_STATIC_THOUSANDS_SEPARATOR; } template FMT_FUNC Char internal::decimal_point_impl(locale_ref) { return '.'; } #endif FMT_API FMT_FUNC format_error::~format_error() FMT_NOEXCEPT {} FMT_API FMT_FUNC system_error::~system_error() FMT_NOEXCEPT {} FMT_FUNC void system_error::init(int err_code, string_view format_str, format_args args) { error_code_ = err_code; memory_buffer buffer; format_system_error(buffer, err_code, vformat(format_str, args)); std::runtime_error& base = *this; base = std::runtime_error(to_string(buffer)); } namespace internal { template <> FMT_FUNC int count_digits<4>(internal::fallback_uintptr n) { // Assume little endian; pointer formatting is implementation-defined anyway. int i = static_cast(sizeof(void*)) - 1; while (i > 0 && n.value[i] == 0) --i; auto char_digits = std::numeric_limits::digits / 4; return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1; } template int format_float(char* buf, std::size_t size, const char* format, int precision, T value) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (precision > 100000) throw std::runtime_error( "fuzz mode - avoid large allocation inside snprintf"); #endif // Suppress the warning about nonliteral format string. auto snprintf_ptr = FMT_SNPRINTF; return precision < 0 ? snprintf_ptr(buf, size, format, value) : snprintf_ptr(buf, size, format, precision, value); } template const char basic_data::digits[] = "0001020304050607080910111213141516171819" "2021222324252627282930313233343536373839" "4041424344454647484950515253545556575859" "6061626364656667686970717273747576777879" "8081828384858687888990919293949596979899"; template const char basic_data::hex_digits[] = "0123456789abcdef"; #define FMT_POWERS_OF_10(factor) \ factor * 10, factor * 100, factor * 1000, factor * 10000, factor * 100000, \ factor * 1000000, factor * 10000000, factor * 100000000, \ factor * 1000000000 template const uint64_t basic_data::powers_of_10_64[] = { 1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ull), 10000000000000000000ull}; template const uint32_t basic_data::zero_or_powers_of_10_32[] = {0, FMT_POWERS_OF_10(1)}; template const uint64_t basic_data::zero_or_powers_of_10_64[] = { 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ull), 10000000000000000000ull}; // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340. // These are generated by support/compute-powers.py. template const uint64_t basic_data::pow10_significands[] = { 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76, 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df, 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c, 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5, 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57, 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7, 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e, 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996, 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126, 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053, 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f, 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b, 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06, 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb, 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000, 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984, 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068, 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8, 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758, 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85, 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d, 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25, 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2, 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a, 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410, 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129, 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85, 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841, 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b, }; // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding // to significands above. template const int16_t basic_data::pow10_exponents[] = { -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066}; template const char basic_data::foreground_color[] = "\x1b[38;2;"; template const char basic_data::background_color[] = "\x1b[48;2;"; template const char basic_data::reset_color[] = "\x1b[0m"; template const wchar_t basic_data::wreset_color[] = L"\x1b[0m"; template struct bits { static FMT_CONSTEXPR_DECL const int value = static_cast(sizeof(T) * std::numeric_limits::digits); }; // A handmade floating-point number f * pow(2, e). class fp { private: using significand_type = uint64_t; // All sizes are in bits. // Subtract 1 to account for an implicit most significant bit in the // normalized form. static FMT_CONSTEXPR_DECL const int double_significand_size = std::numeric_limits::digits - 1; static FMT_CONSTEXPR_DECL const uint64_t implicit_bit = 1ull << double_significand_size; public: significand_type f; int e; static FMT_CONSTEXPR_DECL const int significand_size = bits::value; fp() : f(0), e(0) {} fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {} // Constructs fp from an IEEE754 double. It is a template to prevent compile // errors on platforms where double is not IEEE754. template explicit fp(Double d) { // Assume double is in the format [sign][exponent][significand]. using limits = std::numeric_limits; const int exponent_size = bits::value - double_significand_size - 1; // -1 for sign const uint64_t significand_mask = implicit_bit - 1; const uint64_t exponent_mask = (~0ull >> 1) & ~significand_mask; const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1; auto u = bit_cast(d); auto biased_e = (u & exponent_mask) >> double_significand_size; f = u & significand_mask; if (biased_e != 0) f += implicit_bit; else biased_e = 1; // Subnormals use biased exponent 1 (min exponent). e = static_cast(biased_e - exponent_bias - double_significand_size); } // Normalizes the value converted from double and multiplied by (1 << SHIFT). template void normalize() { // Handle subnormals. auto shifted_implicit_bit = implicit_bit << SHIFT; while ((f & shifted_implicit_bit) == 0) { f <<= 1; --e; } // Subtract 1 to account for hidden bit. auto offset = significand_size - double_significand_size - SHIFT - 1; f <<= offset; e -= offset; } // Compute lower and upper boundaries (m^- and m^+ in the Grisu paper), where // a boundary is a value half way between the number and its predecessor // (lower) or successor (upper). The upper boundary is normalized and lower // has the same exponent but may be not normalized. void compute_boundaries(fp& lower, fp& upper) const { lower = f == implicit_bit ? fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1); upper = fp((f << 1) + 1, e - 1); upper.normalize<1>(); // 1 is to account for the exponent shift above. lower.f <<= lower.e - upper.e; lower.e = upper.e; } }; // Returns an fp number representing x - y. Result may not be normalized. inline fp operator-(fp x, fp y) { FMT_ASSERT(x.f >= y.f && x.e == y.e, "invalid operands"); return fp(x.f - y.f, x.e); } // Computes an fp number r with r.f = x.f * y.f / pow(2, 64) rounded to nearest // with half-up tie breaking, r.e = x.e + y.e + 64. Result may not be // normalized. FMT_FUNC fp operator*(fp x, fp y) { int exp = x.e + y.e + 64; #if FMT_USE_INT128 auto product = static_cast<__uint128_t>(x.f) * y.f; auto f = static_cast(product >> 64); if ((static_cast(product) & (1ULL << 63)) != 0) ++f; return fp(f, exp); #else // Multiply 32-bit parts of significands. uint64_t mask = (1ULL << 32) - 1; uint64_t a = x.f >> 32, b = x.f & mask; uint64_t c = y.f >> 32, d = y.f & mask; uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d; // Compute mid 64-bit of result and round. uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31); return fp(ac + (ad >> 32) + (bc >> 32) + (mid >> 32), exp); #endif } // Returns cached power (of 10) c_k = c_k.f * pow(2, c_k.e) such that its // (binary) exponent satisfies min_exponent <= c_k.e <= min_exponent + 28. FMT_FUNC fp get_cached_power(int min_exponent, int& pow10_exponent) { const double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10) int index = static_cast( std::ceil((min_exponent + fp::significand_size - 1) * one_over_log2_10)); // Decimal exponent of the first (smallest) cached power of 10. const int first_dec_exp = -348; // Difference between 2 consecutive decimal exponents in cached powers of 10. const int dec_exp_step = 8; index = (index - first_dec_exp - 1) / dec_exp_step + 1; pow10_exponent = first_dec_exp + index * dec_exp_step; return fp(data::pow10_significands[index], data::pow10_exponents[index]); } enum round_direction { unknown, up, down }; // Given the divisor (normally a power of 10), the remainder = v % divisor for // some number v and the error, returns whether v should be rounded up, down, or // whether the rounding direction can't be determined due to error. // error should be less than divisor / 2. inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder, uint64_t error) { FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow. FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow. FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow. // Round down if (remainder + error) * 2 <= divisor. if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2) return down; // Round up if (remainder - error) * 2 >= divisor. if (remainder >= error && remainder - error >= divisor - (remainder - error)) { return up; } return unknown; } namespace digits { enum result { more, // Generate more digits. done, // Done generating digits. error // Digit generation cancelled due to an error. }; } // Generates output using the Grisu digit-gen algorithm. // error: the size of the region (lower, upper) outside of which numbers // definitely do not round to value (Delta in Grisu3). template digits::result grisu_gen_digits(fp value, uint64_t error, int& exp, Handler& handler) { fp one(1ull << -value.e, value.e); // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be // zero because it contains a product of two 64-bit numbers with MSB set (due // to normalization) - 1, shifted right by at most 60 bits. uint32_t integral = static_cast(value.f >> -one.e); FMT_ASSERT(integral != 0, ""); FMT_ASSERT(integral == value.f >> -one.e, ""); // The fractional part of scaled value (p2 in Grisu) c = value % one. uint64_t fractional = value.f & (one.f - 1); exp = count_digits(integral); // kappa in Grisu. // Divide by 10 to prevent overflow. auto result = handler.on_start(data::powers_of_10_64[exp - 1] << -one.e, value.f / 10, error * 10, exp); if (result != digits::more) return result; // Generate digits for the integral part. This can produce up to 10 digits. do { uint32_t digit = 0; // This optimization by miloyip reduces the number of integer divisions by // one per iteration. switch (exp) { case 10: digit = integral / 1000000000; integral %= 1000000000; break; case 9: digit = integral / 100000000; integral %= 100000000; break; case 8: digit = integral / 10000000; integral %= 10000000; break; case 7: digit = integral / 1000000; integral %= 1000000; break; case 6: digit = integral / 100000; integral %= 100000; break; case 5: digit = integral / 10000; integral %= 10000; break; case 4: digit = integral / 1000; integral %= 1000; break; case 3: digit = integral / 100; integral %= 100; break; case 2: digit = integral / 10; integral %= 10; break; case 1: digit = integral; integral = 0; break; default: FMT_ASSERT(false, "invalid number of digits"); } --exp; uint64_t remainder = (static_cast(integral) << -one.e) + fractional; result = handler.on_digit(static_cast('0' + digit), data::powers_of_10_64[exp] << -one.e, remainder, error, exp, true); if (result != digits::more) return result; } while (exp > 0); // Generate digits for the fractional part. for (;;) { fractional *= 10; error *= 10; char digit = static_cast('0' + static_cast(fractional >> -one.e)); fractional &= one.f - 1; --exp; result = handler.on_digit(digit, one.f, fractional, error, exp, false); if (result != digits::more) return result; } } // The fixed precision digit handler. struct fixed_handler { char* buf; int size; int precision; int exp10; bool fixed; digits::result on_start(uint64_t divisor, uint64_t remainder, uint64_t error, int& exp) { // Non-fixed formats require at least one digit and no precision adjustment. if (!fixed) return digits::more; // Adjust fixed precision by exponent because it is relative to decimal // point. precision += exp + exp10; // Check if precision is satisfied just by leading zeros, e.g. // format("{:.2f}", 0.001) gives "0.00" without generating any digits. if (precision > 0) return digits::more; if (precision < 0) return digits::done; auto dir = get_round_direction(divisor, remainder, error); if (dir == unknown) return digits::error; buf[size++] = dir == up ? '1' : '0'; return digits::done; } digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, uint64_t error, int, bool integral) { FMT_ASSERT(remainder < divisor, ""); buf[size++] = digit; if (size < precision) return digits::more; if (!integral) { // Check if error * 2 < divisor with overflow prevention. // The check is not needed for the integral part because error = 1 // and divisor > (1 << 32) there. if (error >= divisor || error >= divisor - error) return digits::error; } else { FMT_ASSERT(error == 1 && divisor > 2, ""); } auto dir = get_round_direction(divisor, remainder, error); if (dir != up) return dir == down ? digits::done : digits::error; ++buf[size - 1]; for (int i = size - 1; i > 0 && buf[i] > '9'; --i) { buf[i] = '0'; ++buf[i - 1]; } if (buf[0] > '9') { buf[0] = '1'; buf[size++] = '0'; } return digits::done; } }; // The shortest representation digit handler. template struct grisu_shortest_handler { char* buf; int size; // Distance between scaled value and upper bound (wp_W in Grisu3). uint64_t diff; digits::result on_start(uint64_t, uint64_t, uint64_t, int&) { return digits::more; } // Decrement the generated number approaching value from above. void round(uint64_t d, uint64_t divisor, uint64_t& remainder, uint64_t error) { while ( remainder < d && error - remainder >= divisor && (remainder + divisor < d || d - remainder >= remainder + divisor - d)) { --buf[size - 1]; remainder += divisor; } } // Implements Grisu's round_weed. digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, uint64_t error, int exp, bool integral) { buf[size++] = digit; if (remainder >= error) return digits::more; if (GRISU_VERSION != 3) { uint64_t d = integral ? diff : diff * data::powers_of_10_64[-exp]; round(d, divisor, remainder, error); return digits::done; } uint64_t unit = integral ? 1 : data::powers_of_10_64[-exp]; uint64_t up = (diff - 1) * unit; // wp_Wup round(up, divisor, remainder, error); uint64_t down = (diff + 1) * unit; // wp_Wdown if (remainder < down && error - remainder >= divisor && (remainder + divisor < down || down - remainder > remainder + divisor - down)) { return digits::error; } return 2 * unit <= remainder && remainder <= error - 4 * unit ? digits::done : digits::error; } }; template > FMT_API bool grisu_format(Double value, buffer& buf, int precision, unsigned options, int& exp) { FMT_ASSERT(value >= 0, "value is negative"); bool fixed = (options & grisu_options::fixed) != 0; if (value <= 0) { // <= instead of == to silence a warning. if (precision <= 0 || !fixed) { exp = 0; buf.push_back('0'); } else { exp = -precision; buf.resize(precision); std::uninitialized_fill_n(buf.data(), precision, '0'); } return true; } fp fp_value(value); const int min_exp = -60; // alpha in Grisu. int cached_exp10 = 0; // K in Grisu. if (precision != -1) { if (precision > 17) return false; fp_value.normalize(); auto cached_pow = get_cached_power( min_exp - (fp_value.e + fp::significand_size), cached_exp10); fp_value = fp_value * cached_pow; fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed}; if (grisu_gen_digits(fp_value, 1, exp, handler) == digits::error) return false; buf.resize(to_unsigned(handler.size)); } else { fp lower, upper; // w^- and w^+ in the Grisu paper. fp_value.compute_boundaries(lower, upper); // Find a cached power of 10 such that multiplying upper by it will bring // the exponent in the range [min_exp, -32]. auto cached_pow = get_cached_power( // \tilde{c}_{-k} in Grisu. min_exp - (upper.e + fp::significand_size), cached_exp10); fp_value.normalize(); fp_value = fp_value * cached_pow; lower = lower * cached_pow; // \tilde{M}^- in Grisu. upper = upper * cached_pow; // \tilde{M}^+ in Grisu. assert(min_exp <= upper.e && upper.e <= -32); auto result = digits::result(); int size = 0; if ((options & grisu_options::grisu3) != 0) { --lower.f; // \tilde{M}^- - 1 ulp -> M^-_{\downarrow}. ++upper.f; // \tilde{M}^+ + 1 ulp -> M^+_{\uparrow}. // Numbers outside of (lower, upper) definitely do not round to value. grisu_shortest_handler<3> handler{buf.data(), 0, (upper - fp_value).f}; result = grisu_gen_digits(upper, upper.f - lower.f, exp, handler); size = handler.size; } else { ++lower.f; // \tilde{M}^- + 1 ulp -> M^-_{\uparrow}. --upper.f; // \tilde{M}^+ - 1 ulp -> M^+_{\downarrow}. grisu_shortest_handler<2> handler{buf.data(), 0, (upper - fp_value).f}; result = grisu_gen_digits(upper, upper.f - lower.f, exp, handler); size = handler.size; } if (result == digits::error) return false; buf.resize(to_unsigned(size)); } exp -= cached_exp10; return true; } template char* sprintf_format(Double value, internal::buffer& buf, sprintf_specs specs) { // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. FMT_ASSERT(buf.capacity() != 0, "empty buffer"); // Build format string. enum { max_format_size = 10 }; // longest format: %#-*.*Lg char format[max_format_size]; char* format_ptr = format; *format_ptr++ = '%'; if (specs.alt || !specs.type) *format_ptr++ = '#'; if (specs.precision >= 0) { *format_ptr++ = '.'; *format_ptr++ = '*'; } if (std::is_same::value) *format_ptr++ = 'L'; char type = specs.type; if (type == '%') type = 'f'; else if (type == 0 || type == 'n') type = 'g'; #if FMT_MSC_VER if (type == 'F') { // MSVC's printf doesn't support 'F'. type = 'f'; } #endif *format_ptr++ = type; *format_ptr = '\0'; // Format using snprintf. char* start = nullptr; char* decimal_point_pos = nullptr; for (;;) { std::size_t buffer_size = buf.capacity(); start = &buf[0]; int result = format_float(start, buffer_size, format, specs.precision, value); if (result >= 0) { unsigned n = internal::to_unsigned(result); if (n < buf.capacity()) { // Find the decimal point. auto p = buf.data(), end = p + n; if (*p == '+' || *p == '-') ++p; if (specs.type != 'a' && specs.type != 'A') { while (p < end && *p >= '0' && *p <= '9') ++p; if (p < end && *p != 'e' && *p != 'E') { decimal_point_pos = p; if (!specs.type) { // Keep only one trailing zero after the decimal point. ++p; if (*p == '0') ++p; while (p != end && *p >= '1' && *p <= '9') ++p; char* where = p; while (p != end && *p == '0') ++p; if (p == end || *p < '0' || *p > '9') { if (p != end) std::memmove(where, p, to_unsigned(end - p)); n -= static_cast(p - where); } } } } buf.resize(n); break; // The buffer is large enough - continue with formatting. } buf.reserve(n + 1); } else { // If result is negative we ask to increase the capacity by at least 1, // but as std::vector, the buffer grows exponentially. buf.reserve(buf.capacity() + 1); } } return decimal_point_pos; } } // namespace internal #if FMT_USE_WINDOWS_H FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) { static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; if (s.size() > INT_MAX) FMT_THROW(windows_error(ERROR_INVALID_PARAMETER, ERROR_MSG)); int s_size = static_cast(s.size()); if (s_size == 0) { // MultiByteToWideChar does not support zero length, handle separately. buffer_.resize(1); buffer_[0] = 0; return; } int length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, nullptr, 0); if (length == 0) FMT_THROW(windows_error(GetLastError(), ERROR_MSG)); buffer_.resize(length + 1); length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length); if (length == 0) FMT_THROW(windows_error(GetLastError(), ERROR_MSG)); buffer_[length] = 0; } FMT_FUNC internal::utf16_to_utf8::utf16_to_utf8(wstring_view s) { if (int error_code = convert(s)) { FMT_THROW(windows_error(error_code, "cannot convert string from UTF-16 to UTF-8")); } } FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) { if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER; int s_size = static_cast(s.size()); if (s_size == 0) { // WideCharToMultiByte does not support zero length, handle separately. buffer_.resize(1); buffer_[0] = 0; return 0; } int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, nullptr, 0, nullptr, nullptr); if (length == 0) return GetLastError(); buffer_.resize(length + 1); length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, nullptr, nullptr); if (length == 0) return GetLastError(); buffer_[length] = 0; return 0; } FMT_FUNC void windows_error::init(int err_code, string_view format_str, format_args args) { error_code_ = err_code; memory_buffer buffer; internal::format_windows_error(buffer, err_code, vformat(format_str, args)); std::runtime_error& base = *this; base = std::runtime_error(to_string(buffer)); } FMT_FUNC void internal::format_windows_error(internal::buffer& out, int error_code, string_view message) FMT_NOEXCEPT { FMT_TRY { wmemory_buffer buf; buf.resize(inline_buffer_size); for (;;) { wchar_t* system_message = &buf[0]; int result = FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message, static_cast(buf.size()), nullptr); if (result != 0) { utf16_to_utf8 utf8_message; if (utf8_message.convert(system_message) == ERROR_SUCCESS) { internal::writer w(out); w.write(message); w.write(": "); w.write(utf8_message); return; } break; } if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) break; // Can't get error message, report error code instead. buf.resize(buf.size() * 2); } } FMT_CATCH(...) {} format_error_code(out, error_code, message); } #endif // FMT_USE_WINDOWS_H FMT_FUNC void format_system_error(internal::buffer& out, int error_code, string_view message) FMT_NOEXCEPT { FMT_TRY { memory_buffer buf; buf.resize(inline_buffer_size); for (;;) { char* system_message = &buf[0]; int result = internal::safe_strerror(error_code, system_message, buf.size()); if (result == 0) { internal::writer w(out); w.write(message); w.write(": "); w.write(system_message); return; } if (result != ERANGE) break; // Can't get error message, report error code instead. buf.resize(buf.size() * 2); } } FMT_CATCH(...) {} format_error_code(out, error_code, message); } FMT_FUNC void internal::error_handler::on_error(const char* message) { FMT_THROW(format_error(message)); } FMT_FUNC void report_system_error(int error_code, fmt::string_view message) FMT_NOEXCEPT { report_error(format_system_error, error_code, message); } #if FMT_USE_WINDOWS_H FMT_FUNC void report_windows_error(int error_code, fmt::string_view message) FMT_NOEXCEPT { report_error(internal::format_windows_error, error_code, message); } #endif FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { memory_buffer buffer; internal::vformat_to(buffer, format_str, basic_format_args>(args)); internal::fwrite_fully(buffer.data(), 1, buffer.size(), f); } FMT_FUNC void vprint(std::FILE* f, wstring_view format_str, wformat_args args) { wmemory_buffer buffer; internal::vformat_to(buffer, format_str, args); internal::fwrite_fully(buffer.data(), sizeof(wchar_t), buffer.size(), f); } FMT_FUNC void vprint(string_view format_str, format_args args) { vprint(stdout, format_str, args); } FMT_FUNC void vprint(wstring_view format_str, wformat_args args) { vprint(stdout, format_str, args); } FMT_END_NAMESPACE #ifdef _MSC_VER # pragma warning(pop) #endif #endif // FMT_FORMAT_INL_H_ ================================================ FILE: src/third_party/fmt/include/fmt/format.h ================================================ /* Formatting library for C++ Copyright (c) 2012 - present, Victor Zverovich All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FMT_FORMAT_H_ #define FMT_FORMAT_H_ #include #include #include #include #include #include #include #include #include #include "core.h" #ifdef __clang__ # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else # define FMT_CLANG_VERSION 0 #endif #ifdef __INTEL_COMPILER # define FMT_ICC_VERSION __INTEL_COMPILER #elif defined(__ICL) # define FMT_ICC_VERSION __ICL #else # define FMT_ICC_VERSION 0 #endif #ifdef __NVCC__ # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__) #else # define FMT_CUDA_VERSION 0 #endif #ifdef __has_builtin # define FMT_HAS_BUILTIN(x) __has_builtin(x) #else # define FMT_HAS_BUILTIN(x) 0 #endif #ifndef FMT_THROW # if FMT_EXCEPTIONS # if FMT_MSC_VER FMT_BEGIN_NAMESPACE namespace internal { template inline void do_throw(const Exception& x) { // Silence unreachable code warnings in MSVC because these are nearly // impossible to fix in a generic code. volatile bool b = true; if (b) throw x; } } // namespace internal FMT_END_NAMESPACE # define FMT_THROW(x) fmt::internal::do_throw(x) # else # define FMT_THROW(x) throw x # endif # else # define FMT_THROW(x) \ do { \ static_cast(sizeof(x)); \ assert(false); \ } while (false) # endif #endif #ifndef FMT_USE_USER_DEFINED_LITERALS // For Intel and NVIDIA compilers both they and the system gcc/msc support UDLs. # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ FMT_MSC_VER >= 1900) && \ (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || FMT_ICC_VERSION >= 1500 || \ FMT_CUDA_VERSION >= 700) # define FMT_USE_USER_DEFINED_LITERALS 1 # else # define FMT_USE_USER_DEFINED_LITERALS 0 # endif #endif #ifndef FMT_USE_UDL_TEMPLATE // EDG front end based compilers (icc, nvcc) do not support UDL templates yet // and GCC 9 warns about them. # if FMT_USE_USER_DEFINED_LITERALS && FMT_ICC_VERSION == 0 && \ FMT_CUDA_VERSION == 0 && \ ((FMT_GCC_VERSION >= 600 && FMT_GCC_VERSION <= 900 && \ __cplusplus >= 201402L) || \ FMT_CLANG_VERSION >= 304) # define FMT_USE_UDL_TEMPLATE 1 # else # define FMT_USE_UDL_TEMPLATE 0 # endif #endif #ifdef FMT_USE_INT128 // Do nothing. #elif defined(__SIZEOF_INT128__) # define FMT_USE_INT128 1 #else # define FMT_USE_INT128 0 #endif // __builtin_clz is broken in clang with Microsoft CodeGen: // https://github.com/fmtlib/fmt/issues/519 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) #endif #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) #endif // Some compilers masquerade as both MSVC and GCC-likes or otherwise support // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the // MSVC intrinsics if the clz and clzll builtins are not available. #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED) # include // _BitScanReverse, _BitScanReverse64 FMT_BEGIN_NAMESPACE namespace internal { // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. # ifndef __clang__ # pragma intrinsic(_BitScanReverse) # endif inline uint32_t clz(uint32_t x) { unsigned long r = 0; _BitScanReverse(&r, x); assert(x != 0); // Static analysis complains about using uninitialized data // "r", but the only way that can happen is if "x" is 0, // which the callers guarantee to not happen. # pragma warning(suppress : 6102) return 31 - r; } # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n) # if defined(_WIN64) && !defined(__clang__) # pragma intrinsic(_BitScanReverse64) # endif inline uint32_t clzll(uint64_t x) { unsigned long r = 0; # ifdef _WIN64 _BitScanReverse64(&r, x); # else // Scan the high 32 bits. if (_BitScanReverse(&r, static_cast(x >> 32))) return 63 - (r + 32); // Scan the low 32 bits. _BitScanReverse(&r, static_cast(x)); # endif assert(x != 0); // Static analysis complains about using uninitialized data // "r", but the only way that can happen is if "x" is 0, // which the callers guarantee to not happen. # pragma warning(suppress : 6102) return 63 - r; } # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n) } // namespace internal FMT_END_NAMESPACE #endif FMT_BEGIN_NAMESPACE namespace internal { // A fallback implementation of uintptr_t for systems that lack it. struct fallback_uintptr { unsigned char value[sizeof(void*)]; }; #ifdef UINTPTR_MAX using uintptr_t = ::uintptr_t; #else using uintptr_t = fallback_uintptr; #endif // An equivalent of `*reinterpret_cast(&source)` that doesn't produce // undefined behavior (e.g. due to type aliasing). // Example: uint64_t d = bit_cast(2.718); template inline Dest bit_cast(const Source& source) { static_assert(sizeof(Dest) == sizeof(Source), "size mismatch"); Dest dest; std::memcpy(&dest, &source, sizeof(dest)); return dest; } // An approximation of iterator_t for pre-C++20 systems. template using iterator_t = decltype(std::begin(std::declval())); // Detect the iterator category of *any* given type in a SFINAE-friendly way. // Unfortunately, older implementations of std::iterator_traits are not safe // for use in a SFINAE-context. template struct iterator_category : std::false_type {}; template struct iterator_category { using type = std::random_access_iterator_tag; }; template struct iterator_category> { using type = typename It::iterator_category; }; // Detect if *any* given type models the OutputIterator concept. template class is_output_iterator { // Check for mutability because all iterator categories derived from // std::input_iterator_tag *may* also meet the requirements of an // OutputIterator, thereby falling into the category of 'mutable iterators' // [iterator.requirements.general] clause 4. The compiler reveals this // property only at the point of *actually dereferencing* the iterator! template static decltype(*(std::declval())) test(std::input_iterator_tag); template static char& test(std::output_iterator_tag); template static const char& test(...); using type = decltype(test(typename iterator_category::type{})); public: static const bool value = !std::is_const>::value; }; // A workaround for std::string not having mutable data() until C++17. template inline Char* get_data(std::basic_string& s) { return &s[0]; } template inline typename Container::value_type* get_data(Container& c) { return c.data(); } #ifdef _SECURE_SCL // Make a checked iterator to avoid MSVC warnings. template using checked_ptr = stdext::checked_array_iterator; template checked_ptr make_checked(T* p, std::size_t size) { return {p, size}; } #else template using checked_ptr = T*; template inline T* make_checked(T* p, std::size_t) { return p; } #endif template ::value)> inline checked_ptr reserve( std::back_insert_iterator& it, std::size_t n) { Container& c = get_container(it); std::size_t size = c.size(); c.resize(size + n); return make_checked(get_data(c) + size, n); } template inline Iterator& reserve(Iterator& it, std::size_t) { return it; } // An output iterator that counts the number of objects written to it and // discards them. template class counting_iterator { private: std::size_t count_; mutable T blackhole_; public: using iterator_category = std::output_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&; using _Unchecked_type = counting_iterator; // Mark iterator as checked. counting_iterator() : count_(0) {} std::size_t count() const { return count_; } counting_iterator& operator++() { ++count_; return *this; } counting_iterator operator++(int) { auto it = *this; ++*this; return it; } T& operator*() const { return blackhole_; } }; template class truncating_iterator_base { protected: OutputIt out_; std::size_t limit_; std::size_t count_; truncating_iterator_base(OutputIt out, std::size_t limit) : out_(out), limit_(limit), count_(0) {} public: using iterator_category = std::output_iterator_tag; using difference_type = void; using pointer = void; using reference = void; using _Unchecked_type = truncating_iterator_base; // Mark iterator as checked. OutputIt base() const { return out_; } std::size_t count() const { return count_; } }; // An output iterator that truncates the output and counts the number of objects // written to it. template ::value_type>::type> class truncating_iterator; template class truncating_iterator : public truncating_iterator_base { using traits = std::iterator_traits; mutable typename traits::value_type blackhole_; public: using value_type = typename traits::value_type; truncating_iterator(OutputIt out, std::size_t limit) : truncating_iterator_base(out, limit) {} truncating_iterator& operator++() { if (this->count_++ < this->limit_) ++this->out_; return *this; } truncating_iterator operator++(int) { auto it = *this; ++*this; return it; } value_type& operator*() const { return this->count_ < this->limit_ ? *this->out_ : blackhole_; } }; template class truncating_iterator : public truncating_iterator_base { public: using value_type = typename OutputIt::container_type::value_type; truncating_iterator(OutputIt out, std::size_t limit) : truncating_iterator_base(out, limit) {} truncating_iterator& operator=(value_type val) { if (this->count_++ < this->limit_) this->out_ = val; return *this; } truncating_iterator& operator++() { return *this; } truncating_iterator& operator++(int) { return *this; } truncating_iterator& operator*() { return *this; } }; // A range with the specified output iterator and value type. template class output_range { private: OutputIt it_; public: using value_type = T; using iterator = OutputIt; struct sentinel {}; explicit output_range(OutputIt it) : it_(it) {} OutputIt begin() const { return it_; } sentinel end() const { return {}; } // Sentinel is not used yet. }; // A range with an iterator appending to a buffer. template class buffer_range : public output_range>, T> { public: using iterator = std::back_insert_iterator>; using output_range::output_range; buffer_range(buffer& buf) : output_range(std::back_inserter(buf)) {} }; template inline size_t count_code_points(basic_string_view s) { return s.size(); } // Counts the number of code points in a UTF-8 string. inline size_t count_code_points(basic_string_view s) { const char8_t* data = s.data(); size_t num_code_points = 0; for (size_t i = 0, size = s.size(); i != size; ++i) { if ((data[i] & 0xc0) != 0x80) ++num_code_points; } return num_code_points; } inline char8_t to_char8_t(char c) { return static_cast(c); } template using needs_conversion = bool_constant< std::is_same::value_type, char>::value && std::is_same::value>; template ::value)> OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { return std::copy(begin, end, it); } template ::value)> OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { return std::transform(begin, end, it, to_char8_t); } #ifndef FMT_USE_GRISU # define FMT_USE_GRISU 1 #endif template constexpr bool use_grisu() { return FMT_USE_GRISU && std::numeric_limits::is_iec559 && sizeof(T) <= sizeof(double); } template template void buffer::append(const U* begin, const U* end) { std::size_t new_size = size_ + to_unsigned(end - begin); reserve(new_size); std::uninitialized_copy(begin, end, make_checked(ptr_, capacity_) + size_); size_ = new_size; } } // namespace internal // A UTF-8 string view. class u8string_view : public basic_string_view { public: u8string_view(const char* s) : basic_string_view(reinterpret_cast(s)) {} u8string_view(const char* s, size_t count) FMT_NOEXCEPT : basic_string_view(reinterpret_cast(s), count) { } }; #if FMT_USE_USER_DEFINED_LITERALS inline namespace literals { inline u8string_view operator"" _u(const char* s, std::size_t n) { return {s, n}; } } // namespace literals #endif // The number of characters to store in the basic_memory_buffer object itself // to avoid dynamic memory allocation. enum { inline_buffer_size = 500 }; /** \rst A dynamically growing memory buffer for trivially copyable/constructible types with the first ``SIZE`` elements stored in the object itself. You can use one of the following type aliases for common character types: +----------------+------------------------------+ | Type | Definition | +================+==============================+ | memory_buffer | basic_memory_buffer | +----------------+------------------------------+ | wmemory_buffer | basic_memory_buffer | +----------------+------------------------------+ **Example**:: fmt::memory_buffer out; format_to(out, "The answer is {}.", 42); This will append the following output to the ``out`` object: .. code-block:: none The answer is 42. The output can be converted to an ``std::string`` with ``to_string(out)``. \endrst */ template > class basic_memory_buffer : private Allocator, public internal::buffer { private: T store_[SIZE]; // Deallocate memory allocated by the buffer. void deallocate() { T* data = this->data(); if (data != store_) Allocator::deallocate(data, this->capacity()); } protected: void grow(std::size_t size) FMT_OVERRIDE; public: using value_type = T; using const_reference = const T&; explicit basic_memory_buffer(const Allocator& alloc = Allocator()) : Allocator(alloc) { this->set(store_, SIZE); } ~basic_memory_buffer() { deallocate(); } private: // Move data from other to this buffer. void move(basic_memory_buffer& other) { Allocator &this_alloc = *this, &other_alloc = other; this_alloc = std::move(other_alloc); T* data = other.data(); std::size_t size = other.size(), capacity = other.capacity(); if (data == other.store_) { this->set(store_, capacity); std::uninitialized_copy(other.store_, other.store_ + size, internal::make_checked(store_, capacity)); } else { this->set(data, capacity); // Set pointer to the inline array so that delete is not called // when deallocating. other.set(other.store_, 0); } this->resize(size); } public: /** \rst Constructs a :class:`fmt::basic_memory_buffer` object moving the content of the other object to it. \endrst */ basic_memory_buffer(basic_memory_buffer&& other) { move(other); } /** \rst Moves the content of the other ``basic_memory_buffer`` object to this one. \endrst */ basic_memory_buffer& operator=(basic_memory_buffer&& other) { assert(this != &other); deallocate(); move(other); return *this; } // Returns a copy of the allocator associated with this buffer. Allocator get_allocator() const { return *this; } }; template void basic_memory_buffer::grow(std::size_t size) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (size > 1000) throw std::runtime_error("fuzz mode - won't grow that much"); #endif std::size_t old_capacity = this->capacity(); std::size_t new_capacity = old_capacity + old_capacity / 2; if (size > new_capacity) new_capacity = size; T* old_data = this->data(); T* new_data = std::allocator_traits::allocate(*this, new_capacity); // The following code doesn't throw, so the raw pointer above doesn't leak. std::uninitialized_copy(old_data, old_data + this->size(), internal::make_checked(new_data, new_capacity)); this->set(new_data, new_capacity); // deallocate must not throw according to the standard, but even if it does, // the buffer already uses the new storage and will deallocate it in // destructor. if (old_data != store_) Allocator::deallocate(old_data, old_capacity); } using memory_buffer = basic_memory_buffer; using wmemory_buffer = basic_memory_buffer; /** A formatting error such as invalid format string. */ class FMT_API format_error : public std::runtime_error { public: explicit format_error(const char* message) : std::runtime_error(message) {} explicit format_error(const std::string& message) : std::runtime_error(message) {} ~format_error() FMT_NOEXCEPT; }; namespace internal { // Returns true if value is negative, false otherwise. // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. template ::is_signed)> FMT_CONSTEXPR bool is_negative(T value) { return value < 0; } template ::is_signed)> FMT_CONSTEXPR bool is_negative(T) { return false; } // Smallest of uint32_t and uint64_t that is large enough to represent all // values of T. template using uint32_or_64_t = conditional_t::digits <= 32, uint32_t, uint64_t>; // Static data is placed in this class template for the header-only config. template struct FMT_EXTERN_TEMPLATE_API basic_data { static const uint64_t powers_of_10_64[]; static const uint32_t zero_or_powers_of_10_32[]; static const uint64_t zero_or_powers_of_10_64[]; static const uint64_t pow10_significands[]; static const int16_t pow10_exponents[]; static const char digits[]; static const char hex_digits[]; static const char foreground_color[]; static const char background_color[]; static const char reset_color[5]; static const wchar_t wreset_color[5]; }; FMT_EXTERN template struct basic_data; // This is a struct rather than an alias to avoid shadowing warnings in gcc. struct data : basic_data<> {}; #ifdef FMT_BUILTIN_CLZLL // Returns the number of decimal digits in n. Leading zeros are not counted // except for n == 0 in which case count_digits returns 1. inline int count_digits(uint64_t n) { // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12; return t - (n < data::zero_or_powers_of_10_64[t]) + 1; } #else // Fallback version of count_digits used when __builtin_clz is not available. inline int count_digits(uint64_t n) { int count = 1; for (;;) { // Integer division is slow so do it for a group of four digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. if (n < 10) return count; if (n < 100) return count + 1; if (n < 1000) return count + 2; if (n < 10000) return count + 3; n /= 10000u; count += 4; } } #endif // Counts the number of digits in n. BITS = log2(radix). template inline int count_digits(UInt n) { int num_digits = 0; do { ++num_digits; } while ((n >>= BITS) != 0); return num_digits; } template <> int count_digits<4>(internal::fallback_uintptr n); #if FMT_HAS_CPP_ATTRIBUTE(always_inline) # define FMT_ALWAYS_INLINE __attribute__((always_inline)) #else # define FMT_ALWAYS_INLINE #endif template inline char* lg(uint32_t n, Handler h) FMT_ALWAYS_INLINE; // Computes g = floor(log10(n)) and calls h.on(n); template inline char* lg(uint32_t n, Handler h) { return n < 100 ? n < 10 ? h.template on<0>(n) : h.template on<1>(n) : n < 1000000 ? n < 10000 ? n < 1000 ? h.template on<2>(n) : h.template on<3>(n) : n < 100000 ? h.template on<4>(n) : h.template on<5>(n) : n < 100000000 ? n < 10000000 ? h.template on<6>(n) : h.template on<7>(n) : n < 1000000000 ? h.template on<8>(n) : h.template on<9>(n); } // An lg handler that formats a decimal number. // Usage: lg(n, decimal_formatter(buffer)); class decimal_formatter { private: char* buffer_; void write_pair(unsigned N, uint32_t index) { std::memcpy(buffer_ + N, data::digits + index * 2, 2); } public: explicit decimal_formatter(char* buf) : buffer_(buf) {} template char* on(uint32_t u) { if (N == 0) { *buffer_ = static_cast(u) + '0'; } else if (N == 1) { write_pair(0, u); } else { // The idea of using 4.32 fixed-point numbers is based on // https://github.com/jeaiii/itoa unsigned n = N - 1; unsigned a = n / 5 * n * 53 / 16; uint64_t t = ((1ULL << (32 + a)) / data::zero_or_powers_of_10_32[n] + 1 - n / 9); t = ((t * u) >> a) + n / 5 * 4; write_pair(0, t >> 32); for (unsigned i = 2; i < N; i += 2) { t = 100ULL * static_cast(t); write_pair(i, t >> 32); } if (N % 2 == 0) { buffer_[N] = static_cast((10ULL * static_cast(t)) >> 32) + '0'; } } return buffer_ += N + 1; } }; #ifdef FMT_BUILTIN_CLZ // Optional version of count_digits for better performance on 32-bit platforms. inline int count_digits(uint32_t n) { int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12; return t - (n < data::zero_or_powers_of_10_32[t]) + 1; } #endif template FMT_API Char thousands_sep_impl(locale_ref loc); template inline Char thousands_sep(locale_ref loc) { return Char(thousands_sep_impl(loc)); } template <> inline wchar_t thousands_sep(locale_ref loc) { return thousands_sep_impl(loc); } template FMT_API Char decimal_point_impl(locale_ref loc); template inline Char decimal_point(locale_ref loc) { return Char(decimal_point_impl(loc)); } template <> inline wchar_t decimal_point(locale_ref loc) { return decimal_point_impl(loc); } // Formats a decimal unsigned integer value writing into buffer. // add_thousands_sep is called after writing each char to add a thousands // separator if necessary. template inline Char* format_decimal(Char* buffer, UInt value, int num_digits, F add_thousands_sep) { FMT_ASSERT(num_digits >= 0, "invalid digit count"); buffer += num_digits; Char* end = buffer; while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. unsigned index = static_cast((value % 100) * 2); value /= 100; *--buffer = static_cast(data::digits[index + 1]); add_thousands_sep(buffer); *--buffer = static_cast(data::digits[index]); add_thousands_sep(buffer); } if (value < 10) { *--buffer = static_cast('0' + value); return end; } unsigned index = static_cast(value * 2); *--buffer = static_cast(data::digits[index + 1]); add_thousands_sep(buffer); *--buffer = static_cast(data::digits[index]); return end; } template inline Iterator format_decimal(Iterator out, UInt value, int num_digits, F add_thousands_sep) { FMT_ASSERT(num_digits >= 0, "invalid digit count"); // Buffer should be large enough to hold all digits (<= digits10 + 1). enum { max_size = std::numeric_limits::digits10 + 1 }; Char buffer[max_size + max_size / 3]; auto end = format_decimal(buffer, value, num_digits, add_thousands_sep); return internal::copy_str(buffer, end, out); } template inline It format_decimal(It out, UInt value, int num_digits) { return format_decimal(out, value, num_digits, [](Char*) {}); } template inline Char* format_uint(Char* buffer, UInt value, int num_digits, bool upper = false) { buffer += num_digits; Char* end = buffer; do { const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits; unsigned digit = (value & ((1 << BASE_BITS) - 1)); *--buffer = static_cast(BASE_BITS < 4 ? static_cast('0' + digit) : digits[digit]); } while ((value >>= BASE_BITS) != 0); return end; } template Char* format_uint(Char* buffer, internal::fallback_uintptr n, int num_digits, bool = false) { auto char_digits = std::numeric_limits::digits / 4; int start = (num_digits + char_digits - 1) / char_digits - 1; if (int start_digits = num_digits % char_digits) { unsigned value = n.value[start--]; buffer = format_uint(buffer, value, start_digits); } for (; start >= 0; --start) { unsigned value = n.value[start]; buffer += char_digits; auto p = buffer; for (int i = 0; i < char_digits; ++i) { unsigned digit = (value & ((1 << BASE_BITS) - 1)); *--p = static_cast(data::hex_digits[digit]); value >>= BASE_BITS; } } return buffer; } template inline It format_uint(It out, UInt value, int num_digits, bool upper = false) { // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1). char buffer[std::numeric_limits::digits / BASE_BITS + 1]; format_uint(buffer, value, num_digits, upper); return internal::copy_str(buffer, buffer + num_digits, out); } #ifndef _WIN32 # define FMT_USE_WINDOWS_H 0 #elif !defined(FMT_USE_WINDOWS_H) # define FMT_USE_WINDOWS_H 1 #endif // Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h. // All the functionality that relies on it will be disabled too. #if FMT_USE_WINDOWS_H // A converter from UTF-8 to UTF-16. // It is only provided for Windows since other systems support UTF-8 natively. class utf8_to_utf16 { private: wmemory_buffer buffer_; public: FMT_API explicit utf8_to_utf16(string_view s); operator wstring_view() const { return wstring_view(&buffer_[0], size()); } size_t size() const { return buffer_.size() - 1; } const wchar_t* c_str() const { return &buffer_[0]; } std::wstring str() const { return std::wstring(&buffer_[0], size()); } }; // A converter from UTF-16 to UTF-8. // It is only provided for Windows since other systems support UTF-8 natively. class utf16_to_utf8 { private: memory_buffer buffer_; public: utf16_to_utf8() {} FMT_API explicit utf16_to_utf8(wstring_view s); operator string_view() const { return string_view(&buffer_[0], size()); } size_t size() const { return buffer_.size() - 1; } const char* c_str() const { return &buffer_[0]; } std::string str() const { return std::string(&buffer_[0], size()); } // Performs conversion returning a system error code instead of // throwing exception on conversion error. This method may still throw // in case of memory allocation error. FMT_API int convert(wstring_view s); }; FMT_API void format_windows_error(fmt::internal::buffer& out, int error_code, fmt::string_view message) FMT_NOEXCEPT; #endif template struct null {}; // Workaround an array initialization issue in gcc 4.8. template struct fill_t { private: Char data_[6]; public: FMT_CONSTEXPR Char& operator[](size_t index) { return data_[index]; } FMT_CONSTEXPR const Char& operator[](size_t index) const { return data_[index]; } static FMT_CONSTEXPR fill_t make() { auto fill = fill_t(); fill[0] = Char(' '); return fill; } }; } // namespace internal // We cannot use enum classes as bit fields because of a gcc bug // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414. namespace align { enum type { none, left, right, center, numeric }; } using align_t = align::type; namespace sign { enum type { none, minus, plus, space }; } using sign_t = sign::type; // Format specifiers for built-in and string types. template struct basic_format_specs { int width; int precision; char type; align_t align : 4; sign_t sign : 3; bool alt : 1; // Alternate form ('#'). internal::fill_t fill; constexpr basic_format_specs() : width(0), precision(-1), type(0), align(align::none), sign(sign::none), alt(false), fill(internal::fill_t::make()) {} }; using format_specs = basic_format_specs; namespace internal { // Writes the exponent exp in the form "[+-]d{2,3}" to buffer. template It write_exponent(int exp, It it) { FMT_ASSERT(-1000 < exp && exp < 1000, "exponent out of range"); if (exp < 0) { *it++ = static_cast('-'); exp = -exp; } else { *it++ = static_cast('+'); } if (exp >= 100) { *it++ = static_cast(static_cast('0' + exp / 100)); exp %= 100; } const char* d = data::digits + exp * 2; *it++ = static_cast(d[0]); *it++ = static_cast(d[1]); return it; } struct gen_digits_params { int num_digits; bool fixed; bool upper; bool trailing_zeros; }; // The number is given as v = digits * pow(10, exp). template It grisu_prettify(const char* digits, int size, int exp, It it, gen_digits_params params, Char decimal_point) { // pow(10, full_exp - 1) <= v <= pow(10, full_exp). int full_exp = size + exp; if (!params.fixed) { // Insert a decimal point after the first digit and add an exponent. *it++ = static_cast(*digits); if (size > 1) *it++ = decimal_point; exp += size - 1; it = copy_str(digits + 1, digits + size, it); if (size < params.num_digits) it = std::fill_n(it, params.num_digits - size, static_cast('0')); *it++ = static_cast(params.upper ? 'E' : 'e'); return write_exponent(exp, it); } if (size <= full_exp) { // 1234e7 -> 12340000000[.0+] it = copy_str(digits, digits + size, it); it = std::fill_n(it, full_exp - size, static_cast('0')); int num_zeros = (std::max)(params.num_digits - full_exp, 1); if (params.trailing_zeros) { *it++ = decimal_point; #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (num_zeros > 1000) throw std::runtime_error("fuzz mode - avoiding excessive cpu use"); #endif it = std::fill_n(it, num_zeros, static_cast('0')); } } else if (full_exp > 0) { // 1234e-2 -> 12.34[0+] it = copy_str(digits, digits + full_exp, it); if (!params.trailing_zeros) { // Remove trailing zeros. while (size > full_exp && digits[size - 1] == '0') --size; if (size != full_exp) *it++ = decimal_point; return copy_str(digits + full_exp, digits + size, it); } *it++ = decimal_point; it = copy_str(digits + full_exp, digits + size, it); if (params.num_digits > size) { // Add trailing zeros. int num_zeros = params.num_digits - size; it = std::fill_n(it, num_zeros, static_cast('0')); } } else { // 1234e-6 -> 0.001234 *it++ = static_cast('0'); int num_zeros = -full_exp; if (params.num_digits >= 0 && params.num_digits < num_zeros) num_zeros = params.num_digits; if (!params.trailing_zeros) while (size > 0 && digits[size - 1] == '0') --size; if (num_zeros != 0 || size != 0) { *it++ = decimal_point; it = std::fill_n(it, num_zeros, static_cast('0')); it = copy_str(digits, digits + size, it); } } return it; } namespace grisu_options { enum { fixed = 1, grisu3 = 2 }; } // Formats value using the Grisu algorithm: // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf template FMT_API bool grisu_format(Double, buffer&, int, unsigned, int&); template inline bool grisu_format(Double, buffer&, int, unsigned, int&) { return false; } struct sprintf_specs { int precision; char type; bool alt : 1; template constexpr sprintf_specs(basic_format_specs specs) : precision(specs.precision), type(specs.type), alt(specs.alt) {} constexpr bool has_precision() const { return precision >= 0; } }; template char* sprintf_format(Double, internal::buffer&, sprintf_specs); template FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) { switch (spec) { case 0: case 'd': handler.on_dec(); break; case 'x': case 'X': handler.on_hex(); break; case 'b': case 'B': handler.on_bin(); break; case 'o': handler.on_oct(); break; case 'n': handler.on_num(); break; default: handler.on_error(); } } template FMT_CONSTEXPR void handle_float_type_spec(char spec, Handler&& handler) { switch (spec) { case 0: case 'g': case 'G': handler.on_general(); break; case 'e': case 'E': handler.on_exp(); break; case 'f': case 'F': handler.on_fixed(); break; case '%': handler.on_percent(); break; case 'a': case 'A': handler.on_hex(); break; case 'n': handler.on_num(); break; default: handler.on_error(); break; } } template FMT_CONSTEXPR void handle_char_specs(const basic_format_specs* specs, Handler&& handler) { if (!specs) return handler.on_char(); if (specs->type && specs->type != 'c') return handler.on_int(); if (specs->align == align::numeric || specs->sign != sign::none || specs->alt) handler.on_error("invalid format specifier for char"); handler.on_char(); } template FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler&& handler) { if (spec == 0 || spec == 's') handler.on_string(); else if (spec == 'p') handler.on_pointer(); else handler.on_error("invalid type specifier"); } template FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler&& eh) { if (spec != 0 && spec != 's') eh.on_error("invalid type specifier"); } template FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler&& eh) { if (spec != 0 && spec != 'p') eh.on_error("invalid type specifier"); } template class int_type_checker : private ErrorHandler { public: FMT_CONSTEXPR explicit int_type_checker(ErrorHandler eh) : ErrorHandler(eh) {} FMT_CONSTEXPR void on_dec() {} FMT_CONSTEXPR void on_hex() {} FMT_CONSTEXPR void on_bin() {} FMT_CONSTEXPR void on_oct() {} FMT_CONSTEXPR void on_num() {} FMT_CONSTEXPR void on_error() { ErrorHandler::on_error("invalid type specifier"); } }; template class float_type_checker : private ErrorHandler { public: FMT_CONSTEXPR explicit float_type_checker(ErrorHandler eh) : ErrorHandler(eh) {} FMT_CONSTEXPR void on_general() {} FMT_CONSTEXPR void on_exp() {} FMT_CONSTEXPR void on_fixed() {} FMT_CONSTEXPR void on_percent() {} FMT_CONSTEXPR void on_hex() {} FMT_CONSTEXPR void on_num() {} FMT_CONSTEXPR void on_error() { ErrorHandler::on_error("invalid type specifier"); } }; template class char_specs_checker : public ErrorHandler { private: char type_; public: FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh) : ErrorHandler(eh), type_(type) {} FMT_CONSTEXPR void on_int() { handle_int_type_spec(type_, int_type_checker(*this)); } FMT_CONSTEXPR void on_char() {} }; template class cstring_type_checker : public ErrorHandler { public: FMT_CONSTEXPR explicit cstring_type_checker(ErrorHandler eh) : ErrorHandler(eh) {} FMT_CONSTEXPR void on_string() {} FMT_CONSTEXPR void on_pointer() {} }; template void arg_map::init(const basic_format_args& args) { if (map_) return; map_ = new entry[internal::to_unsigned(args.max_size())]; if (args.is_packed()) { for (int i = 0;; ++i) { internal::type arg_type = args.type(i); if (arg_type == internal::none_type) return; if (arg_type == internal::named_arg_type) push_back(args.values_[i]); } } for (int i = 0;; ++i) { auto type = args.args_[i].type_; if (type == internal::none_type) return; if (type == internal::named_arg_type) push_back(args.args_[i].value_); } } // This template provides operations for formatting and writing data into a // character range. template class basic_writer { public: using char_type = typename Range::value_type; using iterator = typename Range::iterator; using format_specs = basic_format_specs; private: iterator out_; // Output iterator. internal::locale_ref locale_; // Attempts to reserve space for n extra characters in the output range. // Returns a pointer to the reserved range or a reference to out_. auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) { return internal::reserve(out_, n); } template struct padded_int_writer { size_t size_; string_view prefix; char_type fill; std::size_t padding; F f; size_t size() const { return size_; } size_t width() const { return size_; } template void operator()(It&& it) const { if (prefix.size() != 0) it = internal::copy_str(prefix.begin(), prefix.end(), it); it = std::fill_n(it, padding, fill); f(it); } }; // Writes an integer in the format // // where are written by f(it). template void write_int(int num_digits, string_view prefix, format_specs specs, F f) { std::size_t size = prefix.size() + internal::to_unsigned(num_digits); char_type fill = specs.fill[0]; std::size_t padding = 0; if (specs.align == align::numeric) { auto unsiged_width = internal::to_unsigned(specs.width); if (unsiged_width > size) { padding = unsiged_width - size; size = unsiged_width; } } else if (specs.precision > num_digits) { size = prefix.size() + internal::to_unsigned(specs.precision); padding = internal::to_unsigned(specs.precision - num_digits); fill = static_cast('0'); } if (specs.align == align::none) specs.align = align::right; write_padded(specs, padded_int_writer{size, prefix, fill, padding, f}); } // Writes a decimal integer. template void write_decimal(Int value) { auto abs_value = static_cast>(value); bool is_negative = internal::is_negative(value); if (is_negative) abs_value = 0 - abs_value; int num_digits = internal::count_digits(abs_value); auto&& it = reserve((is_negative ? 1 : 0) + static_cast(num_digits)); if (is_negative) *it++ = static_cast('-'); it = internal::format_decimal(it, abs_value, num_digits); } // The handle_int_type_spec handler that writes an integer. template struct int_writer { using unsigned_type = uint32_or_64_t; basic_writer& writer; const Specs& specs; unsigned_type abs_value; char prefix[4]; unsigned prefix_size; string_view get_prefix() const { return string_view(prefix, prefix_size); } int_writer(basic_writer& w, Int value, const Specs& s) : writer(w), specs(s), abs_value(static_cast(value)), prefix_size(0) { if (internal::is_negative(value)) { prefix[0] = '-'; ++prefix_size; abs_value = 0 - abs_value; } else if (specs.sign != sign::none && specs.sign != sign::minus) { prefix[0] = specs.sign == sign::plus ? '+' : ' '; ++prefix_size; } } struct dec_writer { unsigned_type abs_value; int num_digits; template void operator()(It&& it) const { it = internal::format_decimal(it, abs_value, num_digits); } }; void on_dec() { int num_digits = internal::count_digits(abs_value); writer.write_int(num_digits, get_prefix(), specs, dec_writer{abs_value, num_digits}); } struct hex_writer { int_writer& self; int num_digits; template void operator()(It&& it) const { it = internal::format_uint<4, char_type>(it, self.abs_value, num_digits, self.specs.type != 'x'); } }; void on_hex() { if (specs.alt) { prefix[prefix_size++] = '0'; prefix[prefix_size++] = specs.type; } int num_digits = internal::count_digits<4>(abs_value); writer.write_int(num_digits, get_prefix(), specs, hex_writer{*this, num_digits}); } template struct bin_writer { unsigned_type abs_value; int num_digits; template void operator()(It&& it) const { it = internal::format_uint(it, abs_value, num_digits); } }; void on_bin() { if (specs.alt) { prefix[prefix_size++] = '0'; prefix[prefix_size++] = static_cast(specs.type); } int num_digits = internal::count_digits<1>(abs_value); writer.write_int(num_digits, get_prefix(), specs, bin_writer<1>{abs_value, num_digits}); } void on_oct() { int num_digits = internal::count_digits<3>(abs_value); if (specs.alt && specs.precision <= num_digits) { // Octal prefix '0' is counted as a digit, so only add it if precision // is not greater than the number of digits. prefix[prefix_size++] = '0'; } writer.write_int(num_digits, get_prefix(), specs, bin_writer<3>{abs_value, num_digits}); } enum { sep_size = 1 }; struct num_writer { unsigned_type abs_value; int size; char_type sep; template void operator()(It&& it) const { basic_string_view s(&sep, sep_size); // Index of a decimal digit with the least significant digit having // index 0. unsigned digit_index = 0; it = internal::format_decimal( it, abs_value, size, [s, &digit_index](char_type*& buffer) { if (++digit_index % 3 != 0) return; buffer -= s.size(); std::uninitialized_copy(s.data(), s.data() + s.size(), internal::make_checked(buffer, s.size())); }); } }; void on_num() { int num_digits = internal::count_digits(abs_value); char_type sep = internal::thousands_sep(writer.locale_); int size = num_digits + sep_size * ((num_digits - 1) / 3); writer.write_int(size, get_prefix(), specs, num_writer{abs_value, size, sep}); } FMT_NORETURN void on_error() { FMT_THROW(format_error("invalid type specifier")); } }; enum { inf_size = 3 }; // This is an enum to workaround a bug in MSVC. struct inf_or_nan_writer { char sign; bool as_percentage; const char* str; size_t size() const { return static_cast(inf_size + (sign ? 1 : 0) + (as_percentage ? 1 : 0)); } size_t width() const { return size(); } template void operator()(It&& it) const { if (sign) *it++ = static_cast(sign); it = internal::copy_str( str, str + static_cast(inf_size), it); if (as_percentage) *it++ = static_cast('%'); } }; struct double_writer { char sign; internal::buffer& buffer; char* decimal_point_pos; char_type decimal_point; size_t size() const { return buffer.size() + (sign ? 1 : 0); } size_t width() const { return size(); } template void operator()(It&& it) { if (sign) *it++ = static_cast(sign); auto begin = buffer.begin(); if (decimal_point_pos) { it = internal::copy_str(begin, decimal_point_pos, it); *it++ = decimal_point; begin = decimal_point_pos + 1; } it = internal::copy_str(begin, buffer.end(), it); } }; class grisu_writer { private: internal::buffer& digits_; size_t size_; char sign_; int exp_; internal::gen_digits_params params_; char_type decimal_point_; public: grisu_writer(char sign, internal::buffer& digits, int exp, const internal::gen_digits_params& params, char_type decimal_point) : digits_(digits), sign_(sign), exp_(exp), params_(params), decimal_point_(decimal_point) { int num_digits = static_cast(digits.size()); int full_exp = num_digits + exp - 1; int precision = params.num_digits > 0 ? params.num_digits : 11; params_.fixed |= full_exp >= -4 && full_exp < precision; auto it = internal::grisu_prettify( digits.data(), num_digits, exp, internal::counting_iterator(), params_, '.'); size_ = it.count(); } size_t size() const { return size_ + (sign_ ? 1 : 0); } size_t width() const { return size(); } template void operator()(It&& it) { if (sign_) *it++ = static_cast(sign_); int num_digits = static_cast(digits_.size()); it = internal::grisu_prettify(digits_.data(), num_digits, exp_, it, params_, decimal_point_); } }; template struct str_writer { const Char* s; size_t size_; size_t size() const { return size_; } size_t width() const { return internal::count_code_points(basic_string_view(s, size_)); } template void operator()(It&& it) const { it = internal::copy_str(s, s + size_, it); } }; template struct pointer_writer { UIntPtr value; int num_digits; size_t size() const { return to_unsigned(num_digits) + 2; } size_t width() const { return size(); } template void operator()(It&& it) const { *it++ = static_cast('0'); *it++ = static_cast('x'); it = internal::format_uint<4, char_type>(it, value, num_digits); } }; public: /** Constructs a ``basic_writer`` object. */ explicit basic_writer(Range out, internal::locale_ref loc = internal::locale_ref()) : out_(out.begin()), locale_(loc) {} iterator out() const { return out_; } // Writes a value in the format // // where is written by f(it). template void write_padded(const format_specs& specs, F&& f) { // User-perceived width (in code points). unsigned width = to_unsigned(specs.width); size_t size = f.size(); // The number of code units. size_t num_code_points = width != 0 ? f.width() : size; if (width <= num_code_points) return f(reserve(size)); auto&& it = reserve(width + (size - num_code_points)); char_type fill = specs.fill[0]; std::size_t padding = width - num_code_points; if (specs.align == align::right) { it = std::fill_n(it, padding, fill); f(it); } else if (specs.align == align::center) { std::size_t left_padding = padding / 2; it = std::fill_n(it, left_padding, fill); f(it); it = std::fill_n(it, padding - left_padding, fill); } else { f(it); it = std::fill_n(it, padding, fill); } } void write(int value) { write_decimal(value); } void write(long value) { write_decimal(value); } void write(long long value) { write_decimal(value); } void write(unsigned value) { write_decimal(value); } void write(unsigned long value) { write_decimal(value); } void write(unsigned long long value) { write_decimal(value); } // Writes a formatted integer. template void write_int(T value, const Spec& spec) { internal::handle_int_type_spec(spec.type, int_writer(*this, value, spec)); } void write(double value, const format_specs& specs = format_specs()) { write_double(value, specs); } /** \rst Formats *value* using the general format for floating-point numbers (``'g'``) and writes it to the buffer. \endrst */ void write(long double value, const format_specs& specs = format_specs()) { write_double(value, specs); } // Formats a floating-point number (double or long double). template ()> void write_double(T value, const format_specs& specs); /** Writes a character to the buffer. */ void write(char value) { auto&& it = reserve(1); *it++ = value; } template ::value)> void write(Char value) { auto&& it = reserve(1); *it++ = value; } /** \rst Writes *value* to the buffer. \endrst */ void write(string_view value) { auto&& it = reserve(value.size()); it = internal::copy_str(value.begin(), value.end(), it); } void write(wstring_view value) { static_assert(std::is_same::value, ""); auto&& it = reserve(value.size()); it = std::copy(value.begin(), value.end(), it); } // Writes a formatted string. template void write(const Char* s, std::size_t size, const format_specs& specs) { write_padded(specs, str_writer{s, size}); } template void write(basic_string_view s, const format_specs& specs = format_specs()) { const Char* data = s.data(); std::size_t size = s.size(); if (specs.precision >= 0 && internal::to_unsigned(specs.precision) < size) size = internal::to_unsigned(specs.precision); write(data, size, specs); } template void write_pointer(UIntPtr value, const format_specs* specs) { int num_digits = internal::count_digits<4>(value); auto pw = pointer_writer{value, num_digits}; if (!specs) return pw(reserve(to_unsigned(num_digits) + 2)); format_specs specs_copy = *specs; if (specs_copy.align == align::none) specs_copy.align = align::right; write_padded(specs_copy, pw); } }; using writer = basic_writer>; template class arg_formatter_base { public: using char_type = typename Range::value_type; using iterator = typename Range::iterator; using format_specs = basic_format_specs; private: using writer_type = basic_writer; writer_type writer_; format_specs* specs_; struct char_writer { char_type value; size_t size() const { return 1; } size_t width() const { return 1; } template void operator()(It&& it) const { *it++ = value; } }; void write_char(char_type value) { if (specs_) writer_.write_padded(*specs_, char_writer{value}); else writer_.write(value); } void write_pointer(const void* p) { writer_.write_pointer(internal::bit_cast(p), specs_); } protected: writer_type& writer() { return writer_; } FMT_DEPRECATED format_specs* spec() { return specs_; } format_specs* specs() { return specs_; } iterator out() { return writer_.out(); } void write(bool value) { string_view sv(value ? "true" : "false"); specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); } void write(const char_type* value) { if (!value) FMT_THROW(format_error("string pointer is null")); auto length = std::char_traits::length(value); basic_string_view sv(value, length); specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); } public: arg_formatter_base(Range r, format_specs* s, locale_ref loc) : writer_(r, loc), specs_(s) {} iterator operator()(monostate) { FMT_ASSERT(false, "invalid argument type"); return out(); } template ::value)> iterator operator()(T value) { if (specs_) writer_.write_int(value, *specs_); else writer_.write(value); return out(); } iterator operator()(char_type value) { internal::handle_char_specs( specs_, char_spec_handler(*this, static_cast(value))); return out(); } iterator operator()(bool value) { if (specs_ && specs_->type) return (*this)(value ? 1 : 0); write(value != 0); return out(); } template ::value)> iterator operator()(T value) { writer_.write_double(value, specs_ ? *specs_ : format_specs()); return out(); } struct char_spec_handler : ErrorHandler { arg_formatter_base& formatter; char_type value; char_spec_handler(arg_formatter_base& f, char_type val) : formatter(f), value(val) {} void on_int() { if (formatter.specs_) formatter.writer_.write_int(value, *formatter.specs_); else formatter.writer_.write(value); } void on_char() { formatter.write_char(value); } }; struct cstring_spec_handler : internal::error_handler { arg_formatter_base& formatter; const char_type* value; cstring_spec_handler(arg_formatter_base& f, const char_type* val) : formatter(f), value(val) {} void on_string() { formatter.write(value); } void on_pointer() { formatter.write_pointer(value); } }; iterator operator()(const char_type* value) { if (!specs_) return write(value), out(); internal::handle_cstring_type_spec(specs_->type, cstring_spec_handler(*this, value)); return out(); } iterator operator()(basic_string_view value) { if (specs_) { internal::check_string_type_spec(specs_->type, internal::error_handler()); writer_.write(value, *specs_); } else { writer_.write(value); } return out(); } iterator operator()(const void* value) { if (specs_) check_pointer_type_spec(specs_->type, internal::error_handler()); write_pointer(value); return out(); } }; template FMT_CONSTEXPR bool is_name_start(Char c) { return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; } // Parses the range [begin, end) as an unsigned integer. This function assumes // that the range is non-empty and the first character is a digit. template FMT_CONSTEXPR int parse_nonnegative_int(const Char*& begin, const Char* end, ErrorHandler&& eh) { assert(begin != end && '0' <= *begin && *begin <= '9'); if (*begin == '0') { ++begin; return 0; } unsigned value = 0; // Convert to unsigned to prevent a warning. unsigned max_int = (std::numeric_limits::max)(); unsigned big = max_int / 10; do { // Check for overflow. if (value > big) { value = max_int + 1; break; } value = value * 10 + unsigned(*begin - '0'); ++begin; } while (begin != end && '0' <= *begin && *begin <= '9'); if (value > max_int) eh.on_error("number is too big"); return static_cast(value); } template class custom_formatter { private: using char_type = typename Context::char_type; basic_parse_context& parse_ctx_; Context& ctx_; public: explicit custom_formatter(basic_parse_context& parse_ctx, Context& ctx) : parse_ctx_(parse_ctx), ctx_(ctx) {} bool operator()(typename basic_format_arg::handle h) const { h.format(parse_ctx_, ctx_); return true; } template bool operator()(T) const { return false; } }; template using is_integer = bool_constant::value && !std::is_same::value && !std::is_same::value && !std::is_same::value>; template class width_checker { public: explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {} template ::value)> FMT_CONSTEXPR unsigned long long operator()(T value) { if (is_negative(value)) handler_.on_error("negative width"); return static_cast(value); } template ::value)> FMT_CONSTEXPR unsigned long long operator()(T) { handler_.on_error("width is not integer"); return 0; } private: ErrorHandler& handler_; }; template class precision_checker { public: explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {} template ::value)> FMT_CONSTEXPR unsigned long long operator()(T value) { if (is_negative(value)) handler_.on_error("negative precision"); return static_cast(value); } template ::value)> FMT_CONSTEXPR unsigned long long operator()(T) { handler_.on_error("precision is not integer"); return 0; } private: ErrorHandler& handler_; }; // A format specifier handler that sets fields in basic_format_specs. template class specs_setter { public: explicit FMT_CONSTEXPR specs_setter(basic_format_specs& specs) : specs_(specs) {} FMT_CONSTEXPR specs_setter(const specs_setter& other) : specs_(other.specs_) {} FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; } FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill[0] = fill; } FMT_CONSTEXPR void on_plus() { specs_.sign = sign::plus; } FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; } FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; } FMT_CONSTEXPR void on_hash() { specs_.alt = true; } FMT_CONSTEXPR void on_zero() { specs_.align = align::numeric; specs_.fill[0] = Char('0'); } FMT_CONSTEXPR void on_width(int width) { specs_.width = width; } FMT_CONSTEXPR void on_precision(int precision) { specs_.precision = precision; } FMT_CONSTEXPR void end_precision() {} FMT_CONSTEXPR void on_type(Char type) { specs_.type = static_cast(type); } protected: basic_format_specs& specs_; }; template class numeric_specs_checker { public: FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, internal::type arg_type) : error_handler_(eh), arg_type_(arg_type) {} FMT_CONSTEXPR void require_numeric_argument() { if (!is_arithmetic(arg_type_)) error_handler_.on_error("format specifier requires numeric argument"); } FMT_CONSTEXPR void check_sign() { require_numeric_argument(); if (is_integral(arg_type_) && arg_type_ != int_type && arg_type_ != long_long_type && arg_type_ != internal::char_type) { error_handler_.on_error("format specifier requires signed argument"); } } FMT_CONSTEXPR void check_precision() { if (is_integral(arg_type_) || arg_type_ == internal::pointer_type) error_handler_.on_error("precision not allowed for this argument type"); } private: ErrorHandler& error_handler_; internal::type arg_type_; }; // A format specifier handler that checks if specifiers are consistent with the // argument type. template class specs_checker : public Handler { public: FMT_CONSTEXPR specs_checker(const Handler& handler, internal::type arg_type) : Handler(handler), checker_(*this, arg_type) {} FMT_CONSTEXPR specs_checker(const specs_checker& other) : Handler(other), checker_(*this, other.arg_type_) {} FMT_CONSTEXPR void on_align(align_t align) { if (align == align::numeric) checker_.require_numeric_argument(); Handler::on_align(align); } FMT_CONSTEXPR void on_plus() { checker_.check_sign(); Handler::on_plus(); } FMT_CONSTEXPR void on_minus() { checker_.check_sign(); Handler::on_minus(); } FMT_CONSTEXPR void on_space() { checker_.check_sign(); Handler::on_space(); } FMT_CONSTEXPR void on_hash() { checker_.require_numeric_argument(); Handler::on_hash(); } FMT_CONSTEXPR void on_zero() { checker_.require_numeric_argument(); Handler::on_zero(); } FMT_CONSTEXPR void end_precision() { checker_.check_precision(); } private: numeric_specs_checker checker_; }; template